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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [actel/] [ordb1a3pe1500/] [rtl/] [verilog/] [versatile_mem_ctrl/] [rtl/] [verilog/] [fsm_sdr_16.v] - Blame information for rev 408

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 408 julius
`timescale 1ns/1ns
2
`include "sdr_16_defines.v"
3
module fsm_sdr_16 (
4
                   adr_i, we_i, bte_i, cti_i, sel_i,
5
                   fifo_empty, fifo_rd_adr, fifo_rd_data, count0,
6
                   refresh_req, cmd_aref, cmd_read, state_idle,
7
                   ba, a, cmd, dqm, dq_oe,
8
                   sdram_burst_reading,
9
                   debug_state, debug_fifo_we_record,
10
                   sdram_clk, sdram_fifo_wr, sdram_rst
11
                   );
12
 
13
   /* Now these are defined
14
    parameter ba_size = 2;
15
    parameter row_size = 13;
16
    parameter col_size = 9;
17
    */
18
 
19
   input [`BA_SIZE+`ROW_SIZE+`COL_SIZE-1:0] adr_i;
20
   input                                 we_i;
21
   input [1:0]                            bte_i;
22
   input [2:0]                            cti_i;
23
   input [3:0]                            sel_i;
24
 
25
   input                                 fifo_empty;
26
   output                                fifo_rd_adr, fifo_rd_data;
27
   output reg                            count0;
28
 
29
   input                                 refresh_req;
30
   output reg                            cmd_aref; // used for rerfresh ack
31
   output reg                            cmd_read; // used for ingress fifo control
32
   output                                state_idle; // state=idle
33
 
34
   output reg [1:0]                       ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
35
   output reg [12:0]                      a /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
36
   output reg [2:0]                       cmd /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
37
   output reg [1:0]                       dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
38
   output reg                            dq_oe;
39
 
40
   output                                sdram_burst_reading;
41
   input                                 sdram_clk, sdram_fifo_wr, sdram_rst;
42
 
43
   output [2:0]                   debug_state;
44
   output [3:0]                   debug_fifo_we_record;
45
 
46
   wire [`BA_SIZE-1:0]                    bank;
47
   wire [`ROW_SIZE-1:0]                   row;
48
   wire [`COL_SIZE-1:0]                   col;
49
   wire [12:0]                            col_reg_a10_fix;
50
   reg [0:31]                             shreg;
51
   wire                                  stall; // active if write burst need data
52
 
53
   reg [0:15]                             fifo_sel_reg_int;
54
   reg [1:0]                              fifo_sel_domain_reg_int;
55
 
56
   // adr_reg {ba,row,col,we}
57
   reg [1:0]                              ba_reg;
58
   reg [`ROW_SIZE-1:0]                    row_reg;
59
   reg [`COL_SIZE-1:0]                    col_reg;
60
   reg                                   we_reg;
61
   reg [1:0]                              bte_reg;
62
   reg [2:0]                              cti_reg;
63
 
64
   // to keep track of open rows per bank
65
   reg [`ROW_SIZE-1:0]                    open_row[0:3];
66
   reg [0:3]                              open_ba;
67
   wire                                  current_bank_closed, current_row_open;
68
   reg                                   current_bank_closed_reg, current_row_open_reg;
69
 
70
   parameter [2:0] classic=3'b000,
71
                constant=3'b001,
72
                increment=3'b010,
73
                endburst=3'b111;
74
 
75
   parameter [1:0] linear = 2'b00,
76
                beat4  = 2'b01,
77
                beat8  = 2'b10,
78
                beat16 = 2'b11;
79
 
80
   parameter [2:0] cmd_nop = 3'b111,
81
                cmd_act = 3'b011,
82
                cmd_rd  = 3'b101,
83
                cmd_wr  = 3'b100,
84
                cmd_pch = 3'b010,
85
                cmd_rfr = 3'b001,
86
                cmd_lmr = 3'b000;
87
 
88
   // ctrl FSM
89
 
90
/*    define instead of param, as synplify is doing weird things
91
 parameter [2:0] init = 3'b000,
92
                idle = 3'b001,
93
                rfr  = 3'b010,
94
                adr  = 3'b011,
95
                pch  = 3'b100,
96
                act  = 3'b101,
97
                w4d  = 3'b110,
98
                rw   = 3'b111;
99
 */
100
`define FSM_INIT 3'b000
101
`define FSM_IDLE 3'b001
102
`define FSM_RFR  3'b010
103
`define FSM_ADR  3'b011
104
`define FSM_PCH  3'b100
105
`define FSM_ACT  3'b101
106
`define FSM_W4D  3'b110
107
`define FSM_RW   3'b111
108
 
109
   reg [2:0]                              state, next;
110
 
111
   assign debug_state = state;
112
 
113
   function [12:0] a10_fix;
114
      input [`COL_SIZE-1:0]               a;
