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

Subversion Repositories wbddr3

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

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 18 dgisselq
const unsigned
45
                ckRESET = 64000, // 200us @ 320MHz
46
                ckCKE = 160000, // 500us @ 320MHz
47
                ckCL = 5,
48 16 dgisselq
                ckCWL = 5,
49 18 dgisselq
                ckRP = 5,
50
                ckWR = 5,
51
                ckRAS = 12,
52
                ckRC = 16,
53 16 dgisselq
                ckMRD = 4,
54
                ckMOD = 12,
55
                ckZQinit = 512,
56
                ckODT = ckCWL-2,
57 18 dgisselq
                ckXPR = 56, // Exit reset clocks from CKE HIGH to valid command
58
                ckRFC = 52, // Clocks from refresh to activate
59
                ckREFI = 2496, // 7.8us @ 320MHz
60 16 dgisselq
                DDR_MR2 = 0x0040 | (((ckCWL-5)&7)<<3),
61
                DDR_MR1 = 0x0044,
62
                DDR_MR0 = 0x0000 | (((ckCL-4)&0x07)<<4) | ((ckCL>11)?0x4:0)
63
                                |((ckWR==16)?0
64
                                        :(ckWR>=8)?((((ckWR-8)>>1)+8)<<9)
65
                                        :((ckWR-5+1)<<9)),
66 18 dgisselq
                // Don't pull in any refreshes ...
67 16 dgisselq
                nREF = 1;
68 4 dgisselq
 
69 14 dgisselq
BANKINFO::BANKINFO(void) {
70
        m_state = 0; m_row = 0; m_wcounter = 0; m_min_time_before_precharge=0;
71
}
72
 
