Ejemplo n.º 1
0
 def __init__(self, dut, num_samples, input_width):
     clk = Clock(dut.clk_i, 40)
     clk_3x = Clock(dut.clk_3x_i, 120)
     self.multiclock = MultiClock([clk, clk_3x])
     self.dut = dut
     self.re_inputs = random_samples(input_width, num_samples)
     self.im_inputs = random_samples(input_width, num_samples)
     self.outputs = np.fft.fft(self.re_inputs + 1j * self.im_inputs)
Ejemplo n.º 2
0
class FT245_TB:
    """
    FT2232H FT245 asynchronous mode FIFO testbench class.
    """

    def __init__(self, dut):
        clk = Clock(dut.clk, 40)
        ft_clk = Clock(dut.ft_clk, 60)
        slow_ft_clk = Clock(dut.slow_ft_clk, 7.5)
        self.multiclock = MultiClock([clk, ft_clk, slow_ft_clk])
        self.dut = dut

    @cocotb.coroutine
    async def setup(self):
        self.multiclock.start_all_clocks()
        await self.reset()

    @cocotb.coroutine
    async def reset(self):
        await self.await_all_clocks()
        self.dut.rst_n <= 0
        await self.await_all_clocks()
        self.dut.rst_n <= 1

    @cocotb.coroutine
    async def await_all_clocks(self):
        trigs = []
        for clk in self.multiclock.clocks:
            trigs.append(RisingEdge(clk.clk))

        await Combine(*trigs)

    @cocotb.coroutine
    async def fpga_write_continuous(self, inputs):
        """
        Continuously write from FPGA. When inputs have been exhausted,
        write zeros.
        """
        sample_ctr = 0
        num_samples = len(inputs)
        self.dut.wren <= 1
        while True:
            if sample_ctr < num_samples:
                self.dut.wrdata <= BinaryValue(
                    int(inputs[sample_ctr].item()), 64, binaryRepresentation=2
                )
            else:
                self.dut.wrdata <= 0
            sample_ctr += 1
            await RisingEdge(self.dut.clk)
Ejemplo n.º 3
0
class PllSyncCtrTB:
    def __init__(self, dut):
        fst_clk = Clock(dut.fst_clk, 80)
        slw_clk = Clock(dut.slw_clk, 10)
        self.multiclock = MultiClock([fst_clk, slw_clk])
        self.dut = dut

    @cocotb.coroutine
    async def setup(self):
        self.multiclock.start_all_clocks()
        await self.await_all_clocks()
        self.dut.rst_n <= 0
        await self.await_all_clocks()
        self.dut.rst_n <= 1

    @cocotb.coroutine
    async def await_all_clocks(self):
        trigs = []
        for clk in self.multiclock.clocks:
            trigs.append(RisingEdge(clk.clk))

        await Combine(*trigs)
Ejemplo n.º 4
0
 def __init__(self, dut):
     fst_clk = Clock(dut.fst_clk, 80)
     slw_clk = Clock(dut.slw_clk, 10)
     self.multiclock = MultiClock([fst_clk, slw_clk])
     self.dut = dut
Ejemplo n.º 5
0
class FFTTB:
    """
    R22 SDF FFT testbench class.
    """
    def __init__(self, dut, num_samples, input_width):
        clk = Clock(dut.clk_i, 40)
        clk_3x = Clock(dut.clk_3x_i, 120)
        self.multiclock = MultiClock([clk, clk_3x])
        self.dut = dut
        self.re_inputs = random_samples(input_width, num_samples)
        self.im_inputs = random_samples(input_width, num_samples)
        self.outputs = np.fft.fft(self.re_inputs + 1j * self.im_inputs)

    @cocotb.coroutine
    async def setup(self):
        self.multiclock.start_all_clocks()
        await self.reset()

    @cocotb.coroutine
    async def reset(self):
        await self.await_all_clocks()
        self.dut.rst_n <= 0
        await self.await_all_clocks()
        self.dut.rst_n <= 1

    @cocotb.coroutine
    async def await_all_clocks(self):
        """
        Wait for positive edge on both clocks before proceeding.
        """
        trigs = []
        for clk in self.multiclock.clocks:
            trigs.append(RisingEdge(clk.clk))

        await Combine(*trigs)

    def check_outputs(self, tolerance):
        """
        Check that the measured outputs are within the specified tolerance
        of the actual outputs. Raise a test failure if not. If the
        tolerance is satisfied, return a tuple of the difference
        values.
        """
        bit_rev_ctr = self.dut.data_ctr_o.value.integer
        rval = self.dut.data_re_o.value.signed_integer
        rexp = np.real(self.outputs)[bit_rev_ctr].item()
        rdiff = rval - rexp
        ival = self.dut.data_im_o.value.signed_integer
        iexp = np.imag(self.outputs)[bit_rev_ctr].item()
        idiff = ival - iexp
        if abs(rval - rexp) > tolerance:
            raise TestFailure(("Actual real output differs from expected."
                               " Actual: %d, expected: %d, difference: %d."
                               " Tolerance set at %d.") %
                              (rval, rexp, rval - rexp, tolerance))

        if abs(ival - iexp) > tolerance:
            raise TestFailure(("Actual imaginary output differs from expected."
                               " Actual: %d, expected: %d, difference: %d."
                               " Tolerance set at %d.") %
                              (ival, iexp, ival - iexp, tolerance))

        return (rdiff, idiff)

    @cocotb.coroutine
    async def write_inputs(self):
        """
        Send all calculated inputs to dut.
        """
        ctr = 0
        num_samples = len(self.re_inputs)
        while True:
            if ctr < num_samples:
                self.dut.data_re_i <= self.re_inputs[ctr].item()
                self.dut.data_im_i <= self.im_inputs[ctr].item()
            else:
                self.dut.data_re_i <= 0
                self.dut.data_im_i <= 0

            await RisingEdge(self.dut.clk_i)
            ctr += 1

    @cocotb.coroutine
    async def send_intermittent_resets(self):
        """
        Randomly send reset signals to FFT.
        """
        timestep = min(self.multiclock.clock_periods())
        while True:
            self.dut.rst_n <= 1
            time_on = timestep * np.random.randint(1e2, 1e4, dtype=int)
            await Timer(time_on)
            self.dut.rst_n <= 0
            time_off = timestep * np.random.randint(1e2, 1e3, dtype=int)
            await Timer(time_off)
