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

Subversion Repositories ax8

[/] [ax8/] [trunk/] [sw/] [hex2rom.cpp] - Blame information for rev 14

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

Line No. Rev Author Line
1 14 jesus
//
2
// Binary and intel/motorola hex to VHDL ROM converter
3
//
4
// Version : 0220
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
// 0220 : Changed array ROM format, added support for Xilinx .UCF generation
58
//
59
 
60
#include <stdio.h>
61
#include <string>
62
#include <vector>
63
#include <iostream>
64
 
65
using namespace std;
66
 
67
#if !(defined(max)) && _MSC_VER
68
        // VC fix
69
        #define max __max
70
#endif
71
 
72
class MemBlock
73
{
74
public:
75
        unsigned long m_startAddress;
76
        vector<unsigned char> m_bytes;
77
};
78
 
79
class File
80
{
81
public:
82
        explicit File(const char *fileName, const char *mode)
83
        {
84
                m_file = fopen(fileName, mode);
85
                if (m_file != NULL)
86
                {
87
                        return;
88
                }
89
                string errorStr = "Error opening ";
90
                errorStr += fileName;
91
                errorStr += "\n";
92
                throw errorStr;
93
        }
94
 
95
        ~File()
96
        {
97
                fclose(m_file);
98
        }
99
 
100
        // Read binary file
101
        void ReadBin(unsigned long limit)
102
        {
103
                m_top = 0;
104
 
105
                m_chunks.push_back(MemBlock());
106
                m_chunks.back().m_startAddress = 0;
107
 
108
                cerr << "Reading binary file\n";
109
 
110
                int tmp = fgetc(m_file);
111
 
112
                while (!feof(m_file))
113
                {
114
                        m_chunks.back().m_bytes.push_back(tmp);
115
 
116
                        if (m_chunks.back().m_bytes.size() > limit + 1)
117
                        {
118
                                m_chunks.back().m_bytes.pop_back();
119
                                m_top = m_chunks.back().m_bytes.size() - 1;
120
                                cerr << "Ignoring data above address space!\n";
121
                                cerr << " Limit: " << limit << "\n";
122
                                return;
123
                        }
124
 
125
                        tmp = fgetc(m_file);
126
                }
127
 
128
                m_top = m_chunks.back().m_bytes.size() - 1;
129
 
130
                if (!m_chunks.back().m_bytes.size())
131
                {
132
                        cerr << "No data!\n";
133
 
134
                        m_chunks.pop_back();
135
                }
136
        }
137
 
138
        // Read hex file
139
        void ReadHex(unsigned long limit)
140
        {
141
                char szLine[1024];
142
                bool formatDetected = false;
143
                bool intel;
144
                bool endSeen = false;
145
                bool linear = true;                             // Only used for intel hex
146
                unsigned long addressBase = 0;   // Only used for intel hex
147
                unsigned long dataRecords = 0;   // Only used for s-record
148
                while (!feof(m_file))
149
                {
150
                        if (fgets(szLine, 1024, m_file) == 0)
151
                        {
152
                                if (ferror(m_file))
153
                                {
154
                                        throw "Error reading input!\n";
155
                                }
156
                                continue;
157
                        }
158
 
159
                        if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
160
                        {
161
                                szLine[strlen(szLine) - 1] = 0;
162
                        }
163
 
164
                        if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
165
                        {
166
                                szLine[strlen(szLine) - 1] = 0;
167
                        }
168
 
169
                        if (strlen(szLine) == 1023)
170
                        {
171
                                throw "Hex file lines to long!\n";
172
                        }
173
                        // Ignore blank lines
174
                        if (szLine[0] == '\n')
175
                        {
176
                                continue;
177
                        }
178
                        // Detect format and warn if garbage lines are found
179
                        if (!formatDetected)
180
                        {
181
                                if (szLine[0] != ':' && szLine[0] != 'S')
182
                                {
183
                                        cerr << "Ignoring garbage line!\n";
184
                                        continue;
185
                                }
186
                                if (szLine[0] == 'S')
187
                                {
188
                                        intel = false;
189
                                        cerr << "Detected S-Record\n";
190
                                }
191
                                else
192
                                {
193
                                        intel = true;
194
                                        cerr << "Detected intel hex file\n";
195
                                }
196
                                formatDetected = true;
197
                        }
198
                        else if ((intel && szLine[0] != ':') ||
199
                                        (!intel && szLine[0] != 'S'))
200
                        {
201
                                cerr << "Ignoring garbage line!\n";
202
                                continue;
203
                        }
204
 
205
                        if (endSeen)
206
                        {
207
                                throw "Hex line after end of file record!\n";
208
                        }
209
 
210
                        if (intel)
211
                        {
212
                                unsigned long   dataBytes;
213
                                unsigned long   startAddress;
214
                                unsigned long   type;
215
                                if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3)
216
                                {
217
                                        throw "Hex line beginning corrupt!\n";
218
                                }
219
                                // Check line length
220
                                if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0)
221
                                {
222
                                        throw "Hex line length incorrect!\n";
223
                                }
224
                                // Check line checksum
225
                                unsigned char   checkSum = 0;
226
                                unsigned long   tmp;
227
                                for (unsigned int i = 0; i <= dataBytes + 4; ++i)
228
                                {
229
                                        if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1)
230
                                        {
231
                                                throw "Hex line data corrupt!\n";
232
                                        }
233
                                        checkSum += tmp;
234
                                }
235
                                if (checkSum != 0)
236
                                {
237
                                        throw "Hex line checksum error!\n";
238
                                }
239
 
240
                                switch (type)
241
                                {
242
                                case 0:
243
                                        // Data record
244
                                        if (!linear)
245
                                        {
246
                                                // Segmented
247
                                                unsigned long test = startAddress;
248
                                                test += dataBytes;
249
                                                if (test > 0xffff)
250
                                                {
251
                                                        throw "Can't handle wrapped segments!\n";
252
                                                }
253
                                        }
254
                                        if (!m_chunks.size() ||
255
                                                m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
256
                                                addressBase + startAddress)
257
                                        {
258
                                                m_chunks.push_back(MemBlock());
259
                                                m_chunks.back().m_startAddress = addressBase + startAddress;
260
                                        }
261
                                        {
262
                                                unsigned char i = 0;
263
                                                for (i = 0; i < dataBytes; ++i)
264
                                                {
265
                                                        sscanf(&szLine[9 + i * 2], "%2lx", &tmp);
266
                                                        if (addressBase + startAddress + i > limit)
267
                                                        {
268
                                                                cerr << "Ignoring data above address space!\n";
269
                                                                cerr << "Data address: " << addressBase + startAddress + i;
270
                                                                cerr << " Limit: " << limit << "\n";
271
                                                                if (!m_chunks.back().m_bytes.size())
272
                                                                {
273
                                                                        m_chunks.pop_back();
274
                                                                }
275
                                                                continue;
276
                                                        }
277
                                                        m_chunks.back().m_bytes.push_back(tmp);
278
                                                }
279
                                        }
280
                                        break;
281
 
282
                                case 1:
283
                                        // End-of-file record
284
                                        if (dataBytes != 0)
285
                                        {
286
                                                cerr << "Warning: End of file record not zero length!\n";
287
                                        }
288
                                        if (startAddress != 0)
289
                                        {
290
                                                cerr << "Warning: End of file record address not zero!\n";
291
                                        }
292
                                        endSeen = true;
293
                                        break;
294
 
295
                                case 2:
296
                                        // Extended segment address record
297
                                        if (dataBytes != 2)
298
                                        {
299
                                                throw "Length field must be 2 in extended segment address record!\n";
300
                                        }
301
                                        if (startAddress != 0)
302
                                        {
303
                                                throw "Address field must be zero in extended segment address record!\n";
304
                                        }
305
                                        sscanf(&szLine[9], "%4lx", &startAddress);
306
                                        addressBase = startAddress << 4;
307
                                        linear = false;
308
                                        break;
309
 
310
                                case 3:
311
                                        // Start segment address record
312
                                        if (dataBytes != 4)
313
                                        {
314
                                                cerr << "Warning: Length field must be 4 in start segment address record!\n";
315
                                        }
316
                                        if (startAddress != 0)
317
                                        {
318
                                                cerr << "Warning: Address field must be zero in start segment address record!\n";
319
                                        }
320
                                        if (dataBytes == 4)
321
                                        {
322
                                                unsigned long ssa;
323
                                                char    ssaStr[16];
324
                                                sscanf(&szLine[9], "%8lx", &ssa);
325
                                                sprintf(ssaStr, "%08X\n", ssa);
326
                                                cerr << "Segment start address (CS/IP): ";
327
                                                cerr << ssaStr;
328
                                        }
329
                                        break;
330
 
331
                                case 4:
332
                                        // Extended linear address record
333
                                        if (dataBytes != 2)
334
                                        {
335
                                                throw "Length field must be 2 in extended linear address record!\n";
336
                                        }
337
                                        if (startAddress != 0)
338
                                        {
339
                                                throw "Address field must be zero in extended linear address record!\n";
340
                                        }
341
                                        sscanf(&szLine[9], "%4lx", &startAddress);
342
                                        addressBase = ((unsigned long)startAddress) << 16;
343
                                        linear = true;
344
                                        break;
345
 
346
                                case 5:
347
                                        // Start linear address record
348
                                        if (dataBytes != 4)
349
                                        {
350
                                                cerr << "Warning: Length field must be 4 in start linear address record!\n";
351
                                        }
352
                                        if (startAddress != 0)
353
                                        {
354
                                                cerr << "Warning: Address field must be zero in start linear address record!\n";
355
                                        }
356
                                        if (dataBytes == 4)
357
                                        {
358
                                                unsigned long lsa;
359
                                                char    lsaStr[16];
360
                                                sscanf(&szLine[9], "%8lx", &lsa);
361
                                                sprintf(lsaStr, "%08X\n", lsa);
362
                                                cerr << "Linear start address: ";
363
                                                cerr << lsaStr;
364
                                        }
365
                                        break;
366
 
367
                                default:
368
                                        cerr << "Waring: Unknown record found!\n";
369
                                }
370
                        }