115
      integer                            i;
116
      begin
117
         for (i=0;i<13;i=i+1) begin
118
            if (i<10)
119
              if (i<`COL_SIZE)
120
                a10_fix[i] = a[i];
121
              else
122
                a10_fix[i] = 1'b0;
123
            else if (i==10)
124
              a10_fix[i] = 1'b0;
125
            else
126
              if (i<`COL_SIZE)
127
                a10_fix[i] = a[i-1];
128
              else
129
                a10_fix[i] = 1'b0;
130
         end
131
      end
132
   endfunction
133
 
134
 
135
   assign {bank,row,col} = adr_i;
136
 
137
   always @ (posedge sdram_clk or posedge sdram_rst)
138
     if (sdram_rst)
139
       state <= `FSM_INIT;
140
     else
141
       state <= next;
142
 
143
   always @*
144
     begin
145
        next = 3'bx;
146
        case (state)
147
          `FSM_INIT:
148
            if (shreg[31])
149
              next = `FSM_IDLE;
150
            else
151
              next = `FSM_INIT;
152
          `FSM_IDLE:
153
            if (refresh_req)
154
              next = `FSM_RFR;
155
            else if (!shreg[0] & !fifo_empty)
156
              next = `FSM_ADR;
157
            else
158
              next = `FSM_IDLE;
159
          `FSM_RFR:
160
            if (shreg[5])
161
              next = `FSM_IDLE;
162
            else
163
              next = `FSM_RFR;
164
          `FSM_ADR:
165
            if (shreg[5])
166
              begin
167
                 if (current_bank_closed_reg)
168
                   next = `FSM_ACT;
169
                 else if (current_row_open_reg)
170
                   next = (we_reg) ?  `FSM_W4D : `FSM_RW;
171
                 else
172
                   next = `FSM_PCH;
173
              end
174
            else
175
              next = `FSM_ADR;
176
          `FSM_PCH:
177
            if (shreg[1])
178
              next = `FSM_ACT;
179
            else
180
              next = `FSM_PCH;
181
          `FSM_ACT:
182
            if (shreg[2])
183
              begin
184
`ifdef SLOW_WB_CLOCK
185
                 // Automatiacally go to wait for data if burst writing
186
                 if ((|bte_reg) & we_reg & cti_reg==increment)
187
                   next = `FSM_W4D;
188
                 else if ((!fifo_empty | !we_reg))
189
                   next = `FSM_RW;
190
`else
191
                 if ((!fifo_empty | !we_reg))
192
                   next = `FSM_RW;
193
`endif
194
                 else if (fifo_empty)
195
                   next = `FSM_W4D;
196
              end
197
            else
198
              next = `FSM_ACT;
199
`ifdef SLOW_WB_CLOCK
200
          // Add some wait here if bursting and the wishbone clock is slow
201
          `FSM_W4D:
202
            if (!fifo_empty & ((cti_reg!=increment)|(cti_reg==increment /*& bte_reg==beat4*/  & shreg[14])))
203
              next = `FSM_RW;
204
`else
205
          `FSM_W4D:
206
            if (!fifo_empty)
207
              next = `FSM_RW;
208
`endif
209
            else
210
              next = `FSM_W4D;
211
          `FSM_RW:
212
            if ((bte_reg==linear | !(cti_reg==increment)) & shreg[1])
213
              next = `FSM_IDLE;
214
            else if (bte_reg==beat4 & shreg[7])
215
              next = `FSM_IDLE;
