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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [rtl/] [wbsdram.v] - Blame information for rev 102

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

Line No. Rev Author Line
1 2 dgisselq
///////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    wbsdram.v
4
//
5
// Project:     XuLA2 board
6
//
7
// Purpose:     Provide 32-bit wishbone access to the SDRAM memory on a XuLA2
8
//              LX-25 board.  Specifically, on each access, the controller will
9
//      activate an appropriate bank of RAM (the SDRAM has four banks), and
10
//      then issue the read/write command.  In the case of walking off the
11
//      bank, the controller will activate the next bank before you get to it.
12
//      Upon concluding any wishbone access, all banks will be precharged and
13
//      returned to idle.
14
//
15
//      This particular implementation represents a second generation version
16
//      because my first version was too complex.  To speed things up, this
17
//      version includes an extra wait state where the wishbone inputs are
18
//      clocked into a flip flop before any action is taken on them.
19
//
20
// Creator:     Dan Gisselquist, Ph.D.
21
//              Gisselquist Technology, LLC
22
//
23
///////////////////////////////////////////////////////////////////////////
24
//
25
// Copyright (C) 2015, Gisselquist Technology, LLC
26
//
27
// This program is free software (firmware): you can redistribute it and/or
28
// modify it under the terms of  the GNU General Public License as published
29
// by the Free Software Foundation, either version 3 of the License, or (at
30
// your option) any later version.
31
//
32
// This program is distributed in the hope that it will be useful, but WITHOUT
33
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
34
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
35
// for more details.
36
//
37
// You should have received a copy of the GNU General Public License along
38
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
39
// target there if the PDF file isn't present.)  If not, see
40
// <http://www.gnu.org/licenses/> for a copy.
41
//
42
// License:     GPL, v3, as defined and found on www.gnu.org,
43
//              http://www.gnu.org/licenses/gpl.html
44
//
45
//
46
/////////////////////////////////////////////////////////////////////////////
47
//
48
`define DMOD_GETINPUT   1'b0
49
`define DMOD_PUTOUTPUT  1'b1
50
`define RAM_OPERATIONAL 2'b00
51
`define RAM_POWER_UP    2'b01
52
`define RAM_SET_MODE    2'b10
53
`define RAM_INITIAL_REFRESH     2'b11
54
 
55
module  wbsdram(i_clk,
56
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
57
                        o_wb_ack, o_wb_stall, o_wb_data,
58
                o_ram_cs_n, o_ram_cke, o_ram_ras_n, o_ram_cas_n, o_ram_we_n,
59
                        o_ram_bs, o_ram_addr,
60
                        o_ram_dmod, i_ram_data, o_ram_data, o_ram_dqm,
61
                o_debug);
62
        parameter       RDLY = 6;
63
        input                   i_clk;
64
        // Wishbone
65
        //      inputs
66
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
67
        input           [22:0]   i_wb_addr;
68
        input           [31:0]   i_wb_data;
69
        //      outputs
70
        output  wire            o_wb_ack;
71
        output  reg             o_wb_stall;
72
        output  wire [31:0]      o_wb_data;
73
        // SDRAM control
74
        output  wire            o_ram_cke;
75
        output  reg             o_ram_cs_n,
76
                                o_ram_ras_n, o_ram_cas_n, o_ram_we_n;
77
        output  reg     [1:0]    o_ram_bs;
78
        output  reg     [12:0]   o_ram_addr;
79
        output  reg             o_ram_dmod;
80
        input           [15:0]   i_ram_data;
81
        output  reg     [15:0]   o_ram_data;
82
        output  reg     [1:0]    o_ram_dqm;
83
        output  wire    [31:0]   o_debug;
84
 
85
 
86
        // Calculate some metrics
87
 
88
        //
89
        // First, do we *need* a refresh now --- i.e., must we break out of
90
        // whatever we are doing to issue a refresh command?
91
        //
92
        // The step size here must be such that 8192 charges may be done in
93
        // 64 ms.  Thus for a clock of:
