我试图了解在某些控制情况下BRAM存储器中的写入和读取是如何发生的。请告诉我我的代码中是否存在任何概念错误:
module bram_dual(wrt_data,addr_w,rst,clk,wr_en,read_data,rd_en);
input [17:0]wrt_data;
input clk,rst,wr_en;
input [4:0]addr_w;
output [17:0]read_data;
output rd_en;
reg [17:0]ram[0:23];
integer i;
always@(posedge clk) begin
if(rst)begin
for (i=0;i<23;i=i+1)begin
ram[i]<={24{1'b0}};
end
end
else
if(wr_en) begin
ram[addr_w]<=wrt_data;
end
end
assign read_data=rd_en ? ram[addr_w]:0;
endmodule
测试台:
module tb_bram;
reg [17:0]wrt_data;
reg clk,rst,wr_en;
reg [4:0]addr_w;
wire [17:0]read_data;
wire rd_en;
integer j;
bram_dual dut1 (.wrt_data(wrt_data),
.clk(clk),
.rst(rst),
.wr_en(wr_en),
.addr_w(addr_w),
.read_data(read_data),
.rd_en(rd_en)
);
initial begin
rst<=1;
clk<=0;
#20;
rst <=0;
end
always@(posedge clk) begin
if (rst) begin
wr_en<=0;
wrt_data<=0;
addr_w<=0;
end
else begin
if (wr_en) begin
for (j=0;j<23;j=j+1) begin
wrt_data<=j;
addr_w<=j;
end
end
else begin
wrt_data<=0;
end
end
end
always #10 clk=~clk;
endmodule
我有关于将数据写入 bram 内存和从 bram 内存读取数据的问题。
我可以使用两个信号将数据写入bram并从bram读取数据吗?
如写入操作时: 通过该信号将数据写入bram -> write_enable , address_write
读取操作: 读取启用,地址读取
我可以使用单独的使能信号进行写入和读取操作吗? 同样,我们也可以做地址吗?
理论上我知道我可以,但从逻辑上讲,当我尝试用 Verilog 编码来做到这一点时,我失败了。
您的
bram_dual
模块中有一些错误。
rd_en
应该是 input
端口,而不是 output
端口。
您仅重置
ram
中的 23 个位置,但您应该重置所有 24 个位置。
这是更正后的代码:
module bram_dual(wrt_data,addr_w,rst,clk,wr_en,read_data,rd_en);
input [17:0]wrt_data;
input clk,rst,wr_en;
input [4:0]addr_w;
output [17:0]read_data;
input rd_en;
reg [17:0]ram[0:23];
integer i;
always@(posedge clk) begin
if(rst)begin
for (i=0;i<24;i=i+1)begin
ram[i]<={24{1'b0}};
end
end
else
if(wr_en) begin
ram[addr_w]<=wrt_data;
end
end
assign read_data=rd_en ? ram[addr_w]:0;
endmodule
在测试台中,您需要将
rd_en
更改为reg
并驱动信号。
目前,我认为您应该只使用
initial
块来进行写入和读取。我从测试台中删除了 always
块,因为我认为它使事情变得复杂。我在初始块中添加了代码,将 5 写入地址 0,然后读取地址 0:
module tb_bram;
reg [17:0]wrt_data;
reg clk,rst,wr_en;
reg [4:0]addr_w;
wire [17:0]read_data;
reg rd_en;
integer j;
bram_dual dut1 (.wrt_data(wrt_data),
.clk(clk),
.rst(rst),
.wr_en(wr_en),
.addr_w(addr_w),
.read_data(read_data),
.rd_en(rd_en)
);
initial begin
rst <= 1;
clk <= 0;
wr_en <= 0;
rd_en <= 0;
wrt_data <= 0;
addr_w <= 0;
repeat (1) @(posedge clk);
rst <= 0;
repeat (2) @(posedge clk);
wr_en <= 1;
wrt_data <= 5;
repeat (1) @(posedge clk);
wr_en <= 0;
wrt_data <= 0;
repeat (2) @(posedge clk);
rd_en <= 1;
repeat (1) @(posedge clk);
rd_en <= 0;
repeat (2) @(posedge clk);
$finish;
end
always #10 clk=~clk;
endmodule
模拟输出: