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

Subversion Repositories t51

[/] [t51/] [trunk/] [sw/] [hex2rom.cpp] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 jesus
//
2
// Binary and intel/motorola hex to VHDL ROM entity converter
3
//
4
// Version : 0215
5
//
6
// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
7
//
8
// All rights reserved
9
//
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// Redistributions of source code must retain the above copyright notice,
14
// this list of conditions and the following disclaimer.
15
//
16
// Redistributions in binary form must reproduce the above copyright
17
// notice, this list of conditions and the following disclaimer in the
18
// documentation and/or other materials provided with the distribution.
19
//
20
// Neither the name of the author nor the names of other contributors may
21
// be used to endorse or promote products derived from this software without
22
// specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
28
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
// POSSIBILITY OF SUCH DAMAGE.
35
//
36
// Please report bugs to the author, but before you do so, please
37
// make sure that this is not a derivative work and that
38
// you have the latest version of this file.
39
//
40
// The latest version of this file can be found at:
41
//      http://www.opencores.org/cvsweb.shtml/t51/
42
//
43
// Limitations :
44
//      No support for wrapped intel segments
45
//      Requires stl to compile
46
//
47
// File history :
48
//
49
// 0146 : Initial release
50
//
51
// 0150 : Added binary read
52
//
53
// 0208 : Changed some errors to warnings
54
//
55
// 0215 : Added support for synchronous ROM
56
//
57
 
58
#include <stdio.h>
59
#include <string>
60
#include <vector>
61
#include <iostream>
62
 
63
using namespace std;
64
 
65
#if !(defined(max)) && _MSC_VER
66
        // VC fix
67
        #define max __max
68
#endif
69
 
70
class MemBlock
71
{
72
public:
73
        unsigned long m_startAddress;
74
        vector<unsigned char> m_bytes;
75
};
76
 
