前言
提前給出一些觀點(diǎn):
- 仿真是為了仿真,所以不要設(shè)置極限情況,例如在時(shí)鐘上升沿通過(guò)阻塞賦值給數(shù)據(jù),應(yīng)該避免這種情況;
- 各種不同的仿真軟件對(duì)時(shí)鐘上升沿通過(guò)阻塞賦值給數(shù)據(jù)的理解不一致,例如modelsim和isim;
- 可以使用非阻塞賦值設(shè)置數(shù)據(jù)值,避免在時(shí)鐘上升沿時(shí)刻使用阻塞賦值給數(shù)據(jù)。
本文最后會(huì)給出推薦的仿真觀點(diǎn)。
實(shí)踐分析
事實(shí)上,上面三點(diǎn)說(shuō)的是針對(duì)一種情況,我們舉一個(gè)簡(jiǎn)單的例子說(shuō)明。我們的設(shè)計(jì)文件,很簡(jiǎn)單,就是一個(gè)檢測(cè)上升沿的程序:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Engineer: Reborn Lee
// website : https://blog.csdn.net/Reborn_Lee
//////////////////////////////////////////////////////////////////////////////////
module delay(
input wire in,
input wire clk,
input wire rst,
output reg out_r3
);
reg in_reg;
always@(posedge clk) begin
if(rst) begin
in_reg <= 0;
end
else begin
in_reg <= in;
end
end
wire mid_pos;
assign mid_pos = ~in_reg & in;
reg reg_pos;
reg reg1_pos;
reg reg2_pos;
always@(posedge clk) begin
if(rst) begin
reg_pos <= 0;
reg1_pos <= 0;
reg2_pos <= 0;
out_r3 <= 0;
end
else begin
reg_pos <= mid_pos;
reg1_pos <= reg_pos;
reg2_pos <= reg1_pos;
out_r3 <= reg2_pos;
end
end
endmodule
如下,我們的testbench為:
`timescale 1ns / 1ps
// Engineer: Reborn Lee
// website : https://blog.csdn.net/Reborn_Lee
module sim_delay;
reg clk;
reg rst;
reg in;
wire out_r3;
initial begin
clk = 0;
forever begin
#5 clk = ~clk;
end
end
initial begin
rst = 1;
in = 0;
#20
rst = 0;
#100
@(posedge clk) begin
in = 1;
end
#300
in = 0;
end
delay delay_inst(
.in(in),
.clk(clk),
.rst(rst),
.out_r3(out_r3)
);
endmodule
我們對(duì)輸入進(jìn)行賦值:
@(posedge clk) begin
in = 1;
end
可見(jiàn),使用的是阻塞賦值,且在時(shí)鐘上升沿賦值;
在這種情況下,我們使用vivado自帶的仿真工具仿真,得到結(jié)果如下:
isim仿真工具
可見(jiàn),得不到上升沿,這我們其實(shí)也能理解;由于是行為仿真,所以,一切都是理想的,不考慮延遲;我們使用阻塞賦值在時(shí)鐘上升沿時(shí)刻給輸入賦值,立即生效;固然,我們的時(shí)鐘在上升沿采樣的時(shí)候,得到in_reg和in是同邊沿的,這樣自然就得不到邊沿了,后面延遲多拍也自然無(wú)用。
這是vivado的仿真工具isim對(duì)這種情況的理解。
現(xiàn)在問(wèn)題來(lái)了,當(dāng)我們使用modelsim進(jìn)行仿真的時(shí)候,情況是這樣的:
modelsim仿真工具
它會(huì)對(duì)in延遲一整拍,也就是要給時(shí)鐘,最終也就能得到上升沿了。同樣的設(shè)計(jì),同樣的仿真文件,為何會(huì)出現(xiàn)這樣的差異呢?這里給出的解釋是仿真工具對(duì)這種情況的理解問(wèn)題:在實(shí)際情況中(考慮真實(shí)環(huán)境,存在延遲),這種輸入的邊沿出現(xiàn)在時(shí)鐘的有效沿,本身就是不合法的,因?yàn)檫@會(huì)導(dǎo)致時(shí)序通過(guò)不了,例如建立時(shí)間。對(duì)于這種情況,modelsim或者questasim的處理就比較直接,我不準(zhǔn)出現(xiàn)這種情況,如果你出現(xiàn)了,我們認(rèn)為此刻無(wú)效。其效果類似于非阻塞賦值:
@(posedge clk) begin
in <= 1;
end
這里使用了非阻塞賦值,那么在時(shí)鐘上升沿時(shí)刻,in的值就沒(méi)那么快生效,如此,無(wú)論在那個(gè)平臺(tái)仿真,仿真情況都一致了。
下面是這種情況下在任意平臺(tái)的仿真圖:
任意平臺(tái)
推薦的仿真設(shè)計(jì)
開(kāi)門見(jiàn)山,在時(shí)鐘有效沿時(shí)刻給數(shù)據(jù)是不符合實(shí)際的,是極端的做法,這在實(shí)際情況中不會(huì)出現(xiàn),即使出現(xiàn),綜合布線工具也會(huì)重新布線避免這種情況,否則就是時(shí)許違規(guī)。因此為了有意義的仿真且統(tǒng)一仿真平臺(tái),我們應(yīng)該在距離有效沿一定延遲給數(shù)據(jù),例如:
#100
@(posedge clk) begin
#1 in = 1;
end
或者:
#100
@(negedge clk) begin
in = 1;
end
總之,別在有效沿給數(shù)據(jù),以這種情況為例,給出仿真圖:
#100
@(posedge clk) begin
#1 in = 1;
end
推薦的仿真方式
總結(jié)
從上面的分析可以看出,為了適應(yīng)不同的仿真平臺(tái)(并不是說(shuō)哪個(gè)仿真平臺(tái)錯(cuò)了) ,且本著仿真意義的實(shí)際情況,我們不應(yīng)該在極端的情況下進(jìn)行仿真,不僅沒(méi)有意義,而且讓人疑惑。推薦的做法是在下降沿或者距離時(shí)鐘的上升沿有一定的延遲給數(shù)據(jù),這才能避開(kāi)不同平臺(tái)的差異且有實(shí)際意義。
-
FPGA設(shè)計(jì)
+關(guān)注
關(guān)注
9文章
428瀏覽量
26452 -
仿真器
+關(guān)注
關(guān)注
14文章
1011瀏覽量
83559 -
Vivado
+關(guān)注
關(guān)注
19文章
803瀏覽量
66151
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論