def SideType(num_tracks, layers): layers_dict = { f"layer{l}": magma.Array(num_tracks, magma.Bits(l)) for l in layers } T = magma.Tuple(**layers_dict) return magma.Tuple(I=magma.In(T), O=magma.Out(T))
def test_array_nesting(): T = m.Array[10, m.Tuple(I=m.In(m.Bit), O=m.Out(m.Bit))] Foo = m.DefineCircuit("Foo", "IFC", T) for i in range(10): m.wire(Foo.IFC[i].I, Foo.IFC[i].O) m.EndCircuit() m.compile("build/test_array_nesting", Foo, output="coreir") assert check_files_equal(__file__, f"build/test_array_nesting.json", f"gold/test_array_nesting.json")
def APBMaster(addr_width, data_width, num_sel=1): assert data_width <= 32 PSELs = {} for i in range(num_sel): PSELs[f"PSEL{i}"] = m.Out(m.Bit) return m.Tuple( **APBBase(addr_width, data_width), **PSELs, )
def APBSlave(addr_width, data_width, slave_id_or_ids): """ slave_id_or_ids is either an id (e.g. 2) or a list of ids ([0, 1, 2]) """ if isinstance(slave_id_or_ids, int): slave_id_or_ids = [slave_id_or_ids] # APBBase is defined in terms of the master, so we define PSEL as an output # since the entire type will be flipped PSEL = {f"PSEL{slave_id}": m.Out(m.Bit) for slave_id in slave_id_or_ids} return m.Tuple(**APBBase(addr_width, data_width), **PSEL).flip()
def test_nesting(): bar = m.DefineCircuit( "bar", "I", m.Tuple(x=m.In(m.Tuple(a=m.Bit, b=m.Bit)), y=m.Out(m.Tuple(a=m.Bit, b=m.Bit)), z=m.Tuple(a=m.In(m.Bit), b=m.Out(m.Bit)))) foo = def_foo() foo_inst0 = foo() foo_inst1 = foo() foo_inst2 = foo() m.wire(foo_inst0.ifc.I, bar.I.x.a) m.wire(foo_inst0.ifc.O, bar.I.y.a) m.wire(foo_inst1.ifc.I, bar.I.x.b) m.wire(foo_inst1.ifc.O, bar.I.y.b) m.wire(foo_inst2.ifc.I, bar.I.z.a) m.wire(foo_inst2.ifc.O, bar.I.z.b) m.EndCircuit() m.compile("build/test_nesting", bar, output="coreir") assert check_files_equal(__file__, f"build/test_nesting.json", f"gold/test_nesting.json")
def test_multi_direction_tuple_instance(): bar = m.DefineCircuit("bar", "ifc", m.Tuple(I=m.In(m.Bit), O=m.Out(m.Bit))) foo_inst = def_foo()() m.wire(bar.ifc.I, foo_inst.ifc.I) m.wire(bar.ifc.O, foo_inst.ifc.O) m.EndCircuit() m.compile("build/test_multi_direction_tuple_instance", bar, output="coreir") assert check_files_equal( __file__, f"build/test_multi_direction_tuple_instance.json", f"gold/test_multi_direction_tuple_instance.json")
def test_multi_direction_tuple_instance_bulk(): bar = m.DefineCircuit("bar", "ifc", m.Tuple(I=m.In(m.Bit), O=m.Out(m.Bit))) foo_inst = def_foo()() m.wire(bar.ifc, foo_inst.ifc) m.EndCircuit() m.compile("build/test_multi_direction_tuple_instance_bulk", bar, output="coreir") # NOTE: Should be the same as previous test, so we use that as a check assert check_files_equal( __file__, f"build/test_multi_direction_tuple_instance_bulk.json", f"gold/test_multi_direction_tuple_instance.json")
class TestNestedClockTuple(m.Circuit): io = m.IO(I=m.In(m.Tuple(clk1=m.Clock, clk2=m.Clock, i=m.Bit)), O=m.Out(m.Bits(2))) @classmethod def definition(io): ff0 = mantle.FF() ff1 = mantle.FF() m.wire(io.I.clk1, ff0.CLK) m.wire(io.I.clk2, ff1.CLK) m.wire(io.I.i, ff0.I) m.wire(io.I.i, ff1.I) m.wire(m.bits([ff0.O, ff1.O]), io.O)
def MMIOType(addr_width, data_width): """ This function returns a class (parameterized by @addr_width and @data_width) which can be used as the magma ports with these inputs and outputs 1. rd_en 2. rd_addr 3. rd_data 4. wr_en 5. wr_addr 6. wr_Data """ _MMIOType = magma.Tuple(wr_en=magma.In(magma.Bit), wr_addr=magma.In(magma.Bits[addr_width]), wr_data=magma.In(magma.Bits[data_width]), rd_en=magma.In(magma.Bit), rd_addr=magma.In(magma.Bits[addr_width]), rd_data=magma.Out(magma.Bits[data_width])) return _MMIOType
def AXI4SlaveType(addr_width, data_width): """ This function returns a axi4-slave class (parameterized by @addr_width and @data_width) which can be used as the magma ports with these inputs and outputs Below is AXI4-Lite interface ports in verilog input logic [`$cfg_addr_width-1`:0] AWADDR, input logic AWVALID, output logic AWREADY, input logic [`$cfg_bus_width-1`:0] WDATA, input logic WVALID, output logic WREADY, input logic [`$cfg_bus_width-1`:0] ARADDR, input logic ARVALID, output logic ARREADY, output logic [`$cfg_bus_width-1`:0] RDATA, output logic [1:0] RRESP, output logic RVALID, input logic RREADY, output logic interrupt, """ _AXI4SlaveType = magma.Tuple(awaddr=magma.In(magma.Bits[addr_width]), awvalid=magma.In(magma.Bit), awready=magma.Out(magma.Bit), wdata=magma.In(magma.Bits[data_width]), wvalid=magma.In(magma.Bit), wready=magma.Out(magma.Bit), araddr=magma.In(magma.Bits[addr_width]), arvalid=magma.In(magma.Bit), arready=magma.Out(magma.Bit), rdata=magma.Out(magma.Bits[data_width]), rresp=magma.Out(magma.Bits[2]), rvalid=magma.Out(magma.Bit), rready=magma.In(magma.Bit), interrupt=magma.Out(magma.Bit)) return _AXI4SlaveType
def Tester(circuit, lines): args = {name: type(port) for name, port in circuit.interface.ports.items()} args = m.Tuple(args) print(circuit) print(args) clock = None for name, port in circuit.interface.ports.items(): if isinstance(port, m.ClockType): clock = port #print(clock) tester = fault.Tester(circuit, clock=clock) for line in lines: #print("line", line[:-1]) testargs = cast(str2bits(line[:-1]), args) if clock: process_inputs(circuit, tester, testargs) print('tester.eval()') tester.eval() process_outputs(circuit, tester, testargs) print('tester.step()') tester.step() print('tester.eval()') tester.eval() print('tester.step()') tester.step() else: process_inputs(circuit, tester, testargs) tester.eval() print('tester.eval()') process_outputs(circuit, tester, testargs) #tester.compile_and_run(target='python') #tester.compile_and_run(directory="build", target="verilator", flags=["-Wno-fatal"]) return tester
return _Circuit TestBasicCircuit = define_simple_circuit(m.Bit, "BasicCircuit") TestArrayCircuit = define_simple_circuit(m.Array[3, m.Bit], "ArrayCircuit") TestByteCircuit = define_simple_circuit(m.Bits[8], "ByteCircuit") TestSIntCircuit = define_simple_circuit(m.SInt[3], "SIntCircuit") TestNestedArraysCircuit = define_simple_circuit(m.Array[3, m.Bits[4]], "NestedArraysCircuit") TestDoubleNestedArraysCircuit = define_simple_circuit( m.Array[2, m.Array[3, m.Bits[4]]], "DoubleNestedArraysCircuit") TestBasicClkCircuit = define_simple_circuit(m.Bit, "BasicClkCircuit", True) TestBasicClkCircuitCopy = define_simple_circuit(m.Bit, "BasicClkCircuitCopy", True) TestTupleCircuit = define_simple_circuit(m.Tuple(a=m.Bits[4], b=m.Bits[4]), "TupleCircuit") T = m.Bits[3] class TestPeekCircuit(m.Circuit): __test__ = False # Disable pytest discovery IO = ["I", m.In(T), "O0", m.Out(T), "O1", m.Out(T)] @classmethod def definition(io): m.wire(io.I, io.O0) m.wire(io.I, io.O1)
def Point2D(num_bits): return m.Tuple(x=Coordinate(num_bits), y=Coordinate(num_bits))
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")
def test_pretty_print_array_of_nested_tuple(): t = m.Tuple(a=m.Bits[5], b=m.UInt[3], c=m.SInt[4]) u = m.Tuple(x=t, y=t) v = m.Array[3, u] assert m.util.pretty_str(v) == """\
def return_magma_named_tuple(I: m.Bits[2]) -> m.Tuple(x=m.Bit, y=m.Bit): return m.namedtuple(x=I[0], y=I[1])
def test_pretty_print_tuple(): t = m.Tuple(a=m.Bit, b=m.Bit, c=m.Bit) assert m.util.pretty_str(t) == """\
def test_pretty_print_tuple_recursive(): t = m.Tuple(a=m.Bit, b=m.Bit, c=m.Bit) u = m.Tuple(x=t, y=t) assert m.util.pretty_str(u) == """\
def baseIO(): dictIO = {"in0": m.In(m.Bit), "out0": m.Out(m.Bit)} return m.Tuple(**dictIO)
TestBasicCircuit = define_simple_circuit(m.Bit, "BasicCircuit") TestArrayCircuit = define_simple_circuit(m.Array[3, m.Bit], "ArrayCircuit") TestByteCircuit = define_simple_circuit(m.Bits[8], "ByteCircuit") TestUInt32Circuit = define_simple_circuit(m.UInt[32], "UInt32Circuit") TestUInt64Circuit = define_simple_circuit(m.UInt[64], "UInt64Circuit") TestUInt128Circuit = define_simple_circuit(m.UInt[128], "UInt128Circuit") TestSIntCircuit = define_simple_circuit(m.SInt[4], "SIntCircuit") TestNestedArraysCircuit = define_simple_circuit(m.Array[3, m.Bits[4]], "NestedArraysCircuit") TestDoubleNestedArraysCircuit = define_simple_circuit( m.Array[2, m.Array[3, m.Bits[4]]], "DoubleNestedArraysCircuit") TestBasicClkCircuit = define_simple_circuit(m.Bit, "BasicClkCircuit", True) TestBasicClkCircuitCopy = define_simple_circuit(m.Bit, "BasicClkCircuitCopy", True) TestTupleCircuit = define_simple_circuit(m.Tuple(a=m.Bits[4], b=m.Bits[4]), "TupleCircuit") TestNestedTupleCircuit = define_simple_circuit( m.Tuple(a=m.Tuple(k=m.Bits[5], v=m.Bits[2]), b=m.Bits[4]), "NestedTupleCircuit") T = m.Bits[3] class TestPeekCircuit(m.Circuit): __test__ = False # Disable pytest discovery IO = ["I", m.In(T), "O0", m.Out(T), "O1", m.Out(T)] @classmethod def definition(io): m.wire(io.I, io.O0)
def make_Float(exponent_width, significand_width): # Adapted from the chisel documentation # https://github.com/freechipsproject/chisel3/wiki/Bundles-and-Vecs return m.Tuple(sign=m.Bit, exponent=m.UInt[exponent_width], significand=m.UInt[significand_width])
def make_HandshakeData(data_type): in_type = m.Tuple(data=m.In(data_type), valid=m.In(m.Bit), ready=m.Out(m.Bit)) out_type = m.Flip(in_type) return in_type, out_type
def ConfigurationType(addr_width, data_width): return magma.Tuple(config_addr=magma.Bits[addr_width], config_data=magma.Bits[data_width], read=magma.Bits[1], write=magma.Bits[1])
def test_pretty_print_array_of_tuple(): t = m.Tuple(a=m.Bit, b=m.Bit, c=m.Bit) u = m.Array[3, t] assert m.util.pretty_str(u) == """\
def def_foo(): foo = m.DefineCircuit("Foo", "ifc", m.Tuple(I=m.In(m.Bit), O=m.Out(m.Bit))) m.wire(foo.ifc.I, foo.ifc.O) m.EndCircuit() return foo
def ConfigurationType(addr_width, data_width): return magma.Tuple(config_addr=magma.Bits(addr_width), config_data=magma.Bits(data_width), read=magma.Bits(1), write=magma.Bits(1) )
m.EndCircuit() try: m.compile("build/test_unwired_output", main) assert False, "Should raise exception" except Exception as e: assert str( e ) == "Argument main.I of type Array[2, Array[3, Out(Bit)]] is not supported, the verilog backend only supports simple 1-d array of bits of the form Array(N, Bit)" # noqa @pytest.mark.parametrize("target,suffix", [("verilog", "v"), ("coreir", "json")]) @pytest.mark.parametrize( "T", [m.Bit, m.Bits[2], m.Array[2, m.Bit], m.Tuple(x=m.Bit, y=m.Bit)]) def test_anon_value(target, suffix, T): And2 = m.DeclareCircuit('And2', "I0", m.In(T), "I1", m.In(T), "O", m.Out(T)) main = m.DefineCircuit("main", "I0", m.In(T), "I1", m.In(T), "O", m.Out(T)) and2 = And2() m.wire(main.I0, and2.I0) m.wire(main.I1, and2.I1) tmp = T() m.wire(and2.O, tmp) m.wire(tmp, main.O) m.EndCircuit()
def return_magma_tuple(I: m.Bits[2]) -> m.Tuple(m.Bit, m.Bit): return m.tuple_([I[0], I[1]])
def _from_fields(mcs, fields, name, bases, ns, cache, **kwargs): assert fields return m.Tuple(**fields)
def hierIO(): dictIO = {"baseIO": baseIO(), "ctr": m.In(m.Bit)} return m.Tuple(**dictIO)