371
                        else
372
                        {
373
                                // S-record
374
                                unsigned long   count;
375
                                char                    type;
376
                                if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2)
377
                                {
378
                                        throw "Hex line beginning corrupt!\n";
379
                                }
380
                                // Check line length
381
                                if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0)
382
                                {
383
                                        throw "Hex line length incorrect!\n";
384
                                }
385
                                // Check line checksum
386
                                unsigned char   checkSum = 0;
387
                                unsigned long   tmp;
388
                                for (unsigned int i = 0; i < count + 1; ++i)
389
                                {
390
                                        if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1)
391
                                        {
392
                                                throw "Hex line data corrupt!\n";
393
                                        }
394
                                        checkSum += tmp;
395
                                }
396
                                if (checkSum != 255)
397
                                {
398
                                        throw "Hex line checksum error!\n";
399
                                }
400
 
401
                                switch (type)
402
                                {
403
                                case '0':
404
                                        // Header record
405
                                        {
406
                                                char header[256];
407
                                                unsigned char i = 0;
408
                                                for (i = 0; i + 3 < count; ++i)
409
                                                {
410
                                                        sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
411
                                                        header[i] = tmp;
412
                                                }
413
                                                header[i] = 0;
414
                                                if (i > 0)
415
                                                {
416
                                                        cerr << "Module name: " << header << "\n";
417
                                                }
418
                                        }
419
                                        break;
420
 
421
                                case '1':
422
                                case '2':
423
                                case '3':
424
                                        // Data record
425
                                        {
426
                                                dataRecords++;
427
                                                unsigned long   startAddress;
428
                                                if (type == '1')
429
                                                {
430
                                                        sscanf(&szLine[4], "%4lx", &startAddress);
431
                                                }
432
                                                else if (type == '2')
433
                                                {
434
                                                        sscanf(&szLine[4], "%6lx", &startAddress);
435
                                                }
436
                                                else
437
                                                {
438
                                                        sscanf(&szLine[4], "%8lx", &startAddress);
439
                                                }
440
 
441
                                                if (!m_chunks.size() ||
442
                                                        m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
443
                                                        startAddress)
444
                                                {
445
                                                        m_chunks.push_back(MemBlock());
446
                                                        m_chunks.back().m_startAddress = startAddress;
447
                                                }
448
                                                unsigned char i = 0;
449
                                                for (i = (type - '1'); i + 3 < count; ++i)
450
                                                {
451
                                                        sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
452
                                                        if (startAddress + i > limit)
453
                                                        {
454
                                                                cerr << "Ignoring data above address space!\n";
455
                                                                cerr << "Data address: " << startAddress + i;
456
                                                                cerr << " Limit: " << limit << "\n";
457
                                                                if (!m_chunks.back().m_bytes.size())
458
                                                                {
459
                                                                        m_chunks.pop_back();
460
                                                                }
461
                                                                continue;
462
                                                        }
463
                                                        m_chunks.back().m_bytes.push_back(tmp);
464
                                                }
465
                                        }
466
                                        break;
467
 
468
                                case '5':
469
                                        // Count record
470
                                        {
471
                                                unsigned long   address;
472
                                                sscanf(&szLine[4], "%4lx", &address);
473
                                                if (address != dataRecords)
474
                                                {
475
                                                        throw "Wrong number of data records!\n";
476
                                                }
477
                                        }
478
                                        break;
479
 
480
                                case '7':
481
                                case '8':
482
                                case '9':
483
                                        // Start address record
484
                                        cerr << "Ignoring start address record!\n";
485
                                        break;
486
 
487
                                default:
488
                                        cerr << "Unknown record found!\n";
489
                                }
