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