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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_1_1/] [sw/] [hex2rom/] [hex2rom.cpp] - Blame information for rev 295

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

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

powered by: WebSVN 2.1.0

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