【3.4】双口RAM模块的FPGA实现

目录

1.引言

2.双口RAM的FPGA实现原理

3.子模块RAM2x256C的verilog实现

步骤1:端口与参数定义

步骤2:分区信号同步寄存

步骤3:双模式硬件实现

4.双口RAM顶层模块的verilog实现


1.引言

256点FFT设计时的双口RAM模块,其核心功能是实现数据的乒乓缓冲、并行读写、地址逆序重排,解决FFT运算中数据输入、缓存、输出的时序冲突问题。这个模块支持10位位宽的实部DR和虚部DI数据并行存储,内置256深度的双分区RAM。

2.双口RAM的FPGA实现原理

模块将512深度的RAM划分为两个256深度的子分区,通过最高位地址控制分区切换:一个分区用于写入新数据,另一个分区用于读取旧数据,实现读写完全并行,无数据冲突,满足实时信号处理的流水线需求。

其中:

**地址逆序映射原理:**输出地址采用4位比特位逆序(addr[3:0]与addr[7:4]交换),这是FFT算法的核心要求------FFT运算需要输入数据按位逆序排列,模块内置地址逆序逻辑,无需外部电路处理,简化系统设计。

**同步时序控制原理:**所有操作基于时钟上升沿同步,包含复位、启动、使能三级控制,内置地址计数器和就绪计数器,自动完成256点数据的缓存与输出,输出信号标记数据处理完成。

**双配置兼容原理:**子模块RAM2x256C支持单端口RAM和双端口RAM两种硬件实现,兼容不同FPGA器件的RAM资源,提升工程移植性。

3.子模块RAM2x256C的verilog实现

我们首先给出这个模块的整体程序,然后再介绍下其具体的实现过程:

复制代码
// DESCRIPTION	:	2-port RAM

`timescale 1 ns / 1 ps
  

module RAM2x256C( 
                 CLK,
					  ED,
					  WE,
					  ODD,
					  ADDRW,
					  ADDRR,
					  DR,
					  DI,
					  DOR,
					  DOI);
					  
	parameter nb=10;	
	
	
	output [nb-1:0] DOR ;
	wire [nb-1:0] DOR ;
	output [nb-1:0] DOI ;
	wire [nb-1:0] DOI ;
	input CLK ;
	wire CLK ;
	input ED ;
	wire ED ;
	input WE ;	     //write enable
	wire WE ;
	input ODD ;	  // RAM part switshing
	wire ODD ;
	input [7:0] ADDRW ;
	wire [7:0] ADDRW ;
	input [7:0] ADDRR ;
	wire [7:0] ADDRR ;
	input [nb-1:0] DR ;
	wire [nb-1:0] DR ;
	input [nb-1:0] DI ;
	wire [nb-1:0] DI ;	
	
	reg	oddd,odd2;
	always @( posedge CLK) begin //switch which reswiches the RAM parts
			if (ED)	begin
					oddd<=ODD;
					odd2<=oddd;
				end
		end 
	`ifdef 	FFT256bufferports1
	//One-port RAMs are used
	wire we0,we1;
	wire	[nb-1:0] dor0,dor1,doi0,doi1;
	wire	[7:0] addr0,addr1;		   
	
	
	
	assign	addr0 =ODD?  ADDRW: ADDRR;		//MUXA0
	assign	addr1 = ~ODD? ADDRW:ADDRR;	// MUXA1
	assign	we0   =ODD?  WE: 0;		     // MUXW0: 
	assign	we1   =~ODD? WE: 0;			 // MUXW1:
	
	//1-st half - write when odd=1	 read when odd=0
	RAM256 #(nb) URAM0(.CLK(CLK),.ED(ED),.WE(we0), .ADDR(addr0),.DI(DR),.DO(dor0)); // 
	RAM256 #(nb) URAM1(.CLK(CLK),.ED(ED),.WE(we0), .ADDR(addr0),.DI(DI),.DO(doi0));	 
	
	//2-d half
	RAM256 #(nb) URAM2(.CLK(CLK),.ED(ED),.WE(we1), .ADDR(addr1),.DI(DR),.DO(dor1));//	  
	RAM256 #(nb) URAM3(.CLK(CLK),.ED(ED),.WE(we1), .ADDR(addr1),.DI(DI),.DO(doi1));		
	
	assign	DOR=~odd2? dor0 : dor1;		 // MUXDR: 
	assign	DOI=~odd2? doi0 : doi1;	//  MUXDI:
	
	`else 		
	//Two-port RAM is used
	wire [8:0] addrr2 = {ODD,ADDRR};
	wire [8:0] addrw2 = {~ODD,ADDRW};
	wire [2*nb-1:0] di= {DR,DI} ;	

	//wire [2*nb-1:0] doi;	
	reg [2*nb-1:0] doi;	
	
	reg [2*nb-1:0] ram [511:0];
	reg [8:0] read_addra;
	always @(posedge CLK) begin
			if (ED)
				begin
					if (WE)
						ram[addrw2] <= di;
					read_addra <= addrr2;	
				   doi = ram[read_addra];			
				end
		end
	//assign 	 
	
	assign	DOR=doi[2*nb-1:nb];		 // Real read data 
	assign	DOI=doi[nb-1:0];		 // Imaginary read data
	
	
	`endif 	
