欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

异步简单双口RAM的实现

程序员文章站 2024-02-22 22:57:22
...

RAM的分类

RAM,随机存取存储器,有单口和双口之分,单口RAM只有一个数据线和地址线,不能同时进行读取操作,双口RAM有读和写两个地址线和数据线。因此双口RAM使用要比单口RAM广泛。

双口RAM有真双口和简单双口之分,真双口有两个读端口和两个写端口,简单双口只有一个读端口和一个写端口,一般读写要求不高时,简单双口RAM就能满足我们的需求。另外根据时钟的不同,RAM还有同步异步之分,同步RAM是指读写采用同一个时钟,异步RAM是指读写的时钟不同。

异步简单双口RAM的实现

实现的双口RAM的功能是:建立一个宽度为8bit深度为8的RAM,然后把0-7写入,并在尚未完全写完时就开始读取数据,最终全部读出。程序如下:

module single_dualram(
	input	wire		clk1,//写时钟
	input	wire		clk2,//读时钟
	input	wire		we,//写使能
	input	wire		rd,//读使能
	input	wire [2:0]	we_addr,//写地址
	input 	wire [2:0]  rd_addr,//读地址
	input	wire [7:0]  datain,//写数据
	output  reg  [7:0]  dataout//读数据
	);
reg [7:0]mem[7:0];

always @(posedge clk1) begin
	if (we == 1'b1) begin
		mem[we_addr] <= datain;
	end
end

always @(posedge clk2) begin
	if (rd == 1'b1) begin
		dataout <= mem[rd_addr];
	end
end

endmodule

testbench模块:

`timescale 1ns/1ns
module tb_single_dualram();
reg				clk1,clk2;
reg				we,rd;
reg	[7:0]		we_addr,rd_addr;
reg	[7:0]		datain;
wire[7:0]		dataout;

initial begin
	clk1 = 0;
	clk2 = 0;
	we   = 0;
	rd 	 = 0;
	we_addr = 0;
	rd_addr = 0;
	datain  = 0;
end

always #10 clk1 = ~clk1;
always #10 clk2 = ~clk2;

initial begin
	#25
	we = 1;
	#50
	rd = 1;
	#100
	we = 0;
end

initial begin
	#20
	repeat(7)
	#20
	begin
		we_addr = we_addr +1;
		datain  = datain + 1;
	end
end
initial begin
	#75
	repeat(7)
	#20
	begin
		rd_addr = rd_addr +1;
	end
end

initial
#240
rd = 0;

single_dualram inst_single_dualram(
	.clk1    (clk1),
	.clk2    (clk2),
	.we      (we),
	.rd      (rd),
	.we_addr (we_addr),
	.rd_addr (rd_addr),
	.datain  (datain),
	.dataout (dataout)
	);

endmodule

波形图如下,可以看到效果达到预期:

异步简单双口RAM的实现

在modelesim中检查存储器信息,可以发现已经将0-7存入RAM,如下图所示:

异步简单双口RAM的实现 

相关标签: FPGA verilog fpga