前言: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. 当BPM业务流程管理遇上制造业

    2015年5月,K2正式与赛科利签约,准备上线核心采购类流程,包括PR.PO.Payment.供应商管理等. 上海赛科利汽车模具技术应用有限公司隶属于上汽集团,现有员工2300余人.为解决汽车“安全” ...

  2. web前端基础篇③

    1.video视频 audio音频 controls出现控件 loop循环 autoplay自动播放例:<video/audio src=“地址” controls=“controls” loo ...

  3. java SE 常用的排序算法

    java程序员会用到的经典排序算法实现 常用的排序算法(以下代码包含的)有以下五类: A.插入排序(直接插入排序.希尔排序) B.交换排序(冒泡排序.快速排序) C.选择排序(直接选择排序.堆排序) ...

  4. GridView控件中加自动排列序号

    GridView控件中加自动排列序号 为 Gridview 增加一个新的空白列,如下: <asp:BoundField  HeaderText="序号">    < ...

  5. UIlabel 属性text

    UILabel *pLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,100,200,100)]; pLabel.text = @"测试 ...

  6. 黑马程序员——【Java基础】——正则表达式

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 1. 概念:符合一定规则的表达式. 2. 作用:用于专门操作字符串. 3. 特点:用一些特定的符 ...

  7. [Algorithm Basics] Sorting, LinkedList

    Time complexity: Binary search O(log2 n): i=0.   n elements:         ------------------- i=1.   n/2 ...

  8. C#代码示例_调试

    调试信息 可使用如下两个命令输出调试信息: l Debug.WriteLine() l Trace.WriteLine() 这两个命令函数的用法几乎完全相同,但有一个重要区别.第一个命令仅在调试模式下 ...

  9. Node.js高级编程读书笔记 - 6 应用程序构建和调试 - Never

    Explanation 现阶段console.log(...),util.inspect(...), JSON.stringify(...)在控制台输出已经够用了[2015/07/19]. 单元测试隶 ...

  10. frame和bounds区别

    学习ios开发有一段时间了,项目也做了两个了,今天看视频,突然发现view的frame和bound两个属性,发现bound怎么也想不明白,好像饶你了死胡同里,经过一番尝试和思考,终于弄明白bound的 ...