加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

FPGA入門基礎(chǔ)之Testbench仿真文件編寫示例

04/29 11:50
5143
閱讀需 19 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

引言:在編寫完HDL代碼后,往往需要通過仿真軟件Modelsim或者Vivadao自帶的仿真功能對HDL代碼功能進(jìn)行驗(yàn)證,此時(shí)我們需要編寫Testbench文件對HDL功能進(jìn)行測試驗(yàn)證。本文我們介紹寫Testbench編寫的一些要點(diǎn)。

1.Testbench文件結(jié)構(gòu)模板

編寫Testbench的目的是為了測試設(shè)計(jì)電路的功能、性能與設(shè)計(jì)的預(yù)期是否相符。驗(yàn)證軟件功能通過包括以下步驟:

? 產(chǎn)生合適的模擬激勵(lì)(波形):該激勵(lì)通常要覆蓋被測HDL模塊(黑盒或者稱作DUT模塊)所有可能得輸入狀態(tài);
? 將產(chǎn)生的激勵(lì)加入到被測試模塊中并觀察其響應(yīng):即將DUT模塊例化到Testbench文件中,運(yùn)行仿真軟測測試;
? 將輸出響應(yīng)與期望值相比較:該步驟是驗(yàn)證DUT功能較耗時(shí)的部分,需要仔細(xì)分析代碼功能是否達(dá)到預(yù)期設(shè)計(jì),所有代碼段功能是否正常。

Testbench結(jié)構(gòu)一般模板如下:

module Test_bench_name();//通常無輸入無輸出//01:信號或變量聲明定義//--邏輯設(shè)計(jì)中輸入對應(yīng) reg 型//--邏輯設(shè)計(jì)中輸出對應(yīng) wire 型//02:使用 initial 或 always 語句產(chǎn)生激勵(lì)//03:例化待測試DUT模塊//04:監(jiān)控和比較輸出響應(yīng)endmodule

2.時(shí)鐘激勵(lì)輸入示例

常見的時(shí)鐘有:50%占空比連續(xù)時(shí)鐘、固定周期數(shù)時(shí)鐘、非50%占空比時(shí)鐘,示例如下。

/*----------------------------------------------------------------時(shí)鐘激勵(lì)產(chǎn)生方法一:50%占空比時(shí)鐘----------------------------------------------------------------*/parameter ClockPeriod=10; //參數(shù)化時(shí)鐘周期initial  begin    clk_i=0;    forever#(ClockPeriod/2) clk_i = ~clk_i; end
/*---------------------------------------------------------------- 時(shí)鐘激勵(lì)產(chǎn)生方法二:50%占空比時(shí)鐘----------------------------------------------------------------*/initialbegin  clk_i=0; endalways #(ClockPeriod/2) clk_i=~clk_i;
/*---------------------------------------------------------------- 時(shí)鐘激勵(lì)產(chǎn)生方法三:產(chǎn)生固定數(shù)量的時(shí)鐘脈沖----------------------------------------------------------------*/parameter ClockPeriod=10; //參數(shù)化時(shí)鐘周期initialbegin  clk_i=0;   repeat(6)  #(ClockPeriod/2) clk_i=~clk_i; end
/*---------------------------------------------------------------- 時(shí)鐘激勵(lì)產(chǎn)生方法四:產(chǎn)生非占空比為 50%的時(shí)鐘----------------------------------------------------------------*/parameter ClockPeriod=10; //參數(shù)化時(shí)鐘周期initialbeginclk_i=0;forever  begin    #((ClockPeriod/2)-2) clk_i=0;    #((ClockPeriod/2)+2) clk_i=1;     endend

3.復(fù)位激勵(lì)輸入示例

復(fù)位輸入主要包括異步復(fù)位、同步復(fù)位,代碼示例如下。

