예제 #1
0
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)
예제 #2
0
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")
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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")