Example #1
0
def test_ffe(dut):

    cocotb.fork(Clock(dut.clk, 1, units='ns').start())
    yield reset(dut)

    dut.en <= 1

    yield Timer(10, units='ns')

    fir_output = np.zeros(100, dtype=int)

    fir_input_prbs = np.random.choice([128, 1920], (100))
    fir_input_pulse = np.concatenate((np.ones(50) * 128, np.ones(50) * -128))
    for i, val in enumerate(fir_input_prbs.astype('int')):
        dut.din <= val
        yield RisingEdge(dut.clk)
        fir_output[i] = dut.dout.value.signed_integer

    # test read_values
    yield Timer(10, units='ns')

    plt.figure()
    plt.plot(np.where(fir_input_prbs == 128, 128, -128))
    plt.plot(fir_output)
    plt.show(block=True)
    #_ = input('Presione enter para terminar')
    plt.close()
Example #2
0
def test_counter(dut):

    cocotb.fork(Clock(dut.clockdsp, 1, units='ns').start())
    yield reset(dut)

    dut.log_in_ram_run_from_micro <= 1
    yield RisingEdge(dut.log_out_full_from_ram)
    dut.log_in_ram_run_from_micro <= 0

    yield Timer(10, units='ns')

    read_values = []

    for address in range(2**15):
        dut.log_read_addr_from_micro <= address
        yield RisingEdge(dut.clockdsp)
        read_values.append(dut.log_read_addr_from_micro.value.integer)

    # test read_values
    yield Timer(10, units='ns')

    values = list(range(2**15))

    if values != read_values:
        print(read_values)
        raise TestFailure("Los valores no coinciden")
Example #3
0
 def async_rst(self):
     """ This function execute the reset_n for 40ns
     it also set all input signals to default value
     """
     self.dut._log.info("begin Rst")
     for n, t in self.dut._sub_handles.items():
         if isinstance(t, handle.ModifiableObject):
             t.value = 0
     yield Timer(40, 'ns')
     self.dut.reset_n <= 1
     yield Timer(15, 'ns')
     self.dut._log.info("end Rst")
Example #4
0
def test_cordic(dut):
    cocotb.fork(Clock(dut.clk, 1, units='ns').start())
    yield reset(dut)

    for i in range(16):
        dut.en_i <= 1
        dut.data <= i
        yield Timer(12, units='ns')
        dut.en_i <= 0
        yield Timer(1, units='ns')

    yield RisingEdge(dut.clk)
    for _ in range(10):
        yield RisingEdge(dut.clk)
Example #5
0
def test_cordic(dut):
    cocotb.fork(Clock(dut.clk, 1, units='ns').start())
    yield reset(dut)
    #     yield Timer(12, units='ns')

    for i in range(len(xValues)):
        dut.en_i <= 1
        dut.x_i <= xValues[i]
        dut.y_i <= yValues[i]
        yield Timer(1, units='ns')
        dut.en_i <= 0
        yield Timer(13, units='ns')

    yield RisingEdge(dut.clk)
    for _ in range(10):
        yield RisingEdge(dut.clk)
Example #6
0
def reset(dut):
    dut.run <= 0
    dut.rst <= 1
    yield Timer(15, units='ns')
    yield RisingEdge(dut.clk)
    dut.rst <= 0
    yield RisingEdge(dut.clk)
    dut.rst._log.info("Reset complete")
Example #7
0
def reset(dut):
    dut.start <= 0
    dut.din <= 0
    dut.rst <= 1
    yield Timer(1500)
    yield RisingEdge(dut.clk)
    dut.rst <= 0
    yield RisingEdge(dut.clk)
    dut.rst._log.info("Reset complete")
Example #8
0
def test_cordic(dut):
    cocotb.fork(Clock(dut.clk, 1, units='ns').start())
    yield reset(dut)
    dut.en_i <= 1
    yield Timer(99, units='ns')
    yield RisingEdge(dut.clk)
    dut.en_i <= 0
    dut.rst <= 1
    for _ in range(10):
        yield RisingEdge(dut.clk)
