Ejemplo n.º 1
0
class Coincidence_Timer:
    def __init__(self, mode):
        if mode == 0:
            self.PC_OV = Overlay("TDC/TDC_OVERLAY_wrapper.bit", 0)
            print("Loaded two channel coincidence rising edge TDC")
        elif mode == 1:
            self.PC_OV = Overlay("TDC/SC_TDC_OVERLAY.bit", 0)
            print("Loaded single channel inter rising edge TDC")
        else:
            print("What?")
            self.PC_OV = Overlay("TDC/TDC_OVERLAY_wrapper.bit", 0)
            print("Loaded two channel coincidence rising edge TDC")
        self.PC_OV.download()
        self.GPIO = MMIO(it_a_gpio_addr, axi_gpio_range)
        self.GPIO_INT = MMIO(it_a_gpioi_addr, axi_gpio_range)
        self.GPIO.write(ch1_dir, 0xFFFFFFFF)
        self.GPIO.write(ch2_dir, 0x0)
        self.GPIO_INT.write(ch1_dir, 0xFFFFFFFF)
        self.GPIO.write(ch2_data, 0x0)  #Hold system in reset for now

    def arm_and_wait(self):
        self.GPIO.write(ch2_data, 0x1)
        op = 0
        while (self.GPIO_INT.read(ch1_data) == 0x0):
            pass
        if (self.GPIO_INT.read(ch1_data) == 0x1):
            op = self.GPIO.read(ch1_data)
            self.GPIO.write(ch2_data, 0x0)
        return op

    def tval_to_time(self, tval):
        return tval * (1 / 450000000)
Ejemplo n.º 2
0
    def __init__(self, chunkSize, numClasses, numFeatures):
        self.numClasses = numClasses
        self.numFeatures = numFeatures
           
        # -------------------------
        #   Download Overlay.
        # -------------------------    

        ol = Overlay("LogisticRegression.bit")
        ol.download()  
        
        # -------------------------
        #   Physical address of the Accelerator Adapter IP.
        # -------------------------

        ADDR_Accelerator_Adapter_BASE = int(PL.ip_dict["SEG_LR_gradients_kernel_accel_0_if_Reg"][0], 16)
        ADDR_Accelerator_Adapter_RANGE = int(PL.ip_dict["SEG_LR_gradients_kernel_accel_0_if_Reg"][1], 16)

        # -------------------------
        #    Initialize new MMIO object. 
        # -------------------------

        self.bus = MMIO(ADDR_Accelerator_Adapter_BASE, ADDR_Accelerator_Adapter_RANGE)

        # -------------------------
        #   Physical addresses of the DMA IPs.
        # -------------------------

        ADDR_DMA0_BASE = int(PL.ip_dict["SEG_dm_0_Reg"][0], 16)
        ADDR_DMA1_BASE = int(PL.ip_dict["SEG_dm_1_Reg"][0], 16)
        ADDR_DMA2_BASE = int(PL.ip_dict["SEG_dm_2_Reg"][0], 16)
        ADDR_DMA3_BASE = int(PL.ip_dict["SEG_dm_3_Reg"][0], 16)

        # -------------------------
        #    Initialize new DMA objects. 
        # -------------------------

        self.dma0 = DMA(ADDR_DMA0_BASE, direction = DMA_TO_DEV)    # data1 DMA.
        self.dma1 = DMA(ADDR_DMA1_BASE, direction = DMA_TO_DEV)    # data2 DMA.
        self.dma2 = DMA(ADDR_DMA2_BASE, direction = DMA_TO_DEV)    # weights DMA.
        self.dma3 = DMA(ADDR_DMA3_BASE, direction = DMA_FROM_DEV)  # gradients DMA.
        
        # -------------------------
        #    Allocate physically contiguous memory buffers.
        # -------------------------

        self.dma0.create_buf(int(chunkSize / 2) * (self.numClasses + (1 + self.numFeatures)) * 4, 1)
        self.dma1.create_buf(int(chunkSize / 2) * (self.numClasses + (1 + self.numFeatures)) * 4, 1)
        self.dma2.create_buf((self.numClasses * (1 + self.numFeatures)) * 4, 1)
        self.dma3.create_buf((self.numClasses * (1 + self.numFeatures)) * 4, 1)

        # -------------------------
        #    Get CFFI pointers to objects' internal buffers.
        # -------------------------

        self.data1_buf = self.dma0.get_buf(32, data_type = "float")
        self.data2_buf = self.dma1.get_buf(32, data_type = "float")
        self.weights_buf = self.dma2.get_buf(32, data_type = "float")
        self.gradients_buf = self.dma3.get_buf(32, data_type = "float")
Ejemplo n.º 3
0
 def __init__(self):
     ol = Overlay("DDR_CT_TEST_OV_wrapper.bit", 0)
     ol.download()
     self.DATA = MMIO(0x41200000, 0x10000)
     self.UTIL = MMIO(0x41210000, 0x10000)
     self.DEBUG = MMIO(0x41220000, 0x10000)
     self.UTIL.write(0x0, 0x0)
     self.UTIL.write(0x8, 0b0)
Ejemplo n.º 4
0
 def __init__(self):
     ol = Overlay("TEST_wrapper.bit",0)
     ol.download()
     self.DELAY = MMIO(0x41200000,0x10000)
     self.CTIME0 = MMIO(0x41210000,0x10000)
     self.CTIME1 = MMIO(0x41220000,0x10000)
     self.O_UTIL = MMIO(0x41230000,0x10000)
     self.I_UTIL = MMIO(0x41240000,0x10000)
Ejemplo n.º 5
0
class pz1sofi():
    """Class to control the Sobel filter hardware

    Attributes
    ----------
    bitfile : str
    Absolute path to bitstream
    libfile : str
    Absolute path to shared library
    overlay : Overlay
    Pynq-Z1 Sobel filter overlay
    frame_gray : 
    Pointer to intermediate gray image
    """
    def __init__(self):
        #Set attributes
        self.bitfile = BITFILE
        self.libfile = LIBFILE
        self._ffi = cffi.FFI()
        #Accelerator functions
        self._ffi.cdef("void _p0_rgb_2_gray_0(uint8_t * input," +
                       "uint8_t * output);")
        self._ffi.cdef("void _p0_sobel_filter_0(uint8_t * input," +
                       "uint8_t * output);")
        self._ffilib = self._ffi.dlopen(LIBFILE)
        self.overlay = Overlay(self.bitfile)
        #XLNK functions
        self._ffi.cdef("void *cma_alloc(uint32_t len," +
                       "uint32_t cacheable);")
        self._ffi.cdef("void cma_free(void *buf);")
        #Allocate memory for gray frame
        self.frame_gray = self._ffi.cast(
            "uint8_t *", self._ffilib.cma_alloc(1920 * 1080, 0))
        #Check if bitstream is loaded
        if not Overlay.is_loaded(self.overlay):
            self.overlay.download()

    def get_frame_ptr(self, hdmi_in_frame):
        """...
        """
        return self._ffi.cast("uint8_t *", hdmi_in_frame.frame_addr())

    def sobel_filter(self, frame_in, frame_out, num_frames=1, get_fps=False):
        """...
        """
        if get_fps:
            import time
            time1 = time.time()
        for i in range(num_frames):
            self._ffilib._p0_rgb_2_gray_0(frame_in, self.frame_gray)
            self._ffilib._p0_sobel_filter_0(self.frame_gray, frame_out)
        if get_fps:
            time2 = time.time()
            return num_frames / (time2 - time1)

    def __del__(self):
        #Deallocate memory for gray frame
        self._ffilib.cma_free(self._ffi.cast("void *", self.frame_gray))
Ejemplo n.º 6
0
class ST:
    def __init__(self):
        self.ov = Overlay("TEST_wrapper.bit", 0)
        self.ov.download()
        self.DATA = MMIO(0x41200000, 0x10000)
        self.UTIL = MMIO(0x41210000, 0x10000)
        self.DELAY0 = MMIO(0x41220000, 0x10000)
        self.DELAY1 = MMIO(0x41230000, 0x10000)
        self.DEBUG = MMIO(0x41240000, 0x10000)
        self.DUTIL = MMIO(0x41250000, 0x10000)

        log.info("Ready")

    def wait_for_rdy(self):
        while (self.UTIL.read(0x8) == 0):
            pass

    def read_time(self):
        course_time = self.DATA.read(0x0)
        log.debug("CT: " + str(course_time))
        finetimes = self.DATA.read(0x8)
        preftime = finetimes & 0xFF
        postftime = (finetimes & 0xFF00) >> 8
        log.debug("PRE: " + str(preftime))
        log.debug("POST: " + str(postftime))
        timetoconv = preftime - postftime
        timetoconv *= FTIME
        time = course_time / COURSE_CLK + timetoconv
        return time

    def proc(self):
        self.DUTIL.write(0x0, 0x1)
        sleep(0.1)
        self.UTIL.write(0x0, 0x1)
        self.wait_for_rdy()
        self.read_debug()
        time = self.read_time()
        log.info("TIME: " + str(time * 1e9))
        self.UTIL.write(0x0, 0x0)
        self.DUTIL.write(0x0, 0x0)
        return time

    def set_delays(self, dels):
        #self.DUTIL.write(0x0,0x1)
        self.DELAY0.write(0x0, int(dels[0]))
        self.DELAY0.write(0x8, int(dels[1]))
        self.DELAY1.write(0x0, int(dels[2]))
        self.DELAY1.write(0x8, int(dels[3]))
        #self.DUTIL.write(0x0,0x1)
    def read_debug(self):
        staten = self.DEBUG.read(0x0)
        for i in range(8):
            mask = 0xF
            log.debug("STATEN" + str(i) + ": " +
                      format((staten >> (4 * i)) & mask, '#006b'))
        log.debug("STATENFULL: " + bin(staten))
        log.debug("STATEL: " + bin(self.DEBUG.read(0x8)))
Ejemplo n.º 7
0
 def __init__(self):
     ol = Overlay("TEST_wrapper.bit", 0)
     ol.download()
     self.DATA = MMIO(0x43c00000, 0x10000)
     self.UTIL = MMIO(0x43c10000, 0x10000)
     self.loaded_data = []
     for i in range(FIFO_BUFFER):
         self.loaded_data.append(0)
     self.loaded_count = 0
Ejemplo n.º 8
0
 def __init__(self):
     ol = Overlay("SCS_TT_TEST_wrapper.bit", 0)
     ol.download()
     self.UTIL = MMIO(0x41200000, 0x10000)
     self.UTIL.write(0x8, int(REF_CLK))
     self.DATA0 = MMIO(0x41210000, 0x10000)
     self.DATA1 = MMIO(0x41220000, 0x10000)
     self.DATA_UTIL = MMIO(0x41230000, 0x10000)
     self.DEBUG0 = MMIO(0x41240000, 0x10000)
     self.DEBUG1 = MMIO(0x41250000, 0x10000)
Ejemplo n.º 9
0
class clock_gen:
    def __init__(self):
        self.PC_OV = Overlay("TDC/PG_OV_wrapper.bit", 0)
        self.PC_OV.download()
        self.CLK_WIZ = MMIO(BASE_ADDR, 0x10000)
        self.CLK_WIZ.write(CCON0, 0xA01)
        self.CLK_WIZ.write(CCON2, 0x5)
        while (self.CLK_WIZ.read(SR) == 0):
            pass
        self.CLK_WIZ.write(CCON23, 0x3)
Ejemplo n.º 10
0
    def __init__(self):
        ol = Overlay("TEST_wrapper.bit",0)
        ol.download()
        self.CONFIG = MMIO(0x43c00000,0x10000)
        self.DATA0 = MMIO(0x43c10000,0x10000)
        self.DATA1 = MMIO(0x43c20000,0x10000)
        self.DELAY = MMIO(0x43c30000,0x10000)
        self.UTIL = MMIO(0x43c40000,0x10000)

        self.loaded_data = []
        for i in range(FIFO_DEPTH):
            self.loaded_data.append(0)
        self.loaded_count = 0
Ejemplo n.º 11
0
    def init_accelerator(self, bit_file=TINIER_YOLO_BIT_FILE, json_network=W1A3_JSON, json_layer=JSON_TINIER_YOLO):
        """ Initialize accelerator memory and configuration. """

        if bit_file :
            ol = Overlay(bit_file)
            ol.download()

        if not self.init:
            with open(json_network, 'r') as f:
                self.network_json = json.load(f)

            with open(json_layer, 'r') as f:
                self.layer_json = json.load(f)

            self.lib.initParameters(1,0);
            self.lib.initAccelerator(json_network.encode(), json_layer.encode())
            self.init = True
