Line 1... |
Line 1... |
#include "assert.h"
|
#include "assert.h"
|
#include "stdio.h"
|
#include "stdio.h"
|
#include "stdint.h"
|
#include "stdint.h"
|
#include "string.h"
|
#include "string.h"
|
|
|
const char * hex_file = 0;
|
uint8_t buffer[0x10000]; // 64 k is max. for Intel hex.
|
const char * vhdl_file = 0;
|
uint8_t slice [0x10000]; // 16 k is max. for Xilinx bram
|
|
|
uint8_t buffer[0x10000];
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// get a byte (from cp pointing into Intel hex file).
|
|
//
|
uint32_t
|
uint32_t
|
get_byte(const char * cp)
|
get_byte(const char * cp)
|
{
|
{
|
uint32_t value;
|
uint32_t value;
|
const char cc[3] = { cp[0], cp[1], 0 };
|
const char cc[3] = { cp[0], cp[1], 0 };
|
const int cnt = sscanf(cc, "%X", &value);
|
const int cnt = sscanf(cc, "%X", &value);
|
assert(cnt == 1);
|
assert(cnt == 1);
|
return value;
|
return value;
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// read an Intel hex file into buffer
|
void
|
void
|
read_file(FILE * in)
|
read_file(FILE * in)
|
{
|
{
|
memset(buffer, 0xFF, sizeof(buffer));
|
memset(buffer, 0xFF, sizeof(buffer));
|
char line[200];
|
char line[200];
|
Line 50... |
Line 53... |
const uint32_t sum = get_byte(d);
|
const uint32_t sum = get_byte(d);
|
assert(sum == csum);
|
assert(sum == csum);
|
}
|
}
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
void
|
//
|
write_vector(FILE * out, bool odd, uint32_t mem, uint32_t v)
|
// copy a slice from buffer into slice.
|
|
// buffer is organized as 32-bit x items.
|
|
// slice is organized as bits x items.
|
|
//
|
|
void copy_slice(uint32_t slice_num, uint32_t port_bits, uint32_t mem_bits)
|
{
|
{
|
const uint8_t * base = buffer;
|
assert(mem_bits == 0x1000 || mem_bits == 0x4000);
|
|
|
// total memory is 2 even bytes, 2 odd bytes, 2 even bytes, ...
|
const uint32_t items = mem_bits/port_bits;
|
//
|
const uint32_t mask = (1 << port_bits) - 1;
|
if (odd) base += 2;
|
const uint8_t * src = buffer;
|
|
|
// total memory is 4 kByte organized into 8 memories.
|
memset(slice, 0, sizeof(slice));
|
// thus each of the 16 vectors covers 256 bytes.
|
|
//
|
|
base += v*256;
|
|
|
|
// memories 0 and 1 are the low byte of the opcode while
|
for (uint32_t i = 0; i < items; ++i)
|
// memories 2 and 3 are the high byte.
|
{
|
//
|
// read one 32-bit value;
|
if (mem >= 2) ++base;
|
const uint32_t v0 = *src++;
|
|
const uint32_t v1 = *src++;
|
|
const uint32_t v2 = *src++;
|
|
const uint32_t v3 = *src++;
|
|
const uint32_t v = (v3 << 24 |
|
|
v2 << 16 |
|
|
v1 << 8 |
|
|
v0 ) >> (slice_num*port_bits) & mask;
|
|
|
const char * px = odd ? "po" : "pe";
|
if (port_bits == 16)
|
fprintf(out, "constant %s_%u_%2.2X : BIT_VECTOR := X\"", px, mem, v);
|
{
|
for (int32_t d = 63; d >= 0; --d)
|
assert(v < 0x10000);
|
|
slice[2*i] = v;
|
|
slice[2*i + 1] = v >> 8;
|
|
}
|
|
else if (port_bits == 8)
|
|
{
|
|
assert(v < 0x100);
|
|
slice[i] = v;
|
|
}
|
|
else if (port_bits == 4)
|
|
{
|
|
assert(v < 0x10);
|
|
slice[i >> 1] |= v << (4*(i & 1));
|
|
}
|
|
else if (port_bits == 2)
|
|
{
|
|
assert(v < 0x04);
|
|
slice[i >> 2] |= v << (2*(i & 3));
|
|
}
|
|
else if (port_bits == 1)
|
{
|
{
|
uint32_t q = base[4*d];
|
assert(v < 0x02);
|
if (mem & 1) q >>= 4; // high nibble
|
slice[i >> 3] |= v << ((i & 7));
|
else q &= 0x0F; // low nibble
|
}
|
fprintf(out, "%X", q);
|
else assert(0 && "Bad aspect ratio.");
|
|
}
|
}
|
}
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// write one initialization vector
|
|
//
|
|
void
|
|
write_vector(FILE * out, uint32_t mem, uint32_t vec, const uint8_t * data)
|
|
{
|
|
fprintf(out, "constant p%u_%2.2X : BIT_VECTOR := X\"", mem, vec);
|
|
for (int32_t d = 31; d >= 0; --d)
|
|
fprintf(out, "%2.2X", data[d]);
|
|
|
fprintf(out, "\";\r\n");
|
fprintf(out, "\";\r\n");
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// write one memory
|
|
//
|
void
|
void
|
write_mem(FILE * out, bool odd, uint32_t mem)
|
write_mem(FILE * out, uint32_t mem, uint32_t bytes)
|
{
|
{
|
const char * px = odd ? "po" : "pe";
|
fprintf(out, "-- content of p_%u --------------------------------------"
|
|
"--------------------------------------------\r\n", mem);
|
|
|
fprintf(out, "-- content of %s_%u --------------------------------------"
|
const uint8_t * src = slice;
|
"--------------------------------------------\r\n", px, mem);
|
for (uint32_t v = 0; v < bytes/32; ++v)
|
|
write_vector(out, mem, v, src + 32*v);
|
for (uint32_t v = 0; v < 16; ++v)
|
|
write_vector(out, odd, mem, v);
|
|
|
|
fprintf(out, "\r\n");
|
fprintf(out, "\r\n");
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// write the entire memory_contents file.
|
|
//
|
void
|
void
|
write_file(FILE * out)
|
write_file(FILE * out, uint32_t bits)
|
{
|
{
|
fprintf(out,
|
fprintf(out,
|
"\r\n"
|
"\r\n"
|
"library IEEE;\r\n"
|
"library IEEE;\r\n"
|
"use IEEE.STD_LOGIC_1164.all;\r\n"
|
"use IEEE.STD_LOGIC_1164.all;\r\n"
|
"\r\n"
|
"\r\n"
|
"package prog_mem_content is\r\n"
|
"package prog_mem_content is\r\n"
|
"\r\n");
|
"\r\n");
|
|
|
for (uint32_t m = 0; m < 4; ++m)
|
const uint32_t mems = 16/bits;
|
write_mem(out, false, m);
|
|
|
|
for (uint32_t m = 0; m < 4; ++m)
|
for (uint32_t m = 0; m < 2*mems; ++m)
|
write_mem(out, true, m);
|
{
|
|
copy_slice(m, bits, 0x1000);
|
|
write_mem(out, m, 0x200);
|
|
}
|
|
|
fprintf(out,
|
fprintf(out,
|
"end prog_mem_content;\r\n"
|
"end prog_mem_content;\r\n"
|
"\r\n");
|
"\r\n");
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
int
|
int
|
main(int argc, char * argv[])
|
main(int argc, char * argv[])
|
{
|
{
|
if (argc > 1) hex_file = argv[1];
|
uint32_t bits = 4;
|
if (argc > 2) vhdl_file = argv[2];
|
const char * prog = *argv++; --argc;
|
|
|
|
if (argc && !strcmp(*argv, "-1")) { bits = 1; ++argv; --argc; }
|
|
else if (argc && !strcmp(*argv, "-2")) { bits = 2; ++argv; --argc; }
|
|
else if (argc && !strcmp(*argv, "-4")) { bits = 4; ++argv; --argc; }
|
|
else if (argc && !strcmp(*argv, "-8")) { bits = 8; ++argv; --argc; }
|
|
else if (argc && !strcmp(*argv, "-16")) { bits = 16; ++argv; --argc; }
|
|
|
|
const char * hex_file = 0;
|
|
const char * vhdl_file = 0;
|
|
|
|
if (argc) { hex_file = *argv++; --argc; }
|
|
if (argc) { vhdl_file = *argv++; --argc; }
|
|
assert(argc == 0);
|
|
|
FILE * in = stdin;
|
FILE * in = stdin;
|
if (hex_file) in = fopen(hex_file, "r");
|
if (hex_file) in = fopen(hex_file, "r");
|
assert(in);
|
assert(in);
|
read_file(in);
|
read_file(in);
|
fclose(in);
|
fclose(in);
|
|
|
FILE * out = stdout;
|
FILE * out = stdout;
|
if (vhdl_file) out = fopen(vhdl_file, "w");
|
if (vhdl_file) out = fopen(vhdl_file, "w");
|
write_file(out);
|
write_file(out, bits);
|
assert(out);
|
assert(out);
|
}
|
}
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
No newline at end of file
|
No newline at end of file
|