首页 > 代码库 > SDR SDRAM控制器设计

SDR SDRAM控制器设计

<style>p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; font-size: 10.5pt; font-family: "Calibri", "sans-serif" } h1 { margin-top: 0cm; margin-right: 0cm; margin-left: 21.6pt; margin-bottom: .0001pt; text-align: justify; text-indent: -21.6pt; line-height: 240%; page-break-after: avoid; font-size: 16.0pt; font-family: "Times New Roman", "serif" } h2 { margin-top: 0cm; margin-right: 0cm; margin-left: 28.8pt; margin-bottom: .0001pt; text-align: justify; text-indent: -28.8pt; line-height: 173%; page-break-after: avoid; font-size: 15.0pt; font-family: "Times New Roman", "serif" } h3 { margin-top: 0cm; margin-right: 0cm; margin-left: 36.0pt; margin-bottom: .0001pt; text-align: justify; text-indent: -36.0pt; line-height: 173%; page-break-after: avoid; font-size: 14.0pt; font-family: "Times New Roman", "serif" } h4 { margin-top: 0cm; margin-right: 0cm; margin-left: 43.2pt; margin-bottom: .0001pt; text-align: justify; text-indent: -43.2pt; line-height: 156%; page-break-after: avoid; font-size: 14.0pt; font-family: "Times New Roman", "serif" } h5 { margin-top: 0cm; margin-right: 0cm; margin-left: 50.4pt; margin-bottom: .0001pt; text-align: justify; text-indent: -50.4pt; line-height: 156%; page-break-after: avoid; font-size: 14.0pt; font-family: "Calibri", "sans-serif" } h6 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 57.6pt; text-align: justify; text-indent: -57.6pt; line-height: 133%; page-break-after: avoid; font-size: 12.0pt; font-family: "Cambria", "serif" } p.MsoHeading7,li.MsoHeading7,div.MsoHeading7 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 64.8pt; text-align: justify; text-indent: -64.8pt; line-height: 133%; page-break-after: avoid; font-size: 12.0pt; font-family: "Calibri", "sans-serif"; font-weight: bold } p.MsoHeading8,li.MsoHeading8,div.MsoHeading8 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 72.0pt; text-align: justify; text-indent: -72.0pt; line-height: 133%; page-break-after: avoid; font-size: 12.0pt; font-family: "Cambria", "serif" } p.MsoHeading9,li.MsoHeading9,div.MsoHeading9 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 79.2pt; text-align: justify; text-indent: -79.2pt; line-height: 133%; page-break-after: avoid; font-size: 10.5pt; font-family: "Cambria", "serif" } p.MsoFooter,li.MsoFooter,div.MsoFooter { margin: 0cm; margin-bottom: .0001pt; font-size: 9.0pt; font-family: "Calibri", "sans-serif" } p.MsoTitle,li.MsoTitle,div.MsoTitle { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.0pt; margin-left: 0cm; text-align: center; font-size: 16.0pt; font-family: "Cambria", "serif"; font-weight: bold } span.1Char { font-family: 黑体; font-weight: bold } span.2Char { font-family: 黑体; font-weight: bold } span.3Char { font-family: 黑体; font-weight: bold } span.4Char { font-family: 黑体; font-weight: bold } span.5Char { font-family: "Calibri", "sans-serif"; font-weight: bold } span.6Char { font-family: "Cambria", "serif"; font-weight: bold } span.7Char { font-family: "Calibri", "sans-serif"; font-weight: bold } span.8Char { font-family: "Cambria", "serif" } span.9Char { font-family: "Cambria", "serif" } span.Char { font-family: "Calibri", "sans-serif" } span.Char0 { font-family: "Cambria", "serif"; font-weight: bold } .MsoChpDefault { font-size: 10.0pt } div.Section1 { } ol { margin-bottom: 0cm } ul { margin-bottom: 0cm }</style>

 

SDR SDRAM控制器设计

 

1sdram控制器概述

1.1       sdram控制器简介

该控制器为SDR SDRAM操作提供一个简单的接口,使得读写SDRAM像读写普通FIFO或者SRAM一样简单。该控制器具有如下特性:

l  读写时钟:100Mhz—133Mhz      

l  读写端口:两个独立的写端口和两个独立的读端口

l  Burst length1248

l  CAS latency23

l  地址宽、数据、FIFO深度参数化配置

l  缓存FIFO采用RTL级描述,方便移植

l  采样Verilog HDL语言描述,方便移植

 

1.2       sdram简介

(略)

 

2sdram控制器应用说明

2.1       端口列表

端口名

方向

位宽

功能说明

clk

input

 