94
        //      ClkRate(MHz)    (64ms/1000(ms/s)*ClkRate)/8192
95
        //      100 MHz         781
96
        //       96 MHz         750
97
        //       92 MHz         718
98
        //       88 MHz         687
99
        //       84 MHz         656
100
        //       80 MHz         625
101
        //
102 46 dgisselq
        // However, since we do two refresh cycles everytime we need a refresh,
103
        // this standard is close to overkill--but we'll use it anyway.  At
104
        // some later time we should address this, once we are entirely
105
        // convinced that the memory is otherwise working without failure.  Of
106
        // course, at that time, it may no longer be a priority ...
107
        //
108 2 dgisselq
        reg             need_refresh;
109
        reg     [9:0]    refresh_clk;
110
        wire    refresh_cmd;
111
        assign  refresh_cmd = (~o_ram_cs_n)&&(~o_ram_ras_n)&&(~o_ram_cas_n)&&(o_ram_we_n);
112
        initial refresh_clk = 0;
113
        always @(posedge i_clk)
114
        begin
115
                if (refresh_cmd)
116
                        refresh_clk <= 10'd625; // Make suitable for 80 MHz clk
117
                else if (|refresh_clk)
118
                        refresh_clk <= refresh_clk - 10'h1;
119
        end
120
        initial need_refresh = 1'b0;
121
        always @(posedge i_clk)