77
class File
78
{
79
public:
80
        explicit File(const char *fileName, const char *mode)
81
        {
82
                m_file = fopen(fileName, mode);
83
                if (m_file != NULL)
84
                {
85
                        return;
86
                }
87
                string errorStr = "Error opening ";
88
                errorStr += fileName;
89
                errorStr += "\n";
90
                throw errorStr;
91
        }
92
 
93
        ~File()
94
        {
95
                fclose(m_file);
96
        }
97
 
98
        // Read binary file
99
        void ReadBin(unsigned long limit)
100
        {
101
                m_top = 0;
102
 
103
                m_chunks.push_back(MemBlock());
104
                m_chunks.back().m_startAddress = 0;
105
 
106
                cerr << "Reading binary file\n";
107
 
108
                int tmp = fgetc(m_file);
109
 
110
                while (!feof(m_file))
111
                {
112
                        m_chunks.back().m_bytes.push_back(tmp);
113
 
114
                        if (m_chunks.back().m_bytes.size() > limit + 1)
115
                        {
116
                                m_chunks.back().m_bytes.pop_back();
117
                                m_top = m_chunks.back().m_bytes.size() - 1;
118
                                cerr << "Ignoring data above address space!\n";
119
                                cerr << " Limit: " << limit << "\n";
120
                                return;
121
                        }
122
 
123
                        tmp = fgetc(m_file);
124
                }
125
 
126
                m_top = m_chunks.back().m_bytes.size() - 1;
127
 
128
                if (!m_chunks.back().m_bytes.size())
129
                {
130
                        cerr << "No data!\n";
131
 
132
                        m_chunks.pop_back();
133
                }
134
        }
135
 
136
        // Read hex file
137
        void ReadHex(unsigned long limit)
138
        {
139
                char szLine[1024];
140
                bool formatDetected = false;
141
                bool intel;
142
                bool endSeen = false;
143
                bool linear = true;                             // Only used for intel hex
144
                unsigned long addressBase = 0;   // Only used for intel hex
145
                unsigned long dataRecords = 0;   // Only used for s-record
146
                while (!feof(m_file))
147
                {
148
                        if (fgets(szLine, 1024, m_file) == 0)
149
                        {
150
                                if (ferror(m_file))
151
                                {
152
                                        throw "Error reading input!\n";
153
                                }
154
                                continue;
155
                        }
156
 
157
                        if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
158
                        {
159
                                szLine[strlen(szLine) - 1] = 0;
160
                        }
161
 
162
                        if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
163
                        {
164
                                szLine[strlen(szLine) - 1] = 0;
165
                        }
166
 
167
                        if (strlen(szLine) == 1023)
168
                        {
169
                                throw "Hex file lines to long!\n";
170
                        }
171
                        // Ignore blank lines
172
                        if (szLine[0] == '\n')
173
                        {
174
                                continue;
175
                        }
176
                        // Detect format and warn if garbage lines are found
177
                        if (!formatDetected)
178
                        {
179
                                if (szLine[0] != ':' && szLine[0] != 'S')
180
                                {
181
                                        cerr << "Ignoring garbage line!\n";
182
                                        continue;
183
                                }
184
                                if (szLine[0] == 'S')
185
                                {
186
                                        intel = false;
187
                                        cerr << "Detected S-Record\n";
188
                                }
189
                                else
190
                                {
191
                                        intel = true;
192
                                        cerr << "Detected intel hex file\n";
193
                                }
194
                                formatDetected = true;
195
                        }
196
                        else if ((intel && szLine[0] != ':') ||
197
                                        (!intel && szLine[0] != 'S'))
198
                        {
199
                                cerr << "Ignoring garbage line!\n";
200
                                continue;
201
                        }
202
 
203
                        if (endSeen)
204
                        {
205
                                throw "Hex line after end of file record!\n";
206
                        }
207
 
208
                        if (intel)
209
                        {
210
                                unsigned long   dataBytes;
211
                                unsigned long   startAddress;
212
                                unsigned long   type;
213
                                if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3)
214
                                {
215
                                        throw "Hex line beginning corrupt!\n";
216
                                }
217
                                // Check line length
218
                                if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0)
219
                                {
220
                                        throw "Hex line length incorrect!\n";
221
                                }
222
                                // Check line checksum
223
                                unsigned char   checkSum = 0;
224
                                unsigned long   tmp;
225
                                for (unsigned int i = 0; i <= dataBytes + 4; ++i)
226
                                {
227
                                        if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1)
228
                                        {
229
                                                throw "Hex line data corrupt!\n";
230
                                        }
231
                                        checkSum += tmp;
232
                                }
233
                                if (checkSum != 0)
234
                                {
235
                                        throw "Hex line checksum error!\n";
236
                                }
237
 
238
                                switch (type)
239
                                {
240
                                case 0:
241
                                        // Data record
242
                                        if (!linear)
243
                                        {
244
                                                // Segmented
245
                                                unsigned long test = startAddress;
246
                                                test += dataBytes;
247
                                                if (test > 0xffff)
248
                                                {
249
                                                        throw "Can't handle wrapped segments!\n";
250
                                                }
251
                                        }
252
                                        if (!m_chunks.size() ||
253
                                                m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
254
                                                addressBase + startAddress)
255
                                        {
256
                                                m_chunks.push_back(MemBlock());
257
                                                m_chunks.back().m_startAddress = addressBase + startAddress;
258
                                        }
259
                                        {
260
                                                unsigned char i = 0;
261
                                                for (i = 0; i < dataBytes; ++i)
262
                                                {
263
                                                        sscanf(&szLine[9 + i * 2], "%2lx", &tmp);
264
                                                        if (addressBase + startAddress + i > limit)
265
                                                        {
266
                                                                cerr << "Ignoring data above address space!\n";
267
                                                                cerr << "Data address: " << addressBase + startAddress + i;
268
                                                                cerr << " Limit: " << limit << "\n";
269
                                                                if (!m_chunks.back().m_bytes.size())
270
                                                                {
271
                                                                        m_chunks.pop_back();
272
                                                                }
273
                                                                continue;
274
                                                        }
275
                                                        m_chunks.back().m_bytes.push_back(tmp);
276
                                                }
277
                                        }
278
                                        break;
279
 
280
                                case 1:
281
                                        // End-of-file record
282
                                        if (dataBytes != 0)
283
                                        {
284
                                                cerr << "Warning: End of file record not zero length!\n";
285
                                        }
286
                                        if (startAddress != 0)
287
                                        {
288
                                                cerr << "Warning: End of file record address not zero!\n";
289
                                        }
290
                                        endSeen = true;
291
                                        break;
292
 
293
                                case 2:
294
                                        // Extended segment address record
295
                                        if (dataBytes != 2)
296
                                        {
297
                                                throw "Length field must be 2 in extended segment address record!\n";
298
                                        }
299
                                        if (startAddress != 0)
300
                                        {
301
                                                throw "Address field must be zero in extended segment address record!\n";
302
                                        }
303
                                        sscanf(&szLine[9], "%4lx", &startAddress);
304
                                        addressBase = startAddress << 4;
305
                                        linear = false;
306
                                        break;
307
 
308
                                case 3:
309
                                        // Start segment address record
310
                                        if (dataBytes != 4)
311
                                        {
312
                                                cerr << "Warning: Length field must be 4 in start segment address record!\n";
313
                                        }
314
                                        if (startAddress != 0)
315
                                        {
316
                                                cerr << "Warning: Address field must be zero in start segment address record!\n";
317
                                        }
318
                                        if (dataBytes == 4)
319
                                        {
320
                                                unsigned long ssa;
321
                                                char    ssaStr[16];
322
                                                sscanf(&szLine[9], "%8lx", &ssa);
323
                                                sprintf(ssaStr, "%08X\n", ssa);
324
                                                cerr << "Segment start address (CS/IP): ";
325
                                                cerr << ssaStr;
326
                                        }
327
                                        break;
328
 
329
                                case 4:
330
                                        // Extended linear address record
331
                                        if (dataBytes != 2)
332
                                        {
333
                                                throw "Length field must be 2 in extended linear address record!\n";
334
                                        }
335
                                        if (startAddress != 0)
336
                                        {
337
                                                throw "Address field must be zero in extended linear address record!\n";
338
                                        }
339
                                        sscanf(&szLine[9], "%4lx", &startAddress);
340
                                        addressBase = ((unsigned long)startAddress) << 16;
341
                                        linear = true;
342
                                        break;
343
 
344
                                case 5:
345
                                        // Start linear address record
346
                                        if (dataBytes != 4)
347
                                        {
348
                                                cerr << "Warning: Length field must be 4 in start linear address record!\n";
349
                                        }
350
                                        if (startAddress != 0)
351
                                        {
352
                                                cerr << "Warning: Address field must be zero in start linear address record!\n";
353
                                        }
354
                                        if (dataBytes == 4)
355
                                        {
356
                                                unsigned long lsa;
357
                                                char    lsaStr[16];
358
                                                sscanf(&szLine[9], "%8lx", &lsa);
359
                                                sprintf(lsaStr, "%08X\n", lsa);
360
                                                cerr << "Linear start address: ";
361
                                                cerr << lsaStr;
362
                                        }
363
                                        break;
364
 
365
                                default:
366
                                        cerr << "Waring: Unknown record found!\n";
367
                                }
368
                        }