系统时钟输入,该时钟与sdram_clk需要有70°的相位差。

rst

input

 

系统复位输入,低电平复位

 

 

 

 

sdram_clke

output

1

SDRAM 时钟使能

sdram_cs_n

output

1

SDRAM片选,低有效

sdram_ras_n

output

1

SDRAM行选通,低有效

sdram_cas_n

output

1

SDRAM 列选通,低有效

sdram_we_n

output

1

SDRAM 写使能,低有效

sdram_ba

output

2

SDRAM Bank地址

sdram_addr

output

`ROWSIZE

SDRAM /列地址

sdram_dq

inout

`DSIZE

SDRAM 数据

sdram_dqm

output

2

SDRAM 数据屏蔽信号

 

 

 

 

wr1_clk

input

1

写端口1 时钟

wr1_load

input

1

写端口1起始地址Load信号

wr1_req

input

1

写端口1 FIFO请求

wr1_addr

input

`ASIZE

写端口1 起始地址

wr1_data

input

`DSIZE

写端口1 写入数据

wr1_full

output

1

写端口1 FIFO满标志

wr1_usedw

output

`FIFO_ASIZE

写端口1 FIFO存储空间用量

rd1_clk

input

1

读端口1 时钟

rd1_ load

input

1

读端口1起始地址和读长度 Load信号

rd1_req

input

1

读端口1 FIFO请求

rd1_addr

input

`ASIZE

读端口1 起始地址

rd1_data

input

`DSIZE

读端口1 写入数据

rd1_length

input

`ASIZE

读端口1 读长度信号

rd1_empty

output

1

读端口1 FIFO空标志

rd1_usedw

output

`FIFO_ASIZE

读端口1 FIFO存储空间用量

 

 

 

 

wr2_clk

input

1

写端口2 时钟

wr2_ load

input

1

写端口2起始地址Load信号

wr2_req

input

1

写端口2 FIFO请求

wr2_addr

input

`ASIZE

写端口2 起始地址

wr2_data

input

`DSIZE

写端口2 写入数据

wr2_full

output

1

写端口2 FIFO满标志

wr2_usedw

output

`FIFO_ASIZE

写端口2 FIFO存储空间用量

rd2_clk

input

1

读端口2 时钟

rd2_ load

input

1

读端口2起始地址和读长度 Load信号

rd2_req

input

1

读端口2 FIFO请求

rd2_addr

input

`ASIZE

读端口2 起始地址

rd2_data

input

`DSIZE

读端口2 写入数据

rd2_length

input

`ASIZE

读端口2 读长度信号

rd2_empty

output

1

读端口2 FIFO空标志

rd2_usedw

output

`FIFO_ASIZE

读端口2 FIFO存储空间用量

 

 

 

 

sdram_init_done

output

1

SDRAM控制器初始化完成

 

端口连接图如下

技术分享

 

2.2       接口操作时序

2.2.1    写操作

首先设置起始地址,然后往FIFO里面写数据即可。控制器会自动帮你完成接下来的一切。

 

设置起始地址时序图

技术分享

wr1 FIFO写入数据时序图

技术分享

 

写操作端口仿真波形图

技术分享

上图中,在wr2_load有效之后,wr2_addr_cnt载入起始地址,即w0x40_0100BL=4,所以每完成一次Burst Writewr1_addr_cnt4.

 

2.2.2    读操作

读操作与写操作类似,也是先设置起始地址,只不过在设置起始地址时,同时设置读长度rdx_length

设置读起始地址和读长度之后,控制器会自动去读取SDRAM中相应地址段的数据并存入FIFO,我们只需要判断FIFO是否有数据,将其读出来即可。

下图为读FIFO的时序图。

 

技术分享

读操作仿真波形

技术分享

 

2.3       参数定义

Implemant到具体的项目中时,需要根据选用的SDRAM芯片修改sdr_sdram.h里的以下参数:

`COLSIZE           :        列地址位宽

`ROWSIZE         :        行地址位宽

`BANKSIZE        :        Bank地址位宽

`FIFO_ASIZE     :        FIFO深度配置,可不修改,默认是256

 

`BL                      :        突发长度

其他的参数可不修改

sdr_sdram.h主要宏定义如下

 

//

`define  COLSIZE        8

`define  ROWSIZE        12

`define  BANKSIZE       2

 

`define  COLSTART       0

`define  ROWSTART       (`COLSIZE)

`define  BANKSTART      (`COLSIZE+`ROWSTART)

 

`define  ASIZE          (`COLSIZE+`ROWSIZE+`BANKSIZE)

`define  DSIZE          16

`define  FIFO_ASIZE     8

 

