Skip to content

Commit 0a1f655

Browse files
committed
Merge branch 'master' of https://github.com/verilog-to-routing/vtr-verilog-to-routing into placement_move_primitive
2 parents ccffd51 + 4233826 commit 0a1f655

10 files changed

+150
-25
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,12 @@ struct t_pin_to_pin_annotation {
12251225
* parent_pb_graph_node : parent pb graph node
12261226
* total_primitive_count : Total number of this primitive type in the cluster. If there are 10 ALMs per cluster
12271227
* and 2 FFs per ALM (given the mode of the parent of this primitive) then the total is 20.
1228+
* This member is only used by nodes corresponding to primitive sites.
1229+
* flat_site_index : Index of this primitive site within its primitive type within this cluster type.
1230+
* Values are in [0...total_primitive_count-1], e.g. if there are 10 ALMs per cluster, 2 FFS
1231+
* and 2 LUTs per ALM, then flat site indices for FFs would run from 0 to 19, and flat site
1232+
indices for LUTs would run from 0 to 19. This member is only used by nodes corresponding
1233+
to primitive sites. It is used when reconstructing clusters from a flat placement file.
12281234
* illegal_modes : vector containing illegal modes that result in conflicts during routing
12291235
*/
12301236
class t_pb_graph_node {
@@ -1287,6 +1293,8 @@ class t_pb_graph_node {
12871293
int num_output_pin_class; /* number of output pin classes that this pb_graph_node has */
12881294

12891295
int total_primitive_count; /* total number of this primitive type in the cluster */
1296+
int flat_site_index; /* index of this primitive within sites of its type in this cluster */
1297+
12901298

12911299
/* Interconnect instances for this pb
12921300
* Only used for power

libs/libvtrutil/src/vtr_assert.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ void handle_assert(const char* expr, const char* file, unsigned int line, const
1616
fprintf(stderr, " (%s)", msg);
1717
}
1818
fprintf(stderr, ".\n");
19+
fflush(stdout);
20+
fflush(stderr);
1921
std::abort();
2022
}
2123

vpr/src/pack/cluster_placement.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,14 @@ t_cluster_placement_stats* alloc_and_load_cluster_placement_stats() {
8686
* primitives_list - a list of primitives indexed to match atom_block_ids of molecule.
8787
* Expects an allocated array of primitives ptrs as inputs.
8888
* This function loads the array with the lowest cost primitives that implement molecule
89+
* force_site - optional user-specified primitive site on which to place the molecule; if a force_site
90+
* argument is provided, the function either selects the specified site or reports failure.
91+
* If the force_site argument is set to its default value (-1), vpr selects an available site.
8992
*/
9093
bool get_next_primitive_list(t_cluster_placement_stats* cluster_placement_stats,
9194
const t_pack_molecule* molecule,
92-
t_pb_graph_node** primitives_list) {
95+
t_pb_graph_node** primitives_list,
96+
int force_site) {
9397
std::unordered_multimap<int, t_cluster_placement_primitive*>::iterator best;
9498

9599
int i;
@@ -136,6 +140,23 @@ bool get_next_primitive_list(t_cluster_placement_stats* cluster_placement_stats,
136140
continue;
137141
}
138142

143+
144+
/* check for force site match, if applicable */
145+
if (force_site > -1) {
146+
if (force_site == it->second->pb_graph_node->flat_site_index) {
147+
cost = try_place_molecule(molecule, it->second->pb_graph_node, primitives_list);
148+
if (cost < HUGE_POSITIVE_FLOAT) {
149+
cluster_placement_stats->move_primitive_to_inflight(i, it);
150+
return true;
151+
} else {
152+
break;
153+
}
154+
} else {
155+
++it;
156+
continue;
157+
}
158+
}
159+
139160
/* try place molecule at root location cur */
140161
cost = try_place_molecule(molecule, it->second->pb_graph_node, primitives_list);
141162

@@ -153,6 +174,11 @@ bool get_next_primitive_list(t_cluster_placement_stats* cluster_placement_stats,
153174
}
154175
}
155176

177+
/* if force_site was specified but not found, fail */
178+
if (force_site > -1) {
179+
found_best = false;
180+
}
181+
156182
if (!found_best) {
157183
/* failed to find a placement */
158184
for (i = 0; i < molecule->num_blocks; i++) {

vpr/src/pack/cluster_placement.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
#ifndef CLUSTER_PLACEMENT_H
77
#define CLUSTER_PLACEMENT_H
88
#include "arch_types.h"
9+
#include "vpr_types.h"
910

1011
t_cluster_placement_stats* alloc_and_load_cluster_placement_stats();
1112
bool get_next_primitive_list(
1213
t_cluster_placement_stats* cluster_placement_stats,
1314
const t_pack_molecule* molecule,
14-
t_pb_graph_node** primitives_list);
15+
t_pb_graph_node** primitives_list,
16+
int force_site = -1);
1517
void commit_primitive(t_cluster_placement_stats* cluster_placement_stats,
1618
const t_pb_graph_node* primitive);
1719
void set_mode_cluster_placement_stats(const t_pb_graph_node* complex_block,

vpr/src/pack/cluster_util.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,8 @@ e_block_pack_status try_pack_molecule(t_cluster_placement_stats* cluster_placeme
932932
int feasible_block_array_size,
933933
t_ext_pin_util max_external_pin_util,
934934
PartitionRegion& temp_cluster_pr,
935-
NocGroupId& temp_noc_grp_id) {
935+
NocGroupId& temp_noc_grp_id,
936+
int force_site) {
936937
t_pb* parent;
937938
t_pb* cur_pb;
938939

@@ -1009,7 +1010,7 @@ e_block_pack_status try_pack_molecule(t_cluster_placement_stats* cluster_placeme
10091010

10101011
while (block_pack_status != e_block_pack_status::BLK_PASSED) {
10111012
if (get_next_primitive_list(cluster_placement_stats_ptr, molecule,
1012-
primitives_list)) {
1013+
primitives_list, force_site)) {
10131014
block_pack_status = e_block_pack_status::BLK_PASSED;
10141015

10151016
int failed_location = 0;
@@ -1383,7 +1384,8 @@ bool atom_cluster_noc_group_check(AtomBlockId blk_id,
13831384
ClusterBlockId clb_index,
13841385
int verbosity,
13851386
NocGroupId& temp_cluster_noc_grp_id) {
1386-
const NocGroupId atom_noc_grp_id = g_vpr_ctx.cl_helper().atom_noc_grp_id[blk_id];
1387+
const auto& atom_noc_grp_ids = g_vpr_ctx.cl_helper().atom_noc_grp_id;
1388+
const NocGroupId atom_noc_grp_id = atom_noc_grp_ids.empty() ? NocGroupId::INVALID() : atom_noc_grp_ids[blk_id];
13871389

13881390
if (temp_cluster_noc_grp_id == NocGroupId::INVALID()) {
13891391
// the cluster does not have a NoC group

vpr/src/pack/cluster_util.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ e_block_pack_status try_pack_molecule(t_cluster_placement_stats* cluster_placeme
214214
int feasible_block_array_size,
215215
t_ext_pin_util max_external_pin_util,
216216
PartitionRegion& temp_cluster_pr,
217-
NocGroupId& temp_noc_grp_id);
217+
NocGroupId& temp_noc_grp_id,
218+
int force_site = -1);
218219

219220
void try_fill_cluster(const t_packer_opts& packer_opts,
220221
t_cluster_placement_stats* cur_cluster_placement_stats_ptr,
@@ -493,4 +494,4 @@ bool cleanup_pb(t_pb* pb);
493494
void alloc_and_load_pb_stats(t_pb* pb, const int feasible_block_array_size);
494495

495496
void init_clb_atoms_lookup(vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>>& atoms_lookup);
496-
#endif
497+
#endif

vpr/src/pack/pb_type_graph.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ static void alloc_and_load_pb_graph(t_pb_graph_node* pb_graph_node,
4848
t_pb_graph_node* parent_pb_graph_node,
4949
t_pb_type* pb_type,
5050
const int index,
51+
const int flat_index,
5152
bool load_power_structures,
5253
int& pin_count_in_cluster,
5354
int& primitive_num);
@@ -135,6 +136,11 @@ static bool check_input_pins_equivalence(const t_pb_graph_pin* cur_pin,
135136
std::map<int, int>& edges_map,
136137
int* line_num);
137138

139+
/* computes the index of a pb graph node at its level of the pb hierarchy */
140+
static int compute_flat_index_for_child_node(int num_children_of_type,
141+
int parent_flat_index,
142+
int child_index);
143+
138144
/**
139145
* Allocate memory into types and load the pb graph with interconnect edges
140146
*/
@@ -153,6 +159,7 @@ void alloc_and_load_all_pb_graphs(bool load_power_structures, bool is_flat) {
153159
nullptr,
154160
type.pb_type,
155161
0,
162+
0,
156163
load_power_structures,
157164
pin_count_in_cluster,
158165
primitive_num);
@@ -227,6 +234,7 @@ static void alloc_and_load_pb_graph(t_pb_graph_node* pb_graph_node,
227234
t_pb_graph_node* parent_pb_graph_node,
228235
t_pb_type* pb_type,
229236
const int index,
237+
const int flat_index,
230238
bool load_power_structures,
231239
int& pin_count_in_cluster,
232240
int& primitive_num) {
@@ -240,6 +248,9 @@ static void alloc_and_load_pb_graph(t_pb_graph_node* pb_graph_node,
240248
pb_graph_node->num_output_ports = 0;
241249
pb_graph_node->num_clock_ports = 0;
242250

251+
pb_graph_node->total_primitive_count = 0;
252+
pb_graph_node->flat_site_index = 0;
253+
243254
/* Generate ports for pb graph node */
244255
for (i = 0; i < pb_type->num_ports; i++) {
245256
if (pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) {
@@ -356,11 +367,15 @@ static void alloc_and_load_pb_graph(t_pb_graph_node* pb_graph_node,
356367
sizeof(t_pb_graph_node*));
357368
for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
358369
pb_graph_node->child_pb_graph_nodes[i][j] = (t_pb_graph_node*)vtr::calloc(pb_type->modes[i].pb_type_children[j].num_pb, sizeof(t_pb_graph_node));
359-
for (k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) {
370+
int num_children_of_type = pb_type->modes[i].pb_type_children[j].num_pb;
371+
372+
for (k = 0; k < num_children_of_type; k++) {
373+
int child_flat_index = compute_flat_index_for_child_node(num_children_of_type, flat_index, k);
360374
alloc_and_load_pb_graph(&pb_graph_node->child_pb_graph_nodes[i][j][k],
361375
pb_graph_node,
362376
&pb_type->modes[i].pb_type_children[j],
363377
k,
378+
child_flat_index,
364379
load_power_structures,
365380
pin_count_in_cluster,
366381
primitive_num);
@@ -378,6 +393,22 @@ static void alloc_and_load_pb_graph(t_pb_graph_node* pb_graph_node,
378393
&pb_type->modes[i],
379394
load_power_structures);
380395
}
396+
397+
398+
// update the total number of primitives of that type
399+
if (pb_graph_node->is_primitive()) {
400+
int total_count = 1;
401+
auto pb_node = pb_graph_node;
402+
while (!pb_node->is_root()) {
403+
total_count *= pb_node->pb_type->num_pb;
404+
pb_node = pb_node->parent_pb_graph_node;
405+
}
406+
pb_graph_node->total_primitive_count = total_count;
407+
408+
// if this is a primitive, then flat_index corresponds
409+
// to its index within all primitives of this type
410+
pb_graph_node->flat_site_index = flat_index;
411+
}
381412
}
382413

383414
static void alloc_and_load_pb_graph_pin_sinks(t_pb_graph_node* pb_graph_node) {
@@ -1911,3 +1942,22 @@ const t_pb_graph_edge* get_edge_between_pins(const t_pb_graph_pin* driver_pin, c
19111942

19121943
return nullptr;
19131944
}
1945+
1946+
/* Date:June 8th, 2024
1947+
* Author: Kate Thurmer
1948+
* Purpose: This subroutine computes the index of a pb graph node at its
1949+
level of the pb hierarchy; it is computed by the parent and
1950+
passed to each child of each child pb type. When the child is
1951+
a primitive, the computed indes is its flat site index.
1952+
For example, if there are 10 ALMs, each with 2 FFs and 2 LUTs,
1953+
then the ALM at index N, when calling this function for
1954+
its FF child at index M, would compute the child's index as:
1955+
N*(FFs per ALM) + M
1956+
e.g. for FF[1] in ALM[5], this returns
1957+
5*(2 FFS per ALM) + 1 = 11
1958+
*/
1959+
static int compute_flat_index_for_child_node(int num_children_of_type,
1960+
int parent_flat_index,
1961+
int child_index) {
1962+
return parent_flat_index*num_children_of_type + child_index;
1963+
}

vpr/src/pack/re_cluster.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,6 @@ bool move_mol_to_new_cluster(t_pack_molecule* molecule,
7373
//Commit or revert the move
7474
if (is_created) {
7575
commit_mol_move(old_clb, new_clb, during_packing, true);
76-
// Update the clb-->atoms lookup table
77-
helper_ctx.atoms_lookup.resize(helper_ctx.total_clb_num);
78-
for (int i_atom = 0; i_atom < molecule_size; ++i_atom) {
79-
if (molecule->atom_block_ids[i_atom]) {
80-
helper_ctx.atoms_lookup[new_clb].insert(molecule->atom_block_ids[i_atom]);
81-
}
82-
}
83-
8476
VTR_LOGV(verbosity > 4, "Atom:%zu is moved to a new cluster\n", molecule->atom_block_ids[molecule->root]);
8577
} else {
8678
revert_mol_move(old_clb, molecule, old_router_data, during_packing, clustering_data);

vpr/src/pack/re_cluster_util.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule,
127127
t_clustering_data& clustering_data,
128128
t_lb_router_data** router_data,
129129
PartitionRegion& temp_cluster_pr,
130-
NocGroupId& temp_cluster_noc_grp_id) {
130+
NocGroupId& temp_cluster_noc_grp_id,
131+
enum e_detailed_routing_stages detailed_routing_stage,
132+
int force_site) {
131133
auto& atom_ctx = g_vpr_ctx.atom();
132134
auto& floorplanning_ctx = g_vpr_ctx.mutable_floorplanning();
133135
auto& helper_ctx = g_vpr_ctx.mutable_cl_helper();
@@ -162,14 +164,15 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule,
162164
helper_ctx.num_models,
163165
helper_ctx.max_cluster_size,
164166
clb_index,
165-
E_DETAILED_ROUTE_FOR_EACH_ATOM,
167+
detailed_routing_stage,
166168
*router_data,
167169
0,
168170
enable_pin_feasibility_filter,
169171
0,
170172
FULL_EXTERNAL_PIN_UTIL,
171173
temp_cluster_pr,
172-
temp_cluster_noc_grp_id);
174+
temp_cluster_noc_grp_id,
175+
force_site);
173176

174177
// If clustering succeeds, add it to the clb netlist
175178
if (pack_result == e_block_pack_status::BLK_PASSED) {
@@ -185,6 +188,14 @@ bool start_new_cluster_for_mol(t_pack_molecule* molecule,
185188
int molecule_size = get_array_size_of_molecule(molecule);
186189
update_cluster_pb_stats(molecule, molecule_size, clb_index, true);
187190

191+
// Update the clb-->atoms lookup table
192+
helper_ctx.atoms_lookup.resize(helper_ctx.total_clb_num);
193+
for (int i_atom = 0; i_atom < molecule_size; ++i_atom) {
194+
if (molecule->atom_block_ids[i_atom]) {
195+
helper_ctx.atoms_lookup[clb_index].insert(molecule->atom_block_ids[i_atom]);
196+
}
197+
}
198+
188199
//If you are still in packing, update the clustering data. Otherwise, update the clustered netlist.
189200
if (during_packing) {
190201
clustering_data.intra_lb_routing.push_back((*router_data)->saved_lb_nets);
@@ -211,7 +222,10 @@ bool pack_mol_in_existing_cluster(t_pack_molecule* molecule,
211222
bool during_packing,
212223
t_clustering_data& clustering_data,
213224
t_lb_router_data*& router_data,
214-
bool enable_pin_feasibility_filter) {
225+
enum e_detailed_routing_stages detailed_routing_stage,
226+
bool enable_pin_feasibility_filter,
227+
int force_site) {
228+
215229
auto& helper_ctx = g_vpr_ctx.mutable_cl_helper();
216230
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
217231

@@ -237,15 +251,16 @@ bool pack_mol_in_existing_cluster(t_pack_molecule* molecule,
237251
helper_ctx.num_models,
238252
helper_ctx.max_cluster_size,
239253
new_clb,
240-
E_DETAILED_ROUTE_FOR_EACH_ATOM,
254+
detailed_routing_stage,
241255
router_data,
242256
0,
243257
enable_pin_feasibility_filter,
244258
//false,
245259
helper_ctx.feasible_block_array_size,
246260
target_ext_pin_util,
247261
temp_cluster_pr,
248-
temp_cluster_noc_grp_id);
262+
temp_cluster_noc_grp_id,
263+
force_site);
249264

250265
// If clustering succeeds, add it to the clb netlist
251266
if (pack_result == e_block_pack_status::BLK_PASSED) {

0 commit comments

Comments
 (0)