Commit cff1a962 authored by garcialasheras's avatar garcialasheras

Base multi-tool support update

parent 9e679858
This diff is collapsed.
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -24,11 +25,11 @@ from check_manifest import CheckManifest
from clean import CleanModules
from fetch import FetchModules
from fetch_makefile import GenerateFetchMakefile
from ise_makefile import GenerateISEMakefile
from ise_project import GenerateISEProject
from list_files import ListFiles
from list_modules import ListModules
from merge_cores import MergeCores
from quartus_project import GenerateQuartusProject
from synthesis_project import GenerateSynthesisProject
from synthesis import GenerateSynthesisMakefile
from remote_synthesis import GenerateRemoteSynthesisMakefile
from simulation import GenerateSimulationMakefile
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
#
# This file is part of Hdlmake.
#
# Hdlmake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hdlmake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import logging
import os
from dependable_file import DependableFile
from action import Action
from tools.quartus import QuartusProject
class GenerateQuartusProject(Action):
def run(self):
if self.env["quartus_path"] is None:
logging.error("Can't generate a Quartus project. Quartus not found.")
quit()
else:
logging.info("Generating/updating Quartus project.")
self._check_all_fetched_or_quit()
if os.path.exists(self.top_module.syn_project) or os.path.exists(self.top_module.syn_project + ".qsf"):
self._update_existing_quartus_project()
else:
self._create_new_quartus_project()
logging.info("Quartus project file generated.")
def _create_new_quartus_project(self):
top_mod = self.modules_pool.get_top_module()
fileset = self.modules_pool.build_file_set()
non_dependable = fileset.inversed_filter(DependableFile)
fileset.add(non_dependable)
prj = QuartusProject(top_mod.syn_project)
prj.add_files(fileset)
prj.add_initial_properties(top_mod.syn_device,
top_mod.syn_grade,
top_mod.syn_package,
top_mod.syn_top)
prj.preflow = top_mod.quartus_preflow
prj.postflow = top_mod.quartus_postflow
prj.emit()
def _update_existing_quartus_project(self):
top_mod = self.modules_pool.get_top_module()
fileset = self.modules_pool.build_file_set()
non_dependable = fileset.inversed_filter(DependableFile)
fileset.add(non_dependable)
prj = QuartusProject(top_mod.syn_project)
prj.read()
prj.preflow = top_mod.quartus_preflow
prj.postflow = top_mod.quartus_postflow
prj.add_files(fileset)
prj.emit()
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -26,29 +27,10 @@ import sys
import global_mod
from srcfile import SourceFileFactory
import importlib
class GenerateRemoteSynthesisMakefile(Action):
def run(self):
self._check_all_fetched_or_quit()
logging.info("Generating makefile for remote synthesis.")
top_mod = self.modules_pool.get_top_module()
tcl = self._search_tcl_file()
if tcl is None:
self._generate_tcl()
tcl = "run.tcl"
files = self.modules_pool.build_global_file_set()
sff = SourceFileFactory()
files.add(sff.new(tcl, module=None))
files.add(sff.new(top_mod.syn_project, module=None))
global_mod.makefile_writer.generate_remote_synthesis_makefile(files=files, name=top_mod.syn_name,
cwd=os.getcwd(), user=self.env["rsynth_user"],
server=self.env["rsynth_server"])
logging.info("Remote synthesis makefile generated.")
class GenerateRemoteSynthesisMakefile(Action):
def _check_manifest(self):
if not self.top_module.action == "synthesis":
......@@ -59,7 +41,16 @@ class GenerateRemoteSynthesisMakefile(Action):
logging.error("syn_project must be set in the manifest.")
sys.exit("Exiting")
def run(self):
self._check_all_fetched_or_quit()
self._check_manifest()
tool_object = global_mod.tool_module.ToolControls()
self._generate_remote_synthesis_makefile(tool_object)
def _search_tcl_file(self, directory=None):
# This function is used in _generate_remote_ise_makefile
if directory is None:
directory = "."
filenames = os.listdir(directory)
......@@ -76,7 +67,33 @@ class GenerateRemoteSynthesisMakefile(Action):
return tcls[0]
def _generate_tcl(self):
# This function is used in _generate_remote_ise_makefile
f = open("run.tcl", "w")
f.write("project open " + self.top_module.syn_project + '\n')
f.write("process run {Generate Programming File} -force rerun_all\n")
f.close()
def _generate_remote_synthesis_makefile(self, tool_object):
logging.info("Generating makefile for remote synthesis.")
top_mod = self.modules_pool.get_top_module()
tcl = self._search_tcl_file()
if tcl is None:
self._generate_tcl()
tcl = "run.tcl"
files = self.modules_pool.build_global_file_set()
sff = SourceFileFactory()
files.add(sff.new(tcl, module=None))
files.add(sff.new(top_mod.syn_project, module=None))
tool_object.generate_remote_synthesis_makefile(files=files, name=top_mod.syn_name,
cwd=os.getcwd(), user=self.env["rsynth_user"],
server=self.env["rsynth_server"])
logging.info("Remote synthesis makefile generated.")
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -27,72 +28,52 @@ import logging
import sys
import global_mod
import importlib
class GenerateSimulationMakefile(Action):
def _check_manifest(self):
if not self.modules_pool.get_top_module().top_module:
logging.error("top_module variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.modules_pool.get_top_module().sim_tool:
logging.error("sim_tool variable must be set in the top manifest.")
sys.exit("Exiting")
def run(self):
self._check_all_fetched_or_quit()
self._check_manifest()
tm = self.modules_pool.top_module
if tm.sim_tool == "iverilog":
logging.info("Generating simulation makefile for iverilog")
self._generate_iverilog_makefile()
elif tm.sim_tool == "isim":
self._generate_isim_makefile()
logging.info("Generating simulation makefile for isim")
elif tm.sim_tool == "vsim" or tm.sim_tool == "modelsim":
self._generate_vsim_makefile()
logging.info("Generating simulation makefile for vsim")
else:
logging.error("Unrecognized or not specified simulation tool: %s\nPlease set sim_tool in the top manifest." % str(tm.sim_tool))
sys.exit("Exiting")
tool_object = global_mod.tool_module.ToolControls()
self._generate_simulation_makefile(tool_object)
logging.info("Simulation makefile generated.")
def _generate_vsim_makefile(self):
if self.env["modelsim_path"] is None and self.options.force is not True:
logging.error("Can't generate a Modelsim makefile. Modelsim not found.")
sys.exit("Exiting")
logging.info("Generating ModelSim makefile for simulation.")
pool = self.modules_pool
top_module = pool.get_top_module()
fset = pool.build_file_set()
dep_files = fset.filter(DepFile)
dep_solver.solve(dep_files)
global_mod.makefile_writer.generate_vsim_makefile(dep_files, top_module)
def _generate_simulation_makefile(self, tool_object):
def _generate_isim_makefile(self):
if self.env["isim_path"] is None and self.env["xilinx"] is None:
logging.error("Can't generate an ISim makefile. ISim not found.")
tool_info = tool_object.get_keys()
if sys.platform == 'cygwin':
bin_name = tool_info['windows_bin']
else:
bin_name = tool_info['linux_bin']
path_key = tool_info['id'] + '_path'
version_key = tool_info['id'] + '_version'
name = tool_info['name']
if self.env[path_key] is None and self.options.force is not True:
logging.error("Can't generate a " + name + " makefile. " + bin_name + " not found.")
sys.exit("Exiting")
logging.info("Generating ISE Simulation (ISim) makefile for simulation.")
logging.info("Generating " + name + " makefile for simulation.")
pool = self.modules_pool
top_module = pool.get_top_module()
fset = pool.build_file_set()
dep_files = fset.filter(DepFile)
dep_solver.solve(dep_files)
global_mod.makefile_writer.generate_isim_makefile(dep_files, top_module)
def _generate_iverilog_makefile(self):
logging.info("Generating IVerilog makefile for simulation.")
if self.env["iverilog_path"] is None:
logging.error("Can't generate an IVerilog makefile. IVerilog not found.")
sys.exit("Exiting")
pool = self.modules_pool
tm = pool.get_top_module()
fset = pool.build_file_set()
dep_solver.solve(fset)
tool_object.generate_simulation_makefile(dep_files, top_module)
global_mod.makefile_writer.generate_iverilog_makefile(fset, tm, pool)
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -20,22 +21,54 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from action import Action
from dep_file import DepFile
import new_dep_solver as dep_solver
import logging
import sys
import global_mod
from action import Action
import importlib
class GenerateSynthesisMakefile(Action):
class GenerateISEMakefile(Action):
def _check_manifest(self):
self._check_manifest_variable_is_set("syn_tool")
# NOTE: top_module is not used in synthesis!!
if not self.modules_pool.get_top_module().syn_top:
logging.error("syn_top variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.modules_pool.get_top_module().syn_tool:
logging.error("syn_tool variable must be set in the top manifest.")
sys.exit("Exiting")
def run(self):
logging.info("Generating makefile for local synthesis.")
if global_mod.env["ise_path"]:
ise_path = global_mod.env["ise_path"]
self._check_all_fetched_or_quit()
self._check_manifest()
tool_object = global_mod.tool_module.ToolControls()
self._generate_synthesis_makefile(tool_object)
def _generate_synthesis_makefile(self, tool_object):
tool_info = tool_object.get_keys()
if sys.platform == 'cygwin':
bin_name = tool_info['windows_bin']
else:
bin_name = tool_info['linux_bin']
path_key = tool_info['id'] + '_path'
version_key = tool_info['id'] + '_version'
name = tool_info['name']
if global_mod.env[path_key]:
tool_path = global_mod.env[path_key]
else:
ise_path = ""
tool_path = ""
logging.info("Generating synthesis makefile for " + name)
tool_object.generate_synthesis_makefile(top_mod=self.modules_pool.get_top_module(),
tool_path=tool_path)
logging.info("Synthesis makefile generated.")
global_mod.makefile_writer.generate_ise_makefile(top_mod=self.modules_pool.get_top_module(),
ise_path=ise_path)
logging.info("Local synthesis makefile generated.")
\ No newline at end of file
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -25,73 +26,43 @@ from action import Action
import sys
import os
import new_dep_solver as dep_solver
from tools.ise import ISEProject
from srcfile import SourceFileFactory
from dependable_file import DependableFile
import global_mod
from util import path
import importlib
class GenerateISEProject(Action):
def _check_manifest(self):
# self._check_manifest_variable_is_set("top_module")
self._check_manifest_variable_is_set("syn_device")
self._check_manifest_variable_is_set("syn_grade")
self._check_manifest_variable_is_set("syn_package")
self._check_manifest_variable_is_set("syn_top")
def _check_env(self):
env = self.env
if not self.options.force:
if self.env["ise_path"] is None:
logging.error("Can't generate an ISE project. ISE not found.")
quit()
if not env["ise_version"]:
logging.error("Xilinx version cannot be deduced. Cannot generate ISE "
"project file properly. Please use syn_ise_version in the manifest "
"or set")
sys.exit("Exiting")
logging.info("Generating project for ISE v. %s" % env["ise_version"])
def run(self):
self._check_all_fetched_or_quit()
logging.info("Generating/updating ISE project file.")
if os.path.exists(self.top_module.syn_project) or os.path.exists(self.top_module.syn_project + ".xise"):
self._handle_ise_project(update=True)
else:
self._handle_ise_project(update=False)
logging.info("ISE project file generated.")
class GenerateSynthesisProject(Action):
def _handle_ise_project(self, update=False):
top_mod = self.modules_pool.get_top_module()
fileset = self.modules_pool.build_file_set()
flist = dep_solver.make_dependency_sorted_list(fileset)
assert isinstance(flist, list)
def _check_manifest(self):
if not self.modules_pool.get_top_module().syn_tool:
logging.error("syn_tool variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.modules_pool.get_top_module().syn_device:
logging.error("syn_device variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.modules_pool.get_top_module().syn_grade:
logging.error("syn_grade variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.modules_pool.get_top_module().syn_package:
logging.error("syn_package variable must be set in the top manifest.")
sys.exit("Exiting")
if not self.modules_pool.get_top_module().syn_top:
logging.error("syn_top variable must be set in the top manifest.")
sys.exit("Exiting")
prj = ISEProject(ise=self.env["ise_version"],
top_mod=self.modules_pool.get_top_module())
prj.add_files(flist)
sff = SourceFileFactory()
logging.debug(top_mod.vlog_opt)
if self.options.generate_project_vhd:
self._write_project_vhd()
prj.add_files([sff.new(path=path.rel2abs("project.vhd"),
module=self.modules_pool.get_module_by_path("."))])\
def run(self):
self._check_all_fetched_or_quit()
self._check_manifest()
tool_object = global_mod.tool_module.ToolControls()
self._generate_synthesis_project(tool_object)
prj.add_libs(fileset.get_libs())
if update is True:
try:
prj.load_xml(top_mod.syn_project)
except:
logging.error("Error while reading the project file.\n"
"Are you sure that syn_project indicates a correct ISE project file?")
raise
else:
prj.add_initial_properties()
logging.info("Writing down .xise project file")
prj.emit_xml(top_mod.syn_project)
def _write_project_vhd(self):
def _write_project_vhd(self, tool, version):
from string import Template
from datetime import date
import getpass
......@@ -141,7 +112,7 @@ end sdb_meta_pkg;""")
for digit in date_string:
date_std_logic_vector.append("{0:04b}".format(int(digit)))
syn_tool_version = global_mod.env["ise_version"]
syn_tool_version = version
syn_tool_version = re.sub("\D", "", syn_tool_version)
syn_tool_std_logic_vector = []
for digit in syn_tool_version:
......@@ -150,7 +121,7 @@ end sdb_meta_pkg;""")
filled_template = template.substitute(repo_url=global_mod.top_module.url,
syn_module_name=global_mod.top_module.syn_top,
syn_commit_id=global_mod.top_module.revision,
syn_tool_name="ISE",
syn_tool_name=tool.upper(),
syn_tool_version="0000"*(8-len(syn_tool_std_logic_vector))+''.join(syn_tool_std_logic_vector),
syn_tool_version_str=syn_tool_version,
syn_date=''.join(date_std_logic_vector),
......@@ -158,3 +129,59 @@ end sdb_meta_pkg;""")
syn_username=getpass.getuser())
project_vhd.write(filled_template)
project_vhd.close()
def _generate_synthesis_project(self, tool_object):
tool_info = tool_object.get_keys()
if sys.platform == 'cygwin':
bin_name = tool_info['windows_bin']
else:
bin_name = tool_info['linux_bin']
path_key = tool_info['id'] + '_path'
version_key = tool_info['id'] + '_version'
name = tool_info['name']
id_value = tool_info['id']
ext_value = tool_info['project_ext']
env = self.env
if not self.options.force:
if self.env[path_key] is None:
logging.error("Can't generate an " + name + " project. " + name + " not found.")
quit()
if not env[version_key]:
logging.error(name + " version cannot be deduced. Cannot generate " + name + " "
"project file properly. Please use syn_" + id_value + "_version in the manifest "
"or set")
sys.exit("Exiting")
logging.info("Generating project for " + name + " v. %s" % env[version_key])
if os.path.exists(self.top_module.syn_project) or os.path.exists(self.top_module.syn_project + "." + ext_value):
logging.info("Existing project detected: updating...")
update=True
else:
logging.info("No previous project: creating a new one...")
update=False
top_mod = self.modules_pool.get_top_module()
fileset = self.modules_pool.build_file_set()
non_dependable = fileset.inversed_filter(DependableFile)
fileset.add(non_dependable)
sff = SourceFileFactory()
if self.options.generate_project_vhd:
self._write_project_vhd(id_value, env[version_key])
fileset.add([sff.new(path=path.rel2abs("project.vhd"),
module=self.modules_pool.get_module_by_path("."))])\
tool_object.generate_synthesis_project(update=update,
tool_version=self.env[version_key],
top_mod=self.modules_pool.get_top_module(),
fileset = fileset)
logging.info(name + " project file generated.")
This diff is collapsed.
......@@ -26,4 +26,5 @@ from git import Git
GIT = 1
SVN = 2
LOCAL = 3
GITSUBMODULE = 4
\ No newline at end of file
GITSUBMODULE = 4
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -21,16 +22,11 @@
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
from makefile_writer import MakefileWriter
options = None
top_module = None
global_target = "''"
mod_pool = None
sim_tool = None
env = None
makefile_writer = MakefileWriter()
#######
#this var is modified by the build makefile - DON'T TOUCH IT!
BUILD_ID = "2013Feb22:341efe"
######
tool_module = None
This diff is collapsed.
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -72,6 +73,7 @@ class ManifestParser(ConfigParser):
self.add_delimiter()
self.add_option('quartus_preflow', default=None, help = "Quartus pre-flow script file", type = '')
self.add_option('quartus_postmodule', default=None, help = "Quartus post-module script file", type = '')
self.add_option('quartus_postflow', default=None, help = "Quartus post-flow script file", type = '')
self.add_delimiter()
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -37,7 +38,7 @@ class Module(object):
@source.setter
def source(self, value):
if value not in [fetch.GIT, fetch.SVN, fetch.LOCAL, fetch.GITSUBMODULE]:
raise ValueError("Inproper source: " + value)
raise ValueError("Improper source: " + value)
self._source = value
@source.deleter
......@@ -76,6 +77,7 @@ class Module(object):
self.vcom_opt = None
self.revision = None
self.quartus_preflow = None
self.quartus_postmodule = None
self.quartus_postflow = None
self._files = None
self.manifest = None
......@@ -403,6 +405,14 @@ class Module(object):
quit()
self.quartus_preflow = TCLFile(path)
if self.manifest_dict["quartus_postmodule"] != None:
path = path_mod.rel2abs(self.manifest_dict["quartus_postmodule"], self.path);
if not os.path.exists(path):
p.error("quartus_postmodule file listed in " + self.manifest.path + " doesn't exist: "
+ path + ".\nExiting.")
quit()
self.quartus_postmodule = TCLFile(path)
if self.manifest_dict["quartus_postflow"] != None:
path = path_mod.rel2abs(self.manifest_dict["quartus_postflow"], self.path);
if not os.path.exists(path):
......
#!/usr/bin/python
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -23,7 +24,8 @@
from __future__ import print_function
import logging
from dep_file import DepFile
import tools
import global_mod
class DepParser(object):
......@@ -88,7 +90,7 @@ def solve(fileset):
continue
if rel.rel_type is DepRelation.INCLUDE: # INCLUDE are already solved by preprocessor
continue
if rel.library() in tools.get_standard_libraries(): # dont care about standard libs
if rel.library() in global_mod.tool_module.ToolControls().get_standard_libraries(): # dont care about standard libs
continue
satisfied_by = set()
......
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Copyright (c) 2013, 2014 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Multi-tool support by Javier D. Garcia-Lasheras (javier@garcialasheras.com)
#
# This file is part of Hdlmake.
#
......@@ -25,9 +26,6 @@ import os
import global_mod
import logging
from module import Module
from tools import ise
from tools import modelsim
from tools import quartus
from util import path as path_mod
from dep_file import DepFile, File
......@@ -46,11 +44,6 @@ class SourceFile(DepFile):
include_paths=module.include_dirs[:])
# def gen_index(self):
# self.__class__.cur_index = self.__class__.cur_index+1
# return self.__class__.cur_index
class VHDLFile(SourceFile):
def __init__(self, path, module, library=None, vcom_opt=None):
SourceFile.__init__(self, path=path, module=module, library=library)
......@@ -68,89 +61,6 @@ class VHDLFile(SourceFile):
else:
return False
# def _create_deps_provides(self):
# if self._check_encryption():
# self.dep_index = SourceFile.gen_index(self)
# else:
# self.dep_provides = list(self._search_packages())
# logging.debug(self.path + " provides " + str(self.dep_provides))
# def _create_deps_requires(self):
# if self._check_encryption():
# self.dep_index = SourceFile.gen_index(self)
# else:
# self.dep_requires = list(self._search_use_clauses())
# logging.debug(self.path + " provides " + str(self.dep_provides))
# def _search_use_clauses(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.
# """
# # Modification here! global_mod.top_module.action does not
# # get set for top module in time. FIX this
# std_libs = ['std', 'ieee']
# if global_mod.top_module.action == "simulation":
# try:
# if global_mod.top_module.sim_tool == "isim":
# std_libs = ise.XilinxsiminiReader().get_libraries()
# elif global_mod.top_module.sim_tool == "vsim" or global_mod.top_module.sim_tool == "modelsim":
# std_libs = modelsim.ModelsiminiReader().get_libraries()
# elif global_mod.top_module.sim_tool == "iverilog":
# std_libs = modelsim.MODELSIM_STANDARD_LIBS
# else:
# logging.warning("Could not determine simulation tool. Defaulting to Modelsim")
# std_libs = modelsim.MODELSIM_STANDARD_LIBS
# except RuntimeError as e:
# logging.error("I/O error: ({0})".format(e.message))
# logging.error("Picking standard Modelsim simulation libraries. Try to fix the error.")
# std_libs = modelsim.MODELSIM_STARDAND_LIBS
# elif global_mod.top_module.action == "synthesis":
# if global_mod.top_module.target == "xilinx":
# std_libs = ise.ISE_STANDARD_LIBS
# elif global_mod.top_module.target == "altera":
# std_libs = quartus.QUARTUS_STANDARD_LIBS
# import re
# try:
# f = open(self.path, "r")
# 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:
# #identifiers and keywords are case-insensitive in VHDL
# line_lower = line.lower()
# m = re.match(use_pattern, line_lower)
# if m is not None:
# use_lines.append(m.group(1))
# ret = set()
# for line in use_lines:
# m = re.match(lib_pattern, line)
# if m is not None:
# #omit standard libraries
# if (m.group(1)).lower() in std_libs:
# continue
# if self.library != "work":
# #if a file is put in a library, `work' points this library
# new = (self.library.lower(), m.group(2).lower())
# else:
# new = (m.group(1).lower(), m.group(2).lower())
# #dont add if the tuple is already in the list
# if new in self.dep_provides:
# continue
# ret.add(new)
# f.close()
# return ret
class VerilogFile(SourceFile):
def __init__(self, path, module, library=None, vlog_opt=None, include_dirs=None):
......@@ -166,78 +76,6 @@ class VerilogFile(SourceFile):
self.include_dirs.extend(include_dirs)
self.include_dirs.append(path_mod.relpath(self.dirname))
# def _create_deps_provides(self):
# # self.dep_requires = self.__search_includes()
# # self.dep_provides = self.name
# self.dep_provides = self.name
# def _create_deps_requires(self):
# # self.dep_requires = self.__search_includes()
# # self.dep_provides = self.name
# if global_mod.top_module.sim_tool == "iverilog":
# deps = self._get_iverilog_dependencies()
# self.dep_requires = deps
# else:
# self.dep_requires = self._search_includes()
# def _get_iverilog_dependencies(self):
# #todo: check to see dependencies.list doesn't exist already
# if self.path.endswith(".vh") and global_mod.top_module.sim_tool == "iverilog":
# return []
# inc_dirs = []
# #inc_dirs = global_mod.top_module.include_dirs
# inc_dirs = self.include_dirs
# if global_mod.mod_pool:
# inc_dirs.extend([os.path.relpath(m.path) for m in global_mod.mod_pool])
# inc_dirs = list(set(inc_dirs))
# vlog_opt = global_mod.top_module.vlog_opt
# depfilename = "dependencies.list"
# command = "iverilog -dsimulate -wno-timescale -t null -m" + depfilename
# command += "".join(map(lambda x: " -y"+x, inc_dirs))
# command += "".join(map(lambda x: " -i"+x, inc_dirs))
# # todo: have to find a way to handle this cleanly
# if self.rel_path().find("config_romx_llrf4") > -1:
# command += " " + vlog_opt
# else:
# command += " " + vlog_opt + " " + self.rel_path()
# logging.debug("running %s" % command)
# retcode = os.system(command)
# # iverilog_cmd = popen(command, shell=true, stdin=pipe,
# # stdout=pipe, close_fds=true)
# # iverilog_cmd.stdout.readlines()
# # iverilog_cmd.wait()
# # retcode = iverilog_cmd.returncode
# print("retcode", retcode)
# if retcode and retcode != 256:
# logging.error("dependencies not met for %s" % str(self.path))
# logging.debug(command, self.include_dirs, inc_dirs, global_mod.mod_pool)
# quit()
# elif retcode == 256:
# #dependencies met
# pass
# depfile = open(depfilename, "r")
# depfiles = list(set([l.strip() for l in depfile.readlines()]))
# depfile.close()
# return depfiles
# def _search_includes(self):
# import re
# f = open(self.path, "r")
# try:
# text = f.readlines()
# except unicodedecodeerror:
# return []
# include_pattern = re.compile("^[ \t]*`include[ \t]+\"([^ \"]+)\".*$")
# ret = []
# for line in text:
# #in verilog and sv identifiers are case-sensitive
# m = re.match(include_pattern, line)
# if m is not none:
# ret.append(m.group(1))
# f.close()
# return ret
class SVFile(VerilogFile):
pass
......@@ -264,6 +102,7 @@ class SignalTapFile(File):
class SDCFile(File):
# Synopsys Design Constraints
pass
......@@ -275,12 +114,40 @@ class DPFFile(File):
pass
class XMPFile(File):
# Xilinx Embedded Micro Processor
pass
class PPRFile(File):
# Xilinx PlanAhead Project
pass
class XCOFile(File):
# Xilinx Core Generator File
pass
# class NGCFile(SourceFile):
# def __init__(self, path, module):
# SourceFile.__init__(self, path=path, module=module)
class NGCFile(File):
# Xilinx Generated Netlist File
pass
class LDFFile(File):
# Lattice Diamond Project File
pass
class LPFFile(File):
# Lattice Preference/Constraint File
pass
class EDFFile(File):
# EDIF Netlist Files
pass
class PDCFile(File):
# Physical Design Constraints
pass
class WBGenFile(File):
pass
......@@ -380,4 +247,18 @@ class SourceFileFactory:
nf = QIPFile(path=path, module=module)
elif extension == 'dpf':
nf = DPFFile(path=path, module=module)
elif extension == 'xmp':
nf = XMPFile(path=path, module=module)
elif extension == 'ppr':
nf = PPRFile(path=path, module=module)
elif extension == 'xco':
nf = XCOFile(path=path, module=module)
elif extension == 'ldf':
nf = LDFFile(path=path, module=module)
elif extension == 'lpf':
nf = LPFFile(path=path, module=module)
elif extension == 'edf' or extension == 'edif' or extension == 'edi' or extension == 'edn':
nf = EDFFile(path=path, module=module)
elif extension == 'pdc':
nf = PDCFile(path=path, module=module)
return nf
#!/usr/bin/env python
def get_standard_libraries():
import global_mod
import quartus
import ise
import modelsim
import iverilog
import isim
tm = global_mod.top_module
if tm.action == "simulation":
if tm.sim_tool == "modelsim" or tm.sim_tool == "vsim":
return modelsim.MODELSIM_STANDARD_LIBS
elif tm.sim_tool == "isim":
return isim.ISIM_STANDARD_LIBS
elif tm.sim_tool == "iverilog":
return iverilog.IVERILOG_STANDARD_LIBS
else:
if tm.syn_tool == "quartus":
return quartus.QUARTUS_STANDARD_LIBS
elif tm.syn_tool == "ise":
return ise.ISE_STANDARD_LIBS
This diff is collapsed.
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
#
# This file is part of Hdlmake.
#
# Hdlmake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hdlmake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
import os.path
from subprocess import Popen, PIPE
ISIM_STANDARD_LIBS = ['std', 'ieee', 'ieee_proposed', 'vl', 'synopsys',
'simprim', 'unisim', 'unimacro', 'aim', 'cpld',
'pls', 'xilinxcorelib', 'aim_ver', 'cpld_ver',
'simprims_ver', 'unisims_ver', 'uni9000_ver',
'unimacro_ver', 'xilinxcorelib_ver', 'secureip']
def detect_isim_version(path):
isim = Popen("%s --version | awk '{print $2}'" % os.path.join(path, "vlogcomp"),
shell=True,
close_fds=True,
stdin=PIPE,
stdout=PIPE)
print os.path.join(path, "vlogcomp")
try:
isim_version = isim.stdout.readlines()[0].strip()
except:
return None
return isim_version
#!/usr/bin/env python
from subprocess import Popen, PIPE
IVERILOG_STANDARD_LIBS = ['std', 'ieee', 'ieee_proposed', 'vl', 'synopsys',
'simprim', 'unisim', 'unimacro', 'aim', 'cpld',
'pls', 'xilinxcorelib', 'aim_ver', 'cpld_ver',
'simprims_ver', 'unisims_ver', 'uni9000_ver',
'unimacro_ver', 'xilinxcorelib_ver', 'secureip']
def detect_iverilog_version(path):
iverilog = Popen("iverilog -v 2>/dev/null| awk '{if(NR==1) print $4}'",
shell=True,
stdin=PIPE,
stdout=PIPE,
close_fds=True)
version = iverilog.stdout.readlines()[0].strip()
return version
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
# Modified to allow ISim simulation by Lucas Russo (lucas.russo@lnls.br)
# Modified to allow ISim simulation by Adrian Byszuk (adrian.byszuk@lnls.br)
#
# This file is part of Hdlmake.
#
# Hdlmake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hdlmake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import print_function
import xml.dom.minidom
import xml.parsers.expat
import re
import os
XmlImpl = xml.dom.minidom.getDOMImplementation()
MODELSIM_STANDARD_LIBS = ['ieee', 'std']
def detect_modelsim_version(path):
pass
class ModelsiminiReader(object):
def __init__(self, path=None):
if path is None:
path = os.path.join(global_mod.env["modelsim_path"], "/modelsim.ini")
self.path = path
def get_libraries(self):
new_section = "\[[^\[\]]+\]"
libs = []
try:
ini = open(self.path, "r")
except Exception:
return []
#p.info("Reading 'modelsim.ini' located in: '"+ str(self.path))
reading_libraries = False
for line in ini:
line = line.split(" ")[0]
line = line.strip()
if line == "":
continue
if line.lower() == "[library]":
reading_libraries = True
continue
if re.search(new_section, line):
if reading_libraries is True:
#reading_libraries = False
break
else:
continue
if reading_libraries:
line = line.split('=')
lib = line[0].strip()
libs.append(lib.lower())
return libs
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 CERN
# Author: Pawel Szostek (pawel.szostek@cern.ch)
#
# This file is part of Hdlmake.
#
# Hdlmake is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Hdlmake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
#
QUARTUS_STANDARD_LIBS = ['altera', 'altera_mf', 'lpm', 'ieee', 'std']
def detect_quartus_version(path):
pass
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}
def __init__(self, command, what=None, name=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.section_id = section_id
def emit(self):
words = []
words.append(dict([(b, a) for a, b in self.t.items()])[self.command])
if self.what is not None:
words.append(self.what)
if self.name is not None:
words.append("-name")
words.append(self.name_type)
words.append(self.name)
if self.from_ is not None:
words.append("-from")
words.append(self.from_)
if self.to is not None:
words.append("-to")
words.append(self.to)
if self.section_id is not None:
words.append("-section_id")
words.append(self.section_id)
return ' '.join(words)
class QuartusProject:
def __init__(self, filename):
self.properties = []
self.files = []
self.filename = filename
self.preflow = None
self.postflow = None
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()
def __emit_scripts(self):
tmp = 'set_global_assignment -name {0} "quartus_sh:{1}"'
pre = post = ""
if self.preflow:
pre = tmp.format("PRE_FLOW_SCRIPT_FILE", self.preflow.rel_path())
if self.postflow:
post = tmp.format("POST_FLOW_SCTIPT_FILE", self.postflow.rel_path())
return pre+'\n'+post+'\n'
def __emit_files(self):
from srcfile import VHDLFile, VerilogFile, SignalTapFile, SDCFile, QIPFile, DPFFile
tmp = "set_global_assignment -name {0} {1}"
ret = []
for f in self.files:
if isinstance(f, VHDLFile):
line = tmp.format("VHDL_FILE", f.rel_path())
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, DPFFile):
line = tmp.format("MISC_FILE", f.rel_path())
else:
continue
ret.append(line)
return ('\n'.join(ret))+'\n'
def add_property(self, val):
#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)
def read(self):
def __gather_string(words, first_index):
i = first_index
ret = []
if words[i][0] != '"':
return (words[i], 1)
else:
while True:
ret.append(words[i])
if words[i][len(words[i])-1] == '"':
return (' '.join(ret), len(ret))
i = i + 1
f = open(self.filename+'.qsf', "r")
lines = [l.strip() for l in f.readlines()]
lines = [l for l in lines if l != "" and l[0] != '#']
QPP = _QuartusProjectProperty
for line in lines:
words = line.split()
command = QPP.t[words[0]]
what = name = name_type = from_ = to = section_id = None
i = 1
while True:
if i >= len(words):
break
if words[i] == "-name":
name_type = words[i+1]
name, add = __gather_string(words, i+2)
i = i+2+add
continue
elif words[i] == "-section_id":
section_id, add = __gather_string(words, i+1)
i = i+1+add
continue
elif words[i] == "-to":
to, add = __gather_string(words, i+1)
i = i+1+add
continue
elif words[i] == "-from":
from_, add = __gather_string(words, i+1)
i = i+2
continue
else:
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)
self.add_property(prop)
f.close()
def add_initial_properties(self, syn_device, syn_grade, syn_package, syn_top):
import re
family_names = {
"^EP2AGX.*$": "Arria II GX",
"^EP3C.*$": "Cyclone III"
}
for key in family_names:
if re.match(key, syn_device.upper()):
family = family_names[key]
devstring = (syn_device + syn_package + syn_grade).upper()
QPP = _QuartusProjectProperty
self.add_property(QPP(QPP.SET_GLOBAL_ASSIGNMENT, name_type='FAMILY', name='"'+family+'"'))
self.add_property(QPP(QPP.SET_GLOBAL_ASSIGNMENT, name_type='DEVICE', name=devstring))
self.add_property(QPP(QPP.SET_GLOBAL_ASSIGNMENT, name_type='TOP_LEVEL_ENTITY', name=syn_top))
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