SDRAM接口练习3

SDRAM接口练习3

添加读操作-全页读模式

module work_3(clk,rst_n,wr_req,waddr,wdata,wr_ack,rd_req,rd_ack,rdata,rdata_vld,cke,cs,ras,cas,we,dqm,addr,bank,dq);
input clk;
input rst_n;
input wr_req;
input [21:0] waddr;// without [21:0], bank<=waddr[21:20] error
input [15:0] wdata;
output wr_ack;
input rd_req;
output rd_ack;
output rdata;
output rdata_vld;
input cke;
output cs;
output ras;
output cas;
output we;
output dqm;
output addr;
output bank;
output dq;
parameter T=10;
parameter T_NOP=10000;
parameter TRP=2;
parameter TRC=6;
parameter TMRD=2;
parameter TRCD=3;
parameter MODE_VALUE  = 12'b0000_0010_0111;
//
parameter      INIT_NOP    = 1;//
parameter      INIT_CHARGE = 2;//
parameter      INIT_REF1   = 3;//
parameter      INIT_REF2   = 4;//
parameter      INIT_MODE   = 5;//
parameter      ST_IDLE     = 6;//
parameter      ST_REF      = 7;//
parameter      WR_ACTIVE     = 8;
parameter      WR_WRITE     = 9;
parameter      WR_CHARGE    = 10;
parameter      RD_ACTIVE     = 11;
parameter      RD_READ     = 12;
parameter      RD_CHARGE    = 13;

reg cs;
reg ras;
reg cas;
reg we;
reg wr_ack;
reg rd_ack;
reg [1:0] dqm;
reg [11:0] addr;
reg [1:0] bank;
reg [15:0] dq;
reg [3:0] state_c;//10
reg [3:0] state_n;
reg [13:0] count;
reg [13:0] x;//2^14=2048*8>10000
reg [10:0] count1;//2^11=2048
reg [3:0] command;
reg rdata_vld;

wire INIT_NOP2CHARGE;
wire INIT_CHARGE2REF1; 
wire  INIT_REF12REF2;  
wire INIT_REF22MODE; 
wire MODE2IDLE ;
wire ST_IDLE2REF;
wire ST_REF2IDLE;
wire IDLE2ACTIVE;
wire WR_ACTIVE2WRITE;
wire WR_WRITE2CHARGE ;
wire CHARGE2IDLE ;

wire IDLE2RD_ACTIVE;
wire RD_ACTIVE2READ;
wire RD_READ2CHARGE;
wire RD_CHARGE2IDLE;

assign INIT_NOP2CHARGE = (state_c == INIT_NOP)    && (count==1);
assign INIT_CHARGE2REF1= (state_c == INIT_CHARGE) && (count==1);
assign INIT_REF12REF2   = (state_c == INIT_REF1)   && (count==1);
assign INIT_REF22MODE   = (state_c == INIT_REF2)   && (count==1);
assign MODE2IDLE     = ((state_c == INIT_MODE)  && (count==1));
assign ST_IDLE2REF   = (state_c == ST_IDLE)     && (count1==1) &&  (wr_req==0);//
assign ST_REF2IDLE  = (state_c == ST_REF)     && (count==1) ;//

assign IDLE2ACTIVE      = (state_c == ST_IDLE)     && (count==1)   &&  (wr_req==1) &&  (rd_req==0);
assign WR_ACTIVE2WRITE     = (state_c == WR_ACTIVE)     && (count==1);
assign WR_WRITE2CHARGE      = (state_c == WR_WRITE)     && (count==1);
assign CHARGE2IDLE      = (state_c == WR_CHARGE)     && (count==1);

assign IDLE2RD_ACTIVE      = (state_c == ST_IDLE)     && (count==1)   &&  (rd_req==1);
assign RD_ACTIVE2READ      = (state_c == RD_ACTIVE)     && (count==1);
assign RD_READ2CHARGE      = (state_c == RD_READ)     && (count==1);
assign RD_CHARGE2IDLE      = (state_c == RD_CHARGE)     && (count==1);

