项目名称
双口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
仿真结果