Beispiel #1
0
def test_optional_assignment(target):

    EQ = m.DefineCircuit("eq", "I0", m.In(m.Bit), "I1", m.In(m.Bit), "O",
                         m.Out(m.Bit))
    m.wire(0, EQ.O)
    m.EndDefine()

    @m.circuit.combinational
    def logic(a: m.Bit) -> (m.Bit, m.Bit):
        d = m.bit(1)
        if EQ()(a, m.bit(0)):
            c = m.bit(1)
        else:
            c = m.bit(0)
            d = m.bit(1)
        return (c, d)

    class Foo(m.Circuit):
        IO = ["a", m.In(m.Bit),
              "c", m.Out(m.Bit),
              "d", m.Out(m.Bit)]

        @classmethod
        def definition(io):
            c, d = logic(io.a)
            m.wire(c, io.c)
            m.wire(d, io.d)

    compile_and_check("optional_assignment", Foo, target)
Beispiel #2
0
def test_hash_verilog():
    [foo0] = m.DefineFromVerilog("""
module foo(input I, output O);
    assign O = I;
endmodule""")
    foo1 = m.DefineCircuit("foo", "I", m.In(m.Bit), "O", m.Out(m.Bit))
    m.EndCircuit()

    top = m.DefineCircuit("top", "I", m.In(m.Bit), "O", m.Out(m.Bit))
    foo0_inst = foo0()
    foo1_inst = foo1()
    m.wire(top.I, foo0_inst.I)
    m.wire(foo0_inst.O, foo1_inst.I)
    m.wire(foo1_inst.O, top.O)
    m.EndDefine()

    assert repr(foo0) == repr(foo1)

    # Run the uniquification pass as a mechanism to check that foo0 and foo1
    # hash to two different things even though they have the same repr.
    pass_ = m.UniquificationPass(top, None)
    pass_._run(top)
    foo_seen = pass_.seen["foo"]
    assert len(foo_seen) == 2
    for v in foo_seen.values():
        assert len(v) == 1
    expected_ids_ = {id(v[0]) for v in foo_seen.values()}
    ids_ = {id(foo0), id(foo1)}
    assert expected_ids_ == ids_
def test_include_verilog(target, simulator):
    SB_DFF = m.DeclareCircuit('SB_DFF', "D", m.In(m.Bit), "Q", m.Out(m.Bit),
                              "C", m.In(m.Clock))
    main = m.DefineCircuit('main', "I", m.In(m.Bit), "O", m.Out(m.Bit),
                           *m.ClockInterface())
    ff = SB_DFF()
    m.wire(ff.D, main.I)
    m.wire(ff.Q, main.O)
    m.EndDefine()

    tester = fault.Tester(main, main.CLK)
    tester.poke(main.CLK, 0)
    tester.poke(main.I, 1)
    tester.eval()
    tester.expect(main.O, 0)
    tester.step(2)
    tester.expect(main.O, 1)
    sb_dff_filename = pathlib.Path("tests/sb_dff_sim.v").resolve()

    kwargs = {}
    if simulator is not None:
        kwargs["simulator"] = simulator

    with tempfile.TemporaryDirectory() as tmp_dir:
        tester.compile_and_run(target=target, directory=tmp_dir,
                               include_verilog_libraries=[sb_dff_filename],
                               **kwargs)

    if target in ["verilator"]:
        # Should work by including the tests/ directory which contains the
        # verilog file SB_DFF.v
        dir_path = os.path.dirname(os.path.realpath(__file__))
        with tempfile.TemporaryDirectory() as tmp_dir:
            tester.compile_and_run(target=target, directory=tmp_dir,
                                   include_directories=[dir_path], **kwargs)
Beispiel #4
0
def create_io1out_pad():
    cb = m.DefineCircuit("io1out_pad", "clk", m.In(m.Clock), "rst",
                         m.In(m.Reset), "config_data", m.In(m.Bits(32)),
                         "config_addr", m.In(m.Bits(32)), "tile_id",
                         m.In(m.Bits(16)), "pin_0", m.In(m.Bit), "pin_1",
                         m.In(m.Bit), "pin_2", m.In(m.Bit), "pin_3",
                         m.In(m.Bit), "top_pin", m.Out(m.Bits(1)))

    # Configuration data
    config_reg = mantle.Register(32, init=0, has_ce=True, has_reset=True)
    addr_match = mantle.EQ(16)
    m.wire(addr_match.I0, cb.config_addr[0:16])
    m.wire(addr_match.I1, cb.tile_id)
    m.wire(addr_match.O, config_reg.CE)

    m.wire(cb.config_data, config_reg.I)
    m.wire(cb.clk, config_reg.CLK)

    rst_inv = mantle.Invert(1)
    m.wire(rst_inv.I[0], cb.rst)
    m.wire(rst_inv.O[0], config_reg.RESET)

    # Config mux
    config_mux = mantle.Mux(height=4, width=1)
    m.wire(config_mux.O, cb.top_pin)
    m.wire(config_mux.S, config_reg.O[0:2])

    m.wire(cb.pin_0, config_mux.I0[0])
    m.wire(cb.pin_1, config_mux.I1[0])
    m.wire(cb.pin_2, config_mux.I2[0])
    m.wire(cb.pin_3, config_mux.I3[0])

    m.EndDefine()

    return cb
Beispiel #5
0
def test_multiple_assign(target):
    EQ = m.DefineCircuit("eq", "I0", m.In(m.Bit), "I1", m.In(m.Bit), "O",
                         m.Out(m.Bit))
    m.wire(0, EQ.O)
    m.EndDefine()

    @m.circuit.combinational
    def logic(a: m.Bit) -> (m.Bit,):
        if EQ()(a, m.bit(0)):
            c = m.bit(1)
            c = m.bit(0)
        else:
            c = m.bit(0)
            c = m.bit(1)
        return (c,)

    class Foo(m.Circuit):
        IO = ["a", m.In(m.Bit),
              "c", m.Out(m.Bit)]

        @classmethod
        def definition(io):
            c = logic(io.a)
            m.wire(c, io.c)

    compile_and_check("multiple_assign", Foo, target)
def test_binary_primitive(binary_primitive, width):

    primitive_name, primitive_op, signed = binary_primitive
    prim = m.DeclareCircuit(f"primitive_name",
                            "in0",
                            m.In(m.Array(width, m.Bit)),
                            "in1",
                            m.In(m.Array(width, m.Bit)),
                            "out",
                            m.Out(m.Array(width, m.Bit)),
                            coreir_lib="coreir",
                            coreir_name=primitive_name,
                            coreir_genargs={"width": width})
    circ = m.DefineCircuit(f"DesignTop", "I0", m.In(m.Array(width, m.Bit)),
                           "I1", m.In(m.Array(width, m.Bit)), "O",
                           m.Out(m.Array(width, m.Bit)))
    inst = prim()
    m.wire(circ.I0, inst.in0)
    m.wire(circ.I1, inst.in1)
    m.wire(circ.O, inst.out)
    m.EndDefine()
    m.compile(f"build/{primitive_name}", circ, output="coreir")

    dir_path = os.path.dirname(os.path.realpath(__file__))
    result = delegator.run(
        f"CGRAMapper/bin/cgra-mapper build/{primitive_name}.json build/{primitive_name}_mapped.json",
        cwd=dir_path)
    assert not result.return_code, result.out + "\n" + result.err

    result = delegator.run(f"./CGRAGenerator/bin/generate.csh")
    assert not result.return_code, result.out + "\n" + result.err
    result = delegator.run(
        f"CGRAGenerator/bitstream/bsbuilder/serpent.csh build/{primitive_name}_mapped.json -cgra_info CGRAGenerator/hardware/generator_z/top/cgra_info.txt -o build/{primitive_name}_mapped_annotated"
    )
    assert not result.return_code, result.out + "\n" + result.err
