当我在进行基于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的第一个边缘上,它的值是(1+3+5+6)=15;这是我在原始硬件中观察到的。而在模拟结果中,在clk(即abc3)前面的结果为6。由于systemverilog模拟器为非阻塞语句安排分配任务,我相信创建了4个sum实例,即。
sum <= sum + abc[0];
sum <= sum + abc[1];
sum <= sum + abc[2];
sum <= sum + abc[3];由于所有的排定作业同时进行,可能是最后一个实例更新的和,我们有一个和<= 0+ 6的值。如果我错了,请纠正我。
现在,我的问题是如何使模拟器按顺序安排这些任务,以便即使在模拟中也能得到15的值?由于阻塞分配不是一个综合选项,我找不到任何方法来保持RTL的一致性。谢谢。
发布于 2016-02-19 16:09:38
你的分析似乎是正确的。你试过以下几种方法吗?
logic [7:0] temp;
always@(*) begin
temp = 0;
for (int i = 0; i < 4; i = i + 1)
temp = temp + abc[i];
end
always @(posedge clk)
sum <= temp;这样,sum只能在时钟边缘更新,但是我们仍然可以在组合块中展开for循环(所以添加应该仍然按预期工作)。
发布于 2016-02-19 17:51:42
SystemVerilog有一个内置的和数组缩减操作符,它消除了对回线的需求。
sum <= abc.sum() with (8'(item));需要将数据转换为8位,因为默认情况下,结果的类型与数组元素类型相同。
发布于 2016-02-21 15:10:40
我想,您可以在另一个始终块中使用阻塞赋值(它不是时钟边缘敏感的组合块),它的输出可以提供给posedge clk上的posedge clk
reg [7:0] temp_sum;
always @ (*)
begin
temp_sum = abc[0];
temp_sum = temp_sum + abc[1];
temp_sum = temp_sum + abc[2];
temp_sum = temp_sum + abc[3];
end
always @ (posedge clk)
sum <= temp_sum;我想这可能有用。
https://stackoverflow.com/questions/35508992
复制相似问题