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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [bench/] [cpp/] [sdramsim.cpp] - Blame information for rev 38

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

Line No. Rev Author Line
1 4 dgisselq
#include <stdio.h>
2
#include <stdlib.h>
3
#include <assert.h>
4
 
5
#include "sdramsim.h"
6
 
7
short   SDRAMSIM::operator()(int clk, int cke, int cs_n, int ras_n, int cas_n, int we_n,
8
                int bs, unsigned addr, int driv, short data) {
9
        short   result = 0;
10
 
11 37 dgisselq
        if (driv) // If the bus is going out, reads don't make sense ... but
12
                result = data; // read what we output anyway
13
        else if (!clk) // If the clock is zero, return our last value
14
                return m_last_value; // Always called w/clk=1, thus never here
15 4 dgisselq
        if (!cke) {
16
                fprintf(stderr, "This simulation only supports CKE high!\n");
17
                fprintf(stderr, "\tCKE   = %d\n", cke);
18
                fprintf(stderr, "\tCS_n  = %d\n", cs_n);
19
                fprintf(stderr, "\tRAS_n = %d\n", ras_n);
20
                fprintf(stderr, "\tCAS_n = %d\n", cas_n);
21
                fprintf(stderr, "\tWE_n  = %d\n", we_n);
22
                assert(cke);
23
        }
24
 
25
        if (m_pwrup < POWERED_UP_STATE) {
26
                if (m_clocks_till_idle > 0)
27
                        m_clocks_till_idle--;
28
                if (m_pwrup == 0) {
29
                        assert((ras_n)&&(cas_n)&&(we_n));
30
                        if (m_clocks_till_idle == 0) {
31
                                m_pwrup++;
32 37 dgisselq
                                // printf("Successful power up wait, moving to state #1\n");
33 4 dgisselq
                        }
34
                } else if (m_pwrup == 1) {
35
                        if ((!cs_n)&&(!ras_n)&&(cas_n)&&(!we_n)&&(addr&0x0400)) {
36
                                // Wait until a precharge all banks command
37
                                m_pwrup++;
38 37 dgisselq
                                // printf("Successful precharge command, moving to state #2\n");
39 4 dgisselq
                                m_clocks_till_idle = 8;
40
                        }
41
                } else if (m_pwrup == 2) {
42
                        // Need 8 auto refresh cycles before or after the mode
43
                        // set command.  We'll insist they be before.
44
                        if (m_clocks_till_idle == 0) {
45
                                m_pwrup++;
46 37 dgisselq
                                // printf("Successful initial auto-refresh, waiting for mode-set\n");
47 4 dgisselq
                                for(int i=0; i<m_nrefresh; i++)
48
                                        m_refresh_time[i] = MAX_REFRESH_TIME;
49
                        } else
50
                                assert((!cs_n)&&(!ras_n)&&(!cas_n)&&(we_n));
51
                } else if (m_pwrup == 3) {
52
                        const int tRSC = 2;
53
                        if ((!cs_n)&&(!ras_n)&&(!cas_n)&&(!we_n)){
54
                                // mode set
55 37 dgisselq
                                // printf("Mode set: %08x\n", addr);
56 4 dgisselq
                                assert(addr == 0x021);
57
                                m_pwrup++;
58 37 dgisselq
                                // printf("Successful mode set, moving to state #3, tRSC = %d\n", tRSC);
59 4 dgisselq
                                m_clocks_till_idle=tRSC;
60
                        }
61
                } else if (m_pwrup == 4) {
62
                        assert(cs_n);
63
                        if (m_clocks_till_idle == 0) {
64
                                m_pwrup = POWERED_UP_STATE;
65
                                m_clocks_till_idle = 0;
66 37 dgisselq
                                // printf("Successful settup!  SDRAM switching to operational\n");
67 4 dgisselq
                        } else if (m_clocks_till_idle == 1) {
68
                                ;
69
                        } else assert(0 && "Should never get here!");
70
                } else if (m_pwrup == 5) {
71
                        if ((!cs_n)&&(!ras_n)&&(!cas_n)&&(we_n)) {
72
                                if (m_clocks_till_idle == 0) {
73
                                        m_pwrup = POWERED_UP_STATE;
74
                                        m_clocks_till_idle = 0;
75
 
76
                                        for(int i=0; i<m_nrefresh; i++)
77
                                                m_refresh_time[i] = MAX_REFRESH_TIME;
78
                                }
79
                        } else {
80
                                assert(0);
81
                        }
82
                }
83
                m_next_wr = false;
84
        } else { // In operation ...
85
                for(int i=0; i<m_nrefresh; i++)
86
                        m_refresh_time[i]--;
87
                if (m_refresh_time[m_refresh_loc] < 0) {
88
                        assert(0 && "Failed refresh requirement");
89
                } for(int i=0; i<NBANKS; i++) {
90
                        m_bank_status[i] >>= 1;
91
                        if (m_bank_status[i]&2)
92
                                m_bank_status[i] |= 4;
93
                        if (m_bank_status[i]&1) { // Bank is open
94
                                m_bank_open_time[i] --;
95
                                if (m_bank_open_time[i] < 0) {
96
                                        assert(0 && "Bank held open too long");
97
                                }
98
                        }
99
                }
100
 
101
                if (m_clocks_till_idle)
102
                        m_clocks_till_idle--;
103
 
104
                if (m_fail > 0) {
105
                        m_fail--;
106
                        if (m_fail == 0) {
107
                                fprintf(stderr, "Failing on schedule\n");
108
                                exit(-3);
109
                        }
110
                }
111
 
112
                if ((m_clocks_till_idle > 0)&&(m_next_wr)) {
113 37 dgisselq
                        // printf("SDRAM[%08x] <= %04x\n", m_wr_addr, data & 0x0ffff);
114 4 dgisselq
                        m_mem[m_wr_addr++] = data;
115
                        result = data;
116
                        m_next_wr = false;
117
                }
118
                m_qloc = (m_qloc + 1)&m_qmask;
119 37 dgisselq
                result = (driv)?data:m_qdata[(m_qloc)&m_qmask];
120
                m_qdata[(m_qloc)&m_qmask] = 0;
121 4 dgisselq
 
122 37 dgisselq
                // if (result != 0)
123
                        // printf("%d RESULT[%3d] = %04x\n", clk, m_qloc, result&0x0ffff);
124
 
125 4 dgisselq
                if ((!cs_n)&&(!ras_n)&&(!cas_n)&&(we_n)) {
126
                        // Auto-refresh command
127
                        m_refresh_time[m_refresh_loc] = MAX_REFRESH_TIME;
128
                        m_refresh_loc++;
129
                        if (m_refresh_loc >= m_nrefresh)
130
                                m_refresh_loc = 0;
131
                        assert((m_bank_status[0]&6) == 0);
132
                        assert((m_bank_status[1]&6) == 0);
133
                        assert((m_bank_status[2]&6) == 0);
134
                        assert((m_bank_status[3]&6) == 0);
135
                } else if ((!cs_n)&&(!ras_n)&&(cas_n)&&(!we_n)) {
136
                        if (addr&0x0400) {
137
                                // Bank/Precharge All CMD
138
                                for(int i=0; i<NBANKS; i++)
139
                                        m_bank_status[i] &= 0x03;
140
                        } else {
141
                                // Precharge/close single bank
142
                                assert(0 == (bs & (~3))); // Assert w/in bounds
143
                                m_bank_status[bs] &= 0x03; // Close the bank
144
 
145 37 dgisselq
                                // printf("Precharging bank %d\n", bs);
146 4 dgisselq
                        }
147
                } else if ((!cs_n)&&(!ras_n)&&(cas_n)&&(we_n)) {
148 37 dgisselq
                        // printf("Activating bank %d\n", bs);
149 4 dgisselq
                        // Activate a bank!
150
                        if (0 != (bs & (~3))) {
151
                                m_fail = 2;
152
                                fprintf(stderr, "ERR: Activating a bank w/ more than 2 bits\n");
153
                                // assert(0 == (bs & (~3))); // Assert w/in bounds
154
                        } else if (m_bank_status[bs] != 0) {
155
                                fprintf(stderr, "ERR: Status of bank [bs=%d] = %d != 0\n",
156
                                        bs, m_bank_status[bs]);
157
                                m_fail = 4;
158
                                // assert(m_bank_status[bs]==0); // Assert bank was closed
159
                        }
160
                        m_bank_status[bs] |= 4;
161
                        m_bank_open_time[bs] = MAX_BANKOPEN_TIME;
162
                        m_bank_row[bs] = addr;
163
                } else if ((!cs_n)&&(ras_n)&&(!cas_n)) {
164 37 dgisselq
                        // printf("R/W Op\n");
165 4 dgisselq
                        if (!we_n) {
166
                                // Initiate a write
167
                                assert(0 == (bs & (~3))); // Assert w/in bounds
168
                                assert(m_bank_status[bs]&1); // Assert bank is open
169
 
170
                                m_wr_addr = m_bank_row[bs];
171
                                m_wr_addr <<= 2;
172
                                m_wr_addr |= bs;
173
                                m_wr_addr <<= 9;
174
                                m_wr_addr |= (addr & 0x01ff);
175
 
176
                                assert(driv);
177 37 dgisselq
                                // printf("SDRAM[%08x] <= %04x\n", m_wr_addr, data & 0x0ffff);
178 4 dgisselq
                                m_mem[m_wr_addr++] = data;
179
                                m_clocks_till_idle = 2;
180
                                m_next_wr = true;
181
 
182
                                if (addr & 0x0400) { // Auto precharge
183
                                        m_bank_status[bs] &= 3;
184
                                        m_bank_open_time[bs] = MAX_BANKOPEN_TIME;
185
                                }
186
                        } else { // Initiate a read
187
                                assert(0 == (bs & (~3))); // Assert w/in bounds
188
                                assert(m_bank_status[bs]&1); // Assert bank is open
189
 
190
                                unsigned        rd_addr;
191
 
192
                                rd_addr = m_bank_row[bs] & 0x01fff;
193
                                rd_addr <<= 2;
194
                                rd_addr |= bs;
195
                                rd_addr <<= 9;
196
                                rd_addr |= (addr & 0x01ff);
197
 
198
                                assert(!driv);
199 37 dgisselq
                                // printf("SDRAM.Q[%2d] %04x <= SDRAM[%08x]\n",
200
                                        // (m_qloc+3)&m_qmask,
201
                                        // m_mem[rd_addr] & 0x0ffff, rd_addr);
202
                                m_qdata[(m_qloc+3)&m_qmask] = m_mem[rd_addr++];
203
                                // printf("SDRAM.Q[%2d] %04x <= SDRAM[%08x]\n",
204
                                        // (m_qloc+4)&m_qmask,
205
                                        // m_mem[rd_addr] & 0x0ffff, rd_addr);
206
                                m_qdata[(m_qloc+4)&m_qmask] = m_mem[rd_addr++];
207 4 dgisselq
                                m_clocks_till_idle = 2;
208
 
209
                                if (addr & 0x0400) { // Auto precharge
210
                                        m_bank_status[bs] &= 3;
211
                                        m_bank_open_time[bs] = MAX_BANKOPEN_TIME;
212
                                }
213
                        }
214
                } else if (cs_n) {
215
                        // Chips not asserted, DESELECT CMD equivalent of a NOOP
216
                } else if ((ras_n)&&(cas_n)&&(we_n)) {
217
                        // NOOP command
218
                } else {
219
                        fprintf(stderr, "Unrecognized memory command!\n");
220
                        fprintf(stderr, "\tCS_n  = %d\n", cs_n);
221
                        fprintf(stderr, "\tRAS_n = %d\n", ras_n);
222
                        fprintf(stderr, "\tCAS_n = %d\n", cas_n);
223
                        fprintf(stderr, "\tWE_n  = %d\n", we_n);
224
                        assert(0 && "Unrecognizned command");
225
                }
226
        }
227
 
228
        return result & 0x0ffff;
229
}
230
 
231
 

powered by: WebSVN 2.1.0

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