def test_two_ops(): Top = m.DefineCircuit("test_two_ops", "I0", m.In(m.UInt(8)), "I1", m.In(m.UInt(8)), "O", m.Out(m.UInt(8))) result = Top.I0 + Top.I1 - Top.I0 m.wire(result, Top.O) m.EndCircuit() m.compile("test_two_ops", Top, output="coreir-verilog", inline=True) # assert check_files_equal(__file__, "build/test_two_ops.v", # "gold/test_two_ops.v") # Roundabout way to do this since we can't pass the --inline flag through # fault's tester interface yet tester = fault.Tester(Top) for i in range(0, 16): I0 = fault.random.random_bv(8) I1 = fault.random.random_bv(8) tester.poke(Top.I0, I0) tester.poke(Top.I1, I1) tester.eval() tester.expect(Top.O, I0 + I1 - I0) tester.compile_and_run(target="verilator", skip_compile=True, directory=".")
def wrap(inst, cirb): for io in inst.IO: argtype = inst.IO.__getitem__(inst.IO, io) print(io, argtype, argtype.isoutput()) if argtype.isoutput(): t = Term(cirb, 1) m.wire(getattr(inst, io), t)
def test_wire1(): b0 = BitOut(name='b0') assert b0.isoutput() b1 = BitIn(name='b1') assert b1.isinput() print('wire(b0,b1)') wire(b0, b1) assert b0.port.wires is b1.port.wires #wires = b0.port.wires #print 'inputs:', [str(p) for p in wires.inputs] #print 'outputs:', [str(p) for p in wires.outputs] assert len(b0.port.wires.inputs) == 1 assert len(b0.port.wires.outputs) == 1 assert b0.wired() assert b1.wired() assert b0.trace() is b1 assert b1.trace() is b0 assert b0.value() is None assert b1.value() is b0
def definition(io): # Generate the sum m.wire(XOr(3)(io.I0, io.I1, io.CIN), io.O) # Generate the carry m.wire( Or(3)(And(2)(io.I0, io.I1), And(2)(io.I1, io.CIN), And(2)(io.I0, io.CIN)), io.COUT)
def compose(circuit1, circuit2): # check that circuit2.outputs == circuit1.inputs wire(circuit2, circuit1) args = [] args += inputargs(circuit2) args += outputargs(circuit1) return AnonymousCircuit(args)
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}")
def test_inv(): Test = m.DefineCircuit("INV", "I", m.In(m.Bit), "O", m.Out(m.Bit)) inv = greenpak4.GP_INV() m.wire(Test.I, inv.IN) m.wire(inv.OUT, Test.O) com(Test, 'inv')
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_for_loop_def(target, suffix): m.set_codegen_debug_info(True) And2 = m.DeclareCircuit('And2', "I0", m.In(m.Bit), "I1", m.In(m.Bit), "O", m.Out(m.Bit)) main = m.DefineCircuit("main", "I", m.In(m.Bits[2]), "O", m.Out(m.Bit)) and2_prev = None for i in range(0, 4): and2 = And2() if i == 0: m.wire(main.I[0], and2.I0) m.wire(main.I[1], and2.I1) else: m.wire(and2_prev.O, and2.I0) m.wire(main.I[1], and2.I1) and2_prev = and2 m.wire(and2.O, main.O) m.EndCircuit() m.compile("build/test_for_loop_def", main, output=target) m.set_codegen_debug_info(False) assert check_files_equal(__file__, f"build/test_for_loop_def.{suffix}", f"gold/test_for_loop_def.{suffix}")
class _CoreirWrapCircuit(magma.Circuit): name = self.name() io = magma.IO(**self.decl()) wrapper = Wrapper() magma.wire(io.I, wrapper.interface.ports["in"]) magma.wire(wrapper.out, io.O)
def definition(io): # Generate the sum _sum = io.a ^ io.b ^ io.cin m.wire(_sum, io.out) # Generate the carry carry = (io.a & io.b) | (io.b & io.cin) | (io.a & io.cin) m.wire(carry, io.cout)
def test_str_repr(): And2 = m.DeclareCircuit('And2', "I0", m.In(m.Bit), "I1", m.In(m.Bit), "O", m.Out(m.Bit)) XOr2 = m.DeclareCircuit('XOr2', "I0", m.In(m.Bit), "I1", m.In(m.Bit), "O", m.Out(m.Bit)) Logic2 = m.DefineCircuit('Logic2', 'I0', m.In(m.Bit), 'I1', m.In(m.Bit), 'O', m.Out(m.Bit)) m.wire(XOr2()(And2()(Logic2.I0, Logic2.I1), 1), Logic2.O) m.EndCircuit() assert str(Logic2) == "Logic2(I0: In(Bit), I1: In(Bit), O: Out(Bit))" print(repr(Logic2)) assert repr(Logic2) == """\ Logic2 = DefineCircuit("Logic2", "I0", In(Bit), "I1", In(Bit), "O", Out(Bit)) And2_inst0 = And2() XOr2_inst0 = XOr2() wire(Logic2.I0, And2_inst0.I0) wire(Logic2.I1, And2_inst0.I1) wire(And2_inst0.O, XOr2_inst0.I0) wire(1, XOr2_inst0.I1) wire(XOr2_inst0.O, Logic2.O) EndCircuit()\ """ expected = [ "XOr2_inst0<XOr2(I0: In(Bit), I1: In(Bit), O: Out(Bit))>", "And2_inst0<And2(I0: In(Bit), I1: In(Bit), O: Out(Bit))>" ] for inst, expected in zip(Logic2.instances, expected): assert str(inst) == expected
def RAM(n): # RAM16 + CIN def ram16(x, y, s, e): ram = RAM16(0, o=False) return CARRY(ram, 'CIN', 'COUT', 0, site=s, elem=e) # # Need to feed increment through COUT of the lower slice # # wire A into cy0 # lut selects cy0 # lut = LUT('A&~A', o=False, site=site, elem='Y') lut = CARRY(lut, None, 'COUT', 'A', o=False, site=site, elem='Y') c = Wire() lut(c) ram = forkjoin(col(ram16, n, site.delta(0, 1)), 'jff') ram.I = [ram.I + [c]] # [DI, A, WE] + [INCR] wire(lut.COUT, ram.CIN) return ram
def definition(def_): def buf(y): return Buf(loc=(0, y // 8, y % 8)) buffer = join(col(buf, width)) wire(def_.I, buffer.I0) wire(buffer.O, def_.O)
def definition(io): # Generate the sum sum_ = XOr(2)(io.I0, io.I1) # Generate the carry cout = And(2)(io.I0, io.I1) m.wire(sum_, io.O) m.wire(cout, io.COUT)
class Adder(AdderNDecl): io = AdderNDecl.io adders = [mantle.FullAdder() for _ in range(N)] adders = m.fold(adders, foldargs={"CIN": "COUT"}) COUT, O = adders(I0=io.I0, I1=io.I1, CIN=io.CIN) m.wire(O, io.O) m.wire(COUT, io.COUT)
class Register(m.Circuit): name = f"Register_has_ce_{has_ce}_has_reset_{has_reset}_" \ f"has_async_reset_{has_async_reset}_" \ f"has_async_resetn_{has_async_resetn}_" \ f"type_{_type.__name__}_n_{n}" io = m.IO(I=m.In(T), O=m.Out(T)) io += m.ClockIO(has_ce=has_ce, has_reset=has_reset, has_async_reset=has_async_reset, has_async_resetn=has_async_resetn) reg = DefineCoreirReg(n, init, has_async_reset, has_async_resetn, _type)(name="value") I = io.I O = reg.O if n is None: O = O[0] if has_reset and has_ce: if reset_priority: I = mantle.mux([O, I], io.CE, name="enable_mux") I = mantle.mux([I, m.bits(init, n)], io.RESET) else: I = mantle.mux([I, m.bits(init, n)], io.RESET) I = mantle.mux([O, I], io.CE, name="enable_mux") elif has_ce: I = mantle.mux([O, I], io.CE, name="enable_mux") elif has_reset: I = mantle.mux([I, m.bits(init, n)], io.RESET) if n is None: m.wire(I, reg.I[0]) else: m.wire(I, reg.I) m.wire(io.O, O)
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)
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)
def definition(io): # Swap this line with the commented code in the following line # to induce a failure in the behavioral test O = io.I0.zext(1) + io.I1.zext(1) + m.bits(io.CIN, 1).zext(N) # O = io.I0.zext(1) - io.I1.zext(1) - m.bits(io.CIN, 1).zext(N) m.wire(O[:N], io.O) m.wire(O[-1], io.COUT)
def definition(io): config_reg_reset_bit_vector = \ generate_reset_value(constant_bit_count, default_value, reset_val, mux_sel_bit_count) config_cb = mantle.Register(config_reg_width, init=config_reg_reset_bit_vector, has_ce=True, has_async_reset=True) config_addr_zero = m.bits(0, 8) == io.config_addr[24:32] config_cb(io.config_data, CE=m.bit(io.config_en) & config_addr_zero) # if the top 8 bits of config_addr are 0, then read_data is equal # to the value of the config register, otherwise it is 0 m.wire(io.read_data, mantle.mux([m.uint(0, 32), config_cb.O], config_addr_zero)) output_mux = generate_output_mux(num_tracks, feedthrough_outputs, has_constant, width, mux_sel_bit_count, constant_bit_count, io, config_cb) # NOTE: This is a dummy! fix it later! m.wire(output_mux.O, io.out) return
def wire_reg(reg, reg_input, reg_output=None): m.wire(reg_input, reg.data_in) m.wire(reg.clk, io.CLK) m.wire(reg.reset, io.RESET) m.wire(reg.en, m.bit(1)) if reg_output is not None: m.wire(reg.data_out, reg_output)
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)
def definition(io): adders = [FullAdder() for _ in range(N)] circ = m.braid(adders, foldargs={"cin": "cout"}) m.wire(io.a, circ.a) m.wire(io.b, circ.b) m.wire(io.cin, circ.cin) m.wire(io.cout, circ.cout) m.wire(io.out, circ.out)
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 test_simple_top(): Top = m.DefineCircuit("Top", "I0", m.In(m.UInt(8)), "I1", m.In(m.UInt(8)), "O", m.Out(m.UInt(8))) sum_ = Top.I0 + Top.I1 m.wire(sum_, Top.O) m.EndCircuit() m.compile("test_simple_top", Top, output="coreir-verilog", inline=True)
class Adder(AdderNDecl): io = AdderNDecl.io # Swap this line with the commented code in the following line # to induce a failure in the behavioral test O = io.I0.zext(1) + io.I1.zext(1) + m.bits(io.CIN, 1).zext(N) # O = io.I0.zext(1) - io.I1.zext(1) - m.bits(io.CIN, 1).zext(N) m.wire(O[:N], io.O) m.wire(O[-1], io.COUT)
def definition(io): # Generate the sum sum_ = XOr(3)(io.I0, io.I1, io.CIN) # Generate the carry cout = Or(3)(And(2)(io.I0, io.I1), And(2)(io.I1, io.CIN), And(2)(io.I0, io.CIN)) m.wire(sum_, io.O) m.wire(cout, io.COUT)
def definition(io): reg = DefineCoreirReg(n, init, has_async_reset, _type)() I = io.I if has_reset: I = mantle.mux([io.I, m.bits(init, n)], io.RESET) if has_ce: I = mantle.mux([reg.O, I], io.CE) m.wire(I, reg.I) m.wire(io.O, reg.O)
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 definition(io): rm = RigelMod() m.wire(io.I,rm.process_input) out = rm.process_output+m.uint(10,8) m.wire(io.O,out) m.wire(rm.CE,m.bit(True))