前言:sram顾名思义静态随机存储器,分为asram异步型和ssram同步型。这里驱动DE2上一块ISSI公司的512KB的asram。

  设计思路:因为实际应用中单字节读写效率不高,所以本设计中仿照sdram的页突发读写,提高sram的效率。因为sram不像sdram需要定期刷新以及行列地址复用,因此省却很多麻烦。拿到手册以后主要关注的就是其最快运行时钟以及数据稳定的建立时间和保持时间,以及控制线的时间参数,这些参数可以由datasheet的时序参数的min time和max time确定,通过这些参数可以简化后续的读写的时序图。

  注意事项:

      (a)在读操作中,读指令有效到数据有效输出有一个CLK的延迟,即latency;

      (b)为了避免读写操作过程中,数据与地址之间的时钟差,其中sys_data_o与sdram_data_r寄存器直接用latch建模,综合后出现的警告;

      (c)模块时钟工作在100MHz,移植过程中pll视情况而定,pll工作于normal模式即可l;

  总结:以上代码结果仿真和硬件测试,并未做超频测试。这里附出源码。

源码1:sram控制器

 `timescale  ns /  ps
`define SIM
`define IS61LV25616AL_10TL
`define SYS_CLK
`define BURST
`define BURST_WIDTH
module sram_ctrl(
sys_clk,
sys_rst_n,
//read
sys_rd_addr_i,
rreq_i,
sys_data_o,
sram_rd_ack_o,
sram_rd_valid_o,
//write
wreq_i,
sys_wr_addr_i,
sys_data_i,
sram_wr_valid_o,
sram_wr_ack_o,
//sram
sram_ce_n,
sram_oe_n,
sram_we_n,
sram_lb_n,
sram_ub_n,
sram_addr,
sram_data
);
`ifdef IS61LV25616AL_10TL
`define DSIZE
`define ASIZE
`endif
input sys_clk;
input sys_rst_n;
//read
input [`ASIZE-:] sys_rd_addr_i;
input rreq_i;
output [`DSIZE-:] sys_data_o;
output sram_rd_ack_o;
output sram_rd_valid_o;
//write
input [`ASIZE-:] sys_wr_addr_i;
input wreq_i;
input [`DSIZE-:] sys_data_i;
output sram_wr_ack_o;
output sram_wr_valid_o;
//sram
output sram_ce_n;
output sram_oe_n;
output sram_we_n;
output sram_lb_n;
output sram_ub_n;
output [`ASIZE-:] sram_addr;
inout [`DSIZE-:] sram_data;
//command
parameter CMD_NOP = 'b01000,
CMD_READ = 'b10000,
CMD_WRITE = 'b00100;
reg [:] cmd_r = CMD_NOP;
assign {sram_we_n,sram_ce_n,sram_oe_n,sram_lb_n,sram_ub_n} = cmd_r;
//FSM PARAMS
`ifdef SIM
parameter ST_WIDTH = ;
parameter IDLE = "IDLE.",
READ = "READ.",
RD = "RD...",
END = "END..",
WR = "WR...";
`else
`define FSM
parameter ST_WIDTH = ;
parameter IDLE = `FSM'b0_0001,
READ = `FSM'b0_0010,
RD = `FSM'b0_0100,
END = `FSM'b0_1000,
WR = `FSM'b1_0000;
`endif
//capture the posedge of rreq
reg rreq_r = ;
always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) rreq_r <= 0;
else rreq_r <= rreq_i;
end
wire do_rreq = rreq_i & ~rreq_r;
//generate the rd_start signal
reg rd_start = ;
always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) rd_start <= 0;
else if(sram_rd_ack_o == 'b1) rd_start <= 0;
else if(do_rreq) rd_start <= ;
else rd_start <= rd_start;
end
//capture the posedge of wreq
reg wreq_r = ;
always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) wreq_r <= 0;
else wreq_r <= wreq_i;
end
wire do_wreq = wreq_i & ~wreq_r;
//generate the rd_start signal
reg wr_start = ;
always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) wr_start <= 0;
else if(sram_wr_ack_o == 'b1) wr_start <= 0;
else if(do_wreq) wr_start <= ;
else wr_start <= wr_start;
end
//FSM register
reg [`BURST_WIDTH-:] bit_cnt = ;
reg [ST_WIDTH-:] c_st = IDLE;
reg [ST_WIDTH-:] n_st = IDLE;
reg link = ; //0:read while 1:write reg [`ASIZE-:] sram_addr = ;
//fsm-1
always @ (posedge sys_clk) begin
if('b0 == sys_rst_n) c_st <= IDLE;
else c_st <= n_st;
end
//fsm-2
always @ (*) begin
case(c_st)
IDLE:begin
if(rd_start == 'b1) begin
n_st = READ;end
else if(wr_start == 'b1) begin
n_st = WR;end
else begin
n_st = IDLE;end
end
READ:n_st = RD;
RD:n_st = (bit_cnt == `BURST)?END:RD;
END:n_st = IDLE;
WR:n_st = (bit_cnt == `BURST)?END:WR;
default:n_st = IDLE;
endcase
end
//fsm-3
always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) begin
bit_cnt <= ;
link <= ;
sram_addr <= `ASIZE'h3FFFF;
cmd_r <= CMD_NOP;
end
else begin
case(n_st)
IDLE:begin
bit_cnt <= ;
link <= ;
sram_addr <= sram_addr;
cmd_r <= CMD_NOP;
end
READ:begin
bit_cnt <= bit_cnt;
sram_addr <= sys_rd_addr_i;
link <=;
cmd_r <= CMD_READ;
end
RD:begin
bit_cnt <= (bit_cnt == `BURST)?`BURST_WIDTH'd0:bit_cnt + 1'd1;
link <= ;
sram_addr <= (bit_cnt == `BURST-)?sram_addr:sram_addr + 'd1;
cmd_r <= CMD_READ;
end
END:begin
bit_cnt <= ;
link <= ;
sram_addr <= sram_addr;
cmd_r <= CMD_NOP;
end
WR:begin
bit_cnt <= (bit_cnt == `BURST)?`BURST_WIDTH'd0:bit_cnt + 1'd1;
sram_addr <= (bit_cnt == `BURST)?sram_addr:sram_addr + 'd1;
link <=;
cmd_r <= CMD_WRITE;
end
default:begin
bit_cnt <= ;
link <= ;
sram_addr <= `ASIZE'h3FFFF;
cmd_r <= CMD_NOP;end
endcase
end
end
//generate sys_data_o
reg [`DSIZE-:] sys_data_o = ;
always @ (*) begin
if(c_st == RD) sys_data_o <= sram_data;
else sys_data_o <= sys_data_o;
end
//generate sram_data_r
reg [`DSIZE-:] sram_data_r = ;
always @ (*) begin
if(c_st == WR) sram_data_r <= sys_data_i;
else sram_data_r <= sram_data_r;
end
//assign
assign sram_data = (link == 'b1)?sram_data_r:16'hzzzz;
assign sram_rd_ack_o = ((c_st == END)&&(rd_start == 'b1))?1'b1:'b0;
assign sram_rd_valid_o = (c_st == RD)?'b1:1'b0;
assign sram_wr_ack_o = ((c_st == END)&&(wr_start == 'b1))?1'b1:'b0;
assign sram_wr_valid_o = (c_st == WR)?'b1:1'b0; endmodule

源码2:读驱动

 `timescale  ns /  ps
`define BURST
`define BURST_WIDTH
`define ASIZE
module sram_rd_driver(
sys_clk,
sys_rst_n,
key_n,
sram_rd_valid_i,
rreq_o,
sys_rd_addr_o
);
input sys_clk;
input sys_rst_n;
input key_n;
input sram_rd_valid_i;
output rreq_o;
output [`ASIZE-:] sys_rd_addr_o;
//generate the rreq_o
reg key_r = ;
reg rreq_o = ;
always @ (posedge sys_clk) begin
if('b0 == sys_rst_n) key_r <= 1;
else key_r <= key_n;
end wire rd_trigger = ~key_n & key_r;
always @ (posedge sys_clk) begin
if('b0 == sys_rst_n) rreq_o <= 0;
else if(rd_trigger) rreq_o <= ;
else rreq_o <= ;
end //generate the sys_rd_addr_o
reg [`ASIZE-:] sys_rd_addr_o = ;
always @ (posedge sys_clk) begin
if('b0 == sys_rst_n) sys_rd_addr_o <= 0;
else if(sram_rd_valid_i) sys_rd_addr_o <= sys_rd_addr_o + 'd1;
else sys_rd_addr_o <= sys_rd_addr_o;
end endmodule

源码3:写驱动

 `timescale  ns /  ps
`define BURST
`define BURST_WIDTH
`define ASIZE
`define DSIZE
module sram_wr_driver(
sys_clk,
sys_rst_n,
wr_key_n,
sram_wr_valid_i,
wreq_o,
sys_wr_addr_o,
sys_data_o
);
input sys_clk;
input sys_rst_n;
input wr_key_n;
input sram_wr_valid_i;
output wreq_o;
output [`ASIZE-:] sys_wr_addr_o;
output [`DSIZE-:] sys_data_o; //capture negedge of wr_key_n
reg wr_key_r = ;
always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) wr_key_r <= 1;
else wr_key_r <= wr_key_n;
end
//generate wreq_o
reg wreq_o = ;
wire wr_trigger = ~wr_key_n & wr_key_r;
always @ (posedge sys_clk) begin
if('b0 == sys_rst_n) wreq_o <= 0;
else if(wr_trigger) wreq_o <= ;
else wreq_o <= ;
end
//generate sys_data_o and sys_wr_addr_o
reg [`ASIZE-:] sys_wr_addr_o = ;
reg [`DSIZE-:] sys_data_o = ; always @ (posedge sys_clk) begin
if(sys_rst_n == 'b0) begin
sys_wr_addr_o <= ;
sys_data_o <= ;end
else if(sram_wr_valid_i) begin
sys_wr_addr_o <= sys_wr_addr_o + 'd1;
sys_data_o <= sys_data_o + 'd1;end
else begin
sys_wr_addr_o <= sys_wr_addr_o;
sys_data_o <= sys_data_o;end
end endmodule

源码4:顶层例化

 `timescale  ns /  ps
`define ASIZE
`define DSIZE
module sram(
sys_clk,
sys_rst_n,
key_n,
wr_key_n,
//sram
sram_ce_n,
sram_oe_n,
sram_we_n,
sram_lb_n,
sram_ub_n,
sram_data,
sram_addr
);
input sys_clk;
input sys_rst_n;
input key_n;
input wr_key_n;
//SRAM
output sram_ce_n;
output sram_oe_n;
output sram_we_n;
output sram_lb_n;
output sram_ub_n;
inout [`DSIZE-:] sram_data;
output [`ASIZE-:] sram_addr; wire rreq;
wire sram_rd_ack;
wire sram_rd_valid;
wire [`ASIZE-:] sys_rd_addr; //from driver module
wire [`DSIZE-:] sys_data_o; wire wreq;
wire sram_wr_ack;
wire sram_wr_valid;
wire [`ASIZE-:] sys_wr_addr;
wire [`DSIZE-:] sys_data_i; //for hardware wire sys_clk100;
pll100 pll100_inst (
.inclk0 ( sys_clk ),
.c0 ( sys_clk100 )
); sram_ctrl inst_sram_ctrl(
.sys_clk(sys_clk100),
.sys_rst_n(sys_rst_n),
//read
.sys_rd_addr_i(sys_rd_addr),
.rreq_i(rreq),
.sys_data_o(sys_data_o),
.sram_rd_ack_o(sram_rd_ack),
.sram_rd_valid_o(sram_rd_valid),
////write
.wreq_i(wreq),
.sys_wr_addr_i(sys_wr_addr),
.sys_data_i(sys_data_i),
.sram_wr_valid_o(sram_wr_valid),
.sram_wr_ack_o(sram_wr_ack),
//sram
.sram_ce_n(sram_ce_n),
.sram_oe_n(sram_oe_n),
.sram_we_n(sram_we_n),
.sram_lb_n(sram_lb_n),
.sram_ub_n(sram_ub_n),
.sram_addr(sram_addr),
.sram_data(sram_data)
); sram_wr_driver inst_sram_wr_driver(
.sys_clk(sys_clk100),
.sys_rst_n(sys_rst_n),
.wr_key_n(wr_key_n),
.sram_wr_valid_i(sram_wr_valid),
.wreq_o(wreq),
.sys_wr_addr_o(sys_wr_addr),
.sys_data_o(sys_data_i)
); sram_rd_driver inst_sram_rd_driver(
.sys_clk(sys_clk100),
.sys_rst_n(sys_rst_n),
.key_n(key_n),
.sram_rd_valid_i(sram_rd_valid),
.rreq_o(rreq),
.sys_rd_addr_o(sys_rd_addr)
); endmodule

异步SRAM控制器的Verilog建模的更多相关文章

  1. Norflash控制器的Verilog建模之一

    摘要:今天驱动一款SPANSION公司生产的norflash——S29AL032D70,没有别的参考资料,大致了解一下norflash的内部cmos电路架构以及其用途之后,直接看手册吧. 如何看手册: ...

  2. SDRAM控制器的Verilog建模之一

    前言:作为经典存储器的三剑客中的flash和sram已经建模测试过了,虽然现在都已经ddr2,ddr3,667MHZ.1333MHZ的天下了,但是接下这周来准备写一下sdram的controller. ...

  3. Norflash控制器的Verilog建模之二(仿真)

    前言:经过几天修改,norflash控制器基本已经完成,通过仿真.完整的norflash包含2个模块:直接操作硬件的norflash_ctrl.v与控制ctrl模块的驱动norflash_driver ...

  4. I2C控制器的Verilog建模之三(完结版)

    前言:终于到了测试篇,不过悲剧了一下.按照之前<二>里面的思路,在顶层用一个复用器驱动读写独立模块的I2C总线确实失败.虽然综合过去了,不过警告里已经说明:底层的2个原本是inout三态口 ...

  5. Norflash控制器的Verilog建模之三(測試)

    前言:回校了,辦好手續就著手寫測試篇.初步的norflash控制器已經完成,通過硬件測試.目前的norflash完成扇区块擦除.单字节写.单字节读3个功能.博文最后附上源码. 总结:和之前的博文一样, ...

  6. VGA逐行扫描控制器的Verilog建模

    前言:因为VGA是一种模拟图像传输数据接口,所要将数字信号用DAC转换成模拟量.本文用的一款ADI公司高精度的视频IC,实则一款高带宽的视频DAC.因为VGA时序较为简单,并且网上的VGA驱动基本大同 ...

  7. I2C控制器的Verilog建模之一

    前言:之前申请了ADI公司的一款ADV7181CBSTZ的视频解码芯片,正好原装DE2板子安的是同系列的ADV7181BBSTZ.虽然都是ADV7181的宗出,但是寄存器配置等等还是有些诧异,引脚也不 ...

  8. I2C控制器的Verilog建模之二

    前言:接着上一篇的I2C写操作,今天要实现一个I2C的读操作.虽然在ADV7181B配置内部寄存器时没有必要使用到读操作,但是为了进一步确认寄存器是否在I2C写模块下被正确配置,这一步是必不可少的. ...

  9. 高性能异步SRAM技术角度

    当前有两个不同系列的异步SRAM:快速SRAM(支持高速存取)和低功耗SRAM(低功耗).从技术角度看来,这种权衡是合理的.在低功耗SRAM中,通过采用特殊栅诱导漏极泄漏(GIDL)控制技术控制待机电 ...

随机推荐

  1. UITableView使用的一些技巧

    1.如果想自己在视图中加一条线,和UITableView的cell的分割线颜色粗细一样,那么可以: UIView *lineView = [[UIView alloc] initWithFrame:C ...

  2. jQueryMobile控件之ListView

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 2014年5月份第3周51Aspx源码发布详情

    HGM简单连连看游戏源码  2014-5-19 [VS2010]源码描述:这是一款基于WinForm窗体程序的简单水果连连看的小游戏.界面比较美观, 功能如下:该游戏可以显示当前关卡,还有剩余时间.重 ...

  4. 在VS下使用 GitFlow管理项目开发

    在VS下使用 GitFlow管理项目开发 1.右键将你的解决方案添加到源代码管理,如果你的VS没有安装git,会提示安装,安装完成之后,在团队资源管理可以看到如下界面 (图一) 2.安装gitflow ...

  5. 日常笔记 ---- 图形学-Frenel函数材质球实现方式

    图形学-Frenel函数材质球实现方式   调个材质 大概公式 自发光= 自定义边光颜色* ((1-法线与视角方向点乘)的 自定义幂次方 ) 这个是比较简单方法   模型的法线与视角方向 角度越大 表 ...

  6. apt-get命令详解

    apt-cache search # ------(package 搜索包) apt-cache show #------(package 获取包的相关信息,如说明.大小.版本等) sudo apt- ...

  7. linux命令:ln

    1.命令介绍: nl用来显示文件的行号并打印出来. 2.命令格式: nl [选项] 文件 3.命令参数: -b  :指定行号指定的方式,主要有两种: -b a :表示不论是否为空行,也同样列出行号(类 ...

  8. Sublime Text 配置

    Sublime Text 配置 1.键盘映射 映射成emacs的键盘方式: Preferences --> Key Bounding - user:然后复制如下配置信息(注意取消前缀“...-- ...

  9. uva 11582

    #include <iostream> #include <map> #include <cmath> #include <vector> #inclu ...

  10. async 函数学习笔记

    async函数就是Generator函数的语法糖. var fs = require('fs'); var readFile = function (fileName) { return new Pr ...