Repository: phanrahan/magma

Issue:
Undriven port bug
Mamga reports errors of undriven ports even though it's connected.

How to reproduce:
Uinsg `magma-lang==2.2.18`
Remove this hack here:
https://github.com/StanfordAHA/canal/blob/37799cb4db4e5260ea538b8650c5446759e7892c/canal/circuit.py#L1090
Then run `python tests/test_circuit.py` to see the error.

To make the error more obvious, I wired to the same port multiple times. Here is the output when the hack is in place:
```
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[0], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[1], Old Output: VCC, New Output: GND
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[2], Old Output: VCC, New Output: GND
```

Here is the output when the hack is removed:
```
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_WEST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_NORTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T0_EAST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T0_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_NORTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[0], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_SOUTH_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[1], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_WEST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_EAST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_NORTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_WEST_SB_IN_B16.valid_out, New Output: VCC
WARNING:magma:Wiring multiple outputs to same wire, using last connection. Input: MUX_SB_T1_EAST_SB_OUT_B16.valid_in[2], Old Output: SB_ID0_2TRACKS_B16_ReadyValidCore.WIRE_SB_T1_WEST_SB_IN_B16.valid_out, New Output: VCC
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T0_NORTH_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T0_SOUTH_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T0_EAST_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T0_WEST_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T1_NORTH_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T1_SOUTH_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T1_EAST_SB_OUT_B16.valid_in not driven
ERROR:magma:SB_ID0_2TRACKS_B16_ReadyValidCore.MUX_SB_T1_WEST_SB_OUT_B16.valid_in not driven
```

You can see that the duplicated connection is properly detected yet the undriven logic can't pick up the correct connection. You should see similar output if the second redundant connection is removed.

Discussion:

Patch:
diff --git a/magma/find_unconnected_ports.py b/magma/find_unconnected_ports.py
index fd98acb2..0a57d5c5 100644
--- a/magma/find_unconnected_ports.py
+++ b/magma/find_unconnected_ports.py
@@ -133,4 +133,4 @@ def find_and_log_unconnected_ports(ckt):
         visitor = _make_unconnected_port_diagnostic_visitor_cls()()
         diagnostics = visitor.visit(port)
         for diagnostic in diagnostics:
-            _logger.debug(diagnostic.make_wiring_log())
+            _logger.error(diagnostic.make_wiring_log())


Test patch:
diff --git a/tests/test_circuit/test_new_style_syntax.py b/tests/test_circuit/test_new_style_syntax.py
index 33acaccf..a365e1b4 100644
--- a/tests/test_circuit/test_new_style_syntax.py
+++ b/tests/test_circuit/test_new_style_syntax.py
@@ -1,7 +1,7 @@
 import magma as m
 from magma.common import wrap_with_context_manager
 from magma.logging import logging_level
-from magma.testing.utils import has_warning, has_error, has_debug
+from magma.testing.utils import has_warning, has_error
 
 
 def _check_foo_interface(Foo):
@@ -76,9 +76,9 @@ def test_new_style_unconnected(caplog):
 
     assert m.isdefinition(_Foo)
     assert has_error(caplog, "_Foo.O not driven")
-    assert has_debug(caplog, "_Foo.O")
-    assert has_debug(caplog, "    _Foo.O[0]: Connected")
-    assert has_debug(caplog, "    _Foo.O[1]: Unconnected")
+    assert has_error(caplog, "_Foo.O")
+    assert has_error(caplog, "    _Foo.O[0]: Connected")
+    assert has_error(caplog, "    _Foo.O[1]: Unconnected")
 
 
 def test_new_style_with_definition_method(caplog):
@@ -130,9 +130,9 @@ def test_inst_wiring_error(caplog):
         caplog,
         "Cannot wire _Foo._Bar_inst0.O (Out(Bits[1])) to _Foo.O (In(Bit))")
     assert has_error(caplog, "_Foo.O not driven")
-    assert has_debug(caplog, "_Foo.O: Unconnected")
+    assert has_error(caplog, "_Foo.O: Unconnected")
     assert has_error(caplog, "_Foo._Bar_inst0.I not driven")
-    assert has_debug(caplog, "_Foo._Bar_inst0.I: Unconnected")
+    assert has_error(caplog, "_Foo._Bar_inst0.I: Unconnected")
 
 
 def test_nested_definition():
diff --git a/tests/test_circuit/test_unconnected.py b/tests/test_circuit/test_unconnected.py
index 390e8b13..a64605b7 100644
--- a/tests/test_circuit/test_unconnected.py
+++ b/tests/test_circuit/test_unconnected.py
@@ -5,7 +5,7 @@ import magma as m
 from magma.common import wrap_with_context_manager
 from magma.logging import logging_level
 from magma.testing import magma_debug_section
-from magma.testing.utils import has_error, has_debug
+from magma.testing.utils import has_error
 
 
 def _make_unconnected_io():
@@ -58,9 +58,9 @@ def test_unconnected_io(caplog):
         expected = """\x1b[1mtests/test_circuit/test_unconnected.py:12\x1b[0m: _Circuit.O not driven
 >>     class _Circuit(m.Circuit):"""
         assert has_error(caplog, expected)
