加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

FPGA笔记5:基于SRAM读写实验

(2015-12-19 12:40:36)
标签:

fpga

veriloghdl

分类: FPGA学习笔记

SRAM管脚分配:
A0-A14     地址输入                           I/O0-I/O7         数据输入、输出口         
CEn           芯片使能输入,低有效     OEn                  芯片使能输出,低有效
WEn          写使能输入,低有效       VCC    电源         GND   数字地
为节约管脚资源,可以将使能输入CEn和使能输出OEn接地,直接控制写使能WEn 来操作SRAM的读写。
图2 SRAM读时序
图3 SRAM写时序
       在写数据时,比较高效率的操作是送数据和地址,同时将WEn置低。然后延时twc(write cycle time,datasheet中规定至少70ns,实验中是20ns*8),再将WEn置高,这时数据写入相应地址;在读取数据时,将地址放到SRAM地址总线上,然后延时tAA(address access time,datasheet中规定至少70ns,实验中是20ns*8)时间后就读出数据。


本实验功能:对SRAM进行遍历式读写,若读写数据一致,指示灯亮;若不一致,指示灯灭
module  sram(clk,rst_n,led, address,write_en,data);
input clk,rst_n;
output led;//指示灯,灯亮:读写正确;灯灭:读写数据不一致
output[14:0] address;//SRAM地址
output write_en;//写使能,低电平有效
inout[7:0] data;//SRAM数据

reg[25:0] delay; //完成一次读写操作为1.28s
always @ (posedge clk or negedge rst_n)
if(!rst_n) delay <= 26'd0;
else delay <= delay+1;

wire write;//产生写请求
wire read;//产生读请求
assign write=(delay==26'd9999);//0.2ms写数据
assign read=(delay==26'd19999);//再隔0.2ms读数据

reg [7:0]write_data;//写入数据
always @ (posedge clk or negedge rst_n)//更新下一次的数据
if(!rst_n) write_data <= 8'd0;
else if(delay == 26'd29999) write_data <= write_data+1'b1;

reg [14:0]addr_r;//数据地址
always @ (posedge clk or negedge rst_n)
if(!rst_n) addr_r <= 15'd0;
else if(delay == 26'd29999) addr_r <= addr_r+1'b1; //更新下一次数据地址

reg [7:0]read_data;//读取数据
reg led_r;
always @ (posedge clk or negedge rst_n)
if(!rst_n) led_r <= 1'b0;
else if(delay == 26'd29999) begin
      if(read_data==write_data)led_r <= 1'b1;//数据读写一致,亮灯
else led_r <= 1'b0;//数据读写不一致,灭灯
end
assign led=led_r;

parameter IDLE = 4'd0;
parameter WRT0 = 4'd1;
parameter WRT1 = 4'd2;
parameter REA0 = 4'd3;
parameter REA1 = 4'd4;

reg[3:0] cstate,nstate;

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;//读写操作均不为零
`define DELAY_160 (cnt==3'd7)//延时20ns*8 完成一次读(写)数据

//两段式状态机写法
always @ (posedge clk or negedge rst_n)
if(!rst_n) cstate <= IDLE;
else cstate <= nstate;

always @ (cstate or write or read or cnt)
case (cstate)
   IDLE:if(write) nstate<=WRT0;//写请求有效
    else if(read)nstate<=REA0;//读请求有效
 else nstate<=IDLE;
   WRT0:if(`DELAY_160)nstate<=WRT1;
    else nstate<=WRT0;
WRT1:nstate<=IDLE;
REA0:if(`DELAY_160)nstate<=REA1;
    else nstate<=REA0;
REA1:nstate<=IDLE;
default:nstate<=IDLE;
endcase
assign address=addr_r; //SRAM 地址

always @ (posedge clk or negedge rst_n)
if(!rst_n) read_data <= 8'd0;
else if(cstate == REA1) read_data <=data;

reg link;//数据线data双向口控制寄存器,连接=1 ,断开=0,处于高阻状态;
always @ (posedge clk or negedge rst_n)
if(!rst_n) link <=1'b0;
else
case (cstate)
IDLE: if(write) link <= 1'b1; //
 else if(read) link <= 1'b0; //
 else link <= 1'b0;
WRT0: link <= 1'b1;
default: link <= 1'b0;
endcase
assign data = link ? write_data : 8'bzz; // 向SRAM写入数据
assign  write_en= ~link;

endmodule

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有