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

Subversion Repositories wbddr3

[/] [wbddr3/] [trunk/] [bench/] [cpp/] [ddrsdramsim.cpp] - Blame information for rev 16

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

Line No. Rev Author Line
1 4 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    ddrsdramsim.cpp
4
//
5
// Project:     A wishbone controlled DDR3 SDRAM memory controller.
6
//
7
// Purpose:     
8
//
9
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11
//
12
////////////////////////////////////////////////////////////////////////////////
13
//
14
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
15
//
16
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of  the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20
//
21
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
28
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
#include <stdio.h>
39
#include <assert.h>
40
 
41 16 dgisselq
#include "ddrsdramsim.h"
42
 
43 9 dgisselq
#define PREFIX  "DDR3-SDRAM"
44 16 dgisselq
const unsigned ckCL = 6,
45
                ckCWL = 5,
46
                ckRP = 6,
47
                ckWR = 6,
48
                ckRAS = 15,
49
                ckRC = 20,
50
                ckMRD = 4,
51
                ckMOD = 12,
52
                ckZQinit = 512,
53
                ckODT = ckCWL-2,
54
                ckRFC = 64, // Clocks from refresh to activate
55
                ckREFI = 1560*NWIDTH, // 7.8us @ 200MHz = 7.8e-6 * 200e6 = 1560
56
                DDR_MR2 = 0x0040 | (((ckCWL-5)&7)<<3),
57
                DDR_MR1 = 0x0044,
58
                DDR_MR0 = 0x0000 | (((ckCL-4)&0x07)<<4) | ((ckCL>11)?0x4:0)
59
                                |((ckWR==16)?0
60
                                        :(ckWR>=8)?((((ckWR-8)>>1)+8)<<9)
61
                                        :((ckWR-5+1)<<9)),
62
                nREF = 1;
63 4 dgisselq
 
64 14 dgisselq
BANKINFO::BANKINFO(void) {
65
        m_state = 0; m_row = 0; m_wcounter = 0; m_min_time_before_precharge=0;
66
}
67
 