Ejemplo n.º 12
0
class PulseCounter:
    def __init__(self):
        self.PC_OV = Overlay("TDC/Counter_Overlay_wrapper.bit", 0)
        self.PC_OV.download()
        self.GPIO_DATA = []
        self.GPIO_UTILITY = []
        for i in range(4):
            self.GPIO_DATA.append(
                MMIO(axi_gpio_base_addr + 2 * i * axi_gpio_range,
                     axi_gpio_range))
            self.GPIO_DATA[i].write(ch1_dir, 0xFFFFFFFF)
            self.GPIO_DATA[i].write(ch2_dir, 0x0)
            self.GPIO_DATA[i].write(ch2_data, 0xFFFFFFFF)
        for i in range(4):
            self.GPIO_UTILITY.append(
                MMIO(axi_gpio_base_addr + (1 + 2 * i) * axi_gpio_range,
                     axi_gpio_range))
            self.GPIO_UTILITY[i].write(ch1_dir, 0x0)
            self.GPIO_UTILITY[i].write(ch1_data, 0x0)
            self.GPIO_UTILITY[i].write(ch2_dir, 0xFFFFFFFF)

    # Sets the timer threshold (window of counting) for all channels (cannot set different windows for individual channels
    def set_threshold(self, val):
        newval = int(val)
        for i in range(4):
            self.GPIO_DATA[i].write(ch2_data, newval)

    # Reads the counts of each channel and returns a 4 size vector containing counts for each channel
    def read_incidents(self):
        return [self.GPIO_DATA[i].read(ch1_data) for i in range(4)]

    # Reads the status of the counting, if its finished or not, as there are 4 channels, the result is a 4 bit integer
    def read_utility(self):
        outpi = 0x0
        for i in range(4):
            outpi = outpi | (self.GPIO_UTILITY[i].read(ch2_data) & 0B1) << i
        #return self.GPIO_UTILITY[0].read(ch2_data)
        #print(bin(outpi))
        return outpi

    # Allows setting of the reset lines to the pulse counter and timer of all channels (cannot individually reset channels)
    def set_ctl_lines(self, r0, r1, EN):
        val = r1 << 1 | r0
        val = val | EN << 1
        for i in range(4):
            self.GPIO_UTILITY[i].write(ch1_data, val)
Ejemplo n.º 13
0
    def init_accelerator(self, bit_file=DOREFANET_BIT_FILE, json_network=W1A2_JSON, json_layer=DOREFANET_LAYER_JSON):
        """ Initialize accelerator memory and configuration. """

        if bit_file :
            ol = Overlay(bit_file)
            ol.download()

        if not self.init:
            with open(json_network, 'r') as f:
                self.network_json = json.load(f)

            with open(json_layer, 'r') as f:
                self.layer_json = json.load(f)

            self.lib.initParameters(1,0);
            self.lib.initAccelerator(json_network.encode(), json_layer.encode())
            self.init = True
Ejemplo n.º 14
0
    def download_bitstream(self):
        """Download the bitstream

        Downloads the bitstream onto hardware using overlay class.
        Also gives you access to overlay.

        Parameters
        ----------
        None

        Returns
        -------
        None

        """
        global ws2812_overlay
        ws2812_overlay = Overlay(self.bitfile)
        ws2812_overlay.download()
Ejemplo n.º 15
0
    def __init__(self):
        self.ffi = cffi.FFI()
        if IS_PYNQ:
            bitfile = "../pynq_chainer/HLS/bitstream.bit"
            libfile = "../pynq_chainer/HLS/src/libaccel.so"
            #self.ffi.cdef("int _Z18_p0_mmult_accel1_0PfS_S_iii(float*, float*, float*, int, int, int);")
            self.ffi.cdef(
                "int _Z17_p0_mmult_accel_0PfS_S_iii(float*, float*, float*, int, int, int);"
            )
            self.lib = self.ffi.dlopen(libfile)
            #self.accel_fn = self.lib._Z18_p0_mmult_accel1_0PfS_S_iii
            self.accel_fn = self.lib._Z17_p0_mmult_accel_0PfS_S_iii

            overlay = Overlay(bitfile)
            if not overlay.is_loaded():
                overlay.download()
                print("load Overlay")
        else:
            self.accel_fn = pcsim.mmult_accel
class HuffmanEncodingCore(Singleton):
    def __init__(self):
        self.overlay = Overlay('huffman_core_wrapper/bitstream/irq-test.bit')
        self.overlay.download()
        self.huff_core = self.overlay.huffman_encoding_0

    def start_calc(self):
        # enable interrupt
        self.huff_core.write(ip_intr_en_addr, 1)
        # read done interrupt
        self.huff_core.write(ip_intr_status_addr, 1)
        # start
        self.huff_core.write(ctrl_base_addr, 1)

    def feed_data(self, freq_table):
        if (not freq_table):
            return
        # write symbol and frequency to huffman core
        for idx, ele in enumerate(freq_table):
            # write to encoding core memory
            if (not ele == None):
                (val, freq) = ele
                self.huff_core.write(sym_histo_val_addr + 4 * idx, ord(val))
                self.huff_core.write(sym_histo_freq_addr + 4 * idx, freq)

    def read_code_word(self, freq_table):
        encoding = {'symbol': [], 'total': 0}
        for idx, ele in enumerate(freq_table):
            if (not ele == None):
                (val, freq) = ele
                encoding['symbol'].append(
                    self.huff_core.read(encoding_addr + 4 * ord(val)))
        encoding['total'] = self.huff_core.read(non_zero_cnt_data_addr)
        return encoding

    def calc_encoding(self, freq_table):
        self.feed_data(freq_table)
        start = time.time()
        self.start_calc()
        end = time.time()
        encoding = self.read_code_word(freq_table)
        return {'encoding': encoding, 'consume': end - start}
Ejemplo n.º 17
0
class mcolorl:
    def __init__(self):
        self.mcolv = Overlay("mcolor/design_1_wrapper.bit", 0)
        self.mcolv.download()
        self.axi_gpio_h = MMIO(axi_gpio_addr, axi_gpio_range)
        self.axi_gpio_h.write(0x4, 0x0)
        self.axi_gpio_h.write(0x0, 0x0)
        self.buffer = 0

    def led(self, led, r, g, b):
        shift = 0
        if (led == 1):
            shift = 3
        self.buffer = self.buffer | (int(str(r) + str(g) + str(b), 2) << shift)
        self.axi_gpio_h.write(0x0, self.buffer)

    def cust(self, val):
        self.axi_gpio_h.write(0x0, val)

    def clrbuf(self):
        self.buffer = 0
        self.axi_gpio_h.write(0x0, self.buffer)
Ejemplo n.º 18
0
def test_mmio():
    """Test whether MMIO class is working properly.
    
    Generate random tests to swipe through the entire range:
    
    >>> mmio.write(all offsets, random data)
    
    Steps:
    
    1. Initialize an instance with length in bytes
    
    2. Write an integer to a given offset.
    
    3. Write a number within the range [0, 2^32-1] into a 4-byte location.
    
    4. Change to the next offset and repeat.
    
    """
    ol = Overlay('base.bit')
    
    ol.download()
    sleep(0.2)
    mmio_base = ol.ip_dict['SEG_mb_bram_ctrl_1_Mem0'][0]
    mmio_range = ol.ip_dict['SEG_mb_bram_ctrl_1_Mem0'][1]
    mmio = MMIO(mmio_base, mmio_range)
    for offset in range(0, 100, general_const.MMIO_WORD_LENGTH):
        data1 = randint(0, pow(2,32)-1)
        mmio.write(offset, data1)
        sleep(0.02)
        data2 = mmio.read(offset)
        assert data1==data2, \
            'MMIO read back a wrong random value at offset {}.'.format(offset)
        mmio.write(offset, 0)
        sleep(0.02)
        assert mmio.read(offset)==0, \
            'MMIO read back a wrong fixed value at offset {}.'.format(offset)
            
    del ol
    
Ejemplo n.º 19
0
    def __init__(self):
        self.ffi = cffi.FFI()
        if IS_PYNQ:
            bitfile = "../pynq_chainer/HLS/bitstream.bit"
            libfile = "../pynq_chainer/HLS/src/libaccel.so"
            #self.ffi.cdef("void _Z17_p0_mmult_accel_0PiS_S_ii(int*, int*, int*, int, int);")
            #self.ffi.cdef("void _Z20_p0_binary_connect_0tPiS_S_tt(unsigned short, int*, int*, int*, unsigned short, unsigned short);")
            self.ffi.cdef(
                "void _Z17_p0_BlackBoxJam_0P7ap_uintILi32EES1_bjjjS0_(unsigned int*, unsigned int*, bool, unsigned int, unsigned int, unsigned int, unsigned int);"
            )
            self.lib = self.ffi.dlopen(libfile)
            print(self.lib.__dict__)
            #self.accel_fn = self.lib._Z17_p0_mmult_accel_0PiS_S_ii
            #self.accel_fn = self.lib._Z20_p0_binary_connect_0tPiS_S_tt
            self.accel_fn = self.lib._Z17_p0_BlackBoxJam_0P7ap_uintILi32EES1_bjjjS0_

            overlay = Overlay(bitfile)
            if not overlay.is_loaded():
                overlay.download()
                print("load Overlay")
        else:
            self.accel_fn = pcsim.mmult_accel
Ejemplo n.º 20
0
def test_mmio():
    """Test whether MMIO class is working properly.
    
    Generate random tests to swipe through the entire range:
    
    >>> mmio.write(all offsets, random data)
    
    Steps:
    
    1. Initialize an instance with length in bytes
    
    2. Write an integer to a given offset.
    
    3. Write a number within the range [0, 2^32-1] into a 4-byte location.
    
    4. Change to the next offset and repeat.
    
    """
    ol = Overlay('base.bit')
    
    ol.download()
    sleep(0.2)
    mmio_base = int(ol.get_ip_addr_base('SEG_mb_bram_ctrl_1_Mem0'),16)
    mmio_range = int(ol.get_ip_addr_range('SEG_mb_bram_ctrl_1_Mem0'),16)
    mmio = MMIO(mmio_base, mmio_range)
    for offset in range(0, 100, general_const.MMIO_WORD_LENGTH):
        data1 = randint(0, pow(2,32)-1)
        mmio.write(offset, data1)
        sleep(0.02)
        data2 = mmio.read(offset)
        assert data1==data2, \
            'MMIO read back a wrong random value at offset {}.'.format(offset)
        mmio.write(offset, 0)
        sleep(0.02)
        assert mmio.read(offset)==0, \
            'MMIO read back a wrong fixed value at offset {}.'.format(offset)
            
    del ol
    
Ejemplo n.º 21
0
class GPIOModulesCTL:
    def __init__(self):
        self.overlay = Overlay("SerDesTestOverlay/design_1_wrapper.bit", 0)
        self.overlay.download()
        #Multicolor LEDs
        self.axi_gpio_0_h = MMIO(axi_gpio_0_addr, axi_gpio_range)
        self.axi_gpio_0_h.write(0x4, 0x0)
        self.axi_gpio_0_h.write(0x0, 0x0)
        #SelectIO Interface
        self.axi_gpio_1_h = MMIO(axi_gpio_1_addr, axi_gpio_range)
        self.axi_gpio_1_h.write(0x4, 0xFFFFFFFF)
        #PLL lock indicators
        self.axi_gpio_2_h = MMIO(axi_gpio_2_addr, axi_gpio_range)
        self.axi_gpio_2_h.write(0x4, 0xFFFFFFFF)

    def gpio_0_write(self, val):
        self.axi_gpio_0_h.write(0x0, val)

    def gpio_1_read(self):
        return self.axi_gpio_1_h.read(0x0)

    def gpio_2_read(self):
        return self.axi_gpio_2_h.read(0x0)
