Commit aa701a7a authored by Pawel Szostek's avatar Pawel Szostek

Ported to OOP

parent 3943b299
......@@ -6,7 +6,7 @@ import string
import global_mod
import msg as p
std_libs = ['ieee', 'altera_mf', 'cycloneiii', 'lpm', 'std', 'unisim']
def try_utf8(data):
try:
......@@ -84,101 +84,26 @@ def generate_deps_for_sv_files(files):
file_files_dict[file] = search_for_sv_include(file)
return file_files_dict
def generate_deps_for_vhdl_in_modules(module_manifest_dict):
from path import search_for_manifest
from mnfst import parse_manifest
opt_map_dict = {}
for module in list(module_manifest_dict.keys()):
if module_manifest_dict[module] != None:
opt_map_dict[module] = parse_manifest(module_manifest_dict[module])
module_files_dict = {}
from path import make_list_of_files
module_files_dict = {}
for module in list(module_manifest_dict.keys()):
manifest = module_manifest_dict[module]
module_files_dict.update(make_list_of_files(dict([(module,manifest)]), file_type="vhd"))
p.vpprint(module_files_dict)
all_files = []
file_lib_dict = {}
for module in module_files_dict:
for file in module_files_dict[module]:
if module in opt_map_dict:
file_lib_dict[os.path.abspath(file)] = opt_map_dict[module].library
else:
file_lib_dict[os.path.abspath(file)] = "work"
all_files.append(os.path.abspath(file))
all_files = list(set(all_files))
all_vhdl_files = [x for x in all_files if os.path.splitext(x)[1] == '.vhd']
p.vpprint(all_vhdl_files)
file_use_clause_dict = {}
for file in all_vhdl_files:
file_use_clause_dict[file] = search_for_use(file)
p.vpprint(file_use_clause_dict)
package_file_dict = {}
for file in all_vhdl_files:
packages = search_for_package(file) #look for package definitions
if len(packages) != 0: #if there are some packages in the file
for package in packages:
if package in package_file_dict:
p.echo("There might be a problem... Compilation unit " + package +
" has several instances:\n\t" + file + "\n\t" + package_file_dict[package])
package_file_dict[package.lower()] = [package_file_dict[package.lower()], file]#///////////////////////////////////////////////////
package_file_dict[package.lower()] = file #map found package to scanned file
file_basename = os.path.basename(file)
file_purename = os.path.splitext(file_basename)[0]
if file_purename in package_file_dict and package_file_dict[file_purename.lower()] != file:
p.echo("There might be a problem... Compilation unit " + file_purename +
" has several instances:\n\t" + file + "\n\t" + package_file_dict[file_purename])
package_file_dict[file_purename.lower()] = file
p.vpprint(package_file_dict)
p.vpprint(file_lib_dict)
file_file_dict = {}
for file in all_vhdl_files:
file_units_list = file_use_clause_dict[file]
for unit in file_units_list:
if unit[1].lower() in package_file_dict:
if unit[0].lower() == file_lib_dict[package_file_dict[unit[1].lower()]]:
if file in file_file_dict:
file_file_dict[file].append(package_file_dict[unit[1].lower()])
else:
file_file_dict[file] = [package_file_dict[unit[1].lower()]]
else:
p.echo("Cannot resolve dependency: " + file + " depends on "
+"compilation unit " + str(unit) + ", which cannot be found")
for file in all_vhdl_files:
if file not in file_file_dict:
file_file_dict[file] = []
p.vpprint(file_file_dict)
return file_file_dict, file_lib_dict
def modelsim_ini_path():
vsim_path = os.popen("which vsim").read().strip()
bin_path = os.path.dirname(vsim_path)
return os.path.abspath(bin_path+"/../")
def generate_list_makefile(file_deps_dict, file_lib_dict):
def generate_list_makefile(file_deps_dict, filename="Makefile.list"):
from time import gmtime, strftime
import path
date = strftime("%a, %d %b %Y %H:%M:%S", gmtime())
notices = """#######################################################################
# This makefile has been automatically generated by hdl-make
# for project """ + path.url_basename(global_mod.cwd) + """ on """ + date + """
# on """ + date + """
#######################################################################
"""
rp = os.path.relpath
f = open(global_mod.ise_list_makefile, "w")
f = open(filename, "w")
f.write(notices)
f.write("file: create_a_file\n")
f.write("create_a_file:\n\t\t@printf \"\" > " + global_mod.ise_list_file + "\n")
f.write("create_a_file:\n\t\t@printf \"\" > ise_list \n")
f.write("file: ")
for file in file_deps_dict:
f.write(rp(file)+"__print \\\n")
......@@ -187,17 +112,17 @@ def generate_list_makefile(file_deps_dict, file_lib_dict):
f.write(rp(file)+"__print: ")
f.write(' '.join( rp(x)+"__print" for x in file_deps_dict[file]))
f.write('\n')
f.write("\t\t@echo \'"+file_lib_dict[file]+';'+rp(file)+"\' >> "+global_mod.ise_list_file+"\n\n")
f.write("\t\t@echo \'"+file_lib_dict[file]+';'+rp(file)+"\' >> ise_list\n\n")
f.write("\t\t@echo Done.")
def generate_makefile(file_deps_dict, file_lib_dict):
def generate_makefile(file_deps_dict, filename="Makefile"):
from time import gmtime, strftime
import path
#from path import relpath as rp
date = strftime("%a, %d %b %Y %H:%M:%S", gmtime())
notices = """#######################################################################
# This makefile has been automatically generated by hdl-make
# for testbench """ + path.url_basename(global_mod.cwd) + """ on """ + date + """
# on """ + date + """
#######################################################################
"""
......@@ -230,17 +155,15 @@ clean:
"""
#open the file and write the above preambule (part 1)
f = open("Makefile", "w")
f = open(filename, "w")
f.write(notices)
f.write(make_preambule_p1)
libs = set(v for k,v in list(file_lib_dict.items()))
libs = set(file.library for file in list(file_deps_dict.keys()))
#list vhdl objects (_primary.dat files)
f.write("VHDL_OBJ := ")
for file in file_deps_dict:
basename = os.path.basename(file)
purename = os.path.splitext(basename)[0]
f.write(file_lib_dict[file]+'/'+purename+ "/."+purename+" \\\n")
f.write(file.library+'/'+file.purename+ "/."+file.purename+" \\\n")
f.write('\n')
f.write('LIBS := ')
......@@ -252,8 +175,8 @@ clean:
f.write('\n')
f.write(make_preambule_p2)
vlo = global_mod.opt_map.vlog_opt
vmo = global_mod.opt_map.vmap_opt
vlo = global_mod.top_module.vlog_opt
vmo = global_mod.top_module.vmap_opt
for lib in libs:
f.write(lib+"/."+lib+":\n")
f.write(' '.join(["\t(vlib", vlo, lib, "&&", "vmap", vmo, "-modelsimini modelsim.ini",
......@@ -264,21 +187,21 @@ clean:
#list rules for all _primary.dat files
rp = os.path.relpath
vco = global_mod.opt_map.vcom_opt
vco = global_mod.top_module.vcom_opt
for file in file_deps_dict:
lib = file_lib_dict[file]
basename = os.path.basename(file)
purename = os.path.splitext(basename)[0]
lib = file.library
basename = file.name
purename = file.purename
#each .dat depends on corresponding .vhd file
f.write(os.path.join(lib, purename, "."+purename) + ": "+rp(file)+'\n')
f.write(' '.join(["\t\tvcom $(VCOM_FLAGS)", vco, "-work", lib, rp(file),
f.write(os.path.join(lib, purename, "."+purename) + ": "+rp(file.path)+'\n')
f.write(' '.join(["\t\tvcom $(VCOM_FLAGS)", vco, "-work", lib, rp(file.path),
"&&", "mkdir -p", os.path.join(lib, purename), "&&", "touch", os.path.join(lib, purename, '.'+ purename), '\n']))
f.write('\n')
if len(file_deps_dict[file]) != 0:
f.write(os.path.join(lib, purename, "."+purename) +":")
for dep_file in file_deps_dict[file]:
short_dep_file = os.path.splitext(os.path.basename(dep_file))[0]
f.write(" \\\n"+ os.path.join(file_lib_dict[dep_file], short_dep_file, "."+short_dep_file))
name = dep_file.purename
f.write(" \\\n"+ os.path.join(dep_file.library, name, "."+name))
f.write('\n\n')
f.close()
\ No newline at end of file
......@@ -14,25 +14,10 @@ import string
import global_mod
import msg as p
import optparse
from fetch import fetch_from_svn, fetch_from_git, parse_repo_url
import mnfst
def inject_files_into_ise(ise_file, files_list):
ise = open(ise_file, "r")
ise_lines = ise.readlines()
file_template = ' '+ "<file xil_pn:name=\"{0}\" xil_pn:type=\"FILE_VHDL\"/>\n"
files_pattern = re.compile('[ \t]*<files>[ \t]*')
new_ise = []
for line in ise_lines:
new_ise.append(line)
if re.match(files_pattern, line) != None:
for file in files_list:
new_ise.append(file_template.format(os.path.relpath(file)))
new_ise_file = open(ise_file + ".new", "w")
new_ise_file.write(''.join(new_ise))
new_ise_file.close()
from module import Module
from helper_classes import Manifest, SourceFile
#from fetch import fetch_from_svn, fetch_from_git, parse_repo_url
#import mnfst
def check_address_length(module):
p = module.popen("uname -a")
......@@ -46,9 +31,8 @@ def check_address_length(module):
return 64
else:
return None
def main():
import depend
#import depend
global_mod.t0 = time.time()
parser = optparse.OptionParser()
parser.add_option("--manifest-help", action="store_true", dest="manifest_help",
......@@ -70,8 +54,16 @@ def main():
# check if manifest is given in the command line
# if yes, then use it
# if no, the look for it in the current directory (python manifest has priority)
file = None
if os.path.exists("manifest.py"):
global_mod.top_manifest = os.path.abspath("manifest.py")
file = "manfiest.py"
elif os.path.exitsts("Manifest.py"):
file = "Manifest.py"
if file != None:
top_manifest = Manifest(path=os.path.abspath(file))
global_mod.top_module = Module(manifest=top_manifest, source="local", fetchto=".")
global_mod.top_module.parse_manifest()
else:
p.echo("No manifest found. At least an empty one is needed")
quit()
......@@ -81,50 +73,64 @@ def main():
if global_mod.options.synth_user != None:
global_mod.synth_user = global_mod.options.synth_user
global_mod.opt_map = mnfst.parse_manifest(global_mod.top_manifest)
#if global_mod.options.tcl == None:
# if global_mod.opt_map.tcl == None: #option taken, but no tcl given -> find it
# tcl_pat = re.compile("^.*\.tcl$")
# for file in os.listdir("."): #try to find it in the current dir
# if re.match(tcl_pat, file):
# global_mod.opt_map.tcl = file
# break
#else:
# global_mod.opt_map.tcl = global_mod.options.tcl
if global_mod.opt_map.fetchto != None:
global_mod.fetchto = global_mod.opt_map.fetchto
else:
global_mod.fetchto = global_mod.hdlm_path
if global_mod.options.tcl == None:
if global_mod.opt_map.tcl == None: #option taken, but no tcl given -> find it
tcl_pat = re.compile("^.*\.tcl$")
for file in os.listdir("."): #try to find it in the current dir
if re.match(tcl_pat, file):
global_mod.opt_map.tcl = file
break
else:
global_mod.opt_map.tcl = global_mod.options.tcl
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.manifest_help == True:
parser = mnfst.init_manifest_parser()
parser.print_help()
ManifestParser().print_help()
elif global_mod.options.fetch == True:
fetch()
elif global_mod.options.local == True:
local_synthesis()
elif global_mod.options.remote == True:
remote_synthesis()
elif global_mod.options.make_list == True:
generate_list_makefile()
elif global_mod.options.make == True:
generate_makefile()
elif global_mod.options.inject == True:
inject_into_ise()
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.fetch == True:
modules = mnfst.fetch_manifest(global_mod.top_manifest, global_mod.opt_map)
def fetch():
modules = global_mod.top_module.fetch()
p.vprint("Involved modules:")
p.vpprint(modules)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.local == True:
if global_mod.opt_map.tcl == None:
complain_tcl()
p.vprint([str(m) for m in modules])
def inject_into_ise():
if global_mod.options.ise_project == None:
p.echo("You forgot to specify .xise file, didn't you?")
quit()
if not os.path.exists("/opt/Xilinx/" + global_mod.opt_map.ise):
p.echo("The script can't find demanded ISE version: " + global_mod.opt_map.ise)
if not os.path.exists(global_mod.options.ise_project):
p.echo("Given ise file doesn't exist")
quit()
address_length = check_address_length(os)
if address_length == 32 or address_length == None:
path_ext = global_mod.ise_path_32[global_mod.opt_map.ise]
else:
p.echo("Don't know how to run settings script for ISE version: " + global_mod.opt_map.ise)
results = os.popen("export PATH=$PATH:"+path_ext+" &&xtclsh " + global_mod.opt_map.tcl + " run_process")
p.echo(results.readlines())
quit()
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.remote == True:
import depend
module_manifest_dict = path.make_list_of_modules(global_mod.top_manifest, global_mod.opt_map)
p.vprint("Modules that will be taken into account in the makefile: ")
p.vpprint(modules)
module_files_dict = path.make_list_of_files(module_manifest_dict, file_type="vhd")
p.vprint("List of used files")
p.vpprint(module_files_dict)
inject_files_into_ise(global_mod.options.ise_project, files)
def generate_makefile():
import depend
tm = global_mod.top_module
deps = tm.generate_deps_for_vhdl_in_modules()
depend.generate_makefile(deps)
#NOT YET TRANSFORMED INTO CLASSES
def remote_synthesis():
if global_mod.opt_map.tcl == None: #option not taken but mandatory
p.echo("For Xilinx synthesis a .tcl file in the top module is required")
quit()
......@@ -182,47 +188,36 @@ def main():
if global_mod.options.no_del != True:
p.echo("Deleting synthesis folder")
global_mod.ssh.system('rm -rf ' + dest_folder)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.make_list == True:
import depend
modules = path.make_list_of_modules(global_mod.top_manifest, global_mod.opt_map)
p.vprint("Modules that will be taken into account in the makefile: " + str(modules))
deps, libs = depend.generate_deps_for_vhdl_in_modules(modules)
depend.generate_list_makefile(deps, libs)
os.system("make -f " + global_mod.ise_list_makefile)
os.remove(global_mod.ise_list_makefile)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.make == True:
import depend
module_manifest_dict = path.make_list_of_modules(global_mod.top_manifest, global_mod.opt_map)
p.vprint("Modules that will be taken into account in the makefile: ")
p.vpprint(module_manifest_dict)
deps, libs = depend.generate_deps_for_vhdl_in_modules(module_manifest_dict)
depend.generate_makefile(deps, libs)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if global_mod.options.inject == True:
if global_mod.options.ise_project == None:
p.echo("You forgot to specify .xise file, didn't you?")
def local_synthesis():
if global_mod.options.tcl == None:
p.echo("No .tcl file found. Exiting")
quit()
if not os.path.exists(global_mod.options.ise_project):
p.echo("Given ise file doesn't exist")
ise = global_mod.top_module.ise
tcl = global_mod.options.tcl
if not os.path.exists("/opt/Xilinx/" + ise):
p.echo("The script can't find demanded ISE version: " + ise)
quit()
import depend
module_manifest_dict = path.make_list_of_modules(global_mod.top_manifest, global_mod.opt_map)
p.vprint("Modules that will be taken into account in the makefile: ")
p.vpprint(modules)
module_files_dict = path.make_list_of_files(module_manifest_dict, file_type="vhd")
p.vprint("List of used files")
p.vpprint(module_files_dict)
inject_files_into_ise(global_mod.options.ise_project, files)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
address_length = check_address_length(os)
if address_length == 32 or address_length == None:
path_ext = global_mod.ise_path_32[ise]
else:
p.echo("Don't know how to run settings script for ISE version: " + ise)
results = os.popen("export PATH=$PATH:"+path_ext+" && xtclsh " + tcl + " run_process")
p.echo(results.readlines())
quit()
def generate_list_makefile():
import depend
tm = global_mod.top_module
modules = tm.make_list_of_modules()
p.vprint("Modules that will be taken into account in the makefile: " + str([str(i) for i in modules]))
deps = depend.generate_deps_for_vhdl_in_modules(modules)
depend.generate_list_makefile(deps)
os.system("make -f Makefile.list")
os.remove("Makefile.list")
if __name__ == "__main__":
#global options' map for use in the entire script
t0 = None
......
# -*- coding: utf-8 -*-
import path as path_mod
import msg as p
import os
import cfgparse2 as cfg
class Manifest:
def __init__(self, path = None, url = None):
if not isinstance(path, basestring):
raise ValueError("Path must be an instance of basestring")
if path == None and url == None:
raise ValueError("When creating a manifest a path or an URL must be given")
if path != None and url == None:
self.url = path
if path_mod.is_abs_path(path):
self.path = path
else:
raise ValueError("When creating a Manifest, path must be absolute path")
def __str__(self):
return self.url
def exists(self):
return os.path.exists(self.path)
class ManifestParser:
def __init__(self, manifest = None):
manifest_parser = cfg.ConfigParser(description="Configuration options description", allow_py = True)
manifest_parser.add_option('fetchto', default=None, help="Destination for fetched modules")
manifest_parser.add_option('root_module', default=None, help="Path to root module for currently parsed")
manifest_parser.add_option('name', default=None, help="Name of the folder at remote synthesis machine")
manifest_parser.add_option('tcl', default=None, help="Path to .tcl file used in synthesis")
manifest_parser.add_option('ise', default=None, help="Version of ISE to be used in synthesis")
manifest_parser.add_option('vsim_opt', default="", help="Additional options for vsim")
manifest_parser.add_option('vcom_opt', default="", help="Additional options for vcom")
manifest_parser.add_option('vlog_opt', default="", help="Additional options for vlog")
manifest_parser.add_option('vmap_opt', default="", help="Additional options for vmap")
manifest_parser.add_option('modules', dest="svn", keys="svn", default=list(),
help="List of modules to be fetched from SVN")
manifest_parser.add_option('modules', dest="git", keys="git", default=[],
help="List of modules to be fetched from git")
manifest_parser.add_option('modules', dest="local", keys="local", default=[],
help="List of local modules")
manifest_parser.add_option('library', dest="library", default="work",
help="Destination library for module's VHDL files")
manifest_parser.add_option('files', default=[], help="List of files from the current module")
self.parser = manifest_parser
def add_manifest(self, manifest):
self.parser.add_file(manifest.path)
def parse(self):
return self.parser.parse()
def print_help():
self.parser.print_help()
class SourceFile:
def __init__(self, path, type=None):
self.path = path
self.name = os.path.basename(self.path)
self.type = type
self.purename = os.path.splitext(self.name)[0]
def __str__(self):
return self.path
def write(self, lines):
file = open(os.path.join(self.path,self.name), "w")
file.write(''.join(new_ise))
file.close()
def extension(self):
tmp = self.path.rsplit('.')
ext = tmp[len(tmp)-1]
return ext
def search_for_use(self):
"""
Reads a file and looks for 'use' clause. For every 'use' with
non-standard library a tuple (lib, file) is returned in a list.
"""
import re
std_libs = ['ieee', 'altera_mf', 'cycloneiii', 'lpm', 'std', 'unisim']
f = open(self.path, "r")
try:
text = f.readlines()
except UnicodeDecodeError:
return []
use_pattern = re.compile("^[ \t]*use[ \t]+([^; ]+)[ \t]*;.*$")
lib_pattern = re.compile("([^.]+)\.([^.]+)\.all")
use_lines = []
for line in text:
m = re.match(use_pattern, line)
if m != None:
use_lines.append(m.group(1))
ret = []
for line in use_lines:
m = re.match(lib_pattern, line)
if m != None:
if (m.group(1)).lower() in std_libs:
continue
ret.append((m.group(1),m.group(2)))
f.close()
self.use = ret
def search_for_package(self):
"""
Reads a file and looks for package clase. Returns list of packages' names
from the file
"""
import re
f = open(self.path, "r")
try:
text = f.readlines()
except UnicodeDecodeError:
return []
package_pattern = re.compile("^[ \t]*package[ \t]+([^ \t]+)[ \t]+is[ \t]*$")
ret = []
for line in text:
m = re.match(package_pattern, line)
if m != None:
ret.append(m.group(1))
f.close()
self.package = ret
class IseProjectFile(SourceFile):
def __init__(self, path=None, type="ise"):
SourceFile.__init__(self, path=path, type=type)
def inject_file_list(self, files_list):
ise = open(self.path, "r")
ise_lines = ise.readlines()
file_template = ' '+ "<file xil_pn:name=\"{0}\" xil_pn:type=\"FILE_VHDL\"/>\n"
files_pattern = re.compile('[ \t]*<files>[ \t]*')
new_ise = []
for line in ise_lines:
new_ise.append(line)
if re.match(files_pattern, line) != None:
for file in files_list:
new_ise.append(file_template.format(os.path.relpath(file)))
new_ise_file = SourceFile(path=self.path, name=self.name+".new")
new_ise_file.write(new_ise)
class VHDLFile(SourceFile):
def __init__(self, path=None, type="vhdl", library="work"):
SourceFile.__init__(self,path= path, type=type)
self.library = library
self.use = self.search_for_use_()
self.package = self.search_for_package_()
class ModuleOptions(object):
def __init__(self):
self.items = { "files" : None, #files from the module that should be taken
"fetchto" : None, #where this module should be fetched to, when fetching
"path" : None, #where the module is storek
"url" : None, #URL to the module
"manifest" : None, #manifest object
"source" : None, #where it should be fetched from
"isparsed" : None, #
"isfetched" : None,
"library" : None, #target library for the vhdl compilation
"root_module" : None, #root module object
"local" : None, #local modules
"git" : None, #git modules
"svn" : None, #svn modules
"ise" : None,
"tcl" : None,
"vmap_opt" : None,
"vlog_opt" : None,
"vcom_opt" : None
}
def __setitem__(self, key, value):
if key in self.items:
self.items[key] = value
else:
raise KeyError("__setitem__: there is no such key: "+str(key))
def __getitem__(self, key):
if key in self.items:
return self.items[key]
else:
raise KeyError("__getitem__:there is no such key: "+str(key))
This diff is collapsed.
......@@ -59,7 +59,7 @@ def relpath(p1, p2 = None):
#def filter_files(files, extension):
#
def rel2abs(path, base = os.curdir):
def rel2abs(path, base = None):
"""
converts a relative path to an absolute path.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment