FPGA操控SDRAM.docx

上传人:b****8 文档编号:10490480 上传时间:2023-02-13 格式:DOCX 页数:30 大小:51.88KB
下载 相关 举报
FPGA操控SDRAM.docx_第1页
第1页 / 共30页
FPGA操控SDRAM.docx_第2页
第2页 / 共30页
FPGA操控SDRAM.docx_第3页
第3页 / 共30页
FPGA操控SDRAM.docx_第4页
第4页 / 共30页
FPGA操控SDRAM.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

FPGA操控SDRAM.docx

《FPGA操控SDRAM.docx》由会员分享,可在线阅读,更多相关《FPGA操控SDRAM.docx(30页珍藏版)》请在冰豆网上搜索。

FPGA操控SDRAM.docx

FPGA操控SDRAM

FPGA操控SDRAM

所用FPGA芯片:

EP2C8Q208C8

所用内存:

H57V2562GTR-75C

顶层模块:

modulesdram

clk,

ext_rst_n,

/**********************/

sdramclk,//SDRAM的引脚

ledpio,//发光二极管,打酱油的

addr,

ba,

cas_n,

cke,

cs_n,

dq,

dqm,

ras_n,

we_n,

/*****************/

flash_nce_n,

sram_nce_n

/******************/

);

/******************/

inputclk;

inputext_rst_n;

output[7:

0]ledpio;//八位流水

/**************************/

output[12:

0]addr;

output[1:

0]ba;

outputcas_n;

outputcke;

outputcs_n;

inout[15:

0]dq;

output[1:

0]dqm;

outputras_n;

outputwe_n;

outputsdramclk;

/**************************/

outputflash_nce_n=1'b1;

outputsram_nce_n=1'b1;

assigncs_n=1'b0;

assigncke=1'b1;

assigndqm=2'b00;

/****************************/

wirewr_n;

wire[4:

0]cmd;

wirerefquest;

wirerfinish;

wirewfinish;

sys_cmds1

.clk(clk_100m),

.rst_n(ext_rst_n),

.wr_n(wr_n),//由数据产生模块决定现在是读还是写状态

.cmd(cmd),

.refquest(refquest),

.rfinish(rfinish),//读完成标志位,每完成一次读操作出现一次上升沿

.wfinish(wfinish)//写完成标志位,每完成一次写操作出现一次上升沿

);

/***************************/

wire[12:

0]rowadd;

wire[8:

0]caadd;

wire[15:

0]indata;

wire[15:

0]outdata;

sys_ctrls2

.clk(clk_100m),

.cmd(cmd),

.rowadd(rowadd),//行地址输入

.caadd(caadd),//列地址输入

.indata(indata),//数据输入

.outdata(outdata),//从内存读回数据后,将数据输出

.addr(addr),

.ba(ba),

.cas_n(cas_n),

.dq(dq),

.ras_n(ras_n),

.we_n(we_n),

.refquest(refquest)

);

assignledpio=outdata[7:

0];

/*****************************/

wireclk_100m;

pll100mp1(

.inclk0(clk),

.c0(clk_100m),

.c1(sdramclk));

/*****************************/

dataproduced1

.clk(clk_100m),

.wr_n(wr_n),

.data(indata),

.rowadd(rowadd),

.caadd(caadd),

.rst_n(ext_rst_n),

.rfinish(rfinish),//读完成标志位,每完成一次读操作出现一次上升沿

.wfinish(wfinish)//写完成标志位,每完成一次写操作出现一次上升沿

);

/******************************/

Endmodule

 

内存状态控制模块:

modulesys_cmd

clk,

rst_n,

wr_n,

cmd,

refquest,//刷新请求位,为高时请求外部执行刷新操作

rfinish,//读完成标志位,每完成一次读操作出现一次上升沿

wfinish//写完成标志位,每完成一次写操作出现一次上升沿

);

/*************************/

parametercnt_200us=20000;//SDRAM在开机时的初始化过程,上电后要有200us的输入稳定期

parameterinicycle=8;//200us以后就是要对所有L-Bank预充电,再往后给SDRAM8次的刷新命令

parametertRFC=6;//预刷新操作需要的等待时间要比预充电长的多,大约需要6个时钟周期(60ns)

parametertRP=2;//在发出预充电命令之后,要经过一段时间才能允许发送RAS行有效命令打开

//新的工作行,这个间隔被称为tRP(PrechargecommandPeriod,预充电有效周期)。

parametertRCD=3;//在发送列读写命令时必须要与行有效命令有一个间隔

//这个间隔被定义为tRCD,即RAStoCASDelay(RAS至CAS延迟),

parameterCL=3;

parametertWR=2;//数据的真正写入需要一定的周期。

为了保证数据的可靠写入,

//都会留出足够的写入/校正时间(tWR,WriteRecoveryTime)

/***************************/

parameterINI=5'b00001;

parameterININOP=5'b00010;

parameterPRECHARGEALL=5'b00011;//预充电

