ModelSim Memory Content import from Intel Hex

  • Follow


Hello,

I'm looking for an import utility from Intel Hex to the supported
formats of ModelSim,
e. g. MTI or Verilog (Hex).


Many thanks in advance
Udo

0
Reply WeikEngOff (37) 5/24/2007 4:33:29 PM

"Udo" <WeikEngOff@aol.com> wrote in message 
news:1180024409.822436.36850@h2g2000hsg.googlegroups.com...
> Hello,
>
> I'm looking for an import utility from Intel Hex to the supported
> formats of ModelSim,
> e. g. MTI or Verilog (Hex).

Well, here's a Systemverilog program to read HEX-80 format into a reg[]
array.  Are there different variations of the HEX format?  I wrote this
one for Keil's C51 (8051) compiler. You can modify it for your needs:

//
//
//         Author:                 R***** L***
//
//         Filename:               keil_hex2bin.sv
//
//         Date of Creation:       Sun May 20 12:14:48 2007
//
//         Version:                $Revision: 1.1 $
//
//         Date of Latest Version: $Date: 2007/05/20 12:14:48 $
//
//
//         Description: This is a utility to convert Keil-C51's HEX-80 
(*.hex)
//              output into a $readmemb compatible ASCII-file.
//              For HEX-80 info, see 
http://www.keil.com/support/docs/1584.htm
//

// requires Modelsim 6.1g or later (Systemverilog 3.1a)

///////////////////////////////////////////////////////////////////////////////
// 
//
//  This library is free software; you can redistribute it and/or 
//
//  modify it under the terms of the GNU Lesser General Public 
//
//  License as published by the Free Software Foundation; either 
//
//  version 2.1 of the License, or (at your option) any later version. 
//
// 
//
//  This library is distributed in the hope that it will be useful, 
//
//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
//
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
//
//  Lesser General Public License for more details. 
//
// 
//
//  Full details of the license can be found in the file LGPL.TXT. 
//
// 
//
//  You should have received a copy of the GNU Lesser General Public 
//
//  License along with this library; if not, write to the Free Software 
//
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
//
// 
//
///////////////////////////////////////////////////////////////////////////////

/*
  from http://www.keil.com/support/docs/1584.htm

:10246200464C5549442050524F46494C4500464C33
|||||||||||                              CC->Checksum
|||||||||DD->Data
|||||||TT->Record Type
|||AAAA->Address
|LL->Record Length
:->Colon

*/

`ifndef INFILENAME
  `define INFILENAME "keil.hex"
`endif

module keil_hex2bin();

parameter string infilename = `INFILENAME; // default input filename
localparam int BUFFER_SIZE = 65536; // # address-locations
localparam int LINE_SIZE = 500;    // max# bytes per textline

bit  [7:0] memory [0:BUFFER_SIZE-1];

typedef struct {
  bit flag_eof;   // end-of-file
  bit flag_colon; // TRUE==valid record, FALSE==no entry
  int length;  // # bytes in entry
  bit [15:0] address;
  bit [7:0] checksum;
  bit [7:0] record_type;
  bit [7:0] data [0:LINE_SIZE-1]; // data
} t_hex80entry;

int fh_in = 0;
int fh_bin_out = 0;
int fh_hex_out = 0; // FILE-pointers

///////////////////////////////////////////////////////////////////////////////

function void open_file( input string name );
  // make sure we aren't in the middle of processing another file
  assert ( fh_in == 0 ) else
    $fatal( 1, "%m(): a file is already open for reading!", name );

  fh_in = $fopen( name, "r" );
  assert ( fh_in != 0 )
    $info( "%m(): initiating read of '%0s'", name ); else
    $fatal( 1, "%m(): $fopen( \"%0s\", \"r\" ) failed!", name );
endfunction : open_file

///////////////////////////////////////////////////////////////////////////////

function void close_file( int fhandle );
  // make sure we aren't in the middle of processing another file
  assert ( fhandle != 0 )
    $info( "%m(): closing file-handle 'h%h", fhandle ); else
    $error( "%m(): no file was open for reading!" );

  $fclose( fhandle );
endfunction : close_file

///////////////////////////////////////////////////////////////////////////////

function t_hex80entry parse_line( input string line );
int error;
int data_byte_count;
bit [7:0] temp_byte, sum;
string phrase; // substring of line[]

  int length;  // # bytes in entry
  bit [15:0] address;
  bit [7:0] record_type;
  bit [7:0] checksum;

begin
  parse_line = '{default:'0};

  if ( line.len() < 10 )
    return parse_line;  // too short, can't possibly be a valid entry
  else if ( line[0] !== ":" )
    return parse_line;  // no starting colon
  else if ( line == ":00000001FF\n" )
    begin
      parse_line.flag_eof = 1'b1;  // got end of file!
      return parse_line;
    end

 /* get first few fields
 :LLAAAATT
 |||||||TT->Record Type
 |||AAAA->Address
 |LL->Record Length
 */

 // if we made it this far, entry appears to be valid!
 parse_line.flag_colon = 1'b1;

/*
 error = 0;
 phrase = line.substr( 1, 2 );
 error += $sscanf( phrase, "%02h", parse_line.length );

 phrase = line.substr( 3, 6 );
 error += $sscanf( phrase, "%04h", parse_line.address );

 phrase = line.substr( 7, 8 );
 error += $sscanf( phrase, "%02h", parse_line.record_type );
 */

 // Modelsim 6.1g workaround - $sscanf can't output to struct/union
  error = $sscanf( line, ":%02h%04h%02h", length,
          address, record_type );
   parse_line.length = length;
   parse_line.address = address;
   parse_line.record_type = record_type;

// error = $sscanf( line, ":%02h%04h%02h", parse_line.length,
//          parse_line.address, parse_line.record_type );

 assert ( error == 3 ) else begin
   $error("%m(): '%0s' (%0d)", line, error );
   parse_line.flag_colon = 1'b0;
 end

 // now get checksum (last 2 chars of line[])
 phrase = line.substr( line.len()-3, line.len()-2 );
// error = $sscanf( phrase, "%02h", parse_line.checksum );
 error = $sscanf( phrase, "%02h", checksum );
 parse_line.checksum = checksum;
 assert ( error == 1 ) else begin
   $error("%m(): checksum: '%0s' (%0d)", phrase, error );
   parse_line.flag_colon = 1'b0;
 end

 // now extract the data-payload

 error = 0;
 for ( int i = 0; i < data_byte_count; ++i ) begin
   phrase = line.substr( (i*2)+9, (i*2)+10 );
   error += $sscanf( phrase, "%02h", parse_line.data[i] );
 end
 assert ( error == data_byte_count ) else begin
   $error("%m(): DATA: '%0s' (%0d!=%0d)", phrase, error,
          data_byte_count );
   parse_line.flag_colon = 1'b0;
 end

 // finally, validate the checksum
 sum = 0;
 error = 0;
 for ( int i = 1; i < (line.len()-1); i=i+2 ) begin
   phrase = line.substr( i, i+1 );
   error += $sscanf( phrase, "%02h", temp_byte );
   sum += temp_byte;
 end

 assert ( sum == 0 ) else
   $error( "%m(): Checksum (%0d bytes) mismatch (%h!=%h)", error, sum,
            parse_line.checksum );

end
endfunction : parse_line

///////////////////////////////////////////////////////////////////////////////

task create_file( output int fhandle, input string filename );
  assert ( fhandle == 0 ) else begin
    $warning( "%m( '%0s' ): fhandle(0x%h) is already in use, overwriting!",
            filename, fhandle );
    $fclose( fhandle );
    end

  fhandle = $fopen( filename, "w" );
  assert ( fhandle != 0 )
    $info( "%m(): creating file '%0s'", filename ); else
    $fatal( 1, "%m(): could not create file '%0s'!", filename );
endtask : create_file

initial begin : main
  t_hex80entry h;
  int  n;
  string line;
  string outfilename_bin, outfilename_hex;
  // standalone mode

  // assume the last 5-letters of the filename are '.xyz'
  //   (If that's not the case, then we'll accidentally truncate the 
filename!)
  outfilename_bin = infilename.substr(0, infilename.len()-5) ;
  outfilename_hex = infilename.substr(0, infilename.len()-5) ;

  outfilename_bin = {outfilename_bin, ".dua"}; // $readmemb-compat output
  outfilename_hex = {outfilename_bin, ".dhx"}; // $readmemh-compat output

  open_file( infilename );

  n = $fgets( line, fh_in );
  while ( n > 0 ) begin
    h = parse_line( line );
    assert ( n < (LINE_SIZE*2) ) else
      $fatal( 1, "Line exceeded internal line-buffer size (%0d chars) !",
                 LINE_SIZE*2 );
    if ( h.flag_colon && (!h.flag_eof) )
      $display( "0x%h: %0d bytes, CHK=%h", h.address, h.length, 
h.checksum );
    n = $fgets( line, fh_in );

    // copy entry-data to internal-memory
    for ( int j = 0; j < h.length; ++j )
      memory[ h.address+j ] = h.data[j];
  end

  close_file( fh_in );

  // Create and dump the contents to $readmemb and readmemh files
  create_file( fh_bin_out, outfilename_bin );
  create_file( fh_hex_out, outfilename_hex );

  for ( int i = 0; i < BUFFER_SIZE; ++i ) begin
    $fdisplay( fh_bin_out, "%08b", memory[ i ] );
    $fdisplay( fh_hex_out, "%02h", memory[ i ] );
  end
  $fclose( fh_bin_out );
  $fclose( fh_hex_out );

  $finish;
end : main
endmodule : keil_hex2bin 


0
Reply Xilinx 5/26/2007 5:25:03 AM


1 Replies
319 Views

(page loaded in 0.699 seconds)

Similiar Articles:










7/23/2012 10:25:26 AM


Reply: