diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index f5f2c3c7e..c9b44cd92 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -822,6 +822,9 @@ struct t_mode { t_pb_type* parent_pb_type = nullptr; int index = 0; + /* Xifan Tang: Specify if the mode is packable or not */ + bool packable = true; + /* Power related members */ t_mode_power* mode_power = nullptr; diff --git a/libs/libarchfpga/src/read_xml_arch_file.cpp b/libs/libarchfpga/src/read_xml_arch_file.cpp index cabb17bbb..cf2dd72c3 100644 --- a/libs/libarchfpga/src/read_xml_arch_file.cpp +++ b/libs/libarchfpga/src/read_xml_arch_file.cpp @@ -1956,6 +1956,20 @@ static void ProcessMode(pugi::xml_node Parent, t_mode* mode, const bool timing_e mode->name = vtr::strdup(Prop); } + /* Xifan Tang: parse XML about if this mode is packable or not */ + mode->packable = true; + /* If the parent mode is not packable, all the child mode should be unpackable as well */ + if (nullptr != mode->parent_pb_type->parent_mode) { + mode->packable = mode->parent_pb_type->parent_mode->packable; + } + /* Override if user specify */ + mode->packable = get_attribute(Parent, "packable", loc_data, ReqOpt::OPTIONAL).as_bool(mode->packable); + if (false == mode->packable) { + VTR_LOG("mode '%s[%s]' is defined by user to be not packable\n", + mode->parent_pb_type->name, + mode->name); + } + mode->num_pb_type_children = count_children(Parent, "pb_type", loc_data, ReqOpt::OPTIONAL); if (mode->num_pb_type_children > 0) { mode->pb_type_children = new t_pb_type[mode->num_pb_type_children]; diff --git a/openfpga/test_vpr_arch/k6_N10_40nm.xml b/openfpga/test_vpr_arch/k6_N10_40nm.xml index 630011e84..83b4948a8 100644 --- a/openfpga/test_vpr_arch/k6_N10_40nm.xml +++ b/openfpga/test_vpr_arch/k6_N10_40nm.xml @@ -139,7 +139,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_N10_tileable_40nm.xml b/openfpga/test_vpr_arch/k6_N10_tileable_40nm.xml index d86d7aa62..ceacbb3f2 100644 --- a/openfpga/test_vpr_arch/k6_N10_tileable_40nm.xml +++ b/openfpga/test_vpr_arch/k6_N10_tileable_40nm.xml @@ -139,7 +139,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_40nm.xml index ef9268810..8476a5155 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_40nm.xml @@ -158,7 +158,7 @@ - + @@ -230,7 +230,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml index bbe041562..504431eb0 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_40nm.xml @@ -245,7 +245,7 @@ - + @@ -321,7 +321,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_mem16K_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_mem16K_40nm.xml index 850eb5450..3ecd20733 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_mem16K_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_adder_chain_mem16K_40nm.xml @@ -282,7 +282,7 @@ - + @@ -358,7 +358,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_40nm.xml index 2c528c13c..146a170e5 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_40nm.xml @@ -158,7 +158,7 @@ - + @@ -230,7 +230,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml index eea76837f..19b27b88b 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml @@ -245,7 +245,7 @@ - + @@ -321,7 +321,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_40nm.xml index 9422c3a09..4c0751db4 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_40nm.xml @@ -282,7 +282,7 @@ - + @@ -358,7 +358,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_aib_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_aib_40nm.xml index e196cb83c..37dbb2b93 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_aib_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_aib_40nm.xml @@ -348,7 +348,7 @@ - + @@ -424,7 +424,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_multi_io_capacity_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_multi_io_capacity_40nm.xml index 8eb6f32bf..ff7c3278b 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_multi_io_capacity_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_multi_io_capacity_40nm.xml @@ -316,7 +316,7 @@ - + @@ -392,7 +392,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_reduced_io_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_reduced_io_40nm.xml index 6f8c4cfae..d9adc9056 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_reduced_io_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_mem16K_reduced_io_40nm.xml @@ -285,7 +285,7 @@ - + @@ -361,7 +361,7 @@ - + diff --git a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_wide_mem16K_40nm.xml b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_wide_mem16K_40nm.xml index f07f16c80..7eda2aa2f 100644 --- a/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_wide_mem16K_40nm.xml +++ b/openfpga/test_vpr_arch/k6_frac_N10_tileable_adder_chain_wide_mem16K_40nm.xml @@ -282,7 +282,7 @@ - + @@ -358,7 +358,7 @@ - + diff --git a/vpr/src/pack/cluster.cpp b/vpr/src/pack/cluster.cpp index fa9d4d8f8..51de31f7e 100644 --- a/vpr/src/pack/cluster.cpp +++ b/vpr/src/pack/cluster.cpp @@ -1458,6 +1458,11 @@ static enum e_block_pack_status try_place_atom_block_rec(const t_pb_graph_node* } pb_type = pb_graph_node->pb_type; + /* Xifan Tang: bypass unpackable modes */ + if (false == pb_type->parent_mode->packable) { + return BLK_FAILED_FEASIBLE; + } + is_primitive = (pb_type->num_modes == 0); if (is_primitive) { diff --git a/vpr/src/pack/cluster_router.cpp b/vpr/src/pack/cluster_router.cpp index d94691053..7f2cd37d9 100644 --- a/vpr/src/pack/cluster_router.cpp +++ b/vpr/src/pack/cluster_router.cpp @@ -1173,6 +1173,10 @@ static void expand_node_all_modes(t_lb_router_data* router_data, t_expansion_nod if (cur_mode != -1 && mode != cur_mode) { continue; } + /* Xifan Tang: Do not expand in unpackable modes */ + if (false == pin->parent_node->pb_type->parent_mode->packable) { + continue; + } /* Check whether a mode is illegal. If it is then the node will not be expanded */ bool is_illegal = false; diff --git a/vpr/src/pack/prepack.cpp b/vpr/src/pack/prepack.cpp index 28e8c2bc5..cf9ccdd6d 100644 --- a/vpr/src/pack/prepack.cpp +++ b/vpr/src/pack/prepack.cpp @@ -791,6 +791,13 @@ t_pack_molecule* alloc_and_load_pack_molecules(t_pack_patterns* list_of_pack_pat * TODO: Need to investigate better mapping strategies than first-fit */ for (i = 0; i < num_packing_patterns; i++) { + + /* Xifan Tang: skip patterns that belong to unpackable modes */ + if ( (nullptr != list_of_pack_patterns[i].root_block->pb_type->parent_mode) + && (false == list_of_pack_patterns[i].root_block->pb_type->parent_mode->packable) ) { + continue; + } + best_pattern = 0; for (j = 1; j < num_packing_patterns; j++) { if (is_used[best_pattern]) { @@ -799,7 +806,7 @@ t_pack_molecule* alloc_and_load_pack_molecules(t_pack_patterns* list_of_pack_pat best_pattern = j; } } - VTR_ASSERT(is_used[best_pattern] == false); + VTR_ASSERT(is_used[best_pattern] == false); is_used[best_pattern] = true; auto blocks = atom_ctx.nlist.blocks(); @@ -1213,6 +1220,11 @@ static t_pb_graph_node* get_expected_lowest_cost_primitive_for_atom_block_in_pb_ } } else { for (i = 0; i < curr_pb_graph_node->pb_type->num_modes; i++) { + /* Xifan Tang: early fail if this primitive in a unpackable mode */ + if (false == curr_pb_graph_node->pb_type->modes[i].packable) { + continue; + } + for (j = 0; j < curr_pb_graph_node->pb_type->modes[i].num_pb_type_children; j++) { *cost = UNDEFINED; cur = get_expected_lowest_cost_primitive_for_atom_block_in_pb_graph_node(blk_id, &curr_pb_graph_node->child_pb_graph_nodes[i][j][0], cost);