@@ -1071,8 +1071,11 @@ static bool try_expand_molecule(t_pack_molecule& molecule,
1071
1071
/* *
1072
1072
* Find the atom block in the netlist driven by this pin of the input atom block
1073
1073
* If doesn't exist return AtomBlockId::INVALID()
1074
+ * TODO: Limitation — For pack patterns other than chains,
1075
+ * the block should be driven by only one block
1074
1076
* block_id : id of the atom block that is driving the net connected to the sink block
1075
1077
* connections : pack pattern connections from the given block
1078
+ * is_chain_pattern : whether the pattern is a chain
1076
1079
*/
1077
1080
static AtomBlockId get_sink_block (const AtomBlockId block_id,
1078
1081
const t_pack_pattern_connections& connections,
@@ -1086,36 +1089,40 @@ static AtomBlockId get_sink_block(const AtomBlockId block_id,
1086
1089
const int to_pin_number = connections.to_pin ->pin_number ;
1087
1090
const auto & to_pb_type = connections.to_block ->pb_type ;
1088
1091
1089
- if (from_port_id) {
1090
- auto net_id = atom_nlist.port_net (from_port_id, from_pin_number);
1091
- if (net_id.is_valid ()) {
1092
- const auto & net_sinks = atom_nlist.net_sinks (net_id);
1093
- if (is_chain_pattern) {
1094
- // If the pattern is a chain, allow nets with multiple sinks.
1095
- // This enables forming chains where the COUT is connected both to
1096
- // the next element in the chain and to the block's output pin.
1097
- for (const auto & sink_pin_id : net_sinks) {
1098
- auto sink_block_id = atom_nlist.pin_block (sink_pin_id);
1099
- if (primitive_type_feasible (sink_block_id, to_pb_type)) {
1100
- auto to_port_id = atom_nlist.find_atom_port (sink_block_id, to_port_model);
1101
- auto to_pin_id = atom_nlist.find_pin (to_port_id, BitIndex (to_pin_number));
1102
- if (to_pin_id == sink_pin_id) {
1103
- return sink_block_id;
1104
- }
1105
- }
1106
- }
1107
- } else {
1108
- // For non-chain patterns, we conservatively only consider the sink block
1109
- // if the net fanout is 1. To clarify, consider a case where the output of a LUT
1110
- // is connected to both a register and an unregistered output that feeds another block.
1111
- // If the intra-cluster architecture doesn't support having both registered and
1112
- // unregistered outputs simultaneously, this could lead to a packing failure.
1113
- if (net_sinks.size () == 1 ) {
1114
- auto sink_pin_id = *(net_sinks.begin ());
1115
- return atom_nlist.pin_block (sink_pin_id);
1092
+ if (!from_port_id.is_valid ()) {
1093
+ return AtomBlockId::INVALID ();
1094
+ }
1095
+
1096
+ auto net_id = atom_nlist.port_net (from_port_id, from_pin_number);
1097
+ if (!net_id.is_valid ()) {
1098
+ return AtomBlockId::INVALID ();
1099
+ }
1100
+
1101
+ const auto & net_sinks = atom_nlist.net_sinks (net_id);
1102
+ if (is_chain_pattern) {
1103
+ // If the pattern is a chain, allow nets with multiple sinks.
1104
+ // This enables forming chains where the COUT is connected both to
1105
+ // the next element in the chain and to the block's output pin.
1106
+ for (const auto & sink_pin_id : net_sinks) {
1107
+ auto sink_block_id = atom_nlist.pin_block (sink_pin_id);
1108
+ if (primitive_type_feasible (sink_block_id, to_pb_type)) {
1109
+ auto to_port_id = atom_nlist.find_atom_port (sink_block_id, to_port_model);
1110
+ auto to_pin_id = atom_nlist.find_pin (to_port_id, BitIndex (to_pin_number));
1111
+ if (to_pin_id == sink_pin_id) {
1112
+ return sink_block_id;
1116
1113
}
1117
1114
}
1118
1115
}
1116
+ } else {
1117
+ // For non-chain patterns, we conservatively only consider the sink block
1118
+ // if the net fanout is 1. To clarify, consider a case where the output of a LUT
1119
+ // is connected to both a register and an unregistered output that feeds another block.
1120
+ // If the intra-cluster architecture doesn't support having both registered and
1121
+ // unregistered outputs simultaneously, this could lead to a packing failure.
1122
+ if (net_sinks.size () == 1 ) {
1123
+ auto sink_pin_id = *(net_sinks.begin ());
1124
+ return atom_nlist.pin_block (sink_pin_id);
1125
+ }
1119
1126
}
1120
1127
1121
1128
return AtomBlockId::INVALID ();
@@ -1135,24 +1142,26 @@ static AtomBlockId get_driving_block(const AtomBlockId block_id,
1135
1142
auto to_pin_number = connections.to_pin ->pin_number ;
1136
1143
auto to_port_id = atom_nlist.find_atom_port (block_id, to_port_model);
1137
1144
1138
- if (to_port_id) {
1139
- auto net_id = atom_nlist.port_net (to_port_id, to_pin_number);
1140
- if (net_id && atom_nlist.net_sinks (net_id).size () == 1 ) { /* Single fanout assumption */
1141
- auto driver_blk_id = atom_nlist.net_driver_block (net_id);
1145
+ if (!to_port_id.is_valid ()) {
1146
+ return AtomBlockId::INVALID ();
1147
+ }
1142
1148
1143
- if (to_port_model->is_clock ) {
1144
- auto driver_blk_type = atom_nlist.block_type (driver_blk_id);
1149
+ auto net_id = atom_nlist.port_net (to_port_id, to_pin_number);
1150
+ if (net_id && atom_nlist.net_sinks (net_id).size () == 1 ) { /* Single fanout assumption */
1151
+ auto driver_blk_id = atom_nlist.net_driver_block (net_id);
1145
1152
1146
- // TODO: support multi-clock primitives.
1147
- // If the driver block is a .input block, this assertion should not
1148
- // be triggered as the sink block might have only one input pin, which
1149
- // would be a clock pin in case the sink block primitive is a clock generator,
1150
- // resulting in a pin_number == 0.
1151
- VTR_ASSERT (to_pin_number == 1 || (to_pin_number == 0 && driver_blk_type == AtomBlockType::INPAD));
1152
- }
1153
+ if (to_port_model->is_clock ) {
1154
+ auto driver_blk_type = atom_nlist.block_type (driver_blk_id);
1153
1155
1154
- return driver_blk_id;
1156
+ // TODO: support multi-clock primitives.
1157
+ // If the driver block is a .input block, this assertion should not
1158
+ // be triggered as the sink block might have only one input pin, which
1159
+ // would be a clock pin in case the sink block primitive is a clock generator,
1160
+ // resulting in a pin_number == 0.
1161
+ VTR_ASSERT (to_pin_number == 1 || (to_pin_number == 0 && driver_blk_type == AtomBlockType::INPAD));
1155
1162
}
1163
+
1164
+ return driver_blk_id;
1156
1165
}
1157
1166
1158
1167
return AtomBlockId::INVALID ();
0 commit comments