diff --git a/libs/libpcf/src/base/repack_design_constraints.h b/libs/libpcf/src/base/repack_design_constraints.h index 31db9562d..55ddbca7f 100644 --- a/libs/libpcf/src/base/repack_design_constraints.h +++ b/libs/libpcf/src/base/repack_design_constraints.h @@ -36,7 +36,11 @@ constexpr const char* REPACK_DESIGN_CONSTRAINT_OPEN_NET = "OPEN"; *******************************************************************/ class RepackDesignConstraints { public: /* Type of design constraints */ - enum e_design_constraint_type { PIN_ASSIGNMENT, NUM_DESIGN_CONSTRAINT_TYPES }; + enum e_design_constraint_type { + PIN_ASSIGNMENT, + IGNORE_NET, + NUM_DESIGN_CONSTRAINT_TYPES + }; public: /* Types */ typedef vtr::vector pin_info = pin_tokenizer.split('.'); + /* Expect two contents, otherwise error out */ + if (pin_info.size() != 2) { + std::string err_msg = + std::string("Invalid content '") + pin_ctx_to_parse + + std::string("' to skip, expect .\n"); + VTR_LOG_ERROR(err_msg.c_str()); + VTR_ASSERT(pin_info.size() == 2); + } + std::string pb_type_name = pin_info[0]; + openfpga::PortParser port_parser(pin_info[1]); + openfpga::BasicPort curr_port = port_parser.port(); + if (!curr_port.is_valid()) { + std::string err_msg = + std::string("Invalid pin definition '") + pin_ctx_to_parse + + std::string("', expect .[int:int]\n"); + VTR_LOG_ERROR(err_msg.c_str()); + VTR_ASSERT(curr_port.is_valid()); + } + repack_design_constraints.set_pb_type(design_constraint_id, pb_type_name); + repack_design_constraints.set_pin(design_constraint_id, curr_port); + repack_design_constraints.set_net( + design_constraint_id, + get_attribute(xml_pin_constraint, "name", loc_data).as_string()); +} + /******************************************************************** * Parse XML codes about to an object of *RepackDesignConstraints @@ -80,11 +124,16 @@ RepackDesignConstraints read_xml_repack_design_constraints( for (pugi::xml_node xml_design_constraint : xml_root.children()) { /* Error out if the XML child has an invalid name! */ - if (xml_design_constraint.name() != std::string("pin_constraint")) { - bad_tag(xml_design_constraint, loc_data, xml_root, {"pin_constraint"}); + if (xml_design_constraint.name() == std::string("pin_constraint")) { + read_xml_pin_constraint(xml_design_constraint, loc_data, + repack_design_constraints); + } else if (xml_design_constraint.name() == std::string("ignore_net")) { + read_xml_ignore_net_constraint(xml_design_constraint, loc_data, + repack_design_constraints); + } else { + bad_tag(xml_design_constraint, loc_data, xml_root, + {"pin_constraint", "ignore_net"}); } - read_xml_pin_constraint(xml_design_constraint, loc_data, - repack_design_constraints); } } catch (pugiutil::XmlError& e) { archfpga_throw(design_constraint_fname, e.line(), "%s", e.what()); diff --git a/openfpga/src/repack/repack.cpp b/openfpga/src/repack/repack.cpp index f80a42a41..35f45d7a1 100644 --- a/openfpga/src/repack/repack.cpp +++ b/openfpga/src/repack/repack.cpp @@ -575,10 +575,13 @@ static void add_lb_router_nets( /* Only for global net which should be ignored, cache the sink nodes */ BasicPort curr_pin(std::string(source_pb_pin->port->name), source_pb_pin->pin_number, source_pb_pin->pin_number); - if ((clustering_ctx.clb_nlist.net_is_ignored(cluster_net_id)) && - (clustering_ctx.clb_nlist.net_is_global(cluster_net_id)) && - (options.is_pin_ignore_global_nets(std::string(lb_type->pb_type->name), - curr_pin))) { + if ((clustering_ctx.clb_nlist.net_is_ignored(cluster_net_id) && + clustering_ctx.clb_nlist.net_is_global(cluster_net_id) && + options.is_pin_ignore_global_nets(std::string(lb_type->pb_type->name), + curr_pin)) || + (options.net_is_specified_to_be_ignored( + atom_ctx.nlist.net_name(pb_pin_mapped_nets[source_pb_pin]), + std::string(lb_type->pb_type->name), curr_pin))) { /* Find the net mapped to this pin in clustering results*/ AtomNetId atom_net_id = pb_pin_mapped_nets[source_pb_pin]; diff --git a/openfpga/src/repack/repack_option.cpp b/openfpga/src/repack/repack_option.cpp index b3a06f60f..af48ae2df 100644 --- a/openfpga/src/repack/repack_option.cpp +++ b/openfpga/src/repack/repack_option.cpp @@ -46,6 +46,24 @@ bool RepackOption::is_pin_ignore_global_nets(const std::string& pb_type_name, return false; } +bool RepackOption::net_is_specified_to_be_ignored(std::string cluster_net_name, + std::string pb_type_name, + const BasicPort& pin) const { + const RepackDesignConstraints& design_constraint = design_constraints(); + /* If found a constraint, record the net name */ + for (const RepackDesignConstraintId id_ : + design_constraint.design_constraints()) { + if (design_constraint.type(id_) == RepackDesignConstraints::IGNORE_NET && + design_constraint.pb_type(id_) == pb_type_name && + design_constraint.net(id_) == cluster_net_name) { + if (design_constraint.pin(id_).mergeable(pin) && + design_constraint.pin(id_).contained(pin)) + return true; + } + } + return false; +} + bool RepackOption::verbose_output() const { return verbose_output_; } /****************************************************************************** diff --git a/openfpga/src/repack/repack_option.h b/openfpga/src/repack/repack_option.h index 24f46633d..9fdb3392f 100644 --- a/openfpga/src/repack/repack_option.h +++ b/openfpga/src/repack/repack_option.h @@ -25,6 +25,9 @@ class RepackOption { /* Identify if a pin should ignore all the global nets */ bool is_pin_ignore_global_nets(const std::string& pb_type_name, const BasicPort& pin) const; + bool net_is_specified_to_be_ignored(std::string cluster_net_name, + std::string pb_type_name, + const BasicPort& pin) const; bool verbose_output() const; public: /* Public mutators */ diff --git a/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/pin_constraints.xml b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/pin_constraints.xml new file mode 100644 index 000000000..e297abb77 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/pin_constraints.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/repack_design_constraints.xml b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/repack_design_constraints.xml new file mode 100644 index 000000000..7c329b3e6 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/repack_design_constraints.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/rst_on_lut_pc.xml b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/rst_on_lut_pc.xml new file mode 100644 index 000000000..00b4b2bd6 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/rst_on_lut_pc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/rst_on_lut_repack_dc.xml b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/rst_on_lut_repack_dc.xml new file mode 100644 index 000000000..71153e425 --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/rst_on_lut_repack_dc.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/task.conf b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/task.conf new file mode 100644 index 000000000..63ffd257c --- /dev/null +++ b/openfpga_flow/tasks/fpga_bitstream/repack_ignore_nets/config/task.conf @@ -0,0 +1,50 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = false +spice_output=false +verilog_output=true +timeout_each_job = 3*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/ignore_global_nets_on_pins_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_repack_design_constraint_file=${PATH:TASK_DIR}/config/repack_design_constraints.xml +openfpga_vpr_device_layout=2x2 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N4_tileable_fracff_localRstGen_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/two_dff_inv_rst/two_dff_inv_rst.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/rst_on_lut/rst_on_lut.v + +[SYNTHESIS_PARAM] +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_sim.v +bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_map.v +bench_read_verilog_options_common = -nolatches +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys + +bench0_top = two_dff_inv_rst +bench0_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/pin_constraints.xml +bench0_openfpga_repack_design_constraint_file=${PATH:TASK_DIR}/config/repack_design_constraints.xml + +bench1_top = rst_on_lut +bench1_openfpga_pin_constraints_file = ${PATH:TASK_DIR}/config/rst_on_lut_pc.xml +bench1_openfpga_repack_design_constraint_file=${PATH:TASK_DIR}/config/rst_on_lut_repack_dc.xml + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist=