| 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
 |