/*---------------------------------------------------------------- 復(fù)位信號產(chǎn)生方法一:異步復(fù)位----------------------------------------------------------------*/initialbegin  rst_n_i=1;  #100; rst_n_i=0;  #100; rst_n_i=1; end/*---------------------------------------------------------------- 復(fù)位信號產(chǎn)生方法二:同步復(fù)位----------------------------------------------------------------*/initialbegin  rst_n_i=1; clk_i = 0;  @(negedge clk_i)  rst_n_i=0;  #100; //固定時(shí)間復(fù)位  repeat(10) @(negedge clk_i); //固定周期數(shù)復(fù)位  @(negedge clk_i)  rst_n_i=1; endalways #5 clk_i=~clk_i;

/*---------------------------------------------------------------- 復(fù)位信號產(chǎn)生方法三:復(fù)位任務(wù)封裝----------------------------------------------------------------*/task reset;input [31:0] reset_time; //復(fù)位時(shí)間可調(diào),輸入復(fù)位時(shí)間  RST_ING=0; //復(fù)位方式可調(diào),低電平高電平  begin    rst_n=RST_ING; //復(fù)位中    #reset_time; //復(fù)位時(shí)間    rst_n_i=~RST_ING; //撤銷復(fù)位,復(fù)位結(jié)束  endendtask

4.雙向口inout示例

/*---------------------------------------------------------------- 雙向信號inout 在 testbench 中定義為 wire 型變量----------------------------------------------------------------*/reg  sck;wire sda;   //inout信號sda定義為wire型reg  sda_r; //inout 輸出定義為reg型reg  sda_en;assign sda_r = (sda_en) ? mosi : 1'bz;assign sda =sda_r;

5.特殊信號設(shè)計(jì)

/*---------------------------------------------------------------- 特殊激勵(lì)信號產(chǎn)生描述一:輸入信號任務(wù)封裝----------------------------------------------------------------*/task i_data;  input [7:0] dut_data;  begin@(posedge data_en); send_data=0;    @(posedge data_en); send_data=dut_data[0];    @(posedge data_en); send_data=dut_data[1];    @(posedge data_en); send_data=dut_data[2];    @(posedge data_en); send_data=dut_data[3];    @(posedge data_en); send_data=dut_data[4];    @(posedge data_en); send_data=dut_data[5];    @(posedge data_en); send_data=dut_data[6];    @(posedge data_en); send_data=dut_data[7];    @(posedge data_en); send_data=1;    #100;   endendtask//調(diào)用方法:i_data(8'hXX);
/*---------------------------------------------------------------- 特殊激勵(lì)信號產(chǎn)生描述二:多輸入信號任務(wù)封裝----------------------------------------------------------------*/task more_input;  input [7:0] a;  input [7:0] b;  input [31:0] times;   output [8:0] c;  begin    repeat(times) //等待 times 個(gè)時(shí)鐘上升沿    @(posedge clk_i) c=a+b; //時(shí)鐘上升沿 a,b 相加  endendtask//調(diào)用方法:more_input(x,y,t,z);?//按聲明順序
/*---------------------------------------------------------------- 特殊激勵(lì)信號產(chǎn)生描述三:輸入信號產(chǎn)生,一次 SRAM 寫信號產(chǎn)生----------------------------------------------------------------*/initialbegin  cs_n=1; //片選無效  wr_n=1; //寫使能無效  rd_n=1; //讀使能無效  addr=8'hxx; //地址無效  data=8'hzz; //數(shù)據(jù)無效  #100; cs_n=0; //片選有效  wr_n=0; //寫使能有效  addr=8'hF1; //寫入地址  data=8'h2C; //寫入數(shù)據(jù)  #100; cs_n=1; wr_n=1;  #10; addr=8'hxx;  data=8'hzz; end
/*----------------------------------------------------------------特殊激勵(lì)信號產(chǎn)生描述四:@與 wait----------------------------------------------------------------*///@使用沿觸發(fā)//wait 語句都是使用電平觸發(fā)initialbegin  start=1'b1;   wait(en=1'b1);  #10; start=1'b0; end

6.仿真控制語句及系統(tǒng)任務(wù)描述

