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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [sim/] [verilator/] [soc/] [hdd/] [main.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
#include <cstdio>
2
#include <cstdlib>
3
 
4
#include "Vhdd.h"
5
#include "verilated.h"
6
#include "verilated_vcd_c.h"
7
 
8
//------------------------------------------------------------------------------
9
 
10
typedef unsigned int uint32;
11
typedef unsigned char uint8;
12
 
13
//------------------------------------------------------------------------------
14
 
15
enum state_t {
16
    S_IDLE,
17
 
18
    S_IO_READ_1,
19
    S_IO_READ_2,
20
    S_IO_READ_3,
21
 
22
    S_IO_WRITE_1,
23
    S_IO_WRITE_2,
24
    S_IO_WRITE_3,
25
 
26
    S_DELAY
27
};
28
 
29
uint32  address;
30
uint32  byteena;
31
uint32  value;
32
state_t state = S_IDLE;
33
 
34
uint32  delay;
35
 
36
void check_byteena(uint32 byteena) {
37
    if(byteena == 0 || byteena == 5 || byteena == 9 || byteena == 10 || byteena == 11 || byteena == 13) {
38
        printf("ERROR: invalid byteena: %x\n", byteena);
39
        exit(-1);
40
    }
41
 
42
    if(address == 0x03F4 && byteena != 0x4) {
43
        printf("ERROR: read not from 0x3F6.\n");
44
        exit(-1);
45
    }
46
}
47
 
48
bool is_address_ok(uint32 address) {
49
    if(address >= 0x01F0 && address <= 0x01F7) return true;
50
    if(address >= 0x03F4 && address <= 0x03F7) return true;
51
 
52
    return false;
53
}
54
 
55
bool next_record() {
56
    static FILE *fp = NULL;
57
 
58
    if(fp == NULL) {
59
        fp = fopen("./../../../../backup/run-5-win311-32file/track.txt", "rb");
60
        if(fp == NULL) {
61
            printf("ERROR: can not open file.\n");
62
            exit(-1);
63
        }
64
    }
65
 
66
    do {
67
        char line[256];
68
        memset(line, 0, sizeof(line));
69
 
70
        char *res = fgets(line, sizeof(line), fp);
71
        if(res == NULL) {
72
            fclose(fp);
73
            fp = NULL;
74
            return false;
75
        }
76
 
77
//printf("line: %s\n", line);
78
 
79
        int count;
80
 
81
        count = sscanf(line, "io rd %x %x %x", &address, &byteena, &value);
82
        if(count == 3 && is_address_ok(address)) {
83
            check_byteena(byteena);
84
            state = S_IO_READ_1;
85
printf("line: %s", line);
86
            return true;
87
        }
88
        count = sscanf(line, "io wr %x %x %x", &address, &byteena, &value);
89
        if(count == 3 && is_address_ok(address)) {
90
            check_byteena(byteena);
91
            state = S_IO_WRITE_1;
92
printf("line: %s", line);
93
            return true;
94
        }
95
 
96
    } while(true);
97
 
98
    return false;
99
}
100
 
101
//------------------------------------------------------------------------------
102
 
103
uint32 hd_cylinders = 1024;
104
uint32 hd_heads = 16;
105
uint32 hd_spt = 63;
106
uint32 hd_total_sectors = hd_cylinders * hd_heads * hd_spt;
107
 
108
unsigned int identify[256] = {
109
    0x0040,                                         //word 0
110
    (hd_cylinders > 16383)? 16383 : hd_cylinders,   //word 1
111
    0x0000,                                         //word 2 reserved
112
    hd_heads,                                       //word 3
113
    (unsigned short)(512 * hd_spt),                 //word 4
114
    512,                                            //word 5
115
    hd_spt,                                         //word 6
116
    0x0000,                                         //word 7 vendor specific
117
    0x0000,                                         //word 8 vendor specific
118
    0x0000,                                         //word 9 vendor specific
119
    ('B' << 8) | 'X',                               //word 10
120
    ('H' << 8) | 'D',                               //word 11
121
    ('0' << 8) | '0',                               //word 12
122
    ('0' << 8) | '1',                               //word 13
123
    ('1' << 8) | ' ',                               //word 14
124
    (' ' << 8) | ' ',                               //word 15
125
    (' ' << 8) | ' ',                               //word 16
126
    (' ' << 8) | ' ',                               //word 17
127
    (' ' << 8) | ' ',                               //word 18
128
    (' ' << 8) | ' ',                               //word 19
129
    3,                                              //word 20 buffer type
130
    512,                                            //word 21 cache size
131
    4,                                              //word 22 number of ecc bytes
132
    0,0,0,0,                                        //words 23..26 firmware revision
133
    ('H' << 8) | 'D',                               //words 27..46 model number
134
    ('m' << 8) | 'o',
135
    ('d' << 8) | 'e',
136
    ('l' << 8) | ' ',
137
    (' ' << 8) | ' ',
138
    (' ' << 8) | ' ',
139
    (' ' << 8) | ' ',
140
    (' ' << 8) | ' ',
141
    (' ' << 8) | ' ',
142
    (' ' << 8) | ' ',
143
    (' ' << 8) | ' ',
144
    (' ' << 8) | ' ',
145
    (' ' << 8) | ' ',
146
    (' ' << 8) | ' ',
147
    (' ' << 8) | ' ',
148
    (' ' << 8) | ' ',
149
    (' ' << 8) | ' ',
150
    (' ' << 8) | ' ',
151
    (' ' << 8) | ' ',
152
    (' ' << 8) | ' ',
153
    16,                                             //word 47 max multiple sectors
154
    1,                                              //word 48 dword io
155
    1<<9,                                           //word 49 lba supported
156
    0x0000,                                         //word 50 reserved
157
    0x0200,                                         //word 51 pio timing
158
    0x0200,                                         //word 52 pio timing
159
    0x0007,                                         //word 53 valid fields
160
    (hd_cylinders > 16383)? 16383 : hd_cylinders,   //word 54
161
    hd_heads,                                       //word 55
162
    hd_spt,                                         //word 56
163
    hd_total_sectors & 0xFFFF,                      //word 57
164
    hd_total_sectors >> 16,                         //word 58
165
    0x0000,                                         //word 59 multiple sectors
166
    hd_total_sectors & 0xFFFF,                      //word 60
167
    hd_total_sectors >> 16,                         //word 61
168
    0x0000,                                         //word 62 single word dma modes
169
    0x0000,                                         //word 63 multiple word dma modes
170
    0x0000,                                         //word 64 pio modes
171
    120,120,120,120,                                //word 65..68
172
    0,0,0,0,0,0,0,0,0,0,0,                          //word 69..79
173
    0x007E,                                         //word 80 ata modes
174
    0x0000,                                         //word 81 minor version number
175
    1<<14,                                          //word 82 supported commands
176
    (1<<14) | (1<<13) | (1<<12) | (1<<10),          //word 83
177
    1<<14,                                          //word 84
178
    1<<14,                                          //word 85
179
    (1<<14) | (1<<13) | (1<<12) | (1<<10),          //word 86
180
    1<<14,                                          //word 87
181
    0x0000,                                         //word 88
182
    0,0,0,0,                                        //word 89..92
183
    1 | (1<<14) | 0x2000,                           //word 93
184
    0,0,0,0,0,0,                                    //word 94..99
185
    hd_total_sectors & 0xFFFF,                      //word 100
186
    hd_total_sectors >> 16,                         //word 101
187
    0,                                              //word 102
188
    0,                                              //word 103
189
 
190
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,//word 104..127
191
 
192
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                //word 128..255
193
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
194
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
195
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
196
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
197
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
198
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
199
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
200
};
201
 
202
//------------------------------------------------------------------------------
203
 
204
uint32 sd_address;
205
uint32 sd_sector_count;
206
uint32 sd_command;
207
 
208
bool sd_mutex = false;
209
 
210
int main(int argc, char **argv) {
211
    Verilated::commandArgs(argc, argv);
212
 
213
    Verilated::traceEverOn(true);
214
    VerilatedVcdC* tracer = new VerilatedVcdC;
215
 
216
    Vhdd *top = new Vhdd();
217
    top->trace (tracer, 99);
218
    //tracer->rolloverMB(1000000);
219
    tracer->open("hdd.vcd");
220
 
221
    bool dump = false;
222
 
223
    //reset
224
    top->clk = 0; top->rst_n = 1; top->eval();
225
    top->clk = 1; top->rst_n = 1; top->eval();
226
    top->clk = 1; top->rst_n = 0; top->eval();
227
    top->clk = 0; top->rst_n = 0; top->eval();
228
    top->clk = 0; top->rst_n = 1; top->eval();
229
 
230
    uint32 cycle = 0;
231
 
232
 
233
//#error initialize mgmt for hd_cylinders ...
234
 
235
    for(uint32 i=0; i<128; i++) {
236
 
237
        top->mgmt_write = 1;
238
        top->mgmt_writedata = ((unsigned int)identify[2*i+1] << 16) | (unsigned int)identify[2*i+0];
239
 
240
        top->clk = 0;
241
        top->eval();
242
        if(dump) tracer->dump(cycle++);
243
 
244
        top->clk = 1;
245
        top->eval();
246
        if(dump) tracer->dump(cycle++);
247
 
248
        tracer->flush();
249
    }
250
    top->mgmt_write = 0;
251
 
252
    uint32 loop_run = 0;
253
    while(!Verilated::gotFinish()) {
254
        loop_run++;
255
        //if(loop_run > 111920000) dump = true;
256
 
257
        //----------------------------------------------------------------------
258
 
259
        if(state == S_IDLE) {
260
            bool res = next_record();
261
            if(res == false) {
262
                printf("End of file.\n");
263
                break;
264
            }
265
        }
266
 
267
        if(top->irq) {
268
            printf("ERROR: irq set.\n");
269
            exit(-1);
270
        }
271
 
272
        //----------------------------------------------------------------------
273
 
274
        top->sd_master_waitrequest = 0;
275
        top->sd_master_readdatavalid = 0;
276
 
277
        if(top->sd_master_read) {
278
            sd_mutex = true;
279
            top->sd_master_readdata = 2;
280
        }
281
        else if(sd_mutex) {
282
            top->sd_master_readdatavalid = 1;
283
            sd_mutex = false;
284
        }
285
 
286
        if(top->sd_master_write) {
287
            printf("sd_master %08x %08x\n", top->sd_master_address, top->sd_master_writedata);
288
 
289
            if(top->sd_master_address == 0x00000004) sd_address      = top->sd_master_writedata;
290
            if(top->sd_master_address == 0x00000008) sd_sector_count = top->sd_master_writedata;
291
            if(top->sd_master_address == 0x0000000C) sd_command      = top->sd_master_writedata;
292
        }
293
        else if(sd_command != 0) {
294
 
295
            if(sd_command == 2) { //read
296
 
297
                FILE *fp = fopen("/home/alek/temp/bochs-run/hd_copy_for_sim.img", "rb");
298
 
299
                for(uint32 i=0; i<sd_sector_count*128; i++) {
300
 
301
                    fseek(fp, (sd_address*512)+(i*4), SEEK_SET);
302
 
303
                    uint32 val;
304
                    fread(&val, 4, 1, fp);
305
 
306
                    //printf("pos: %d %08x\n", (sd_address*512)+(i*4), val);
307
 
308
                    top->sd_slave_write = 1;
309
                    top->sd_slave_writedata = val;
310
 
311
                    top->clk = 0;
312
                    top->eval();
313
                    if(dump) tracer->dump(cycle++);
314
 
315
                    top->clk = 1;
316
                    top->eval();
317
                    if(dump) tracer->dump(cycle++);
318
 
319
                    tracer->flush();
320
                }
321
 
322
                top->sd_slave_write = 0;
323
                sd_command = 0;
324
 
325
                for(uint32 i=0; i<30; i++) {
326
                    top->clk = 0;
327
                    top->eval();
328
                    if(dump) tracer->dump(cycle++);
329
 
330
                    top->clk = 1;
331
                    top->eval();
332
                    if(dump) tracer->dump(cycle++);
333
 
334
                    tracer->flush();
335
                }
336
 
337
                fclose(fp);
338
            }
339
            else if(sd_command == 3) { //write
340
 
341
                FILE *fp = fopen("/home/alek/temp/bochs-run/hd_copy_for_sim.img", "r+b");
342
 
343
                bool wait = false;
344
                for(uint32 i=0; i<sd_sector_count*128*2; i++) {
345
 
346
                    top->sd_slave_read = (wait == false)? 1 : 0;
347
 
348
                    top->clk = 0;
349
                    top->eval();
350
                    if(dump) tracer->dump(cycle++);
351
 
352
                    top->clk = 1;
353
                    top->eval();
354
                    if(dump) tracer->dump(cycle++);
355
 
356
                    tracer->flush();
357
 
358
                    if(wait) {
359
                        wait = (wait == false)? true : false;
360
                        continue;
361
                    }
362
 
363
                    //--- write
364
 
365
                    fseek(fp, (sd_address*512)+(i*4/2), SEEK_SET);
366
 
367
                    uint32 val = top->sd_slave_readdata;
368
                    fwrite(&val, 4, 1, fp);
369
 
370
                    wait = (wait == false)? true : false;
371
                }
372
 
373
                top->sd_slave_read = 0;
374
                sd_command = 0;
375
 
376
                for(uint32 i=0; i<30; i++) {
377
                    top->clk = 0;
378
                    top->eval();
379
                    if(dump) tracer->dump(cycle++);
380
 
381
                    top->clk = 1;
382
                    top->eval();
383
                    if(dump) tracer->dump(cycle++);
384
 
385
                    tracer->flush();
386
                }
387
 
388
                fclose(fp);
389
 
390
                //getchar();
391
            }
392
 
393
        }
394
 
395
 
396
        //----------------------------------------------------------------------
397
 
398
        if(state == S_DELAY) {
399
            delay--;
400
 
401
            if(delay == 0) {
402
                state = S_IDLE;
403
            }
404
        }
405
        else if(state == S_IO_READ_1) {
406
            if(address >= 0x01F0 && address <= 0x01F7) {
407
                top->io_address = (address >> 2) & 0x1;
408
                top->io_byteenable = byteena & 0xF;
409
                top->io_read = 1;
410
            }
411
            else if(address >= 0x03F4 && address <= 0x03F6) {
412
                top->ide_3f6_read = 1;
413
            }
414
            else {
415
                printf("ERROR: invalid io rd address: %08x\n", address);
416
                exit(-1);
417
            }
418
            state = S_IO_READ_2;
419
        }
420
        else if(state == S_IO_READ_2) {
421
            uint32 top_readdata = 0;
422
 
423
            if(address >= 0x01F0 && address <= 0x01F7)      top_readdata = top->io_readdata & 0xFFFFFFFF;
424
            else if(address >= 0x03F4 && address <= 0x03F7) top_readdata = (top->ide_3f6_readdata & 0xFF) << 16;
425
 
426
            top->io_read = 0;
427
            top->ide_3f6_read = 0;
428
 
429
            //clear index pulse
430
            if(address == 0x01F4 && byteena == 0x8) {
431
                top_readdata &= ~0x02000000;
432
                value &= ~0x02000000;
433
            }
434
 
435
            if(byteena == 3) top_readdata &= 0x0000FFFF;
436
 
437
            if(top_readdata != value) {
438
                printf("mismatch io rd %08x %x %08x != %08x, loop: %d\n", address, byteena, value, top_readdata, loop_run);
439
 
440
                static int ign_cnt = 0;
441
                ign_cnt++;
442
 
443
//if(! ((address == 0x01F4 && byteena == 0x8)))
444
//if(ign_cnt >= 5)
445
exit(0);
446
            }
447
 
448
            delay = 200;
449
            state = S_DELAY;
450
        }
451
        else if(state == S_IO_WRITE_1) {
452
            if(address >= 0x01F0 && address <= 0x01F7) {
453
                top->io_address = (address >> 2) & 0x1;
454
                top->io_write = 1;
455
                top->io_writedata = value;
456
                top->io_byteenable = byteena & 0xF;
457
            }
458
            else if(address >= 0x03F4 && address <= 0x03F7) {
459
                top->ide_3f6_write = 1;
460
                top->ide_3f6_writedata = (value >> 8*2) & 0xFF;
461
            }
462
            else {
463
                printf("ERROR: invalid io wr address: %08x\n", address);
464
                exit(-1);
465
            }
466
            state = S_IO_WRITE_2;
467
        }
468
        else if(state == S_IO_WRITE_2) {
469
 
470
            top->io_write = 0;
471
            top->ide_3f6_write = 0;
472
 
473
            delay = 200;
474
            state = S_DELAY;
475
        }
476
 
477
        //----------------------------------------------------------------------
478
 
479
        top->clk = 0;
480
        top->eval();
481
        if(dump) tracer->dump(cycle++);
482
 
483
        top->clk = 1;
484
        top->eval();
485
        if(dump) tracer->dump(cycle++);
486
 
487
        tracer->flush();
488
    }
489
    tracer->close();
490
    delete tracer;
491
    delete top;
492
 
493
    return 0;
494
}
495
 
496
//------------------------------------------------------------------------------
497
 
498
/*
499
    input               clk,
500
    input               rst_n,
501
 
502
    //irq
503
    output reg          irq,
504
 
505
    //avalon slave
506
    input               io_address,
507
    input       [3:0]   io_byteenable,
508
    input               io_read,
509
    output reg  [31:0]  io_readdata,
510
    input               io_write,
511
    input       [31:0]  io_writedata,
512
 
513
    //ide shared port 0x3F6
514
    input               ide_3f6_read,
515
    output reg  [7:0]   ide_3f6_readdata,
516
    input               ide_3f6_write,
517
    input       [7:0]   ide_3f6_writedata,
518
 
519
    //master to control sd
520
    output      [31:0]  sd_master_address,
521
    input               sd_master_waitrequest,
522
    output              sd_master_read,
523
    input               sd_master_readdatavalid,
524
    input       [31:0]  sd_master_readdata,
525
    output              sd_master_write,
526
    output      [31:0]  sd_master_writedata,
527
 
528
    //slave with data from/to sd
529
    input       [8:0]   sd_slave_address,
530
    input               sd_slave_read,
531
    output reg  [31:0]  sd_slave_readdata,
532
    input               sd_slave_write,
533
    input       [31:0]  sd_slave_writedata,
534
 
535
    //management slave
536
    //0x00.[31:0]:    identify write
537
    //0x01.[16:0]:    media cylinders
538
    //0x02.[4:0]:     media heads
539
    //0x03.[8:0]:     media spt
540
    //0x04.[13:0]:    media sectors per cylinder = spt * heads
541
    //0x05.[31:0]:    media sectors total
542
    //0x06.[31:0]:    media sd base
543
 
544
    input       [2:0]   mgmt_address,
545
    input               mgmt_write,
546
    input       [31:0]  mgmt_writedata
547
*/

powered by: WebSVN 2.1.0

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