Ejemplo n.º 22
0
class MaxLayer(object):
    def __init__(self, layer, fm, dim, xlnk, batchsize=1):
        self.layer = layer
        self.fm = fm
        self.dim = dim
        self.xlnk = xlnk
        self.batchsize = batchsize

        self.ol = Overlay(
            os.path.dirname(os.path.realpath(__file__)) + "/bitstream/" +
            self.layer + ".bit")
        self.dma = self.ol.axi_dma_0

        self.cmaOutMax = []
        for b in range(self.batchsize):
            self.cmaOutMax.append(
                self.xlnk.cma_array(shape=(self.fm * (self.dim**2), ),
                                    dtype=np.float32))

    def __call__(self, input):
        self.ol.download()

        self.dma.sendchannel.start()
        self.dma.recvchannel.start()

        b = 0
        while b < self.batchsize:
            self.dma.recvchannel.transfer(self.cmaOutMax[b])
            self.dma.sendchannel.transfer(input[b])

            self.dma.sendchannel.wait()
            self.dma.recvchannel.wait()

            b += 1

        return self.cmaOutMax
Ejemplo n.º 23
0
class SP_TOOLS:
    def __init__(self):
        self.OV = Overlay("Single_Photons/SP_OVERLAY.bit", 0)
        self.OV.download()
        ##Initialize pulse counter
        axi_offset = 0
        #Initialize data channels
        self.PC_DAT = []
        global axi_range
        for i in range(4):
            self.PC_DAT.append(MMIO(axi_base_addr + (i * axi_range),
                                    axi_range))
            self.PC_DAT[i].write(ch1_dir, agpi)  #ch1 is counts
            self.PC_DAT[i].write(ch2_dir, agpo)  #Ch2 is window
            self.PC_DAT[i].write(ch2_data, 0xFFFFFFFF)
        #Initialize utility channels
        axi_offset = 4
        self.PC_UTIL = []
        for i in range(4):
            self.PC_UTIL.append(
                MMIO(axi_base_addr + ((i + axi_offset) * axi_range),
                     axi_range))
            self.PC_UTIL[i].write(ch1_dir, agpo)  #Reset
            self.PC_UTIL[i].write(ch1_data, 0x0)  #Hold in reset
            self.PC_UTIL[i].write(ch2_dir, agpi)  #Ready
        #Initialize trigger controller
        self.T_UTIL = MMIO(0x41200000, 0x10000)
        self.T_UTIL.write(ch2_dir, 0x0)
        self.T_UTIL.write(ch2_data, 0x0)
        self.T_RDY_UTIL = MMIO(0x41210000, 0x10000)
        self.T_RDY_UTIL.write(ch1_dir, 0x1)
        ##Initialize single channel inter-rising_edge detection
        axi_offset = 8
        self.ST_DAT = MMIO(axi_base_addr + axi_offset * axi_range, axi_range)
        self.ST_DAT.write(ch1_dir, agpi)
        self.ST_DAT.write(ch2_dir, agpo)
        self.ST_DAT.write(ch2_data, 0x0)  #Hold in reset
        self.ST_RDY = MMIO(axi_base_addr + (axi_offset + 1) * axi_range,
                           axi_range)
        self.ST_RDY.write(ch1_dir, agpi)
        ##Initialize interchannel coincidence timer
        axi_offset = 10
        self.CT_DAT = MMIO(axi_base_addr + axi_offset * axi_range, axi_range)
        self.CT_DAT.write(ch1_dir, agpi)
        self.CT_DAT.write(ch2_dir, agpo)
        self.CT_DAT.write(ch2_data, 0x0)  #Hold in reset
        self.CT_RDY = MMIO(axi_base_addr + (axi_offset + 1) * axi_range,
                           axi_range)
        self.CT_RDY.write(ch1_dir, agpi)
        ##Initialize Pulse generator
        axi_offset = 12
        iDC = 0.5
        iFREQ = 440.0
        ph0, ph1 = self.encode_phase_inc(iFREQ)
        iDCenc = self.calc_dc_lim(iFREQ, iDC)
        self.PG_PH = []
        self.PG_AUX = []
        self.chfreqs = [440.0, 440.0, 440.0, 440.0]
        self.chdcs = [0.5, 0.5, 0.5, 0.5]
        self.chdelays = [0, 0, 0, 0]
        for i in range(4):  #Phase increments
            tap = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            tap.write(ch1_dir, agpo)
            tap.write(ch2_dir, agpo)
            tap.write(ch1_data, ph0)
            tap.write(ch2_data, ph1)
            self.PG_PH.append(tap)
            axi_offset += 1
            self.chfreqs[i] = 440.0
        for i in range(4):  #Duty length and delay
            tdc = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            tdc.write(ch1_dir, agpo)
            tdc.write(ch1_data, iDCenc)
            tdc.write(ch2_dir, agpo)
            tdc.write(ch2_data, 0x0)
            self.PG_AUX.append(tdc)
            axi_offset += 1
            self.chdcs[i] = 0.5
        self.PG_UTIL = MMIO(0x43D40000,
                            0x10000)  #increment load and master reset
        self.PG_UTIL.write(ch1_dir, agpo)
        self.PG_UTIL.write(ch2_dir, agpo)
        self.PG_UTIL.write(ch1_data, 0x0)  #SEt loader to 0
        self.PG_UTIL.write(ch2_data, 0x0)  #Hold in reset
        #Routine to write initial phase increments
        self.PG_UTIL.write(ch2_data, 0x1)
        self.PG_UTIL.write(ch1_data, 0xF)
        sleep(slt)
        self.PG_UTIL.write(ch1_data, 0x0)
        #Channel enable controller
        self.T_UTIL.write(ch1_dir, 0x0)
        self.T_UTIL.write(ch1_data, 0xF)  #SEt all channels to high impedance
        axi_offset += 1
        self.pg_ch_stat = 0xF
        #self.PG_UTIL.write(ch2_data,0x0)
        ##Initialize Time Tagger
        #initialize detector MMIOs
        self.TT_DET = []
        for i in range(4):
            temp = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            temp.write(ch1_dir, 0xFFFFFFFF)
            temp.write(ch2_dir, 0xFFFFFFFF)
            self.TT_DET.append(temp)
            axi_offset += 1
        #Initialize timeout MMIO
        self.TT_TIME_OUT = MMIO(axi_base_addr + (axi_offset * axi_range),
                                axi_range)
        self.TT_TIME_OUT.write(ch1_dir, 0x0)
        self.TT_TIME_OUT.write(ch2_dir, 0x0)
        self.TT_TIME_OUT.write(ch1_data, 0xFFFFFFFF)
        self.TT_TIME_OUT.write(ch2_data, 0xFFFF)
        axi_offset += 1
        #Initialize utility
        print(hex(axi_base_addr + (axi_offset * axi_range)))
        print(hex(axi_range))
        self.TT_UTIL = MMIO(axi_base_addr + (axi_offset * axi_range),
                            axi_range)
        self.TT_UTIL.write(ch1_dir, 0x0)
        self.TT_UTIL.write(ch2_dir, 0xFFFFFFFF)
        self.TT_UTIL.write(ch1_data, 0x0)  #Hold system in reset
        axi_offset += 1
        ##Initialize IDELAY
        self.iDD_DATA = []
        self.iDD_UTIL = []
        for i in range(6):
            tempdel = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            tempdel.write(ch1_data, 0x0)
            tempdel.write(ch2_data, 0x0)
            self.iDD_DATA.append(tempdel)
            axi_offset += 1
        for i in range(6):
            temputil = MMIO(axi_base_addr + (axi_offset * axi_range),
                            axi_range)
            temputil.write(ch1_data, 0x1)
            temputil.write(ch2_data, 0x1)
            self.iDD_UTIL.append((temputil))
            axi_offset += 1

    ####------------------PHOTON COUNTER---------------------------------------------------####
    def pc_set_window(
            self, window,
            channels):  #Channels is 4 bit integer, window is in seconds
        m = 0B0001
        wval = int(window * TIMER_CLK)
        if (wval > 0xFFFFFFFF or wval <= 0):
            print(
                "Window must be between 34.35973836s and 0, cannot be 0 seconds"
            )
            return
        for i in range(4):
            if ((0B0001 << i) & channels) != 0:
                self.PC_DAT[i].write(ch2_data, wval)

    def pc_wait_for_rdy(self, channel, mode):
        if mode == 0:
            if (self.PC_UTIL[channel].read(ch2_data) == 0):
                while (self.PC_UTIL[channel].read(ch2_data) == 0):
                    pass
            else:
                while (self.PC_UTIL[channel].read(ch2_data) == 1):
                    pass
        else:
            if (self.T_RDY_UTIL.read(ch1_data) == 0):
                while (self.T_RDY_UTIL.read(ch1_data) == 0):
                    pass

    def pc_ex_triggered(self, window):
        self.pc_set_window(window, 0xF)
        self.T_UTIL.write(ch2_data, 0x1)
        self.pc_wait_for_rdy(0, 0)
        retval = []
        for i in range(4):
            retval.append(self.pc_read_counts(i))
        self.T_UTIL.write(ch2_data, 0x0)
        return retval

    def pc_ex_trig_stop(self):
        self.T_UTIL.write(ch2_data, 0x3)
        for i in range(4):
            self.PC_DAT[i].write(ch2_data, 0xFFFFFFFF)
        self.pc_wait_for_rdy(0, 1)
        retval = []
        for i in range(4):
            retval.append(self.pc_read_counts(i))
        self.T_UTIL.write(ch2_data, 0x0)
        return retval

    def pc_enable_channels(self, channels):  #channels a 4 bit integer
        for i in range(4):
            if ((0B0001 << i) & channels) != 0:
                self.PC_UTIL[i].write(ch1_data, 0x1)

    def pc_disable_channels(self, channels):  #Channels a 4 bit integer
        for i in range(4):
            if ((0B0001 << i) & channels) != 0:
                self.PC_UTIL[i].write(ch1_data, 0x0)

    def pc_read_counts(self, channel):
        return self.PC_DAT[channel].read(ch1_data)

    ####----------------------------------------------------------------------------------####
    ####------------------Single line inter-rising_edge timer-----------------------------####
    def st_arm_and_wait(self):
        self.ST_DAT.write(ch2_data, 0x1)  #Enable
        op = 0
        while (self.ST_RDY.read(ch1_data) == 0x0):  #Wait for ready
            pass
        if (self.ST_RDY.read(ch1_data) == 0x1):
            op = self.ST_DAT.read(ch1_data)  #Read time
            self.ST_DAT.write(ch2_data, 0x0)
        return op * (1 / REF_CLK)

    ####----------------------------------------------------------------------------------####
    ####------------------Two channel photon coincidence timer----------------------------####
    def ct_arm_and_wait(self):
        self.CT_DAT.write(ch2_data, 0x1)  # Enable
        op = 0
        #print("Armed")
        while (self.CT_RDY.read(ch1_data) == 0x0):  # Wait for ready
            pass
        #print("Triggered")
        if (self.CT_RDY.read(ch1_data) == 0x1):
            #print("Reading")
            op = self.CT_DAT.read(ch1_data)  # Read time
            self.CT_DAT.write(ch2_data, 0x0)
        return op * (1 / REF_CLK)

    ####---------------------Signal generator---------------------------------------------####

    def pg_disable(self):
        self.PG_UTIL.write(ch2_data, 0x0)

    def pg_enable(self):
        self.PG_UTIL.write(ch2_data, 0x1)

    def pg_enable_channel(self, channel):
        self.pg_ch_stat = ~(~self.pg_ch_stat | (0B0001 << channel))
        self.T_UTIL.write(ch1_data, self.pg_ch_stat)

    def pg_disable_channel(self, channel):
        self.pg_ch_stat = self.pg_ch_stat | (0b0001 << channel)
        self.T_UTIL.write(ch1_data, self.pg_ch_stat)

    def pg_set_channel_freq(self, channel, freq):
        nenc = self.encode_phase_inc(2 * freq)
        self.PG_PH[channel].write(ch1_data, nenc[0])
        self.PG_PH[channel].write(ch2_data, nenc[1])
        self.PG_UTIL.write(ch1_data, 0xF)
        sleep(slt)
        self.PG_UTIL.write(ch1_data, 0x0)
        newdc = self.calc_dc_lim(freq, self.chdcs[channel])
        self.PG_UTIL.write(ch2_data, 0x0)
        self.PG_AUX[channel].write(ch1_data, newdc)
        self.PG_AUX[channel].write(ch2_data,
                                   self.calc_delay(self.chdelays[channel]))
        self.PG_UTIL.write(ch2_data, 0x1)
        self.chfreqs[channel] = freq

    def pg_set_dc(self, channel, dc):  #Dc from 0 to 1
        dcenc = self.calc_dc_lim(self.chfreqs[channel], dc)
        self.PG_UTIL.write(ch2_data, 0x0)
        self.PG_AUX[channel].write(ch1_data, dcenc)
        self.PG_UTIL.write(ch2_data, 0x1)
        self.chdcs[channel] = dc

    def pg_set_pw(self, channel, pw):
        pwv = self.calc_delay(pw / 1000)
        self.PG_UTIL.write(ch2_data, 0x0)
        self.PG_AUX[channel].write(ch1_data, pwv)
        self.PG_UTIL.write(ch2_data, 0x1)
        tlim = REF_CLK / self.chfreqs[channel]
        self.chdcs[channel] = pwv / tlim

    def pg_set_delay(self, channel, delay):  #Delay in seconds
        delv = self.calc_delay(delay)
        self.PG_UTIL.write(ch2_data, 0x0)
        self.PG_AUX[channel].write(ch2_data, delv)
        self.chdelays[channel] = delay
        self.PG_UTIL.write(ch2_data, 0x1)

    def encode_phase_inc(self, freq):
        enc = int((freq * 2**PHASE_BIT_DEPTH) / REF_CLK)
        lsb = enc & 0xFFFFFFFF
        msb = (enc >> 32) & 0xFFFF
        return [lsb, msb]

    def calc_dc_lim(self, freq, dc):  #dc from 0 to 1
        dc_t = int(REF_CLK / freq)
        return int(dc_t * dc)

    def calc_delay(self, delay):
        return int(delay * REF_CLK)

    def TT_concat48(self, lsb, msb):
        retval = (lsb & 0xFFFFFFFF) | ((msb & 0xFFFF) << 32)
        return retval

    def TT_slice48(self, xsl):
        lsb = xsl & 0xFFFFFFFF
        msb = (xsl >> 32) & 0xFFFF
        return [lsb, msb]

    def TT_set_timeout(self, time):
        tval = time * REF_CLK
        lsb, msb = self.TT_slice48(int(tval))
        self.TT_TIME_OUT.write(ch1_data, lsb)
        self.TT_TIME_OUT.write(ch2_data, msb)

    def TT_reset(self):
        self.TT_UTIL.write(ch1_data, 0b0)

    def TT_activate(self, timeout):
        self.TT_set_timeout(timeout)
        self.TT_UTIL.write(ch1_data, 0b1)

    def TT_read_times(self):
        retvals = []
        for i in range(4):
            lsb = self.TT_DET[i].read(ch1_data)
            msb = self.TT_DET[i].read(ch2_data)
            retvals.append(self.TT_concat48(lsb, msb))
        return retvals

    def TT_read_states(self):
        return self.TT_UTIL.read(ch2_data) & 0xF

    def TT_read_rdy(self):
        return (self.TT_UTIL.read(ch2_data) >> 4) & 0x1

    def TT_proc(self):
        print("Waiting for data")
        if (self.TT_read_rdy() == 0):
            print("1")
            while (self.TT_read_rdy() == 0):
                pass
        else:
            print("0")
            while (self.TT_read_rdy() == 1):
                pass
        vals = self.TT_read_times()
        states = self.TT_read_states()
        return {
            'T1': vals[0] * (1 / REF_CLK),
            'T2': vals[1] * (1 / REF_CLK),
            'T3': vals[2] * (1 / REF_CLK),
            'T4': vals[3] * (1 / REF_CLK),
            'T1s': (states & 1),
            'T2s': ((states >> 1) & 0b1),
            'T3s': ((states >> 2) & 0b1),
            'T4s': ((states >> 3) & 0b1)
        }

    def DD_idelay(self, channel, tap, stage):
        print("Setting input delay on channel " + str(channel) +
              " dline tap of " + str(tap) + " with " + str(stage) +
              " stage(s).")
        self.iDD_UTIL[channel].write(ch1_data, 0x0)
        sleep(slt)
        self.iDD_UTIL[channel].write(ch1_data, 0x1)
        self.iDD_DATA[channel].write(ch1_data, tap)
        self.iDD_DATA[channel].write(ch2_data, stage)
