双口ram读写

本文详细介绍了一种基于Verilog的双口RAM设计方法,包括代码实现与仿真验证。设计中,A端口用于写入0到1023的数据,而B端口则负责读取这些数据,两端口时钟频率相同,仿真采用50MHz写入、12.5MHz读取。双端口RAM允许同时读写操作,提高了数据处理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目名称

双口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

仿真结果

 

### 双口RAM读写时序及相关技术细节 #### 一、双口RAM的工作原理 双口RAM是一种具有两个独立端口的存储器结构,允许同时通过这两个端口进行访问。它分为两种类型:真双口RAM和伪双口RAM。 - **真双口RAM**支持在同一时刻既可以从A端口读取数据也可以从B端口写入数据,或者反之亦然[^1]。 - **伪双口RAM**则通常在一个时钟周期内仅能完成单一操作(即要么只读,要么只写),但在逻辑设计上模拟了双端口的行为[^2]。 #### 二、双口RAM读写时序图解析 以下是典型的双口RAM读写时序描述: 1. **时钟信号 (Clock)** 所有操作都由全局时钟控制,在每一个上升沿触发相应的动作。测试平台中的`always#(`clk_period/2)`语句定义了一个周期为20ns的理想化时钟波形[^2]。 2. **写入过程** - 当`wren`信号被置高电平时表示当前处于写状态; - 数据总线上的值会被存放到指定地址位置处; - 写入延迟一般较小,具体取决于硬件实现方式以及工艺条件等因素[^1]。 3. **读取过程** - 如果某一时段内未设置任何写请求,则默认执行的是读命令; - 用户只需提供有效的读指针即可获得对应单元内的数值; - 需要注意的是某些架构下可能存在透明模式下的特殊行为。 ```verilog initial begin data = 8'd0; rdaddress = 8'd30; wraddress = 8'd0; wren = 1'b0; #(CLK_PERIOD * 20 + 1'b1); for(i = 0; i <= 15; i = i + 1'b1) begin // Write loop wren = 1'b1; data = 255 - i; // Input data sequence wraddress = i; // Target write address #(CLK_PERIOD); end wren = 1'b0; #(CLK_PERIOD * 20); for(i = 0; i <= 15; i = i + 1'b1) begin // Read loop rdaddress = i; // Source read address #(CLK_PERIOD); end #(CLK_PERIOD * 20); $stop(); end ``` 以上代码片段展示了如何利用Verilog HDL构建一个基本的功能仿真环境来验证DPRAM模块的核心特性。 #### 三、关键技术点分析 - **并发能力**: 理论上讲只要两路通道之间不存在冲突就可以并行运作从而提高吞吐量[^1]. - **仲裁机制**: 对于那些可能引起竞争状况的情况比如同一瞬间试图向同一个物理内存块发起相互排斥的操作时候就需要额外加入判断逻辑予以协调处理. ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值