OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [rtl/] [verilog/] [components/] [wb_sdram_ctrl/] [wb_sdram_ctrl_16_ip.v] - Rev 18

Compare with Previous | Blame | View Log

module delay #
  (
   parameter depth = 3,
   parameter width = 2
   )
     (
    input [width-1:0] d,
    output [width-1:0] q,
    input    clk,
    input   rst
      );
   reg [width-1:0] dffs [1:depth];
   integer i;
   always @ (posedge clk or posedge rst)
     if (rst)
       for ( i=1; i < depth+1; i= i + 1)
	 dffs[i] <= {depth{1'b0}};
     else
       begin
	  dffs[1] <= d;	  
	  for ( i=2; i < depth+1; i= i + 1)
	    dffs[i] <= dffs[i-1];
       end
   assign q = dffs[depth];
endmodule 
`if COL_SIZE==9
module wb_sdram_ctrl_fsm (
  output reg [14:0] a,
  output reg accept_cmd,
  output reg [2:0] cmd,
  output reg cmd_ack,
  output reg cs_n,
  output reg [1:0] dq_i_ce,
  output reg [16-1:0] dq_o,
  output reg dq_oe,
  output reg [16/8-1:0] dqm,
  output reg ref_ack,
  input wire [31:0] d,
  input dly_100us,
  input end_of_burst,
  input ref_req,
  input sdram_clk,
  input wb_ack,
  input [`WB_ADR_I_HI:`WB_ADR_I_LO] wb_adr_i,
  input wb_cyc,
  input wb_rst,
  input wire [3:0] wb_sel,
  input wb_stb,
  input wb_we 
);
  parameter 
  IDLE            = 17, 
  ACT_ROW         = 12, 
  AREF            = 11, 
  ARF1            = 16, 
  ARF2            = 19, 
  AWAIT_CMD       = 10, 
  BURST_TERMINATE = 6, 
  LMR             = 4, 
  NOP1            = 0, 
  NOP2            = 14, 
  NOP3            = 15, 
  NOP4            = 9, 
  NOP5            = 8, 
  NOP6            = 7, 
  PRE             = 5, 
  PRECHARGE       = 18, 
  READ            = 3, 
  READ_BURST      = 13, 
  WRITE           = 2, 
  WRITE_BURST     = 1; 
  reg [19:0] state;
  reg [19:0] nextstate;
  always @* begin
    nextstate = 20'b00000000000000000000;
    a[14:0] = {2'b00,13'b0000000000000}; 
    accept_cmd = 1'b0; 
    cmd[2:0] = 3'b111; 
    cmd_ack = 1'b0; 
    cs_n = 1'b0; 
    dq_i_ce[1:0] = 2'b00; 
    dq_o[16-1:0] = d[16-1:0]; 
    dq_oe = 1'b0; 
    dqm[16/8-1:0] = {(16/8){1'b0}}; 
    ref_ack = 1'b0; 
    case (1'b1) 
      state[IDLE]           : begin
                                           cs_n = 1'b1;
        if (dly_100us)                     nextstate[PRE] = 1'b1;
        else                               nextstate[IDLE] = 1'b1; 
      end
      state[ACT_ROW]        : begin
                                           a[14:0] = {`BA,`ROW};
                                           cmd[2:0] = 3'b011;
                                           nextstate[NOP5] = 1'b1;
      end
      state[AREF]           : begin
                                           cmd[2:0] = 3'b001;
                                           ref_ack = 1'b1;
                                           nextstate[NOP4] = 1'b1;
      end
      state[ARF1]           : begin
                                           cmd[2:0] = 3'b001;
                                           nextstate[NOP2] = 1'b1;
      end
      state[ARF2]           : begin
                                           cmd[2:0] = 3'b001;
                                           nextstate[NOP3] = 1'b1;
      end
      state[AWAIT_CMD]      : begin
                                           accept_cmd = 1'b1;
                                           cs_n = 1'b1;
        if (ref_req)                       nextstate[AREF] = 1'b1;
        else if (wb_stb & wb_cyc)          nextstate[ACT_ROW] = 1'b1;
        else                               nextstate[AWAIT_CMD] = 1'b1; 
      end
      state[BURST_TERMINATE]: begin
                                           cmd[2:0] = 3'b110;
                                           nextstate[PRECHARGE] = 1'b1;
      end
      state[LMR]            : begin
                                           a[14:0] = {2'b00,3'b000,1'b1,2'b00,3'd2,1'b0,3'b000};
                                           cmd[2:0] = 3'b000;
                                           nextstate[AWAIT_CMD] = 1'b1;
      end
      state[NOP1]           :              nextstate[ARF1] = 1'b1;
      state[NOP2]           :              nextstate[ARF2] = 1'b1;
      state[NOP3]           :              nextstate[LMR] = 1'b1;
      state[NOP4]           :              nextstate[AWAIT_CMD] = 1'b1;
      state[NOP5]           : if (wb_we)   nextstate[WRITE_BURST] = 1'b1;
                              else         nextstate[READ_BURST] = 1'b1;
      state[NOP6]           : if (wb_ack)  nextstate[AWAIT_CMD] = 1'b1;
                              else         nextstate[NOP6] = 1'b1; 
      state[PRE]            : begin
                                           a[14:0] = {2'b00,13'b0010000000000};
                                           cmd[2:0] = 3'b010;
                                           nextstate[NOP1] = 1'b1;
      end
      state[PRECHARGE]      : begin
                                           a[14:0] = {2'b00,13'b0010000000000};
                                           cmd[2:0] = 3'b010;
                                           nextstate[NOP6] = 1'b1;
      end
      state[READ]           : begin
                                           cmd_ack = 1'b1;
                                           dq_i_ce[1:0] = 2'b01;
        if (!end_of_burst)                 nextstate[READ_BURST] = 1'b1;
        else                               nextstate[BURST_TERMINATE] = 1'b1;
      end
      state[READ_BURST]     : begin
                                           a[14:0] = {`BA,{,wb_adr_i[9:1],1'b0};
                                           cmd[2:0] = 3'b101;
                                           dq_i_ce[1:0] = 2'b10;
                                           nextstate[READ] = 1'b1;
      end
      state[WRITE]          : begin
                                           cmd_ack = 1'b1;
                                           dq_o[16-1:0] = d[15:0];
                                           dq_oe = 1'b1;
                                           dqm[16/8-1:0] = !wb_sel[1:0];
        if (!end_of_burst)                 nextstate[WRITE_BURST] = 1'b1;
        else                               nextstate[BURST_TERMINATE] = 1'b1;
      end
      state[WRITE_BURST]    : begin
                                           a[14:0] = {`BA,{,wb_adr_i[9:1],1'b0};
                                           cmd[2:0] = 3'b100;
                                           dq_o[16-1:0] = d[31:16];
                                           dq_oe = 1'b1;
                                           dqm[16/8-1:0] = !wb_sel[3:2];
                                           nextstate[WRITE] = 1'b1;
      end
    endcase
  end
  always @(posedge sdram_clk or posedge wb_rst) begin
    if (wb_rst)
      state <= 20'b00000000000000000001 << IDLE;
    else
      state <= nextstate;
  end
  reg [119:0] statename;
  always @* begin
    case (1)
      state[IDLE]           : statename = "IDLE";
      state[ACT_ROW]        : statename = "ACT_ROW";
      state[AREF]           : statename = "AREF";
      state[ARF1]           : statename = "ARF1";
      state[ARF2]           : statename = "ARF2";
      state[AWAIT_CMD]      : statename = "AWAIT_CMD";
      state[BURST_TERMINATE]: statename = "BURST_TERMINATE";
      state[LMR]            : statename = "LMR";
      state[NOP1]           : statename = "NOP1";
      state[NOP2]           : statename = "NOP2";
      state[NOP3]           : statename = "NOP3";
      state[NOP4]           : statename = "NOP4";
      state[NOP5]           : statename = "NOP5";
      state[NOP6]           : statename = "NOP6";
      state[PRE]            : statename = "PRE";
      state[PRECHARGE]      : statename = "PRECHARGE";
      state[READ]           : statename = "READ";
      state[READ_BURST]     : statename = "READ_BURST";
      state[WRITE]          : statename = "WRITE";
      state[WRITE_BURST]    : statename = "WRITE_BURST";
      default        :        statename = "XXXXXXXXXXXXXXX";
    endcase
  end
endmodule
`if COL_SIZE==9
module wb_sdram_ctrl
  (
    input [31:0] wb_dat_i,
    output reg [31:0] wb_dat_o,
    input [3:0]       wb_sel_i,
    input [`WB_ADR_I_HI:`WB_ADR_I_LO]      wb_adr_i,
    input 	      wb_we_i,
    input [2:0]       wb_cti_i,
    input 	      wb_stb_i,
    input 	      wb_cyc_i,
    output  	      wb_ack_o,
    output 	      sdr_cke_o,   
    output reg	      sdr_cs_n_o,  
    output reg	      sdr_ras_n_o, 
    output reg	      sdr_cas_n_o, 
    output reg	      sdr_we_n_o,  
    output reg [12:0] sdr_a_o,
    output reg  [1:0] sdr_ba_o,
    inout [16-1:0] sdr_dq_io,
    output reg [16/8-1:0] sdr_dqm_o,
    input sdram_clk,
    input wb_clk,
    input wb_rst
   );
   reg    ref_req;
   wire   ref_ack;
   wire	  cmd_ack;
   wire   end_of_burst;
   assign end_of_burst = (wb_cti_i == 3'b111) | (wb_cti_i == 3'b000);
   reg [4-1:0] burst_counter;
   wire [1:0]  sdr_ba;
   wire [12:0] sdr_a;
   wire [16/8-1:0]  dq_i_ce1,dq_i_ce2;
   reg 	       sdr_dq_oe_reg;
   wire [16-1:0] sdr_dq_i, sdr_dq_o;
   wire [16/8-1:0] sdr_dqm;
   reg [12:0] counter;
   wire       counter_zf; 
   assign counter_zf = (counter==13'd0);    
   always @ (posedge wb_clk or posedge wb_rst)
     if (wb_rst)
       counter <= 12'd4095;
     else if (counter_zf)
       counter <= 12'd390;
     else
       counter <= counter - 1;
   always @ (posedge wb_clk or posedge wb_rst)
     if (wb_rst)
       ref_req <= 1'b0;
     else
       if (counter_zf)
	 ref_req <= 1'b1;
       else if (ref_ack)
	 ref_req <= 1'b0;
   always @ (posedge sdram_clk or posedge wb_rst)
     if (wb_rst)
       burst_counter <= 0;
     else
       if (rd_ack)
	 burst_counter <= burst_counter + 1;
       else
	 burst_counter <= wb_adr_i[5:2];
   wb_sdram_ctrl_fsm fsm0
     (
      .dly_100us(counter_zf),
      .ref_req(ref_req),
      .ref_ack(ref_ack),
      .accept_cmd(),
      .wb_stb(wb_stb_i),
      .wb_cyc(wb_cyc_i),
      .wb_we(wb_we_i),
      .wb_ack(wb_ack_o), 
      .end_of_burst(end_of_burst),
      .cmd_ack(cmd_ack),
      .wb_sel(wb_sel_i),
      .wb_adr_i({wb_adr_i[`WB_ADR_I_HI:`WB_ADR_I_LO+3],burst_counter}),
      .a({sdr_ba,sdr_a}),
      .cmd({ras, cas, we}),
      .cs_n(sdr_cs_n),
      .sdram_clk(sdram_clk),
      .wb_rst(wb_rst)
      );
   always @ (posedge sdram_clk or posedge wb_rst)
     if (wb_rst)
       begin
	  sdr_cs_n_o <= 1'b1;
	  {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= 3'b111;	  
	  {sdr_ba_o,sdr_a_o} <= 15'd0;
	  sdr_dqm_o <= {16/8{1'b0}};
       end
     else
       begin
	  sdr_cs_n_o <= sdr_cs_n;	  
	  {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= {ras, cas, we};
	  {sdr_ba_o,sdr_a_o} <= {sdr_ba,sdr_a};
	  sdr_dqm_o <= sdr_dqm;
       end
   assign sdr_cke_o = 1'b1;
   reg [16-1:0] sdr_dq_o_reg;
   always @ (posedge sdram_clk or posedge wb_rst)
     if (wb_rst)
       {sdr_dq_oe_reg,sdr_dq_o_reg} <= {1'b0,16'd0};
     else
       {sdr_dq_oe_reg,sdr_dq_o_reg} <= {sdr_dq_oe,sdr_dq_o};
   assign #1 sdr_dq_io = sdr_dq_oe_reg ? sdr_dq_o_reg : {16{1'bz}};
   assign #1 sdr_dq_i = sdr_dq_io;
   delay #
     (
      .depth(2+1),
      .width(16/8)
      )
   delay0
     (
      .d(dq_i_ce1),
      .q(dq_i_ce2),
      .clk(sdram_clk),
      .rst(wb_rst)
      );
   delay #
     (
      .depth(2+2),
      .width(1)
      )
   delay1
     (
      .d(cmd_ack),
      .q(wb_ack_o),
      .clk(sdram_clk),
      .rst(wb_rst)
      );
   always @ (posedge sdram_clk or posedge wb_rst)
     if (wb_rst)
       begin
	  wb_dat_o <= 32'd0;
       end
     else
       begin
	  if (dq_i_ce2[1])
	    wb_dat_o[31:16] <= sdr_dq_i;
	  if (dq_i_ce2[0])
	    wb_dat_o[15:0] <= sdr_dq_i;
       end
endmodule 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.