Refactoring: use the tools Makefile generators in a cleaner way

parent 295335c4
......@@ -34,8 +34,6 @@ from .module_pool import ModulePool
from . import fetch as fetch_mod
from ._version import __version__
from .tools import WriterSim, WriterSyn
def main():
"""This is the main function, where HDLMake starts.
......@@ -101,6 +99,39 @@ def main():
_action_runner(modules_pool)
def _load_tool(modules_pool):
"""Funtion that checks the provided module_pool and generate an
initialized instance of the the appropriated tool class"""
from hdlmake.tools import (ToolIVerilog, ToolISim, ToolModelsim,
ToolActiveHDL, ToolRiviera, ToolGHDL,
ToolISE, ToolPlanAhead, ToolVivado,
ToolQuartus, ToolDiamond, ToolLibero)
available_tools = {'iverilog': ToolIVerilog,
'isim': ToolISim,
'modelsim': ToolModelsim,
'active_hdl': ToolActiveHDL,
'riviera': ToolRiviera,
'ghdl': ToolGHDL,
'ise': ToolISE,
'planahead': ToolPlanAhead,
'vivado': ToolVivado,
'quartus': ToolQuartus,
'diamond': ToolDiamond,
'libero': ToolLibero}
manifest_dict = modules_pool.get_top_module().manifest_dict
if manifest_dict['action'] is 'simulation':
tool_name = manifest_dict['sim_tool']
elif manifest_dict['action'] is 'synthesis':
tool_name = manifest_dict['syn_tool']
else:
logging.error("Unknown action: %s", tool_name)
if tool_name in available_tools:
return available_tools[tool_name]()
else:
logging.error("Unknown tool: %s", tool_name)
quit()
def _action_runner(modules_pool):
"""Funtion that decodes and executed the action selected by the user"""
top_mod = modules_pool.get_top_module()
......@@ -116,11 +147,11 @@ def _action_runner(modules_pool):
"project.")
quit()
if top_mod.action == "simulation":
sim_writer = WriterSim(modules_pool)
sim_writer.simulation_makefile()
sim_writer = _load_tool(modules_pool)
sim_writer.simulation_makefile(modules_pool)
elif top_mod.action == "synthesis":
syn_writer = WriterSyn(modules_pool)
syn_writer.synthesis_project()
syn_writer = _load_tool(modules_pool)
syn_writer.synthesis_project(modules_pool)
# modules_pool.synthesis_makefile()
elif top_mod.action == "qsys_hw_tcl_update":
if not top_mod.manifest_dict["hw_tcl_filename"]:
......@@ -130,11 +161,11 @@ def _action_runner(modules_pool):
quit()
modules_pool.qsys_hw_tcl_update()
elif options.command == "make-simulation":
sim_writer = WriterSim(modules_pool)
sim_writer.simulation_makefile()
sim_writer = _load_tool(modules_pool)
sim_writer.simulation_makefile(modules_pool)
elif options.command == "make-synthesis":
syn_writer = WriterSyn(modules_pool)
syn_writer.synthesis_project()
syn_writer = _load_tool(modules_pool)
syn_writer.synthesis_project(modules_pool)
elif options.command == "fetch":
modules_pool.fetch()
elif options.command == "clean":
......
......@@ -20,4 +20,3 @@ from .quartus import ToolQuartus
from .diamond import ToolDiamond
from .libero import ToolLibero
from .writer import WriterSim, WriterSyn
......@@ -48,6 +48,7 @@ class ToolActiveHDL(ToolSim):
super(ToolActiveHDL, self).__init__()
self._tool_info.update(ToolActiveHDL.TOOL_INFO)
self._hdl_files.extend(ToolActiveHDL.HDL_FILES)
self._standard_libs.extend(ToolActiveHDL.STANDARD_LIBS)
self._clean_targets.update(ToolActiveHDL.CLEAN_TARGETS)
def makefile_sim_compilation(self):
......
......@@ -67,6 +67,7 @@ class ToolDiamond(ToolSyn):
self._tool_info.update(ToolDiamond.TOOL_INFO)
self._hdl_files.extend(ToolDiamond.HDL_FILES)
self._supported_files.extend(ToolDiamond.SUPPORTED_FILES)
self._standard_libs.extend(ToolDiamond.STANDARD_LIBS)
self._clean_targets.update(ToolDiamond.CLEAN_TARGETS)
self._tcl_controls.update(ToolDiamond.TCL_CONTROLS)
......
......@@ -54,6 +54,7 @@ class ToolGHDL(ToolSim):
super(ToolGHDL, self).__init__()
self._tool_info.update(ToolGHDL.TOOL_INFO)
self._hdl_files.extend(ToolGHDL.HDL_FILES)
self._standard_libs.extend(ToolGHDL.STANDARD_LIBS)
self._clean_targets.update(ToolGHDL.CLEAN_TARGETS)
self._simulator_controls.update(ToolGHDL.SIMULATOR_CONTROLS)
......
......@@ -100,6 +100,7 @@ class ToolISE(ToolSyn):
self._tool_info.update(ToolISE.TOOL_INFO)
self._hdl_files.extend(ToolISE.HDL_FILES)
self._supported_files.extend(ToolISE.SUPPORTED_FILES)
self._standard_libs.extend(ToolISE.STANDARD_LIBS)
self._clean_targets.update(ToolISE.CLEAN_TARGETS)
self._tcl_controls.update(ToolISE.TCL_CONTROLS)
......
......@@ -63,6 +63,7 @@ class ToolISim(ToolSim):
super(ToolISim, self).__init__()
self._tool_info.update(ToolISim.TOOL_INFO)
self._hdl_files.extend(ToolISim.HDL_FILES)
self._standard_libs.extend(ToolISim.STANDARD_LIBS)
self._clean_targets.update(ToolISim.CLEAN_TARGETS)
def makefile_sim_top(self):
......
......@@ -57,6 +57,7 @@ class ToolIVerilog(ToolSim):
super(ToolIVerilog, self).__init__()
self._tool_info.update(ToolIVerilog.TOOL_INFO)
self._hdl_files.extend(ToolIVerilog.HDL_FILES)
self._standard_libs.extend(ToolIVerilog.STANDARD_LIBS)
self._clean_targets.update(ToolIVerilog.CLEAN_TARGETS)
self._simulator_controls.update(ToolIVerilog.SIMULATOR_CONTROLS)
......
......@@ -68,6 +68,7 @@ class ToolLibero(ToolSyn):
self._tool_info.update(ToolLibero.TOOL_INFO)
self._hdl_files.extend(ToolLibero.HDL_FILES)
self._supported_files.extend(ToolLibero.SUPPORTED_FILES)
self._standard_libs.extend(ToolLibero.STANDARD_LIBS)
self._clean_targets.update(ToolLibero.CLEAN_TARGETS)
self._tcl_controls.update(ToolLibero.TCL_CONTROLS)
......
"""Module providing the simulation functionality for writing Makefiles"""
import os
import sys
import string
import logging
from .makefile import ToolMakefile
from hdlmake.util import path as path_mod
from hdlmake.srcfile import VerilogFile, VHDLFile, SVFile
from hdlmake.dep_file import DepFile
def _check_simulation_manifest(manifest_dict):
"""Check if the simulation keys are provided by the top manifest"""
if not manifest_dict["sim_top"]:
logging.error("sim_top variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest_dict["sim_tool"]:
logging.error("sim_tool variable must be set in the top manifest.")
sys.exit("Exiting")
class ToolSim(ToolMakefile):
......@@ -16,6 +29,30 @@ class ToolSim(ToolMakefile):
super(ToolSim, self).__init__()
self._simulator_controls = {}
def simulation_makefile(self, pool):
"""Execute the simulation action"""
_check_simulation_manifest(pool.top_module.manifest_dict)
pool.check_all_fetched_or_quit()
pool.env.check_tool(self)
logging.info("Generating " + self._tool_info['name'] +
" makefile for simulation.")
top_module = pool.get_top_module()
fset = pool.build_file_set(
top_module.manifest_dict["sim_top"],
standard_libs=self._standard_libs)
# Filter the not parseable files!
dep_files = fset.filter(DepFile)
# dep_solver.solve(dep_files)
self.makefile_setup(top_module, dep_files)
self.makefile_sim_top()
self.makefile_sim_options()
self.makefile_sim_local()
self.makefile_sim_sources()
self.makefile_sim_compilation()
self.makefile_sim_command()
self.makefile_sim_clean()
self.makefile_sim_phony()
def makefile_sim_top(self):
"""Generic method to write the simulation Makefile top section"""
top_parameter = string.Template("""\
......@@ -26,7 +63,12 @@ PWD := $$(shell pwd)
top_module=self.top_module.manifest_dict["sim_top"]))
def makefile_sim_options(self):
"""End stub method to write the synthesis Makefile options section"""
"""End stub method to write the simulation Makefile options section"""
pass
def makefile_sim_compilation(self):
"""End stub method to write the simulation Makefile compilation
section"""
pass
def makefile_sim_local(self):
......
"""Module providing the synthesis functionality for writing Makefiles"""
import sys
import logging
import string
from .makefile import ToolMakefile
from hdlmake.util import path as path_mod
def _check_synthesis_manifest(manifest_dict):
"""Check the manifest contains all the keys for a synthesis project"""
if not manifest_dict["syn_tool"]:
logging.error(
"syn_tool variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest_dict["syn_device"]:
logging.error(
"syn_device variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest_dict["syn_grade"]:
logging.error(
"syn_grade variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest_dict["syn_package"]:
logging.error(
"syn_package variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest_dict["syn_top"]:
logging.error(
"syn_top variable must be set in the top manifest.")
class ToolSyn(ToolMakefile):
"""Class that provides the synthesis Makefile writing methods and status"""
......@@ -13,6 +38,45 @@ class ToolSyn(ToolMakefile):
def __init__(self):
super(ToolSyn, self).__init__()
def synthesis_project(self, pool):
"""Generate a project for the specific synthesis tool"""
_check_synthesis_manifest(pool.top_module.manifest_dict)
pool.check_all_fetched_or_quit()
tool_info = self._tool_info
path_key = tool_info['id'] + '_path'
name = tool_info['name']
env = pool.env
env.check_tool(self)
top_module = pool.get_top_module()
if env[path_key]:
tool_path = env[path_key]
else:
tool_path = ""
fileset = pool.build_file_set(
top_module.manifest_dict["syn_top"],
standard_libs=self._standard_libs)
sup_files = pool.build_complete_file_set()
privative_files = []
for file_aux in sup_files:
if any(isinstance(file_aux, file_type)
for file_type in self._supported_files):
privative_files.append(file_aux)
if len(privative_files) > 0:
logging.info("Detected %d supported files that are not parseable",
len(privative_files))
fileset.add(privative_files)
self.makefile_setup(top_module, fileset)
self.makefile_includes()
self.makefile_syn_top(tool_path)
self.makefile_syn_tcl()
self.makefile_syn_files()
self.makefile_syn_local()
self.makefile_syn_command()
self.makefile_syn_build()
self.makefile_syn_clean()
self.makefile_syn_phony()
logging.info(name + " project file generated.")
def makefile_syn_top(self, tool_path):
"""Create the top part of the synthesis Makefile"""
if path_mod.check_windows():
......@@ -99,6 +163,10 @@ export TCL_BITSTREAM
tcl_par=self._tcl_controls["par"],
tcl_bitstream=self._tcl_controls["bitstream"]))
def makefile_syn_files(self):
"""End stub method to write the synthesis files section"""
pass
def makefile_syn_local(self):
"""Generic method to write the synthesis Makefile local target"""
self.writeln("#target for performing local synthesis\n"
......
......@@ -41,6 +41,7 @@ class ToolMakefile(object):
self._tcl_controls = {}
self._hdl_files = []
self._supported_files = []
self._standard_libs = []
self.top_module = None
self.fileset = None
if filename:
......
......@@ -53,6 +53,7 @@ class ToolModelsim(VsimMakefileWriter):
self.additional_deps.append("modelsim.ini")
self._tool_info.update(ToolModelsim.TOOL_INFO)
self._clean_targets.update(ToolModelsim.CLEAN_TARGETS)
self._standard_libs.extend(ToolModelsim.STANDARD_LIBS)
def makefile_sim_options(self):
"""Print the Modelsim options to the Makefile"""
......
......@@ -54,5 +54,6 @@ class ToolPlanAhead(ToolXilinx):
super(ToolPlanAhead, self).__init__()
self._tool_info.update(ToolPlanAhead.TOOL_INFO)
self._supported_files.extend(ToolPlanAhead.SUPPORTED_FILES)
self._standard_libs.extend(ToolPlanAhead.STANDARD_LIBS)
self._clean_targets.update(ToolPlanAhead.CLEAN_TARGETS)
self._tcl_controls.update(ToolPlanAhead.TCL_CONTROLS)
......@@ -86,6 +86,7 @@ class ToolQuartus(ToolSyn):
self._tool_info.update(ToolQuartus.TOOL_INFO)
self._hdl_files.extend(ToolQuartus.HDL_FILES)
self._supported_files.extend(ToolQuartus.SUPPORTED_FILES)
self._standard_libs.extend(ToolQuartus.STANDARD_LIBS)
self._clean_targets.update(ToolQuartus.CLEAN_TARGETS)
self._tcl_controls.update(ToolQuartus.TCL_CONTROLS)
......
......@@ -81,4 +81,5 @@ class ToolRiviera(VsimMakefileWriter):
super(ToolRiviera, self).__init__()
self.vcom_flags.append("-2008")
self._tool_info.update(ToolRiviera.TOOL_INFO)
self._standard_libs.extend(ToolRiviera.STANDARD_LIBS)
self._clean_targets.update(ToolRiviera.CLEAN_TARGETS)
......@@ -64,6 +64,7 @@ class ToolVivado(ToolXilinx, ToolSim):
super(ToolVivado, self).__init__()
self._tool_info.update(ToolVivado.TOOL_INFO)
self._supported_files.extend(ToolVivado.SUPPORTED_FILES)
self._standard_libs.extend(ToolVivado.STANDARD_LIBS)
self._clean_targets.update(ToolVivado.CLEAN_TARGETS)
self._tcl_controls.update(ToolVivado.TCL_CONTROLS)
self._simulator_controls.update(ToolVivado.SIMULATOR_CONTROLS)
......
"""Package containing the classes required to print a Makefile"""
import logging
import sys
from hdlmake.dep_file import DepFile
from hdlmake.tools import (
ToolIVerilog, ToolISim, ToolModelsim,
ToolActiveHDL, ToolRiviera, ToolGHDL)
from hdlmake.tools import (
ToolISE, ToolPlanAhead, ToolVivado,
ToolQuartus, ToolDiamond, ToolLibero)
class WriterSim(object):
"""Class that is in charge of writing simulation Makefiles"""
def __init__(self, module_pool):
self.pool = module_pool
self.iverilog = ToolIVerilog()
self.isim = ToolISim()
self.modelsim = ToolModelsim()
self.active_hdl = ToolActiveHDL()
self.riviera = ToolRiviera()
self.ghdl = ToolGHDL()
self.vivado = ToolVivado()
def _check_simulation_makefile(self):
"""Check if the simulation keys are provided by the top manifest"""
if not self.pool.get_top_module().manifest_dict["sim_top"]:
logging.error("sim_top variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.pool.get_top_module().manifest_dict["sim_tool"]:
logging.error("sim_tool variable must be set in the top manifest.")
sys.exit("Exiting")
def simulation_makefile(self):
"""Execute the simulation action"""
self._check_simulation_makefile()
self.pool.check_all_fetched_or_quit()
tool_name = self.pool.get_top_module().manifest_dict["sim_tool"]
tool_dict = {"iverilog": self.iverilog,
"isim": self.isim,
"modelsim": self.modelsim,
"active-hdl": self.active_hdl,
"riviera": self.riviera,
"ghdl": self.ghdl,
"vivado": self.vivado}
if not tool_name in tool_dict:
logging.error("Unknown sim_tool: %s", tool_name)
sys.exit("Exiting")
tool_object = tool_dict[tool_name]
tool_info = tool_object.TOOL_INFO
name = tool_info['name']
self.pool.env.check_tool(tool_object)
logging.info("Generating " + name + " makefile for simulation.")
top_module = self.pool.get_top_module()
fset = self.pool.build_file_set(
top_module.manifest_dict["sim_top"],
standard_libs=tool_object.STANDARD_LIBS)
# Filter the not parseable files!
dep_files = fset.filter(DepFile)
# dep_solver.solve(dep_files)
tool_object.makefile_setup(top_module, dep_files)
tool_object.makefile_sim_top()
tool_object.makefile_sim_options()
tool_object.makefile_sim_local()
tool_object.makefile_sim_sources()
tool_object.makefile_sim_compilation()
tool_object.makefile_sim_command()
tool_object.makefile_sim_clean()
tool_object.makefile_sim_phony()
class WriterSyn(object):
"""Class that is in charge of writing synthesis Makefiles"""
def __init__(self, module_pool):
self.pool = module_pool
self.ise = ToolISE()
self.planahead = ToolPlanAhead()
self.vivado = ToolVivado()
self.quartus = ToolQuartus()
self.diamond = ToolDiamond()
self.libero = ToolLibero()
def _load_synthesis_tool(self):
"""Returns a tool_object that provides the synthesis tool interface"""
tool_name = self.pool.get_top_module().manifest_dict["syn_tool"]
tool_dict = {"ise": self.ise,
"planahead": self.planahead,
"vivado": self.vivado,
"quartus": self.quartus,
"diamond": self.diamond,
"libero": self.libero}
if not tool_name in tool_dict:
logging.error("Synthesis tool not recognized: %s", tool_name)
quit()
return tool_dict[tool_name]
def _check_synthesis_project(self):
"""Check the manifest contains all the keys for a synthesis project"""
manifest = self.pool.get_top_module().manifest_dict
if not manifest["syn_tool"]:
logging.error(
"syn_tool variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_device"]:
logging.error(
"syn_device variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_grade"]:
logging.error(
"syn_grade variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_package"]:
logging.error(
"syn_package variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_top"]:
logging.error(
"syn_top variable must be set in the top manifest.")
sys.exit("Exiting")
def synthesis_project(self):
"""Generate a project for the specific synthesis tool"""
self._check_synthesis_project()
self.pool.check_all_fetched_or_quit()
tool_object = self._load_synthesis_tool()
tool_info = tool_object.TOOL_INFO
path_key = tool_info['id'] + '_path'
name = tool_info['name']
env = self.pool.env
env.check_tool(tool_object)
top_module = self.pool.get_top_module()
if env[path_key]:
tool_path = env[path_key]
else:
tool_path = ""
fileset = self.pool.build_file_set(
top_module.manifest_dict["syn_top"],
standard_libs=tool_object.STANDARD_LIBS)
sup_files = self.pool.build_complete_file_set()
privative_files = []
for file_aux in sup_files:
if any(isinstance(file_aux, file_type)
for file_type in tool_object.SUPPORTED_FILES):
privative_files.append(file_aux)
if len(privative_files) > 0:
logging.info("Detected %d supported files that are not parseable",
len(privative_files))
fileset.add(privative_files)
tool_object.makefile_setup(top_module, fileset)
tool_object.makefile_includes()
tool_object.makefile_syn_top(tool_path)
tool_object.makefile_syn_tcl()
tool_object.makefile_syn_files()
tool_object.makefile_syn_local()
tool_object.makefile_syn_command()
tool_object.makefile_syn_build()
tool_object.makefile_syn_clean()
tool_object.makefile_syn_phony()
logging.info(name + " project file generated.")
......@@ -28,9 +28,6 @@ from .make_syn import ToolSyn
from hdlmake.srcfile import VHDLFile, VerilogFile, SVFile, TCLFile
VIVADO_STANDARD_LIBS = ['ieee', 'std']
class ToolXilinx(ToolSyn):
"""Class providing the interface for Xilinx Vivado synthesis"""
......
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