Ejemplo n.º 6
0
def test_normalize_periods_for_simulation():
    clocks = MultiClock([Clock(None, 60, 0), Clock(None, 40, 0)])
    for clk in clocks.clocks:
        print("period: {}, phase: {}".format(clk.period, clk.phase))

    assert True
Ejemplo n.º 7
0
 def __init__(self, dut):
     rdclk = Clock(dut.rdclk, 60)
     wrclk = Clock(dut.wrclk, 40)
     self.multiclock = MultiClock([rdclk, wrclk])
     self.dut = dut
Ejemplo n.º 8
0
class AsyncFifoTB:
    """
    Async FIFO testbench class. Used to setup, drive and monitor the
    async FIFO under test.
    """
    def __init__(self, dut):
        rdclk = Clock(dut.rdclk, 60)
        wrclk = Clock(dut.wrclk, 40)
        self.multiclock = MultiClock([rdclk, wrclk])
        self.dut = dut

    @cocotb.coroutine
    async def setup(self):
        """Startup the async FIFO."""
        self.multiclock.start_all_clocks()
        await self.reset()

    @cocotb.coroutine
    async def reset(self):
        """
        Perform a sufficiently long reset to be registered by all clock
        domains.
        """
        await self.await_all_clocks()
        self.dut.rst_n <= 0
        self.dut.rden <= 0
        self.dut.wren <= 0
        await self.await_all_clocks()
        self.dut.rst_n <= 1

    @cocotb.coroutine
    async def await_all_clocks(self):
        """
        Wait for positive edge on both clocks before proceeding.
        """
        trigs = []
        for clk in self.multiclock.clocks:
            trigs.append(RisingEdge(clk.clk))

        await Combine(*trigs)

    @cocotb.coroutine
    async def write(self, val):
        """Write a value to the FIFO."""
        await RisingEdge(self.dut.wrclk)
        self.dut.wren <= 1
        self.dut.wrdata <= val
        await RisingEdge(self.dut.wrclk)

    @cocotb.coroutine
    async def read(self):
        """Read a value from the FIFO."""
        await RisingEdge(self.dut.rdclk)
        self.dut.rden <= 1
        await RisingEdge(self.dut.rdclk)
        await ReadOnly()
        rdval = self.dut.rddata.value
        return rdval

    @cocotb.coroutine
    async def wait_n_read_cycles(self, ncycles):
        """Wait ncycles cycles for rdclk."""
        await RisingEdge(self.dut.rdclk)
        self.dut.rden <= 0
        while ncycles > 0:
            ncycles -= 1
            await RisingEdge(self.dut.rdclk)

    @cocotb.coroutine
    async def wait_n_write_cycles(self, ncycles):
        """Wait ncycles cycles for wrclk."""
        await RisingEdge(self.dut.wrclk)
        self.dut.wren <= 0
        while ncycles > 0:
            ncycles -= 1
            await RisingEdge(self.dut.wrclk)

    @cocotb.coroutine
    async def get_value(self, obj):
        """
        Return the current value of some part of the FIFO. Note that this
        does not wait for a clock edge, so care should be taken that
        the read is performed at the desired time.

        obj: The value to read (e.g. dut.wraddr)
        """
        await ReadOnly()
        return obj.value
Ejemplo n.º 9
0
 def __init__(self, dut):
     clk = Clock(dut.clk, 40)
     ft_clk = Clock(dut.ft_clk, 60)
     slow_ft_clk = Clock(dut.slow_ft_clk, 7.5)
     self.multiclock = MultiClock([clk, ft_clk, slow_ft_clk])
     self.dut = dut