73 4 dgisselq
void    BANKINFO::tick(int cmd, unsigned addr) {
74 12 dgisselq
        if (m_wcounter)
75
                m_wcounter--;
76 4 dgisselq
        switch(cmd) {
77 14 dgisselq
                case DDR_REFRESH:
78
                        assert(m_state == 0);
79
                        break;
80 4 dgisselq
                case DDR_PRECHARGE:
81 16 dgisselq
                        // assert((m_state&((1<<ckRP)-1)) == ((1<<ckRP)-1));
82
                        m_state &= -2;
83 8 dgisselq
                        // While the specification allows precharging an already
84
                        // precharged bank, we can keep that from happening
85
                        // here:
86
                        // assert(m_state&7);
87
                        // Only problem is, this will currently break our
88
                        // refresh logic.
89 16 dgisselq
                        /*
90 14 dgisselq
                        if (m_min_time_before_precharge != 0) {
91
                                printf("BANK-FAIL: TIME-BEFORE-PRECHARGE = %d (should be zero)\n", m_min_time_before_precharge);
92
                                assert(m_min_time_before_precharge == 0);
93
                        } if (m_min_time_before_activate != 0) {
94
                                printf("BANK-FAIL: TIME-BEFORE-ACTIVATE = %d (should be zero)\n", m_min_time_before_activate);
95
                                assert(m_min_time_before_activate==0);
96
                        }
97 16 dgisselq
                        */
98 4 dgisselq
                        break;
99
                case DDR_ACTIVATE:
100 18 dgisselq
                        // assert((m_state&((1<<ckRP)-1)) == 0);
101
                        if (((m_state&((1<<ckRP)-1))!=0)&&((addr&0x7fff) != m_row)) {
102
                                printf(PREFIX "::BANK-FAIL: Attempt to Activate an already active bank without closing it first (m_state = %x)\n", m_state);
103
                                // assert((m_state&((1<<ckRP)-1))==0);
104
                        } else if((m_state&((1<<ckRP)-1)) != 0) {
105
                                printf(PREFIX "::DOUBLE-ACTIVATE!!\n");
106 14 dgisselq
                        }
107 16 dgisselq
 
108
                        /*
109 14 dgisselq
                        if (m_wcounter != 0) {
110
                                printf("BANK-FAIL: ACTIVATE too soon after write (wcounter = %d)\n", m_wcounter);
111
                                assert(m_wcounter == 0);
112
                        } if (m_min_time_before_activate!=0) {
113
                                printf("BANK-FAIL: ACTIVATE too soon after last activate, (ctr=%d)\n", m_min_time_before_activate);
114
                                assert(m_min_time_before_activate==0);
115
                        }
116 16 dgisselq
                        */
117 6 dgisselq
                        m_state = 1;
118 4 dgisselq
                        m_row = addr & 0x7fff;
119 18 dgisselq
                        printf(PREFIX "::BANK -- Setting address to %04x\n", m_row);
120 14 dgisselq
                        m_min_time_before_precharge = ckRAS;
121
                        m_min_time_before_activate = ckRC;
122 4 dgisselq
                        break;
123
                case DDR_READ: case DDR_WRITE:
124 12 dgisselq
                        if (DDR_READ)
125
                                assert(m_wcounter == 0);
126
                        else
127
                                m_wcounter = 3+4+4;
128 16 dgisselq
                        if ((m_state&((1<<ckRP)-1)) != ((1<<ckRP)-1)) {
129
                                printf(PREFIX "::R/W Error: m_state = %08x, ckRP = %d (%08x)\n",
130
                                        m_state, ckRP, ((1<<ckRP)-1));
131 18 dgisselq
                                // assert((m_state&((1<<ckRP)-1)) == ((1<<ckRP)-1));
132 16 dgisselq
                        }
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_ZQS:
139 16 dgisselq
                        assert((m_state&((1<<ckRP)-1)) == 0);
140 14 dgisselq
                        if (m_min_time_before_precharge)
141
                                m_min_time_before_precharge--;
142
                        if (m_min_time_before_activate)
143
                                m_min_time_before_activate--;
144 4 dgisselq
                        break;
145
                case DDR_NOOP:
146 18 dgisselq
                        // NO BREAK: Fall through.  On a NOOP we do the same
147
                        // as if the chip were de-selected.
148
                default:
149 4 dgisselq
                        m_state <<= 1;
150
                        m_state |= (m_state&2)>>1;
151 16 dgisselq
                        m_state &= ((1<<ckRP)-1);
152 18 dgisselq
                        // Else the chip was de-selected, and we only need
153
                        // tick time away -- as in a NOOP.
154 14 dgisselq
                        if (m_min_time_before_precharge)
155
                                m_min_time_before_precharge--;
156
                        if (m_min_time_before_activate)
157
                                m_min_time_before_activate--;
158 4 dgisselq
                        break;
159
        }
160
}
161
 
162
int gbl_state, gbl_counts;
163
 
164
DDRSDRAMSIM::DDRSDRAMSIM(int lglen) {
165
        m_memlen = (1<<(lglen-2));
166
        m_mem = new unsigned[m_memlen];
167
        m_reset_state = 0;
168
        m_reset_counts= 0;
169 16 dgisselq
        assert(NTIMESLOTS > ckCL+3);
170 4 dgisselq
        m_bus = new BUSTIMESLOT[NTIMESLOTS];
171
        for(int i=0; i<NTIMESLOTS; i++)
172
                m_bus[i].m_used = 0;
173 13 dgisselq
        for(int i=0; i<NTIMESLOTS; i++)
174
                m_bus[i].m_rtt = 0;
175 4 dgisselq
        m_busloc = 0;
176
}
177
 