def test_ram():
    main = m.DefineCircuit("main", "rdata", m.Out(m.Bit), "CLKIN",
                           m.In(m.Clock))

    ram = mantle.RAM(4, 1, name="ram")

    waddr = mantle.Counter(2, cout=False)
    wdata = mantle.Counter(1, cout=False)
    we = 1
    raddr = mantle.Counter(2, cout=False)

    ram(raddr, waddr, wdata, we, CLK=main.CLKIN)

    m.wire(ram.RDATA[0], main.rdata)
    m.EndDefine()
    if m.mantle_target == "coreir":
        output = "coreir"
        suffix = "json"
    else:
        output = "verilog"
        suffix = "v"
    m.compile(f"build/test_common_ram_{m.mantle_target}", main, output)
    assert check_files_equal(
        __file__, f"build/test_common_ram_{m.mantle_target}.{suffix}",
        f"gold/test_common_ram_{m.mantle_target}.{suffix}")
Beispiel #8
0
def test_env_mod(target, simulator):
    myinv = m.DefineCircuit('myinv', 'a', m.In(m.Bit), 'y', m.Out(m.Bit))
    m.wire(~myinv.a, myinv.y)
    m.EndDefine()

    tester = fault.InvTester(myinv, in_='a', out='y')

    tester.compile_and_run(target=target, simulator=simulator, tmp_dir=True)
Beispiel #9
0
def test_tester_verilog_wrapped(target, simulator):
    SimpleALU = m.DefineFromVerilogFile("tests/simple_alu.v",
                                        type_map={"CLK": m.In(m.Clock)},
                                        target_modules=["SimpleALU"])[0]

    circ = m.DefineCircuit("top",
                           "a", m.In(m.Bits[16]),
                           "b", m.In(m.Bits[16]),
                           "c", m.Out(m.Bits[16]),
                           "config_data", m.In(m.Bits[2]),
                           "config_en", m.In(m.Bit),
                           "CLK", m.In(m.Clock))
    simple_alu = SimpleALU()
    m.wire(simple_alu.a, circ.a)
    m.wire(simple_alu.b, circ.b)
    m.wire(simple_alu.c, circ.c)
    m.wire(simple_alu.config_data, circ.config_data)
    m.wire(simple_alu.config_en, circ.config_en)
    m.wire(simple_alu.CLK, circ.CLK)
    m.EndDefine()

    tester = fault.Tester(circ, circ.CLK)
    tester.verilator_include("SimpleALU")
    tester.verilator_include("ConfigReg")
    tester.circuit.CLK = 0
    for i in range(0, 4):
        tester.poke(
            fault.WrappedVerilogInternalPort("SimpleALU_inst0.config_reg.Q",
                                             m.Bits[2]),
            i)
        tester.step(2)
        tester.expect(
            fault.WrappedVerilogInternalPort("SimpleALU_inst0.opcode",
                                             m.Bits[2]),
            i)
        signal = tester.peek(
            fault.WrappedVerilogInternalPort("SimpleALU_inst0.opcode",
                                             m.Bits[2]))
        tester.expect(
            fault.WrappedVerilogInternalPort("SimpleALU_inst0.opcode",
                                             m.Bits[2]),
            signal)
        tester.expect(
            fault.WrappedVerilogInternalPort(
                "SimpleALU_inst0.config_reg.Q", m.Bits[2]),
            i)
        signal = tester.peek(
            fault.WrappedVerilogInternalPort(
                "SimpleALU_inst0.config_reg.Q", m.Bits[2]))
        tester.expect(
            fault.WrappedVerilogInternalPort(
                "SimpleALU_inst0.config_reg.Q", m.Bits[2]),
            signal)
    with tempfile.TemporaryDirectory(dir=".") as _dir:
        if target == "verilator":
            tester.compile_and_run(target, directory=_dir, flags=["-Wno-fatal"])
        else:
            tester.compile_and_run(target, directory=_dir, simulator=simulator)
Beispiel #10
0
def test_enum():
    class State(m.Enum):
        zero = 0
        one = 1
        two = 2

    circuit = m.DefineCircuit('enum_test', "I", m.In(State), "O",
                              m.Out(m.Array[2, State]))
    m.wire(circuit.I, circuit.O[0])
    m.wire(State.zero, circuit.O[1])
    m.EndDefine()
    m.compile("build/test_enum", circuit, output="coreir-verilog")
    assert check_files_equal(__file__, "build/test_enum.v", "gold/test_enum.v")
