当我在基于SystemVerilog的FPGA设计工作时,我遇到了一种情况,我必须在时钟边缘计算4个元素的数组之和 . 我能够使用带有非阻塞赋值语句的for循环来做到这一点 .
该设计在Quartus 15.0上成功合成,但当我尝试在Modelsim Altera上使用相同的RTL运行模拟时,结果出乎意料 . 我已经编写了一个示例代码来说明相同的内容 .
module schedule;
logic [7:0] abc [0:3];
logic [7:0] sum=0;
logic clk=0;
always begin
#5.0ns clk <= ~clk;
end
initial begin
abc = '{1,3,5,6};
end
initial @(posedge clk) begin
for(int i = 0; i <= 3;i++ ) begin
sum <= sum + abc[i];
end
end
initial
$monitor("Sum is %d",sum);
endmodule
This image shows the simulation results.
在此示例代码中, sum 是使用非阻塞分配计算的 . 它的目的是在clk的第一个构造上具有(1 3 5 6)= 15的值;我在原始硬件中观察到过 . 但是在模拟中,结果是clk(即 abc[3] )的结果是6 . 由于systemverilog模拟器为非阻塞语句安排了分配,我相信会创建4个sum实例 .
sum <= sum + abc[0];
sum <= sum + abc[1];
sum <= sum + abc[2];
sum <= sum + abc[3];
由于所有预定的分配同时发生,可能是最后一个实例更新的总和,我们有一个sum <= 0的值 . 如果我错了,请纠正我 .
现在我的问题是如何使模拟器按顺序安排这些分配,以便即使在模拟中我也能获得15的值?由于阻塞分配不是综合中的一个选项,我无法找到任何方法来保持RTL的一致性 . 谢谢 .
3 回答
您的分析似乎正确 . 您是否尝试过以下方法?
这样,
sum
只在时钟边沿上更新,但我们仍然可以在组合块中展开for
循环(因此添加仍应按预期工作) .SystemVerilog具有内置和数组减少运算符,无需for循环
需要转换为8位,因为默认情况下,结果的类型与数组元素类型相同 .
我想,你可以在另一个总阻塞中使用阻塞分配(这不是时钟边缘敏感,组合阻塞),它可以提供给
posedge clk
的sum
我想,这可能会奏效 .