68 4 dgisselq
void    BANKINFO::tick(int cmd, unsigned addr) {
69 12 dgisselq
        if (m_wcounter)
70
                m_wcounter--;
71 4 dgisselq
        switch(cmd) {
72 14 dgisselq
                case DDR_REFRESH:
73
                        assert(m_state == 0);
74
                        break;
75 4 dgisselq
                case DDR_PRECHARGE:
76 16 dgisselq
                        // assert((m_state&((1<<ckRP)-1)) == ((1<<ckRP)-1));
77
                        m_state &= -2;
78 8 dgisselq
                        // While the specification allows precharging an already
79
                        // precharged bank, we can keep that from happening
80
                        // here:
81
                        // assert(m_state&7);
82
                        // Only problem is, this will currently break our
83
                        // refresh logic.
84 16 dgisselq
                        /*
85 14 dgisselq
                        if (m_min_time_before_precharge != 0) {
86
                                printf("BANK-FAIL: TIME-BEFORE-PRECHARGE = %d (should be zero)\n", m_min_time_before_precharge);
87
                                assert(m_min_time_before_precharge == 0);
88
                        } if (m_min_time_before_activate != 0) {
89
                                printf("BANK-FAIL: TIME-BEFORE-ACTIVATE = %d (should be zero)\n", m_min_time_before_activate);
90
                                assert(m_min_time_before_activate==0);
91
                        }
92 16 dgisselq
                        */
93 4 dgisselq
                        break;
94
                case DDR_ACTIVATE:
95 16 dgisselq
                        assert((m_state&((1<<ckRP)-1)) == 0);
96 14 dgisselq
                        if (((m_state&7)!=0)&&((addr&0x7fff) != m_row)) {
97
                                printf("BANK-FAIL: Attempt to Activate an already active bank without closing it first (m_state = %x)\n", m_state);
98
                                assert((m_state&7)==0);
99
                        }
100 16 dgisselq
 
101
                        /*
102 14 dgisselq
                        if (m_wcounter != 0) {
103
                                printf("BANK-FAIL: ACTIVATE too soon after write (wcounter = %d)\n", m_wcounter);
104
                                assert(m_wcounter == 0);
105
                        } if (m_min_time_before_activate!=0) {
106
                                printf("BANK-FAIL: ACTIVATE too soon after last activate, (ctr=%d)\n", m_min_time_before_activate);
107
                                assert(m_min_time_before_activate==0);
108
                        }
109 16 dgisselq
                        */
110 6 dgisselq
                        m_state = 1;
111 4 dgisselq
                        m_row = addr & 0x7fff;
112 16 dgisselq
printf("BANK -- Setting address to %04x\n", m_row);
113 14 dgisselq
                        m_min_time_before_precharge = ckRAS;
114
                        m_min_time_before_activate = ckRC;
115 4 dgisselq
                        break;
116
                case DDR_READ: case DDR_WRITE:
117 12 dgisselq
                        if (DDR_READ)
118
                                assert(m_wcounter == 0);
119
                        else
120
                                m_wcounter = 3+4+4;
121 16 dgisselq
                        if ((m_state&((1<<ckRP)-1)) != ((1<<ckRP)-1)) {
122
                                printf(PREFIX "::R/W Error: m_state = %08x, ckRP = %d (%08x)\n",
123
                                        m_state, ckRP, ((1<<ckRP)-1));
124
                                assert((m_state&((1<<ckRP)-1)) == ((1<<ckRP)-1));
125
                        }
126 14 dgisselq
                        if (m_min_time_before_precharge)
127
                                m_min_time_before_precharge--;
128
                        if (m_min_time_before_activate)
129
                                m_min_time_before_activate--;
130 4 dgisselq
                        break;
131
                case DDR_ZQS:
132 16 dgisselq
                        assert((m_state&((1<<ckRP)-1)) == 0);
133 14 dgisselq
                        if (m_min_time_before_precharge)
134
                                m_min_time_before_precharge--;
135
                        if (m_min_time_before_activate)
136
                                m_min_time_before_activate--;
137 4 dgisselq
                        break;
138
                case DDR_NOOP:
139
                        m_state <<= 1;
140
                        m_state |= (m_state&2)>>1;
141 16 dgisselq
                        m_state &= ((1<<ckRP)-1);
142 14 dgisselq
                        if (m_min_time_before_precharge)
143
                                m_min_time_before_precharge--;
144
                        if (m_min_time_before_activate)
145
                                m_min_time_before_activate--;
146 4 dgisselq
                        break;
147
                default:
148
                        break;
149
        }
150
}
151
 
152
int gbl_state, gbl_counts;
153
 
154
DDRSDRAMSIM::DDRSDRAMSIM(int lglen) {
155
        m_memlen = (1<<(lglen-2));
156
        m_mem = new unsigned[m_memlen];
157
        m_reset_state = 0;
158
        m_reset_counts= 0;
159 16 dgisselq
        assert(NTIMESLOTS > ckCL+3);
160 4 dgisselq
        m_bus = new BUSTIMESLOT[NTIMESLOTS];
161
        for(int i=0; i<NTIMESLOTS; i++)
162
                m_bus[i].m_used = 0;
163 13 dgisselq
        for(int i=0; i<NTIMESLOTS; i++)
164
                m_bus[i].m_rtt = 0;
165 4 dgisselq
        m_busloc = 0;
166
}
167
 