369
                        else
370
                        {
371
                                // S-record
372
                                unsigned long   count;
373
                                char                    type;
374
                                if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2)
375
                                {
376
                                        throw "Hex line beginning corrupt!\n";
377
                                }
378
                                // Check line length
379
                                if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0)
380
                                {
381
                                        throw "Hex line length incorrect!\n";
382
                                }
383
                                // Check line checksum
384
                                unsigned char   checkSum = 0;
385
                                unsigned long   tmp;
386
                                for (unsigned int i = 0; i < count + 1; ++i)
387
                                {
388
                                        if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1)
389
                                        {
390
                                                throw "Hex line data corrupt!\n";
391
                                        }
392
                                        checkSum += tmp;
393
                                }
394
                                if (checkSum != 255)
395
                                {
396
                                        throw "Hex line checksum error!\n";
397
                                }
398
 
399
                                switch (type)
400
                                {
401
                                case '0':
402
                                        // Header record
403
                                        {
404
                                                char header[256];
405
                                                unsigned char i = 0;
406
                                                for (i = 0; i + 3 < count; ++i)
407
                                                {
408
                                                        sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
409
                                                        header[i] = tmp;
410
                                                }
411
                                                header[i] = 0;
412
                                                if (i > 0)
413
                                                {
414
                                                        cerr << "Module name: " << header << "\n";
415
                                                }
416
                                        }
417
                                        break;
418
 
419
                                case '1':
420
                                case '2':
421
                                case '3':
422
                                        // Data record
423
                                        {
424
                                                dataRecords++;
425
                                                unsigned long   startAddress;
426
                                                if (type == '1')
427
                                                {
428
                                                        sscanf(&szLine[4], "%4lx", &startAddress);
429
                                                }
430
                                                else if (type == '2')
431
                                                {
432
                                                        sscanf(&szLine[4], "%6lx", &startAddress);
433
                                                }
434
                                                else
435
                                                {
436
                                                        sscanf(&szLine[4], "%8lx", &startAddress);
437
                                                }
438
 
439
                                                if (!m_chunks.size() ||
440
                                                        m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
441
                                                        startAddress)
442
                                                {
443
                                                        m_chunks.push_back(MemBlock());
444
                                                        m_chunks.back().m_startAddress = startAddress;
445
                                                }
446
                                                unsigned char i = 0;
447
                                                for (i = (type - '1'); i + 3 < count; ++i)
448
                                                {
449
                                                        sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
450
                                                        if (startAddress + i > limit)
451
                                                        {
452
                                                                cerr << "Ignoring data above address space!\n";
453
                                                                cerr << "Data address: " << startAddress + i;
454
                                                                cerr << " Limit: " << limit << "\n";
455
                                                                if (!m_chunks.back().m_bytes.size())
456
                                                                {
457
                                                                        m_chunks.pop_back();
458
                                                                }
459
                                                                continue;
460
                                                        }
461
                                                        m_chunks.back().m_bytes.push_back(tmp);
462
                                                }
463
                                        }
464
                                        break;
465
 
466
                                case '5':
467
                                        // Count record
468
                                        {
469
                                                unsigned long   address;
470
                                                sscanf(&szLine[4], "%4lx", &address);
471
                                                if (address != dataRecords)
472
                                                {
473
                                                        throw "Wrong number of data records!\n";
474
                                                }
475
                                        }
476
                                        break;
477
 
478
                                case '7':
479
                                case '8':
480
                                case '9':
481
                                        // Start address record
482
                                        cerr << "Ignoring start address record!\n";
483
                                        break;
484
 
485
                                default:
486
                                        cerr << "Unknown record found!\n";
487
                                }
488
                        }
489
                }
490
                if (intel && !endSeen)
491
                {
492
                        cerr << "No end of file record!\n";
493
                }
494
                if (!m_chunks.size())
495
                {
496
                        throw "No data in file!\n";
497
                }
498
                vector<MemBlock>::iterator      vi;
499
                m_top = 0;
500
                for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
501
                {
502
                        m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1);
503
                }
504
        }
505
 
506
        // Rather inefficient this one, fix sometime
507
        bool GetByte(const unsigned long address, unsigned char &chr)
508
        {
509
                vector<MemBlock>::iterator      vi;
510
 
511
                for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
512
                {
513
                        if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address)
514
                        {
515
                                break;
516
                        }
517
                }
518
                if (vi == m_chunks.end())
519
                {
520
                        return false;
521
                }
522
                chr = vi->m_bytes[address - vi->m_startAddress];
523
                return true;
524
        }
525
 
526
        bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str)
527
        {
528
                bool                    ok = false;
529
                long                    i;
530
                unsigned char   chr;
531
                unsigned long   data = 0;
532
                unsigned long   tmp;
533
 
534
                if (lEndian)
535
                {
536
                        for (i = 0; i < (bits + 7) / 8; ++i)
537
                        {
538
                                ok |= GetByte(address + i, chr);
539
                                tmp = chr;
540
                                data |= tmp << (8 * i);
541
                        }
542
                }
543
                else
544
                {
545
                        for (i = 0; i < (bits + 7) / 8; ++i)
546
                        {
547
                                ok |= GetByte(address + i, chr);
548
                                tmp = chr;
549
                                data |= tmp << (8 * ((bits + 7) / 8 - i - 1));
550
                        }
551
                }
552
 
553
                if (!ok)
554
                {
555
                        return false;
556
                }
557
 
558
                unsigned long mask = 1;
559
 
560
                str = "";
561
                for (i = 0; i < bits; i++)
562
                {
563
                        if (data & mask)
564
                        {
565
                                str.insert(0,"1");
566
                        }
567
                        else
568
                        {
569
                                str.insert(0,"0");
570
                        }
571
                        mask <<= 1;
572
                }
573
                return true;
574
        }
575
 
576
        FILE *Handle() { return m_file; };
577
        vector<MemBlock>        m_chunks;
578
        unsigned long           m_top;
579
private:
580
        FILE                            *m_file;
