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

Subversion Repositories ppx16

[/] [ppx16/] [trunk/] [sw/] [hex2rom.cpp] - Blame information for rev 22

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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