From 55ff90905f1b37335dbee97bcf20d28a974369de Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 8 Dec 2020 10:12:57 -0700 Subject: [PATCH] [DC] Add scripts to automate the synthesis for local encoders --- SNPS_DC/SCRIPTS/dc_template.tcl | 51 +++++++++++ SNPS_DC/SCRIPTS/run_dc_synth.py | 144 ++++++++++++++++++++++++++++++++ SNPS_DC/synth_local_encoders.sh | 1 + 3 files changed, 196 insertions(+) create mode 100644 SNPS_DC/SCRIPTS/dc_template.tcl create mode 100644 SNPS_DC/SCRIPTS/run_dc_synth.py create mode 100644 SNPS_DC/synth_local_encoders.sh diff --git a/SNPS_DC/SCRIPTS/dc_template.tcl b/SNPS_DC/SCRIPTS/dc_template.tcl new file mode 100644 index 0000000..2d4f70d --- /dev/null +++ b/SNPS_DC/SCRIPTS/dc_template.tcl @@ -0,0 +1,51 @@ +########################################################## +# Template scripts to synthesize a combinational circuit +# using Design Compiler +# Author: Xifan Tang +# Organization: University of Utah +# Date: September 4th, 2020 +########################################################## + +# Variable declaration +set CTRITICAL_PATH 1; # [ns] + +# Make sure a clean start +remove_design -all + +set DB_FILE "/research/ece/lnis/CAD_TOOLS/DKITS/skywater/skywater-pdk/vendor/synopsys/results/lib/sky130_fd_sc_hd/db_nldm/sky130_fd_sc_hd__tt_025C_1v80.db" + +# Read standard cell library +# Here we consider the Skywater 130nm High Density(HD) cell library +read_db ${DB_FILE} +set target_library ${DB_FILE} +set link_library ${DB_FILE} + +set DESIGN_NAME DESIGN_NAME_VAR +set RTL_NETLIST RTL_NETLIST_VAR + +# Parse the HDL +analyze -f verilog ${RTL_NETLIST} +elaborate ${DESIGN_NAME} + +# Set constraints +# Push to 0 for the minimum area +set_max_area 0 + +# Link to technology library and start compilation +link +compile -map_effort high + +# Output netlist +write -format Verilog -output ../GATE_NETLISTS/${DESIGN_NAME}_post_synth.v + +# Report results +report_unit > ../RPT/${DESIGN_NAME}_unit.rpt +report_area > ../RPT/${DESIGN_NAME}_area.rpt +report_timing > ../RPT/${DESIGN_NAME}_timing.rpt +report_power > ../RPT/${DESIGN_NAME}_power.rpt +report_reference > ../RPT/${DESIGN_NAME}_reference.rpt + +# Finish here +exit + + diff --git a/SNPS_DC/SCRIPTS/run_dc_synth.py b/SNPS_DC/SCRIPTS/run_dc_synth.py new file mode 100644 index 0000000..64cd650 --- /dev/null +++ b/SNPS_DC/SCRIPTS/run_dc_synth.py @@ -0,0 +1,144 @@ +##################################################################### +# Python script to execute Design Compiler Synthesis for a given template tcl script +# This script will +# - Create the tcl script as synthesis recipe +# - Run Design Compiler +# - Analyze output log files and return succeed or failure +##################################################################### + +import sys +import os +from os.path import dirname, abspath, isfile +import shutil +import re +import argparse +import logging +import subprocess + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) +##################################################################### +# Main function of this script, so that it can be called by other scripts +##################################################################### +def main(args): + ##################################################################### + # Parse the options + ##################################################################### + parser = argparse.ArgumentParser(description='Run Synopsys Design Compiler Synthesis for an input netlist') + parser.add_argument('--rtl_netlist', required=True, + help='Specify the file path to the RTL netlist as input') + parser.add_argument('--recipe_template', required=True, + help='Specify the file path to tcl script contain template synthesis recipe') + parser.add_argument('--technology_library', required=True, + help='Specify the technology library which the RTL netlist will be mapped to') + parser.add_argument('--project_workspace', required=True, + help='Specify the directory to run Design Compiler') + args = parser.parse_args(args) + + run_dc_batch_synth(args.rtl_netlist, args.recipe_template, args.technology_library, args.project_workspace) + +##################################################################### +# A function to execute a single-run of Design Compiler for a RTL design +##################################################################### +def run_dc_synth(rtl_netlist, rtl_design_name, recipe_template, technology_library, project_workspace): + project_abs_path = os.path.abspath(project_workspace) + if not os.path.isdir(project_abs_path): + logging.debug("Creating Design Compiler project directory : " + project_abs_path + " ...\n") + os.makedirs(project_abs_path, exist_ok=True) + logging.debug("Done\n") + + ##################################################################### + # Create the Tcl script for Design Compiler + ##################################################################### + # Get absolute path to the template tcl script, it must be valid + template_tcl_path = os.path.abspath(recipe_template) + assert(isfile(template_tcl_path)) + + # Create output file handler + tcl_file_path = project_abs_path + "/" + os.path.basename(rtl_design_name) + "_dc.tcl" + logging.debug("Generating Tcl script from template recipe: " + tcl_file_path) + + tcl_file = open(tcl_file_path, "w") + + with open(template_tcl_path, "r") as wp: + template_tcl_file = wp.readlines() + for line_num, curr_line in enumerate(template_tcl_file): + line2output = curr_line + # Replace keywords with custom values + line2output = re.sub("TECH_DB_VAR", technology_library, curr_line) + line2output = re.sub("DESIGN_NAME_VAR", rtl_design_name, curr_line) + line2output = re.sub("RTL_NETLIST_VAR", rtl_netlist, curr_line) + # Finished processing + # Output the line + tcl_file.write(line2output) + + tcl_file.close() + logging.debug("Done") + + ##################################################################### + # Run Design Compiler + ##################################################################### + curr_dir = os.getcwd() + # Change to the project directory + os.chdir(project_abs_path) + logging.debug("Changed to directory: " + project_abs_path) + + # Run Design Compiler + dc_log_file_path = project_abs_path + "/" + os.path.basename(rtl_design_name) + "_dc.log" + dc_shell_bin = "dc_shell" + dc_shell_cmd = dc_shell_bin + " -f " + os.path.abspath(tcl_file_path) + " > " + dc_log_file_path + logging.debug("Running Design Compiler by : " + dc_shell_cmd) + subprocess.run(dc_shell_cmd, shell=True, check=True) + + # Go back to current directory + os.chdir(curr_dir) + +##################################################################### +# Main function of this script, so that it can be called by other scripts +##################################################################### +def run_dc_batch_synth(rtl_netlist, recipe_template, technology_library, project_workspace): + ##################################################################### + # Check options: + # - Input files must be valid + # Otherwise, error out + ##################################################################### + if not isfile(rtl_netlist): + logging.error("Invalid RTL netlist: " + rtr_netlist + "\nFile does not exist!\n") + exit(1) + + if not isfile(recipe_template): + logging.error("Invalid recipe template: " + recipe_template + "\nFile does not exist!\n") + exit(1) + + if not isfile(technology_library): + logging.error("Invalid technology library: " + technology_library + "\nFile does not exist!\n") + exit(1) + + ##################################################################### + # Collect all the RTL designs to synthesis from the RTL netlist + ##################################################################### + rtl_design_names = [] + with open(rtl_netlist, "r") as wp: + rtl_file = wp.readlines() + # If a line starts with 'module', it is an RTL design to be synthesized + for line_num, curr_line in enumerate(rtl_file): + if (curr_line.startswith("module")): + # Get the design name + rtl_design_name = re.findall("module(\s+)(\w+)\(", curr_line)[0][1] + rtl_design_names.append(rtl_design_name) + + logging.info("Found " + str(len(rtl_design_names)) + " RTL designs to synthesize") + + # Get absolute path to the template tcl script, it must be valid + rtl_netlist_abs_path = os.path.abspath(rtl_netlist) + assert(isfile(rtl_netlist_abs_path)) + + for rtl_design_name in rtl_design_names: + logging.info("Running Design Compiler for design: " + rtl_design_name) + run_dc_synth(rtl_netlist_abs_path, rtl_design_name, recipe_template, technology_library, project_workspace) + logging.info("Done") + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/SNPS_DC/synth_local_encoders.sh b/SNPS_DC/synth_local_encoders.sh new file mode 100644 index 0000000..c9c2c6e --- /dev/null +++ b/SNPS_DC/synth_local_encoders.sh @@ -0,0 +1 @@ +python3 SCRIPTS/run_dc_synth.py --rtl_netlist ../HDL/k4_N8_reset_softadder_caravel_io_FPGA_12x12_customhd_cc/SRC/sub_module/local_encoder.v --recipe_template SCRIPTS/dc_template.tcl --technology_library ../PDK/skywater-pdk/vendor/synopsys/results/lib/sky130_fd_sc_hd/db_nldm/sky130_fd_sc_hd__tt_025C_1v80.db --project_workspace ./TEMP