`define  CL             3

//-----------------------

//  BL setting

//  000 --1

//  001 --2

//  010 --4

//  011 --8

//  111 --full page

`define  BL             3‘b10

 

`define  RCD            1

`define  RRD            1

`define  PM             0

 

`define  REF_TIME       16‘d781

`define  POWERUP_DELAY  16‘d10000

//-------------------------------

 

 

 

 

3SDRAM控制器电路框图

3.1       电路框图

技术分享

 

n  读、写FIFO均为异步FIFO,用于缓存读、写数据

n  ctrlpath模块负责完成上电初始化SDRAM,每隔固定时间进行自动刷新防止数据丢失,查询WR1,WR2,RD1,RD24个端口是否有读写请求,并发出相应的命令;

n  CMD模块根据Ctrlpathcmd命令,生成相应的SDRAM控制信号;

n  Datapath模块完成数据流的控制,即从WR FIFO中读数据送到sdram数据总线,或者从sdram数据总线读取数据存入RD FIFO,并保证其时序相互匹配。

 

 

 

3.2       CtrlPath状态机分析

Ctrlpath模块状态机共有如下12个状态。

//fsm sate define   

parameter IDLE    = (1 << 0),    //上电复位默认状态,等100us后进入INIT

INIT    = (1 << 1),   //初始化

ARBIT   = (1 << 2),  //仲裁状态,扫描4个读写接口是否有读写请求

AREF    = (1 << 3),  //自动刷新

AREF2   = (1 << 4),  //自动刷新等待

ACT     = (1 << 5),  //Active

RCD     = (1 << 6),  //RCD延迟等待

WR_S1     = (1 << 7), //写命令发出

WR_S2     = (1 << 8),//等待BurstWrite完成

RD_S1     = (1 << 9), //读命令发出

RD_S2     = (1 << 10),  //等待Burst Read完成

TRP     = (1 << 11)    //Precharge RAS延迟等待

状态转移示意图如下(由Verdi软件产生)

 

技术分享

 

l  复位结束后在IDLE状态等待100us,然后进入INIT状态。

l  INIT状态完成SDRAM芯片的初始化,初始化主要完成了以下几个操作:一个预充电、两个周期自动刷新,以及LMR,即Mode寄存器设置。

RTL代码如下:

技术分享

LMR指令模式寄存器设置:

技术分享

对应的仿真波形。

技术分享

初始化完成后,即跳转到了ARBIT状态。

l  ARBIT状态为要在以下几个状态之间进行选择:空操作、刷新操作、写端口1请求,写端口2请求,读端口1请求,读端口2请求。仲裁代码如下:

技术分享

need_aref表示需要刷新,need_aref有效,则直接跳转到AREF状态;

port_sel为端口选择:0选择wr11选择wr22选择rd13选择rd2.所以上面的语句就是判断当前选择的端口是否有请求,有请求的话就跳转到ACT状态。

关于端口的查询机制,我用了如下代码:

技术分享

技术分享

并不是每时每刻,每个端口都有请求信号,所以上面的处理方式可以快速地切换到有请求信号的端口。这样可以使查询时间最小化,提高了数据吞吐率。

l  ACT状态发出Active命令;

l  RCDRAS to CAS delay。延迟结束后感觉端口选择信号port_sel选择进入RD-S1还是进入WR_S1状态。

l  WR_S1RD-S1状态分别为写和读命令发出状态。

l  WR_S2RD_S2,等待操作完成。

l  TRP状态是为了等待Precharge完成。因为我们在读写时,A10=1,所以每次读或写结束,SDRAM会自动进行precharge操作。而PrechargeACT命令之间,需要一个tRP的间隔。

 

以下是BL=4的时的写操作和读操作仿真波形截图

 

技术分享

BL=4 写操作:ARBIT->ACT->RCD-WR_S1->WR_S2-TRP->ARBIT

 

技术分享

BL=4,读操作:ARBIT->AC6-RCD->RD_S1->RD_S2->TRP->ARBIT

 

3.3       Datapath

该模块根据cmd命令,生成相应的FIFO/写信号。FIFO读写时,注意调整好数据之间的步调一致。下面说下写信号和读信号怎么生成。

 

写操作比较简单,因为写命令会数据是同时发出的,并不需要等待,所以,可直接由写命令生成FIFO读请求信号

技术分享

读的时候,与写基本一样,但是需要经过一个CAS Latency延迟。

技术分享

技术分享

技术分享

 

4测试验证

为了测试该控制器的功能是否正确,做了一个串口收发和指令解析模块,通过串口向其发送读写指令。指令定义如下:

指令格式:

命令字段

数据字段

结束符

说明

@

起始地址

设置读/写起始地址

#

写入数据

写数据到FIFO

%

读长度

设置读长度

 

串口发送的格式为ASCII码,命令的第一个字符为@,或#,或%,分别代表设置地址,写如数据,设置读长度;所有命令以分号结束。

 

整个小系统电路结构示意图如下:

技术分享

测试用例测试:

以下命令串是从0x100地址,开始写入4444555, ……,def0,共12个数据,然后将其读回。

@100;

#4444;

#5555;

#6666;

#7777;

#8888;

#9999;

#aaaa;

#bbbb;

#1234;

#5678;

#9abc;

#def0;

%c;

串口测试结果截图如下:

技术分享

收到的数据和写入的数据是一致的,说明读写是正确的。

<style>p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; font-size: 10.5pt; font-family: "Calibri", "sans-serif" } h1 { margin-top: 0cm; margin-right: 0cm; margin-left: 21.6pt; margin-bottom: .0001pt; text-align: justify; text-indent: -21.6pt; line-height: 240%; page-break-after: avoid; font-size: 16.0pt; font-family: "Times New Roman", "serif" } h2 { margin-top: 0cm; margin-right: 0cm; margin-left: 28.8pt; margin-bottom: .0001pt; text-align: justify; text-indent: -28.8pt; line-height: 173%; page-break-after: avoid; font-size: 15.0pt; font-family: "Times New Roman", "serif" } h3 { margin-top: 0cm; margin-right: 0cm; margin-left: 36.0pt; margin-bottom: .0001pt; text-align: justify; text-indent: -36.0pt; line-height: 173%; page-break-after: avoid; font-size: 14.0pt; font-family: "Times New Roman", "serif" } h4 { margin-top: 0cm; margin-right: 0cm; margin-left: 43.2pt; margin-bottom: .0001pt; text-align: justify; text-indent: -43.2pt; line-height: 156%; page-break-after: avoid; font-size: 14.0pt; font-family: "Times New Roman", "serif" } h5 { margin-top: 0cm; margin-right: 0cm; margin-left: 50.4pt; margin-bottom: .0001pt; text-align: justify; text-indent: -50.4pt; line-height: 156%; page-break-after: avoid; font-size: 14.0pt; font-family: "Calibri", "sans-serif" } h6 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 57.6pt; text-align: justify; text-indent: -57.6pt; line-height: 133%; page-break-after: avoid; font-size: 12.0pt; font-family: "Cambria", "serif" } p.MsoHeading7,li.MsoHeading7,div.MsoHeading7 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 64.8pt; text-align: justify; text-indent: -64.8pt; line-height: 133%; page-break-after: avoid; font-size: 12.0pt; font-family: "Calibri", "sans-serif"; font-weight: bold } p.MsoHeading8,li.MsoHeading8,div.MsoHeading8 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 72.0pt; text-align: justify; text-indent: -72.0pt; line-height: 133%; page-break-after: avoid; font-size: 12.0pt; font-family: "Cambria", "serif" } p.MsoHeading9,li.MsoHeading9,div.MsoHeading9 { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.2pt; margin-left: 79.2pt; text-align: justify; text-indent: -79.2pt; line-height: 133%; page-break-after: avoid; font-size: 10.5pt; font-family: "Cambria", "serif" } p.MsoFooter,li.MsoFooter,div.MsoFooter { margin: 0cm; margin-bottom: .0001pt; font-size: 9.0pt; font-family: "Calibri", "sans-serif" } p.MsoTitle,li.MsoTitle,div.MsoTitle { margin-top: 12.0pt; margin-right: 0cm; margin-bottom: 3.0pt; margin-left: 0cm; text-align: center; font-size: 16.0pt; font-family: "Cambria", "serif"; font-weight: bold } span.1Char { font-family: 黑体; font-weight: bold } span.2Char { font-family: 黑体; font-weight: bold } span.3Char { font-family: 黑体; font-weight: bold } span.4Char { font-family: 黑体; font-weight: bold } span.5Char { font-family: "Calibri", "sans-serif"; font-weight: bold } span.6Char { font-family: "Cambria", "serif"; font-weight: bold } span.7Char { font-family: "Calibri", "sans-serif"; font-weight: bold } span.8Char { font-family: "Cambria", "serif" } span.9Char { font-family: "Cambria", "serif" } span.Char { font-family: "Calibri", "sans-serif" } span.Char0 { font-family: "Cambria", "serif"; font-weight: bold } .MsoChpDefault { font-size: 10.0pt } div.Section1 { } ol { margin-bottom: 0cm } ul { margin-bottom: 0cm }</style>

SDR SDRAM控制器设计