/*---------------------------------------------------------------- 仿真控制語句及系統(tǒng)任務(wù)描述----------------------------------------------------------------*/$stop  // 停止運(yùn)行仿真,modelsim 中可繼續(xù)仿真$stop(n) //帶參數(shù)系統(tǒng)任務(wù),根據(jù)參數(shù) 0,1或2不同,輸出仿真信息$finish //結(jié)束運(yùn)行仿真,不可繼續(xù)仿真$finish(n) //帶參數(shù)系統(tǒng)任務(wù),根據(jù)參數(shù) 0,1或2不同,輸出仿真信息//0:不輸出任何信息//1:輸出當(dāng)前仿真時(shí)刻和位置//2:輸出當(dāng)前仿真時(shí)刻、位置和仿真過程中用到的 memory 以及 CPU 時(shí)間的統(tǒng)計(jì)$random //產(chǎn)生隨機(jī)數(shù)$random % n //產(chǎn)生范圍-n 到 n 之間的隨機(jī)數(shù){$random} % n //產(chǎn)生范圍 0 到 n 之間的隨機(jī)數(shù)/*----------------------------------------------------------------

7. 仿真終端顯示描述

/*---------------------------------------------------------------- 仿真終端顯示描述----------------------------------------------------------------*/$monitor //仿真打印輸出, 打印出仿真過程中的變量,使其終端顯示/*$monitor($time,,,"clk=%d reset=%d out=%d",clk,reset,out);*/ $display //終端打印字符串,顯示仿真結(jié)果等/*$display(” Simulation start ! ");$display(” At time %t,input is %b%b%b,output is %b",$time,a,b,en,z); */$time //返回 64 位整型時(shí)間$stime //返回 32 位整型時(shí)間$realtime //實(shí)行實(shí)型模擬時(shí)間

8. 文本輸入方式

/*---------------------------------------------------------------- 文本輸入方式:$readmemb/$readmemh----------------------------------------------------------------*///verilog 提供了讀入文本的系統(tǒng)函數(shù)$readmemb/$readmemh("<數(shù)據(jù)文件名>",<存儲器名>);$readmemb/$readmemh("<數(shù)據(jù)文件名>",<存儲器名>,<起始地址>);$readmemb/$readmemh("<數(shù)據(jù)文件名>",<存儲器名>,<起始地址>,<結(jié)束地址>);$readmemb:/*讀取二進(jìn)制數(shù)據(jù),讀取文件內(nèi)容只能包含:空白位置,注釋行,二進(jìn)制數(shù)數(shù)據(jù)中不能包含位寬說明和格式說明,每個(gè)數(shù)字必須是二進(jìn)制數(shù)字。*/$readmemh:/*讀取十六進(jìn)制數(shù)據(jù),讀取文件內(nèi)容只能包含:空白位置,注釋行,十六進(jìn)制數(shù)數(shù)據(jù)中不能包含位寬說明和格式說明,每個(gè)數(shù)字必須是十六進(jìn)制數(shù)字。*/

 

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級 參考價(jià)格 更多信息
M4A5-64/32-10VNC48 1 Lattice Semiconductor Corporation EE PLD, 10ns, 64-Cell, CMOS, PQFP48, 1.40 MM HEIGHT, LEAD FREE, TQFP-48

ECAD模型

下載ECAD模型
$6.09 查看
EPM2210F324I5N 1 Intel Corporation Flash PLD, 11.2ns, 1700-Cell, CMOS, PBGA324, 19 X 19 MM, 1 MM PITCH, LEAD FREE, FBGA-324
$56.29 查看
XC6SLX45-2CSG324I 1 AMD Xilinx Field Programmable Gate Array, 3411 CLBs, 667MHz, 43661-Cell, CMOS, PBGA324, 15 X 15 MM, 0.80 MM PITCH, LEAD FREE, BGA-324
$65.17 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

專注FPGA技術(shù)開發(fā),涉及Intel FPGA、Xilinx FPGA技術(shù)開發(fā),開發(fā)環(huán)境使用,代碼風(fēng)格、時(shí)序收斂、器件架構(gòu)以及軟硬件項(xiàng)目實(shí)戰(zhàn)開發(fā),個(gè)人公眾號:FPGA技術(shù)實(shí)戰(zhàn)。