Beispiel #11
0
def create_io1in_pad():
    cb = m.DefineCircuit("io1in_pad", "clk", m.In(m.Clock), "rst",
                         m.In(m.Reset), "pin_0", m.Out(m.Bit), "pin_1",
                         m.Out(m.Bit), "pin_2", m.Out(m.Bit), "pin_3",
                         m.Out(m.Bit), "top_pin", m.In(m.Bits(1)))

    m.wire(cb.pin_0, cb.top_pin[0])
    m.wire(cb.pin_1, cb.top_pin[0])
    m.wire(cb.pin_2, cb.top_pin[0])
    m.wire(cb.pin_3, cb.top_pin[0])

    m.EndDefine()

    return cb
Beispiel #12
0
def test_assign(width, output):
    T = m.util.BitOrBits(width)
    name = f"test_assign_operator_{width}_{output}"
    circ = m.DefineCircuit(name, "a", m.In(T), "b", m.In(T), "c", m.Out(T))
    and2 = DeclareAnd(width)()
    and2.I0 <= circ.a
    and2.I1 <= circ.b
    circ.c <= and2.O
    m.EndDefine()

    m.compile(f"build/{name}", circ, output)
    suffix = "v" if output == "verilog" else "json"
    assert check_files_equal(__file__, f"build/{name}.{suffix}",
                             f"gold/{name}.{suffix}")
Beispiel #13
0
def test_ram():
    main = m.DefineCircuit("main", "rdata", m.Out(m.Bit), "CLKIN",
                           m.In(m.Clock))

    ram = mantle.RAM(4, 1)

    waddr = mantle.Counter(4)
    wdata = mantle.Counter(1)
    we = 1
    raddr = mantle.FF()(mantle.Counter(4))

    ram(raddr, waddr, wdata, we, CLK=main.CLKIN)

    m.wire(ram.RDATA, main.rdata)
    m.EndDefine()
    m.compile("build/test_common_ram", main)
Beispiel #14
0
def to_fpga(rx):
    icestick = IceStick()
    icestick.Clock.on()
    icestick.D1.on()

    main = icestick.DefineMain()

    rom = string_to_rom('x' * 16)
    matcher = Matcher(rx)

    m.wire(rom, matcher.char)
    m.wire(matcher.match, main.D1)

    m.EndDefine()

    m.compile('regulair', main)
Beispiel #15
0
def test_ram():
    main = m.DefineCircuit("main", "rdata", m.Out(m.Bit), "CLKIN",
                           m.In(m.Clock))

    ram = mantle.RAM(4, 1)

    waddr = mantle.Counter(4, cout=False)
    wdata = mantle.Counter(1, cout=False)
    we = 1
    raddr = mantle.Counter(4, cout=False)

    ram(raddr, waddr, wdata, we, CLK=main.CLKIN)

    m.wire(ram.RDATA[0], main.rdata)
    m.EndDefine()
    if m.mantle_target == "coreir":
        output = "coreir"
    else:
        output = "verilog"
    m.compile("build/test_common_ram", main, output)
Beispiel #16
0
def test_uniquify_verilog():
    [foo0] = m.DefineFromVerilog("""
module foo(input I, output O);
    assign O = I;
endmodule""")
    [foo1] = m.DefineFromVerilog("""
module foo(input II, output OO);
    assign OO = II;
endmodule""")
    assert repr(foo0) != repr(foo1)
    top = m.DefineCircuit("top", "I", m.In(m.Bit), "O", m.Out(m.Bit))
    foo0_inst = foo0()
    foo1_inst = foo1()
    m.wire(top.I, foo0_inst.I)
    m.wire(foo0_inst.O, foo1_inst.II)
    m.wire(foo1_inst.OO, top.O)
    m.EndDefine()

    with pytest.raises(Exception) as pytest_e:
        m.compile(f"top", top, output="coreir")
        assert False
    assert pytest_e.type is Exception
    assert pytest_e.value.args == \
        ("Can not rename a verilog wrapped file",)
Beispiel #17
0
import magma as m
from loam.boards.gpdevboard import GPDevBoard

