//
|
//
|
// Binary and intel/motorola hex to VHDL ROM converter
|
// Binary and intel/motorola hex to VHDL ROM converter
|
//
|
//
|
// Version : 0244
|
// Version : 0244
|
//
|
//
|
// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
//
|
//
|
// All rights reserved
|
// All rights reserved
|
//
|
//
|
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
// modification, are permitted provided that the following conditions are met:
|
// modification, are permitted provided that the following conditions are met:
|
//
|
//
|
// Redistributions of source code must retain the above copyright notice,
|
// Redistributions of source code must retain the above copyright notice,
|
// this list of conditions and the following disclaimer.
|
// this list of conditions and the following disclaimer.
|
//
|
//
|
// Redistributions in binary form must reproduce the above copyright
|
// Redistributions in binary form must reproduce the above copyright
|
// notice, this list of conditions and the following disclaimer in the
|
// notice, this list of conditions and the following disclaimer in the
|
// documentation and/or other materials provided with the distribution.
|
// documentation and/or other materials provided with the distribution.
|
//
|
//
|
// Neither the name of the author nor the names of other contributors may
|
// Neither the name of the author nor the names of other contributors may
|
// be used to endorse or promote products derived from this software without
|
// be used to endorse or promote products derived from this software without
|
// specific prior written permission.
|
// specific prior written permission.
|
//
|
//
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
//
|
//
|
// Please report bugs to the author, but before you do so, please
|
// Please report bugs to the author, but before you do so, please
|
// make sure that this is not a derivative work and that
|
// make sure that this is not a derivative work and that
|
// you have the latest version of this file.
|
// you have the latest version of this file.
|
//
|
//
|
// The latest version of this file can be found at:
|
// The latest version of this file can be found at:
|
// http://www.opencores.org/cvsweb.shtml/t51/
|
// http://www.opencores.org/cvsweb.shtml/t51/
|
//
|
//
|
// Limitations :
|
// Limitations :
|
// No support for wrapped intel segments
|
// No support for wrapped intel segments
|
// Requires stl to compile
|
// Requires stl to compile
|
//
|
//
|
// File history :
|
// File history :
|
//
|
//
|
// 0146 : Initial release
|
// 0146 : Initial release
|
//
|
//
|
// 0150 : Added binary read
|
// 0150 : Added binary read
|
//
|
//
|
// 0208 : Changed some errors to warnings
|
// 0208 : Changed some errors to warnings
|
//
|
//
|
// 0215 : Added support for synchronous ROM
|
// 0215 : Added support for synchronous ROM
|
//
|
//
|
// 0220 : Changed array ROM format, added support for Xilinx .UCF generation
|
// 0220 : Changed array ROM format, added support for Xilinx .UCF generation
|
//
|
//
|
// 0221 : Fixed small .UCF generation for small ROMs
|
// 0221 : Fixed small .UCF generation for small ROMs
|
//
|
//
|
// 0244 : Added Leonardo .UCF option
|
// 0244 : Added Leonardo .UCF option
|
//
|
//
|
// 28-Apr-2008 : Generate D for synchronous ROM in clocked process.
|
// 28-Apr-2008 : Generate D for synchronous ROM in clocked process.
|
//
|
//
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <string>
|
#include <string>
|
#include <vector>
|
#include <vector>
|
#include <iostream>
|
#include <iostream>
|
|
|
using namespace std;
|
using namespace std;
|
|
|
#if !(defined(max)) && _MSC_VER
|
#if !(defined(max)) && _MSC_VER
|
// VC fix
|
// VC fix
|
#define max __max
|
#define max __max
|
#endif
|
#endif
|
|
|
class MemBlock
|
class MemBlock
|
{
|
{
|
public:
|
public:
|
unsigned long m_startAddress;
|
unsigned long m_startAddress;
|
vector<unsigned char> m_bytes;
|
vector<unsigned char> m_bytes;
|
};
|
};
|
|
|
class File
|
class File
|
{
|
{
|
public:
|
public:
|
explicit File(const char *fileName, const char *mode)
|
explicit File(const char *fileName, const char *mode)
|
{
|
{
|
m_file = fopen(fileName, mode);
|
m_file = fopen(fileName, mode);
|
if (m_file != NULL)
|
if (m_file != NULL)
|
{
|
{
|
return;
|
return;
|
}
|
}
|
string errorStr = "Error opening ";
|
string errorStr = "Error opening ";
|
errorStr += fileName;
|
errorStr += fileName;
|
errorStr += "\n";
|
errorStr += "\n";
|
throw errorStr;
|
throw errorStr;
|
}
|
}
|
|
|
~File()
|
~File()
|
{
|
{
|
fclose(m_file);
|
fclose(m_file);
|
}
|
}
|
|
|
// Read binary file
|
// Read binary file
|
void ReadBin(unsigned long limit)
|
void ReadBin(unsigned long limit)
|
{
|
{
|
m_top = 0;
|
m_top = 0;
|
|
|
m_chunks.push_back(MemBlock());
|
m_chunks.push_back(MemBlock());
|
m_chunks.back().m_startAddress = 0;
|
m_chunks.back().m_startAddress = 0;
|
|
|
cerr << "Reading binary file\n";
|
cerr << "Reading binary file\n";
|
|
|
int tmp = fgetc(m_file);
|
int tmp = fgetc(m_file);
|
|
|
while (!feof(m_file))
|
while (!feof(m_file))
|
{
|
{
|
m_chunks.back().m_bytes.push_back(tmp);
|
m_chunks.back().m_bytes.push_back(tmp);
|
|
|
if (m_chunks.back().m_bytes.size() > limit + 1)
|
if (m_chunks.back().m_bytes.size() > limit + 1)
|
{
|
{
|
m_chunks.back().m_bytes.pop_back();
|
m_chunks.back().m_bytes.pop_back();
|
m_top = m_chunks.back().m_bytes.size() - 1;
|
m_top = m_chunks.back().m_bytes.size() - 1;
|
cerr << "Ignoring data above address space!\n";
|
cerr << "Ignoring data above address space!\n";
|
cerr << " Limit: " << limit << "\n";
|
cerr << " Limit: " << limit << "\n";
|
return;
|
return;
|
}
|
}
|
|
|
tmp = fgetc(m_file);
|
tmp = fgetc(m_file);
|
}
|
}
|
|
|
m_top = m_chunks.back().m_bytes.size() - 1;
|
m_top = m_chunks.back().m_bytes.size() - 1;
|
|
|
if (!m_chunks.back().m_bytes.size())
|
if (!m_chunks.back().m_bytes.size())
|
{
|
{
|
cerr << "No data!\n";
|
cerr << "No data!\n";
|
|
|
m_chunks.pop_back();
|
m_chunks.pop_back();
|
}
|
}
|
}
|
}
|
|
|
// Read hex file
|
// Read hex file
|
void ReadHex(unsigned long limit)
|
void ReadHex(unsigned long limit)
|
{
|
{
|
char szLine[1024];
|
char szLine[1024];
|
bool formatDetected = false;
|
bool formatDetected = false;
|
bool intel;
|
bool intel;
|
bool endSeen = false;
|
bool endSeen = false;
|
bool linear = true; // Only used for intel hex
|
bool linear = true; // Only used for intel hex
|
unsigned long addressBase = 0; // Only used for intel hex
|
unsigned long addressBase = 0; // Only used for intel hex
|
unsigned long dataRecords = 0; // Only used for s-record
|
unsigned long dataRecords = 0; // Only used for s-record
|
while (!feof(m_file))
|
while (!feof(m_file))
|
{
|
{
|
if (fgets(szLine, 1024, m_file) == 0)
|
if (fgets(szLine, 1024, m_file) == 0)
|
{
|
{
|
if (ferror(m_file))
|
if (ferror(m_file))
|
{
|
{
|
throw "Error reading input!\n";
|
throw "Error reading input!\n";
|
}
|
}
|
continue;
|
continue;
|
}
|
}
|
|
|
if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
|
if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
|
{
|
{
|
szLine[strlen(szLine) - 1] = 0;
|
szLine[strlen(szLine) - 1] = 0;
|
}
|
}
|
|
|
if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
|
if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD)
|
{
|
{
|
szLine[strlen(szLine) - 1] = 0;
|
szLine[strlen(szLine) - 1] = 0;
|
}
|
}
|
|
|
if (strlen(szLine) == 1023)
|
if (strlen(szLine) == 1023)
|
{
|
{
|
throw "Hex file lines to long!\n";
|
throw "Hex file lines to long!\n";
|
}
|
}
|
// Ignore blank lines
|
// Ignore blank lines
|
if (szLine[0] == '\n')
|
if (szLine[0] == '\n')
|
{
|
{
|
continue;
|
continue;
|
}
|
}
|
// Detect format and warn if garbage lines are found
|
// Detect format and warn if garbage lines are found
|
if (!formatDetected)
|
if (!formatDetected)
|
{
|
{
|
if (szLine[0] != ':' && szLine[0] != 'S')
|
if (szLine[0] != ':' && szLine[0] != 'S')
|
{
|
{
|
cerr << "Ignoring garbage line!\n";
|
cerr << "Ignoring garbage line!\n";
|
continue;
|
continue;
|
}
|
}
|
if (szLine[0] == 'S')
|
if (szLine[0] == 'S')
|
{
|
{
|
intel = false;
|
intel = false;
|
cerr << "Detected S-Record\n";
|
cerr << "Detected S-Record\n";
|
}
|
}
|
else
|
else
|
{
|
{
|
intel = true;
|
intel = true;
|
cerr << "Detected intel hex file\n";
|
cerr << "Detected intel hex file\n";
|
}
|
}
|
formatDetected = true;
|
formatDetected = true;
|
}
|
}
|
else if ((intel && szLine[0] != ':') ||
|
else if ((intel && szLine[0] != ':') ||
|
(!intel && szLine[0] != 'S'))
|
(!intel && szLine[0] != 'S'))
|
{
|
{
|
cerr << "Ignoring garbage line!\n";
|
cerr << "Ignoring garbage line!\n";
|
continue;
|
continue;
|
}
|
}
|
|
|
if (endSeen)
|
if (endSeen)
|
{
|
{
|
throw "Hex line after end of file record!\n";
|
throw "Hex line after end of file record!\n";
|
}
|
}
|
|
|
if (intel)
|
if (intel)
|
{
|
{
|
unsigned long dataBytes;
|
unsigned long dataBytes;
|
unsigned long startAddress;
|
unsigned long startAddress;
|
unsigned long type;
|
unsigned long type;
|
if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3)
|
if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3)
|
{
|
{
|
throw "Hex line beginning corrupt!\n";
|
throw "Hex line beginning corrupt!\n";
|
}
|
}
|
// Check line length
|
// Check line length
|
if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0)
|
if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0)
|
{
|
{
|
throw "Hex line length incorrect!\n";
|
throw "Hex line length incorrect!\n";
|
}
|
}
|
// Check line checksum
|
// Check line checksum
|
unsigned char checkSum = 0;
|
unsigned char checkSum = 0;
|
unsigned long tmp;
|
unsigned long tmp;
|
for (unsigned int i = 0; i <= dataBytes + 4; ++i)
|
for (unsigned int i = 0; i <= dataBytes + 4; ++i)
|
{
|
{
|
if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1)
|
if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1)
|
{
|
{
|
throw "Hex line data corrupt!\n";
|
throw "Hex line data corrupt!\n";
|
}
|
}
|
checkSum += tmp;
|
checkSum += tmp;
|
}
|
}
|
if (checkSum != 0)
|
if (checkSum != 0)
|
{
|
{
|
throw "Hex line checksum error!\n";
|
throw "Hex line checksum error!\n";
|
}
|
}
|
|
|
switch (type)
|
switch (type)
|
{
|
{
|
case 0:
|
case 0:
|
// Data record
|
// Data record
|
if (!linear)
|
if (!linear)
|
{
|
{
|
// Segmented
|
// Segmented
|
unsigned long test = startAddress;
|
unsigned long test = startAddress;
|
test += dataBytes;
|
test += dataBytes;
|
if (test > 0xffff)
|
if (test > 0xffff)
|
{
|
{
|
throw "Can't handle wrapped segments!\n";
|
throw "Can't handle wrapped segments!\n";
|
}
|
}
|
}
|
}
|
if (!m_chunks.size() ||
|
if (!m_chunks.size() ||
|
m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
|
m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
|
addressBase + startAddress)
|
addressBase + startAddress)
|
{
|
{
|
m_chunks.push_back(MemBlock());
|
m_chunks.push_back(MemBlock());
|
m_chunks.back().m_startAddress = addressBase + startAddress;
|
m_chunks.back().m_startAddress = addressBase + startAddress;
|
}
|
}
|
{
|
{
|
unsigned char i = 0;
|
unsigned char i = 0;
|
for (i = 0; i < dataBytes; ++i)
|
for (i = 0; i < dataBytes; ++i)
|
{
|
{
|
sscanf(&szLine[9 + i * 2], "%2lx", &tmp);
|
sscanf(&szLine[9 + i * 2], "%2lx", &tmp);
|
if (addressBase + startAddress + i > limit)
|
if (addressBase + startAddress + i > limit)
|
{
|
{
|
cerr << "Ignoring data above address space!\n";
|
cerr << "Ignoring data above address space!\n";
|
cerr << "Data address: " << addressBase + startAddress + i;
|
cerr << "Data address: " << addressBase + startAddress + i;
|
cerr << " Limit: " << limit << "\n";
|
cerr << " Limit: " << limit << "\n";
|
if (!m_chunks.back().m_bytes.size())
|
if (!m_chunks.back().m_bytes.size())
|
{
|
{
|
m_chunks.pop_back();
|
m_chunks.pop_back();
|
}
|
}
|
continue;
|
continue;
|
}
|
}
|
m_chunks.back().m_bytes.push_back(tmp);
|
m_chunks.back().m_bytes.push_back(tmp);
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
|
case 1:
|
case 1:
|
// End-of-file record
|
// End-of-file record
|
if (dataBytes != 0)
|
if (dataBytes != 0)
|
{
|
{
|
cerr << "Warning: End of file record not zero length!\n";
|
cerr << "Warning: End of file record not zero length!\n";
|
}
|
}
|
if (startAddress != 0)
|
if (startAddress != 0)
|
{
|
{
|
cerr << "Warning: End of file record address not zero!\n";
|
cerr << "Warning: End of file record address not zero!\n";
|
}
|
}
|
endSeen = true;
|
endSeen = true;
|
break;
|
break;
|
|
|
case 2:
|
case 2:
|
// Extended segment address record
|
// Extended segment address record
|
if (dataBytes != 2)
|
if (dataBytes != 2)
|
{
|
{
|
throw "Length field must be 2 in extended segment address record!\n";
|
throw "Length field must be 2 in extended segment address record!\n";
|
}
|
}
|
if (startAddress != 0)
|
if (startAddress != 0)
|
{
|
{
|
throw "Address field must be zero in extended segment address record!\n";
|
throw "Address field must be zero in extended segment address record!\n";
|
}
|
}
|
sscanf(&szLine[9], "%4lx", &startAddress);
|
sscanf(&szLine[9], "%4lx", &startAddress);
|
addressBase = startAddress << 4;
|
addressBase = startAddress << 4;
|
linear = false;
|
linear = false;
|
break;
|
break;
|
|
|
case 3:
|
case 3:
|
// Start segment address record
|
// Start segment address record
|
if (dataBytes != 4)
|
if (dataBytes != 4)
|
{
|
{
|
cerr << "Warning: Length field must be 4 in start segment address record!\n";
|
cerr << "Warning: Length field must be 4 in start segment address record!\n";
|
}
|
}
|
if (startAddress != 0)
|
if (startAddress != 0)
|
{
|
{
|
cerr << "Warning: Address field must be zero in start segment address record!\n";
|
cerr << "Warning: Address field must be zero in start segment address record!\n";
|
}
|
}
|
if (dataBytes == 4)
|
if (dataBytes == 4)
|
{
|
{
|
unsigned long ssa;
|
unsigned long ssa;
|
char ssaStr[16];
|
char ssaStr[16];
|
sscanf(&szLine[9], "%8lx", &ssa);
|
sscanf(&szLine[9], "%8lx", &ssa);
|
sprintf(ssaStr, "%08X\n", ssa);
|
sprintf(ssaStr, "%08X\n", ssa);
|
cerr << "Segment start address (CS/IP): ";
|
cerr << "Segment start address (CS/IP): ";
|
cerr << ssaStr;
|
cerr << ssaStr;
|
}
|
}
|
break;
|
break;
|
|
|
case 4:
|
case 4:
|
// Extended linear address record
|
// Extended linear address record
|
if (dataBytes != 2)
|
if (dataBytes != 2)
|
{
|
{
|
throw "Length field must be 2 in extended linear address record!\n";
|
throw "Length field must be 2 in extended linear address record!\n";
|
}
|
}
|
if (startAddress != 0)
|
if (startAddress != 0)
|
{
|
{
|
throw "Address field must be zero in extended linear address record!\n";
|
throw "Address field must be zero in extended linear address record!\n";
|
}
|
}
|
sscanf(&szLine[9], "%4lx", &startAddress);
|
sscanf(&szLine[9], "%4lx", &startAddress);
|
addressBase = ((unsigned long)startAddress) << 16;
|
addressBase = ((unsigned long)startAddress) << 16;
|
linear = true;
|
linear = true;
|
break;
|
break;
|
|
|
case 5:
|
case 5:
|
// Start linear address record
|
// Start linear address record
|
if (dataBytes != 4)
|
if (dataBytes != 4)
|
{
|
{
|
cerr << "Warning: Length field must be 4 in start linear address record!\n";
|
cerr << "Warning: Length field must be 4 in start linear address record!\n";
|
}
|
}
|
if (startAddress != 0)
|
if (startAddress != 0)
|
{
|
{
|
cerr << "Warning: Address field must be zero in start linear address record!\n";
|
cerr << "Warning: Address field must be zero in start linear address record!\n";
|
}
|
}
|
if (dataBytes == 4)
|
if (dataBytes == 4)
|
{
|
{
|
unsigned long lsa;
|
unsigned long lsa;
|
char lsaStr[16];
|
char lsaStr[16];
|
sscanf(&szLine[9], "%8lx", &lsa);
|
sscanf(&szLine[9], "%8lx", &lsa);
|
sprintf(lsaStr, "%08X\n", lsa);
|
sprintf(lsaStr, "%08X\n", lsa);
|
cerr << "Linear start address: ";
|
cerr << "Linear start address: ";
|
cerr << lsaStr;
|
cerr << lsaStr;
|
}
|
}
|
break;
|
break;
|
|
|
default:
|
default:
|
cerr << "Waring: Unknown record found!\n";
|
cerr << "Waring: Unknown record found!\n";
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
// S-record
|
// S-record
|
unsigned long count;
|
unsigned long count;
|
char type;
|
char type;
|
if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2)
|
if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2)
|
{
|
{
|
throw "Hex line beginning corrupt!\n";
|
throw "Hex line beginning corrupt!\n";
|
}
|
}
|
// Check line length
|
// Check line length
|
if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0)
|
if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0)
|
{
|
{
|
throw "Hex line length incorrect!\n";
|
throw "Hex line length incorrect!\n";
|
}
|
}
|
// Check line checksum
|
// Check line checksum
|
unsigned char checkSum = 0;
|
unsigned char checkSum = 0;
|
unsigned long tmp;
|
unsigned long tmp;
|
for (unsigned int i = 0; i < count + 1; ++i)
|
for (unsigned int i = 0; i < count + 1; ++i)
|
{
|
{
|
if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1)
|
if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1)
|
{
|
{
|
throw "Hex line data corrupt!\n";
|
throw "Hex line data corrupt!\n";
|
}
|
}
|
checkSum += tmp;
|
checkSum += tmp;
|
}
|
}
|
if (checkSum != 255)
|
if (checkSum != 255)
|
{
|
{
|
throw "Hex line checksum error!\n";
|
throw "Hex line checksum error!\n";
|
}
|
}
|
|
|
switch (type)
|
switch (type)
|
{
|
{
|
case '0':
|
case '0':
|
// Header record
|
// Header record
|
{
|
{
|
char header[256];
|
char header[256];
|
unsigned char i = 0;
|
unsigned char i = 0;
|
for (i = 0; i + 3 < count; ++i)
|
for (i = 0; i + 3 < count; ++i)
|
{
|
{
|
sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
|
sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
|
header[i] = tmp;
|
header[i] = tmp;
|
}
|
}
|
header[i] = 0;
|
header[i] = 0;
|
if (i > 0)
|
if (i > 0)
|
{
|
{
|
cerr << "Module name: " << header << "\n";
|
cerr << "Module name: " << header << "\n";
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
|
case '1':
|
case '1':
|
case '2':
|
case '2':
|
case '3':
|
case '3':
|
// Data record
|
// Data record
|
{
|
{
|
dataRecords++;
|
dataRecords++;
|
unsigned long startAddress;
|
unsigned long startAddress;
|
if (type == '1')
|
if (type == '1')
|
{
|
{
|
sscanf(&szLine[4], "%4lx", &startAddress);
|
sscanf(&szLine[4], "%4lx", &startAddress);
|
}
|
}
|
else if (type == '2')
|
else if (type == '2')
|
{
|
{
|
sscanf(&szLine[4], "%6lx", &startAddress);
|
sscanf(&szLine[4], "%6lx", &startAddress);
|
}
|
}
|
else
|
else
|
{
|
{
|
sscanf(&szLine[4], "%8lx", &startAddress);
|
sscanf(&szLine[4], "%8lx", &startAddress);
|
}
|
}
|
|
|
if (!m_chunks.size() ||
|
if (!m_chunks.size() ||
|
m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
|
m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() !=
|
startAddress)
|
startAddress)
|
{
|
{
|
m_chunks.push_back(MemBlock());
|
m_chunks.push_back(MemBlock());
|
m_chunks.back().m_startAddress = startAddress;
|
m_chunks.back().m_startAddress = startAddress;
|
}
|
}
|
unsigned char i = 0;
|
unsigned char i = 0;
|
for (i = (type - '1'); i + 3 < count; ++i)
|
for (i = (type - '1'); i + 3 < count; ++i)
|
{
|
{
|
sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
|
sscanf(&szLine[8 + i * 2], "%2lx", &tmp);
|
if (startAddress + i > limit)
|
if (startAddress + i > limit)
|
{
|
{
|
cerr << "Ignoring data above address space!\n";
|
cerr << "Ignoring data above address space!\n";
|
cerr << "Data address: " << startAddress + i;
|
cerr << "Data address: " << startAddress + i;
|
cerr << " Limit: " << limit << "\n";
|
cerr << " Limit: " << limit << "\n";
|
if (!m_chunks.back().m_bytes.size())
|
if (!m_chunks.back().m_bytes.size())
|
{
|
{
|
m_chunks.pop_back();
|
m_chunks.pop_back();
|
}
|
}
|
continue;
|
continue;
|
}
|
}
|
m_chunks.back().m_bytes.push_back(tmp);
|
m_chunks.back().m_bytes.push_back(tmp);
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
|
case '5':
|
case '5':
|
// Count record
|
// Count record
|
{
|
{
|
unsigned long address;
|
unsigned long address;
|
sscanf(&szLine[4], "%4lx", &address);
|
sscanf(&szLine[4], "%4lx", &address);
|
if (address != dataRecords)
|
if (address != dataRecords)
|
{
|
{
|
throw "Wrong number of data records!\n";
|
throw "Wrong number of data records!\n";
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
|
case '7':
|
case '7':
|
case '8':
|
case '8':
|
case '9':
|
case '9':
|
// Start address record
|
// Start address record
|
cerr << "Ignoring start address record!\n";
|
cerr << "Ignoring start address record!\n";
|
break;
|
break;
|
|
|
default:
|
default:
|
cerr << "Unknown record found!\n";
|
cerr << "Unknown record found!\n";
|
}
|
}
|
}
|
}
|
}
|
}
|
if (intel && !endSeen)
|
if (intel && !endSeen)
|
{
|
{
|
cerr << "No end of file record!\n";
|
cerr << "No end of file record!\n";
|
}
|
}
|
if (!m_chunks.size())
|
if (!m_chunks.size())
|
{
|
{
|
throw "No data in file!\n";
|
throw "No data in file!\n";
|
}
|
}
|
vector<MemBlock>::iterator vi;
|
vector<MemBlock>::iterator vi;
|
m_top = 0;
|
m_top = 0;
|
for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
|
for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
|
{
|
{
|
m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1);
|
m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1);
|
}
|
}
|
}
|
}
|
|
|
// Rather inefficient this one, fix sometime
|
// Rather inefficient this one, fix sometime
|
bool GetByte(const unsigned long address, unsigned char &chr)
|
bool GetByte(const unsigned long address, unsigned char &chr)
|
{
|
{
|
vector<MemBlock>::iterator vi;
|
vector<MemBlock>::iterator vi;
|
|
|
for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
|
for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++)
|
{
|
{
|
if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address)
|
if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address)
|
{
|
{
|
break;
|
break;
|
}
|
}
|
}
|
}
|
if (vi == m_chunks.end())
|
if (vi == m_chunks.end())
|
{
|
{
|
return false;
|
return false;
|
}
|
}
|
chr = vi->m_bytes[address - vi->m_startAddress];
|
chr = vi->m_bytes[address - vi->m_startAddress];
|
return true;
|
return true;
|
}
|
}
|
|
|
bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str)
|
bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str)
|
{
|
{
|
bool ok = false;
|
bool ok = false;
|
long i;
|
long i;
|
unsigned char chr;
|
unsigned char chr;
|
unsigned long data = 0;
|
unsigned long data = 0;
|
unsigned long tmp;
|
unsigned long tmp;
|
|
|
if (lEndian)
|
if (lEndian)
|
{
|
{
|
for (i = 0; i < (bits + 7) / 8; ++i)
|
for (i = 0; i < (bits + 7) / 8; ++i)
|
{
|
{
|
ok |= GetByte(address + i, chr);
|
ok |= GetByte(address + i, chr);
|
tmp = chr;
|
tmp = chr;
|
data |= tmp << (8 * i);
|
data |= tmp << (8 * i);
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for (i = 0; i < (bits + 7) / 8; ++i)
|
for (i = 0; i < (bits + 7) / 8; ++i)
|
{
|
{
|
ok |= GetByte(address + i, chr);
|
ok |= GetByte(address + i, chr);
|
tmp = chr;
|
tmp = chr;
|
data |= tmp << (8 * ((bits + 7) / 8 - i - 1));
|
data |= tmp << (8 * ((bits + 7) / 8 - i - 1));
|
}
|
}
|
}
|
}
|
|
|
if (!ok)
|
if (!ok)
|
{
|
{
|
return false;
|
return false;
|
}
|
}
|
|
|
unsigned long mask = 1;
|
unsigned long mask = 1;
|
|
|
str = "";
|
str = "";
|
for (i = 0; i < bits; i++)
|
for (i = 0; i < bits; i++)
|
{
|
{
|
if (data & mask)
|
if (data & mask)
|
{
|
{
|
str.insert(0,"1");
|
str.insert(0,"1");
|
}
|
}
|
else
|
else
|
{
|
{
|
str.insert(0,"0");
|
str.insert(0,"0");
|
}
|
}
|
mask <<= 1;
|
mask <<= 1;
|
}
|
}
|
return true;
|
return true;
|
}
|
}
|
|
|
FILE *Handle() { return m_file; };
|
FILE *Handle() { return m_file; };
|
vector<MemBlock> m_chunks;
|
vector<MemBlock> m_chunks;
|
unsigned long m_top;
|
unsigned long m_top;
|
private:
|
private:
|
FILE *m_file;
|
FILE *m_file;
|
};
|
};
|
|
|
|
|
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
{
|
{
|
cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0244\n";
|
cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0244\n";
|
|
|
try
|
try
|
{
|
{
|
unsigned long aWidth;
|
unsigned long aWidth;
|
unsigned long dWidth;
|
unsigned long dWidth;
|
char endian;
|
char endian;
|
char O = 0;
|
char O = 0;
|
|
|
if (!(argc == 4 || argc == 5))
|
if (!(argc == 4 || argc == 5))
|
{
|
{
|
cerr << "\nUsage: hex2rom [-b] <input file> <entity name> <format>\n";
|
cerr << "\nUsage: hex2rom [-b] <input file> <entity name> <format>\n";
|
cerr << "\nIf the -b option is specified the file is read as a binary file\n";
|
cerr << "\nIf the -b option is specified the file is read as a binary file\n";
|
cerr << "Hex input files must be intel hex or motorola s-record\n";
|
cerr << "Hex input files must be intel hex or motorola s-record\n";
|
cerr << "\nThe format string has the format AEDOS where:\n";
|
cerr << "\nThe format string has the format AEDOS where:\n";
|
cerr << " A = Address bits\n";
|
cerr << " A = Address bits\n";
|
cerr << " E = Endianness, l or b\n";
|
cerr << " E = Endianness, l or b\n";
|
cerr << " D = Data bits\n";
|
cerr << " D = Data bits\n";
|
cerr << " O = ROM type: (one optional character)\n";
|
cerr << " O = ROM type: (one optional character)\n";
|
cerr << " z for tri-state output\n";
|
cerr << " z for tri-state output\n";
|
cerr << " a for array ROM\n";
|
cerr << " a for array ROM\n";
|
cerr << " s for synchronous ROM\n";
|
cerr << " s for synchronous ROM\n";
|
cerr << " u for XST ucf\n";
|
cerr << " u for XST ucf\n";
|
cerr << " l for Leonardo ucf\n";
|
cerr << " l for Leonardo ucf\n";
|
cerr << " S = SelectRAM usage in 1/16 parts (only used when O = u)\n";
|
cerr << " S = SelectRAM usage in 1/16 parts (only used when O = u)\n";
|
cerr << "\nExample:\n";
|
cerr << "\nExample:\n";
|
cerr << " hex2rom test.hex Test_ROM 18b16z\n\n";
|
cerr << " hex2rom test.hex Test_ROM 18b16z\n\n";
|
return -1;
|
return -1;
|
}
|
}
|
|
|
string inFileName;
|
string inFileName;
|
string outFileName;
|
string outFileName;
|
|
|
unsigned long bytes;
|
unsigned long bytes;
|
unsigned long select = 0;
|
unsigned long select = 0;
|
|
|
if (argc == 5)
|
if (argc == 5)
|
{
|
{
|
if (strcmp(argv[1], "-b"))
|
if (strcmp(argv[1], "-b"))
|
{
|
{
|
throw "Error in arguments!\n";
|
throw "Error in arguments!\n";
|
}
|
}
|
}
|
}
|
|
|
int result;
|
int result;
|
|
|
result = sscanf(argv[argc - 1], "%lu%c%lu%c%lu", &aWidth, &endian, &dWidth, &O, &select);
|
result = sscanf(argv[argc - 1], "%lu%c%lu%c%lu", &aWidth, &endian, &dWidth, &O, &select);
|
if (result < 3)
|
if (result < 3)
|
{
|
{
|
throw "Error in output format argument!\n";
|
throw "Error in output format argument!\n";
|
}
|
}
|
|
|
if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's' && O != 'u' && O != 'l'))
|
if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's' && O != 'u' && O != 'l'))
|
{
|
{
|
throw "Error in output format argument!\n";
|
throw "Error in output format argument!\n";
|
}
|
}
|
inFileName = argv[argc - 3];
|
inFileName = argv[argc - 3];
|
outFileName = argv[argc - 2];
|
outFileName = argv[argc - 2];
|
|
|
bytes = (dWidth + 7) / 8;
|
bytes = (dWidth + 7) / 8;
|
|
|
File inFile(inFileName.c_str(), "rb");
|
File inFile(inFileName.c_str(), "rb");
|
|
|
if (argc == 4)
|
if (argc == 4)
|
{
|
{
|
inFile.ReadHex((1UL << aWidth) * bytes - 1);
|
inFile.ReadHex((1UL << aWidth) * bytes - 1);
|
}
|
}
|
else
|
else
|
{
|
{
|
inFile.ReadBin((1UL << aWidth) * bytes - 1);
|
inFile.ReadBin((1UL << aWidth) * bytes - 1);
|
}
|
}
|
|
|
string line;
|
string line;
|
|
|
unsigned long words = 1;
|
unsigned long words = 1;
|
unsigned long i = inFile.m_top;
|
unsigned long i = inFile.m_top;
|
i /= bytes;
|
i /= bytes;
|
|
|
while (i != 0)
|
while (i != 0)
|
{
|
{
|
i >>= 1;
|
i >>= 1;
|
words <<= 1;
|
words <<= 1;
|
}
|
}
|
|
|
if (O != 'u' && O != 'l')
|
if (O != 'u' && O != 'l')
|
{
|
{
|
printf("-- This file was generated with hex2rom written by Daniel Wallner\n");
|
printf("-- This file was generated with hex2rom written by Daniel Wallner\n");
|
printf("\nlibrary IEEE;");
|
printf("\nlibrary IEEE;");
|
printf("\nuse IEEE.std_logic_1164.all;");
|
printf("\nuse IEEE.std_logic_1164.all;");
|
printf("\nuse IEEE.numeric_std.all;");
|
printf("\nuse IEEE.numeric_std.all;");
|
printf("\n\nentity %s is", outFileName.c_str());
|
printf("\n\nentity %s is", outFileName.c_str());
|
printf("\n\tport(");
|
printf("\n\tport(");
|
if (O == 'z')
|
if (O == 'z')
|
{
|
{
|
printf("\n\t\tCE_n\t: in std_logic;", dWidth - 1);
|
printf("\n\t\tCE_n\t: in std_logic;", dWidth - 1);
|
printf("\n\t\tOE_n\t: in std_logic;", dWidth - 1);
|
printf("\n\t\tOE_n\t: in std_logic;", dWidth - 1);
|
}
|
}
|
if (O == 's')
|
if (O == 's')
|
{
|
{
|
printf("\n\t\tClk\t: in std_logic;", dWidth - 1);
|
printf("\n\t\tClk\t: in std_logic;", dWidth - 1);
|
}
|
}
|
printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1);
|
printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1);
|
printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1);
|
printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1);
|
printf("\n\t);");
|
printf("\n\t);");
|
printf("\nend %s;", outFileName.c_str());
|
printf("\nend %s;", outFileName.c_str());
|
printf("\n\narchitecture rtl of %s is", outFileName.c_str());
|
printf("\n\narchitecture rtl of %s is", outFileName.c_str());
|
if (!O)
|
if (!O)
|
{
|
{
|
printf("\nbegin");
|
printf("\nbegin");
|
printf("\n\tprocess (A)");
|
printf("\n\tprocess (A)");
|
printf("\n\tbegin");
|
printf("\n\tbegin");
|
printf("\n\t\tcase to_integer(unsigned(A)) is");
|
printf("\n\t\tcase to_integer(unsigned(A)) is");
|
}
|
}
|
else if (O == 's')
|
else if (O == 's')
|
{
|
{
|
printf("\nbegin");
|
printf("\nbegin");
|
printf("\n\tprocess (Clk)");
|
printf("\n\tprocess (Clk)");
|
printf("\n\tbegin");
|
printf("\n\tbegin");
|
printf("\n\t\tif Clk'event and Clk = '1' then");
|
printf("\n\t\tif Clk'event and Clk = '1' then");
|
printf("\n\t\tcase to_integer(unsigned(A)) is");
|
printf("\n\t\tcase to_integer(unsigned(A)) is");
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1);
|
printf("\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1);
|
printf("\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1);
|
printf("\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1);
|
printf("\n\tconstant ROM: ROM_TABLE := ROM_TABLE'(");
|
printf("\n\tconstant ROM: ROM_TABLE := ROM_TABLE'(");
|
}
|
}
|
|
|
string str;
|
string str;
|
string strDC;
|
string strDC;
|
for (i = 0; i < dWidth; i++)
|
for (i = 0; i < dWidth; i++)
|
{
|
{
|
strDC.insert(0, "-");
|
strDC.insert(0, "-");
|
}
|
}
|
for (i = 0; i < words; i++)
|
for (i = 0; i < words; i++)
|
{
|
{
|
if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str))
|
if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str))
|
{
|
{
|
str = strDC;
|
str = strDC;
|
}
|
}
|
if (!O || O == 's')
|
if (!O || O == 's')
|
{
|
{
|
if (inFile.m_top / bytes >= i)
|
if (inFile.m_top / bytes >= i)
|
{
|
{
|
printf("\n\t\twhen %06d => D <= \"%s\";",i, str.c_str());
|
printf("\n\t\twhen %06d => D <= \"%s\";",i, str.c_str());
|
printf("\t-- 0x%04X", i * bytes);
|
printf("\t-- 0x%04X", i * bytes);
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\n\t\t\"%s", str.c_str());
|
printf("\n\t\t\"%s", str.c_str());
|
if (i != words - 1)
|
if (i != words - 1)
|
{
|
{
|
printf("\",");
|
printf("\",");
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\");");
|
printf("\");");
|
}
|
}
|
printf("\t-- 0x%04X", i * bytes);
|
printf("\t-- 0x%04X", i * bytes);
|
}
|
}
|
}
|
}
|
|
|
if (!O || O == 's')
|
if (!O || O == 's')
|
{
|
{
|
printf("\n\t\twhen others => D <= \"%s\";", strDC.c_str());
|
printf("\n\t\twhen others => D <= \"%s\";", strDC.c_str());
|
printf("\n\t\tend case;");
|
printf("\n\t\tend case;");
|
if (O == 's')
|
if (O == 's')
|
printf("\n\tend if;");
|
printf("\n\tend if;");
|
printf("\n\tend process;");
|
printf("\n\tend process;");
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\nbegin");
|
printf("\nbegin");
|
if (O == 'z')
|
if (O == 'z')
|
{
|
{
|
printf("\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');");
|
printf("\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');");
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\n\tD <= ROM(to_integer(unsigned(A)));");
|
printf("\n\tD <= ROM(to_integer(unsigned(A)));");
|
}
|
}
|
}
|
}
|
printf("\nend;\n");
|
printf("\nend;\n");
|
}
|
}
|
else
|
else
|
{
|
{
|
unsigned long selectIter = 0;
|
unsigned long selectIter = 0;
|
unsigned long blockIter = 0;
|
unsigned long blockIter = 0;
|
|
|
if (!select)
|
if (!select)
|
{
|
{
|
blockIter = ((1UL << aWidth) + 511) / 512;
|
blockIter = ((1UL << aWidth) + 511) / 512;
|
}
|
}
|
else if (select == 16)
|
else if (select == 16)
|
{
|
{
|
selectIter = ((1UL << aWidth) + 15) / 16;
|
selectIter = ((1UL << aWidth) + 15) / 16;
|
}
|
}
|
else
|
else
|
{
|
{
|
blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512;
|
blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512;
|
selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16;
|
selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16;
|
}
|
}
|
|
|
cerr << "Creating .ucf file with " << selectIter * bytes;
|
cerr << "Creating .ucf file with " << selectIter * bytes;
|
cerr << " LUTs and " << blockIter * bytes << " block RAMs\n";
|
cerr << " LUTs and " << blockIter * bytes << " block RAMs\n";
|
|
|
unsigned long blockTotal = ((1UL << aWidth) + 511) / 512;
|
unsigned long blockTotal = ((1UL << aWidth) + 511) / 512;
|
|
|
printf("# This file was generated with hex2rom written by Daniel Wallner\n");
|
printf("# This file was generated with hex2rom written by Daniel Wallner\n");
|
|
|
for (i = 0; i < selectIter; i++)
|
for (i = 0; i < selectIter; i++)
|
{
|
{
|
unsigned long base = i * 16 * bytes;
|
unsigned long base = i * 16 * bytes;
|
unsigned long j;
|
unsigned long j;
|
unsigned char c;
|
unsigned char c;
|
unsigned long pos;
|
unsigned long pos;
|
|
|
// Check that there is any actual data in segment
|
// Check that there is any actual data in segment
|
bool init = false;
|
bool init = false;
|
for (pos = 0; pos < bytes * 16; pos++)
|
for (pos = 0; pos < bytes * 16; pos++)
|
{
|
{
|
init = inFile.GetByte(base + pos, c);
|
init = inFile.GetByte(base + pos, c);
|
if (init)
|
if (init)
|
{
|
{
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
if (init)
|
if (init)
|
{
|
{
|
for (j = 0; j < dWidth; j++)
|
for (j = 0; j < dWidth; j++)
|
{
|
{
|
unsigned long bitMask = 1;
|
unsigned long bitMask = 1;
|
unsigned long bits = 0;
|
unsigned long bits = 0;
|
|
|
for (pos = 0; pos < 16; pos++)
|
for (pos = 0; pos < 16; pos++)
|
{
|
{
|
unsigned long addr;
|
unsigned long addr;
|
|
|
if (endian = 'l')
|
if (endian = 'l')
|
{
|
{
|
addr = base + bytes * pos + j / 8;
|
addr = base + bytes * pos + j / 8;
|
}
|
}
|
else
|
else
|
{
|
{
|
addr = base + bytes * pos + bytes - j / 8 - 1;
|
addr = base + bytes * pos + bytes - j / 8 - 1;
|
}
|
}
|
|
|
c = 0;
|
c = 0;
|
inFile.GetByte(addr, c);
|
inFile.GetByte(addr, c);
|
if (c & (1 << (j % 8)))
|
if (c & (1 << (j % 8)))
|
{
|
{
|
bits |= bitMask;
|
bits |= bitMask;
|
}
|
}
|
bitMask <<= 1;
|
bitMask <<= 1;
|
}
|
}
|
|
|
if (O == 'u')
|
if (O == 'u')
|
{
|
{
|
if (selectIter == 1)
|
if (selectIter == 1)
|
{
|
{
|
printf("\nINST *s%s%d INIT = %04X;", outFileName.c_str(), j, bits);
|
printf("\nINST *s%s%d INIT = %04X;", outFileName.c_str(), j, bits);
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\nINST *s%s%d%d INIT = %04X;", outFileName.c_str(), i, j, bits);
|
printf("\nINST *s%s%d%d INIT = %04X;", outFileName.c_str(), i, j, bits);
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (selectIter == 1)
|
if (selectIter == 1)
|
{
|
{
|
printf("\nINST *sG1_%d_S%s INIT = %04X;", j, outFileName.c_str(), bits);
|
printf("\nINST *sG1_%d_S%s INIT = %04X;", j, outFileName.c_str(), bits);
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\nINST *sG1_%d_sG2_%d_S%s INIT = %04X;", i, j, outFileName.c_str(), bits);
|
printf("\nINST *sG1_%d_sG2_%d_S%s INIT = %04X;", i, j, outFileName.c_str(), bits);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
for (i = blockTotal - blockIter; i < blockTotal; i++)
|
for (i = blockTotal - blockIter; i < blockTotal; i++)
|
{
|
{
|
unsigned long j;
|
unsigned long j;
|
for (j = 0; j < bytes; j++)
|
for (j = 0; j < bytes; j++)
|
{
|
{
|
unsigned long k;
|
unsigned long k;
|
for (k = 0; k < 16; k++)
|
for (k = 0; k < 16; k++)
|
{
|
{
|
unsigned long base = i * 512 * bytes + k * 32 * bytes;
|
unsigned long base = i * 512 * bytes + k * 32 * bytes;
|
unsigned char c;
|
unsigned char c;
|
unsigned long pos;
|
unsigned long pos;
|
|
|
// Check that there is any actual data in segment
|
// Check that there is any actual data in segment
|
bool init = false;
|
bool init = false;
|
for (pos = 0; pos < 32; pos++)
|
for (pos = 0; pos < 32; pos++)
|
{
|
{
|
init = inFile.GetByte(base + bytes * pos + j, c);
|
init = inFile.GetByte(base + bytes * pos + j, c);
|
if (init)
|
if (init)
|
{
|
{
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
if (init)
|
if (init)
|
{
|
{
|
if (O == 'u')
|
if (O == 'u')
|
{
|
{
|
if (blockIter == 1)
|
if (blockIter == 1)
|
{
|
{
|
printf("\nINST *b%s%d INIT_%02X = ", outFileName.c_str(), j, k);
|
printf("\nINST *b%s%d INIT_%02X = ", outFileName.c_str(), j, k);
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\nINST *b%s%d%d INIT_%02X = ", outFileName.c_str(), i, j, k);
|
printf("\nINST *b%s%d%d INIT_%02X = ", outFileName.c_str(), i, j, k);
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (blockIter == 1)
|
if (blockIter == 1)
|
{
|
{
|
printf("\nINST *bG1_%d_B%s INIT_%02X = ", j, outFileName.c_str(), k);
|
printf("\nINST *bG1_%d_B%s INIT_%02X = ", j, outFileName.c_str(), k);
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("\nINST *bG1_%d_bG2_%d_B%s INIT_%02X = ", i, j, outFileName.c_str(), k);
|
printf("\nINST *bG1_%d_bG2_%d_B%s INIT_%02X = ", i, j, outFileName.c_str(), k);
|
}
|
}
|
}
|
}
|
for (pos = 0; pos < 32; pos++)
|
for (pos = 0; pos < 32; pos++)
|
{
|
{
|
unsigned long addr;
|
unsigned long addr;
|
|
|
if (endian = 'l')
|
if (endian = 'l')
|
{
|
{
|
addr = base + bytes * (31 - pos) + j;
|
addr = base + bytes * (31 - pos) + j;
|
}
|
}
|
else
|
else
|
{
|
{
|
addr = base + bytes * (31 - pos) + bytes - j - 1;
|
addr = base + bytes * (31 - pos) + bytes - j - 1;
|
}
|
}
|
|
|
c = 0;
|
c = 0;
|
inFile.GetByte(addr, c);
|
inFile.GetByte(addr, c);
|
printf("%02X", c);
|
printf("%02X", c);
|
}
|
}
|
printf(";");
|
printf(";");
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
printf("\n");
|
printf("\n");
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
catch (string error)
|
catch (string error)
|
{
|
{
|
cerr << "Fatal: " << error;
|
cerr << "Fatal: " << error;
|
}
|
}
|
catch (const char *error)
|
catch (const char *error)
|
{
|
{
|
cerr << "Fatal: " << error;
|
cerr << "Fatal: " << error;
|
}
|
}
|
return -1;
|
return -1;
|
}
|
}
|
|
|