This notebook shows the various features for inspecting circuits using str and repr.


In [1]:
import magma as m
m.set_mantle_target("ice40")

In [2]:
import mantle

Logic2 = m.DefineCircuit('Logic2', 'I0', m.In(m.Bit), 'I1', m.In(m.Bit), 'O', m.Out(m.Bit))
m.wire((Logic2.I0 & Logic2.I1) ^ 1, Logic2.O)
m.EndCircuit()


import lattice ice40
import lattice mantle40

Calling print on a circuit definition, call str. str returns the type signature of the circuit.


In [3]:
print(Logic2)


Logic2(I0: In(Bit), I1: In(Bit), O: Out(Bit))

Calling repr on the circuit returns a python code snippet that could be executed to recreate the circuit.


In [4]:
print(repr(Logic2))


Logic2 = DefineCircuit("Logic2", "I0", In(Bit), "I1", In(Bit), "O", Out(Bit))
inst0 = And2()
inst1 = XOr2()
wire(Logic2.I0, inst0.I[0])
wire(Logic2.I1, inst0.I[1])
wire(inst0.O, inst1.I[0])
wire(1, inst1.I[1])
wire(inst1.O, Logic2.O)
EndCircuit()

Here's an example of introspecting the circuit definition instances. We can iterate over the instances attribute of the circuit to get access to each instance. Then, we can print the instance out to get a debug string. We can also iterate over the IO.ports dictionary to get the name and type of each port


In [5]:
for inst in Logic2.instances:
    print(f"Instance={inst}")
    print("    ports=")
    for name, type_ in inst.IO.ports.items():
        print(f"        {name}: {type_}")


Instance=inst0<And2(I: In(Bits(2)), O: Out(Bit))>
    ports=
        I: In(Bits(2))
        O: Out(Bit)
Instance=inst1<XOr2(I: In(Bits(2)), O: Out(Bit))>
    ports=
        I: In(Bits(2))
        O: Out(Bit)

In [ ]: