Skip to content

Commit c800558

Browse files
Merge branch 'master' into remove_per_layer_bb
2 parents 3a02a43 + f7d53a4 commit c800558

19 files changed

Lines changed: 2363 additions & 666 deletions

File tree

.readthedocs.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ sphinx:
1010
builder: dirhtml
1111
configuration: doc/src/conf.py
1212

13-
# Optionally build your docs in additional formats such as PDF and ePub
14-
formats: all
13+
# Build the HTML site and the downloadable PDF. Each format is a separate full
14+
# Sphinx run; also building htmlzip and epub pushed the build past Read the Docs'
15+
# time limit, so those are left off. Add them back here only if needed.
16+
formats:
17+
- pdf
1518

1619
# Optionally set the version of Python and requirements required to build your docs
1720
build:

doc/_doxygen/vpr.dox

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ EXTRACT_STATIC = YES
88
WARN_IF_UNDOCUMENTED = NO
99
INPUT = ../../vpr ../../libs/libarchfpga/
1010
RECURSIVE = YES
11+
EXCLUDE_PATTERNS = */test/* */tests/* */gen/*
1112
GENERATE_HTML = NO
1213
GENERATE_LATEX = NO
1314
GENERATE_XML = YES

doc/src/mosaic/index.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,3 @@ Mosaic is a Yosys-based synthesis frontend for VTR, it is an alternative to Pamr
1414
Select Mosaic with ``-start mosaic`` on :ref:`run_vtr_flow`. Parmys remains the default frontend. Mosaic writes a LUT-mapped BLIF (``<circuit>.mosaic.blif``), so the flow skips the external ABC stage and continues into VPR.
1515

1616
The default VTR build includes Mosaic (``WITH_MOSAIC``, default ``ON``). The plugin is installed at ``build/share/yosys/plugins/mosaic.so``.
17-
18-
.. toctree::
19-
:maxdepth: 2
20-
21-
users
22-
developers

doc/src/vpr/command_line_usage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,8 @@ For people not working on CAD, you can probably leave all the options to their d
862862

863863
Controls the verbosity of clustering output.
864864
Larger values produce more detailed output, which may be useful for debugging architecture packing problems.
865+
At ``2`` (the default) the clustered-netlist check prints only aggregate counts of unusual blocks (e.g. single-output blocks that may be constant generators).
866+
At ``3`` or higher these blocks are also listed individually.
865867

866868
**Default:** ``2``
867869

libs/EXTERNAL/libcatch2

Submodule libcatch2 updated 57 files

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pandas
55
numpy
66
scipy
77
# Python linter and formatter
8-
click==8.4.2
8+
click==8.5.0
99
black==26.5.1
1010
pylint==4.0.7
1111

vpr/src/analytical_place/full_legalization/full_legalizer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class APClusterPlacer {
160160
const char* constraints_file)
161161
: place_macros_(place_macros) {
162162
// Initialize the block loc registry.
163-
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
163+
BlkLocRegistry& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
164164
blk_loc_registry.init();
165165

166166
// Place the fixed blocks and mark them as fixed.
@@ -188,7 +188,7 @@ class APClusterPlacer {
188188
const FloorplanningContext& floorplanning_ctx = g_vpr_ctx.floorplanning();
189189
const ClusteringContext& cluster_ctx = g_vpr_ctx.clustering();
190190
const auto& block_locs = g_vpr_ctx.placement().block_locs();
191-
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
191+
BlkLocRegistry& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
192192
// If this block has already been placed, just return true.
193193
// TODO: This should be investigated further. What I think is happening
194194
// is that a macro is being placed which contains another cluster.
@@ -232,7 +232,7 @@ class APClusterPlacer {
232232
// centroid, then random, then exhaustive.
233233
bool exhaustively_place_cluster(ClusterBlockId clb_blk_id) {
234234
const auto& block_locs = g_vpr_ctx.placement().block_locs();
235-
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
235+
BlkLocRegistry& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
236236
// If this block has already been placed, just return true.
237237
// TODO: See similar comment above.
238238
if (is_block_placed(clb_blk_id, block_locs))
@@ -343,7 +343,7 @@ FlatRecon::sort_and_group_blocks_by_tile(const PartialPlacement& p_placement) {
343343
for (APBlockId blk_id : ap_netlist_.blocks()) {
344344
t_physical_tile_loc tile_loc = p_placement.get_containing_tile_loc(blk_id);
345345
for (PackMoleculeId mol_id : ap_netlist_.block_molecules(blk_id)) {
346-
const auto& mol = prepacker_.get_molecule(mol_id);
346+
const t_pack_molecule& mol = prepacker_.get_molecule(mol_id);
347347

348348
int num_ext_inputs = prepacker_.calc_molecule_stats(mol_id, atom_netlist_, arch_.models).num_used_ext_inputs;
349349
bool long_chain = mol.is_chain() && prepacker_.get_molecule_chain_info(mol.chain_id).is_long_chain;
@@ -374,7 +374,7 @@ FlatRecon::sort_and_group_blocks_by_tile(const PartialPlacement& p_placement) {
374374
// Group the molecules by root tile. Any non-zero offset gets
375375
// pulled back to its root.
376376
std::unordered_map<t_physical_tile_loc, std::vector<PackMoleculeId>> tile_blocks;
377-
mol_desired_physical_tile_loc.reserve(prepacker_.molecules().size());
377+
mol_desired_physical_tile_loc.resize(prepacker_.molecules().size());
378378
for (const auto& [mol_id, ext_pins, is_long_chain, tile_loc] : sorted_blocks) {
379379
int width_offset = device_grid_.get_width_offset(tile_loc);
380380
int height_offset = device_grid_.get_height_offset(tile_loc);
@@ -1366,7 +1366,7 @@ void FullLegalizer::update_drawing_data_structures() {
13661366
}
13671367

13681368
void FullLegalizer::recreate_device_if_needed() {
1369-
const auto& device_ctx = g_vpr_ctx.device();
1369+
const DeviceContext& device_ctx = g_vpr_ctx.device();
13701370
// Capture before grid recreation: vpr_create_device_grid only writes
13711371
// device_ctx.grid and does not touch the RR graph, so this flag remains
13721372
// valid after the call.

vpr/src/base/atom_netlist_utils.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,16 @@ void print_netlist_as_blif(FILE* f, const AtomNetlist& netlist, const LogicalMod
415415

416416
int mark_constant_generators(AtomNetlist& netlist, e_const_gen_inference const_gen_inference_method, const LogicalModels& models, int verbosity) {
417417
int num_undriven_pins_marked_const = mark_undriven_primitive_outputs_as_constant(netlist, verbosity);
418-
VTR_LOGV(verbosity > 0, "Inferred %4d additional primitive pins as constant generators since they have no combinationally connected inputs\n", num_undriven_pins_marked_const);
418+
// A primitive output with nothing feeding it can never change, so it is marked as a constant.
419+
VTR_LOGV(verbosity > 0 && num_undriven_pins_marked_const > 0,
420+
"Found %d primitive output pin(s) with no connected inputs; marked them as constants\n",
421+
num_undriven_pins_marked_const);
419422

420423
int num_inferred_pins_marked_const = infer_and_mark_constant_pins(netlist, const_gen_inference_method, models, verbosity);
421-
VTR_LOGV(verbosity > 0, "Inferred %4d additional primitive pins as constant generators due to constant inputs\n", num_inferred_pins_marked_const);
424+
// A primitive output whose inputs are all constant is itself constant.
425+
VTR_LOGV(verbosity > 0 && num_inferred_pins_marked_const > 0,
426+
"Found %d primitive output pin(s) driven only by constants; marked them as constants\n",
427+
num_inferred_pins_marked_const);
422428

423429
return num_undriven_pins_marked_const + num_inferred_pins_marked_const;
424430
}

vpr/src/base/check_netlist.cpp

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,19 @@ static int check_connections_to_global_clb_pins(ClusterNetId net_id, int verbosi
3333

3434
static int check_for_duplicated_names();
3535

36-
static int check_clb_conn(ClusterBlockId iblk, int num_conn);
36+
/**
37+
* @brief Checks that the connections into and out of the clb make sense.
38+
*
39+
* A block with a single connection is flagged: an input-only block is hanging
40+
* logic that should have been swept (removed before packing by iteratively
41+
* deleting primitives, nets, and I/Os that have no path to a primary output),
42+
* and an output-only block is likely a constant generator.
43+
*/
44+
static int check_clb_conn(ClusterBlockId iblk,
45+
int num_conn,
46+
int verbosity,
47+
int& num_input_only_blocks,
48+
int& num_output_only_blocks);
3749

