项目名称
双口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)begina_wren<=0;a_addr<=10'd0;a_data<=10'd0;endelse if(a_addr<10'd1023)begina_wren<=1;a_addr<=a_addr+1'b1;a_data<=a_data+1'b1;endelsebegina_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)beginb_wren<=0;b_addr<=10'd0;endelsebeginb_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 beginrst_n=0;#200;rst_n=1;
endendmodule
仿真结果