-        assert has_debug(caplog, "_Circuit.O")
-        assert has_debug(caplog, "    _Circuit.O[0]: Connected")
-        assert has_debug(caplog, "    _Circuit.O[1]: Unconnected")
+        assert has_error(caplog, "_Circuit.O")
+        assert has_error(caplog, "    _Circuit.O[0]: Connected")
+        assert has_error(caplog, "    _Circuit.O[1]: Unconnected")
 
 
 @wrap_with_context_manager(logging_level("DEBUG"))
@@ -70,7 +70,7 @@ def test_unconnected_instance(caplog):
         expected = """\x1b[1mtests/test_circuit/test_unconnected.py:31\x1b[0m: _Circuit.buf.I not driven
 >>         buf = _Buffer()"""
         assert has_error(caplog, expected)
-        assert has_debug(caplog, "_Circuit.buf.I: Unconnected")
+        assert has_error(caplog, "_Circuit.buf.I: Unconnected")
 
 
 @pytest.mark.parametrize("typ", [m.Clock, m.Reset, m.AsyncReset])
diff --git a/tests/test_deprecated/test_old_io_syntax/test_old_io_syntax_unconnected.py b/tests/test_deprecated/test_old_io_syntax/test_old_io_syntax_unconnected.py
index 681624e8..4484343e 100644
--- a/tests/test_deprecated/test_old_io_syntax/test_old_io_syntax_unconnected.py
+++ b/tests/test_deprecated/test_old_io_syntax/test_old_io_syntax_unconnected.py
@@ -5,7 +5,7 @@ import magma as m
 from magma.common import wrap_with_context_manager
 from magma.logging import logging_level
 from magma.testing import magma_debug_section
-from magma.testing.utils import has_error, has_debug
+from magma.testing.utils import has_error
 
 
 def _make_unconnected_io():
@@ -67,9 +67,9 @@ def test_unconnected_io(caplog):
         expected = """\x1b[1mtests/test_deprecated/test_old_io_syntax/test_old_io_syntax_unconnected.py:12\x1b[0m: _Circuit.O not driven
 >>     class _Circuit(m.Circuit):"""
         assert has_error(caplog, expected)
-        assert has_debug(caplog, "_Circuit.O")
-        assert has_debug(caplog, "    _Circuit.O[0]: Connected")
-        assert has_debug(caplog, "    _Circuit.O[1]: Unconnected")
+        assert has_error(caplog, "_Circuit.O")
+        assert has_error(caplog, "    _Circuit.O[0]: Connected")
+        assert has_error(caplog, "    _Circuit.O[1]: Unconnected")
 
 
 @wrap_with_context_manager(logging_level("DEBUG"))
@@ -79,7 +79,7 @@ def test_unconnected_instance(caplog):
         expected = """\x1b[1mtests/test_deprecated/test_old_io_syntax/test_old_io_syntax_unconnected.py:36\x1b[0m: _Circuit.buf.I not driven
 >>             buf = _Buffer()"""
         assert has_error(caplog, expected)
-        assert has_debug(caplog, "_Circuit.buf.I: Unconnected")
+        assert has_error(caplog, "_Circuit.buf.I: Unconnected")
 
 
 @pytest.mark.parametrize("typ", [m.Clock, m.Reset, m.AsyncReset])
diff --git a/tests/test_errors/test_tuple_errors.py b/tests/test_errors/test_tuple_errors.py
index 1a95fd69..2b869f1b 100644
--- a/tests/test_errors/test_tuple_errors.py
+++ b/tests/test_errors/test_tuple_errors.py
@@ -145,6 +145,29 @@ Cannot wire Foo.A.x (Out(Bits[4])) to Foo.A.y (In(Bits[2]))\
 """
 
 
+def test_product_width_mismatch3(caplog):
+    class T(m.Product):
+        x = m.In(m.Bits[4])
+        y = m.Out(m.Bits[2])
+
+    class Foo(m.Circuit):
+        io = m.IO(A=T, B=T, C=m.Out(m.Bit))
+        io.A.y[0] @= io.A.x[0]  # Partially wired
+        io.B.y @= io.A.x[2:]
+        io.C @= 0
+
+    with pytest.raises(Exception) as e:
+        m.compile("build/Foo", Foo)
+    assert str(e.value) == "Found circuit with errors: Foo"
+    expected = """\
+Foo.A.y not driven
+Foo.A.y
+    Foo.A.y[0]: Connected
+    Foo.A.y[1]: Unconnected\
+"""
+    assert "\n".join(caplog.messages) == expected
+
+
 @wrap_with_context_manager(logging_level("DEBUG"))
 def test_unwired_mixed(caplog):
     class T(m.Product):
diff --git a/tests/test_wire/test_errors.py b/tests/test_wire/test_errors.py
index 9cb8a3c3..937dd7d0 100644
--- a/tests/test_wire/test_errors.py
+++ b/tests/test_wire/test_errors.py
@@ -4,7 +4,7 @@ from magma import *
 from magma.common import wrap_with_context_manager
 from magma.logging import logging_level
 from magma.testing.utils import (
-    has_error, has_warning, has_debug, magma_debug_section
+    has_error, has_warning, magma_debug_section
 )
 
 
@@ -200,7 +200,7 @@ def test_hanging_anon_error(caplog):
         assert has_error(caplog, msg)
         msg = "_Foo.O: Unconnected"
         assert caplog.records[1].message == msg
-        assert has_debug(caplog, msg)
+        assert has_error(caplog, msg)
 
 
 def test_wire_tuple_to_clock():