Verilog - 从外部记忆中获得即时响应

时间:2016-02-05 12:52:40

标签: verilog hdl

我试图编写一个Verilog模块,该模块在每个周期中迭代外部存储器的元素。我现在面临的问题是,在同一个循环中,在循环期间更改存储器地址不会导致输入数据被更改。更改地址不会导致输入数据被更改在一个循环中。我将用一些代码说明问题:

module r(input rst, ..., output reg [MEMORY_ADDR_WIDTH-1:0] addr, input memory_value);

//...
always @(posedge clk) begin
    //...
    for(addr = 0; addr < MEMORY_SIZE; addr = addr+1) begin        
        if (memory_value) //...
        // PROBLEM: changing addr in this loop doesn't cause memory_value to change
    end
end
endmodule

以下是我实例化模块的方法

module top;

 reg mem[MEMORY_SIZE-1:0];
    wire [MEMORY_ADD_WIDTH-1:0] addr;
    //...
    r r( rst, ..., addr, mem[addr]);
endmodule

我使用Modelsim来模拟设计。首先,这是预期的行为,如果这是一个常见的解决方法吗?

1 个答案:

答案 0 :(得分:1)

Verilog中的

for循环用于创建赋值的多个副本。循环自动展开(这就是它需要常量边界的原因)。

例如

always@(posedge clk)
for (i=1; i<4; i=i+1)
    foo[i] <= foo[i-1]*foo[i-1];

相当于

always@(posedge clk) begin
    foo[1] <= foo[0]*foo[0];
    foo[2] <= foo[1]*foo[1];
    foo[3] <= foo[2]*foo[2];
end

因此,您提供的代码永远不会为addr分配值,这可能是您没有看到任何更改的原因。 (与i未出现在我的示例的第二部分中的方式相同)

请考虑将它们分开。:

always@(posedge clk)
    addr<=(addr+1)%ADDR_MAX;

always@(*)begin
    if (memory_value) // mem[addr]
    //...
end