简介:
RAM(Random Access Memory),随机存储器,是一种用来暂时存储中间数据的存储器,掉电易失,按照类型可以分为单口ram,双口ram,其中双口ram又有简单(伪)的ram,真双端口ram,在异步FIFO的内部就是一个双端口ram存储数据,ram 是最简单的ip,在FPGA和ASIC设计中会经常用到成熟的ram,重点理解ram的输出输入特性,了解在项目中如何使用RAM,以及如何控制RAM的读出和写入。
注意点
FIFO也是一个端口只读,一个端口只写,FIFO与伪双端口ram的区别在于,FIFO是先入先出,没有地址线,不能对存储单元寻址;而伪双端口ram两个端口都有地址线,可以对存储单元寻址。
异步时钟域的缓存只要是双端口器件都可以完成,但是fifo不与要对地址进行控制,是最方便和简单的。
时序图查看相关的数据手册
Verilog代码实现
module RAM #(
parameter FIFO_DATA_WIDTH = 3,
parameter FIFO_ADDR_WIDTH = 2,
)(
input clk_w ,
input rst_w ,
input clk_r ,
input rst_r ,
input full ,
input empty ,
input w_en ,
input r_en ,
input [FIFO_ADDR_WIDTH-1:0] w_addr ,
input [FIFO_ADDR_WIDTH-1:0] r_addr ,
input [FIFO_DATA_WIDTH-1:0] data_in,
output reg [FIFO_DATA_WIDTH-1:0] data_out ,
);
//======================================================================================
reg [FIFO_DATA_WIDTH-1:0] mem [{FIFO_ADDR_WIDTH{1'b1}}:0];
integer i ;
always @(posedge clk_w or negedge rst_w) begin
if(!rst_w)begin
for(i=0;i<=FIFO_DATA_WIDTH;i+i+1)begin
mem[i] <= {FIFO_DATA_WIDTH{1'b0}} ;
end
end
else if(w_en && full==0)begin
mem[w_addr] <= data_in ;
end
else begin
mem[w_addr] <= {FIFO_DATA_WIDTH{1'b0}};
end
end
//===========================================================================
always@(posedge clk_r or negedge rst_r)begin
if(!rst_r)
begin
data_out <= {FIFO_DATA_WIDTH{1'b0}};
end
else if(r_en && empty==0)begin
data_out <= mem[r_addr];
end
else begin
data_out <= {FIFO_DATA_WIDTH{1'b0}};
end
end
endmodule
总结:
双口ram四种操作情况
1两个端口不同时对同一个地址单元写入数据。(ok)
2两个端口同时对一个地址单元读出数据(ok)
3两个端口同时对同一个地址单元写入数据(write err)
4两个端口同时对同一个地址单元,一个写入数据,一个读取数据(read err )