为什么verilog模拟器将净延迟建模为惯性延迟而不是传输延迟?

时间:2017-11-30 18:51:50

标签: verilog system-verilog

我正在使用具有净延迟的电线连接测试台中的DDR模型,以模拟电路板上的走线延迟。迹线可以在其传输线中保持1或2位,但由于模拟器将净延迟建模为惯性延迟,因此所有位都被滤除为毛刺。我甚至没有这样的时钟。 SystemVerilog规范在此主题上并不明确。因此,我猜测模拟器不希望在性能和存储方面产生成本,将其建模为传输延迟。但是,我坚信传输延迟是用于净延迟的正确方法,因为否则用自己的延迟建模每个bidir信号的麻烦是巨大的。你怎么看?

这是我的测试用例。

`timescale 1ps/1ps

module sim_top  ();

parameter realtime NET_DELAY = 80ps;
parameter realtime PULSE_DELAY = 50ps;

logic driver;
initial begin
  driver = 0;
  forever #PULSE_DELAY driver = !driver;
end

wire #NET_DELAY a;
assign a = driver;
always @(posedge a or negedge a) begin
  $display("a=%b @ %t", a, $time);
end

logic b;
always @(*) begin
  b <= #NET_DELAY driver;
end

always @(posedge b or negedge b) begin
  $display("b=%b @ %t", b, $time);
end


initial begin
 #1ns;
 $finish;
end
endmodule

2 个答案:

答案 0 :(得分:0)

可以使用#delays with non-blocking assighments来模拟传输延迟:

always @*
   out <= #delay input;

这接近于惯性延迟:

assign
    #delay out = input;

其余的主要是行为模拟工件,只应在测试平台中使用。

我发现这篇文章对这个问题非常有用: http://www-inst.eecs.berkeley.edu/~cs152/fa06/handouts/CummingsHDLCON1999_BehavioralDelays_Rev1_1.pdf

答案 1 :(得分:0)

  

所以,我猜测模拟器不希望在性能和存储方面产生成本,将其建模为传输延迟。

我可以想象你是如何得到这种推理的。据我所知,你的假设是不正确的。

真正的逻辑门具有惯性延迟。这种延迟是由RC(电阻和电容)引起的,它继承到器件,路由或有意添加。 Verilog使用惯性延迟来模拟实际逻辑的延迟行为。

我找不到引用,但是通过与具有Verilog之前经验的工程师的讨论,早期的Verilog只模拟了门(想想Verilog原语andornand,{{1等等)。分配语句和总是在一段时间后添加块以及合成的可能性。非阻塞(bufif0)分配在很晚之后添加(并从我听到的VHDL中复制),但是在Verilog之前由IEEE执行。

以与gate相同的方式分配语句句柄延迟。请参阅IEEE1800-2012§10.3.3连续分配延迟

  

给予连续分配的延迟应指定右侧操作数值变化与左侧分配之间的持续时间。如果左侧引用标量网,那么 延迟应以与门延迟相同的方式处理 ;也就是说,输出上升,下降和变为高阻抗可以给出不同的延迟(见28.16)。

我猜分配语句使用与门相同类型的延迟来重用现有代码(在模拟器内,而不是Verilog代码)来管理延迟并保持延迟定义的连续性。它也更容易映射,例如:<=assign #1 out = in;相同。

对于实际电路,当您希望延迟为10且滤波器为0.5时,您需要具有小RC的20个延迟单元链。如果你想要一个10的延迟和滤波器,你可以使用一个带有大RC的延迟单元。从理论上讲,合成器可以将此延迟信息用于目标延迟和过滤控制(我想不出任何合成器实际上是这样做的;我所知道的所有合成器都忽略了RTL延迟)。

通常,非阻塞(buf #1 (out,in);)分配用于同步逻辑(边沿敏感触发器和电平敏感锁存器)。传输延迟是主要的例外,但仅应用于不能合成的行为建模。如果您知道实际延迟路径将具有的过滤量,我建议将其编码如下:

<=

与纯惯性延迟方法相比,它更清晰,CPU密集度更低:

reg out;
wire #(FILTER) in_filtered = in;
always @* out <= #(TOTAL_DELAY-FILTER) in_filter; // must be >=0.0