endmodule

上述程序实现的是实际的存储单元,支持双配置模式,实现并行读写、分区切换、数据输出,实现步骤如下:

步骤1:端口与参数定义

输出端口:

RDY:就绪标志,高电平表示256点数据缓存完成,可读取;

DOR:实部数据输出;

DOI:虚部数据输出;

输入端口:

CLK:系统时钟;

RST:高电平同步复位;

ED:数据使能信号(高电平有效,触发读写操作);

START:启动信号(高电平初始化缓存);

DR:实部数据输入;

DI:虚部数据输入。

步骤2:分区信号同步寄存

通过oddd和odd2两个寄存器,对分区信号ODD进行两级同步寄存,保证跨时钟域数据稳定,避免亚稳态,最终odd2用于输出数据选择。

步骤3:双模式硬件实现

模块通过宏定义,支持两种RAM实现方式:

模式1:单端口RAM模式(宏定义开启)

适用于不支持双端口RAM的低端FPGA,用4个256深度单端口RAM实现乒乓缓冲:

地址多路选择:根据ODD信号,将写地址/读地址分配给两个RAM分区;

写使能多路选择:一个分区写入时,另一个分区禁止写入;

数据输出选择:根据同步后的odd2信号,选择对应分区的实部/虚部数据输出。

模式2:双端口RAM模式(默认模式)

适用于主流FPGA,使用1个512深度双端口RAM,硬件资源更高效:

地址拼接:将分区信号与读写地址拼接为9位地址(512深度);

数据拼接:将实部(DR)和虚部(DI)拼接为20位数据并行存储;

同步读写:时钟上升沿触发,写使能有效时写入数据,同时寄存读地址,输出对应数据;

数据拆分:将读取的20位数据拆分为实部(DOR)和虚部(DOI)输出。

4.双口RAM顶层模块的verilog实现

该模块是整个缓存的控制核心,负责地址生成、计数器管理、就绪信号输出、子模块调用,其整体的verilog程序如下:

复制代码
//FPGA/MATLAB/simulink仿真工作室
//微信公众号:matworld
`timescale 1 ns / 1 ps
  
module BUFRAM256C ( CLK ,RST ,ED ,START ,DR ,DI ,RDY ,DOR ,DOI );
	parameter nb=10;
	output RDY ;
	reg RDY ;
	output [nb-1:0] DOR ;
	wire [nb-1:0] DOR ;
	output [nb-1:0] DOI ;
	wire [nb-1:0] DOI ;
	
	input CLK ;
	wire CLK ;
	input RST ;
	wire RST ;
	input ED ;
	wire ED ;
	input START ;
	wire START ;
	input [nb-1:0] DR ;
	wire [nb-1:0] DR ;
	input [nb-1:0] DI ;
	wire [nb-1:0] DI ;
	
	wire odd, we;
	wire [7:0] addrw,addrr;
	reg [8:0] addr;
	reg [9:0] ct2;		//counter for the RDY signal		 		  
	
	always @(posedge CLK)	//   CTADDR
		begin
			if (RST) begin
					addr<=8'b0000_0000;
					ct2<= 9'b10000_0001;  
				RDY<=1'b0; end
			else if (START) begin 
					addr<=8'b0000_0000;
					ct2<= 8'b0000_0000;  
				RDY<=1'b0;end
			else if (ED)	begin
				RDY<=1'b0;
					addr<=addr+1; 
					if (ct2!=257) 
					ct2<=ct2+1;
					if (ct2==256) 
					 RDY<=1'b1;
				end 
		end
			
	
assign	addrw=	addr[7:0];
assign	odd=addr[8];	   			// signal which switches the 2 parts of the buffer
assign	addrr={addr[3 : 0], addr[7 : 4]};	  // 16-th inverse output address
assign	we = ED;	  
	
	RAM2x256C #(nb)	URAM(.CLK(CLK),.ED(ED),.WE(we),.ODD(odd),
	.ADDRW(addrw),	.ADDRR(addrr),
	.DR(DR),.DI(DI),
	.DOR(DOR),	.DOI(DOI));	   
	
endmodule

上述程序中:

输出端口:

RDY:就绪标志,高电平表示256点数据缓存完成,可读取;

DOR:实部数据输出;

DOI:虚部数据输出;

输入端口:

CLK:系统时钟;

RST:高电平同步复位;

ED:数据使能信号(高电平有效,触发读写操作);

START:启动信号(高电平初始化缓存);

DR:实部数据输入;

DI:虚部数据输入。

上述verilog程序中:

addr[8:0]:9位地址寄存器,低8位为读写地址,最高位为分区切换信号(odd);

ct2[9:0]:10位计数器,用于生成RDY就绪信号;

addrw:写地址(8位);

addrr:读地址(8位,逆序映射);

we:写使能信号,直接映射ED信号。

程序分三种工作状态:

复位状态(RST=1)

地址寄存器addr清零,计数器ct2初始化为 9'b10000_0001,RDY 信号拉低,模块进入初始待机状态。

启动状态(START=1)

地址清零,计数器ct2清零,RDY拉低,模块开始准备接收256点数据。

数据使能状态(ED=1)

RDY拉低,地址自动加1;计数器ct2自增(最大257);

当ct2=256时,RDY拉高,标记256点数据缓存完成。

通过上述过程,在连续输入256个数据后,自动输出就绪信号,通知外部电路读取数据。

然后调用子模块RAM2x256C,将时钟、使能、写使能、分区信号、读写地址、输入输出数据全部传递给子模块,完成数据的实际存储与读取。

整个双口RAM存储模块的RTL结构图如下图所示:

相关推荐
三万棵雪松3 小时前
【嵌入式刷题硬件设计基础(一)】
fpga开发·嵌入式·硬件基础
扣脑壳的FPGAer3 小时前
Xilinx远程更新之watchdog Timer1/ Timer2
fpga开发
ALINX技术博客3 小时前
【黑金云课堂】FPGA技术教程Linux开发:Petalinux安装
linux·运维·fpga开发
豆包公子17 小时前
虚拟机配置共享文件&烧录FPGA bit文件
fpga开发
c-u-r-ry3019 小时前
pll/mmcm输入时钟配置页面警告
经验分享·fpga开发
逻辑诗篇21 小时前
硬核算力集结!TMS320C6678、XC7K690T等、匠行科技SBC819模拟信号采集处理板,解锁高端测控新标杆
科技·fpga开发
狂奔蜗牛(bradley)1 天前
FPGA基础知识:深度剖析异步复位同步释放
fpga开发
发发就是发1 天前
USB系统架构概述:从一次诡异的枚举失败说起
驱动开发·单片机·嵌入式硬件·算法·fpga开发
Shang180989357262 天前
T31ZX 君正/INGENIC智能视频处理器T31ZX可提供软硬件资料T31Z采用先进的低功耗设计
嵌入式硬件·fpga开发·音视频·t31zx智能视频处理器