这是一段包含3个不同的always语句的代码,这些语句应该可以合成。问题出在以下方面:
always_comb
begin
c_cntr1 = cntr1;
c_func_val1 = diff (0, c_cntr1);
if (read)
c_cntr1 = cntr1+1;
end
我希望当c_cntr1更改并调用该函数并重新评估c_func_val1时,将对always_comb进行重新评估,但事实并非如此。我对LRM的解释不正确吗?
这是一个完整的测试用例,它显示错误的行为,而其他2个总是阻止的块将产生正确的结果。我在NC上运行它。我还没有检查其他模拟器或综合工具。
完整的测试用例
module test_always_comb();
reg clk, resetn, read;
initial
begin
clk = 0;
resetn = 0;
forever #5 clk = ~clk;
end
initial
begin
resetn = 0;
read = 0;
@(posedge clk);
@(posedge clk);
resetn = 1;
for (int i = 0; i < 10; i++)
begin
@(posedge clk);
if (i%2 == 0)
read= 1;
else
read= 0;
end
$finish;
end
always@(posedge clk)
if (resetn)
begin
$display("Value of c_func_val1 is %d, cntr is %d, c_cntr is %d\n", c_func_val1, cntr1, c_cntr1);
$display("Value of c_func_val2 is %d, cntr is %d, c_cntr is %d\n", c_func_val2, cntr2, c_cntr2);
$display("Value of c_func_val3 is %d, cntr is %d, c_cntr is %d\n", c_func_val3, cntr3, c_cntr3);
end
// Synesizable Design Code
function automatic [4:0] diff
(
input [4:0] num1,
input [4:0] num2
);
return num2;
endfunction // diff
logic [4:0] c_cntr1, c_cntr2, c_cntr3, c_func_val1, c_func_val2, c_func_val3;
reg [4:0] cntr1, cntr2, cntr3;
always_comb
begin
c_cntr1 = cntr1;
c_func_val1 = diff (0, c_cntr1);
if (read)
c_cntr1 = cntr1+1;
end
always_comb
begin
c_cntr2 = cntr2;
if (read)
c_cntr2 = cntr2+1;
c_func_val2 = diff (0, c_cntr2);
end
always @(*)
begin
c_cntr3 = cntr3;
if (read)
c_cntr3 = cntr3+1;
c_func_val3 = diff (0, c_cntr3);
end
always_ff @(posedge clk or negedge resetn)
begin
if (~resetn)
begin
cntr1 <= 0;
cntr2 <= 0;
cntr3 <= 0;
end
else
begin
cntr1 <= c_cntr1;
cntr2 <= c_cntr2;
cntr3 <= c_cntr3;
end
end
endmodule
感谢您的帮助。