Вот фрагмент кода с 3 различными операторами всегда, который должен быть синтезируемым. Проблемы со следующим:
always_comb
begin
c_cntr1 = cntr1;
c_func_val1 = diff (0, c_cntr1);
if (read)
c_cntr1 = cntr1+1;
end
Я ожидал, что Always_comb будет переоценен при изменении c_cntr1, вызове функции и повторной оценке c_func_val1, но это не так. Я неправильно интерпретирую 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
Спасибо за вашу помощь.