示例#1
0
def test_prio2(dut):
    global messages
    global cnt_plan

    ##### Test Global Parameters    
    messages = 20   
    cnt_plan = 8*messages 
    
    dut.log.setLevel(logging.INFO)
    
    #Setup Clocks
    cocotb.fork(Clock(dut.clk, clkref_period).start())
    cocotb.fork(Clock(dut.clk2, clksys_period).start())
    clkedge = RisingEdge(dut.clk)
    
    # Reset the DUT
    dut.log.debug("Resetting DUT")
    dut.reset_n     <= 0
    dut.reset_n2    <= 0
    dut.en_in       <= 0
    yield Timer(50*clksys_period)
    dut.log.debug("Out of reset")
    
    dut.reset_n     <= 1
    dut.reset_n2    <= 1
    yield Timer(50*clksys_period)
    
   #Timestamp capture routine. Save TSs to compare later against expected values    
    cocotb.fork(tscheck(dut))   
    
    #Data/Signal Generators for WB Slave
    replyWaitGen    = genw.random_data(1, 3)
    ackGen          = genw.random_data(0, 1)
    stallGen        = genb.bit_toggler(genw.random_data(0, 10), genw.random_data(1, 50))
    #Callback for WB SLave
    output = rec(dut)
    #instantiate WB Slave
    wbs  = WishboneSlave(entity=dut, name="wbm", clock=dut.clk, callback=output.receive, stallwaitgen=stallGen, replywaitgen=replyWaitGen)
    wbs.log.setLevel(logging.INFO)    
    
    #instantiate WB Master    
    wbm  = WishboneMaster(dut, "wbs", dut.clk, 500)
    wbm.log.setLevel(logging.INFO) 
    #Stimulus routine. Generate Cycles for WB Master 
    yield datagen(dut, wbm, messages)

    
    ##### TEST Evaluation ######
    
    #wait for all ops to finish
    cnt_timeout = cnt_plan*20
    while (cnt_timeout) and ((cnt_recv < cnt_plan) and (len(tsList) < len(tsExpList))):
        yield clkedge
        cnt_timeout -= 1
    
    #either timeout or all operations complete. Continue      
    yield Timer(50*clksys_period)
    print ""    
    print "%s%s" % (" "*117, "*"*40)
    print ""
    #check for timeout  
    if cnt_timeout <= 0:
        raise TestFailure("Timeout: Not all Operations made it through. Planned: %u Sent: %u Received: %u" % (cnt_plan, cnt_send, cnt_recv)) 
   
    #check if we got too many sent ops for some reason 
    if (cnt_send > cnt_plan):
        raise TestFailure("There were more replies than sent operations. Planned: %u Sent: %u Received: %u" % (cnt_plan, cnt_send, cnt_recv)) 
        
    #check if we got too replies many for some reason 
    if (cnt_recv > cnt_plan):
        raise TestFailure("There were more replies than sent operations. Planned: %u Sent: %u Received: %u" % (cnt_plan, cnt_send, cnt_recv)) 
    
    #check timestamps against expected values
    s = set(tsList)
    result = [x for x in tsExpList if x not in s]
    if len(result):
        raise TestFailure("Expected Timestamps missing from actual result: %s\n Expected: %s\n Got:      %s" % (result, tsExpList, tsList))                        
        
    #all okay, test passed
    print ("Expected Timestamps missing from actual result: %s\n Expected: %s\n Got:      %s" % (result, tsExpList, tsList))                        
        
    raise TestSuccess("All operations processed, all expected timestamps present.\nPlanned: %u Sent: %u Received: %u\nMessages: %u Timestamps: %u" % (cnt_plan, cnt_send, cnt_recv, output.cntcyc-1, messages - len(result)))
    print "*"*80

  #  L = []
   # thread.start_new_thread(input_thread, (L,))
  #  print "Press Any key to close"
  #  while True:
  #     if L: 
  #        print L
  #        break
  #     yield RisingEdge(dut.clk2)

    print "DONE *****"