Example #9
0
def test_counter(dut):

    cocotb.fork(Clock(dut.clk, 1, units='ns').start())
    yield reset(dut)

    dut.run <= 1
    yield Timer(99, units='ns')
    yield RisingEdge(dut.clk)
    dut.run <= 0
    for _ in range(10):
        yield RisingEdge(dut.clk)
Example #10
0
def reset(dut):
    dut.en_i <= 0
    dut.rst <= 1
    dut.x_i <= 0
    dut.y_i <= 1000
    dut.z_i <= 0
    yield Timer(15, units='ns')
    yield RisingEdge(dut.clk)
    dut.rst <= 0
    yield RisingEdge(dut.clk)
    dut.rst._log.info("Reset complete")
Example #11
0
def reset(dut):
    dut.soft_reset <= 1
    dut.step_mu <= 0
    dut.connect_ch_to_dsp <= 0
    dut.rf_enables_module <= 0
    dut.log_in_ram_run_from_micro <= 0
    dut.log_read_addr_from_micro <= 0

    yield Timer(15, units='ns')
    yield RisingEdge(dut.clockdsp)
    dut.soft_reset <= 0
    yield RisingEdge(dut.clockdsp)
    dut.soft_reset._log.info("Reset complete")
Example #12
0
def reset(dut):
    dut.rst <= 1
    dut.en <= 0
    dut.din <= 0

    dut.coef0 <= 0
    dut.coef1 <= 0
    dut.coef2 <= 0
    dut.coef3 <= 128
    dut.coef4 <= 0
    dut.coef5 <= 0
    dut.coef6 <= 0

    yield Timer(15, units='ns')
    yield RisingEdge(dut.clk)
    dut.rst <= 0
    yield RisingEdge(dut.clk)
    dut.rst._log.info("Reset complete")
Example #13
0
def test_dsp(dut):

    cocotb.fork(Clock(dut.clockdsp, 1, units='ns').start())
    yield reset(dut)

    yield Timer(10, units='ns')
    dut.step_mu <= 4  # 0,1,4,16

    N = 1000
    dut.rf_enables_module <= 1
    fir_output = np.zeros(N, dtype=int)
    err_output = np.zeros(N, dtype=int)
    coefs_out = np.zeros((N, 7), dtype=int)

    fir_input_prbs = np.convolve(np.random.choice([128, -128], (N)),
                                 channel[ch_sel],
                                 mode='same')
    fir_input_pulse = np.concatenate((np.ones(50) * 128, np.ones(50) * -128))
    for i, val in enumerate(fir_input_prbs.astype('int')):
        dut.connect_ch_to_dsp <= val
        yield RisingEdge(dut.clockdsp)
        fir_output[i] = dut.ffe_inst.o_data.value.signed_integer
        err_output[i] = dut.error.value.signed_integer
        for k in range(7):
            coefs_out[i, k] = dut.ffe_inst.coefs[k].value.signed_integer

    # test read_values
    yield Timer(10, units='ns')

    plt.figure()
    plt.plot(np.where(fir_input_prbs == 128, 128, -128))
    plt.plot(fir_output)
    plt.figure()
    plt.plot(err_output)

    plt.figure()
    plt.subplot(2, 1, 1)
    plt.stem(fir_output[0:200])
    plt.grid()
    plt.ylim((np.min(fir_output) - 0.5, np.max(fir_output) + 0.5))
    plt.ylabel('Amplitude')
    plt.xlabel('Samples')
    plt.title('FFE Output and Error - HW')
    plt.subplot(2, 1, 2)
    plt.plot(err_output)
    plt.grid()
    plt.ylim((np.min(err_output) - 0.5, np.max(err_output) + 0.5))
    plt.ylabel('Amplitude')
    plt.xlabel('Samples')

    plt.figure()
    plt.subplot(3, 1, 1)
    plt.plot(coefs_out)
    plt.grid()
    plt.ylim((min(coefs_out[len(coefs_out) - 1]) - 12,
              max(coefs_out[len(coefs_out) - 1]) + 12))
    plt.ylabel('Amplitude')
    plt.title('Taps of FFE')
    plt.subplot(3, 1, 2)
    plt.stem(coefs_out[len(coefs_out) - 1])
    plt.grid()
    plt.ylim((min(coefs_out[len(coefs_out) - 1]) - 0.5,
              max(coefs_out[len(coefs_out) - 1]) + 0.5))
    plt.ylabel('Amplitude')
    plt.subplot(3, 1, 3)
    plt.stem(np.convolve(channel[ch_sel], coefs_out[len(coefs_out) - 1]))
    plt.grid()
    plt.ylim((min(coefs_out[len(coefs_out) - 1]) - 0.5,
              max(coefs_out[len(coefs_out) - 1]) + 0.5))
    plt.ylabel('Conv.Ch.Taps')
    plt.xlabel('Samples')

    plt.show(block=True)

    plt.close()