Ejemplo n.º 24
0
def solve(boardstr, seed=12345, zero_padding=False):
    print('boardstr:')
    print(boardstr)
    print('seed:')
    print(seed)
    print('')

    # ボード文字列から X, Y, Z を読んでくる
    size_x = (ord(boardstr[1]) - ord('0')) * 10 + (ord(boardstr[2]) - ord('0'))
    size_y = (ord(boardstr[4]) - ord('0')) * 10 + (ord(boardstr[5]) - ord('0'))
    size_z = (ord(boardstr[7]) - ord('0'))

    # Overlay 読み込み
    OL = Overlay('pynqrouter.bit')
    OL.download()
    print(OL.ip_dict)
    print('Overlay loaded!')

    # MMIO 接続 (pynqrouter)
    mmio = MMIO(int(PL.ip_dict[IP][0]), int(PL.ip_dict[IP][1]))

    # MMIO 接続 & リセット (LED)
    mmio_led = MMIO(int(PL.ip_dict[IP_LED][0]), int(PL.ip_dict[IP_LED][1]))
    mmio_led.write(0, 0)

    # 入力データをセット
    imem = pack(boardstr)
    for i in range(len(imem)):
        mmio.write(OFFSET_BOARD + (i * 4), imem[i])

    mmio.write(OFFSET_SEED, seed)

    # スタート
    # ap_start (0 番地の 1 ビット目 = 1)
    mmio.write(0, 1)
    print('Start!')
    time_start = time.time()

    # ap_done (0 番地の 2 ビット目 = 2) が立つまで待ってもいいが
    #   done は一瞬だけ立つだけのことがあるから
    # ap_idle (0 番地の 3 ビット目 = 4) を待ったほうが良い
    iteration = 0
    while (mmio.read(0) & 4) == 0:
        # 動いてるっぽく見えるようにLチカさせる
        iteration += 1
        if iteration == 10000:
            mmio_led.write(0, 3)
        elif 20000 <= iteration:
            mmio_led.write(0, 12)
            iteration = 0

    # 完了の確認
    print('Done!')
    print('control:', mmio.read(0))
    time_done = time.time()
    elapsed = time_done - time_start
    print('elapsed:', elapsed)
    print('')

    # 状態の取得
    status = int(mmio.read(OFFSET_STATUS))
    print('status:', status)
    if status != 0:
        # 解けなかったらLEDを消す
        mmio_led.write(0, 0)
        sys.stderr.write('Cannot solve it!\n')
        return {'solved': False, 'solution': '', 'elapsed': -1.0}
    print('Solved!')

    # 解けたらLEDを全部つける
    mmio_led.write(0, 15)

    # 出力
    omem = []
    for i in range(len(imem)):
        omem.append(mmio.read(OFFSET_BOARD + (i * 4)))
    boards = unpack(omem)

    # 回答の生成
    solution = ('SIZE ' + str(size_x) + 'X' + str(size_y) + 'X' + str(size_z) +
                '\n')
    for z in range(size_z):
        solution += ('LAYER ' + str(z + 1) + '\n')
        for y in range(size_y):
            for x in range(size_x):
                if x != 0:
                    solution += ','
                i = ((x * MAX_X + y) << BITWIDTH_Z) | z
                if zero_padding:
                    solution += '{0:0>2}'.format(boards[i])  # 2桁の0詰め
                else:
                    solution += str(boards[i])  # 普通に表示
            solution += '\n'

    return {'solved': True, 'solution': solution, 'elapsed': elapsed}
Ejemplo n.º 25
0
#!/usr/bin/python3
from pynq import Overlay
from pynq import Xlnk
import numpy as np
import time
xlnk = Xlnk()

ol = Overlay("vpu_ddr4_100M.bit")
for i in ol.ip_dict:
    print(i)
ol.download()

