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
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
import os import pytest from pynq import PL from pynq import Overlay from pynq import Clocks from pynq.pl import BS_BOOT from pynq.ps import DEFAULT_CLK_MHZ __author__ = "Yun Rock Qu" __copyright__ = "Copyright 2016, Xilinx" __email__ = "*****@*****.**" bitfile1 = BS_BOOT bitfile2 = PL.bitfile_name ol1 = Overlay(bitfile1) ol2 = Overlay(bitfile2) cpu_mhz = 0 bitfile1_fclk0_mhz = DEFAULT_CLK_MHZ bitfile1_fclk1_mhz = DEFAULT_CLK_MHZ bitfile1_fclk2_mhz = DEFAULT_CLK_MHZ bitfile1_fclk3_mhz = DEFAULT_CLK_MHZ bitfile2_fclk0_mhz = DEFAULT_CLK_MHZ bitfile2_fclk1_mhz = DEFAULT_CLK_MHZ bitfile2_fclk2_mhz = DEFAULT_CLK_MHZ bitfile2_fclk3_mhz = DEFAULT_CLK_MHZ @pytest.mark.run(order=2) def test_overlay():
print("Xlnk buffer x-values: ", px_buffer) print("Xlnk buffer y-values: ", py_buffer) print("Xlnk buffer Z-values: ", pz_buffer) #reset the ADC adc.reset() # Now Transfer the contents of the buffers to the Custom IPs in PL via AXI DMA # X-Values to X-Function, Y-Values to Y Function, Z-Values to Z-Function #First delete the base overlay del ol #load the overlay for the custom streaming XYZ-values IP built and tested in TEST D from pynq import Overlay overlay = Overlay('/home/xilinx/pynq/overlays/stream_xyz/stream_xyz.bit') #Test the overlay #overlay? #returns the IP blocks contained in the Overlay which were built for each function #overlay.ip_dict # returns full path to each dma x,y,z = x_function.dmaz, y_function.dmay, z_function.dmaz #assign the DMAs which are the IPs built to recive and operate on the incomming buffer data dma_x = overlay.x_function.dmax dma_y = overlay.y_function.dmay dma_z = overlay.z_function.dmaz # Trigger the DMA transfer of the samples from buffers to the PL #set up send channel xyz dma_x.sendchannel.transfer(px_buffer) dma_y.sendchannel.transfer(py_buffer)
from pynq import Overlay from os import path current_dir = path.abspath(path.dirname(__file__)) bitfile = path.join(current_dir, "stable.bit") o = Overlay(bitfile) o.download()
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("SP_OVERLAY.bit", 0) self.OV.download() axi_offset = 0 ##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 #43c4 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 #43c8 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))) axi_offset += 1 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) #43c9 ##Initialize IDELAY self.DELAY_TAPS = MMIO(axi_base_addr + (axi_offset * axi_range), 0x10000) plog.info("IDELAY: " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43ca ##Initialize pulse counter #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("PCDAT" + str(i) + " -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43ce #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("PCUT" + str(i) + " -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43d2 #Initialize trigger controller self.T_UTIL = MMIO(0x41210000, 0x10000) self.T_UTIL.write(ch2_dir, 0x0) self.T_UTIL.write(ch2_data, 0x0) self.T_RDY_UTIL = MMIO(0x41200000, 0x10000) self.T_RDY_UTIL.write(ch1_dir, 0x1) ##Initialize single channel inter-rising_edge detection self.ST_FIFO_BUFFER = [] self.ST_loaded_count = 0 for i in range(FIFO_DEPTH): self.ST_FIFO_BUFFER.append(0) self.ST_DATA = MMIO(axi_base_addr + axi_offset * axi_range, axi_range) plog.info("STDAT -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 self.ST_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range, axi_range) self.ST_UTIL.write(ch1_data, 0x0) plog.info("STUTIL -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 ##Initialize interchannel coincidence timer self.CT_FIFO_BUFFER = [] self.CT_loaded_count = 0 for i in range(FIFO_DEPTH): self.CT_FIFO_BUFFER.append(0) self.CT_DATA = MMIO(axi_base_addr + axi_offset * axi_range, axi_range) plog.info("CTDAT -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 self.CT_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range, axi_range) self.CT_UTIL.write(ch1_data, self.CT_UTIL.read(0x0) & 0b110) plog.info("CTUTIL -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43d6 ##Initialize time tagger self.TT_FIFO_BUFFER = [] for i in range(FIFO_DEPTH): self.TT_FIFO_BUFFER.append(0) self.TT_loaded_count = 0 self.TT_CONFIG = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range) self.TT_CONFIG.write(ch2_data, 0x0) 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 self.IDELAY_DEBUG = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range) plog.info("IDELAY_DEBUG: " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 plog.debug("AXI_RANGE -- " + hex(axi_range)) #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 self.pg_ch_stat = 0xF sleep(0.05) self.IDELAY_DEBUG.write(0x0, 0x1) #self.PG_UTIL.write(ch2_data,0x0) sleep(0.1) self.IDELAY_DEBUG.write(0x0, 0x1) #Initial delay valus self.DDs = [] self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0)
import numpy as np from PIL import Image from time import time import matplotlib.pyplot as plt sys.path.append('/home/xilinx') from pynq import Overlay from pynq import allocate if __name__ == "__main__": print("Entry:", sys.argv[0]) print("System argument(s):", len(sys.argv)) print("Start of \"" + sys.argv[0] + "\"") ol = Overlay("/home/xilinx/f04525034/histogram/design_1.bit") ipHist = ol.top_img_hist_equaliz1_0 im = Image.open("/home/xilinx/f04525034/histogram/test_1080p.bmp") img = np.array(im).astype(np.uint8) #Buf = np.zeros(1080,dtype=np.int32) #for i in range(3): # print(i*8) # print(img[:,0,i]<<(i*8)) # Buf += img[:,0,i]<<(i*8) #print(Buf[0]) test = img.transpose(1, 0, 2).reshape((-1, 3)) print(img.shape) plt.title("Original colored image")
# 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. # ############################################################################### print("Running testXfphase.py ...") print("Loading overlay") from pynq import Overlay bs = Overlay("/usr/local/lib/python3.6/dist-packages/pynq_cv/overlays/xv2phase.bit") bs.download() print("Loading xlnk") from pynq import Xlnk Xlnk.set_allocator_library('/usr/local/lib/python3.6/dist-packages/pynq_cv/overlays/xv2phase.so') mem_manager = Xlnk() import pynq_cv.overlays.xv2phase as xv2 import numpy as np import cv2 import time import OpenCVUtils as cvu print("Loading image ../images/bigBunny_1080.png")
#!/usr/bin/env python # coding: utf-8 # # Canny Edge # from PIL import Image import numpy as np import matplotlib.pyplot as plt %matplotlib inline from pynq import Xlnk, Overlay canny = Overlay("canny.xclbin") image_path = "input_image.jpg" original_image = Image.open(image_path) canny_edge = canny.canny_1 canny_edge.signature low_threshold = 0 high_threshold = 255 height = 1920 width = 1080 in_buffer = allocate((height, width), np.uint8) out_buffer = allocate((height, width), np.uint8) start_time = time.time()
# 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. # ############################################################################### print("Running testXfAccumulateWeighted.py ...") print("Loading overlay") from pynq import Overlay bs = Overlay( "/usr/local/lib/python3.6/dist-packages/pynq_cv/overlays/xv2accumulateWeighted.bit" ) bs.download() print("Loading xlnk") from pynq import Xlnk Xlnk.set_allocator_library( '/usr/local/lib/python3.6/dist-packages/pynq_cv/overlays/xv2accumulateWeighted.so' ) mem_manager = Xlnk() import pynq_cv.overlays.xv2accumulateWeighted as xv2 import numpy as np import cv2 import time
#Testing Sending data captured from the PS on the ZYNQ chip Temperature #Collecting seven samples, sending the data to a custom IP on the PL to average the seven values #Then send the result of the calculation back to the PS for printing #John Tracey DCU August 2019 MECE from pynq import Overlay overlay = Overlay('/home/xilinx/pynq/overlays/average/average.bit') test_funct = overlay.average_0 import time temp= [None] * 7 # temp array for 7 values count = 0 while count < 7: # getting the cpu temp 7 times count = count +1 with open('/sys/devices/soc0/amba/f8007100.adc/iio:device0/in_temp0_raw') as f: #open file to get cpu temp value for line in f: temp[count-1] = int(line) # populate the array with 7 sperate cpu temperature values print(temp[count-1]) time.sleep(.005) #write temperaturevalues to address 0x00 to 0x18 the values to registers a,b,c,d,e,f,g in programmable logic test_funct.write(0x00, temp[0]) test_funct.write(0x04, temp[1]) test_funct.write(0x08, temp[2]) test_funct.write(0x0C, temp[3]) test_funct.write(0x10, temp[4]) test_funct.write(0x14, temp[5]) test_funct.write(0x18, temp[6]) #read from register h address 0x1C which should give the average of the 7 numbers sent to the IP
def __init__(self, addr_port_client=("192.168.1.100", 3000)): print('FPGA_Connect_Object init') self.resolution = [640, 360] self.client_port = addr_port_client team_name = 'SystemsETHZ' # agent = Agent(team_name) interval_time = 0 xlnk = Xlnk() xlnk.xlnk_reset() ###########################variable initializing###################### OVERLAY_PATH = '/home/xilinx/jupyter_notebooks/dac_2019_contest/common/' + team_name + '/ultra96_v04.bit' WEIGHTS_FILE_NAME = '/home/xilinx/jupyter_notebooks/dac_2019_contest/common/' + team_name + '/weights_file_v04_demo.txt' ###########################change board settings###################### ###########################download overlay###################### overlay = Overlay(OVERLAY_PATH) self.dma = overlay.axi_dma_0 self.nn_ctrl = MMIO(0xA0010000, length=1024) ###########################download weights###################### self.MINIBATCH_SIZE = 1 self.height = 176 self.width = 320 pixel_bits = 24 pixels_per_line = 384 / pixel_bits self.num_lines = int((self.height * self.width) / pixels_per_line) self.in_buffer = xlnk.cma_array(shape=(self.MINIBATCH_SIZE * self.num_lines, 64), dtype=np.uint8) fire1_num_out_lines = (self.height / 4) * (self.width / 4) * self.MINIBATCH_SIZE self.fire1_out_buffer = xlnk.cma_array(shape=(int( 16 * fire1_num_out_lines), ), dtype=np.uint32) fire2_num_out_lines = (self.height / 8) * (self.width / 8) * self.MINIBATCH_SIZE self.fire2_out_buffer = xlnk.cma_array(shape=(int( 16 * fire2_num_out_lines), ), dtype=np.uint32) fire3_num_out_lines = (self.height / 16) * (self.width / 16) * self.MINIBATCH_SIZE self.fire3_out_buffer = xlnk.cma_array(shape=(int( 16 * fire3_num_out_lines), ), dtype=np.uint32) self.fire4_out_buffer = xlnk.cma_array(shape=(int( 16 * fire3_num_out_lines), ), dtype=np.uint32) self.fire5_out_buffer = xlnk.cma_array(shape=(int( 16 * fire3_num_out_lines), ), dtype=np.uint32) final_num_lines = int((self.height / 16) * (self.width / 16)) self.bndboxes = [ xlnk.cma_array(shape=(self.MINIBATCH_SIZE, final_num_lines, 16), dtype=np.int32), xlnk.cma_array(shape=(self.MINIBATCH_SIZE, final_num_lines, 16), dtype=np.int32), xlnk.cma_array(shape=(self.MINIBATCH_SIZE, final_num_lines, 16), dtype=np.int32), xlnk.cma_array(shape=(self.MINIBATCH_SIZE, final_num_lines, 16), dtype=np.int32) ] self.obj_array = np.zeros((self.MINIBATCH_SIZE, final_num_lines)) NUM_LAYERS = 3 + 4 * 4 weights_file = open(WEIGHTS_FILE_NAME, "r") layer = 0 total_iterations = np.zeros(NUM_LAYERS) for line in weights_file: if "layer" in line: temp = line.split(": ") layer = int(temp[1]) if "total_iterations" in line: temp = line.split(": ") total_iterations[layer] = int(temp[1]) weights_file.close() weightfactors_length = np.zeros(NUM_LAYERS) self.weightsfactors = [] for i in range(0, NUM_LAYERS): weightfactors_length[i] = int(total_iterations[i]) self.weightsfactors.append( xlnk.cma_array(shape=(int(16 * weightfactors_length[i]), ), dtype=np.uint32)) self.obj_factors = np.zeros(4) self.box_factors = np.zeros(4) index = 0 weights_file = open(WEIGHTS_FILE_NAME, "r") for line in weights_file: if "layer" in line: temp = line.split(": ") layer = int(temp[1]) index = 0 elif "total_iterations" not in line: if "obj_factor" in line: temp = line.split(' ') self.obj_factors[int(temp[1])] = int(temp[2]) elif "box_factor" in line: temp = line.split(' ') self.box_factors[int(temp[1])] = int(temp[2]) else: no0x = line.split('0x')[-1] base = 1 while base < len(no0x): part = no0x[-1 * (base + 8):-1 * base] self.weightsfactors[layer][index * 16 + int(base / 8)] = int( part, 16) base += 8 index += 1
from pynq import Overlay import sys import socket ol = Overlay('design_1.bit') ol.download() print('Loaded bitstream') # Load the two AXI devices into variables buf = ol.axi_bram_ctrl_0 nic = ol.Pmod_NIC100_AXI_0 # Some offsets for the AXI nic busy = 0 rx_tx = 4 rx_len = 8 tx_len = 12 # Constants BITMASK_RX = 0b01 BITMASK_TX = 0b10 ARP_REQUEST = [0, 1] ETH_TYPE_ARP = [0x08, 0x06] ETH_TYPE_IP = [0x08, 0x00] ICMP_PING_REPLY = [0x00] ICMP_PING_REQUEST = [0x08] IP_BASE = [192, 168, 2, 99] IP_PROT_ICMP = [0x01] MAC_BASE = [0xab] * 6 MAC_BROADCAST = [0xff] * 6
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) 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) 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) 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) while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass 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 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
def __init__(self): global dma self.dance_labels = np.array(['dab', 'elbowkick', 'gun', 'hair', 'left', 'listen', 'pointhigh', 'right', 'sidepump', 'logout', 'stationary', 'wipetable']) self.pos_labels = np.array(['left', 'right', 'stationary']) dance_weights_dir = "weights_dance_sat_40_mav_10_new" pos_weights_dir = "weights_pos_sat_40_mav_10_stat" weight_0 = np.load(f'{dance_weights_dir}/weight_0.npy') weight_1 = np.load(f'{dance_weights_dir}/weight_1.npy') weight_2 = np.load(f'{dance_weights_dir}/weight_2.npy') weight_3 = np.load(f'{dance_weights_dir}/weight_3.npy') weight_4 = np.load(f'{dance_weights_dir}/weight_4.npy') bias_0 = np.load(f'{dance_weights_dir}/bias_0.npy') bias_1 = np.load(f'{dance_weights_dir}/bias_1.npy') bias_2 = np.load(f'{dance_weights_dir}/bias_2.npy') bias_3 = np.load(f'{dance_weights_dir}/bias_3.npy') bias_4 = np.load(f'{dance_weights_dir}/bias_4.npy') weight_0_pos = np.load(f'{pos_weights_dir}/weight_0.npy') weight_1_pos = np.load(f'{pos_weights_dir}/weight_1.npy') weight_2_pos = np.load(f'{pos_weights_dir}/weight_2.npy') weight_3_pos = np.load(f'{pos_weights_dir}/weight_3.npy') bias_0_pos = np.load(f'{pos_weights_dir}/bias_0.npy') bias_1_pos = np.load(f'{pos_weights_dir}/bias_1.npy') bias_2_pos = np.load(f'{pos_weights_dir}/bias_2.npy') bias_3_pos = np.load(f'{pos_weights_dir}/bias_3.npy') self.scaler_mean = np.load(f'{dance_weights_dir}/mean.npy') self.scaler_scale = np.load(f'{dance_weights_dir}/scale.npy') self.scaler_mean_pos = np.load(f'{pos_weights_dir}/scaler_mean.npy') self.scaler_scale_pos = np.load(f'{pos_weights_dir}/scaler_scale.npy') overlay = Overlay('final.bit') # load bitstream inside FPGA dma = overlay.axi_dma_0 self.choose_model = allocate(shape=(1,), dtype=np.float32) input_buffer0 = allocate(shape=(100,), dtype=np.float32) input_buffer1 = allocate(shape=(128,), dtype=np.float32) input_buffer2 = allocate(shape=(12,), dtype=np.float32) input_buffer3 = allocate(shape=(32,), dtype=np.float32) input_buffer4 = allocate(shape=(3,), dtype=np.float32) output_buffer0 = allocate(shape=(12,), dtype=np.float32) output_buffer1 = allocate(shape=(3,), dtype=np.float32) ##load dance weights for i in range(128): for k in range(100): input_buffer0[k] = weight_0[k][i] dma.sendchannel.transfer(input_buffer0) dma.sendchannel.wait() for i in range(128): for k in range(128): input_buffer1[k] = weight_1[k][i] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for i in range(128): for k in range(128): input_buffer1[k] = weight_2[k][i] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for i in range(128): for k in range(128): input_buffer1[k] = weight_3[k][i] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for i in range(12): for k in range(128): input_buffer1[k] = weight_4[k][i] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() ##bias for k in range(128): input_buffer1[k] = bias_0[k] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for k in range(128): input_buffer1[k] = bias_1[k] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for k in range(128): input_buffer1[k] = bias_2[k] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for k in range(128): input_buffer1[k] = bias_3[k] dma.sendchannel.transfer(input_buffer1) dma.sendchannel.wait() for k in range(12): input_buffer2[k] = bias_4[k] dma.sendchannel.transfer(input_buffer2) dma.sendchannel.wait() ##load position weights for i in range(32): for k in range(100): input_buffer0[k] = weight_0_pos[k][i] dma.sendchannel.transfer(input_buffer0) dma.sendchannel.wait() for i in range(32): for k in range(32): input_buffer3[k] = weight_1_pos[k][i] dma.sendchannel.transfer(input_buffer3) dma.sendchannel.wait() for i in range(32): for k in range(32): input_buffer3[k] = weight_2_pos[k][i] dma.sendchannel.transfer(input_buffer3) dma.sendchannel.wait() for i in range(3): for k in range(32): input_buffer3[k] = weight_3_pos[k][i] dma.sendchannel.transfer(input_buffer3) dma.sendchannel.wait() ##bias for k in range(32): input_buffer3[k] = bias_0_pos[k] dma.sendchannel.transfer(input_buffer3) dma.sendchannel.wait() for k in range(32): input_buffer3[k] = bias_1_pos[k] dma.sendchannel.transfer(input_buffer3) dma.sendchannel.wait() for k in range(32): input_buffer3[k] = bias_2_pos[k] dma.sendchannel.transfer(input_buffer3) dma.sendchannel.wait() for k in range(3): input_buffer4[k] = bias_3_pos[k] dma.sendchannel.transfer(input_buffer4) dma.sendchannel.wait() self.fns = [getattr(features,f) for f in features.__dict__ if callable(getattr(features, f)) and f.startswith("get_")]
from pynq import Overlay from pynq import Xlnk import numpy as np import cv2 from PIL import Image as PIL_Image from PIL import ImageEnhance from PIL import ImageOps from scipy import misc overlay = Overlay('lenet.bit') top = overlay.top_fun_0 # 寄存器地址 # CTRL 0x00 # IN_DRAM_DATA 0x10 # W_DRAM_DATA 0x18 # OUT_DRAM_DATA 0x20 # BIAS_DRAM_DATA 0x28 # LAYER_DATA 0x30 def top_fun(pic_in, w_in, out, bias, layer): top.write(0x10, pic_in) #pic_in top.write(0x18, w_in) #w top.write(0x20, out) #out top.write(0x28, bias) #bias top.write(0x30, layer) #layer top.write(0x00, 0x01) #写入1 将ap_start置1 启动 while (top.read(0) != 0x04): #等待完成 a = 1 return 0
# -*- coding: utf-8 -*- """ Created on Sun Nov 24 11:44:12 2019 @author: LHN """ import time start = time.clock() import numpy import os from pynq import Overlay overlay=Overlay('/home/xilinx/pynq/overlays/distance/diatance.bit') overlay? distance_ip=overlay.distance distance_ip? #定义一个三维点类 class Point(object): def __init__(self,x,y,z): self.x = x self.y = y self.z = z points = [] filename = '/home/workspace/horse_1100.pcd' filename2 = '/home/workspace/horse_1100_dataRadiusOutlierRemoval' #读取pcd文件,从pcd的第12行开始是三维点 with open(filename+'.pcd') as f: for line in f.readlines()[11:len(f.readlines())-1]: strs = line.split(' ')
scalar_args.append(ba.arguments[param.name]) return Call(vlnv, stream_args, scalar_args, return_type=ret_type) else: return func(*args, **kwargs) return wrapped_function return decorator from pynq import Overlay Overlay('base.bit').download() from pynq.drivers import DMA import pynq.drivers.dma Overlay( '/home/xilinx/jupyter_notebooks/PYNQ_CNN/Theano/Lenet/Bitstream/lenet.bit' ).download() def prepare_execution(plan, dma, return_port): if type(plan) is Wrapper: d = DMAWrapper(len(dma)) d.set_data(plan.wrapped, plan.dtype()) dma.append(d) hw_switch.set_route(d.ports[1][0], return_port) elif type(plan) is Call:
img = xlnk.cma_array(shape=[160,320,16], dtype=np.uint8) fm = xlnk.cma_array(shape=(628115*32), dtype=np.uint8) weight = xlnk.cma_array(shape=(220672), dtype=np.int16) biasm = xlnk.cma_array(shape=(432*16), dtype=np.int16) bbox = np.empty(64, dtype=np.int16) print("Allocating memory done") parameter = np.fromfile("SkyNet.bin", dtype=np.int16) np.copyto(weight, parameter[0:220672]) np.copyto(biasm[0:428*16], parameter[220672:]) print("Parameters loading done") overlay = Overlay("SEUer2.bit") print("Bitstream loaded") SkyNet = overlay.SkyNet_0 SkyNet.write(0x10, img.physical_address) SkyNet.write(0x1c, fm.physical_address) SkyNet.write(0x28, weight.physical_address) SkyNet.write(0x34, biasm.physical_address) rails = pynq.get_rails() recorder = pynq.DataRecorder(rails['5V'].power) IMAGE_NAMES = get_image_batch() IMAGE_NAMES_LEN = len(IMAGE_NAMES) image_queue = Queue(1000)
#os.write(temp, bytes("5 10\n", "utf-8")); #os.close(temp) print(location) # store output of the program as a byte string in s # s = subprocess.check_output("../octomap/octomap/bin/shared_mem_to_bt "+location, stdin = data, shell = True) # stream = os.popen("../octomap/octomap/bin/shared_mem_to_bt "+location) # output = stream.read() # print(output) os.system("../octomap/octomap/bin/shared_mem_to_bt "+location) # decode s to a normal string #print(s.decode("utf-8")) #print(s) if __name__ == "__main__": #overlay = Overlay('/home/xilinx/sgm_pynq_ver/census_mgm_multi_bit/design_1.bit') overlay = Overlay('./Bitstream/5Sections/design_1.bit') overlay ffi = cffi.FFI() #Being used to convert FPGA accessable memory to np array capl = cv2.VideoCapture(0) #image = cv2.imread('/home/xilinx/sgm_pynq_ver/test_images/right_image32.jpg', 0); imagel = np.zeros((ZED_IMAGE_HEIGHT,ZED_IMAGE_WIDTH),dtype=np.ubyte) imager = np.zeros((ZED_IMAGE_HEIGHT,ZED_IMAGE_WIDTH),dtype=np.ubyte) rectified_left = np.zeros((ZED_IMAGE_HEIGHT,ZED_IMAGE_WIDTH),dtype=np.ubyte) rectified_right = np.zeros((ZED_IMAGE_HEIGHT,ZED_IMAGE_WIDTH),dtype=np.ubyte) buffer_left = np.zeros((IMG_HEIGHT,IMG_WIDTH),dtype=np.ubyte) buffer_right = np.zeros((IMG_HEIGHT,IMG_WIDTH),dtype=np.ubyte) disp_median_buff = np.zeros((IMG_HEIGHT,IMG_WIDTH),dtype=np.ubyte) # imagel[0:ZED_IMAGE_HEIGHT,0:640] = image[0:ZED_IMAGE_HEIGHT,0:640] # imager[0:ZED_IMAGE_HEIGHT,0:640] = image[0:ZED_IMAGE_HEIGHT,672:1312]
def gradients_kernel_accel(data, weights): numClasses = 10 numFeatures = 784 chunkSize = int(len(data) / (numClasses + (1 + 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. # ------------------------- 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. # ------------------------- dma0 = DMA(ADDR_DMA0_BASE, direction=DMA_TO_DEV) # data1 DMA dma1 = DMA(ADDR_DMA1_BASE, direction=DMA_TO_DEV) # data2 DMA dma2 = DMA(ADDR_DMA2_BASE, direction=DMA_TO_DEV) # weights DMA dma3 = DMA(ADDR_DMA3_BASE, direction=DMA_FROM_DEV) # gradients DMA # ------------------------- # Allocate physically contiguous memory buffers. # ------------------------- dma0.create_buf(int(chunkSize * (numClasses + (1 + numFeatures)) / 2) * 4) dma1.create_buf(int(chunkSize * (numClasses + (1 + numFeatures)) / 2) * 4) dma2.create_buf((numClasses * (1 + numFeatures)) * 4) dma3.create_buf((numClasses * (1 + numFeatures)) * 4) # ------------------------- # Get CFFI pointers to objects' internal buffers. # ------------------------- data1_buf = dma0.get_buf(data_type="float") data2_buf = dma1.get_buf(data_type="float") weights_buf = dma2.get_buf(data_type="float") gradients_buf = dma3.get_buf(data_type="float") for i in range(0, int(chunkSize * (numClasses + (1 + numFeatures)) / 2)): data1_buf[i] = float(data[i]) data2_buf[i] = float( data[int(chunkSize * (numClasses + (1 + numFeatures)) / 2) + i]) for kj in range(0, numClasses * (1 + numFeatures)): weights_buf[kj] = float(weights[kj]) # ------------------------- # Write data to MMIO. # ------------------------- CMD = 0x0028 # Command. ISCALAR0_DATA = 0x0080 # Input Scalar-0 Write Data FIFO. bus.write(ISCALAR0_DATA, int(chunkSize)) bus.write(CMD, 0x00010001) bus.write(CMD, 0x00020000) bus.write(CMD, 0x00000107) # ------------------------- # Transfer data using DMAs (Non-blocking). # Block while DMAs are busy. # ------------------------- dma0.transfer(int(chunkSize * (numClasses + (1 + numFeatures)) / 2) * 4, direction=DMA_TO_DEV) dma1.transfer(int(chunkSize * (numClasses + (1 + numFeatures)) / 2) * 4, direction=DMA_TO_DEV) dma2.transfer((numClasses * (1 + numFeatures)) * 4, direction=DMA_TO_DEV) dma0.wait() dma1.wait() dma2.wait() dma3.transfer((numClasses * (1 + numFeatures)) * 4, direction=DMA_FROM_DEV) dma3.wait() gradients = [] for kj in range(0, numClasses * (1 + numFeatures)): gradients.append(float(gradients_buf[kj])) # ------------------------- # Destructors for DMA objects. # ------------------------- dma0.__del__() dma1.__del__() dma2.__del__() dma3.__del__() return gradients
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("SP_OVERLAY.bit", 0) self.OV.download() axi_offset = 0 ##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 #43c4 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 #43c8 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))) axi_offset += 1 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) #43c9 ##Initialize IDELAY self.DELAY_TAPS = MMIO(axi_base_addr + (axi_offset * axi_range), 0x10000) plog.info("IDELAY: " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43ca ##Initialize pulse counter #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("PCDAT" + str(i) + " -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43ce #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("PCUT" + str(i) + " -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43d2 #Initialize trigger controller self.T_UTIL = MMIO(0x41210000, 0x10000) self.T_UTIL.write(ch2_dir, 0x0) self.T_UTIL.write(ch2_data, 0x0) self.T_RDY_UTIL = MMIO(0x41200000, 0x10000) self.T_RDY_UTIL.write(ch1_dir, 0x1) ##Initialize single channel inter-rising_edge detection self.ST_FIFO_BUFFER = [] self.ST_loaded_count = 0 for i in range(FIFO_DEPTH): self.ST_FIFO_BUFFER.append(0) self.ST_DATA = MMIO(axi_base_addr + axi_offset * axi_range, axi_range) plog.info("STDAT -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 self.ST_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range, axi_range) self.ST_UTIL.write(ch1_data, 0x0) plog.info("STUTIL -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 ##Initialize interchannel coincidence timer self.CT_FIFO_BUFFER = [] self.CT_loaded_count = 0 for i in range(FIFO_DEPTH): self.CT_FIFO_BUFFER.append(0) self.CT_DATA = MMIO(axi_base_addr + axi_offset * axi_range, axi_range) plog.info("CTDAT -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 self.CT_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range, axi_range) self.CT_UTIL.write(ch1_data, self.CT_UTIL.read(0x0) & 0b110) plog.info("CTUTIL -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43d6 ##Initialize time tagger self.TT_FIFO_BUFFER = [] for i in range(FIFO_DEPTH): self.TT_FIFO_BUFFER.append(0) self.TT_loaded_count = 0 self.TT_CONFIG = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range) self.TT_CONFIG.write(ch2_data, 0x0) 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 self.IDELAY_DEBUG = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range) plog.info("IDELAY_DEBUG: " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 plog.debug("AXI_RANGE -- " + hex(axi_range)) #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 self.pg_ch_stat = 0xF sleep(0.05) self.IDELAY_DEBUG.write(0x0, 0x1) #self.PG_UTIL.write(ch2_data,0x0) sleep(0.1) self.IDELAY_DEBUG.write(0x0, 0x1) #Initial delay valus self.DDs = [] self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) def restart(self): self.__init__() 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_read_coarse(self): """ Reads coarse timer counter value Returns ------- :class:`int` Interdetection time in counter clock cycles """ return self.ST_DATA.read(0x0) def st_read_fine(self): """ Reads the fine time offsets from the rising edge of the coarse clock. Returns ------- :class:`int` Fine time offsets """ return self.ST_DATA.read(0x8) def st_read_drdy(self): """ Reads whether data is valid to be read Returns ------- :class:`int` Value of the valid line (0 or 1) """ return self.ST_UTIL.read(0x8) & 0b1 def st_read_empty(self): """ Reads whether the FIFO is empty Returns ------- :class:`int` 0 or 1 for not empty and empty respectively """ return (self.ST_UTIL.read(0x8) & 0b10) >> 1 def st_read_full(self): """ Reads whether the FIFO is full Returns ------- :class:`int` 0 or 1 for not full and full respectively """ return (self.ST_UTIL.read(0x8) & 0b100) >> 1 def st_set_mreset(self, val): """ Sets the master reset of the module (active low), when in reset the module is disabled Parameters ---------- val : :class:`int` Value of the reset line (0 or 1) """ lastval = self.ST_UTIL.read(0x0) & 0b110 self.ST_UTIL.write(0x0, lastval | (val & 0b1)) def st_set_req(self, val): """ Sets the data request line to indicate to the FIFO read controller to clock a single data point out of the FIFO (ACTIVE HIGH) Parameters ---------- val : :class:`int` Value of the request line (0 or 1) """ lastval = self.ST_UTIL.read(0x0) & 0b101 self.ST_UTIL.write(0x0, lastval | ((val << 1) & 0b10)) def st_set_dreset(self, val): """ SEts the FIFO read controller's reset, to reset it back to awaiting a request signal (active low) Parameters ---------- val : :class:`int` Value of the reset line (0 or 1) """ lastval = self.ST_UTIL.read(0x0) & 0b011 self.ST_UTIL.write(0x0, lastval | ((val << 2) & 0b100)) def st_start(self): """ Starts the single channel inter rising edge timer module """ self.st_set_mreset(1) def st_stop(self): """ Stops the inter rising edge timer module """ self.st_set_mreset(0) self.st_set_dreset(0) def st_flush_buffer(self): """ HELPER - NOT USED CURRENTLY - Flushes the local FIFO buffer (NOT THE HARDWARE FIFO, TO Do THAT CAL st_read2048() AND THEN FLUSH) """ for i in range(FIFO_DEPTH): self.ST_FIFO_BUFFER[i] = 0 self.ST_loaded_count = 0 def st_proc(self): """ Reads 2048 values from the FIFO (or until empty) and places the data into a dictionary with length and module ID ready to be sent over socket. Returns ------- :class:`dict` Dictionary containing module identification, length of data list, and the data list """ self.st_read2048() return { "MOD": "ST", "LEN": self.ST_loaded_count, "DAT": self.ST_FIFO_BUFFER } def st_read2048(self): """ Reads data from the FIFO until empty and stores each recovered data point in the local FIFO buffer. """ if (self.st_read_empty() == 1): plog.warning("FIFO EMPTY") return for i in range(FIFO_DEPTH): if (self.st_read_empty() == 1): self.ST_loaded_count = i return self.st_set_dreset( 1) #Pull FIFO read controller out of reset and request data self.st_set_req(1) while (self.st_read_drdy() == 0): pass self.ST_FIFO_BUFFER[i] = self.st_read_coarse() | self.st_read_fine( ) << 32 #Concatenate both fine and coarse times and store the resulting value into the local buffer #print(self.loaded_data[i]&0xFFFFFFFF) self.st_set_req( 0) #Deassert the request line and reset the read controller self.st_set_dreset(0) self.ST_loaded_count = FIFO_DEPTH ####----------------------------------------------------------------------------------#### ####------------------Two channel photon coincidence timer----------------------------#### def ct_start(self, mode): """ Starts the two channel coincidence timer Parameters ---------- mode : :class:`int` Line select mode, whether to treat the first channel as start or second, or whichever is detected first (0,1,2) """ if (mode != 2): self.ct_set_fsel(mode) self.ct_set_bidir(0) else: self.ct_set_bidir(1) self.ct_set_mreset(1) def ct_stop(self): """ Stops the two channel coincidence timer """ self.ct_set_mreset(0) def ct_flush_buffer(self): """ HELPER - NOT USED CURRENTLY - Flushes the local FIFO buffer (NOT THE HARDWARE FIFO, TO Do THAT CAL ct_read2048() AND THEN FLUSH) """ for i in range(FIFO_DEPTH): self.CT_FIFO_BUFFER[i] = 0 self.loaded_count = 0 def ct_proc(self): """ Reads 2048 values from the FIFO (or until empty) and places the data into a dictionary with length and module ID ready to be sent over socket. Returns ------- :class:`dict` Dictionary containing module identification, length of data list, and the data list """ self.ct_read2048() return { "MOD": "CT", "LEN": self.loaded_count, "DAT": self.CT_FIFO_BUFFER } def ct_read2048(self): """ Reads data from the FIFO until empty and stores each recovered data point in the local FIFO buffer. """ if (self.ct_read_empty() == 1): return for i in range(FIFO_DEPTH): if (self.ct_read_empty() == 1): self.loaded_count = i return self.ct_set_dreset(1) self.ct_set_req(1) while (self.ct_read_drdy() == 0): pass self.CT_FIFO_BUFFER[i] = self.ct_read_coarse( ) | self.ct_read_fine() << 32 #print(self.loaded_data[i]&0xFFFFFFFF) self.ct_set_req(0) self.ct_set_dreset(0) self.loaded_count = FIFO_DEPTH def ct_read_coarse(self): """ Reads coarse timer counter value Returns ------- :class:`int` Interdetection time in counter clock cycles """ return self.CT_DATA.read(0x0) def ct_read_fine(self): """ Reads the fine time offsets from the rising edge of the coarse clock. Returns ------- :class:`int` Fine time offsets """ return self.CT_DATA.read(0x8) def ct_set_fsel(self, val): """ Sets the first detection channel select line. Parameters ---------- val : :class:`int` 0 to treat Ch1 as start signal, 1 to treat CH2 as start signal """ lastval = self.CT_UTIL.read(0x0) & 0b11101 self.CT_UTIL.write(0x0, lastval | ((val << 1) & 0b10)) def ct_set_bidir(self, val): """ Sets whether the module chooses the start signal based on which channel is detected first (ACTIVE HIGH), if set, the setting of ct_set_fsel() is ignored. Parameters ---------- val : :class:`int` 0 or 1 to give precendence to fsel line or to pick based off which comes first respectively. Returns ------- """ lastval = self.CT_UTIL.read(0x0) & 0b11011 self.CT_UTIL.write(0x0, lastval | ((val << 2) & 0b100)) def ct_read_drdy(self): """ Reads whether data is valid to be read Returns ------- :class:`int` Value of the valid line (0 or 1) """ return self.CT_UTIL.read(0x8) & 0b1 def ct_read_empty(self): """ Reads whether the FIFO is empty Returns ------- :class:`int` 0 or 1 for not empty and empty respectively """ return (self.CT_UTIL.read(0x8) & 0b10) >> 1 def ct_read_full(self): """ Reads whether the FIFO is full Returns ------- :class:`int` 0 or 1 for not full and full respectively """ return (self.CT_UTIL.read(0x8) & 0b100) >> 1 def ct_set_mreset(self, val): """ Sets the master reset of the module (active low), when in reset the module is disabled Parameters ---------- val : :class:`int` Value of the reset line (0 or 1) """ lastval = self.CT_UTIL.read(0x0) & 0b11110 self.CT_UTIL.write(0x0, lastval | (val & 0b1)) def ct_set_req(self, val): """ Sets the data request line to indicate to the FIFO read controller to clock a single data point out of the FIFO (ACTIVE HIGH) Parameters ---------- val : :class:`int` Value of the request line (0 or 1) """ lastval = self.CT_UTIL.read(0x0) & 0b01111 self.CT_UTIL.write(0x0, lastval | ((val << 4) & 0b10000)) def ct_set_dreset(self, val): """ SEts the FIFO read controller's reset, to reset it back to awaiting a request signal (active low) Parameters ---------- val : :class:`int` Value of the reset line (0 or 1) """ lastval = self.CT_UTIL.read(0x0) & 0b10111 self.CT_UTIL.write(0x0, lastval | ((val << 3) & 0b1000)) ####---------------------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 = DDS_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) / DDS_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(DDS_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 * DDS_REF_CLK) #TIME TAGGER FUNCTIONS----------------------------------------------- def tt_start(self, timeout): """ Starts the time tagger module Parameters ---------- timeout : :class:`int` Number of counter cycles to wait for. """ self.tt_set_timeout(timeout) self.tt_set_mreset(1) def tt_stop(self): """ Stops the time tagger """ self.tt_set_mreset(0) def tt_flush_buffer(self): """ HELPER - NOT USED CURRENTLY - Flushes the local FIFO buffer (NOT THE HARDWARE FIFO, TO Do THAT CAL tt_read2048() AND THEN FLUSH) """ for i in range(FIFO_DEPTH): self.TT_FIFO_BUFFER[i] = 0 self.TT_loaded_count = 0 def tt_proc(self): """ Reads 2048 values from the FIFO (or until empty) and places the data into a dictionary with length and module ID ready to be sent over socket. Returns ------- :class:`dict` Dictionary containing module identification, length of data list, and the data list """ self.tt_read2048() data = { "MOD": "TT", "LEN": self.TT_loaded_count, "DAT": self.TT_FIFO_BUFFER } return data def tt_read2048(self): """ Reads data from the FIFO until empty and stores each recovered data point in the local FIFO buffer. """ if (self.tt_read_empty() == 1): return for i in range(FIFO_DEPTH): if (self.tt_read_empty() == 1): self.TT_loaded_count = i return self.tt_set_dreset(1) self.tt_set_req(1) while (self.tt_read_drdy() == 0): pass #Concatenate each part of current run (Coarse and fine times for each channel and time outs) into a singular integer and place in local buffer self.TT_FIFO_BUFFER[i] = ((self.tt_read_coarse() | self.tt_read_fine() << 128 | self.tt_read_timeouts() << 168)) self.tt_set_req(0) self.tt_set_dreset(0) self.TT_loaded_count = FIFO_DEPTH def tt_read_coarse(self): """ Reads coarse timer counter value Returns ------- :class:`int` Concatenated coarse times for each channel """ d0 = self.TT_DATA0.read(0x0) d1 = self.TT_DATA0.read(0x8) << 32 d2 = self.TT_DATA1.read(0x0) << 64 d3 = self.TT_DATA1.read(0x8) << 96 return d0 | d1 | d2 | d3 def tt_read_fine(self): """ Reads the fine time offsets from the rising edge of the coarse clock. Returns ------- :class:`int` Concatenated fine time offsets for each channel. """ return self.TT_DELAY_DATA.read(0x0) | (self.TT_DELAY_DATA.read(0x8) & 0xFF) << 32 def tt_read_drdy(self): """ Reads whether data is valid to be read Returns ------- :class:`int` Value of the valid line (0 or 1) """ return (self.TT_UTIL.read(0x8) & 0b100) >> 2 def tt_read_empty(self): """ Reads whether the FIFO is empty Returns ------- :class:`int` 0 or 1 for not empty and empty respectively """ return (self.TT_UTIL.read(0x8) & 0b1) def tt_read_full(self): """ Reads whether the FIFO is full Returns ------- :class:`int` 0 or 1 for not full and full respectively """ return (self.TT_UTIL.read(0x8) & 0b10) >> 1 def tt_set_mreset(self, val): """ Sets the master reset of the module (active low), when in reset the module is disabled Parameters ---------- val : :class:`int` Value of the reset line (0 or 1) """ lastval = self.TT_CONFIG.read(0x8) & 0b110 self.TT_CONFIG.write(0x8, lastval | (val & 0b1)) def tt_set_req(self, val): """ Sets the data request line to indicate to the FIFO read controller to clock a single data point out of the FIFO (ACTIVE HIGH) Parameters ---------- val : :class:`int` Value of the request line (0 or 1) """ lastval = self.TT_CONFIG.read(0x8) & 0b101 self.TT_CONFIG.write(0x8, lastval | ((val << 1) & 0b10)) def tt_set_dreset(self, val): """ SEts the FIFO read controller's reset, to reset it back to awaiting a request signal (active low) Parameters ---------- val : :class:`int` Value of the reset line (0 or 1) """ lastval = self.TT_CONFIG.read(0x8) & 0b011 self.TT_CONFIG.write(0x8, lastval | ((val << 2) & 0b100)) def tt_set_timeout(self, val): """ Sets the time out data bus for the time tagger Parameters ---------- val : :class:`int` 32 bit integer stating the time out in TDC_REF_CLK cycles """ self.TT_CONFIG.write(0x0, val & 0xFFFFFFFF) def tt_read_timeouts(self): """ Reads the channel time out statuses Returns ------- :class:`int` 4 bit binary encoded integer showing the time out state for each line (0 if the channel timed out) """ return self.TT_UTIL.read(0x0) #TIME_TAGGER_END----------------------------------------------------- def DD_idelay(self, channel, tap0, tap1): """Sets the input delay of the specified channel by configuring the delay line taps and the number of delay line stages to include Channels 4 and 5 are T0 and END TRIG Parameters ---------- channel : :class:`int` Channel to delay (0-5) tap0 : :class:`int` Delay line tap (0-31) tap1 : :class:`int` Delay line cascaded tap (0-31) """ concattaps = tap0 | (tap1 << 5) self.DDs[channel] = concattaps allconcat0 = self.DDs[4] | (self.DDs[0] << 10) | (self.DDs[1] << 20) allconcat1 = self.DDs[2] | (self.DDs[3] << 10) | (self.DDs[5] << 20) self.DELAY_TAPS.write(0x0, allconcat0) self.DELAY_TAPS.write(0x8, allconcat1) # if(channel <=2): # dp0 = self.DELAY_TAPS.read(0x0) | (0b1111111111 << (channel*10)) # dp1 = dp0 & (concattaps << (channel*10)) # self.DELAY_TAPS.write(0x0,dp1) # else: # dp0 = self.DELAY_TAPS.read(0x8) | (0b1111111111 << ((channel-3) * 10)) # dp1 = dp0 & (concattaps << ((channel-3) * 10)) # self.DELAY_TAPS.write(0x8, dp1) plog.info("Setting input delay on channel " + str(channel) + " dline taps T0:" + str(tap0) + " T1:" + str(tap1)) self.IDELAY_DEBUG.write(0x8, 0b1) sleep(0.1) self.IDELAY_DEBUG.write(0x8, 0b0) # plog.debug("DP0: "+bin(dp0)) # plog.debug("DP1: " + bin(dp1)) self.IDELAY_DEBUG.write(0x0, 0x1) sleep(0.05) plog.debug("OBS0: " + bin(self.IDELAY_DEBUG.read(0x0))) def uencode(self, val, length): """[DEPRECIATED] - NOT USED - 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
X_PADDING4 = int((KERNEL_WIDTH4 - 1 / 2)) Y_PADDING4 = int((KERNEL_HEIGHT4 - 1) / 2) else: X_PADDING4 = 0 Y_PADDING4 = 0 OUT_CH4 = 10 OUT_WIDTH4 = int((IN_WIDTH4 + 2 * X_PADDING4 - KERNEL_WIDTH4) / X_STRIDE4 + 1) OUT_HEIGHT4 = int((IN_HEIGHT4 + 2 * Y_PADDING4 - KERNEL_HEIGHT4) / Y_STRIDE4 + 1) # In[20]: xlnk = Xlnk() ol = Overlay("bitstream/cnn0.bit") ol.download() conv = ol.Conv_0 pool = ol.Pool_0 print("Overlay download finish") # In[17]: ol.ip_dict # In[18]: #input image image = xlnk.cma_array(shape=(IN_HEIGHT1, IN_WIDTH1, IN_CH1), cacheable=0, dtype=np.float32)
import os import time from PIL import Image from matplotlib import pyplot import cv2 from datetime import datetime from pynq import Xlnk from pynq import Overlay from pynq.mmio import MMIO from loader import loader import scipy.misc from IPython.display import display print('FPGA Initializing...') OVERLAY_PATH = 'overlay.bit' overlay = Overlay(OVERLAY_PATH) dma = overlay.axi_dma_0 xlnk = Xlnk() nn_ctrl = MMIO(0x43c00000, length=1024) print('Got nn_ctrl!') ## FPGA Parameters height = 28 width = 28 pixel_bits = 8 pixels_per_line = 448 / pixel_bits num_lines = int((height * width) / pixels_per_line) # hostName = "localhost"
if vlnv in metadata.functions: stream_args=[] scalar_args=[] for param in sig.parameters.values(): if type(param.annotation) is list: stream_args.append(wrap_arg(ba.arguments[param.name],param.annotation[0])) else: scalar_args.append(ba.arguments[param.name]) return Call(vlnv,stream_args,scalar_args,return_type=ret_type) else: return func(*args,**kwargs) return wrapped_function return decorator from pynq import Overlay Overlay('base.bit').download() from pynq.drivers import DMA import pynq.drivers.dma Overlay('/home/xilinx/jupyter_notebooks/PYNQ_Classification/PYNQ_SIDE/Theano/CIFAR_10/Bitstream/decorator_cifar10_16b.bit').download() def prepare_execution(plan,dma,return_port): if type(plan) is Wrapper: d=DMAWrapper(len(dma)) d.set_data(plan.wrapped,plan.dtype()) dma.append(d) hw_switch.set_route(d.ports[1][0],return_port) elif type(plan) is Call: in_ports=metadata.functions[plan.func].in_ports out_ports=metadata.functions[plan.func].out_ports name=metadata.functions[plan.func].name mmio=None
import cv2 import numpy as np from pynq.board import Switch from pynq import Overlay Overlay("base.bit").download() cap = cv2.VideoCapture(0) fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('output.avi', fourcc, 5, (640, 480)) #for red color # lower mask (0-10) lower_1 = np.array([0, 100, 100]) upper_1 = np.array([10, 255, 255]) if not cap.isOpened(): print('Camera is not open.') cap.open(0) else: print('Start') while cap.isOpened(): if Switch(0).read(): print('switch 0 read') break ret, frame = cap.read() if ret: hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, lower_1, upper_1) hsv = cv2.bitwise_and(hsv, hsv, mask=mask) cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
def __init__(self): overlay = Overlay("./design_1.bit") self.hw_compute = overlay.DoCompute_0
import sys import numpy as np from time import time import matplotlib.pyplot as plt sys.path.append('/home/xilinx') from pynq import Overlay from pynq import allocate if __name__ == "__main__": print("Entry:", sys.argv[0]) print("System argument(s):", len(sys.argv)) print("Start of \"" + sys.argv[0] + "\"") ol = Overlay("/home/xilinx/IPBitFile/fp_accum.bit") ipfpaccum = ol.fp_accum_0 ipDMAIn = ol.axi_dma_in_0 ipDMAOut = ol.axi_dma_out_0 fiSamples = open("samples_triangular_wave.txt", "r+") numSamples = 0 line = fiSamples.readline() while line: numSamples = numSamples + 1 line = fiSamples.readline() inBuffer0 = allocate(shape=(numSamples,), dtype=np.int32) outBuffer0 = allocate(shape=(numSamples,), dtype=np.int32) fiSamples.seek(0) for i in range(numSamples):
import numpy as np import random from time import time import matplotlib.pyplot as plt sys.path.append('/home/xilinx') from pynq import Overlay from pynq import allocate if __name__ == "__main__": print("Entry:", sys.argv[0]) print("System argument(s):", len(sys.argv)) print("Start of \"" + sys.argv[0] + "\"") ol = Overlay("/home/xilinx/IPBitFile/rsErasure.bit") ipFIRN11 = ol.rs_erasure_0 # fiSamples = open("samples_triangular_wave.txt", "r+") outC = allocate(shape=(4, ), dtype=np.int8) inD = allocate(shape=(12, ), dtype=np.int8) survival_pattern = allocate(shape=(1, ), dtype=np.int16) codeid = allocate(shape=(1, ), dtype=np.int8) # errcnt = 0 linecnt = 0 # suberrcnt = [0, 0, 0, 0] sublincnt = [0, 0, 0, 0] with open('./tv_rs_erasure_in.txt', 'r') as f_in: for line in f_in:
else: scalar_args.append(ba.arguments[param.name]) return Call(vlnv, stream_args, scalar_args, return_type=ret_type) else: return func(*args, **kwargs) return wrapped_function return decorator from pynq import Overlay Overlay('base.bit').download() from pynq.drivers import DMA import pynq.drivers.dma Overlay( '/home/xilinx/jupyter_notebooks/PYNQ_CNN/Theano/CIFAR_10/Bitstream/cifar_10.bit' ).download() def prepare_execution(plan, dma, return_port): if type(plan) is Wrapper: d = DMAWrapper(len(dma)) d.set_data(plan.wrapped, plan.dtype()) dma.append(d) hw_switch.set_route(d.ports[1][0], return_port) elif type(plan) is Call: in_ports = metadata.functions[plan.func].in_ports
MODE6 = 0 #0:VALID, 1:SAME if (MODE6): X_PADDING6 = int((KERNEL_WIDTH6 - 1 / 2)) Y_PADDING6 = int((KERNEL_HEIGHT6 - 1) / 2) else: X_PADDING6 = 0 Y_PADDING6 = 0 OUT_CH6 = 2 OUT_WIDTH6 = int((IN_WIDTH6 + 2 * X_PADDING6 - KERNEL_WIDTH6) / X_STRIDE6 + 1) OUT_HEIGHT6 = int((IN_HEIGHT6 + 2 * Y_PADDING6 - KERNEL_HEIGHT6) / Y_STRIDE6 + 1) xlnk = Xlnk() ol = Overlay("ai.bit") ol.ip_dict ol.download() conv = ol.Conv_0 pool = ol.Pool_0 print("Overlay download finish") #input image image = xlnk.cma_array(shape=(IN_HEIGHT1, IN_WIDTH1, IN_CH1), cacheable=0, dtype=np.float32) #conv1 W_conv1 = xlnk.cma_array(shape=(KERNEL_HEIGHT1, KERNEL_WIDTH1, IN_CH1, OUT_CH1), cacheable=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
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("SP_OVERLAY.bit", 0) self.OV.download() axi_offset = 0 ##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 #43c4 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 #43c8 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))) axi_offset += 1 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) #43c9 ##Initialize IDELAY self.DELAY_TAPS = MMIO(axi_base_addr + (axi_offset * axi_range), 0x10000) plog.info("IDELAY: " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43ca ##Initialize pulse counter #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("PCDAT" + str(i) + " -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43ce #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("PCUT" + str(i) + " -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43d2 #Initialize trigger controller self.T_UTIL = MMIO(0x41210000, 0x10000) self.T_UTIL.write(ch2_dir, 0x0) self.T_UTIL.write(ch2_data, 0x0) self.T_RDY_UTIL = MMIO(0x41200000, 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("STDAT -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 self.ST_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range, axi_range) self.ST_UTIL.write(ch1_data, 0x0) plog.info("STUTIL -- " + 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("CTDAT -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 self.CT_UTIL = MMIO(axi_base_addr + (axi_offset) * axi_range, axi_range) self.CT_UTIL.write(ch1_data, self.CT_UTIL.read(0x0) & 0b110) plog.info("CTUTIL -- " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 #43d6 ##Initialize time tagger self.TT_CONFIG = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range) self.TT_CONFIG.write(ch2_data, 0x0) 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 self.IDELAY_DEBUG = MMIO(axi_base_addr + (axi_offset * axi_range), axi_range) plog.info("IDELAY_DEBUG: " + hex(axi_base_addr + (axi_offset * axi_range))) axi_offset += 1 plog.debug("AXI_RANGE -- " + hex(axi_range)) #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 self.pg_ch_stat = 0xF sleep(0.05) self.IDELAY_DEBUG.write(0x0, 0x1) #self.PG_UTIL.write(ch2_data,0x0) sleep(0.1) self.IDELAY_DEBUG.write(0x0, 0x1) #Initial delay valus self.DDs = [] self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) self.DDs.append(0) def restart(self): self.__init__() 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_UTIL.read(ch2_data)) == 0: #Wait for ready pass op = self.ST_DATA.read(ch1_data) / DET_REF_CLK #Read time dels = self.ST_DATA.read( ch2_data) #Read start and finish fine time values #ADd and subtract start and end fine time values from coarse time #to the coarse time op = op + (((dels & 0xFF)) - ((dels & 0xFF00) >> 8)) * FTIME self.ST_UTIL.write(ch1_data, 0x0) return op ####----------------------------------------------------------------------------------#### ####------------------Two channel photon coincidence timer----------------------------#### def ct_arm_and_wait(self, mode): """Arm two channel rising edge coincidence timer and hang until time data is ready (On channel 0 and 1) Parameters ---------- mode : :class:`int` Defines which channel to listen for start rising edge or either (0,1 or 2) Returns ------- :class:`float` Time between rising edges (in seconds) """ print("Starting CT") #Set which channel the hardware is listening to for the start pulse and take the submodule out of reset enabling it if (mode == int(LineSelectMode.DONTCARE)): self.CT_UTIL.write(0x0, self.CT_UTIL.read(0x0) | 0b100) else: self.CT_UTIL.write(0x0, self.CT_UTIL.read(0x0) & 0b001) self.CT_UTIL.write(0x0, self.CT_UTIL.read(0x0) | (int(mode) << 1)) self.CT_UTIL.write(0x0, self.CT_UTIL.read(0x0) | 0b1) #Wait for the coincidence time to be ready (waits until the second pulse) while (self.CT_UTIL.read(ch2_data)) == 0: pass #Read coarse time sleep(0.1) coarse_time = self.CT_DATA.read(ch1_data) / DET_REF_CLK finetimeconcat = self.CT_DATA.read(ch2_data) #Read fine times #Include fine time offsets with the coarse time ftime0 = finetimeconcat & 0xFF ftime1 = (finetimeconcat & 0xFF00) >> 8 self.CT_UTIL.write( ch1_data, self.CT_UTIL.read(0x0) & 0b110) #Disable coincidence timer by placing it in reset return coarse_time + (ftime0 - ftime1) * FTIME ####---------------------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) / DDS_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(DDS_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 * DDS_REF_CLK) def TT_wait_for_rdy(self): """Wait until time tagger tags each channel or times out (Hangs the thread) """ #Wait for a transition on the data readyline if (self.TT_UTIL.read(ch2_data)) == 0: while (self.TT_UTIL.read(ch2_data)) == 0: pass else: while (self.TT_UTIL.read(ch2_data)) == 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 * DET_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_CONFIG.write(ch2_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 ftt0 = self.TT_DELAY_DATA.read(ch2_data) stimet0 = ( ftt0) * FTIME #Calculate the fine time offset of the t0 signal plog.debug("T0FT: " + bin(ftt0)) dels = self.TT_DELAY_DATA.read( ch1_data ) #Fine times for channels 0-3 (Each is concatenated in binary) #Calculating the fine time offsets for each channel stimet1 = ((dels & 0xFF)) * FTIME stimet2 = ((dels & 0xFF00) >> 8) * FTIME stimet3 = ((dels & 0xFF0000) >> 16) * FTIME stimet4 = ((dels & 0xFF000000) >> 24) * FTIME plog.debug("T1FT: " + bin((dels & 0xFF))) #Include fine time offsets with the coarse times cttime1 = self.TT_DATA0.read(ch1_data) ctime1 = cttime1 / DET_REF_CLK - stimet1 + stimet0 ctime2 = self.TT_DATA0.read(ch2_data) / DET_REF_CLK - stimet2 + stimet0 ctime3 = self.TT_DATA1.read(ch1_data) / DET_REF_CLK - stimet3 + stimet0 ctime4 = self.TT_DATA1.read(ch2_data) / DET_REF_CLK - stimet4 + stimet0 plog.debug("T1CT: " + str(cttime1)) timeouts = (self.TT_UTIL.read(ch1_data)) #Read time outs #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_CONFIG.write(ch2_data, 0x0) def DD_idelay(self, channel, tap0, tap1): """Sets the input delay of the specified channel by configuring the delay line taps and the number of delay line stages to include Channels 4 and 5 are T0 and END TRIG Parameters ---------- channel : :class:`int` Channel to delay (0-5) tap0 : :class:`int` Delay line tap (0-31) tap1 : :class:`int` Delay line cascaded tap (0-31) """ concattaps = tap0 | (tap1 << 5) self.DDs[channel] = concattaps allconcat0 = self.DDs[4] | (self.DDs[0] << 10) | (self.DDs[1] << 20) allconcat1 = self.DDs[2] | (self.DDs[3] << 10) | (self.DDs[5] << 20) self.DELAY_TAPS.write(0x0, allconcat0) self.DELAY_TAPS.write(0x8, allconcat1) # if(channel <=2): # dp0 = self.DELAY_TAPS.read(0x0) | (0b1111111111 << (channel*10)) # dp1 = dp0 & (concattaps << (channel*10)) # self.DELAY_TAPS.write(0x0,dp1) # else: # dp0 = self.DELAY_TAPS.read(0x8) | (0b1111111111 << ((channel-3) * 10)) # dp1 = dp0 & (concattaps << ((channel-3) * 10)) # self.DELAY_TAPS.write(0x8, dp1) plog.info("Setting input delay on channel " + str(channel) + " dline taps T0:" + str(tap0) + " T1:" + str(tap1)) self.IDELAY_DEBUG.write(0x8, 0b1) sleep(0.1) self.IDELAY_DEBUG.write(0x8, 0b0) # plog.debug("DP0: "+bin(dp0)) # plog.debug("DP1: " + bin(dp1)) self.IDELAY_DEBUG.write(0x0, 0x1) sleep(0.05) plog.debug("OBS0: " + bin(self.IDELAY_DEBUG.read(0x0))) def uencode(self, val, length): """[DEPRECIATED] 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