always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  state_c<=INIT_NOP;
 end
 else begin
  state_c<=state_n;
 end
end

always @ (*) begin
 if (!rst_n) begin
  state_n=state_c;
 end
 else begin
  case (state_c)
   INIT_NOP : begin//1
    if (INIT_NOP2CHARGE) begin
     state_n=INIT_CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_CHARGE : begin//2
    if (INIT_CHARGE2REF1) begin
     state_n=INIT_REF1;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_REF1 : begin//3
    if (INIT_REF12REF2) begin
     state_n=INIT_REF2;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_REF2 : begin//4
    if (INIT_REF22MODE) begin
     state_n=INIT_MODE;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_MODE : begin//5
    if (MODE2IDLE) begin
     state_n=ST_IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   ST_IDLE : begin//6
    if (ST_IDLE2REF) begin
     state_n=ST_REF;
    end
    else if (IDLE2ACTIVE) begin
     state_n=WR_ACTIVE;
    end
    else if (IDLE2RD_ACTIVE) begin
     state_n=RD_ACTIVE;
    end
    else begin
     state_n=state_c;
    end
   end
   ST_REF : begin//7
    if (ST_REF2IDLE) begin
     state_n=ST_IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   WR_ACTIVE : begin//8
    if (WR_ACTIVE2WRITE) begin
     state_n=WR_WRITE;
    end
    else begin
     state_n=state_c;
    end
   end
  WR_WRITE : begin//9
    if (WR_WRITE2CHARGE) begin
     state_n=WR_CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
  WR_CHARGE : begin//10
    if (CHARGE2IDLE) begin
     state_n=ST_IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   RD_ACTIVE : begin//11
    if (RD_ACTIVE2READ) begin
     state_n=RD_READ;
    end
    else begin
     state_n=state_c;
    end
   end
   RD_READ : begin//12
    if (RD_READ2CHARGE) begin
     state_n=RD_CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
  RD_CHARGE: begin//13
    if (RD_CHARGE2IDLE) begin
     state_n=ST_IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   default : begin//default
    state_n=INIT_NOP;
   end
  endcase
 end
end

//
always  @(*)begin
 if(state_c==INIT_CHARGE || state_c==WR_CHARGE || state_c==RD_CHARGE) begin//2 10 13
   x = TRP;
 end
 else if(state_c==INIT_REF1 || state_c==INIT_REF2 || state_c==ST_REF)begin// 347 
   x = TRC;
 end
 else if(state_c==INIT_MODE)begin//5
  x = TMRD;
 end
 else if(state_c==WR_ACTIVE || state_c==RD_ACTIVE)begin//8 11
  x = TRCD;
 end
 else if(state_c==WR_WRITE || state_c==RD_READ)begin//9 12
  x = 256;
 end
 else begin
  x =  T_NOP;//1
 end
end
//count
always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  count<= T_NOP-1;
 end
 else begin
   if (count==0)
    count<= x-1;
   else
    count<=count-1;
 end
 end
 always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  count1<=1300-1;
 end
 else if (state_c==ST_IDLE) begin//6
   if (count==0)
    count1<= 1300-1;
   else
    count1<=count-1;
 end
 else begin
   count1<= 1300-1;
 end
 end
//command
always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  command<=4'b0111;
 end
 else begin
  if (INIT_NOP2CHARGE||WR_WRITE2CHARGE ||RD_READ2CHARGE)
   command<=4'b0010;
  else if (INIT_CHARGE2REF1||INIT_REF12REF2||ST_IDLE2REF)
   command<=4'b0001;
  else if (INIT_REF22MODE)
   command<=4'b0000;
  else if (IDLE2ACTIVE)
   command<=4'b0011;
  else if (WR_ACTIVE2WRITE)
   command<=4'b0100; 
  else if (RD_ACTIVE2READ)
   command<=4'b0101; 
  else
   command<=4'b0111;
 end
