Minulla on Xilinx FPGA -levy, jossa on 50 MHz: n kristalli. Minun on jaettava se 2 Hz: iin VHDL: ssä. Kuinka teen tämän?
Minulla on Xilinx FPGA -levy, jossa on 50 MHz: n kristalli. Minun on jaettava se 2 Hz: iin VHDL: ssä. Kuinka teen tämän?
Periaatteessa tähän on kaksi tapaa. Ensimmäinen on käyttää Xilinx-natiivikellosyntetisaattorin ydintä. Yksi tämän eduista on, että Xlinx-työkalut tunnistavat kellon sellaisenaan ja reitittävät sen vaadittujen reittien läpi. Työkalut käsittelevät myös kaikki aikarajoitukset (ei oikeastaan sovellettavissa tässä tapauksessa, koska se on 2 Hz: n kello).
Toinen tapa on laskurin avulla laskea nopeamman kellopulssin määrä, kunnes puolet hitaammasta kellonaika on kulunut. Esimerkiksi sinun tapauksessasi nopeiden kellopulssien määrä, joka muodostaa yhden hitaan kellojakson kellojakson, on 50000000/2 = 25000000. Koska haluamme puoli kellojaksoa, se on 25000000/2 = 12500000 kutakin puolijaksoa kohti . (kunkin korkean tai matalan kesto).
VHDL: ssä se näyttää tältä:
library IEEE; use IEEE.STD_LOGIC_1164.all; - Poista seuraava kommentti kirjastoilmoitus, jos käytetään - aritmeettisia toimintoja allekirjoitetuilla tai allekirjoittamattomilla arvoilla, käytä IEEE.NUMERIC_STD.all; entiteetti scale_clock on portti (clk_50Mhz: in std_logic; rst: in std_logic; clk_2Hz: out std_logic); end scale_clock; arkkitehtuuri Scale_clock-käyttäytyminen on signaalin esijärjestelmä : allekirjoittamaton (23 - 0); signaali clk_2Hz_i: std_logic; aloita gen_clk: prosessi (clk_50Mhz, ensimmäinen) alkaa - prosessi gen_clk, jos rst = '1', sitten clk_2Hz_i < = '0'; esijäähdytin < = (muut = > '0'); elsif rising_edge (clk_50Mhz) sitten - nouseva kellon reuna, jos escalkali = X "BEBC20", sitten - 12 500 000 heksadesimaalissa < = (muut = > '0'); clk_2Hz_i < = ei clk_2Hz_i; muut esijäähdyttimet < = esijäähdyttimet + "1"; loppu Jos; loppu Jos; end process gen_clk; clk_2Hz < = clk_2Hz_i; end Behavioral;
Huomattavat asiat:
EDIT: clk_2Hz_i käytetään lähtösignaalin puskurointiin. VHDL ei halua käyttää signaalia tehtävän oikealla puolella, kun se on myös lähtö.
Käytä kellon esiasteikkoa.
Esikalkkeri-arvon arvo on (kellonopeus / haluttu kellonopeuden nopeus) / 2 joten (50Mhz (50,000,000) / 2hz (2)) / 2 = 12,500,000, joka binaarisesti olisi 101111101011110000100000 .
Yksinkertaisemmin: (50 000 000) / 2) / 2 = 12 500 000 muunna binaariseksi -> 101111101011110000100000
Tässä on jotkut koodit tekemisistä: Käytä newClock-toimintoa mihin tahansa 2 Hz: n tarvitsemaan ...
kirjasto IEEE; käytä IEEE.STD_LOGIC_1164.ALL; käytä IEEE.STD_LOGIC_UNSIGNED.ALL; entiteetti ClockPrescaler on portti ( kello: STD_LOGIC-tilassa; - 50 MHz Led: ulos STD_LOGIC); loppu ClockPrescaler; arkkitehtuuri ClockPrescaler-käyttäytyminen on - esijäähdyttimen tulisi olla (kellonopeus / haluttu_kellonopeus) / 2, koska haluat nousevan reunan jokaisen jakson esiskalaattorille: STD_LOGIC_VECTOR (23 alaspäin) 0): = "101111101011110000100000"; - 12 500 000 binaarisignaalin esilaskurin_laskuri: STD_LOGIC_VECTOR (23 alas 0): = (muut = > '0'); signaali newClock: std_logic: = '0'; alkaa Led < = newClock; countClock: prosessi (kello, newClock) alkaa, jos nouseva_reuna (kello) sitten prescaler_counter < = prescaler_counter + 1; if (prescaler_counter > -esikalkkuri) sitten - Iterate newClock < = not newClock; prescaler_counter < = (muut = > '0'); loppu Jos; loppu Jos; lopeta prosessi; lopeta käyttäytyminen;
Et yleensä halua kelloa mitään hidasta, luo vain käyttöönotto oikealla nopeudella ja käytä sitä logiikassa:
if rising_edge (50MHz_clk) and enable = ' 1 'sitten
voit luoda käyttöönoton näin:
prosessimuuttujien määrä: luonnollinen; aloita, jos nouseva reuna (50MHz_clk) otetaan sitten käyttöön < =' 0 ' ; määrä: = laskenta + 1; jos count = clock_freq / haluttu_freq ota < = '1' käyttöön; määrä: = 0; loppu Jos; end if; lopeta prosessi;
luo pari vakiota kellotaajuudellasi ja haluamallasi aktivointitaajuudella ja poissa. Käynnistä itse dokumentoiva koodi.
Ehdotan mieluummin Xilinx primitice -digitaalikellon hallintaohjelman IP-osoitteen käyttämistä.
Siinä on graafinen asetusrajapinta, jossa voit määrittää haluamasi taajuuden. Se luo komponentin, jonka taajuus on haluamasi lähtö.
Se löytyy ohjatusta IP-toiminnosta;
Ja sitten voit määritä haluamasi taajuus:
Faktori = tulosignaalin frecuency / output-prescaler-frecuency.
CE = Clock Enable. Sen pitäisi olla yhden kellon (clk) leveä pulssi tai korkea, jos sitä ei käytetä.
Q = Yhden kellon leveän pulssin lähtösignaali halutulla frukiteetilla.
kirjasto IEEE ; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entiteetin esijärjestelmä on yleinen (FACTOR: kokonaisluku); portti (clk: in std_logic; rst: in std_logic; CE: in std_logic; Q: out std_logic); end preskaler; prescalerin_esimerkin_arkkitehtuuri on signaalin counter_reg, counter_next: kokonaislukualue 0 - FACTOR-1; signaali Q_seuraava: std_logic; Aloita - for_prescaler -prosessi (clk, rst) alkaa - prosessi, jos rst = '1', sitten - asynkroninen nollaus (aktiivinen matala) counter_reg < = 0; elsif clk'event ja clk = '1' sitten - nouseva kellon reuna counter_reg < = counter_next; loppu Jos; lopeta prosessi; prosessi (counter_reg, CE) alkaa - prosessi Q_seuraava < = '0'; counter_next < = laskuri_reg; jos CE = '1', niin jos counter_reg = FACTOR-1, sitten counter_next < = 0; Q_seuraava < = '1'; else counter_next < = counter_reg + 1; loppu Jos; loppu Jos; lopeta prosessi; prosessi (clk, rst) alkaa - prosessi, jos rst = '1', sitten - asynkroninen nollaus (aktiivinen matala) Q < = '0'; elsif clk'event ja clk = '1' sitten - nouseva kellonreuna Q < = Q_seuraava; loppu Jos; lopeta prosessi; end for_prescaler;