@@ -1103,16 +1103,30 @@ static AtomBlockId get_sink_block(const AtomBlockId block_id,
11031103 // If the pattern is a chain, allow nets with multiple sinks.
11041104 // This enables forming chains where the COUT is connected both to
11051105 // 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 ();
11061108 for (const auto & sink_pin_id : net_sinks) {
11071109 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+ }
11081113 if (primitive_type_feasible (sink_block_id, to_pb_type)) {
11091114 auto to_port_id = atom_nlist.find_atom_port (sink_block_id, to_port_model);
11101115 auto to_pin_id = atom_nlist.find_pin (to_port_id, BitIndex (to_pin_number));
11111116 if (to_pin_id == sink_pin_id) {
1112- return sink_block_id;
1117+ pattern_sink_block_id = sink_block_id;
11131118 }
11141119 }
11151120 }
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;
11161130 } else {
11171131 // For non-chain patterns, we conservatively only consider the sink block
11181132 // if the net fanout is 1. To clarify, consider a case where the output of a LUT
0 commit comments