168 16 dgisselq
unsigned DDRSDRAMSIM::apply(int reset_n, int cke,
169 4 dgisselq
                int csn, int rasn, int casn, int wen,
170
                int dqs, int dm, int odt, int busoe,
171
                int addr, int ba, int data) {
172 13 dgisselq
        BUSTIMESLOT     *ts, *nxtts;
173 4 dgisselq
        int     cmd = (reset_n?0:32)|(cke?0:16)|(csn?8:0)
174
                        |(rasn?4:0)|(casn?2:0)|(wen?1:0);
175 13 dgisselq
 
176 4 dgisselq
        if ((m_reset_state!=0)&&(reset_n==0)) {
177
                m_reset_state = 0;
178
                m_reset_counts = 0;
179
        } else if (m_reset_state < 16) {
180 16 dgisselq
                // printf(PREFIX "::Reset-CMD = %02x,BA=%d,ADDR=%04x, counts = %d\n", cmd, ba, addr, m_reset_counts);
181 4 dgisselq
                switch(m_reset_state) {
182
                case 0:
183
                        m_reset_counts++;
184
                        if (reset_n) {
185 16 dgisselq
                                assert(m_reset_counts > 40000*NWIDTH);
186 4 dgisselq
                                m_reset_counts = 0;
187
                                m_reset_state = 1;
188
                        } break;
189
                case 1:
190
                        m_reset_counts++;
191
                        if (cke) {
192 16 dgisselq
                                assert(m_reset_counts > 100000*NWIDTH);
193 4 dgisselq
                                m_reset_counts = 0;
194
                                m_reset_state = 2;
195
                        } break;
196
                case 2:
197
                        m_reset_counts++;
198 6 dgisselq
                        assert(cke);
199 4 dgisselq
                        if (cmd != DDR_NOOP) {
200 16 dgisselq
                                assert(m_reset_counts > (int)(ckRFC+2*NWIDTH));
201 4 dgisselq
                                m_reset_counts = 0;
202
                                m_reset_state = 3;
203
                                assert(cmd == DDR_MRSET);
204 14 dgisselq
                                // Set MR2
205 4 dgisselq
                                assert(ba == 2);
206 16 dgisselq
                                printf(PREFIX "::Checking DDR-MR2(%04x) against %04x\n", addr, DDR_MR2);
207
                                assert(addr == DDR_MR2);
208 4 dgisselq
                        } break;
209
                case 3:
210
                        m_reset_counts++;
211 6 dgisselq
                        assert(cke);
212 4 dgisselq
                        if (cmd != DDR_NOOP) {
213 16 dgisselq
                                assert(m_reset_counts >= (int)ckMRD);
214 4 dgisselq
                                m_reset_counts = 0;
215
                                m_reset_state = 4;
216
                                assert(cmd == DDR_MRSET);
217 14 dgisselq
                                // Set MR1
218
                                assert(ba == 1);
219 16 dgisselq
                                assert(addr == DDR_MR1);
220 4 dgisselq
                        } break;
221
                case 4:
222
                        m_reset_counts++;
223 6 dgisselq
                        assert(cke);
224 4 dgisselq
                        if (cmd != DDR_NOOP) {
225 9 dgisselq
                                printf(PREFIX "::RESET-CMD[4]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
226 16 dgisselq
                                assert(m_reset_counts >= (int)ckMRD);
227 4 dgisselq
                                m_reset_counts = 0;
228
                                m_reset_state = 5;
229
                                assert(cmd == DDR_MRSET);
230 14 dgisselq
                                // Set MR0
231 4 dgisselq
                                assert(ba == 0);
232 16 dgisselq
                                assert(addr == DDR_MR0);
233 4 dgisselq
                        } break;
234
                case 5:
235
                        m_reset_counts++;
236 6 dgisselq
                        assert(cke);
237 4 dgisselq
                        if (cmd != DDR_NOOP) {
238 9 dgisselq
                                printf(PREFIX "::RESET-CMD[5]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
239 16 dgisselq
                                assert(m_reset_counts >= (int)ckMOD);
240 4 dgisselq
                                m_reset_counts = 0;
241
                                m_reset_state = 6;
242
                                assert(cmd == DDR_ZQS);
243 5 dgisselq
                                assert(addr == 0x400);
244 4 dgisselq
                        } break;
245
                case 6:
246
                        m_reset_counts++;
247 6 dgisselq
                        assert(cke);
248 4 dgisselq
                        if (cmd != DDR_NOOP) {
249 9 dgisselq
                                printf(PREFIX "::RESET-CMD[6]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
250 16 dgisselq
                                assert(m_reset_counts >= (int)ckZQinit);
251 4 dgisselq
                                m_reset_counts = 0;
252
                                m_reset_state = 7;
253
                                assert(cmd == DDR_PRECHARGE);
254 5 dgisselq
                                assert(addr == 0x400);
255 4 dgisselq
                        } break;
256
                case 7:
257
                        m_reset_counts++;
258 6 dgisselq
                        assert(cke);
259 4 dgisselq
                        if (cmd != DDR_NOOP) {
260 9 dgisselq
                                printf(PREFIX "::RESET-CMD[7]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
261 16 dgisselq
                                assert(m_reset_counts >= (int)ckRP);
262 4 dgisselq
                                m_reset_counts = 0;
263
                                m_reset_state = 8;
264
                                assert(cmd == DDR_REFRESH);
265 6 dgisselq
                                m_clocks_since_refresh = 0;
266 4 dgisselq
                        } break;
267
                case 8:
268
                        m_reset_counts++;
269 6 dgisselq
                        assert(cke);
270 4 dgisselq
                        assert(cmd == DDR_NOOP);
271 16 dgisselq
                        if (m_reset_counts > (int)ckRFC) {
272 4 dgisselq
                                m_reset_state = 16;
273 9 dgisselq
                                printf(PREFIX ": Leaving reset state\n");
274 5 dgisselq
                        }
275 4 dgisselq
                        break;
276
                default:
277
                        break;
278
                }
279
 
280
                gbl_state = m_reset_state;
281
                gbl_counts= m_reset_counts;
282 6 dgisselq
                m_nrefresh_issued = nREF;
283 7 dgisselq
                m_clocks_since_refresh++;
284 14 dgisselq
                for(int i=0; i<NBANKS; i++)
285
                        m_bank[i].tick(cmd, 0);
286 6 dgisselq
        } else if (!cke) {
287 4 dgisselq
                assert(0&&"Clock not enabled!");
288 6 dgisselq
        } else if ((cmd == DDR_REFRESH)||(m_nrefresh_issued < (int)nREF)) {
289
                if (DDR_REFRESH == cmd) {
290
                        m_clocks_since_refresh = 0;
291
                        if (m_nrefresh_issued >= (int)nREF)
292 7 dgisselq
                                m_nrefresh_issued = 1;
293 6 dgisselq
                        else
294
                                m_nrefresh_issued++;
295
                } else {
296
                        m_clocks_since_refresh++;
297
                        assert(DDR_NOOP == cmd);
298
                }
299
                for(int i=0; i<NBANKS; i++)
300 14 dgisselq
                        m_bank[i].tick(cmd,0);
301 7 dgisselq
 
302
                if (m_nrefresh_issued == nREF)
303 9 dgisselq
                        printf(PREFIX "::Refresh cycle complete\n");
304 6 dgisselq
        } else {
305
                // In operational mode!!
306
 
307
                m_clocks_since_refresh++;
308 16 dgisselq
                if (m_clocks_since_refresh > (int)ckREFI) {
309
                        printf(PREFIX "::ERROR! Clocks since refresh = %d, which isn\'t less than %d\n", m_clocks_since_refresh, ckREFI);
310
                }
311
                assert(m_clocks_since_refresh <= (int)ckREFI);
312 6 dgisselq
                switch(cmd) {
313 4 dgisselq
                case DDR_MRSET:
314
                        assert(0&&"Modes should only be set in reset startup");
315
                        for(int i=0; i<NBANKS; i++)
316
                                m_bank[i].tick(DDR_MRSET,0);
317
                        break;
318
                case DDR_REFRESH:
319
                        for(int i=0; i<NBANKS; i++)
320
                                m_bank[i].tick(DDR_REFRESH,0);
321 6 dgisselq
                        m_clocks_since_refresh = 0;
322
                        assert(0 && "Internal err: Refresh should be handled above");
323 4 dgisselq
                        break;
324
                case DDR_PRECHARGE:
325 14 dgisselq
                        if (addr & 0x400) {
326 4 dgisselq
                                // Precharge all
327 16 dgisselq
                                printf(PREFIX "::Precharging all banks\n");
328 4 dgisselq
                                for(int i=0; i<NBANKS; i++)
329
                                        m_bank[i].tick(DDR_PRECHARGE,0);
330
                        } else {
331 16 dgisselq
                                printf(PREFIX "::Precharging bank [%d]\n", ba);
332 4 dgisselq
                                m_bank[ba].tick(DDR_PRECHARGE,0);
333
                                for(int i=0; i<NBANKS; i++)
334
                                        if (ba != i)
335
                                                m_bank[i].tick(DDR_NOOP,0);
336
                        }
337
                        break;
338
                case DDR_ACTIVATE:
339 16 dgisselq
                        if (m_clocks_since_refresh < (int)ckRFC) {
340
                                printf(PREFIX "::ACTIVATE -- not enough clocks since refresh, %d < %d should be true\n", m_clocks_since_refresh, ckRFC);
341
                                assert(m_clocks_since_refresh >= (int)ckRFC);
342
                        }
343 14 dgisselq
                        printf(PREFIX "::Activating bank %d, address %08x\n", ba, addr);
344 4 dgisselq
                        m_bank[ba].tick(DDR_ACTIVATE,addr);
345
                        for(int i=0; i<NBANKS; i++)
346
                                if (i!=ba) m_bank[i].tick(DDR_NOOP,0);
347
                        break;
348
                case DDR_WRITE:
349
                        {
350 6 dgisselq
                                // This SIM doesn't handle out of order writes
351
                                assert((addr&7)==0);
352
                                m_bank[ba].tick(DDR_WRITE, addr);
353 4 dgisselq
                                for(int i=0; i<NBANKS; i++)
354 6 dgisselq
                                        if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
355 7 dgisselq
                                unsigned caddr = m_bank[ba].m_row;
356 8 dgisselq
                                caddr <<= 3;
357 7 dgisselq
                                caddr |= ba;
358
                                caddr <<= 10;
359
                                caddr |= addr;
360
                                caddr &= ~7;
361
                                caddr >>= 1;
362 4 dgisselq
 
363
                                BUSTIMESLOT *tp;
364 16 dgisselq
                                int     offset = m_busloc+ckCWL+1;
365 4 dgisselq
 
366 7 dgisselq
                                tp = &m_bus[(offset+0)&(NTIMESLOTS-1)];
367 9 dgisselq
                                // printf("Setting bus timeslots from (now=%d)+%d=%d to now+%d+3\n", m_busloc, ckCL,(m_busloc+ckCL)&(NTIMESLOTS-1), ckCL);
368 7 dgisselq
                                tp->m_addr = caddr  ;
369 4 dgisselq
                                tp->m_used = 1;
370
                                tp->m_read = 0;
371
 
372 7 dgisselq
                                tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
373
                                tp->m_addr = caddr+1;
374 4 dgisselq
                                tp->m_used = 1;
375
                                tp->m_read = 0;
376
 
377 7 dgisselq
                                tp = &m_bus[(offset+2)&(NTIMESLOTS-1)];
378
                                tp->m_addr = caddr+2;
379 4 dgisselq
                                tp->m_used = 1;
380
                                tp->m_read = 0;
381
 
382 7 dgisselq
                                tp = &m_bus[(offset+3)&(NTIMESLOTS-1)];
383
                                tp->m_addr = caddr+3;
384 4 dgisselq
                                tp->m_used = 1;
385
                                tp->m_read = 0;
386
                        } break;
387
                case DDR_READ:
388
                        {
389 6 dgisselq
                                // This SIM doesn't handle out of order reads
390
                                assert((addr&7)==0);
391
                                m_bank[ba].tick(DDR_READ, addr);
392 4 dgisselq
                                for(int i=0; i<NBANKS; i++)
393 6 dgisselq
                                        if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
394 7 dgisselq
                                unsigned caddr = m_bank[ba].m_row;
395 8 dgisselq
                                caddr <<= 3;
396 7 dgisselq
                                caddr |= ba;
397
                                caddr <<= 10;
398
                                caddr |= addr;
399
                                caddr &= ~7;
400
                                caddr >>= 1;
401 4 dgisselq
 
402
                                BUSTIMESLOT *tp;
403 16 dgisselq
 
404
                                printf(PREFIX"::READ(%03x:%d:%03x => %08x) Queuing %08x:%08x:%08x:%08x\n",
405
                                        m_bank[ba].m_row, ba, addr,
406
                                        caddr,
407
                                        m_mem[caddr  ], m_mem[caddr+1],
408
                                        m_mem[caddr+2], m_mem[caddr+3]);
409 8 dgisselq
                                int offset = (m_busloc+ckCL+1)&(NTIMESLOTS-1);
410
                                tp = &m_bus[(offset)&(NTIMESLOTS-1)];
411 7 dgisselq
                                tp->m_data = m_mem[caddr];
412
                                tp->m_addr = caddr;
413 4 dgisselq
                                tp->m_used = 1;
414
                                tp->m_read = 1;
415
 
416 8 dgisselq
                                tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
417 7 dgisselq
                                tp->m_data = m_mem[caddr+1];
418
                                tp->m_addr = caddr+1;
419 4 dgisselq
                                tp->m_used = 1;
420
                                tp->m_read = 1;
421
 
422 8 dgisselq
                                tp = &m_bus[(offset+2)&(NTIMESLOTS-1)];
423 7 dgisselq
                                tp->m_data = m_mem[caddr+2];
424
                                tp->m_addr = caddr+2;
425 4 dgisselq
                                tp->m_used = 1;
426
                                tp->m_read = 1;
427
 
428 8 dgisselq
                                tp = &m_bus[(offset+3)&(NTIMESLOTS-1)];
429 7 dgisselq
                                tp->m_data = m_mem[caddr+3];
430
                                tp->m_addr = caddr+3;
431 4 dgisselq
                                tp->m_used = 1;
432
                                tp->m_read = 1;
433
                        } break;
434
                case DDR_ZQS:
435
                        assert(0&&"Sim does not support ZQS outside of startup");
436
                        break;
437
                case DDR_NOOP:
438
                        for(int i=0; i<NBANKS; i++)
439
                                m_bank[i].tick(DDR_NOOP,addr);
440
                        break;
441
                default: // We are deselecteda
442
                        for(int i=0; i<NBANKS; i++)
443
                                m_bank[i].tick(DDR_NOOP,addr);
444
                        break;
445 6 dgisselq
                }
446 13 dgisselq
 
447 14 dgisselq
                if (false) {
448 13 dgisselq
                        bool flag = false;
449
                        for(int i=0; i<5; i++) {
450
                                int bl = (m_busloc+1+i)&(NTIMESLOTS-1);
451
                                nxtts = &m_bus[bl];
452
                                if (nxtts->m_used) {
453
                                        flag = true;
454
                                        break;
455
                                }
456
                        } if (flag) {
457 16 dgisselq
                        printf(PREFIX "::DQS = %d BUSLOC = %d\n", dqs, (m_busloc+1)&(NTIMESLOTS-1));
458 13 dgisselq
                        for(int i=0; i<5; i++) {
459
                                int bl = (m_busloc+1+i)&(NTIMESLOTS-1);
460
                                nxtts = &m_bus[bl];
461
                                printf("BUS[%2d] ", bl);
462
                                if (nxtts->m_used)
463
                                        printf(" USED");
464
                                if (nxtts->m_read)
465
                                        printf(" READ");
466
                                if (nxtts->m_rtt)
467
                                        printf(" RTT");
468
                                printf("\n");
469
                        }}
470
                }
471
 
472
                ts = &m_bus[(m_busloc+1)&(NTIMESLOTS-1)];
473 16 dgisselq
                if (dqs) {
474
                        /*
475
                        if ((!ts->m_rtt)||(!m_last_rtt)) {
476
                                printf(PREFIX "ODT(dqs is true) m_rtt is %s and last_rtt is %s.  Both should be true if DQS.  (ERROR!)\n",
477
                                        (ts->m_rtt)?"true":"false",
478
                                        (m_last_rtt)?"true":"false");
479
                        } */
480 13 dgisselq
                        assert((ts->m_rtt)&&(m_last_rtt));
481 16 dgisselq
                } else if (!m_last_dqs)
482 13 dgisselq
                        assert(!m_last_rtt);
483 4 dgisselq
        }
484
 
485
        m_busloc = (m_busloc+1)&(NTIMESLOTS-1);
486
 
487 13 dgisselq
        ts = &m_bus[m_busloc];
488
        nxtts = &m_bus[(m_busloc+1)&(NTIMESLOTS-1)];
489 4 dgisselq
        unsigned vl = ts->m_data;
490 16 dgisselq
 
491 4 dgisselq
        assert( ((!ts->m_used)||(busoe))
492 13 dgisselq
                || ((ts->m_used)&&(ts->m_read)&&(!busoe))
493
                || ((ts->m_used)&&(!ts->m_read)&&(busoe))
494
                );
495 4 dgisselq
 
496 13 dgisselq
        m_last_dqs = dqs;
497
        m_last_rtt = ts->m_rtt;
498
 
499
        if (ts->m_used) {
500
                if (ts->m_read)
501
                        assert((!dqs)&&(!m_last_dqs));
502
                else
503
                        assert((dqs) && (m_last_dqs));
504
        } else if (!nxtts->m_used)
505
                assert(!dqs);
506
 
507 4 dgisselq
        assert((!ts->m_used)||(ts->m_addr < (unsigned)m_memlen));
508 16 dgisselq
        if ((ts->m_used)&&(!ts->m_read)&&(dm != 0x0f)) {
509
                printf(PREFIX "::Setting MEM[%08x] = %08x (%02x)\n", ts->m_addr, data, dm);
510
                unsigned mask = 0;
511
                if (dm&0x08) mask = 0x0ff;
512
                mask <<= 8; if (dm&0x004) mask |= 0x0ff;
513
                mask <<= 8; if (dm&0x002) mask |= 0x0ff;
514
                mask <<= 8; if (dm&0x001) mask |= 0x0ff;
515
                m_mem[ts->m_addr] = (data & (~mask)) | (m_mem[ts->m_addr]&mask);
516
        } else if ((ts->m_used)&&(ts->m_read)) {
517
                printf(PREFIX ":: %08x\n", vl);
518 7 dgisselq
        }
519 13 dgisselq
 
520 16 dgisselq
        m_bus[(m_busloc+ckODT-1)&(NTIMESLOTS-1)].m_rtt = (odt)&&(reset_n);
521 4 dgisselq
        ts->m_used = 0;
522
        ts->m_read = 0;
523
        ts->m_addr = -1;
524 13 dgisselq
        ts->m_rtt  = 0;
525 4 dgisselq
        return (!busoe)?vl:data;
526
}
527
 

powered by: WebSVN 2.1.0

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