122
                need_refresh <= (refresh_clk == 10'h00)&&(~refresh_cmd);
123
 
124
        reg     in_refresh;
125
        reg     [2:0]    in_refresh_clk;
126
        initial in_refresh_clk = 3'h0;
127
        always @(posedge i_clk)
128
                if (refresh_cmd)
129
                        in_refresh_clk <= 3'h6;
130
                else if (|in_refresh_clk)
131
                        in_refresh_clk <= in_refresh_clk - 3'h1;
132
        always @(posedge i_clk)
133
                in_refresh <= (in_refresh_clk != 3'h0)||(refresh_cmd);
134
 
135
 
136
        reg     [2:0]    bank_active     [0:3];
137
        reg     [(RDLY-1):0]     r_barrell_ack;
138
        reg             r_pending;
139
        reg             r_we;
140
        reg     [22:0]   r_addr;
141
        reg     [31:0]   r_data;
142
        reg     [12:0]   bank_row        [0:3];
143
 
144
 
145
        //
146
        // Second, do we *need* a precharge now --- must be break out of 
147
        // whatever we are doing to issue a precharge command?
148
        //
149
        // Keep in mind, the number of clocks to wait has to be reduced by
150
        // the amount of time it may take us to go into a precharge state.
151 46 dgisselq
        // You may also notice that the precharge requirement is tighter
152
        // than this one, so ... perhaps this isn't as required?
153 2 dgisselq
        //
154 46 dgisselq
`ifdef  PRECHARGE_COUNTERS
155
        /*
156
         *
157
         * I'm commenting this out.  As long as we are doing one refresh
158
         * cycle every 625 (or even 1250) clocks, and as long as that refresh
159
         * cycle requires that all banks be precharged, then we will never run
160
         * out of the maximum active to precharge command period.
161
         *
162
         * If the logic isn't needed, then, let's get rid of it.
163
         *
164
         */
165 2 dgisselq
        reg     [3:0]    need_precharge;
166
        genvar  k;
167
        generate
168
        for(k=0; k<4; k=k+1)
169
        begin : precharge_genvar_loop
170
                wire    precharge_cmd;
171
                assign  precharge_cmd = ((~o_ram_cs_n)&&(~o_ram_ras_n)&&(o_ram_cas_n)&&(~o_ram_we_n)
172
                                &&((o_ram_addr[10])||(o_ram_bs == k[1:0])))
173
                        // Also on read or write with precharge
174
                        ||(~o_ram_cs_n)&&(o_ram_ras_n)&&(~o_ram_cas_n)&&(o_ram_addr[10]);
175
 
176
                reg     [9:0]    precharge_clk;
177
                initial precharge_clk = 0;
178
                always @(posedge i_clk)
179
                begin
180
                        if ((precharge_cmd)||(bank_active[k] == 0))
181 46 dgisselq
                                // This needs to be 100_000 ns, or 10_000
182
                                // clocks.  A value of 1000 is *highly*
183
                                // conservative.
184 2 dgisselq
                                precharge_clk <= 10'd1000;
185
                        else if (|precharge_clk)
186
                                precharge_clk <= precharge_clk - 10'h1;
187
                end
188
                initial need_precharge[k] = 1'b0;
189
                always @(posedge i_clk)
190
                        need_precharge[k] <= ~(|precharge_clk);
191
        end // precharge_genvar_loop
192
        endgenerate
193 46 dgisselq
`else
194
        wire    [3:0]    need_precharge;
195
        assign  need_precharge = 4'h0;
196
`endif
197 2 dgisselq
 
198
 
199
 
200
        reg     [15:0]   clocks_til_idle;
201
        reg     [1:0]    r_state;
202
        wire            bus_cyc;
203
        assign  bus_cyc  = ((i_wb_cyc)&&(i_wb_stb)&&(~o_wb_stall));
204
        reg     nxt_dmod;
205
 
206
        // Pre-process pending operations
207
        wire    pending;
208
        initial r_pending = 1'b0;
209
        reg     [22:5]  fwd_addr;
210
        always @(posedge i_clk)
211
                if (bus_cyc)
212
                begin
213
                        r_pending <= 1'b1;
214
                        r_we      <= i_wb_we;
215
                        r_addr    <= i_wb_addr;
216
                        r_data    <= i_wb_data;
217
                        fwd_addr  <= i_wb_addr[22:5] + 18'h01;
218
                end else if ((~o_ram_cs_n)&&(o_ram_ras_n)&&(~o_ram_cas_n))
219
                        r_pending <= 1'b0;
220
                else if (~i_wb_cyc)
221
                        r_pending <= 1'b0;
222
 
223
        reg     r_bank_valid;
224
        initial r_bank_valid = 1'b0;
225
        always @(posedge i_clk)
226
                if (bus_cyc)
227
                        r_bank_valid <=((bank_active[i_wb_addr[9:8]][2])
228
                                        &&(bank_row[i_wb_addr[9:8]]==r_addr[22:10]));
229
                else
230
                        r_bank_valid <= ((bank_active[r_addr[9:8]][2])
231
                                        &&(bank_row[r_addr[9:8]]==r_addr[22:10]));
232
        reg     fwd_bank_valid;
233
        initial fwd_bank_valid = 0;
234
        always @(posedge i_clk)
235
                fwd_bank_valid <= ((bank_active[fwd_addr[9:8]][2])
236
                                        &&(bank_row[fwd_addr[9:8]]==fwd_addr[22:10]));
237
 
238
        assign  pending = (r_pending)&&(o_wb_stall);
239
 
240
        // Address MAP:
241
        //      23-bits bits in, 24-bits out
242
        //
243
        //      222 1111 1111 1100 0000 0000
244
        //      210 9876 5432 1098 7654 3210
245
        //      rrr rrrr rrrr rrBB cccc cccc 0
246
        //                         8765 4321 0
247
        //
248
        initial r_barrell_ack = 0;
249
        initial r_state = `RAM_POWER_UP;
250
        initial clocks_til_idle = 16'd20500;
251
        initial o_wb_stall = 1'b1;
252
        initial o_ram_dmod = `DMOD_GETINPUT;
253
        initial nxt_dmod = `DMOD_GETINPUT;
254
        initial o_ram_cs_n  = 1'b0;
255
        initial o_ram_ras_n = 1'b1;
256
        initial o_ram_cas_n = 1'b1;
257
        initial o_ram_we_n  = 1'b1;
258
        initial o_ram_dqm   = 2'b11;
259
        assign  o_ram_cke   = 1'b1;
260
        initial bank_active[0] = 3'b000;
261
        initial bank_active[1] = 3'b000;
262
        initial bank_active[2] = 3'b000;
263
        initial bank_active[3] = 3'b000;
264
        always @(posedge i_clk)
265
        if (r_state == `RAM_OPERATIONAL)
266
        begin
267
                o_wb_stall <= (r_pending)||(bus_cyc);
268
                r_barrell_ack <= r_barrell_ack >> 1;
269
                nxt_dmod <= `DMOD_GETINPUT;
270
                o_ram_dmod <= nxt_dmod;
271
 
272
                //
273 46 dgisselq
                // We assume that, whatever state the bank is in, that it
274
                // continues in that state and set up a series of shift
275
                // registers to contain that information.  If it will not
276
                // continue in that state, all that therefore needs to be 
277
                // done is to set bank_active[?][2] below.
278
                //
279 2 dgisselq
                bank_active[0] <= { bank_active[0][2], bank_active[0][2:1] };
280
                bank_active[1] <= { bank_active[1][2], bank_active[1][2:1] };
281
                bank_active[2] <= { bank_active[2][2], bank_active[2][2:1] };
282
                bank_active[3] <= { bank_active[3][2], bank_active[3][2:1] };
283
                //
284
                o_ram_cs_n <= (~i_wb_cyc);
285
                // o_ram_cke  <= 1'b1;
286
                o_ram_dqm  <= 2'b0;
287
                if (|clocks_til_idle[2:0])
288
                        clocks_til_idle[2:0] <= clocks_til_idle[2:0] - 3'h1;
289
 
290
                // Default command is a
291
                //      NOOP if (i_wb_cyc)
292
                //      Device deselect if (~i_wb_cyc)
293
                // o_ram_cs_n  <= (~i_wb_cyc) above, NOOP
294
                o_ram_ras_n <= 1'b1;
295
                o_ram_cas_n <= 1'b1;
296
                o_ram_we_n  <= 1'b1;
297
 
298 46 dgisselq
                // o_ram_data <= r_data[15:0];
299 2 dgisselq
 
300 46 dgisselq
                if (nxt_dmod)
301
                        ;
302
                else
303 2 dgisselq
                if ((~i_wb_cyc)||(|need_precharge)||(need_refresh))
304
                begin // Issue a precharge all command (if any banks are open),
305
                // otherwise an autorefresh command
306
                        if ((bank_active[0][2:1]==2'b10)
307
                                        ||(bank_active[1][2:1]==2'b10)
308
                                        ||(bank_active[2][2:1]==2'b10)
309 46 dgisselq
                                        ||(bank_active[3][2:1]==2'b10)
310
                                ||(|clocks_til_idle[2:0]))
311 2 dgisselq
                        begin
312
                                // Do nothing this clock
313
                                // Can't precharge a bank immediately after
314
                                // activating it
315
                        end else if (bank_active[0][2]
316
                                ||(bank_active[1][2])
317
                                ||(bank_active[2][2])
318
                                ||(bank_active[3][2]))
319
                        begin  // Close all active banks
320
                                o_ram_cs_n  <= 1'b0;
321
                                o_ram_ras_n <= 1'b0;
322
                                o_ram_cas_n <= 1'b1;
323
                                o_ram_we_n  <= 1'b0;
324
                                o_ram_addr[10] <= 1'b1;
325
                                bank_active[0][2] <= 1'b0;
326
                                bank_active[1][2] <= 1'b0;
327
                                bank_active[2][2] <= 1'b0;
328
                                bank_active[3][2] <= 1'b0;
329
                        end else if ((|bank_active[0])
330
                                        ||(|bank_active[1])
331
                                        ||(|bank_active[2])
332
                                        ||(|bank_active[3]))
333
                                // Can't precharge yet, the bus is still busy
334
                        begin end else if ((~in_refresh)&&((refresh_clk[9:8]==2'b00)||(need_refresh)))
335
                        begin // Send autorefresh command
336
                                o_ram_cs_n  <= 1'b0;
337
                                o_ram_ras_n <= 1'b0;
338
                                o_ram_cas_n <= 1'b0;
339
                                o_ram_we_n  <= 1'b1;
340
                        end // Else just send NOOP's, the default command
341 46 dgisselq
                // end else if (nxt_dmod)
342
                // begin
343 2 dgisselq
                        // Last half of a two cycle write
344 46 dgisselq
                        // o_ram_data <= r_data[15:0];
345
                        //
346
                        // While this does need to take precedence over all
347
                        // other commands, it doesn't need to take precedence
348
                        // over the the deactivate/precharge commands from
349
                        // above.
350
                        //
351
                        // We could probably even speed ourselves up a touch
352
                        // by moving this condition down below activating
353
                        // and closing active banks. ... only problem is when I
354
                        // last tried that I broke everything so ... that's not
355
                        // my problem.
356 2 dgisselq
                end else if (in_refresh)
357
                begin
358
                        // NOOPS only here, until we are out of refresh
359
                end else if ((pending)&&(~r_bank_valid)&&(bank_active[r_addr[9:8]]==3'h0))
360
                begin // Need to activate the requested bank
361
                        o_ram_cs_n  <= 1'b0;
362
                        o_ram_ras_n <= 1'b0;
363
                        o_ram_cas_n <= 1'b1;
364
                        o_ram_we_n  <= 1'b1;
365
                        o_ram_addr  <= r_addr[22:10];
366
                        o_ram_bs    <= r_addr[9:8];
367
                        // clocks_til_idle[2:0] <= 1;
368
                        bank_active[r_addr[9:8]][2] <= 1'b1;
369
                        bank_row[r_addr[9:8]] <= r_addr[22:10];
370
                        //
371
                end else if ((pending)&&(~r_bank_valid)
372
                                &&(bank_active[r_addr[9:8]]==3'b111))
373
                begin // Need to close an active bank
374
                        o_ram_cs_n  <= 1'b0;
375
                        o_ram_ras_n <= 1'b0;
376
                        o_ram_cas_n <= 1'b1;
377
                        o_ram_we_n  <= 1'b0;
378
                        // o_ram_addr  <= r_addr[22:10];
379
                        o_ram_addr[10]<= 1'b0;
380
                        o_ram_bs    <= r_addr[9:8];
381
                        // clocks_til_idle[2:0] <= 1;
382
                        bank_active[r_addr[9:8]][2] <= 1'b0;
383
                        // bank_row[r_addr[9:8]] <= r_addr[22:10];
384
                end else if ((pending)&&(~r_we)
385
                                &&(bank_active[r_addr[9:8]][2])
386
                                &&(r_bank_valid)
387
                                &&(clocks_til_idle[2:0] < 4))
388
                begin // Issue the read command
389
                        o_ram_cs_n  <= 1'b0;
390
                        o_ram_ras_n <= 1'b1;
391
                        o_ram_cas_n <= 1'b0;
392
                        o_ram_we_n  <= 1'b1;
393
                        o_ram_addr  <= { 4'h0, r_addr[7:0], 1'b0 };
394
                        o_ram_bs    <= r_addr[9:8];
395
                        clocks_til_idle[2:0] <= 4;
396
 
397
                        o_wb_stall <= 1'b0;
398
                        r_barrell_ack[(RDLY-1)] <= 1'b1;
399
                end else if ((pending)&&(r_we)
400
                        &&(bank_active[r_addr[9:8]][2])
401
                        &&(r_bank_valid)
402
                        &&(clocks_til_idle[2:0] == 0))
403
                begin // Issue the write command
404
                        o_ram_cs_n  <= 1'b0;
405
                        o_ram_ras_n <= 1'b1;
406
                        o_ram_cas_n <= 1'b0;
407
                        o_ram_we_n  <= 1'b0;
408
                        o_ram_addr  <= { 4'h0, r_addr[7:0], 1'b0 };
409
                        o_ram_bs    <= r_addr[9:8];
410
                        clocks_til_idle[2:0] <= 3'h1;
411
 
412
                        o_wb_stall <= 1'b0;
413
                        r_barrell_ack[1] <= 1'b1;
414 46 dgisselq
                        // o_ram_data <= r_data[31:16];
415 2 dgisselq
                        //
416
                        o_ram_dmod <= `DMOD_PUTOUTPUT;
417
                        nxt_dmod <= `DMOD_PUTOUTPUT;
418
                end else if ((r_pending)&&(r_addr[7:0] >= 8'hf0)
419
                                &&(~fwd_bank_valid))
420
                begin
421
                        // Do I need to close the next bank I'll need?
422
                        if (bank_active[fwd_addr[9:8]][2:1]==2'b11)
423
                        begin // Need to close the bank first
424
                                o_ram_cs_n <= 1'b0;
425
                                o_ram_ras_n <= 1'b0;
426
                                o_ram_cas_n <= 1'b1;
427
                                o_ram_we_n  <= 1'b0;
428
                                o_ram_addr[10] <= 1'b0;
429
                                o_ram_bs       <= fwd_addr[9:8];
430
                                bank_active[fwd_addr[9:8]][2] <= 1'b0;
431
                        end else if (bank_active[fwd_addr[9:8]]==3'b000)
432
                        begin
433
                                // Need to (pre-)activate the next bank
434
                                o_ram_cs_n  <= 1'b0;
435
                                o_ram_ras_n <= 1'b0;
436
                                o_ram_cas_n <= 1'b1;
437
                                o_ram_we_n  <= 1'b1;
438
                                o_ram_addr  <= fwd_addr[22:10];
439
                                o_ram_bs    <= fwd_addr[9:8];
440
                                // clocks_til_idle[3:0] <= 1;
441
                                bank_active[fwd_addr[9:8]] <= 3'h4;
442
                                bank_row[fwd_addr[9:8]] <= fwd_addr[22:10];
443
                        end
444
                end
445
        end else if (r_state == `RAM_POWER_UP)
446
        begin
447
                // All signals must be held in NOOP state during powerup
448
                o_ram_dqm <= 2'b11;
449
                // o_ram_cke <= 1'b1;
450
                o_ram_cs_n  <= 1'b0;
451
                o_ram_ras_n <= 1'b1;
452
                o_ram_cas_n <= 1'b1;
453
                o_ram_we_n  <= 1'b1;
454
                o_ram_dmod  <= `DMOD_GETINPUT;
455
                if (clocks_til_idle == 0)
456
                begin
457
                        r_state <= `RAM_INITIAL_REFRESH;
458
                        clocks_til_idle[3:0] <= 4'ha;
459
                        o_ram_cs_n  <= 1'b0;
460
                        o_ram_ras_n <= 1'b0;
461
                        o_ram_cas_n <= 1'b1;
462
                        o_ram_we_n  <= 1'b0;
463
                        o_ram_addr[10] <= 1'b1;
464
                end else
465
                        clocks_til_idle <= clocks_til_idle - 16'h01;
466
 
467
                o_wb_stall  <= 1'b1;
468
                r_barrell_ack[(RDLY-1):0] <= 0;
469
        end else if (r_state == `RAM_INITIAL_REFRESH)
470
        begin
471
                //
472
                o_ram_cs_n  <= 1'b0;
473
                o_ram_ras_n <= 1'b0;
474
                o_ram_cas_n <= 1'b0;
475
                o_ram_we_n  <= 1'b1;
476
                o_ram_dmod  <= `DMOD_GETINPUT;
477
                o_ram_addr  <= { 3'b000, 1'b0, 2'b00, 3'b010, 1'b0, 3'b001 };
478
                if (clocks_til_idle[3:0] == 4'h0)
479
                begin
480
                        r_state <= `RAM_SET_MODE;
481
                        o_ram_we_n <= 1'b0;
482
                        clocks_til_idle[3:0] <= 4'h2;
483
                end else
484
                        clocks_til_idle[3:0] <= clocks_til_idle[3:0] - 4'h1;
485
 
486
                o_wb_stall  <= 1'b1;
487
                r_barrell_ack[(RDLY-1):0] <= 0;
488
        end else if (r_state == `RAM_SET_MODE)
489
        begin
490
                // Set mode cycle
491
                o_ram_cs_n  <= 1'b1;
492
                o_ram_ras_n <= 1'b0;
493
                o_ram_cas_n <= 1'b0;
494
                o_ram_we_n  <= 1'b0;
495
                o_ram_dmod  <= `DMOD_GETINPUT;
496
 
497
                if (clocks_til_idle[3:0] == 4'h0)
498
                        r_state <= `RAM_OPERATIONAL;
499
                else
500
                        clocks_til_idle[3:0] <= clocks_til_idle[3:0]-4'h1;
501
 
502
                o_wb_stall  <= 1'b1;
503
                r_barrell_ack[(RDLY-1):0] <= 0;
504
        end
505
 
506 46 dgisselq
        always @(posedge i_clk)
507
                if (nxt_dmod)
508
                        o_ram_data <= r_data[15:0];
509
                else
510
                        o_ram_data <= r_data[31:16];
511
 
512 37 dgisselq
`ifdef  VERILATOR
513
        // While I hate to build something that works one way under Verilator
514
        // and another way in practice, this really isn't that.  The problem
515 39 dgisselq
        // \/erilator is having is resolved in toplevel.v---one file that
516
        // \/erilator doesn't implement.  In toplevel.v, there's not only a
517 37 dgisselq
        // single clocked latch but two taking place.  Here, we replicate one
518
        // of those.  The second takes place (somehow) within the sdramsim.cpp
519
        // file.
520
        reg     [15:0]   ram_data, last_ram_data;
521
        always @(posedge i_clk)
522
                ram_data <= i_ram_data;
523
        always @(posedge i_clk)
524
                last_ram_data <= ram_data;
525
`else
526 2 dgisselq
        reg     [15:0]   last_ram_data;
527
        always @(posedge i_clk)
528
                last_ram_data <= i_ram_data;
529 37 dgisselq
`endif
530 2 dgisselq
        assign  o_wb_ack  = r_barrell_ack[0];
531
        assign  o_wb_data = { last_ram_data, i_ram_data };
532
 
533
        //
534
        // The following outputs are not necessary for the functionality of
535
        // the SDRAM, but they can be used to feed an external "scope" to
536
        // get an idea of what the internals of this SDRAM are doing.
537
        //
538
        // Just be aware of the r_we: it is set based upon the currently pending
539
        // transaction, or (if none is pending) based upon the last transaction.
540
        // If you want to capture the first value "written" to the device,
541
        // you'll need to write a nothing value to the device to set r_we.
542
        // The first value "written" to the device can be caught in the next
543
        // interaction after that.
544
        //
545 46 dgisselq
        reg     trigger;
546
        always @(posedge i_clk)
547
                trigger <= ((o_wb_data[15:0]==o_wb_data[31:16])
548
                        &&(o_wb_ack)&&(~i_wb_we));
549
 
550
 
551
        assign  o_debug = { i_wb_cyc, i_wb_stb, i_wb_we, o_wb_ack, o_wb_stall, // 5
552
                o_ram_cs_n, o_ram_ras_n, o_ram_cas_n, o_ram_we_n, o_ram_bs,//6
553
                        o_ram_dmod, r_pending,                          //  2
554
                        trigger,                                        //  1
555
                        o_ram_addr[9:0],                         // 10 more
556
                        (r_we) ? { o_ram_data[7:0] }                     //  8 values
557 2 dgisselq
                                : { o_wb_data[23:20], o_wb_data[3:0] }
558
                        // i_ram_data[7:0]
559
                         };
560
endmodule

powered by: WebSVN 2.1.0

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