为什么访问时的2个内存块之间有延迟?
Why there is a dely between 2 memory block of the while accesing?
我正在为椭圆曲线加密系统构建一个模约简模块。我想访问 Ram,以便在 2 个时钟脉冲中读取 2 个地址。但是我的代码出现了延迟,以至于它变成了 3。
module memtest3(
input memread,
input memwrite,
input [3:0] addr0,
input [3:0] addr1,
input clk,load0,load1,
input [31:0] write_data1,
input [31:0] write_data0,
output reg [31:0] read_data1,
output reg [31:0] read_data0);
reg [3:0] addr [1:0];
reg [31:0] memo [10:0];
//----------------<Memory module>-----------------//
integer i,j;
initial begin
for(i=0;i<11;i=i+1)begin
memo[i]<=i;
end
end
always @(posedge clk)begin
if(memwrite==1'b1)begin
memo[addr[0]]<=write_data0;
memo[addr[1]]<=write_data1;
end
else if(memread==1'b1) begin
read_data0<=memo[addr[0]];
read_data1<=memo[addr[1]];
end
end
//----------------<Memory Addressing>----------------//
always @(posedge clk)begin
/*if(memread==1'b1)begin
if(i<<5)begin
addr[0]<=i;
addr[1]<=i+1;
i<=i+2;
end
end*/
if(memread==1'b1)begin
if(i<<4)begin
if(load0==1'b1)begin
addr[0]<=i;
addr[1]<=i+1;
end
else if(load1==1'b1)begin
addr[0]<=i;
addr[1]<=i+1;
end
i<=i+2;
end
end
end
endmodule
如果我将 i 更改为 i+7,那么读取 addr[0] 的数据将花费更多时间。你能帮我吗。我没头绪。
当你有 2 个像这样的闩锁时:
always @(posedge clk)
a <= b;
always @(posedge clk)
b <= c;
posedge 后a
的结果将是b
的旧值。
所以,如果 b
是 1 而 c
是 2,在 posedge
a --> 1 (old b)
b --> 2 (old c)
如果您需要保证 a
获得 b
的新值,您有几个选择:
1) 使用组合过程计算 b
:
always @(*)
b = c;
2) 在 clk 的负边分配 b
always @(negedge clk)
b <= c;
3) 您可以通过在当前阶段对其进行评估来确保您的 b
在特定时钟边缘具有您需要的值,如下所示。
always @(posedge clk) begin
a <= b;
next_b <= c;
end
always @*
b = next_b;
还有其他方法可以但对变量有限制。例如,如果 b
只是翻牌逻辑中使用的临时变量,您可以使用阻塞赋值来评估它。但不要在其他任何地方使用它:
always @(posedge clk) begin
b = c; // b only used inside this block and uses BA
a <= b;
end
你得想想哪种方法更适合你。可能在 negedge 处递增 i
可以工作。您还必须了解 'memread' 的计算方式。
我正在为椭圆曲线加密系统构建一个模约简模块。我想访问 Ram,以便在 2 个时钟脉冲中读取 2 个地址。但是我的代码出现了延迟,以至于它变成了 3。
module memtest3(
input memread,
input memwrite,
input [3:0] addr0,
input [3:0] addr1,
input clk,load0,load1,
input [31:0] write_data1,
input [31:0] write_data0,
output reg [31:0] read_data1,
output reg [31:0] read_data0);
reg [3:0] addr [1:0];
reg [31:0] memo [10:0];
//----------------<Memory module>-----------------//
integer i,j;
initial begin
for(i=0;i<11;i=i+1)begin
memo[i]<=i;
end
end
always @(posedge clk)begin
if(memwrite==1'b1)begin
memo[addr[0]]<=write_data0;
memo[addr[1]]<=write_data1;
end
else if(memread==1'b1) begin
read_data0<=memo[addr[0]];
read_data1<=memo[addr[1]];
end
end
//----------------<Memory Addressing>----------------//
always @(posedge clk)begin
/*if(memread==1'b1)begin
if(i<<5)begin
addr[0]<=i;
addr[1]<=i+1;
i<=i+2;
end
end*/
if(memread==1'b1)begin
if(i<<4)begin
if(load0==1'b1)begin
addr[0]<=i;
addr[1]<=i+1;
end
else if(load1==1'b1)begin
addr[0]<=i;
addr[1]<=i+1;
end
i<=i+2;
end
end
end
endmodule
如果我将 i 更改为 i+7,那么读取 addr[0] 的数据将花费更多时间。你能帮我吗。我没头绪。
当你有 2 个像这样的闩锁时:
always @(posedge clk)
a <= b;
always @(posedge clk)
b <= c;
posedge 后a
的结果将是b
的旧值。
所以,如果 b
是 1 而 c
是 2,在 posedge
a --> 1 (old b)
b --> 2 (old c)
如果您需要保证 a
获得 b
的新值,您有几个选择:
1) 使用组合过程计算 b
:
always @(*)
b = c;
2) 在 clk 的负边分配 b
always @(negedge clk)
b <= c;
3) 您可以通过在当前阶段对其进行评估来确保您的 b
在特定时钟边缘具有您需要的值,如下所示。
always @(posedge clk) begin
a <= b;
next_b <= c;
end
always @*
b = next_b;
还有其他方法可以但对变量有限制。例如,如果 b
只是翻牌逻辑中使用的临时变量,您可以使用阻塞赋值来评估它。但不要在其他任何地方使用它:
always @(posedge clk) begin
b = c; // b only used inside this block and uses BA
a <= b;
end
你得想想哪种方法更适合你。可能在 negedge 处递增 i
可以工作。您还必须了解 'memread' 的计算方式。