end
//assign {cs,ras,cas,we}=command;
always @(*) begin
 cs=command[3];
 ras=command[2];
 cas=command[1];
 we=command[0];
 end
 
//dqm
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  dqm<=2'b00;
 end
 else begin
  if (state_c==INIT_NOP||state_c==INIT_CHARGE||state_c==INIT_REF1||state_c==INIT_REF2||state_c==INIT_MODE)
   dqm<=2'b11;
  else
   dqm<=2'b00;
 end
end
//addr
always @(*) begin
 if (!rst_n) begin
  addr=12'b0000_0000_0000;
 end
 else begin
  if (state_c==INIT_MODE)
   addr=MODE_VALUE;
  else if (state_c==INIT_CHARGE)
   addr=12'b0100_0000_0000;
  else if (state_c==WR_WRITE || state_c==RD_READ)
   addr=waddr[7:0];
  else if (state_c==WR_ACTIVE || state_c==RD_ACTIVE)
   addr=waddr[19:8];
  else 
   addr=12'b0;
 end
end
//bank
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  bank<=2'b00;
 end
 else begin
  if (WR_ACTIVE2WRITE || IDLE2ACTIVE || RD_ACTIVE2READ || IDLE2RD_ACTIVE)
   bank<=waddr[21:20];
  else
   bank<=2'b00;
 end
end
//dq
always @(*) begin
 if (!rst_n) begin
  dq=16'hzzzz;
 end
 else if (state_c==WR_WRITE) begin//
  dq=wdata;
 end
 else if (state_c==RD_READ) begin//
  dq=rdata;
 end
 else
  dq=16'hzzzz;
end
//wr_ack    assign wr_ack=wr_active_start
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  wr_ack<=0;
 end
 else begin
  if (WR_ACTIVE2WRITE) //(state_c == WR_ACTIVE)     && (count==1)
  wr_ack<=1;
  else
  wr_ack<=0;
 end
end
//rd_ack
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  rd_ack<=0;
 end
 else begin
  if (RD_ACTIVE2READ) //(state_c == WR_ACTIVE)     && (count==1)
  rd_ack<=1;
  else
  rd_ack<=0;
 end
end
//rdata_vld
always @(*) begin
 if (!rst_n) begin
  rdata_vld=0;
 end
 else begin
  if (state_c==RD_READ) //(state_c == WR_ACTIVE)     && (count==1)
  rdata_vld=1;
  else
  rdata_vld=0;
 end
end
endmodule


module work_3_test();
reg clk;
reg rst_n;
reg wr_req;
reg [21:0] waddr;// without [21:0], bank<=waddr[21:20] error
reg [15:0] wdata;
wire wr_ack;
reg rd_req;
wire rd_ack;
wire rdata;
wire rdata_vld;
reg cke;
wire cs;
wire ras;
wire cas;
wire we;
wire dqm;
wire addr;
wire bank;
wire dq;
work_3 work_3_test(
.clk(clk),
.rst_n(rst_n),
.wr_req(wr_req),
.waddr(waddr),
.wdata(wdata),
.wr_ack(wr_ack),
.rd_req(rd_req),
.rd_ack(rd_ack),
.rdata(rdata),
.rdata_vld(rdata_vld),
.cke(cke),
.cs(cs),
.ras(ras),
.cas(cas),
.we(we),
.dqm(dqm),
.addr(addr),
.bank(bank),
.dq(dq)
);
initial begin
 clk=1'b0;
 forever #5 clk=~clk;
end
initial begin
 rst_n=1'b0;
 cke=1'b1;
 waddr=22'b01_0001_0111_0000_0001_1010;
 wdata=16'b0111_0000_0001_1010;
 wr_req=1'b0;
 rd_req=1'b1;
 #7 rst_n=1'b1;
end
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值