ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SDRAM接口练习4

2021-08-03 22:58:18  阅读:194  来源: 互联网

标签:count SDRAM wire 练习 state 接口 flag && assign


SDRAM接口练习4

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/08/03 09:39:06
// Design Name: 
// Module Name: work_4
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module work_4(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=2;
parameter Tread=256;
parameter Twrite=256;
parameter Tidle=2;
parameter MODE_VALUE  = 12'b0000_0010_0111;//M9 = 0 burst模式  M6 M5 M4 = 3'b010 输出延时为2个时钟周期;M3 = 0 burst类型(连续模式) M2 M1 M0 = 3'b111 全页模式
//
parameter      NOP    = 1;//
parameter      CHARGE = 2;//
parameter      REF   = 3;//
parameter      MODE   = 4;//
parameter      IDLE     = 5;//
parameter      ACTIVE     = 6;
parameter      WRITE     = 7;
parameter      READ     = 8;
parameter      REF2     = 9;

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 NOP2CHARGE;
wire CHARGE2REF;   
wire REF2REF2;  
wire REF22MODE; 
wire MODE2IDLE ;
wire IDLE2REF;
wire REF2IDLE;
wire IDLE2ACTIVE;
wire ACTIVE2WRITE;
wire WRITE2CHARGE ;
wire CHARGE2IDLE ;
wire ACTIVE2READ;
wire READ2CHARGE;
wire resh_req;
reg init_flag;
wire wr_flag;
wire rd_flag;
//reg init_resh_cnt;//初始化过程自动刷新计数 区分REF2REF 还是REF2MODE
assign wr_flag= (wr_req==1) &&  (rd_req==0);
assign rd_flag= (rd_req==1);
assign resh_req=  (wr_req==1 || rd_req==1);

assign NOP2CHARGE = (state_c == NOP)    && (count==1) ;
assign CHARGE2REF= (state_c == CHARGE) && (count==1) && init_flag==1;
assign REF2REF2   = (state_c == REF)   && (count==1)  && (init_flag==1)  ;
assign REF22MODE  = (state_c == REF2)   && (count==1)  && (init_flag==1)  ;
assign MODE2IDLE     = (state_c == MODE)  && (count==1);
assign IDLE2REF   = (state_c == IDLE)     && (count1==1) ;//
assign REF2IDLE  = (state_c == REF)     && (count==1) && (init_flag==0) ;//

assign IDLE2ACTIVE      = (state_c == IDLE)     && (count==1)   &&  ( (wr_flag==1)||(rd_flag==1) ) ;
assign ACTIVE2WRITE     = (state_c == ACTIVE)     && (count==1)&&  (wr_flag==1);
assign WRITE2CHARGE      = (state_c == WRITE)     && (count==1);
assign CHARGE2IDLE      = (state_c == CHARGE)     && (count==1) && ( (wr_flag==1)||(rd_flag==1) );

assign ACTIVE2READ      = (state_c == ACTIVE)     && (count==1)&&  (rd_flag==1) ;
assign READ2CHARGE      = (state_c == READ)     && (count==1);

always  @(posedge clk or negedge rst_n) begin
 if (rst_n==1'b0) begin
  init_flag <= 1;
 end
 else if (MODE2IDLE) begin
  init_flag <= 0;
 end
end
//always  @(posedge clk or negedge rst_n) begin
// if (rst_n==1'b0) begin
//  init_resh_cnt <= 0;
// end
// else if (REF2REF) begin
//  init_resh_cnt <= 1;
// end
// else if (REF2MODE) begin
//  init_resh_cnt <= 0;
// end
//end
    
always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  state_c<=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)
   NOP : begin//1
    if (NOP2CHARGE) begin
     state_n=CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
   CHARGE : begin//2
    if (CHARGE2REF) begin
     state_n=REF;
    end
    else if (CHARGE2IDLE) begin
     state_n=IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   REF : begin//3
    if (REF2IDLE) begin
     state_n=IDLE;
    end
    else if (REF2REF2) begin
     state_n=REF2;
    end
    else begin
     state_n=state_c;
    end
   end
   REF2 : begin//3
    if (REF22MODE) begin
     state_n=MODE;
    end
    else begin
     state_n=state_c;
    end
   end
   MODE : begin//
    if (MODE2IDLE) begin
     state_n=IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   IDLE : begin//
    if (IDLE2REF) begin
     state_n=REF;
    end
    else if (IDLE2ACTIVE) begin
     state_n=ACTIVE;
    end
    else begin
     state_n=state_c;
    end
   end
   ACTIVE : begin//
    if (ACTIVE2WRITE) begin
     state_n=WRITE;
    end
    else if (ACTIVE2READ) begin
     state_n=READ;
    end
    else begin
     state_n=state_c;
    end
   end
  WRITE : begin
    if (WRITE2CHARGE) begin
     state_n=CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
   READ : begin
    if (READ2CHARGE) begin
     state_n=CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
   default : begin//default
    state_n=NOP;
   end
  endcase
 end
end

//
always  @(*)begin
 if(state_c==CHARGE) begin
   x = TRP;
 end
 else if(state_c==REF || state_c==REF2 )begin
   x = TRC;
 end
 else if(state_c==MODE)begin
  x = TMRD;
 end
 else if(state_c==ACTIVE )begin
  x = TRCD;
 end
 else if(state_c==WRITE )begin
  x = Twrite;
 end
 else if(state_c== READ )begin
  x = Tread;
 end
 else if(state_c== IDLE && (wr_flag==0 || rd_flag==0))begin
  x = Tidle;
 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==IDLE && wr_flag==0 && rd_flag==0 ) 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 (NOP2CHARGE||WRITE2CHARGE ||READ2CHARGE)
   command<=4'b0010;
  else if (CHARGE2REF  || IDLE2REF)
   command<=4'b0001;
  else if (REF22MODE)
   command<=4'b0000;
  else if (IDLE2ACTIVE)
   command<=4'b0011;
  else if (ACTIVE2WRITE)
   command<=4'b0100; 
  else if (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==NOP||state_c==CHARGE|| state_c==REF ||state_c==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==MODE)
   addr=MODE_VALUE;
  else if (state_c==CHARGE)
   addr=12'b0100_0000_0000;
  else if (state_c==WRITE || state_c==READ)
   addr=waddr[7:0];
  else if (state_c==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 (ACTIVE2WRITE || IDLE2ACTIVE || ACTIVE2READ || IDLE2ACTIVE)
   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==WRITE) begin//
  dq=wdata;
 end
 else if (state_c==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 (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 (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==READ) //(state_c == WR_ACTIVE)     && (count==1)
  rdata_vld=1;
  else
  rdata_vld=0;
 end
end
endmodule

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/08/03 19:53:57
// Design Name: 
// Module Name: work_4_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module work_4_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_4 work_4_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

在这里插入图片描述
在这里插入图片描述

标签:count,SDRAM,wire,练习,state,接口,flag,&&,assign
来源: https://blog.csdn.net/qq_46300065/article/details/119361062

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有