Improve coding style for all the tools

parent 2aee04b8
......@@ -21,13 +21,14 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
import string
"""Module providing support for Aldec Active-HDL simulator"""
from hdlmake.action import ActionMakefile
from hdlmake.srcfile import VHDLFile, VerilogFile, SVFile
class ToolActiveHDL(ActionMakefile):
"""Class providing the interface to control an Active-HDL simulation"""
TOOL_INFO = {
'name': 'Aldec Active-HDL',
......@@ -40,11 +41,14 @@ class ToolActiveHDL(ActionMakefile):
def __init__(self):
super(ToolActiveHDL, self).__init__()
def detect_version(self, path):
"""Get the version from the Aldec-HDL binary program"""
pass
def _print_clean(self, top_module):
"""Print the Makefile clean target for Aldec Active-HDL simulator"""
self.writeln("""\
#target for cleaning all intermediate stuff
clean:
......@@ -57,41 +61,36 @@ mrproper: clean
def _print_sim_compilation(self, fileset, top_module):
# TODO: ??
"""Print Makefile compilation target for Aldec Active-HDL simulator"""
self.writeln("simulation:")
self.writeln(
"\t\techo \"# Active-HDL command file, generated by HDLMake\" > run.command")
self.writeln("\t\techo \"# Active-HDL command file,"
" generated by HDLMake\" > run.command")
self.writeln()
self.writeln(
"\t\techo \"# Create library and set as default target\" >> run.command")
self.writeln("\t\techo \"# Create library and set as"
" default target\" >> run.command")
self.writeln("\t\techo \"alib work\" >> run.command")
self.writeln("\t\techo \"set worklib work\" >> run.command")
self.writeln()
self.writeln(
"\t\techo \"# Compiling HDL source files\" >> run.command")
for vl in fileset.filter(VerilogFile):
for vl_file in fileset.filter(VerilogFile):
self.writeln(
"\t\techo \"alog " +
vl.rel_path(
vl_file.rel_path(
) +
"\" >> run.command")
for sv in fileset.filter(SVFile):
for sv_file in fileset.filter(SVFile):
self.writeln(
"\t\techo \"alog " +
sv.rel_path(
sv_file.rel_path(
) +
"\" >> run.command")
for vhdl in fileset.filter(VHDLFile):
for vhdl_file in fileset.filter(VHDLFile):
self.writeln(
"\t\techo \"acom " +
vhdl.rel_path(
vhdl_file.rel_path(
) +
"\" >> run.command")
self.writeln()
self.writeln("\t\tvsimsa -do run.command")
......@@ -21,10 +21,11 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Lattice Diamond IDE"""
import subprocess
import sys
import os
import logging
import string
from hdlmake.action import ActionMakefile
......@@ -34,6 +35,7 @@ DIAMOND_STANDARD_LIBS = ['ieee', 'std']
class ToolDiamond(ActionMakefile):
"""Class providing the interface for Lattice Diamond synthesis"""
TOOL_INFO = {
'name': 'Diamond',
......@@ -46,11 +48,17 @@ class ToolDiamond(ActionMakefile):
def __init__(self):
super(ToolDiamond, self).__init__()
self.files = []
self.filename = None
self.header = None
self.tclname = 'temporal.tcl'
def detect_version(self, path):
"""Get version from the Lattice Diamond program"""
return 'unknown'
def generate_synthesis_makefile(self, top_mod, tool_path):
"""Generate a synthesis Makefile for a Lattice Diamond project"""
makefile_tmplt = string.Template("""PROJECT := ${project_name}
DIAMOND_CRAP := \
$$(PROJECT)1.sty \
......@@ -108,17 +116,15 @@ mrproper:
syn_post_cmd=syn_post_cmd,
diamondc_path=os.path.join(tool_path, bin_name))
self.write(makefile_text)
for f in top_mod.incl_makefiles:
if os.path.exists(f):
self.write("include %s\n" % f)
for file_aux in top_mod.incl_makefiles:
if os.path.exists(file_aux):
self.write("include %s\n" % file_aux)
def generate_synthesis_project(
self, update=False, tool_version='', top_mod=None, fileset=None):
self.files = []
def generate_synthesis_project(self, update=False, tool_version='',
top_mod=None, fileset=None):
"""Create project for Lattice Diamond synthesis"""
self.filename = top_mod.manifest_dict["syn_project"]
self.header = None
self.tclname = 'temporal.tcl'
if update is True:
self.update_project()
else:
......@@ -131,26 +137,28 @@ mrproper:
self.execute()
def emit(self, update=False):
f = open(self.tclname, "w")
f.write(self.header + '\n')
f.write(self.__emit_files(update=update))
f.write('prj_project save\n')
f.write('prj_project close\n')
f.close()
"""Create a TCL file to feed Lattice Diamond command interpreter"""
file_aux = open(self.tclname, "w")
file_aux.write(self.header + '\n')
file_aux.write(self.__emit_files(update=update))
file_aux.write('prj_project save\n')
file_aux.write('prj_project close\n')
file_aux.close()
def execute(self):
"""Feed the TCL file to the Lattice Diamond command interpreter"""
# The binary name for Diamond is different in Linux and Windows
if sys.platform == 'cygwin':
tmp = 'pnmainc {0}'
else:
tmp = 'diamondc {0}'
cmd = tmp.format(self.tclname)
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
process_aux = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
# But do not wait till diamond finish, start displaying output
# immediately ##
while True:
out = p.stderr.read(1)
if out == '' and p.poll() is not None:
out = process_aux.stderr.read(1)
if out == '' and process_aux.poll() is not None:
break
if out != '':
sys.stdout.write(out)
......@@ -158,39 +166,53 @@ mrproper:
os.remove(self.tclname)
def add_files(self, fileset):
for f in fileset:
self.files.append(f)
"""Add files to the inner fileset"""
for file_aux in fileset:
self.files.append(file_aux)
def create_project(self,
syn_device,
syn_grade,
syn_package,
syn_top):
tmp = 'prj_project new -name {0} -impl {0} -dev {1} -synthesis \"synplify\"'
"""Create an empty Lattice Diamond project"""
tmp = ('prj_project new -name {0} -impl {0}'
' -dev {1} -synthesis \"synplify\"')
target = syn_device + syn_grade + syn_package
self.header = tmp.format(self.filename, target.upper())
def update_project(self):
"""Create an empty Lattice Diamond project"""
tmp = 'prj_project open \"{0}\"'
self.header = tmp.format(self.filename + '.ldf')
def __emit_files(self, update=False):
"""Emit files required for building the Lattice Diamond project"""
tmp = 'prj_src {0} \"{1}\"'
ret = []
for f in self.files:
for file_aux in self.files:
line = ''
if isinstance(f, VHDLFile) or isinstance(f, VerilogFile) or isinstance(f, SVFile) or isinstance(f, EDFFile):
if (isinstance(file_aux, VHDLFile) or
isinstance(file_aux, VerilogFile) or
isinstance(file_aux, SVFile) or
isinstance(file_aux, EDFFile)):
if update:
line = line + '\n' + tmp.format('remove', f.rel_path())
line = line + '\n' + tmp.format('add', f.rel_path())
elif isinstance(f, LPFFile):
line = line + '\n' + tmp.format('remove',
file_aux.rel_path())
line = line + '\n' + tmp.format('add',
file_aux.rel_path())
elif isinstance(file_aux, LPFFile):
if update:
line = line + '\n' + \
tmp.format('enable', self.filename + '.lpf')
line = line + '\n' + tmp.format('remove', f.rel_path())
line = line + '\n' + tmp.format('add -exclude', f.rel_path())
line = line + '\n' + tmp.format('enable', f.rel_path())
line = line + '\n' + tmp.format('remove',
file_aux.rel_path())
line = line + '\n' + tmp.format('add -exclude',
file_aux.rel_path())
line = line + '\n' + tmp.format('enable',
file_aux.rel_path())
else:
continue
ret.append(line)
return ('\n'.join(ret)) + '\n'
......@@ -21,6 +21,8 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for GHDL simulator"""
import string
from hdlmake.action import ActionMakefile
from hdlmake.srcfile import VHDLFile
......@@ -28,6 +30,7 @@ from hdlmake.srcfile import VHDLFile
GHDL_STANDARD_LIBS = ['ieee', 'std']
class ToolGHDL(ActionMakefile):
"""Class providing the interface for Lattice Diamond synthesis"""
TOOL_INFO = {
'name': 'GHDL',
......@@ -41,10 +44,12 @@ class ToolGHDL(ActionMakefile):
super(ToolGHDL, self).__init__()
def detect_version(self, path):
"""Get tool version for GHDL"""
pass
def _print_sim_options(self, top_module):
"""Print the GHDL options to the Makefile"""
if top_module.manifest_dict["ghdl_opt"]:
ghdl_opt = top_module.manifest_dict["ghdl_opt"]
else:
......@@ -56,6 +61,7 @@ class ToolGHDL(ActionMakefile):
def _print_clean(self, top_module):
"""Print the Makefile clean target for GHDL"""
self.writeln("""\
#target for cleaning all intermediate stuff
clean:
......@@ -68,7 +74,7 @@ mrproper: clean
def _print_sim_compilation(self, fileset, top_module):
# TODO: vhdl87 vs vhdl97 options
"""Print the GDHL simulation compilation target"""
self.writeln("simulation:")
self.writeln("\t\t# Analyze sources")
for vhdl in fileset.filter(VHDLFile):
......
......@@ -23,13 +23,13 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Xilinx ISim simulator"""
import os
import os.path
from subprocess import Popen, PIPE
import logging
import sys
import string
import platform
from hdlmake.util import path as path_mod
from hdlmake.action import ActionMakefile
......@@ -44,6 +44,7 @@ ISIM_STANDARD_LIBS = ['std', 'ieee', 'ieee_proposed', 'vl', 'synopsys',
class ToolISim(ActionMakefile):
"""Class providing the interface for Xilinx ISim simulator"""
TOOL_INFO = {
'name': 'ISim',
......@@ -57,6 +58,7 @@ class ToolISim(ActionMakefile):
super(ToolISim, self).__init__()
def detect_version(self, path):
"""Get version from Xilinx ISim simulator program"""
is_windows = path_mod.check_windows()
isim = Popen(
"%s --version | awk '{print $2}'" % os.path.join(path, "vlogcomp"),
......@@ -73,21 +75,28 @@ class ToolISim(ActionMakefile):
def _print_sim_top(self, top_module):
"""Print the top section of the Makefile for Xilinx ISim"""
self.writeln("""## variables #############################
PWD := $(shell pwd)
TOP_MODULE := """ + top_module.manifest_dict["sim_top"] + """
FUSE_OUTPUT ?= isim_proj
XILINX_INI_PATH := """ + self.__get_xilinxsim_ini_dir(top_module.pool.env) + """
XILINX_INI_PATH := """ + self.__get_xilinxsim_ini_dir(top_module.pool.env) +
"""
""")
def _print_sim_options(self, top_module):
self.writeln("""VHPCOMP_FLAGS := -intstyle default -incremental -initfile xilinxsim.ini
"""Print the Xilinx ISim simulation options in the Makefile"""
self.writeln("""VHPCOMP_FLAGS := -intstyle default \
-incremental -initfile xilinxsim.ini
ISIM_FLAGS :=
VLOGCOMP_FLAGS := -intstyle default -incremental -initfile xilinxsim.ini """ + self.__get_rid_of_isim_incdirs(top_module.manifest_dict["vlog_opt"]) + """
VLOGCOMP_FLAGS := -intstyle default -incremental -initfile xilinxsim.ini """ +
self.__get_rid_of_isim_incdirs(
top_module.manifest_dict["vlog_opt"]) + """
""")
def _print_clean(self, top_module):
"""Print the Makefile clean target for Xilinx ISim simulator"""
self.writeln("""\
#target for cleaning all intermediate stuff
clean:
......@@ -100,8 +109,8 @@ mrproper: clean
""")
def _print_sim_compilation(self, fileset, top_module):
"""Print the compile simulation target for Xilinx ISim"""
make_preambule_p2 = """## rules #################################
simulation: xilinxsim.ini $(LIB_IND) $(VERILOG_OBJ) $(VHDL_OBJ) fuse
$(VERILOG_OBJ): $(LIB_IND) xilinxsim.ini
......@@ -124,7 +133,6 @@ fuse:
self.write(' '.join([lib + "/." + lib for lib in libs]))
self.write('\n')
self.writeln(make_preambule_p2)
# ISim does not have a vmap command to insert additional libraries in
......@@ -132,7 +140,8 @@ fuse:
for lib in libs:
self.write(lib + "/." + lib + ":\n")
self.write(
' '.join(["\t(mkdir", lib, "&&", "touch", lib + "/." + lib + " "]))
' '.join(["\t(mkdir", lib, "&&", "touch",
lib + "/." + lib + " "]))
# self.write(' '.join(["&&", "echo", "\""+lib+"="+lib+"/."+lib+"\"
# ", ">>", "xilinxsim.ini) "]))
self.write(
......@@ -151,124 +160,130 @@ fuse:
# rules for all _primary.dat files for sv
# incdir = ""
objs = []
for vl in fileset.filter(VerilogFile):
comp_obj = os.path.join(vl.library, vl.purename)
for vl_file in fileset.filter(VerilogFile):
comp_obj = os.path.join(vl_file.library, vl_file.purename)
objs.append(comp_obj)
# self.write(os.path.join(vl.library, vl.purename, '.'+vl.purename+"_"+vl.extension())+': ')
# self.write(os.path.join(vl_file.library, vl_file.purename,
# '.'+vl_file.purename+"_"+vl_file.extension())+': ')
# self.writeln(".PHONY: " + os.path.join(comp_obj,
# '.'+vl.purename+"_"+vl.extension()))
# '.'+vl_file.purename+"_"+vl_file.extension()))
self.write(
os.path.join(
comp_obj,
'.' +
vl.purename +
vl_file.purename +
"_" +
vl.extension(
vl_file.extension(
)) +
': ')
self.write(vl.rel_path() + ' ')
self.write(vl_file.rel_path() + ' ')
self.writeln(
' '.join([fname.rel_path() for fname in vl.depends_on]))
self.write("\t\tvlogcomp -work " + vl.library + "=./" + vl.library)
' '.join([fname.rel_path() for fname in vl_file.depends_on]))
self.write("\t\tvlogcomp -work " + vl_file.library
+ "=./" + vl_file.library)
self.write(" $(VLOGCOMP_FLAGS) ")
# if isinstance(vl, SVFile):
# if isinstance(vl_file, SVFile):
# self.write(" -sv ")
# incdir = "-i "
# incdir += " -i ".join(vl.include_dirs)
# incdir += " -i ".join(vl_file.include_dirs)
# incdir += " "
if vl.include_dirs:
if vl_file.include_dirs:
self.write(' -i ')
self.write(' '.join(vl.include_dirs) + ' ')
self.writeln(vl.vlog_opt + " $<")
self.write(' '.join(vl_file.include_dirs) + ' ')
self.writeln(vl_file.vlog_opt + " $<")
self.write("\t\t@mkdir -p $(dir $@)")
self.writeln(" && touch $@ \n\n")
self.write("\n")
# list rules for all _primary.dat files for vhdl
for vhdl in fileset.filter(VHDLFile):
lib = vhdl.library
purename = vhdl.purename
for vhdl_file in fileset.filter(VHDLFile):
lib = vhdl_file.library
purename = vhdl_file.purename
comp_obj = os.path.join(lib, purename)
objs.append(comp_obj)
# each .dat depends on corresponding .vhd file and its dependencies
# self.write(os.path.join(lib, purename, "."+purename+"_"+ vhdl.extension()) + ": "+ vhdl.rel_path()+" " + os.path.join(lib, purename, "."+purename) + '\n')
# self.write(os.path.join(lib, purename, "."+purename+"_"
# + vhdl_file.extension()) + ": "+ vhdl_file.rel_path()+" "
# + os.path.join(lib, purename, "."+purename) + '\n')
# self.writeln(".PHONY: " + os.path.join(comp_obj,
# "."+purename+"_"+ vhdl.extension()))
# "."+purename+"_"+ vhdl_file.extension()))
self.write(
os.path.join(
comp_obj,
"." + purename + "_" + vhdl.extension(
)) + ": " + vhdl.rel_path(
"." + purename + "_" + vhdl_file.extension(
)) + ": " + vhdl_file.rel_path(
) + " " + os.path.join(
lib,
purename,
"." + purename) + '\n')
self.writeln(
' '.join(["\t\tvhpcomp $(VHPCOMP_FLAGS)",
vhdl.vcom_opt,
vhdl_file.vcom_opt,
"-work",
lib + "=./" + lib,
"$< "]))
self.writeln("\t\t@mkdir -p $(dir $@) && touch $@\n")
self.writeln()
# dependency meta-target. This rule just list the dependencies of the above file
# if len(vhdl.depends_on) != 0:
# self.writeln(".PHONY: " + os.path.join(lib, purename, "."+purename))
# Touch the dependency file as well. In this way, "make" will recompile only what is needed (out of date)
# if len(vhdl.depends_on) != 0:
# dependency meta-target.
# This rule just list the dependencies of the above file
# if len(vhdl_file.depends_on) != 0:
# self.writeln(".PHONY: " + os.path.join(
# lib, purename, "."+purename))
# Touch the dependency file as well. In this way, "make" will
# recompile only what is needed (out of date)
# if len(vhdl_file.depends_on) != 0:
self.write(os.path.join(lib, purename, "." + purename) + ":")
for dep_file in vhdl.depends_on:
for dep_file in vhdl_file.depends_on:
if dep_file in fileset:
name = dep_file.purename
self.write(
" \\\n" + os.path.join(dep_file.library,
name,
"." + name + "_" + vhdl.extension()))
name, "." + name + "_" +
vhdl_file.extension()))
else:
self.write(" \\\n" + os.path.join(dep_file.rel_path()))
self.write('\n')
self.writeln("\t\t@mkdir -p $(dir $@) && touch $@\n")
# FIX. Make it more robust
def __get_rid_of_isim_incdirs(self, vlog_opt):
"""Clean the vlog options from include dirs"""
if not vlog_opt:
vlog_opt = ""
vlogs = vlog_opt.split(' ')
ret = []
skip = False
for v in vlogs:
for vlog_option in vlogs:
if skip:
skip = False
continue
if not v.startswith("-i"):
ret.append(v)
if not vlog_option.startswith("-i"):
ret.append(vlog_option)
else:
skip = True
return ' '.join(ret)
def __get_xilinxsim_ini_dir(self, env):
"""Get Xilinx ISim ini simulation file"""
if env["isim_path"]:
xilinx_dir = str(os.path.join(env["isim_path"], "..", ".."))
else:
logging.error("Cannot calculate xilinx tools base directory")
quit()
hdl_language = 'vhdl' # 'verilog'
if sys.platform == 'cygwin':
os_prefix = 'nt'
else:
os_prefix = 'lin'
if env["architecture"] == 32:
arch_sufix = ''
else:
arch_sufix = '64'
xilinx_ini_path = str(os.path.join(xilinx_dir,
hdl_language,
"hdp",
os_prefix + arch_sufix))
# Ensure the path is absolute and normalized
return os.path.abspath(xilinx_ini_path)
......@@ -21,11 +21,10 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for IVerilog (Icarus Verilog) simulator"""
from subprocess import Popen, PIPE
import string
import os
import platform
import logging
from hdlmake.util import path as path_mod
from hdlmake.action import ActionMakefile
......@@ -40,6 +39,7 @@ IVERILOG_STANDARD_LIBS = ['std', 'ieee', 'ieee_proposed', 'vl', 'synopsys',
class ToolIVerilog(ActionMakefile):
"""Class providing the interface for Icarus Verilog simulator"""
TOOL_INFO = {
'name': 'Icarus Verilog',
......@@ -53,6 +53,7 @@ class ToolIVerilog(ActionMakefile):
super(ToolIVerilog, self).__init__()
def detect_version(self, path):
"""Get version from Icarus Verilog program"""
is_windows = path_mod.check_windows()
iverilog = Popen("iverilog -v 2>/dev/null| awk '{if(NR==1) print $4}'",
shell=True,
......@@ -63,30 +64,30 @@ class ToolIVerilog(ActionMakefile):
return version
def _print_sim_compilation(self, fileset, top_module):
"""Generate compile simulation Makefile target for IVerilog"""
self.writeln("simulation:")
self.writeln(
"\t\techo \"# IVerilog command file, generated by HDLMake\" > run.command")
self.writeln("\t\techo \"# IVerilog command file,"
" generated by HDLMake\" > run.command")
for inc in top_module.get_include_dirs_list():
self.writeln("\t\techo \"+incdir+" + inc + "\" >> run.command")
for vl in fileset.filter(VerilogFile):
self.writeln("\t\techo \"" + vl.rel_path() + "\" >> run.command")
for vlog in fileset.filter(VerilogFile):
self.writeln("\t\techo \"" + vlog.rel_path() + "\" >> run.command")
for vhdl in fileset.filter(VHDLFile):
self.writeln("\t\techo \"" + vhdl.rel_path() + "\" >> run.command")
for sv in fileset.filter(SVFile):
self.writeln("\t\techo \"" + sv.rel_path() + "\" >> run.command")
self.writeln("""
\t\tiverilog $(IVERILOG_OPT) -s $(TOP_MODULE) -o $(TOP_MODULE).vvp -c run.command
for svlog in fileset.filter(SVFile):
self.writeln("\t\techo \"" + svlog.rel_path() + "\" >> run.command")
""")
self.writeln("\t\tiverilog $(IVERILOG_OPT) -s $(TOP_MODULE)"
" -o $(TOP_MODULE).vvp -c run.command")
def _print_sim_options(self, top_module):
"""Print the IVerilog options to the Makefile"""
if top_module.manifest_dict["iverilog_opt"]:
iverilog_opt = top_module.manifest_dict["iverilog_opt"]
else:
......@@ -98,6 +99,7 @@ class ToolIVerilog(ActionMakefile):
def _print_clean(self, top_module):
"""Print the Makefile clean target for Icarus Verilog"""
self.writeln("""\
#target for cleaning all intermediate stuff
clean:
......
......@@ -21,11 +21,12 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Microsemi Libero IDE synthesis"""
import subprocess
import sys
import os
import string
import logging
from hdlmake.action import ActionMakefile
from hdlmake.srcfile import VHDLFile, VerilogFile, SDCFile, PDCFile
......@@ -35,6 +36,7 @@ LIBERO_STANDARD_LIBS = ['ieee', 'std']
class ToolLibero(ActionMakefile):
"""Class providing the interface for Microsemi Libero IDE synthesis"""
TOOL_INFO = {
'name': 'Libero',
......@@ -47,11 +49,21 @@ class ToolLibero(ActionMakefile):
def __init__(self):
super(ToolLibero, self).__init__()
self.files = []
self.filename = None
self.syn_device = None
self.syn_grade = None
self.syn_package = None
self.syn_top = None
self.header = None
self.tclname = 'temporal.tcl'
def detect_version(self, path):
"""Get version for Microsemi Libero IDE synthesis"""
return 'unknown'
def generate_synthesis_makefile(self, top_mod, tool_path):
"""Generate the synthesis Makefile for Microsemi Libero IDE"""
makefile_tmplt = string.Template("""PROJECT := ${project_name}
LIBERO_CRAP := \
run.tcl
......@@ -105,21 +117,19 @@ mrproper:
syn_post_cmd=syn_post_cmd,
libero_sh_path=os.path.join(tool_path, "libero"))
self.write(makefile_text)
for f in top_mod.incl_makefiles:
if os.path.exists(f):
self.write("include %s\n" % f)
for file_aux in top_mod.incl_makefiles:
if os.path.exists(file_aux):
self.write("include %s\n" % file_aux)
def generate_synthesis_project(
self, update=False, tool_version='', top_mod=None, fileset=None):
self.files = []
"""Create a Microsemi Libero IDE synthesis project"""
self.filename = top_mod.manifest_dict["syn_project"]
self.syn_device = top_mod.manifest_dict["syn_device"]
self.syn_grade = top_mod.manifest_dict["syn_grade"]
self.syn_package = top_mod.manifest_dict["syn_package"]
self.syn_top = top_mod.manifest_dict["syn_top"]
self.header = None
self.tclname = 'temporal.tcl'
if update is True:
self.update_project()
......@@ -130,22 +140,24 @@ mrproper:
self.execute()
def emit(self, update=False):
f = open(self.tclname, "w")
f.write(self.header + '\n')
f.write(self.__emit_files(update=update))
f.write('save_project\n')
f.write('close_project\n')
f.close()
"""Emit the TCL file that is required to generate the project"""
file_aux = open(self.tclname, "w")
file_aux.write(self.header + '\n')
file_aux.write(self.__emit_files(update=update))
file_aux.write('save_project\n')
file_aux.write('close_project\n')
file_aux.close()
def execute(self):
"""Feed the TCL script to Microsemi Libero IDE command interpreter"""
tmp = 'libero SCRIPT:{0}'
cmd = tmp.format(self.tclname)
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
process_aux = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
# But do not wait till Libero finish, start displaying output
# immediately ##
while True:
out = p.stderr.read(1)
if out == '' and p.poll() is not None:
out = process_aux.stderr.read(1)
if out == '' and process_aux.poll() is not None:
break
if out != '':
sys.stdout.write(out)
......@@ -153,11 +165,15 @@ mrproper:
os.remove(self.tclname)
def add_files(self, fileset):
for f in fileset:
self.files.append(f)
"""Add files to the inner fileset"""
for file_aux in fileset:
self.files.append(file_aux)
def create_project(self):
tmp = 'new_project -location {{./{0}}} -name {{{0}}} -hdl {{VHDL}} -family {{ProASIC3}} -die {{{1}}} -package {{{2}}} -speed {{{3}}} -die_voltage {{1.5}}'
"""Create a new Microsemi Libero IDE project"""
tmp = ('new_project -location {{./{0}}} -name {{{0}}} -hdl'
' {{VHDL}} -family {{ProASIC3}} -die {{{1}}} -package'
' {{{2}}} -speed {{{3}}} -die_voltage {{1.5}}')
self.header = tmp.format(
self.filename,
self.syn_device.upper(),
......@@ -165,26 +181,30 @@ mrproper:
self.syn_grade)
def update_project(self):
"""Update an existing Microsemi Libero IDE project"""
tmp = 'open_project -file {{{0}/{0}.prjx}}'
self.header = tmp.format(self.filename)
def __emit_files(self, update=False):
"""Emit the supported HDL files that need to be added to the project"""
link_string = 'create_links {0} {{{1}}}'
enable_string = 'organize_tool_files -tool {{{0}}} -file {{{1}}} -module {{{2}::work}} -input_type {{constraint}}'
enable_string = ('organize_tool_files -tool {{{0}}} -file {{{1}}}'
' -module {{{2}::work}} -input_type {{constraint}}')
synthesis_constraints = []
compilation_constraints = []
ret = []
# First stage: linking files
for f in self.files:
if isinstance(f, VHDLFile) or isinstance(f, VerilogFile):
line = link_string.format('-hdl_source', f.rel_path())
elif isinstance(f, SDCFile):
line = link_string.format('-sdc', f.rel_path())
synthesis_constraints.append(f)
compilation_constraints.append(f)
elif isinstance(f, PDCFile):
line = link_string.format('-pdc', f.rel_path())
compilation_constraints.append(f)
for file_aux in self.files:
if (isinstance(file_aux, VHDLFile) or
isinstance(file_aux, VerilogFile)):
line = link_string.format('-hdl_source', file_aux.rel_path())
elif isinstance(file_aux, SDCFile):
line = link_string.format('-sdc', file_aux.rel_path())
synthesis_constraints.append(file_aux)
compilation_constraints.append(file_aux)
elif isinstance(file_aux, PDCFile):
line = link_string.format('-pdc', file_aux.rel_path())
compilation_constraints.append(file_aux)
else:
continue
ret.append(line)
......@@ -192,8 +212,8 @@ mrproper:
# module needs to be present!)
if synthesis_constraints:
line = 'organize_tool_files -tool {SYNTHESIZE} '
for f in synthesis_constraints:
line = line + '-file {' + f.rel_path() + '} '
for file_aux in synthesis_constraints:
line = line + '-file {' + file_aux.rel_path() + '} '
line = line + \
'-module {' + self.syn_top + '::work} -input_type {constraint}'
ret.append(line)
......@@ -201,8 +221,8 @@ mrproper:
# module needs to be present!)
if compilation_constraints:
line = 'organize_tool_files -tool {COMPILE} '
for f in compilation_constraints:
line = line + '-file {' + f.rel_path() + '} '
for file_aux in compilation_constraints:
line = line + '-file {' + file_aux.rel_path() + '} '
line = line + \
'-module {' + self.syn_top + '::work} -input_type {constraint}'
ret.append(line)
......
......@@ -21,18 +21,19 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Mentor Modelsim simulation"""
from __future__ import print_function
import xml.dom.minidom
import os
from .sim_makefile_support import VsimMakefileWriter
XmlImpl = xml.dom.minidom.getDOMImplementation()
MODELSIM_STANDARD_LIBS = ['ieee', 'std', 'altera_mf']
class ToolModelsim(VsimMakefileWriter):
"""Class providing the interface for Mentor Modelsim simulator"""
TOOL_INFO = {
'name': 'Modelsim',
......@@ -55,10 +56,12 @@ class ToolModelsim(VsimMakefileWriter):
["./modelsim.ini", "transcript", "*.vcd", "*.wlf"])
def detect_version(self, path):
"""Get version from the Mentor Modelsim program"""
pass
def _print_sim_options(self, top_module):
"""Print the Modelsim options to the Makefile"""
if top_module.pool.env["modelsim_path"]:
modelsim_ini_path = os.path.join(
top_module.pool.env["modelsim_path"],
......
......@@ -21,11 +21,12 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Xilinx PlanAhead synthesis"""
import subprocess
import sys
import os
import string
from string import Template
import logging
from hdlmake.action import ActionMakefile
......@@ -37,6 +38,8 @@ PLANAHEAD_STANDARD_LIBS = ['ieee', 'std']
class ToolPlanAhead(ActionMakefile):
"""Class providing the interface for Xilinx PlanAhead synthesis"""
TOOL_INFO = {
'name': 'PlanAhead',
......@@ -49,11 +52,18 @@ class ToolPlanAhead(ActionMakefile):
def __init__(self):
super(ToolPlanAhead, self).__init__()
self.properties = []
self.files = []
self.filename = None
self.header = None
self.tclname = 'temporal.tcl'
def detect_version(self, path):
"""Get the Xilinx PlanAhead program version"""
return 'unknown'
def generate_synthesis_makefile(self, top_mod, tool_path):
"""Generate a synthesis Makefile for Xilinx PlanAhead"""
makefile_tmplt = string.Template("""PROJECT := ${project_name}
PLANAHEAD_CRAP := \
planAhead_* \
......@@ -115,18 +125,15 @@ mrproper:
syn_post_cmd=syn_post_cmd,
planahead_sh_path=os.path.join(tool_path, "planAhead"))
self.write(makefile_text)
for f in top_mod.incl_makefiles:
if os.path.exists(f):
self.write("include %s\n" % f)
for file_aux in top_mod.incl_makefiles:
if os.path.exists(file_aux):
self.write("include %s\n" % file_aux)
def generate_synthesis_project(
self, update=False, tool_version='', top_mod=None, fileset=None):
self.properties = []
self.files = []
"""Create a Xilinx PlanAhead project"""
self.filename = top_mod.manifest_dict["syn_project"]
self.header = None
self.tclname = 'temporal.tcl'
if update is True:
logging.info("Existing project detected: updating...")
self.update_project()
......@@ -144,25 +151,27 @@ mrproper:
logging.info("PlanAhead project file generated.")
def emit(self):
f = open(self.tclname, "w")
f.write(self.header + '\n')
for p in self.properties:
f.write(p.emit() + '\n')
f.write(self.__emit_files())
f.write('update_compile_order -fileset sources_1\n')
f.write('update_compile_order -fileset sim_1\n')
f.write('exit\n')
f.close()
"""Emit the TCL file that will be used to generate the project"""
file_aux = open(self.tclname, "w")
file_aux.write(self.header + '\n')
for prop in self.properties:
file_aux.write(prop.emit() + '\n')
file_aux.write(self.__emit_files())
file_aux.write('update_compile_order -fileset sources_1\n')
file_aux.write('update_compile_order -fileset sim_1\n')
file_aux.write('exit\n')
file_aux.close()
def execute(self):
"""Source the TCL file to the Xilinx PlanAhead interpreter"""
tmp = 'planAhead -mode tcl -source {0}'
cmd = tmp.format(self.tclname)
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
process_aux = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
# But do not wait till planahead finish, start displaying output
# immediately ##
while True:
out = p.stderr.read(1)
if out == '' and p.poll() is not None:
out = process_aux.stderr.read(1)
if out == '' and process_aux.poll() is not None:
break
if out != '':
sys.stdout.write(out)
......@@ -170,10 +179,12 @@ mrproper:
os.remove(self.tclname)
def add_files(self, fileset):
for f in fileset:
self.files.append(f)
"""Add files to the inner fileset"""
for file_aux in fileset:
self.files.append(file_aux)
def add_property(self, new_property):
"""Add a new Xilinx PlanAhead property to the defined set"""
self.properties.append(new_property)
def add_initial_properties(self,
......@@ -181,20 +192,21 @@ mrproper:
syn_grade,
syn_package,
syn_top):
PAPP = _PlanAheadProjectProperty
"""Add the initial properties to the Xilinx PlanAhead project"""
prop = _PlanAheadProjectProperty
self.add_property(
PAPP(
prop(
name='part',
value=syn_device +
syn_package +
syn_grade,
objects='current_project'))
self.add_property(
PAPP(name='target_language',
prop(name='target_language',
value='VHDL',
objects='current_project'))
self.add_property(
PAPP(
prop(
name='ng.output_hdl_format',
value='VHDL',
objects='get_filesets sim_1'))
......@@ -202,39 +214,50 @@ mrproper:
# self.add_property(PAPP(name='steps.bitgen.args.b', value='true',
# objects='get_runs impl_1'))
self.add_property(
PAPP(name='top',
prop(name='top',
value=syn_top,
objects='get_property srcset [current_run]'))
def create_project(self):
"""Create an empty Xilinx PlanAhead project"""
tmp = 'create_project {0} ./'
self.header = tmp.format(self.filename)
def update_project(self):
"""Update an existing Xilinx PlanAhead project"""
tmp = 'open_project ./{0}'
self.header = tmp.format(self.filename + '.ppr')
def __emit_properties(self):
"""Add to the project the different properties that have been defined"""
tmp = "set_property {0} {1} [{2}]"
ret = []
for p in self.properties:
line = tmp.format(p.name, p.value, p.objects)
for prop in self.properties:
line = tmp.format(prop.name, prop.value, prop.objects)
ret.append(line)
return ('\n'.join(ret)) + '\n'
def __emit_files(self):
"""Add to the project the different files defined in the design"""
tmp = "add_files -norecurse {0}"
ret = []
for f in self.files:
if isinstance(f, VHDLFile) or isinstance(f, VerilogFile) or isinstance(f, SVFile) or isinstance(f, UCFFile) or isinstance(f, NGCFile) or isinstance(f, XMPFile) or isinstance(f, XCOFile):
line = tmp.format(f.rel_path())
for file_aux in self.files:
if (isinstance(file_aux, VHDLFile) or
isinstance(file_aux, VerilogFile) or
isinstance(file_aux, SVFile) or
isinstance(file_aux, UCFFile) or
isinstance(file_aux, NGCFile) or
isinstance(file_aux, XMPFile) or
isinstance(file_aux, XCOFile)):
line = tmp.format(file_aux.rel_path())
else:
continue
ret.append(line)
return ('\n'.join(ret)) + '\n'
class _PlanAheadProjectProperty:
class _PlanAheadProjectProperty(object):
"""Class that serves as a convenient storage for PlanAhead properties"""
def __init__(self, name=None, value=None, objects=None):
self.name = name
......@@ -242,6 +265,7 @@ class _PlanAheadProjectProperty:
self.objects = objects
def emit(self):
"""Emit the property defined by the class inner parameters"""
tmp = "set_property {0} {1} [{2}]"
line = tmp.format(self.name, self.value, self.objects)
return(line)
return line
......@@ -21,13 +21,13 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Altera Quartus synthesis"""
import os
import sys
import string
from string import Template
import logging
from hdlmake import fetch
from hdlmake.action import ActionMakefile
from hdlmake.util import path as path_mod
from hdlmake.srcfile import (VHDLFile, VerilogFile, SVFile,
......@@ -39,6 +39,7 @@ QUARTUS_STANDARD_LIBS = ['altera', 'altera_mf', 'lpm', 'ieee', 'std']
class ToolQuartus(ActionMakefile):
"""Class providing the interface for Altera Quartus synthesis"""
TOOL_INFO = {
'name': 'Quartus',
......@@ -54,12 +55,17 @@ class ToolQuartus(ActionMakefile):
self._preflow = None
self._postmodule = None
self._postflow = None
self.properties = []
self.files = []
self.filename = None
super(ToolQuartus, self).__init__()
def detect_version(self, path):
"""Get Altera Quartus version from the binary program"""
return 'unknown'
def generate_synthesis_makefile(self, top_mod, tool_path):
"""Generate the synthesis Makefile for Altera Quartus"""
makefile_tmplt = string.Template("""PROJECT := ${project_name}
QUARTUS_CRAP := \
$$(PROJECT).asm.rpt \
......@@ -124,9 +130,9 @@ mrproper:
syn_post_cmd=syn_post_cmd,
quartus_sh_path=os.path.join(tool_path, "quartus_sh"))
self.write(makefile_text)
for f in top_mod.incl_makefiles:
if os.path.exists(f):
self.write("include %s\n" % f)
for file_aux in top_mod.incl_makefiles:
if os.path.exists(file_aux):
self.write("include %s\n" % file_aux)
def _set_tcl_files(self, mod):
......@@ -162,34 +168,30 @@ mrproper:
def generate_synthesis_project(
self, update=False, tool_version='', top_mod=None, fileset=None):
self.properties = []
self.files = []
"""Generate an Altera Quartus synthesis project"""
self.filename = top_mod.manifest_dict["syn_project"]
self._set_tcl_files(top_mod)
if update is True:
self.read()
else:
self.add_initial_properties(top_mod.manifest_dict["syn_device"],
top_mod.manifest_dict["syn_family"],
top_mod.manifest_dict["syn_grade"],
top_mod.manifest_dict["syn_package"],
top_mod.manifest_dict["syn_top"])
self.add_initial_properties(top_mod)
self.add_files(fileset)
self.emit()
def emit(self):
f = open(self.filename + '.qsf', "w")
for p in self.properties:
f.write(p.emit() + '\n')
f.write(self.__emit_files())
f.write(self.__emit_scripts())
f.close()
f = open(self.filename + '.qpf', "w")
f.write("PROJECT_REVISION = \"" + self.filename + "\"\n")
f.close()
"""Emit both the QSF and the QPF files with the needed properties"""
file_aux = open(self.filename + '.qsf', "w")
for prop in self.properties:
file_aux.write(prop.emit() + '\n')
file_aux.write(self.__emit_files())
file_aux.write(self.__emit_scripts())
file_aux.close()
file_aux = open(self.filename + '.qpf', "w")
file_aux.write("PROJECT_REVISION = \"" + self.filename + "\"\n")
file_aux.close()
def __emit_scripts(self):
"""Emit the required TCL scripts to handle the synthesis process"""
tmp = 'set_global_assignment -name {0} "quartus_sh:{1}"'
pre = mod = post = ""
if self._preflow:
......@@ -207,39 +209,42 @@ mrproper:
return pre + '\n' + mod + '\n' + post + '\n'
def __emit_files(self):
"""Emit the HDL design files to be added to the project"""
tmp = "set_global_assignment -name {0} {1}"
tmplib = tmp + " -library {2}"
ret = []
for f in self.files:
if isinstance(f, VHDLFile):
line = tmplib.format("VHDL_FILE", f.rel_path(), f.library)
elif isinstance(f, SVFile):
for file_aux in self.files:
if isinstance(file_aux, VHDLFile):
line = tmplib.format("VHDL_FILE",
file_aux.rel_path(), file_aux.library)
elif isinstance(file_aux, SVFile):
line = tmplib.format(
"SYSTEMVERILOG_FILE",
f.rel_path(),
f.library)
elif isinstance(f, VerilogFile):
line = tmp.format("VERILOG_FILE", f.rel_path())
elif isinstance(f, SignalTapFile):
line = tmp.format("SIGNALTAP_FILE", f.rel_path())
elif isinstance(f, SDCFile):
line = tmp.format("SDC_FILE", f.rel_path())
elif isinstance(f, QIPFile):
line = tmp.format("QIP_FILE", f.rel_path())
elif isinstance(f, QSYSFile):
line = tmp.format("QSYS_FILE", f.rel_path())
elif isinstance(f, DPFFile):
line = tmp.format("MISC_FILE", f.rel_path())
elif isinstance(f, QSFFile):
line = tmp.format("SOURCE_TCL_SCRIPT_FILE", f.rel_path())
elif isinstance(f, BSFFile):
line = tmp.format("BSF_FILE", f.rel_path())
elif isinstance(f, BDFFile):
line = tmp.format("BDF_FILE", f.rel_path())
elif isinstance(f, TDFFile):
line = tmp.format("AHDL_FILE", f.rel_path())
elif isinstance(f, GDFFile):
line = tmp.format("GDF_FILE", f.rel_path())
file_aux.rel_path(),
file_aux.library)
elif isinstance(file_aux, VerilogFile):
line = tmp.format("VERILOG_FILE", file_aux.rel_path())
elif isinstance(file_aux, SignalTapFile):
line = tmp.format("SIGNALTAP_FILE", file_aux.rel_path())
elif isinstance(file_aux, SDCFile):
line = tmp.format("SDC_FILE", file_aux.rel_path())
elif isinstance(file_aux, QIPFile):
line = tmp.format("QIP_FILE", file_aux.rel_path())
elif isinstance(file_aux, QSYSFile):
line = tmp.format("QSYS_FILE", file_aux.rel_path())
elif isinstance(file_aux, DPFFile):
line = tmp.format("MISC_FILE", file_aux.rel_path())
elif isinstance(file_aux, QSFFile):
line = tmp.format("SOURCE_TCL_SCRIPT_FILE",
file_aux.rel_path())
elif isinstance(file_aux, BSFFile):
line = tmp.format("BSF_FILE", file_aux.rel_path())
elif isinstance(file_aux, BDFFile):
line = tmp.format("BDF_FILE", file_aux.rel_path())
elif isinstance(file_aux, TDFFile):
line = tmp.format("AHDL_FILE", file_aux.rel_path())
elif isinstance(file_aux, GDFFile):
line = tmp.format("GDF_FILE", file_aux.rel_path())
else:
continue
ret.append(line)
......@@ -247,17 +252,22 @@ mrproper:
def add_property(self, val):
"""Add Altera Quartus property to the set of already existing ones"""
# don't save files (they are unneeded)
if val.name_type is not None and "_FILE" in val.name_type:
return
self.properties.append(val)
def add_files(self, fileset):
for f in fileset:
self.files.append(f)
"""Add files to the inner fileset"""
for file_aux in fileset:
self.files.append(file_aux)
def read(self):
"""Read properties from an existing Altera Quartus project file"""
def __gather_string(words, first_index):
"""Funtion that returns a string from the supplied index"""
i = first_index
ret = []
if words[i][0] != '"':
......@@ -269,14 +279,14 @@ mrproper:
return (' '.join(ret), len(ret))
i = i + 1
f = open(self.filename + '.qsf', "r")
lines = [l.strip() for l in f.readlines()]
file_aux = open(self.filename + '.qsf', "r")
lines = [l.strip() for l in file_aux.readlines()]
lines = [l for l in lines if l != "" and l[0] != '#']
QPP = _QuartusProjectProperty
q_prop = _QuartusProjectProperty
for line in lines:
words = line.split()
command = QPP.t[words[0]]
what = name = name_type = from_ = to = section_id = None
command = q_prop.PROP_TYPE[words[0]]
what = name = name_type = from_ = to_ = section_id = None
i = 1
while True:
if i >= len(words):
......@@ -292,7 +302,7 @@ mrproper:
i = i + 1 + add
continue
elif words[i] == "-to":
to, add = __gather_string(words, i + 1)
to_, add = __gather_string(words, i + 1)
i = i + 1 + add
continue
elif words[i] == "-from":
......@@ -303,18 +313,18 @@ mrproper:
what = words[i]
i = i + 1
continue
prop = QPP(command=command,
what=what, name=name,
name_type=name_type,
from_=from_,
to=to,
section_id=section_id)
prop = q_prop(command=command,
what=what, name=name,
name_type=name_type,
from_=from_,
to_=to_,
section_id=section_id)
self.add_property(prop)
f.close()
file_aux.close()
def add_initial_properties(
self, syn_device, syn_family, syn_grade, syn_package, syn_top):
def add_initial_properties(self, top_mod):
"""Add initial properties to the Altera Quartus project"""
import re
family_names = {
"^EP2AGX.*$": "Arria II GX",
......@@ -324,57 +334,69 @@ mrproper:
"^5S.*$": "Stratix V",
}
syn_device = top_mod.manifest_dict["syn_device"],
syn_family = top_mod.manifest_dict["syn_family"],
syn_grade = top_mod.manifest_dict["syn_grade"],
syn_package = top_mod.manifest_dict["syn_package"],
syn_top = top_mod.manifest_dict["syn_top"]
if syn_family is None:
for key in family_names:
if re.match(key, syn_device.upper()):
syn_family = family_names[key]
logging.debug(
"Auto-guessed syn_family to be %s (%s => %s)" %
(syn_family, syn_device, key))
"Auto-guessed syn_family to be %s (%s => %s)",
syn_family, syn_device, key)
if syn_family is None:
logging.error(
"Could not auto-guess device family, please specify in Manifest.py using syn_family!")
logging.error("Could not auto-guess device family, please "
"specify in Manifest.py using syn_family!")
sys.exit("\nExiting")
devstring = (syn_device + syn_package + syn_grade).upper()
QPP = _QuartusProjectProperty
q_prop = _QuartusProjectProperty
self.add_property(
QPP(QPP.SET_GLOBAL_ASSIGNMENT,
q_prop(q_prop.SET_GLOBAL_ASSIGNMENT,
name_type='FAMILY',
name='"' + syn_family + '"'))
self.add_property(
QPP(QPP.SET_GLOBAL_ASSIGNMENT,
q_prop(q_prop.SET_GLOBAL_ASSIGNMENT,
name_type='DEVICE',
name=devstring))
self.add_property(
QPP(QPP.SET_GLOBAL_ASSIGNMENT,
q_prop(q_prop.SET_GLOBAL_ASSIGNMENT,
name_type='TOP_LEVEL_ENTITY',
name=syn_top))
class _QuartusProjectProperty:
SET_GLOBAL_INSTANCE, SET_INSTANCE_ASSIGNMENT, SET_LOCATION_ASSIGNMENT, SET_GLOBAL_ASSIGNMENT = range(
4)
t = {"set_global_instance": SET_GLOBAL_INSTANCE,
"set_instance_assignment": SET_INSTANCE_ASSIGNMENT,
"set_location_assignment": SET_LOCATION_ASSIGNMENT,
"set_global_assignment": SET_GLOBAL_ASSIGNMENT}
class _QuartusProjectProperty(object):
"""Class that serves as a container for Altera Quartus properties"""
SET_GLOBAL_INSTANCE = 0
SET_INSTANCE_ASSIGNMENT = 1
SET_LOCATION_ASSIGNMENT = 2
SET_GLOBAL_ASSIGNMENT = 3
PROP_TYPE = {"set_global_instance": SET_GLOBAL_INSTANCE,
"set_instance_assignment": SET_INSTANCE_ASSIGNMENT,
"set_location_assignment": SET_LOCATION_ASSIGNMENT,
"set_global_assignment": SET_GLOBAL_ASSIGNMENT}
def __init__(self, command, what=None, name=None,
name_type=None, from_=None, to=None, section_id=None):
name_type=None, from_=None, to_=None, section_id=None):
self.command = command
self.what = what
self.name = name
self.name_type = name_type
self.from_ = from_
self.to = to
self.to_ = to_
self.section_id = section_id
def emit(self):
"""Emit a formated property from a defined Altera Quartus one"""
words = []
words.append(dict([(b, a) for a, b in self.t.items()])[self.command])
words.append(dict([(b, a) for a, b in
self.PROP_TYPE.items()])[self.command])
if self.what is not None:
words.append(self.what)
if self.name is not None:
......@@ -384,10 +406,11 @@ class _QuartusProjectProperty:
if self.from_ is not None:
words.append("-from")
words.append(self.from_)
if self.to is not None:
if self.to_ is not None:
words.append("-to")
words.append(self.to)
words.append(self.to_)
if self.section_id is not None:
words.append("-section_id")
words.append(self.section_id)
return ' '.join(words)
......@@ -22,6 +22,8 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Aldec Riviera-PRO simulation"""
from __future__ import print_function
from .sim_makefile_support import VsimMakefileWriter
......@@ -61,6 +63,7 @@ RIVIERA_STANDARD_LIBS.extend(RIVIERA_XILINX_VLOG_LIBRARIES)
class ToolRiviera(VsimMakefileWriter):
"""Class providing the interface for Aldec Riviera-PRO simulator"""
TOOL_INFO = {
'name': 'Riviera',
......@@ -76,5 +79,6 @@ class ToolRiviera(VsimMakefileWriter):
self.additional_clean.extend(["*.asdb", "*.vcd", ])
def detect_version(self, path):
"""Get version from Aldec Riviera-PRO binary program"""
pass
......@@ -21,11 +21,14 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing common stuff for Modelsim, Vsim... like simulators"""
import os
import platform
import string
from hdlmake.action import ActionMakefile
from hdlmake.srcfile import VerilogFile, VHDLFile, SVFile
class VsimMakefileWriter(ActionMakefile):
......@@ -62,8 +65,10 @@ class VsimMakefileWriter(ActionMakefile):
def _print_sim_options(self, top_module):
"""Print the vsim options to the Makefile"""
self.vlog_flags.append(
self.__get_rid_of_vsim_incdirs(top_module.manifest_dict["vlog_opt"]))
self.__get_rid_of_vsim_incdirs(
top_module.manifest_dict["vlog_opt"]))
self.vcom_flags.append(top_module.manifest_dict["vcom_opt"])
self.vmap_flags.append(top_module.manifest_dict["vmap_opt"])
self.vsim_flags.append(top_module.manifest_dict["vsim_opt"])
......@@ -78,6 +83,7 @@ class VsimMakefileWriter(ActionMakefile):
self.writeln("VMAP_FLAGS := %s" % (' '.join(self.vmap_flags)))
def _print_clean(self, top_module):
"""Print the Makefile clean target"""
if platform.system() == 'Windows':
del_command = "rm -rf"
else:
......@@ -91,11 +97,9 @@ class VsimMakefileWriter(ActionMakefile):
def _print_sim_compilation(self, fileset, top_module):
"""Write a properly formatted Makefile for the simulator.
The Makefile format is shared, but flags, dependencies, clean rules,
etc are defined by the specific tool.
"""
from hdlmake.srcfile import VerilogFile, VHDLFile, SVFile
if platform.system() == 'Windows':
del_command = "rm -rf"
......@@ -137,74 +141,68 @@ class VsimMakefileWriter(ActionMakefile):
self.write(lib + slash_char + "." + lib + ":\n")
vmap_command = "vmap $(VMAP_FLAGS)"
self.write(' '.join(["\t(vlib", lib, "&&", vmap_command,
lib, "&&", "touch", lib + slash_char + "." + lib, ")"]))
lib, "&&", "touch", lib + slash_char + "." + lib, ")"]))
self.write(' '.join(["||", del_command, lib, "\n"]))
self.write('\n\n')
# rules for all _primary.dat files for sv
for vl in fileset.filter(VerilogFile):
self.write(
"%s: %s" % (os.path.join(vl.library, vl.purename, ".%s_%s" % (vl.purename, vl.extension())),
vl.rel_path())
)
for vlog in fileset.filter(VerilogFile):
self.write("%s: %s" % (os.path.join(vlog.library, vlog.purename,
".%s_%s" % (vlog.purename, vlog.extension())), vlog.rel_path()))
# list dependencies, do not include the target file
for dep_file in [dfile for dfile in vl.depends_on if dfile is not vl]:
if dep_file in fileset: # the dep_file is compiled -> we depend on marker file
for dep_file in [dfile for dfile
in vlog.depends_on if dfile is not vlog]:
if dep_file in fileset:
name = dep_file.purename
extension = dep_file.extension()
self.write(
" \\\n" + os.path.join(dep_file.library, name, ".%s_%s" %
(name, extension)))
self.write(" \\\n" + os.path.join(dep_file.library,
name, ".%s_%s" % (name, extension)))
else: # the file is included -> we depend directly on the file
self.write(" \\\n" + dep_file.rel_path())
self.writeln()
#
# self.write("\t\tvlog -work "+vl.library)
# self.write("\t\tvlog -work "+vlog.library)
# self.write(" $(VLOG_FLAGS) ")
# if isinstance(vl, SVFile):
# self.write(" -sv ")
# incdir = "+incdir+"
# incdir += '+'.join(vl.include_dirs)
# incdir += '+'.join(vlog.include_dirs)
# incdir += " "
# self.write(incdir)
# self.writeln(vl.vlog_opt+" $<")
#
compile_template = string.Template(
"\t\tvlog -work ${library} $$(VLOG_FLAGS) ${sv_option} $${INCLUDE_DIRS} $$<")
compile_line = compile_template.substitute(library=vl.library,
sv_option="-sv" if isinstance(vl, SVFile) else "")
# self.writeln(vlog.vlog_opt+" $<")
compile_template = string.Template("\t\tvlog -work ${library}"
" $$(VLOG_FLAGS) ${sv_option} $${INCLUDE_DIRS} $$<")
compile_line = compile_template.substitute(
library=vlog.library, sv_option="-sv"
if isinstance(vlog, SVFile) else "")
self.writeln(compile_line)
self.write("\t\t@" + mkdir_command + " $(dir $@)")
self.writeln(" && touch $@ \n\n")
self.write("\n")
self.writeln()
# list rules for all _primary.dat files for vhdl
for vhdl in fileset.filter(VHDLFile):
lib = vhdl.library
purename = vhdl.purename
# each .dat depends on corresponding .vhd file
self.write(
"%s: %s" % (os.path.join(lib, purename, "." + purename + "_" + vhdl.extension()),
vhdl.rel_path())
)
self.write("%s: %s" % (os.path.join(lib, purename, "." +
purename + "_" + vhdl.extension()), vhdl.rel_path()))
# list dependencies, do not include the target file
for dep_file in [dfile for dfile in vhdl.depends_on if dfile is not vhdl]:
if dep_file in fileset: # the dep_file is compiled -> we depend on marker file
for dep_file in [dfile for dfile in vhdl.depends_on
if dfile is not vhdl]:
if dep_file in fileset:
name = dep_file.purename
extension = dep_file.extension()
self.write(
" \\\n" + os.path.join(dep_file.library, name, ".%s_%s" %
(name, extension)))
else: # the file is included -> we depend directly on the file
self.write(" \\\n" + os.path.join(dep_file.library,
name, ".%s_%s" % (name, extension)))
else:
self.write(" \\\n" + dep_file.rel_path())
self.writeln()
self.writeln(
' '.join(["\t\tvcom $(VCOM_FLAGS)", vhdl.vcom_opt, "-work", lib, "$< "]))
self.writeln("\t\t@" + mkdir_command + " $(dir $@) && touch $@ \n")
self.writeln()
self.writeln(' '.join(["\t\tvcom $(VCOM_FLAGS)",
vhdl.vcom_opt, "-work", lib, "$< "]))
self.writeln("\t\t@" + mkdir_command +
" $(dir $@) && touch $@ \n\n")
def __create_copy_rule(self, name, src):
"""Get a Makefile rule named name, which depends on src, copying it to
......@@ -219,11 +217,13 @@ class VsimMakefileWriter(ActionMakefile):
return rule
def __get_rid_of_vsim_incdirs(self, vlog_opt=""):
"""Parse the VLOG options and purge the included dirs"""
if not vlog_opt:
vlog_opt = ""
vlogs = vlog_opt.split(' ')
ret = []
for v in vlogs:
if not v.startswith("+incdir+"):
ret.append(v)
for vlog_aux in vlogs:
if not vlog_aux.startswith("+incdir+"):
ret.append(vlog_aux)
return ' '.join(ret)
......@@ -21,6 +21,8 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
"""Module providing support for Xilinx Vivado synthesis"""
import subprocess
import sys
import os
......@@ -36,6 +38,7 @@ VIVADO_STANDARD_LIBS = ['ieee', 'std']
class ToolVivado(ActionMakefile):
"""Class providing the interface for Xilinx Vivado synthesis"""
TOOL_INFO = {
'name': 'vivado',
......@@ -50,11 +53,18 @@ class ToolVivado(ActionMakefile):
def __init__(self):
super(ToolVivado, self).__init__()
self.properties = []
self.files = []
self.filename = None
self.header = None
self.tclname = 'temporal.tcl'
def detect_version(self, path):
"""Get version from Xilinx Vivado binary program"""
return 'unknown'
def generate_synthesis_makefile(self, top_mod, tool_path):
"""Generate a synthesis Makefile for Xilinx Vivado"""
makefile_tmplt = string.Template("""PROJECT := ${project_name}
VIVADO_CRAP := \
run.tcl
......@@ -114,17 +124,14 @@ mrproper:
syn_post_cmd=syn_post_cmd,
vivado_sh_path=os.path.join(tool_path, "vivado"))
self.write(makefile_text)
for f in top_mod.incl_makefiles:
if os.path.exists(f):
self.write("include %s\n" % f)
for file_aux in top_mod.incl_makefiles:
if os.path.exists(file_aux):
self.write("include %s\n" % file_aux)
def generate_synthesis_project(
self, update=False, tool_version='', top_mod=None, fileset=None):
self.properties = []
self.files = []
"""Generate a Xilinx Vivado synthesis project"""
self.filename = top_mod.manifest_dict["syn_project"]
self.header = None
self.tclname = 'temporal.tcl'
if update is True:
logging.info("Existing project detected: updating...")
self.update_project()
......@@ -138,29 +145,30 @@ mrproper:
self.add_files(fileset)
self.emit()
self.execute()
logging.info("Vivado project file generated.")
def emit(self):
f = open(self.tclname, "w")
f.write(self.header + '\n')
for p in self.properties:
f.write(p.emit() + '\n')
f.write(self.__emit_files())
f.write('update_compile_order -fileset sources_1\n')
f.write('update_compile_order -fileset sim_1\n')
f.write('exit\n')
f.close()
"""Emit the TCL file that will be feeded to the Vivado interpreter"""
file_aux = open(self.tclname, "w")
file_aux.write(self.header + '\n')
for prop in self.properties:
file_aux.write(prop.emit() + '\n')
file_aux.write(self.__emit_files())
file_aux.write('update_compile_order -fileset sources_1\n')
file_aux.write('update_compile_order -fileset sim_1\n')
file_aux.write('exit\n')
file_aux.close()
def execute(self):
"""Feed the TCL file to the Xilinx Vivado command line interpreter"""
tmp = 'vivado -mode tcl -source {0}'
cmd = tmp.format(self.tclname)
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
process_aux = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
# But do not wait till Vivado finish, start displaying output
# immediately ##
while True:
out = p.stderr.read(1)
if out == '' and p.poll() is not None:
out = process_aux.stderr.read(1)
if out == '' and process_aux.poll() is not None:
break
if out != '':
sys.stdout.write(out)
......@@ -168,20 +176,20 @@ mrproper:
os.remove(self.tclname)
def add_files(self, fileset):
for f in fileset:
self.files.append(f)
"""Add files to the inner fileset"""
for file_aux in fileset:
self.files.append(file_aux)
def add_property(self, new_property):
"""Add a new propertiy to the Xilinx Vivado project"""
self.properties.append(new_property)
def add_initial_properties(self,
syn_device,
syn_grade,
syn_package,
syn_top):
PAPP = _VivadoProjectProperty
def add_initial_properties(self, syn_device, syn_grade,
syn_package, syn_top):
"""Add initial properties to the Xilinx Vivado project"""
vivado_prop = _VivadoProjectProperty
self.add_property(
PAPP(
vivado_prop(
name='part',
value=syn_device +
syn_package +
......@@ -191,51 +199,64 @@ mrproper:
# value='em.avnet.com:microzed_7010:part0:1.0',
# objects='current_project'))
self.add_property(
PAPP(name='target_language',
value='VHDL',
objects='current_project'))
vivado_prop(name='target_language',
value='VHDL',
objects='current_project'))
# self.add_property(PAPP(name='ng.output_hdl_format', value='VHDL', objects='get_filesets sim_1'))
# self.add_property(PAPP(name='ng.output_hdl_format',
# value='VHDL', objects='get_filesets sim_1'))
# the bitgen b arg generates a raw configuration bitstream
# self.add_property(PAPP(name='steps.bitgen.args.b', value='true',
# objects='get_runs impl_1'))
self.add_property(
PAPP(name='top',
value=syn_top,
objects='get_property srcset [current_run]'))
vivado_prop(name='top',
value=syn_top,
objects='get_property srcset [current_run]'))
def create_project(self):
"""Create an empty Xilinx Vivado project"""
tmp = 'create_project {0} ./'
self.header = tmp.format(self.filename)
def update_project(self):
"""Update an existing Xilinx Vivado project"""
tmp = 'open_project ./{0}'
self.header = tmp.format(self.filename + '.xpr')
def __emit_properties(self):
"""Emit the properties to be added to the project"""
tmp = "set_property {0} {1} [{2}]"
ret = []
for p in self.properties:
line = tmp.format(p.name, p.value, p.objects)
for prop in self.properties:
line = tmp.format(prop.name, prop.value, prop.objects)
ret.append(line)
return ('\n'.join(ret)) + '\n'
def __emit_files(self):
"""Emit the design HDL files that must be added to the project"""
tmp = "add_files -norecurse {0}"
tcl = "source {0}"
ret = []
for f in self.files:
if isinstance(f, VHDLFile) or isinstance(f, VerilogFile) or isinstance(f, SVFile) or isinstance(f, UCFFile) or isinstance(f, NGCFile) or isinstance(f, XMPFile) or isinstance(f, XCOFile) or isinstance(f, BDFile):
line = tmp.format(f.rel_path())
elif isinstance(f, TCLFile):
line = tcl.format(f.rel_path())
for file_aux in self.files:
if (isinstance(file_aux, VHDLFile) or
isinstance(file_aux, VerilogFile) or
isinstance(file_aux, SVFile) or
isinstance(file_aux, UCFFile) or
isinstance(file_aux, NGCFile) or
isinstance(file_aux, XMPFile) or
isinstance(file_aux, XCOFile) or
isinstance(file_aux, BDFile)):
line = tmp.format(file_aux.rel_path())
elif isinstance(file_aux, TCLFile):
line = tcl.format(file_aux.rel_path())
else:
continue
ret.append(line)
return ('\n'.join(ret)) + '\n'
class _VivadoProjectProperty:
class _VivadoProjectProperty(object):
"""Class providing an storage for Xilinx Vivado properties"""
def __init__(self, name=None, value=None, objects=None):
self.name = name
......@@ -243,6 +264,8 @@ class _VivadoProjectProperty:
self.objects = objects
def emit(self):
"""Emit the Xilinx Vivado property the class instance contains"""
tmp = "set_property {0} {1} [{2}]"
line = tmp.format(self.name, self.value, self.objects)
return(line)
return line
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