Fix include in Icarus Verilog and update the associated tests

parent 3e9257b0
......@@ -43,6 +43,7 @@ class ModulePool(list):
self.hierarchy_dict = None
self.hierarchy_tree =None
self.hierarchy_solved =None
self.hierarchy_includes =None
def set_environment(self, env):
self.env = env
......@@ -209,7 +210,7 @@ class ModulePool(list):
all_files = self.build_complete_file_set()
from srcfile import SourceFileSet
source_files = SourceFileSet()
(self.hierarchy_dag, self.hierarchy_dict, self.hierarchy_tree, self.hierarchy_solved) = dep_solver.solve(all_files, top_entity)
(self.hierarchy_dag, self.hierarchy_dict, self.hierarchy_tree, self.hierarchy_solved, self.hierarchy_includes) = dep_solver.solve(all_files, top_entity)
def get_top_module(self):
return self.top_module
......
......@@ -128,6 +128,7 @@ def solve(fileset, top_entity):
if isinstance(investigated_file, VerilogFile) :
# In verilog world, packages are related with SystemVerilog
# In verilog world, packages are related with SystemVerilog
for module_test in investigated_file.provided_modules:
hierarchy.add_node(module_test.model)
......@@ -150,11 +151,22 @@ def solve(fileset, top_entity):
if not (hierarchy_dict[component] in solved_files):
solved_files.append(hierarchy_dict[component])
logging.info("Dependencies solved: %s files added to the hierarchy" % len(solved_files))
solved_includes = []
for f in solved_files:
if isinstance(f, VerilogFile):
if f.includes:
if not (f in solved_includes):
solved_includes.append(f)
logging.info("Dependencies solved:\n"
+ " - %s total files have been analyzed\n" % len(fset)
+ " - %s files added to the hierarchy\n" % len(solved_files)
+ " - %s includes added to the hierarchy" % len(solved_includes)
)
logging.debug("SOLVE END")
return (hierarchy, hierarchy_dict, top_hierarchy, solved_files)
return (hierarchy, hierarchy_dict, top_hierarchy, solved_files, solved_includes)
def make_dependency_sorted_list(fileset, purge_unused=True, reverse=False):
......
......@@ -79,6 +79,7 @@ class VerilogFile(SourceFile):
self.include_dirs.extend(include_dirs)
self.include_dirs.append(path_mod.relpath(self.dirname))
self.provided_modules = []
self.includes = []
class SVFile(VerilogFile):
pass
......
......@@ -26,6 +26,7 @@ import string
import os
import logging
from hdlmake.util import path as path_mod
from hdlmake.makefile_writer import MakefileWriter
......@@ -77,9 +78,9 @@ run.command \
ivl_vhdl_work
#target for performing local simulation
local: sim_pre_cmd simulation sim_post_cmd
local: sim_pre_cmd command simulation sim_post_cmd
simulation:
command:
""")
makefile_text_1 = makefile_tmplt_1.substitute(
......@@ -89,16 +90,32 @@ simulation:
self.writeln("\t\techo \"# IVerilog command file, generated by HDLMake\" > run.command")
for inc in top_module.include_dirs:
self.writeln("\t\techo \"+incdir+" + inc + "\" >> run.command")
#for inc in top_module.include_dirs:
# self.writeln("\t\techo \"+incdir+" + inc + "\" >> run.command")
solved_includes = []
for f in fileset:
if isinstance(f, VerilogFile):
if f.includes:
for included_f in f.includes:
included_dir = os.path.dirname(included_f)
if not (included_dir in solved_includes):
solved_includes.append(included_dir)
if solved_includes:
self.writeln("\t\techo \"# Included directories:\" >> run.command")
for inc in solved_includes:
self.writeln("\t\techo \"+incdir+" + path_mod.relpath(inc)+ "\" >> run.command")
# The list starts from top_module: reverse!
self.writeln("\t\techo \"# Hierarchy for HDL sources:\" >> run.command")
fileset.reverse()
for f in fileset:
self.writeln("\t\techo \"" + f.rel_path() + "\" >> run.command")
makefile_tmplt_2 = string.Template("""
simulation:
\t\tiverilog ${iverilog_opt} -s $$(TOP_MODULE) -o $$(TOP_MODULE).vvp -c run.command
sim_pre_cmd:
......@@ -141,66 +158,3 @@ mrproper: clean
self.write(makefile_text_2)
# Below is the old makefile generator: I'll keep it for some time while testing
def generate_iverilog_makefile(self, fileset, top_module, modules_pool):
print('javi checkpoint 0')
from hdlmake.srcfile import VerilogFile
for f in top_module.incl_makefiles:
self.writeln("include " + f)
target_list = []
for vl in fileset.filter(VerilogFile):
rel_dir_path = os.path.dirname(vl.rel_path())
if rel_dir_path:
rel_dir_path = rel_dir_path + '/'
target_name = os.path.join(rel_dir_path+vl.purename)
target_list.append(target_name)
dependencies_string = ' '.join([f.rel_path() for f in vl.depends_on if (f.name != vl.name)])
include_dirs = list(set([os.path.dirname(f.rel_path()) for f in vl.depends_on if f.name.endswith("vh")]))
while "" in include_dirs:
include_dirs.remove("")
include_dir_string = " -I".join(include_dirs)
if include_dir_string:
include_dir_string = ' -I'+include_dir_string
self.writeln("VFLAGS_"+target_name+"="+include_dir_string)
self.writeln('# jd checkpoint')
self.writeln(target_name+"_deps = "+dependencies_string)
print('javi target_list', target_list)
sim_only_files = []
for m in modules_pool:
for f in m.sim_only_files:
sim_only_files.append(f.name)
print('javi sim_only_files', sim_only_files)
# bit file targets are those that are only used in simulation
bit_targets = []
for m in modules_pool:
bit_targets = bit_targets + list(m.bit_file_targets)
print('javi bit_targets', bit_targets)
for bt in bit_targets:
bt = bt.purename
bt_syn_deps = []
# This can perhaps be done faster (?)
for vl in fileset.filter(VerilogFile):
if vl.purename == bt:
for f in vl.depends_on:
if (f.name != vl.name and f.name not in sim_only_files):
bt_syn_deps.append(f)
self.writeln(bt+'syn_deps = '+ ' '.join([f.rel_path() for f in bt_syn_deps]))
if not os.path.exists("%s.ucf" % bt):
logging.warning("The file %s.ucf doesn't exist!" % bt)
self.writeln(bt+".bit:\t"+bt+".v $("+bt+"syn_deps) "+bt+".ucf")
part=(top_module.syn_device+'-'+
top_module.syn_package+
top_module.syn_grade)
self.writeln("\tPART="+part+" $(SYNTH) "+bt+" $^")
self.writeln("\tmv _xilinx/"+bt+".bit $@")
self.writeln("clean:")
self.writeln("\t\trm -f "+" ".join(target_list)+"\n\t\trm -rf _xilinx")
......@@ -200,6 +200,7 @@ class VerilogPreprocessor(object):
if matches["include"]:
included_file_path = self._search_include(last.group(1), os.path.dirname(file_name))
self.vlog_file.includes.append(included_file_path)
logging.debug("File being parsed %s (library %s) includes %s" % (file_name, library, included_file_path))
line = self._preprocess_file(file_content=open(included_file_path, "r").read(),
file_name=included_file_path, library=library)
......@@ -569,20 +570,13 @@ class VerilogParser(DepParser):
logging.debug( "%s has %d includes." % (str(dep_file), len(includes)))
except KeyError:
logging.debug(str(dep_file) + " has no includes.")
#look for packages used inside in file
#it may generate false dependencies as package in SV can be used by:
# import my_package::*;
#or directly
# logic var = my_package::MY_CONST;
#The same way constants and others can be imported directly from other modules:
# logic var = my_other_module::MY_CONST;
#and HdlMake will anyway create dependency marking my_other_module as requested package
import_pattern = re.compile("(\w+) *::(\w+|\\*)")
def do_imports(s):
logging.debug("file %s imports/uses %s.%s package" %( dep_file.path , dep_file.library, s.group(1) ) )
dep_file.add_relation( DepRelation( "%s.%s" % (dep_file.library, s.group(1)) , DepRelation.USE, DepRelation.PACKAGE))
re.subn(import_pattern, do_imports, buf)
#def do_imports(s):
# logging.debug("file %s imports/uses %s.%s package" %( dep_file.path , dep_file.library, s.group(1) ) )
# dep_file.add_relation( DepRelation( "%s.%s" % (dep_file.library, s.group(1)) , DepRelation.USE, DepRelation.PACKAGE))
#re.subn(import_pattern, do_imports, buf)
#----------------------------------------------
use_packages = import_pattern.findall(buf)
dep_file.used_packages = use_packages
......
action = "simulation"
sim_tool = "iverilog"
iverilog_opt = "-g2012"
top_module = "counter_tb"
sim_pre_cmd ="echo IMPORTANT, IVerilog always needs a Verilog testbench, no matter if the DUT is written in VHDL!"
......
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