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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [tools/] [ihex2vlog/] [ihex2vlog.c] - Diff between revs 65 and 68

Only display areas with differences | Details | Blame | View Log

Rev 65 Rev 68
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//
//
// ihex2vlog.c by Moti Litochevski, Nov 12, 2011  
// ihex2vlog.c by Moti Litochevski, Nov 12, 2011  
// This program reads an Intel HEX file and generates memory Verilog module or 
// This program reads an Intel HEX file and generates memory Verilog module or 
// Xilinx RAMB16/RAMB4 verilog initialization vectors. 
// Xilinx RAMB16/RAMB4 verilog initialization vectors. 
//
//
// This program uses the ihex.c functions by Paul Stoffregen.
// This program uses the ihex.c functions by Paul Stoffregen.
//
//
// The project was compiled using the Tiny C Compiler using the following command line:
// The project was compiled using the Tiny C Compiler using the following command line:
//              tcc ihex2vlog.c ihex.c 
//              tcc ihex2vlog.c ihex.c 
//
//
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//
//
// This file is released to the public domain under the BSD 2-clause license.
// This file is released to the public domain under the BSD 2-clause license.
//
//
// Copyright (c) 2012, Moti Litochevski
// Copyright (c) 2012, Moti Litochevski
// All rights reserved.
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification, are 
// Redistribution and use in source and binary forms, with or without modification, are 
// permitted provided that the following conditions are met:
// permitted provided that the following conditions are met:
//   o Redistributions of source code must retain the above copyright notice, this list 
//   o Redistributions of source code must retain the above copyright notice, this list 
//     of conditions and the following disclaimer.
//     of conditions and the following disclaimer.
//   o Redistributions in binary form must reproduce the above copyright notice, this 
//   o Redistributions in binary form must reproduce the above copyright notice, this 
//     list of conditions and the following disclaimer in the documentation and/or 
//     list of conditions and the following disclaimer in the documentation and/or 
//     other materials provided with the distribution.
//     other materials provided with the distribution.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
// WHETHER IN 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.
//
//
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
 
 
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
 
 
// constants 
// constants 
#define MAX_BUF_SIZE            65536 
#define MAX_BUF_SIZE            65536 
 
 
/* this loads an intel hex file into the memory[] array */
/* this loads an intel hex file into the memory[] array */
int load_file(char *filename);
int load_file(char *filename);
 
 
// the loaded memory is stored in a global variable with maximum size of 64K bytes 
// the loaded memory is stored in a global variable with maximum size of 64K bytes 
int     memory[MAX_BUF_SIZE];
int     memory[MAX_BUF_SIZE];
 
 
// Xilinx RAMB16 default parameters 
// Xilinx RAMB16 default parameters 
// total size of RAM memory block in bytes 
// total size of RAM memory block in bytes 
#define RAM_BLOCK_SIZE          2048
#define RAM_BLOCK_SIZE          2048
// maxmimum number of memory blocks - each memory block contains RAM_BLOCK_SIZE bytes 
// maxmimum number of memory blocks - each memory block contains RAM_BLOCK_SIZE bytes 
#define RAM_BLOCKS                      8 
#define RAM_BLOCKS                      8 
// number of rows in RAM block initialization vectors 
// number of rows in RAM block initialization vectors 
#define RAM_ROWS                        64 
#define RAM_ROWS                        64 
// number of bytes per row in RAM block initialization vectors 
// number of bytes per row in RAM block initialization vectors 
#define RAM_BYTEPERROW          32 
#define RAM_BYTEPERROW          32 
// Xilinx RAMB4 parameters 
// Xilinx RAMB4 parameters 
#define RAMB4_BLOCK_SIZE        512
#define RAMB4_BLOCK_SIZE        512
#define RAMB4_BLOCKS            32 
#define RAMB4_BLOCKS            32 
#define RAMB4_ROWS                      16 
#define RAMB4_ROWS                      16 
#define RAMB4_BYTEPERROW        32 
#define RAMB4_BYTEPERROW        32 
 
 
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int main (int argc, char *argv[])
int main (int argc, char *argv[])
{
{
FILE *file;
FILE *file;
int index, hex_len, block_num, iblock, irow;
int index, hex_len, block_num, iblock, irow;
int address, value, argi;
int address, value, argi;
int block_size, blocks_num, raws_num, bytes_num;
int block_size, blocks_num, raws_num, bytes_num;
char *argstr, modname[24];
char *argstr, modname[24];
 
 
        // init block size to zero to sign generic Verilog code 
        // init block size to zero to sign generic Verilog code 
        block_size = 0;
        block_size = 0;
        // default address width 
        // default address width 
        raws_num = 16;
        raws_num = 16;
        bytes_num = 0;
        bytes_num = 0;
        // set default module name 
        // set default module name 
        strcpy(modname, "ram_image");
        strcpy(modname, "ram_image");
 
 
        // announce program start 
        // announce program start 
        printf("ihex2vlog conversion tool:\n");
        printf("ihex2vlog conversion tool:\n");
 
 
        // check program usage 
        // check program usage 
        if (argc < 3) {
        if (argc < 3) {
                printf("\n");
                printf("\n");
                printf("ERROR: incorrect usage of program.\n");
                printf("ERROR: incorrect usage of program.\n");
                printf("\n");
                printf("\n");
                printf("Usage: ihex2vlog [-a/s/m/4/16] <in.hex> <out.v>\n");
                printf("Usage: ihex2vlog [-a/s/m/4/16] <in.hex> <out.v>\n");
                printf("optional parameters:\n");
                printf("optional parameters:\n");
                printf("     -a<width>  generate initialization vectors for generic Verilog\n");
                printf("     -a<width>  generate initialization vectors for generic Verilog\n");
                printf("                code with specified address bus width. value should be\n");
                printf("                code with specified address bus width. value should be\n");
                printf("                in the range 8 to 16.\n");
                printf("                in the range 8 to 16.\n");
                printf("                this is the default option with width = 16\n");
                printf("                this is the default option with width = 16\n");
                printf("     -s<value>  set size of generic verilog memory size.\n");
                printf("     -s<value>  set size of generic verilog memory size.\n");
                printf("                value should be in the range 256 to 65536.\n");
                printf("                value should be in the range 256 to 65536.\n");
                printf("                default value is 2**<width> (address width defined above).\n");
                printf("                default value is 2**<width> (address width defined above).\n");
                printf("     -m<name>   set module name for generic verilog memory.\n");
                printf("     -m<name>   set module name for generic verilog memory.\n");
                printf("                default value is \"ram_image\".\n");
                printf("                default value is \"ram_image\".\n");
                printf("     -4         generate initialization vectors for Xilinx RAMB4.\n");
                printf("     -4         generate initialization vectors for Xilinx RAMB4.\n");
                printf("     -16        generate initialization vectors for Xilinx RAMB16.\n");
                printf("     -16        generate initialization vectors for Xilinx RAMB16.\n");
                printf("\n");
                printf("\n");
                printf("Example: ihex2vlog test.ihx ram_image.v\n");
                printf("Example: ihex2vlog test.ihx ram_image.v\n");
                return -1;
                return -1;
        }
        }
 
 
        // clear the memory array 
        // clear the memory array 
        for (index = 0; index < MAX_BUF_SIZE; index++) {
        for (index = 0; index < MAX_BUF_SIZE; index++) {
                memory[index] = 0;
                memory[index] = 0;
        }
        }
 
 
        // check optional options 
        // check optional options 
        argi = 1;
        argi = 1;
        argstr = argv[argi];
        argstr = argv[argi];
        while (argstr[0]=='-') {
        while (argstr[0]=='-') {
                // check Xilinx RAMB4 option 
                // check Xilinx RAMB4 option 
                if (argstr[1] == '4') {
                if (argstr[1] == '4') {
                        // init block definition values for Xilinx RAMB4 block size 
                        // init block definition values for Xilinx RAMB4 block size 
                        block_size = RAMB4_BLOCK_SIZE;
                        block_size = RAMB4_BLOCK_SIZE;
                        blocks_num = RAMB4_BLOCKS;
                        blocks_num = RAMB4_BLOCKS;
                        raws_num = RAMB4_ROWS;
                        raws_num = RAMB4_ROWS;
                        bytes_num = RAMB4_BYTEPERROW;
                        bytes_num = RAMB4_BYTEPERROW;
                }
                }
                else if ((argstr[1] == '1') & (argstr[2] == '6')) {
                else if ((argstr[1] == '1') & (argstr[2] == '6')) {
                        // init block definition values for Xilinx RAMB16 block size 
                        // init block definition values for Xilinx RAMB16 block size 
                        block_size = RAM_BLOCK_SIZE;
                        block_size = RAM_BLOCK_SIZE;
                        blocks_num = RAM_BLOCKS;
                        blocks_num = RAM_BLOCKS;
                        raws_num = RAM_ROWS;
                        raws_num = RAM_ROWS;
                        bytes_num = RAM_BYTEPERROW;
                        bytes_num = RAM_BYTEPERROW;
                }
                }
                else if (argstr[1] == 'a') {
                else if (argstr[1] == 'a') {
                        // for generic infered RAM Verilog code this option specifies the 
                        // for generic infered RAM Verilog code this option specifies the 
                        // address bus width 
                        // address bus width 
                        sscanf(&argstr[2], "%d", &raws_num);
                        sscanf(&argstr[2], "%d", &raws_num);
                        if ((raws_num < 8) | (raws_num > 16)) {
                        if ((raws_num < 8) | (raws_num > 16)) {
                                printf("\nERROR: Address width value error (%d)\n\n", raws_num);
                                printf("\nERROR: Address width value error (%d)\n\n", raws_num);
                                return -1;
                                return -1;
                        }
                        }
                        //check if memory length should be calculated 
                        //check if memory length should be calculated 
                        if (bytes_num == 0) {
                        if (bytes_num == 0) {
                                // calculate the actual memory size 
                                // calculate the actual memory size 
                                bytes_num=1;
                                bytes_num=1;
                                for (index=0; index<raws_num; index++)
                                for (index=0; index<raws_num; index++)
                                        bytes_num=bytes_num*2;
                                        bytes_num=bytes_num*2;
                        }
                        }
                }
                }
                else if (argstr[1] == 's') {
                else if (argstr[1] == 's') {
                        // set memory size option 
                        // set memory size option 
                        sscanf(&argstr[2], "%d", &bytes_num);
                        sscanf(&argstr[2], "%d", &bytes_num);
                        if ((bytes_num < 256) | (bytes_num > MAX_BUF_SIZE)) {
                        if ((bytes_num < 256) | (bytes_num > MAX_BUF_SIZE)) {
                                printf("\nERROR: Memory size value error (%d)\n\n", bytes_num);
                                printf("\nERROR: Memory size value error (%d)\n\n", bytes_num);
                                return -1;
                                return -1;
                        }
                        }
                }
                }
                else if (argstr[1] == 'm') {
                else if (argstr[1] == 'm') {
                        // set generic verilog memory module name 
                        // set generic verilog memory module name 
                        strcpy(modname, &argstr[2]);
                        strcpy(modname, &argstr[2]);
                }
                }
                else
                else
                        printf("\nERROR: Unsupported option \"%s\"\n\n", argstr);
                        printf("\nERROR: Unsupported option \"%s\"\n\n", argstr);
                // update parameter index 
                // update parameter index 
                argi++;
                argi++;
                argstr = argv[argi];
                argstr = argv[argi];
        }
        }
 
 
        // read input hex file into the memory array 
        // read input hex file into the memory array 
        hex_len = load_file(argv[argi]);
        hex_len = load_file(argv[argi]);
        printf("HEX memory top address %d\n", hex_len);
        printf("HEX memory top address %d\n", hex_len);
        // check if file loaded OK 
        // check if file loaded OK 
        if (hex_len < 1) {
        if (hex_len < 1) {
                printf("ERROR: Can't read '%s'!\n", argv[argi]);
                printf("ERROR: Can't read '%s'!\n", argv[argi]);
                return -1;
                return -1;
        }
        }
 
 
        // announce output file name 
        // announce output file name 
        printf("Writing output file to: %s\n", argv[argi+1]);
        printf("Writing output file to: %s\n", argv[argi+1]);
        // open output file 
        // open output file 
        file = fopen(argv[argi+1], "wt");
        file = fopen(argv[argi+1], "wt");
        if (file == NULL) {
        if (file == NULL) {
                printf("ERROR: Can't write '%s'!\n", argv[argi+1]);
                printf("ERROR: Can't write '%s'!\n", argv[argi+1]);
                return -1;
                return -1;
        }
        }
 
 
        // check if Xilinx RAMB memory is used or generic verilog RAM 
        // check if Xilinx RAMB memory is used or generic verilog RAM 
        if (block_size) {
        if (block_size) {
                // calculate the number of required RAM blocks 
                // calculate the number of required RAM blocks 
                block_num = hex_len / block_size;
                block_num = hex_len / block_size;
                printf("HEX file requires %d RAM blocks\n", block_num+1);
                printf("HEX file requires %d RAM blocks\n", block_num+1);
 
 
                // write file header 
                // write file header 
                fprintf(file, "// RAM image for input code file: %s\n", argv[argi]);
                fprintf(file, "// RAM image for input code file: %s\n", argv[argi]);
                // write memory block defines to enable only required memory blocks 
                // write memory block defines to enable only required memory blocks 
                fprintf(file, "// enable memory blocks \n");
                fprintf(file, "// enable memory blocks \n");
                fprintf(file, "`ifdef EN_ALL_BLOCKS\n");
                fprintf(file, "`ifdef EN_ALL_BLOCKS\n");
                for (iblock = 0; iblock < blocks_num; iblock++) {
                for (iblock = 0; iblock < blocks_num; iblock++) {
                        fprintf(file, "`define EN_BLOCK%d     1 \n", iblock);
                        fprintf(file, "`define EN_BLOCK%d     1 \n", iblock);
                }
                }
                fprintf(file, "`else\n");
                fprintf(file, "`else\n");
                // write the memory block enable flags 
                // write the memory block enable flags 
                for (iblock = 0; iblock < block_num+1; iblock++) {
                for (iblock = 0; iblock < block_num+1; iblock++) {
                        fprintf(file, "`define EN_BLOCK%d     1 \n", iblock);
                        fprintf(file, "`define EN_BLOCK%d     1 \n", iblock);
                }
                }
                fprintf(file, "`endif\n");
                fprintf(file, "`endif\n");
                fprintf(file, "\n");
                fprintf(file, "\n");
 
 
                // write memory blocks 
                // write memory blocks 
                for (iblock = 0; iblock <= block_num; iblock++) {
                for (iblock = 0; iblock <= block_num; iblock++) {
                        // write memory block header 
                        // write memory block header 
                        fprintf(file, "// block %d \n", iblock);
                        fprintf(file, "// block %d \n", iblock);
 
 
                        // loop though block rows 
                        // loop though block rows 
                        for (irow = 0; irow < raws_num; irow++) {
                        for (irow = 0; irow < raws_num; irow++) {
                                // write start of line 
                                // write start of line 
                                fprintf(file, "defparam mem%d.INIT_%X%X = 256'h", iblock, irow/16, irow & 0xf);
                                fprintf(file, "defparam mem%d.INIT_%X%X = 256'h", iblock, irow/16, irow & 0xf);
 
 
                                // write memory bytes 
                                // write memory bytes 
                                for (index = 0; index < bytes_num; index++) {
                                for (index = 0; index < bytes_num; index++) {
                                        address = iblock*block_size + irow*bytes_num + bytes_num - index - 1;
                                        address = iblock*block_size + irow*bytes_num + bytes_num - index - 1;
 
 
                                        if (address < hex_len)
                                        if (address < hex_len)
                                                value = memory[address] & 0xff;
                                                value = memory[address] & 0xff;
                                        else
                                        else
                                                value = 0;
                                                value = 0;
 
 
                                        fprintf(file, "%x%x", value/16, value & 0xf);
                                        fprintf(file, "%x%x", value/16, value & 0xf);
                                }
                                }
                                fprintf(file, ";\n");
                                fprintf(file, ";\n");
                        }
                        }
                }
                }
        }
        }
        else {
        else {
                // generate generic Verilog RAM code 
                // generate generic Verilog RAM code 
                printf("Generate generic Verilog RAM code.\n");
                printf("Generate generic Verilog RAM code.\n");
 
 
                // write output file header 
                // write output file header 
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//\n");
                fprintf(file, "//\n");
                fprintf(file, "// RAM image for input code file: %s\n", argv[argi]);
                fprintf(file, "// RAM image for input code file: %s\n", argv[argi]);
                fprintf(file, "//\n");
                fprintf(file, "//\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "module %s\n", modname);
                fprintf(file, "module %s\n", modname);
                fprintf(file, "(\n");
                fprintf(file, "(\n");
                fprintf(file, " clk, addr, \n");
                fprintf(file, " clk, addr, \n");
                fprintf(file, " we, din, dout\n");
                fprintf(file, " we, din, dout\n");
                fprintf(file, ");\n");
                fprintf(file, ");\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "input           clk;\n");
                fprintf(file, "input           clk;\n");
                fprintf(file, "input   [%d:0]  addr;\n", raws_num-1);
                fprintf(file, "input   [%d:0]  addr;\n", raws_num-1);
                fprintf(file, "input           we;\n");
                fprintf(file, "input           we;\n");
                fprintf(file, "input   [7:0]   din;\n");
                fprintf(file, "input   [7:0]   din;\n");
                fprintf(file, "output  [7:0]   dout;\n");
                fprintf(file, "output  [7:0]   dout;\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "reg [7:0] dout;\n");
                fprintf(file, "reg [7:0] dout;\n");
                fprintf(file, "reg [7:0] ram [%d:0];\n", bytes_num-1);
                fprintf(file, "reg [7:0] ram [%d:0];\n", bytes_num-1);
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "initial \n");
                fprintf(file, "initial \n");
                fprintf(file, "begin\n");
                fprintf(file, "begin\n");
                // dump memory values as RAM init values 
                // dump memory values as RAM init values 
                for (index=0; index<bytes_num; index++) {
                for (index=0; index<bytes_num; index++) {
                        if ((index&3) == 0) fprintf(file, "    ");
                        if ((index&3) == 0) fprintf(file, "    ");
                        fprintf(file, "ram[%d] = 8\'h%x%x; ", index, (memory[index]/16)&0xf, memory[index]&0xf);
                        fprintf(file, "ram[%d] = 8\'h%x%x; ", index, (memory[index]/16)&0xf, memory[index]&0xf);
                        if ((index&3) == 3) fprintf(file, "\n");
                        if ((index&3) == 3) fprintf(file, "\n");
                }
                }
                fprintf(file, "end\n");
                fprintf(file, "end\n");
                fprintf(file, "\n");
                fprintf(file, "\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "always @(posedge clk)\n");
                fprintf(file, "always @(posedge clk)\n");
                fprintf(file, "begin\n");
                fprintf(file, "begin\n");
                fprintf(file, "    if (we)\n");
                fprintf(file, "    if (we)\n");
 
                fprintf(file, "    begin\n");
                fprintf(file, "        ram[addr] <= din;\n");
                fprintf(file, "        ram[addr] <= din;\n");
 
                fprintf(file, "        dout <= din;\n");
 
                fprintf(file, "    end\n");
 
                fprintf(file, "    else\n");
                fprintf(file, "    dout <= ram[addr];\n");
                fprintf(file, "    dout <= ram[addr];\n");
                fprintf(file, "end\n");
                fprintf(file, "end\n");
                fprintf(file, "\n");
                fprintf(file, "\n");
                fprintf(file, "endmodule\n");
                fprintf(file, "endmodule\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
                fprintf(file, "//-----------------------------------------------------------------------------\n");
        }
        }
 
 
        // close output file 
        // close output file 
        fclose(file);
        fclose(file);
        return 0;
        return 0;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
 
 

powered by: WebSVN 2.1.0

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