Membuat Testbench yang Diakibatkan Tcl untuk Modul Kode-Kunci VHDL
Sebagian besar simulator VHDL mengekspos Tool Command Language (Tcl) sebagai antarmuka skrip utamanya. Saat Anda mengetik perintah di konsol simulator, Anda menggunakan Tcl, dan Anda juga dapat menulis skrip yang menggerakkan dan mengamati desain VHDL Anda.
Artikel ini memandu Anda melalui pembuatan testbench yang memeriksa dirinya sendiri yang menggunakan Tcl—daripada VHDL—untuk memverifikasi perilaku modul kode-kunci sederhana. Hasilnya adalah rangka uji yang jelas, mudah dipelihara, yang dapat dijalankan, dimodifikasi, dan digunakan kembali tanpa merekompilasi VHDL.
Sebelum menyelami testbench, mari kita tinjau Device Under Test (DUT). Modul ini mengemulasi kunci sederhana yang membuka coffre ketika urutan numerik yang benar dimasukkan pada PIN pad.
Meskipun banyak orang menyebut perangkat semacam ini sebagai "kunci kombinasi," istilah yang benar adalah "kunci permutasi"—urutan digit penting. Untuk kejelasan, kami akan menyebutnya kode kunci di seluruh artikel.
Ilustrasi di atas menunjukkan kotak hotel yang khas. Untuk kesederhanaan, desain kami hanya menggunakan tombol numerik dan menghilangkan tombol CLEAR dan LOCK.
Bagaimana Modul Kode Kunci Bekerja
Kunci dimulai dalam kondisi terkunci. Ketika pengguna memasukkan empat digit berurutan yang cocok dengan PIN rahasia, kunci terbuka. Memasukkan urutan yang salah mengunci ulang perangkat. Perilaku ini diimplementasikan sebagai detektor urutan sederhana dalam VHDL.
Gelombang ini menunjukkan waktu modul. Selain clock dan reset, modul menerima dua input: input_digit (integer 0–9) dan input_enable (std_logic). DUT mengambil digit pada tepi clock naik ketika enable tinggi.
Outputnya hanya unlock, std_logic yang menjadi tinggi hanya ketika empat digit berurutan cocok dengan PIN yang benar. Dalam contoh ini, kata sandi adalah 1234.
Entitas
Definisi entitas berikut mengkodekan PIN rahasia melalui generics. Setiap generic adalah integer dalam rentang 0–9, yang mewakili digit Binary Coded Decimal (BCD).
entity code_lock is generic (pin0, pin1, pin2, pin3 : integer range 0 to 9); port ( clk : in std_logic; rst : in std_logic; input_digit : in integer range 0 to 9; input_enable : in std_logic; unlock : out std_logic ); end code_lock;
Wilayah Deklaratif
Modul ini menggunakan satu sinyal internal—shift register 4-bit yang menyimpan digit terbaru yang dimasukkan. Kami mengizinkan register untuk menampung nilai dari –1 hingga 9. Nilai khusus –1 digunakan untuk kondisi reset, memastikan bahwa PIN 0000 tidak membuka kunci secara default.
type pins_type is array (0 to 3) of integer range -1 to 9; signal pins : pins_type;
Implementasi
Arsitektur mencakup tugas kombinatorial yang mengeluarkan unlock tinggi ketika shift register cocok dengan nilai generic PIN. Karena pins di-clock, unlock hanya berubah pada tepi clock naik.
Proses berikut mengimplementasikan shift register. Pada reset, semua entri diatur ke –1. Ketika input_enable tinggi pada tepi naik, digit saat ini disimpan pada posisi 0, dan digit sebelumnya bergeser ke kanan.
PINS_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then pins <= (others => -1); else if input_enable = '1' then pins(0) <= input_digit; pins(1 to 3) <= pins(0 to 2); end if; end if; end if; end process;
Testbench VHDL
Meski kita akan menggunakan Tcl untuk logika verifikasi, kita masih memerlukan testbench VHDL dasar untuk menghasilkan sinyal clock dan reset. Berikut adalah file testbench VHDL lengkap.
library ieee; use ieee.std_logic_1164.all; entity code_lock_tb is end code_lock_tb; architecture sim of code_lock_tb is constant clk_hz : integer := 100e6; constant clock_period : time := 1 sec / clk_hz; signal clk : std_logic := '1'; signal rst : std_logic := '1'; signal input_digit : integer range 0 to 9; signal input_enable : std_logic := '0'; signal unlock : std_logic; begin clk <= not clk after clock_period; DUT : entity work.code_lock(rtl) generic map (1,2,3,4) port map ( clk => clk, rst => rst, input_digit => input_digit, input_enable => input_enable, unlock => unlock ); end architecture;
Testbench Tcl
Berikut adalah skrip Tcl yang berjalan di dalam ModelSim. Jika Anda menggunakan Vivado atau simulator lain, penyesuaian kecil akan diperlukan, karena beberapa perintah spesifik untuk simulator. Lihat ModelSim Command Reference Manual untuk detailnya.
Unduh proyek contoh menggunakan formulir di bawah ini.
Menggunakan Namespace
Mengemas skrip dalam namespace mencegah benturan tidak sengaja dengan variabel global. Semua kode Tcl berada di dalam namespace codelocktb.
namespace eval ::codelocktb { # Semua kode Tcl di sini }
Menginisialisasi Simulasi
Kami memulai simulasi dengan vsim dan memuat file gelombang jika ada.
# Muat simulasi vsim work.code_lock_tb # Muat gelombang jika ada if {[file exists wave.do]} { do wave.do }
Mengimpor Nilai VHDL ke Tcl
Menggunakan perintah examine ModelSim, kita membaca konstanta clock_period dan generics PIN. Cuplikan berikut mengekstrak nilai numerik dan satuan waktu.
Kami juga menginisialisasi variabel errorCount untuk melacak kegagalan.
variable errorCount 0
Mencetak dengan Stempel Waktu
Perintah echo menampilkan pesan di konsol ModelSim di semua platform. Prosedur berikut menambahkan awalan waktu simulasi saat ini pada setiap pesan.
proc printMsg { msg } { global now variable timeUnits echo $now $timeUnits: $msg }
Menjalankan untuk Jumlah Siklus Clock Tertentu
Karena DUT sensitif clock, kami maju waktu dalam kelipatan periode clock.
proc runClockCycles { count } { variable clockPeriod variable timeUnits set t [expr {$clockPeriod * $count}] run $t $timeUnits }
Memeriksa Nilai Sinyal
Prosedur checkSignal membandingkan sinyal VHDL terhadap nilai yang diharapkan, melaporkan kesalahan jika berbeda.
proc checkSignal { signalName expectedVal } { variable errorCount set val [examine $signalName] if {$val != $expectedVal} { printMsg "ERROR: $signalName=$val (expected=$expectedVal)" incr errorCount } }
Mensimulasikan Entri PIN
Prosedur ini menggerakkan input DUT untuk mensimulasikan pengguna memasukkan PIN 4 digit. Ini memeriksa output unlock setelah semua empat digit diterapkan.
proc tryPin { digits } { variable pinCode set pinStatus "incorrect" if { $digits == $pinCode } { set pinStatus "correct" } printMsg "Entering $pinStatus PIN code: $digits" foreach i $digits { force input_digit $i -deposit force input_enable 1 -deposit runClockCycles 1 force input_enable 0 -deposit runClockCycles 1 } if { $pinStatus == "correct" } { checkSignal unlock 1 } else { checkSignal unlock 0 } }
Urutan Uji dan Pelaporan Hasil
Setelah periode inisialisasi singkat, skrip melepaskan reset dan menjalankan beberapa kasus uji: dua kasus sudut (0000 dan 9999), PIN yang benar, dan urutan PIN terbalik. Kemudian ia melaporkan hasil keseluruhan.
Selama karir saya, saya telah menulis banyak testbench berbasis Tcl. Mereka menawarkan keuntungan unik: pengujian interaktif, kemampuan untuk memodifikasi rangka uji tanpa merekompilasi, dan lapisan verifikasi tambahan yang melindungi dari bug baik dalam desain maupun testbench.
Namun, ada trade-off. Skrip Tcl berjalan lebih lambat daripada testbench VHDL murni, dan bahasa tersebut bisa rapuh—kesalahan sulit ditangkap sejak dini, dan debugging kurang intuitif dibandingkan bahasa tingkat tinggi seperti Python.
Meskipun memiliki kekurangan ini, Tcl tetap menjadi bahasa perekat de facto untuk alat FPGA dan simulasi. Jika Anda bekerja dengan Xilinx Vivado, Intel Quartus, atau Mentor Graphics Questa, menguasai Tcl akan membayar dividen. Silakan berbagi pengalaman Anda di komentar di bawah.