parameterPRECHARGEALLNOP=5'b00100;//预充电

parameterMRS=5'b00101;

parameterMRSNOP=5'b00111;

parameterREFRESH=5'b01000;

parameterREFRESHNOP=5'b01001;

//以上四个状态是用来初始化的

parameterRAS=5'b01010;

parameterRASNOP=5'b01011;

parameterCAS=5'b01100;

parameterCASNOP=5'b01101;

parameterR_W_PRECHARGE=5'b11110;//由于SDRAM的寻址具有独占性,所以在进行完读写操作后,

//如果要对同一L-Bank的另一行进行寻址,就要将原来有效(工作)的行关闭,重新发送行/列地址?

//L-Bank关闭现有工作行,准备打开新行的操作就是预充电(Precharge)。

//预充电可以通过命令控制,也可以通过辅助设定让芯片在每次读写操作之后自动进行预充电。

?

parameterR_W_PRECHARGENOP=5'b10000;

/***************************/

parameterRE=5'b01110;//确定当前是读状态还是写状态

parameterWR=5'b01111;

parameterREWAIT=5'b10001;

parameterREFIN=5'b10010;

parameterWRFIN=5'b10011;

/*******************************/

parameterRECNT=782;//刷新周期为7.8125μs

/***************************/

inputclk;

inputrst_n;

inputwr_n;

output[4:

0]cmd;

outputrefquest;//刷新请求位,为高时请求外部执行刷新操作

outputrfinish;//读完成标志位,每完成一次读操作出现一次上升沿

outputwfinish;//写完成标志位,每完成一次写操作出现一次上升沿

/************************/

assigncmd=state;

reg[4:

0]state;

reg[15:

0]cnt;

reg[3:

0]refreshcnt;//初始化要八个刷新周期,每个刷新周期70ns

/***************************/

reg[15:

0]Tcnt;//刷新周期为7.8125μs

reg[3:

0]Tcout;//而每次刷新所占用的时间为9个时钟周期

regrefquest;//刷新请求位,为高时请求外部执行刷新操作

regrefinish;//刷新完成标志位,高表示刷新完成,可以正常操作,否则要等待

regrfinish;//读完成标志位,每完成一次读操作出现一次上升沿

regwfinish;//写完成标志位,每完成一次写操作出现一次上升沿

always@(posedgeclkornegedgerst_n)

if(!

rst_n)

begin

Tcnt<=16'b0;

Tcout<=4'b0;

refquest<=1'b0;

refinish<=1'b1;

end

elseif(Tcnt>=RECNT)

begin

if(Tcout>=9)

begin

refquest<=1'b0;

refinish<=1'b1;//发出刷新请求并等待九个时钟周期后,刷新操作完成

Tcout<=4'b0;

Tcnt<=16'b0;

end

else

begin

refquest<=1'b1;

refinish<=1'b0;

Tcout<=Tcout+1'b1;

Tcnt<=Tcnt;

end

end

else

Tcnt<=Tcnt+1'b1;

/*****************************/

always@(posedgeclkornegedgerst_n)

begin

if(!

rst_n)

begin

state<=INI;

cnt<=16'b0;

refreshcnt<=4'b0;

rfinish<=1'b0;

wfinish<=1'b0;

end

elseif(refinish)

begin

case(state)

INI:

begin

if(cnt>=cnt_200us)//上电后要有200us的输入稳定期

begin

cnt<=16'b0;

state<=ININOP;

end

else

begin

cnt<=cnt+1'b1;

state<=state;

end

end

ININOP:

state<=PRECHARGEALL;

/****************************************/

PRECHARGEALL:

//所有L-Bank预充电

begin

state<=PRECHARGEALLNOP;

end

PRECHARGEALLNOP:

state<=REFRESH;

/****************************************/

REFRESH:

//预充电完成了就要连续进行八个预刷新

if(refreshcnt>=inicycle)//给SDRAM8次的刷新命令

begin

refreshcnt<=4'b0;

state<=MRS;

end

else

begin

state<=REFRESHNOP;

refreshcnt<=refreshcnt+1'b1;

end

REFRESHNOP:

if(cnt>=tRFC)//预刷新操作需要的等待时间要比预充电长的多,大约需要6个时钟周期(60ns)

begin

cnt<=16'b0;

state<=REFRESH;

end

else

begin

cnt<=cnt+1'b1;

state<=state;

end

/****************************************/

MRS:

//模式寄存器设置

state<=MRSNOP;

MRSNOP:

state<=RAS;

/****************************************/

RAS:

//行有效

begin

state<=RASNOP;

rfinish<=1'b0;//读完成标志位,每完成一次读操作出现一次上升沿

wfinish<=1'b0;//写完成标志位,每完成一次写操作出现一次上升沿

end

RASNOP:

//在发送列读写命令时必须要与行有效命令有一个间隔

//这个间隔被定义为tRCD,即RAStoCASDelay(RAS至CAS延迟),