490
                        }
491
                }
492
                if (intel && !endSeen)
493
                {
494
                        cerr << "No end of file record!\n";
495
                }
496
                if (!m_chunks.size())
497
                {
498
                        throw "No data in file!\n";
499
                }
500
                vector<MemBlock>::iterator      vi;
501
                m_top = 0;
502
                for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
503
                {
504
                        m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1);
505
                }
506
        }
507
 
508
        // Rather inefficient this one, fix sometime
509
        bool GetByte(const unsigned long address, unsigned char &chr)
510
        {
511
                vector<MemBlock>::iterator      vi;
512
 
513
                for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
514
                {
515
                        if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address)
516
                        {
517
                                break;
518
                        }
519
                }
520
                if (vi == m_chunks.end())
521
                {
522
                        return false;
523
                }
524
                chr = vi->m_bytes[address - vi->m_startAddress];
525
                return true;
526
        }
527
 
528
        bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str)
529
        {
530
                bool                    ok = false;
531
                long                    i;
532
                unsigned char   chr;
533
                unsigned long   data = 0;
534
                unsigned long   tmp;
535
 
536
                if (lEndian)
537
                {
538
                        for (i = 0; i < (bits + 7) / 8; ++i)
539
                        {
540
                                ok |= GetByte(address + i, chr);
541
                                tmp = chr;
542
                                data |= tmp << (8 * i);
543
                        }
544
                }
545
                else
546
                {
547
                        for (i = 0; i < (bits + 7) / 8; ++i)
548
                        {
549
                                ok |= GetByte(address + i, chr);
550
                                tmp = chr;
551
                                data |= tmp << (8 * ((bits + 7) / 8 - i - 1));
552
                        }
553
                }
554
 
555
                if (!ok)
556
                {
557
                        return false;
558
                }
559
 
560
                unsigned long mask = 1;
561
 
562
                str = "";
563
                for (i = 0; i < bits; i++)
564
                {
565
                        if (data & mask)
566
                        {
567
                                str.insert(0,"1");
568
                        }
569
                        else
570
                        {
571
                                str.insert(0,"0");
572
                        }
573
                        mask <<= 1;
574
                }
575
                return true;
576
        }
