def bench():
    """ Unit test for digital_decimator. """
    
    clock = Signal(bool(False))
    reset = Signal(bool(False))
    clkDataOut = Signal(bool(False))
    dataIn = Signal(intbv(0)[16:])
    dataOut = Signal(intbv(0)[16:])
    decimationRatioBase = Signal(intbv(0, min = 0, max = 11))
    
    dut_digital_decimator = digital_decimator(clock, reset, dataIn, dataOut, decimationRatioBase, clkDataOut)
    
    @always(delay(PERIOD//2))
    def clkgen():
        clock.next = not clock

    @instance
    def stimulus():
        reset.next = True
        decimationRatioBase.next = 0
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 1
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 2
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 3
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 4
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 5
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 6
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 7
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        
        reset.next = True
        decimationRatioBase.next = 8
        yield delay(100)
        reset.next = False
        for i in range(0, 10000):
            dataIn.next = random.randint(0, (2**16-1))
            #dataIn.next = 10
            yield clock.negedge
        dataIn.next = 0
        
        raise StopSimulation

    return dut_digital_decimator, clkgen, stimulus
def top(reset, clock, clockFtdi, adc1data, adc2data, adc1pd, adc2pd, adc1relatt, adc2relatt, 
        adc1relco, adc2relco, led0, led1, logicAnalyzer, la1dir, la2dir, la1oe, la2oe,
        serialOut, load, ldac, clkDacOut, sda, scl, rxf, oe, txe, rd, wr, siwu, adbus):
    
    decimatorNewValueFlag = Signal(bool(False))
    ft245din = Signal(intbv(0)[8:])
    ft245din.driven = 'reg'
    ft245dout = Signal(intbv(0)[8:])
    ft245dout.driven = 'reg'
    ft245rw = Signal(bool(False))
    ft245rw.driven = 'reg'
    ft245reset = Signal(bool(False))
    ft245reset.driven = 'wire'
    ft245busy = Signal(bool(False))
    ft245busy.driven = 'wire'
    ft245dataWaitIn = Signal(bool(False))
    ft245dataWaitIn.driven = 'wire'
    ft245dataWaitOut = Signal(bool(False))
    ft245dataWaitOut.driven = 'wire'
    ft245strobe = Signal(bool(False))
    ft245strobe.driven = 'wire'
    dacReset = Signal(bool(False))
    dacReset.driven = 'wire'
    dacBusy = Signal(bool(False))
    dacBusy.driven = 'wire'
    dacStrobe = Signal(bool(False))
    dacStrobe.driven = 'wire'
    dacVrefTopA = Signal(intbv(0)[8:])
    dacVrefTopA.driven = 'reg'
    dacVrefTopB = Signal(intbv(0)[8:])
    dacVrefTopB.driven = 'reg'
    dacVrefBotA = Signal(intbv(0)[8:])
    dacVrefBotA.driven = 'reg'
    dacVrefBotB = Signal(intbv(0)[8:])
    dacVrefBotB.driven = 'reg'
    digipotValue = Signal(intbv(0)[7:])
    digipotValue.driven = 'reg'
    digipotReset = Signal(bool(False))
    digipotReset.driven = 'wire'
    digipotBusy = Signal(bool(False))
    digipotBusy.driven = 'wire'
    digipotStrobe = Signal(bool(False))
    digipotStrobe.driven = 'wire'
    bufferclock = Signal(bool(False))
    bufferclock.driven = 'wire'
    bufferReset = Signal(bool(False))
    bufferReset.driven = 'wire'
    bufferDataIn = Signal(intbv(0)[32:])
    bufferDataIn.driven = 'reg'
    bufferDataOut = Signal(intbv(0)[32:])
    bufferDataOut.driven = 'reg'
    bufferReady = Signal(bool(False))
    bufferReady.driven = 'wire'
    bufferOutputInputReady = Signal(bool(False))
    bufferOutputInputReady.driven = 'wire'
    bufferAllowWriteOverlap = Signal(bool(False))
    bufferAllowWriteOverlap.driven = 'wire'
    bufferUseSdram = Signal(bool(False))
    bufferUseSdram.driven = 'wire'
    bufferDataDirection = Signal(bool(False))
    bufferDataDirection.driven = 'wire'
    decimationRatioBase = Signal(intbv(0, min = 0, max = 9))
    decimationRatioBase.driven = 'reg'
    decimationRatio = Signal(intbv(0, min = 0, max = MAXIMAL_RATIO+1))
    
    decimationStyle = Signal(intbv(0)[2:])
    decimationStyle.driven = 'reg'
    analogTrigger1Reset = Signal(bool(False))
    analogTrigger1Reset.driven = 'wire'
    trigger1Type = Signal(bool(False))
    trigger1Type.driven = 'wire'
    trigger1Slope = Signal(bool(False))
    trigger1Slope.driven = 'wire'
    analog1Trigger = Signal(bool(False))
    analog1Trigger.driven = 'wire'
    trigger1Value = Signal(intbv(0)[8:])
    trigger1Value.driven = 'reg'
    analogTrigger2Reset = Signal(bool(False))
    analogTrigger2Reset.driven = 'wire'
    trigger2Type = Signal(bool(False))
    trigger2Type.driven = 'wire'
    trigger2Slope = Signal(bool(False))
    trigger2Slope.driven = 'wire'
    analog2Trigger = Signal(bool(False))
    analog2Trigger.driven = 'wire'
    trigger2Value = Signal(intbv(0)[8:])
    trigger2Value.driven = 'reg'
    digitalTriggerReset = Signal(bool(False))
    digitalTriggerReset.driven = 'wire'
    digiTrigger = Signal(bool(False))
    digiTrigger.driven = 'wire'
    triggerPattern = Signal(intbv(0)[64:])
    triggerPattern.driven = 'reg'
    triggerSamples = Signal(intbv(0, min = 0, max = 4))
    triggerSamples.driven = 'reg'
    decimator1out = Signal(intbv(0)[8:])
    decimator1out.driven = 'reg'
    decimator2out = Signal(intbv(0)[8:])
    decimator2out.driven = 'reg'
    decimatorclock = Signal(bool(False))
    #decimatorclock.driven = 'wire'
    decimator1in = Signal(intbv(0)[8:])
    decimator2in = Signal(intbv(0)[8:])
    oe_i = Signal(bool(False))
    rxf_i = Signal(bool(False))
    txe_i = Signal(bool(False))
    rd_i = Signal(bool(False))
    wr_i = Signal(bool(False))
    siwu_i = Signal(bool(False))
    serialOut_i = Signal(bool(False))
    load_i = Signal(bool(False))
    ldac_i = Signal(bool(False))
    clkDacOut_i = Signal(bool(False))
    adc1pd_i = Signal(bool(False))
    adc2pd_i = Signal(bool(False))
    adc1relatt_i = Signal(bool(False))
    adc2relatt_i = Signal(bool(False))
    adc1relco_i = Signal(bool(False))
    adc2relco_i = Signal(bool(False))
    led0_i = Signal(bool(False))
    led1_i = Signal(bool(False))
    logicAnalyzer_i = Signal(intbv(0)[16:])
    logicAnalyzer_dec = Signal(intbv(0)[16:])
    la1dir_i = Signal(bool(False))
    la2dir_i = Signal(bool(False))
    la1oe_i  = Signal(bool(False))
    la2oe_i  = Signal(bool(False))
    clock_i = Signal(bool(False))
    clockFtdi_i = Signal(bool(False))
    reset_i = Signal(bool(False))
    alwaysEn  = Signal(bool(False))
    
    @always_comb
    def connectSignals():
        decimator1in.next = adc1data
        decimator2in.next = adc2data
        oe.next = oe_i
        rxf_i.next = rxf
        txe_i.next = txe
        rd.next = rd_i
        wr.next = wr_i
        siwu.next = siwu_i
        serialOut.next = serialOut_i
        load.next = load_i
        ldac.next = ldac_i
        clkDacOut.next = clkDacOut_i
        adc1pd.next = adc1pd_i
        adc2pd.next = adc2pd_i
        adc1relatt.next = adc1relatt_i
        adc2relatt.next = adc2relatt_i
        adc1relco.next = adc1relco_i
        adc2relco.next = adc2relco_i
        led0.next = led0_i
        led1.next = led1_i
        logicAnalyzer_i.next = logicAnalyzer
        la1dir.next = la1dir_i
        la2dir.next = la2dir_i
        la1oe.next  = la1oe_i
        la2oe.next  = la2oe_i
        clock_i.next = clock
        clockFtdi_i.next = clockFtdi
        reset_i.next = reset
    
    
    controller.vhdl_instance = "controller"
    inst_controller = controller(clockFtdi_i, reset_i, ft245din, ft245dout, ft245rw, ft245busy, oe_i, wr_i,
                   ft245dataWaitIn, ft245dataWaitOut, ft245strobe, ft245reset, dacReset, 
                   dacVrefTopA, dacVrefTopB, dacVrefBotA, dacVrefBotB, dacStrobe, dacBusy,
                   digipotReset, digipotValue, digipotStrobe, digipotBusy, bufferReset, 
                   bufferDataOut, bufferDataIn, bufferReady, bufferOutputInputReady,
                   bufferAllowWriteOverlap, bufferDataDirection, decimatorNewValueFlag,
                   decimationRatioBase, decimationStyle, decimator1out, decimator2out,
                   trigger1Type, trigger1Slope, analogTrigger1Reset, trigger1Value,
                   analog1Trigger, trigger2Type, trigger2Slope, analogTrigger2Reset,
                   trigger2Value, analog2Trigger, digitalTriggerReset, triggerPattern, 
                   triggerSamples, digiTrigger, adc1pd_i, adc2pd_i, adc1relatt_i, adc2relatt_i, 
                   adc1relco_i, adc2relco_i, led0_i, led1_i, logicAnalyzer_dec, la1dir_i, la2dir_i, la1oe_i, la2oe_i, clock_i)
    
    decimator_clock_divisor.vhdl_instance = "decimator_clock_divisor"
    inst_decimator_clock_divisor = decimator_clock_divisor(clock_i, reset_i, decimationRatioBase, decimationRatio, decimatorclock, decimatorNewValueFlag, alwaysEn)
    
    digital_decimator.vhdl_instance = "digital_decimator"
    inst_digital_decimator = digital_decimator(clock_i, reset_i, logicAnalyzer_i, logicAnalyzer_dec, decimationRatio, decimatorclock)
    
    decimator.vhdl_instance = "decimator"
    inst_decimator1 = decimator(clock_i, reset_i, decimator1in, decimator1out, decimationRatio, decimationRatioBase, decimationStyle, decimatorclock, decimatorNewValueFlag)
    inst_decimator2 = decimator(clock_i, reset_i, decimator2in, decimator2out, decimationRatio, decimationRatioBase, decimationStyle, decimatorclock, decimatorNewValueFlag)
    trigger_analog.vhdl_instance = "trigger_analog"
    inst_trigger_analog1 = trigger_analog(clock_i, analogTrigger1Reset, decimator1out, 
                                        trigger1Type, trigger1Slope, trigger1Value, analog1Trigger, decimatorclock, alwaysEn)
    inst_trigger_analog2 = trigger_analog(clock_i, analogTrigger2Reset, decimator2out, 
                                        trigger2Type, trigger2Slope, trigger2Value, analog2Trigger, decimatorclock, alwaysEn)
    trigger_digital.vhdl_instance = "trigger_digital"
    inst_trigger_digital = trigger_digital(decimatorclock, digitalTriggerReset, logicAnalyzer_dec, triggerPattern, triggerSamples, digiTrigger, decimatorclock, alwaysEn)
    dac_controller.vhdl_instance = "dac_controller"
    inst_dac_controller = dac_controller(clockFtdi_i, dacReset, dacVrefTopA, dacVrefTopB, dacVrefBotA, dacVrefBotB, dacStrobe, 
                                       serialOut_i, load_i, ldac_i, clkDacOut_i, dacBusy)
    digipot_controller.vhdl_instance = "digipot_controller"
    inst_digipot_controller = digipot_controller(clockFtdi_i, digipotReset, digipotValue, digipotStrobe, digipotBusy, sda, scl)
    
    buff.vhdl_instance = "buff"
    inst_buffer = buff(clock_i, bufferReset, bufferDataIn, bufferDataOut, bufferReady, bufferOutputInputReady, 
                        bufferAllowWriteOverlap, bufferDataDirection, decimatorclock, clockFtdi, alwaysEn)
    ft245sync.vhdl_instance = "ft245sync"
    inst_ft245sync = ft245sync(clockFtdi_i, ft245reset, rxf_i, txe_i, rd_i, wr_i, oe_i, siwu_i, adbus, ft245din, ft245dout, 
                                                   ft245rw, ft245busy, ft245dataWaitIn, ft245dataWaitOut, ft245strobe)
    return connectSignals, inst_decimator1, inst_decimator2, inst_controller, inst_trigger_analog1, inst_trigger_analog2, \
           inst_buffer, inst_ft245sync, inst_digipot_controller, inst_dac_controller, inst_trigger_digital, \
           inst_digital_decimator, inst_decimator_clock_divisor