Skip to content

Commit d75c699

Browse files
authored
Merge pull request #2881 from AlexandreSinger/feature-ap-flow
[Pack] Cleaned Up try_pack API
2 parents 4539a8f + bf3f72c commit d75c699

File tree

3 files changed

+175
-161
lines changed

3 files changed

+175
-161
lines changed

vpr/src/base/vpr_api.cpp

Lines changed: 3 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,6 @@ static void free_complex_block_types();
109109
static void free_device(const t_det_routing_arch& routing_arch);
110110
static void free_circuit();
111111

112-
static void get_intercluster_switch_fanin_estimates(const t_vpr_setup& vpr_setup,
113-
const t_arch& arch,
114-
const int wire_segment_length,
115-
int* opin_switch_fanin,
116-
int* wire_switch_fanin,
117-
int* ipin_switch_fanin);
118112
/* Local subroutines end */
119113

120114
///@brief Display general VPR information
@@ -641,53 +635,6 @@ bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
641635
bool vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) {
642636
vtr::ScopedStartFinishTimer timer("Packing");
643637

644-
/* If needed, estimate inter-cluster delay. Assume the average routing hop goes out of
645-
* a block through an opin switch to a length-4 wire, then through a wire switch to another
646-
* length-4 wire, then through a wire-to-ipin-switch into another block. */
647-
int wire_segment_length = 4;
648-
649-
float inter_cluster_delay = UNDEFINED;
650-
if (vpr_setup.PackerOpts.timing_driven
651-
&& vpr_setup.PackerOpts.auto_compute_inter_cluster_net_delay) {
652-
/* We want to determine a reasonable fan-in to the opin, wire, and ipin switches, based
653-
* on which the intercluster delays can be estimated. The fan-in of a switch influences its
654-
* delay.
655-
*
656-
* The fan-in of the switch depends on the architecture (unidirectional/bidirectional), as
657-
* well as Fc_in/out and Fs */
658-
int opin_switch_fanin, wire_switch_fanin, ipin_switch_fanin;
659-
get_intercluster_switch_fanin_estimates(vpr_setup, arch, wire_segment_length, &opin_switch_fanin,
660-
&wire_switch_fanin, &ipin_switch_fanin);
661-
662-
float Tdel_opin_switch, R_opin_switch, Cout_opin_switch;
663-
float opin_switch_del = get_arch_switch_info(arch.Segments[0].arch_opin_switch, opin_switch_fanin,
664-
Tdel_opin_switch, R_opin_switch, Cout_opin_switch);
665-
666-
float Tdel_wire_switch, R_wire_switch, Cout_wire_switch;
667-
float wire_switch_del = get_arch_switch_info(arch.Segments[0].arch_wire_switch, wire_switch_fanin,
668-
Tdel_wire_switch, R_wire_switch, Cout_wire_switch);
669-
670-
float Tdel_wtoi_switch, R_wtoi_switch, Cout_wtoi_switch;
671-
float wtoi_switch_del = get_arch_switch_info(vpr_setup.RoutingArch.wire_to_arch_ipin_switch, ipin_switch_fanin,
672-
Tdel_wtoi_switch, R_wtoi_switch, Cout_wtoi_switch);
673-
674-
float Rmetal = arch.Segments[0].Rmetal;
675-
float Cmetal = arch.Segments[0].Cmetal;
676-
677-
/* The delay of a wire with its driving switch is the switch delay plus the
678-
* product of the equivalent resistance and capacitance experienced by the wire. */
679-
680-
float first_wire_seg_delay = opin_switch_del
681-
+ (R_opin_switch + Rmetal * (float)wire_segment_length / 2)
682-
* (Cout_opin_switch + Cmetal * (float)wire_segment_length);
683-
float second_wire_seg_delay = wire_switch_del
684-
+ (R_wire_switch + Rmetal * (float)wire_segment_length / 2)
685-
* (Cout_wire_switch + Cmetal * (float)wire_segment_length);
686-
inter_cluster_delay = 4
687-
* (first_wire_seg_delay + second_wire_seg_delay
688-
+ wtoi_switch_del); /* multiply by 4 to get a more conservative estimate */
689-
}
690-
691638
// Read in the flat placement if a flat placement file is provided and it
692639
// has not been loaded already.
693640
if (!vpr_setup.FileNameOpts.read_flat_place_file.empty() &&
@@ -698,8 +645,9 @@ bool vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) {
698645
}
699646

700647
return try_pack(&vpr_setup.PackerOpts, &vpr_setup.AnalysisOpts,
701-
&arch, vpr_setup.user_models,
702-
vpr_setup.library_models, inter_cluster_delay,
648+
arch, vpr_setup.RoutingArch,
649+
vpr_setup.user_models,
650+
vpr_setup.library_models,
703651
vpr_setup.PackerRRGraph, g_vpr_ctx.atom().flat_placement_info);
704652
}
705653

@@ -1212,100 +1160,6 @@ void vpr_close_graphics(const t_vpr_setup& /*vpr_setup*/) {
12121160
free_draw_structs();
12131161
}
12141162