#gpio=ol.axi_gpio_0
#gpio.write(0,0xF);
#
Ejemplo n.º 26
0
class SP_TOOLS:
    def __init__(self):
        """Initializes the hardware by first loading and configuring the FPGA with the hardware design and then by creating handles for each AXI GPIO block that allows connection from the processing system to the FPGA fabric.

        """
        #Import FPGA configuration file and download
        self.OV = Overlay("Single_Photons/SP_OVERLAY.bit", 0)
        self.OV.download()
        ##Initialize pulse counter
        axi_offset = 0
        #Initialize data channels
        self.PC_DAT = []  #Holds all the handles for the data GPIO blocks
        #Initialize AXI GPIO modules
        for i in range(4):
            self.PC_DAT.append(
                MMIO(axi_base_addr + (axi_offset * axi_range), axi_range))
            self.PC_DAT[i].write(ch1_dir, agpi)  #ch1 is counts
            self.PC_DAT[i].write(ch2_dir, agpo)  #Ch2 is window
            self.PC_DAT[i].write(ch2_data, 0xFFFFFFFF)
            plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
            axi_offset += 1

        #Initialize utility channels
        self.PC_UTIL = []  #Utility GPIO modules (containing reset signal and
        for i in range(4):
            self.PC_UTIL.append(
                MMIO(axi_base_addr + ((axi_offset) * axi_range), axi_range))
            self.PC_UTIL[i].write(ch1_dir, agpo)  #Reset
            self.PC_UTIL[i].write(ch1_data, 0x0)  #Hold in reset
            self.PC_UTIL[i].write(ch2_dir, agpi)  #Ready
            plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
            axi_offset += 1
        #Initialize trigger controller
        self.T_UTIL = MMIO(0x41200000, 0x10000)
        self.T_UTIL.write(ch2_dir, 0x0)
        self.T_UTIL.write(ch2_data, 0x0)
        self.T_RDY_UTIL = MMIO(0x41210000, 0x10000)
        self.T_RDY_UTIL.write(ch1_dir, 0x1)
        ##Initialize single channel inter-rising_edge detection
        self.ST_DATA = MMIO(axi_base_addr + axi_offset * axi_range, axi_range)
        plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        self.ST_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range,
                            axi_range)
        plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        ##Initialize interchannel coincidence timer
        self.CT_DATA = MMIO(axi_base_addr + axi_offset * axi_range, axi_range)
        plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        self.CT_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range,
                            axi_range)
        plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        ##Initialize time tagger
        self.TT_CONFIG = MMIO(axi_base_addr + (axi_offset * axi_range),
                              axi_range)
        plog.info("TT_CONFIG: " + hex(axi_base_addr +
                                      (axi_offset * axi_range)))
        axi_offset += 1
        self.TT_DATA0 = MMIO(axi_base_addr + (axi_offset * axi_range),
                             axi_range)
        plog.info("TT_DATA0: " + hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        self.TT_DATA1 = MMIO(axi_base_addr + (axi_offset * axi_range),
                             axi_range)
        plog.info("TT_DATA1: " + hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        self.TT_DELAY_DATA = MMIO(axi_base_addr + (axi_offset * axi_range),
                                  axi_range)
        plog.info("TT_DELAY: " + hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        self.TT_UTIL = MMIO(axi_base_addr + (axi_offset * axi_range),
                            axi_range)
        plog.info("TT_UTIL: " + hex(axi_base_addr + (axi_offset * axi_range)))
        axi_offset += 1
        ##Initialize Pulse generator
        iDC = 0.5  #Initial duty cycle and frequency
        iFREQ = 440.0
        ph0, ph1 = self.encode_phase_inc(iFREQ)
        iDCenc = self.calc_dc_lim(iFREQ, iDC)
        self.PG_PH = [
        ]  #AXI GPIO handles for phase increments for each channel
        self.PG_AUX = [
        ]  #AXI GPIO handles for duty cycle(ch1) and delay(ch2) of the GPIO block
        self.chfreqs = [440.0, 440.0, 440.0,
                        440.0]  #Initial frequency settings of each channel
        self.chdcs = [0.5, 0.5, 0.5, 0.5]  #Initial duty cycles of each channel
        self.chdelays = [0, 0, 0, 0]  #Initial delays of each channel
        for i in range(4):  #Duty length and delay
            tdc = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            tdc.write(ch1_dir, agpo)
            tdc.write(ch1_data, iDCenc)
            tdc.write(ch2_dir, agpo)
            tdc.write(ch2_data, 0x0)
            self.PG_AUX.append(tdc)
            plog.info("DC" + str(i) + " " + hex(axi_base_addr +
                                                (axi_offset * axi_range)))
            axi_offset += 1
            self.chdcs[i] = 0.5
        for i in range(4):  #Phase increments
            tap = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            tap.write(ch1_dir, agpo)
            tap.write(ch2_dir, agpo)
            tap.write(ch1_data, ph0)
            tap.write(ch2_data, ph1)
            self.PG_PH.append(tap)
            plog.info("PH" + str(i) + " " + hex(axi_base_addr +
                                                (axi_offset * axi_range)))
            axi_offset += 1
            self.chfreqs[i] = 440.0
        self.PG_UTIL = MMIO(axi_base_addr + (axi_offset * axi_range),
                            0x10000)  #increment load and master reset
        plog.info("PGUTIL: " + hex(axi_base_addr + (axi_offset * axi_range)))
        self.PG_UTIL.write(ch1_dir, agpo)
        self.PG_UTIL.write(ch2_dir, agpo)
        self.PG_UTIL.write(ch1_data, 0x0)  #SEt loader to 0
        self.PG_UTIL.write(ch2_data, 0x0)  #Hold in reset
        #Routine to write initial phase increments
        self.PG_UTIL.write(ch2_data, 0x1)
        self.PG_UTIL.write(ch1_data, 0xF)
        sleep(slt)
        self.PG_UTIL.write(ch1_data, 0x0)
        #Channel enable controller
        #The enable controller is a tristate controlled buffer which when disabling the output places the channels into
        #a high impedance state allowing other devices connected to the same output to assert control (also to prevent the pynq from blowing up if its connected to something that also outputs signals)
        self.T_UTIL.write(ch1_dir, 0x0)
        self.T_UTIL.write(ch1_data, 0xF)  #SEt all channels to high impedance
        axi_offset += 1
        self.pg_ch_stat = 0xF
        #self.PG_UTIL.write(ch2_data,0x0)
        ##Initialize IDELAY
        self.iDD_DATA = [
        ]  #AXI GPIO handles for delay data GPIO blocks (which control tap and stages)
        self.iDD_UTIL = []  #AXI GPIO handles for delay utility (reset)
        for i in range(6):
            tempdel = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range)
            plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
            tempdel.write(ch1_data, 0x0)
            tempdel.write(ch2_data, 0x0)
            self.iDD_DATA.append(tempdel)
            axi_offset += 1
        for i in range(6):
            temputil = MMIO(axi_base_addr + (axi_offset * axi_range),
                            axi_range)
            plog.info(hex(axi_base_addr + (axi_offset * axi_range)))
            temputil.write(ch1_data, 0x1)
            temputil.write(ch2_data, 0x1)
            self.iDD_UTIL.append((temputil))
            axi_offset += 1

    ####------------------PHOTON COUNTER---------------------------------------------------####
    def pc_set_window(
            self, window,
            channels):  #Channels is 4 bit integer, window is in seconds
        """Sets the pulse counter counting window period



        Parameters
        ----------
        window : :class:`float`
            Time to count for (in seconds)
        channels : :class:`int`
            Channels to count on (binary encoded)


        """
        m = 0B0001
        wval = int(window * TIMER_CLK)
        if (wval > 0xFFFFFFFF or wval <= 0):
            plog.error(
                "Window must be between 34.35973836s and 0, cannot be 0 seconds"
            )
            return
        for i in range(4):
            if ((0B0001 << i) & channels) != 0:
                self.PC_DAT[i].write(ch2_data, wval)

    def pc_wait_for_rdy(self, channel, mode):
        """Hangs the thread until the counter has data ready to be acquired

        Parameters
        ----------
        channel : :class:`int`
            Channel to wait for
        mode : :class:`int`
            Mode of operation, 0 for fixed window mode, or 1 for external stop trigger mode


        """
        if mode == 0:  #If when the counter stops is defined by time window
            if (self.PC_UTIL[channel].read(ch2_data) == 0):
                while (self.PC_UTIL[channel].read(ch2_data) == 0):
                    pass
            else:
                while (self.PC_UTIL[channel].read(ch2_data) == 1):
                    pass
        else:  #If when the counter stops is defined by an external stop signal
            if (self.T_RDY_UTIL.read(ch1_data) == 0):
                while (self.T_RDY_UTIL.read(ch1_data) == 0):
                    pass

    def pc_ex_triggered(self, window):
        """Start counting function for externally supplied start signal

        Parameters
        ----------
        window : :class:`int`
            Counting window (in seconds)

        Returns
        -------
        :class:`list` of `int`
            List of counts for each channel

        """
        #Set the window of all channels to specified window value and start the counter
        self.pc_set_window(window, 0xF)
        self.T_UTIL.write(
            ch2_data, 0x1
        )  #Set the external trigger block to activate the counter once trigger pulse occurs
        #Wait till the counter finishes counting
        self.pc_wait_for_rdy(0, 0)
        retval = []
        for i in range(4):
            retval.append(self.pc_read_counts(
                i))  #Append each channels counts to output array
        self.T_UTIL.write(ch2_data, 0x0)
        return retval

    def pc_ex_trig_stop(self):
        """Enables and waits for the pulse counter to stop counting (based off when the stop signal is pulsed) and returns the counts for each channel.

        Returns
        -------
        :class:`list` of `int`
            Array of counts for each channel
        """
        # Set the trigger controller to start the counter when the start trigger is acquired
        # and stop the counter when the stop signal is acquired

        self.T_UTIL.write(ch2_data, 0x3)
        #Set the window for all channels to maximum (as window is unknown in this mode and externally defined)
        for i in range(4):
            self.PC_DAT[i].write(ch2_data, 0xFFFFFFFF)
        #Wait until the stop trigger is acquired
        self.pc_wait_for_rdy(0, 1)
        retval = []
        #Read, store and return all count values as an array
        for i in range(4):
            retval.append(self.pc_read_counts(i))
        self.T_UTIL.write(ch2_data, 0x0)
        return retval

    def pc_enable_channels(self, channels):  #channels a 4 bit integer
        """Enable counting on supplied channels

        Parameters
        ----------
        channels : :class:`int`
            Channels to enable counting on (binary encoded)


        """
        #Enable any channel that is indicated by a 1 in the 4 bit integer
        for i in range(4):
            if ((0B0001 << i) & channels) != 0:
                self.PC_UTIL[i].write(ch1_data, 0x1)

    def pc_disable_channels(self, channels):  #Channels a 4 bit integer
        """Disable counting on supplied channels

        Parameters
        ----------
        channels : :class:`int`
            Channels to disable counting on (binary encoded)



        """
        #Disable any channel that is indicated by a 1 in the 4 bit integer
        for i in range(4):
            if ((0B0001 << i) & channels) != 0:
                self.PC_UTIL[i].write(ch1_data, 0x0)

    def pc_read_counts(self, channel):
        """Read counts on channel specified

        Parameters
        ----------
        channel : :class:`int`
            Channel to read counts of (0-3)

        Returns
        -------
        :class:`int`
            Number of counts

        """
        return self.PC_DAT[channel].read(ch1_data)

    ####----------------------------------------------------------------------------------####
    ####------------------Single line inter-rising_edge timer-----------------------------####
    def st_arm_and_wait(self):
        """Arm single channel inter-rising_edge timer and hang until time data is ready to be acquired

        Returns
        -------
        :class:`float`
            Time between detected rising edges (in seconds)
        """
        self.ST_UTIL.write(ch1_data, 0x1)  #Enable
        while (self.ST_DATA.read(ch2_data) & 0b1) == 0:  #Wait for ready
            pass
        op = self.ST_DATA.read(ch1_data) / REF_CLK  #Read time
        dels = self.ST_DATA.read(
            ch2_data)  #Read start and finish delay line values
        #Count the number of ones in both start and finish delay line states, multiply with the delay resolution and add start delay value and subtract stop delay value
        #to the coarse time
        op = op + (self.uencode((dels & 0b111111110) >> 1, 8) - self.uencode(
            (dels & 0b11111111000000000) >> 9, 8)) * FTIME
        self.ST_UTIL.write(ch1_data, 0x0)
        return op

    ####----------------------------------------------------------------------------------####
    ####------------------Two channel photon coincidence timer----------------------------####
    def ct_arm_and_wait(self, first):
        """Arm two channel rising edge coincidence timer and hang until time data is ready (On channel 0 and 1)

        Parameters
        ----------
        first : :class:`int`
            Defines which channel to listen for start rising edge (0 or 1)

        Returns
        -------
        :class:`float`
            Time between rising edges (in seconds)

        """
        #Set which channel the hardware is listening to for the start pulse and take the submodule out of reset enabling it
        self.CT_UTIL.write(ch2_data, first)
        self.CT_UTIL.write(ch1_data, 0x1)
        #Wait for the coincidence time to be ready (waits until the second pulse)
        while (self.CT_DATA.read(ch2_data) & 0b1) == 0:
            pass
        #Read coarse time
        tm = self.CT_DATA.read(ch1_data) / REF_CLK
        dels = self.CT_DATA.read(
            ch2_data
        )  #Read delay line states including the data ready bit which must be shifted out below
        #Include fine time offsets with the coarse time
        tm = tm + (self.uencode((dels & 0b111111110) >> 1, 8) - self.uencode(
            (dels & 0b11111111000000000) >> 9, 8)) * FTIME
        self.CT_UTIL.write(
            ch1_data, 0x0)  #Disable coincidence timer by placing it in reset
        return tm

    ####---------------------Signal generator---------------------------------------------####

    def pg_disable(self):
        """Disable signal generator, holds the submodule in reset bringing all outputs low


        """
        self.PG_UTIL.write(ch2_data, 0x0)

    def pg_enable(self):
        """Enables the signal generator, takes hardware submodule out of reset


        """
        self.PG_UTIL.write(ch2_data, 0x1)

    def pg_enable_channel(self, channel):
        """Enable specified channel, takes channel out of tristate high Z mode

        Parameters
        ----------
        channel : :class:`int`
            Channel to enable (0-3)



        """
        #As the enable lines are active low, must set the channel specified's place from a 1 to a 0.
        self.pg_ch_stat = ~(~self.pg_ch_stat | (0B0001 << channel))
        self.T_UTIL.write(ch1_data, self.pg_ch_stat)

    def pg_disable_channel(self, channel):
        """Disable specified channel, places channel into tristate high Z mode

        Parameters
        ----------
        channel : :class:`int`
            Channel to disable (0-3)



        """
        self.pg_ch_stat = self.pg_ch_stat | (0b0001 << channel)
        self.T_UTIL.write(ch1_data, self.pg_ch_stat)

    def pg_set_channel_freq(self, channel, freq):
        """Sets the frequency of the specified channel

        Parameters
        ----------
        channel : :class:`int`
            Channel to set frequency of (0-3)
        freq : :class:`float`
            Frequency to set channel to (in Hz)


        """
        nenc = self.encode_phase_inc(
            2 * freq
        )  #Calculate the phase increment value required by the DDS Compiler
        self.PG_PH[channel].write(
            ch1_data,
            nenc[0])  #Write LSB(31 downto 0) of total 48 bits to the DDS
        self.PG_PH[channel].write(
            ch2_data, nenc[1])  #Write MSB(47 downto 32) of 48 bits to the DDS
        self.PG_UTIL.write(
            ch1_data,
            0xF)  #Enable loading of phase increments to the DDS Compiler
        sleep(slt)
        self.PG_UTIL.write(ch1_data, 0x0)
        #Calculate duty cycle counter limit
        newdc = self.calc_dc_lim(freq, self.chdcs[channel])
        self.PG_UTIL.write(ch2_data, 0x0)  #Disable signal generator
        #Write new settings to the hardware
        self.PG_AUX[channel].write(ch1_data, newdc)
        self.PG_AUX[channel].write(ch2_data,
                                   self.calc_delay(self.chdelays[channel]))
        self.PG_UTIL.write(ch2_data, 0x1)  #Re-enable signal generator
        self.chfreqs[
            channel] = freq  #Synchronzie the host setting of the frequency to the frequency setting on the hardware

    def pg_set_dc(self, channel, dc):  #Dc from 0 to 1
        """Sets the duty cycle of the specified channel

        Parameters
        ----------
        channel : :class:`int`
            Channel to set the duty cycle of (0-3)
        dc : :class:`float`
            Duty cycle to set the specified channel to (0-1)



        """
        #Calculate the duty cycle counter limit from new duty cycle value
        dcenc = self.calc_dc_lim(self.chfreqs[channel], dc)
        self.PG_UTIL.write(ch2_data, 0x0)  #dsaible signal generator
        self.PG_AUX[channel].write(ch1_data,
                                   dcenc)  #WRite new duty cycle counter value
        self.PG_UTIL.write(ch2_data, 0x1)  #Re-enable
        self.chdcs[
            channel] = dc  #Sync the host setting of the duty cycle to the duty cycyel setting on hardware

    def pg_set_pw(self, channel, pw):
        """Sets the pulse width of the channel specified

        Parameters
        ----------
        channel : :class:`int`
            Channel to set pulse width of (0-3)
        pw : :class:`float`
            Pulse width to set channel to (in milliseconds)



        """
        pwv = self.calc_delay(
            pw / 1000)  #Calculating duty cycle counter value from time
        self.PG_UTIL.write(ch2_data, 0x0)  #Disable signal generator
        self.PG_AUX[channel].write(
            ch1_data,
            pwv)  #Write the new duty cycle counter value to the hardware
        self.PG_UTIL.write(ch2_data, 0x1)  #Re-enable signal generator
        #Calculate what the new duty cycle of the signal is in 0-1 rather than pulse width and save that as the host setting
        tlim = REF_CLK / self.chfreqs[channel]
        self.chdcs[channel] = pwv / tlim

    def pg_set_delay(self, channel, delay):  #Delay in seconds
        """Sets the delay of the specified channel

        Parameters
        ----------
        channel : :class:`int`
            Channel to set delay of (0-3)
        delay : :class:`float`
            The delay the specified channel is to be set to(in seconds)



        """
        delv = self.calc_delay(
            delay
        )  #Calculate the counter value the delay counter must count upto before enabling the channel
        self.PG_UTIL.write(
            ch2_data, 0x0
        )  #Disable the signal generator, write the delay value to the delay controller
        self.PG_AUX[channel].write(ch2_data, delv)
        self.chdelays[channel] = delay  #Save the delay setting
        self.PG_UTIL.write(ch2_data, 0x1)  #Restart the signal generator

    def encode_phase_inc(self, freq):
        """Converts a supplied frequency to a phase increment amount that is supplied to the DDS modules to produce the necessary sine wave.
        Internally used function, should not be called directly.

        Parameters
        ----------
        freq : :class:`float`
            Frequency in Hz

        Returns
        -------
        :class:`list` of :class:`float`
            48 bit phase increment, first element is 32 bit LSB, second element is 16 bit MSB
        :class:`float`
            is 32 bit LSB
        :class:`float`
            is 16 bit MSB

        """
        enc = int(
            (freq * 2**PHASE_BIT_DEPTH) / REF_CLK
        )  #Calculate the phase increment of the DDS to produce the required frequency
        #Split the 48 bit number into 32 and 16 bits
        lsb = enc & 0xFFFFFFFF
        msb = (enc >> 32) & 0xFFFF
        return [lsb, msb]

    def calc_dc_lim(self, freq, dc):  #dc from 0 to 1
        """Calculates the count value of the hardware counter where the output changes from high to low after this count value is passed by the hardware counter

        Parameters
        ----------
        freq : :class:`float`
            Frequency of the signal currently being emitted.
        dc : :class:`float`
            Duty cycle value (0-1)

        Returns
        -------
        :class:`int`
            Count value the hardware counter counts up to before switching the output signal from high to low.

        """
        dc_t = int(REF_CLK / freq)
        return int(dc_t * dc)

    def calc_delay(self, delay):
        """Calculates the delay timer count value from a time in seconds

        Parameters
        ----------
        delay : :class:`float`
            Delay time in seconds

        Returns
        -------
        :class:`int`
            Count limit for delay timer

        """
        return int(delay * REF_CLK)

    def TT_wait_for_rdy(self):
        """Wait until time tagger tags each channel or times out (Hangs the thread)



        """
        if (self.TT_UTIL.read(ch2_data) & 0b1) == 0:
            while (self.TT_UTIL.read(ch2_data) & 0b1) == 0:
                pass
        else:
            while (self.TT_UTIL.read(ch2_data) & 0b1) == 1:
                pass

    def TT_set_timeout(self, timeval):
        """Set the time out of the time tagger

        Parameters
        ----------
        timeval : :class:`float`
            Time out in seconds


        """
        tcount = timeval * REF_CLK  #Calculate time out counter value
        self.TT_CONFIG.write(
            ch1_data,
            int(tcount))  #Write the new counter value to the time tagger

    def TT_activate(self, time):
        """Sets the time out of the time tagger and pulls the time tagger out of reset, activating it

        Parameters
        ----------
        time : :class:`float`
            Time out in seconds



        """
        self.TT_set_timeout(time)
        self.TT_UTIL.write(ch1_data, 0x1)

    def TT_proc(self):
        """Time tagger sampling process, waits until time tagger has data ready, then calculates time intervals for each channel from T0 and includes fine times and returns a time interval for each channel and which channels timed out.

        Returns
        -------
        :class:`dict`
            A dictionary containing time intervals ('T1'...'T4') and boolean time outs ('T1s'...'T4s')

        """
        self.TT_wait_for_rdy(
        )  #Wait until the time tagger has finished tagging or has timed out
        stimet0 = self.uencode(
            self.TT_DELAY_DATA.read(ch2_data),
            8) * FTIME  #Calculate the fine time offset of the t0 signal
        dels = self.TT_DELAY_DATA.read(
            ch1_data
        )  #Delay line states for channels 0-3 (Each is concatenated in binary)
        #Calculating the fine time offsets for each channel
        stimet1 = self.uencode((dels & 0xFF), 8) * FTIME
        stimet2 = self.uencode((dels & 0xFF00) >> 8, 8) * FTIME
        stimet3 = self.uencode((dels & 0xFF0000) >> 16, 8) * FTIME
        stimet4 = self.uencode((dels & 0xFF000000) >> 24, 8) * FTIME
        #Include fine time offsets with the coarse times
        ctime1 = self.TT_DATA0.read(ch1_data) / REF_CLK - stimet1 + stimet0
        ctime2 = self.TT_DATA0.read(ch2_data) / REF_CLK - stimet2 + stimet0
        ctime3 = self.TT_DATA1.read(ch1_data) / REF_CLK - stimet3 + stimet0
        ctime4 = self.TT_DATA1.read(ch2_data) / REF_CLK - stimet4 + stimet0
        timeouts = (self.TT_UTIL.read(ch2_data) & 0b11110
                    ) >> 1  #Read time outs and shift out the data ready line
        #Store all information in dictionary and return it
        outdict = {
            "T1": ctime1,
            "T2": ctime2,
            "T3": ctime3,
            "T4": ctime4,
            "T1s": timeouts & 0b1,
            "T2s": (timeouts & 0b10) >> 1,
            "T3s": (timeouts & 0b100) >> 2,
            "T4s": (timeouts & 0b1000) >> 3
        }
        return outdict

    def TT_reset(self):
        """Puts time tagger into reset, stopping it


        """
        self.TT_UTIL.write(ch1_data, 0x0)

    def DD_idelay(self, channel, tap, stage):
        """Sets the input delay of the specified channel by configuring the delay line taps and the number of delay line stages to include

        Parameters
        ----------
        channel : :class:`int`
            Channel to delay (0-3)
        tap : :class:`int`
            Delay line tap (0-31)
        stage : :class:`int`
            Number of delay line stages (0-7)


        """
        plog.info("Setting input delay on channel " + str(channel) +
                  " dline tap of " + str(tap) + " with " + str(stage) +
                  " stage(s).")
        self.iDD_UTIL[channel].write(ch1_data,
                                     0x0)  #Reset and unreset the delay block
        sleep(slt)
        self.iDD_UTIL[channel].write(ch1_data, 0x1)
        self.iDD_DATA[channel].write(
            ch1_data, tap)  #Load the delay line tap for the top stage
        self.iDD_DATA[channel].write(
            ch2_data,
            stage)  #Select how many stages are activated below the top stage

    def uencode(self, val, length):
        """Calculates the number of binary ones in an integer of specified length

        Parameters
        ----------
        val : :class:`int`
            Arbitrary integer to get the number of binary ones from
        length : :class:`int`
            Length of the binary integer to include when counting up the ones.

        Returns
        -------
        :class:`int`
            The total number of ones within the binary length specified in the specified integer

        """
        cnt = 0
        for i in range(
                length
        ):  #Just counts how many ones in binary there are in the range specified by length
            if ((val >> i) & 0b1 == 1):
                cnt += 1
        return cnt
Ejemplo n.º 27
0
from pynq import Overlay

ol = Overlay("audiovideo.bit")
ol.download()

from time import sleep
from pynq.video import Frame, vga
from IPython.display import Image
from pynq.board import Switch
import numpy as np
import time
from pynq.board import Button
import os
import pylab as p
import sys
import cv2 
from pynq.pmods import PMOD_OLED

#oled configuration
oled = PMOD_OLED(1)
stream = ''

# get the Zybo switches
switches = [Switch(i) for i in range(4)]

# monitor configuration
video_out_res_mode = 0 # 640x480 @ 60Hz
frame_out_w = 1920
frame_out_h = 1080

# camera configuration
Ejemplo n.º 28
0
class ConvLayer(object):
    def __init__(self, layer, fm, dim, xlnk, runFactor=1, batchsize=1):
        self.layer = layer
        self.fm = fm
        self.dim = dim
        self.xlnk = xlnk
        self.runFactor = runFactor
        self.batchsize = batchsize

        self.COMPUTE = 0
        self.CONV_WEIGHT = 1

        self.ol = Overlay(
            os.path.dirname(os.path.realpath(__file__)) + "/bitstream/" +
            layer + ".bit")
        self.dma = self.ol.axi_dma_0
        self.ip = MMIO(self.ol.ip_dict[self.layer]['phys_addr'],
                       self.ol.ip_dict[self.layer]['addr_range'])

        self.wBuff = []
        self.initWeights()

        self.cmaOut = []
        self.cmaTemp = []
        for b in range(self.batchsize):
            self.cmaOut.append(
                self.xlnk.cma_array(shape=(self.fm * (self.dim**2), ),
                                    dtype=np.float32))
            self.allocaCmaTemp()

    def __call__(self, input):
        self.ol.download()

        self.dma.sendchannel.start()
        self.dma.recvchannel.start()

        full = [list() for b in range(self.batchsize)]

        r = 0
        while r < self.runFactor:
            self.ip.write(0x10, self.CONV_WEIGHT)
            self.ip.write(0x00, 1)  # ap_start

            self.dma.sendchannel.transfer(self.wBuff[r])
            self.dma.sendchannel.wait()

            b = 0
            while b < self.batchsize:
                self.ip.write(0x10, self.COMPUTE)

                self.ip.write(0x00, 1)  # ap_start

                self.dma.recvchannel.transfer(self.cmaTemp[b][r])
                self.dma.sendchannel.transfer(input[b])

                self.dma.sendchannel.wait()
                self.dma.recvchannel.wait()

                temp = self.cmaTemp[b][r].reshape(
                    (self.dim**2, int(self.fm / self.runFactor)))
                temp = temp.transpose()
                temp = temp.reshape(
                    int(self.fm / self.runFactor) * (self.dim**2))
                full[b] = np.concatenate((full[b], temp))

                b += 1

            r += 1

        b = 0
        while b < self.batchsize:
            full[b] = full[b].reshape(self.fm,
                                      (self.dim**2)).transpose().flatten()
            np.copyto(self.cmaOut[b], full[b])
            b += 1

        return self.cmaOut

    def allocaCmaTemp(self):
        t = []
        for i in range(self.runFactor):
            t.append(
                self.xlnk.cma_array(shape=(int(self.fm / self.runFactor) *
                                           (self.dim**2), ),
                                    dtype=np.float32))
        self.cmaTemp.append(t)

    def initWeights(self):
        w = np.load(
            os.path.dirname(os.path.realpath(__file__)) + "/weights/" +
            self.layer + "/W.npy")
        b = np.load(
            os.path.dirname(os.path.realpath(__file__)) + "/weights/" +
            self.layer + "/b.npy")

        w = w.reshape((self.runFactor, -1))
        b = b.reshape((self.runFactor, -1))

        for i in range(self.runFactor):
            buff = self.xlnk.cma_array(shape=(w[i].size + b[i].size, ),
                                       dtype=np.float32)
            np.concatenate((w[i], b[i]), out=buff)
            self.wBuff.append(buff)
Ejemplo n.º 29
0
class cv2pynq():
    MAX_WIDTH = 1920
    MAX_HEIGHT = 1080

    def __init__(self, load_overlay=True):
        #self.bitstream_name = None
        self.bitstream_name = "opencv.bit"
        self.bitstream_path = os.path.join(CV2PYNQ_BIT_DIR,
                                           self.bitstream_name)
        self.ol = Overlay(self.bitstream_path)
        self.ol.download()
        self.ol.reset()
        self.img_filters = self.ol.image_filters
        self.dmaOut = self.img_filters.axi_dma_0.sendchannel
        self.dmaIn = self.img_filters.axi_dma_0.recvchannel
        self.dmaOut.stop()
        self.dmaIn.stop()
        self.dmaIn.start()
        self.dmaOut.start()
        self.filter2DType = -1  # filter types: SobelX=0, SobelY=1, ScharrX=2, ScharrY=3, Laplacian1=4, Laplacian3=5
        self.filter2D_5Type = -1  # filter types: SobelX=0, SobelY=1,                     Laplacian5=4
        self.f2D = self.img_filters.filter2D_hls_0
        self.f2D.reset()
        self.f2D_5 = self.img_filters.filter2D_hls_5_0
        self.f2D_5.reset()

    def close(self):
        self.dmaOut.stop()
        self.dmaIn.stop()

    def Sobel(self, src, ddepth, dx, dy, dst, ksize):
        if (ksize == 3):
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if (dx == 1) and (dy == 0):
                if self.filter2DType != 0:
                    self.filter2DType = 0
                    self.f2D.r1 = 0x000100ff  #[-1  0  1]
                    self.f2D.r2 = 0x000200fe  #[-2  0  2]
                    self.f2D.r3 = 0x000100ff  #[-1  0  1]
            elif (dx == 0) and (dy == 1):
                if self.filter2DType != 1:
                    self.filter2DType = 1
                    self.f2D.r1 = 0x00fffeff  #[-1 -2 -1]
                    self.f2D.r2 = 0x00000000  #[ 0  0  0]
                    self.f2D.r3 = 0x00010201  #[ 1  2  1]
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(0)
            self.f2D.start()
            return self.filter2D(src, dst)
        else:  #ksize == 5
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if (dx == 1) and (dy == 0):
                if self.filter2D_5Type != 0:
                    self.filter2D_5Type = 0
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-6,  -12,  0,    12,   6,

                    0xfa, 0xf4, 0x00, 0x0c, 0x06, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    0,0,0]) #fill up to allign with 4
            elif (dx == 0) and (dy == 1):
                if self.filter2D_5Type != 1:
                    self.filter2D_5Type = 1
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -4,   -6,   -4,   -1,

                    0xff, 0xfc, 0xfa, 0xfc, 0xff, \
                    #-2,  -8,   -12,  -8,   -2,

                    0xfe, 0xf8, 0xf4, 0xf8, 0xfe, \
                    # 0,  0,    0,    0,    0,

                    0x00, 0x00, 0x00, 0x00, 0x00, \
                    # 2,  8,    12,   8,    2,

                    0x02, 0x08, 0x0c, 0x08, 0x02, \
                    # 1,  4,    6,    4,    1,

                    0x01, 0x04, 0x06, 0x04, 0x01, \
                    0,0,0]) #fill up to allign with 4
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(1)
            self.f2D_5.start()
            return self.filter2D(src, dst)

    def Laplacian(self, src, ddepth, dst, ksize):
        if ksize == 5:
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if self.filter2D_5Type != 4:
                self.filter2D_5Type = 4  # "Laplacian_5"
                self.f2D_5.par_V = bytes([ \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #4,   -8,   -24,  -8,   4,

                0x04, 0xf8, 0xe8, 0xf8, 0x04, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                0,0,0]) #fill up to allign with 4
            self.img_filters.select_filter(1)
            self.f2D_5.start()
            return self.filter2D(src, dst)
        else:  #ksize 1 or 3
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if ksize == 1:
                if (self.filter2DType != 4):
                    self.filter2DType = 4  # "Laplacian_1"
                    self.f2D.r1 = 0x00000100  #[ 0  1  0]
                    self.f2D.r2 = 0x0001fc01  #[ 1 -4  1]
                    self.f2D.r3 = 0x00000100  #[ 0  1  0]
            elif ksize == 3:
                if (self.filter2DType != 5):
                    self.filter2DType = 5  # "Laplacian_3"
                    self.f2D.r1 = 0x00020002  #[ 2  0  2]
                    self.f2D.r2 = 0x0000f800  #[ 0 -8  0]
                    self.f2D.r3 = 0x00020002  #[ 2  0  2]
            self.img_filters.select_filter(0)
            self.f2D.start()
            return self.filter2D(src, dst)

    def filter2D(self, src, dst):
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
Ejemplo n.º 30
0
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
###############################################################################

