双口ram读写

项目名称

双口ram读写

具体要求

将0-1023存入ram并读出,a端口写入数据,b端口读出数据,两个端口的时钟频率设置相同,仿真时以50m写入12.5m读取

单端口时读和写不能同时进行,双端口ram多了一个读地址,可以同时读写

设计架构

                  

代码设计

verilog代码设计

ram ipcore创建,位宽10,深度1024

顶层模块设计

module dram_top(
	input					a_clk,
	input					b_clk,
	input					rst_n,
	
	output [9:0]		a_q,
	output [9:0]		b_q
);

wire a_wren;
wire b_wren;
wire [9:0]a_addr;
wire [9:0]b_addr;
wire [9:0]a_data;
dram_ctrl dram_ctrl(
	.a_clk(a_clk),
	.b_clk(b_clk),
	.rst_n(rst_n),

	.a_wren(a_wren),//写请求
	.a_addr(a_addr),//写地址
	.a_data(a_data),//写数据

	.b_wren(b_wren),//写请求
	.b_addr(b_addr) //写地址
);

my_ram  my_ram(
	.address_a(a_addr),
	.address_b(b_addr),
	.clock_a(a_clk),
	.clock_b(b_clk),
	.data_a(a_data),
	.data_b(),
	.wren_a(a_wren),
	.wren_b(b_wren),
	.q_a(a_q),
	.q_b(b_q)
);

endmodule

ram读写控制

module dram_ctrl(
	input					a_clk,
	input					b_clk,
	input					rst_n,
	
	output	reg    	a_wren,//写请求
	output	reg[9:0]	a_addr,//写地址
	output	reg[9:0]	a_data,//写数据
	
	output 	reg		b_wren,//写请求
	output	reg[9:0] b_addr //写地址
);

always@(posedge a_clk or negedge rst_n)
	if(!rst_n)
		begin
			a_wren<=0;
			a_addr<=10'd0;
			a_data<=10'd0;
		end
	else if(a_addr<10'd1023)
		begin
			a_wren<=1;
			a_addr<=a_addr+1'b1;
			a_data<=a_data+1'b1;
		end
	else
		begin
			a_wren<=0;
			a_addr<=a_addr;
			a_data<=a_data;
		end
//a端口写数据,b端口读数据,b端口写请求关闭,读出a端口的数据
always@(posedge b_clk or negedge rst_n)
	if(!rst_n)
		begin
			b_wren<=0;
			b_addr<=10'd0;
		end
	else
		begin
			b_addr<=b_addr+1;
		end
endmodule

仿真代码

`timescale 1ns/1ns
module dram_top_tb;
	reg					a_clk;
	reg					b_clk;
	reg					rst_n;
	
	wire    [9:0]		a_q;
	wire    [9:0]		b_q;

dram_top dram_top(
	.a_clk(a_clk),
	.b_clk(b_clk),
	.rst_n(rst_n),

	.a_q(a_q),
	.b_q(b_q)
);

initial a_clk=0;
always #10 a_clk=~a_clk;//以50mhz的时钟写入

initial b_clk=0;
always #40 b_clk=~b_clk;//以12.5mhz的时钟读取数据

initial begin
	rst_n=0;
	#200;
	rst_n=1;
end

endmodule

仿真结果

 

猜你喜欢

转载自blog.csdn.net/weixin_43533751/article/details/106979614