赞
踩
之前一直没太搞懂这个SRAM 是用来做什么的,现在做完了vga的觉得这个SRAM的作用很大,说白了这就是个储存器,而在我vga的字符的读取显示中,难度最大的也是在存储器上,之前有人建议我在做的时候改用ram可以实现字符的动态显示而不是局限于自己独自开辟的显示区域,下面我就先从SRAM入手,好好的介绍下这几个存储器(最近更ROM RAM SRAM )
在有数据传输的地方就会有存储器
SRAM(static RAM):异步传输易失存储器
优点:读写传输迅速,控制时序不复杂(这里我用的特权的板子就直接把他们写的东西拿来用了)
找来任何一颗SRAM芯片的datasheet,会发现它们的时序操作大同小异,在这里总结一些它们共性的东西,也提一些用Verilog简单的快速操作SRAM的技巧。SRAM内部的结构如图所示,
1、要访问实际的Momory区域,FPGA必须送地址(A0-A14)和控制信号(CE \OE \WE ),
2、SRAM内部有与此对应的地址译码(decoder)
3、控制处理电路(control circuit)。
这样,数据总线(I/O0-I/O7)上的数据就可以相应的读或写了。
这里就以本实验使用的IS62LV256-45U为例进行说明。其管脚定义如表所示。
序号 | 管脚 | 方向 | 描述 |
1 | A0-A14 | Input | 地址总线。 |
2 | CEn | Input | 芯片使能输入,低有效。 |
3 | OEn | Input | 输出使能输入,低有效。 |
4 | WEn | Input | 写使能输入,低有效。 |
5 | I/O0-I/O7 | Inout | 数据输入/输出总线。 |
6 | VCC | Input | 电源。 |
7 | GND | Input | 数字地。 |
本设计的硬件原理图如图所示。
图6.59 SRAM接口
对于SRAM的读操作时序,其波形如图所示。
对于SRAM的写操作时序,其波形如图所示。
代码如下:
- module top(ext_clk_25m,ext_rst_n,led,
- sram_cs_n,sram_we_n,sram_oe_n,
- sram_data,sram_addr
- );
- input ext_clk_25m;
- input ext_rst_n;
- output led;
- output sram_cs_n;
- output sram_we_n;
- output sram_oe_n;
- output [14:0] sram_addr;
- inout [7:0] sram_data;
-
- wire clk_12m5;
- wire clk_25m;
- wire clk_50m;
- wire clk_65m;
- wire clk_108m;
- wire clk_130m;
- wire sys_rst_n;
-
- pll_controller uut_pll_controller
- (// Clock in ports
- .CLK_IN1(ext_clk_25m), // IN
- // Clock out ports
- .CLK_OUT1(clk_12m5), // OUT
- .CLK_OUT2(clk_25m), // OUT
- .CLK_OUT3(clk_50m), // OUT
- .CLK_OUT4(clk_65m), // OUT
- .CLK_OUT5(clk_108m), // OUT
- .CLK_OUT6(clk_130m), // OUT
- // Status and control signals
- .RESET(~ext_rst_n),// IN
- .LOCKED(sys_rst_n)
- );
-
- //定时写sram测试模块
- wire sramwr_req;
- wire sramrd_req;
- wire [7:0] sramwr_data;
- wire [7:0] sramrd_data;
- wire [14:0] sramwr_addr;
- wire [14:0] sramrd_addr;
- test_timing uut_test_timing(
- .clk(clk_50m),
- .rst_n(sys_rst_n),
- .led(led),
- .sramwr_req(sramwr_req),
- .sramrd_req(sramrd_req),
- .sramwr_data(sramwr_data),
- .sramrd_data(sramrd_data),
- .sramwr_addr(sramwr_addr),
- .sramrd_addr(sramrd_addr)
- );
- //sram基本读写模块
- sram_controller uut_sram_controller(
- .clk(clk_50m),
- .rst_n(sys_rst_n),
- .sramwr_req(sramwr_req),
- .sramrd_req(sramrd_req),
- .sramwr_data(sramwr_data),
- .sramrd_data(sramrd_data),
- .sramwr_addr(sramwr_addr),
- .sramrd_addr(sramrd_addr),
- .sram_cs_n(sram_cs_n),
- .sram_we_n(sram_we_n),
- .sram_oe_n(sram_oe_n),
- .sram_addr(sram_addr),
- .sram_data(sram_data)
- );
- endmodule
- module test_timing(clk,rst_n,led,sramwr_req,sramrd_req,sramwr_data,sramrd_data,sramwr_addr,sramrd_addr
- );
- input clk;//输入时钟
- input rst_n;//复位信号
- output reg led;//LED指示灯
- output sramwr_req ;//SRAM写请求信号,高电位有效,用于状态机控制
- output sramrd_req ;//SRAM读请求信号,高电位有效,用于状态机控制
- output reg [7:0] sramwr_data;//SRAM写入数据寄存器
- input [7:0] sramrd_data;//SRAM读出数据寄存器
- output reg [14:0]sramwr_addr;//SRAM写入地址寄存器
- output reg [14:0]sramrd_addr;//SRAM读取地址寄存器
-
- //一秒定时
-
- reg[25:0] delay;
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- delay<=1'b0;
- end
- else if(delay<26'd49_999_999)begin
- delay<=delay+1'b1;
- end
- else begin
- delay<=1'b0;
- end
- end
- assign sramwr_req =(delay==26'd1000);
- assign sramrd_req =(delay==26'd1100);
- //定时写入数据寄存器
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sramwr_data<=8'd0;
- end
- else if(delay==26'd4000)begin
- sramwr_data<=sramrd_data+1'b1;
- end
- end
- //定时SRAM读和写地址寄存器
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sramwr_addr<=1'b0;
- end
- else if(delay==26'd4000)begin
- sramwr_addr<=sramwr_addr+1'b1;
- end
- end
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sramrd_addr<=1'b0;
- end
- else if(delay==26'd4000)begin
- sramrd_addr<=sramrd_addr+1'b1;
- end
- end
- //比较数据
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- led<=1'b1;
- end
- else if(delay==26'd3000)begin
- if(sramrd_data==sramwr_data)begin
- led<=1'b0;
- end
- else begin
- led<=1'b1;
- end
- end
- end
-
-
- endmodule
- module sram_controller(clk,rst_n,
- sramwr_req,sramrd_req,sramwr_data,sramrd_data,sramwr_addr,sramrd_addr,
- sram_cs_n,sram_we_n,sram_oe_n,sram_addr,sram_data
- );
- input clk;
- input rst_n;
- //读写控制信号
- input sramwr_req;//SRAM写请求信号,高电位有效,用于状态机控制
- input sramrd_req;//SRAM读请求信号,高电位有效,用于状态机控制
- input [7:0] sramwr_data;//SRAM写入数据寄存器
- output reg [7:0]sramrd_data;//SRAM读出数据寄存器
- input [14:0] sramwr_addr;//SRAM写入地址寄存器
- input [14:0] sramrd_addr;//SRAM读取地址寄存器
- //FPGA与芯片的接口信号
- output reg sram_cs_n;//SRAM片选信号
- output reg sram_we_n;//SRAM写入信号
- output reg sram_oe_n;//SRAM输出选通信号
- output reg [14:0] sram_addr;//地址总线
- inout [7:0] sram_data;//数据总线
- `define DELAY_00NS (cnt==3'd0)
- `define DELAY_20NS (cnt==3'd1)
- `define DELAY_40NS (cnt==3'd2)
- `define DELAY_60NS (cnt==3'd3)
- parameter IDLE = 4'd0,
- WRT0 = 4'd1,
- WRT1 = 4'd2,
- REA0 = 4'd3,
- REA1 = 4'd4;
- reg [3:0]state_c;
- reg [3:0]state_n;
- reg [2:0] cnt;
- //延时计数器
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- cnt<=1'b0;
- end
- else if(state_c==IDLE)begin
- cnt<=1'b0;
- end
- else begin
- cnt<=cnt+1'b1;
- end
- end
-
- //SRAM读写状态机
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- state_c<=IDLE;
- end
- else begin
- state_c<=state_n;
- end
- end
- always@(state_c or sramwr_req or sramrd_req or cnt)begin
- case(state_c)
- IDLE:if(sramwr_req==1'b1)begin
- state_n<=WRT0;
- end
- else if(sramrd_req==1'b1)begin
- state_n<=REA0;
- end
- else begin
- state_n<=IDLE;
- end
- WRT0:if(`DELAY_60NS)begin
- state_n<=WRT1;
- end
- else begin
- state_n<=WRT0;
- end
- WRT1:state_n<=IDLE;
- REA0:if(`DELAY_60NS)begin
- state_n<=REA1;
- end
- else begin
- state_n<=REA0;
- end
- REA1:state_n<=IDLE;
- default:state_n<=IDLE;
- endcase
- end
- //地址赋值
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sram_addr<=15'd0;
- end
- else if(state_c==WRT0)begin
- sram_addr<=sramwr_addr;
- end
- else if(state_c==WRT1)begin
- sram_addr<=15'd0;
- end
- else if(state_c==REA0)begin
- sram_addr<=sramrd_addr;
- end
- else if(state_c==REA1)begin
- sram_addr<=15'd0;
- end
- end
- reg sdlink;
- //SRAM读写控制
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sramrd_data<=8'd0;
- end
- else if((state_c==REA0)&&`DELAY_60NS)begin
- sramrd_data<=sram_data;
- end
- end
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sdlink<=1'b0;
- end
- else if(state_c==WRT0)begin
- sdlink<=1'b1;
- end
- else if(state_c==WRT1)begin
- sdlink<=1'b0;
- end
- end
- assign sram_data = sdlink?sramwr_data:8'hzz;
- //SRAM片选控制
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sram_cs_n<=1'b1;
- end
- else if(state_c==WRT0)begin
- if(`DELAY_00NS)begin
- sram_cs_n<=1'b1;
- end
- else begin
- sram_cs_n<=1'b0;
- end
- end
- else if(state_c==REA0)begin
- sram_cs_n<=1'b0;
- end
- else begin
- sram_cs_n<=1'b1;
- end
- end
- //读选通控制
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sram_oe_n<=1'b1;
- end
- else if(state_c==REA0)begin
- sram_oe_n<=1'b0;
- end
- else begin
- sram_oe_n<=1'b1;
- end
- end
-
- //写选通控制
- always@(posedge clk or negedge rst_n)begin
- if(rst_n==1'b0)begin
- sram_we_n<=1'b1;
- end
- else if(state_c==WRT0)begin
- if(`DELAY_20NS)begin
- sram_we_n<=1'b0;
- end
- else if(`DELAY_60NS)begin
- sram_we_n<=1'b1;
- end
- end
- end
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。