SDRAM接口练习1

SDRAM接口练习1

verilog代码

module sdram_work_1 (clk,rst_n,cke,cs,ras,cas,we,dqm,addr,bank,dq);
input clk;
input rst_n;
output 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 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;//
reg cke;
reg cs;
reg ras;
reg cas;
reg we;
reg [1:0] dqm;
reg [11:0] addr;
reg [1:0] bank;
reg [15:0] dq;
reg [2:0] state_c;
reg [2:0] state_n;
reg [13:0] count;
reg [3:0] command;
wire INIT_CHARGE_START;
wire INIT_REF1_START; 
wire INIT_REF2_START;  
wire INIT_MODE_START; 
wire ST_IDLE_START;
wire ST_REF_START;

assign INIT_CHARGE_START = (state_c == INIT_NOP)    && (count==1);
assign INIT_REF1_START   = (state_c == INIT_CHARGE) && (count==1);
assign INIT_REF2_START   = (state_c == INIT_REF1)   && (count==1);
assign INIT_MODE_START   = (state_c == INIT_REF2)   && (count==1);
assign ST_IDLE_START     = ((state_c == INIT_MODE)  && (count==1))|| ((state_c == ST_REF) && (count==1));
assign ST_REF_START      = (state_c == ST_IDLE)     && (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
    if (INIT_CHARGE_START) begin//1
     state_n=INIT_CHARGE;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_CHARGE : begin
    if (INIT_REF1_START) begin//2
     state_n=INIT_REF1;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_REF1 : begin
    if (INIT_REF2_START) begin//3
     state_n=INIT_REF2;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_REF2 : begin
    if (INIT_MODE_START) begin//4
     state_n=INIT_MODE;
    end
    else begin
     state_n=state_c;
    end
   end
   INIT_MODE : begin
    if (ST_IDLE_START) begin//5
     state_n=ST_IDLE;
    end
    else begin
     state_n=state_c;
    end
   end
   ST_IDLE : begin
    if (ST_REF_START) begin//6   count1
     state_n=ST_REF;
    end
    else begin
     state_n=state_c;
    end
   end
   ST_REF : begin
    if (ST_IDLE_START) begin//7
     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)begin
//   x = TRP;
// end
// else if(state_c==INIT_REF1 || state_c==INIT_REF2 || state_c==ST_REF)begin
//   x = TRC;
// end
// else if(state_c==INIT_MODE)begin
//  x = TMRD;
// end
// else begin
//  x =  T_NOP;
// end
//end
//count
always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  count<= T_NOP-1;
 end
 else begin
  if (state_c==INIT_CHARGE) begin 
   if (count==0)
    count<= TRP-1;
   else
    count<=count-1;//
  end
  else if (state_c==INIT_REF1 || state_c==INIT_REF2|| state_c==ST_REF )begin
   if (count==0)
    count<= TRC-1;
   else
    count<=count-1;
  end
  else if (state_c==INIT_MODE )begin
   if (count==0)
    count<= TMRD-1;
   else
    count<=count-1;
  end 
  else if (state_c==ST_IDLE )begin
   if (count==0)
    count<= 1562-1;
   else
    count<=count-1;
  end 
  else begin
   if (count==0)
    count<= T_NOP-1;
   else
    count<=count-1;
  end 
 end
end

//cke
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  cke<=1;
 end
 else begin
  cke<=1;
 end
end

always @ (posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  command<=4'b0111;
 end
 else begin
  if (INIT_CHARGE_START)
   command<=4'b0010;
  else if (INIT_REF1_START||INIT_REF2_START||ST_REF_START)
   command<=4'b0001;
  else if (INIT_MODE_START)
   command<=4'b0000;
  else
   command<=4'b0111;
 end
end
 
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 
   addr=12'b0;
 end
end
//bank
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  bank<=2'b00;
 end
 else begin
  bank<=2'b00;
 end
end
//dq
always @(posedge clk or negedge rst_n) begin
 if (!rst_n) begin
  dq<=16'hzzzz;
 end
 else begin
  dq<=16'hzzzz;
 end
end
endmodule

testbench文件:

`timescale 1ns/1ns
module work_1_test();
reg clk;
reg rst_n;
wire cke;
wire cs;
wire ras;
wire cas;
wire we;
wire [1:0] dqm;
wire [11:0] addr;
wire [1:0] bank;
wire [15:0] dq;
parameter T=10;
sdram_work_1 #(.T(10)) work_1_test(
.clk(clk),
.rst_n(rst_n),
.cke(cke),
.cs(cs),
.ras(ras),
.cas(cas),
.we(we),
.dqm(dqm),
.addr(addr),
.bank(bank),
.dq(dq)
);
initial begin
 clk=1'b0;
 forever #(T/2) clk=~clk;
end
initial begin
 rst_n=1'b0;
 #(T*10) rst_n=1'b1;
end
endmodule

vivado仿真结果:
在这里插入图片描述

1状态到2状态经过10000个时钟周期;2-3,2个;3-4,6个;4-5,6个;5-6,2个.
状态2时,addr=0100_0000_0000; 状态5时,addr=12’b0000_0010_0111;其他12’b0;
cs,ras,cas,we在各个状态的第一拍给出正确指令;347第一拍-0001;5第一拍-0000;1第一拍-01111;2第一拍-0010;其余时间0111.
cke一直1;dqm初始化-高,其余-低;dq一直高阻态,bank一直0。

在这里插入图片描述

6-7,1562个; 7-6,6个.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值