if(cnt>=tRCD)

begin

if(wr_n)

state<=RE;//wr_n为高,对内存进行读操作

else

state<=WR;//wr_n为低,对内存进行写操作

cnt<=16'b0;

end

else

begin

cnt<=cnt+1'b1;

state<=state;

end

/****************************************/

RE:

//列读写

state<=REWAIT;

REWAIT:

//在CAS发出之后,仍要经过一定的时间才能有数据输出,

//从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为CL(CASLatency,CAS潜伏期)。

if(cnt>=CL)

begin

cnt<=16'b0;

state<=REFIN;

end

else

begin

cnt<=cnt+1'b1;

state<=state;

end

REFIN:

begin

state<=R_W_PRECHARGE;

rfinish<=1'b1;//读完成标志位,每完成一次读操作出现一次上升沿

end

/****************************************/

WR:

//列读写

state<=WRFIN;

WRFIN:

//数据的真正写入需要一定的周期。

为了保证数据的可靠写入,

//都会留出足够的写入/校正时间(tWR,WriteRecoveryTime)

if(cnt>=tWR)

begin

cnt<=16'b0;

wfinish<=1'b1;//写完成标志位,每完成一次写操作出现一次上升沿

state<=R_W_PRECHARGE;

end

else

begin

cnt<=cnt+1'b1;

state<=state;

end

/********************************/

R_W_PRECHARGE:

state<=R_W_PRECHARGENOP;

R_W_PRECHARGENOP:

if(cnt>=tRP)//在发出预充电命令之后,要经过一段时间才能允许发送RAS行有效命令打开

//新的工作行,这个间隔被称为tRP(PrechargecommandPeriod,预充电有效周期)。

begin

cnt<=16'b0;

state<=RAS;

end

else

begin

cnt<=cnt+1'b1;

state<=state;

end

/****************************************/

endcase

end

else

state<=state;

end

/***************************/

Endmodule

 

操作内存接口模块:

modulesys_ctrl

clk,

cmd,

rowadd,//行地址输入

caadd,//列地址输入

indata,//数据输入

outdata,//从内存读回数据后,将数据输出

/*************************/

addr,

ba,

cas_n,

dq,

ras_n,

we_n,

/***************************/

refquest

);

/***************************/

inputclk;

inputrefquest;//刷新请求位,出现上升沿发出一条刷新命令

input[4:

0]cmd;

input[12:

0]rowadd;

input[8:

0]caadd;

input[15:

0]indata;

output[15:

0]outdata;

/************************/

output[12:

0]addr;

output[1:

0]ba;

outputcas_n;

inout[15:

0]dq;

outputras_n;

outputwe_n;//为低时,向内存写数据

/******************************/

reg[12:

0]addr;

reg[1:

0]ba;//这里只对第零个bank进行操作

regcas_n;

reg[15:

0]wrdata;//写数据寄存器

reg[15:

0]redata;//读数据寄存器

regras_n;

regwe_n;

/**************************/

parameterINI=5'b00001;

parameterININOP=5'b00010;

parameterPRECHARGEALL=5'b00011;//预充电

parameterPRECHARGEALLNOP=5'b00100;//预充电

parameterMRS=5'b00101;

parameterMRSNOP=5'b00111;

parameterREFRESH=5'b01000;

parameterREFRESHNOP=5'b01001;

//以上四个状态是用来初始化的

parameterRAS=5'b01010;

parameterRASNOP=5'b01011;

parameterCAS=5'b01100;

parameterCASNOP=5'b01101;

parameterR_W_PRECHARGE=5'b10000;//由于SDRAM的寻址具有独占性,所以在进行完读写操作后,

//如果要对同一L-Bank的另一行进行寻址,就要将原来有效(工作)的行关闭,重新发送行/列地址。

parameterR_W_PRECHARGENOP=5'b10101;

/***************************/

parameterRE=5'b01110;//确定当前是读状态还是写状态

parameterWR=5'b01111;

parameterREFIN=5'b10010;

parameterREWAIT=5'b10011;

parameterWRFIN=5'b10100;

/*******************************/

reg[15:

0]outdata;

always@(posedgeclk)

begin

wrdata<=indata;

outdata<=redata;

end

/***********************************/

assigndq=we_n?

16'bz:

wrdata;//为低时,向内存写数据,为高时从内存读数据(先设置为输出高阻态)

regrefquest_temp1;//检测refquest的上升沿

regrefquest_temp2;

always@(posedgeclk)

begin

refquest_temp1<=refquest;

refquest_temp2<=refquest_temp1;

if(~refquest_temp2&refquest_temp1)//刷新请求位,出现上升沿发出一条刷新命令

begin

ras_n=1'b0;

cas_n=1'b0;

we_n=1'b1;

end

elseif(!

refquest)//refquest为高时,还处于刷新状态

begin

case(cmd)

ININOP:

begin

ras_n<=1'b1;

cas_n<=1'b1;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 管理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1