2016-02-05 22 views
0

我正在尝试编写一个Verilog模块,它在每个周期的中迭代外部存储器的元素。我现在面临的问题是,在周期内更改内存地址不会导致输入数据在同一周期内发生更改.ie:更改地址不会导致输入数据在一个周期内更改cycle.I'll说明问题与一些代码: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仿真设计。首先,这是否是预期的行为,如果是常见的解决方法?

+0

“memory_value”是输入到“R”模块等“r”模块,本身不会更改“memory_value”的值。那么,通过“在此循环中更改addr不会导致memory_value更改”,您是什么意思? –

+0

@KaranShah作为OP指定他们正在与内存交谈,他们可能希望'memory_value'在他们在addr上提供新值时发生改变(这不会发生;请参阅我的回答) – wilcroft

回答

1

for Verilog中的循环用于创建作业的多个副本。循环自动展开(这就是为什么它需要不断的界限)。

例如

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

相当于

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

所以,你从来没有提供的代码分配一个值addr,为什么你没有看到任何改变,这是可能的。 (在相同的方式,i没有在我的例子中的第二部分出现)


考虑,而不是将它们分了:

[email protected](posedge clk) 
    addr<=(addr+1)%ADDR_MAX; 

[email protected](*)begin 
    if (memory_value) // mem[addr] 
    //... 
end 
+0

这完全是逻辑。尽管你会如何处理这种情况? – user2268997

+0

分割你的代码。将时钟块作为地址的计数器,并使用组合块来评估“memory_value”。我假设你只想在每个时钟周期执行一次检查。 (我将编辑一些代码作为例子) – wilcroft

+0

如果你想在一个循环中进行多次内存读取,你需要一个支持该内存的内存(并且在这一点上,为每个想要处理的记忆词提供一个单独的模块)。 – wilcroft