forget about simulating submitted designs for now, too hard
diff --git a/configure.py b/configure.py
index 47c8112..69f386b 100755
--- a/configure.py
+++ b/configure.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-import re
+import re, glob
import yaml
from typing import List
from urllib.parse import urlparse
@@ -15,6 +15,14 @@
tmp_dir = '/tmp/tt'
DEFAULT_NUM_PROJECTS = 473
+def unique(duplist):
+ unique_list = []
+ # traverse for all elements
+ for x in duplist:
+ # check if exists in unique_list or not
+ if x not in unique_list:
+ unique_list.append(x)
+ return unique_list
class Projects():
@@ -50,7 +58,7 @@
# clone git repos locally & gds artifacts from action build
if args.clone_all:
- logging.info(f"cloning & fetching gds")
+ logging.info(f"cloning & fetching gds for {project}")
if filler == False:
project.clone()
project.fetch_gds()
@@ -65,6 +73,13 @@
project.copy_files_to_caravel()
self.projects.append(project)
+
+ # now do some sanity checks
+ all_macro_instances = [ project.get_macro_instance() for project in self.projects ]
+ assert len(all_macro_instances) == len(unique(all_macro_instances))
+
+ all_top_files = [ project.get_top_verilog_file() for project in self.projects if not project.fill ]
+ assert len(all_top_files) == len(unique(all_top_files))
def check_dupes(self):
@@ -125,11 +140,6 @@
assert len(top_verilog) == 1
return top_verilog[0]
- def prep_src_file(self, src):
- filename = os.path.basename(src)
- # make filename unique
- return f'{self.index}_{filename}'
-
def clone(self):
try:
git.Repo.clone_from(self.git_url, self.local_dir)
@@ -142,8 +152,8 @@
pass
def __str__(self):
- return f"[{self.index:03} : {self.git_url} fill {self.fill} wokwi id {self.wokwi_id}]"
- #return f"[{self.index:03} : {self.git_url}]"
+ return f"[{self.index:03} : {self.git_url}]"
+ #return f"[{self.index:03} : {self.git_url} fill {self.fill} wokwi id {self.wokwi_id}]"
def fetch_gds(self):
install_artifacts(self.git_url, self.local_dir)
@@ -189,31 +199,26 @@
if self.is_hdl():
return f'`include "{self.get_top_verilog_file()}"\n'
else:
- # return diff if fill
return f'`include "user_module_{self.wokwi_id}.v"\n'
# for GL sims
def get_gl_verilog_names(self):
if self.is_hdl():
- return [f"{self.top_module}.v"]
+ return f"{self.top_module}.v"
else:
- # return diff if fill
- return [f'user_module_{self.wokwi_id}.v']
+ return f'user_module_{self.wokwi_id}.v'
def get_top_verilog_file(self):
if self.is_hdl():
- return self.prep_src_file(self.top_verilog_file)
+ # make sure it's unique and without leading directories
+ filename = os.path.basename(self.top_verilog_file)
+ return f'{self.index}_{filename}'
else:
- # return diff if fill
- return [f'user_module_{self.wokwi_id}.v']
+ return f'user_module_{self.wokwi_id}.v'
# for the includes file for simulation
def get_verilog_names(self):
- if self.is_hdl():
- return [ self.prep_src_file(src) for src in self.src_files ]
- else:
- # return diff if fill
- return [f'user_module_{self.wokwi_id}.v']
+ return [ self.get_gl_verilog_names() ]
def get_giturl(self):
return self.git_url
@@ -222,16 +227,12 @@
if self.is_hdl():
# this is going to fail if people use duplicate top module names
# and can't be fixed by changing the name as that will not match with the gds or lef
- to_uniquify = []
files = [
(f"{self.index}/runs/wokwi/results/final/gds/{self.top_module}.gds", f"gds/{self.top_module}.gds"),
(f"{self.index}/runs/wokwi/results/final/lef/{self.top_module}.lef", f"lef/{self.top_module}.lef"),
(f"{self.index}/runs/wokwi/results/final/verilog/gl/{self.top_module}.v", f"verilog/gl/{self.top_module}.v"),
+ (f"{self.index}/src/{self.top_verilog_file}", f"verilog/rtl/{self.get_top_verilog_file()}"),
]
- for src in self.src_files:
- prepped = self.prep_src_file(src)
- files.append((f"{self.index}/src/{src}", f"verilog/rtl/{prepped}"))
- to_uniquify.append(f"verilog/rtl/{prepped}")
else:
# copy all important files to the correct places. Everything is dependent on the id
files = [
@@ -247,87 +248,13 @@
logging.debug(f"copy {from_path} to {to_path}")
shutil.copyfile(from_path, to_path)
- # Uniquify the Verilog for this project
- if self.is_hdl():
- all_modules = self.uniquify_project(self.index, to_uniquify)
- print(all_modules)
- def uniquify_project(self, wokwi_id : str, rtl_files : List[str]) -> None:
- """
- Ensure all modules within a given subproject include the Wokwi ID, this
- avoids collisions between names. This is a relatively simplistic function
- for uniquification, it could probably be improved a lot.
-
- :param wokwi_id: The unique ID for the project
- :param rtl_files: List of paths to Verilog files to uniquify
- """
- # Identify all of the module names in this project
- rgx_mod = re.compile(r"(?:^|[\W])module[\s]{1,}([\w]+)")
- all_mod = set()
- full_txt = {}
- for path in rtl_files:
- with open(path, "r", encoding="utf-8") as fh:
- # Pull in full text
- full_txt[path] = list(fh.readlines())
- # Strip single and multi line comments
- in_block = False
- clean = []
- for line in full_txt[path]:
- if "/*" in line and "*/" in line:
- line = line.split("/*")[0] + line.split("*/")[1]
- elif "/*" in line:
- line = line.split("/*")[0]
- in_block = True
- elif in_block and "*/" in line:
- line = line.split("*/")[1]
- in_block = False
- clean.append(line.split("//")[0].strip())
- # Join cleaned up lines together
- flat_text = " ".join(clean)
- # Search for 'module X' declarations
- for match in rgx_mod.finditer(flat_text):
- all_mod.add(match.group(1))
- # Replace just the names which don't contain the Wokwi ID
- problems = { x for x in all_mod if str(wokwi_id) not in x }
- if problems:
- # Create regular expression to match uses of the module name
- rgx_repl = re.compile(rf"\b({'|'.join(problems)})\b")
- # Run through each Verilog file
- for path, orig_txt in full_txt.items():
- new_txt = []
- for line in orig_txt:
- # For every match, substitute with a safe module name
- for match in list(rgx_repl.finditer(line))[::-1]:
- m_start, m_end = match.span()
- m_sub = f"{match.group(1)}_{wokwi_id}"
- line = line[:m_start] + m_sub + line[m_end:]
- # Some projects seem to have hardcoded RTL and forgotten
- # to replace 'USER_MODULE_ID' with the Wokwi ID
- if "_USER_MODULE_ID_" in line:
- line = line.replace("_USER_MODULE_ID_", "_")
- new_txt.append(line)
- # Overwrite the file
- logging.info(f"Writing uniquified RTL for {path}")
- with open(path, "w", encoding="utf-8") as fh:
- fh.writelines(new_txt)
-
- return all_mod
-
class CaravelConfig():
def __init__(self, projects, num_projects):
self.projects = projects
self.num_projects = num_projects
- @classmethod
- def unique(cls, duplist):
- unique_list = []
- # traverse for all elements
- for x in duplist:
- # check if exists in unique_list or not
- if x not in unique_list:
- unique_list.append(x)
- return unique_list
# create macro file & positions, power hooks
def create_macro_config(self):
@@ -420,8 +347,8 @@
gdss.append(self.projects[i].get_macro_gds_name())
# can't have duplicates or OpenLane crashes at PDN
- lefs = CaravelConfig.unique(lefs)
- gdss = CaravelConfig.unique(gdss)
+ lefs = unique(lefs)
+ gdss = unique(gdss)
with open("openlane/user_project_wrapper/extra_lef_gds.tcl", 'w') as fh:
fh.write('set ::env(EXTRA_LEFS) "\\\n')
@@ -555,7 +482,7 @@
verilogs = []
for i in range(self.num_projects):
verilogs.append(self.projects[i].get_verilog_include())
- verilogs = CaravelConfig.unique(verilogs)
+ verilogs = unique(verilogs)
with open('verilog/rtl/user_project_includes.v', 'w') as fh:
fh.write('`include "scan_controller/scan_controller.v"\n')
@@ -567,7 +494,7 @@
verilog_files = []
for i in range(self.num_projects):
verilog_files += self.projects[i].get_verilog_names()
- verilog_files = CaravelConfig.unique(verilog_files)
+ verilog_files = unique(verilog_files)
with open('verilog/includes/includes.rtl.caravel_user_project', 'w') as fh:
fh.write('-v $(USER_PROJECT_VERILOG)/rtl/user_project_wrapper.v\n')
fh.write('-v $(USER_PROJECT_VERILOG)/rtl/scan_controller/scan_controller.v\n')
@@ -580,7 +507,7 @@
verilog_files = []
for i in range(self.num_projects):
verilog_files += self.projects[i].get_gl_verilog_names()
- verilog_files = CaravelConfig.unique(verilog_files)
+ verilog_files = unique(verilog_files)
with open('verilog/includes/includes.gl.caravel_user_project', 'w') as fh:
fh.write('-v $(USER_PROJECT_VERILOG)/gl/user_project_wrapper.v\n')
fh.write('-v $(USER_PROJECT_VERILOG)/gl/scan_controller.v\n')