178 16 dgisselq
unsigned DDRSDRAMSIM::apply(int reset_n, int cke,
179 4 dgisselq
                int csn, int rasn, int casn, int wen,
180
                int dqs, int dm, int odt, int busoe,
181
                int addr, int ba, int data) {
182 13 dgisselq
        BUSTIMESLOT     *ts, *nxtts;
183 4 dgisselq
        int     cmd = (reset_n?0:32)|(cke?0:16)|(csn?8:0)
184
                        |(rasn?4:0)|(casn?2:0)|(wen?1:0);
185 13 dgisselq
 
186 4 dgisselq
        if ((m_reset_state!=0)&&(reset_n==0)) {
187
                m_reset_state = 0;
188
                m_reset_counts = 0;
189
        } else if (m_reset_state < 16) {
190 16 dgisselq
                // printf(PREFIX "::Reset-CMD = %02x,BA=%d,ADDR=%04x, counts = %d\n", cmd, ba, addr, m_reset_counts);
191 4 dgisselq
                switch(m_reset_state) {
192
                case 0:
193
                        m_reset_counts++;
194
                        if (reset_n) {
195 18 dgisselq
                                assert(m_reset_counts >= (int)ckRESET);
196 4 dgisselq
                                m_reset_counts = 0;
197
                                m_reset_state = 1;
198
                        } break;
199
                case 1:
200
                        m_reset_counts++;
201
                        if (cke) {
202 18 dgisselq
                                assert(m_reset_counts >= (int)ckCKE);
203 4 dgisselq
                                m_reset_counts = 0;
204
                                m_reset_state = 2;
205
                        } break;
206
                case 2:
207
                        m_reset_counts++;
208 6 dgisselq
                        assert(cke);
209 18 dgisselq
                        if ((cmd != DDR_NOOP)&&(cmd&DDR_DESELECT)==0) {
210
                                assert(m_reset_counts >= (int)ckXPR);
211 4 dgisselq
                                m_reset_counts = 0;
212
                                m_reset_state = 3;
213
                                assert(cmd == DDR_MRSET);
214 14 dgisselq
                                // Set MR2
215 4 dgisselq
                                assert(ba == 2);
216 16 dgisselq
                                printf(PREFIX "::Checking DDR-MR2(%04x) against %04x\n", addr, DDR_MR2);
217
                                assert(addr == DDR_MR2);
218 4 dgisselq
                        } break;
219
                case 3:
220
                        m_reset_counts++;
221 6 dgisselq
                        assert(cke);
222 18 dgisselq
                        if ((cmd != DDR_NOOP)&&(cmd&DDR_DESELECT)==0) {
223 16 dgisselq
                                assert(m_reset_counts >= (int)ckMRD);
224 4 dgisselq
                                m_reset_counts = 0;
225
                                m_reset_state = 4;
226
                                assert(cmd == DDR_MRSET);
227 14 dgisselq
                                // Set MR1
228
                                assert(ba == 1);
229 16 dgisselq
                                assert(addr == DDR_MR1);
230 4 dgisselq
                        } break;
231
                case 4:
232
                        m_reset_counts++;
233 6 dgisselq
                        assert(cke);
234 18 dgisselq
                        if ((cmd != DDR_NOOP)&&(cmd&DDR_DESELECT)==0) {
235 9 dgisselq
                                printf(PREFIX "::RESET-CMD[4]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
236 16 dgisselq
                                assert(m_reset_counts >= (int)ckMRD);
237 4 dgisselq
                                m_reset_counts = 0;
238
                                m_reset_state = 5;
239
                                assert(cmd == DDR_MRSET);
240 14 dgisselq
                                // Set MR0
241 4 dgisselq
                                assert(ba == 0);
242 16 dgisselq
                                assert(addr == DDR_MR0);
243 4 dgisselq
                        } break;
244
                case 5:
245
                        m_reset_counts++;
246 6 dgisselq
                        assert(cke);
247 18 dgisselq
                        if ((cmd != DDR_NOOP)&&(cmd&DDR_DESELECT)==0) {
248 9 dgisselq
                                printf(PREFIX "::RESET-CMD[5]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
249 16 dgisselq
                                assert(m_reset_counts >= (int)ckMOD);
250 4 dgisselq
                                m_reset_counts = 0;
251
                                m_reset_state = 6;
252
                                assert(cmd == DDR_ZQS);
253 5 dgisselq
                                assert(addr == 0x400);
254 4 dgisselq
                        } break;
255
                case 6:
256
                        m_reset_counts++;
257 6 dgisselq
                        assert(cke);
258 18 dgisselq
                        if ((cmd != DDR_NOOP)&&(cmd&DDR_DESELECT)==0) {
259 9 dgisselq
                                printf(PREFIX "::RESET-CMD[6]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
260 16 dgisselq
                                assert(m_reset_counts >= (int)ckZQinit);
261 4 dgisselq
                                m_reset_counts = 0;
262
                                m_reset_state = 7;
263
                                assert(cmd == DDR_PRECHARGE);
264 5 dgisselq
                                assert(addr == 0x400);
265 4 dgisselq
                        } break;
266
                case 7:
267
                        m_reset_counts++;
268 6 dgisselq
                        assert(cke);
269 18 dgisselq
                        if ((cmd != DDR_NOOP)&&(cmd&DDR_DESELECT)==0) {
270 9 dgisselq
                                printf(PREFIX "::RESET-CMD[7]: %d:%08x[%d]@0x%04x\n", cmd, m_reset_counts, ba, addr);
271 16 dgisselq
                                assert(m_reset_counts >= (int)ckRP);
272 4 dgisselq
                                m_reset_counts = 0;
273
                                m_reset_state = 8;
274
                                assert(cmd == DDR_REFRESH);
275 6 dgisselq
                                m_clocks_since_refresh = 0;
276 4 dgisselq
                        } break;
277
                case 8:
278
                        m_reset_counts++;
279 6 dgisselq
                        assert(cke);
280 18 dgisselq
                        assert((cmd == DDR_NOOP)||(cmd&DDR_DESELECT));
281 16 dgisselq
                        if (m_reset_counts > (int)ckRFC) {
282 4 dgisselq
                                m_reset_state = 16;
283 9 dgisselq
                                printf(PREFIX ": Leaving reset state\n");
284 5 dgisselq
                        }
285 4 dgisselq
                        break;
286
                default:
287
                        break;
288
                }
289
 
290
                gbl_state = m_reset_state;
291
                gbl_counts= m_reset_counts;
292 6 dgisselq
                m_nrefresh_issued = nREF;
293 7 dgisselq
                m_clocks_since_refresh++;
294 14 dgisselq
                for(int i=0; i<NBANKS; i++)
295
                        m_bank[i].tick(cmd, 0);
296 6 dgisselq
        } else if (!cke) {
297 4 dgisselq
                assert(0&&"Clock not enabled!");
298 6 dgisselq
        } else if ((cmd == DDR_REFRESH)||(m_nrefresh_issued < (int)nREF)) {
299
                if (DDR_REFRESH == cmd) {
300
                        m_clocks_since_refresh = 0;
301
                        if (m_nrefresh_issued >= (int)nREF)
302 7 dgisselq
                                m_nrefresh_issued = 1;
303 6 dgisselq
                        else
304
                                m_nrefresh_issued++;
305
                } else {
306
                        m_clocks_since_refresh++;
307
                        assert(DDR_NOOP == cmd);
308
                }
309
                for(int i=0; i<NBANKS; i++)
310 14 dgisselq
                        m_bank[i].tick(cmd,0);
311 7 dgisselq
 
312
                if (m_nrefresh_issued == nREF)
313 9 dgisselq
                        printf(PREFIX "::Refresh cycle complete\n");
314 6 dgisselq
        } else {
315
                // In operational mode!!
316
 
317
                m_clocks_since_refresh++;
318 16 dgisselq
                if (m_clocks_since_refresh > (int)ckREFI) {
319
                        printf(PREFIX "::ERROR! Clocks since refresh = %d, which isn\'t less than %d\n", m_clocks_since_refresh, ckREFI);
320
                }
321
                assert(m_clocks_since_refresh <= (int)ckREFI);
322 6 dgisselq
                switch(cmd) {
323 4 dgisselq
                case DDR_MRSET:
324
                        assert(0&&"Modes should only be set in reset startup");
325
                        for(int i=0; i<NBANKS; i++)
326
                                m_bank[i].tick(DDR_MRSET,0);
327
                        break;
328
                case DDR_REFRESH:
329
                        for(int i=0; i<NBANKS; i++)
330
                                m_bank[i].tick(DDR_REFRESH,0);
331 6 dgisselq
                        m_clocks_since_refresh = 0;
332
                        assert(0 && "Internal err: Refresh should be handled above");
333 4 dgisselq
                        break;
334
                case DDR_PRECHARGE:
335 14 dgisselq
                        if (addr & 0x400) {
336 4 dgisselq
                                // Precharge all
337 16 dgisselq
                                printf(PREFIX "::Precharging all banks\n");
338 4 dgisselq
                                for(int i=0; i<NBANKS; i++)
339
                                        m_bank[i].tick(DDR_PRECHARGE,0);
340
                        } else {
341 16 dgisselq
                                printf(PREFIX "::Precharging bank [%d]\n", ba);
342 4 dgisselq
                                m_bank[ba].tick(DDR_PRECHARGE,0);
343
                                for(int i=0; i<NBANKS; i++)
344
                                        if (ba != i)
345
                                                m_bank[i].tick(DDR_NOOP,0);
346
                        }
347
                        break;
348
                case DDR_ACTIVATE:
349 16 dgisselq
                        if (m_clocks_since_refresh < (int)ckRFC) {
350
                                printf(PREFIX "::ACTIVATE -- not enough clocks since refresh, %d < %d should be true\n", m_clocks_since_refresh, ckRFC);
351
                                assert(m_clocks_since_refresh >= (int)ckRFC);
352
                        }
353 14 dgisselq
                        printf(PREFIX "::Activating bank %d, address %08x\n", ba, addr);
354 4 dgisselq
                        m_bank[ba].tick(DDR_ACTIVATE,addr);
355
                        for(int i=0; i<NBANKS; i++)
356
                                if (i!=ba) m_bank[i].tick(DDR_NOOP,0);
357
                        break;
358
                case DDR_WRITE:
359
                        {
360 6 dgisselq
                                // This SIM doesn't handle out of order writes
361
                                assert((addr&7)==0);
362
                                m_bank[ba].tick(DDR_WRITE, addr);
363 4 dgisselq
                                for(int i=0; i<NBANKS; i++)
364 6 dgisselq
                                        if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
365 7 dgisselq
                                unsigned caddr = m_bank[ba].m_row;
366 8 dgisselq
                                caddr <<= 3;
367 7 dgisselq
                                caddr |= ba;
368
                                caddr <<= 10;
369
                                caddr |= addr;
370
                                caddr &= ~7;
371
                                caddr >>= 1;
372 4 dgisselq
 
373
                                BUSTIMESLOT *tp;
374 16 dgisselq
                                int     offset = m_busloc+ckCWL+1;
375 4 dgisselq
 
376 7 dgisselq
                                tp = &m_bus[(offset+0)&(NTIMESLOTS-1)];
377 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);
378 7 dgisselq
                                tp->m_addr = caddr  ;
379 4 dgisselq
                                tp->m_used = 1;
380
                                tp->m_read = 0;
381
 
382 7 dgisselq
                                tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
383
                                tp->m_addr = caddr+1;
384 4 dgisselq
                                tp->m_used = 1;
385
                                tp->m_read = 0;
386
 
387 7 dgisselq
                                tp = &m_bus[(offset+2)&(NTIMESLOTS-1)];
388
                                tp->m_addr = caddr+2;
389 4 dgisselq
                                tp->m_used = 1;
390
                                tp->m_read = 0;
391
 
392 7 dgisselq
                                tp = &m_bus[(offset+3)&(NTIMESLOTS-1)];
393
                                tp->m_addr = caddr+3;
394 4 dgisselq
                                tp->m_used = 1;
395
                                tp->m_read = 0;
396
                        } break;
397
                case DDR_READ:
398
                        {
399 6 dgisselq
                                // This SIM doesn't handle out of order reads
400
                                assert((addr&7)==0);
401
                                m_bank[ba].tick(DDR_READ, addr);
402 4 dgisselq
                                for(int i=0; i<NBANKS; i++)
403 6 dgisselq
                                        if (i!=ba)m_bank[i].tick(DDR_NOOP,addr);
404 7 dgisselq
                                unsigned caddr = m_bank[ba].m_row;
405 8 dgisselq
                                caddr <<= 3;
406 7 dgisselq
                                caddr |= ba;
407
                                caddr <<= 10;
408
                                caddr |= addr;
409
                                caddr &= ~7;
410
                                caddr >>= 1;
411 4 dgisselq
 
412
                                BUSTIMESLOT *tp;
413 16 dgisselq
 
414
                                printf(PREFIX"::READ(%03x:%d:%03x => %08x) Queuing %08x:%08x:%08x:%08x\n",
415
                                        m_bank[ba].m_row, ba, addr,
416
                                        caddr,
417
                                        m_mem[caddr  ], m_mem[caddr+1],
418
                                        m_mem[caddr+2], m_mem[caddr+3]);
419 8 dgisselq
                                int offset = (m_busloc+ckCL+1)&(NTIMESLOTS-1);
420
                                tp = &m_bus[(offset)&(NTIMESLOTS-1)];
421 7 dgisselq
                                tp->m_data = m_mem[caddr];
422
                                tp->m_addr = caddr;
423 4 dgisselq
                                tp->m_used = 1;
424
                                tp->m_read = 1;
425
 
426 8 dgisselq
                                tp = &m_bus[(offset+1)&(NTIMESLOTS-1)];
427 7 dgisselq
                                tp->m_data = m_mem[caddr+1];
428
                                tp->m_addr = caddr+1;
429 4 dgisselq
                                tp->m_used = 1;
430
                                tp->m_read = 1;
431
 
432 8 dgisselq
                                tp = &m_bus[(offset+2)&(NTIMESLOTS-1)];
433 7 dgisselq
                                tp->m_data = m_mem[caddr+2];
434
                                tp->m_addr = caddr+2;
435 4 dgisselq
                                tp->m_used = 1;
436
                                tp->m_read = 1;
437
 
438 8 dgisselq
                                tp = &m_bus[(offset+3)&(NTIMESLOTS-1)];
439 7 dgisselq
                                tp->m_data = m_mem[caddr+3];
440
                                tp->m_addr = caddr+3;
441 4 dgisselq
                                tp->m_used = 1;
442
                                tp->m_read = 1;
443
                        } break;
444
                case DDR_ZQS:
445
                        assert(0&&"Sim does not support ZQS outside of startup");
446
                        break;
447
                case DDR_NOOP:
448 18 dgisselq
                default: // We are deselected
449 4 dgisselq
                        for(int i=0; i<NBANKS; i++)
450
                                m_bank[i].tick(DDR_NOOP,addr);
451
                        break;
452 6 dgisselq
                }
453 13 dgisselq
 
454 14 dgisselq
                if (false) {
455 13 dgisselq
                        bool flag = false;
456
                        for(int i=0; i<5; i++) {
457
                                int bl = (m_busloc+1+i)&(NTIMESLOTS-1);
458
                                nxtts = &m_bus[bl];
459
                                if (nxtts->m_used) {
460
                                        flag = true;
461
                                        break;
462
                                }
463
                        } if (flag) {
464 16 dgisselq
                        printf(PREFIX "::DQS = %d BUSLOC = %d\n", dqs, (m_busloc+1)&(NTIMESLOTS-1));
465 13 dgisselq
                        for(int i=0; i<5; i++) {
466
                                int bl = (m_busloc+1+i)&(NTIMESLOTS-1);
467
                                nxtts = &m_bus[bl];
468
                                printf("BUS[%2d] ", bl);
469
                                if (nxtts->m_used)
470
                                        printf(" USED");
471
                                if (nxtts->m_read)
472
                                        printf(" READ");
473
                                if (nxtts->m_rtt)
474
                                        printf(" RTT");
475
                                printf("\n");
476
                        }}
477
                }
478
 
479
                ts = &m_bus[(m_busloc+1)&(NTIMESLOTS-1)];
480 16 dgisselq
                if (dqs) {
481
                        if ((!ts->m_rtt)||(!m_last_rtt)) {
482
                                printf(PREFIX "ODT(dqs is true) m_rtt is %s and last_rtt is %s.  Both should be true if DQS.  (ERROR!)\n",
483
                                        (ts->m_rtt)?"true":"false",
484
                                        (m_last_rtt)?"true":"false");
485 18 dgisselq
                        }
486 13 dgisselq
                        assert((ts->m_rtt)&&(m_last_rtt));
487 18 dgisselq
                } // else if (!m_last_dqs)
488
                //      assert(!m_last_rtt);
489 4 dgisselq
        }
490
 
491
        m_busloc = (m_busloc+1)&(NTIMESLOTS-1);
492
 
493 13 dgisselq
        ts = &m_bus[m_busloc];
494
        nxtts = &m_bus[(m_busloc+1)&(NTIMESLOTS-1)];
495 4 dgisselq
        unsigned vl = ts->m_data;
496 16 dgisselq
 
497 18 dgisselq
        /*
498 4 dgisselq
        assert( ((!ts->m_used)||(busoe))
499 13 dgisselq
                || ((ts->m_used)&&(ts->m_read)&&(!busoe))
500
                || ((ts->m_used)&&(!ts->m_read)&&(busoe))
501
                );
502 18 dgisselq
        */
503 4 dgisselq
 
504 13 dgisselq
        m_last_dqs = dqs;
505
        m_last_rtt = ts->m_rtt;
506
 
507 18 dgisselq
        /*
508 13 dgisselq
        if (ts->m_used) {
509
                if (ts->m_read)
510
                        assert((!dqs)&&(!m_last_dqs));
511
                else
512
                        assert((dqs) && (m_last_dqs));
513
        } else if (!nxtts->m_used)
514
                assert(!dqs);
515 18 dgisselq
        */
516 13 dgisselq
 
517 18 dgisselq
        // assert((!ts->m_used)||(ts->m_addr < (unsigned)m_memlen));
518 16 dgisselq
        if ((ts->m_used)&&(!ts->m_read)&&(dm != 0x0f)) {
519
                printf(PREFIX "::Setting MEM[%08x] = %08x (%02x)\n", ts->m_addr, data, dm);
520
                unsigned mask = 0;
521
                if (dm&0x08) mask = 0x0ff;
522
                mask <<= 8; if (dm&0x004) mask |= 0x0ff;
523
                mask <<= 8; if (dm&0x002) mask |= 0x0ff;
524
                mask <<= 8; if (dm&0x001) mask |= 0x0ff;
525
                m_mem[ts->m_addr] = (data & (~mask)) | (m_mem[ts->m_addr]&mask);
526
        } else if ((ts->m_used)&&(ts->m_read)) {
527
                printf(PREFIX ":: %08x\n", vl);
528 7 dgisselq
        }
529 13 dgisselq
 
530 16 dgisselq
        m_bus[(m_busloc+ckODT-1)&(NTIMESLOTS-1)].m_rtt = (odt)&&(reset_n);
531 4 dgisselq
        ts->m_used = 0;
532
        ts->m_read = 0;
533
        ts->m_addr = -1;
534 13 dgisselq
        ts->m_rtt  = 0;
535 4 dgisselq
        return (!busoe)?vl:data;
536
}
537
 

powered by: WebSVN 2.1.0

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