diff --git a/.travis/regression.sh b/.travis/regression.sh deleted file mode 100755 index 5d9be167d..000000000 --- a/.travis/regression.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# Regression test version 1.0 - -# Set variables -my_pwd=$PWD -fpga_flow_scripts=${my_pwd}/fpga_flow/scripts -vpr_path=${my_pwd}/vpr7_x2p/vpr -benchmark="test_modes" -include_netlists="_include_netlists.v" -compiled_file="compiled_$benchmark" -tb_formal_postfix="_top_formal_verification_random_tb" -verilog_output_dirname="${benchmark}_Verilog" -log_file="${benchmark}_sim.log" -new_reg_sh="my_regression.sh" - - -cd $fpga_flow_scripts - -perl rewrite_path_in_file.pl -i $vpr_path/regression_verilog.sh -o $vpr_path/$new_reg_sh - -cd $my_pwd - -# Move to vpr folder -cd $vpr_path - -# Remove former log file -rm -f $log_file -rm -f $compiled_file - -# Start the script -> run the fpga generation -> run the simulation -> check the log file -source $new_reg_sh -iverilog -o $compiled_file $verilog_output_dirname/SRC/$benchmark$include_netlists -s $benchmark$tb_formal_postfix -vvp $compiled_file -j 16 >> $log_file - -result=`grep "Succeed" $log_file` -if ["$result" = ""]; then - result=`grep "Failed" $log_file` - if ["$result" = ""]; then - echo "Unexpected error, Verification didn't run" - cd $my_pwd - exit 1 - else - echo "Verification failed" - cd $my_pwd - exit 2 - fi -else - echo "Verification succeed" - cd $my_pwd -fi diff --git a/.travis/script.sh b/.travis/script.sh index e87ed510b..a7ee7539c 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -26,8 +26,6 @@ end_section "OpenFPGA.build" $SPACER cd - -./.travis/regression.sh - -#cd fpga_flow -#./regression_fpga_flow.sh -#cd - +# python3.5 ./openfpga_flow/scripts/run_fpga_task.py regression/regression_quick +chmod 755 run_test.sh +./run_test.sh \ No newline at end of file diff --git a/openfpga_flow/benchmarks/Test_Modes/test_modes.act b/openfpga_flow/benchmarks/Test_Modes/test_modes.act new file mode 100644 index 000000000..a58956a8e --- /dev/null +++ b/openfpga_flow/benchmarks/Test_Modes/test_modes.act @@ -0,0 +1,67 @@ +cint01 0.485400 0.188600 +n01 0.489000 0.213200 +cint02 0.502400 0.203200 +n02 0.509200 0.195200 +cint03 0.507200 0.192200 +n03 0.502400 0.201600 +cint04 0.463200 0.199400 +n04 0.522000 0.191000 +n05 0.486800 0.204800 +reg0 0.463000 0.195400 +reg1 0.487400 0.196600 +reg2 0.506200 0.195000 +reg3 0.492200 0.208200 +reg4 0.507200 0.204800 +reg5 0.500400 0.200600 +reg6 0.500800 0.203400 +reg7 0.509600 0.198800 +reg8 0.492200 0.188000 +reg9 0.504800 0.204400 +reg10 0.507600 0.203200 +reg11 0.494200 0.203600 +clk 0.534600 0.203800 +a_0 0.478200 0.203800 +a_1 0.514800 0.208600 +a_2 0.505800 0.204600 +a_3 0.500000 0.195200 +b_0 0.530800 0.192800 +b_1 0.495800 0.195400 +b_2 0.496600 0.201200 +b_3 0.492000 0.200200 +cin 0.502600 0.202200 +e 0.495200 0.201000 +f 0.504000 0.203400 +g 0.498200 0.202000 +reg_a_0 0.478200 0.203800 +reg_a_1 0.514800 0.208600 +reg_a_2 0.505800 0.204600 +reg_a_3 0.500000 0.195200 +reg_b_0 0.530800 0.192800 +reg_b_1 0.495800 0.195400 +reg_b_2 0.496600 0.201200 +reg_b_3 0.492000 0.200200 +reg_cin 0.502600 0.202200 +sum_0 0.489000 0.213200 +sum_1 0.509200 0.195200 +sum_2 0.502400 0.201600 +sum_3 0.522000 0.191000 +cout 0.486800 0.204800 +ref0 0.000000 0.000000 +n57 0.478200 0.097457 +n62 0.514800 0.107387 +n67 0.505800 0.103487 +n72 0.500000 0.097600 +n77 0.530800 0.102338 +n82 0.495800 0.096879 +n87 0.496600 0.099916 +n92 0.492000 0.098498 +n97 0.502600 0.101626 +d0 0.617800 0.046719 +x 0.492200 0.102476 +y 0.509600 0.101308 +z 0.494200 0.100619 +n102 0.489000 0.104255 +n106 0.509200 0.099396 +n110 0.502400 0.101284 +n114 0.522000 0.099702 +n118 0.486800 0.099697 diff --git a/openfpga_flow/benchmarks/Test_Modes/test_modes.blif b/openfpga_flow/benchmarks/Test_Modes/test_modes.blif new file mode 100644 index 000000000..f7ed4cb33 --- /dev/null +++ b/openfpga_flow/benchmarks/Test_Modes/test_modes.blif @@ -0,0 +1,94 @@ +# Benchmark "test" written by ABC on Tue Apr 30 17:17:10 2019 +.model test_modes +.inputs clk a_0 a_1 a_2 a_3 b_0 b_1 b_2 b_3 cin e f g +.outputs sum_0 sum_1 sum_2 sum_3 cout x y z + +.latch n57 reg_a_0 re clk 0 +.latch n62 reg_a_1 re clk 0 +.latch n67 reg_a_2 re clk 0 +.latch n72 reg_a_3 re clk 0 +.latch n77 reg_b_0 re clk 0 +.latch n82 reg_b_1 re clk 0 +.latch n87 reg_b_2 re clk 0 +.latch n92 reg_b_3 re clk 0 +.latch n97 reg_cin re clk 0 +.latch n102 sum_0 re clk 0 +.latch n106 sum_1 re clk 0 +.latch n110 sum_2 re clk 0 +.latch n114 sum_3 re clk 0 +.latch n118 cout re clk 0 + + +.subckt adder a=reg_a_0 b=reg_b_0 cin=reg_cin cout=cint01 sumout=n01 +.subckt adder a=reg_a_1 b=reg_b_1 cin=cint01 cout=cint02 sumout=n02 +.subckt adder a=reg_a_2 b=reg_b_2 cin=cint02 cout=cint03 sumout=n03 +.subckt adder a=reg_a_3 b=reg_b_3 cin=cint03 cout=cint04 sumout=n04 +.subckt adder a=ref0 b=ref0 cin=cint04 cout=unconn sumout=n05 + +.subckt shift D=d0 clk=clk Q=reg0 +.subckt shift D=reg0 clk=clk Q=reg1 +.subckt shift D=reg1 clk=clk Q=reg2 +.subckt shift D=reg2 clk=clk Q=reg3 +.subckt shift D=reg3 clk=clk Q=reg4 +.subckt shift D=reg4 clk=clk Q=reg5 +.subckt shift D=reg5 clk=clk Q=reg6 +.subckt shift D=reg6 clk=clk Q=reg7 +.subckt shift D=reg7 clk=clk Q=reg8 +.subckt shift D=reg8 clk=clk Q=reg9 +.subckt shift D=reg9 clk=clk Q=reg10 +.subckt shift D=reg10 clk=clk Q=reg11 + +.names ref0 + 0 +.names a_0 n57 +1 1 +.names a_1 n62 +1 1 +.names a_2 n67 +1 1 +.names a_3 n72 +1 1 +.names b_0 n77 +1 1 +.names b_1 n82 +1 1 +.names b_2 n87 +1 1 +.names b_3 n92 +1 1 +.names cin n97 +1 1 +.names e f g d0 +1-1 1 +-0- 1 +.names reg3 x +1 1 +.names reg7 y +1 1 +.names reg11 z +1 1 +.names n01 n102 +1 1 +.names n02 n106 +1 1 +.names n03 n110 +1 1 +.names n04 n114 +1 1 +.names n05 n118 +1 1 +.end + + +.model adder +.inputs a b cin +.outputs cout sumout +.blackbox +.end + + +.model shift +.inputs D clk +.outputs Q +.blackbox +.end diff --git a/openfpga_flow/benchmarks/Test_Modes/test_modes.v b/openfpga_flow/benchmarks/Test_Modes/test_modes.v new file mode 100644 index 000000000..8090d2903 --- /dev/null +++ b/openfpga_flow/benchmarks/Test_Modes/test_modes.v @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////// +// // +// Benchmark using all modes of k8 architecture // +// // +//////////////////////////////////////////////////////// + +`timescale 1 ns/ 1 ps + +module test_modes( + clk, + a_0, + a_1, + a_2, + a_3, + b_0, + b_1, + b_2, + b_3, + cin, + e, + f, + g, + sum_0, + sum_1, + sum_2, + sum_3, + cout, + x, + y, + z ); + + input wire clk, a_0, a_1, a_2, a_3, b_0, b_1, b_2, b_3, cin, e, f, g; + output reg sum_0, sum_1, sum_2, sum_3, cout; + output wire x, y, z; + + wire d0; + wire [4:0] n0; + wire [3:0] a, b; + reg reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg10, reg11, reg_a_0, reg_a_1, reg_a_2, reg_a_3, reg_b_0, reg_b_1, reg_b_2, reg_b_3, reg_cin; + + assign a = {reg_a_3, reg_a_2, reg_a_1, reg_a_0}; + assign b = {reg_b_3, reg_b_2, reg_b_1, reg_b_0}; + assign d0 = (e && g) || !f; + assign n0 = a + b + reg_cin; + assign x = reg3; + assign y = reg7; + assign z = reg11; + + always @(posedge clk) begin + reg0 <= d0; + reg1 <= reg0; + reg2 <= reg1; + reg3 <= reg2; + reg4 <= reg3; + reg5 <= reg4; + reg6 <= reg5; + reg7 <= reg6; + reg8 <= reg7; + reg9 <= reg8; + reg10 <= reg9; + reg11 <= reg10; + reg_a_0 <= a_0; + reg_a_1 <= a_1; + reg_a_2 <= a_2; + reg_a_3 <= a_3; + reg_b_0 <= b_0; + reg_b_1 <= b_1; + reg_b_2 <= b_2; + reg_b_3 <= b_3; + reg_cin <= cin; + sum_0 <= n0[0]; + sum_1 <= n0[1]; + sum_2 <= n0[2]; + sum_3 <= n0[3]; + cout <= n0[4]; + end + +endmodule diff --git a/openfpga_flow/misc/fpgaflow_default_tool_path.conf b/openfpga_flow/misc/fpgaflow_default_tool_path.conf index d33fc4e80..d41183ac8 100644 --- a/openfpga_flow/misc/fpgaflow_default_tool_path.conf +++ b/openfpga_flow/misc/fpgaflow_default_tool_path.conf @@ -13,7 +13,7 @@ iverilog_path = iverilog include_netlist_verification = ${PATH:OPENFPGA_PATH}/vpr7_x2p/vpr/VerilogNetlists [FLOW_SCRIPT_CONFIG] -valid_flows = standard,vtr,vtr_standard,yosys_vpr +valid_flows = standard,vpr_blif,vtr,vtr_standard,yosys_vpr [DEFAULT_PARSE_RESULT_VPR] # parser format = , diff --git a/openfpga_flow/scripts/run_fpga_flow.py b/openfpga_flow/scripts/run_fpga_flow.py index 2a01e561e..f9971b6aa 100644 --- a/openfpga_flow/scripts/run_fpga_flow.py +++ b/openfpga_flow/scripts/run_fpga_flow.py @@ -2,6 +2,7 @@ import os import sys import shutil import time +from datetime import timedelta import shlex import glob import argparse @@ -13,6 +14,9 @@ import threading from string import Template import re import xml.etree.ElementTree as ET +from importlib import util +if util.find_spec("humanize"): + import humanize # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Initialise general paths for the script @@ -57,6 +61,15 @@ parser.add_argument('--run_dir', type=str, help="Directory to store intermidiate file & final results") parser.add_argument('--yosys_tmpl', type=str, help="Alternate yosys template, generates top_module.blif") +parser.add_argument('--debug', action="store_true", + help="Run script in debug mode") + +# Blif_VPR Only flow arguments +parser.add_argument('--activity_file', type=str, + help="Activity file used while running yosys flow") +parser.add_argument('--base_verilog', type=str, + help="Original Verilog file to run verification in " + + "blif_VPR flow") # ACE2 and power estimation related arguments parser.add_argument('--K', type=int, @@ -97,6 +110,8 @@ X2PParse.add_argument('--vpr_fpga_x2p_signal_density_weight', type=float, help="Specify the signal_density_weight of VPR FPGA SPICE") X2PParse.add_argument('--vpr_fpga_x2p_sim_window_size', type=float, help="specify the sim_window_size of VPR FPGA SPICE") +X2PParse.add_argument('--vpr_fpga_x2p_compact_routing_hierarchy', + action="store_true", help="Compact_routing_hierarchy") # VPR - FPGA-SPICE Extension SPParse = parser.add_argument_group('FPGA-SPICE Extension') @@ -160,6 +175,8 @@ VeriPar.add_argument('--vpr_fpga_verilog_print_input_blif_tb', VeriPar.add_argument('--vpr_fpga_verilog_print_modelsim_autodeck', type=str, help="Print modelsim " + "simulation script", metavar="") +VeriPar.add_argument('--vpr_fpga_verilog_explicit_mapping', action="store_true", + help="Explicit Mapping") # VPR - FPGA-Bitstream Extension BSparse = parser.add_argument_group('FPGA-Bitstream Extension') @@ -175,13 +192,14 @@ RegParse.add_argument("--end_flow_with_test", action="store_true", # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Global varaibles declaration # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -# Varible to store logger instance -logger = None -# arguments are parsed at the end of the script depending upon whether script -# is called externally or as a standalone -args = None +# Setting up print and logging system +logging.basicConfig(level=logging.INFO, stream=sys.stdout, + format='%(levelname)s - %(message)s') +logger = logging.getLogger('OpenFPGA_Flow_Logs') + # variable to store script_configuration and cad tool paths config, cad_tools = None, None +ExecTime = {} # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Main program starts here @@ -197,18 +215,34 @@ def main(): if (args.fpga_flow == "yosys_vpr"): logger.info('Running "yosys_vpr" Flow') run_yosys_with_abc() - if (args.fpga_flow == "vtr"): - run_odin2() - run_abc_vtr() - if (args.fpga_flow == "vtr_standard"): - run_abc_for_standarad() - if args.power: - run_ace2() - run_pro_blif_3arg() - run_rewrite_verilog() + run_rewrite_verilog() + if args.power: + run_ace2() + run_pro_blif_3arg() + if (args.fpga_flow == "vpr_blif"): + collect_files_for_vpr() + # if (args.fpga_flow == "vtr"): + # run_odin2() + # run_abc_vtr() + # if (args.fpga_flow == "vtr_standard"): + # run_abc_for_standarad() run_vpr() if args.end_flow_with_test: run_netlists_verification() + + ExecTime["End"] = time.time() + def timestr(x): return humanize.naturaldelta(timedelta(seconds=x)) \ + if "humanize" in sys.modules else str(int(x)) + " Sec " + TimeInfo = ("Openfpga_flow completed, " + + "Total Time Taken %s " % + timestr(ExecTime["End"]-ExecTime["Start"]) + + "VPR Time %s " % + timestr(ExecTime["VPREnd"]-ExecTime["VPRStart"])) + TimeInfo += ("Verification Time %s " % + timestr(ExecTime["VerificationEnd"] - + ExecTime["VerificationStart"]) + if args.end_flow_with_test else "") + logger.info(TimeInfo) exit() # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = @@ -249,9 +283,13 @@ def validate_command_line_arguments(): """ logger.info("Validating commnad line arguments") + if args.debug: + logger.info("Setting loggger in debug mode") + logger.setLevel(logging.DEBUG) + # Check if flow supported if not args.fpga_flow in config.get("FLOW_SCRIPT_CONFIG", "valid_flows"): - clean_up_and_exit("%s Flow not supported"%args.fpga_flow) + clean_up_and_exit("%s Flow not supported" % args.fpga_flow) # Check if argument list is consistant for eacharg, dependent in config.items("CMD_ARGUMENT_DEPENDANCY"): @@ -259,8 +297,8 @@ def validate_command_line_arguments(): dependent = dependent.split(",") for eachdep in dependent: if not any([getattr(args, i, 0) for i in eachdep.split("|")]): - clean_up_and_exit("'%s' argument depends on (%s) argumets"% - (eacharg, ", ".join(dependent).replace("|", " or "))) + clean_up_and_exit("'%s' argument depends on (%s) argumets" % + (eacharg, ", ".join(dependent).replace("|", " or "))) # Filter provided architecrue files args.arch_file = os.path.abspath(args.arch_file) @@ -273,7 +311,7 @@ def validate_command_line_arguments(): if os.path.isdir(args.benchmark_files[index]): logger.warning("Skipping directory in bench %s" % everyinput) logger.warning("Directory is not support in benchmark list" + - "use wildcard pattern to add files") + "use wildcard pattern to add files") continue for everyfile in glob.glob(args.benchmark_files[index]): if not os.path.isfile(everyfile): @@ -289,6 +327,10 @@ def validate_command_line_arguments(): # Expand run directory to absolute path args.run_dir = os.path.abspath(args.run_dir) + if args.activity_file: + args.activity_file = os.path.abspath(args.activity_file) + if args.base_verilog: + args.base_verilog = os.path.abspath(args.base_verilog) def ask_user_quetion(condition, question): @@ -492,14 +534,25 @@ def run_pro_blif_3arg(): logger.info("blif_3args output is written in file %s" % filename) +def collect_files_for_vpr(): + if len(args.benchmark_files) > 1: + logger.error("Expecting Single Benchmark BLif file.") + shutil.copy(args.benchmark_files[0], args.top_module+".blif") + shutil.copy(args.activity_file, args.top_module+"_ace_out.act") + shutil.copy(args.base_verilog, args.top_module+"_output_verilog.v") + + def run_vpr(): - # Run Standard VPR Flow - min_channel_width = run_standard_vpr( - args.top_module+".blif", - -1, - args.top_module+"_min_chan_width_vpr.txt") - logger.info("Standard VPR flow routed with minimum %d Channels" % - min_channel_width) + ExecTime["VPRStart"] = time.time() + + if not args.fix_route_chan_width: + # Run Standard VPR Flow + min_channel_width = run_standard_vpr( + args.top_module+".blif", + -1, + args.top_module+"_min_chan_width_vpr.txt") + logger.info("Standard VPR flow routed with minimum %d Channels" % + min_channel_width) # Minimum routing channel width if (args.min_route_chan_width): @@ -512,8 +565,8 @@ def run_vpr(): while(1): res = run_standard_vpr(args.top_module+".blif", int(min_channel_width), - args.top_module+"_reroute_vpr.txt", - route_only=True) + args.top_module+"_reroute_vpr.txt", + route_only=True) if res: logger.info("Routing with channel width=%d successful" % @@ -544,6 +597,7 @@ def run_vpr(): extract_vpr_stats(logfile=args.top_module+".power", r_filename="vpr_power_stat", parse_section="power") + ExecTime["VPREnd"] = time.time() def run_standard_vpr(bench_blif, fixed_chan_width, logfile, route_only=False): @@ -567,7 +621,7 @@ def run_standard_vpr(bench_blif, fixed_chan_width, logfile, route_only=False): command += ["--timing_driven_clustering", "off"] # channel width option if fixed_chan_width >= 0: - command += ["--route_chan_width", "%d"%fixed_chan_width] + command += ["--route_chan_width", "%d" % fixed_chan_width] if args.vpr_use_tileable_route_chan_width: command += ["--use_tileable_route_chan_width"] @@ -580,6 +634,9 @@ def run_standard_vpr(bench_blif, fixed_chan_width, logfile, route_only=False): if args.vpr_fpga_x2p_sim_window_size: command += ["--fpga_x2p_sim_window_size", args.vpr_fpga_x2p_sim_window_size] + if args.vpr_fpga_x2p_compact_routing_hierarchy: + command += ["--fpga_x2p_compact_routing_hierarchy"] + if args.vpr_fpga_spice_sim_mt_num: command += ["--fpga_spice_sim_mt_num", args.vpr_fpga_spice_sim_mt_num] @@ -621,6 +678,8 @@ def run_standard_vpr(bench_blif, fixed_chan_width, logfile, route_only=False): args.top_module+"_output_verilog.v"] if args.vpr_fpga_verilog_include_timing: command += ["--fpga_verilog_include_timing"] + if args.vpr_fpga_verilog_explicit_mapping: + command += ["--fpga_verilog_explicit_mapping"] if args.vpr_fpga_verilog_include_signal_init: command += ["--fpga_verilog_include_signal_init"] if args.vpr_fpga_verilog_formal_verification_top_netlist: @@ -661,6 +720,7 @@ def run_standard_vpr(bench_blif, fixed_chan_width, logfile, route_only=False): chan_width = None try: + logger.debug("Running VPR : " + " ".join(command)) with open(logfile, 'w+') as output: output.write(" ".join(command)+"\n") process = subprocess.run(command, @@ -708,8 +768,8 @@ def extract_vpr_stats(logfile, r_filename="vpr_stat", parse_section="vpr"): extract_val = str(match.group(1)) elif filt_function.strip() == "scientific": try: - mult = {"m":1E-3, "u":1E-6, "n":1E-9, - "K":1E-3, "M":1E-6, "G":1E-9,}.get(match.group(2)[0], 1) + mult = {"m": 1E-3, "u": 1E-6, "n": 1E-9, + "K": 1E-3, "M": 1E-6, "G": 1E-9, }.get(match.group(2)[0], 1) except: mult = 1 extract_val = float(match.group(1))*mult @@ -717,7 +777,7 @@ def extract_vpr_stats(logfile, r_filename="vpr_stat", parse_section="vpr"): extract_val = match.group(1) except: logger.exception("Filter failed") - extract_val= "Filter Failed" + extract_val = "Filter Failed" resultDict[name] = extract_val dummyparser = ConfigParser() @@ -726,7 +786,7 @@ def extract_vpr_stats(logfile, r_filename="vpr_stat", parse_section="vpr"): with open(r_filename+'.result', 'w') as configfile: dummyparser.write(configfile) logger.info("%s result extracted in file %s" % - (parse_section,r_filename+'.result')) + (parse_section, r_filename+'.result')) def run_rewrite_verilog(): @@ -747,13 +807,15 @@ def run_rewrite_verilog(): if process.returncode: logger.info("Rewrite veri yosys run failed with returncode %d", process.returncode) - except: + except Exception as e: logger.exception("Failed to run VPR") + print(e.output) clean_up_and_exit("") logger.info("Yosys output is written in file yosys_rewrite_veri_output.txt") def run_netlists_verification(): + ExecTime["VerificationStart"] = time.time() compiled_file = "compiled_"+args.top_module # include_netlists = args.top_module+"_include_netlists.v" tb_top_formal = args.top_module+"_top_formal_verification_random_tb" @@ -777,9 +839,11 @@ def run_netlists_verification(): logger.info("VVP Simulation Successful") else: logger.info(str(output).split("\n")[-1]) + ExecTime["VerificationEnd"] = time.time() def run_command(taskname, logfile, command, exit_if_fail=True): + logger.info("Launching %s " % taskname) try: with open(logfile, 'w+') as output: output.write(" ".join(command)+"\n") @@ -810,11 +874,6 @@ def process_failed_vpr_run(vpr_output): if __name__ == "__main__": - # Setting up print and logging system - logging.basicConfig(level=logging.DEBUG, stream=sys.stdout, - format='%(levelname)s - %(message)s') - logger = logging.getLogger('OpenFPGA_Flow_Logs') - - # Parse commandline argument + ExecTime["Start"] = time.time() args = parser.parse_args() main() diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index 6d1bf4a4b..b445c9d7e 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -2,6 +2,7 @@ import os import sys import shutil import time +from datetime import timedelta import shlex import argparse from configparser import ConfigParser, ExtendedInterpolation @@ -13,6 +14,10 @@ import csv from string import Template import run_fpga_flow import pprint +from importlib import util + +if util.find_spec("humanize"): + import humanize # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # Configure logging system @@ -33,6 +38,10 @@ parser.add_argument('--maxthreads', type=int, default=2, parser.add_argument('--config', help="Override default configuration") parser.add_argument('--test_run', action="store_true", help="Dummy run shows final generated VPR commands") +parser.add_argument('--debug', action="store_true", + help="Run script in debug mode") +parser.add_argument('--skip_tread_logs', action="store_true", + help="Skips logs from running thread") args = parser.parse_args() # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = @@ -76,7 +85,10 @@ def clean_up_and_exit(msg): def validate_command_line_arguments(): - pass + if args.debug: + logger.info("Setting loggger in debug mode") + logger.setLevel(logging.DEBUG) + logger.info("Set up to run %d Parallel threads", args.maxthreads) def generate_each_task_actions(taskname): @@ -143,7 +155,8 @@ def generate_each_task_actions(taskname): " with path %s " % (eachpath)) bench_files += files - ys_for_task = task_conf.get("SYNTHESIS_PARAM", "bench_yosys_common") + ys_for_task = task_conf.get("SYNTHESIS_PARAM", "bench_yosys_common", + fallback="") benchmark_list.append({ "files": bench_files, "top_module": task_conf.get("SYNTHESIS_PARAM", bech_name+"_top", @@ -215,36 +228,59 @@ def create_run_command(curr_job_dir, archfile, benchmark_obj, task_conf): command += ["--vpr_fpga_spice"] if task_conf.getboolean("GENERAL", "verilog_output", fallback=False): command += ["--vpr_fpga_verilog"] + command += ["--vpr_fpga_verilog_dir", "."] + command += ["--vpr_fpga_x2p_rename_illegal_port"] # Add other paramters to pass for key, values in task_conf["SCRIPT_PARAM"].items(): - command += ["--"+key, values] + command += ["--"+key, values] if values else ["--"+key] + + if args.debug: + command += ["--debug"] return command +def strip_child_logger_info(line): + try: + logtype, message = line.split(" - ", 1) + lognumb = {"CRITICAL": 50, "ERROR": 40, "WARNING": 30, + "INFO": 20, "DEBUG": 10, "NOTSET": 0} + logger.log(lognumb["INFO"], message) + except: + logger.info(line) + + def run_single_script(s, eachJob): logger.debug('Added job in pool') with s: logger.debug("Running OpenFPGA flow with " + " ".join(eachJob["commands"])) name = threading.currentThread().getName() + eachJob["starttime"] = time.time() try: logfile = "%s_out.log" % name with open(logfile, 'w+') as output: - process = subprocess.run(["python3.5", - gc["script_default"]] + - eachJob["commands"], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) - output.write(process.stdout) + process = subprocess.Popen(["python3.5", + gc["script_default"]] + + eachJob["commands"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True) + for line in process.stdout: + if not args.skip_tread_logs: + strip_child_logger_info(line[:-1]) + sys.stdout.buffer.flush() + output.write(line) + process.wait() eachJob["status"] = True except: - logger.error("Failed to execute openfpga flow - " + - eachJob["name"]) - # logger.exception("Failed to launch openfpga flow") - logger.info("%s Finished " % name) + logger.exception("Failed to execute openfpga flow - " + + eachJob["name"]) + eachJob["endtime"] = time.time() + timediff = timedelta(seconds=(eachJob["endtime"]-eachJob["starttime"])) + timestr = humanize.naturaldelta(timediff) if "humanize" in sys.modules \ + else str(timediff) + logger.info("%s Finished, Time Taken %s " % (name, timestr)) def run_actions(job_run_list): diff --git a/openfpga_flow/tasks/regression/regression_quick/config/golden_results.txt b/openfpga_flow/tasks/regression/regression_quick/config/golden_results.txt new file mode 100644 index 000000000..edde206c7 --- /dev/null +++ b/openfpga_flow/tasks/regression/regression_quick/config/golden_results.txt @@ -0,0 +1,2 @@ +arch circuit vpr_revision vpr_status error num_pre_packed_nets num_pre_packed_blocks num_post_packed_nets num_post_packed_blocks device_width device_height num_clb num_io num_outputs num_memories num_mult placed_wirelength_est placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est min_chan_width routed_wirelength min_chan_width_route_success_iteration crit_path_routed_wirelength crit_path_route_success_iteration critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile crit_path_routing_area_total crit_path_routing_area_per_tile odin_synth_time abc_synth_time abc_cec_time abc_sec_time ace_time pack_time place_time min_chan_width_route_time crit_path_route_time vtr_flow_elapsed_time max_vpr_mem max_odin_mem max_abc_mem +k6_frac_N10_mem32K_40nm.xml ch_intrinsics.v 30d086154 success 419 549 298 249 10 10 19 99 130 1 0 2262 2.74023 -250.655 -2.74023 42 2555 15 2250 12 3.5255 -318.677 -3.5255 0 0 3.92691e+06 1.57199e+06 236681. 2366.81 297605. 2976.05 0.03 0.00 -1 -1 -1 0.15 0.27 0.64 0.06 1.70 -1 -1 -1 diff --git a/openfpga_flow/tasks/regression/regression_quick/config/task.conf b/openfpga_flow/tasks/regression/regression_quick/config/task.conf new file mode 100644 index 000000000..277a3b6b7 --- /dev/null +++ b/openfpga_flow/tasks/regression/regression_quick/config/task.conf @@ -0,0 +1,38 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_22nm/22nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/s298/s298.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/alu4/alu4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/tseng/tseng.v + +[SYNTHESIS_PARAM] +bench0_top = s298 +bench1_top = alu4 +bench2_top = tseng + +[SCRIPT_PARAM] +min_route_chan_width=1.3 +end_flow_with_test= +vpr_fpga_verilog_include_icarus_simulator= +vpr_fpga_verilog_formal_verification_top_netlist= +vpr_fpga_verilog_include_timing= +vpr_fpga_verilog_include_signal_init= +vpr_fpga_verilog_print_autocheck_top_testbench= + +[POST_RUN] \ No newline at end of file diff --git a/run_test.sh b/run_test.sh index 2acefd58d..d218e9c52 100644 --- a/run_test.sh +++ b/run_test.sh @@ -1,16 +1,46 @@ +# python3.5 openfpga_flow/scripts/run_fpga_flow.py \ +# ./openfpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml \ +# ./openfpga_flow/benchmarks/MCNC_Verilog/s298/s298.v \ +# --top_module s298 \ +# --power \ +# --power_tech ./openfpga_flow/tech/PTM_22nm/22nm.xml \ +# --min_route_chan_width 1.3 \ +# --vpr_fpga_verilog \ +# --vpr_fpga_verilog_dir . \ +# --vpr_fpga_x2p_rename_illegal_port \ +# --end_flow_with_test \ +# --vpr_fpga_verilog_include_icarus_simulator \ +# --vpr_fpga_verilog_formal_verification_top_netlist \ +# --vpr_fpga_verilog_include_timing \ +# --vpr_fpga_verilog_include_signal_init \ +# --vpr_fpga_verilog_print_autocheck_top_testbench + + + python3.5 openfpga_flow/scripts/run_fpga_flow.py \ ./openfpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml \ -./openfpga_flow/benchmarks/MCNC_Verilog/s298/s298.v \ ---top_module s298 \ +./openfpga_flow/benchmarks/Test_Modes/test_modes.blif \ +--fpga_flow vpr_blif \ +--top_module test_modes \ +--activity_file ./openfpga_flow/benchmarks/Test_Modes/test_modes.act \ +--base_verilog ./openfpga_flow/benchmarks/Test_Modes/test_modes.v \ --power \ ---power_tech ./openfpga_flow/tech/PTM_22nm/22nm.xml \ ---min_route_chan_width 1.3 \ +--power_tech ./openfpga_flow/tech/PTM_45nm/45nm.xml \ +--fix_route_chan_width 300 \ --vpr_fpga_verilog \ --vpr_fpga_verilog_dir . \ --vpr_fpga_x2p_rename_illegal_port \ ---end_flow_with_test \ --vpr_fpga_verilog_include_icarus_simulator \ --vpr_fpga_verilog_formal_verification_top_netlist \ --vpr_fpga_verilog_include_timing \ --vpr_fpga_verilog_include_signal_init \ ---vpr_fpga_verilog_print_autocheck_top_testbench \ No newline at end of file +--vpr_fpga_verilog_print_autocheck_top_testbench \ +--debug \ +--vpr_fpga_bitstream_generator \ +--vpr_fpga_verilog_print_user_defined_template \ +--vpr_fpga_verilog_print_report_timing_tcl \ +--vpr_fpga_verilog_print_sdc_pnr \ +--vpr_fpga_verilog_print_sdc_analysis \ +--vpr_fpga_x2p_compact_routing_hierarchy \ +--end_flow_with_test +