当我在基于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
在这个样例代码中,使用了非阻塞赋值来计算 sum。原本它应该在 clk 的第一个 posedge 上取到 (1+3+5+6)=15 的值;而我已经在原始硬件上观察到了这个情况。但是在模拟中,结果在 clk 的 posedge 处为 6(即 abc[3])。由于 SystemVerilog 模拟器会为非阻塞语句安排分配,我相信会创建出 4 个 sum 实例。
sum <= sum + abc[0];
sum <= sum + abc[1];
sum <= sum + abc[2];
sum <= sum + abc[3];
由于所有预定的任务同时发生,可能最后一个实例更新的总和为sum,而我们得到的值是sum <= 0 + 6。如果我错了,请纠正我。
现在我的问题是,如何让模拟器按顺序安排这些任务,以便在模拟中获得值15?由于在综合中不能使用阻塞赋值,我找不到任何保持RTL一致的方法。谢谢。