示例#2
0
async def fir_filter_test(dut):
    """
    Load test data from files and send them through the DUT.
    Compare input and output afterwards.
    """
    EnablePlots = True

    timestamp_start = time.time()

    # --------------------------------------------------------------------------
    # Constants
    # --------------------------------------------------------------------------

    # Number of seconds to process
    n_sec = 0.001

    # Derived constants
    num_samples = int(n_sec * fm_global.fs_rx_c)

    # --------------------------------------------------------------------------
    # Load data from files
    # --------------------------------------------------------------------------
    filename = "../../../../../../sim/matlab/verification_data/rx_fm_channel_data.txt"
    data_i = []
    with open(filename) as fd:
        val_count = 0
        for line in fd:
            data_i.append(float(line.strip('\n')))
            val_count += 1
            # Stop after required number of samples
            if val_count >= num_samples:
                break

    # Convert to fixed point and back to int
    data_i_fp = to_fixed_point(data_i, fm_global.fp_width_c,
                               fm_global.fp_width_frac_c)
    data_i_int = fixed_to_int(data_i_fp)

    filename = "../../../../../../sim/matlab/verification_data/rx_pilot.txt"
    gold_data_o = []
    with open(filename) as fd:
        val_count = 0
        for line in fd:
            gold_data_o.append(float(line.strip('\n')))
            val_count += 1
            # Stop after required number of samples
            if val_count >= num_samples:
                break

    # Convert to fixed point
    gold_data_o_fp = to_fixed_point(gold_data_o, fm_global.fp_width_c,
                                    fm_global.fp_width_frac_c)

    # --------------------------------------------------------------------------
    # Prepare environment
    # --------------------------------------------------------------------------
    tb = FM_TB(dut, num_samples)

    # Generate clock
    clk_period_ns = round(1 / tb.CLOCK_FREQ_MHZ * 1e3)
    clk = Clock(dut.iClk, period=clk_period_ns, units='ns')
    clk_gen = cocotb.fork(clk.start())

    # Generate FIR input strobe
    strobe_num_cycles_high = 1
    strobe_num_cycles_low = tb.CLOCK_FREQ_MHZ * 1e6 // fm_global.fs_rx_c - strobe_num_cycles_high
    tb.fir_in_strobe.start(
        bit_toggler(repeat(strobe_num_cycles_high),
                    repeat(strobe_num_cycles_low)))

    N_FIR = 73  # see filter_bp_pilot_coeffs_c in DUT (DspFir)
    assert strobe_num_cycles_low >= N_FIR, \
        "The FIR filter takes N_FIR clock cycles to produce a result! Use a lower sampling frequency!!"

    print("strobe_num_cycles_high : %d" % strobe_num_cycles_high)
    print("strobe_num_cycles_low  : %d" % strobe_num_cycles_low)

    # --------------------------------------------------------------------------
    # Run test on DUT
    # --------------------------------------------------------------------------

    # Reset the DUT before any tests begin
    await tb.assign_defaults()
    await tb.reset()

    # Fork the 'receiving part'
    fir_out_fork = cocotb.fork(
        tb.read_fir_result(fm_global.pilot_output_scale_c, num_samples))

    # Send input data through filter
    dut._log.info("Sending input data through filter ...")

    for i, sample in enumerate(data_i_int):
        await RisingEdge(dut.iValDry)
        dut.iDdry <= int(sample)

    await RisingEdge(dut.iValDry)

    # Await forked routines to stop
    await fir_out_fork

    # Measure time
    timestamp_end = time.time()
    dut._log.info("Execution took {:.2f} seconds.".format(timestamp_end -
                                                          timestamp_start))

    num_received = len(tb.data_out)
    num_expected = len(gold_data_o_fp)

    # --------------------------------------------------------------------------
    # Plots
    # --------------------------------------------------------------------------
    if EnablePlots:
        dut._log.info("Plots ...")

        fig = plt.figure()
        plt.plot(np.arange(0, num_expected) / fm_global.fs_rx_c,
                 from_fixed_point(gold_data_o_fp),
                 "b",
                 label="gold_data_o_fp")
        plt.plot(np.arange(0, num_received) / fm_global.fs_rx_c,
                 tb.data_out,
                 "r",
                 label="data_out")
        plt.title("Pilot")
        plt.grid(True)
        plt.legend()
        fig.tight_layout()
        plt.xlim([0, num_samples / fm_global.fs_rx_c])
        plt.show()

    # --------------------------------------------------------------------------
    # Compare results
    # --------------------------------------------------------------------------

    # Sanity check
    if num_received < num_expected:
        raise cocotb.result.TestError(
            "Did not capture enough output values: {} actual, {} expected.".
            format(num_received, num_expected))

    # Skip first N samples
    skip_N = 10
    dut._log.info(f"Skipping first N={skip_N} samples.")
    gold_data_o_fp = gold_data_o_fp[skip_N:]
    tb.data_out = tb.data_out[skip_N:]

    max_diff = 2**-5
    for i, res in enumerate(tb.data_out):
        diff = gold_data_o_fp[i] - res
        if abs(from_fixed_point(diff)) > max_diff:
            msg = "FIR output [{}] is not matching the expected values: {}>{}.".format(
                i, abs(from_fixed_point(diff)), max_diff)
            raise cocotb.result.TestError(msg)
            # dut._log.info(msg)

    norm_res = np.linalg.norm(
        np.array(from_fixed_point(gold_data_o_fp[0:num_received])) -
        np.array(tb.data_out), 2)
    dut._log.info("2-Norm = {}".format(norm_res))

    dut._log.info("Done.")