581
};
582
 
583
 
584
int main (int argc, char *argv[])
585
{
586
        cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0215\n";
587
 
588
        try
589
        {
590
                unsigned long aWidth;
591
                unsigned long dWidth;
592
                char endian;
593
                char O = 0;
594
 
595
                if (!(argc == 4 || argc == 5))
596
                {
597
                        cerr << "\nUsage: hex2rom [-b] <input file> <entity name> <format>\n";
598
                        cerr << "\nIf the -b option is specified the file is read as a binary file\n";
599
                        cerr << "Hex input files must be intel hex or motorola s-record\n";
600
                        cerr << "\nThe format string has the format AEDO where:\n";
601
                        cerr << "  A = Address bits\n";
602
                        cerr << "  E = Endianness, l or b\n";
603
                        cerr << "  D = Data bits\n";
604
                        cerr << "  O = ROM type: (one optional character)\n";
605
                        cerr << "      z for tri-state output\n";
606
                        cerr << "      a for array ROM \n";
607
                        cerr << "      s for synchronous ROM \n";
608
                        cerr << "\nExample:\n";
609
                        cerr << "  hex2rom test.hex Test_ROM 18b16z\n\n";
610
                        return -1;
611
                }
612
 
613
                string  inFileName;
614
                string  outFileName;
615
 
616
                unsigned long   bytes;
617
 
618
                if (argc == 4)
619
                {
620
                        int result;
621
                        result = sscanf(argv[3], "%lu%c%lu%c", &aWidth, &endian, &dWidth, &O);
622
                        if (result < 3)
623
                        {
624
                                throw "Error in output format argument!\n";
625
                        }
626
 
627
                        if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's'))
628
                        {
629
                                throw "Error in output format argument!\n";
630
                        }
631
                        inFileName = argv[1];
632
                        outFileName = argv[2];
633
                }
634
                else
635
                {
636
                        if (strcmp(argv[1], "-b"))
637
                        {
638
                                throw "Error in arguments!\n";
639
                        }
640
 
641
                        int result;
642
                        result = sscanf(argv[4], "%lu%c%lu%c", &aWidth, &endian, &dWidth, &O);
643
                        if (result < 3)
644
                        {
645
                                throw "Error in output format argument!\n";
646
                        }
647
 
648
                        if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's'))
649
                        {
650
                                throw "Error in output format argument!\n";
651
                        }
652
                        inFileName = argv[2];
653
                        outFileName = argv[3];
654
                }
655
 
656
                bytes = (dWidth + 7) / 8;
657
 
658
                File    inFile(inFileName.c_str(), "rb");
659
 
660
                if (argc == 4)
661
                {
662
                        inFile.ReadHex((1UL << aWidth) * bytes - 1);
663
                }
664
                else
665
                {
666
                        inFile.ReadBin((1UL << aWidth) * bytes - 1);
667
                }
668
 
669
                string outFileNameWE = outFileName + ".vhd";
670
                File    outFile(outFileNameWE.c_str(), "wt");
671
 
672
                string                          line;
673
 
674
                unsigned long   words = 1;
675
                unsigned long   i = inFile.m_top;
676
                i /= bytes;
677
 
678
                while (i != 0)
679
                {
680
                        i >>= 1;
681
                        words <<= 1;
682
                }
683
 
684
                fprintf(outFile.Handle(), "-- This file was generated with hex2rom written by Daniel Wallner\n");
685
                fprintf(outFile.Handle(), "\nlibrary IEEE;");
686
                fprintf(outFile.Handle(), "\nuse IEEE.std_logic_1164.all;");
687
                fprintf(outFile.Handle(), "\nuse IEEE.numeric_std.all;");
688
                fprintf(outFile.Handle(), "\n\nentity %s is", outFileName.c_str());
689
                fprintf(outFile.Handle(), "\n\tport(");
690
                if (O == 'z')
691
                {
692
                        fprintf(outFile.Handle(), "\n\t\tCE_n\t: in std_logic;", dWidth - 1);
693
                        fprintf(outFile.Handle(), "\n\t\tOE_n\t: in std_logic;", dWidth - 1);
694
                }
695
                if (O == 's')
696
                {
697
                        fprintf(outFile.Handle(), "\n\t\tClk\t: in std_logic;", dWidth - 1);
698
                }
