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

Subversion Repositories xulalx25soc

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

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
        if (driv)
12
                result = data;
13
        else if (!clk)
14
                return m_last_value;
15
        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
                                printf("Successful power up wait, moving to state #1\n");
33
                        }
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
                                printf("Successful precharge command, moving to state #2\n");
39
                                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
                                printf("Successful initial auto-refresh, waiting for mode-set\n");
47
                                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
                                printf("Mode set: %08x\n", addr);
56
                                assert(addr == 0x021);
57
                                m_pwrup++;
58
                                printf("Successful mode set, moving to state #3, tRSC = %d\n", tRSC);
59
                                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
                                printf("Successful settup!  SDRAM switching to operational\n");
67
                        } 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
                        printf("SDRAM[%08x] <= %04x\n", m_wr_addr, data & 0x0ffff);
114
                        m_mem[m_wr_addr++] = data;
115
                        result = data;
116
                        m_next_wr = false;
117
                } else {
118
                        result = (driv)?data:m_qdata[m_qloc];
119
                }
120
                m_qloc = (m_qloc + 1)&m_qmask;
121
 
122
                if ((!cs_n)&&(!ras_n)&&(!cas_n)&&(we_n)) {
123
                        // Auto-refresh command
124
                        m_refresh_time[m_refresh_loc] = MAX_REFRESH_TIME;
125
                        m_refresh_loc++;
126
                        if (m_refresh_loc >= m_nrefresh)
127
                                m_refresh_loc = 0;
128
                        assert((m_bank_status[0]&6) == 0);
129
                        assert((m_bank_status[1]&6) == 0);
130
                        assert((m_bank_status[2]&6) == 0);
131
                        assert((m_bank_status[3]&6) == 0);
132
                } else if ((!cs_n)&&(!ras_n)&&(cas_n)&&(!we_n)) {
133
                        if (addr&0x0400) {
134
                                // Bank/Precharge All CMD
135
                                for(int i=0; i<NBANKS; i++)
136
                                        m_bank_status[i] &= 0x03;
137
                        } else {
138
                                // Precharge/close single bank
139
                                assert(0 == (bs & (~3))); // Assert w/in bounds
140
                                m_bank_status[bs] &= 0x03; // Close the bank
141
 
142
                                printf("Precharging bank %d\n", bs);
143
                        }
144
                } else if ((!cs_n)&&(!ras_n)&&(cas_n)&&(we_n)) {
145
                        printf("Activating bank %d\n", bs);
146
                        // Activate a bank!
147
                        if (0 != (bs & (~3))) {
148
                                m_fail = 2;
149
                                fprintf(stderr, "ERR: Activating a bank w/ more than 2 bits\n");
150
                                // assert(0 == (bs & (~3))); // Assert w/in bounds
151
                        } else if (m_bank_status[bs] != 0) {
152
                                fprintf(stderr, "ERR: Status of bank [bs=%d] = %d != 0\n",
153
                                        bs, m_bank_status[bs]);
154
                                m_fail = 4;
155
                                // assert(m_bank_status[bs]==0); // Assert bank was closed
156
                        }
157
                        m_bank_status[bs] |= 4;
158
                        m_bank_open_time[bs] = MAX_BANKOPEN_TIME;
159
                        m_bank_row[bs] = addr;
160
                } else if ((!cs_n)&&(ras_n)&&(!cas_n)) {
161
                        printf("R/W Op\n");
162
                        if (!we_n) {
163
                                // Initiate a write
164
                                assert(0 == (bs & (~3))); // Assert w/in bounds
165
                                assert(m_bank_status[bs]&1); // Assert bank is open
166
 
167
                                m_wr_addr = m_bank_row[bs];
168
                                m_wr_addr <<= 2;
169
                                m_wr_addr |= bs;
170
                                m_wr_addr <<= 9;
171
                                m_wr_addr |= (addr & 0x01ff);
172
 
173
                                assert(driv);
174
                                printf("SDRAM[%08x] <= %04x\n", m_wr_addr, data & 0x0ffff);
175
                                m_mem[m_wr_addr++] = data;
176
                                m_clocks_till_idle = 2;
177
                                m_next_wr = true;
178
 
179
                                if (addr & 0x0400) { // Auto precharge
180
                                        m_bank_status[bs] &= 3;
181
                                        m_bank_open_time[bs] = MAX_BANKOPEN_TIME;
182
                                }
183
                        } else { // Initiate a read
184
                                assert(0 == (bs & (~3))); // Assert w/in bounds
185
                                assert(m_bank_status[bs]&1); // Assert bank is open
186
 
187
                                unsigned        rd_addr;
188
 
189
                                rd_addr = m_bank_row[bs] & 0x01fff;
190
                                rd_addr <<= 2;
191
                                rd_addr |= bs;
192
                                rd_addr <<= 9;
193
                                rd_addr |= (addr & 0x01ff);
194
 
195
                                assert(!driv);
196
                                printf("SDRAM.Q %04x <= SDRAM[%08x]\n",
197
                                        m_mem[rd_addr] & 0x0ffff, rd_addr);
198
                                m_qdata[(m_qloc+1)&m_qmask] = m_mem[rd_addr++];
199
                                printf("SDRAM.Q %04x <= SDRAM[%08x]\n",
200
                                        m_mem[rd_addr] & 0x0ffff, rd_addr);
201
                                m_qdata[(m_qloc+2)&m_qmask] = m_mem[rd_addr++];
202
                                m_clocks_till_idle = 2;
203
 
204
                                if (addr & 0x0400) { // Auto precharge
205
                                        m_bank_status[bs] &= 3;
206
                                        m_bank_open_time[bs] = MAX_BANKOPEN_TIME;
207
                                }
208
                        }
209
                } else if (cs_n) {
210
                        // Chips not asserted, DESELECT CMD equivalent of a NOOP
211
                } else if ((ras_n)&&(cas_n)&&(we_n)) {
212
                        // NOOP command
213
                } else {
214
                        fprintf(stderr, "Unrecognized memory command!\n");
215
                        fprintf(stderr, "\tCS_n  = %d\n", cs_n);
216
                        fprintf(stderr, "\tRAS_n = %d\n", ras_n);
217
                        fprintf(stderr, "\tCAS_n = %d\n", cas_n);
218
                        fprintf(stderr, "\tWE_n  = %d\n", we_n);
219
                        assert(0 && "Unrecognizned command");
220
                }
221
        }
222
 
223
        return result & 0x0ffff;
224
}
225
 
226
 

powered by: WebSVN 2.1.0

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