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] - Blame information for rev 60

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 unneback
`include "wb_sdram_ctrl_defines.v"
2
module `MODULE_NAME
3
  (
4
   // wishbone i/f
5
    input [31:0]      wb_dat_i,
6
    output [31:0]     wb_dat_o,
7
    input [3:0]       wb_sel_i,
8
    input [`WB_ADR_HI:2]      wb_adr_i,
9
    input             wb_we_i,
10
    input [2:0]       wb_cti_i,
11
    input             wb_stb_i,
12
    input             wb_cyc_i,
13
    output            wb_ack_o,
14
   // SDRAM IO
15
    output            sdr_cke_o,
16
    output reg        sdr_cs_n_o,
17
    output reg        sdr_ras_n_o,
18
    output reg        sdr_cas_n_o,
19
    output reg        sdr_we_n_o,
20
    output reg [12:0] sdr_a_o,
21
    output reg  [1:0] sdr_ba_o,
22
    inout [`SDRAM_DATA_WIDTH-1:0] sdr_dq_io,
23
    output reg [`SDRAM_DATA_WIDTH/8-1:0] sdr_dqm_o,
24
   // system
25
    input sdram_clk,
26
    input wb_clk,
27
    input wb_rst
28
   );
29
 
30
   reg    ref_req;
31
   wire   ref_ack;
32 43 julius
   /* verilator lint_off UNOPTFLAT */
33 18 unneback
   wire   rd_ack, rd_ack_o, wr_ack, wr_ack_o, cmd_ack;
34 43 julius
   /* verilator lint_on UNOPTFLAT */
35 18 unneback
   reg [`BA_SIZE-1:0] ba;
36
   reg [`ROW_SIZE-1:0] row;
37
 
38
   // terminate current cycle if !stb&!cyc, empty fifo
39
   // restart if adr_fail (non consecutive adr inc), empty fifo
40
   wire   terminate, adr_fail, clear;
41
 
42
   wire   end_of_burst;
43
   wire   burst_counter_set;
44
   reg [`COL_SIZE-1:0]  burst_counter;
45
`ifdef SDRAM16
46
   wire [`BURST_SIZE:0] burst_counter_next;
