def test_rd_ptr(target): m.UIntType.__add__ = lambda x, y: DeclareCoreirCircuit( "add", *["I0", m.In(m.UInt[len(x)]), "I1", m.In(m.UInt[len(x)]), "O", m.Out(m.UInt[len(x)])], coreir_name="add", coreir_genargs={"width": len(x)}, coreir_lib="coreir" )()(x, y) @m.circuit.sequential(async_reset=True) class RdPtr: def __init__(self): self.rd_ptr: m.UInt[10] = m.uint(0, 10) def __call__(self, read: m.Bit) -> m.Bits[10]: orig_rd_ptr = self.rd_ptr # FIXME: Bug in magma sequential means we always have to specify a next # value (won't use current value by default) self.rd_ptr = orig_rd_ptr if read: self.rd_ptr = self.rd_ptr + 1 return orig_rd_ptr compile_and_check("RdPtr", RdPtr, target)
def test_seq_simple(target, async_reset): @m.circuit.sequential(async_reset=async_reset) class TestBasic: def __init__(self): self.x: m.Bits[2] = m.bits(0, 2) self.y: m.Bits[2] = m.bits(0, 2) def __call__(self, I: m.Bits[2]) -> m.Bits[2]: O = self.y self.y = self.x self.x = I return O compile_and_check("TestBasic" + ("ARST" if async_reset else ""), TestBasic, target) if target == "coreir-verilog" and not async_reset: """ The following sequence was used to create the verilator driver: tester = fault.Tester(TestBasic, clock=TestBasic.CLK) tester.circuit.I = 1 tester.step(2) tester.circuit.I = 2 tester.step(2) tester.circuit.O.expect(1) tester.circuit.I = 3 tester.step(2) tester.circuit.O.expect(2) tester.circuit.I = 0 tester.step(2) tester.circuit.O.expect(3) """ _run_verilator(TestBasic, directory="tests/test_syntax/build")
def test_multiple_return(target, async_reset): T = m.Bits[4] m._BitType.__eq__ = lambda x, y: DeclareCoreirCircuit( "eq", *["I0", m.In(m.Bit), "I1", m.In(m.Bit), "O", m.Out(m.Bit)], coreir_name="and", coreir_lib="corebit" )()(x, y) m.BitsType.__eq__ = lambda x, y: DeclareCoreirCircuit( "eq", *["I0", m.In(m.Bits[len(x)]), "I1", m.In(m.Bits[len(x)]), "O", m.Out(m.Bit)], coreir_genargs={"width": len(x)}, coreir_name="eq", coreir_lib="coreir" )()(x, y) @m.circuit.sequential(async_reset=async_reset) class Register: def __init__(self): self.value: T = T(0) def __call__(self, value: T, en: m.Bit) -> T: retvalue = self.value if en: self.value = value else: self.value = self.value return retvalue @m.circuit.sequential(async_reset=async_reset) class RegisterMode: def __init__(self): self.register: Register = Register(0) def __call__(self, mode: m.Bits[2], const_: T, value: T, clk_en: m.Bit, config_we: m.Bit, config_data: T) -> (T, T): if config_we == m.Bit(1): reg_val = self.register(config_data, m.Bit(1)) return reg_val, reg_val elif mode == m.bits(0, 2): reg_val = self.register(value, m.Bit(False)) return const_, reg_val elif mode == m.bits(1, 2): reg_val = self.register(value, m.Bit(False)) return value, reg_val elif mode == m.bits(2, 2): reg_val = self.register(value, clk_en) return reg_val, reg_val compile_and_check("RegisterMode" + ("ARST" if async_reset else ""), RegisterMode, target)
def test_array_of_bits(target): @m.circuit.sequential(async_reset=True) class ArrayOfBitsSeq: def __init__(self): self.register_array: m.Array[15, m.Bits[1024]] = \ m.array([m.bits(0, 1024) for _ in range(15)]) def __call__(self, I: m.Array[15, m.Bits[1024]]) -> \ m.Array[15, m.Bits[1024]]: O = self.register_array self.register_array = I return O compile_and_check("ArrayOfBitsSeq", ArrayOfBitsSeq, target)
def test_seq_hierarchy(target, async_reset): @m.cache_definition def DefineCustomRegister(width, init=0): @m.circuit.sequential(async_reset=async_reset) class Register: def __init__(self): self.value: m.Bits[width] = m.bits(init, width) def __call__(self, I: m.Bits[width]) -> m.Bits[width]: O = self.value self.value = I return O return Register CustomRegister0 = DefineCustomRegister(2, init=0) CustomRegister1 = DefineCustomRegister(2, init=1) @m.circuit.sequential(async_reset=async_reset) class TestShiftRegister: def __init__(self): self.x: CustomRegister0 = CustomRegister0() self.y: CustomRegister1 = CustomRegister1() def __call__(self, I: m.Bits[2]) -> m.Bits[2]: x_prev = self.x(I) y_prev = self.y(x_prev) return y_prev compile_and_check("TestShiftRegister" + ("ARST" if async_reset else ""), TestShiftRegister, target) if target == "coreir-verilog" and not async_reset: """ The following sequence was used to create the verilator driver: tester = fault.Tester(TestShiftRegister, clock=TestShiftRegister.CLK) tester.circuit.I = 1 tester.step(2) tester.circuit.I = 2 tester.step(2) tester.circuit.O.expect(1) tester.circuit.I = 3 tester.step(2) tester.circuit.O.expect(2) tester.circuit.I = 0 tester.step(2) tester.circuit.O.expect(3) """ _run_verilator(TestShiftRegister, directory="tests/test_syntax/build")