print("Running testXfFilter2D.py ...")
print("Loading overlay")
from pynq import Overlay
bs = Overlay(
    "/usr/local/lib/python3.6/dist-packages/pynq_cv/overlays/xv2filter2D.bit")
bs.download()

print("Loading xlnk")
from pynq import Xlnk
Xlnk.set_allocator_library(
    '/usr/local/lib/python3.6/dist-packages/pynq_cv/overlays/xv2filter2D.so')
mem_manager = Xlnk()

import pynq_cv.overlays.xv2filter2D as xv2
import numpy as np
import cv2
import time

import OpenCVUtils as cvu

print("Loading image ../images/bigBunny_1080.png")
Ejemplo n.º 31
0
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of [project] nor the names of its
#   contributors may be used to endorse or promote products derived from
#   this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from pynq import Overlay

o = Overlay("bismo.bit")
o.download()
Ejemplo n.º 32
0
import time
from pynq import Overlay
#import numpy as np
from pynq import Xlnk
M = 200
N = 200
xlnk = Xlnk();
overlay = Overlay('/home/xilinx/pynq/overlays/HMM_v4/HMM_v4_4.bit')
overlay.download()
HMM_test = overlay.HMM_Scoring_0

arr_m=xlnk.cma_array(shape=(200,),cacheable=0,dtype=int)
arr_n=xlnk.cma_array(shape=(200,),cacheable=0,dtype=int)
arr_x=xlnk.cma_array(shape=(200,),cacheable=0,dtype=int)

s1 = "gcgagcgaactgcggatagttacactaacacacgaggcacgtggttgggagttacggccatgcaatggatagctcctgcatgatcggttattatacagcccattttgggcgccttccaaaggatctacttatcagaaggggtggtgccgcataactctgaccggtgggcgtagtcatagcagacttttgccgggaacgca"
s2 = "tggtccatctgcttggtggcagccgcaagatgccaattattggcgcggtcgacggggctgctatctgaatatcatatggtcttcacggagacaggaacttagcaaggtactaatcccacgcaaagtctttttttcaaaaatccagtctagtcctattatatatcctcggaaaacggtattaggacatcgggtacattcta"
s3 = "tttattgtttttgatctcgcgtctcaaagtagctccgacacacaagcggcccttggagactgctcccgagtgcctaggggcatttggtacaaggcggttataaaacgacgacctttccccttagtgcacctgggcaggctcacaccattcctccaccgtgtgtattatttgaggggaaggattctcctgtggcggctctt"
s4 = "tcaggacccaaggaggtatcaagattggaagattgtctccaggttctataggcaaaatgcaccgccctcaacggccagatgccggccgcagacttagatatgaatagaatcgggtcaagctctgctacatagattctcctccgtgctcgataactgccggagtttacgcgataagattagcggcactcttcgctgggacc"
arr1 = list(s1)
arr2 = list(s2)
arr3 = list(s3)
b1 = {}
b2 = {}
b3 = {}