47
   reg [`BURST_SIZE:0]   burst_counter_init;
48
`endif
49
 
50
   wire                 fifo_we;
51
 
52
   wire [1:0]  sdr_ba;
53
   wire [12:0] sdr_a;
54
 
55
   reg         sdr_dq_oe_reg;
56
   wire [`SDRAM_DATA_WIDTH-1:0] sdr_dq_i, sdr_dq_o;
57
   wire [`SDRAM_DATA_WIDTH/8-1:0] sdr_dqm;
58
 
59
   // counter 100us delay and refresh interval
60
   reg [12:0] counter;
61
   wire       counter_zf; // counter zero flag
62
   assign counter_zf = (counter==13'd0);
63
   always @ (posedge wb_clk or posedge wb_rst)
64
     if (wb_rst)
65
       counter <= 13'd`DLY_INIT;
66
     else if (counter_zf)
67
       counter <= 13'd`AREF_INIT;
68
     else
69
       counter <= counter - 13'd1;
70
 
71
   always @ (posedge wb_clk or posedge wb_rst)
72
     if (wb_rst)
73
       ref_req <= 1'b0;
74
     else
75
       if (counter_zf)
76
         ref_req <= 1'b1;
77
       else if (ref_ack)
78
         ref_req <= 1'b0;
79
 
80
`ifdef SDRAM16
81
   assign burst_counter_next = burst_counter[`BURST_SIZE:0] + {{`BURST_SIZE{1'b0}},1'b1};
82
   always @ (posedge sdram_clk or posedge wb_rst)
83
     if (wb_rst)
84
       begin
85
          ba <= `BA_SIZE'd0;
86
          row <= `ROW_SIZE'd0;
87
          burst_counter_init <= `BURST_SIZE'd0;
88
          burst_counter <= `COL_SIZE'd0;
89
       end
90
     else
91
       if (burst_counter_set)
92
         begin
93
            ba <= `BA;
94 38 julius
            row <= `ROW;
95
            // A fix of the fix.
96
            // We previously adjusted the burst_counter, which is very important - it determines the address
97
            // we generate and use for the SDRAM column addressing.
98
            // So instead, when we receive an (arguably incorrect) access request, with the cycle indicator
99
            // showing "burst end" (wb_cti_i=3'b111), we change burst_counter_init so it should show that
100
            // the transfer will end after a single 32-bit word transaction has taken place (2 16-bit word
101
            // transactions)
102
            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};
103
            burst_counter <= {wb_adr_i[`COL_SIZE+2:2],1'b0};
104 18 unneback
         end
105
       else if (rd_ack | wr_ack)
106
         begin
107
            burst_counter[`BURST_SIZE:0] <= burst_counter_next;
108
         end
109
   assign end_of_burst = (wb_cti_i==3'b000) ? (burst_counter[0]==1'b1) : (burst_counter_next == burst_counter_init);
110
`endif
111
 
112
   wb_sdram_ctrl_fsm fsm0
113
     (
114
      .dly_100us(counter_zf),
115
      .ref_req(ref_req),
116
      .ref_ack(ref_ack),
117
      .accept_cmd(burst_counter_set),
118
      .rd_ack(rd_ack),
119
      .wr_ack(wr_ack),
120
      .clear(clear),
121
      .wb_stb(wb_stb_i),
122
      .wb_cyc(wb_cyc_i),
123
      .wb_we(wb_we_i),
124
      .wb_ack(wb_ack_o & ((wb_cti_i==3'b000) | (wb_cti_i==3'b111))),
125
      .end_of_burst(end_of_burst),
126
      .wb_adr_i({`BA,`ROW,burst_counter}),
127
      .a({sdr_ba,sdr_a}),
128
      .cmd(`CMD),
129
      .cs_n(sdr_cs_n),
130
      .sdram_clk(sdram_clk),
131
      .wb_rst(wb_rst)
132
      );
133
 
134
`ifdef SDRAM16
135
   assign sdr_dqm = ((burst_counter[0]==1'b0) & wr_ack) ? ~wb_sel_i[3:2] :
136
                    ((burst_counter[0]==1'b1) & wr_ack) ? ~wb_sel_i[1:0] :
137
                    2'b00;
138
`endif
139
 
140
   // output registers
141
   always @ (posedge sdram_clk or posedge wb_rst)
142
     if (wb_rst)
143
       begin
144
          sdr_cs_n_o <= 1'b1;
145
          {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= `CMD_NOP;
146
          {sdr_ba_o,sdr_a_o} <= 15'd0;
147
          sdr_dqm_o <= {`SDRAM_DATA_WIDTH/8{1'b0}};
148
       end
149
     else
150
       begin
151
          sdr_cs_n_o <= #1 sdr_cs_n;
152
          {sdr_ras_n_o, sdr_cas_n_o, sdr_we_n_o} <= #1 `CMD;
153
          {sdr_ba_o,sdr_a_o} <= #1 {sdr_ba,sdr_a};
154
          sdr_dqm_o <= #1 sdr_dqm;
155
  end
156
 
157
   assign sdr_cke_o = 1'b1;
158
 
159
`ifdef SDRAM16
160
   assign sdr_dq_o = (burst_counter[0]==1'b0) ? wb_dat_i[31:16] : wb_dat_i[15:0];
161
`endif
162
 
163
   // Tristate driver for data bus
164 22 julius
//   assign sdr_dq_oe = wr_ack; -- sdr_dq_oe was not declared! changed its only reference --jb
165 18 unneback
   reg [`SDRAM_DATA_WIDTH-1:0] sdr_dq_o_reg;
166
   always @ (posedge sdram_clk or posedge wb_rst)
167
     if (wb_rst)
168
       {sdr_dq_oe_reg,sdr_dq_o_reg} <= {1'b0,`SDRAM_DATA_WIDTH'd0};
169
     else
170 22 julius
       {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
171 18 unneback
 
172
   assign #1 sdr_dq_io = sdr_dq_oe_reg ? sdr_dq_o_reg : {`SDRAM_DATA_WIDTH{1'bz}};
173
   assign #1 sdr_dq_i = sdr_dq_io;
174
 
175
   // delay fifo_fill in accordance to cas latency
176
   delay #
177
     (
178
      .depth(`CL+1),
179
      .width(1)
180
      )
181
   delay1
182
     (
183
      .d(rd_ack),
184
      .q(fifo_we),
185
      .clear(clear | terminate),
186
      .clk(sdram_clk),
187
      .rst(wb_rst)
188
      );
189
 
190
`ifdef SDRAM16
191
   assign wr_ack_o = wr_ack & burst_counter[0];
192
`endif
193
 
194
 
195
   // wishbone buffer
196
   wb_sdram_ctrl_fifo fifo
197
     (
198
      .d_i(sdr_dq_i),
199
      .we_i(fifo_we),
200
      .clear(clear | terminate),
201
      .clk_i(sdram_clk),
202
      .wb_dat_o(wb_dat_o),
203
      .wb_cyc_i(wb_cyc_i),
204
      .wb_stb_i(wb_stb_i),
205
      .wb_ack_o(rd_ack_o),
206
      .wb_clk(wb_clk),
207
      .rst(wb_rst)
208
   );
209
 
210 37 julius
 
211 18 unneback
   assign terminate = ~wb_cyc_i & ~wb_stb_i;
212
   assign adr_fail = ~(wb_adr_i[`WB_ADR_HI:4]=={ba,row,burst_counter[`COL_SIZE-1:3]});
213
   assign clear = adr_fail & rd_ack_o;
214 43 julius
/* verilator lint_off UNOPTFLAT */
215 18 unneback
   assign wb_ack_o = (rd_ack_o & !adr_fail) | wr_ack_o;
216 43 julius
/* verilator lint_on UNOPTFLAT */
217 18 unneback
endmodule // wb_sdram_ctrl

powered by: WebSVN 2.1.0

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