以下代码是我写作的简单案例。
模块bar
将根据a
对operation
执行某些操作。问题是,我无法正确分配result
(应在b
的输出foo1
之后分配)。
我找到了一种解决方法,只需在#1
之前添加result = r1
即可。我想知道模块之间同步的正确方法是什么?
module foo1(
input a,
output reg b
);
always@(a)
b = a;
endmodule
module foo2(
input a,
output reg b
);
always@(a)
b = ~a;
endmodule
module bar(
input a,
input operation,
output b
);
reg result;
assign b = result;
wire r1, r2;
foo1 submod1(a, r1);
foo2 submod2(a, r2);
always@(a or operation) begin
case (operation)
1'b0:
result = r1;
1'b1:
result = r2;
endcase
end
initial begin
$dumpfile("foobar.vcd");
$dumpvars(0, r1);
$dumpvars(0, r2);
$dumpvars(0, result);
$dumpvars(0, operation);
end
endmodule
module test;
reg a, op;
wire r;
bar mod(a,op,r);
integer i;
initial begin
a = 0;
op = 0;
for (i=0; i<8; i=i+1)
#10 a = ~a;
end
endmodule
答案 0 :(得分:1)
您可能没有看到正确传播结果的原因是因为您的结果敏感度列表不完整。你包含一个和你的操作真的需要包括r1和r2才能拥有正确的组合逻辑。如果将它们添加到灵敏度列表中,它应该按预期运行:
always@(operation or r1 or r2) begin
case (operation)
1'b0:
result = r1;
1'b1:
result = r2;
endcase
end
但是,最好不要使用像always_comb
这样的SystemVerilog结构来至少使用Verilogs always @(*)
来组合逻辑。这样,你就不会像在这次一样冒险丢失敏感度列表项目。
答案 1 :(得分:1)
分配result
的敏感度列表不正确。 always@(a or operation)
应为always@(r1 or r2 or operation)
或always @*
。
除了放置在程序块(begin
- end
)中的代码之外,Verilog会模拟所有乱序。这意味着always@(a or operation)
可以在r1
和r2
更新之前执行。
对于组合逻辑,我建议使用always @*
(或等效的always @(*)
)。这是IEEE Std 1364-2001中引入的所有现代模拟器支持的自动灵敏度列表(即计算出灵敏度列表中的内容)。如果您需要遵循IEEE Std 1364-1995,请使用always@(r1 or r2 or operation)