仿真,也叫模擬,是通過使用EDA仿真工具,通過輸入測試信號,比對輸出信號(波形、文本或者VCD文件)和期望值,來確認是否得到與期望所一致的正確的設計結果,驗證設計的正確性。驗證是一個證明設計思路如何實現,保證設計在功能上正確的一個過程。驗證在Verilog HDL設計的整個流程中分爲4個階段:
階段1: 功能驗證——>階段2: 綜合後驗證——>階段3: 時序驗證——>階段4: 板級驗證
1、Testbench及其結構
在仿真的時候Testbench用來產生測試激勵給待驗證設計(Design Under Verification,DUV),或者稱爲待測設計(Design Under Test,DUT)。
2、測試程序的一般結構
由於Testbench是一個測試平臺,信號集成在模塊內部,沒有輸入輸出。 在Testbench模塊內,例化待測設計的頂層模塊,並把測試行爲的代碼封裝在內,直接對待測系統提供測試激勵。
從圖中可以清晰地看出Testbench的主要功能:
(1)爲DUT提供激勵信號。
(2)正確實例化DUT。
(3)將仿真數據顯示在終端或者存爲文件,也可以顯示在波形窗口中以供分析檢查。
(4)複雜設計可以使用EDA工具,或者通過用戶接口自動比較仿真結果與理想值,實現結果的自動檢查。
在編寫Testbench時需要注意的問題 :
(1)testbench代碼不需要可綜合
Testbench代碼只是硬件行爲描述不是硬件設計 。
(2)行爲級描述效率高
Verilog HDL語言具備5個描述層次,分別爲開關級、門級、RTL級、算法級和系統級。
(3)掌握結構化、程式化的描述方式
結構化的描述有利於設計維護,可通過initial、always以及assign語句將不同的測試激勵劃分開來。一般不要將所有的測試都放在一個語句塊中。
(1)testbench代碼不需要可綜合
Testbench代碼只是硬件行爲描述不是硬件設計 。
(2)行爲級描述效率高
Verilog HDL語言具備5個描述層次,分別爲開關級、門級、RTL級、算法級和系統級。
(3)掌握結構化、程式化的描述方式
結構化的描述有利於設計維護,可通過initial、always以及assign語句將不同的測試激勵劃分開來。一般不要將所有的測試都放在一個語句塊中。
3、測試平臺舉例
測試平臺需要產生時鐘信號、復位信號和一系列的仿真向量,觀察DUT的響應,確認仿真結果。
DUT的仿真平臺
(1)組合邏輯電路仿真環境的搭建
實例:
全加器的真值表
Verilog HDL編寫的全加器程序代碼:
module adder1(a,b,ci,so,co);
input a,b,ci;
output so,co;
assign{co,so}=a+b+ci;
endmodule
Verilog HDL測試程序代碼:
module adder1_tb;
wire so,co;
reg a,b,ci;
adder1 U1(a,b,ci,so,co); //模塊例化
initial // 測試信號產生
begin
a=0;b=0;ci=0;
#20 a=0;b=0;ci=1;
#20 a=0;b=1;ci=0;
#20 a=0;b=1;ci=1;
#20 a=1;b=0;ci=0;
#20 a=1;b=0;ci=1;
#20 a=1;b=1;ci=0;
#20 a=1;b=1;ci=1;
#200 $finish;
end
endmodule
全加器的輸入a、b和ci定義爲reg型變量;把輸出so和co定義爲wire型變量用模塊例化語句“adder1 U1(a,b,ci,so,co);”把全加器設計電路例化到測試仿真環境中;用initial塊語句改變輸入的變化並生成測試條件,輸入的變化語句完全根據全加器的真值表編寫。
仿真結果:
(2)時序邏輯電路仿真環境的搭建
在於時序邏輯電路仿真環境中,需要考慮時序、定時信息和全局復位、置位等信號要求,並定義這些信號。
實例:
Verilog HDL編寫的十進制加法計數器源程序代碼:
module cnt10(clk,rst,ena,q,cout);
input clk,rst,ena;
output [3:0] q;
output cout;
reg [3:0] q;
always @ (posedge clk or posedge rst)
begin
if(rst)q=4'b0000;
else if(ena)
begin
if(q<9)q=q+1;
else q=0;
end
end
assign cout=q[3]&q[0];
endmodule
module cnt10_tb;
reg clk,rst,ena;
wire [3:0] q;
wire cout;
cnt10 U1(clk,rst,ena,q,cout); //模塊實例化
always #50 clk=~clk; //時鐘信號產生
initial begin
clk=0;rst=0;ena=1; //控制信號產生
#1200 rst=1;
#120 rst=0;
#2000 ena=0;
#200 ena=1;
#20000 $finish;
end
endmodule
實例化語句“cnt10 U1(clk,rst,ena,q,cout);”把十進制計數模塊例化到仿真環境中;在always中用語句“#50 clk=~clk;”產生週期爲100(標準時間單位)的時鐘方波;用initial塊生成復位信號rst和使能控制信號ena的測試條件。
仿真結果: