欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 【特权FPGA】之SRAM读写

【特权FPGA】之SRAM读写

2025/4/15 13:43:36 来源:https://blog.csdn.net/TommiWei/article/details/147126324  浏览:    关键词:【特权FPGA】之SRAM读写

1 前言

SRAM(静态随机存取存储器)是一种基于双稳态触发器设计的半导体存储器,通过电路自身的稳态特性存储数据,无需周期性刷新即可维持信息1。与DRAM(动态随机存取存储器)不同,SRAM在通电期间数据始终稳定,因此具有更高的访问速度和更低的延迟。

应用场景
  • CPU缓存:如L1/L2/L3缓存,利用SRAM的高速特性减少CPU与主存间的延迟1
  • 高速寄存器:用于存储处理器核心的临时数据,支持快速计算。
  • 嵌入式系统:在实时性要求高的场景(如网络设备、航天器)中作为关键存储器。
  • 低功耗设备:因静态特性,适合电池供电设备中需快速唤醒的场景。

说来也惭愧,自己十年前学的知识,十年后,由于自己的原因,有的要重头开始,再学一遍。不管是做项目也好,做学术也罢。知识永远都是相互贯通的。比如说当你拿到了一块芯片。你如果想要了解这款芯片,就要先看看他的datasheet。然后实现他的数字功能。

本文借助特权老师这座大山,简单浅显的给大家分享一下我对SRAM的理解。

我很想给大家免费分享下IS62LV256这款芯片的datasheet,但是我不知道该如何分享。似乎没有一个好的办法。这里就以本实验使用的 IS62LV256-70U 为例进行说明。

2 IS62LV256用户手册

功能框图

作为一名合格的硬件工程师,看datasheet往往是工作开展的第一步。

表1 SRAM管脚定义

具体在硬件连接的时候,其实很多人喜欢直接把输出使能信号 OEn 和片选信号 CEn 接地,这样一来不仅节省了处理器和 SRAM 连接的管脚数,而且在读写 SRAM的时候其实只要对写使能信号 WEn 操作就可以了,简化了代码部分。本设计的硬件原理图如下图所示。 

 因为在硬件上已经把 CEn 和 OEn 拉低了,所以在不进行写 SRAM 的时候,实际上 SRAM 的数据总线上的值是对应地址总线的数据。为了避免误操作,可以把地址总线置高阻态,如果不去操作数据总线(最好不是复用的数据总线)也无大碍。因为这样简化了设计。对于 SRAM 的操作时序,只要关心地址总线、数据总线和写使能 WEn 信号。

SRAM读时序

SRAM写时序

 表2 SRAM读写实验接口定义

该实验实现了对 SRAM 的每一个地址进行遍历读写操作,然后比对读写前后的数据是否正确,最后通过一个 LED 灯的亮灭进行指示。


3 整体代码

`timescale 1ns / 1psmodule sram_test(clk			,rst_n		,led			,sram_addr	,sram_wr_n	,sram_data);input 			clk		;			// 50MHz
input 			rst_n	;			// 低电平复位
output 			led		;			// LED1// CPLD与SRAM外部接口
output[14:0] 	sram_addr;		// SRAM地址总线
output 			sram_wr_n;		// SRAM写选通
inout[7:0] 		sram_data;		// SRAM数据总线reg[25:0] delay;				//延时计数器,控制LED灯的亮灭 always @ (posedge clk or negedge rst_n)if(!rst_n) delay <= 26'd0;else delay <= delay+1;	//不断计数,周期约为1.28sreg[7:0] 	wr_data				;			// SRAM写入数据总线	
reg[7:0] 	rd_data				;			// SRAM读出数据 
reg[14:0] 	addr_r				;			// SRAM地址总线
wire 		sram_wr_req			;			// SRAM写请求信号
wire 		sram_rd_req			;			// SRAM读请求信号
reg 		led_r				;			// LED寄存器assign sram_wr_req = (delay == 26'd9999);	//产生写请求信号
assign sram_rd_req = (delay == 26'd19999);	//产生读请求信号always @ (posedge clk or negedge rst_n)if(!rst_n) wr_data <= 8'd0;else if(delay == 26'd29999) wr_data <= wr_data+1'b1;	//写入数据每1.28s自增1always @ (posedge clk or negedge rst_n)if(!rst_n) addr_r <= 15'd0;else if(delay == 26'd29999) addr_r <= addr_r+1'b1;	//写入地址每1.28s自增1always @ (posedge clk or negedge rst_n)if(!rst_n) led_r <= 1'b0;else if(delay == 26'd20099) begin	//每1.28s比较一次同一地址写入和读出的数据if(wr_data == rd_data) led_r <= 1'b1;	//写入和读出数据一致,LED点亮else led_r <= 1'b0;						//写入和读出数据不同,LED熄灭end
assign led = led_r;`define	DELAY_80NS		(cnt==3'd7)reg[2:0] cnt;	//延时计数器always @ (posedge clk or negedge rst_n)if(!rst_n) cnt <= 3'd0;else if(cstate == IDLE) cnt <= 3'd0;else cnt <= cnt+1'b1;// 两段式状态机
parameter	IDLE	= 4'd0,WRT0	= 4'd1,WRT1	= 4'd2,REA0	= 4'd3,REA1	= 4'd4;reg[3:0] cstate,nstate;// 时序逻辑
always @ (posedge clk or negedge rst_n)if(!rst_n) cstate <= IDLE;else cstate <= nstate;// 组合逻辑
always @ (cstate or sram_wr_req or sram_rd_req or cnt)case (cstate)IDLE: if(sram_wr_req) nstate <= WRT0;		//进入写状态else if(sram_rd_req) nstate <= REA0;	//进入读状态else nstate <= IDLE;WRT0: if(`DELAY_80NS) nstate <= WRT1;else nstate <= WRT0;				//延时等待160ns	WRT1: nstate <= IDLE;			//写结束,返回REA0: if(`DELAY_80NS) nstate <= REA1;else nstate <= REA0;				//延时等待160nsREA1: nstate <= IDLE;			//读结束,返回default: nstate <= IDLE;endcase//-------------------------------------assign sram_addr = addr_r;	// SRAM地址总线连接//-------------------------------------			
reg sdlink;				// SRAM数据总线控制信号always @ (posedge clk or negedge rst_n)if(!rst_n) rd_data <= 8'd0;else if(cstate == REA1) rd_data <= sram_data;		//读出数据always @ (posedge clk or negedge rst_n)if(!rst_n) sdlink <=1'b0;  elsecase (cstate)IDLE: if(sram_wr_req) sdlink <= 1'b1;		//进入连续写状态,,sram内部寄存器接收数据else if(sram_rd_req) sdlink <= 1'b0;	//进入单字节读状态,SRAM输出--> FPGA,SRAM的输入接口是高阻else sdlink <= 1'b0;WRT0: sdlink <= 1'b1;default: sdlink <= 1'b0;endcaseassign sram_data = sdlink ? wr_data : 8'hzz;	// SRAM地址总线连接			
assign sram_wr_n = ~sdlink;endmodule

  • 写操作:当写使能/有效时,数据流向为CPU→SRAM,此时SRAM内部锁存器接收数据
assign sram_data = sdlink ? wr_data : 8'hzz;	// sdlink==1
  • 读操作:当输出使能/有效时,数据流向为SRAM→CPU,此时数据线呈现驱动状态
sram_data = sdlink ? wr_data : 8'hzz; //sdlink ==0

FPGA读取SRAM中的数据,SRAM的输入是高阻状态。

4 仿真代码

`timescale 1ns/1ns
module tb_sramtest();//input
reg clk;		// 50MHz
reg rst_n;	//低电平复位//output
wire led;		// LED1
wire[14:0] sram_addr;	// SRAM地址总线
wire sram_wr_n;		// SRAM写选通//inout
wire [7:0] sram_data;	// SRAM数据总线sram_test	sram_test(.clk(clk),.rst_n(rst_n),.led(led),.sram_addr(sram_addr),.sram_wr_n(sram_wr_n),.sram_data(sram_data));initial beginrst_n = 0;#200; rst_n = 1;
endinitial beginclk = 0;forever #10 clk = ~clk;
endendmodule

4 总结

这节内容使用了2段式的状态机。代码给人的直观感受就是很清晰明了。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词