VHDL與Verilog硬件描述語(yǔ)言TestBench的編寫(xiě)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
與Verilog硬件描述語(yǔ)言在數(shù)字電路的設(shè)計(jì)中使用的非常普遍,無(wú)論是哪種語(yǔ)言,仿真都是必不可少的。而且隨著設(shè)計(jì)復(fù)雜度的提高,仿真工具的重要性就越來(lái)越凸顯出來(lái)。在一些小的設(shè)計(jì)中,用TestBench來(lái)進(jìn)行仿真是一個(gè)很不錯(cuò)的選擇。VHDL與Verilog語(yǔ)言的語(yǔ)法規(guī)則不同,它們的TestBench的具體寫(xiě)法也不同,但是應(yīng)包含的基本結(jié)構(gòu)大體相似,在VHDL的仿真文件中應(yīng)包含以下幾點(diǎn):實(shí)體和結(jié)構(gòu)體聲明、信號(hào)聲明、頂層設(shè)計(jì)實(shí)例化、提供激勵(lì);Verilog的仿真文件應(yīng)包括:模塊聲明、信號(hào)聲明、頂層設(shè)計(jì)實(shí)例化、提供激勵(lì)。大致思想都是相似的。
簡(jiǎn)單的說(shuō),TestBench就是一種驗(yàn)證手段,從軟件層面對(duì)設(shè)計(jì)的硬件電路進(jìn)行仿真。具體來(lái)講,一般是在你的仿真文件里,產(chǎn)生激勵(lì)信號(hào),作用于被仿真的設(shè)計(jì)文件DUT(Design Under Test),產(chǎn)生相應(yīng)的輸出,然后根據(jù)輸出信號(hào)檢驗(yàn)設(shè)計(jì)的電路是否存在問(wèn)題或者存在哪些問(wèn)題。
下面以FPGA板中驅(qū)動(dòng)流水燈的一段程序?yàn)槔?,?jiǎn)單介紹一下兩種語(yǔ)言的TestBench的編寫(xiě)。
1 module led_run(clk,rst,led); 2 input clk,rst; 3 output reg [7:0] led; 4 reg [25:0] clk_cnt; 5 reg clk_tmp; 6 reg [3:0] temp; 7 8 always@(posedge clk or negedge rst) 9 begin10 if(!rst)11 begin12 clk_cnt<=26'd0;13 clk_tmp<=1'b1;14 end15 else16 begin17 if(clk_cnt==26'b11111111111111111111111111)18 begin19 clk_cnt<=26'd0;20 clk_tmp<=~clk_tmp;21 end22 else23 clk_cnt<=clk_cnt+1'b1;24 end25 end26 27 always@(posedge clk_tmp or negedge rst)28 begin29 if(!rst)30 temp<=4'd15;31 else32 temp<=temp+1'b1;33 end34 35 always@(temp)36 begin37 case(temp)38 4'd0 :led<=8'b11111110;39 4'd1 :led<=8'b11111100;40 4'd2 :led<=8'b11111000;41 4'd3 :led<=8'b11110000;42 4'd4 :led<=8'b11100000;43 4'd5 :led<=8'b11000000;44 4'd6 :led<=8'b10000000;45 4'd7 :led<=8'b00000000;46 4'd8 :led<=8'b00000001;47 4'd9 :led<=8'b00000011;48 4'd10:led<=8'b00000111;49 4'd11:led<=8'b00001111;50 4'd12:led<=8'b00011111;51 4'd13:led<=8'b00111111;52 4'd14:led<=8'b01111111;53 4'd15:led<=8'b11111111;54 default:;55 endcase56 end57 58 endmodule
上面是一段流水燈的代碼,控制8位流水燈依次點(diǎn)亮,再依次熄滅。第一個(gè)always語(yǔ)句完成分頻功能,第二個(gè)always語(yǔ)句用于計(jì)數(shù),共16個(gè)值,第三個(gè)always語(yǔ)句根據(jù)計(jì)數(shù)的值選擇LED燈的狀態(tài)。其中clk、rst分別為時(shí)鐘和復(fù)位信號(hào),led為驅(qū)動(dòng)流水燈的輸出信號(hào)。接下來(lái)針對(duì)這一設(shè)計(jì)編寫(xiě)其TestBench文件。
1 /************TestBench*************/ 2 module tb_led_run; 3 reg clk,rst; 4 wire led; 5 6 initial 7 begin 8 rst=1; 9 #30 rst=0;10 #40 rst=1;11 end12 13 initial14 begin15 clk=1;16 forever #20 clk=~clk;17 end18 19 led_run led1(.clk(clk),.rst(rst),.led(led));20 endmodule
由于只需要時(shí)鐘和復(fù)位信號(hào)即可,故在其仿真文件并不復(fù)雜,建立測(cè)試模塊,進(jìn)行信號(hào)聲明,在兩個(gè)initial中分別提供clk和rst信號(hào),最后進(jìn)行例化。當(dāng)然注意一點(diǎn),在仿真時(shí)要把分頻模塊去掉,或者將分頻系數(shù)改小,否則仿真時(shí)不容易觀察波形。下面是在Modelsim中仿真得到的波形(分頻模塊改為2分頻)。
總結(jié)起來(lái),Verilog的TestBench有著相對(duì)固定的寫(xiě)法:
module test_bench; 端口聲明語(yǔ)句 initial begin 產(chǎn)生時(shí)鐘信號(hào) end initial begin 提供激勵(lì)源 end 例化語(yǔ)句endmodule
最主要的是在initial語(yǔ)句中進(jìn)行激勵(lì)的生成,這要根據(jù)具體的設(shè)計(jì)來(lái)分析。
下面對(duì)比介紹VHDL語(yǔ)言TestBench的寫(xiě)法。同樣的功能,驅(qū)動(dòng)流水燈,VHDL的程序如下:
1 LIBRARY IEEE; 2 USE IEEE.STD_LOGIC_1164.ALL; 3 USE IEEE.STD_LOGIC_UNSIGNED.ALL; 4 5 ENTITY led_run IS 6 PORT(clk:in std_logic; 7 rst:in std_logic; 8 led:out std_logic_vector(7 downto 0):="11111111" ); 9 END led_run;10 11 ARCHITECTURE arc_led_run OF led_run IS12 signal temp:std_logic_vector(3 downto 0);13 signal clk_cnt:std_logic_vector(25 downto 0);14 signal clk_tmp:std_logic:='1';15 BEGIN16 divider:PROCESS(clk,rst)17 BEGIN18 if(rst='0') then19 clk_cnt<="00000000000000000000000000";20 elsif(clk'event and clk='1') then21 clk_cnt<=clk_cnt+1;22 if(clk_cnt="11111111111111111111111111") then 23 clk_cnt<="00000000000000000000000000";24 clk_tmp<=NOT clk_tmp;25 end if;26 end if;27 END PROCESS;28 29 PROCESS(clk_tmp,rst)30 BEGIN31 if(rst='0') then32 temp<="1111"; --all the led off33 elsif(clk_tmp'event and clk_tmp='1') then34 temp<=temp+1;35 end if;36 END PROCESS;37 38 PROCESS(temp)39 BEGIN40 case temp is41 when"0000"=>led<="11111110";42 when"0001"=>led<="11111100";43 when"0010"=>led<="11111000";44 when"0011"=>led<="11110000";45 when"0100"=>led<="11100000";46 when"0101"=>led<="11000000";47 when"0110"=>led<="10000000";48 when"0111"=>led<="00000000";49 when"1000"=>led<="00000001";50 when"1001"=>led<="00000011";51 when"1010"=>led<="00000111";52 when"1011"=>led<="00001111";53 when"1100"=>led<="00011111";54 when"1101"=>led<="00111111";55 when"1110"=>led<="01111111";56 when"1111"=>led<="11111111";57 when others=>NULL;58 end case;59 END PROCESS;60 61 END arc_led_run;
根據(jù)語(yǔ)法要求,首先聲明庫(kù),接著定義實(shí)體和結(jié)構(gòu)體。在結(jié)構(gòu)體中用三個(gè)進(jìn)程(PROCESS)分別實(shí)現(xiàn)分頻、計(jì)數(shù)、流水燈狀態(tài)分配的功能,功能相當(dāng)于上面Verilog程序中的三個(gè)always語(yǔ)句。接下來(lái)寫(xiě)TestBench文件:
1 ---------------TestBench----------------- 2 LIBRARY IEEE; 3 USE IEEE.STD_LOGIC_1164.ALL; 4 5 6 ENTITY tb_led_run IS --空實(shí)體 7 END tb_led_run; 8 9 10 ARCHITECTURE arc_tb_led_run OF tb_led_run IS --結(jié)構(gòu)體11 12 COMPONENT led_run IS --元件聲明13 PORT(clk:in std_logic;14 rst:in std_logic;15 led:out std_logic_vector(7 downto 0));16 END COMPONENT;17 18 signal clk,rst:std_logic;19 signal led:std_logic_vector(7 downto 0);20 constant clk_period:time:=5 ns;21 22 BEGIN23 24 DUT:led_run PORT MAP(clk=>clk,rst=>rst,led=>led); --元件例化25 26 clk_gen:PROCESS27 BEGIN28 clk<='1';29 wait for clk_period/2;30 clk<='0';31 wait for clk_period/2;32 END PROCESS;33 34 tb:PROCESS35 BEGIN36 rst<='0';37 wait for 12 ns;38 rst<='1';39 wait;40 END PROCESS;41 42 END arc_tb_led_run;
在這個(gè)TestBench中同樣只需要提供clk和rst信號(hào),分別在兩個(gè)進(jìn)程實(shí)現(xiàn),Modelsim中的仿真結(jié)果如下(同樣在仿真的時(shí)候?qū)⒎诸l系數(shù)改為2):
總結(jié)一下,VHDL的TestBench寫(xiě)法也有相對(duì)固定的格式:
相對(duì)與Verilog語(yǔ)言來(lái)說(shuō),VHDL的TestBench除了自身的庫(kù)聲明以及Entity和Architecture之外,還需要進(jìn)行元件的聲明,即將被測(cè)試的設(shè)計(jì)聲明為一個(gè)元件,然后對(duì)其例化。在激勵(lì)的產(chǎn)生方面與Verilog思路相同。
從上面的程序可以看出,Verilog語(yǔ)言相對(duì)比較隨意一些,從C語(yǔ)言編程中繼承了多種操作符和結(jié)構(gòu);而VHDL的語(yǔ)法則比較嚴(yán)謹(jǐn),有固定的格式。但在功能的實(shí)現(xiàn)上二者大同小異。比如Verilog中的always語(yǔ)句,在VHDL中可以找到PROCESS與之對(duì)應(yīng),當(dāng)然更多的是不同。兩種語(yǔ)言均可在不同的抽象層次對(duì)電路進(jìn)行描述:系統(tǒng)級(jí)、算法級(jí)、寄存器傳輸級(jí)、邏輯門(mén)級(jí)和開(kāi)關(guān)電路級(jí),但是VHDL更擅長(zhǎng)系統(tǒng)級(jí),而Verilog更方便底層描述。在學(xué)習(xí)硬件描述語(yǔ)言的時(shí)候不妨對(duì)比學(xué)習(xí)一下,相信會(huì)對(duì)電路設(shè)計(jì)的理解更加深一層。