无法 load/store 数据 from/in SRAM:读取数据未知
Cannot load/store data from/in SRAM: read data is unknown
我有一个与 SRAM 存储器的 Verilog 实现相关的问题。模块 sram_1port
应该是一个时钟地址可寻址 SRAM 存储器,它有一个读使能信号和一个写使能信号。模块 control_sram
应该 read/write SRAM 中的数据。数据连续存储在连续的内存地址中。当我尝试模拟电路行为时出现问题,因此 rd_data
信号在整个模拟过程中未确定。所以,内存内容无法输出,我也不知道为什么。是存储数据的时候有问题,应该输出内容的时候有问题,还是两者都有问题?
module sram_1port(
input clk,
input [15:0] address,
input wr,rd,
input [2:0] wr_data,
output reg [2:0] rd_data
);
reg [2:0] mem_reg [15:0];
always @ (posedge clk) begin
if(wr) mem_reg[address] <= wr_data;
else if(rd) rd_data <= mem_reg[address];
end
endmodule
//automaton
module control_sram(
input clk, wr, rd,
input [2:0] wr_data,//read 1 instruction/clk
output [2:0] rd_data,//output
output reg [15:0] out//outputs address
);
reg [15:0] address,address_rd,address_wr;
initial address = 16'd0;
initial address_wr = 16'd0;
initial address_rd = 16'd0;
sram_1port i0(.clk(clk),.address(address),.wr(wr),
.rd(rd),.wr_data(wr_data),.rd_data(rd_data));
always @(posedge clk) begin
if(wr) begin
address_wr = address_wr + 1;
address = address_wr;
address_rd = 16'd0;
end
else if(rd) begin
address_rd = address_rd + 1;
address = address_rd;
address_wr = 16'd0;
end
end
always @ * out = address;
endmodule
//tb for control_sram
module control_sram_tb(
output reg clk,wr,rd,
output reg [2:0] wr_data,
output [2:0] rd_data,
output [15:0] out
);
control_sram cut(.clk(clk),.wr(wr),.rd(rd),.wr_data(wr_data),
.rd_data(rd_data),.out(out));
initial $dumpvars(0,control_sram_tb);
initial begin
clk = 1'd1;
repeat (260000)
#100 clk = ~clk;
end
initial begin
wr_data = 3'd1;
#3000000 wr_data = 3'd2;
#1000000 wr_data = 3'd1;
#3000000 wr_data = 3'd0;
#2000000 wr_data = 3'd3;
#1000000 wr_data = 3'd1;
end
initial begin
rd = 1'b0;
#13000000 rd = 1'b1;
end
initial begin
wr = 1'b1;
#13000000 wr = 1'b0;
end
endmodule
当我 运行 你的模拟时,我看到 rd_data
在时间 13_000_200ns 从 X 变为 1,并且在 3_000ns 期间保持在 1,然后它 returns 到 X。如果将波形放大到那个时间间隔,您应该会看到。如果你在 icarus 上看不到,运行 你在 edaplayground 上用不同的模拟器进行模拟。
此外,您声明您的内存 (mem_reg
) 有 16 个位置 ([15:0]
)。但是,我看到您的 address
为您的写入和读取取值 17、18、19 等。您试图访问不在您记忆中的位置似乎很奇怪。当您为读取执行此操作时,您会得到 X(如预期的那样)。看来你只需要一个 4 位地址,而不是 16 位地址。
我有一个与 SRAM 存储器的 Verilog 实现相关的问题。模块 sram_1port
应该是一个时钟地址可寻址 SRAM 存储器,它有一个读使能信号和一个写使能信号。模块 control_sram
应该 read/write SRAM 中的数据。数据连续存储在连续的内存地址中。当我尝试模拟电路行为时出现问题,因此 rd_data
信号在整个模拟过程中未确定。所以,内存内容无法输出,我也不知道为什么。是存储数据的时候有问题,应该输出内容的时候有问题,还是两者都有问题?
module sram_1port(
input clk,
input [15:0] address,
input wr,rd,
input [2:0] wr_data,
output reg [2:0] rd_data
);
reg [2:0] mem_reg [15:0];
always @ (posedge clk) begin
if(wr) mem_reg[address] <= wr_data;
else if(rd) rd_data <= mem_reg[address];
end
endmodule
//automaton
module control_sram(
input clk, wr, rd,
input [2:0] wr_data,//read 1 instruction/clk
output [2:0] rd_data,//output
output reg [15:0] out//outputs address
);
reg [15:0] address,address_rd,address_wr;
initial address = 16'd0;
initial address_wr = 16'd0;
initial address_rd = 16'd0;
sram_1port i0(.clk(clk),.address(address),.wr(wr),
.rd(rd),.wr_data(wr_data),.rd_data(rd_data));
always @(posedge clk) begin
if(wr) begin
address_wr = address_wr + 1;
address = address_wr;
address_rd = 16'd0;
end
else if(rd) begin
address_rd = address_rd + 1;
address = address_rd;
address_wr = 16'd0;
end
end
always @ * out = address;
endmodule
//tb for control_sram
module control_sram_tb(
output reg clk,wr,rd,
output reg [2:0] wr_data,
output [2:0] rd_data,
output [15:0] out
);
control_sram cut(.clk(clk),.wr(wr),.rd(rd),.wr_data(wr_data),
.rd_data(rd_data),.out(out));
initial $dumpvars(0,control_sram_tb);
initial begin
clk = 1'd1;
repeat (260000)
#100 clk = ~clk;
end
initial begin
wr_data = 3'd1;
#3000000 wr_data = 3'd2;
#1000000 wr_data = 3'd1;
#3000000 wr_data = 3'd0;
#2000000 wr_data = 3'd3;
#1000000 wr_data = 3'd1;
end
initial begin
rd = 1'b0;
#13000000 rd = 1'b1;
end
initial begin
wr = 1'b1;
#13000000 wr = 1'b0;
end
endmodule
当我 运行 你的模拟时,我看到 rd_data
在时间 13_000_200ns 从 X 变为 1,并且在 3_000ns 期间保持在 1,然后它 returns 到 X。如果将波形放大到那个时间间隔,您应该会看到。如果你在 icarus 上看不到,运行 你在 edaplayground 上用不同的模拟器进行模拟。
此外,您声明您的内存 (mem_reg
) 有 16 个位置 ([15:0]
)。但是,我看到您的 address
为您的写入和读取取值 17、18、19 等。您试图访问不在您记忆中的位置似乎很奇怪。当您为读取执行此操作时,您会得到 X(如预期的那样)。看来你只需要一个 4 位地址,而不是 16 位地址。