diff --git a/SCRIPT/openfpga_shell_script/skywater_generate_testbench_using_key_example_script.openfpga b/SCRIPT/openfpga_shell_script/skywater_generate_testbench_using_key_example_script.openfpga index b2cf0f9..fbac2ed 100644 --- a/SCRIPT/openfpga_shell_script/skywater_generate_testbench_using_key_example_script.openfpga +++ b/SCRIPT/openfpga_shell_script/skywater_generate_testbench_using_key_example_script.openfpga @@ -59,8 +59,10 @@ write_verilog_testbench --file ${OPENFPGA_VERILOG_OUTPUT_DIR}/verilog_testbench --print_top_testbench \ --print_preconfig_top_testbench \ --print_simulation_ini ${OPENFPGA_VERILOG_OUTPUT_DIR}/SimulationDeck/simulation_deck.ini \ - --include_signal_init \ --explicit_port_mapping +# Exclude signal initialization since it does not help simulator converge +# due to the lack of reset pins for flip-flops +#--include_signal_init # Write the SDC to run timing analysis for a mapped FPGA fabric write_analysis_sdc --file ${OPENFPGA_VERILOG_OUTPUT_DIR}/sdc_analysis diff --git a/SCRIPT/repo_setup.py b/SCRIPT/repo_setup.py index ee233f7..a2a988a 100644 --- a/SCRIPT/repo_setup.py +++ b/SCRIPT/repo_setup.py @@ -11,6 +11,7 @@ import shutil import re import argparse import logging +import subprocess ##################################################################### # Initialize logger @@ -64,7 +65,8 @@ for root, dirs, files in os.walk(openfpga_arch_template_dirpath): shutil.copy(openfpga_arch_template_dirpath + src_file, des_file); homepath_to_replace = re.sub("/", "\/", skywater_openfpga_homepath); cmd = "sed -i 's/${SKYWATER_OPENFPGA_HOME}/" + homepath_to_replace + "/g' " + des_file; - os.system(cmd); + # Error out if this command fails + subprocess.run(cmd, shell=True, check=True); num_arch_file_processed += 1; logging.info("Processed for " + str(num_arch_file_processed) + " openfpga architecture templates"); @@ -102,7 +104,8 @@ for task_template_file in get_list_of_task_config_files(skywater_openfpga_task_d shutil.copy(task_template_file, task_conf_file); homepath_to_replace = re.sub("/", "\/", skywater_openfpga_homepath); cmd = "sed -i 's/${SKYWATER_OPENFPGA_HOME}/" + homepath_to_replace + "/g' " + task_conf_file; - os.system(cmd); + # Error out if this command fails + subprocess.run(cmd, shell=True, check=True); num_task_config_file_processed += 1; logging.info("Processed for " + str(num_task_config_file_processed) + "openfpga task templates"); @@ -148,12 +151,14 @@ for task_name in openfpga_task_list: # Remove all the previous runs in the openfpga task to ensure a clean start logging.info("Clean up previous runs for openfpga task: " + task_name + "..."); cmd = "python3 openfpga_flow/scripts/run_fpga_task.py " + task_name + " --debug --show_thread_logs --remove_run_dir all"; - os.system(cmd); + # Error out if this task run fails + subprocess.run(cmd, shell=True, check=True); logging.info("Done"); # Execute new task run cmd = "python3 openfpga_flow/scripts/run_fpga_task.py " + task_name + " --debug --show_thread_logs"; logging.info("Running openfpga task: " + task_name + "..."); - os.system(cmd); + # Error out if this task run fails + subprocess.run(cmd, shell=True, check=True); logging.info("Done"); os.chdir(skywater_openfpga_homepath); diff --git a/TESTBENCH/common/post_pnr_testbench_converter.py b/TESTBENCH/common/post_pnr_testbench_converter.py new file mode 100644 index 0000000..9cd2d54 --- /dev/null +++ b/TESTBENCH/common/post_pnr_testbench_converter.py @@ -0,0 +1,91 @@ +##################################################################### +# Python script to convert pre-PnR Verilog testbench +# to post-PnR Verilog testbench +# This script will +# - Add ports required by post-PnR Verilog module +# - Scan-chain head and tail ports +# - Add signal stimuli for the scan-chain head and tails +# - Rename fpga_top to fpga_core when instanciate Design Under Test (DUT) +##################################################################### + +import os +from os.path import dirname, abspath, isfile +import shutil +import re +import argparse +import logging + +##################################################################### +# Initialize logger +##################################################################### +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) + +##################################################################### +# Parse the options +##################################################################### +parser = argparse.ArgumentParser(description='Converter for post-PnR Verilog testbench') +parser.add_argument('--pre_pnr_testbench', required=True, + help='Specify the file path for the pre-PnR Verilog testbench as input') +parser.add_argument('--post_pnr_testbench', required=True, + help='Specify the file path for the post-PnR Verilog testbench to be outputted') +args = parser.parse_args() + +##################################################################### +# Check options: +# - Input file must be valid +# Otherwise, error out +# - Remove any output file if already exist +# TODO: give a warning when remove files +##################################################################### +if not isfile(args.pre_pnr_testbench): + logging.error("Invalid pre-PnR testbench: " + args.pre_pnr_testbench + "\nFile does not exist!\n") + exit(1) +if isfile(args.post_pnr_testbench): + logging.warn("Remove existing post-PnR testbench: " + args.post_pnr_testbench + "!\n") + os.remove(args.post_pnr_testbench) + +##################################################################### +# Open the post-pnr Verilog testbench and start modification +##################################################################### +logging.info("Converting pre-PnR testbench:"+ args.pre_pnr_testbench) +logging.info(" To post-PnR testbench:"+ args.post_pnr_testbench) +# Create output file handler +tb_file = open(args.post_pnr_testbench, "w") + +# Read line by line from pre-PnR testbench +with open(args.pre_pnr_testbench, "r") as wp: + template_netlist = wp.readlines() + for line_num, curr_line in enumerate(template_netlist): + # If the current line satisfy the following conditions + # It should be modified and outputted to post-PnR Verilog testbenches + # Other lines can be directly copied to post-PnR Verilog testbenches + line2output = curr_line \ + # Condition A: + # Add sc_head and sc_tail wire definition after ccff tail definition + if (curr_line == "wire [0:0] ccff_tail;\n"): + line2output = line2output \ + + "// ---- Scan-chain head ----\n" \ + + "wire [0:0] sc_head;\n" \ + + "// ---- Scan-chain tail ----\n" \ + + "wire [0:0] sc_tail;\n" + # Condition B: + # Assign an initial value to sc_head after other ports + elif (curr_line == "\tassign IO_ISOL_N[0] = 1'b1;\n"): + line2output = line2output \ + + "\tassign sc_head[0] = 1'b0;\n" + # Condition C: + # Replace fpga_top with fpga_core in DUT instanciation + elif (curr_line == "\tfpga_top FPGA_DUT (\n"): + line2output = "\tfpga_core FPGA_DUT (\n" + # Condition D: + # Add sc_head and sc_tail to the port mapping of FPGA core instance + elif (curr_line == "\t\t.ccff_tail(ccff_tail[0]));\n"): + line2output = "\t\t.ccff_tail(ccff_tail[0]),\n" \ + + "\t\t.sc_head(sc_head[0]),\n" \ + + "\t\t.sc_tail(sc_tail[0])\n" \ + + "\t\t);\n" + + tb_file.write(line2output) + +tb_file.close() +logging.info("Done")