577
 
578
        FILE *Handle() { return m_file; };
579
        vector<MemBlock>        m_chunks;
580
        unsigned long           m_top;
581
private:
582
        FILE                            *m_file;
583
};
584
 
585
 
586
int main (int argc, char *argv[])
587
{
588
        cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0220\n";
589
 
590
        try
591
        {
592
                unsigned long aWidth;
593
                unsigned long dWidth;
594
                char endian;
595
                char O = 0;
596
 
597
                if (!(argc == 4 || argc == 5))
598
                {
599
                        cerr << "\nUsage: hex2rom [-b] <input file> <entity name> <format>\n";
600
                        cerr << "\nIf the -b option is specified the file is read as a binary file\n";
601
                        cerr << "Hex input files must be intel hex or motorola s-record\n";
602
                        cerr << "\nThe format string has the format AEDOS where:\n";
603
                        cerr << "  A = Address bits\n";
604
                        cerr << "  E = Endianness, l or b\n";
605
                        cerr << "  D = Data bits\n";
606
                        cerr << "  O = ROM type: (one optional character)\n";
607
                        cerr << "      z for tri-state output\n";
608
                        cerr << "      a for array ROM\n";
609
                        cerr << "      s for synchronous ROM\n";
610
                        cerr << "      u for xilinx ucf\n";
611
                        cerr << "  S = SelectRAM usage in 1/16 parts (only used when O = u)\n";
612
                        cerr << "\nExample:\n";
613
                        cerr << "  hex2rom test.hex Test_ROM 18b16z\n\n";
614
                        return -1;
615
                }
616
 
617
                string  inFileName;
618
                string  outFileName;
619
 
620
                unsigned long   bytes;
621
                unsigned long   select = 0;
622
 
623
                if (argc == 5)
624
                {
625
                        if (strcmp(argv[1], "-b"))
626
                        {
627
                                throw "Error in arguments!\n";
628
                        }
629
                }
630
 
631
                int result;
632
 
633
                result = sscanf(argv[argc - 1], "%lu%c%lu%c%lu", &aWidth, &endian, &dWidth, &O, &select);
634
                if (result < 3)
635
                {
636
                        throw "Error in output format argument!\n";
637
                }
638
 
639
                if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's' && O != 'u'))
