我试图在verilog的输出寄存器中读取5个周期后的内存值。我怎么做? 例如,如果我有一个看起来像这样的代码,
reg[31:0] mem[0:5];
if(high==1)
begin
newcount1<=count2;
mem[i]<=newcount1;
i<=i+1;
count2=0;
end
在5个操作周期之后,无论我得到什么内存值,我如何在另一个输出寄存器中读取它们?我可以在这5个周期进行平均操作吗?并得到一个名义价值?
答案 0 :(得分:0)
假设您的内存数据输出为 mem_data ,您希望使用在 mem_data_out 中读取 5个周期的延迟 。
parameter MDP_Latency = 4;
reg [31:0] mem_data_out;
reg [31:0] [MDP_Latency - 1 : 0] mem_data_out_temp;
always@(posedge clk) begin
if(!reset) begin
for(int i = 0; i < MDP_Latency; i ++)
begin
mem_data_out <= 'd0;
mem_data_out_temp[i] <= 'd0;
end
end
else
begin
for(int i = 0; i < MDP_Latency; i ++)
begin
if(i == 0)
begin
mem_data_out_temp[i] <= mem_data;
end
else
begin
mem_data_out_temp[i] <= mem_data_out_temp[i - 1];
end
end
mem_data_out <= mem_data_out_temp[MDP_Latency];
end
end
`
答案 1 :(得分:0)
让我们看看发布的代码:
reg[31:0] mem[0:5];
if(high==1)
begin
newcount1<=count2;
mem[i]<=newcount1;
i<=i+1;
count2=0;
end
缺少缩进使其难以阅读,我没有被宣布。内存实际上是6个位置,0到5。
您的条件和作业不在内部且initial
或always
阻止。
我不确定你对count2做了什么,但混合阻塞和非阻塞被认为是不好的做法,可以做到但你必须非常小心,不要让RTL与门不匹配。
User1932872使用for循环发布了一个答案,它看起来像一个有效的答案,但我认为在这个阶段循环过于复杂的学习和理解你在HDL中创建的内容。在学习的过程中,我会避免使用这些功能,并且只使用它们一次对整个流程感到满意。
reg[31:0] mem[0:4]; //5 Locations
always @(posedge clk) begin //Clked process assignmnets use non-blocking(<=)
mem[0]<=newcount1;
mem[1]<=mem[0];
mem[2]<=mem[1];
mem[3]<=mem[2];
mem[4]<=mem[3];
end
通过这种结构,我们可以通过mem [0]到mem [4]看到数据流水线。我们暗示5个触发器,其中第一个输出将数据驱动到下一个。它们的组合总和可以是:
reg [31+4:0] sum; //The +4 allows for bitgrowth you may need to truncate or limit.
always @* begin // Combinatorial use blocking (=)
sum = mem[0] + mem[1] + mem[2] + mem[3] + mem[4];
end