699
                fprintf(outFile.Handle(), "\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1);
700
                fprintf(outFile.Handle(), "\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1);
701
                fprintf(outFile.Handle(), "\n\t);");
702
                fprintf(outFile.Handle(), "\nend %s;", outFileName.c_str());
703
                fprintf(outFile.Handle(), "\n\narchitecture rtl of %s is", outFileName.c_str());
704
                if (!O)
705
                {
706
                        fprintf(outFile.Handle(), "\nbegin");
707
                        fprintf(outFile.Handle(), "\n\tprocess (A)");
708
                        fprintf(outFile.Handle(), "\n\tbegin");
709
                        fprintf(outFile.Handle(), "\n\t\tcase to_integer(unsigned(A)) is");
710
                }
711
                else if (O == 's')
712
                {
713
                        fprintf(outFile.Handle(), "\n\tsignal A_r : std_logic_vector(%d downto 0);", aWidth - 1);
714
                        fprintf(outFile.Handle(), "\nbegin");
715
                        fprintf(outFile.Handle(), "\n\tprocess (Clk)");
716
                        fprintf(outFile.Handle(), "\n\tbegin");
717
                        fprintf(outFile.Handle(), "\n\t\tif Clk'event and Clk = '1' then");
718
                        fprintf(outFile.Handle(), "\n\t\t\tA_r <= A;");
719
                        fprintf(outFile.Handle(), "\n\t\tend if;");
720
                        fprintf(outFile.Handle(), "\n\tend process;");
721
                        fprintf(outFile.Handle(), "\n\tprocess (A_r)");
722
                        fprintf(outFile.Handle(), "\n\tbegin");
723
                        fprintf(outFile.Handle(), "\n\t\tcase to_integer(unsigned(A_r)) is");
724
                }
725
                else
726
                {
727
                        fprintf(outFile.Handle(), "\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1);
728
                        fprintf(outFile.Handle(), "\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1);
729
                        fprintf(outFile.Handle(), "\n\tconstant ROM: ROM_TABLE := ROM_TABLE'(");
730
                }
731
 
732
                string str;
733
                string strDC;
734
                for (i = 0; i < dWidth; i++)
735
                {
736
                        strDC.insert(0, "-");
737
                }
738
                for (i = 0; i < words; i++)
739
                {
740
                        if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str))
741
                        {
742
                                str = strDC;
743
                        }
744
                        if (!O || O == 's')
745
                        {
746
                                if (inFile.m_top / bytes >= i)
747
                                {
748
                                        fprintf(outFile.Handle(),
749
                                                        "\n\t\twhen %06d => D <= \"%s\";",i, str.c_str());
750
                                        fprintf(outFile.Handle(), "\t-- 0x%04X", i * bytes);
751
                                }
752
                        }
753
                        else
754
                        {
755
                                fprintf(outFile.Handle(), "\n\t\tROM_WORD'(\"%s", str.c_str());
756
                                if (i != words - 1)
757
                                {
758
                                        fprintf(outFile.Handle(), "\"),");
759
                                }
760
                                else
761
                                {
762
                                        fprintf(outFile.Handle(), "\"));");
763
                                }
764
                                fprintf(outFile.Handle(), "\t-- 0x%04X", i * bytes);
765
                        }
766
                }
767
 
768
                if (!O || O == 's')
769
                {
770
                        fprintf(outFile.Handle(), "\n\t\twhen others => D <= \"%s\";", strDC.c_str());
771
                        fprintf(outFile.Handle(), "\n\t\tend case;");
772
                        fprintf(outFile.Handle(), "\n\tend process;");
773
                }
774
                else
775
                {
776
                        fprintf(outFile.Handle(), "\nbegin");
777
                        if (O == 'z')
778
                        {
779
                                fprintf(outFile.Handle(), "\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');");
780
                        }
781
                        else
782
                        {
783
                                fprintf(outFile.Handle(), "\n\tD <= ROM(to_integer(unsigned(A)));");
784
                        }
785
                }
786
                fprintf(outFile.Handle(), "\nend;\n");
787
 
788
                return 0;
789
        }
790
        catch (string error)
791
        {
792
                cerr << "Fatal: " << error;
793
        }
794
        catch (const char *error)
795
        {
796
                cerr << "Fatal: " << error;
797
        }
798
        return -1;
799
}

powered by: WebSVN 2.1.0

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