216
`ifdef BEAT8
217
            else if (bte_reg==beat8 & shreg[15])
218
              next = `FSM_IDLE;
219
`endif
220
`ifdef BEAT16
221
            else if (bte_reg==beat16 & shreg[31])
222
              next = `FSM_IDLE;
223
`endif
224
            else
225
              next = `FSM_RW;
226
        endcase
227
     end // always @ *
228
 
229
 
230
   // active if write burst need data
231
   assign stall = state==`FSM_RW & next==`FSM_RW & fifo_empty & count0 & we_reg;
232
 
233
   // counter
234
   always @ (posedge sdram_clk or posedge sdram_rst)
235
     begin
236
        if (sdram_rst) begin
237
           shreg   <= {1'b1,{31{1'b0}}};
238
           count0  <= 1'b0;
239
        end else
240
          if (state!=next) begin
241
             shreg   <= {1'b1,{31{1'b0}}};
242
             count0  <= 1'b0;
243
          end else
244
            if (~stall) begin
245
               shreg   <= shreg >> 1;
246
               count0  <= ~count0;
247
            end
248
     end
249
 
250
   // ba, a, cmd
251
   // col_reg_a10 has bit [10] set to zero to disable auto precharge
252
   assign col_reg_a10_fix = a10_fix(col_reg);
253
 
254
   // outputs dependent on state vector
255
   always @ (posedge sdram_clk or posedge sdram_rst)
256
     begin
257
        if (sdram_rst) begin
258
           {ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
259
           dqm <= 2'b11;
260
           cmd_aref <= 1'b0;
261
           cmd_read <= 1'b0;
262
           dq_oe <= 1'b0;
263
           {open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <=
264
                                                  {4'b0000,{`ROW_SIZE*4{1'b0}}};
265
           {ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
266
                     {2'b00, {`ROW_SIZE{1'b0}}, {`COL_SIZE{1'b0}}, 1'b0,3'b000, 2'b00 };
267
        end else begin
268
           {ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
269
           dqm <= 2'b11;
270
           cmd_aref <= 1'b0;
271
           cmd_read <= 1'b0;
272
           dq_oe <= 1'b0;
273
           case (state)
274
             `FSM_INIT:
275
               if (shreg[3]) begin
276
                  {ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
277
                  open_ba[ba_reg] <= 1'b0;
278
               end else if (shreg[7] | shreg[19])
279
                 {ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
280
               else if (shreg[31])
281
                 {ba,a,cmd} <=
282
                  {2'b00,3'b000,`INIT_WB,2'b00,`INIT_CL,`INIT_BT,`INIT_BL, cmd_lmr};
283
             `FSM_RFR:
284
               if (shreg[0]) begin
285
                  {ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
286
                  open_ba <= 4'b0000;
287
               end else if (shreg[2])
288
                 {ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
289
             `FSM_ADR:
290
               if (shreg[4])
291
                 {ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
292
                                                {bank,row,col,we_i,cti_i,bte_i};
293
             `FSM_PCH:
294
               if (shreg[0]) begin
295
                  {ba,a,cmd} <= {ba_reg,13'd0,cmd_pch};
296
                  //open_ba <= 4'b0000;
297
                  open_ba[ba_reg] <= 1'b0;
298
               end
299
             `FSM_ACT:
300
               if (shreg[0]) begin
301
                  {ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act};
302
                  {open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg};
303
               end
304
             `FSM_RW:
305
               begin
306
                  if (we_reg & !count0)
307
                    cmd <= cmd_wr;
308
                  else if (!count0)
309
                    {cmd,cmd_read} <= {cmd_rd,1'b1};
310
                  else
311
                    cmd <= cmd_nop;
312
                  if (we_reg)
313
                    begin
314
                       dqm <= count0 ? ~sel_i[1:0] : ~sel_i[3:2];
315
                    end
316
                  else
317
                    dqm <= 2'b00;
318
                  //if (we_reg)
319
                  dq_oe <= we_reg;//1'b1;
320
                  if (!stall)
321
                    begin
322
                       if (cti_reg==increment)
323
                         case (bte_reg)
324
                           linear: {ba,a} <= {ba_reg,col_reg_a10_fix};
325
                           beat4:  {ba,a,col_reg[2:0]} <=
326
                                  {ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1};
327
          `ifdef BEAT8
328
                           beat8:  {ba,a,col_reg[3:0]} <=
329
                                  {ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1};
330
          `endif
331
          `ifdef BEAT16
332
                           beat16: {ba,a,col_reg[4:0]} <=
333
                                  {ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1};
334
          `endif
335
                         endcase // case (bte_reg)
336
                       else
337
                         {ba,a} <= {ba_reg,col_reg_a10_fix};
338
 
339
                    end // if (!stall)
340
               end
341
                           endcase
342
        end
343
     end
344
 
345
   reg fifo_read_data_en;
346
   always @(posedge sdram_clk)
347
     if (sdram_rst)
348
       fifo_read_data_en <= 1;
349
     else if (next==`FSM_RW)
350
       fifo_read_data_en <= ~fifo_read_data_en;
351
     else
352
       fifo_read_data_en <= 1;
353
 
354
   reg [3:0] beat4_data_read_limiter; // Use this to record how many times we've pulsed fifo_rd_data
355
   // Only 3 bits, becuase we're looking at when fifo_read_data_en goes low - should only happen 3
356
   // times for a 4-beat burst
357
   always @(posedge sdram_clk)
358
     if (sdram_rst)
359
       beat4_data_read_limiter <= 0;
360
     else if(state==`FSM_ADR)
361
       beat4_data_read_limiter <= 0;
362
     else if (!fifo_read_data_en)
363
       beat4_data_read_limiter <= {beat4_data_read_limiter[2:0],1'b1};
364
 
365
 
366
 
367
   // rd_adr goes high when next adr is fetched from sync RAM and during write burst
368
   assign fifo_rd_adr  = state==`FSM_ADR & shreg[1];
369
 
370
   assign fifo_rd_data = (((state!=`FSM_RW & next==`FSM_RW)|(state==`FSM_RW & (cti_reg==increment && bte_reg==beat4 & fifo_read_data_en & !(&beat4_data_read_limiter)))) & we_reg & !fifo_empty);
371
 
372
   /*
373
   assign fifo_rd_data = ((state==`FSM_RW & next==`FSM_RW) &
374
                          we_reg & !count0 & !fifo_empty);
375
*/
376
   assign state_idle = (state==`FSM_IDLE);
377
 
378
   // bank and row open ?
379
   assign current_bank_closed = !(open_ba[bank]);
380
   assign current_row_open = open_row[bank]==row;
381
 
382
   always @ (posedge sdram_clk or posedge sdram_rst)
383
     if (sdram_rst)
384
       {current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0};
385
     else
386
       //if (state==adr & counter[1:0]==2'b10)
387
       {current_bank_closed_reg, current_row_open_reg} <=
388
                                        {current_bank_closed, current_row_open};
389
 
390
   // Record the number of write enables going to INGRESS fifo (ie. that we 
391
   // generate when we're reading) - this makes sure we keep track of when a
392
   // burst read is in progress, and we can signal the wishbone bus to wait
393
   // for this data to be put into the FIFO before it'll empty it when it's
394
   // had a terminated burst transfer.
395
   reg [3:0] fifo_we_record;
396
   assign debug_fifo_we_record = fifo_we_record;
397
   always @(posedge sdram_clk)
398
     if (sdram_rst)
399
       fifo_we_record <= 0;
400
     else if (next==`FSM_RW & ((state==`FSM_ADR)|(state==`FSM_ACT)) &
401
              cti_reg==increment & (bte_reg==beat4) & !we_reg)
402
       fifo_we_record <= 4'b0001;
403
     else if (sdram_fifo_wr)
404
       fifo_we_record <= {fifo_we_record[2:0],1'b0};
405
`ifdef SDRAM_WB_SAME_CLOCKS
406
   assign sdram_burst_reading = |fifo_we_record;
407
`else
408
   assign sdram_burst_reading = 0;
409
`endif
410
 
411
 
412
endmodule

powered by: WebSVN 2.1.0

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