refactor naming, move to GL verilog for blackboxing
diff --git a/INFO.md b/INFO.md index 8fd5784..6282201 100644 --- a/INFO.md +++ b/INFO.md
@@ -129,7 +129,3 @@ Then to create the GDS: make user_project_wrapper - -## Verification - -See the separate [verification](verification.md) doc.
diff --git a/verification.md b/VERIFICATION.md similarity index 100% rename from verification.md rename to VERIFICATION.md
diff --git a/configure.py b/configure.py index c165d41..e2a0f33 100755 --- a/configure.py +++ b/configure.py
@@ -82,14 +82,16 @@ # 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)) + self.assert_unique(all_macro_instances) - all_top_files = [project.get_top_verilog_file() for project in self.projects if not project.is_fill()] - assert len(all_top_files) == len(unique(all_top_files)) + all_top_files = [project.get_top_verilog_filename() for project in self.projects if not project.is_fill()] + self.assert_unique(all_top_files) - def check_dupes(self): - from project_urls import project_urls - duplicates = [item for item, count in collections.Counter(project_urls).items() if count > 1] + all_gds_files = [project.get_macro_gds_filename() for project in self.projects if not project.is_fill()] + self.assert_unique(all_gds_files) + + def assert_unique(self, check): + duplicates = [item for item, count in collections.Counter(check).items() if count > 1] if duplicates: logging.error("duplicate projects: {}".format(duplicates)) exit(1) @@ -107,9 +109,9 @@ # if the project is a filler, then use the config from the first fill project def gen_local_dir(self, fill_id): if self.fill: - return os.path.join(os.path.join(self.project_dir, str(fill_id))) + return os.path.join(os.path.join(self.project_dir, f'{fill_id :03}')) else: - return os.path.join(os.path.join(self.project_dir, str(self.index))) + return os.path.join(os.path.join(self.project_dir, f'{self.index :03}')) def check_ports(self): top = self.get_macro_name() @@ -173,13 +175,13 @@ self.yaml['project']['git_url'] = self.git_url if self.is_hdl(): - self.top_module = self.yaml['project']['top_module'] - self.src_files = self.yaml['project']['source_files'] - self.top_verilog_file = self.find_top_verilog() + self.top_module = self.yaml['project']['top_module'] + self.src_files = self.yaml['project']['source_files'] + self.top_verilog_filename = self.find_top_verilog() else: - self.top_module = f"user_module_{self.wokwi_id}" - self.src_files = [f"user_module_{self.wokwi_id}.v"] - self.top_verilog_file = self.src_files[0] + self.top_module = f"user_module_{self.wokwi_id}" + self.src_files = [f"user_module_{self.wokwi_id}.v"] + self.top_verilog_filename = self.src_files[0] self.macro_instance = f"{self.top_module}_{self.index}" self.scanchain_instance = f"scanchain_{self.index}" @@ -251,57 +253,41 @@ return self.index # name of the gds file - def get_macro_gds_name(self): + def get_macro_gds_filename(self): return f"{self.top_module}.gds" - def get_macro_lef_name(self): + def get_macro_lef_filename(self): return f"{self.top_module}.lef" - # for black boxing when building GDS, just need module name and ports - def get_verilog_include(self): - return f'`include "{self.get_top_verilog_file()}"\n' - - # for GL sims - def get_gl_verilog_names(self): + # for GL sims & blackboxing + def get_gl_verilog_filename(self): return f"{self.top_module}.v" - def get_top_verilog_file(self): + # for simulations + def get_top_verilog_filename(self): if self.is_hdl(): - # make sure it's unique and without leading directories - filename = os.path.basename(self.top_verilog_file) + # make sure it's unique & without leading directories + # a few people use 'top.v', which is OK as long as the top module is called something more unique + # but then it needs to be made unique so the source can be found + filename = os.path.basename(self.top_verilog_filename) return f'{self.index}_{filename}' else: - return f'user_module_{self.wokwi_id}.v' - - # for the includes file for simulation - def get_verilog_names(self): - return [self.get_gl_verilog_names()] + return self.top_verilog_filename def get_git_url(self): return self.git_url def copy_files_to_caravel(self): - 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 - 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()}"), - ] - else: - # copy all important files to the correct places. Everything is dependent on the id - files = [ - (f"{self.index}/runs/wokwi/results/final/gds/user_module_{self.wokwi_id}.gds", f"gds/user_module_{self.wokwi_id}.gds"), - (f"{self.index}/runs/wokwi/results/final/lef/user_module_{self.wokwi_id}.lef", f"lef/user_module_{self.wokwi_id}.lef"), - (f"{self.index}/runs/wokwi/results/final/verilog/gl/user_module_{self.wokwi_id}.v", f"verilog/gl/user_module_{self.wokwi_id}.v"), - (f"{self.index}/src/user_module_{self.wokwi_id}.v", f"verilog/rtl/user_module_{self.wokwi_id}.v"), - ] + files = [ + (f"runs/wokwi/results/final/gds/{self.get_macro_gds_filename()}", f"gds/{self.get_macro_gds_filename()}"), + (f"runs/wokwi/results/final/lef/{self.get_macro_lef_filename()}", f"lef/{self.get_macro_lef_filename()}"), + (f"runs/wokwi/results/final/verilog/gl/{self.get_gl_verilog_filename()}", f"verilog/gl/{self.get_gl_verilog_filename()}"), + (f"src/{self.top_verilog_filename}", f"verilog/rtl/{self.get_top_verilog_filename()}"), + ] logging.debug("copying files into position") for from_path, to_path in files: - from_path = os.path.join(self.project_dir, from_path) + from_path = os.path.join(self.local_dir, from_path) logging.debug(f"copy {from_path} to {to_path}") shutil.copyfile(from_path, to_path) @@ -395,16 +381,13 @@ fh.write('"\n') # extra_lef_gds.tcl - logging.info("creating extra_lef_gds.tcl") lefs = [] gdss = [] - for i in range(self.num_projects): - lefs.append(self.projects[i].get_macro_lef_name()) - gdss.append(self.projects[i].get_macro_gds_name()) - - # can't have duplicates or OpenLane crashes at PDN - lefs = unique(lefs) - gdss = unique(gdss) + logging.info("creating extra_lef_gds.tcl") + for project in self.projects: + if not project.is_fill(): + lefs.append(project.get_macro_lef_filename()) + gdss.append(project.get_macro_gds_filename()) with open("openlane/user_project_wrapper/extra_lef_gds.tcl", 'w') as fh: fh.write('set ::env(EXTRA_LEFS) "\\\n') @@ -533,42 +516,32 @@ with open("upw_post.v", "r") as fh_post: fh.write(fh_post.read()) - # build the user_project_includes.v file - used for blackboxing when building the GDS - verilogs = [] - for i in range(self.num_projects): - verilogs.append(self.projects[i].get_verilog_include()) - verilogs = unique(verilogs) - - with open('verilog/rtl/user_project_includes.v', 'w') as fh: - fh.write('`include "scan_controller/scan_controller.v"\n') - fh.write('`include "scanchain/scanchain.v"\n') - for verilog in verilogs: - fh.write(verilog) + # build the blackbox_project_includes.v file - used for blackboxing when building the GDS + with open('verilog/blackbox_project_includes.v', 'w') as fh: + fh.write('`include "rtl/scan_controller/scan_controller.v"\n') + fh.write('`include "rtl/scanchain/scanchain.v"\n') + for project in self.projects: + if not project.is_fill(): + fh.write(f'`include "gl/{project.get_gl_verilog_filename()}"\n') # build complete list of filenames for sim - verilog_files = [] - for i in range(self.num_projects): - verilog_files += self.projects[i].get_verilog_names() - 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') fh.write('-v $(USER_PROJECT_VERILOG)/rtl/scanchain/scanchain.v\n') fh.write('-v $(USER_PROJECT_VERILOG)/rtl/cells.v\n') - for verilog in verilog_files: - fh.write('-v $(USER_PROJECT_VERILOG)/rtl/{}\n'.format(verilog)) + for project in self.projects: + if not project.is_fill(): + fh.write(f'-v $(USER_PROJECT_VERILOG)/rtl/{project.get_top_verilog_filename()}\n') # build GL includes - verilog_files = [] - for i in range(self.num_projects): - verilog_files += self.projects[i].get_gl_verilog_names() - 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') fh.write('-v $(USER_PROJECT_VERILOG)/gl/scanchain.v\n') - for verilog in verilog_files: - fh.write('-v $(USER_PROJECT_VERILOG)/gl/{}\n'.format(verilog)) + for project in self.projects: + if not project.is_fill(): + fh.write(f'-v $(USER_PROJECT_VERILOG)/gl/{project.get_gl_verilog_filename()}"\n') def list(self): for project in self.projects: @@ -621,6 +594,9 @@ with open("INFO.md") as fh: doc_info = fh.read() + with open("VERIFICATION.md") as fh: + doc_verification = fh.read() + with open(args.dump_markdown, 'w') as fh: fh.write(doc_header) @@ -649,6 +625,8 @@ # ending fh.write(doc_info) + fh.write("\n\pagebreak\n") + fh.write(doc_verification) logging.info(f'wrote markdown to {args.dump_markdown}') @@ -686,7 +664,6 @@ log.addHandler(ch) projects = Projects(args) -# projects.check_dupes() docs = Docs(projects.projects, args=args) caravel = CaravelConfig(projects.projects, num_projects=args.limit_num_projects)