640
                {
641
                        throw "Error in output format argument!\n";
642
                }
643
                inFileName = argv[argc - 3];
644
                outFileName = argv[argc - 2];
645
 
646
                bytes = (dWidth + 7) / 8;
647
 
648
                File    inFile(inFileName.c_str(), "rb");
649
 
650
                if (argc == 4)
651
                {
652
                        inFile.ReadHex((1UL << aWidth) * bytes - 1);
653
                }
654
                else
655
                {
656
                        inFile.ReadBin((1UL << aWidth) * bytes - 1);
657
                }
658
 
659
                string                          line;
660
 
661
                unsigned long   words = 1;
662
                unsigned long   i = inFile.m_top;
663
                i /= bytes;
664
 
665
                while (i != 0)
666
                {
667
                        i >>= 1;
668
                        words <<= 1;
669
                }
670
 
671
                if (O != 'u')
672
                {
673
                        printf("-- This file was generated with hex2rom written by Daniel Wallner\n");
674
                        printf("\nlibrary IEEE;");
675
                        printf("\nuse IEEE.std_logic_1164.all;");
676
                        printf("\nuse IEEE.numeric_std.all;");
677
                        printf("\n\nentity %s is", outFileName.c_str());
678
                        printf("\n\tport(");
679
                        if (O == 'z')
680
                        {
681
                                printf("\n\t\tCE_n\t: in std_logic;", dWidth - 1);
682
                                printf("\n\t\tOE_n\t: in std_logic;", dWidth - 1);
683
                        }
684
                        if (O == 's')
685
                        {
686
                                printf("\n\t\tClk\t: in std_logic;", dWidth - 1);
687
                        }
688
                        printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1);
