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

Subversion Repositories versatile_mem_ctrl

[/] [versatile_mem_ctrl/] [trunk/] [rtl/] [verilog/] [sdr_sdram_ctrl.v] - Blame information for rev 111

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 111 unneback
//`include "versatile_mem_ctrl_defines.v"
2
`ifdef SDR
3
`timescale 1ns/1ns
4
`define MODULE sdr16
5
module `BASE`MODULE (
6
`undef MODULE
7
    // wisbone i/f
8
`ifdef SDR_NO_BURST
9
    dat_i, adr_i, sel_i, we_i, cyc_i, stb_i, dat_o, ack_o,
10
`else
11
    dat_i, adr_i, sel_i, bte_i, we_i, cyc_i, stb_i, dat_o, ack_o,
12
`endif
13
    // SDR SDRAM
14
    ba, a, cmd, cke, cs_n, dqm, dq_i, dq_o, dq_oe,
15
    // system
16
    clk, rst);
17
 
18
    // external data bus size
19
    parameter dat_size = `SDR_SDRAM_DATA_WIDTH;
20
 
21
    // memory geometry parameters
22
    parameter ba_size  = `SDR_BA_SIZE;
23
    parameter row_size = `SDR_ROW_SIZE;
24
    parameter col_size = `SDR_COL_SIZE;
25
    parameter cl = `SDR_INIT_CL;
26
    // memory timing parameters
27
    parameter tRFC = `SDR_TRFC;
28
    parameter tRP  = `SDR_TRP;
29
    parameter tRCD = `SDR_TRCD;
30
    parameter tMRD = `SDR_TMRD;
31
 
32
    // LMR
33
    // [12:10] reserved
34
    // [9]     WB, write burst; 0 - programmed burst length, 1 - single location
35
    // [8:7]   OP Mode, 2'b00
36
    // [6:4]   CAS Latency; 3'b010 - 2, 3'b011 - 3
37
    // [3]     BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved
38
    // [2:0]   Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page
39
    parameter init_wb = `SDR_INIT_WB;
40
    parameter init_cl = `SDR_INIT_CL;
41
    parameter init_bt = `SDR_INIT_BT;
42
    parameter init_bl = `SDR_INIT_BL;
43
 
44
    input [31:0] dat_i;
45
    input [ba_size+col_size+row_size:1] adr_i;
46
    input [3:0] sel_i;
47
`ifndef SDR_NO_BURST
48
    input [1:0] bte_i;
49
`endif
50
    input we_i, cyc_i, stb_i;
51
    output [31:0] dat_o;
52
    output ack_o;
53
 
54
    output [ba_size-1:0]    ba;
55
    output reg [12:0]   a;
56
    output reg [2:0]    cmd; // {ras,cas,we}
57
    output cke, cs_n;
58
    output reg [1:0]    dqm;
59
    output [dat_size-1:0]       dq_o;
60
    output reg          dq_oe;
61
    input  [dat_size-1:0]       dq_i;
62
 
63
    input clk, rst;
64
 
65
    wire [ba_size-1:0]   bank;
66
    wire [row_size-1:0] row;
67
    wire [col_size-1:0] col;
68
    wire [12:0]         col_a10_fix;
69
`ifdef SDR_BEAT16
70
    parameter col_reg_width = 5;
71
    reg [4:0]            col_reg;
72
`else
73
`ifdef SDR_BEAT8
74
    parameter col_reg_width = 4;
75
    reg [3:0]            col_reg;
76
`else
77
`ifdef SDR_BEAT4
78
    parameter col_reg_width = 3;
79
    reg [2:0]            col_reg;
80
`endif
81
`endif
82
`endif
83
    wire [0:31]  shreg;
84
    wire                count0;
85
    wire                stall; // active if write burst need data
86
    wire                ref_cnt_zero;
87
    reg                 refresh_req;
88
 
89
    wire ack_rd, rd_ack_emptyflag;
90
    wire ack_wr;
91
 
92
    // to keep track of open rows per bank
93
    reg [row_size-1:0]   open_row[0:3];
94
    reg [0:3]            open_ba;
95
    reg                 current_bank_closed, current_row_open;
96
 
97
`ifndef SDR_RFR_WRAP_VALUE
98
    parameter rfr_length = 10;
99
    parameter rfr_wrap_value = 1010;
100
`else
101
    parameter rfr_length = `SDR_RFR_LENGTH;
102
    parameter rfr_wrap_value = `SDR_RFR_WRAP_VALUE;