arr1 = [w.replace('a', '1')for w in arr1]
arr1 = [w.replace('c', '2') for w in arr1]
arr1 = [w.replace('g', '3') for w in arr1]
arr1 = [w.replace('t', '4') for w in arr1]
arr2 = [x.replace('a', '1')for x in arr2]
Ejemplo n.º 33
0
class cv2pynq():
    MAX_WIDTH = 1920
    MAX_HEIGHT = 1080

    def __init__(self, load_overlay=True):
        self.bitstream_name = None
        self.bitstream_name = "cv2pynq03.bit"
        self.bitstream_path = os.path.join(CV2PYNQ_BIT_DIR,
                                           self.bitstream_name)
        self.ol = Overlay(self.bitstream_path)
        self.ol.download()
        self.ol.reset()
        self.xlnk = Xlnk()
        self.partitions = 10  #split the cma into partitions for pipelined transfer
        self.cmaPartitionLen = self.MAX_HEIGHT * self.MAX_WIDTH / self.partitions
        self.listOfcma = [
            self.xlnk.cma_array(shape=(int(self.MAX_HEIGHT / self.partitions),
                                       self.MAX_WIDTH),
                                dtype=np.uint8) for i in range(self.partitions)
        ]
        self.img_filters = self.ol.image_filters
        self.dmaOut = self.img_filters.axi_dma_0.sendchannel
        self.dmaIn = self.img_filters.axi_dma_0.recvchannel
        self.dmaOut.stop()
        self.dmaIn.stop()
        self.dmaIn.start()
        self.dmaOut.start()
        self.filter2DType = -1  # filter types: SobelX=0, SobelY=1, ScharrX=2, ScharrY=3, Laplacian1=4, Laplacian3=5
        self.filter2D_5Type = -1  # filter types: SobelX=0, SobelY=1,                     Laplacian5=4
        self.filter2DfType = -1  # filter types: blur=0, GaussianBlur=1
        self.ffi = FFI()
        self.f2D = self.img_filters.filter2D_hls_0
        self.f2D.reset()
        self.f2D_5 = self.img_filters.filter2D_hls_5_0
        self.f2D_5.reset()
        self.f2D_f = self.img_filters.filter2D_f_0
        self.f2D_f.reset()
        self.erodeIP = self.img_filters.erode_hls_0
        self.erodeIP.reset()
        self.dilateIP = self.img_filters.dilate_hls_0
        self.dilateIP.reset()
        self.cmaBuffer_0 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer0 = self.cmaBuffer_0.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer0.init(self.cmaBuffer_0)
        self.cmaBuffer_1 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer1 = self.cmaBuffer_1.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer1.init(self.cmaBuffer_1)
        self.cmaBuffer_2 = self.xlnk.cma_array(
            shape=(self.MAX_HEIGHT * 4, self.MAX_WIDTH),
            dtype=np.uint8)  # *4 for CornerHarris return
        self.cmaBuffer2 = self.cmaBuffer_2.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer2.init(self.cmaBuffer_2)
        self.CannyIP = self.img_filters.canny_edge_0
        self.CannyIP.reset()
        #self.cornerHarrisIP = self.img_filters.CornerHarris_hls_0
        #self.cornerHarrisIP.reset()

    def close(self):
        #self.dmaOut.stop()
        #self.dmaIn.stop()
        self.cmaBuffer_0.close()
        self.cmaBuffer_1.close()
        self.cmaBuffer_2.close()
        for cma in self.listOfcma:
            cma.close()

    def Sobel(self, src, ddepth, dx, dy, dst, ksize):
        if (ksize == 3):
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if (dx == 1) and (dy == 0):
                if self.filter2DType != 0:
                    self.filter2DType = 0
                    self.f2D.r1 = 0x000100ff  #[-1  0  1]
                    self.f2D.r2 = 0x000200fe  #[-2  0  2]
                    self.f2D.r3 = 0x000100ff  #[-1  0  1]
            elif (dx == 0) and (dy == 1):
                if self.filter2DType != 1:
                    self.filter2DType = 1
                    self.f2D.r1 = 0x00fffeff  #[-1 -2 -1]
                    self.f2D.r2 = 0x00000000  #[ 0  0  0]
                    self.f2D.r3 = 0x00010201  #[ 1  2  1]
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(1)
            self.f2D.start()
            return self.filter2D(src, dst)
        else:  #ksize == 5
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if (dx == 1) and (dy == 0):
                if self.filter2D_5Type != 0:
                    self.filter2D_5Type = 0
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-6,  -12,  0,    12,   6,

                    0xfa, 0xf4, 0x00, 0x0c, 0x06, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    0,0,0]) #fill up to allign with 4
            elif (dx == 0) and (dy == 1):
                if self.filter2D_5Type != 1:
                    self.filter2D_5Type = 1
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -4,   -6,   -4,   -1,

                    0xff, 0xfc, 0xfa, 0xfc, 0xff, \
                    #-2,  -8,   -12,  -8,   -2,

                    0xfe, 0xf8, 0xf4, 0xf8, 0xfe, \
                    # 0,  0,    0,    0,    0,

                    0x00, 0x00, 0x00, 0x00, 0x00, \
                    # 2,  8,    12,   8,    2,

                    0x02, 0x08, 0x0c, 0x08, 0x02, \
                    # 1,  4,    6,    4,    1,

                    0x01, 0x04, 0x06, 0x04, 0x01, \
                    0,0,0]) #fill up to allign with 4
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(5)
            self.f2D_5.start()
            return self.filter2D(src, dst)

    def Scharr(self, src, ddepth, dx, dy, dst):
        self.f2D.rows = src.shape[0]
        self.f2D.columns = src.shape[1]
        self.f2D.channels = 1
        if (dx == 1) and (dy == 0):
            if self.filter2DType != 2:
                self.filter2DType = 2
                self.f2D.r1 = 0x000300fd  #[-3  0  3]
                self.f2D.r2 = 0x000a00f6  #[-10 0 10]
                self.f2D.r3 = 0x000300fd  #[-3  0  3]
        elif (dx == 0) and (dy == 1):
            if self.filter2DType != 3:
                self.filter2DType = 3
                self.f2D.r1 = 0x00fdf6fd  #[-3 -10 -3]
                self.f2D.r2 = 0x00000000  #[ 0   0  0]
                self.f2D.r3 = 0x00030a03  #[ 3  10  3]
        else:
            raise RuntimeError("Incorrect dx dy configuration")
        self.img_filters.select_filter(1)
        self.f2D.start()
        return self.filter2D(src, dst)

    def Laplacian(self, src, ddepth, dst, ksize):
        if ksize == 5:
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if self.filter2D_5Type != 4:
                self.filter2D_5Type = 4  # "Laplacian_5"
                self.f2D_5.par_V = bytes([ \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #4,   -8,   -24,  -8,   4,

                0x04, 0xf8, 0xe8, 0xf8, 0x04, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                0,0,0]) #fill up to allign with 4
            self.img_filters.select_filter(5)
            self.f2D_5.start()
            return self.filter2D(src, dst)
        else:  #ksize 1 or 3
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if ksize == 1:
                if (self.filter2DType != 4):
                    self.filter2DType = 4  # "Laplacian_1"
                    self.f2D.r1 = 0x00000100  #[ 0  1  0]
                    self.f2D.r2 = 0x0001fc01  #[ 1 -4  1]
                    self.f2D.r3 = 0x00000100  #[ 0  1  0]
            elif ksize == 3:
                if (self.filter2DType != 5):
                    self.filter2DType = 5  # "Laplacian_3"
                    self.f2D.r1 = 0x00020002  #[ 2  0  2]
                    self.f2D.r2 = 0x0000f800  #[ 0 -8  0]
                    self.f2D.r3 = 0x00020002  #[ 2  0  2]
            self.img_filters.select_filter(1)
            self.f2D.start()
            return self.filter2D(src, dst)

    def blur(self, src, ksize, dst):
        self.f2D_f.rows = src.shape[0]
        self.f2D_f.columns = src.shape[1]
        if (self.filter2DfType != 0):
            self.filter2DfType = 0  #blur
            mean = self.floatToFixed(1 / 9, cv2pynqDriverFilter2D_f.K_FP_W,
                                     cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r11 = mean
            self.f2D_f.r12 = mean
            self.f2D_f.r13 = mean
            self.f2D_f.r21 = mean
            self.f2D_f.r22 = mean
            self.f2D_f.r23 = mean
            self.f2D_f.r31 = mean
            self.f2D_f.r32 = mean
            self.f2D_f.r33 = mean
        self.img_filters.select_filter(2)
        self.f2D_f.start()
        return self.filter2D(src, dst)

    def GaussianBlur(self, src, ksize, sigmaX, sigmaY, dst):
        self.f2D_f.rows = src.shape[0]
        self.f2D_f.columns = src.shape[1]
        if (self.filter2DfType != 1):
            self.filter2DfType = 1  #GaussianBlur
            if (sigmaX <= 0):
                sigmaX = 0.3 * ((ksize[0] - 1) * 0.5 - 1) + 0.8
            if (sigmaY <= 0):
                sigmaY = sigmaX
            kX = cv2.getGaussianKernel(3, sigmaX, ktype=cv2.CV_32F)  #kernel X
            kY = cv2.getGaussianKernel(3, sigmaY, ktype=cv2.CV_32F)  #kernel Y
            self.f2D_f.r11 = self.floatToFixed(kY[0] * kX[0],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r12 = self.floatToFixed(kY[0] * kX[1],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r13 = self.floatToFixed(kY[0] * kX[2],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r21 = self.floatToFixed(kY[1] * kX[0],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r22 = self.floatToFixed(kY[1] * kX[1],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r23 = self.floatToFixed(kY[1] * kX[2],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r31 = self.floatToFixed(kY[2] * kX[0],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r32 = self.floatToFixed(kY[2] * kX[1],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r33 = self.floatToFixed(kY[2] * kX[2],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
        self.img_filters.select_filter(2)
        self.f2D_f.start()
        return self.filter2D(src, dst)

    def erode(self, src, kernel, dst, iterations, mode):
        self.img_filters.select_filter(3)
        return self.erodeDilateKernel(src, kernel, dst, iterations, mode,
                                      self.erodeIP)

    def dilate(self, src, kernel, dst, iterations, mode):
        self.img_filters.select_filter(4)
        return self.erodeDilateKernel(src, kernel, dst, iterations, mode,
                                      self.dilateIP)

    def Canny(self, src, threshold1, threshold2, dst):
        self.img_filters.select_filter(0)
        self.CannyIP.rows = src.shape[0]
        self.CannyIP.columns = src.shape[1]
        self.CannyIP.threshold1 = threshold1
        self.CannyIP.threshold2 = threshold2
        self.CannyIP.start()
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst

        self.cmaBuffer1.nbytes = src.nbytes
        self.dmaIn.transfer(self.cmaBuffer1)
        if hasattr(src, 'physical_address'):
            self.dmaOut.transfer(src)
        else:
            self.cmaBuffer0.nbytes = src.nbytes
            self.copyNto(self.cmaBuffer0, src, src.nbytes)
            self.dmaOut.transfer(self.cmaBuffer0)
        self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        return ret

    def filter2D(self, src, dst):
        if dst is None:
            self.cmaBuffer1.nbytes = src.nbytes
        elif hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
        if hasattr(src, 'physical_address'):
            self.dmaIn.transfer(self.cmaBuffer1)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
        else:  #pipeline the copy to contiguous memory and filter calculation in hardware
            if src.nbytes < 184800:  #440x420
                self.partitions = 1
            elif src.nbytes < 180000:  #600x300
                self.partitions = 2
            elif src.nbytes < 231200:  #680x340
                self.partitions = 4
            else:
                self.partitions = 8
            self.cmaBuffer1.nbytes = src.nbytes
            self.dmaIn.transfer(self.cmaBuffer1)
            chunks_len = int(src.nbytes / (self.partitions))
            self.cmaBuffer0.nbytes = chunks_len
            self.cmaBuffer2.nbytes = chunks_len
            #self.copyNto(src,self.cmaBuffer0,chunks_len)
            self.copyNto(self.cmaBuffer0, src, chunks_len)
            for i in range(1, self.partitions):
                if i % 2 == 1:
                    while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                        pass
                    self.dmaOut.transfer(self.cmaBuffer0)
                    #self.copyNtoOff(src ,self.cmaBuffer2,chunks_len, i*chunks_len, 0)
                    self.copyNtoOff(self.cmaBuffer2, src, chunks_len, 0,
                                    i * chunks_len)
                else:
                    while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                        pass
                    self.dmaOut.transfer(self.cmaBuffer2)
                    #self.copyNtoOff(src ,self.cmaBuffer0,chunks_len,  i*chunks_len, 0)
                    self.copyNtoOff(self.cmaBuffer0, src, chunks_len, 0,
                                    i * chunks_len)
            while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                pass
            self.dmaOut.transfer(self.cmaBuffer2)
            rest = src.nbytes % self.partitions
            if rest > 0:  #cleanup any remaining data and send it to HW
                #self.copyNtoOff(src ,self.cmaBuffer0,chunks_len, self.partitions*chunks_len, 0)
                self.copyNtoOff(self.cmaBuffer0, src, chunks_len, 0,
                                self.partitions * chunks_len)
                while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                    pass
                self.dmaOut.transfer(self.cmaBuffer0)
                rest -= chunks_len
            self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        return ret

    def floatToFixed(self, f, total_bits, fract_bits):
        """convert float f to a signed fixed point with #total_bits and #frac_bits after the point"""
        fix = int((abs(f) * (1 << fract_bits)))
        if (f < 0):
            fix += 1 << total_bits - 1
        return fix

    def erodeDilateKernel(self, src, kernel, dst, iterations, mode, filter):
        filter.mode = mode
        filter.rows = src.shape[0]
        filter.columns = src.shape[1]
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            filter.start()
            if iterations > 1:
                self.dmaIn.transfer(self.cmaBuffer1)
            else:
                self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            self.cmaBuffer2.nbytes = src.nbytes  #buffer = self.xlnk.cma_array(src.shape, dtype=np.uint8)
            for i in range(2, iterations + 1):
                filter.start()
                if i % 2 == 0:
                    self.dmaIn.transfer(self.cmaBuffer2)
                    if i != iterations:  #avoid copy after last iteration
                        self.dmaOut.transfer(self.cmaBuffer1)
                    else:
                        self.dmaOut.transfer(dst)
                else:
                    self.dmaIn.transfer(self.cmaBuffer1)
                    if i != iterations:
                        self.dmaOut.transfer(self.cmaBuffer2)
                    else:
                        self.dmaOut.transfer(dst)
                self.dmaIn.wait()
            return dst
        self.cmaBuffer0.nbytes = src.nbytes
        self.cmaBuffer1.nbytes = src.nbytes
        filter.start()
        self.dmaIn.transfer(self.cmaBuffer1)
        if hasattr(src, 'physical_address'):
            self.dmaOut.transfer(src)
        else:
            self.copyNto(self.cmaBuffer0, src,
                         src.nbytes)  #np.copyto(srcBuffer,src)
            self.dmaOut.transfer(self.cmaBuffer0)
        self.dmaIn.wait()
        self.cmaBuffer2.nbytes = src.nbytes  #buffer = self.xlnk.cma_array(src.shape, dtype=np.uint8)
        for i in range(2, iterations + 1):
            filter.start()
            if i % 2 == 0:
                self.dmaIn.transfer(self.cmaBuffer2)
                self.dmaOut.transfer(self.cmaBuffer1)
            else:
                self.dmaIn.transfer(self.cmaBuffer1)
                self.dmaOut.transfer(self.cmaBuffer2)
            self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        if iterations % 2 == 1:
            self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        else:
            self.copyNto(ret, self.cmaBuffer2, ret.nbytes)
        return ret

    '''def cornerHarris(self, src, k, dst):
        self.img_filters.select_filter(5)
        self.cornerHarrisIP.rows = src.shape[0]
        self.cornerHarrisIP.columns = src.shape[1]
        self.cornerHarrisIP.start()
        if hasattr(src, 'physical_address') and hasattr(dst, 'physical_address') and (dst.nbytes == src.nbytes*4):    
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
        
        self.cmaBuffer2.nbytes = src.nbytes*4
        self.dmaIn.transfer(self.cmaBuffer2)
        if hasattr(src, 'physical_address') :
            self.dmaOut.transfer(src)        
        else:
            self.cmaBuffer0.nbytes = src.nbytes
            self.copyNto(self.cmaBuffer0,src,src.nbytes)
            self.dmaOut.transfer(self.cmaBuffer0)        
        self.dmaIn.wait()
        ret = np.ndarray(src.shape,np.float32)
        self.copyNto(ret,self.cmaBuffer2,ret.nbytes)
        return ret'''

    def copyNto(self, dst, src, N):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        self.ffi.memmove(dstPtr, srcPtr, N)

    def copyNtoOff(self, dst, src, N, dstOffset, srcOffset):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        dstPtr += dstOffset
        srcPtr += srcOffset
        self.ffi.memmove(dstPtr, srcPtr, N)

    class ContiguousArrayCv2pynq(ContiguousArray):
        def init(self, cmaArray):
            self._nbytes = cmaArray.nbytes
            self.physical_address = cmaArray.physical_address
            self.cacheable = cmaArray.cacheable

        # overwrite access to nbytes with own function
        @property
        def nbytes(self):
            return self._nbytes

        @nbytes.setter
        def nbytes(self, value):
            self._nbytes = value