class sequencer: def __init__(self): self.dacRes = 65536 self.dacRange = [-10, 10] self.dacRangeConv = float(167772) / self.dacRes self.dacIncrMax = 268435455 self.dacTimeRes = 1.6e3 # in us self.ddsAmpRange = [0, 5] self.ddsFreqRange = [0, 500] self.ddsFreqRangeConv = 8589930 # (2^32 - 1)/500 MHz self.ddsAmpRangeConv = 818.4 # (2^10 - 1)/1.25 mW self.ddsTimeRes = 1.6e3 # in us # initialize DACs self.dac0 = DAC81416(fifo_devices['DAC81416_0']) self.dac1 = DAC81416(fifo_devices['DAC81416_1']) self.dds0 = AD9959(fifo_devices['AD9959_0']) self.dds1 = AD9959(fifo_devices['AD9959_1']) self.dds2 = AD9959(fifo_devices['AD9959_2']) self.fifo_dac0_seq = AXIS_FIFO(fifo_devices['DAC81416_0_seq']) self.fifo_dac1_seq = AXIS_FIFO(fifo_devices['DAC81416_1_seq']) # initialize DDSs self.fifo_dds_atw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_atw']) self.fifo_dds_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_ftw']) self.fifo_dds0_atw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_atw']) self.fifo_dds0_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_ftw']) self.fifo_dds1_atw_seq = AXIS_FIFO(fifo_devices['AD9959_1_seq_atw']) self.fifo_dds1_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_1_seq_ftw']) self.fifo_dds2_atw_seq = AXIS_FIFO(fifo_devices['AD9959_2_seq_atw']) self.fifo_dds2_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_2_seq_ftw']) # self.dds = AD9959(dds_device) # initialize DDS self.gpio2 = AXI_GPIO(gpio_devices['axi_gpio_2']) self.fifo_dio_seq = AXIS_FIFO(fifo_devices['GPIO_seq']) def initExp(self): print('initializing experiment') self.mod_disable() reset() dds_lock_pll.dds_lock_pll() def getWord(self, bytes): return bytes[3] + bytes[2] + bytes[1] + bytes[0] def soft_trigger(self): trigger() def write_dio_point(self, point): #01XXAAAA TTTTTTTT DDDDDDDD self.fifo_dio_seq.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.outputA)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.outputB)) def write_dio(self, byte_buf): #01XXAAAA TTTTTTTT DDDDDDDD self.fifo_dio_seq.write_axis_fifo(byte_buf, MSB_first=False) def write_dac_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(63 downto 48); #acc_steps <= gpio_in(47 downto 32); #acc_incr <= gpio_in(31 downto 4); #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); fifo.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo( struct.pack('>I', point.start * 256 * 256 + point.steps)) fifo.write_axis_fifo(struct.pack('>I', point.incr * 16 + point.chan)) def write_atw_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #unused <= gpio_in(63 downto 58); #acc_start <= gpio_in(57 downto 48); #acc_steps <= gpio_in(47 downto 32); #unused <= gpio_in(31 downto 26); #acc_incr <= gpio_in(25 downto 4); #unused <= gpio_in( 3 downto 2); #acc_chan <= gpio_in( 1 downto 0); self.fifo_dds_atw_seq.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) self.fifo_dds_atw_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dds_atw_seq.write_axis_fifo( struct.pack('>I', point.start * 256 * 256 + point.steps)) self.fifo_dds_atw_seq.write_axis_fifo( struct.pack('>I', point.incr * 16 + point.chan)) def write_ftw_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(95 downto 64); #acc_steps <= gpio_in(63 downto 48); #acc_incr <= gpio_in(47 downto 4); #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); incr_hi = int(math.floor(point.incr * 1.0 / 2**28)) incr_lo = point.incr - incr_hi * 2**28 self.fifo_dds_ftw_seq.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) self.fifo_dds_ftw_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dds_ftw_seq.write_axis_fifo(struct.pack('>I', point.start)) self.fifo_dds_ftw_seq.write_axis_fifo( struct.pack('>I', point.steps * 256 * 256 + incr_hi)) self.fifo_dds_ftw_seq.write_axis_fifo( struct.pack('>I', incr_lo * 16 + point.chan)) def reset_DAC(self): self.dac = DAC81416(device) # initialize DAC def set_DAC(self, channel, value): valueInt = int((value - self.dacRange[0]) * self.dacRes / (self.dacRange[1] - self.dacRange[0])) assert channel >= 0 and channel <= 31, 'Invalid channel for DAC81416 in set_DAC' if (channel > 15): channel = channel - 16 self.dac1.set_DAC(channel, valueInt) else: self.dac0.set_DAC(channel, valueInt) def set_DDS(slef, channel, amp, freq): ampValueInt = amp * self.ddsAmpRangeConv freqValueInt = amp * self.ddsFreqRangeConv assert channel >= 0 and channel <= 11, 'Invalid channel for AD9959 in set_DDS' if (channel > 7): channel = channel - 8 self.dds2.set_DDS(channel, ampValueInt, freqValueInt) elif (3 < channel < 8): channel = channel - 4 self.dds1.set_DDS(channel, ampValueInt, freqValueInt) else: self.dds0.set_DDS(channel, ampValueInt, freqValueInt) def mod_enable(self): self.gpio2.set_bit(0, channel=1) def mod_disable(self): self.gpio2.clear_bit(0, channel=1) def reset_disable_mod(self): print('disabling mod and resetting sequencers') self.gpio2.write_axi_gpio(0xffff0000, channel=2) self.gpio2.write_axi_gpio(0x0000ffff, channel=2) self.mod_disable() def mod_report(self): print((self.gpio2.read_axi_gpio(channel=1))) def dac_seq_write_points(self, byte_len, byte_buf, num_snapshots): print('DAC points') points0 = [] points1 = [] for ii in range(num_snapshots): [t, chan, s, end, duration] = self.dac_read_point( byte_buf[ii * byte_len:ii * byte_len + byte_len]) num_steps = duration / self.dacTimeRes if (int(num_steps) <= 1): ramp_inc = 0 else: ramp_inc = int((end - s) * self.dacRangeConv / (num_steps)) # print(s, end, num_steps, ramp_inc) if (ramp_inc < -0.1): ramp_inc = int(self.dacIncrMax + ramp_inc) print("ramp_inc = ", ramp_inc, " num_steps = ", num_steps, " dacRangeConv = ", self.dacRangeConv) if (chan < 16): points0.append( DAC_seq_point(address=len(points0), time=t, start=s, steps=duration, incr=ramp_inc, chan=chan)) else: points1.append( DAC_seq_point(address=len(points1), time=t, start=s, steps=duration, incr=ramp_inc, chan=chan - 16)) if (len(points0) != 0): points0.append( DAC_seq_point(address=len(points0), time=0, start=0, steps=0, incr=0, chan=0)) if (len(points1) != 0): points1.append( DAC_seq_point(address=len(points1), time=0, start=0, steps=0, incr=0, chan=0)) for i in range(1, len(points0)): for j in range(i): # print(i,j) if (points0[i].time == points0[j].time): points0[i].time = points0[i].time + 1 for i in range(1, len(points1)): for j in range(i): if (points1[i].time == points1[j].time): points1[i].time = points1[i].time + 1 for point in points0: print("add: ", point.address) print("time: ", point.time) print("start: ", point.start) print("steps: ", point.steps) print("incr: ", point.incr) print("chan: ", point.chan) self.write_dac_point(self.fifo_dac0_seq, point) for point in points1: print("add: ", point.address) print("time: ", point.time) print("start: ", point.start) print("steps: ", point.steps) print("incr: ", point.incr) print("chan: ", point.chan) self.write_dac_point(self.fifo_dac1_seq, point) def dds_seq_write_points(self, byte_len, byte_buf, num_snapshots): ftw_points = [] atw_points = [] for ii in range(num_snapshots): [t, channel, aorf, s, end, duration] = self.dds_read_point( byte_buf[ii * byte_len:ii * byte_len + byte_len]) num_steps = (duration / self.ddsTimeRes) - 1 if (num_steps == 0): ramp_inc = 0 else: ramp_inc = int((end - s) / num_steps) if (aorf == 'f'): if (ramp_inc < 0): ramp_inc = int(self.ddsFreqRangeConv + ramp_inc) ftw_points.append( DDS_ftw_seq_point(address=ii, time=t, start=s, steps=duration, incr=ramp_inc, chan=channel)) elif (aorf == 'a'): if (ramp_inc < 0): ramp_inc = int(self.ddsAmpRangeConv + ramp_inc) atw_points.append( DDS_atw_seq_point(address=ii, time=t, start=s, steps=duration, incr=ramp_inc, chan=channel)) else: print("invalid dds type. set to 'f' for freq or 'a' for amp") for channel in range(0, 4, 4): ftw_points.append( DDS_ftw_seq_point(address=num_snapshots, time=0, start=0, steps=0, incr=0, chan=channel)) atw_points.append( DDS_atw_seq_point(address=num_snapshots, time=0, start=0, steps=0, incr=0, chan=channel)) for point in ftw_points: print("freq time = ", point.time) print("freq chan = ", point.chan) print("freq start = ", point.start) if (point.chan < 4): fifo = self.fifo_dds0_ftw_seq elif (4 <= point.chan < 8): point.chan = point.chan - 4 fifo = self.fifo_dds1_ftw_seq else: point.chan = point.chan - 8 fifo = self.fifo_dds2_ftw_seq self.write_ftw_point(fifo, point) for point in atw_points: print("amp time = ", point.time) print("amp chan = ", point.chan) print("amp start = ", point.start) if (point.chan < 4): fifo = self.fifo_dds0_atw_seq elif (4 <= point.chan < 8): point.chan = point.chan - 4 fifo = self.fifo_dds1_atw_seq else: point.chan = point.chan - 8 fifo = self.fifo_dds2_atw_seq self.write_atw_point(fifo, point) def dds_seq_write_atw_points(self): points = [] #these ramps should complete in just under 64 ms points.append( DDS_atw_seq_point(address=0, time=0, start=1023, steps=0, incr=0, chan=0)) #25% to 75% # points.append(DDS_atw_seq_point(address=1,time=1000,start=256,steps=1,incr=0,chan=3)) #25% to 75% points.append( DDS_atw_seq_point(address=1, time=0, start=0, steps=0, incr=0, chan=0)) for point in points: self.write_atw_point(self.fifo_dds_atw_seq, point) def dds_seq_write_ftw_points(self): points = [] # points.append(DDS_ftw_seq_point(address=0,time=0,start=200000000,steps=0,incr=0,chan=0)) # ~ points.append(DDS_ftw_seq_point(address=0,time= 0,start=800000,steps=10000,incr=30000,chan=0)) points.append( DDS_ftw_seq_point(address=0, time=0, start=100000, steps=2500, incr=240000, chan=0)) points.append( DDS_ftw_seq_point(address=1, time=0, start=0, steps=0, incr=0, chan=0)) for point in points: self.write_ftw_point(self.fifo_dds_ftw_seq, point) def dio_seq_write_points(self, byte_len, byte_buf, num_snapshots): points = [] for ii in range(num_snapshots): [t, outA, outB] = self.dio_read_point( byte_buf[ii * byte_len:ii * byte_len + byte_len]) points.append( GPIO_seq_point(address=ii, time=t, outputA=outA, outputB=outB)) # points.append(GPIO_seq_point(address=num_snapshots,time=6400000,outputA=0x00000000,outputB=0x00000000)) points.append( GPIO_seq_point(address=num_snapshots, time=0, outputA=0x00000000, outputB=0x00000000)) for point in points: print("add: ", point.address) print("time: ", point.time) print("outputA: ", point.outputA) print("outputB: ", point.outputB) # with open("/dev/axis_fifo_0x0000000080004000", "wb") as character: for point in points: # writeToSeqGPIO(character, point) seqWords = getSeqGPIOWords(point) for word in seqWords: # print word self.fifo_dio_seq.write_axis_fifo(word[0], MSB_first=False) def dio_read_point(self, snapshot): # print snapshot snapshot_split = snapshot.split('_') t = int(snapshot_split[0].strip('t'), 16) out = snapshot_split[1].strip('b').strip('\0') outB = int(out[:8], 16) outA = int(out[8:], 16) return [t, outA, outB] def dac_read_point(self, snapshot): snapshot_split = snapshot.split('_') t = int(snapshot_split[0].strip('t'), 16) chan = int(snapshot_split[1].strip('c'), 16) start = int(self.dacRes * (float(snapshot_split[2].strip('s')) - self.dacRange[0]) / (self.dacRange[1] - self.dacRange[0])) end = int(self.dacRes * (float(snapshot_split[3].strip('e')) - self.dacRange[0]) / (self.dacRange[1] - self.dacRange[0])) duration = int(snapshot_split[4].strip('d').strip('\0'), 16) return [t, chan, start, end, duration] def dds_read_point(self, snapshot): snapshot_split = snapshot.split('_') t = int(snapshot_split[0].strip('t'), 16) chan = int(snapshot_split[1].strip('c'), 16) aorf = snapshot_split[2] if (aorf == 'f'): ddsConv = self.ddsFreqRangeConv else: ddsConv = self.ddsAmpRangeConv start = int(float(snapshot_split[3].strip('s')) * ddsConv) end = int(float(snapshot_split[4].strip('e')) * ddsConv) duration = int(snapshot_split[5].strip('d').strip('\0'), 16) return [t, chan, aorf, start, end, duration]
class DAC81416: """Class to control DAC81416 in project KA012. Very simple class just used for testing. """ def __init__(self, device=None, noinit=False): if device is None: self.fifo = AXIS_FIFO() else: self.fifo = AXIS_FIFO(device) if not noinit: #SPI config register #sets device in active mode #activates streaming mode self.fifo.write_axis_fifo("\x00\x03\x0A\x8C") #GEN config #activate internal ref self.fifo.write_axis_fifo("\x00\x04\x3F\x00") #BRDCONFIG - disable broadcast mode self.fifo.write_axis_fifo("\x00\x05\x00\x00") #SYNCCONFIG - activate LDAC self.fifo.write_axis_fifo("\x00\x06\xFF\xFF") #TOGGCONFIG0 - leave at default self.fifo.write_axis_fifo("\x00\x07\x00\x00") #TOGGCONFIG1 - leave at default self.fifo.write_axis_fifo("\x00\x08\x00\x00") #DACRANGE set to +-10V self.fifo.write_axis_fifo("\x00\x0A\xAA\xAA") #DACRANGE set to +-10V self.fifo.write_axis_fifo("\x00\x0B\xAA\xAA") #DACRANGE set to +-10V self.fifo.write_axis_fifo("\x00\x0C\xAA\xAA") #DACRANGE set to +-10V self.fifo.write_axis_fifo("\x00\x0D\xAA\xAA") #TRIGGER - leave at default self.fifo.write_axis_fifo("\x00\x0E\x00\x00") #power down control self.fifo.write_axis_fifo("\x00\x09\x00\x00") for channel in range(16): self.set_DAC(channel, 0) #self.set_DAC(channel, 256*128) def set_DAC(self, channel, value): assert channel >= 0 and channel <= 15, 'Invalid channel for DAC81416 in set_DAC' val = b"\x00" + struct.pack('B', channel + 16) + struct.pack( '>H', value) if self.fifo is not None: self.fifo.write_axis_fifo(val)
class DAC_ramp_tester: def __init__(self, dac_a, dac_b, device_seq0, device_seq1, main_seq): self.dac_a = dac_a DAC81416(dac_a) # initialize DAC self.dac_b = dac_b DAC81416(dac_b) # initialize DAC self.gpio2 = AXI_GPIO(gpio_devices['axi_gpio_2']) self.fifo_dac_seq0 = AXIS_FIFO(device_seq0) self.fifo_dac_seq1 = AXIS_FIFO(device_seq1) self.fifo_main_seq = AXIS_FIFO(main_seq) def write_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #clr_incr <= gpio_in(52 downto 52); #acc_chan <= gpio_in(51 downto 48); #acc_start <= gpio_in(47 downto 32); #acc_incr <= gpio_in(31 downto 0); fifo.write_axis_fifo(b"\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo( struct.pack( '>I', point.clr_incr * 16 * 256 * 256 + point.chan * 256 * 256 + point.start)) fifo.write_axis_fifo(struct.pack('>I', point.incr)) def reset_DAC(self): DAC81416(self.dac_a) # initialize DAC DAC81416(self.dac_b) # initialize DAC def mod_enable(self): self.gpio2.set_bit(0, channel=1) def mod_disable(self): self.gpio2.clear_bit(0, channel=1) def mod_report(self): print(self.gpio2.read_axi_gpio(channel=1)) def dac_seq_write_points(self): points0 = [] points1 = [] #step 100 LSB per 10 us points0.append( DAC_seq_point(address=0, time=0, start=100, incr=6553600, chan=0, clr_incr=0)) points0.append( DAC_seq_point(address=1, time=1, start=1000, incr=6553600, chan=1, clr_incr=0)) points0.append( DAC_seq_point(address=2, time=2, start=2000, incr=6553600, chan=2, clr_incr=0)) points0.append( DAC_seq_point(address=3, time=3, start=3000, incr=6553600, chan=3, clr_incr=0)) points0.append( DAC_seq_point(address=4, time=4, start=4000, incr=6553600, chan=4, clr_incr=0)) points0.append( DAC_seq_point(address=5, time=5, start=5000, incr=6553600, chan=5, clr_incr=0)) points0.append( DAC_seq_point(address=6, time=6, start=6000, incr=6553600, chan=6, clr_incr=0)) points0.append( DAC_seq_point(address=7, time=7, start=7000, incr=6553600, chan=7, clr_incr=0)) points0.append( DAC_seq_point(address=8, time=8, start=8000, incr=6553600, chan=8, clr_incr=0)) points0.append( DAC_seq_point(address=9, time=9, start=9000, incr=6553600, chan=9, clr_incr=0)) points0.append( DAC_seq_point(address=10, time=10, start=10000, incr=6553600, chan=10, clr_incr=0)) points0.append( DAC_seq_point(address=11, time=11, start=11000, incr=6553600, chan=11, clr_incr=0)) points0.append( DAC_seq_point(address=12, time=12, start=12000, incr=6553600, chan=12, clr_incr=0)) points0.append( DAC_seq_point(address=13, time=13, start=13000, incr=6553600, chan=13, clr_incr=0)) points0.append( DAC_seq_point(address=14, time=14, start=14000, incr=6553600, chan=14, clr_incr=0)) points0.append( DAC_seq_point(address=15, time=15, start=15000, incr=6553600, chan=15, clr_incr=0)) points0.append( DAC_seq_point(address=16, time=0, start=0, incr=0, chan=0, clr_incr=0)) #step 100 LSB per 10 us points1.append( DAC_seq_point(address=0, time=0, start=10000, incr=6553600, chan=0, clr_incr=0)) points1.append( DAC_seq_point(address=1, time=1, start=1000, incr=6553600, chan=1, clr_incr=0)) points1.append( DAC_seq_point(address=2, time=2, start=2000, incr=6553600, chan=2, clr_incr=0)) points1.append( DAC_seq_point(address=3, time=3, start=3000, incr=6553600, chan=3, clr_incr=0)) points1.append( DAC_seq_point(address=4, time=4, start=4000, incr=6553600, chan=4, clr_incr=0)) points1.append( DAC_seq_point(address=5, time=5, start=5000, incr=6553600, chan=5, clr_incr=0)) points1.append( DAC_seq_point(address=6, time=6, start=6000, incr=6553600, chan=6, clr_incr=0)) points1.append( DAC_seq_point(address=7, time=7, start=7000, incr=6553600, chan=7, clr_incr=0)) points1.append( DAC_seq_point(address=8, time=8, start=8000, incr=6553600, chan=8, clr_incr=0)) points1.append( DAC_seq_point(address=9, time=9, start=9000, incr=6553600, chan=9, clr_incr=0)) points1.append( DAC_seq_point(address=10, time=10, start=10000, incr=6553600, chan=10, clr_incr=0)) points1.append( DAC_seq_point(address=11, time=11, start=11000, incr=6553600, chan=11, clr_incr=0)) points1.append( DAC_seq_point(address=12, time=12, start=12000, incr=6553600, chan=12, clr_incr=0)) points1.append( DAC_seq_point(address=13, time=13, start=13000, incr=6553600, chan=13, clr_incr=0)) points1.append( DAC_seq_point(address=14, time=14, start=14000, incr=6553600, chan=14, clr_incr=0)) points1.append( DAC_seq_point(address=15, time=15, start=15000, incr=6553600, chan=15, clr_incr=0)) points1.append( DAC_seq_point(address=16, time=0, start=0, incr=0, chan=0, clr_incr=0)) for point in points0: self.write_point(self.fifo_dac_seq0, point) for point in points1: self.write_point(self.fifo_dac_seq1, point) def dio_seq_write_points(self): points = [] points.append( GPIO_seq_point(address=0, time=1, outputA=0x00000001, outputB=0x00000001)) points.append( GPIO_seq_point(address=1, time=80000, outputA=0x00000000, outputB=0x00000000)) points.append( GPIO_seq_point(address=2, time=160000, outputA=0x00000001, outputB=0x00000001)) points.append( GPIO_seq_point(address=3, time=6400000, outputA=0x00000000, outputB=0x00000000)) points.append( GPIO_seq_point(address=4, time=0, outputA=0x00000000, outputB=0x00000000)) for point in points: print("add: ", point.address) print("time: ", point.time) print("outputA: ", point.outputA) print("outputB: ", point.outputB) # with open("/dev/axis_fifo_0x0000000080004000", "r+b") as character: for point in points: # writeToSeqGPIO(character, point) seqWords = getSeqGPIOWords(point) print("write SeqGPIO", seqWords) for word in seqWords: print(word) self.fifo_main_seq.write_axis_fifo(word[0], MSB_first=False)
from axis_fifo import AXIS_FIFO from devices import fifo_devices import struct fifo = AXIS_FIFO(fifo_devices['AD9959_0']) #Function Register 1 (FR1) fifo.write_axis_fifo("\x00\x80\x00\x00") fifo.write_axis_fifo("\x00\xC0\x00\x00")
class sequencer: def __init__(self): self.dacRes = 65535 #0xffff self.dacRange = [-10, 10] self.dacIncrMax = 0xffffffff # 32bit self.dacRampTimeRes = 2000 #20us in the unit of system clk (10ns) self.ddsAmpRange = [0, 5] self.ddsFreqRange = [0, 500] self.accUpdateFreq = 1.0 # accumulator update freq in MHz, not really used, for reminder self.ddsUpdateFreq = 50.0 # dds update freq in kHz, not really used, for reminder self.ddsFreqRangeConv = 0xffffffff / 500.0 #8589930 # (2^32 - 1)/500 MHz self.ddsAmpRangeConv = 0x3ff/100 # (2^10 - 1)/100 self.ddsFreqIncMax = 0xfffffffffff # 32 ftw + 12 acc = 44bit self.ddsAmpIncMax = 0x3fffff # 10 atw + 12 acc = 22bit # self.ddsTimeRes = 1.0e3 # in us # initialize DACs self.dac0 = DAC81416(fifo_devices['DAC81416_0']) self.dac1 = DAC81416(fifo_devices['DAC81416_1']) self.dds0 = AD9959(fifo_devices['AD9959_0']) self.dds1 = AD9959(fifo_devices['AD9959_1']) self.dds2 = AD9959(fifo_devices['AD9959_2']) self.fifo_dac0_seq = AXIS_FIFO(fifo_devices['DAC81416_0_seq']) self.fifo_dac1_seq = AXIS_FIFO(fifo_devices['DAC81416_1_seq']) dds_lock_pll.dds_lock_pll() # initialize DDSs self.fifo_dds0_atw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_atw']) self.fifo_dds0_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_ftw']) self.fifo_dds1_atw_seq = AXIS_FIFO(fifo_devices['AD9959_1_seq_atw']) self.fifo_dds1_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_1_seq_ftw']) self.fifo_dds2_atw_seq = AXIS_FIFO(fifo_devices['AD9959_2_seq_atw']) self.fifo_dds2_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_2_seq_ftw']) # self.dds = AD9959(dds_device) # initialize DDS self.gpio2 = AXI_GPIO(gpio_devices['axi_gpio_2']) self.fifo_dio_seq = AXIS_FIFO(fifo_devices['GPIO_seq']) reset() def initExp(self): print('******************************************************************************************************************************************************************') print('initializing experiment') self.mod_disable() reset() dds_lock_pll.dds_lock_pll() self.mod_enable() self.mod_report() def getWord(self, bytes): return bytes[3] + bytes[2] + bytes[1] + bytes[0] def soft_trigger(self): trigger() def write_dio_point(self, point): #01XXAAAA TTTTTTTT DDDDDDDD self.fifo_dio_seq.write_axis_fifo(b"\x01\x00" + struct.pack('>H', point.address)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.outputA)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.outputB)) def write_dio(self, byte_buf): #01XXAAAA TTTTTTTT DDDDDDDD self.fifo_dio_seq.write_axis_fifo(byte_buf, MSB_first=False) def write_dac_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #clr_incr <= gpio_in(52 downto 52); #acc_chan <= gpio_in(51 downto 48); #acc_start <= gpio_in(47 downto 32); #acc_incr <= gpio_in(31 downto 0); fifo.write_axis_fifo(b"\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo(struct.pack('>I', point.clr_incr*16*256*256 + point.chan*256*256 + point.start)) fifo.write_axis_fifo(struct.pack('>I', point.incr)) def write_atw_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #unused <= gpio_in(63 downto 58); #acc_start <= gpio_in(57 downto 48); #acc_steps <= gpio_in(47 downto 32); #unused <= gpio_in(31 downto 26); #acc_incr <= gpio_in(25 downto 4); #unused <= gpio_in( 3 downto 2); #acc_chan <= gpio_in( 1 downto 0); # print('addr', point.address, 'time', point.time, 'start', point.start, 'steps', point.steps, 'incr', point.incr, 'channel', point.chan) fifo.write_axis_fifo(b"\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo(struct.pack('>I', (point.start << 16) + point.steps)) fifo.write_axis_fifo(struct.pack('>I', (point.incr << 4) + point.chan)) def write_ftw_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(95 downto 64); #acc_steps <= gpio_in(63 downto 48); #acc_incr <= gpio_in(47 downto 4) 32 ftw + 12 phase acc; #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); incr_hi = point.incr >> 28 #(point.incr & (0xffff << 28)) # acc_incr_hi <= gpio_in(47 downto 32) incr_lo = point.incr & ((1 << 28) - 1) # acc_incr_lo <= gpio_in(31 downto 4) # print point.steps * 256 * 256, incr_hi,incr_lo, point.incr, point.steps * 256 * 256 + incr_hi # print point.incr & (0xffff>>28), point.incr & ((1<<28)-1), (point.steps << 16) + incr_hi, (incr_lo << 4) + point.chan # print incr_hi, incr_lo, point.steps * 256 * 256 + incr_hi, incr_lo * 16 + point.chan fifo.write_axis_fifo(b"\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo(struct.pack('>I', point.start)) fifo.write_axis_fifo(struct.pack('>I', (point.steps << 16) + incr_hi)) fifo.write_axis_fifo(struct.pack('>I', (incr_lo << 4) + point.chan)) def reset_DAC(self): self.dac0 = DAC81416(fifo_devices['DAC81416_0']) self.dac1 = DAC81416(fifo_devices['DAC81416_1']) def set_DAC(self, channel, value): valueInt = int((value-self.dacRange[0])*self.dacRes/(self.dacRange[1]-self.dacRange[0]) + 0.5) assert channel>=0 and channel<=31, 'Invalid channel for DAC81416 in set_DAC' assert valueInt>=0 and valueInt<=65536, 'Invalid value for DAC81416 in set_DAC' if valueInt == 65536: valueInt -= 1 if (channel > 15): channel = channel-16 self.dac1.set_DAC(channel, valueInt) else: self.dac0.set_DAC(channel, valueInt) def set_DDS(self, channel, freq, amp=None): assert channel>=0 and channel<=11, 'Invalid channel for AD9959 in set_DDS' dds_lock_pll.dds_lock_pll() if (channel > 7): channel = channel-8 self.dds2.set_DDS(channel, freq, amp) elif (3 < channel < 8): channel = channel-4 self.dds1.set_DDS(channel, freq, amp) else: self.dds0.set_DDS(channel, freq, amp) def mod_enable(self): print('mod enabled from zynq') self.gpio2.set_bit(0, channel=1) self.mod_report() def mod_disable(self): print('mod disabled from zynq') self.gpio2.clear_bit(0, channel=1) def reset(self): self.gpio2.write_axi_gpio(0xffff0000,channel=2) self.gpio2.write_axi_gpio(0x0000ffff,channel=2) def reset_disable_mod(self): print('disabling mod and resetting sequencers') self.reset() self.mod_disable() def reset_enable_mod(self): print('resetting sequencers and enabling mod') self.mod_disable() dds_lock_pll.dds_lock_pll() self.reset() self.mod_enable() def lock_PLL(self): dds_lock_pll.dds_lock_pll() def mod_report(self): status = int(self.gpio2.read_axi_gpio(channel=1).hex(), 16) if status == 1: print('MOD IS ON, CAN RUN SEQUENCER FOR EXPERIMENT OR CHANGE DAC, TTL NOW') elif status == 0: print('MOD IS OFF, CAN UPDATE DDS GUI NOW') else: print('MOD is not in valid state, a low level bug') def dac_seq_write_points(self, byte_len, byte_buf, num_snapshots): print('DAC points') points0 = [] points1 = [] for ii in range(num_snapshots): # t is in 10ns, s is in V, end is in V, duration is in 10ns [t, chan, s, end, duration] = self.dac_read_point(byte_buf[ii*byte_len: ii*byte_len + byte_len]) print('time',t,'channel', chan,'start', s,'end', end,'duration', duration) num_steps = int(duration/self.dacRampTimeRes + 0.5) # num_steps = int(duration * self.accUpdateFreq) # duration is in us and accUpdateFreq is in MHz if (num_steps < 1): ramp_inc = 0 clr_incr = 1 else: ramp_inc = int(abs((end<<16)-(s<<16))/num_steps+0.5) clr_incr = 0 # print(s, end, num_steps, ramp_inc) if (end<s and ramp_inc != 0): ramp_inc = int(self.dacIncrMax + 1 - ramp_inc) print('time',t,'channel', chan,'start', s,'end', end,'duration', duration, 'num_step',num_steps, 'ramp_inc: ', ramp_inc) t = int(t/self.dacRampTimeRes + 0.5) * self.dacRampTimeRes + (chan%16) if (chan < 16): points0.append(DAC_seq_point(address=len(points0),time=t,start=s,incr=ramp_inc,chan=chan,clr_incr=clr_incr)) else: points1.append(DAC_seq_point(address=len(points1),time=t,start=s,incr=ramp_inc,chan=chan-16,clr_incr=clr_incr)) if (len(points0) != 0): points0.append(DAC_seq_point(address=len(points0), time=0, start=0,incr=0,chan=0,clr_incr=0)) if (len(points1) != 0): points1.append(DAC_seq_point(address=len(points1), time=0, start=0,incr=0,chan=0,clr_incr=0)) for point in points0: print('DAC_seq_point(', 'address=', point.address, ', time = ', point.time, ',start =', point.start, ',incr = ', point.incr, ',chan=', point.chan, ',clr_incr=', point.clr_incr, ')' ) self.write_dac_point(self.fifo_dac0_seq, point) for point in points1: print('DAC_seq_point(', 'address=', point.address, ', time = ', point.time, ',start =', point.start, ',incr = ', point.incr, ',chan=', point.chan, ',clr_incr=', point.clr_incr, ')' ) self.write_dac_point(self.fifo_dac1_seq, point) def dds_seq_write_points(self, byte_len, byte_buf, num_snapshots): ftw_points0=[] ftw_points1=[] ftw_points2=[] atw_points0=[] atw_points1=[] atw_points2=[] for ii in range(num_snapshots): [t, channel, aorf, s, end, duration] = self.dds_read_point(byte_buf[ii*byte_len: ii*byte_len + byte_len]) # num_steps = (duration/self.ddsTimeRes) num_steps = int(duration * self.accUpdateFreq) # duration is in us and accUpdateFreq is in MHz if (num_steps == 0): ramp_inc = 0 else: # ramp_inc = int((end-s)/num_steps) * 4 #somehow setting ddsTimeRes to 1.0e3 and add *4 works for freq ramp final value ramp_inc = int((end - s)*1.0 / num_steps * 4096) # * 1.0 just to avoid zero if end-s < num_steps(this is not true in python3, but in python2 int(2)/int(3)=0), # 4096=0xfff+1 comes from the 12bit accumulator print('time',t,'channel', channel, aorf,'start', s,'end', end,'duration', duration, 'num_step',num_steps, 'ramp_inc: ', ramp_inc) if (aorf == b'f'): if (ramp_inc < 0): # ramp_inc = int(self.ddsFreqRangeConv + ramp_inc) ramp_inc = int(self.ddsFreqIncMax + ramp_inc) if (channel < 4): ftw_points0.append(DDS_ftw_seq_point(address=len(ftw_points0), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) elif (4 <= channel < 8): channel = channel-4 ftw_points1.append(DDS_ftw_seq_point(address=len(ftw_points1), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) else: channel = channel-8 ftw_points2.append(DDS_ftw_seq_point(address=len(ftw_points2), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) elif (aorf == b'a'): if (ramp_inc < 0): ramp_inc = int(self.ddsAmpIncMax + ramp_inc) if (channel < 4): atw_points0.append(DDS_atw_seq_point(address=len(atw_points0), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) elif (4 <= channel < 8): channel = channel-4 atw_points1.append(DDS_atw_seq_point(address=len(atw_points1), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) else: channel = channel-8 atw_points2.append(DDS_atw_seq_point(address=len(atw_points2), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) else: print("invalid dds type. set to 'f' for freq or 'a' for amp") if (len(atw_points0) != 0): atw_points0.append(DDS_atw_seq_point(address=len(atw_points0), time=0, start=0, steps=0, incr=0, chan=0)) if (len(atw_points1) != 0): atw_points1.append(DDS_atw_seq_point(address=len(atw_points1), time=0, start=0, steps=0, incr=0, chan=0)) if (len(atw_points2) != 0): atw_points2.append(DDS_atw_seq_point(address=len(atw_points2), time=0, start=0, steps=0, incr=0, chan=0)) if (len(ftw_points0) != 0): ftw_points0.append(DDS_ftw_seq_point(address=len(ftw_points0), time=0, start=0, steps=0, incr=0, chan=0)) if (len(ftw_points1) != 0): ftw_points1.append(DDS_ftw_seq_point(address=len(ftw_points1), time=0, start=0, steps=0, incr=0, chan=0)) if (len(ftw_points2) != 0): ftw_points2.append(DDS_ftw_seq_point(address=len(ftw_points2), time=0, start=0, steps=0, incr=0, chan=0)) for point in ftw_points0: print("ftw dds0") self.write_ftw_point(self.fifo_dds0_ftw_seq, point) for point in ftw_points1: print("ftw dds1") self.write_ftw_point(self.fifo_dds1_ftw_seq, point) for point in ftw_points2: print("ftw dds2") # print(point.address, point.time, point.chan) self.write_ftw_point(self.fifo_dds2_ftw_seq, point) for point in atw_points0: print("atw dds0") self.write_atw_point(self.fifo_dds0_atw_seq, point) for point in atw_points1: print("atw dds1") self.write_atw_point(self.fifo_dds1_atw_seq, point) for point in atw_points2: print("atw dds2") self.write_atw_point(self.fifo_dds2_atw_seq, point) def dds_seq_write_atw_points(self): points=[] #these ramps should complete in just under 64 ms points.append(DDS_atw_seq_point(address=0,time= 0,start=1023,steps=0,incr=0,chan=0)) #25% to 75% # points.append(DDS_atw_seq_point(address=1,time=1000,start=256,steps=1,incr=0,chan=3)) #25% to 75% points.append(DDS_atw_seq_point(address=1,time= 0,start=0,steps= 0,incr= 0,chan=0)) for point in points: self.write_atw_point(self.fifo_dds_atw_seq, point) def dds_seq_write_ftw_points(self): points=[] # points.append(DDS_ftw_seq_point(address=0,time=0,start=200000000,steps=0,incr=0,chan=0)) # ~ points.append(DDS_ftw_seq_point(address=0,time= 0,start=800000,steps=10000,incr=30000,chan=0)) points.append(DDS_ftw_seq_point(address=0,time=0,start=800000,steps=0,incr=0,chan=1)) points.append(DDS_ftw_seq_point(address=1,time=20000,start=500000,steps=0,incr=0,chan=2)) points.append(DDS_ftw_seq_point(address=2,time=0,start=0,steps=0,incr=0,chan=0)) for point in points: self.write_ftw_point(self.fifo_dds_ftw_seq, point) def dio_seq_write_points(self, byte_len, byte_buf, num_snapshots): print('DIO points') points=[] for ii in range(num_snapshots): [t, outA, outB] = self.dio_read_point(byte_buf[ii*byte_len: ii*byte_len + byte_len]) points.append(GPIO_seq_point(address=ii,time=t,outputA=outA,outputB=outB)) # points.append(GPIO_seq_point(address=num_snapshots,time=6400000,outputA=0x00000000,outputB=0x00000000)) points.append(GPIO_seq_point(address=num_snapshots,time=0,outputA=0x00000000,outputB=0x00000000)) # with open("/dev/axis_fifo_0x0000000080004000", "wb") as character: for point in points: # writeToSeqGPIO(character, point) seqWords = getSeqGPIOWords(point) print('GPIO_seq_point(address = ',point.address, ',time=',point.time, ',outputA = ',"{0:#0{1}x}".format(point.outputA,8+2), ',outputB = ',"{0:#0{1}x}".format(point.outputB,8+2), ')') for word in seqWords: # print word self.fifo_dio_seq.write_axis_fifo(word[0], MSB_first=False) def dio_read_point(self, snapshot): print(snapshot) snapshot_split = snapshot.split(b'_') t = int(snapshot_split[0].strip(b't'), 16) out = snapshot_split[1].strip(b'b').strip(b'\0') outB = int(out[:8], 16) outA = int(out[8:], 16) return [t, outA, outB] def dac_read_point(self, snapshot): print(snapshot) snapshot_split = snapshot.split(b'_') t = int(snapshot_split[0].strip(b't'), 16) chan = int(snapshot_split[1].strip(b'c'), 16) start = int(self.dacRes*(float(snapshot_split[2].strip(b's')) - self.dacRange[0]) /(self.dacRange[1]-self.dacRange[0]) + 0.5) end = int(self.dacRes*(float(snapshot_split[3].strip(b'e')) - self.dacRange[0]) /(self.dacRange[1]-self.dacRange[0]) + 0.5) duration = int(snapshot_split[4].strip(b'd').strip(b'\0'), 16) return [t, chan, start, end, duration] def dds_read_point(self, snapshot): print(snapshot) snapshot_split = snapshot.split(b'_') t = int(snapshot_split[0].strip(b't'), 16) chan = int(snapshot_split[1].strip(b'c'), 16) aorf = snapshot_split[2] if (aorf == b'f'): ddsConv = self.ddsFreqRangeConv elif (aorf == b'a'): ddsConv = self.ddsAmpRangeConv else: print("invalid dds type. set to 'f' for freq or 'a' for amp") start = int(float(snapshot_split[3].strip(b's'))*ddsConv) end = int(float(snapshot_split[4].strip(b'e'))*ddsConv) duration = int(snapshot_split[5].strip(b'd').strip(b'\0'), 16) return [t, chan, aorf, start, end, duration]
class DDS_ramp_tester: def __init__(self, device, device_atw_seq, device_ftw_seq, main_seq): #self.dds = AD9959(device) # initialize DDS -- not needed for now self.gpio2 = AXI_GPIO(gpio_devices['axi_gpio_2']) self.fifo_dds_atw_seq = AXIS_FIFO(device_atw_seq) self.fifo_dds_ftw_seq = AXIS_FIFO(device_ftw_seq) self.fifo_main_seq = AXIS_FIFO(main_seq) def write_atw_point(self, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #unused <= gpio_in(63 downto 58); #acc_start <= gpio_in(57 downto 48); #acc_steps <= gpio_in(47 downto 32); #unused <= gpio_in(31 downto 26); #acc_incr <= gpio_in(25 downto 4); #unused <= gpio_in( 3 downto 2); #acc_chan <= gpio_in( 1 downto 0); self.fifo_dds_atw_seq.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) self.fifo_dds_atw_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dds_atw_seq.write_axis_fifo(struct.pack('>I', point.start*256*256 + point.steps)) self.fifo_dds_atw_seq.write_axis_fifo(struct.pack('>I', point.incr*16+point.chan)) def write_ftw_point(self, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(95 downto 64); #acc_steps <= gpio_in(63 downto 48); #acc_incr <= gpio_in(47 downto 4); #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); incr_hi = int(math.floor(point.incr*1.0/2**28)) incr_lo = point.incr - incr_hi * 2**28 self.fifo_dds_ftw_seq.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) self.fifo_dds_ftw_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dds_ftw_seq.write_axis_fifo(struct.pack('>I', point.start)) self.fifo_dds_ftw_seq.write_axis_fifo(struct.pack('>I', point.steps*256*256 + incr_hi)) self.fifo_dds_ftw_seq.write_axis_fifo(struct.pack('>I', incr_lo*16+point.chan)) #def reset_DDS(self): #--not needed # self.dds = AD9959(device) # initialize DDS def mod_enable(self): self.gpio2.set_bit(0, channel=1) def mod_disable(self): self.gpio2.clear_bit(0, channel=1) def mod_report(self): print((self.gpio2.read_axi_gpio(channel=1))) def dds_seq_write_atw_points(self): points=[] #these ramps should complete in just under 64 ms points.append(DDS_atw_seq_point(address=0,time=10000,start=1023,steps=0,incr=0,chan=1)) #25% to 75% # points.append(DDS_atw_seq_point(address=1,time=1000,start=256,steps=1,incr=0,chan=3)) #25% to 75% points.append(DDS_atw_seq_point(address=1,time=0,start=0,steps= 0,incr= 0,chan=0)) for point in points: self.write_atw_point(point) def dds_seq_write_ftw_points(self): points=[] #these ramps should complete in just under 64 ms points.append(DDS_ftw_seq_point(address=0,time=0,start=472446000,steps=0,incr=0,chan=0)) #points.append(DDS_ftw_seq_point(address=1,time= 20000, start=4000000,steps=0,incr=0,chan=0)) # points.append(DDS_ftw_seq_point(address=1,time=1,start=1000000,steps=1,incr=0,chan=3)) points.append(DDS_ftw_seq_point(address=1,time= 0,start= 0,steps= 0,incr= 0,chan=0)) for point in points: self.write_ftw_point(point) def dio_seq_write_points(self): points=[] points.append(GPIO_seq_point(address=0,time=1,outputA=0x00000001,outputB=0x00000001)) points.append(GPIO_seq_point(address=1,time=20000,outputA=0x00000000,outputB=0x00000000)) points.append(GPIO_seq_point(address=2,time=40000,outputA=0x00000001,outputB=0x00000001)) points.append(GPIO_seq_point(address=3,time=6400000,outputA=0x00000000,outputB=0x00000000)) points.append(GPIO_seq_point(address=4,time=0,outputA=0x00000000,outputB=0x00000000)) for point in points: print("add: ", point.address) print("time: ", point.time) print("outputA: ", point.outputA) print("outputB: ", point.outputB) # with open("/dev/axis_fifo_0x0000000080004000", "wb") as character: for point in points: # writeToSeqGPIO(character, point) seqWords = getSeqGPIOWords(point) for word in seqWords: # print word self.fifo_main_seq.write_axis_fifo(word[0], MSB_first=False)
class DAC_ramp_tester: def __init__(self, device, device_seq0, device_seq1, main_seq): self.dac = DAC81416(device) # initialize DAC self.gpio2 = AXI_GPIO(gpio_devices['axi_gpio_2']) self.fifo_dac_seq0 = AXIS_FIFO(device_seq0) self.fifo_dac_seq1 = AXIS_FIFO(device_seq1) self.fifo_main_seq = AXIS_FIFO(main_seq) def write_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(63 downto 48); #acc_steps <= gpio_in(47 downto 32); #acc_incr <= gpio_in(31 downto 4); #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); fifo.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo(struct.pack('>I', point.start*256*256 + point.steps)) fifo.write_axis_fifo(struct.pack('>I', point.incr*16+point.chan)) def reset_DAC(self): self.dac = DAC81416(device) # initialize DAC def mod_enable(self): self.gpio2.set_bit(0, channel=1) def mod_disable(self): self.gpio2.clear_bit(0, channel=1) def mod_report(self): print(self.gpio2.read_axi_gpio(channel=1)) def dac_seq_write_points(self): points0=[] points1=[] #these ramps should complete in just under 64 ms #points.append(DAC_seq_point(address=0,time=0,start=256*128,steps=20000,incr=4096,chan=0)) points0.append(DAC_seq_point(address=0,time=1,start=256*128,steps=10000,incr=50,chan=0)) # points0.append(DAC_seq_point(address=2,time=160000,start=256*134,steps=0,incr=0,chan=0)) points0.append(DAC_seq_point(address=1, time=0,start=0,steps=0,incr=0,chan=0)) # points1.append(DAC_seq_point(address=0,time=1,start=256*200,steps=1,incr=0,chan=0)) # points1.append(DAC_seq_point(address=1,time=500000,start=256*128,steps=1,incr=0,chan=0)) # points1.append(DAC_seq_point(address=2, time=0,start=0,steps=0,incr=0,chan=0)) for point in points0: self.write_point(self.fifo_dac_seq0, point) for point in points1: self.write_point(self.fifo_dac_seq1, point) def dio_seq_write_points(self): points=[] points.append(GPIO_seq_point(address=0,time=1,outputA=0x00000001,outputB=0x00000001)) points.append(GPIO_seq_point(address=1,time=20000,outputA=0x00000000,outputB=0x00000000)) points.append(GPIO_seq_point(address=2,time=40000,outputA=0x00000001,outputB=0x00000001)) points.append(GPIO_seq_point(address=3,time=6400000,outputA=0x00000000,outputB=0x00000000)) points.append(GPIO_seq_point(address=4,time=0,outputA=0x00000000,outputB=0x00000000)) for point in points: print "add: ", point.address print "time: ", point.time print "outputA: ", point.outputA print "outputB: ", point.outputB # with open("/dev/axis_fifo_0x0000000080004000", "r+b") as character: for point in points: # writeToSeqGPIO(character, point) seqWords = getSeqGPIOWords(point) for word in seqWords: # print word self.fifo_main_seq.write_axis_fifo(word[0], MSB_first=False)
class sequencer: def __init__(self): self.dacRes = 65536 #0xffff self.dacRange = [-10, 10] self.dacRangeConv = float(167772) / self.dacRes self.dacIncrMax = 0xfffffff # 16 atw + 12 acc = 28bit #268435455 # self.dacTimeRes = 1.6e3 # in us self.ddsAmpRange = [0, 5] self.ddsFreqRange = [0, 500] self.accUpdateFreq = 1.0 # accumulator update freq in MHz, not really used, for reminder self.ddsUpdateFreq = 50.0 # dds update freq in kHz, not really used, for reminder self.ddsFreqRangeConv = 0xffffffff / 500.0 #8589930 # (2^32 - 1)/500 MHz self.ddsAmpRangeConv = 0x3ff / 1.25 #818.4 # (2^10 - 1)/1.25 mW self.ddsFreqIncMax = 0xfffffffffff # 32 ftw + 12 acc = 44bit self.ddsAmpIncMax = 0x3fffff # 10 atw + 12 acc = 22bit # self.ddsTimeRes = 1.0e3 # in us # initialize DACs self.dac0 = DAC81416(fifo_devices['DAC81416_0']) self.dac1 = DAC81416(fifo_devices['DAC81416_1']) self.dds0 = AD9959(fifo_devices['AD9959_0']) self.dds1 = AD9959(fifo_devices['AD9959_1']) self.dds2 = AD9959(fifo_devices['AD9959_2']) self.fifo_dac0_seq = AXIS_FIFO(fifo_devices['DAC81416_0_seq']) self.fifo_dac1_seq = AXIS_FIFO(fifo_devices['DAC81416_1_seq']) # initialize DDSs self.fifo_dds_atw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_atw']) self.fifo_dds_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_ftw']) self.fifo_dds0_atw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_atw']) self.fifo_dds0_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_0_seq_ftw']) self.fifo_dds1_atw_seq = AXIS_FIFO(fifo_devices['AD9959_1_seq_atw']) self.fifo_dds1_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_1_seq_ftw']) self.fifo_dds2_atw_seq = AXIS_FIFO(fifo_devices['AD9959_2_seq_atw']) self.fifo_dds2_ftw_seq = AXIS_FIFO(fifo_devices['AD9959_2_seq_ftw']) # self.dds = AD9959(dds_device) # initialize DDS self.gpio2 = AXI_GPIO(gpio_devices['axi_gpio_2']) self.fifo_dio_seq = AXIS_FIFO(fifo_devices['GPIO_seq']) def initExp(self): print '******************************************************************************************************************************************************************' print 'initializing experiment' self.mod_disable() reset() dds_lock_pll.dds_lock_pll() def getWord(self, bytes): return bytes[3] + bytes[2] + bytes[1] + bytes[0] def soft_trigger(self): trigger() def write_dio_point(self, point): #01XXAAAA TTTTTTTT DDDDDDDD self.fifo_dio_seq.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.time)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.outputA)) self.fifo_dio_seq.write_axis_fifo(struct.pack('>I', point.outputB)) def write_dio(self, byte_buf): #01XXAAAA TTTTTTTT DDDDDDDD self.fifo_dio_seq.write_axis_fifo(byte_buf, MSB_first=False) def write_dac_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(63 downto 48); #acc_steps <= gpio_in(47 downto 32); #acc_incr <= gpio_in(31 downto 4); #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); print "add:", point.address, " time:", point.time, " start:", point.start, \ " steps:", point.steps, " incr:", point.incr, " chan:", point.chan fifo.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo( struct.pack('>I', (point.start << 16) + point.steps)) fifo.write_axis_fifo(struct.pack('>I', (point.incr << 4) + point.chan)) def write_atw_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #unused <= gpio_in(63 downto 58); #acc_start <= gpio_in(57 downto 48); #acc_steps <= gpio_in(47 downto 32); #unused <= gpio_in(31 downto 26); #acc_incr <= gpio_in(25 downto 4); #unused <= gpio_in( 3 downto 2); #acc_chan <= gpio_in( 1 downto 0); print 'addr', point.address, 'time', point.time, 'start', point.start, 'steps', point.steps, 'incr', point.incr, 'channel', point.chan fifo.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo( struct.pack('>I', (point.start << 16) + point.steps)) fifo.write_axis_fifo(struct.pack('>I', (point.incr << 4) + point.chan)) def write_ftw_point(self, fifo, point): #01XXAAAA TTTTTTTT DDDDDDDD DDDDDDDD DDDDDDDD #phase acc shifts by 12 bit => 4096 #acc_start <= gpio_in(95 downto 64); #acc_steps <= gpio_in(63 downto 48); #acc_incr <= gpio_in(47 downto 4) 32 ftw + 12 phase acc; #acc_chan <= to_integer(unsigned(gpio_in( 3 downto 0))); incr_hi = point.incr >> 28 #(point.incr & (0xffff << 28)) # acc_incr_hi <= gpio_in(47 downto 32) incr_lo = point.incr & ( (1 << 28) - 1) # acc_incr_lo <= gpio_in(31 downto 4) # print point.steps * 256 * 256, incr_hi,incr_lo, point.incr, point.steps * 256 * 256 + incr_hi # print point.incr & (0xffff>>28), point.incr & ((1<<28)-1), (point.steps << 16) + incr_hi, (incr_lo << 4) + point.chan # print incr_hi, incr_lo, point.steps * 256 * 256 + incr_hi, incr_lo * 16 + point.chan fifo.write_axis_fifo("\x01\x00" + struct.pack('>H', point.address)) fifo.write_axis_fifo(struct.pack('>I', point.time)) fifo.write_axis_fifo(struct.pack('>I', point.start)) fifo.write_axis_fifo(struct.pack('>I', (point.steps << 16) + incr_hi)) fifo.write_axis_fifo(struct.pack('>I', (incr_lo << 4) + point.chan)) def reset_DAC(self): self.dac = DAC81416(device) # initialize DAC def set_DAC(self, channel, value): valueInt = int((value - self.dacRange[0]) * self.dacRes / (self.dacRange[1] - self.dacRange[0])) assert channel >= 0 and channel <= 31, 'Invalid channel for DAC81416 in set_DAC' if (channel > 15): channel = channel - 16 self.dac1.set_DAC(channel, valueInt) else: self.dac0.set_DAC(channel, valueInt) def set_DDS(self, channel, freq, amp=None): assert channel >= 0 and channel <= 11, 'Invalid channel for AD9959 in set_DDS' dds_lock_pll.dds_lock_pll() if (channel > 7): channel = channel - 8 self.dds2.set_DDS(channel, freq, amp) elif (3 < channel < 8): channel = channel - 4 self.dds1.set_DDS(channel, freq, amp) else: self.dds0.set_DDS(channel, freq, amp) def mod_enable(self): self.gpio2.set_bit(0, channel=1) def mod_disable(self): self.gpio2.clear_bit(0, channel=1) def reset_disable_mod(self): print 'disabling mod and resetting sequencers' self.gpio2.write_axi_gpio(0xffff0000, channel=2) self.gpio2.write_axi_gpio(0x0000ffff, channel=2) self.mod_disable() def mod_report(self): print(self.gpio2.read_axi_gpio(channel=1)) def dac_seq_write_points(self, byte_len, byte_buf, num_snapshots): print 'DAC points' points0 = [] points1 = [] for ii in range(num_snapshots): [t, chan, s, end, duration] = self.dac_read_point( byte_buf[ii * byte_len:ii * byte_len + byte_len]) # num_steps = duration/self.dacTimeRes num_steps = int(duration * self.accUpdateFreq ) # duration is in us and accUpdateFreq is in MHz if (int(num_steps) <= 1): ramp_inc = 0 else: # ramp_inc = int((end-s)*self.dacRangeConv/(num_steps)) ramp_inc = int((end - s) * 1.0 / num_steps * 4096) # * 1.0 just to avoid zero if end-s < num_steps(this is not true in python3, but in python2 int(2)/int(3)=0), # 4096=0xfff+1 comes from the 12bit accumulator # print(s, end, num_steps, ramp_inc) if (ramp_inc < 0): ramp_inc = int(self.dacIncrMax + ramp_inc) print 'time', t, 'channel', chan, 'start', s, 'end', end, 'duration', duration, 'num_step', num_steps, 'ramp_inc: ', ramp_inc # print "ramp_inc = ", ramp_inc, " num_steps = ", num_steps, " dacRangeConv = ", self.dacRangeConv if (chan < 16): points0.append( DAC_seq_point(address=len(points0), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=chan)) else: points1.append( DAC_seq_point(address=len(points1), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=chan - 16)) if (len(points0) != 0): points0.append( DAC_seq_point(address=len(points0), time=0, start=0, steps=0, incr=0, chan=0)) if (len(points1) != 0): points1.append( DAC_seq_point(address=len(points1), time=0, start=0, steps=0, incr=0, chan=0)) for i in range(1, len(points0)): for j in range(i): # print(i,j) if (points0[i].time == points0[j].time): points0[i].time = points0[i].time + 1 for i in range(1, len(points1)): for j in range(i): if (points1[i].time == points1[j].time): points1[i].time = points1[i].time + 1 for point in points0: #print "add: ", point.address #print "time: ", point.time #print "start: ", point.start #print "steps: ", point.steps #print "incr: ", point.incr #print "chan: ", point.chan self.write_dac_point(self.fifo_dac0_seq, point) for point in points1: self.write_dac_point(self.fifo_dac1_seq, point) def dds_seq_write_points(self, byte_len, byte_buf, num_snapshots): ftw_points0 = [] ftw_points1 = [] ftw_points2 = [] atw_points0 = [] atw_points1 = [] atw_points2 = [] for ii in range(num_snapshots): [t, channel, aorf, s, end, duration] = self.dds_read_point( byte_buf[ii * byte_len:ii * byte_len + byte_len]) # num_steps = (duration/self.ddsTimeRes) num_steps = int(duration * self.accUpdateFreq ) # duration is in us and accUpdateFreq is in MHz if (num_steps == 0): ramp_inc = 0 else: # ramp_inc = int((end-s)/num_steps) * 4 #somehow setting ddsTimeRes to 1.0e3 and add *4 works for freq ramp final value ramp_inc = int((end - s) * 1.0 / num_steps * 4096) # * 1.0 just to avoid zero if end-s < num_steps(this is not true in python3, but in python2 int(2)/int(3)=0), # 4096=0xfff+1 comes from the 12bit accumulator print 'time', t, 'channel', channel, aorf, 'start', s, 'end', end, 'duration', duration, 'num_step', num_steps, 'ramp_inc: ', ramp_inc if (aorf == 'f'): if (ramp_inc < 0): # ramp_inc = int(self.ddsFreqRangeConv + ramp_inc) ramp_inc = int(self.ddsFreqIncMax + ramp_inc) if (channel < 4): ftw_points0.append( DDS_ftw_seq_point(address=len(ftw_points0), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) elif (4 <= channel < 8): channel = channel - 4 ftw_points1.append( DDS_ftw_seq_point(address=len(ftw_points1), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) else: channel = channel - 8 ftw_points2.append( DDS_ftw_seq_point(address=len(ftw_points2), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) elif (aorf == 'a'): if (ramp_inc < 0): ramp_inc = int(self.ddsAmpIncMax + ramp_inc) if (channel < 4): atw_points0.append( DDS_atw_seq_point(address=len(atw_points0), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) elif (4 <= channel < 8): channel = channel - 4 atw_points1.append( DDS_atw_seq_point(address=len(atw_points1), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) else: channel = channel - 8 atw_points2.append( DDS_atw_seq_point(address=len(atw_points2), time=t, start=s, steps=num_steps, incr=ramp_inc, chan=channel)) else: print "invalid dds type. set to 'f' for freq or 'a' for amp" if (len(atw_points0) != 0): atw_points0.append( DDS_atw_seq_point(address=len(atw_points0), time=0, start=0, steps=0, incr=0, chan=0)) if (len(atw_points1) != 0): atw_points1.append( DDS_atw_seq_point(address=len(atw_points1), time=0, start=0, steps=0, incr=0, chan=0)) if (len(atw_points2) != 0): atw_points2.append( DDS_atw_seq_point(address=len(atw_points2), time=0, start=0, steps=0, incr=0, chan=0)) if (len(ftw_points0) != 0): ftw_points0.append( DDS_ftw_seq_point(address=len(ftw_points0), time=0, start=0, steps=0, incr=0, chan=0)) if (len(ftw_points1) != 0): ftw_points1.append( DDS_ftw_seq_point(address=len(ftw_points1), time=0, start=0, steps=0, incr=0, chan=0)) if (len(ftw_points2) != 0): ftw_points2.append( DDS_ftw_seq_point(address=len(ftw_points2), time=0, start=0, steps=0, incr=0, chan=0)) for point in ftw_points0: print "ftw dds0" self.write_ftw_point(self.fifo_dds0_ftw_seq, point) for point in ftw_points1: print "ftw dds1" self.write_ftw_point(self.fifo_dds1_ftw_seq, point) for point in ftw_points2: print "ftw dds2" print point.address, point.time, point.chan self.write_ftw_point(self.fifo_dds2_ftw_seq, point) for point in atw_points0: print "atw dds0" self.write_atw_point(self.fifo_dds0_atw_seq, point) for point in atw_points1: print "atw dds1" self.write_atw_point(self.fifo_dds1_atw_seq, point) for point in atw_points2: print "atw dds2" self.write_atw_point(self.fifo_dds2_atw_seq, point) def dds_seq_write_atw_points(self): points = [] #these ramps should complete in just under 64 ms points.append( DDS_atw_seq_point(address=0, time=0, start=1023, steps=0, incr=0, chan=0)) #25% to 75% # points.append(DDS_atw_seq_point(address=1,time=1000,start=256,steps=1,incr=0,chan=3)) #25% to 75% points.append( DDS_atw_seq_point(address=1, time=0, start=0, steps=0, incr=0, chan=0)) for point in points: self.write_atw_point(self.fifo_dds_atw_seq, point) def dds_seq_write_ftw_points(self): points = [] # points.append(DDS_ftw_seq_point(address=0,time=0,start=200000000,steps=0,incr=0,chan=0)) # ~ points.append(DDS_ftw_seq_point(address=0,time= 0,start=800000,steps=10000,incr=30000,chan=0)) points.append( DDS_ftw_seq_point(address=0, time=0, start=800000, steps=0, incr=0, chan=1)) points.append( DDS_ftw_seq_point(address=1, time=20000, start=500000, steps=0, incr=0, chan=2)) points.append( DDS_ftw_seq_point(address=2, time=0, start=0, steps=0, incr=0, chan=0)) for point in points: self.write_ftw_point(self.fifo_dds_ftw_seq, point) def dio_seq_write_points(self, byte_len, byte_buf, num_snapshots): print 'DIO points' points = [] for ii in range(num_snapshots): [t, outA, outB] = self.dio_read_point( byte_buf[ii * byte_len:ii * byte_len + byte_len]) points.append( GPIO_seq_point(address=ii, time=t, outputA=outA, outputB=outB)) # points.append(GPIO_seq_point(address=num_snapshots,time=6400000,outputA=0x00000000,outputB=0x00000000)) points.append( GPIO_seq_point(address=num_snapshots, time=0, outputA=0x00000000, outputB=0x00000000)) # with open("/dev/axis_fifo_0x0000000080004000", "r+b") as character: for point in points: # writeToSeqGPIO(character, point) seqWords = getSeqGPIOWords(point) for word in seqWords: # print word self.fifo_dio_seq.write_axis_fifo(word[0], MSB_first=False) def dio_read_point(self, snapshot): print snapshot snapshot_split = snapshot.split('_') t = int(snapshot_split[0].strip('t'), 16) out = snapshot_split[1].strip('b').strip('\0') outB = int(out[:8], 16) outA = int(out[8:], 16) return [t, outA, outB] def dac_read_point(self, snapshot): print snapshot snapshot_split = snapshot.split('_') t = int(snapshot_split[0].strip('t'), 16) chan = int(snapshot_split[1].strip('c'), 16) start = int(self.dacRes * (float(snapshot_split[2].strip('s')) - self.dacRange[0]) / (self.dacRange[1] - self.dacRange[0])) end = int(self.dacRes * (float(snapshot_split[3].strip('e')) - self.dacRange[0]) / (self.dacRange[1] - self.dacRange[0])) duration = int(snapshot_split[4].strip('d').strip('\0'), 16) return [t, chan, start, end, duration] def dds_read_point(self, snapshot): print snapshot snapshot_split = snapshot.split('_') t = int(snapshot_split[0].strip('t'), 16) chan = int(snapshot_split[1].strip('c'), 16) aorf = snapshot_split[2] if (aorf == 'f'): ddsConv = self.ddsFreqRangeConv else: ddsConv = self.ddsAmpRangeConv start = int(float(snapshot_split[3].strip('s')) * ddsConv) end = int(float(snapshot_split[4].strip('e')) * ddsConv) duration = int(snapshot_split[5].strip('d').strip('\0'), 16) return [t, chan, aorf, start, end, duration]