URL
https://opencores.org/ocsvn/ion/ion/trunk
Subversion Repositories ion
Compare Revisions
- This comparison shows the changes necessary to convert path
/ion
- from Rev 219 to Rev 220
- ↔ Reverse comparison
Rev 219 → Rev 220
/trunk/tools/build_pkg/build_pkg.py
0,0 → 1,341
""" |
build_pkg.py -- builds simulation and synthesis configuration package. |
|
The generated package contains configuration constants used by the |
simulation test bench 'mips_tb.vhdl' and by the hardware demo |
'c2sb_demo.vhdl'. |
|
It too includes memory initialization constants containing object code, |
used to initialize simulated and inferred memories, both in simulation |
and in synthesis. |
|
In the code samples, this script is used to generate two separate packages |
for simulation and synthesis. Please refer to the makefiles for detailed |
usage examples. |
""" |
|
import sys |
import os |
import getopt |
|
|
|
def usage(): |
"""Print usage instructions""" |
print "" |
print "usage:" |
print "python build_pkg.py [arguments]\n" |
print "Builds VHDL package from template and binary object files.\n" |
print "The following arguments can be given, in any order:" |
print "" |
print "{b|bin} <filename> Object code file name (Plain binary)" |
print "{n|name} <name> Name of object code constant" |
print "{p|package} <name> Name of target VHDL package" |
print "{project} <name> Name of project (used only in comment)" |
print "{o|output} <filename> Target VHDL file name" |
print "{v|vhdl} <filename> VHDL template" |
print " (defaults to templates/obj_code_kg_template.vhdl)" |
print "{i|indent} <number> Indentation in VHDL tables (decimal)" |
print " (defaults to 4)" |
print "{o|output} <filename> Target VHDL file name" |
print "{t|templates} <path> Path of VHDL template directory" |
print " (defaults to '../templates')" |
print "" |
print "The following optional parameters will define a constant in the VHDL" |
print "package if they are used (simulation configuration):" |
print "" |
print "{s|sim_length} <value> Value of SIMULATION_LENGTH constant." |
print "{log_trigger} <value> Value of LOG_TRIGGER_ADDRESS constant." |
print "{xram_size} <value> Value of SRAM_SIZE constant." |
print "{flash_size} <value> Value of PROM_SIZE constant." |
print "{xram_size} <value> Value of SRAM_SIZE constant." |
print "" |
print "The following optional parameters will define a constant in the VHDL" |
print "package if they are used (simulation and synthesis configuration):" |
print "" |
print "{bram_size} <value> Value of BRAM_SIZE constant." |
|
|
def help(): |
"""Print help message a bit longer than the usage message.""" |
print "\nPurpose:\n" |
print "Builds a VHDL package with configuration constants used in the " |
print "simulation test bench and in the synthesis of the SoC entity." |
print "" |
print "The package file is built from a template (presumably the template" |
print "included with this tool)." |
print "" |
print "See the makefiles of the code samples for usage examples." |
|
|
def parse_hex_line(line): |
"""Parse code line in HEX object file.""" |
line = line.strip() |
slen = int(line[1:3],16) |
sloc = int(line[3:7],16) |
stype = line[7:9] |
sdata = line[9:len(line)-2] |
schk = int(line[len(line)-2:],16) |
|
csum = slen + int(sloc / 256) + (sloc % 256) + int(stype,16) |
bytes = [0, ] * slen |
for i in range(slen): |
sbyte = int(sdata[i*2:i*2+2],16) |
bytes[i] = sbyte; |
csum = csum + sbyte |
|
csum = ~csum |
csum = csum + 1 |
csum = csum % 256 |
if csum != schk: |
return (None, None) |
|
return (sloc, bytes) |
|
|
|
def read_bin_file(bin_filename): |
""" |
Read binary file into a byte array. |
Returns (code, size, bottom, top), where: |
|
code = array of bytes in file order (endianess irrelevant). |
size = number of bytes read from file. |
bottom = always zero. |
top = size - 1 |
""" |
objcode = [0, ] * 128*1024 # FIXME arbitrary limit should be removed |
bottom = 0 |
top = -1 |
#(objcode, top, bottom) |
|
# Read binary file |
f = open(bin_filename, "rb") |
try: |
size = os.path.getsize(bin_filename) |
objcode = [0, ] * size |
i = 0 |
byte = f.read(1) |
while byte != "": |
objcode[i] = ord(byte) |
# Do stuff with byte. |
byte = f.read(1) |
i = i + 1 |
finally: |
f.close() |
|
top = i-1 |
total_bytes = i |
print "Read %d bytes from file '%s'" % (total_bytes, bin_filename) |
return (objcode, total_bytes, bottom, top) |
|
|
def defined(pkg, val): |
|
return pkg.has_key(val) and pkg[val] |
|
|
|
def build_vhdl_code(template_filename, blocks, package_params): |
|
fin = open(template_filename, "r") |
lines = fin.readlines() |
fin.close() |
|
vhdl_code = "" |
|
for line in lines: |
line = line.strip() |
|
while(True): |
if line.rfind("@obj_tables@") >= 0: |
obj_str = ""; |
for block in blocks: |
block_size = block['top'] |
block_data = block['data'] |
if not block.has_key('constant_name'): |
print "Missing initialization constant name" |
sys.exit(2) |
block_name = block['constant_name'] |
block_top = block['top'] |
|
if block_top <= 0: |
# If the array is empty, we need to use special syntax |
obj_str = obj_str + \ |
("constant %s : t_obj_code(0 to 0) := " + \ |
"(others => X\"00\");\n") % block_name |
else: |
# Array contains binary data from file: write it |
obj_str = obj_str + \ |
"constant %s : t_obj_code(0 to %d) := (\n" % \ |
(block_name, block_top-1) |
obj_str = obj_str + " "*package_params['indent'] |
for i in range(block_size): |
if i != (block_size-1): |
sbyte = "X\"%02x\", " % block_data[i] |
else: |
sbyte = "X\"%02x\" " % block_data[i] |
obj_str = obj_str + sbyte |
if (i % 8) == 7: |
obj_str = obj_str + "\n" + " "*package_params['indent'] |
obj_str = obj_str + ");\n\n" |
|
line = line.replace("@obj_tables@",obj_str) |
elif line.rfind("@constants@") >= 0: |
str = "" |
|
if defined(package_params, 'sim_length'): |
str = str + \ |
"constant SIMULATION_LENGTH : integer := %d;\n" % \ |
int(package_params['sim_length']) |
if defined(package_params,'trigger_address'): |
str = str + \ |
"constant LOG_TRIGGER_ADDRESS : t_word := X\"%08x\";\n" % \ |
int(package_params['trigger_address'],16) |
if defined(package_params,'xram_size'): |
str = str + \ |
"constant SRAM_SIZE : integer := %d;\n" % \ |
int(package_params['xram_size']) |
if defined(package_params,'flash_size'): |
str = str + \ |
"constant PROM_SIZE : integer := %d;\n" % \ |
int(package_params['flash_size']) |
if defined(package_params,'boot_bram_size'): |
str = str + \ |
"constant BRAM_SIZE : integer := %d;\n" % \ |
int(package_params['boot_bram_size']) |
|
line = line.replace("@constants@", str) |
elif line.rfind("@project_name@") >= 0: |
line = line.replace("@project_name@",package_params['proj_name']) |
elif line.rfind("@obj_pkg_name@") >= 0: |
line = line.replace("@obj_pkg_name@",package_params['package_name']) |
else: |
break |
|
vhdl_code = vhdl_code + line + "\n" |
|
return vhdl_code |
|
|
def main(argv): |
|
try: |
opts, _ = getopt.getopt(argv, "hp:c:o:i:v:b:t:n:s:", |
["help", "package=", "constant=", |
"output=", "indent=", "vhdl=", "bin=", "templates=", |
"name=", "sim_length=", |
# parameters with no short-form |
"project=", "log_trigger=", "xram_size=", "flash_size=", |
"bram_size=", |
"empty"]) |
except getopt.GetoptError, err: |
print "" |
print err |
usage() |
sys.exit(2) |
|
# Set default values for all command line parameters |
template_dir_name = "../templates" |
vhdl_filename = "obj_code_pkg_template.vhdl" |
target_filename = None |
|
package_params = { |
'bram_size': 1024, |
'xram_size': 0, |
'flash_size': 0, |
'trigger_address': None, |
'indent': 2, |
'project_name': "<anonymous>", |
'package_name': "obj_code_pkg" |
} |
|
block_params = {} |
blocks = [] |
|
|
# Parse command line parameters |
for opt, arg in opts: |
# Options that affect the whole file |
if opt in ("-h", "--help"): |
usage() |
help() |
exit(1) |
if opt in ("-v", "--vhdl"): |
vhdl_filename = arg |
elif opt in ("-t", "--templates"): |
template_dir_name = arg |
elif opt in ("-i", "--indent"): |
package_params['indent'] = int(arg) |
elif opt in ("-o", "--output"): |
target_filename = arg |
elif opt in ("-p", "--package"): |
package_params['package_name'] = arg |
elif opt in ("--project"): |
package_params['proj_name'] = arg |
elif opt in ("--log_trigger"): |
package_params['trigger_address'] = arg |
elif opt in ("-s", "--sim_length"): |
package_params['sim_length'] = arg |
elif opt in ("--xram_size"): |
package_params['xram_size'] = arg |
elif opt in ("--flash_size"): |
package_params['flash_size'] = arg |
elif opt in ("--bram_size"): |
package_params['boot_bram_size'] = arg |
# Options for one initialization block |
elif opt in ("-n", "--name"): |
if block_params.has_key('constant_name'): |
blocks.append(block_params) |
block_params = {} |
block_params['constant_name'] = arg |
elif opt in ("-b", "--bin"): |
if block_params.has_key('bin_filename'): |
blocks.append(block_params) |
block_params = {} |
block_params['bin_filename'] = arg |
|
if len(block_params.keys())>0: |
blocks.append(block_params) |
|
# Make sure we have a target file name |
if not target_filename: |
print "Target file not specified -- use -o" |
sys.exit(1) |
|
# Read all the binary data blocks |
for block in blocks: |
if block.has_key('bin_filename'): |
if block['bin_filename']: |
(xcode, _, _, top) = read_bin_file(block['bin_filename']); |
block['data'] = xcode |
block['top'] = top |
else: |
# Named block is empty |
block['data'] = [] |
block['top'] = 0 |
|
# Compose template file name |
template_filename = template_dir_name + "/" + vhdl_filename |
|
# Ready to go: build the package file contents |
vhdl_code = build_vhdl_code(template_filename, blocks, package_params); |
|
# Finally, write the package text to the target file |
fout = None |
try: |
fout = open(target_filename, "w") |
fout.write(vhdl_code) |
fout.close() |
print "VHDL code written to %s" % target_filename |
except: |
print "Trouble opening %s for output" % target_filename |
finally: |
if fout: fout.close() |
|
|
if __name__ == "__main__": |
main(sys.argv[1:]) |
|
sys.exit(0) |
|
/trunk/tools/build_pkg/templates/obj_code_pkg_template.vhdl
0,0 → 1,60
-------------------------------------------------------------------------------- |
-- obj_code_pkg.vhdl -- Application object code in vhdl constant string format. |
-------------------------------------------------------------------------------- |
-- Built for project '@project_name@'. |
-------------------------------------------------------------------------------- |
-- This file contains object code in the form of a VHDL byte table constant. |
-- This constant can be used to initialize FPGA memories for synthesis or |
-- simulation. |
-- Note that the object code is stored as a plain byte table in byte address |
-- order. This table knows nothing of data endianess and can be used to |
-- initialize 32-, 16- or 8-bit-wide memory -- memory initialization functions |
-- can be found in package mips_pkg. |
-------------------------------------------------------------------------------- |
-- Copyright (C) 2012 Jose A. Ruiz |
-- |
-- This source file may be used and distributed without |
-- restriction provided that this copyright statement is not |
-- removed from the file and that any derivative work contains |
-- the original copyright notice and the associated disclaimer. |
-- |
-- This source file 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 source 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. |
-- |
-- You should have received a copy of the GNU Lesser General |
-- Public License along with this source; if not, download it |
-- from http://www.opencores.org/lgpl.shtml |
-------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.mips_pkg.all; |
|
package @obj_pkg_name@ is |
|
-- Hardcoded simulation parameters --------------------------------------------- |
|
-- Simulation clock rate |
constant CLOCK_RATE : integer := 50e6; |
-- Simulation clock period |
constant T : time := (1.0e9/real(CLOCK_RATE)) * 1 ns; |
|
-- Other simulation parameters ------------------------------------------------- |
|
@constants@ |
|
-- Memory initialization data -------------------------------------------------- |
|
@obj_tables@ |
|
end package @obj_pkg_name@; |