Mengapa tidak menggunakan IP Xilinx clock manager?
Arturs Vancans
Jawaban:
19
Pada dasarnya, ada dua cara untuk melakukan ini. Yang pertama adalah menggunakan inti synthesizer clock asli Xilinx. Salah satu keuntungannya adalah alat Xlinx akan mengenali jam seperti itu dan merutekannya melalui jalur yang diperlukan. Alat ini juga akan menangani kendala waktu apa pun (tidak benar-benar berlaku dalam kasus ini, karena ini adalah jam 2Hz)
Cara kedua adalah menggunakan penghitung untuk menghitung jumlah pulsa clock yang lebih cepat hingga setengah dari periode clock Anda yang lebih lambat berlalu. Misalnya, untuk kasus Anda, jumlah pulsa clock cepat yang membentuk satu periode clock dari siklus clock lambat adalah 50000000/2 = 25000000. Karena kami ingin setengah periode clock, itu 25000000/2 = 12500000 untuk setiap setengah siklus . (durasi masing-masing tinggi atau rendah).
Begini tampilannya di VHDL:
library IEEE;use IEEE.STD_LOGIC_1164.all;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned valuesuse IEEE.NUMERIC_STD.all;entity scale_clock isport(
clk_50Mhz :instd_logic;
rst :instd_logic;
clk_2Hz :outstd_logic);end scale_clock;architecture Behavioral of scale_clock issignal prescaler :unsigned(23downto0);signal clk_2Hz_i :std_logic;begin
gen_clk :process(clk_50Mhz, rst)begin-- process gen_clkif rst ='1'then
clk_2Hz_i <='0';
prescaler <=(others=>'0');elsif rising_edge(clk_50Mhz)then-- rising clock edgeif prescaler =X"BEBC20"then-- 12 500 000 in hex
prescaler <=(others=>'0');
clk_2Hz_i <=not clk_2Hz_i;else
prescaler <= prescaler +"1";endif;endif;endprocess gen_clk;
clk_2Hz <= clk_2Hz_i;end Behavioral;
Hal yang perlu diperhatikan:
Jam yang dihasilkan adalah nol selama reset. Ini ok untuk beberapa aplikasi, dan tidak untuk yang lain, itu hanya tergantung apa yang Anda butuhkan untuk jam.
Jam yang dihasilkan akan dialihkan sebagai sinyal normal oleh alat sintesis Xilinx.
2Hz sangat lambat. Simulasi sebentar akan membutuhkan waktu. Ini adalah sejumlah kecil kode, sehingga harus relatif cepat untuk mensimulasikan bahkan selama 1 detik, tetapi jika Anda mulai menambahkan kode, waktu yang dibutuhkan untuk mensimulasikan siklus clock 2 Hz bisa sangat lama.
EDIT: clk_2Hz_i digunakan untuk buffer sinyal output. VHDL tidak suka menggunakan sinyal di sebelah kanan tugas ketika itu juga merupakan output.
Tidak buruk, tetapi Anda dapat menambahkan / membandingkan unsigned dengan integer, jadi: if prescaler = 50_000_000/4 then ...dan prescaler <= prescaler + 1;akan sedikit lebih sederhana.
Brian Drummond
@StaceyAnne Mencoba ini, saya mendapatkan "Tidak dapat membaca dari objek 'out' clk_o; gunakan 'buffer' atau 'inout'" apakah saya melewatkan sesuatu?
menghindari
Membalas, diperlukan buffer pada output. VHDL tidak menyukai fakta bahwa clk_2Hzini adalah output, tetapi nilainya sedang dibaca di baris ini clk_2Hz <= not clk_2Hz;. Saya sudah mengedit dalam perbaikan.
stanri
+1 Contoh yang bagus. Tapi di sinilah ketidaktahuan saya menunjukkan (baru VHDL). Apa perbedaan antara prescaler <= (others => '0');dan prescaler <= '0';?
cbmeeks
NVM! Saya benar-benar merindukan apa othersyang digunakan ketika membaca buku VHDL yang saya miliki. Itu hanya jalan pintas untuk mendeklarasikan semua bit "lain" ke nilai yang sama daripada menggunakan sesuatu seperti "00000000000000000000 ....", dll.
cbmeeks
9
Gunakan prescaler jam.
Nilai prescaler Anda akan menjadi Anda (clock_speed / diinginkan_clock_speed) / 2 so (50Mhz (50.000.000) / 2hz (2)) / 2 = 12.500.000 yang dalam biner adalah 101111101011110000100000000.
Lebih sederhana: (50.000.000) / 2) / 2 = 12.500.000 dikonversi ke biner -> 101111101011110000100000000
Berikut adalah beberapa kode yang harus dilakukan: Gunakan newClock untuk apa pun yang Anda butuhkan 2hz untuk ...
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity ClockPrescaler isport(
clock :inSTD_LOGIC;-- 50 Mhz
Led :outSTD_LOGIC);end ClockPrescaler;architecture Behavioral of ClockPrescaler is-- prescaler should be (clock_speed/desired_clock_speed)/2 because you want a rising edge every periodsignal prescaler:STD_LOGIC_VECTOR(23downto0):="101111101011110000100000";-- 12,500,000 in binarysignal prescaler_counter:STD_LOGIC_VECTOR(23downto0):=(others=>'0');signal newClock :std_logic:='0';begin
Led <= newClock;
countClock:process(clock, newClock)beginif rising_edge(clock)then
prescaler_counter <= prescaler_counter +1;if(prescaler_counter > prescaler)then-- Iterate
newClock <=not newClock;
prescaler_counter <=(others=>'0');endif;endif;endprocess;end Behavioral;
Sepertinya Anda menghasilkan dua jam, satu dari 0,5 Hz dan satu dari 1 Hz? (Karena periode jam Anda adalah prescaler Anda * 2?). Juga, "+" akan memberikan kesalahan, karena Anda menambahkan slv, dan saya tidak begitu yakin tentang menggunakan properti overflow dari add dengan cara ini. mengapa tidak pergi saja newClock : std_logic := '0', hitung hingga prescaler / 2 dan tetapkan newClk <= not newClk?
stanri
Terima kasih, logika saya agak kacau. Saya memperbarui posting awal saya dengan beberapa kode yang diuji sekarang dan beberapa saran Anda :)
MLM
Ugh - semua itu dan nol dan komentar untuk mengatakan apa itu sebenarnya! Mengapa tidak menggunakan kompiler untuk melakukannya untuk Anda ??? Dan mengapa tidak menggunakan bilangan bulat saja?
Martin Thompson
Saya mungkin salah, tapi saya pikir menggunakan nilai default ketika mendefinisikan sinyal dalam arsitektur seperti dalam ": = (others => '0')" tidak dapat disintesis.
Arturs Vancans
Ini dapat disintesis, tetapi pada dasarnya hanya bekerja pada FPGA berbasis SRAM, seperti kebanyakan dari Xilinx, Altera atau Lattice.
Yann Vernier
8
Anda biasanya tidak benar-benar ingin clock apa pun yang lambat, buat saja sebuah mengaktifkan pada tingkat yang benar dan menggunakannya dalam logika:
Ini memiliki antarmuka pengaturan grafis di mana Anda dapat menentukan frekuensi apa yang Anda inginkan. Ini akan menghasilkan komponen dengan output yang Anda inginkan sebagai frekuensi.
Itu dapat ditemukan di IP Wizard;
Dan kemudian Anda akan dapat menentukan frekuensi apa yang Anda inginkan:
Jawaban:
Pada dasarnya, ada dua cara untuk melakukan ini. Yang pertama adalah menggunakan inti synthesizer clock asli Xilinx. Salah satu keuntungannya adalah alat Xlinx akan mengenali jam seperti itu dan merutekannya melalui jalur yang diperlukan. Alat ini juga akan menangani kendala waktu apa pun (tidak benar-benar berlaku dalam kasus ini, karena ini adalah jam 2Hz)
Cara kedua adalah menggunakan penghitung untuk menghitung jumlah pulsa clock yang lebih cepat hingga setengah dari periode clock Anda yang lebih lambat berlalu. Misalnya, untuk kasus Anda, jumlah pulsa clock cepat yang membentuk satu periode clock dari siklus clock lambat adalah 50000000/2 = 25000000. Karena kami ingin setengah periode clock, itu 25000000/2 = 12500000 untuk setiap setengah siklus . (durasi masing-masing tinggi atau rendah).
Begini tampilannya di VHDL:
Hal yang perlu diperhatikan:
EDIT: clk_2Hz_i digunakan untuk buffer sinyal output. VHDL tidak suka menggunakan sinyal di sebelah kanan tugas ketika itu juga merupakan output.
sumber
if prescaler = 50_000_000/4 then ...
danprescaler <= prescaler + 1;
akan sedikit lebih sederhana.clk_2Hz
ini adalah output, tetapi nilainya sedang dibaca di baris iniclk_2Hz <= not clk_2Hz;
. Saya sudah mengedit dalam perbaikan.prescaler <= (others => '0');
danprescaler <= '0';
?others
yang digunakan ketika membaca buku VHDL yang saya miliki. Itu hanya jalan pintas untuk mendeklarasikan semua bit "lain" ke nilai yang sama daripada menggunakan sesuatu seperti "00000000000000000000 ....", dll.Gunakan prescaler jam.
Nilai prescaler Anda akan menjadi Anda (clock_speed / diinginkan_clock_speed) / 2 so (50Mhz (50.000.000) / 2hz (2)) / 2 = 12.500.000 yang dalam biner adalah 101111101011110000100000000.
Lebih sederhana: (50.000.000) / 2) / 2 = 12.500.000 dikonversi ke biner -> 101111101011110000100000000
Berikut adalah beberapa kode yang harus dilakukan: Gunakan newClock untuk apa pun yang Anda butuhkan 2hz untuk ...
sumber
newClock : std_logic := '0'
, hitung hingga prescaler / 2 dan tetapkannewClk <= not newClk
?Anda biasanya tidak benar-benar ingin clock apa pun yang lambat, buat saja sebuah mengaktifkan pada tingkat yang benar dan menggunakannya dalam logika:
Anda dapat membuat mengaktifkan dengan demikian:
buat beberapa konstanta dengan frekuensi jam Anda dan frekuensi aktifkan yang diinginkan dan pergilah, dengan kode dokumentasi sendiri untuk boot.
sumber
Saya lebih suka menyarankan menggunakan Xilinx primitice digital clock manager IP .
Ini memiliki antarmuka pengaturan grafis di mana Anda dapat menentukan frekuensi apa yang Anda inginkan. Ini akan menghasilkan komponen dengan output yang Anda inginkan sebagai frekuensi.
Itu dapat ditemukan di IP Wizard;
Dan kemudian Anda akan dapat menentukan frekuensi apa yang Anda inginkan:
sumber
Faktor = frekuensi-sinyal-input-input / output-prescaler-frekuensi.
CE = Clock Enable. Seharusnya pulsa lebar satu jam (clk) atau tinggi jika tidak digunakan.
T = Sinyal keluaran pulsa lebar satu jam dengan frekuensi yang diinginkan.
sumber