689
                        printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1);
690
                        printf("\n\t);");
691
                        printf("\nend %s;", outFileName.c_str());
692
                        printf("\n\narchitecture rtl of %s is", outFileName.c_str());
693
                        if (!O)
694
                        {
695
                                printf("\nbegin");
696
                                printf("\n\tprocess (A)");
697
                                printf("\n\tbegin");
698
                                printf("\n\t\tcase to_integer(unsigned(A)) is");
699
                        }
700
                        else if (O == 's')
701
                        {
702
                                printf("\n\tsignal A_r : std_logic_vector(%d downto 0);", aWidth - 1);
703
                                printf("\nbegin");
704
                                printf("\n\tprocess (Clk)");
705
                                printf("\n\tbegin");
706
                                printf("\n\t\tif Clk'event and Clk = '1' then");
707
                                printf("\n\t\t\tA_r <= A;");
708
                                printf("\n\t\tend if;");
709
                                printf("\n\tend process;");
710
                                printf("\n\tprocess (A_r)");
711
                                printf("\n\tbegin");
712
                                printf("\n\t\tcase to_integer(unsigned(A_r)) is");
713
                        }
714
                        else
715
                        {
716
                                printf("\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1);
717
                                printf("\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1);
718
                                printf("\n\tconstant ROM: ROM_TABLE := ROM_TABLE'(");
719
                        }
720
 
721
                        string str;
722
                        string strDC;
723
                        for (i = 0; i < dWidth; i++)
724
                        {
725
                                strDC.insert(0, "-");
726
                        }
727
                        for (i = 0; i < words; i++)
728
                        {
729
                                if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str))
730
                                {
731
                                        str = strDC;
732
                                }
733
                                if (!O || O == 's')
734
                                {
735
                                        if (inFile.m_top / bytes >= i)
736
                                        {
737
                                                printf("\n\t\twhen %06d => D <= \"%s\";",i, str.c_str());
738
                                                printf("\t-- 0x%04X", i * bytes);
739
                                        }
740
                                }
741
                                else
742
                                {
743
                                        printf("\n\t\t\"%s", str.c_str());
744
                                        if (i != words - 1)
745
                                        {
746
                                                printf("\",");
747
                                        }
748
                                        else
749
                                        {
750
                                                printf("\");");
751
                                        }
752
                                        printf("\t-- 0x%04X", i * bytes);
753
                                }
754
                        }
755
 
756
                        if (!O || O == 's')
757
                        {
758
                                printf("\n\t\twhen others => D <= \"%s\";", strDC.c_str());
759
                                printf("\n\t\tend case;");
760
                                printf("\n\tend process;");
761
                        }
762
                        else
763
                        {
764
                                printf("\nbegin");
765
                                if (O == 'z')
766
                                {
767
                                        printf("\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');");
768
                                }
769
                                else
770
                                {
771
                                        printf("\n\tD <= ROM(to_integer(unsigned(A)));");
772
                                }
773
                        }
774
                        printf("\nend;\n");
775
                }
776
                else