103
`endif
104
 
105
    // cti
106
    parameter [2:0] classic = 3'b000,
107
                    endofburst = 3'b111;
108
 
109
    // bte      
110
    parameter [1:0] linear = 2'b00,
111
                    beat4  = 2'b01,
112
                    beat8  = 2'b10,
113
                    beat16 = 2'b11;
114
 
115
    parameter [2:0] cmd_nop = 3'b111,
116
                    cmd_act = 3'b011,
117
                    cmd_rd  = 3'b101,
118
                    cmd_wr  = 3'b100,
119
                    cmd_pch = 3'b010,
120
                    cmd_rfr = 3'b001,
121
                    cmd_lmr = 3'b000;
122
 
123
// ctrl FSM
124
`define FSM_INIT 3'b000
125
`define FSM_IDLE 3'b001
126
`define FSM_RFR  3'b010
127
`define FSM_ADR  3'b011
128
`define FSM_PCH  3'b100
129
`define FSM_ACT  3'b101
130
`define FSM_RW   3'b111
131
 
132
    assign cke = 1'b1;
133
    assign cs_n = 1'b0;
134
 
135
    reg [2:0] state, next;
136
 
137
    function [12:0] a10_fix;
138
        input [col_size-1:0] a;
139
        integer i;
140
    begin
141
        for (i=0;i<13;i=i+1) begin
142
            if (i<10)
143
              if (i<col_size)
144
                a10_fix[i] = a[i];
145
              else
146
                a10_fix[i] = 1'b0;
147
            else if (i==10)
148
              a10_fix[i] = 1'b0;
149
            else
150
              if (i<col_size)
151
                a10_fix[i] = a[i-1];
152
              else
153
                a10_fix[i] = 1'b0;
154
        end
155
    end
156
    endfunction
157
 
158
    assign {bank,row,col} = adr_i;
159
 
160
    always @ (posedge clk or posedge rst)
161
    if (rst)
162
       state <= `FSM_INIT;
163
    else
164
       state <= next;
165
 
166
    always @*
167
    begin
168
        next = state;
169
        case (state)
170
        `FSM_INIT:
171
            if (shreg[3+tRP+tRFC+tRFC+tMRD]) next = `FSM_IDLE;
172
        `FSM_IDLE:
173
            if (refresh_req) next = `FSM_RFR;
174
            else if (cyc_i & stb_i & rd_ack_emptyflag) next = `FSM_ADR;
175
        `FSM_RFR:
176
            if (shreg[tRP+tRFC-2]) next = `FSM_IDLE; // take away two cycles because no cmd will be issued in idle and adr
177
        `FSM_ADR:
178
            if (current_bank_closed) next = `FSM_ACT;
179
            else if (current_row_open) next = `FSM_RW;
180
            else next = `FSM_PCH;
181
        `FSM_PCH:
182
            if (shreg[tRP]) next = `FSM_ACT;
183
        `FSM_ACT:
184
            if (shreg[tRCD]) next = `FSM_RW;
185
        `FSM_RW:
186
`ifdef SDR_NO_BURST
187
            if (shreg[1]) next = `FSM_IDLE;
188
`else
189
            if (bte_i==linear & shreg[1]) next = `FSM_IDLE;
190
`ifdef SDR_BEAT4
191
            else if (bte_i==beat4 & shreg[7]) next = `FSM_IDLE;
192
`endif
193
`ifdef SDR_BEAT8
194
            else if (bte_i==beat8 & shreg[15]) next = `FSM_IDLE;
195
`endif
196
`ifdef SDR_BEAT16
197
            else if (bte_i==beat16 & shreg[31]) next = `FSM_IDLE;
198
`endif
199
`endif
200
        endcase
201
    end
202
 
203
    // active if write burst need data
204
    assign stall = state==`FSM_RW & next==`FSM_RW & ~stb_i & count0 & we_i;
205
 
206
    // counter
207
`define MODULE cnt_shreg_ce_clear
208
    `VLBASE`MODULE # ( .length(32))
209
`undef MODULE
210
        cnt0 (
211
            .cke(!stall),
212
            .clear(state!=next),
213
            .q(shreg),
214
            .rst(rst),
215
            .clk(clk));
216
 
217
`define MODULE dff_ce_clear
218
    `VLBASE`MODULE
219
`undef MODULE
220
        dff_count0 (
221
            .d(!count0),
222
            .ce(!stall),
223
            .clear(state!=next),
224
            .q(count0),
225
            .rst(rst),
226
            .clk(clk));
227
 
228
    // ba, a, cmd
229
    // col_reg_a10 has bit [10] set to zero to disable auto precharge
230
`ifdef SDR_NO_BURST
231
    assign col_a10_fix = a10_fix(col);
232
`else
233
    assign col_a10_fix = a10_fix({col[col_size-1:col_reg_width],col_reg});
234
`endif
235
 
236
    // outputs dependent on state vector
237
    always @ (*)
238
        begin
