【Verilog設計—Testbench仿真】基礎知識,應知應會

一、testbench基本結構

通常,testbench沒有輸入與輸出端口,應包括信號或變量定義、產生激勵波形語句、例化設計模塊以及監控和比較響應輸出語句。

module test_bench;   
    //信號或變量定義聲明
    //使用initial或always語句來產生激勵波形
    //例化設計模塊
    //監控和比較輸出響應
endmodule

二、常用產生激勵描述方式

(1)產生時鐘的幾種方式

  1. initial,產生佔空比爲50%的時鐘
    initial
        begin
            clk = 0;
            #delay;
            forever
            #(period/2) clk = ~ clk;
        end
    
  2. always,產生佔空比爲50%的時鐘
    initial
    	clk = 0;
    always
    	#(period/2) clk = ~ clk;
    
  3. repeat,產生確定數目的時鐘脈衝
    initial
        begin
            clk = 0;
            repeat(6)
            #(period/2) clk = ~ clk;
        end
    
  4. 產生佔空比非50%的時鐘
    initial
    	clk = 0;
    always
        begin
            #3  clk = ~ clk;
            #2  clk = ~ clk;
        end
    

(2)產生復位信號的幾種方式

  1. 異步復位
    initial
        begin
            rst = 1; 
            #100;            
            rst = 0;
            #500;
            rst = 1;
        end
    
  2. 同步復位①
    initial
        begin
    	    rst = 1; 
    	    @(negedge clk);  //等待時鐘下降沿          
    	    rst = 0;
    	    #30;
    	    @(negedge clk);  //等待時鐘下降沿
    	    rst = 1;
        end
    
  3. 同步復位②
    initial
        begin
    	    rst = 1; 
    	    @(negedge clk);  	     //等待時鐘下降沿          
    	    repeat(3) @(negedge clk);  //經過3個時鐘下降沿
    	    rst = 1;
        end
    

三、常用的Verilog調試語句

(1)兩種調試信息打印語句——$display與$monitor

/*在終端上打印信號的ASCII值*/
initial 
    begin
        $timeformat (-9,1, “ns”,12);           //設置輸出時鐘格式
        $display(“stime clk rst pause ms_h ms_l s_h s_l m_h m_l”); //顯示輸入的字符串
        $monitor(“%t %b %b %b %b %b %b %b %b”,    //設置輸出信號格式
        $realtime,clock,reset,pause,ms_h,ms_l,s_h,s_l,m_h,m_l);     //指定輸出的信號
    end
  • $display:將函數內部雙引號中的字符串輸出在終端上,而$monitor則不同,它的輸出是事件驅動的

上例代碼中,$monitor信號列表中$realtime信號的變化會觸發終端顯示事件的發生,每次$monitor的觸發將會把信號列表中的信號值顯示在終端中。

  • $monitor:語句中的“%”用於定義信號列表中信號的輸出格式。

例如,%t將信號按照時間格式輸出,%b將信號按照二進制格式輸出。另外Verilog HDL語言還提供了其它的輸出格式,比如%h:十六進制、%d:十進制、%o:八進制等。

add wave  -hex /pulse_out_top_inst/Act_x   //Act_x的波形數據將會以十六進制的方式顯示

add wave  -decimal /pulse_out_top_inst/Act_y  //Act_y的波形數據將會以十進制的方式顯示

(2)timescales

'timescale 1ns/1ps                 //度量參考爲1ns,精度爲1ps

module testbench;
	…
    initial 
        begin
            #10 rst = 1;    //10個仿真時間延時,相當於10x1ns=10ns的仿真時間
	…
        end
    initial 
        begin
            //display語句將在每一個仿真推進布進中執行,也就是1ps執行一次
            $display (''%d, rst = %b"m $time, rst);
        end
endmodule
'timescale    reference_time / precision

其中,reference_time是單位時間的度量,precision決定了仿真的推進延遲精度,同時也要設置仿真的推進步進單位。

# 是延遲的意思,而#號後面的數字是延遲的數量,延遲的單位由`timescale控制

比如有:當代碼指定`timescale 1ns/1ps,那麼,#10就是延遲10ns的意思

PS:在同步時序數字邏輯電路的verilog代碼中,是不能加入“#”進行延遲,這不是代碼編寫階段能決定的。

(3)force與release

module	testbench;

    initial 
        begin
            rst = 1;           //在仿真時間零點將rst賦值1
            force data = 101;   //在仿真時間零點強制使data爲101,並保持
            #30 rst = 0;      //在仿真絕對時間30將rst賦值0
            #50 release data;  //在仿真絕對時間80釋放
		                       //data值將保持直到下一個對它的賦值語句
        end
endmodule

force與release語句可以用來強制對執行過程中的reg或wire型信號量賦值。

這兩條語句共同完成一個強制賦值的過程。當一個被force的信號被release以後,這個信號將會保持當時的狀態直到下一個賦值語句產生爲止。

(4)assign/deassign

module	testbench;
	...
	initial 
        begin
            rst = 1;           //在仿真時間零點將rst賦值1
            force data = 101;
            #30 rst = 0;        //在仿真絕對時間30將rst賦值0
            #30 release data;
            ...
		end
	initial 
        begin
		#20 assign rst = 1;  //此條語句覆蓋之前的賦值語句(即絕對時間零點的賦值)
		#30 rst = 0;        //絕對時間50對rst賦值0
		#50 release rst;     //絕對時間100釋放rst信號
endmodule

PS:assign/deassign語句與force/release語句相類似,不過assign/deassign語句只能對設計中的reg型信號賦值。它們常常用來設置輸入值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章