示例#3
0
def test_wb_looback(dut):
    clkref_period = 8
    clksys_period = 16
    
#    """Example of a test using TUN/TAP over WB."""
    cocotb.fork(Clock(dut.clk, clkref_period).start())
    cocotb.fork(Clock(dut.clk2, clksys_period).start())
    
    
    
    
    # Reset the DUT
    dut.log.debug("Resetting DUT")
    dut.reset_n <= 0
    dut.reset_n2 <= 0
    
   
    yield Timer(50*clksys_period)
 
    dut.log.debug("Out of reset")
    dut.log.setLevel(logging.INFO)
    

    tsGen           = genw.random_data(0, 1000, 64)
    idleGenWord     = genw.random_data(0, 5)
    replyWaitGen     = genw.random_data(1, 10)
    idleGenBlock    = genw.random_data(0, 50)
    stallGen        = genb.bit_toggler(genw.random_data(1, 10), genw.random_data(1, 10))
    cntGenX1000     = genw.incrementing_data(0x1000)
    cntGen          = genw.incrementing_data(1)
    stdExp          = WBR(True, None, 6, 5, 5)    
    datGen          = genw.incrementing_data(1)
    errGen          = genb.bit_toggler(genw.random_data(0, 1), genw.random_data(1, 10))
    adrGen          = genw.random_data(0, 50)
    datwrGen        = genw.random_data()
    wordRepeatGen   = genw.random_data(1, 50)
    weGen           = genw.random_data(0, 1)
    
    output = rec(dut)
    
    wbm  = WishboneMaster(dut, "wbm", dut.clk)
    wbm.log.setLevel(logging.INFO)
    
    wbs  = WishboneSlave(entity=dut, name="wbmo", clock=dut.clk, callback=output.receive, errgen=None, datgen=datGen, stallwaitgen=stallGen, replywaitgen=replyWaitGen)
    wbs.log.setLevel(logging.INFO)    
    
    oplist = []
    explist = []
    reslist = []  
    
    #oplist.append([WBO(0x0, 0xDEADBEEF, 123)])    
    
