@@ -1103,16 +1103,30 @@ static AtomBlockId get_sink_block(const AtomBlockId block_id,
1103
1103
// If the pattern is a chain, allow nets with multiple sinks.
1104
1104
// This enables forming chains where the COUT is connected both to
1105
1105
// the next element in the chain and to the block's output pin.
1106
+ bool connected_to_latch = false ;
1107
+ AtomBlockId pattern_sink_block_id = AtomBlockId::INVALID ();
1106
1108
for (const auto & sink_pin_id : net_sinks) {
1107
1109
auto sink_block_id = atom_nlist.pin_block (sink_pin_id);
1110
+ if (atom_nlist.block_model (sink_block_id)->name == std::string (MODEL_LATCH)) {
1111
+ connected_to_latch = true ;
1112
+ }
1108
1113
if (primitive_type_feasible (sink_block_id, to_pb_type)) {
1109
1114
auto to_port_id = atom_nlist.find_atom_port (sink_block_id, to_port_model);
1110
1115
auto to_pin_id = atom_nlist.find_pin (to_port_id, BitIndex (to_pin_number));
1111
1116
if (to_pin_id == sink_pin_id) {
1112
- return sink_block_id;
1117
+ pattern_sink_block_id = sink_block_id;
1113
1118
}
1114
1119
}
1115
1120
}
1121
+ // If the number of sinks is greater than 1, and one of the connected blocks is a latch,
1122
+ // then we drop the block to avoid a situation where only registers or unregistered output
1123
+ // of the block can use the output pin.
1124
+ // TODO: This is a conservative assumption, and ideally we need to do analysis of the architecture
1125
+ // before to determine which pattern is supported by the architecture.
1126
+ if (connected_to_latch && net_sinks.size () > 1 ) {
1127
+ return AtomBlockId::INVALID ();
1128
+ }
1129
+ return pattern_sink_block_id;
1116
1130
} else {
1117
1131
// For non-chain patterns, we conservatively only consider the sink block
1118
1132
// if the net fanout is 1. To clarify, consider a case where the output of a LUT
0 commit comments