3850
static int check_clb_internal_nets(ClusterBlockId iblk, const IntraLbPbPinLookup& intra_lb_pb_pini_lookup);
3951

@@ -104,16 +116,27 @@ void check_netlist(int verbosity, const t_arch& arch) {
104116
IntraLbPbPinLookup intra_lb_pb_pin_lookup(device_ctx.logical_block_types);
105117

106118
/* Check that each block makes sense. */
119+
int num_input_only_blocks = 0;
120+
int num_output_only_blocks = 0;
107121
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
108122
num_conn = (int)cluster_ctx.clb_nlist.block_pins(blk_id).size();
109-
error += check_clb_conn(blk_id, num_conn);
123+
error += check_clb_conn(blk_id, num_conn, verbosity, num_input_only_blocks, num_output_only_blocks);
110124
error += check_clb_internal_nets(blk_id, intra_lb_pb_pin_lookup);
111125
if (error >= ERROR_THRESHOLD) {
112126
VPR_ERROR(VPR_ERROR_OTHER,
113127
"Too many errors in netlist, exiting.\n");
114128
}
115129
}
116130

131+
VTR_LOGV(num_output_only_blocks > 0,
132+
"Found %d logic block(s) with only 1 output pin and no inputs; they may be constant generators%s\n",
133+
num_output_only_blocks,
134+
verbosity > 2 ? "" : " (run with --pack_verbosity 3 to list them)");
135+
VTR_LOGV_WARN(num_input_only_blocks > 0,
136+
"Found %d logic block(s) with only 1 input pin; the whole block is hanging logic that should be swept%s\n",
137+
num_input_only_blocks,
138+
verbosity > 2 ? "" : " (run with --pack_verbosity 3 to list them)");
139+
117140
error += check_for_duplicated_names();
118141

119142
error += check_external_directs_legality(arch);
@@ -162,8 +185,11 @@ static int check_connections_to_global_clb_pins(ClusterNetId net_id, int verbosi
162185
return global_to_non_global_connection_count;
163186
}
164187

165-
///@brief Checks that the connections into and out of the clb make sense.
166-
static int check_clb_conn(ClusterBlockId iblk, int num_conn) {
188+
static int check_clb_conn(ClusterBlockId iblk,
189+
int num_conn,
190+
int verbosity,
191+
int& num_input_only_blocks,
192+
int& num_output_only_blocks) {
167193
auto& cluster_ctx = g_vpr_ctx.clustering();
168194
auto& clb_nlist = cluster_ctx.clb_nlist;
169195

@@ -175,20 +201,22 @@ static int check_clb_conn(ClusterBlockId iblk, int num_conn) {
175201
auto pin_type = clb_nlist.pin_type(pin_id);
176202

177203
if (pin_type == PinType::SINK && !clb_nlist.block_contains_primary_output(iblk)) {
178-
//Input only and not a Primary-Output block
179-
VTR_LOG_WARN(
180-
"Logic block #%d (%s) has only 1 input pin '%s'"
181-
" -- the whole block is hanging logic that should be swept.\n",
182-
iblk, clb_nlist.block_name(iblk).c_str(),
183-
clb_nlist.pin_name(pin_id).c_str());
204+
// Input only and not a Primary-Output block
205+
++num_input_only_blocks;
206+
VTR_LOGV_WARN(verbosity > 2,
207+
"Logic block #%d (%s) has only 1 input pin '%s'"
208+
" -- the whole block is hanging logic that should be swept.\n",
209+
iblk, clb_nlist.block_name(iblk).c_str(),
210+
clb_nlist.pin_name(pin_id).c_str());
184211
}
185212
if (pin_type == PinType::DRIVER && !clb_nlist.block_contains_primary_input(iblk)) {
186-
//Output only and not a Primary-Input block
187-
VTR_LOG_WARN(
188-
"Logic block #%d (%s) has only 1 output pin '%s'."
189-
" It may be a constant generator.\n",
190-
iblk, clb_nlist.block_name(iblk).c_str(),
191-
clb_nlist.pin_name(pin_id).c_str());
213+
// Output only and not a Primary-Input block
214+
++num_output_only_blocks;
215+
VTR_LOGV(verbosity > 2,
216+
"Logic block #%d (%s) has only 1 output pin '%s'."
217+
" It may be a constant generator.\n",
218+
iblk, clb_nlist.block_name(iblk).c_str(),
219+
clb_nlist.pin_name(pin_id).c_str());
192220
}
193221

194222
break;

vpr/src/base/read_netlist.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist,
9292
/**
9393
* @brief This function updates the nets list and the connections between
9494
* that list and the complex block
95+
*
96+
* A net that reaches both global and non-global pins is flagged with a warning.
9597
*/
96-
static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, const AtomNetlist& atom_netlist);
98+
static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, const AtomNetlist& atom_netlist, int verbosity);
9799

98100
static void load_internal_to_block_net_nums(const t_logical_block_type_ptr type, t_pb_routes& pb_route);
99101

@@ -270,7 +272,7 @@ ClusteredNetlist read_netlist(const char* net_file,
270272

271273
mark_constant_generators(clb_nlist, verbosity);
272274

273-
load_external_nets_and_cb(clb_nlist, mutable_atom_netlist);
275+
load_external_nets_and_cb(clb_nlist, mutable_atom_netlist, verbosity);
274276

275277
sync_clustered_and_atom_netlists(clb_nlist, mutable_atom_netlist, mutable_atom_lookup);
276278

@@ -889,7 +891,8 @@ static void process_ports(pugi::xml_node Parent,
889891
}
890892

891893
static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist,
892-
const AtomNetlist& atom_netlist) {
894+
const AtomNetlist& atom_netlist,
895+
int verbosity) {
893896
// Create a set of all unique net names that we can see. We want to ignore
894897
// any nets with the name "open", so we insert that into the map and later
895898
// we just ignore it if it was seen,
@@ -1035,21 +1038,33 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist,
10351038
// set, minus the "open" nets.
10361039
int num_unique_net_names = seen_net_names.size() - 1;
10371040
VTR_ASSERT(static_cast<int>(clb_nlist.nets().size()) == num_unique_net_names);
1041+
int num_mixed_global_nets = 0;
10381042
for (ClusterNetId net_id : clb_nlist.nets()) {
1043+
bool is_ignored_net = clb_nlist.net_is_ignored(net_id);
10391044
for (ClusterPinId pin_id : clb_nlist.net_sinks(net_id)) {
1040-
bool is_ignored_net = clb_nlist.net_is_ignored(net_id);
10411045
t_logical_block_type_ptr block_type = clb_nlist.block_type(clb_nlist.pin_block(pin_id));
10421046
t_physical_tile_type_ptr tile_type = pick_physical_type(block_type);
10431047
int logical_pin = clb_nlist.pin_logical_index(pin_id);
10441048
int physical_pin = get_physical_pin(tile_type, block_type, logical_pin);
10451049

10461050
if (tile_type->is_ignored_pin[physical_pin] != is_ignored_net) {
1047-
VTR_LOG_WARN(
1048-
"Netlist connects net %s to both global and non-global pins.\n",
1049-
clb_nlist.net_name(net_id).c_str());
1051+
++num_mixed_global_nets;
1052+
// The net reaches an ignored (global) pin, so the whole net is
1053+
// treated as global and left unrouted; its non-global sinks get
1054+
// ideal (zero) delay instead of a routed connection.
1055+
VTR_LOGV_WARN(verbosity > 2,
1056+
"Net '%s' connects both routed pins and ignored (global) pins; it will be treated as global and left unrouted, with ideal delay on its non-global sinks.\n",
1057+
clb_nlist.net_name(net_id).c_str());
1058+
break;
10501059
}
10511060
}
10521061
}
1062+
1063+
VTR_LOGV_WARN(num_mixed_global_nets > 0,
1064+
"Found %d net(s) mixing routed and ignored pins; these are left unrouted with ideal delay. "
1065+
"This is expected for clock nets under --clock_modeling ideal; use --clock_modeling route or dedicated_network to route them.%s\n",
1066+
num_mixed_global_nets,
1067+
verbosity > 2 ? "" : " (run with --pack_verbosity 3 to list the nets)");
10531068
}
10541069

10551070
static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verbosity) {

0 commit comments

Comments
 (0)