239
            {a,cmd} = {13'd0,cmd_nop};
240
            dqm = 2'b11;
241
            dq_oe = 1'b0;
242
            case (state)
243
            `FSM_INIT:
244
                if (shreg[3]) begin
245
                    {a,cmd} = {13'b0010000000000, cmd_pch};
246
                end else if (shreg[3+tRP] | shreg[3+tRP+tRFC])
247
                    {a,cmd} = {13'd0, cmd_rfr};
248
                else if (shreg[3+tRP+tRFC+tRFC])
249
                    {a,cmd} = {3'b000,init_wb,2'b00,init_cl,init_bt,init_bl,cmd_lmr};
250
            `FSM_RFR:
251
                if (shreg[0])
252
                    {a,cmd} = {13'b0010000000000, cmd_pch};
253
                else if (shreg[tRP])
254
                    {a,cmd} = {13'd0, cmd_rfr};
255
            `FSM_PCH:
256
                if (shreg[0])
257
                    {a,cmd} = {13'd0,cmd_pch};
258
            `FSM_ACT:
259
                if (shreg[0])
260
                    {a[row_size-1:0],cmd} = {row,cmd_act};
261
            `FSM_RW:
262
                begin
263
                    if (we_i & !count0)
264
                        cmd = cmd_wr;
265
                    else if (!count0)
266
                        cmd = cmd_rd;
267
                    else
268
                        cmd = cmd_nop;
269
                    if (we_i & !count0)
270
                        dqm = ~sel_i[3:2];
271
                    else if (we_i & count0)
272
                        dqm = ~sel_i[1:0];
273
                    else
274
                        dqm = 2'b00;
275
                    if (we_i)
276
                        dq_oe = 1'b1;
277
                    if (~stall)
278
                        a = col_a10_fix;
279
                end
280
            endcase
281
        end
282
 
283
    assign ba = bank;
284
 
285
    // precharge individual bank A10=0
286
    // precharge all bank A10=1
287
    genvar i;
288
    generate
289
    for (i=0;i<2<<ba_size-1;i=i+1) begin
290
 
291
        always @ (posedge clk or posedge rst)
292
        if (rst)
293
            {open_ba[i],open_row[i]} <= {1'b0,{row_size{1'b0}}};
294
        else
295
            if (cmd==cmd_pch & (a[10] | bank==i))
296
                open_ba[i] <= 1'b0;
297
            else if (cmd==cmd_act & bank==i)
298
                {open_ba[i],open_row[i]} <= {1'b1,row};
299
 
300
    end
301
    endgenerate
302
 
303
`ifndef SDR_NO_BURST
304
    always @ (posedge clk or posedge rst)
305
        if (rst)
306
           col_reg <= {col_reg_width{1'b0}};
307
        else
308
            case (state)
309
            `FSM_IDLE:
310
               col_reg <= col[col_reg_width-1:0];
311
            `FSM_RW:
312
               if (~stall)
313
                  case (bte_i)
314
`ifdef SDR_BEAT4
315
                        beat4:  col_reg[2:0] <= col_reg[2:0] + 3'd1;
316
`endif
317
`ifdef SDR_BEAT8
318
                        beat8:  col_reg[3:0] <= col_reg[3:0] + 4'd1;
319
`endif
320
`ifdef SDR_BEAT16
321
                        beat16: col_reg[4:0] <= col_reg[4:0] + 5'd1;
322
`endif
323
                  endcase
324
            endcase
325
`endif
326
 
327
    // bank and row open ?
328
    always @ (posedge clk or posedge rst)
329
    if (rst)
330
       {current_bank_closed, current_row_open} <= {1'b1, 1'b0};
331
    else
332
       {current_bank_closed, current_row_open} <= {!(open_ba[bank]), open_row[bank]==row};
333
 
334
    // refresh counter
335
`define MODULE cnt_lfsr_zq
336
    `VLBASE`MODULE # ( .length(rfr_length), .wrap_value (rfr_wrap_value)) ref_counter0( .zq(ref_cnt_zero), .rst(rst), .clk(clk));
337
`undef MODULE
338
 
339
    always @ (posedge clk or posedge rst)
340
    if (rst)
341
        refresh_req <= 1'b0;
342
    else
343
        if (ref_cnt_zero)
344
            refresh_req <= 1'b1;
345
        else if (state==`FSM_RFR)
346
            refresh_req <= 1'b0;
347
 
348
    assign dat_o[15:0] = dq_i;
349
`define MODULE dff
350
    `VLBASE`MODULE # ( .width(16)) wb_dat_dff ( .d(dat_o[15:0]), .q(dat_o[31:16]), .clk(clk), .rst(rst));
351
`undef MODULE
352
 
353
    assign ack_wr = (state==`FSM_RW & count0 & we_i);
354
 
355
`define MODULE delay_emptyflag
356
    `VLBASE`MODULE # ( .depth(cl+2)) delay0 ( .d(state==`FSM_RW & count0 & !we_i), .q(ack_rd), .emptyflag(rd_ack_emptyflag), .clk(clk), .rst(rst));
357
`undef MODULE
358
 
359
    assign ack_o = ack_rd | ack_wr;
360
 
361
    assign dq_o = (!count0) ? dat_i[31:16] : dat_i[15:0];
362
 
363
endmodule
364
`endif

powered by: WebSVN 2.1.0

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