def init_script_file( yosys_script_full_path, yosys_models_full_path, yosys_spram_full_path, yosys_dpram_full_path, yosys_spram_rename_full_path, yosys_dpram_rename_full_path, circuit_list, output_netlist, memory_addr_width, min_hard_mult_size, min_hard_adder_size, ): """initializing the raw yosys script file""" # specify the input files type for circuit in circuit_list: file_extension = os.path.splitext(circuit)[-1] if file_extension not in FILE_TYPES: raise vtr.VtrError( "Inavlid input file type '{}'".format(file_extension)) # Update the config file vtr.file_replace( yosys_script_full_path, { "XXX": circuit_list[0], "YYY": "./" + YOSYS_LIB_FILES["YSMDL"], "SSS": "./" + YOSYS_LIB_FILES["SPRAM"], "DDD": "./" + YOSYS_LIB_FILES["DPRAM"], "SSR": "./" + YOSYS_LIB_FILES["SPRAMR"], "DDR": "./" + YOSYS_LIB_FILES["DPRAMR"], "TTT": str(vtr.paths.yosys_lib_path), "ZZZ": output_netlist, }, ) # Update the config file vtr.file_replace( yosys_models_full_path, { "PPP": memory_addr_width, "MMM": min_hard_mult_size, "AAA": min_hard_adder_size }, ) # Update the config file files vtr.file_replace(yosys_spram_full_path, {"PPP": memory_addr_width}) vtr.file_replace(yosys_dpram_full_path, {"PPP": memory_addr_width}) vtr.file_replace(yosys_spram_rename_full_path, {"PPP": memory_addr_width}) vtr.file_replace(yosys_dpram_rename_full_path, {"PPP": memory_addr_width})
def process_unknown_args(unknown_args): """ We convert the unknown_args into a dictionary, which is eventually used to generate arguments for VPR """ vpr_args = OrderedDict() while len(unknown_args) > 0: # Get the first argument arg = unknown_args.pop(0) if arg == "": continue if not arg.startswith("-"): raise vtr.VtrError( "Extra argument '{}' intended for VPR does not start with '-'". format(arg)) # To make it a valid kwargs dictionary we trim the initial '-' or '--' from the # argument name assert len(arg) >= 2 if arg[1] == "-": # Double-dash prefix arg = arg[2:] else: # Single-dash prefix arg = arg[1:] # Determine if there is a value associated with this argument if len(unknown_args) == 0 or (unknown_args[0].startswith("-") and arg != "target_ext_pin_util"): # Single value argument, we place these with value 'True' # in vpr_args vpr_args[arg] = True else: # Multivalue argument val = unknown_args.pop(0) if len(unknown_args) != 0 and not unknown_args[0].startswith("-"): temp = val val = [] val.append(temp) while len(unknown_args) != 0 and not unknown_args[0].startswith( "-"): val.append(unknown_args.pop(0)) vpr_args[arg] = val return vpr_args
def init_config_file( odin_config_full_path, circuit_list, architecture_file, output_netlist, memory_addr_width, min_hard_mult_size, min_hard_adder_size, ): """initializing the raw odin config file""" # specify the input files type file_extension = os.path.splitext(circuit_list[0])[-1] if file_extension not in FILE_TYPES: raise vtr.VtrError( "Inavlid input file type '{}'".format(file_extension)) input_file_type = FILE_TYPES[file_extension] # Update the config file vtr.file_replace( odin_config_full_path, { "YYY": architecture_file, "TTT": input_file_type, "ZZZ": output_netlist, "PPP": memory_addr_width, "MMM": min_hard_mult_size, "AAA": min_hard_adder_size, }, ) # loading the given config file config_file = ET.parse(odin_config_full_path) root = config_file.getroot() # based on the base config file verilog_files_tag = root.find("inputs") # remove the template line XXX, verilog_files_tag [1] is a comment verilog_files_tag.remove(verilog_files_tag[1]) for circuit in circuit_list: verilog_file = ET.SubElement(verilog_files_tag, "input_path_and_name") verilog_file.tail = "\n\n\t" if (circuit == circuit_list[-1]) else "\n\n\t\t" verilog_file.text = circuit # update the config file with new values config_file.write(odin_config_full_path)
def run( architecture_file, circuit_file, power_tech_file=None, start_stage=VtrStage.odin, end_stage=VtrStage.vpr, command_runner=vtr.CommandRunner(), temp_dir=Path("./temp"), odin_args=None, abc_args=None, vpr_args=None, keep_intermediate_files=True, keep_result_files=True, odin_config=None, min_hard_mult_size=3, min_hard_adder_size=1, check_equivalent=False, check_incremental_sta_consistency=False, use_old_abc_script=False, relax_w_factor=1.3, check_route=False, check_place=False, ): """ Runs the VTR CAD flow to map the specified circuit_file onto the target architecture_file .. note :: Usage: vtr.run(<architecture_file>,<circuit_file>,[OPTIONS]) Arguments ========= architecture_file : Architecture file to target circuit_file : Circuit to implement Other Parameters ---------------- power_tech_file : Technology power file. Enables power analysis and runs ace start_stage : Stage of the flow to start at end_stage : Stage of the flow to finish at temp_dir : Directory to run in (created if non-existent) command_runner : A CommandRunner object used to run system commands verbosity : whether to output error description or not odin_args : A dictionary of keyword arguments to pass on to ODIN II abc_args : A dictionary of keyword arguments to pass on to ABC vpr_args : A dictionary of keyword arguments to pass on to VPR keep_intermediate_files : Determines if intermediate files are kept or deleted keep_result_files : Determines if the result files are kept or deleted min_hard_mult_size : Tells ODIN II the minimum multiplier size that should be implemented using hard multiplier (if available) min_hard_adder_size : Tells ODIN II the minimum adder size that should be implemented using hard adder (if available). check_equivalent : Enables Logical Equivalence Checks use_old_abc_script : Enables the use of the old ABC script relax_w_factor : Factor by which to relax minimum channel width for critical path delay routing check_incremental_sta_consistency : Do a second-run of the incremental analysis to compare the result files check_route: Check first placement and routing by enabling VPR analysis check_place: Route existing placement by enabling VPR routing. """ # # Initial setup # vpr_args = OrderedDict() if not vpr_args else vpr_args odin_args = OrderedDict() if not odin_args else odin_args abc_args = OrderedDict() if not abc_args else abc_args # Verify that files are Paths or convert them to Paths and check that they exist architecture_file = vtr.util.verify_file(architecture_file, "Architecture") circuit_file = vtr.util.verify_file(circuit_file, "Circuit") if architecture_file.suffix != ".xml": raise vtr.VtrError( "Expected Architecture file as second argument (was {})".format( architecture_file.name)) power_tech_file = vtr.util.verify_file( power_tech_file, "Power") if power_tech_file else None temp_dir = Path(temp_dir) temp_dir.mkdir(parents=True, exist_ok=True) netlist_ext = ".blif" if ".eblif" not in circuit_file.suffixes else ".eblif" # Define useful filenames post_odin_netlist = temp_dir / (circuit_file.stem + ".odin" + netlist_ext) post_abc_netlist = temp_dir / (circuit_file.stem + ".abc" + netlist_ext) post_ace_netlist = temp_dir / (circuit_file.stem + ".ace" + netlist_ext) post_ace_activity_file = temp_dir / (circuit_file.stem + ".act") pre_vpr_netlist = temp_dir / (circuit_file.stem + ".pre-vpr" + netlist_ext) # If the user provided a .blif or .eblif netlist, we use that as the baseline for LEC # (ABC can't LEC behavioural verilog) lec_base_netlist = circuit_file.name if "blif" in circuit_file.suffixes else None # Reference netlist for LEC gen_postsynthesis_netlist = temp_dir / (circuit_file.stem + "_post_synthesis" + netlist_ext) # Copy the circuit and architecture circuit_copy = temp_dir / circuit_file.name architecture_copy = temp_dir / architecture_file.name shutil.copy(str(circuit_file), str(circuit_copy)) shutil.copy(str(architecture_file), str(architecture_copy)) # There are multiple potential paths for the netlist to reach a tool # We initialize it here to the user specified circuit and let downstream # stages update it next_stage_netlist = circuit_copy # # RTL Elaboration & Synthesis # if should_run_stage(VtrStage.odin, start_stage, end_stage) and circuit_file.suffixes != ".blif": vtr.odin.run( architecture_copy, next_stage_netlist, output_netlist=post_odin_netlist, command_runner=command_runner, temp_dir=temp_dir, odin_args=odin_args, odin_config=odin_config, min_hard_mult_size=min_hard_mult_size, min_hard_adder_size=min_hard_adder_size, ) next_stage_netlist = post_odin_netlist lec_base_netlist = post_odin_netlist if not lec_base_netlist else lec_base_netlist # # Logic Optimization & Technology Mapping # if should_run_stage(VtrStage.abc, start_stage, end_stage): vtr.abc.run( architecture_copy, next_stage_netlist, output_netlist=post_abc_netlist, command_runner=command_runner, temp_dir=temp_dir, abc_args=abc_args, keep_intermediate_files=keep_intermediate_files, use_old_abc_script=use_old_abc_script, ) next_stage_netlist = post_abc_netlist lec_base_netlist = post_abc_netlist if not lec_base_netlist else lec_base_netlist # # Power Activity Estimation # if power_tech_file: # The user provided a tech file, so do power analysis if should_run_stage(VtrStage.ace, start_stage, end_stage): vtr.ace.run( next_stage_netlist, old_netlist=post_odin_netlist, output_netlist=post_ace_netlist, output_activity_file=post_ace_activity_file, command_runner=command_runner, temp_dir=temp_dir, ) if not keep_intermediate_files: next_stage_netlist.unlink() post_odin_netlist.unlink() # Use ACE's output netlist next_stage_netlist = post_ace_netlist lec_base_netlist = post_ace_netlist if not lec_base_netlist else lec_base_netlist # Enable power analysis in VPR vpr_args["power"] = True vpr_args["tech_properties"] = str(power_tech_file.resolve()) # # Pack/Place/Route # if should_run_stage(VtrStage.vpr, start_stage, end_stage): # Copy the input netlist for input to vpr shutil.copyfile(str(next_stage_netlist), str(pre_vpr_netlist)) route_fixed_w = "route_chan_width" in vpr_args if (check_route or check_place) and not route_fixed_w: vpr_args["route_chan_width"] = 300 route_fixed_w = True if route_fixed_w: # The User specified a fixed channel width do_second_run = False second_run_args = vpr_args if "write_rr_graph" in vpr_args or "analysis" in vpr_args or "route" in vpr_args: do_second_run = True vtr.vpr.run( architecture_copy, pre_vpr_netlist, circuit_copy.stem, command_runner=command_runner, temp_dir=temp_dir, vpr_args=vpr_args, ) if do_second_run: # Run vpr again with additional parameters. # This is used to ensure that files generated by VPR can be re-loaded by it rr_graph_ext = (Path(second_run_args["write_rr_graph"]).suffix if "write_rr_graph" in second_run_args else ".xml") if check_place: second_run_args["route"] = True if check_route: second_run_args["analysis"] = True vtr.vpr.run_second_time( architecture_copy, pre_vpr_netlist, circuit_copy.stem, command_runner=command_runner, temp_dir=temp_dir, second_run_args=second_run_args, rr_graph_ext=rr_graph_ext, ) else: # First find minW and then re-route at a relaxed W vtr.vpr.run_relax_w( architecture_copy, pre_vpr_netlist, circuit_copy.stem, command_runner=command_runner, relax_w_factor=relax_w_factor, temp_dir=temp_dir, vpr_args=vpr_args, ) lec_base_netlist = pre_vpr_netlist if not lec_base_netlist else lec_base_netlist # # Logical Equivalence Checks (LEC) # if check_equivalent: for file in Path(temp_dir).iterdir(): if "post_synthesis.blif" in str(file): gen_postsynthesis_netlist = file.name break vtr.abc.run_lec( lec_base_netlist, gen_postsynthesis_netlist, command_runner=command_runner, temp_dir=temp_dir, ) # Do a second-run of the incremental analysis to compare the result files if check_incremental_sta_consistency: vtr.vpr.cmp_full_vs_incr_sta( architecture_copy, pre_vpr_netlist, circuit_copy.stem, command_runner=command_runner, vpr_args=vpr_args, temp_dir=temp_dir, ) if not keep_intermediate_files: delete_intermediate_files( next_stage_netlist, post_ace_activity_file, keep_result_files, temp_dir, power_tech_file, )