Penguasaan Pernyataan Generate VHDL: Bangun Debouncer Reusable dengan Mudah
Pernyataan generate VHDL memungkinkan desainer untuk secara otomatis mereplikasi blok kode di beberapa instance, masing-masing terhubung ke sinyal yang berbeda. Pikirkan itu sebagai loop for waktu kompilasi yang dapat membuat proses rantai atau instance modul, secara dramatis mengurangi kode boilerplate dan meningkatkan kemudahan pemeliharaan.
Berbeda dengan loop tradisional yang terbatas pada proses atau subprogram, generate berada langsung di wilayah arsitektur. Saat digabungkan dengan generics, itu menjadi mekanisme yang kuat untuk menciptakan komponen VHDL yang sangat konfigurable dan reusable.
Sintaks Pernyataan Generate
[label :] for <constant_name> in <range> generate [declarations_local_to_each_loop_iteration] [begin] <processes_and_instantiations> end generate [label];
Elemen opsional diapit dalam kurung siku. Anda dapat menghilangkan wilayah deklaratif dan kata kunci begin jika tidak ada objek lokal yang dideklarasikan. <range> mengikuti sintaks integer standar menggunakan to atau downto.
Debouncer Saklar Satu-Bit
Sebelum menyelami generate, mari kita tinjau debouncer sederhana yang membersihkan input satu saklar. Generic timeout_cycles memungkinkan modul untuk menyesuaikan dengan frekuensi clock apa pun. Debouncer ini menekan glitch transien yang terjadi saat saklar mekanis beralihan.
entity debouncer is generic ( timeout_cycles : positive ); port ( clk : in std_logic; rst : in std_logic; switch : in std_logic; switch_debounced : out std_logic ); end debouncer;
Implementasi bergantung pada counter integer yang lebarnya ditentukan oleh generic. Sinyal bayangan debounced digunakan secara internal untuk menjaga logika output tetap bersih.
architecture rtl of debouncer is signal debounced : std_logic; signal counter : integer range 0 to timeout_cycles - 1; begin -- Copy internal signal to output switch_debounced <= debounced; DEBOUNCE_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then counter <= 0; debounced <= switch; else if counter < timeout_cycles - 1 then counter <= counter + 1; elsif switch /= debounced then counter <= 0; debounced <= switch; end if; end if; end if; end process; end architecture;
Simulasi di ModelSim mengonfirmasi bahwa switch_debounced mengikuti input hanya setelah timeout yang ditentukan, secara efektif menyaring artefak bouncing.
Unduh proyek ModelSim lengkap, termasuk testbench, dengan memberikan alamat email Anda di bawah ini. Semua pembaruan dikirim dari VHDLwhiz, dan Anda dapat berhenti berlangganan kapan saja.
Generate Loop dengan Instantiations
Untuk memperluas debouncer ke array saklar, kami menggunakan pernyataan generate untuk membuat beberapa instance secara otomatis.
entity debouncer_gen_inst is generic ( switch_count : positive; timeout_cycles : positive ); port ( clk : in std_logic; rst : in std_logic; switches : in std_logic_vector(switch_count - 1 downto 0); switches_debounced : out std_logic_vector(switch_count - 1 downto 0) ); end debouncer_gen_inst;
Arsitektur menggunakan loop generate untuk membuat instance debouncer untuk setiap bit saklar. Setiap instance berbagi clock dan reset yang sama tetapi terhubung ke elemen vektor yang berbeda.
architecture rtl of debouncer_gen_inst is begin MY_GEN : for i in 0 to switch_count - 1 generate DEBOUNCER : entity work.debouncer(rtl) generic map ( timeout_cycles => timeout_cycles ) port map ( clk => clk, rst => rst, switch => switches(i), switch_debounced => switches_debounced(i) ); end generate; end architecture;
Memberi label pada blok generate (misalnya, MY_GEN) meningkatkan keterbacaan dalam hierarki simulator dan laporan sintesis, sehingga debugging menjadi mudah.
Testbench hanya mengubah saklar 3, jadi gelombang berfokus pada MY_GEN(3). Jalankan contoh ini di ModelSim untuk melihat logika debouncing dalam tindakan.
Generate Loop yang Berisi Proses
Alternatifnya, Anda dapat mengangkat logika debouncer ke dalam blok generate itu sendiri, menghilangkan instantiasi komponen terpisah. Pendekatan ini menunjukkan bahwa loop generate juga dapat membuat proses yang identik dengan sinyal lokal.
architecture rtl of debouncer_gen_proc is begin MY_GEN : for i in 0 to switch_count - 1 generate signal debounced : std_logic; signal counter : integer range 0 to timeout_cycles - 1; begin switches_debounced(i) <= debounced; DEBOUNCE_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then counter <= 0; debounced <= switches(i); else if counter < timeout_cycles - 1 then counter <= counter + 1; elsif switches(i) /= debounced then counter <= 0; debounced <= switches(i); end if; end if; end if; end process; end generate; end architecture;
Hasilnya cocok dengan pendekatan instantiasi modul, tetapi kode terkandung dalam arsitektur. Kedua metode valid; pilih yang paling sesuai dengan gaya desain Anda.
Semua contoh kode, termasuk proyek ModelSim lengkap, tersedia untuk diunduh melalui formulir di bawah ini. Berlangganan VHDLwhiz untuk pembaruan, dan merasa bebas untuk berhenti berlangganan kapan saja.
Punya penggunaan kreatif untuk generate? Bagikan ide Anda di komentar di bawah!