@@ -61,7 +61,7 @@ def optimize(update_working_block=True, block=None, skip_sanity_check=False):
6161def _remove_double_inverts (block , skip_sanity_check = False ):
6262 """ Removes all double invert nets from the block. """
6363
64- # checks if the wirevector is used at a LogicNet other than used_at_net
64+ # checks if the wirevector is used at a LogicNet other than used_at_nets
6565 def is_wirevector_used_elsewhere (wire , used_at_nets ):
6666 for net in block .logic :
6767 if net not in used_at_nets :
@@ -73,24 +73,22 @@ def is_wirevector_used_elsewhere(wire, used_at_nets):
7373 new_logic = set ()
7474 net_exclude_set = set () # removed nets
7575 wire_removal_set = set ()
76- for net1 in block .logic :
77- for net2 in block .logic :
78- # Conditions need to be satisfied for the nets to be removed:
79- # 1. Both nets should be invert nets
80- # 2. Nets should not be in net_exclude_set (nets that are already removed)
81- # 3. The destination of net1 should be the argument of net2
82- # (so we know the nets are connected)
83- # 4. The destination of net1 should not be used elsewhere
84- # (because we can't remove a wire that is used in another net)
85- if net1 .op == '~' and net2 .op == '~' \
86- and net1 not in net_exclude_set and net2 not in net_exclude_set \
87- and net1 .dests [0 ].name == net2 .args [0 ].name \
88- and not is_wirevector_used_elsewhere (net1 .dests [0 ], (net1 , net2 )):
89- new_logic .add (LogicNet ('w' , None , args = net1 .args , dests = net2 .dests ))
90- net_exclude_set .add (net1 )
91- net_exclude_set .add (net2 )
92- wire_removal_set .add (net1 .dests [0 ])
93- break
76+ # Dictionary, key is the destination wire of the invert net, value is the invert net
77+ invert_destination_wires = {}
78+ for net in block .logic :
79+ if net .op == "~" :
80+ invert_destination_wires [net .dests [0 ].name ] = net
81+ for net in invert_destination_wires .values ():
82+ # If the argument of the net is in invert_destination_wires, then it is a double invert
83+ # If the net is in net_exclude_set, then it was already removed, so we do not process it
84+ if net .args [0 ].name in invert_destination_wires and net not in net_exclude_set :
85+ previous_net = invert_destination_wires [net .args [0 ].name ]
86+ if not is_wirevector_used_elsewhere (net .args [0 ], (net , previous_net )) \
87+ and previous_net not in net_exclude_set :
88+ new_logic .add (LogicNet ('w' , None , args = previous_net .args , dests = net .dests ))
89+ wire_removal_set .add (net .args [0 ])
90+ net_exclude_set .add (net )
91+ net_exclude_set .add (previous_net )
9492
9593 for net in block .logic :
9694 if net not in net_exclude_set :
0 commit comments