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.v] - Diff between revs 38 and 42

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 38 Rev 42
Line 1... Line 1...
 
`include "wb_sdram_ctrl_defines.v"
 
module `MODULE_NAME
 
  (
 
   // wishbone i/f
 
    input [31:0]      wb_dat_i,
 
    output [31:0]     wb_dat_o,
 
    input [3:0]       wb_sel_i,
 
    input [`WB_ADR_HI:2]      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,
 
   // SDRAM IO
 
    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 [`SDRAM_DATA_WIDTH-1:0] sdr_dq_io,
 
    output reg [`SDRAM_DATA_WIDTH/8-1:0] sdr_dqm_o,
 
   // system
 
    input sdram_clk,
 
    input wb_clk,
 
    input wb_rst
 
   );
 
 
 
   reg    ref_req;
 
   wire   ref_ack;
 
 
 
   wire   rd_ack, rd_ack_o, wr_ack, wr_ack_o, cmd_ack;
 
 
 
   reg [`BA_SIZE-1:0] ba;
 
   reg [`ROW_SIZE-1:0] row;
 
 
 
   // terminate current cycle if !stb&!cyc, empty fifo
 
   // restart if adr_fail (non consecutive adr inc), empty fifo
 
   wire   terminate, adr_fail, clear;
 
 
 
   wire   end_of_burst;
 
   wire   burst_counter_set;
 
   reg [`COL_SIZE-1:0]  burst_counter;
 
`ifdef SDRAM16
 
   wire [`BURST_SIZE:0] burst_counter_next;
 
   reg [`BURST_SIZE:0]   burst_counter_init;
 
`endif
 
 
 
   wire                 fifo_we;
 
 
 
   wire [1:0]  sdr_ba;
 
   wire [12:0] sdr_a;
 
 
 
   reg         sdr_dq_oe_reg;
 
   wire [`SDRAM_DATA_WIDTH-1:0] sdr_dq_i, sdr_dq_o;
 
   wire [`SDRAM_DATA_WIDTH/8-1:0] sdr_dqm;
 
 
 
   // counter 100us delay and refresh interval
 
   reg [12:0] counter;
 
   wire       counter_zf; // counter zero flag
 
   assign counter_zf = (counter==13'd0);
 
   always @ (posedge wb_clk or posedge wb_rst)
 
     if (wb_rst)
 
       counter <= 13'd`DLY_INIT;
 
     else if (counter_zf)
 
       counter <= 13'd`AREF_INIT;
 
     else
 
       counter <= counter - 13'd1;
 
 
 
   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;
 
 
 
`ifdef SDRAM16
 
   assign burst_counter_next = burst_counter[`BURST_SIZE:0] + {{`BURST_SIZE{1'b0}},1'b1};
 
   always @ (posedge sdram_clk or posedge wb_rst)
 
     if (wb_rst)
 
       begin
 
          ba <= `BA_SIZE'd0;
 
          row <= `ROW_SIZE'd0;
 
          burst_counter_init <= `BURST_SIZE'd0;
 
          burst_counter <= `COL_SIZE'd0;
 
       end
 
     else
 
       if (burst_counter_set)
 
         begin
 
            ba <= `BA;
 
            row <= `ROW;
 
            // A fix of the fix.
 
            // We previously adjusted the burst_counter, which is very important - it determines the address
 
            // we generate and use for the SDRAM column addressing.
 
            // So instead, when we receive an (arguably incorrect) access request, with the cycle indicator
 
            // showing "burst end" (wb_cti_i=3'b111), we change burst_counter_init so it should show that
 
            // the transfer will end after a single 32-bit word transaction has taken place (2 16-bit word
 
            // transactions)
 
            burst_counter_init <= (wb_cti_i == 3'b111) ? {wb_adr_i[`BURST_SIZE-1+2:2],1'b0} + 2 : {wb_adr_i[`BURST_SIZE-1+2:2],1'b0};
 
            burst_counter <= {wb_adr_i[`COL_SIZE+2:2],1'b0};
 
         end
 
       else if (rd_ack | wr_ack)
 
         begin
 
            burst_counter[`BURST_SIZE:0] <= burst_counter_next;
 
         end
 
   assign end_of_burst = (wb_cti_i==3'b000) ? (burst_counter[0]==1'b1) : (burst_counter_next == burst_counter_init);
 
`endif
 
 
 
   wb_sdram_ctrl_fsm fsm0
 
     (
 
      .dly_100us(counter_zf),
 
      .ref_req(ref_req),
 
      .ref_ack(ref_ack),
 
      .accept_cmd(burst_counter_set),
 
      .rd_ack(rd_ack),
 
      .wr_ack(wr_ack),
 
      .clear(clear),
 
      .wb_stb(wb_stb_i),
 
      .wb_cyc(wb_cyc_i),
 
      .wb_we(wb_we_i),
 
      .wb_ack(wb_ack_o & ((wb_cti_i==3'b000) | (wb_cti_i==3'b111))),
 
      .end_of_burst(end_of_burst),
 
      .wb_adr_i({`BA,`ROW,burst_counter}),
 
      .a({sdr_ba,sdr_a}),
 
      .cmd(`CMD),
 
      .cs_n(sdr_cs_n),
 
      .sdram_clk(sdram_clk),
 
      .wb_rst(wb_rst)
 
      );
 
 
 