Example #14
0
def test_tree(dut):
    """Testing APBI2C core"""

    log = cocotb.logging.getLogger("cocotb.test")
    cocotb.fork(Clock(dut.PCLK, 1000).start())

    #instantiate the APB agent (monitor and driver) (see apb.py)
    apb = APBSlave(dut, name=None, clock=dut.PCLK)

    #instantiate the I2C monitor and driver (see i2c.py)
    i2c_monitor = I2CMonitor(dut, name="", clock=dut.PCLK)
    i2c_driver = I2CDriver(dut, name=None, clock=dut.PCLK)

    #write to config register via APB
    @cocotb.coroutine
    def config_write(addr, data):
        xaction = APBTransaction(addr, data, write=True)
        xaction.randomize()
        yield apb.send(xaction)

    #store observed I2C transactions
    received_i2c_xactions = []

    #the catcher for observerd I2C transaction on the interfece
    @I2CCoverage
    def i2c_xaction_catcher(i2c_xaction):
        if LOG_XACTION_ENABLE:
            log.info("I2C Monitor: Transaction 0x%08X" % i2c_xaction.data)
        received_i2c_xactions.append(i2c_xaction)

    #callback to the monitor to call the catcher when I2C transaction observed
    i2c_monitor.add_callback(i2c_xaction_catcher)

    #the catcher for observerd APB transaction on the interfece
    @APBCoverage
    def apb_xaction_catcher(apb_xaction):
        if LOG_XACTION_ENABLE:
            try:
                log.info("APB Transaction %s 0x%08X -> 0x%08X" %
                         ("Write" if apb_xaction.write else "Read ",
                          int(apb_xaction.addr), int(apb_xaction.data)))
            except:
                log.info("APB Transaction %s 0x%08X -> 0x%08s" %
                         ("Write" if apb_xaction.write else "Read ",
                          int(apb_xaction.addr), int(apb_xaction.data)))

    #callback to the monitor to call the catcher when APB transaction observed
    apb.add_callback(apb_xaction_catcher)

    #define "I2C Operation" as a bunch of r/ws with defined number of data
    #and a specific clock divider
    #this is the main stuff to be tested - we want to know if controller
    #correctly processes transfers with different directions, amount of
    #data and SCK period
    class I2C_Operation(Randomized):
        def __init__(self, direction='write', repeat=1, divider=1):
            Randomized.__init__(self)
            self.direction = direction
            self.repeat = repeat
            self.divider = divider
            self.repeat_range = (1, 3)
            self.divider_range = (1, 3)

            #I2C_Operation objects may be fully randomized
            self.addRand("direction", ["write", "read"])
            self.addRand("repeat_range", [(1, 3), (4, 7), (8, 11), (12, 15),
                                          (16, 23), (24, 31)])
            self.addRand("divider_range", [(1, 3), (4, 7), (8, 11), (12, 15),
                                           (16, 23), (24, 31)])

        #post_randomize to pick random values from already randomized ranges
        def post_randomize(self):
            self.repeat = random.randint(self.repeat_range[0],
                                         self.repeat_range[1])
            self.divider = random.randint(self.divider_range[0],
                                          self.divider_range[1])

    #list of completed operations for the summary
    operations_completed = []

    #function sampling operations order coverage (see coverage.py)
    @OperationsOrderCoverage
    def sample_operations_order_coverage(prev_operation, operation):
        pass

    #function sampling operations coverage (see coverage.py)
    @OperationsCoverage
    def sample_operation(operation, ok):
        operations_completed.append((operation, ok))
        if (len(operations_completed) > 1):
            sample_operations_order_coverage(operations_completed[-2][0],
                                             operations_completed[-1][0])
        if ok:
            log.info(
                "Operation %s of %d words, divider %d - OK!" %
                (operation.direction, operation.repeat, operation.divider))
        else:
            log.error(
                "Operation %s of %d words, divider %d - error!" %
                (operation.direction, operation.repeat, operation.divider))

    #a test sequence - complete I2C Write Operation
    @cocotb.coroutine
    def segment_i2c_write_operation(operation):
        expected_out = []
        yield config_write(8, 0x0001 | (operation.divider << 2))

        #create xaction objects and fill FIFO up via APB with data to be send
        apb_xaction = APBTransaction(0, 0, write=True)
        for i in range(operation.repeat):
            i2c_xaction = I2CTransaction(0, write=False)
            i2c_xaction.randomize()
            apb_xaction.data = i2c_xaction.data
            apb_xaction.randomize()
            yield apb.send(apb_xaction)
            expected_out.append(i2c_xaction)

        #wait for FIFO empty - meaning all data sent out
        guard_int = 0
        while not dut.INT_TX.value:
            guard_int = guard_int + 1
            yield RisingEdge(dut.PCLK)
            if guard_int == 50000:
                raise TestFailure("Controller hang-up!")

        #a simple scoreboarding...
        #compare data written to APB with catched on I2C interface
        ok = True
        received_xactions = received_i2c_xactions[-operation.repeat:]
        if len(received_xactions) < operation.repeat:
            ok = False
        else:
            for i in range(operation.repeat):
                if (received_xactions[i] != expected_out[i]):
                    ok = False
                    break

        #call sampling at the and of the sequence
        sample_operation(operation, ok)

    #a test sequence - complete I2C Read Operation
    @cocotb.coroutine
    def segment_i2c_read_operation(operation):
        expected_in = []
        yield config_write(8, 0x0002 | (operation.divider << 2))

        #create I2C xaction objects and send on the interface
        for i in range(operation.repeat):
            i2c_xaction = I2CTransaction(0, write=True)
            i2c_xaction.randomize()
            expected_in.append(i2c_xaction)
            yield i2c_driver.send(i2c_xaction)

        #a simple scoreboarding...
        #compare data written on I2C interface with read from FIFO
        ok = True
        apb_xaction = APBTransaction(0x04, 0, write=False)
        for i in range(operation.repeat):
            try:
                apb_xaction.randomize()
                rdata = yield apb.send(xaction)
                if (rdata != expected_in[i].data):
                    ok = False
            except:
                if LOG_XACTION_ENABLE:
                    log.error("APB read data from FIFO is 'X'")
                ok = False

        #call sampling at the and of the sequence
        sample_operation(operation, ok)

    #a test sequence - APB registers operation (sort of UVM_REG :) )
    @cocotb.coroutine
    def segment_apb_rw(repeat=1, addr=0xC):

        apb_xaction_wr = APBTransaction(addr, 0, write=True)
        apb_xaction_rd = APBTransaction(addr, 0, write=False)

        #just do some APB/RW
        for i in range(repeat):
            data = random.randint(0, 0xFFFFFFFF)
            apb_xaction_wr.randomize()
            apb_xaction_wr.data = data
            yield apb.send(apb_xaction_wr)
            apb_xaction_rd.randomize()
            rdata = yield apb.send(apb_xaction_rd)
            if LOG_XACTION_ENABLE:
                try:
                    if rdata != data:
                        log.error(
                            "APB read data @ 0x%08X does not match written value"
                            % addr)
                except:
                    log.error("APB read data @ 0x%08X is 'X'" % addr)

    #reset the DUT
    dut.PRESETn <= 0
    yield Timer(2000)
    dut.PRESETn <= 1

    yield config_write(12, 0x0100)

    #if checkpoints used, store them in the map, (see checkpoint.py)
    if ENABLE_CHECKPOINTS:
        checkpoints = {}
        get_checkpoint_hier(dut)
        #the fist checkpoint is just after reset
        checkpoints['init'] = (checkpoint(), None)

    #list of already covered operations, used to constraint the randomization
    already_covered = []

    #constraint for the operation randomization - do not use already
    #covered combinations
    def op_constraint(direction, divider_range, repeat_range):
        return not (direction, repeat_range, divider_range) in already_covered

    apb_cover_item = coverage_db["top.apb.writeXdelay"]
    top_cover_item = coverage_db["top"]

    #we define test end condition as reaching 99% coverage at the
    #top cover item
    cov_op = 0
    while cov_op < 90:

        #restore randomly selected checkpoint
        if ENABLE_CHECKPOINTS:
            if CHECKPOINTS_TREE_STRUCTURE:
                chkp_to_restore = random.choice(list(checkpoints.keys()))
            else:
                chkp_to_restore = 'init'

            log.info("Restoring a simulation checkpoint: " + chkp_to_restore)
            current_chceckpoint = checkpoints[chkp_to_restore]
            restore(current_chceckpoint[0])

        #create I2C operation object to be executed
        i2c_op = I2C_Operation()
        #if there is no tree structure, knowledge about already covered
        #cases cannot be used
        if ENABLE_CHECKPOINTS & CHECKPOINTS_TREE_STRUCTURE:
            try:
                i2c_op.randomize_with(op_constraint)
            except:
                i2c_op.randomize()
        else:
            i2c_op.randomize()
        already_covered.append(
            (i2c_op.direction, i2c_op.repeat_range, i2c_op.divider_range))

        #call test sequence
        if i2c_op.direction == "read":
            yield segment_i2c_read_operation(i2c_op)
        else:
            yield segment_i2c_write_operation(i2c_op)

        if ENABLE_CHECKPOINTS:
            #if status is OK, add this simulation point to the checkpoints list
            if operations_completed[-1][1]:
                chkp_name = str(get_sim_time('ns'))
                log.info("Creating a simulation checkpoint: " + chkp_name)
                checkpoints[chkp_name] = (checkpoint(), i2c_op)

        #call APB test sequence as long as cover item apb.writeXdelay
        #coverage level is below 100%
        if apb_cover_item.coverage * 100 / apb_cover_item.size < 100:
            yield segment_apb_rw(repeat=random.randint(1, 5))

        #update the coverage level

        cov_op_prev = cov_op
        cov_op = top_cover_item.coverage * 100.0 / top_cover_item.size
        log.info("Current overall coverage level = %f %%", cov_op)

    #print summary
    log.info("Opertions finished succesfully:")
    for elem in operations_completed:
        if elem[1]:
            log.info("   %s of %d words with divider %d" %
                     (elem[0].direction, elem[0].repeat, elem[0].divider))

    log.info("Opertions finished with error:")
    for elem in operations_completed:
        if not elem[1]:
            log.info("   %s of %d words with divider %d" %
                     (elem[0].direction, elem[0].repeat, elem[0].divider))

    log.info("Functional coverage details:")
    reportCoverage(log.info, bins=False)