sdram控制2
芯片手册要求sdram需要在64ms内刷新8K次,否则里面的数据会丢失,因此在64ms分成8192次,每次刷新充一次电,然后给两次自动刷新命令即可。
/*----------------------------------------------------------------------- Date : 2017-08-29
Description : Design for auto refresh. -----------------------------------------------------------------------*/ module sdram_afreh
(
//global clock
input clk, //system clock
input rst_n, //sync reset //init interface
input flag_init_end, //auto_freh interface
input ref_en,
output reg ref_req,
output reg flag_ref_end, //sdram interface
output reg [:] aref_cmd,
output reg [:] aref_addr
// output [1:0] aref_bank ); //--------------------------------
//Funtion :
parameter CMD_END = 'd10,
DELAY_7US = 'd350,
NOP = 'b0111,
PRECHARGE = 'b0010,
AREF = 'b0001; reg [:] cnt_7us;
reg flag_ref; //处于自刷新阶段标志
reg flag_start; //自刷新启动标志
reg [:] cnt_cmd; //--------------------------------
//Funtion : flag_start always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
flag_start <= 'd0;
else if(flag_init_end)
flag_start <= 'd1;
end //--------------------------------
//Funtion : 7us always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_7us <= 'd0;
else if(cnt_7us == DELAY_7US)
cnt_7us <= 'd0;
else if(flag_start)
cnt_7us <= cnt_7us + 'b1;
end //--------------------------------
//Funtion : flag_ref always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
flag_ref <= 'd0;
else if(cnt_cmd == CMD_END)
flag_ref <= 'd0;
else if(ref_en)
flag_ref <= 'd1;
end //--------------------------------
//Funtion : cnt_cmd always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_cmd <= 'd0;
else if(flag_ref)
cnt_cmd <= cnt_cmd + 'b1;
else
cnt_cmd <= 'd0;
end //--------------------------------
//Funtion : flag_ref_end always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
flag_ref_end <= 'd0;
else if(cnt_cmd == CMD_END)
flag_ref_end <= 'd1;
else
flag_ref_end <= 'd0;
end //--------------------------------
//Funtion : cmd_reg always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
aref_cmd <= NOP;
else case(cnt_cmd)
'd0 :
begin
if(flag_ref)
aref_cmd <= PRECHARGE;
else
aref_cmd <= NOP;
end 'd1 :
begin
aref_cmd <= AREF;
end 'd5 :
begin
aref_cmd <= AREF;
end default :
aref_cmd <= NOP; endcase
end //--------------------------------
//Funtion : sdram_addr always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
aref_addr <= 'd0;
else case(cnt_cmd) 'd0 :
begin
if(flag_ref)
aref_addr <= 'b0_0100_0000_0000;
else
aref_addr <= 'd0;
end default : aref_addr <= 'd0;
endcase
end //--------------------------------
//Funtion : ref_req always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
ref_req <= 'b0;
else if(ref_en)
ref_req <= 'd0;
else if(cnt_7us == DELAY_7US)
ref_req <= 'b1;
end //--------------------------------
//Funtion : bank //assign aref_bank = 2'd0; endmodule
最重要的时仲裁模块,它负责各个模块之间的协调,模块之间控制有三个信号,分别是请求信号requst ,使能信号en ,还有结束标志信号flag_end
flag_end : 结束信号,负责一个状态的结束,比如写模块结束后,该信号就会拉高,时间很短暂,由计数器控制,自己会归0,当结束信号置1时,仲裁模块
里面的状态机就会跳转到仲裁模块,然后跳到下一个模块。
request :请求模块,当该模块里面的数据已经准备好,并且现在的状态机在执行别的状态时,该模块就可以向状态机发送请求,不过当多个模块向状态机发送
请求时这时候就需要一个优先级的概念,在该程序中设定的优先级 刷新 》 写模块 》 读模块
en :使能模块 , 当请求模块发挥作用时,仲裁模块把使能寄存器拉高,代表已经工作在该状态,同时把请求模块置0
地址和命令寄存器在三个模块是通用的,所以就要i用case语句进行选择,考虑时序逻辑有延时,所以用的组合逻辑
sdram_dq是双向端口:当不对该端口赋值的时候需要将该端口变成高阻态
代码
/*----------------------------------------------------------------------- Date : 2017-08-29
Description : Design for sdram_manage . -----------------------------------------------------------------------*/ module sdram_manage
(
//global clock
input clk, //system clock
input rst_n, //sync reset //sdram interface
output sdram_clk,
output sdram_cke,
output sdram_cas_n,
output sdram_cs_n,
output [:] sdram_dqm,
output [:] sdram_bank,
output sdram_ras_n,
output sdram_we_n,
output reg [:] sdram_addr,
inout [:] sdram_dq, //afresh interface
input ref_req,
output reg ref_en ,
input flag_ref_end,
input [:] aref_cmd,
input [:] aref_addr,
// input [1:0] aref_bank, //init interface
input [:] init_cmd,
input [:] init_addr,
// input [1:0] init_bank,
input flag_init_end, //write interface
output reg wr_en,
input wr_req,
input flag_wr_end,
input [:] wr_cmd,
input [:] wr_addr,
// input [1:0] wr_bank,
input [:] wr_dq,
output reg wr_wrig, //read interface
output reg rd_en,
input rd_req,
input flag_rd_end,
input [:] rd_cmd,
input [:] rd_addr,
// input [1:0] rd_bank,
output reg rd_wrig,
output reg [:] state ); //--------------------------------
//Funtion : 参数定义
localparam IDLE = 'b0_0001;
localparam ARBIT = 'b0_0010;
localparam AREF = 'b0_0100;
localparam WRITE = 'b0_1000;
localparam READ = 'b1_0000; parameter DELAY_10US = 'd500;
//reg [4:0] state;
reg [:] cnt_10us;
reg [:] cmd_reg; //--------------------------------
//Funtion : 读触发 和 写触发 //delay
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_10us <= 'd0;
else if(cnt_10us == DELAY_10US - 'b1)
cnt_10us <= 'd0;
else
cnt_10us <= cnt_10us + 'b1;
end always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
wr_wrig <= 'd0;
else if(cnt_10us == DELAY_10US - 'b1)
wr_wrig <= ~wr_wrig;
end always @(posedge clk)
begin
rd_wrig <= ~wr_wrig;
end //--------------------------------
//Funtion wr_en always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
wr_en <= 'b0;
else if(state == ARBIT && ref_req == 'b0 && wr_req)
wr_en <= 'b1;
else
wr_en <= 'b0;
end //--------------------------------
//Funtion ref_en always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
ref_en <= 'b0;
else if(state == ARBIT && ref_req)
ref_en <= 'b1;
else
ref_en <= 'b0;
end //--------------------------------
//Funtion rd_en 优先级 刷新 > 写请求 > 读请求 always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
rd_en <= 'b0;
else if(state == ARBIT && ref_req == 'b0 && wr_req == 1'b0 && rd_req == 'b1)
rd_en <= 'b1;
else
rd_en <= 'b0;
end //--------------------------------
//Funtion : 仲裁状态机 always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
state <= IDLE;
else
case(state) IDLE :
begin
if(flag_init_end)
state <= ARBIT;
else
state <= IDLE;
end
//仲裁
ARBIT :
begin
if(ref_en)
state <= AREF;
else if(wr_en)
state <= WRITE;
else if(rd_en)
state <= READ;
else
state <= ARBIT;
end
//刷新
AREF :
begin
if(flag_ref_end)
state <= ARBIT;
else
state <= AREF;
end
//write
WRITE :
begin
if(flag_wr_end)
state <= ARBIT;
else
state <= WRITE;
end
//read
READ :
begin
if(flag_rd_end)
state <= ARBIT;
else
state <= READ;
end default :
state <= IDLE;
endcase
end //--------------------------------
//Funtion : cmd addr 组合逻辑不会有延时 always @(*)
begin
case(state)
IDLE :
begin
cmd_reg = init_cmd;
sdram_addr = init_addr;
end AREF :
begin
cmd_reg = aref_cmd;
sdram_addr = aref_addr;
end WRITE :
begin
cmd_reg = wr_cmd;
sdram_addr = wr_addr;
end READ :
begin
cmd_reg = rd_cmd;
sdram_addr = rd_addr;
end default :
begin
cmd_reg = 'b0111;
sdram_addr = 'd0;
end endcase
end //--------------------------------
//Funtion : others assign sdram_clk =~ clk;
assign sdram_cke = 'b1;
assign sdram_dqm = 'd0;
assign {sdram_cs_n , sdram_ras_n , sdram_cas_n , sdram_we_n} = cmd_reg;
assign sdram_dq = (state == WRITE) ? wr_dq : {{'bz}};
assign sdram_bank = 'd0; endmodule
最后把sigtab的图片贴上来
在写数据写的是1000 - 4000 然后把它读出来
sdram控制2的更多相关文章
- FPGA之驱动sdram控制兼容性移植实验
cb早在2012年就推出了VIP 视频开发板 V1.4 这套开发板是ep2的,摄像头是ov7670,虽然不如当前的vip20强大,但也算是其雏形. 在vip20后期,cb对sdram以及其他模块进行 ...
- SDRAM读写一字(下)
SDRAM读写一字 SDRAM控制模块 上电后进行初始化状态,初始化完成后进入空闲状态,在此进行判断如下判断: 如果自刷新时间到,则进行自刷新操作,操作完成后重新进入空闲状态: 如果读使能有效则进行读 ...
- SDRAM操作说明
SDRAM是做嵌入式系统中,常用是的缓存数据的器件.基本概念如下(注意区分几个主要常见存储器之间的差异): SDRAM(Synchronous Dynamic Random Access Memory ...
- 第26章 FMC—扩展外部SDRAM
本章参考资料:<STM32F76xxx参考手册2>.<STM32F7xx规格书>.库帮助文档<STM32F779xx_User_Manual.chm>. 关于SDR ...
- FPGA实战操作(1) -- SDRAM(操作说明)
SDRAM是做嵌入式系统中,常用是的缓存数据的器件.基本概念如下(注意区分几个主要常见存储器之间的差异): SDRAM(Synchronous Dynamic Random Access Memory ...
- 第26章 FMC—扩展外部SDRAM—零死角玩转STM32-F429系列
第26章 FMC—扩展外部SDRAM 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...
- DRAM 内存介绍(一)
转载自博客大神迈克老狼的blog: http://www.cnblogs.com/mikewolf2002/archive/2012/11/13/2768804.html 参考资料:http://ww ...
- 十、S3C2440 开发资源
10.1 S3C2440 内部资源 1.2V 内核供电, 1.8V/2.5V/3.3V 储存器供电, 3.3V 外部 I/O 供电,具备 16KB 的指令缓存和 16KB 的数据缓存和 MMU 的微处 ...
- 【iCore3 双核心板_FPGA】实验二十八:基于SDRAM 的VGA 驱动器的设计
本实验设计的VGA显示驱动完全基于FPGA实现,用SDRAM做缓存设备,通过ARM控制VGA显示的内容.ARM 通过FSMC总线向FPGA发送数据,由于总线的速度和VGA的显示速度与SDRAM的读写速 ...
随机推荐
- git - 远程分支
对于用户来说,git给人提交到本地的机会.我们可以在自己的机器上创建不同的branch,来测试和存放不同的代码. 对于代码管理员而言,git有许多优良的特性.管理着不同的分支,同一套源代码可以出不一样 ...
- public/private/protected的具体区别
在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes,认为都是自己的朋友 ...
- RxSwift 系列(一) -- Observables
为什么使用RxSwift? 我们编写的代码绝大多数都涉及对外部事件的响应.当用户点击操作时,我们需要编写一个@IBAction事件来响应.我们需要观察通知,以检测键盘何时改变位置.当网络请求响应数据时 ...
- OI内的排列与组合(简单版)
§1基本原理 △让我们来看下面问题: 从甲地到乙地,可以乘火车,也可以乘汽车,还可以乘轮船.一天中,火车有4班,汽车有2班,轮船有3班.那么,一天中乘坐这些交通工具从甲地到乙地共有多少种不同走法?△分 ...
- WMvare桥接模式固定IP
一.命令行固定IP 1.配置网卡IP地址 在命令行输入"vi /etc/sysconfig/network-scripts/ifcfg-eth0"#eth0为第一块网卡,如果是第二 ...
- (转)Linux端口nmap和netstat命令
场景:弄不清楚端口和服务的关系,总觉得这个命令很有用但是还不清楚如何使用 1 linux端口与服务 1.1 安全概述 网络传输安全.操作系统安全.应用软件安全构成了整个网络应用的安全:其中应用软件安全 ...
- ES6字符串扩展
前面的话 字符串是编程中重要的数据类型,只有熟练掌握字符串操作才能更高效地开发程序.JS字符串的特性总是落后于其它语言,例如,直到 ES5 中字符串才获得了 trim() 方法.而 ES6 则继续添加 ...
- Word2016“此功能看似已中断 并需要修复”问题解决办法
Word2016"此功能看似已中断 并需要修复"问题解决办法 修复步骤: 1. 按Windows 键+R键,输入"regedit"打开注册表. 2.找到以下键值 ...
- ffmpeg编解码视频导致噪声增大的一种解决方法
一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...
- Fancytree Javascript Tree TreeTable 树介绍和使用
Fancytree是一个非常棒的Javascript控件,功能强大,文档健全.在做Javascript Tree控件选型时,主要基于以下几点选择了Fancytree 在Javascript Tree控 ...