777
                {
778
                        unsigned long selectIter = 0;
779
                        unsigned long blockIter = 0;
780
 
781
                        if (!select)
782
                        {
783
                                blockIter = ((1UL << aWidth) + 511) / 512;
784
                        }
785
                        else if (select == 16)
786
                        {
787
                                selectIter = ((1UL << aWidth) + 15) / 16;
788
                        }
789
                        else
790
                        {
791
                                blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512;
792
                                selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16;
793
                        }
794
 
795
                        cerr << "Creating .ucf file with " << selectIter * bytes;
796
                        cerr << " LUTs and "  << blockIter * bytes << " block RAMs\n";
797
 
798
                        unsigned long blockTotal = ((1UL << aWidth) + 511) / 512;
799
 
800
                        printf("# This file was generated with hex2rom written by Daniel Wallner\n");
801
 
802
                        for (i = 0; i < selectIter; i++)
803
                        {
804
                                unsigned long base = i * 16 * bytes;
805
                                unsigned long j;
806
                                unsigned char c;
807
                                unsigned long pos;
808
 
809
                                // Check that there is any actual data in segment
810
                                bool init = false;
811
                                for (pos = 0; pos < bytes * 16; pos++)
812
                                {
813
                                        init = inFile.GetByte(base + pos, c);
814
                                        if (init)
815
                                        {
816
                                                break;
817
                                        }
818
                                }
819
 
820
                                if (init)
821
                                {
822
                                        for (j = 0; j < dWidth; j++)
823
                                        {
824
                                                unsigned long bitMask = 1;
825
                                                unsigned long bits = 0;
826
 
827
                                                for (pos = 0; pos < 16; pos++)
828
                                                {
829
                                                        unsigned long addr;
830
 
831
                                                        if (endian = 'l')
832
                                                        {
833
                                                                addr = base + bytes * pos + j / 8;
834
                                                        }
835
                                                        else
836
                                                        {
837
                                                                addr = base + bytes * pos + bytes - j / 8 - 1;
838
                                                        }
839
 
840
                                                        c = 0;
841
                                                        inFile.GetByte(addr, c);
842
                                                        if (c & (1 << (j % 8)))
843
                                                        {
844
                                                                bits |= bitMask;
845
                                                        }
846
                                                        bitMask <<= 1;
847
                                                }
848
                                                printf("\nINST *s%s%d%d INIT = %04X;", outFileName.c_str(), i, j, bits);
849
                                        }
850
                                }
851
                        }
852
 
853
                        for (i = blockTotal - blockIter; i < blockTotal; i++)
854
                        {
855
                                unsigned long j;
856
                                for (j = 0; j < bytes; j++)
857
                                {
858
                                        unsigned long k;
859
                                        for (k = 0; k < 16; k++)
860
                                        {
861
                                                unsigned long base = i * 512 * bytes + j + k * 32 * bytes;
862
                                                unsigned char c;
863
                                                unsigned long pos;
864
 
865
                                                // Check that there is any actual data in segment
866
                                                bool init = false;
867
                                                for (pos = 0; pos < 32; pos++)
868
                                                {
869
                                                        init = inFile.GetByte(base + bytes * pos + j, c);
870
                                                        if (init)
871
                                                        {
872
                                                                break;
873
                                                        }
874
                                                }
875
 
876
                                                if (init)
877
                                                {
878
                                                        printf("\nINST *b%s%d%d INIT_%02X = ", outFileName.c_str(), i, j, k);
879
                                                        for (pos = 0; pos < 32; pos++)
880
                                                        {
881
                                                                unsigned long addr;
882
 
883
                                                                if (endian = 'l')
884
                                                                {
885
                                                                        addr = base + bytes * (31 - pos) + j;
886
                                                                }
887
                                                                else
888
                                                                {
889
                                                                        addr = base + bytes * (31 - pos) + bytes - j - 1;
890
                                                                }
891
 
892
                                                                c = 0;
893
                                                                inFile.GetByte(addr, c);
894
                                                                printf("%02X", c);
895
                                                        }
896
                                                        printf(";");
897
                                                }
898
                                        }
899
                                }
900
                        }
901
                        printf("\n");
902
                }
903
                return 0;
904
        }
905
        catch (string error)
906
        {
907
                cerr << "Fatal: " << error;
908
        }
909
        catch (const char *error)
910
        {
911
                cerr << "Fatal: " << error;
912
        }
913
        return -1;
914
}

powered by: WebSVN 2.1.0

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