通用的HDL包括VHDL和verilog HDL
HDL既可以用來design也可以用來test/confirm
用HDL寫出來的測試文件稱為test bench
被測試的模塊成為device under test,簡稱DUT,既可以是behavioral級描述也可以是RTL級或gate級描述
verilog simulator是verilog語言的仿真器,waveform viewer是波形觀測器
test bench中應該例化DUT,對應端口名稱可以不同
testbench中使用兩種信號類型: wire reg,test中用法與design時一樣
wire類型不能在always或initial塊中使用
reg類型只能在always或initial塊中使用
initial和always是順序控制模塊,但它們之間是在仿真開始時并行執(zhí)行的
initial和always塊中可以插入begin end或fork join來安排執(zhí)行順序
tesbench開始需要給所有信號設置初值,一般是一個initial塊
默認的wire類型是Z 默認的reg類型是X
`timescale設置了時間步長和時間精度
測試文件中兩項重要的元素是clocks和resets
$display和$monitor格式相同,但?不同
task只能在initial或者always中被調用,用于將重復出現(xiàn)的操作打包出來單獨存放
后仿真時需要庫和SDF文件
所有系統(tǒng)任務都以$開頭,都只能在initial或always模塊里(在initial塊中只執(zhí)行一次,在always里滿足條件將不斷執(zhí)行)
顯示、探測、監(jiān)控任務
%h%H %d%D %b%B %O %o %C%c %S%s %T%t %M%m
以上都以表達式的最大可能值所占用的位數(shù)來顯示表達式當前值
%0h%0H %0d%0D %0b%0B %0O %0o
以上都以表達式的當前值最小占用的位數(shù)來顯示表達式當前值
輸出時,如果所有位均為不定值,則輸出結果為小寫的x;所有位均為高阻則輸出結果為小寫的z
輸出時,如果部分位為高阻值,則輸出結果為大寫的X;部分位為高阻則輸出結果為大寫的Z
$display $displayb $displayo $displayh
格式: $display("simulation time is %t",$time);
$write $writeb $writeo $writeh
格式: $write("simulation time is %t",$time);
$display $write這兩個任務的作用基本相同,唯一的區(qū)別就是$display任務執(zhí)行完以后自動添加一個換行符n,而$write不自動添加
$display("a=%d");和$write("a=%dn");作用相同
用于在滿足某個條件(如時鐘邊沿來時)是輸出仿真數(shù)據(jù)
$strobe $strobeb $strobeh $strobeo
格式: $strobe("the flip-flop value is %b at time %t",q,$time);
用于在指定的時刻之后輸出顯示仿真數(shù)據(jù)
$strobe和$display不同之處在于 $display是遇到該時刻時執(zhí)行,$strobe是當前時刻結束(下一時刻開始)時執(zhí)行
以上任務通常都在always塊中執(zhí)行
$monitor $monitorb $monitorh $monitoro
格式: $monitor("at %t, d=%d,clk=%d",$time,d,clk);
連續(xù)監(jiān)控指定的參數(shù),只要參數(shù)表中的參數(shù)值發(fā)生變化,就在當前仿真時刻結束時顯示
$monitoron開啟所有的$monitor任務 $monitoroff關閉所有的$monitor任務
在多模塊測試時$monitoron 和$monitoroff用于使能和關閉本模塊的監(jiān)視功能
$display $write $strobe 多用于always模塊,$monitor用于initial模塊
always(a or b or c)$display("....");效果與 initial $monitor("...");一樣
文件的打開與關閉:
$fopen打開一個文件(以整數(shù)文件指針方式) 格式:integer file_pointer=$fopen(file_name)
$fclose關閉一個文件(以整數(shù)文件指針方式) 格式: $fclose(file_pointer)
將信息輸出到文件:
顯示任務 寫入任務 探測任務 監(jiān)控任務都有用于向文件輸出信息的相應命令,即
$fdisplay $fdisplayb $fdisplayh $fdisplayo
$fwrite $fwriteb $fwriteh $fwriteo
$fstrobe $fstrobeb $fstrobeh $fstrobeo
$fmonitor $fmonitorb $fmonitorh $fmonitoro
與相應的無文件輸出命令相比,只是多了打開文件、寫入文件、關閉文件三個步驟
從文件中讀數(shù)據(jù):
$readmemb 讀取二進制文件
$readmemh 讀取十六進制文件
格式:
$readmemb("<數(shù)據(jù)文件名>",<存儲器名>);
$readmemb("<數(shù)據(jù)文件名>",<存儲器名>,<起始地址>);
$readmemb("<數(shù)據(jù)文件名>",<存儲器名>,<起始地址>,<結束地址>);
仿真控制任務:
$stop
格式: 在initial中 #500 $stop
$finish
格式: 在initial中 #500 $finish
$stop暫停仿真后返回軟件操作主窗口,將控制權交給user
$finish終止仿真后關閉軟件操作主窗口
時間顯示格式:
$time 返回64位整型時間
$stime 返回32位整型時間
$realtime 返回實型時間
$time 任何時間以`timescale定義的時間單位為單位
$realtime 任何時間以`timescale定義的時間單位+時間精度為單位
隨機函數(shù):
$random(seed)
seed必須是reg或者integer寄存器類型,返回的隨機數(shù)是32位有符號數(shù)
$random%60 產生的是-59~59之間的隨機數(shù)
{$random}%60產生的是0~59之間的隨機數(shù)
可以讓出現(xiàn)時間隨機 也可以讓某些位隨機出現(xiàn)1或0
層次命令: 模塊標示符 任務標示符 函數(shù)標示符 程序塊標識符,通過層次命令可以訪問到任何變量
其他模塊中共享task和function的方法: 1.使用層次路徑名 2.使用頭文件.h來包含需要共享的funtion和task
VCD文件(value change dump文件)是常用的波形記錄文件,與波形的作用等同,是一個ASCII文件
$dumpon $dumpoff 在一個initial塊中控制dump的開始和結束
$dumpvars $dumpfile 分別在initial中指定VCD文件名(*.dump)和變量
dump系統(tǒng)任務基本都在initial模塊中使用
測試模塊的構成部分:
測試模塊命名: modulename_tb
輸入輸出信號(與veilog電路描述文件中的端口屬性相反)
initial或always塊來產生激勵信號
initial或always塊中加入系統(tǒng)任務
模塊實例化
測試中常用的波形有兩類:
initial塊及塊內延遲來產生特定序列
always塊及內內延遲來產生周期性序列
常用always塊來描述時鐘,always產生時鐘的兩種方法;
常用一個initial設置初值;
常用一個initial來設置仿真的啟?刂;
initial中用forever(無數(shù)次)和repeat(有限次)產生循環(huán)信號
技巧:(用assign及延遲可以產生相移時鐘、模塊調用方法可以產生多種規(guī)格的時鐘、讀入.vec文件中數(shù)據(jù)以及比較的寫法)
quartus的語法診錯能力比modesim強, modesim的輸入語法顯示比quartus好
`include命令:
一個`include命令只能指定一個被包含模塊
意義是在包含文件里復制被包含模塊的代碼
易于將一個模塊做成特定功能的塊,然后結構化組織起來
使用時由高層include低層模塊,所有模塊文件放在同一個文件夾內