我在接口中使用时钟模块进行信号混叠。我想将一些位连接在一起形成一个总线,然后从我的驱动程序驱动这个总线。所以,例如:
interface bus_intf (clk);
input logic clk;
logic[1:0] x_lsb;
logic[1:0] x_msb;
clocking driver_bus @(posedge clk)
default input #1step output #0;
output x_bus = {x_msb, x_lsb};
endclocking
endinterface
现在问题是,在我的一个断言中,我需要读取 bus_intf.driver_bus.x_bus 。如SV手册中所述,测试平台不应读取时钟模块的输出变量,如果是,则模拟器会发出错误(或在我的情况下发出警告)。
所以我修改了界面:
interface bus_intf (clk);
input logic clk;
logic[1:0] x_lsb;
logic[1:0] x_msb;
clocking driver_bus @(posedge clk)
default input #1step output #0;
inout x_bus = {x_msb, x_lsb};
endclocking
endinterface
现在的问题是,在我的波形中,我看到创建了两个信号 - x_bus 和 x_bus__o 。我理解为什么Questasim这样做 - 它是分开 inout 声明,所以我可以查看这两个版本。 但是,现在问题是我的所有时钟驱动器都延迟了一个时钟周期!所以连接到DUT的 x_bus__o 比 x_bus 晚一个时钟周期。这是因为我明确指出输出偏差是#0。
知道为什么会这样吗?我做错了什么或者我误解了吗?
答案 0 :(得分:2)
我已将您的代码放在EDAPlayground上并尝试了。它似乎按预期工作。这是我的测试工具:
module top;
bit clk;
always #1 clk = ~clk;
bus_intf busif(clk);
initial begin
@busif.driver_bus;
$display("time = ", $time);
busif.driver_bus.x_bus <= 'hf;
repeat (2)
@(negedge clk);
$display("time = ", $time);
busif.driver_bus.x_bus <= 'ha;
#100;
$finish();
end
always @(busif.x_lsb)
$display("time = ", $time, " x_lsb = ", busif.x_lsb);
always @(busif.x_msb)
$display("time = ", $time, " x_msb = ", busif.x_msb);
endmodule
如果您想在线试用,请点击此链接:http://www.edaplayground.com/x/Utf
如果我在一个posedge上驱动x_bus
,则会立即写入该值,正如#0
输出延迟所预期的那样。如果我驾驶x_bus
在一个地方(或在任何其他时间除了一个假设),那么它将等到下一个时间来驱动该值。无论x_bus
是output
还是inout
,我都会看到此行为。
检查您何时安排写入;这可能是你看到波浪延迟的原因。
答案 1 :(得分:0)
当您有双向流经时钟模块时,从验证到硬件再返回的信号必须通过两个虚拟 D-FF。所以原来的观察是正确的。 1-step 的输入是设计的一个 D-FF;然后返回是一个出现 0ns 的 D-FF 返回(即,就在时钟之后)。时钟模块在需要单周期转向的信号的情况下没有用,因此,如果需要,请避免使用它们。对于大多数设计,它根本没有必要。监控器会观察到一个流水线延迟一个周期的信号,这一般不会有问题。