`ifdef SDRAM16
 
   assign sdr_dqm = ((burst_counter[0]==1'b0) & wr_ack) ? ~wb_sel_i[3:2] :
 
                    ((burst_counter[0]==1'b1) & wr_ack) ? ~wb_sel_i[1:0] :
 
                    2'b00;
 
`endif
 
 
 
   // output registers
 
   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} <= `CMD_NOP;
 
          {sdr_ba_o,sdr_a_o} <= 15'd0;
 
          sdr_dqm_o <= {`SDRAM_DATA_WIDTH/8{1'b0}};
 
       end
 
     else
 
       begin
 
          sdr_cs_n_o <= #1 sdr_cs_n;
 
          {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= #1 `CMD;
 
          {sdr_ba_o,sdr_a_o} <= #1 {sdr_ba,sdr_a};
 
          sdr_dqm_o <= #1 sdr_dqm;
 
  end
 
 
 
   assign sdr_cke_o = 1'b1;
 
 
 
`ifdef SDRAM16
 
   assign sdr_dq_o = (burst_counter[0]==1'b0) ? wb_dat_i[31:16] : wb_dat_i[15:0];
 
`endif
 
 
 
   // Tristate driver for data bus
 
//   assign sdr_dq_oe = wr_ack; -- sdr_dq_oe was not declared! changed its only reference --jb
 
   reg [`SDRAM_DATA_WIDTH-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,`SDRAM_DATA_WIDTH'd0};
 
     else
 
       {sdr_dq_oe_reg,sdr_dq_o_reg} <= {wr_ack,sdr_dq_o};//{sdr_dq_oe_reg,sdr_dq_o_reg} <= {sdr_dq_oe,sdr_dq_o}; --jb
 
 
 
   assign #1 sdr_dq_io = sdr_dq_oe_reg ? sdr_dq_o_reg : {`SDRAM_DATA_WIDTH{1'bz}};
 
   assign #1 sdr_dq_i = sdr_dq_io;
 
 
 
   // delay fifo_fill in accordance to cas latency
 
   delay #
 
     (
 
      .depth(`CL+1),
 
      .width(1)
 
      )
 
   delay1
 
     (
 
      .d(rd_ack),
 
      .q(fifo_we),
 
      .clear(clear | terminate),
 
      .clk(sdram_clk),
 
      .rst(wb_rst)
 
      );
 
 
 
`ifdef SDRAM16
 
   assign wr_ack_o = wr_ack & burst_counter[0];
 
`endif
 
 
 
 
 
   // wishbone buffer
 
   wb_sdram_ctrl_fifo fifo
 
     (
 
      .d_i(sdr_dq_i),
 
      .we_i(fifo_we),
 
      .clear(clear | terminate),
 
      .clk_i(sdram_clk),
 
      .wb_dat_o(wb_dat_o),
 
      .wb_cyc_i(wb_cyc_i),
 
      .wb_stb_i(wb_stb_i),
 
      .wb_ack_o(rd_ack_o),
 
      .wb_clk(wb_clk),
 
      .rst(wb_rst)
 
   );
 
 
 
 
 
   assign terminate = ~wb_cyc_i & ~wb_stb_i;
 
   assign adr_fail = ~(wb_adr_i[`WB_ADR_HI:4]=={ba,row,burst_counter[`COL_SIZE-1:3]});
 
   assign clear = adr_fail & rd_ack_o;
 
 
 
   assign wb_ack_o = (rd_ack_o & !adr_fail) | wr_ack_o;
 
 
 
endmodule // wb_sdram_ctrl
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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