之前有一篇文章介紹過仿真測(cè)試文件編寫的步驟:
1.給A模塊寫測(cè)試,其測(cè)試模塊的模塊名為A_tb,比如原模塊模塊名叫做led,測(cè)試模塊名就叫 led_tb;
2.復(fù)制A模塊的所有輸入輸出端口,也就是I/O聲明部分(input和output信號(hào)),注意這里不包括中間變量(reg型和wire型信號(hào));將所有的input 改為 reg, output 改為 wire;
3.再把A模塊的端口定義部分復(fù)制過來,包括 模塊名到分號(hào)結(jié)束,進(jìn)行模塊例化;
4.測(cè)試模塊的意義就是模擬輸入信號(hào),來驗(yàn)證原模塊的輸出信號(hào)是否符合代碼邏輯,所以在測(cè)試模塊里面需要寫一個(gè)initial塊模擬所有的輸入變量,進(jìn)行賦值操作;
5.如果有時(shí)鐘,需要再產(chǎn)生一個(gè)時(shí)鐘信號(hào);
6.最后添加時(shí)間標(biāo)識(shí)。
這篇文章就詳細(xì)說一下怎么做,舉得例子是上一篇二選一數(shù)據(jù)選擇器的例子,大家可以動(dòng)手做一做。
設(shè)計(jì)背景:
測(cè)試文件在我們的項(xiàng)目中格外的重要,比如我們要驗(yàn)證你的模塊的正確性難道要不停的下板來驗(yàn)證嗎,如果你的項(xiàng)目小還可以,如果編譯一下超過10分鐘了你難道不停的等待,修改中循壞下去嗎,所以如果我們可以設(shè)計(jì)出我們的測(cè)試文件,那么先驗(yàn)證我們的系統(tǒng),如果我們的邏輯都正確了,我們就可以下班來查看,如果還不正確那么我們就可以用quartus 中的工具signaltap來捕捉我們信號(hào)來驗(yàn)證,這些都會(huì)在我們以后的文檔中給大家說明。
設(shè)計(jì)原理:
我們的設(shè)計(jì)就是一個(gè)簡(jiǎn)單的2選一多路選擇器,我們通過給這個(gè)簡(jiǎn)單的多路選擇器來寫測(cè)試文件,讓大家對(duì)測(cè)試有一個(gè)簡(jiǎn)單的認(rèn)識(shí)。
在架構(gòu)中我們可以明白的看出我們?cè)O(shè)計(jì)的架構(gòu),我們的項(xiàng)目中有2個(gè)輸入數(shù)據(jù)data_1,data_2,一個(gè)輸入的選擇位select,還有一個(gè)輸出data_out。其實(shí)給這個(gè)架構(gòu)寫測(cè)試也就是激勵(lì),其實(shí)說白了就是給其寫輸入,當(dāng)給其寫好輸入后,我們不就可以在仿真工具中驗(yàn)證其邏輯關(guān)系了。
設(shè)計(jì)架構(gòu)圖:
sel_1架構(gòu)
總架構(gòu)
設(shè)計(jì)代碼:
我們寫好的代碼如下,大家看下,然后我們給大家講解測(cè)試怎么寫
模塊
0modulesel_1(data_1,data_2,select,data_out);
1
2 inputdata_1,data_2; //數(shù)據(jù)輸入
3 inputselect; //選擇位
4
5 outputregdata_out; //數(shù)據(jù)的輸出
6
7 always@(*)
8 begin
9 if(select) //如果選擇位為高,輸出data_1
10 data_out =data_1;
11 else //如果選擇位為低,輸出data_2
12 data_out =data_2;
13 end
14
15endmodule
測(cè)試模塊
測(cè)試的簡(jiǎn)單寫法,測(cè)試中模塊的輸入定義為寄存器reg型,輸出定義為wire型,然后加上我們的塊 initial ,再加上我們的例化,如下:
0`timescale1ns/1ps
1
2module模塊名;
3
4 reg模塊輸入;
5 wire模塊輸出;
6
7 initialbegin
8
9
10
11
12 end
13
14 模塊名 例化名(
15 .端口(端口),
16 .端口(端口),
17
18 );
19
20endmodule
在測(cè)試中我們也有許多的系統(tǒng)比如我們的系統(tǒng)任務(wù)$stop等,這些都屬于語法知識(shí)了,大家可以買一本適合的書來看看,我們?yōu)槲覀兊脑O(shè)計(jì)寫好的激勵(lì)如下:
0`timescale1ns/1ps //這一行中1ns定義我們測(cè)試時(shí)的時(shí)間單位,后面的ps 是精度
1//前面的timescale英文也就是時(shí)間量程的意思
2
3modulesel_1_tb;//module 后面跟上我們測(cè)試名字,一般我們都寫成模塊名
4//加上_tb,如果我們對(duì)一個(gè)項(xiàng)目的多個(gè)模塊寫測(cè)試我們就能清楚的分清
5
6 regdata_1,data_2; //定義模塊的輸入輸出
7 regselect; //模塊中的輸入定義為寄存器
8
9 wiredata_out; //輸出定義為wire型也就是線型
10
11 initialbegin //initial 是一個(gè)串型執(zhí)行的,在測(cè)試中被綜合,
12 //如果你寫到模塊中,可是會(huì)報(bào)錯(cuò)的
13 data_1 =0; //然后我們就可以定義我們的端口,給我們的端口賦初值
14 data_2 =0;
15 select =0;
16
17 #200data_1 =1;data_2 =0;//延遲200ns給輸入賦值
18 #100select =1; //延遲200ns后給選擇位賦值
19 #100select =0; //延遲200ns后給選擇位賦值
20
21 #200data_1 =0;data_2 =1;
22 #100select =0;
23 #100select =1;
24
25 #300$stop; //$stop 系統(tǒng)任務(wù),也就是停止的意思,這句 就是延遲 300ns后,仿真停止
26 end
27
28 sel_1 sel_1_dut( //模塊的例化,和端口的連接
29 .data_1(data_1),
30 .data_2(data_2),
31 .select(select),
32 .data_out(data_out)
33 );
34
35endmodule
在測(cè)試中如果我們用到時(shí)鐘了怎么辦,我們可以這樣寫,如下
0`timescale1ns/1ps
1
2module模塊名;
3
4 reg模塊輸入;
5 wire模塊輸出;
6 regclk,rst_n;
7
8 initialbegin
9 clk =1;
10 rst_n =0;
11
12 #200.1rst_n =1;
13
14 end
15
16 always#10clk =~clk; //always 一直,這樣可以寫成一個(gè) 50M的時(shí)鐘
17 //說的是延遲10ns翻轉(zhuǎn)一次,也就是一 個(gè)周期20ns
18
19 模塊名 例化名(
20 .端口(端口),
21 .端口(端口),
22
23 );
24
25endmodule
仿真圖:
在仿真中我們可以真實(shí)的看到,當(dāng)數(shù)據(jù)data_1為1,data_2位0的時(shí)候,當(dāng)選擇位select為0的時(shí)候,輸出data_out的值為0也就是data_2的值,當(dāng)select為1的時(shí)候,data_out的值位1,也就是data_1的值,后面的仿真也一樣我們可以清楚的看到。
以上就是對(duì)于二選一數(shù)據(jù)選擇器的仿真測(cè)試文件的編寫細(xì)節(jié),大家可以動(dòng)手去做一做,加油,各位。
-
FPGA
+關(guān)注
關(guān)注
1629文章
21736瀏覽量
603389 -
仿真測(cè)試
+關(guān)注
關(guān)注
0文章
90瀏覽量
11307
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論