gp = GPDevBoard()
gp.fpga.P4.output().on()

main = gp.main()

m.wire(1, main.P4)

m.EndDefine()
Beispiel #18
0
def DefineDecode(i, n):
    circ = m.DefineCircuit(f"Decode{i}{n}", "I", m.In(m.Bits(n)), "O",
                           m.Out(m.Bit))
    m.wire(circ.O, EQ(n)(circ.I, m.bits(i, n)))
    m.EndDefine()
    return circ
Beispiel #19
0
def create_pe_tile():
    pe = m.DefineCircuit(
        "pe_tile", "clk", m.In(m.Clock), "rst", m.In(m.Reset), "config_data",
        m.In(m.Bits(32)), "config_addr", m.In(m.Bits(32)), "tile_id",
        m.In(m.Bits(16)), "side_0_track_0_in", m.In(m.Bits(1)),
        "side_0_track_1_in", m.In(m.Bits(1)), "side_0_track_2_in",
        m.In(m.Bits(1)), "side_0_track_3_in", m.In(m.Bits(1)),
        "side_1_track_0_in", m.In(m.Bits(1)), "side_1_track_1_in",
        m.In(m.Bits(1)), "side_1_track_2_in", m.In(m.Bits(1)),
        "side_1_track_3_in", m.In(m.Bits(1)), "side_2_track_0_in",
        m.In(m.Bits(1)), "side_2_track_1_in", m.In(m.Bits(1)),
        "side_2_track_2_in", m.In(m.Bits(1)), "side_2_track_3_in",
        m.In(m.Bits(1)), "side_3_track_0_in", m.In(m.Bits(1)),
        "side_3_track_1_in", m.In(m.Bits(1)), "side_3_track_2_in",
        m.In(m.Bits(1)), "side_3_track_3_in", m.In(m.Bits(1)),
        "side_0_track_0_out", m.Out(m.Bits(1)), "side_0_track_1_out",
        m.Out(m.Bits(1)), "side_0_track_2_out", m.Out(m.Bits(1)),
        "side_0_track_3_out", m.Out(m.Bits(1)), "side_1_track_0_out",
        m.Out(m.Bits(1)), "side_1_track_1_out", m.Out(m.Bits(1)),
        "side_1_track_2_out", m.Out(m.Bits(1)), "side_1_track_3_out",
        m.Out(m.Bits(1)), "side_2_track_0_out", m.Out(m.Bits(1)),
        "side_2_track_1_out", m.Out(m.Bits(1)), "side_2_track_2_out",
        m.Out(m.Bits(1)), "side_2_track_3_out", m.Out(m.Bits(1)),
        "side_3_track_0_out", m.Out(m.Bits(1)), "side_3_track_1_out",
        m.Out(m.Bits(1)), "side_3_track_2_out", m.Out(
            m.Bits(1)), "side_3_track_3_out", m.Out(m.Bits(1)))

    # Configuration data
    config_reg = mantle.Register(32, init=0, has_ce=True, has_reset=True)
    addr_match = mantle.EQ(16)
    m.wire(addr_match.I0, pe.config_addr[0:16])
    m.wire(addr_match.I1, pe.tile_id)
    m.wire(addr_match.O, config_reg.CE)

    m.wire(pe.config_data, config_reg.I)
    m.wire(pe.clk, config_reg.CLK)

    rst_inv = mantle.Invert(1)
    m.wire(rst_inv.I[0], pe.rst)
    m.wire(rst_inv.O[0], config_reg.RESET)

    # Configure sb = 6, cb0 = 4, cb1 = 5, clb = 7
    config_cb0_eq = mantle.EQ(16)
    m.wire(m.uint(4, 16), config_cb0_eq.I0)
    m.wire(pe.config_addr[16:32], config_cb0_eq.I1)

    config_cb1_eq = mantle.EQ(16)
    m.wire(m.uint(5, 16), config_cb1_eq.I0)
    m.wire(pe.config_addr[16:32], config_cb1_eq.I1)

    config_clb_eq = mantle.EQ(16)
    m.wire(m.uint(7, 16), config_clb_eq.I0)
    m.wire(pe.config_addr[16:32], config_clb_eq.I1)

    config_sb_eq = mantle.EQ(16)
    m.wire(m.uint(6, 16), config_sb_eq.I0)
    m.wire(pe.config_addr[16:32], config_sb_eq.I1)

    config_cb0 = mantle.And(2, 1)
    m.wire(config_cb0.I0[0], config_cb0_eq.O)
    m.wire(config_cb0.I1[0], addr_match.O)

    config_cb1 = mantle.And(2, 1)
    m.wire(config_cb1.I0[0], config_cb1_eq.O)
    m.wire(config_cb1.I1[0], addr_match.O)

    config_clb = mantle.And(2, 1)
    m.wire(config_clb.I0[0], config_clb_eq.O)
    m.wire(config_clb.I1[0], addr_match.O)

    config_sb = mantle.And(2, 1)
    m.wire(config_sb.I0[0], config_sb_eq.O)
    m.wire(config_sb.I1[0], addr_match.O)

    # Add ands!

    # # CB0
    cb0 = create_connect_box(1)()
    m.wire(pe.clk, cb0.clk)
    m.wire(pe.rst, cb0.rst)
    m.wire(pe.config_data, cb0.config_data)
    m.wire(config_cb0.O[0], cb0.config_en)

    # CB1
    cb1 = create_connect_box(1)()
    m.wire(pe.clk, cb1.clk)
    m.wire(pe.rst, cb1.rst)
    m.wire(pe.config_data, cb1.config_data)
    m.wire(config_cb1.O[0], cb1.config_en)

    # CLB
    clb = create_clb(1)()
    m.wire(pe.clk, clb.clk)
    m.wire(pe.rst, clb.rst)
    m.wire(pe.config_data, clb.config_data)
    m.wire(config_clb.O[0], clb.config_en)

    # Switch box
    sb = create_switch_box(1)()
    m.wire(pe.clk, sb.clk)
    m.wire(pe.rst, sb.rst)
    m.wire(pe.config_data, sb.config_data)
    m.wire(config_sb.O[0], sb.config_en)

    m.wire(clb.result, sb.clb_result)

    for side in range(0, 4):
        for track in range(0, 4):
            m.wire(
                getattr(pe,
                        'side_' + str(side) + '_track_' + str(track) + '_in'),
                getattr(sb,
                        'side_' + str(side) + '_track_' + str(track) + '_in'))

    for side in range(0, 4):
        for track in range(0, 4):
            m.wire(
                getattr(pe,
                        'side_' + str(side) + '_track_' + str(track) + '_out'),
                getattr(sb,
                        'side_' + str(side) + '_track_' + str(track) + '_out'))

    # Wiring up CLB, SB and CBs
    m.wire(pe.side_0_track_0_in, cb0.track_0_in)
    m.wire(pe.side_0_track_1_in, cb0.track_1_in)
    m.wire(pe.side_0_track_2_in, cb0.track_2_in)
    m.wire(pe.side_0_track_3_in, cb0.track_3_in)

    m.wire(sb.side_0_track_0_out, cb0.track_0_out)
    m.wire(sb.side_0_track_1_out, cb0.track_1_out)
    m.wire(sb.side_0_track_2_out, cb0.track_2_out)
    m.wire(sb.side_0_track_3_out, cb0.track_3_out)

    m.wire(cb0.out, clb.operand0)

    m.wire(pe.side_1_track_0_in, cb1.track_0_in)
    m.wire(pe.side_1_track_1_in, cb1.track_1_in)
    m.wire(pe.side_1_track_2_in, cb1.track_2_in)
    m.wire(pe.side_1_track_3_in, cb1.track_3_in)

    m.wire(sb.side_1_track_0_out, cb1.track_0_out)
    m.wire(sb.side_1_track_1_out, cb1.track_1_out)
    m.wire(sb.side_1_track_2_out, cb1.track_2_out)
    m.wire(sb.side_1_track_3_out, cb1.track_3_out)

    m.wire(cb1.out, clb.operand1)

    m.EndDefine()

    return pe
