VHDL與Verilog硬件描述語言在數(shù)字電路的設(shè)計(jì)中使用的非常普遍,無論是哪種語言,仿真都是必不可少的。而且隨著設(shè)計(jì)復(fù)雜度的提高,仿真工具的重要性就越來越凸顯出來。在一些小的設(shè)計(jì)中,用TestBench來進(jìn)行仿真是一個(gè)很不錯(cuò)的選擇。
VHDL與Verilog語言的語法規(guī)則不同,它們的TestBench的具體寫法也不同,但是應(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ì)。大致思想都是相似的。
簡單的說,TestBench就是一種驗(yàn)證手段,從軟件層面對(duì)設(shè)計(jì)的硬件電路進(jìn)行仿真。具體來講,一般是在你的仿真文件里,產(chǎn)生激勵(lì)信號(hào),作用于被仿真的設(shè)計(jì)文件DUT(Design Under Test),產(chǎn)生相應(yīng)的輸出,然后根據(jù)輸出信號(hào)檢驗(yàn)設(shè)計(jì)的電路是否存在問題或者存在哪些問題。
下面以FPGA板中驅(qū)動(dòng)流水燈的一段程序?yàn)槔?,簡單介紹一下兩種語言的TestBench的編寫。
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 begin
10 if(!rst)
11 begin
12 clk_cnt《=26‘d0;
13 clk_tmp《=1’b1;
14 end
15 else
16 begin
17 if(clk_cnt==26‘b11111111111111111111111111)
18 begin
19 clk_cnt《=26’d0;
20 clk_tmp《=~clk_tmp;
21 end
22 else
23 clk_cnt《=clk_cnt+1‘b1;
24 end
25 end
26
27 always@(posedge clk_tmp or negedge rst)
28 begin
29 if(!rst)
30 temp《=4’d15;
31 else
32 temp《=temp+1‘b1;
33 end
34
35 always@(temp)
36 begin
37 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 endcase
56 end
57
58 endmodule
上面是一段流水燈的代碼,控制8位流水燈依次點(diǎn)亮,再依次熄滅。第一個(gè)always語句完成分頻功能,第二個(gè)always語句用于計(jì)數(shù),共16個(gè)值,第三個(gè)always語句根據(jù)計(jì)數(shù)的值選擇LED燈的狀態(tài)。其中clk、rst分別為時(shí)鐘和復(fù)位信號(hào),led為驅(qū)動(dòng)流水燈的輸出信號(hào)。接下來針對(duì)這一設(shè)計(jì)編寫其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 end
12
13 initial
14 begin
15 clk=1;
16 forever #20 clk=~clk;
17 end
18
19 led_run led1(.clk(clk),.rst(rst),.led(led));
20 endmodule
由于只需要時(shí)鐘和復(fù)位信號(hào)即可,故在其仿真文件并不復(fù)雜,建立測試模塊,進(jìn)行信號(hào)聲明,在兩個(gè)initial中分別提供clk和rst信號(hào),最后進(jìn)行例化。當(dāng)然注意一點(diǎn),在仿真時(shí)要把分頻模塊去掉,或者將分頻系數(shù)改小,否則仿真時(shí)不容易觀察波形。下面是在Modelsim中仿真得到的波形(分頻模塊改為2分頻)。
總結(jié)起來,Verilog的TestBench有著相對(duì)固定的寫法:
module test_bench;
端口聲明語句
initial
begin
產(chǎn)生時(shí)鐘信號(hào)
end
initial
begin
提供激勵(lì)源
end
例化語句
endmodule
最主要的是在initial語句中進(jìn)行激勵(lì)的生成,這要根據(jù)具體的設(shè)計(jì)來分析。
下面對(duì)比介紹VHDL語言TestBench的寫法。同樣的功能,驅(qū)動(dòng)流水燈,VHDL的程序如下:
1 LIBRARY IEEE;
2 USE IEEE.STD_LOGIC_1164.ALL;
3 USE IEEE.STD_LOGIC_UNSIGNED.ALL;
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 IS
12 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 BEGIN
16 divider:PROCESS(clk,rst)
17 BEGIN
18 if(rst=’0‘) then
19 clk_cnt《=“00000000000000000000000000”;
20 elsif(clk’event and clk=‘1’) then
21 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 BEGIN
31 if(rst=‘0’) then
32 temp《=“1111”; --all the led off
33 elsif(clk_tmp‘event and clk_tmp=’1‘) then
34 temp《=temp+1;
35 end if;
36 END PROCESS;
37
38 PROCESS(temp)
39 BEGIN
40 case temp is
41 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ù)語法要求,首先聲明庫,接著定義實(shí)體和結(jié)構(gòu)體。在結(jié)構(gòu)體中用三個(gè)進(jìn)程(PROCESS)分別實(shí)現(xiàn)分頻、計(jì)數(shù)、流水燈狀態(tài)分配的功能,功能相當(dāng)于上面Verilog程序中的三個(gè)always語句。接下來寫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 BEGIN
23
24 DUT:led_run PORT MAP(clk=》clk,rst=》rst,led=》led); --元件例化
25
26 clk_gen:PROCESS
27 BEGIN
28 clk《=’1‘;
29 wait for clk_period/2;
30 clk《=’0‘;
31 wait for clk_period/2;
32 END PROCESS;
33
34 tb:PROCESS
35 BEGIN
36 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寫法也有相對(duì)固定的格式:
library ieee; --庫聲明
use ieee.std_logic_1164.all;
entity test_bench is --測試平臺(tái)文件的空實(shí)體(不需要端口定義)
end test_bench;
architecture tb_behavior of test_bench is --結(jié)構(gòu)體
component entity_under_test --被測試元件的聲明
port(
list-of-ports-theri-types-and-modes
);
end component;
begin
instantiation:entity_under_test port map --元件例化
(
port-associations
);
process() --產(chǎn)生時(shí)鐘信號(hào)
……
end process;
process() --產(chǎn)生激勵(lì)源
……
end process;
end tb_behavior;
相對(duì)與Verilog語言來說,VHDL的TestBench除了自身的庫聲明以及Entity和Architecture之外,還需要進(jìn)行元件的聲明,即將被測試的設(shè)計(jì)聲明為一個(gè)元件,然后對(duì)其例化。在激勵(lì)的產(chǎn)生方面與Verilog思路相同。
從上面的程序可以看出,Verilog語言相對(duì)比較隨意一些,從C語言編程中繼承了多種操作符和結(jié)構(gòu);而VHDL的語法則比較嚴(yán)謹(jǐn),有固定的格式。但在功能的實(shí)現(xiàn)上二者大同小異。比如Verilog中的always語句,在VHDL中可以找到PROCESS與之對(duì)應(yīng),當(dāng)然更多的是不同。
兩種語言均可在不同的抽象層次對(duì)電路進(jìn)行描述:系統(tǒng)級(jí)、算法級(jí)、寄存器傳輸級(jí)、邏輯門級(jí)和開關(guān)電路級(jí),但是VHDL更擅長系統(tǒng)級(jí),而Verilog更方便底層描述。在學(xué)習(xí)硬件描述語言的時(shí)候不妨對(duì)比學(xué)習(xí)一下,相信會(huì)對(duì)電路設(shè)計(jì)的理解更加深一層。
編輯:jq
-
vhdl
+關(guān)注
關(guān)注
30文章
816瀏覽量
128018
原文標(biāo)題:VHDL與Verilog硬件描述語言TestBench的編寫
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論