#    for i in range(1, 3):
#        tmpOplist = []
#        tmpExplist = []
#        ts = tsGen.next()
#
#        tmpOplist.append(WBO(0x0, ts >> 32,          idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        tmpOplist.append(WBO(0x0, ts & 0xffffffff,   idleGenWord.next()))
#        tmpOplist.append(WBO(0x0, None,   idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        n = cntGenX1000.next()
#        tmpOplist.append(WBO(0x0, n + cntGen.next(), idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        tmpOplist.append(WBO(0x0, n + cntGen.next(), idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        tmpOplist.append(WBO(0x0, n + cntGen.next(), idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        tmpOplist.append(WBO(0x0, n + cntGen.next(), idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        tmpOplist.append(WBO(0x0, n + cntGen.next(), idleGenWord.next()))
#        tmpExplist.append(stdExp)
#        tmpOplist.append(WBO(0x0, None, idleGenBlock.next()))
#        
#        tmpExplist.append(stdExp)
#        oplist += [tmpOplist]
#        explist.append(tmpExplist)
   
    
    for i in range(0, 10):
        tmpOplist = []
        words = wordRepeatGen.next()        
        for i in range(0, words):        
            dat = None        
            if weGen.next():
                dat = datwrGen.next()
            tmpOplist.append(WBO(adrGen.next()*4, dat, idleGenWord.next()))
        oplist += [tmpOplist]    
    
    for cycle in oplist:
        tmp = yield wbm.send_cycle(cycle)
        reslist.append(tmp)     
    
    
    dut.log.info("***** Master - Received Replies:")
    cyccnt = 0    
    
    for cycle in reslist:
        dut.log.info("WBM Cycle #%3u, %3u Ops" % (cyccnt,len(cycle)))
        cyccnt += 1
        cnt = 0
        for res in cycle:
            dat = "      None"
            if res.dat is not None:
                dat = "0x%08x" % res.dat

            ackerr = "ERR"                
            if res.ack:
                ackerr = "ACK"
                
            dut.log.debug("#%3u ACK/ERR: %s RD: %s IDLW: %3u STLW: %3u ACKW: %3u" % (cnt, ackerr, dat, res.waitidle, res.waitstall, res.waitack))
            cnt += 1
#    yield RisingEdge(dut.clk)
  
    #cocotb.fork(lifesign(dut, 5000000))    

  #  L = []
   # thread.start_new_thread(input_thread, (L,))
  #  print "Press Any key to close"
  #  while True:
  #     if L: 
  #        print L
  #        break
  #     yield RisingEdge(dut.clk2)

    print "DONE *****"
