OpenCores
URL https://opencores.org/ocsvn/sdhc-sc-core/sdhc-sc-core/trunk

Subversion Repositories sdhc-sc-core

[/] [sdhc-sc-core/] [trunk/] [grpSdVerification/] [unitSdCardModel/] [src/] [SdCardModel.sv] - Blame information for rev 185

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 164 rkastl
// SDHC-SC-Core
2
// Secure Digital High Capacity Self Configuring Core
3 44 rkastl
//
4 170 rkastl
// (C) Copyright 2010, Rainer Kastl
5
// All rights reserved.
6 164 rkastl
//
7 170 rkastl
// Redistribution and use in source and binary forms, with or without
8
// modification, are permitted provided that the following conditions are met:
9
//     * Redistributions of source code must retain the above copyright
10
//       notice, this list of conditions and the following disclaimer.
11
//     * Redistributions in binary form must reproduce the above copyright
12
//       notice, this list of conditions and the following disclaimer in the
13
//       documentation and/or other materials provided with the distribution.
14
//     * Neither the name of the  nor the
15
//       names of its contributors may be used to endorse or promote products
16
//       derived from this software without specific prior written permission.
17 164 rkastl
//
18 170 rkastl
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  "AS IS" AND
19
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
// DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
22
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 164 rkastl
//
29
// File        : SdCardModel.sv
30
// Owner       : Rainer Kastl
31
// Description : SD Card model
32
// Links       :
33
//
34 44 rkastl
 
35 135 rkastl
`ifndef SDCARDMODEL
36
`define SDCARDMODEL
37
 
38 44 rkastl
const logic cActivated = 1;
39
const logic cInactivated = 0;
40
 
