RAM的交替读写
作者:互联网
一、认识RAM
RAM的分类比较多,单口RAM,双口RAM等等,详细的不再介绍。这里使用的是simple dual port RAM。本次实验的内容是RAM的交替读写,RAM的读写位宽和深度都设置为256x8来完成这部分的内容。
二、 调用RAM ip并按照上述要求进行设置
设置过程如下几个图:
在summary界面中划红线部分可得知,RAM读端口读出的数据会延迟一个时钟周期,相比于地地址而言。
三、设计思路
内部产生一个写使能信号,当写使能信号为高时向RAM中写入数据,写端口的地址开始叠加,当写完数据之后把写使能信号拉低,此时开启RAM的读端口,读地址开始叠加,当读完数据后在写使能信号拉高,开始写入数据,如此往复循环。
绘制波形如下:
四、rtl代码的完成
如下:内部添加的wr_en其实就是RAM的wea信号,wr_addr和rd_addr是对RAM读写端口地址的控制,RAM输出的数据最终连接到端口信号po_data。
`timescale 1ns / 1ps
module ctrl_ram(
input wire clk,
input wire rst_n,
input wire [7:0] pi_data,
output wire [7:0] po_data
);
reg wr_en;
reg [7:0] wr_addr;
reg [7:0] rd_addr;
always @(posedge clk or negedge rst_n)begin
if (rst_n == 1'b0) begin
wr_en <= 1'b1;
end
else if (wr_addr == 'd255) begin
wr_en <= 1'b0;
end
else if (rd_addr == 'd255) begin
wr_en <= 1'b1;
end
end
always @(posedge clk or negedge rst_n)begin
if (rst_n == 1'b0) begin
wr_addr <= 'd0;
end
else if (wr_en == 1'b1 && wr_addr == 'd255) begin
wr_addr <= 'd0;
end
else if (wr_en == 1'b1) begin
wr_addr <= wr_addr + 1'b1;
end
end
always @(posedge clk or negedge rst_n)begin
if (rst_n == 1'b0) begin
rd_addr <= 'd0;
end
else if (wr_en == 1'b0 && rd_addr == 'd255) begin
rd_addr <= 'd0;
end
else if (wr_en == 1'b0) begin
rd_addr <= rd_addr + 1'b1;
end
end
ram256x8 inst_ram256x8 (
.clka(clk), // input wire clka
.wea(wr_en), // input wire [0 : 0] wea
.addra(wr_addr), // input wire [7 : 0] addra
.dina(pi_data), // input wire [7 : 0] dina
.clkb(clk), // input wire clkb
.addrb(rd_addr), // input wire [7 : 0] addrb
.doutb(po_data) // output wire [7 : 0] doutb
);
endmodule
5.写tb并完成仿真
tb如下:这里gen_data仅产生了一次数据256x8的数据,所以仿真的时候读写数据仅完成一次交替。如果想多次交替,可以在写一个for循环,让产生数据的task循环执行即可。
<summarytb代码< summary="">
`timescale 1ns / 1ns
module tb_ctrl_ram();
reg clk;
reg rst_n;
reg [7:0] data;
wire [7:0] po_data;
initial begin
rst_n = 0;
clk = 0;
data = 'd0;
#55;
rst_n = 1;
end
always #10 clk = ~clk;
initial begin
gen_data();
end
task gen_data;
integer i;
begin
@(posedge rst_n);
// repeat (50)@(posedge clk);
for(i=0;i<256;i=i+1)begin
data = i;
@(posedge clk);
end
data = 0;
end
endtask
ctrl_ram inst_ctrl_ram (
.clk(clk),
.rst_n(rst_n),
.pi_data(data),
.po_data(po_data));
endmodule
5.2仿真结果
放大后对比一下写入的数据和读出的数据是否一致即可,这里就不在贴图了。
读端口的波形
你会发现读出的数据相对读端口的地址而言,延迟了一个时钟周期。
标签:clk,数据,读写,RAM,交替,rst,data,reg 来源: https://www.cnblogs.com/xiaoyongstudy/p/16351138.html