示例#4
0
async def axi_stream_dsp_test(dut):
    """
    Load test data from files and send them through the DUT.
    Compare input and output afterwards.
    """

    # --------------------------------------------------------------------------
    # Constants
    # --------------------------------------------------------------------------

    # Number of seconds to process
    n_sec = 0.0025

    # --------------------------------------------------------------------------
    # Prepare environment
    # --------------------------------------------------------------------------
    timestamp_start = time.time()

    tb = FM_TB(dut, n_sec)

    # Generate clock
    clk_period_ns = round(1 / tb.CLOCK_FREQ_MHZ * 1e3)
    clk = Clock(dut.clk_i, period=clk_period_ns, units='ns')
    clk_gen = cocotb.fork(clk.start())

    # --------------------------------------------------------------------------
    # Load data from files
    # --------------------------------------------------------------------------
    dut._log.info("Loading input data ...")

    filename = "../../../../../sim/matlab/verification_data/rx_fm_bb.txt"
    data_fp = helper.loadDataFromFile(filename, tb.model.num_samples_fs_c * 2,
                                      fm_global.fp_width_c, fm_global.fp_width_frac_c)

    # Get interleaved I/Q samples (take every other)
    data_in_i_fp = data_fp[0::2]  # start:end:step
    data_in_q_fp = data_fp[1::2]  # start:end:step

    # Combine IQ samples
    data_in_iq = []
    for i in range(0, len(data_in_i_fp)):
        in_i = int(fixed_to_int(data_in_i_fp[i]))
        in_q = int(fixed_to_int(data_in_q_fp[i]))
        value = (in_q << 16) + in_i
        data_in_iq.append(value)

    # --------------------------------------------------------------------------
    # Run test on DUT
    # --------------------------------------------------------------------------

    # Reset the DUT before any tests begin
    await tb.assign_defaults()
    await tb.reset()

    # Generate backpressure signal (AXI stream tready) for IPs' stream output
    # NOTE:
    #  This is not generating the actual ~40 kHz output frequency (as defined by fm_global.fs_audio_c).
    #  It generates a much faster output, to speed up the testbench (see "output_speedup_factor").
    # NOTE:
    #  This speedup factor needs to be chosen carefully. The IP needs to complete the calculation for one sample,
    #  before the next sample can be taken from the input. Therefore, set the factor small, to ensure enough
    #  low-cycles, to allow the IP to complete one entire calculation.
    output_speedup_factor = 120
    strobe_num_cycles_high = 1
    strobe_num_cycles_low = tb.CLOCK_FREQ_MHZ * 1e6 // fm_global.fs_audio_c // output_speedup_factor - strobe_num_cycles_high
    ratio = strobe_num_cycles_low // strobe_num_cycles_high
    tb.backpressure_i2s.start(bit_toggler(repeat(strobe_num_cycles_high), repeat(strobe_num_cycles_low)))
    assert ratio >= 9, f"output_speedup_factor is set too high ({ratio}<9)! --> IP won't have enough time to calculate a sample, before the next one arrives"

    # Fork the 'receiving parts'
    fm_demod_output_fork = cocotb.fork(tb.read_fm_demod_output())
    fm_channel_data_output_fork = cocotb.fork(tb.read_fm_channel_data_output())
    audio_mono_output_fork = cocotb.fork(tb.read_audio_mono_output())
    pilot_output_fork = cocotb.fork(tb.read_pilot_output())
    carrier_38k_output_fork = cocotb.fork(tb.read_carrier_38k_output())
    audio_lrdiff_output_fork = cocotb.fork(tb.read_audio_lrdiff_output())
    audio_L_output_fork = cocotb.fork(tb.read_audio_L_output())
    audio_R_output_fork = cocotb.fork(tb.read_audio_R_output())
    audio_output_fork = cocotb.fork(tb.read_audio_output())

    # Send input data to IP
    dut._log.info("Sending IQ samples to FM Receiver IP ...")

    for i, value in enumerate(data_in_iq):
        await tb.axis_m.write(value)

    dut._log.info("Waiting to receive enough samples ...")
    # Await forked routines to stop.
    # They stop, when the expected number of samples were read.
    await fm_demod_output_fork
    await fm_channel_data_output_fork
    await audio_mono_output_fork
    await pilot_output_fork
    await carrier_38k_output_fork
    await audio_lrdiff_output_fork
    await audio_L_output_fork
    await audio_R_output_fork
    await audio_output_fork

    # Measure time
    duration_s = int(time.time() - timestamp_start)
    mins, secs = divmod(duration_s, 60)
    dut._log.info("Execution took {:02d}:{:02d} minutes.".format(mins, secs))

    # --------------------------------------------------------------------------
    # Compare results
    # --------------------------------------------------------------------------
    dut._log.info("Comparing data ...")
    tb.compareData()

    # --------------------------------------------------------------------------
    # Write data to file
    # --------------------------------------------------------------------------
    dut._log.info("Writing data to file ...")
    tb.writeDataToFile()

    # --------------------------------------------------------------------------
    # Plots
    # --------------------------------------------------------------------------
    # NOTE: Only showing plots, if results are NOT okay.
    dut._log.info("Plots ...")
    tb.generatePlots()

    dut._log.info("Done.")