41 135 rkastl
`include "Crc.sv";
42
`include "SdCommand.sv";
43 145 rkastl
`include "SdBFM.sv";
44
`include "Logger.sv";
45 153 rkastl
`include "RamAction.sv";
46 44 rkastl
 
47 160 rkastl
class RamModel;
48
        local bit[0:511][7:0] data[];
49
        RamActionMb RamActionOutMb;
50
 
51
        function new(int size);
52
                data = new[size];
53
        endfunction
54
 
55
        function int size();
56
                return data.size();
57
        endfunction
58
 
59
        task getDataBlock(logic[31:0] addr, output SdDataBlock block);
60
                RamAction action = new(RamAction::Read, addr, data[addr]);
61
                block = new();
62
 
63
                for (int i = 0; i < 512; i++) begin
64
                        for (int j = 7; j >= 0; j--) begin
65
                                block.data.push_back(data[addr][i][j]);
66
                        end
67
                end
68
 
69 167 rkastl
                if (RamActionOutMb != null)
70
                begin
71
                        RamActionOutMb.put(action);
72
                end
73 160 rkastl
        endtask
74
 
75
        task setDataBlock(logic[31:0] addr, SdDataBlock block);
76
                for (int i = 0; i < 512; i++) begin
77
                        for (int j = 7; j >= 0; j--) begin
78
                                data[addr][i][j] = block.data.pop_front();
79
                        end
80
                end
81 166 rkastl
 
82
                if (RamActionOutMb != null)
83 160 rkastl
                begin
84
                        RamAction action = new(RamAction::Write, addr, data[addr]);
85
                        RamActionOutMb.put(action);
86
                end
87
        endtask
88
 
89
endclass
90
 
91 151 rkastl
class SdCardModel;
92 153 rkastl
 
93
        SdBfmMb SdTransOutMb;
94
        SdBfmMb SdTransInMb;
95
 
96 157 rkastl
        SdBFM bfm;
97 160 rkastl
        local SdCardModelState state = new();
98 63 rkastl
        local RCA_t rca;
99 59 rkastl
        local logic CCS;
100 100 rkastl
        local Mode_t mode;
101
        local DataMode_t datamode;
102 160 rkastl
        local Logger log = new();
103
        RamModel ram;
104 44 rkastl
 
105 159 rkastl
        //local rand int datasize; // ram addresses = 2^datasize - 1; 512 byte blocks
106
        //constraint cdatasize {datasize == 32;}
107 145 rkastl
 
108 159 rkastl
        /*function void post_randomize() ;
109
                this.ram = new[datasize];
110
        endfunction*/
111 125 rkastl
 
112 153 rkastl
        function new();
113 125 rkastl
                this.CCS = 1;
114 63 rkastl
                rca = 0;
115 100 rkastl
                mode = standard;
116 160 rkastl
                ram = new(100);
117 44 rkastl
        endfunction
118
 
119 157 rkastl
        task start();
120
                fork
121
                        run();
122
                join_none
123
        endtask
124 153 rkastl
 
125 44 rkastl
        task reset();
126
        endtask
127
 
128 53 rkastl
        task automatic init();
129
                SDCommandR7 voltageresponse;
130 57 rkastl
                SDCommandR1 response;
131 59 rkastl
                SDCommandR3 acmd41response;
132 62 rkastl
                SDCommandR2 cidresponse;
133 59 rkastl
                SDOCR ocr;
134 63 rkastl
                SDCommandR6 rcaresponse;
135 100 rkastl
                logic data[$];
136 145 rkastl
                SdBusTransToken token;
137 125 rkastl
 
138 145 rkastl
                log.note("Expecting CMD0");
139 53 rkastl
                // expect CMD0 so that state is clear
140 145 rkastl
                this.bfm.receive(token);
141
                assert(token.id == cSdCmdGoIdleState) else log.error("Received invalid token.");
142 53 rkastl
 
143
                // expect CMD8: voltage and SD 2.00 compatible
144 145 rkastl
                log.note("Expecting CMD8");
145
                this.bfm.receive(token);
146
                assert(token.id == cSdCmdSendIfCond) else log.error("Received invalid token.");
147
                assert(token.arg[12:8] == 'b0001) else
148
                begin
149
                        string msg;
150
                        $swrite(msg, "Received invalid arg: %b", token.arg);
151
                        log.error(msg); // Standard voltage
152
                end;
153 53 rkastl
 
154
                // respond with R7: we are SD 2.00 compatible and compatible to the
155
                // voltage
156 145 rkastl
                voltageresponse = new(token.arg);
157
                this.bfm.send(voltageresponse);
158 53 rkastl
 
159 102 rkastl
                recvCMD55(0);
160 57 rkastl
 
161
                // expect ACMD41 with HCS = 1
162 145 rkastl
                log.note("Expect ACMD41 (with HCS = 1)");
163
                this.bfm.receive(token);
164
                assert(token.id == cSdCmdACMD41) else log.error("Received invalid token.\n");
165
                assert(token.arg == cSdArgACMD41HCS) else begin
166
                        string msg;
167
                        $swrite(msg, "Received invalid arg: %b, Expected: %b", token.arg, cSdArgACMD41HCS);
168
                        log.error(msg);
169
                end;
170
                state.AppCmd = 0;
171 57 rkastl
 
172 145 rkastl
                // respond with R3, not done
173 59 rkastl
                ocr = new(CCS, cSdVoltageWindow);
174
                acmd41response = new(ocr);
175 145 rkastl
                this.bfm.send(acmd41response);
176 60 rkastl
 
177 102 rkastl
                recvCMD55(0);
178 59 rkastl
 
179 60 rkastl
                // expect ACMD41 with HCS = 1
180 145 rkastl
                log.note("Expect ACMD41 (with HCS = 1)");
181
                this.bfm.receive(token);
182
                assert(token.id == cSdCmdACMD41) else log.error("Received invalid token.\n");
183
                assert(token.arg == cSdArgACMD41HCS) else begin
184
                        string msg;
185
                        $swrite(msg, "Received invalid arg: %b, Expected: %b", token.arg, cSdArgACMD41HCS);
186
                        log.error(msg);
187
                end;
188 98 rkastl
                state.AppCmd = 0;
189 60 rkastl
 
190
                // respond with R3
191
                ocr.setBusy(cOCRDone);
192
                acmd41response = new(ocr);
193 145 rkastl
                this.bfm.send(acmd41response);
194 60 rkastl
 
195 62 rkastl
                // expect CMD2
196 145 rkastl
                log.note("Expect CMD2");
197
                this.bfm.receive(token);
198
                assert(token.id == cSdCmdAllSendCID) else log.error("Received invalid token.\n");
199 62 rkastl
 
200
                // respond with R2
201
                cidresponse = new();
202 145 rkastl
                this.bfm.send(cidresponse);
203 62 rkastl
 
204 63 rkastl
                // expect CMD3
205 145 rkastl
                log.note("Expect CMD3");
206
                this.bfm.receive(token);
207
                assert(token.id == cSdCmdSendRelAdr) else log.error("Received invalid token.\n");
208 63 rkastl
 
209
                // respond with R3
210
                rcaresponse = new(rca, state);
211 145 rkastl
                this.bfm.send(rcaresponse);
212 63 rkastl
 
213 96 rkastl
                // expect CMD7
214 145 rkastl
                log.note("Expect CMD7");
215
                this.bfm.receive(token);
216
                assert(token.id == cSdCmdSelCard);
217
                assert(token.arg[31:16] == rca);
218 96 rkastl
 
219 98 rkastl
                // respond with R1, no busy
220
                state.ReadyForData = 1;
221
                response = new(cSdCmdSelCard, state);
222 145 rkastl
                this.bfm.send(response);
223 96 rkastl
 
224 99 rkastl
                // expect ACMD51
225 102 rkastl
                recvCMD55(rca);
226 145 rkastl
                log.note("Expect ACMD51");
227
                this.bfm.receive(token);
228
                assert(token.id == cSdCmdSendSCR);
229 99 rkastl
 
230 150 rkastl
                // respond with R1 and dummy SCR
231 99 rkastl
                response = new(cSdCmdSendSCR, state);
232 150 rkastl
                response.DataBlocks = new[1];
233
                response.DataBlocks[0] = new();
234
 
235 100 rkastl
                // send dummy SCR
236 101 rkastl
                for (int i = 0; i < 64; i++)
237 150 rkastl
                        response.DataBlocks[0].data.push_back(0);
238 100 rkastl
 
239 150 rkastl
                response.DataBlocks[0].data[63-50] = 1;
240
                response.DataBlocks[0].data[63-48] = 1;
241 100 rkastl
 
242 150 rkastl
                this.bfm.send(response);
243 100 rkastl
 
244 102 rkastl
                // expect ACMD6
245
                recvCMD55(rca);
246 145 rkastl
                log.note("Expect ACMD6");
247
                this.bfm.receive(token);
248
                assert(token.id == cSdCmdSetBusWidth);
249
                assert(token.arg == 'h00000002);
250 102 rkastl
 
251
                response = new(cSdCmdSetBusWidth, state);
252 145 rkastl
                this.bfm.send(response);
253 102 rkastl
 
254 150 rkastl
                this.bfm.Mode = wide;
255 123 rkastl
                mode = wide;
256 103 rkastl
 
257
                // expect CMD6
258 145 rkastl
                log.note("Expect CMD6");
259
                this.bfm.receive(token);
260
                assert(token.id == cSdCmdSwitchFuntion);
261
                assert(token.arg == 'h00FFFFF1);
262 103 rkastl
 
263 150 rkastl
                response.DataBlocks = new[1];
264
                response.DataBlocks[0] = new();
265 103 rkastl
 
266
                for (int i = 0; i < 512; i++)
267 150 rkastl
                        response.DataBlocks[0].data.push_back(0);
268 103 rkastl
 
269 150 rkastl
                response.DataBlocks[0].data[511-401] = 1;
270
                response.DataBlocks[0].data[511-376] = 1;
271 104 rkastl
 
272 150 rkastl
                this.bfm.send(response);
273
 
274 104 rkastl
                // expect CMD6 with set
275 145 rkastl
                log.note("Expect CMD6 with set");
276
                this.bfm.receive(token);
277
                assert(token.id == cSdCmdSwitchFuntion);
278
                assert(token.arg == 'h80FFFFF1);
279
                this.bfm.send(response);
280 104 rkastl
 
281
                // switch to 50MHz
282 105 rkastl
                // expect CMD13
283 145 rkastl
                log.note("Expect CMD13");
284
                this.bfm.receive(token);
285
                assert(token.id == cSdCmdSendStatus);
286
                assert(token.arg == rca);
287 105 rkastl
                response = new(cSdCmdSendStatus, state);
288 145 rkastl
                this.bfm.send(response);
289 104 rkastl
 
290 157 rkastl
                log.note("Card init done");
291 122 rkastl
        endtask
292
 
293 148 rkastl
        task run();
294
                this.init();
295
 
296
                forever begin
297
                        SdBusTransToken token;
298
                        this.bfm.receive(token);
299
 
300
                        case (token.id)
301
                                cSdCmdWriteSingleBlock: this.write(token);
302
                                cSdCmdReadSingleBlock: this.read(token);
303
                                default: begin
304
                                                string msg;
305
                                                $swrite(msg, "Token not handled, ID: %b", token.id);
306
                                                log.error(msg);
307
                                end
308
                        endcase
309
                end
310
        endtask
311
 
312
        task read(SdBusTransToken token);
313 122 rkastl
                SDCommandR1 response;
314 126 rkastl
                logic[31:0] addr;
315 122 rkastl
 
316 113 rkastl
                // expect Read
317 145 rkastl
                assert(token.id == cSdCmdReadSingleBlock);
318 159 rkastl
                addr = token.arg;
319
                assert(addr <= ram.size()) else log.error("Read outside of available RAM");
320 113 rkastl
                response = new(cSdCmdReadSingleBlock, state);
321 150 rkastl
                response.DataBlocks = new[1];
322
 
323 159 rkastl
                //$display("Ram before read (%h):  %h", addr, ram[addr]);
324 160 rkastl
                ram.getDataBlock(addr, response.DataBlocks[0]);
325 159 rkastl
 
326 150 rkastl
                this.bfm.send(response);
327 123 rkastl
        endtask
328 113 rkastl
 
329 148 rkastl
        task write(SdBusTransToken token);
330 123 rkastl
                SDCommandR1 response;
331 150 rkastl
                SdDataBlock rdblock;
332 125 rkastl
                logic[31:0] addr;
333 53 rkastl
 
334 123 rkastl
                // expect Write
335 145 rkastl
                assert(token.id == cSdCmdWriteSingleBlock);
336 150 rkastl
                addr = token.arg;
337 159 rkastl
                assert(addr <= ram.size()) else log.error("Write outside of available RAM");
338 123 rkastl
                response = new(cSdCmdWriteSingleBlock, state);
339 145 rkastl
                this.bfm.send(response);
340 123 rkastl
 
341 125 rkastl
                // recv data
342 150 rkastl
                this.bfm.receiveDataBlock(rdblock);
343 160 rkastl
                ram.setDataBlock(addr, rdblock);
344
 
345 150 rkastl
                this.bfm.waitUntilReady();
346
                this.bfm.sendBusy();
347
 
348 53 rkastl
        endtask
349 102 rkastl
 
350
        task recvCMD55(RCA_t rca);
351
                SDCommandR1 response;
352 145 rkastl
                SdBusTransToken token;
353 125 rkastl
 
354 102 rkastl
                // expect CMD55
355 145 rkastl
                this.bfm.receive(token);
356
                assert(token.id == cSdCmdNextIsACMD);
357
                assert(token.arg[31:16] == rca);
358 102 rkastl
                state.recvCMD55();
359
 
360
                // respond with R1
361
                response = new(cSdCmdNextIsACMD, state);
362 145 rkastl
                this.bfm.send(response);
363 102 rkastl
        endtask
364 50 rkastl
 
365 44 rkastl
endclass
366
 
367 151 rkastl
class NoSdCardModel extends SdCardModel;
368 106 rkastl
 
369 153 rkastl
        function new();
370
                super.new();
371 106 rkastl
        endfunction
372
 
373
        task automatic init();
374
        endtask
375
 
376
endclass
377 135 rkastl
 
378
`endif

powered by: WebSVN 2.1.0

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