Beispiel #20
0
def test_key_error():
    default_port_mapping = {
        "I": "in",
        "I0": "in0",
        "I1": "in1",
        "O": "out",
        "S": "sel",
    }

    def DeclareCoreirCircuit(*args, **kwargs):
        return m.DeclareCircuit(*args,
                                **kwargs,
                                renamed_ports=default_port_mapping)

    Mux2x6 = m.DefineCircuit("Mux2x6", "I0", m.In(m.Bits[6]), "I1",
                             m.In(m.Bits[6]), "S", m.In(m.Bit), "O",
                             m.Out(m.Bits[6]))
    mux = DeclareCoreirCircuit(
        f"coreir_commonlib_mux{2}x{6}",
        *[
            "I",
            m.In(
                m.Tuple(data=m.Array[2, m.Bits[6]],
                        sel=m.Bits[m.bitutils.clog2(2)])), "O",
            m.Out(m.Bits[6])
        ],
        coreir_name="muxn",
        coreir_lib="commonlib",
        coreir_genargs={
            "width": 6,
            "N": 2
        })()
    m.wire(Mux2x6.I0, mux.I.data[0])
    m.wire(Mux2x6.I1, mux.I.data[1])
    m.wire(Mux2x6.S, mux.I.sel[0])
    m.wire(mux.O, Mux2x6.O)
    m.EndDefine()

    MuxWrapper_2_6 = m.DefineCircuit("MuxWrapper_2_6", "I",
                                     m.Array[2, m.In(m.Bits[6])], "S",
                                     m.In(m.Bits[1]), "O", m.Out(m.Bits[6]))
    Mux2x6_inst0 = Mux2x6()
    m.wire(MuxWrapper_2_6.I[0], Mux2x6_inst0.I0)
    m.wire(MuxWrapper_2_6.I[1], Mux2x6_inst0.I1)
    m.wire(MuxWrapper_2_6.S[0], Mux2x6_inst0.S)
    m.wire(Mux2x6_inst0.O, MuxWrapper_2_6.O)
    m.EndCircuit()

    MuxWrapper_2_6_copy = m.DefineCircuit("MuxWrapper_2_6", "I",
                                          m.Array[2, m.In(m.Bits[6])], "S",
                                          m.In(m.Bits[1]), "O",
                                          m.Out(m.Bits[6]))
    Mux2x6_inst0 = Mux2x6()
    m.wire(MuxWrapper_2_6_copy.I[0], Mux2x6_inst0.I0)
    m.wire(MuxWrapper_2_6_copy.I[1], Mux2x6_inst0.I1)
    m.wire(MuxWrapper_2_6_copy.S[0], Mux2x6_inst0.S)
    m.wire(Mux2x6_inst0.O, MuxWrapper_2_6_copy.O)
    m.EndCircuit()

    MuxWithDefaultWrapper_2_6_19_0 = m.DefineCircuit(
        "MuxWithDefaultWrapper_2_6_19_0", "I", m.Array[2, m.In(m.Bits[6])],
        "S", m.In(m.Bits[19]), "O", m.Out(m.Bits[6]))
    MuxWrapper_2_6_inst0 = MuxWrapper_2_6()
    MuxWrapper_2_6_inst1 = MuxWrapper_2_6_copy()
    m.wire(MuxWithDefaultWrapper_2_6_19_0.I, MuxWrapper_2_6_inst0.I)
    m.wire(MuxWithDefaultWrapper_2_6_19_0.I, MuxWrapper_2_6_inst1.I)
    m.wire(MuxWithDefaultWrapper_2_6_19_0.S[0], MuxWrapper_2_6_inst0.S[0])
    m.wire(MuxWithDefaultWrapper_2_6_19_0.S[0], MuxWrapper_2_6_inst1.S[0])
    m.wire(MuxWrapper_2_6_inst1.O, MuxWithDefaultWrapper_2_6_19_0.O)
    m.EndCircuit()

    top = MuxWithDefaultWrapper_2_6_19_0
    m.compile(f"build/{top.name}", top, output="coreir")
    assert check_files_equal(__file__, f"build/{top.name}.json",
                             "gold/uniquification_key_error_mux.json")