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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [tools/] [hexconv/] [hexconv.pl] - Blame information for rev 73

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 73 ja_rd
################################################################################
2
# hexconv.pl -- inserts object code in HEX format into an VHDL template.
3
#
4
# This program reads an Intel HEX file with 8-bit object code and inserts it 
5
# into a VHDL template, in the form of a VHDL std_logic_vector array 
6
# initializer. This is meant to initialize FPGA ROM/RAM blocks with object code.
7
# When the program finds a template line which begins with "--@rom_data", it 
8
# replaces the whole line with the VHDL table. 
9
# When it finds the text @PROGNAME@ in a line, it replaces that text with the
10
# file name (without path or extension) of the hex file.
11
# Otherwise, it just copies the template to stdout verbatim.
12
#
13
# See usage details below, and examples in the BAT file in the asm directory.
14
################################################################################
15
 
16
$usage = "Use: hexconv.pl <hexfile> <template file> <start addr> <table size>";
17
 
18
# read command line arguments; HEX file name...
19
$file = shift(@ARGV);
20
if($file eq ''){die $usage};
21
# ...VHDL template file name...
22
$template = shift(@ARGV);
23
if($template eq ''){die $usage};
24
# ...object code start address...
25
$start_addr = shift(@ARGV);
26
if($start_addr eq ''){die $usage};
27
$start_addr = hex $start_addr;
28
# ...and VHDL table size
29
$table_size = shift(@ARGV);
30
if($table_size eq ''){die $usage};
31
$table_size = hex $table_size;
32
 
33
# read HEX file...
34
open(INFO, $file) or die "file $file not found";
35
@lines = <INFO>;
36
close(INFO);
37
 
38
# ...and VHDL template
39
open(INFO, $template) or die "file $template not found";
40
@vhdl_lines = <INFO>;
41
close(INFO);
42
 
43
$min_address = 65536;
44
$max_address = 0;
45
$bytes_read = 0;
46
 
47
# make up a 'ram image' table of 64K bytes where the object code will be put.
48
@data_array = ();
49
for($i=0;$i<65536;$i++){ $data_array[$i] = 0; };
50
 
51
# read input HEX file into ram image table
52
$line_no = 0;
53
foreach $line (@lines){
54
 
55
  chomp($line);
56
  $line_no++;
57
 
58
  if(length($line)>=11 and substr($line, 0, 1) eq ':'){
59
    $total_length = length($line);
60
    $len =  substr($line, 1,2);
61
    $addr = substr($line, 3,4);
62
    $type = substr($line, 7,2);
63
    $csum = substr($line, $total_length-3,2);
64
    $data = substr($line, 9,$total_length-11);
65
 
66
    # Process data records and utterly ignore all others.
67
    # Note that the checksum field is ignored too; we rely on the correctness
68
    # of the hex file.
69
    if($type eq '00'){
70
      $len = hex $len;
71
      $first_addr = hex $addr;
72
      $last_addr = $first_addr + $len - 1;
73
 
74
      if($first_addr < $min_address){
75
        $min_address = $first_addr;
76
      };
77
      if($last_addr > $max_address){
78
        $max_address = $last_addr;
79
      };
80
 
81
      $chksum = 0;
82
      for($i=0;$i<$len;$i++){
83
        $data_byte = substr($line, 9+$i*2, 2);
84
        $data_byte = hex $data_byte;
85
        $chksum += $data_byte;
86
        $data_array[$first_addr+$i] = $data_byte;
87
        $bytes_read++;
88
      }
89
    }
90
  }
91
  else{
92
    die "Wrong format in line $line_no\n";
93
  }
94
}
95
 
96
# Make sure all the object code we read from the hex file will fit in the VHDL
97
# memory; this is a typo-catcher.
98
 
99
if($min_address < $start_addr or $max_address < $start_addr){
100
  die "Hex data out of bounds";
101
}
102
 
103
$upper_bound = $start_addr + $table_size;
104
 
105
if($min_address > $upper_bound or
106
        $max_address > $upper_bound){
107
  die "Hex data out of bounds: ".$upper_bound;
108
}
109
 
110
# debug output
111
#printf "Data address span [%04x : %04x]\n", $min_address, $max_address;
112
#$bytes_defaulted = ($max_address-$min_address+1)-$bytes_read;
113
#if($bytes_defaulted > 0){
114
#  printf "(%d bytes defaulted to 0)\n", $bytes_defaulted;
115
#}
116
 
117
#### Now process the template inserting the ROM bytes where necessary
118
 
119
# display only the template filename, cut away any path that may be present
120
if($template =~ /^.*[\\\/](.*\..*)/){ $template = $1; }
121
# put a reminder in the 1st lines of the VHDL output
122
$comm = "--------------------";
123
print $comm.$comm.$comm.$comm."\n";
124
print "-- Generated from template $template by hexconv.pl\n";
125
 
126
# Extract program name from the hex file name, stripping path and extension
127
if($file =~ /^.*[\\\/](.*)\..*/){
128
  $file = $1;
129
}
130
elsif($file =~ /^(.*)\..*/){
131
  $file = $1;
132
}
133
 
134
# Output template file contents to stdout, line by line, inserting the object
135
# code when we find the 'data tag' "@rom_data".
136
foreach $vhdl (@vhdl_lines){
137
  if($vhdl =~ /^\s*--\@rom_data/){
138
    # if we find the ROM data tag in a comment line, replace line
139
    # with VHDL table.
140
    print_rom_code($start_addr, $table_size, @data_array);
141
  }
142
  else{
143
    # otherwise, output template line
144
    $vhdl =~ s/\@PROGNAME\@/$file/;
145
    printf $vhdl;
146
  };
147
}
148
 
149
# Prints a chunk of bytes as a VHDL table of std_logic_vectors, formatted as 
150
# 8 bytes per column.
151
#
152
# print_rom_code ($obj_code_table, $obj_code_start, $obj_code_size)
153
# $obj_code_start : address of the 1st byte that we want to put in the VHDL RAM.
154
# $obj_code_size : number of bytes to put in the VHDL memory.
155
# @obj_code_table : image of the CPU 64K memory map with the object code in it.
156
sub print_rom_code {
157
  my($obj_code_start, $obj_code_size, @obj_code_table) = @_;
158
  $col = 0;
159
  for($i=0;$i<$obj_code_size;$i++){
160
    $q = $obj_code_table[$obj_code_start+$i];
161
    print $q
162
    printf "X\"%02x\"", $q;
163
    if($i<$obj_code_size-1){
164
      printf ",";
165
    }
166
    $col++;
167
    if($col eq 8){
168
      print "\n";
169
      $col = 0;
170
    }
171
  }
172
}

powered by: WebSVN 2.1.0

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