1215-
/**
1216-
* Since the parameters of a switch may change as a function of its fanin,
1217-
* to get an estimation of inter-cluster delays we need a reasonable estimation
1218-
* of the fan-ins of switches that connect clusters together. These switches are
1219-
* 1) opin to wire switch
1220-
* 2) wire to wire switch
1221-
* 3) wire to ipin switch
1222-
* We can estimate the fan-in of these switches based on the Fc_in/Fc_out of
1223-
* a logic block, and the switch block Fs value
1224-
*/
1225-
static void get_intercluster_switch_fanin_estimates(const t_vpr_setup& vpr_setup,
1226-
const t_arch& arch,
1227-
const int wire_segment_length,
1228-
int* opin_switch_fanin,
1229-
int* wire_switch_fanin,
1230-
int* ipin_switch_fanin) {
1231-
e_directionality directionality;
1232-
int Fs;
1233-
float Fc_in, Fc_out;
1234-
int W = 100; //W is unknown pre-packing, so *if* we need W here, we will assume a value of 100
1235-
1236-
directionality = vpr_setup.RoutingArch.directionality;
1237-
Fs = vpr_setup.RoutingArch.Fs;
1238-
Fc_in = 0, Fc_out = 0;
1239-
1240-
//Build a dummy 10x10 device to determine the 'best' block type to use
1241-
auto grid = create_device_grid(vpr_setup.device_layout, arch.grid_layouts, 10, 10);
1242-
1243-
auto type = find_most_common_tile_type(grid);
1244-
/* get Fc_in/out for most common block (e.g. logic blocks) */
1245-
VTR_ASSERT(!type->fc_specs.empty());
1246-
1247-
//Estimate the maximum Fc_in/Fc_out
1248-
1249-
for (const t_fc_specification& fc_spec : type->fc_specs) {
1250-
float Fc = fc_spec.fc_value;
1251-
1252-
if (fc_spec.fc_value_type == e_fc_value_type::ABSOLUTE) {
1253-
//Convert to estimated fractional
1254-
Fc /= W;
1255-
}
1256-
VTR_ASSERT_MSG(Fc >= 0 && Fc <= 1., "Fc should be fractional");
1257-
1258-
for (int ipin : fc_spec.pins) {
1259-
e_pin_type pin_type = get_pin_type_from_pin_physical_num(type, ipin);
1260-
1261-
if (pin_type == DRIVER) {
1262-
Fc_out = std::max(Fc, Fc_out);
1263-
} else {
1264-
VTR_ASSERT(pin_type == RECEIVER);
1265-
Fc_in = std::max(Fc, Fc_in);
1266-
}
1267-
}
1268-
}
1269-
1270-
/* Estimates of switch fan-in are done as follows:
1271-
* 1) opin to wire switch:
1272-
* 2 CLBs connect to a channel, each with #opins/4 pins. Each pin has Fc_out*W
1273-
* switches, and then we assume the switches are distributed evenly over the W wires.
1274-
* In the unidirectional case, all these switches are then crammed down to W/wire_segment_length wires.
1275-
*
1276-
* Unidirectional: 2 * #opins_per_side * Fc_out * wire_segment_length
1277-
* Bidirectional: 2 * #opins_per_side * Fc_out
1278-
*
1279-
* 2) wire to wire switch
1280-
* A wire segment in a switchblock connects to Fs other wires. Assuming these connections are evenly
1281-
* distributed, each target wire receives Fs connections as well. In the unidirectional case,
1282-
* source wires can only connect to W/wire_segment_length wires.
1283-
*
1284-
* Unidirectional: Fs * wire_segment_length
1285-
* Bidirectional: Fs
1286-
*
1287-
* 3) wire to ipin switch
1288-
* An input pin of a CLB simply receives Fc_in connections.
1289-
*
1290-
* Unidirectional: Fc_in
1291-
* Bidirectional: Fc_in
1292-
*/
1293-
1294-
/* Fan-in to opin/ipin/wire switches depends on whether the architecture is unidirectional/bidirectional */
1295-
(*opin_switch_fanin) = 2 * type->num_drivers / 4 * Fc_out;
1296-
(*wire_switch_fanin) = Fs;
1297-
(*ipin_switch_fanin) = Fc_in;
1298-
if (directionality == UNI_DIRECTIONAL) {
1299-
/* adjustments to opin-to-wire and wire-to-wire switch fan-ins */
1300-
(*opin_switch_fanin) *= wire_segment_length;
1301-
(*wire_switch_fanin) *= wire_segment_length;
1302-
} else if (directionality == BI_DIRECTIONAL) {
1303-
/* no adjustments need to be made here */
1304-
} else {
1305-
VPR_FATAL_ERROR(VPR_ERROR_PACK, "Unrecognized directionality: %d\n", (int)directionality);
1306-
}
1307-
}
1308-
13091163
///@brief Free architecture data structures
13101164
void free_device(const t_det_routing_arch& /*routing_arch*/) {
13111165
auto& device_ctx = g_vpr_ctx.mutable_device();

0 commit comments

Comments
 (0)