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的读写速 ...
随机推荐
- [luogu P3797] 妖梦斩木棒 [线段树]
题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看做由三种小段构成,中间的 ...
- STF,docker学习资料整理
- (转)Java多线程之Lock的使用 (待整理)
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...
- [node] node 版本更新
一. 命令 node -v sudo npm cache clean -f // 清除缓存 sudo npm install -g n // 安装Node 模块 sudo n stable // 升级 ...
- ASP.NET WebAPI Get和Post 传参总结
这里我使用Jquery 来发起异步请求实现数据调用. 继续使用上一文章中的示例,添加一个index.html页面,添加对jquery的引用. 一.无参数Get请求 一般的get请求我们可以使用jque ...
- openstack中使用linux_bridge实现vxlan网络
openstack环境: 1 版本:ocata 2 系统:ubuntu16.04.2 3 控制节点 1个 + 计算节点 1个 4 控制节点网卡为ens33,ip = 172.171.5.200 ens ...
- Json 工具介绍 fastjson gson jackson
1. fastjson fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致, 是目前Java语言中最快的J ...
- hadoop入门,跑出第一个WordCount
1.环境准备 下载:http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz 解压:解压后,修改et ...
- JavaScript中的call()、apply()与bind():
关于call()与apply(): 在JavaScript中,每个函数都有call与apply(),这两个函数都是用来改变函数体内this的指向,并调用相关的参数. 看一个例子: 定义一个animal ...
- EXchange导出通讯录提取url纯文本
用outlook链接邮箱 文件-打开和导出--导出到文件--逗号分隔值--选择联系人--保存 保存为一个后缀为csv的文件 打开该文件 选中该列 用替换功能删掉()符号 用vba脚本删掉汉字 Sub ...