class TestSimGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimGpio.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): ret = self.chip['gpio'].get_data() self.assertEqual([0, 0, 0], ret) self.chip['gpio'].set_data([0xe3, 0xfa, 0x5a]) ret = self.chip['gpio'].get_data() self.assertEqual([0, 0x5a, 0x5a], ret) self.chip['gpio'].set_output_en([0x0f, 0, 0]) ret = self.chip['gpio'].get_data() self.assertEqual([0x33, 0x5a, 0x5a], ret) def test_io_register(self): self.chip['GPIO']['OUT'] = 0xa5 self.chip['GPIO'].write() ret = self.chip['gpio'].get_data() self.assertEqual([0, 0xa5, 0xa5], ret) # TODO: Add register readback and comparison def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run( [os.path.join(os.path.dirname(__file__), 'test_SimGpio.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): self.chip['GPIO'].set_output_en([0xff, 0, 0]) # to remove 'z in simulation ret = self.chip['GPIO'].get_data() self.assertEqual([0, 0, 0], ret) self.chip['GPIO'].set_output_en([0x0f, 0, 0]) self.chip['GPIO'].set_data([0xe3, 0xfa, 0x5a]) ret = self.chip['GPIO'].get_data() self.assertEqual([0x33, 0x5a, 0x5a], ret) ret = self.chip['GPIO2'].get_data() self.assertEqual([0xa5, 0xcd], ret) def test_io_register(self): self.chip['GPIO'].set_output_en([0xff, 0, 0]) # to remove 'z in simulation self.chip['GPIO']['OUT'] = 0xa5 self.chip['GPIO'].write() ret = self.chip['GPIO'].get_data() self.assertEqual([0, 0xa5, 0xa5], ret) # TODO: Add register readback and comparison def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimS2C(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.path.dirname(__file__) + '/test_SimI2c.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_i2c(self): data = [0x85, 0x81, 0xa5, 0x91] self.chip['i2c'].write(0x92, data) ret = self.chip['i2c'].get_data(4) self.assertEqual(ret.tolist(), data) self.chip['i2c'].write(0x92, data[0:1]) self.chip['i2c'].set_data([0, 1, 2, 3]) ret = self.chip['i2c'].read(0x92, 3) self.assertEqual(ret.tolist(), data[1:]) # no ack/no such device exept = False try: self.chip['i2c'].write(0x55, data) except IOError: exept = True self.assertEqual(exept, True) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimS2C(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimI2c.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_i2c(self): data = [0x85, 0x81, 0xa5, 0x91] self.chip['i2c'].write(0x92, data) ret = self.chip['i2c'].get_data(4) self.assertEqual(ret.tolist(), data) self.chip['i2c'].write(0x92, data[0:1]) self.chip['i2c'].set_data([0, 1, 2, 3]) ret = self.chip['i2c'].read(0x92, 3) self.assertEqual(ret.tolist(), data[1:]) # no ack/no such device exept = False try: self.chip['i2c'].write(0x55, data) except IOError: exept = True self.assertEqual(exept, True) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimTlu(unittest.TestCase): def setUp(self): cocotb_compile_and_run( [os.path.join(os.path.dirname(__file__), 'test_SimTdc.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_tdc(self): self.chip['TDC'].ENABLE = 1 self.chip['SEQ'].REPEAT = 1 for index, i in enumerate(range(0, 10)): length = i + 1 self.chip['SEQ'].SIZE = length + 1 self.chip['SEQ']['TDC_IN'][0:length] = True self.chip['SEQ'].write(length) self.chip['SEQ'].START while (not self.chip['SEQ'].is_ready): pass self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 1) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], (index << 12) + length) def test_tdc_overflow(self): self.chip['TDC'].ENABLE = 1 self.chip['SEQ'].REPEAT = 1 for index, i in enumerate(range(4094, 4097)): length = i + 1 self.chip['SEQ_GEN'].SIZE = length + 1 self.chip['SEQ']['TDC_IN'][0:length] = True self.chip['SEQ'].write(length) self.chip['SEQ'].START while (not self.chip['SEQ_GEN'].is_ready): pass self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 1) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], (index << 12) + min(length, 4095)) # overflow 12bit # def test_tdc_delay(self): # pass # # def test_tdc_delay_overflow(self): # pass # # def test_tdc_delay_late_trigger(self): # pass # # def test_tdc_arm(self): # pass def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
def temprature_dose(Directory=False, Sourcemeter=True, time_size=100, delay=2, CurrentLimit=1.000000E-06): ''' Assuming that the cabinet door is the -z x : Number of movements to x direction z: Number of movements inside the cabinet Size_x: size of the steps in x direction ''' t0 = time.time() if Sourcemeter: dut = Dut('sensor_sourcemeter_scan_pyserial.yaml') dut.init() dut['sm'].write(":OUTP ON") dut['sm'].write("*RST") dut['sm'].write(":SOUR:VOLT:RANG 60") dut['sm'].write('SENS:CURR:PROT ' + str(CurrentLimit)) print "The Protection Current limit is", dut['sm'].ask( "SENS:CURR:PROT?") dut['sm'].write(":SOUR:FUNC VOLT") dut['sm'].write(':SOUR:VOLT 50') else: dut = Dut('temprature_scan_pyserial.yaml') dut.init() with tb.open_file(Directory + 'temprature_dose.h5', "w") as out_file_h5: description = np.zeros( (1, ), dtype=np.dtype([("time", "f8"), ("current", "f8"), ("temprature", "f8"), ("humidity", "f8"), ("dew", "f8")])).dtype Data_table = out_file_h5.create_table(out_file_h5.root, name='temprature_dose', description=description, filters=tb.Filters( complib='blosc', complevel=5, fletcher32=False)) read = Data_table.row for i in xrange(time_size): t1 = time.time() read["time"] = t1 - t0 read["temprature"] = dut['ts'].get_temperature() read["humidity"] = dut['ts'].get_humidity() read["dew"] = dut['ts'].get_dew_point() if Sourcemeter: val = dut['sm'].ask(":MEAS:CURR?") current = val[15:-43] else: current = random.randint(1, 101) read["current"] = current read.append() temp = dut['ts'].get_temperature() print temp, t1 - t0, current time.sleep(delay) Data_table.flush() out_file_h5.close()
class TestSimGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimSpi.v']) cnfg = yaml.load(cnfg_yaml) self.chip = Dut(cnfg) self.chip.init() def test_io(self): size = self.chip['spi'].get_size() self.chip['gpio'].reset() self.assertEqual(size, 16 * 8) self.chip['spi'].set_data(range(16)) ret = self.chip['spi'].get_data(size=16, addr=0) #to read back what was written self.assertEqual(ret.tolist(), range(16)) self.chip['spi'].set_data(range(16)) ret = self.chip['spi'].get_data(addr=0) #to read back what was written self.assertEqual(ret.tolist(), range(16)) self.chip['spi'].start() while (not self.chip['spi'].is_done()): time.sleep(0.1) ret = self.chip['spi'].get_data( ) # read back what was received (looped) self.assertEqual(ret.tolist(), range(16)) #spi_rx ret = self.chip['spi_rx'].get_en() self.assertEqual(ret, False) self.chip['spi_rx'].set_en(True) ret = self.chip['spi_rx'].get_en() self.assertEqual(ret, True) self.chip['spi'].start() while (not self.chip['spi'].is_done()): time.sleep(0.1) ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 32) ret = self.chip['fifo'].get_data() data0 = ret.astype(np.uint8) data1 = np.right_shift(ret, 8).astype(np.uint8) data = np.reshape(np.vstack((data1, data0)), -1, order='F') self.assertEqual(data.tolist(), range(16)) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimTimestamp(unittest.TestCase): def setUp(self): cocotb_compile_and_run( [os.path.join(os.path.dirname(__file__), 'test_SimTimestamp.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): self.chip['timestamp'].reset() self.chip['timestamp']["ENABLE"] = 1 self.chip['gpio'].reset() self.chip['fifo'].reset() ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 0) # trigger timestamp self.chip['PULSE_GEN'].set_delay(0x105) self.chip['PULSE_GEN'].set_width(10) self.chip['PULSE_GEN'].set_repeat(1) self.assertEqual(self.chip['PULSE_GEN'].get_delay(), 0x105) self.assertEqual(self.chip['PULSE_GEN'].get_width(), 10) self.assertEqual(self.chip['PULSE_GEN'].get_repeat(), 1) self.chip['PULSE_GEN'].start() while (not self.chip['PULSE_GEN'].is_done()): pass # get data from fifo ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 3 * 4) ret = self.chip['fifo'].get_data() self.assertEqual(len(ret), 3) # check with gpio ret2 = self.chip['gpio'].get_data() self.assertEqual(len(ret2), 8) for i, r in enumerate(ret): self.assertEqual(r & 0xF0000000, 0x50000000) self.assertEqual(r & 0xF000000, 0x1000000 * (3 - i)) self.assertEqual(ret[2] & 0xFFFFFF, 0x10000 * ret2[5] + 0x100 * ret2[6] + ret2[7]) self.assertEqual(ret[1] & 0xFFFFFF, 0x10000 * ret2[2] + 0x100 * ret2[3] + ret2[4]) self.assertEqual(ret[1] & 0xFFFFFF, 0x100 * ret2[0] + ret2[1]) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimAdcRx.v']) cnfg = yaml.load(cnfg_yaml) self.chip = Dut(cnfg) self.chip.init() def test_io(self): pattern = [1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7] self.chip['SEQ_GEN'].set_data(pattern) self.chip['PULSE_GEN'].set_delay(1) self.chip['PULSE_GEN'].set_width(1) self.chip['SEQ_GEN'].set_en_ext_start(True) self.chip['SEQ_GEN'].set_size(8) self.chip['SEQ_GEN'].set_repeat(1) #this is to have something in memory and not X self.chip['PULSE_GEN'].start() self.chip['SEQ_GEN'].is_done() self.chip['SEQ_GEN'].is_done() while (not self.chip['SEQ_GEN'].is_done()): pass #take some data self.chip['FADC'].set_align_to_sync(True) self.chip['FADC'].set_data_count(16) self.chip['FADC'].set_single_data(True) self.chip['FADC'].start() self.chip['PULSE_GEN'].start() self.chip['SEQ_GEN'].is_done() self.chip['SEQ_GEN'].is_done() while (not self.chip['FADC'].is_done()): pass ret = self.chip['fifo'].get_data() self.assertEqual( ret[2:2 + 8].tolist(), [0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107]) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestExampleMIO(unittest.TestCase): def setUp(self): fw_path = get_basil_dir() + "/firmware/modules" cocotb_compile_and_run( [ fw_path + "/gpio/gpio.v", fw_path + "/utils/reset_gen.v", fw_path + "/utils/bus_to_ip.v", fw_path + "/utils/fx2_to_bus.v", os.path.dirname(__file__) + "/../src/example.v", ], top_level="example", sim_bus="basil.utils.sim.SiLibUsbBusDriver", ) with open(os.path.dirname(__file__) + "/example.yaml", "r") as f: cnfg = yaml.load(f) # change to simulation interface cnfg["transfer_layer"][0]["type"] = "SiSim" self.chip = Dut(cnfg) self.chip.init() def test(self): ret = self.chip["GPIO_LED"].get_data() self.assertEqual([0], ret) self.chip["GPIO_LED"]["LED"] = 0x01 self.chip["GPIO_LED"].write() ret = self.chip["GPIO_LED"].get_data() self.assertEqual([0x21], ret) self.chip["GPIO_LED"]["LED"] = 0x02 self.chip["GPIO_LED"].write() ret = self.chip["GPIO_LED"].get_data() self.assertEqual([0x42], ret) self.chip["GPIO_LED"]["LED"] = 0x03 self.chip["GPIO_LED"].write() ret = self.chip["GPIO_LED"].get_data() self.assertEqual([0x63], ret) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimM26(unittest.TestCase): def setUp(self): cocotb_compile_and_run( [os.path.join(os.path.dirname(__file__), 'test_SimFifo8to32.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): for i in range(4): self.chip['INTF'].write(0x1000, [i]) data = [] iterations = 1000 i = 0 while not len(data) == 1: if i >= iterations: break data.extend(self.chip['FIFO'].get_data()) i += 1 assert data[0] == 50462976 self.chip['INTF'].write(0x1000, [4, 5, 6, 7]) data = [] iterations = 1000 i = 0 while not len(data) == 1: if i >= iterations: break data.extend(self.chip['FIFO'].get_data()) i += 1 assert data[0] == 117835012 self.chip['INTF'].write(0x1000, range(8)) data = [] iterations = 1000 i = 0 while not len(data) == 2: if i >= iterations: break data.extend(self.chip['FIFO'].get_data()) i += 1 assert data[0] == 50462976 assert data[1] == 117835012 def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestExampleMIO(unittest.TestCase): def setUp(self): fw_path = os.path.join(get_basil_dir(), 'firmware/modules') cocotb_compile_and_run([ os.path.join(fw_path, 'gpio/gpio.v'), os.path.join(fw_path, 'gpio/gpio_core.v'), os.path.join(fw_path, 'utils/reset_gen.v'), os.path.join(fw_path, 'utils/bus_to_ip.v'), os.path.join(fw_path, 'utils/fx2_to_bus.v'), os.path.join(os.path.dirname(__file__), '../src/example.v') ], top_level='example', sim_bus='basil.utils.sim.SiLibUsbBusDriver') with open(os.path.join(os.path.dirname(__file__), 'example.yaml'), 'r') as f: cnfg = yaml.safe_load(f) # change to simulation interface cnfg['transfer_layer'][0]['type'] = 'SiSim' self.chip = Dut(cnfg) self.chip.init() def test_gpio(self): ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0], ret) self.chip['GPIO_LED']['LED'] = 0x01 self.chip['GPIO_LED'].write() ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0x21], ret) self.chip['GPIO_LED']['LED'] = 0x02 self.chip['GPIO_LED'].write() ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0x42], ret) self.chip['GPIO_LED']['LED'] = 0x03 self.chip['GPIO_LED'].write() ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0x63], ret) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestExampleMIO(unittest.TestCase): def setUp(self): fw_path = os.path.join(get_basil_dir(), 'firmware/modules') cocotb_compile_and_run([ os.path.join(fw_path, 'gpio/gpio.v'), os.path.join(fw_path, 'utils/reset_gen.v'), os.path.join(fw_path, 'utils/bus_to_ip.v'), os.path.join(fw_path, 'utils/fx2_to_bus.v'), os.path.join(os.path.dirname(__file__), '../src/example.v')], top_level='example', sim_bus='basil.utils.sim.SiLibUsbBusDriver' ) with open(os.path.join(os.path.dirname(__file__), 'example.yaml'), 'r') as f: cnfg = yaml.load(f) # change to simulation interface cnfg['transfer_layer'][0]['type'] = 'SiSim' self.chip = Dut(cnfg) self.chip.init() def test_gpio(self): ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0], ret) self.chip['GPIO_LED']['LED'] = 0x01 self.chip['GPIO_LED'].write() ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0x21], ret) self.chip['GPIO_LED']['LED'] = 0x02 self.chip['GPIO_LED'].write() ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0x42], ret) self.chip['GPIO_LED']['LED'] = 0x03 self.chip['GPIO_LED'].write() ret = self.chip['GPIO_LED'].get_data() self.assertEqual([0x63], ret) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class Silab_relay(object): def __init__(self, yaml='relay.yaml'): self.dut = Dut(yaml) self.dut.init() time.sleep(1) def switch(self, channel, state='toggle'): ''' Sets one channel of relay card to defined state or toggles ''' if channel == 'All' or channel == 'all' or channel == 99: send_channel = 99 elif type(channel) == int and channel >= 0 and channel <= 9: send_channel = channel + 2 else: raise ValueError('Channel has to be integer between 0 and 9 or String \'All\'.') if state == 'On' or state == 'on' or state == 1 or state == True: send_state = 1 elif state == 'Off' or state == 'off' or state == 0 or state == False: send_state = 0 elif state == 'toggle' or state == 'Toggle': send_state = 0 if bool(self.get_state(channel)) else 1 print send_state raise NotImplementedError else: raise ValueError('State has to be either 1/0 or \'On\'/\'Off\' or True/False.') self.dut['Arduino'].set_output(channel=send_channel, value=send_state) def switch_to(self, channel): self.switch('all', 'off') self.switch(channel, 'on') def get_state(self, channel='all'): ''' Will only work as long as connection is open. On reconnect, the arduino resets and sets all pins to LOW. ''' state = self.dut['Arduino'].get_state() if channel == 'all' or channel == 'All' or channel == 99: return state elif type(channel) == int and channel >= 0 and channel <= 9: return state[channel] else: raise ValueError('Channel has to be integer between 0 and 9 or String \'All\'.')
class TestSimTlu(unittest.TestCase): def setUp(self): cocotb_compile_and_run(['test_SimTlu.v']) cnfg = yaml.load(cnfg_yaml) self.chip = Dut(cnfg) self.chip.init() def test_version(self): self.assertEqual(self.chip['tlu'].VERSION, 1) def tearDown(self): self.chip.close() # let it close connection and stop simulator time.sleep(1) subprocess.call('make clean', shell=True) subprocess.call('rm -f Makefile', shell=True)
class TestSimGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimAdcRx.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): pattern = [1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7] self.chip['SEQ_GEN'].set_data(pattern) self.chip['PULSE_GEN'].set_delay(1) self.chip['PULSE_GEN'].set_width(1) self.chip['SEQ_GEN'].set_en_ext_start(True) self.chip['SEQ_GEN'].set_size(8) self.chip['SEQ_GEN'].set_repeat(1) # this is to have something in memory and not X self.chip['PULSE_GEN'].start() self.chip['SEQ_GEN'].is_done() self.chip['SEQ_GEN'].is_done() while(not self.chip['SEQ_GEN'].is_done()): pass # take some data self.chip['FADC'].set_align_to_sync(True) self.chip['FADC'].set_data_count(16) self.chip['FADC'].set_single_data(True) self.chip['FADC'].start() self.chip['PULSE_GEN'].start() self.chip['SEQ_GEN'].is_done() self.chip['SEQ_GEN'].is_done() while(not self.chip['FADC'].is_done()): pass ret = self.chip['fifo'].get_data() self.assertEqual(ret[2:2 + 8].tolist(), [0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107]) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimGpio(unittest.TestCase): def __init__(self, testname, tb='test_SimGpio.v', bus_drv='basil.utils.sim.BasilBusDriver', bus_split=False): super(TestSimGpio, self).__init__(testname) self._test_tb = tb self._sim_bus = bus_drv self._bus_split_def = () if bus_split is not False: if bus_split == 'sbus': self._bus_split_def = ("BASIL_SBUS",) elif bus_split == 'top': self._bus_split_def = ("BASIL_TOPSBUS",) def setUp(self): cocotb_compile_and_run(sim_files=[os.path.join(os.path.dirname(__file__), self._test_tb)], sim_bus=self._sim_bus, extra_defines=self._bus_split_def) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): self.chip['GPIO'].set_output_en([0xff, 0, 0]) # to remove 'z in simulation ret = self.chip['GPIO'].get_data() self.assertEqual([0, 0, 0], ret) self.chip['GPIO'].set_output_en([0x0f, 0, 0]) self.chip['GPIO'].set_data([0xe3, 0xfa, 0x5a]) ret = self.chip['GPIO'].get_data() self.assertEqual([0x33, 0x5a, 0x5a], ret) ret = self.chip['GPIO2'].get_data() self.assertEqual([0xa5, 0xcd], ret) def test_io_register(self): self.chip['GPIO'].set_output_en([0xff, 0, 0]) # to remove 'z in simulation self.chip['GPIO']['OUT'] = 0xa5 self.chip['GPIO'].write() ret = self.chip['GPIO'].get_data() self.assertEqual([0, 0xa5, 0xa5], ret) # TODO: Add register readback and comparison def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimScpi(unittest.TestCase): def setUp(self): cfg = yaml.load(cnfg_yaml) self.device = Dut(cfg) self.device.init() def test_read(self): self.assertEqual(self.device['Pulser'].get_frequency(), u'100.00') def test_write(self): self.device['Pulser'].set_on() self.assertEqual(self.device['Pulser'].get_on(), u'0') def test_exception(self): with self.assertRaises(ValueError): self.device['Pulser'].unknown_function() def tearDown(self): self.device.close()
def __init__(self, conf_file="../examples/cooling.yaml", setpoint=-20, monitor=False): # Setup logging self.log = logging.getLogger('N2 Cooling') fh = logging.FileHandler('cooling_2021-05-12_2e15.log') fh.setLevel(logging.INFO) fh.setFormatter(logging.Formatter(FORMAT)) self.log.addHandler(fh) # Setup online monitor if monitor: try: context = zmq.Context() self.socket = context.socket(zmq.PUB) self.socket.bind(monitor) self.log.info("Sending data to server %s" % monitor) except zmq.error.ZMQError: self.log.warning("Cannot connect to socket for data sending") self.socket = None else: self.socket = None # Set up temperature log file self.temp_type = np.dtype([('timestamp', 'u4'), ('temp_1', 'f4'), ('temp_2', 'f4'), ('humidity_1', 'f4'), ('humidity_2', 'f4')]) self.output_file = tb.open_file('cooling.h5', 'a') if '/temperature' in self.output_file: # Table already exists self.temp_table = self.output_file.root.temperature else: self.temp_table = self.output_file.create_table( self.output_file.root, name='temperature', description=self.temp_type, filters=tb.Filters(complevel=5, complib='blosc')) self.setpoint = setpoint devices = Dut(conf_file) devices.init() self.temp_sensors = devices["sensirion"] self.valve = devices["bronkhorst"]
def scan(self, mask_steps=4, repeat_command=100, PrmpVbpDac=80, vthin2Dac=0, columns = [True] * 16, scan_range = [0, 0.2, 0.005], vthin1Dac = 80, preCompVbnDac = 50, mask_filename='', **kwargs): '''Scan loop Parameters ---------- mask : int Number of mask steps. repeat : int Number of injections. ''' inj_factor = 1.0 INJ_LO = 0.0 try: dut = Dut(ScanBase.get_basil_dir(self)+'/examples/lab_devices/agilent33250a_pyserial.yaml') dut.init() logging.info('Connected to '+str(dut['Pulser'].get_info())) except RuntimeError: INJ_LO = 0.2 inj_factor = 2.0 logging.info('External injector not connected. Switch to internal one') self.dut['INJ_LO'].set_voltage(INJ_LO, unit='V') self.dut['global_conf']['PrmpVbpDac'] = 80 self.dut['global_conf']['vthin1Dac'] = 255 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['vffDac'] = 24 self.dut['global_conf']['PrmpVbnFolDac'] = 51 self.dut['global_conf']['vbnLccDac'] = 1 self.dut['global_conf']['compVbnDac'] = 25 self.dut['global_conf']['preCompVbnDac'] = 50 self.dut.write_global() self.dut['control']['RESET'] = 0b01 self.dut['control']['DISABLE_LD'] = 0 self.dut['control']['PIX_D_CONF'] = 0 self.dut['control'].write() self.dut['control']['CLK_OUT_GATE'] = 1 self.dut['control']['CLK_BX_GATE'] = 1 self.dut['control'].write() time.sleep(0.1) self.dut['control']['RESET'] = 0b11 self.dut['control'].write() self.dut['global_conf']['OneSr'] = 1 self.dut['global_conf']['TestHit'] = 0 self.dut['global_conf']['SignLd'] = 0 self.dut['global_conf']['InjEnLd'] = 0 self.dut['global_conf']['TDacLd'] = 0 self.dut['global_conf']['PixConfLd'] = 0 self.dut.write_global() #self.dut['global_conf']['OneSr'] = 0 #all multi columns in parallel self.dut['global_conf']['ColEn'][:] = bitarray.bitarray([True] * 16) #(columns) self.dut['global_conf']['ColSrEn'][:] = bitarray.bitarray([True] * 16) self.dut.write_global() self.dut['pixel_conf'].setall(False) self.dut.write_pixel() self.dut['global_conf']['InjEnLd'] = 1 self.dut.write_global() self.dut['global_conf']['InjEnLd'] = 0 mask_en = np.full([64,64], False, dtype = np.bool) mask_tdac = np.full([64,64], 16, dtype = np.uint8) for inx, col in enumerate(columns): if col: mask_en[inx*4:(inx+1)*4,:] = True if mask_filename: logging.info('Using pixel mask from file: %s', mask_filename) with tb.open_file(mask_filename, 'r') as in_file_h5: mask_tdac = in_file_h5.root.scan_results.tdac_mask[:] mask_en = in_file_h5.root.scan_results.en_mask[:] self.dut.write_en_mask(mask_en) self.dut.write_tune_mask(mask_tdac) self.dut['global_conf']['OneSr'] = 0 self.dut.write_global() self.dut['inj'].set_delay(10000) #this seems to be working OK problem is probably bad injection on GPAC usually +0 self.dut['inj'].set_width(1000) self.dut['inj'].set_repeat(repeat_command) self.dut['inj'].set_en(False) self.dut['trigger'].set_delay(400-4) self.dut['trigger'].set_width(16) self.dut['trigger'].set_repeat(1) self.dut['trigger'].set_en(True) ### self.dut['trigger'].set_delay(10000) #this seems to be working OK problem is probably bad injection on GPAC usually +0 self.dut['trigger'].set_width(16) self.dut['trigger'].set_repeat(repeat_command) self.dut['trigger'].set_en(False) ## logging.debug('Configure TDC') self.dut['tdc']['RESET'] = True self.dut['tdc']['EN_TRIGGER_DIST'] = True self.dut['tdc']['ENABLE_EXTERN'] = False self.dut['tdc']['EN_ARMING'] = False self.dut['tdc']['EN_INVERT_TRIGGER'] = False self.dut['tdc']['EN_INVERT_TDC'] = False self.dut['tdc']['EN_WRITE_TIMESTAMP'] = True lmask = [1] + ( [0] * (mask_steps-1) ) lmask = lmask * ( (64 * 64) / mask_steps + 1 ) lmask = lmask[:64*64] scan_range = np.arange(scan_range[0], scan_range[1], scan_range[2]) / inj_factor for idx, k in enumerate(scan_range): dut['Pulser'].set_voltage(INJ_LO, float(INJ_LO + k), unit='V') self.dut['INJ_HI'].set_voltage( float(INJ_LO + k), unit='V') time.sleep(0.5) bv_mask = bitarray.bitarray(lmask) with self.readout(scan_param_id = idx): logging.info('Scan Parameter: %f (%d of %d)', k, idx+1, len(scan_range)) pbar = ProgressBar(maxval=mask_steps).start() for i in range(mask_steps): self.dut['global_conf']['vthin1Dac'] = 255 self.dut['global_conf']['preCompVbnDac'] = 50 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['PrmpVbpDac'] = 80 self.dut.write_global() time.sleep(0.1) self.dut['pixel_conf'][:] = bv_mask self.dut.write_pixel_col() self.dut['global_conf']['InjEnLd'] = 1 #self.dut['global_conf']['PixConfLd'] = 0b11 self.dut.write_global() bv_mask[1:] = bv_mask[0:-1] bv_mask[0] = 0 self.dut['global_conf']['vthin1Dac'] = vthin1Dac self.dut['global_conf']['preCompVbnDac'] = preCompVbnDac self.dut['global_conf']['vthin2Dac'] = vthin2Dac self.dut['global_conf']['PrmpVbpDac'] = PrmpVbpDac self.dut.write_global() time.sleep(0.1) #self.dut['inj'].start() pbar.update(i) while not self.dut['inj'].is_done(): pass while not self.dut['trigger'].is_done(): pass #self.dut['trigger'].set_repeat(0) #self.dut['control']['CLK_BX_GATE'] = 0 #self.dut['control']['CLK_OUT_GATE'] = 0 #self.dut['control'].write() print('!!!!!!!!!!!!!!!1') self.dut['tdc'].ENABLE = True self.dut['trigger'].start() time.sleep(10) self.dut['tdc'].ENABLE = False print('!!!!!!!!!!!!!!!2') #self.dut['control']['CLK_BX_GATE'] = 1 #self.dut['control']['CLK_OUT_GATE'] = 1 #self.dut['control'].write() scan_results = self.h5_file.create_group("/", 'scan_results', 'Scan Masks') self.h5_file.createCArray(scan_results, 'tdac_mask', obj=mask_tdac) self.h5_file.createCArray(scan_results, 'en_mask', obj=mask_en)
class TestClass(unittest.TestCase): @classmethod def setUpClass(cls): cls.cnfg = yaml.load(cnfg_yaml) cls.dut = Dut(cls.cnfg) cls.dut['spi_module']._require_version = "==1" cls.dut.init() cls.dut['spi_module']._mem_bytes = 4 def test_mem_bytes(self): self.dut.init() self.dut['spi_module']._mem_bytes = 4 self.assertEqual(4, self.dut['spi_module'].MEM_BYTES) self.assertRaises(ValueError, self.dut['spi_module'].set_data, [1, 2, 3, 4, 5]) def test_init_simple(self): self.dut['TEST1'].write() mem = dict() # mem[0] = 0 # reset # mem[0] = 1 mem[16] = 0 # has an offset of 16 bytes mem[17] = 0 mem[18] = 0 mem[19] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'][0] = 1 self.dut['TEST1'].write() mem[19] = 1 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'][31] = 1 self.dut['TEST1'].write() mem[16] = 0x80 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'] = 0 self.dut['TEST1'].write() mem[16] = 0 mem[19] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'] = 0xa55a8001 self.dut['TEST1'].write() mem[16] = 0xa5 mem[17] = 0x5a mem[18] = 0x80 mem[19] = 0x01 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'] = 0 self.dut['TEST1'][11:4] = 0xff self.dut['TEST1'].write() mem[16] = 0x0 mem[17] = 0x0 mem[18] = 0x0f mem[19] = 0xf0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'] = 0 self.dut['TEST1'][11:4] = '10000001' self.dut['TEST1'].write() mem[16] = 0x0 mem[17] = 0x0 mem[18] = 0x08 mem[19] = 0x10 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST1'] = 0 self.dut['TEST1'][11:4] = bitarray('00011000') self.dut['TEST1'].write() mem[16] = 0x0 mem[17] = 0x0 mem[18] = 0x01 mem[19] = 0x80 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_bit_order(self): self.dut['TEST2'].write() mem = dict() # mem[0] = 0 # reset mem[0] = 1 mem[14] = 4 mem[16] = 0 mem[17] = 0 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VINJECT'] = 0x01 self.dut['TEST2'].write() mem[16] = 0x08 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VINJECT'] = 0x02 self.dut['TEST2'].write() mem[16] = 0x10 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VINJECT'] = 0x04 self.dut['TEST2'].write() mem[16] = 0x04 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VINJECT'] = 0x08 self.dut['TEST2'].write() mem[16] = 0x20 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VINJECT'] = 0 self.dut['TEST2']['VINJECT'][0] = 1 self.dut['TEST2'].write() mem[16] = 0x04 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_repeat(self): self.dut['dummy_tl'].mem = dict() # self.dut['TEST2'] = 0 self.dut['TEST2']['VINJECT'] = 0 self.dut['TEST2']['VPULSE'] = 0 self.dut['TEST2'].write() mem = dict() # mem[0] = 1 mem[16] = 0 mem[17] = 0 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['COLUMN'][0]['EnR'] = 1 self.dut['TEST2'].write() mem[17] = 0x02 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['COLUMN'][1]['DACR'] = 1 self.dut['TEST2'].write() mem[18] = 0x10 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_default(self): self.cnfg['registers'][1]['fields'][0]['default'] = 0x01 # VINJECT self.dut = Dut(self.cnfg) self.dut['spi_module']._require_version = "==1" self.dut.init() self.dut['spi_module']._mem_bytes = 32 mem = dict() # mem[0] = 0 # reset mem[0] = 1 mem[14] = 4 mem[16] = 0x08 mem[17] = 0 mem[18] = 0 self.dut['TEST2'].write() self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_fields(self): self.dut['dummy_tl'].mem = dict() self.dut['TEST2']['VINJECT'] = 0 self.dut['TEST2']['VPULSE'] = 0 self.dut['TEST2'].write() mem = dict() # mem[0] = 1 mem[16] = 0 mem[17] = 0 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VPULSE'] = 0x5 self.dut['TEST2'].write() mem = dict() mem[16] = 0 mem[17] = 0x50 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VPULSE'] = bitarray('100001') self.dut['TEST2'].write() mem = dict() mem[16] = 0x02 mem[17] = 0x10 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VPULSE'] = '100001' self.dut['TEST2'].write() mem = dict() mem[16] = 0x02 mem[17] = 0x10 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) self.dut['TEST2']['VPULSE'] = 0b100011 self.dut['TEST2'].write() mem = dict() mem[16] = 0x02 mem[17] = 0x30 mem[18] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem)
class lfcpix(): def __init__(self, conf="lfcpix.yaml"): self.logger = lfcpix_log.LfcpixLog() self.dut = Dut(conf) # init member variables self.debug = 0 self._build_img = np.vectorize(self._build_img_one) self.plot = False # init basil self.dut.init() #### init memory self.mon_en = self.dut["CCPD_SR"]["Pixels"].copy() self.inj_en = self.dut["CCPD_SR"]["Pixels"].copy() self.preamp_en = self.dut["CCPD_SR"]["Pixels"].copy() self.preamp_en_ana = self.dut["CCPD_SR"]["PREAMP_EN_ANA"].copy() self.monitor_en_ana = self.dut["CCPD_SR"]["MONITOR_EN_ANA"].copy() self.sw_mon = self.dut["CCPD_SR"]["SW_MON"].copy() self.sw_inj = self.dut["CCPD_SR"]["SW_INJ"].copy() self.tdac = np.ones([26, 106], int) * 0 def init_chip(self): self.power() self.set_global() self.set_mon_en([14, 25]) self.set_preamp_en() self.set_inj_en([14, 25]) self.set_tdac(0) self.set_inj_all() self.show() def _build_img_one(self, spix): frame = spix / 2768 spix = 2755 - spix % 2768 col = spix / 106 row = spix % 106 if col % 2 == 0: pass elif col % 2 == 1: row = 106 - row return frame, col, row def _build_img2(self, dat): img = np.empty([26, 106], dtype=int) ##### TODO can be more efficient for i in range(0, 26, 2): img[i + 0, :] = np.copy(dat[(i + 0) * 106:(i + 1) * 106]) img[i + 1, :] = np.copy(dat[(i + 1) * 106:(i + 2) * 106][::-1]) return img def _cal_Pixels(self, pix): if isinstance(pix, str): if pix == "all": en_pix = bitarray.bitarray('1' * 2756) en_col = bitarray.bitarray('1' * 10) else: en_pix = bitarray.bitarray('0' * 2756) en_col = bitarray.bitarray('0' * 10) elif isinstance(pix, int): if pix == 0: en_pix = bitarray.bitarray('0' * 2756) en_col = bitarray.bitarray('0' * 10) else: en_pix = bitarray.bitarray('1' * 2756) en_col = bitarray.bitarray('1' * 10) elif isinstance(pix, type(bitarray.bitarray())): en_pix = bitarray.bitarray('0' * 2756) en_col = bitarray.bitarray('0' * 10) for i in range(0, 26, 2): a0 = pix[106 * (i):106 * (i + 1)].copy() a1 = pix[106 * (i + 1):106 * (i + 2)].copy() a1.reverse() en_pix[106 * (i):106 * (i + 2)] = a0 + a1 else: en_pix = bitarray.bitarray('0' * 2756) en_col = bitarray.bitarray('0' * 10) if isinstance(pix[0], int): pix = [pix] for p in pix: if p[0] > 25: en_col[p[0] - 26] = 1 else: r = p[0] % 2 if r == 0: en_pix[p[0] * 106 + p[1]] = 1 elif r == 1: en_pix[(p[0] + 1) * 106 - p[1] - 1] = 1 return en_pix, en_col ############# ### Power, injection, threshold def power(self, pwr_en=True, Vdda=1.8, Vddp=1.5, Vddd=1.8, VCasc2=0.7, TH=1.5, VCascP=1., VCascN=0.52): self.dut['CCPD_vdda'].set_current_limit(204, unit='mA') self.dut['CCPD_vdda'].set_voltage(Vdda, unit='V') self.dut['CCPD_vdda'].set_enable(pwr_en) self.dut['CCPD_vddaPRE'].set_voltage(Vddp, unit='V') self.dut['CCPD_vddaPRE'].set_enable(pwr_en) self.dut['CCPD_vddd'].set_voltage(Vddd, unit='V') self.dut['CCPD_vddd'].set_enable(pwr_en) self.dut['CCPD_VCasc2'].set_voltage(VCasc2, unit='V') self.dut['CCPD_VCascP'].set_voltage(VCascP, unit='V') self.dut['CCPD_TH'].set_voltage(TH, unit='V') self.dut['CCPD_VCascN'].set_voltage(VCascN, unit='V') self.logger.info( "Vdda:%f Vddp:%f Vddd:%f VCasc2:%f VCascN:%f VCascP:%f TH:%f" % (Vdda, Vddp, Vddd, VCasc2, VCascN, VCascP, TH)) def set_inj_all(self, inj_high=1.0, inj_low=0.0, inj_width=500, inj_n=1, delay=700, ext=True): self.dut["CCPD_Injection_high"].set_voltage(inj_high, unit="V") self.inj_high = inj_high self.dut["CCPD_Injection_low"].set_voltage(inj_low, unit="V") self.inj_low = inj_low self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_INJ"]["REPEAT"] = inj_n self.dut["CCPD_PULSE_INJ"]["DELAY"] = inj_width self.dut["CCPD_PULSE_INJ"]["WIDTH"] = inj_width self.dut["CCPD_PULSE_INJ"]["EN"] = 1 self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"] = 1 self.dut["CCPD_PULSE_GATE"]["DELAY"] = delay self.dut["CCPD_PULSE_GATE"]["WIDTH"] = inj_n * inj_width * 2 + 10 self.dut["CCPD_PULSE_GATE"]["EN"] = ext self.logger.info( "inj:%.4f,%.4f inj_width:%d inj_n:%d delay:%d ext:%d" % (inj_high, inj_low, inj_width, inj_n, delay, int(ext))) def set_inj(self, inj_high, inj_low=0.0): self.dut["CCPD_Injection_high"].set_voltage(inj_high, unit="V") self.inj_high = inj_high self.dut["CCPD_Injection_low"].set_voltage(inj_low, unit="V") self.inj_low = inj_low self.logger.info("set_inj inj_high:%f inj_low:%f" % (inj_high, inj_low)) def inject(self): self.dut["CCPD_PULSE_INJ"].start() def set_th(self, TH, thmod=False): self.dut['CCPD_TH'].set_voltage(TH, unit='V') THvol = self.dut['CCPD_TH'].get_voltage(unit='V') self.dut['CCPD_SW']['THON_NEG'] = (not thmod) self.dut['CCPD_SW'].write() self.logger.info("th_set:%f th:%f th_mod:%d" % (TH, THvol, thmod)) def get_th(self): thmod = not self.dut['CCPD_SW']['THON_NEG'] THvol = self.dut['CCPD_TH'].get_voltage(unit='V') self.logger.info("get_th:%f th_mod:%d" % (THvol, thmod)) ############## #### status def get_status(self): stat = { "Vdda": self.dut['CCPD_vdda'].get_voltage(unit='V'), "Vdda_curr": self.dut['CCPD_vdda'].get_current(unit="mA"), "Vddp": self.dut['CCPD_vddaPRE'].get_voltage(unit='V'), "Vddp_curr": self.dut['CCPD_vddaPRE'].get_current(unit="mA"), "Vddd": self.dut['CCPD_vddd'].get_voltage(unit='V'), "Vddd_curr": self.dut['CCPD_vddd'].get_current(unit="mA"), "VCasc2": self.dut['CCPD_VCasc2'].get_voltage(unit='V'), "VCasc2_curr": self.dut['CCPD_VCasc2'].get_current(unit="mA"), "VCascN": self.dut['CCPD_VCascN'].get_voltage(unit='V'), 'VCascN_curr': self.dut['CCPD_VCascN'].get_current(unit="mA"), 'VCascP': self.dut['CCPD_VCascP'].get_voltage(unit='V'), 'VCascP_curr': self.dut['CCPD_VCascP'].get_current(unit="mA"), 'TH': self.dut['CCPD_TH'].get_voltage(unit='V'), 'TH_curr': self.dut['CCPD_TH'].get_current(unit="mA"), ##### TODO make data from get_data 'BLRes': self.dut['CCPD_SR']['BLRes'].tovalue(), 'VAmp': self.dut['CCPD_SR']['VAmp'].tovalue(), 'VPFB': self.dut['CCPD_SR']['VPFB'].tovalue(), 'VPFoll': self.dut['CCPD_SR']['VPFoll'].tovalue(), 'VPLoad': self.dut['CCPD_SR']['VPLoad'].tovalue(), 'IComp': self.dut['CCPD_SR']['IComp'].tovalue(), 'VSTRETCH': self.dut['CCPD_SR']['VSTRETCH'].tovalue(), 'IBOTA': self.dut['CCPD_SR']['IBOTA'].tovalue(), 'IBCS': self.dut['CCPD_SR']['IBCS'].tovalue(), 'WGT': self.dut['CCPD_SR']['WGT'].tovalue(), 'LSBdacL': self.dut['CCPD_SR']['LSBdacL'].tovalue(), 'LSBdacL2': self.dut['CCPD_SR']['LSBdacL2'].tovalue(), 'IBCS2': self.dut['CCPD_SR']['IBCS2'].tovalue(), 'INJ_EN_AnaPassive': self.dut['CCPD_SR']['INJ_EN_AnaPassive'].tovalue(), #"PREAMP_EN_ANA": self.preamp_en_ana.tovalue(), "SW_MON": " ".join(hex(ord(n)) for n in self.sw_mon.tobytes()), "SW_INJ": " ".join(hex(ord(n)) for n in self.sw_inj.tobytes()), "MON_EN": " ".join(hex(ord(n)) for n in self.mon_en.tobytes()), "PREAMP_EN": " ".join(hex(ord(n)) for n in self.preamp_en.tobytes()), "INJECT_EN": " ".join(hex(ord(n)) for n in self.inj_en.tobytes()), "Pixels": " ".join( hex(ord(n)) for n in self.dut["CCPD_SR"]["Pixels"].tobytes()), #"SR_EN":self.dut["CCPD_SR"].get_enable(), ##TODO find this function "SR_REPEAT": self.dut["CCPD_SR"].get_repeat(), "SR_WAIT": self.dut["CCPD_SR"].get_wait(), 'CCPD_SW': self.dut["CCPD_SW"].get_data()[0], 'rx_SW': self.dut["rx"].get_data()[0], 'inj_high': self.inj_high, 'inj_low': self.inj_low, 'INJ_DELAY': self.dut["CCPD_PULSE_INJ"]["DELAY"], 'INJ_WIDTH': self.dut["CCPD_PULSE_INJ"]["WIDTH"], 'INJ_REPEAT': self.dut["CCPD_PULSE_INJ"]["REPEAT"], 'INJ_EN': self.dut["CCPD_PULSE_INJ"]["EN"], 'GATE_DELAY': self.dut["CCPD_PULSE_GATE"]["DELAY"], 'GATE_WIDTH': self.dut["CCPD_PULSE_GATE"]["WIDTH"], 'GATE_REPEAT': self.dut["CCPD_PULSE_GATE"]["REPEAT"], 'GATE_EN': self.dut["CCPD_PULSE_GATE"]["EN"], } return stat def show(self, show="all"): r = self.get_status() self.logger.show(r) ########## ### set registers def _write_SR(self, sw="SW_LDDAC"): if sw == "SW_LDDAC": self.dut['CCPD_SW']['SW_LDPIX'] = 0 self.dut['CCPD_SW']['SW_LDDAC'] = 1 self.dut['CCPD_SW']['SW_HIT'] = 0 elif sw == "SW_LDPIX": self.dut['CCPD_SW']['SW_LDPIX'] = 1 self.dut['CCPD_SW']['SW_LDDAC'] = 0 self.dut['CCPD_SW']['SW_HIT'] = 0 elif sw == "SW_HIT": self.dut['CCPD_SW']['SW_LDPIX'] = 0 self.dut['CCPD_SW']['SW_LDDAC'] = 0 self.dut['CCPD_SW']['SW_HIT'] = 1 else: self.dut['CCPD_SW']['SW_LDPIX'] = 0 self.dut['CCPD_SW']['SW_LDDAC'] = 0 self.dut['CCPD_SW']['SW_HIT'] = 0 self.dut['CCPD_SW'].write() self.dut['CCPD_SR'].set_size(2953) self.dut['CCPD_SR'].set_repeat(1) self.dut['CCPD_SR'].set_wait(0) self.dut['CCPD_SR'].write() self.dut['CCPD_SR'].start() i = 0 while i < 10000: if self.dut['CCPD_SR'].is_done(): break elif i > 100: time.sleep(0.001) i = i + 1 if i == 10000: self.logger.info("ERROR timeout") def set_global(self, BLRes=28, VAmp=26, VPFB=47, VPFoll=12, VPLoad=11, IComp=24, VSTRETCH=5, IBOTA=20, IBCS=23, WGT=32, LSBdacL=32, LSBdacL2=32, IBCS2=23): self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut["CCPD_PULSE_GATE"].reset() self.dut['CCPD_PULSE_GATE'].set_en(False) self.dut["CCPD_PULSE_INJ"].reset() self.dut['CCPD_PULSE_INJ'].set_en(False) self.dut['CCPD_SR']['BLRes'] = BLRes self.dut['CCPD_SR']['VAmp'] = VAmp self.dut['CCPD_SR']['VPFB'] = VPFB self.dut['CCPD_SR']['VPFoll'] = VPFoll self.dut['CCPD_SR']['VPLoad'] = VPLoad self.dut['CCPD_SR']['IComp'] = IComp self.dut['CCPD_SR']['VSTRETCH'] = VSTRETCH self.dut['CCPD_SR']['IBOTA'] = IBOTA self.dut['CCPD_SR']['IBCS'] = IBCS self.dut['CCPD_SR']['WGT'] = WGT self.dut['CCPD_SR']['LSBdacL'] = LSBdacL self.dut['CCPD_SR']['LSBdacL2'] = LSBdacL2 self.dut['CCPD_SR']['IBCS2'] = IBCS2 self.dut['CCPD_SR']['INJ_EN_AnaPassive'] = 0 self._write_SR(sw="SW_LDDAC") self.logger.info( 'BLRes:%d VAmp:%d VPFB=:%d VPFoll:%d VPLoad:%d IComp:%d VSTRETCH:%dIBOTA:%d IBCS:%d WGT:%d LSBdacL:%d LSBdacL2:%d IBCS2:%d' % (BLRes, VAmp, VPFB, VPFoll, VPLoad, IComp, VSTRETCH, IBOTA, IBCS, WGT, LSBdacL, LSBdacL2, IBCS2)) def set_mon_en(self, pix="none"): tmp_spi_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_SPI_RX'].set_en(False) tmp_gate_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_PULSE_GATE'].set_en(False) self.dut['CCPD_SR']['TRIM_EN'] = 0 self.dut['CCPD_SR']['INJECT_EN'] = 0 self.dut['CCPD_SR']['MONITOR_EN'] = 1 self.dut['CCPD_SR']['PREAMP_EN'] = 0 self.dut['CCPD_SR']['PREAMP_EN_ANA'] = self.preamp_en_ana self.dut['CCPD_SR']['SW_INJ'] = self.sw_inj en_pix, en_col = self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels'] = en_pix self.mon_en = en_pix.copy() self.dut['CCPD_SR']['MONITOR_EN_ANA'] = en_col self.monitor_en_ana = en_col.copy() for i in range(0, 2756, 106): self.dut['CCPD_SR']['SW_MON'][i / 106] = self.mon_en[i:i + 106].any() for i in range(10): self.dut['CCPD_SR']['SW_MON'][26 + i] = en_col[i] self.sw_mon = self.dut['CCPD_SR']['SW_MON'].copy() self.dut['CCPD_SR']['BUFFER_EN'] = self.sw_mon.any() self.dut['CCPD_SR']['REGULATOR_EN'] = (self.preamp_en_ana.any() or self.preamp_en[106 * 18:].any()) self._write_SR(sw="SW_LDPIX") self.dut['CCPD_SPI_RX'].set_en(tmp_spi_en) self.dut['CCPD_PULSE_GATE'].set_en(tmp_gate_en) s = "set_mon_en pix:%s lds:%d,%d,%d,%d pixels:%s " % ( pix, self.dut['CCPD_SR']['TRIM_EN'].tovalue(), self.dut['CCPD_SR']['INJECT_EN'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN'].tovalue(), self.dut['CCPD_SR']['PREAMP_EN'].tovalue(), "") s = "%spreamp_en_ana:0x%x monitor_en_ana:0x%x sw_mon:0x%x sw_inj:0x%x regulator:%d buffer:%d " % ( s, self.dut['CCPD_SR']['PREAMP_EN_ANA'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN_ANA'].tovalue(), self.dut['CCPD_SR']['SW_MON'].tovalue(), self.dut['CCPD_SR']['SW_INJ'].tovalue(), self.dut['CCPD_SR']['REGULATOR_EN'].tovalue(), self.dut['CCPD_SR']['BUFFER_EN'].tovalue()) self.logger.info(s) def set_preamp_en(self, pix="all"): tmp_spi_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_SPI_RX'].set_en(False) tmp_gate_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_PULSE_GATE'].set_en(False) self.dut['CCPD_SR']['TRIM_EN'] = 0 self.dut['CCPD_SR']['INJECT_EN'] = 0 self.dut['CCPD_SR']['MONITOR_EN'] = 0 self.dut['CCPD_SR']['PREAMP_EN'] = 1 self.dut['CCPD_SR']['MONITOR_EN_ANA'] = self.monitor_en_ana self.dut['CCPD_SR']['SW_MON'] = self.sw_mon self.dut['CCPD_SR']['SW_INJ'] = self.sw_inj en_pix, en_col = self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels'] = en_pix self.preamp_en = en_pix.copy() self.dut['CCPD_SR']['PREAMP_EN_ANA'] = en_col self.preamp_en_ana = en_col.copy() self.dut['CCPD_SR']['BUFFER_EN'] = self.sw_mon.any() self.dut['CCPD_SR']['REGULATOR_EN'] = (en_col.any() or en_pix[106 * 18:].any()) self._write_SR(sw="SW_LDPIX") self.dut['CCPD_SPI_RX'].set_en(tmp_spi_en) self.dut['CCPD_PULSE_GATE'].set_en(tmp_gate_en) s = "set_preamp_en pix:%s lds:%d,%d,%d,%d pixels:%s " % ( pix, self.dut['CCPD_SR']['TRIM_EN'].tovalue(), self.dut['CCPD_SR']['INJECT_EN'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN'].tovalue(), self.dut['CCPD_SR']['PREAMP_EN'].tovalue(), "") s = "%spreamp_en_ana:0x%x monitor_en_ana:0x%x sw_mon:0x%x sw_inj:0x%x regulator:%d buffer:%d" % ( s, self.dut['CCPD_SR']['PREAMP_EN_ANA'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN_ANA'].tovalue(), self.dut['CCPD_SR']['SW_MON'].tovalue(), self.dut['CCPD_SR']['SW_INJ'].tovalue(), self.dut['CCPD_SR']['REGULATOR_EN'].tovalue(), self.dut['CCPD_SR']['BUFFER_EN'].tovalue()) self.logger.info(s) def set_inj_en(self, pix="none"): tmp_spi_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_SPI_RX'].set_en(False) tmp_gate_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_PULSE_GATE'].set_en(False) self.dut['CCPD_SR']['TRIM_EN'] = 0 self.dut['CCPD_SR']['INJECT_EN'] = 1 self.dut['CCPD_SR']['MONITOR_EN'] = 0 self.dut['CCPD_SR']['PREAMP_EN'] = 0 self.dut['CCPD_SR']['PREAMP_EN_ANA'] = self.preamp_en_ana self.dut['CCPD_SR']['MONITOR_EN_ANA'] = self.monitor_en_ana self.dut['CCPD_SR']['SW_MON'] = self.sw_mon en_pix, en_col = self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels'] = en_pix self.inj_en = en_pix.copy() for i in range(0, 2756, 106 * 2): self.dut['CCPD_SR']['SW_INJ'][i / (106 * 2)] = self.inj_en[i:i + (106 * 2)].any() for i in range(5): self.dut['CCPD_SR']['SW_INJ'][13 + i] = en_col[2 * i:2 * (i + 1)].any() self.sw_inj = self.dut['CCPD_SR']['SW_INJ'].copy() self.dut['CCPD_SR']['BUFFER_EN'] = self.sw_mon.any() self.dut['CCPD_SR']['REGULATOR_EN'] = (self.preamp_en_ana.any() or self.preamp_en[106 * 18:].any()) self._write_SR(sw="SW_LDPIX") self.dut['CCPD_SPI_RX'].set_en(tmp_spi_en) self.dut['CCPD_PULSE_GATE'].set_en(tmp_gate_en) s = "set_inj_en pix:%s lds:%d,%d,%d,%d pixels:%s " % ( pix, self.dut['CCPD_SR']['TRIM_EN'].tovalue(), self.dut['CCPD_SR']['INJECT_EN'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN'].tovalue(), self.dut['CCPD_SR']['PREAMP_EN'].tovalue(), "") s = "%spreamp_en_ana:0x%x monitor_en_ana:0x%x sw_mon:0x%x sw_inj:0x%x regulator:%d buffer:%d" % ( s, self.dut['CCPD_SR']['PREAMP_EN_ANA'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN_ANA'].tovalue(), self.dut['CCPD_SR']['SW_MON'].tovalue(), self.dut['CCPD_SR']['SW_INJ'].tovalue(), self.dut['CCPD_SR']['REGULATOR_EN'].tovalue(), self.dut['CCPD_SR']['BUFFER_EN'].tovalue()) self.logger.info(s) def set_tdac(self, tdac): tmp_spi_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_SPI_RX'].set_en(False) tmp_gate_en = self.dut['CCPD_SPI_RX'].get_en() self.dut['CCPD_PULSE_GATE'].set_en(False) self.dut['CCPD_SR']['INJECT_EN'] = 0 self.dut['CCPD_SR']['MONITOR_EN'] = 0 self.dut['CCPD_SR']['PREAMP_EN'] = 0 self.dut['CCPD_SR']['PREAMP_EN_ANA'] = self.preamp_en_ana self.dut['CCPD_SR']['MONITOR_EN_ANA'] = self.monitor_en_ana self.dut['CCPD_SR']['SW_INJ'] = self.sw_inj self.dut['CCPD_SR']['SW_MON'] = self.sw_mon self.dut['CCPD_SR']['BUFFER_EN'] = self.sw_mon.any() self.dut['CCPD_SR']['REGULATOR_EN'] = (self.preamp_en_ana.any() or self.preamp_en[106 * 18:].any()) if isinstance(tdac, int): tdac = np.ones([26, 106], int) * tdac for i_trim in [1, 2, 4, 8]: pix = bitarray.bitarray( ((np.reshape(tdac, 106 * 26) & i_trim) != 0).tolist()) en_pix, en_col = self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels'] = en_pix self.dut['CCPD_SR']['TRIM_EN'] = i_trim self._write_SR(sw="SW_LDPIX") self.dut['CCPD_SPI_RX'].set_en(tmp_spi_en) self.dut['CCPD_PULSE_GATE'].set_en(tmp_gate_en) np.argwhere(self.tdac != tdac) s = "tdac:" for p in np.argwhere(self.tdac != tdac): s = "%s,[%d,%d]=%d" % (s, p[0], p[1], tdac[p[0], p[1]]) self.logger.info(s) self.tdac = np.copy(tdac) ################ ## HIT register def set_hit(self, mode="inj", repeat=100, gate_delay=50, gate_width=None): ### TODO should be better than this if mode == "inj": inj = True inj_delay = 100 inj_width = 200 if gate_width == None: gate_width = inj_delay + inj_width / 2 thmod = False thon_width = 0 thon_delay = 0 elif mode == "inj_ext": inj = False inj_delay = 0 inj_width = 0 if gate_width == None: gate_width = 1000 thmod = False thon_width = 0 thon_delay = 0 elif mode == "inj_thmod": if gate_width == None: gate_width = 9900 inj = True inj_width = 200 inj_delay = gate_width - inj_width / 2 thmod = True thon_width = gate_width - 10 thon_delay = gate_delay + 10 elif mode == "src": inj = False inj_delay = 0 inj_width = 0 if gate_width == None: gate_width = 9900 thmod = False thon_width = 0 thon_delay = 0 elif mode == "src_thmod": inj = False inj_delay = 0 inj_width = 0 if gate_width == None: gate_width = 9900 thmod = True thon_width = gate_width - 10 thon_delay = gate_delay + 10 sr_wait = gate_width + gate_delay + 5 self.dut['rx']['CCPD_ADC'] = 0 self.dut['rx']['TLU'] = 0 self.dut['rx']['CCPD_TDC'] = 0 self.dut['rx']['CCPD_RX'] = 1 self.dut['rx'].write() self.dut["CCPD_PULSE_THON"].reset() if thmod == False: self.dut["CCPD_PULSE_THON"].set_en(0) else: self.dut["CCPD_PULSE_THON"].set_delay(thon_delay) self.dut["CCPD_PULSE_THON"].set_repeat(1) self.dut["CCPD_PULSE_THON"].set_width(thon_width) self.dut["CCPD_PULSE_THON"].set_en(1) self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["EN"] = 0 self.dut["CCPD_SR"].reset() self.dut["CCPD_SR"] = bitarray.bitarray('1' * 2953) self._write_SR(sw="NONE") self.dut["CCPD_SR"].set_size(2768) self.dut["CCPD_SR"].set_repeat(repeat + 1) self.dut["CCPD_SR"].set_wait(sr_wait) self.dut['CCPD_SW']['SW_LDPIX'] = 0 self.dut['CCPD_SW']['SW_LDDAC'] = 0 if thmod == False: self.dut['CCPD_SW']['THON_NEG'] = 1 else: self.dut['CCPD_SW']['THON_NEG'] = 0 self.dut["CCPD_SW"]["SW_HIT"] = 1 self.dut["CCPD_SW"]["EXT_START_TLU"] = 0 self.dut["CCPD_SW"]["GATE_NEG"] = 0 self.dut['CCPD_SW'].write() if inj == False: self.dut["CCPD_PULSE_INJ"]["EN"] = 0 else: self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_INJ"]["REPEAT"] = 1 self.dut["CCPD_PULSE_INJ"]["DELAY"] = inj_delay self.dut["CCPD_PULSE_INJ"]["WIDTH"] = inj_width self.dut["CCPD_PULSE_INJ"]["EN"] = 1 self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"] = 1 self.dut["CCPD_PULSE_GATE"]["DELAY"] = gate_delay self.dut["CCPD_PULSE_GATE"]["WIDTH"] = gate_width self.dut["CCPD_PULSE_GATE"]["EN"] = 1 # set TDC self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['ENABLE_EXTERN'] = False self.dut['CCPD_TDC']['ENABLE'] = False # reset fifo self.dut['sram'].reset() # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(True) s = "repeat:%d inj_delay:%d inj_width:%d gate_delay:%d gate_width:%d\n" % ( repeat, inj_delay, inj_width, gate_delay, gate_width) s = "%sthod:%d thon_width:%d thon_delay:%d sr_wait:%d" % ( s, thmod, thon_width, thon_delay, sr_wait) self.logger.info(s) def get_hit(self): self.dut['sram'].reset() while self.dut["sram"].get_fifo_size() != 0: self.dut['sram'].get_data() self.dut['sram'].reset() self.dut['sram'].reset() self.dut["CCPD_SR"].start() wait = self.dut["CCPD_SR"].get_wait() repeat = self.dut["CCPD_SR"].get_repeat() i = 0 while self.dut["sram"].get_fifo_size() < 692 * repeat: #while not self.dut['CCPD_SR'].is_done(): ## this dose not work any more if i > 10000 + wait * repeat / 1000: self.logger.info("get_hit ERROR timeout") break elif i > 100: time.sleep(0.001) i = i + 1 return self.dut['sram'].get_data()[173:] ########################## ########### TDC def set_tdc_inj(self, repeat=100, inj_width=500, gate_delay=5, inj_delay=None, gate_width=None, tdc_trig_dist=False): if inj_delay == None: inj_delay = inj_width if gate_width == None: gate_width = inj_width * 2 * repeat + 2 * gate_delay self.dut['rx']['NC'] = 0 self.dut['rx']['TLU'] = 0 self.dut['rx']['CCPD_TDC'] = 1 self.dut['rx']['CCPD_RX'] = 0 self.dut['rx'].write() self.dut['CCPD_SW']['SW_LDPIX'] = 0 self.dut['CCPD_SW']['SW_LDDAC'] = 0 self.dut['CCPD_SW']['SW_HIT'] = 0 self.dut["CCPD_SW"]['THON_NEG'] = 1 self.dut['CCPD_SW'].write() self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_INJ"]["REPEAT"] = repeat self.dut["CCPD_PULSE_INJ"]["DELAY"] = inj_delay self.dut["CCPD_PULSE_INJ"]["WIDTH"] = inj_width self.dut["CCPD_PULSE_INJ"]["EN"] = 1 self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"] = 1 self.dut["CCPD_PULSE_GATE"]["DELAY"] = gate_delay self.dut["CCPD_PULSE_GATE"]["WIDTH"] = gate_width self.dut["CCPD_PULSE_GATE"]["EN"] = 1 self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['EN_INVERT_TDC'] = True self.dut['CCPD_TDC']['EN_TRIGGER_DIST'] = tdc_trig_dist self.dut['CCPD_TDC']['EN_WRITE_TIMESTAMP'] = True self.dut['CCPD_TDC']['ENABLE_EXTERN'] = True self.dut['CCPD_TDC']['ENABLE'] = False self.dut['sram'].reset() s = "set_tdc_inj: repeat=%d inj_width=%d inj_delay=%d gate_width=%d gate_delay=%d tdc_trig_dist=%d" % ( repeat, inj_width, inj_delay, gate_delay, gate_width, tdc_trig_dist) self.logger.info(s) def set_tdc_src(self, mode="src", gate_width=None): if mode == "tlu": inj_width = 100 inj_delay = inj_width if gate_width == None: gate_width = 1 gate_delay = 1 tlu = True else: # mode=="src" inj_width = 0 inj_delay = 0 if gate_width == None: gate_width = 10000000 gate_delay = 5 tlu = False self.dut['rx']['NC'] = 0 self.dut['rx']['TLU'] = 0 self.dut['rx']['CCPD_TDC'] = 1 self.dut['rx']['CCPD_RX'] = 0 self.dut['rx']['TLU'] = tlu self.dut['rx'].write() self.dut['CCPD_SW']['SW_LDPIX'] = 0 self.dut['CCPD_SW']['SW_LDDAC'] = 0 self.dut['CCPD_SW']['SW_HIT'] = 0 self.dut['CCPD_SW']['GATE_NEG'] = 0 self.dut["CCPD_SW"]['THON_NEG'] = 1 self.dut['CCPD_SW']['EXT_START_TLU'] = tlu self.dut['CCPD_SW'].write() self.dut["CCPD_PULSE_THON"].reset() self.dut["CCPD_PULSE_THON"]["EN"] = False self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut["CCPD_SR"].reset() self.dut["CCPD_SR"].set_en(0) self.dut["tlu"]["RESET"] = 0 if tlu == True: self.dut["tlu"]["TRIGGER_MODE"] = 3 self.dut["tlu"]["TRIGGER_LOW_TIMEOUT"] = 0 self.dut["tlu"]["TRIGGER_VETO_SELECT"] = 255 self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"] = 1 self.dut["CCPD_PULSE_GATE"]["DELAY"] = gate_delay self.dut["CCPD_PULSE_GATE"]["WIDTH"] = gate_width self.dut["CCPD_PULSE_GATE"]["EN"] = 1 self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['EN_INVERT_TDC'] = True self.dut['CCPD_TDC']['ENABLE_EXTERN'] = True self.dut['CCPD_TDC']['ENABLE'] = False self.dut['sram'].reset() s = "set_tdc gate_width:%d gate_delay:%d tlu:%d" % (gate_width, gate_delay, tlu) self.logger.info(s) def get_tdc(self): self.dut['sram'].reset() self.dut["CCPD_PULSE_GATE"].start() i = 0 while i < 10000: if self.dut['CCPD_PULSE_GATE'].is_done(): break elif i > 100: time.sleep(0.001) # avoid CPU 100% i = i + 1 if i == 10000: self.logger.info("ERROR timeout") return self.dut['sram'].get_data() def get_data_now(self): return self.dut["sram"].get_data() def save_data_continuous(self, timeout=-1): fname = time.strftime("data_%y%m%d-%H%M%S") self.logger.info("fname:%s.npy" % fname) t0 = time.time() while True: with open("%s_%d.npy" % (fname, i / 10000), "ab") as f: d = self.dut['sram'].get_data() if len(d) == 0: time.sleep(0.1) else: np.save(f, d) f.flush() if (time.time() - t0 > timeout) and timeout > 0: break ################### ### tune and scan def scan_th(self, b=0.78, e=0.7, s=-0.01, mode="src", save=True, pix=[14, 25]): self.dut['CCPD_TH'].set_voltage(b, unit='V') thlist = np.arange(b, e, s) if save == True: fname = time.strftime("hit_%y%m%d-%H%M%S.npy") self.logger.info("scan_th fname:%s" % fname) with open(fname, "ab+") as f: np.save(f, thlist) for th in thlist[1:]: d = self.get_hit() th_meas = self.dut['CCPD_TH'].get_voltage(unit='V') self.dut['CCPD_TH'].set_voltage(th, unit='V') d = self.analyse_hit(d, "img") if self.plot == True: self.ax[0, 0].pcolor(d, vmin=0) plt.pause(0.001) self.logger.info("scan_th %f %d %s" % (th_meas, np.sum(d), str(d[pix[0], pix[1]]))) if save == True: with open(fname, "ab+") as f: np.save(f, d) if save == True: return fname def scan_th_tdc(self, b=1.1, e=0.7, s=-0.01): self.dut['CCPD_TH'].set_voltage(b, unit='V') self.logger.info("scan_th_tdc_simple th cnt ave std") for th in np.arange(b + s, e + s, s): d = self.get_tdc() th_meas = self.dut['CCPD_TH'].get_voltage(unit='V') self.dut['CCPD_TH'].set_voltage(th, unit='V') width, timestamp = self.analyse_tdc(d) cnt = len(width) ave = np.average(width[width > 0]) std = np.std(width[width > 0]) self.logger.info("scan_th_tdc_simple %f %d %f %f" % (th_meas, cnt, ave, std)) def source_tdc(self, n=1000, gate_width=10000000, save=False): fname = None if save == True: fname = time.strftime("srctdc_%y%m%d-%H%M%S.npy") i = 0 self.set_tdc_src(mode='src', gate_width=gate_width) while i < n: d = self.get_tdc() if save == True: with open(fname, "ab+") as f: np.save(f, d) width, timestamp = self.analyse_tdc(d) cnt = len(width) ave = np.average(width[width > 0]) std = np.std(width[width > 0]) self.logger.info("scan_th_tdc_simple %d %d %f %f" % (i, cnt, ave, std)) i = i + 1 return fname def scan_inj_tdc(self, b=1.81, e=0.0, s=-0.05, inj_low=0, save=False): self.dut["CCPD_Injection_high"].set_voltage(b, unit="V") self.inj_high = b self.dut["CCPD_Injection_low"].set_voltage(inj_low, unit="V") self.inj_low = inj_low self.logger.info("scan inj_low inj_high cnt ave std") fname = None if save == True: fname = time.strftime("injtdc_%y%m%d-%H%M%S.npy") with open(fname, "wb") as f: np.save(f, np.arange(b, e, s)) for inj in np.arange(b + s, e, s): d = self.get_tdc() if save == True: with open(fname, "ab+") as f: np.save(f, d) self.dut["CCPD_Injection_high"].set_voltage(inj, unit="V") self.inj_high = inj width, delay = self.analyse_tdc(d) cnt = len(width) ave = np.average(width) std = np.std(width) self.logger.info("scan_inj_tdc %f %f %d %f %f" % (self.inj_low, self.inj_high, cnt, ave, std)) d = self.get_tdc() if save == True: with open(fname, "ab+") as f: np.save(f, d) width, delay = self.analyse_tdc(d) cnt = len(width) ave = np.average(width) std = np.std(width) self.logger.info("scan_inj_tdc %f %f %d %f %f" % (self.inj_low, self.inj_high, cnt, ave, std)) return fname ################# ### analyse data ###TODO separate file def analyse_hit(self, dat, fmt="zs"): dat = dat[(dat & 0xF0000000) == 0x60000000] ret = np.empty([16, len(dat)], dtype=bool) for i in range(16): ret[15 - i, :] = (dat & 2**i == 0 ) ### the first bit goes to ret[15,0] ret = np.reshape(ret, len(dat) * 16, order="F") if fmt == "zs": ret = np.argwhere(ret == True)[:, 0] if len(ret) != 0: frame, col, row = self._build_img(ret) ret = np.transpose(np.array([frame, col, row])) return ret else: return np.array([]) elif fmt == "zs_frame": ret = np.argwhere(ret == True)[:, 0] if len(ret) != 0: frame, col, row = self._build_img(ret) frame = (dat[ret / 16] & 0x0FFF0000) >> 16 ret = np.transpose(np.array([frame, col, row])) return ret else: return np.array([]) elif fmt == "img": img = np.zeros([26, 106]) for i in range(0, len(ret), 2768): img = np.add(img, self._build_img2(ret[i:i + 2756][::-1])) return img else: return "ERROR!! fmt=img,zs,zs_frame" ### TODO to be an exception? def analyse_tdc(self, dat, tdc_trig_dist=False): dat = dat[dat & 0xF0000000 == 0x50000000] ret0 = dat & 0x00000FFF if tdc_trig_dist: ret1 = np.right_shift(dat & 0x000FF000, 12) ret2 = np.right_shift(dat & 0x0FF00000, 20) return ret0, ret1, ret2 else: ret1 = np.right_shift(dat & 0x0FFFF000, 12) return ret0, ret1 def analyse_adc(self, dat): dat = dat[dat & 0xe0000000 == 0xe0000000] if dat[0] & 0xf0000000 != 0xf0000000: self.logger.info( "analyse_adc: first adc data was not the first data 0x%x" % dat[0]) return dat & 0x00003FFF def init_plot(self): self.plot = True plt.ion() fig, self.ax = plt.subplots(2, 2) plt.pause(0.001) self.ax[0, 0].autoscale(False) self.ax[1, 0].autoscale(False) self.ax[0, 0].set_xbound(0, 106) self.ax[0, 0].set_ybound(0, 24) self.ax[1, 0].set_xbound(0, 106) self.ax[1, 0].set_ybound(0, 24)
class TestSimSeq(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimSeq.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): self.assertEqual(self.chip['SEQ_GEN'].get_mem_size(), 8 * 1024) self.chip['SEQ']['S0'][0] = 1 self.chip['SEQ']['S1'][1] = 1 self.chip['SEQ']['S2'][2] = 1 self.chip['SEQ']['S3'][3] = 1 self.chip['SEQ']['S4'][12] = 1 self.chip['SEQ']['S5'][13] = 1 self.chip['SEQ']['S6'][14] = 1 self.chip['SEQ']['S7'][15] = 1 pattern = [0x01, 0x02, 0x04, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0x20, 0x40, 0x80] self.chip['SEQ'].write(16) ret = self.chip['SEQ'].get_data(size=16) self.assertEqual(ret.tolist(), pattern) rec_size = 16 * 4 + 8 self.chip['SEQ_REC'].set_en_ext_start(True) self.chip['SEQ_REC'].set_size(rec_size) self.chip['PULSE_GEN'].set_delay(1) self.chip['PULSE_GEN'].set_width(1) self.assertEqual(self.chip['PULSE_GEN'].get_delay(), 1) self.assertEqual(self.chip['PULSE_GEN'].get_width(), 1) self.chip['SEQ'].set_repeat(4) self.chip['SEQ'].set_en_ext_start(True) self.chip['SEQ'].set_size(16) # self.chip['SEQ'].start() self.chip['PULSE_GEN'].start() while(not self.chip['SEQ'].is_done()): pass ret = self.chip['SEQ_REC'].get_data(size=rec_size) self.assertEqual(ret.tolist(), [0x0] * 2 + pattern * 4 + [0x80] * 6) # 2 clk delay + pattern x4 + 6 x last pattern # self.chip['SEQ'].set_repeat_start(12) self.chip['PULSE_GEN'].start() while(not self.chip['SEQ'].is_done()): pass ret = self.chip['SEQ_REC'].get_data(size=rec_size) self.assertEqual(ret.tolist(), [0x80] * 2 + pattern + pattern[12:] * 3 + [0x80] * 3 * 12 + [0x80] * 6) # 2 clk delay 0x80 > from last pattern + ... self.chip['SEQ'].set_wait(4) self.chip['PULSE_GEN'].start() while(not self.chip['SEQ'].is_done()): pass ret = self.chip['SEQ_REC'].get_data(size=rec_size) lpat = pattern[12:] + [0x80] * 4 self.assertEqual(ret.tolist(), [0x80] * 2 + pattern + [0x80] * 4 + lpat * 3 + [0x80] * (3 * 12 - 4 * 4) + [0x80] * 6) # rec_size = rec_size * 3 self.chip['SEQ_REC'].set_size(rec_size) self.chip['SEQ'].set_clk_divide(3) self.chip['SEQ'].set_wait(3) self.chip['PULSE_GEN'].start() while(not self.chip['SEQ'].is_done()): pass ret = self.chip['SEQ_REC'].get_data(size=rec_size) lpat = pattern[12:] + [0x80] * 3 mu_pat = pattern + [0x80] * 3 + lpat * 3 fm = [] for i in mu_pat: fm += [i, i, i] self.assertEqual(ret.tolist(), [0x80] * 2 + fm + [0x80] * 94) # self.chip['SEQ'].set_wait(0) self.chip['PULSE_GEN'].start() while(not self.chip['SEQ'].is_done()): pass ret = self.chip['SEQ_REC'].get_data(size=rec_size) lpat = pattern[12:] mu_pat = pattern + lpat * 3 fm = [] for i in mu_pat: fm += [i, i, i] self.assertEqual(ret.tolist(), [0x80] * 2 + fm + [0x80] * (94 + 4 * 3 * 3)) # nested loop test pattern = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] self.chip['SEQ'].set_data(pattern) self.chip['SEQ'].set_repeat(4) self.chip['SEQ'].set_repeat_start(2) self.chip['SEQ'].set_nested_start(8) self.chip['SEQ'].set_nested_stop(12) self.chip['SEQ'].set_nested_repeat(3) self.chip['SEQ'].set_clk_divide(1) self.chip['PULSE_GEN'].start() while(not self.chip['SEQ'].is_done()): pass exp_pattern = [0x10, 0x10] exp_pattern += pattern[0:2] rep = pattern[2:8] rep += pattern[8:12] * 3 rep += pattern[12:16] exp_pattern += rep * 4 exp_pattern += [16] * 124 ret = self.chip['SEQ_REC'].get_data(size=rec_size) self.assertEqual(ret.tolist(), exp_pattern) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
def pre_run(self): # clear error queue in case run is executed a second time self.err_queue.queue.clear() # opening ZMQ context and binding socket if self._conf['send_data'] and not self._conf['zmq_context']: logging.info('Creating ZMQ context') self._conf['zmq_context'] = zmq.Context() # contexts are thread safe unlike sockets else: logging.info('Using existing socket') # scan parameters if 'scan_parameters' in self._run_conf: if isinstance(self._run_conf['scan_parameters'], basestring): self._run_conf['scan_parameters'] = ast.literal_eval(self._run_conf['scan_parameters']) sp = namedtuple('scan_parameters', field_names=zip(*self._run_conf['scan_parameters'])[0]) self.scan_parameters = sp(*zip(*self._run_conf['scan_parameters'])[1]) else: sp = namedtuple_with_defaults('scan_parameters', field_names=[]) self.scan_parameters = sp() logging.info('Scan parameter(s): %s', ', '.join(['%s=%s' % (key, value) for (key, value) in self.scan_parameters._asdict().items()]) if self.scan_parameters else 'None') # init DUT if not isinstance(self._conf['dut'], Dut): module_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) if isinstance(self._conf['dut'], basestring): # dirty fix for Windows pathes self._conf['dut'] = os.path.normpath(self._conf['dut'].replace('\\', '/')) # abs path if os.path.isabs(self._conf['dut']): dut = self._conf['dut'] # working dir elif os.path.exists(os.path.join(self._conf['working_dir'], self._conf['dut'])): dut = os.path.join(self._conf['working_dir'], self._conf['dut']) # path of this file elif os.path.exists(os.path.join(module_path, self._conf['dut'])): dut = os.path.join(module_path, self._conf['dut']) else: raise ValueError('dut parameter not a valid path: %s' % self._conf['dut']) else: dut = self._conf['dut'] dut = Dut(dut) # only initialize when DUT was not initialized before if 'dut_configuration' in self._conf and self._conf['dut_configuration']: if isinstance(self._conf['dut_configuration'], basestring): # dirty fix for Windows pathes self._conf['dut_configuration'] = os.path.normpath(self._conf['dut_configuration'].replace('\\', '/')) # abs path if os.path.isabs(self._conf['dut_configuration']): dut_configuration = self._conf['dut_configuration'] # working dir elif os.path.exists(os.path.join(self._conf['working_dir'], self._conf['dut_configuration'])): dut_configuration = os.path.join(self._conf['working_dir'], self._conf['dut_configuration']) # path of dut file elif os.path.exists(os.path.join(os.path.dirname(dut.conf_path), self._conf['dut_configuration'])): dut_configuration = os.path.join(os.path.dirname(dut.conf_path), self._conf['dut_configuration']) # path of this file elif os.path.exists(os.path.join(module_path, self._conf['dut_configuration'])): dut_configuration = os.path.join(module_path, self._conf['dut_configuration']) else: raise ValueError('dut_configuration parameter not a valid path: %s' % self._conf['dut_configuration']) # make dict dut_configuration = RunManager.open_conf(dut_configuration) # change bit file path if 'USB' in dut_configuration and 'bit_file' in dut_configuration['USB'] and dut_configuration['USB']['bit_file']: bit_file = os.path.normpath(dut_configuration['USB']['bit_file'].replace('\\', '/')) # abs path if os.path.isabs(bit_file): pass # working dir elif os.path.exists(os.path.join(self._conf['working_dir'], bit_file)): bit_file = os.path.join(self._conf['working_dir'], bit_file) # path of dut file elif os.path.exists(os.path.join(os.path.dirname(dut.conf_path), bit_file)): bit_file = os.path.join(os.path.dirname(dut.conf_path), bit_file) # path of this file elif os.path.exists(os.path.join(module_path, bit_file)): bit_file = os.path.join(module_path, bit_file) else: raise ValueError('bit_file parameter not a valid path: %s' % bit_file) dut_configuration['USB']['bit_file'] = bit_file else: dut_configuration = self._conf['dut_configuration'] else: dut_configuration = None dut.init(dut_configuration) # assign dut after init in case of exceptions during init self._conf['dut'] = dut # additional init of the DUT self.init_dut() else: pass # do nothing, already initialized # FIFO readout self.fifo_readout = FifoReadout(self.dut) # initialize the FE self.init_fe()
# # ------------------------------------------------------------ # Copyright (c) All rights reserved # SiLab, Institute of Physics, University of Bonn # ------------------------------------------------------------ # ''' This script shows how to use a Suss or Signatone Probe station. BTW: For the PA-200 it is not forseen to be able to communicate with the prober bench software when running on the host PC without using the propriatary and not documented network interface dll. A work around is to use the Suss RS232 interface that is in place to connect to another client PC. To be able to use the Probe station directly with BASIL on the host PC via RS232 a virtual comport has to be created connecting the real comport (that is set in the RS232 Interface application, pbrs232.exe) to a virtual one. This virtual one is then used to steer the probe station within BASIL. ''' from basil.dut import Dut dut = Dut('suss_pa_200.yaml') dut.init() print(dut['SussProber'].get_position()) print(dut['SussProber'].get_die()) dut2 = Dut('SignatoneProber.yaml') dut2.init() print(dut2['SignatoneProber'].get_position()) print(dut2['SignatoneProber'].get_die())
class TestSimSpi(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.path.join(os.path.dirname(__file__), 'test_SimSpi.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): size = self.chip['SPI'].get_SIZE() self.chip['GPIO'].reset() self.assertEqual(size, 16 * 8) self.chip['SPI'].set_data(range(16)) ret = self.chip['SPI'].get_data(size=16, addr=0) # to read back what was written self.assertEqual(ret.tolist(), range(16)) self.chip['SPI'].set_data(range(16)) ret = self.chip['SPI'].get_data(addr=0) # to read back what was written self.assertEqual(ret.tolist(), range(16)) self.chip['SPI'].start() while(not self.chip['SPI'].is_ready): pass ret = self.chip['SPI'].get_data() # read back what was received (looped) self.assertEqual(ret.tolist(), range(16)) # ext_start self.chip['SPI'].set_en(1) self.assertEqual(self.chip['SPI'].get_en(), 1) self.chip['PULSE_GEN'].set_DELAY(1) self.chip['PULSE_GEN'].set_WIDTH(1 + size) self.chip['PULSE_GEN'].set_REPEAT(1) self.assertEqual(self.chip['PULSE_GEN'].get_DELAY(), 1) self.assertEqual(self.chip['PULSE_GEN'].get_WIDTH(), 1 + size) self.assertEqual(self.chip['PULSE_GEN'].get_REPEAT(), 1) self.chip['PULSE_GEN'].start() while(not self.chip['PULSE_GEN'].is_ready): pass ret = self.chip['SPI'].get_data() # read back what was received (looped) self.assertEqual(ret.tolist(), range(16)) # SPI_RX ret = self.chip['SPI_RX'].get_en() self.assertEqual(ret, False) self.chip['SPI_RX'].set_en(True) ret = self.chip['SPI_RX'].get_en() self.assertEqual(ret, True) self.chip['SPI'].start() while(not self.chip['SPI'].is_ready): pass ret = self.chip['FIFO'].get_FIFO_SIZE() self.assertEqual(ret, 32) ret = self.chip['FIFO'].get_data() data0 = ret.astype(np.uint8) data1 = np.right_shift(ret, 8).astype(np.uint8) data = np.reshape(np.vstack((data1, data0)), -1, order='F') self.assertEqual(data.tolist(), range(16)) def test_dut_iter(self): conf = yaml.safe_load(cnfg_yaml) def iter_conf(): for item in conf['registers']: yield item for item in conf['hw_drivers']: yield item for item in conf['transfer_layer']: yield item for mod, mcnf in zip(self.chip, iter_conf()): self.assertEqual(mod.name, mcnf['name']) self.assertEqual(mod.__class__.__name__, mcnf['type']) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimTlu(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.path.dirname(__file__) + '/test_SimTlu.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_simple_trigger_veto(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 2 self.chip['tlu'].TRIGGER_VETO_SELECT = 2 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x07]) # trigger + veto self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 1) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 1) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) def test_simple_trigger_veto_disabled(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 2 self.chip['tlu'].TRIGGER_VETO_SELECT = 252 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x07]) # trigger + veto self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 2) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 2) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) def test_simple_trigger_max_triggers(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].MAX_TRIGGERS = 2 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 2 self.chip['tlu'].TRIGGER_VETO_SELECT = 252 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 2) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 2) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) def test_simple_trigger(self): self.chip['tlu'].TRIGGER_COUNTER = 10 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 1 self.chip['tlu'].TRIGGER_VETO_SELECT = 0 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) readings = 0 while(self.chip['sram'].get_fifo_int_size() < 4 and readings < 1000): readings += 1 # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertGreaterEqual(self.chip['sram'].get_fifo_int_size(), 4) self.assertGreaterEqual(self.chip['tlu'].TRIGGER_COUNTER, 14) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 10) self.assertEqual(data[1], 0x80000000 + 11) self.assertEqual(data[2], 0x80000000 + 12) self.assertEqual(data[3], 0x80000000 + 13) def test_tlu_trigger_handshake(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 3 self.chip['tlu'].TRIGGER_VETO_SELECT = 255 self.chip['tlu'].EN_TLU_VETO = 0 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) readings = 0 while(self.chip['sram'].get_fifo_int_size() < 4 and readings < 1000): readings += 1 # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertGreaterEqual(self.chip['sram'].get_fifo_int_size(), 4) self.assertGreaterEqual(self.chip['tlu'].TRIGGER_COUNTER, 4) self.assertGreaterEqual(self.chip['tlu'].CURRENT_TLU_TRIGGER_NUMBER, 3) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000) self.assertEqual(data[1], 0x80000001) self.assertEqual(data[2], 0x80000002) self.assertEqual(data[3], 0x80000003) def test_tlu_trigger_handshake_veto(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 3 self.chip['tlu'].TRIGGER_VETO_SELECT = 1 self.chip['tlu'].EN_TLU_VETO = 1 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) readings = 0 while(self.chip['sram'].get_fifo_int_size() == 0 and readings < 1000): readings += 1 self.assertEqual(self.chip['sram'].get_fifo_int_size(), 0) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 0) self.assertEqual(self.chip['tlu'].CURRENT_TLU_TRIGGER_NUMBER, 0) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestRegisterHardwareLayer(unittest.TestCase): def setUp(self): self.dut = Dut(os.path.join(os.path.dirname(__file__), 'test_RegisterHardwareLayer.yaml')) self.dut.init() def test_init_non_existing(self): with self.assertRaises(KeyError): self.dut.init({"test_register": {"NON_EXISTING": 1}}) def test_lazy_programming(self): self.dut['test_register'].set_default() self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) self.dut['test_register'].REG5_WO = 255 self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 255, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) self.dut['test_register'].REG5_WO # get value from write-only register, but this will write zero instead self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) def test_get_configuration(self): self.dut.set_configuration(os.path.join(os.path.dirname(__file__), 'test_RegisterHardwareLayer_configuration.yaml')) conf = self.dut['test_register'].get_configuration() self.assertDictEqual({'REG1': 257, 'REG2': 1, 'REG3': 2, 'REG_TEST_INIT': 0, 'REG_BYTE_ARRAY': [1, 2, 3, 4]}, conf) def test_set_configuration(self): self.dut.set_configuration(os.path.join(os.path.dirname(__file__), 'test_RegisterHardwareLayer_configuration.yaml')) self.assertDictEqual({0: 1, 1: 129, 2: 2, 3: 0, 5: 5, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) def test_set_configuration_non_existing(self): with self.assertRaises(KeyError): self.dut.set_configuration({"test_register": {"NON_EXISTING": 1}}) def test_read_only(self): self.assertRaises(IOError, self.dut['test_register']._set, 'REG4_RO', value=0) # def test_write_only(self): # self.assertRaises(IOError, self.dut['test_register']._get, 'REG5_WO') def test_write_only_lazy_programming(self): self.dut['test_register'].set_default() self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) self.dut['test_register'].REG5_WO = 20 self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 20, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) self.dut['test_register'].REG5_WO self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) self.assertIs(None, self.dut['test_register']._get('REG5_WO')) def test_set_default(self): self.dut['test_register'].set_default() self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) def test_set_attribute_add(self): val = self.dut['test_register']._registers['REG1']['default'] self.dut['test_register'].REG1 = val # 12 mem = self.dut['dummy_tl'].mem.copy() self.dut['test_register'].REG1 += 1 # 13 mem[0] = 13 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_write_read_reg(self): for reg in ['REG1', 'REG2', 'REG3']: val = self.dut['test_register']._registers[reg]['default'] self.dut['test_register']._set(reg, val) ret_val = self.dut['test_register']._get(reg) self.assertEqual(ret_val, val) self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) def test_set_attribute_by_value(self): self.dut['test_register'].set_default() self.assertDictEqual({0: 12, 1: 128, 2: 255, 3: 255, 5: 0, 16: 1, 17: 2, 18: 3, 19: 4}, self.dut['dummy_tl'].mem) self.dut['test_register'].REG2 = 0 mem = self.dut['dummy_tl'].mem.copy() mem[1] = 0 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_set_attribute_by_string(self): mem = self.dut['dummy_tl'].mem.copy() self.dut['test_register'].REG3 = '1010101010101010' # dfghfghdfghgfdghf mem[2] = 170 mem[3] = 170 self.assertDictEqual(mem, self.dut['dummy_tl'].mem) def test_get_attribute_by_string(self): self.dut['test_register'].REG3 = '1010101010101010' # 43690 self.assertEqual(43690, self.dut['test_register'].REG3) def test_set_attribute_too_long_string(self): val = '11010101010101010' # 17 bit self.assertRaises(ValueError, self.dut['test_register']._set, 'REG3', value=val) def test_set_attribute_dict_access(self): self.dut['test_register']['REG1'] = 27306 # 27306 self.assertEqual(27306, self.dut['test_register']['REG1']) def test_set_attribute_too_big_val(self): val = 2 ** 16 # max 2 ** 16 - 1 self.assertRaises(ValueError, self.dut['test_register']._set, 'REG3', value=val) def test_set_by_function(self): self.dut['test_register'].set_REG1(27308) self.assertEqual(27308, self.dut['test_register']['REG1']) def test_get_by_function(self): self.dut['test_register']['REG1'] = 27305 # 27306 ret = self.dut['test_register'].get_REG1() self.assertEqual(ret, self.dut['test_register']['REG1']) def test_init_with_dict(self): self.dut['test_register'].set_default() self.dut.init({'test_register': _test_init}) conf = self.dut.get_configuration() self.assertDictEqual({'test_register': {'REG1': 120, 'REG2': 1, 'REG3': 65535, 'REG_TEST_INIT': 15, 'REG_BYTE_ARRAY': [4, 3, 2, 1]}, 'dummy_tl': {}}, conf) def test_get_dut_configuration(self): self.dut['test_register'].set_default() conf = self.dut.get_configuration() self.assertDictEqual({'test_register': {'REG1': 12, 'REG2': 1, 'REG3': 65535, 'REG_TEST_INIT': 0, 'REG_BYTE_ARRAY': [1, 2, 3, 4]}, 'dummy_tl': {}}, conf) def test_get_set_value(self): for val in range(256): self.dut['test_register'].set_value(val, 0, size=8, offset=0) ret_val = self.dut['test_register'].get_value(0, size=8, offset=0) self.assertEqual(ret_val, val) def test_write_read_reg_with_bit_str(self): val = '00110110' # 54 self.dut['test_register'].set_value(val, 0, size=8, offset=0) ret_val = self.dut['test_register'].get_value(0, size=8, offset=0) self.assertEqual(ret_val, int(val, base=2)) def test_write_read_reg_with_offset(self): for offset in range(32): val = 131 self.dut['test_register'].set_value(val, 0, size=8, offset=offset) ret_val = self.dut['test_register'].get_value(0, size=8, offset=offset) self.assertEqual(ret_val, val) def test_write_read_reg_with_size(self): for size in range(8, 33): val = 131 self.dut['test_register'].set_value(val, 0, size=size, offset=7) ret_val = self.dut['test_register'].get_value(0, size=size, offset=7) self.assertEqual(ret_val, val) def test_read_non_existing(self): with self.assertRaises(KeyError): self.dut['test_register'].NON_EXISTING with self.assertRaises(KeyError): self.dut['test_register']['NON_EXISTING'] with self.assertRaises(KeyError): self.dut['test_register'].get_NON_EXISTING() def test_write_non_existing(self): with self.assertRaises(KeyError): self.dut['test_register'].NON_EXISTING = 42 with self.assertRaises(KeyError): self.dut['test_register']['NON_EXISTING'] = 42 with self.assertRaises(KeyError): self.dut['test_register'].set_NON_EXISTING(42) def test_wrong_size(self): self.assertRaises(ValueError, self.dut['test_register'].set_value, 131, addr=0, size=7, offset=7)
class TestSram(unittest.TestCase): def setUp(self): fw_path = get_basil_dir() + "/firmware/modules" cocotb_compile_and_run( [ fw_path + "/gpio/gpio.v", fw_path + "/utils/reset_gen.v", fw_path + "/utils/bus_to_ip.v", fw_path + "/rrp_arbiter/rrp_arbiter.v", fw_path + "/utils/ODDR_sim.v", fw_path + "/utils/generic_fifo.v", fw_path + "/utils/cdc_pulse_sync.v", fw_path + "/utils/fx2_to_bus.v", fw_path + "/pulse_gen/pulse_gen.v", fw_path + "/pulse_gen/pulse_gen_core.v", fw_path + "/sram_fifo/sram_fifo_core.v", fw_path + "/sram_fifo/sram_fifo.v", os.path.dirname(__file__) + "/../firmware/src/sram_test.v", os.path.dirname(__file__) + "/../tests/tb.v", ], top_level="tb", sim_bus="basil.utils.sim.SiLibUsbBusDriver", ) with open(os.path.dirname(__file__) + "/../sram_test.yaml", "r") as f: cnfg = yaml.load(f) # change to simulation interface cnfg["transfer_layer"][0]["type"] = "SiSim" self.chip = Dut(cnfg) self.chip.init() def test_simple(self): self.chip["CONTROL"]["COUNTER_EN"] = 1 self.chip["CONTROL"].write() self.chip["CONTROL"].write() self.chip["CONTROL"]["COUNTER_EN"] = 0 self.chip["CONTROL"].write() for _ in range(10): self.chip["CONTROL"].write() ret = self.chip["fifo"].get_data() self.chip["CONTROL"]["COUNTER_EN"] = 1 self.chip["CONTROL"].write() self.chip["CONTROL"].write() self.chip["CONTROL"].write() self.chip["CONTROL"]["COUNTER_EN"] = 0 for _ in range(10): self.chip["CONTROL"].write() ret = np.hstack((ret, self.chip["fifo"].get_data())) x = np.arange(175 * 4, dtype=np.uint8) x.dtype = np.uint32 self.assertTrue(np.alltrue(ret == x)) self.chip["fifo"].reset() self.chip["CONTROL"]["COUNTER_EN"] = 1 self.chip["CONTROL"].write() self.chip["CONTROL"].write() self.chip["CONTROL"]["COUNTER_EN"] = 0 self.chip["CONTROL"].write() self.chip["CONTROL"].write() self.chip["CONTROL"].write() ret = np.hstack((ret, self.chip["fifo"].get_data())) x = np.arange(245 * 4, dtype=np.uint8) x.dtype = np.uint32 self.assertEqual(ret.tolist(), x.tolist()) def test_full(self): self.chip["CONTROL"]["COUNTER_EN"] = 1 self.chip["CONTROL"].write() for _ in range(2): self.chip["fifo"].get_fifo_size() self.chip["CONTROL"]["COUNTER_EN"] = 0 self.chip["CONTROL"].write() for _ in range(10): self.chip["CONTROL"].write() size = self.chip["fifo"].get_fifo_size() self.assertEqual(size, 512) ret = self.chip["fifo"].get_data() ret = np.hstack((ret, self.chip["fifo"].get_data())) x = np.arange(203 * 4, dtype=np.uint8) x.dtype = np.uint32 self.assertTrue(np.alltrue(ret == x)) def test_overflow(self): self.chip["CONTROL"]["COUNTER_EN"] = 1 self.chip["CONTROL"].write() for _ in range(20): self.chip["fifo"].get_fifo_size() self.chip["CONTROL"]["COUNTER_EN"] = 0 self.chip["CONTROL"].write() for _ in range(10): self.chip["CONTROL"].write() ret = self.chip["fifo"].get_data() while self.chip["fifo"].get_fifo_size(): ret = np.hstack((ret, self.chip["fifo"].get_data())) x = np.arange((128 + 1023) * 4, dtype=np.uint8) x.dtype = np.uint32 self.assertTrue(np.alltrue(ret == x)) self.chip["pulse"].set_delay(1) self.chip["pulse"].set_width(1) self.chip["pulse"].start() ret = self.chip["fifo"].get_data() x = np.arange((128 + 1023) * 4, (128 + 1023 + 1) * 4, dtype=np.uint8) x.dtype = np.uint32 self.assertEqual(ret, x) def test_single(self): self.chip["pulse"].set_delay(1) self.chip["pulse"].set_width(1) self.chip["pulse"].start() self.assertEqual(self.chip["fifo"].get_data().tolist(), [0x03020100]) self.chip["pulse"].start() self.assertEqual(self.chip["fifo"].get_data().tolist(), [0x07060504]) def test_pattern(self): self.chip["PATTERN"] = 0xAA5555AA self.chip["PATTERN"].write() self.chip["CONTROL"]["PATTERN_EN"] = 1 self.chip["CONTROL"].write() self.chip["CONTROL"]["PATTERN_EN"] = 0 self.chip["CONTROL"].write() for _ in range(5): self.chip["CONTROL"].write() self.assertEqual(self.chip["fifo"].get_data().tolist(), [0xAA5555AA] * 35) def test_direct(self): self.chip["CONTROL"]["COUNTER_DIRECT"] = 1 self.chip["CONTROL"].write() size = 648 base_data_addr = self.chip["fifo"]._conf["base_data_addr"] ret = self.chip["intf"].read(base_data_addr, size=size) ret = np.hstack((ret, self.chip["intf"].read(base_data_addr, size=size))) x = np.arange(size * 2, dtype=np.uint8) self.assertEqual(ret.tolist(), x.tolist()) def test_continouse(self): self.chip["pulse"].set_delay(35) self.chip["pulse"].set_width(3) self.chip["pulse"].set_repeat(0) self.chip["pulse"].start() i = 0 error = False for _ in range(100): ret = self.chip["fifo"].get_data() x = np.arange(i * 4, (i + ret.shape[0]) * 4, dtype=np.uint8) x.dtype = np.uint32 i += ret.shape[0] ok = np.alltrue(ret == x) # print 'OK?', ok, ret.shape[0], i, k if not ok: error = True break self.assertFalse(error) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class qmca(object): '''Sets up qMCA setup. Reads data via USB from qMCA setup and sends it via ZeroMQ to Online Monitor. 8000 Hz of waveforms with 200 samples can be read out''' def __init__(self, config='qmca.yaml', sample_count=200, sample_delay=50, threshold=2000, channel=0, adc_differential_voltage=1.9, socket_addr='tcp://127.0.0.1:5678', write_after_n_events = 100000): ''' Parameters ---------- sample_count : int Length of event in ADC samples sample_delay : int Number of ADC samples to add to event before detected peak threshold : int [0:2**14] ADC threshold channel : int [0:3] qMCA channel number outfile_name : string Filename of the raw data output file socket_addr : string Socket address of Online Monitor ''' self.event_count = 0 self.count_lost = 0 self.main_thread = None self.exit = threading.Event() self.write_after_n_events = write_after_n_events self.sample_count = sample_count self.sample_delay = sample_delay # Setup ZeroMQ socket self.socket = zmq.Context().socket(zmq.PUSH) self.socket.setsockopt(zmq.SNDHWM, 10) self.socket.setsockopt(zmq.LINGER, 500) self.socket.bind(socket_addr) # Setup Dut self.dut = Dut(config) self.dut.init() self.dut['PWR0'].set_current_limit(100, unit='mA') self.dut['PWR0'].set_voltage(1.8, unit='V') self.dut['PWR0'].set_enable(True) self.dut['PWR1'].set_current_limit(100, unit='mA') self.dut['PWR1'].set_voltage(1.8, unit='V') self.dut['PWR1'].set_enable(True) self.dut['PWR2'].set_current_limit(100, unit='mA') self.dut['PWR2'].set_voltage(1.8, unit='V') self.dut['PWR2'].set_enable(True) self.dut['PWR3'].set_current_limit(100, unit='mA') self.dut['PWR3'].set_voltage(1.8, unit='V') self.dut['PWR3'].set_enable(True) # Reset ADC and SRAM self.dut['fadc0_rx'].reset() self.dut['DATA_FIFO'].reset() self.adc_differential_voltage = adc_differential_voltage self.set_adc_differential_voltage(adc_differential_voltage) self.set_adc_eventsize(self.sample_count, self.sample_delay) self.set_threshold(threshold) self.select_channel(channel) def start(self, out_filename='event_data'): self.out_filename = out_filename + '.h5' logging.info('Starting main loop in new thread.') self.main_thread = threading.Thread(target=self._main_loop) self.main_thread.start() def stop(self): self.exit.set() if self.main_thread: self.main_thread.join(timeout=1) self.main_thread = None logging.info('Measurement stopped. Recorded %i events.' % self.event_count) else: logging.info('No measurement was running.') def reset_dut(self): self.dut['fadc0_rx'].reset() self.dut['DATA_FIFO'].reset() self.set_adc_differential_voltage(self.adc_differential_voltage) self.set_adc_eventsize(self.sample_count, self.sample_delay) self.event_count = 0 self.count_lost = 0 self.main_thread = None def set_threshold(self, threshold): self.dut['TH']['TH'] = int(threshold) self.dut['TH'].write() self.threshold = threshold def select_channel(self, channel): self.dut['TH']['SEL_ADC_CH'] = channel self.dut['TH'].write() self.channel = channel def set_adc_differential_voltage(self, value): self.adc_differential_voltage = value self.dut['VSRC3'].set_voltage(value, unit='V') def set_adc_eventsize(self, sample_count, sample_delay): self.dut['fadc0_rx'].set_delay(sample_delay) self.dut['fadc0_rx'].set_data_count(sample_count) self.dut['fadc0_rx'].set_single_data(True) self.dut['fadc0_rx'].set_en_trigger(True) self.sample_count = sample_count self.sample_delay = sample_delay def _send_data(self, data, name='qMCA'): try: data_meta_data = dict( name=name, dtype=str(data.dtype), shape=data.shape, thr = self.threshold, ch = self.channel ) self.socket.send_json(data_meta_data, flags=zmq.SNDMORE | zmq.NOBLOCK) self.socket.send(data, flags=zmq.NOBLOCK) # PyZMQ supports sending numpy arrays without copying any data except zmq.Again: pass def _record_data(self): ''' Reads raw event data from SRAM and splits data stream into events ---------- Returns: event_data : np.ndarray Numpy array of single event numpy arrays ''' self.count_lost = self.dut['fadc0_rx'].get_count_lost() # print 'count_lost is %d' % self.count_lost # print 'event_count is %d' % self.event_count if self.count_lost > 0: logging.error('SRAM FIFO overflow number %d. Skip data.', self.count_lost) self.dut['fadc0_rx'].reset() self.set_adc_eventsize(self.sample_count, self.sample_delay) #return single_data = self.dut['DATA_FIFO'].get_data() # Read raw data from SRAM try: if single_data.shape[0] > 200: selection = np.where(single_data & 0x10000000 == 0x10000000)[0] # Make mask from new-event-bit event_data = np.bitwise_and(single_data, 0x00003fff).astype(np.uint32) # Remove new-event-bit from data event_data = np.split(event_data, selection) # Split data into events by means of mask event_data = event_data[1:-1] # Remove first and last event in case of chopping event_data = np.vstack(event_data) # Stack events together else: event_data = np.asarray([np.bitwise_and(single_data, 0x00003fff).astype(np.uint32)]) if event_data.shape[1] == self.sample_count: return event_data except ValueError as e: logging.error('_record_data() experienced a ValueError: ' + str(e)) return def _main_loop(self): logging.info('Beginning measurement. Please open Online Monitor.') last_mod_value = 0 with tb.open_file(self.out_filename, 'w') as self.output_file: output_array = self.output_file.createEArray(self.output_file.root, name='event_data', atom=tb.UIntAtom(), shape=(0, self.sample_count), title='The raw events from the ADC', filters=tb.Filters(complib='blosc', complevel=5, fletcher32=False)) while not self.exit.wait(0.01): events_data = self._record_data() if np.any(events_data): self._send_data(events_data) try: output_array.append(events_data) except ValueError: print events_data, events_data.shape self.event_count += events_data.shape[0] if (self.event_count % self.write_after_n_events < last_mod_value): logging.info('Recorded %d events. Write data to disk.', self.write_after_n_events) output_array.flush() last_mod_value = self.event_count % self.write_after_n_events output_array.flush()
class TestSimMMC3Eth(unittest.TestCase): def setUp(self): sys.path = [os.path.dirname(os.getcwd())] + sys.path proj_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) cocotb_compile_and_run(sim_files=[proj_dir + '/test/mmc3_eth_tb.v'], top_level='tb', include_dirs=(proj_dir, proj_dir + '/src')) ''' with open("test_mmc3_eth.yaml") as conf_file: try: conf = yaml.load(conf_file) except yaml.YAMLError as exception: print(exception) conf['transfer_layer'][0]['type'] self.chip = Dut(conf) self.chip.init() ''' self.chip = Dut(cnfg_yaml) self.chip.init() def test(self): testduration = 10 total_len = 0 tick = 0 tick_old = 0 start_time = time.time() self.chip['GPIO_LED']['LED'] = 0x01 #start data source self.chip['GPIO_LED'].write() while time.time() - start_time < testduration: data = self.chip['FIFO'].get_data() total_len += len(data) time.sleep(0.01) tick = int(time.time() - start_time) if tick != tick_old: print tick tick_old = tick if doprint == True: print data for i in data: if i < (len(data) - 1): assert data[i] == data[ i + 1] - 1 #Check, if received integers are increasing numbers if total_len >= IntsToReceive: break total_len_bits = total_len * 32 #32-bit ints to bits print('Bits received:', total_len_bits, ' data rate:', round((total_len_bits / 1e6 / testduration), 2), ' Mbit/s') self.chip['GPIO_LED']['LED'] = 0x00 #stop data source self.chip['GPIO_LED'].write() def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
import time from basil.dut import Dut # Initialize x-ray tube devices = Dut('xray_tube_pyserial.yaml') devices.init() # Set high voltage and current devices["xray_tube"].set_voltage(10) # 40 kV devices["xray_tube"].set_current(50) # 50 mA print(devices["xray_tube"].get_actual_voltage()) # in kV print(devices["xray_tube"].get_actual_current()) # in mA devices["xray_tube"].set_high_voltage_on() # Turn on HV devices["xray_tube"].set_timer(dur=3600) # 3600 s devices["xray_tube"].activate_timer( ) # Activate the timer (clock symbol on display) devices["xray_tube"].open_shutter( ) # Starts actual irradiation (and timer, if set) time.sleep(10) # Print remaining irradiation time in seconds print(devices["xray_tube"].get_actual_time()) # Print status of HV (bit 6 of status word 0) print(devices["xray_tube"].get_status(0)[1])
class TestSimJtagGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run([ os.path.join(os.path.dirname(__file__), 'jtag_tap.v'), os.path.join(os.path.dirname(__file__), 'test_SimJtagGpio.v') ]) self.chip = Dut(cnfg_yaml) self.chip.init(init_yaml) def test_gpio(self): ID_CODE = BitLogic('0010') BYPASS = BitLogic('1111') DEBUG = BitLogic('1000') ret_ir = BitLogic('0101') # TEST REG INIT dev1ret = StdRegister(driver=None, conf=yaml.safe_load(gpio_yaml)) dev1ret.init() dev1ret['F1'] = 0x1 dev1ret['F2'] = 0x2f dev1ret['F3'] = 0x2 dev1ret['F4'] = 0x17cf4 self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) self.chip['DEV1']['F2'] = 0 self.assertFalse(dev1ret[:] == self.chip['DEV1'][:]) self.chip.set_configuration(init_yaml) self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) self.chip['JTAG'].reset() # IR CODE ret = self.chip['JTAG'].scan_ir([ID_CODE] * 2) self.assertEqual(ret, [ret_ir] * 2) # ID CODE id_code = BitLogic.from_value(0x149B51C3, fmt='I') ret = self.chip['JTAG'].scan_dr(['0' * 32] * 2) self.assertEqual(ret, [id_code] * 2) # BYPASS + ID CODE bypass_code = BitLogic('0') ret = self.chip['JTAG'].scan_ir([ID_CODE, BYPASS]) self.assertEqual(ret, [ret_ir] * 2) ret = self.chip['JTAG'].scan_dr(['0' * 32, '1']) self.assertEqual(ret, [id_code, bypass_code]) ret = self.chip['JTAG'].scan_ir([BYPASS, ID_CODE]) self.assertEqual(ret, [ret_ir] * 2) ret = self.chip['JTAG'].scan_dr(['1', '0' * 32]) self.assertEqual(ret, [bypass_code, id_code]) # DEBUG ret = self.chip['JTAG'].scan_ir([DEBUG, DEBUG]) self.assertEqual(ret, [ret_ir] * 2) self.chip['JTAG'].scan_dr(['1' * 32, '0' * 1 + '1' * 30 + '0' * 1]) ret = self.chip['JTAG'].scan_dr(['0' * 32, '1' * 32]) self.assertEqual( ret, [BitLogic('1' * 32), BitLogic('0' * 1 + '1' * 30 + '0' * 1)]) ret = self.chip['JTAG'].scan_dr(['0' * 32, '0' * 32]) self.assertEqual(ret, [BitLogic('0' * 32), BitLogic('1' * 32)]) # SHIT IN DEV REG/DEBUG self.chip['JTAG'].scan_dr([self.chip['DEV1'][:], self.chip['DEV2'][:]]) # GPIO RETURN dev1ret.frombytes(self.chip['GPIO_DEV1'].get_data()) self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) self.assertFalse(dev1ret[:] == self.chip['DEV2'][:]) dev1ret.frombytes(self.chip['GPIO_DEV2'].get_data()) self.assertEqual(dev1ret[:], self.chip['DEV2'][:]) # JTAG RETURN ret = self.chip['JTAG'].scan_dr(['0' * 32, '0' * 32]) dev1ret.set(ret[0]) self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) dev1ret.set(ret[1]) self.assertEqual(dev1ret[:], self.chip['DEV2'][:]) # REPEATING REGISTER self.chip['JTAG'].scan_dr([self.chip['DEV'][:]]) ret1 = self.chip['JTAG'].scan_dr([self.chip['DEV'][:]]) self.chip['JTAG'].scan_dr([self.chip['DEV1'][:], self.chip['DEV2'][:]]) ret2 = self.chip['JTAG'].scan_dr( [self.chip['DEV1'][:] + self.chip['DEV2'][:]]) ret3 = self.chip['JTAG'].scan_dr( [self.chip['DEV1'][:] + self.chip['DEV2'][:]]) self.assertEqual(ret1[:], ret2[:]) self.assertEqual(ret2[:], ret3[:]) # REPEATING SETTING self.chip['JTAG'].scan_dr(['1' * 32 + '0' * 32]) ret = self.chip['JTAG'].scan_dr(['0' * 32 + '0' * 32]) self.chip['DEV'].set(ret[0]) self.assertEqual(self.chip['DEV'][:], BitLogic('0' * 32 + '1' * 32)) self.chip['JTAG'].scan_dr( [self.chip['DEV1'][:] + self.chip['DEV2'][:]]) ret = self.chip['JTAG'].scan_dr( [self.chip['DEV1'][:] + self.chip['DEV2'][:]]) self.chip['DEV'].set(ret[0]) self.assertEqual(self.chip['DEV'][:], self.chip['DEV1'][:] + self.chip['DEV2'][:]) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
# # ------------------------------------------------------------ # Copyright (c) All rights reserved # SiLab, Institute of Physics, University of Bonn # ------------------------------------------------------------ # ''' This script shows how to read temperature/humidity with Sensition sensors and how to set temperature using a Binder MK 53 climate chamber. The Sensition sensors are read using the Sensirion EK-H4 multiplexer box from the evaluation kit. A serial TL has to be used (http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_EK-H4_Datasheet_V3.pdf). For the communication with the Binder MK 53 also a serial TL has to be used (http://www.binder-world.com). ''' from basil.dut import Dut # Sensirion sensor readout dut = Dut('sensirionEKH4_pyserial.yaml') dut.init() print dut['Thermohygrometer'].get_temperature() print dut['Thermohygrometer'].get_humidity() print dut['Thermohygrometer'].get_dew_point() # Binder MK 53 control dut = Dut('binderMK53_pyserial.yaml') dut.init() print dut['Climatechamber'].get_temperature() print dut['Climatechamber'].get_door_open() print dut['Climatechamber'].get_mode() temperature_target = dut['Climatechamber'].get_temperature_target() dut['Climatechamber'].set_temperature(temperature_target)
class ccpdlfB(ccpdlf): def __init__(self,conf=""): self.init_log() if conf=="": conf="ccpdlf.yaml" self.dut=Dut(conf) self.debug=0 self._build_img=np.vectorize(self._build_img_oneB) self.tdac=np.zeros([24,114],int) self.dut.init() self.set_DACcurrent() self.power() def set_DACcurrent(self,VN=0,VPLoad=0,VPFB=0,VNFoll=0,BLRes=0,VSTRETCH=0,WGT0=0,WGT1=0,WGT2=0,LSBdacL=0): self.dut['probeVN'].set_current(0,unit="uA") self.dut['probeVPLoad'].set_current(0,unit="uA") self.dut['probeVPFB'].set_current(0,unit="uA") self.dut['probeVNFoll'].set_current(0,unit="uA") self.dut['probeBLRes'].set_current(0,unit="uA") self.dut['probeIComp'].set_current(0,unit="uA") self.dut['probeVSTRETCH'].set_current(0,unit="uA") self.dut['probeWGT0'].set_current(0,unit="uA") self.dut['probeWGT1'].set_current(0,unit="uA") self.dut['probeWGT2'].set_current(0,unit="uA") self.dut['probeLSBdacL'].set_current(0,unit="uA") self.logger.info("VN:%f VPLoad:%f VPFB:%f VNFoll:%f BLRes:%f VSTRETCH:%f WGT0:%f WGT1:%f WGT2:%f LSBdacL:%f "%( VN,VPLoad,VPFB,VNFoll,BLRes,VSTRETCH,WGT0,WGT1,WGT2,LSBdacL)) def get_DACcurrent(self): stat={'probeVN': self.dut['probeVN'].get_voltage(unit="V"), 'probeVN_curr': self.dut['probeVN'].get_current(unit="uA"), 'probeVPLoad': self.dut['probeVPLoad'].get_voltage(unit="V"), 'probeVPLoad_curr': self.dut['probeVPLoad'].get_current(unit="mA"), 'probeVPFB': self.dut['probeVPFB'].get_voltage(unit="V"), 'probeVNFoll': self.dut['probeVNFoll'].get_voltage(unit="V"), 'probeVNFoll_curr': self.dut['probeVNFoll'].get_current(unit="mA"), 'probeBLRes': self.dut['probeBLRes'].get_voltage(unit="V"), 'probeBLRes_curr': self.dut['probeBLRes'].get_current(unit="mA"), 'probeIComp': self.dut['probeIComp'].get_voltage(unit="V"), 'probeIComp_curr': self.dut['probeIComp'].get_current(unit="mA"), 'probeVSTRETCH': self.dut['probeVSTRETCH'].get_voltage(unit="V"), 'probeVSTRETCH_curr': self.dut['probeVSTRETCH'].get_current(unit="mA"), 'probeWGT0': self.dut['probeWGT0'].get_voltage(unit="V"), 'probeWGT0_curr': self.dut['probeWGT0'].get_current(unit="mA"), 'probeWGT1': self.dut['probeWGT1'].get_voltage(unit="V"), 'probeWGT1_curr': self.dut['probeWGT1'].get_current(unit="mA"), 'probeWGT2': self.dut['probeWGT2'].get_voltage(unit="V"), 'probeWGT2_curr': self.dut['probeWGT2'].get_current(unit="mA"), 'probeLSBdacL': self.dut['probeLSBdacL'].get_voltage(unit="V"), 'probeLSBdacL_curr': self.dut['probeLSBdacL'].get_current(unit="mA")} return stat def _cal_Pixels(self,pix): if isinstance(pix,str): if pix=="all": en_pix=bitarray.bitarray('1'*2736) else: en_pix=bitarray.bitarray('0'*2736) elif isinstance(pix,int): if pix==0: en_pix=bitarray.bitarray('0'*2736) else: en_pix=bitarray.bitarray('1'*2736) elif isinstance(pix,type(bitarray.bitarray())): en_pix=bitarray.bitarray('0'*2736) for i in range(0,24,4): a0=pix[114*(i):114*(i+1)].copy() a1=pix[114*(i+1):114*(i+2)].copy() a2=pix[114*(i+2):114*(i+3)].copy() a3=pix[114*(i+3):114*(i+4)].copy() a0.reverse() a3.reverse() en_pix[114*(i):114*(i+4)]=a1+a0+a2+a3 else: en_pix=bitarray.bitarray('0'*2736) if isinstance(pix[0],int): pix=[pix] for p in pix: r=p[0]%4 if r==0: en_pix[(p[0]+2)*114-p[1]-1]=1 elif r==1: en_pix[(p[0]-1)*114+p[1]]=1 elif r==2: en_pix[p[0]*114+p[1]]=1 elif r==3: en_pix[(p[0]+1)*114-p[1]-1]=1 return en_pix def _build_img_oneB(self,spix): frame=spix/2736 spix=2735-spix%2736 col=spix/114 row=spix%114 if col%4==0: col=col+1 elif col%4==1: col=col-1 row=113-row elif col%4==2: pass elif col%4==3: row=113-row return frame,col,row
class TestSimJtagGpio(unittest.TestCase): def setUp(self): cocotb_compile_and_run([ os.path.join(os.path.dirname(__file__), 'jtag_tap.v'), os.path.join(os.path.dirname(__file__), 'test_SimJtagGpio.v')] ) self.chip = Dut(cnfg_yaml) self.chip.init(init_yaml) def test_gpio(self): ID_CODE = BitLogic('0010') BYPASS = BitLogic('1111') DEBUG = BitLogic('1000') ret_ir = BitLogic('0101') # TEST REG INIT dev1ret = StdRegister(driver=None, conf=yaml.load(gpio_yaml)) dev1ret.init() dev1ret['F1'] = 0x1 dev1ret['F2'] = 0x2f dev1ret['F3'] = 0x2 dev1ret['F4'] = 0x17cf4 self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) self.chip['DEV1']['F2'] = 0 self.assertFalse(dev1ret[:] == self.chip['DEV1'][:]) self.chip.set_configuration(init_yaml) self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) self.chip['jtag'].reset() # IR CODE ret = self.chip['jtag'].scan_ir([ID_CODE] * 2) self.assertEqual(ret, [ret_ir] * 2) # ID CODE id_code = BitLogic.from_value(0x149B51C3, fmt='I') ret = self.chip['jtag'].scan_dr(['0' * 32] * 2) self.assertEqual(ret, [id_code] * 2) # BYPASS + ID CODE bypass_code = BitLogic('0') ret = self.chip['jtag'].scan_ir([ID_CODE, BYPASS]) self.assertEqual(ret, [ret_ir] * 2) ret = self.chip['jtag'].scan_dr(['0' * 32, '1']) self.assertEqual(ret, [id_code, bypass_code]) ret = self.chip['jtag'].scan_ir([BYPASS, ID_CODE]) self.assertEqual(ret, [ret_ir] * 2) ret = self.chip['jtag'].scan_dr(['1', '0' * 32]) self.assertEqual(ret, [bypass_code, id_code]) # DEBUG ret = self.chip['jtag'].scan_ir([DEBUG, DEBUG]) self.assertEqual(ret, [ret_ir] * 2) self.chip['jtag'].scan_dr(['1' * 32, '0' * 1 + '1' * 30 + '0' * 1]) ret = self.chip['jtag'].scan_dr(['0' * 32, '1' * 32]) self.assertEqual(ret, [BitLogic('1' * 32), BitLogic('0' * 1 + '1' * 30 + '0' * 1)]) ret = self.chip['jtag'].scan_dr(['0' * 32, '0' * 32]) self.assertEqual(ret, [BitLogic('0' * 32), BitLogic('1' * 32)]) # SHIT IN DEV REG/DEBUG self.chip['jtag'].scan_dr([self.chip['DEV1'][:], self.chip['DEV2'][:]]) # GPIO RETURN dev1ret.frombytes(self.chip['gpio_dev1'].get_data()) self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) self.assertFalse(dev1ret[:] == self.chip['DEV2'][:]) dev1ret.frombytes(self.chip['gpio_dev2'].get_data()) self.assertEqual(dev1ret[:], self.chip['DEV2'][:]) # JTAG RETURN ret = self.chip['jtag'].scan_dr(['0' * 32, '0' * 32]) dev1ret.set(ret[0]) self.assertEqual(dev1ret[:], self.chip['DEV1'][:]) dev1ret.set(ret[1]) self.assertEqual(dev1ret[:], self.chip['DEV2'][:]) # REPEATING REGISTER self.chip['jtag'].scan_dr([self.chip['DEV'][:]]) ret1 = self.chip['jtag'].scan_dr([self.chip['DEV'][:]]) self.chip['jtag'].scan_dr([self.chip['DEV1'][:], self.chip['DEV2'][:]]) ret2 = self.chip['jtag'].scan_dr([self.chip['DEV1'][:] + self.chip['DEV2'][:]]) ret3 = self.chip['jtag'].scan_dr([self.chip['DEV1'][:] + self.chip['DEV2'][:]]) self.assertEqual(ret1[:], ret2[:]) self.assertEqual(ret2[:], ret3[:]) # REPEATING SETTING self.chip['jtag'].scan_dr(['1' * 32 + '0' * 32]) ret = self.chip['jtag'].scan_dr(['0' * 32 + '0' * 32]) self.chip['DEV'].set(ret[0]) self.assertEqual(self.chip['DEV'][:], BitLogic('0' * 32 + '1' * 32)) self.chip['jtag'].scan_dr([self.chip['DEV1'][:] + self.chip['DEV2'][:]]) ret = self.chip['jtag'].scan_dr([self.chip['DEV1'][:] + self.chip['DEV2'][:]]) self.chip['DEV'].set(ret[0]) self.assertEqual(self.chip['DEV'][:], self.chip['DEV1'][:] + self.chip['DEV2'][:]) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class ccpdlf(): def __init__(self,conf=""): if conf=="": conf="ccpdlfA.yaml" self.dut=Dut(conf) self.init_log() self.debug=0 self._build_img=np.vectorize(self._build_img_one) self.tdac=np.zeros([24,114],int) self.dut.init() self.set_DACcurrent() self.power() def init_log(self,logfile='ccpdlf.log'): self.logfile=logfile self.logger=logging.getLogger() self.logger.setLevel(logging.DEBUG) fh=logging.FileHandler(logfile) ch=logging.StreamHandler() fh.setLevel(logging.INFO) ch.setLevel(logging.DEBUG) formatter=logging.Formatter('%(asctime)s %(funcName)s %(message)s') fh.setFormatter(formatter) formatterc=logging.Formatter('%(message)s') ch.setFormatter(formatterc) self.logger.addHandler(ch) self.logger.addHandler(fh) def _build_img_one(self,spix): frame=spix/2736 spix=2735-spix%2736 col=spix/114 row=spix%114 if col%4==0: pass elif col%4==1: row=113-row elif col%4==2: col=col+1 elif col%4==3: col=col-1 row=113-row return frame,col,row def archive(self): with open('archive_%s'%self.logfile, 'a') as fo: try: with open(self.logfile) as f: for line in f: fo.write(line) with open(self.logfile,"w") as f: f.write("") except: pass def power(self,pwr_en=True,Vdda=1.8,Vddp=1.5,Vddd=1.8,VCasc=1.0,BL=0.75,TH=0.80,PCBTH=1.3): self.dut['CCPD_Vdda'].set_current_limit(250,unit="raw") self.dut['CCPD_Vdda'].set_voltage(Vdda, unit='V') self.dut['CCPD_Vdda'].set_enable(pwr_en) self.dut['CCPD_vddaPRE'].set_voltage(Vddp, unit='V') self.dut['CCPD_vddaPRE'].set_enable(pwr_en) self.dut['CCPD_vddd'].set_voltage(Vddd, unit='V') self.dut['CCPD_vddd'].set_enable(pwr_en) self.dut['CCPD_VCasc'].set_voltage(VCasc, unit='V') self.dut['CCPD_PCBTH'].set_voltage(PCBTH, unit='V') self.dut['CCPD_BL'].set_voltage(BL, unit='V') self.dut['CCPD_TH'].set_voltage(TH, unit='V') self.logger.info("Vdda:%f Vddp:%f Vddd:%f VCasc:%f BL:%f TH:%f PCBTH:%f"%( Vdda,Vddp,Vddd,VCasc,BL,TH,PCBTH)) def set_DACcurrent(self,VN=0,VPLoad=0,VPFB=0,VNFoll=0,BLRes=0,IComp=0,PBIAS=0,WGT0=0,WGT1=0,WGT2=0,LSBdacL=0): self.dut['probeVN'].set_current(VN,unit="uA") self.dut['probeVPLoad'].set_current(VPLoad,unit="uA") self.dut['probeVPFB'].set_current(VPFB,unit="uA") self.dut['probeVNFoll'].set_current(VNFoll,unit="uA") self.dut['probeBLRes'].set_current(BLRes,unit="uA") self.dut['probeIComp'].set_current(IComp,unit="uA") self.dut['probePBIAS'].set_current(PBIAS,unit="uA") self.dut['probeWGT0'].set_current(WGT0,unit="uA") self.dut['probeWGT1'].set_current(WGT1,unit="uA") self.dut['probeWGT2'].set_current(WGT2,unit="uA") self.dut['probeLSBdacL'].set_current(LSBdacL,unit="uA") self.logger.info("VN:%f VPLoad:%f VPFB:%f VNFoll:%f BLRes:%f IComp:%f PBIAS:%f WGT0:%f WGT1:%f WGT2:%f LSBdacL:%f "%( VN,VPLoad,VPFB,VNFoll,BLRes,IComp,PBIAS,WGT0,WGT1,WGT2,LSBdacL)) def set_pulser(self,inj_high=4.0,inj_low=0.0,period=100,repeat=1,delay=700,ext=True): self.dut["CCPD_Injection_high"].set_voltage(inj_high,unit="V") self.dut["CCPD_Injection_low"].set_voltage(inj_low,unit="V") self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_INJ"]["REPEAT"]=repeat self.dut["CCPD_PULSE_INJ"]["DELAY"]=period/2 self.dut["CCPD_PULSE_INJ"]["WIDTH"]=period-period/2 self.dut["CCPD_PULSE_INJ"]["EN"]=1 self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"]=1 self.dut["CCPD_PULSE_GATE"]["DELAY"]=delay self.dut["CCPD_PULSE_GATE"]["WIDTH"]=period*repeat+10 self.dut["CCPD_PULSE_GATE"]["EN"]=ext self.logger.info("inj:%.4f,%.4f period:%d repeat:%d delay:%d ext:%d"%( inj_high,inj_low,period,repeat,delay,int(ext))) def inject(self): self.dut["CCPD_PULSE_INJ"].start() def set_th(self,TH): self.dut['CCPD_TH'].set_voltage(TH, unit='V') THvol=self.dut['CCPD_TH'].get_voltage(unit='V') self.logger.info("th_set:%f th:%f"%(TH,THvol)) def get_status(self): stat={"Vdda": self.dut['CCPD_Vdda'].get_voltage(unit='V'), "Vdda_curr": self.dut['CCPD_Vdda'].get_current(unit="mA"), "Vddp": self.dut['CCPD_vddaPRE'].get_voltage(unit='V'), "Vddp_curr": self.dut['CCPD_vddaPRE'].get_current(unit="mA"), "Vddd": self.dut['CCPD_vddd'].get_voltage(unit='V'), "Vddd_curr": self.dut['CCPD_vddd'].get_current(unit="mA"), "VCasc": self.dut['CCPD_VCasc'].get_voltage(unit='V'), "VCasc_curr": self.dut['CCPD_VCasc'].get_current(unit="mA"), "PCBTH": self.dut['CCPD_PCBTH'].get_voltage(unit='V'), 'PCBTH_curr': self.dut['CCPD_PCBTH'].get_current(unit="mA"), 'BL': self.dut['CCPD_BL'].get_voltage(unit='V'), 'BL_curr': self.dut['CCPD_BL'].get_current(unit="mA"), 'TH': self.dut['CCPD_TH'].get_voltage(unit='V'), 'TH_curr': self.dut['CCPD_TH'].get_current(unit="mA"), ##### TODO make data from get_data 'BLRes':self.dut['CCPD_SR']['BLRes'].tovalue(), 'VN':self.dut['CCPD_SR']['VN'].tovalue(), 'VPFB':self.dut['CCPD_SR']['VPFB'].tovalue(), 'VPFoll':self.dut['CCPD_SR']['VPFoll'].tovalue(), 'VPLoad':self.dut['CCPD_SR']['VPLoad'].tovalue(), 'LSBdacL':self.dut['CCPD_SR']['LSBdacL'].tovalue(), 'IComp':self.dut['CCPD_SR']['IComp'].tovalue(), 'VSTRETCH':self.dut['CCPD_SR']['VSTRETCH'].tovalue(), 'WGT0':self.dut['CCPD_SR']['WGT0'].tovalue(), 'WGT1':self.dut['CCPD_SR']['WGT1'].tovalue(), 'WGT2':self.dut['CCPD_SR']['WGT2'].tovalue(), 'IDacTEST':self.dut['CCPD_SR']['IDacTEST'].tovalue(), 'IDacLTEST':self.dut['CCPD_SR']['IDacLTEST'].tovalue(), "SW_ANA":self.dut["CCPD_SR"]["SW_ANA"].tovalue(), "Pixels":" ".join(hex(ord(n)) for n in self.dut["CCPD_SR"]["Pixels"].tobytes()), 'CCPD_SW':self.dut["CCPD_SW"].get_data()[0], 'rx_SW':self.dut["rx"].get_data()[0], 'INJ_DELAY':self.dut["CCPD_PULSE_INJ"]["DELAY"], 'INJ_WIDTH':self.dut["CCPD_PULSE_INJ"]["WIDTH"], 'INJ_REPEAT':self.dut["CCPD_PULSE_INJ"]["REPEAT"], 'INJ_EN':self.dut["CCPD_PULSE_INJ"]["EN"], 'GATE_DELAY':self.dut["CCPD_PULSE_GATE"]["DELAY"], 'GATE_WIDTH':self.dut["CCPD_PULSE_GATE"]["WIDTH"], 'GATE_REPEAT':self.dut["CCPD_PULSE_GATE"]["REPEAT"], 'GATE_EN':self.dut["CCPD_PULSE_GATE"]["EN"] } stat.update(self.get_DACcurrent()) return stat def show(self): r= self.get_status() self.logger.info('BLRes:%d VN:%d VPFB:%d VPFoll:%d VPLoad:%d LSBdacL:%d IComp:%d VSTRETCH:%d WGT0:%d WGT1:%d WGT2:%d IDacTEST:%d IDacLTEST:%d'%( r["BLRes"],r["VN"],r["VPFB"],r["VPFoll"],r["VPLoad"],r["LSBdacL"],r["IComp"], r["VSTRETCH"],r["WGT0"],r["WGT1"],r["WGT2"],r["IDacTEST"],r["IDacLTEST"])) self.logger.info("INJ width:%d delay:%d repeat:%d en:%d"%( r["INJ_WIDTH"],r["INJ_DELAY"],r["INJ_REPEAT"],r["INJ_EN"])) self.logger.info("GATE width:%d delay:%d repeat:%d en:%d"%( r["GATE_WIDTH"],r["GATE_DELAY"],r["GATE_REPEAT"],r["GATE_EN"])) def get_DACcurrent(self): stat={'probeVN': self.dut['probeVN'].get_voltage(unit="V"), 'probeVN_curr': self.dut['probeVN'].get_current(unit="uA"), 'probeVPLoad': self.dut['probeVPLoad'].get_voltage(unit="V"), 'probeVPLoad_curr': self.dut['probeVPLoad'].get_current(unit="mA"), 'probeVPFB': self.dut['probeVPFB'].get_voltage(unit="V"), 'probeVNFoll': self.dut['probeVNFoll'].get_voltage(unit="V"), 'probeVNFoll_curr': self.dut['probeVNFoll'].get_current(unit="mA"), 'probeBLRes': self.dut['probeBLRes'].get_voltage(unit="V"), 'probeBLRes_curr': self.dut['probeBLRes'].get_current(unit="mA"), 'probeIComp': self.dut['probeIComp'].get_voltage(unit="V"), 'probeIComp_curr': self.dut['probeIComp'].get_current(unit="mA"), 'probePBIAS': self.dut['probePBIAS'].get_voltage(unit="V"), 'probePBIAS_curr': self.dut['probePBIAS'].get_current(unit="mA"), 'probeWGT0': self.dut['probeWGT0'].get_voltage(unit="V"), 'probeWGT0_curr': self.dut['probeWGT0'].get_current(unit="mA"), 'probeWGT1': self.dut['probeWGT1'].get_voltage(unit="V"), 'probeWGT1_curr': self.dut['probeWGT1'].get_current(unit="mA"), 'probeWGT2': self.dut['probeWGT2'].get_voltage(unit="V"), 'probeWGT2_curr': self.dut['probeWGT2'].get_current(unit="mA"), 'probeLSBdacL': self.dut['probeLSBdacL'].get_voltage(unit="V"), 'probeLSBdacL_curr': self.dut['probeLSBdacL'].get_current(unit="mA")} return stat def _write_SR(self,sw="SW_LDDAC"): if sw=="SW_LDDAC": self.dut['CCPD_SW']['SW_LDPIX']=0 self.dut['CCPD_SW']['SW_LDDAC']=1 self.dut['CCPD_SW']['SW_HIT']=0 elif sw=="SW_LDPIX": self.dut['CCPD_SW']['SW_LDPIX']=1 self.dut['CCPD_SW']['SW_LDDAC']=0 self.dut['CCPD_SW']['SW_HIT']=0 elif sw=="SW_HIT": self.dut['CCPD_SW']['SW_LDPIX']=0 self.dut['CCPD_SW']['SW_LDDAC']=0 self.dut['CCPD_SW']['SW_HIT']=1 else: self.dut['CCPD_SW']['SW_LDPIX']=0 self.dut['CCPD_SW']['SW_LDDAC']=0 self.dut['CCPD_SW']['SW_HIT']=0 self.dut['CCPD_SW'].write() self.dut['CCPD_SR'].set_size(2843) self.dut['CCPD_SR'].set_repeat(1) self.dut['CCPD_SR'].set_wait(0) self.dut['CCPD_SR'].write() self.dut['CCPD_SR'].start() i=0 while i<10000: if self.dut['CCPD_SR'].is_done(): break elif i> 100: time.sleep(0.001) # avoid CPU 100% i=i+1 if i==10000: self.logger.info("ERROR timeout") def set_global(self,BLRes=17,VN=32,VPFB=28,VPFoll=17,VPLoad=14,LSBdacL=12,IComp=17, VSTRETCH=15,WGT0=10,WGT1=35,WGT2=63,IDacTEST=0,IDacLTEST=0): self.dut['CCPD_SR']['BLRes']=BLRes self.dut['CCPD_SR']['VN']=VN self.dut['CCPD_SR']['VPFB']=VPFB self.dut['CCPD_SR']['VPFoll']=VPFoll self.dut['CCPD_SR']['VPLoad']=VPLoad self.dut['CCPD_SR']['LSBdacL']=LSBdacL self.dut['CCPD_SR']['IComp']=IComp self.dut['CCPD_SR']['VSTRETCH']=VSTRETCH self.dut['CCPD_SR']['WGT0']=WGT0 self.dut['CCPD_SR']['WGT1']=WGT1 self.dut['CCPD_SR']['WGT2']=WGT2 self.dut['CCPD_SR']['IDacTEST']=IDacTEST self.dut['CCPD_SR']['IDacLTEST']=IDacLTEST self._write_SR() self.logger.info('BLRes:%d VN:%d VPFB:%d VPFoll:%d VPLoad:%d LSBdacL:%d IComp:%d VSTRETCH:%d WGT0:%d WGT1:%d WGT2:%d IDacTEST:%d IDacLTEST:%d'%( BLRes,VN,VPFB,VPFoll,VPLoad,LSBdacL,IComp,VSTRETCH,WGT0,WGT1,WGT2,IDacTEST,IDacLTEST)) def _cal_Pixels(self,pix): if isinstance(pix,str): if pix=="all": en_pix=bitarray.bitarray('1'*2736) else: en_pix=bitarray.bitarray('0'*2736) elif isinstance(pix,int): if pix==0: en_pix=bitarray.bitarray('0'*2736) else: en_pix=bitarray.bitarray('1'*2736) elif isinstance(pix,type(bitarray.bitarray())): en_pix=bitarray.bitarray('0'*2736) for i in range(0,24,4): a0=pix[114*(i):114*(i+1)].copy() a1=pix[114*(i+1):114*(i+2)].copy() a2=pix[114*(i+2):114*(i+3)].copy() a3=pix[114*(i+3):114*(i+4)].copy() a1.reverse() a2.reverse() en_pix[114*(i):114*(i+4)]=a0+a1+a3+a2 else: en_pix=bitarray.bitarray('0'*2736) if isinstance(pix[0],int): pix=[pix] for p in pix: r=p[0]%4 if r==0: en_pix[p[0]*114+p[1]]=1 elif r==1: en_pix[(p[0]+1)*114-p[1]-1]=1 elif r==2: en_pix[(p[0]+2)*114-p[1]-1]=1 elif r==3: en_pix[(p[0]-1)*114+p[1]]=1 return en_pix def set_mon_en(self,pix="none"): # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut['CCPD_SR']['TRIM_EN']=0 self.dut['CCPD_SR']['INJECT_EN']=0 self.dut['CCPD_SR']['MONITOR_EN']=1 self.dut['CCPD_SR']['PREAMP_EN']=0 en_pix=self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels']=en_pix for i in range(0,2736,114): self.dut['CCPD_SR']['SW_ANA'][i/114]=en_pix[i:i+114].any() self._write_SR(sw="SW_LDPIX") self.preamp_en=self.dut["CCPD_SR"]["Pixels"].copy() self.sw_ana=self.dut['CCPD_SR']['SW_ANA'].copy() s="pix:%s lds:%d,%d,%d,%d sw_ana:0x%x "%(pix, self.dut['CCPD_SR']['TRIM_EN'].tovalue(),self.dut['CCPD_SR']['INJECT_EN'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN'].tovalue(),self.dut['CCPD_SR']['PREAMP_EN'].tovalue(), self.dut['CCPD_SR']['SW_ANA'].tovalue()) if self.debug==1: s="%s pixel_all:%s"%(s,self.dut["CCPD_SR"]["Pixels"].to01()) else: s="%s pixel_any:%d"%(s,self.dut["CCPD_SR"]["Pixels"].any()) self.logger.info(s) def set_preamp_en(self,pix="all"): # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut['CCPD_SR']['TRIM_EN']=0 self.dut['CCPD_SR']['INJECT_EN']=0 self.dut['CCPD_SR']['MONITOR_EN']=0 self.dut['CCPD_SR']['PREAMP_EN']=1 en_pix=self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels']=en_pix self._write_SR(sw="SW_LDPIX") self.preamp_en=self.dut["CCPD_SR"]["Pixels"].copy() s="pix:%s lds:%d,%d,%d,%d sw_ana:0x%x"%(pix, self.dut['CCPD_SR']['TRIM_EN'].tovalue(),self.dut['CCPD_SR']['INJECT_EN'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN'].tovalue(),self.dut['CCPD_SR']['PREAMP_EN'].tovalue(), self.dut['CCPD_SR']['SW_ANA'].tovalue()) if self.debug==1: s="%s pixel_all:%s"%(s,self.dut["CCPD_SR"]["Pixels"].to01()) else: s="%s pixel_any:%d"%(s,self.dut["CCPD_SR"]["Pixels"].any()) self.logger.info(s) def set_inj_en(self,pix="all"): # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut['CCPD_SR']['TRIM_EN']=0 self.dut['CCPD_SR']['INJECT_EN']=1 self.dut['CCPD_SR']['MONITOR_EN']=0 self.dut['CCPD_SR']['PREAMP_EN']=0 en_pix=self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels']=en_pix.copy() self._write_SR(sw="SW_LDPIX") self.inj_en=self.dut["CCPD_SR"]["Pixels"].copy() s="pix:%s lds:%d,%d,%d,%d sw_ana:0x%x"%(pix, self.dut['CCPD_SR']['TRIM_EN'].tovalue(),self.dut['CCPD_SR']['INJECT_EN'].tovalue(), self.dut['CCPD_SR']['MONITOR_EN'].tovalue(),self.dut['CCPD_SR']['PREAMP_EN'].tovalue(), self.dut['CCPD_SR']['SW_ANA'].tovalue()) if self.debug==1: s="%s pixel_all:%s"%(s,self.dut["CCPD_SR"]["Pixels"].to01()) else: s="%s pixel_any:%d"%(s,self.dut["CCPD_SR"]["Pixels"].any()) self.logger.info(s) def set_tdac(self,tdac): # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut['CCPD_SR']['INJECT_EN']=0 self.dut['CCPD_SR']['MONITOR_EN']=0 self.dut['CCPD_SR']['PREAMP_EN']=0 for i_trim in [1,2,4,8]: if isinstance(tdac, int): if (tdac & i_trim)==0: pix=0 else: pix=1 self.tdac=np.ones([24,114],int)*tdac else: ## define tdac=np.zeros([24,114]) pix=bitarray.bitarray(((np.reshape(tdac, 114*24) & i_trim) !=0).tolist()) self.tdac=np.copy(tdac) en_pix=self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels']=en_pix self.dut['CCPD_SR']['TRIM_EN']=i_trim self._write_SR(sw="SW_LDPIX") if self.debug==1: s="tdac:%s"%(str(tdac)) else: s="tdac %d-%d:%d"%(0,0,self.tdac[0,0]) self.logger.info(s) def sel_pix(self,pix=[14,14],inj_en=1,mon_en=1,preamp_en=1,trim_en=0): # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) self.dut['CCPD_SR']['TRIM_EN']=0 self.dut['CCPD_SR']['INJECT_EN']=inj_en self.dut['CCPD_SR']['MONITOR_EN']=mon_en self.dut['CCPD_SR']['PREAMP_EN']=preamp_en en_pix=self._cal_Pixels(pix) self.dut['CCPD_SR']['Pixels']=en_pix if mon_en==1: for i in range(0,2736,114): self.dut['CCPD_SR']['SW_ANA'][i/114]=en_pix[i:i+114].any() self._write_SR(sw="SW_LDPIX") s="pix:%s inj_en:%d mon_en:%d preamp_en:%d"%(str(pix),inj_en,mon_en,preamp_en) self.logger.info(s) def set_hit(self,exp=5100,repeat=100,delay=700,inj_width=50,gate_width=-1): # set gpio self.dut['rx']['FE'] = 0 self.dut['rx']['TLU'] = 0 self.dut['rx']['CCPD_TDC'] = 0 self.dut['rx']['CCPD_RX'] = 1 self.dut['rx'].write() # reset spi self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["EN"]=0 ##disable gate first self.dut["CCPD_SR"].reset() self.dut["CCPD_SR"]=bitarray.bitarray('1'*2843) self._write_SR(sw="NONE") self.dut["CCPD_SR"].set_size(2736) self.dut["CCPD_SR"].set_repeat(repeat) self.dut["CCPD_SR"].set_wait(exp) ## set LD switches self.dut['CCPD_SW']['SW_LDPIX']=0 self.dut['CCPD_SW']['SW_LDDAC']=0 self.dut['CCPD_SW']['SW_HIT']=1 self.dut['CCPD_SW'].write() # set pulser self.dut["CCPD_Injection_high"].set_voltage(4,unit="V") self.dut["CCPD_Injection_low"].set_voltage(0,unit="V") self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_INJ"]["REPEAT"]=1 self.dut["CCPD_PULSE_INJ"]["DELAY"]=inj_width self.dut["CCPD_PULSE_INJ"]["WIDTH"]=inj_width self.dut["CCPD_PULSE_INJ"]["EN"]=1 self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"]=1 self.dut["CCPD_PULSE_GATE"]["DELAY"]=delay if gate_width==-1: gate_width=inj_width*2+250 self.dut["CCPD_PULSE_GATE"]["WIDTH"]=gate_width self.dut["CCPD_PULSE_GATE"]["EN"]=1 # set TDC self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['ENABLE_EXTERN']=False self.dut['CCPD_TDC']['ENABLE']=False # reset fifo self.dut['sram'].reset() # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(True) s="exp:%d repeat:%d delay:%d inj_width:%d gate_width:%d"%( exp,repeat,delay,inj_width,gate_width) self.logger.info(s) def set_tdc(self,gate_width=-1,repeat=100,inj_width=50,delay=10,inj_high=4): # set gpio self.dut['rx']['FE'] = 0 self.dut['rx']['TLU'] = 0 self.dut['rx']['CCPD_TDC'] = 1 self.dut['rx']['CCPD_RX'] = 0 self.dut['rx'].write() self.dut['CCPD_SW']['SW_LDPIX']=0 self.dut['CCPD_SW']['SW_LDDAC']=0 self.dut['CCPD_SW']['SW_HIT']=0 self.dut['CCPD_SW'].write() # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(False) # set pulser self.dut["CCPD_Injection_high"].set_voltage(inj_high,unit="V") self.dut["CCPD_Injection_low"].set_voltage(0,unit="V") self.dut["CCPD_PULSE_INJ"].reset() if inj_width==0: self.dut["CCPD_PULSE_INJ"]["EN"]=0 else: self.dut["CCPD_PULSE_INJ"]["REPEAT"]=repeat self.dut["CCPD_PULSE_INJ"]["DELAY"]=inj_width self.dut["CCPD_PULSE_INJ"]["WIDTH"]=inj_width self.dut["CCPD_PULSE_INJ"]["EN"]=1 if gate_width==-1: gate_width=inj_width*2*repeat+10 self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["REPEAT"]=1 self.dut["CCPD_PULSE_GATE"]["DELAY"]=delay self.dut["CCPD_PULSE_GATE"]["WIDTH"]=gate_width self.dut["CCPD_PULSE_GATE"]["EN"]=0 # reset TDC self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['EN_INVERT_TDC']=True self.dut['CCPD_TDC']['ENABLE_EXTERN']=True self.dut['CCPD_TDC']['ENABLE']=False # reset fifo self.dut['sram'].reset() s="gate_width:%d repeat:%d inj_width:%d delay:%d"%( gate_width,repeat,inj_width,delay) self.logger.info(s) def get_hit(self): self.dut['sram'].reset() self.dut["CCPD_SR"].start() wait=self.dut["CCPD_SR"].get_wait() repeat=self.dut["CCPD_SR"].get_repeat() i=0 while not self.dut['CCPD_SR'].is_done(): if i>10000+wait*repeat/1000: self.logger.info("ERROR timeout") break elif i> 100: time.sleep(0.001) # avoid CPU 100% i=i+1 return self.dut['sram'].get_data() def set_hit2(self,inj_width=50,inj_high=4): # set gpio self.dut['rx']['FE'] = 0 self.dut['rx']['TLU'] = 0 self.dut['rx']['CCPD_TDC'] = 0 self.dut['rx']['CCPD_RX'] = 1 self.dut['rx'].write() # disable gate self.dut["CCPD_PULSE_GATE"].reset() self.dut["CCPD_PULSE_GATE"]["EN"]=0 ##disable gate # reset spi self.dut["CCPD_SR"].reset() self.dut["CCPD_SR"]=bitarray.bitarray('1'*2843) self._write_SR(sw="NONE") self.dut["CCPD_SR"].set_size(2736) self.dut["CCPD_SR"].set_repeat(1) self.dut["CCPD_SR"].set_wait(0) ## set LD switches self.dut['CCPD_SW']['SW_LDPIX']=0 self.dut['CCPD_SW']['SW_LDDAC']=0 self.dut['CCPD_SW']['SW_HIT']=0 self.dut['CCPD_SW'].write() # set pulser self.dut["CCPD_Injection_high"].set_voltage(inj_high,unit="V") self.dut["CCPD_Injection_low"].set_voltage(0,unit="V") self.dut["CCPD_PULSE_INJ"].reset() self.dut["CCPD_PULSE_INJ"]["REPEAT"]=1 self.dut["CCPD_PULSE_INJ"]["DELAY"]=inj_width self.dut["CCPD_PULSE_INJ"]["WIDTH"]=inj_width self.dut["CCPD_PULSE_INJ"]["EN"]=0 # disable TDC self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['ENABLE_EXTERN']=False self.dut['CCPD_TDC']['ENABLE']=False # reset fifo self.dut['sram'].reset() # reset rx self.dut['CCPD_SPI_RX'].reset() self.dut['CCPD_SPI_RX'].set_en(True) s="inj_high:%f inj_width:%d"%( inj_high,inj_width) self.logger.info(s) def get_hit2(self,th,th0): self.dut['sram'].reset() self.set_th(th0) ## open gate self.dut["CCPD_SW"]["TEST_HIT"]=1 self.dut["CCPD_SW"].write() self.set_th(th) ## inject self.dut["CCPD_PULSE_INJ"].start() i=0 while not self.dut['CCPD_SR'].is_done(): if i>1000: self.logger.info("ERROR ccpd_pulse_inj timeout") break i=i+1 ## close gate self.dut["CCPD_SW"]["TEST_HIT"]=0 self.dut["CCPD_SW"].write() self.set_th(th0) ## readout self.dut["CCPD_SR"].start() i=0 while not self.dut['CCPD_SR'].is_done(): if i>10000: self.logger.info("ERROR timeout") break elif i> 100: time.sleep(0.001) # avoid CPU 100% i=i+1 return self.dut['sram'].get_data() def get_tdc(self): self.dut['sram'].reset() self.dut["CCPD_PULSE_GATE"].start() i=0 while i<10000: if self.dut['CCPD_PULSE_GATE'].is_done(): break elif i> 100: time.sleep(0.001) # avoid CPU 100% i=i+1 if i==10000: self.logger.info("ERROR timeout") return self.dut['sram'].get_data() def scan_th(self,b=1.1,e=0.7,s=-0.01,n=100,exp=5100,pix=[14,14]): self.set_hit(repeat=n,exp=exp) self.dut['CCPD_TH'].set_voltage(b, unit='V') for th in np.arange(b+s,e+s,s): d=self.get_hit() th_meas=self.dut['CCPD_TH'].get_voltage(unit='V') self.dut['CCPD_TH'].set_voltage(th, unit='V') p=self.analyse_hit(d) if len(p)==0: cnt=0 else: p=p[np.bitwise_and(p[:,1]==14,p[:,2]==14)] cnt=len(p[p[:,0]!=0]) self.logger.info("%f,%s"%(th_meas,cnt)) def scan_th_tdc(self,b=1.1,e=0.7,s=-0.01,n=1,exp=100000,inj_width=0): self.set_tdc(repeat=n,gate_width=exp,inj_width=inj_width) self.dut['CCPD_TH'].set_voltage(b, unit='V') self.logger.info("th cnt ave std") for th in np.arange(b+s,e+s,s): d=self.get_tdc() th_meas=self.dut['CCPD_TH'].get_voltage(unit='V') self.dut['CCPD_TH'].set_voltage(th, unit='V') width,delay=self.analyse_tdc(d) cnt=len(width) ave=np.average(width) std=np.std(width) self.logger.info("%f %d %f %f"%(th_meas,cnt,ave,std)) def find_th(self,start=1.5,stop=0.5,step=-0.05,exp=100000,full_scurve=False): self.set_tdc(repeat=1,exp=exp,inj_width=0) #self.logger.info("step:%f exp:%d"%(step,exp)) i=0 scurve_flg=0 th_list=np.arange(start,stop,step) while len(th_list)!=i: self.dut['CCPD_TH'].set_voltage(th_list[i], unit='V') d=self.get_tdc() width,delay=self.analyse_tdc(d) cnt=len(width) ave=np.average(width) std=np.std(width) th=self.dut['CCPD_TH'].get_voltage(unit='V') self.logger.info("%f %d %f %f"%(th,cnt,ave,std)) if abs(step)>abs(-0.05*0.99) and cnt>5: if self.debug==1: print "debug change step to 0.005" step=-0.005 th_list=np.arange(th-9*step,stop,step) i=0 elif abs(step)>abs(-0.005*0.99) and cnt>100*0.5: if self.debug==1: print "debug change step to 0.001" step=-0.001 th_list=np.arange(th-6*step,stop,step) i=0 elif abs(step)>abs(-0.001*0.99) and cnt> 100*0.6 and scurve_flg==0: if full_scurve==False: break else: scurve_flg=1 elif scurve_flg==1 and cnt==0: break else: i=i+1 def scan_inj_tdc(self,b=1.81,e=0.0,s=-0.05,n=1,exp=100000,inj_low=0): self.set_tdc(repeat=n,exp=exp,inj_width=0) self.dut['PULSER'].set_voltage(low=inj_low, high=b,unit="V") self.logger.info("th cnt ave std") for inj in np.arange(b+s,e+s,s): d=self.get_tdc() inj_low_meas,inj_high_meas=self.dut['PULSER'].get_voltage(channel=0,unit='V') self.dut['PULSER'].set_voltage(low=inj_low, high=inj,unit="V") width,delay=self.analyse_tdc(d) cnt=len(width) ave=np.average(width) std=np.std(width) self.logger.info("%f %f %d %f %f"%(inj_low_meas,inj_high_meas,cnt,ave,std)) def init_oscillo(self,addr="131.220.167.99"): sys.path.append(r"D:\workspace\hcmos\app\trunk\host\MSO4104B") import MSO4104B_sock self.m=MSO4104B_sock.Mso_sock(addr) def timewalk(self,inj=[1.5,1.25,1.,0.75,0.5,0.4,0.3,0.2,0.1,0.05],inj_low=0,n=10): th=self.dut['CCPD_TH'].get_voltage(unit='V') self.m.init(chs=[1,2,3,4]) self.logger.info("th,inj,i,fname") for i in inj: self.dut["PULSER"].set_voltage(low=inj_low, high=i,unit="V") for j in range(n): f=self.m.measure() self.logger.info("%f %f %d %s"%(th,i,j,f)) def spectrum(self,exp=100,interval=1): # reset TDC self.dut["CCPD_TDC"].reset() self.dut['CCPD_TDC']['EN_INVERT_TDC']=True self.dut['CCPD_TDC']['ENABLE_EXTERN']=False self.dut['CCPD_TDC']['ENABLE']=False # reset fifo self.dut['sram'].reset() self.dut['CCPD_TDC']['ENABLE']=True t=time.time()+exp while time.time()< t: if self.dut["sram"].get_fifo_size()==0: time.sleep(interval) else: d=self.dut["sram"].get_data() width,delay=self.analyse_tdc(d) self.logger.info(str(width)) def analyse_hit(self,dat): dat=dat[dat & 0xF0000000==0x60000000] ret=np.empty([16,len(dat)],dtype=bool) for i in range(16): ret[15-i,:]= (dat & 2**i ==0) ### the first bit goes to ret[15,0] ret=np.reshape(ret,len(dat)*16,order="F") ret=np.argwhere(ret==True)[:,0] if len(ret)!=0: frame,col,row=self._build_img(ret) ret=np.transpose(np.array([frame,col,row])) return ret def analyse_tdc(self,dat): dat=dat[dat & 0xF0000000==0x50000000] ret0=dat & 0x00000FFF ret1=np.right_shift(dat & 0x0FFFF000,12) return ret0,ret1
class TestSimTlu(unittest.TestCase): def setUp(self): cocotb_compile_and_run( [os.path.join(os.path.dirname(__file__), 'test_SimTlu.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_simple_trigger_veto(self): self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].TRIGGER_MODE = 0 self.chip['TLU'].TRIGGER_SELECT = 2 self.chip['TLU'].TRIGGER_VETO_SELECT = 2 self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x06]) # assert trigger and veto signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger and veto signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['TLU'].TRIGGER_ENABLE = False self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 1) self.assertEqual(self.chip['TLU'].TRIGGER_COUNTER, 1) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000 + 0) def test_simple_trigger_veto_disabled(self): self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].TRIGGER_MODE = 0 self.chip['TLU'].TRIGGER_SELECT = 2 self.chip['TLU'].TRIGGER_VETO_SELECT = 252 self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x06]) # assert trigger and veto signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger and veto signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['TLU'].TRIGGER_ENABLE = False self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 2) self.assertEqual(self.chip['TLU'].TRIGGER_COUNTER, 2) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) def test_simple_trigger_threshold(self): self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].TRIGGER_MODE = 0 # select short trigger (one clock cycle) self.chip['TLU'].TRIGGER_SELECT = 4 self.chip['TLU'].TRIGGER_THRESHOLD = 1 # at least one clock cycle self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['TLU'].TRIGGER_ENABLE = False self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 2) self.assertEqual(self.chip['TLU'].TRIGGER_COUNTER, 2) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].TRIGGER_THRESHOLD = 2 # at least two clock cycles self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['TLU'].TRIGGER_ENABLE = False self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 0) self.assertEqual(self.chip['TLU'].TRIGGER_COUNTER, 0) def test_simple_trigger_max_triggers(self): self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].MAX_TRIGGERS = 2 # max. 2 triggers self.chip['TLU'].TRIGGER_MODE = 0 self.chip['TLU'].TRIGGER_SELECT = 2 self.chip['TLU'].TRIGGER_VETO_SELECT = 252 self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['GPIO'].set_data([0x02]) # assert trigger signal self.chip['GPIO'].set_data([0x00]) # de-assert trigger signal self.chip['TLU'].TRIGGER_ENABLE = False self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 2) self.assertEqual(self.chip['TLU'].TRIGGER_COUNTER, 2) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) def test_simple_trigger(self): self.chip['TLU'].TRIGGER_COUNTER = 10 self.chip['TLU'].TRIGGER_MODE = 0 self.chip['TLU'].TRIGGER_SELECT = 1 self.chip['TLU'].TRIGGER_VETO_SELECT = 0 self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x01]) # enable trigger/TLU FSM readings = 0 while (self.chip['FIFO'].get_FIFO_INT_SIZE() < 4 and readings < 10000): readings += 1 self.chip['GPIO'].set_data([0x00]) # disable trigger/TLU FSM self.chip['TLU'].TRIGGER_ENABLE = False self.assertGreaterEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 4) self.assertGreaterEqual(self.chip['TLU'].TRIGGER_COUNTER, 14) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000 + 10) self.assertEqual(data[1], 0x80000000 + 11) self.assertEqual(data[2], 0x80000000 + 12) self.assertEqual(data[3], 0x80000000 + 13) def test_manual_soft_trigger(self): self.chip['TLU'].TRIGGER_COUNTER = 10 self.chip['TLU'].TRIGGER_MODE = 0 self.chip['TLU'].TRIGGER_SELECT = 0 self.chip['TLU'].TRIGGER_VETO_SELECT = 0 self.chip['TLU'].TRIGGER_ENABLE = True for i in range(4): self.chip['TLU'].SOFT_TRIGGER = 1 readings = 0 while (self.chip['FIFO'].get_FIFO_INT_SIZE() <= i and readings < 10000): readings += 1 self.chip['TLU'].TRIGGER_ENABLE = False self.assertGreaterEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 4) self.assertGreaterEqual(self.chip['TLU'].TRIGGER_COUNTER, 14) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000 + 10) self.assertEqual(data[1], 0x80000000 + 11) self.assertEqual(data[2], 0x80000000 + 12) self.assertEqual(data[3], 0x80000000 + 13) def test_tlu_trigger_handshake(self): self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].TRIGGER_MODE = 3 # not used when EN_TLU_VETO is False self.chip['TLU'].TRIGGER_VETO_SELECT = 255 self.chip['TLU'].EN_TLU_VETO = 0 # self.chip['TLU'].DATA_FORMAT = 2 # self.chip['TLU'].TRIGGER_LOW_TIMEOUT = 5 # self.chip['TLU'].TRIGGER_HANDSHAKE_ACCEPT_WAIT_CYCLES = 0 # self.chip['TLU'].HANDSHAKE_BUSY_VETO_WAIT_CYCLES = 0 self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x01]) readings = 0 while (self.chip['FIFO'].get_FIFO_INT_SIZE() < 4 and readings < 1000): readings += 1 self.chip['GPIO'].set_data([0x00]) # disable trigger/TLU FSM self.chip['TLU'].TRIGGER_ENABLE = False self.assertGreaterEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 4) self.assertGreaterEqual(self.chip['TLU'].TRIGGER_COUNTER, 4) self.assertGreaterEqual(self.chip['TLU'].CURRENT_TLU_TRIGGER_NUMBER, 3) data = self.chip['FIFO'].get_data() self.assertEqual(data[0], 0x80000000) self.assertEqual(data[1], 0x80000001) self.assertEqual(data[2], 0x80000002) self.assertEqual(data[3], 0x80000003) def test_tlu_trigger_handshake_veto(self): self.chip['TLU'].TRIGGER_COUNTER = 0 self.chip['TLU'].TRIGGER_MODE = 3 # used when EN_TLU_VETO is True self.chip['TLU'].TRIGGER_VETO_SELECT = 255 self.chip['TLU'].EN_TLU_VETO = 1 self.chip['TLU'].TRIGGER_ENABLE = True self.chip['GPIO'].set_data([0x01]) # enable trigger/TLU FSM readings = 0 while (self.chip['FIFO'].get_FIFO_INT_SIZE() == 0 and readings < 1000): readings += 1 self.assertEqual(self.chip['FIFO'].get_FIFO_INT_SIZE(), 0) self.assertEqual(self.chip['TLU'].TRIGGER_COUNTER, 0) self.assertEqual(self.chip['TLU'].CURRENT_TLU_TRIGGER_NUMBER, 0) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
def scan(self, clock_en1=True, pixels=512, clock_en2=True, trigger_en=True, measure_direction=True, offset=15, mask_steps=4, repeat_command=100, PrmpVbpDac=80, vthin2Dac=0, columns = [True] * 16, scan_range = [0, 0.2, 0.005], vthin1Dac = 80, preCompVbnDac = 50, mask_filename='', **kwargs): '''Scan loop Parameters ---------- mask : int Number of mask steps. repeat : int Number of injections. ''' inj_factor = 1.0 INJ_LO = 0.0 try: dut = Dut(ScanBase.get_basil_dir(self)+'/examples/lab_devices/agilent33250a_pyserial.yaml') dut.init() logging.info('Connected to '+str(dut['Pulser'].get_info())) except RuntimeError: INJ_LO = 0.2 inj_factor = 2.0 logging.info('External injector not connected. Switch to internal one') self.dut['INJ_LO'].set_voltage(INJ_LO, unit='V') self.dut['global_conf']['PrmpVbpDac'] = 80 self.dut['global_conf']['vthin1Dac'] = 255 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['vffDac'] = 24 self.dut['global_conf']['PrmpVbnFolDac'] = 51 self.dut['global_conf']['vbnLccDac'] = 1 self.dut['global_conf']['compVbnDac'] = 25 self.dut['global_conf']['preCompVbnDac'] = 50 self.dut.write_global() self.dut['control']['RESET'] = 0b01 self.dut['control']['DISABLE_LD'] = 0 self.dut['control']['PIX_D_CONF'] = 0#0 self.dut['control'].write() self.dut['control']['CLK_OUT_GATE'] = 1 self.dut['control']['CLK_BX_GATE'] = 1 self.dut['control'].write() time.sleep(0.1) self.dut['control']['RESET'] = 0b11 self.dut['control'].write() self.dut['global_conf']['OneSr'] = 1 self.dut['global_conf']['TestHit'] = 0 self.dut['global_conf']['SignLd'] = 0 self.dut['global_conf']['InjEnLd'] = 0 self.dut['global_conf']['TDacLd'] = 0 self.dut['global_conf']['PixConfLd'] = 0 self.dut.write_global() #self.dut['global_conf']['OneSr'] = 0 #all multi columns in parallel self.dut['global_conf']['ColEn'][:] = bitarray.bitarray([True] * 16) #(columns) self.dut['global_conf']['ColSrEn'][:] = bitarray.bitarray([True] * 16) self.dut.write_global() self.dut['pixel_conf'].setall(False) self.dut.write_pixel() self.dut['global_conf']['InjEnLd'] = 1 self.dut.write_global() self.dut['global_conf']['InjEnLd'] = 0 mask_en = np.full([64,64], False, dtype = np.bool) #mask_tdac = np.full([64,64], 16, dtype = np.uint8) ### if pixels>1 and pixels<=64: mask_en[0:1, :] = True ### if pixels==1: mask_en[0][3]=True #for inx, col in enumerate(columns): #if col: #mask_en[inx*4:(inx+1)*4,:] = True if mask_filename: logging.info('Using pixel mask from file: %s', mask_filename) with tb.open_file(mask_filename, 'r') as in_file_h5: #mask_tdac = in_file_h5.root.scan_results.tdac_mask[:] if pixels>64: mask_en = in_file_h5.root.scan_results.en_mask[:] mask_en = np.full([64, 64], True, dtype=np.bool) self.dut.write_en_mask(mask_en) #self.dut.write_tune_mask(mask_tdac) self.dut['global_conf']['OneSr'] = 0 self.dut.write_global() self.dut['trigger'].set_delay(10000) #trigger for no injection self.dut['trigger'].set_width(16)#16 self.dut['trigger'].set_repeat(1) self.dut['trigger'].set_en(False) logging.debug('Configure TDC') self.dut['tdc']['RESET'] = True self.dut['tdc']['EN_TRIGGER_DIST'] = True self.dut['tdc']['ENABLE_EXTERN'] = False self.dut['tdc']['EN_ARMING'] = False self.dut['tdc']['EN_INVERT_TRIGGER'] = False self.dut['tdc']['EN_INVERT_TDC'] = False self.dut['tdc']['EN_WRITE_TIMESTAMP'] = True lmask = [1] + ( [0] * (mask_steps-1) ) lmask = lmask * ( (64 * 64) / mask_steps + 1 ) lmask = lmask[:64*64] ranges=np.arange(0,(vthin1Dac-offset),1) n=0 m=80 self.dut['global_conf']['vthin1Dac'] = 100 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['preCompVbnDac'] = 10 #self.dut['global_conf']['PrmpVbpDac'] = 36 self.dut.write_global() np.set_printoptions(threshold=np.inf) while (m==80): while(n==0): print "m: ", m, " n: ", n self.dut['global_conf']['vthin1Dac'] = 255 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['preCompVbnDac'] = 50 # self.dut['global_conf']['PrmpVbpDac'] = 36 self.dut.write_global() for ni in range(1,32): time.sleep(0.5) self.dut['global_conf']['OneSr'] = 1 #all multi columns in parallel self.dut.write_global() mask_en = np.full([64, 64], False, dtype=np.bool) self.dut.write_en_mask(mask_en) self.dut.write_global() with self.readout(scan_param_id = ni): logging.info('Scan Parameter: %f (%d of %d)', ni, ni+1, 32) mask_tdac = np.full([64, 64], ni, dtype=np.uint8) print mask_tdac[0][0] self.dut.write_tune_mask(mask_tdac) self.dut['global_conf']['OneSr'] = 0 # all multi columns in parallel self.dut.write_global() mask_en = np.full([64, 64], True, dtype=np.bool) self.dut.write_en_mask(mask_en) self.dut.write_global() time.sleep(0.1) n=n+10 #self.dut['global_conf']['vthin1Dac'] = 255 #self.dut['global_conf']['vthin2Dac'] = 255 #self.dut['global_conf']['preCompVbnDac'] = 100 #self.dut.write_global() #time.sleep(0.01) m=m+10 n=0 scan_results = self.h5_file.create_group("/", 'scan_results', 'Scan Masks') self.h5_file.createCArray(scan_results, 'tdac_mask', obj=mask_tdac) self.h5_file.createCArray(scan_results, 'en_mask', obj=mask_en)
class TestSimSpi(unittest.TestCase): def __init__(self, testname, tb='test_SimSpi.v', bus_drv='basil.utils.sim.BasilBusDriver', bus_split=False): super(TestSimSpi, self).__init__(testname) self._test_tb = tb self._sim_bus = bus_drv self._bus_split_def = () if bus_split is not False: if bus_split == 'sbus': self._bus_split_def = ("BASIL_SBUS",) elif bus_split == 'top': self._bus_split_def = ("BASIL_TOPSBUS",) def setUp(self): cocotb_compile_and_run(sim_files=[os.path.join(os.path.dirname(__file__), self._test_tb)], sim_bus=self._sim_bus, extra_defines=self._bus_split_def) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): size = self.chip['SPI'].get_SIZE() self.chip['GPIO'].reset() self.assertEqual(size, 16 * 8) self.chip['SPI'].set_data(range(16)) ret = self.chip['SPI'].get_data(size=16, addr=0) # to read back what was written self.assertEqual(ret.tolist(), list(range(16))) self.chip['SPI'].set_data(range(16)) ret = self.chip['SPI'].get_data(addr=0) # to read back what was written self.assertEqual(ret.tolist(), list(range(16))) self.chip['SPI'].start() while(not self.chip['SPI'].is_ready): pass ret = self.chip['SPI'].get_data() # read back what was received (looped) self.assertEqual(ret.tolist(), list(range(16))) # ext_start self.chip['SPI'].set_en(1) self.assertEqual(self.chip['SPI'].get_en(), 1) self.chip['PULSE_GEN'].set_DELAY(1) self.chip['PULSE_GEN'].set_WIDTH(1 + size) self.chip['PULSE_GEN'].set_REPEAT(1) self.assertEqual(self.chip['PULSE_GEN'].get_DELAY(), 1) self.assertEqual(self.chip['PULSE_GEN'].get_WIDTH(), 1 + size) self.assertEqual(self.chip['PULSE_GEN'].get_REPEAT(), 1) self.chip['PULSE_GEN'].start() while(not self.chip['PULSE_GEN'].is_ready): pass ret = self.chip['SPI'].get_data() # read back what was received (looped) self.assertEqual(ret.tolist(), list(range(16))) # SPI_RX ret = self.chip['SPI_RX'].get_en() self.assertEqual(ret, False) self.chip['SPI_RX'].set_en(True) ret = self.chip['SPI_RX'].get_en() self.assertEqual(ret, True) self.chip['SPI'].start() while(not self.chip['SPI'].is_ready): pass ret = self.chip['FIFO'].get_FIFO_SIZE() self.assertEqual(ret, 32) ret = self.chip['FIFO'].get_data() data0 = ret.astype(np.uint8) data1 = np.right_shift(ret, 8).astype(np.uint8) data = np.reshape(np.vstack((data1, data0)), -1, order='F') self.assertEqual(data.tolist(), list(range(16))) def test_dut_iter(self): conf = yaml.safe_load(cnfg_yaml) def iter_conf(): for item in conf['registers']: yield item for item in conf['hw_drivers']: yield item for item in conf['transfer_layer']: yield item for mod, mcnf in zip(self.chip, iter_conf()): self.assertEqual(mod.name, mcnf['name']) self.assertEqual(mod.__class__.__name__, mcnf['type']) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimBDAQ53Eth(unittest.TestCase): def setUp(self): sys.path = [os.path.dirname(os.getcwd())] + sys.path proj_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) cocotb_compile_and_run( sim_files=[proj_dir + '/test/bdaq53_eth_tb.v'], top_level='tb', include_dirs=(proj_dir, proj_dir + '/firmware/src') ) with open(proj_dir + '/bdaq53_eth.yaml') as conf_file: try: conf = yaml.safe_load(conf_file) except yaml.YAMLError as exception: print(exception) conf['transfer_layer'][0]['type'] = 'SiSim' conf['transfer_layer'][0]['tcp_connection'] = 'False' # conf['hw_drivers']['FIFO'] = ({'name': 'fifo', # 'type': 'sram_fifo', # 'interface': 'intf', # 'base_addr': 0x8000, # 'base_data_addr': 0x80000000}) conf['hw_drivers'].append({'name': 'FIFO', 'type': 'sram_fifo', 'interface': 'intf', 'base_addr': 0x8000, 'base_data_addr': 0x80000000}) self.chip = Dut(conf) self.chip.init() def test(self): testduration = 10 total_len = 0 tick = 0 tick_old = 0 start_time = time.time() self.chip['CONTROL']['EN'] = 0x01 # start data source self.chip['CONTROL'].write() while time.time() - start_time < testduration: data = self.chip['FIFO'].get_data() total_len += len(data) time.sleep(0.01) tick = int(time.time() - start_time) if tick != tick_old: print(tick) tick_old = tick if doprint: print(data) for i in data: if i < (len(data) - 1): assert data[i] == data[i + 1] - 1 # Check, if received integers are increasing numbers if total_len >= IntsToReceive: break total_len_bits = total_len * 32 # 32-bit ints to bits print('Bits received: {}; Data rate: {}Mbit/s'.format(total_len_bits, round((total_len_bits / 1e6 / testduration), 2))) self.chip['CONTROL']['EN'] = 0x00 # stop data source self.chip['CONTROL'].write() def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class Test(object): def __init__(self): self.dut = Dut(conf) self.dut.init() # fw_version = dut['ETH'].read(0x0000, 1)[0] logging.info("Firmware version: %s" % self.dut['REGISTERS'].VERSION) signal.signal(signal.SIGINT, self.signal_handler) logging.info('Press Ctrl-C to stop') self.stop_thread = Event() self.total_tcp_err_cnt = 0 def signal_handler(self, signum, frame): logging.info('Pressed Ctrl-C...') self.dut['REGISTERS'].TCP_WRITE_DLY = 0 # no TCP data self.time_stop = time.time() self.stop_thread.set() signal.signal(signal.SIGINT, signal.SIG_DFL) # setting default handler def start(self, test_tcp=True, test_bus=True, tcp_write_delay=6, monitor_interval=1.0, deadline=None): if not test_tcp and not test_bus: return self.test_tcp = test_tcp self.test_bus = test_bus # reset registers self.dut['REGISTERS'].RESET # setup register values # Monitor self.monitor_delay = monitor_interval # Speed of displaying netowrk speed # TCP self.tcp_readout_delay = 0.1 # Delay between reading TCP buffer self.dut['REGISTERS'].TCP_WRITE_DLY = 0 # no TCP data self.time_start = time.time() self.total_tcp_err_cnt = 0 self.total_tcp_data_words_read = 0 self.tcp_exception_cnt = 0 self.tcp_read_speeds = None # BUS self.bus_readout_delay = 0.0 # Delay between reading/writing to BUS self.total_bus_err_cnt = 0 self.total_bus_read_write_cnt = 0 self.bus_exception_cnt = 0 self.bus_read_write_speeds = None # initializing threads self.stop_thread.clear() self.mon_t = Thread(target=self.monitor, name='Monitor thread', kwargs={}) self.mon_t.daemon = True self.mon_t.start() if test_tcp: self.tcp_t = Thread(target=self.tcp_read, name='TCP thread', kwargs={}) self.tcp_t.daemon = True self.tcp_t.start() if test_bus: self.bus_t = Thread(target=self.bus_read_write, name='BUS thread', kwargs={}) self.bus_t.daemon = True self.bus_t.start() if test_tcp: self.dut['REGISTERS'].TCP_WRITE_DLY = tcp_write_delay # set TCP write delay: 1 equivalent to write data every clock cycle (1/133MHz=0.0075us=7.5ns) self.time_start = time.time() self.time_stop = self.time_start + 1.0 # while loop for signal handler while not self.stop_thread.wait(0.05): if deadline and self.time_start + deadline < time.time(): self.signal_handler(None, None) self.mon_t.join() self.mon_t = None logging.info("Stopped Monitor thread") if test_tcp: self.tcp_t.join() self.tcp_t = None logging.info("Stopped TCP thread") if test_bus: self.bus_t.join() self.bus_t = None logging.info("Stopped BUS thread") # some statistics logging.info("Total time: %s" % (str(datetime.timedelta(seconds=self.time_stop - self.time_start)))) if test_tcp: logging.info("=== TCP transfer statistics ===") logging.info("TCP data error counter: %d" % self.total_tcp_err_cnt) logging.info("TCP exception counter: %d" % self.tcp_exception_cnt) logging.info("TCP write busy counter: %d" % self.dut['REGISTERS'].TCP_FAILED_WRITE_CNT) logging.info("TCP data words: read: %d, expected: %d" % (self.dut['REGISTERS'].TCP_WRITE_CNT * 4 + self.dut['REGISTERS'].TCP_RECV_WRITE_CNT, self.total_tcp_data_words_read * 4)) if self.total_tcp_data_words_read * 4 / 10.0**6 > 1000000: logging.info("Total amount transmitted: %.2f TB" % (self.total_tcp_data_words_read * 4 / 10.0**12)) elif self.total_tcp_data_words_read * 4 / 10.0**6 > 1000: logging.info("Total amount transmitted: %.2f GB" % (self.total_tcp_data_words_read * 4 / 10.0**9)) else: logging.info("Total amount transmitted: %.2f MB" % (self.total_tcp_data_words_read * 4 / 10.0**6)) total_tcp_avg_read_speed = self.total_tcp_data_words_read * 32 / (self.time_stop - self.time_start) / 10.0**6 if total_tcp_avg_read_speed < 1.0: logging.info("Total average TCP read speed: %.2f kbit/s" % (total_tcp_avg_read_speed * 10**3)) else: logging.info("Total average TCP read speed: %.2f Mbit/s" % (total_tcp_avg_read_speed)) if self.tcp_read_speeds: if np.average(self.tcp_read_speeds) < 1.0: logging.info("TCP read speed (min/median/average/max): %.2f/%.2f/%.2f/%.2f kbit/s" % (np.min(self.tcp_read_speeds) * 10**3, np.median(self.tcp_read_speeds) * 10**3, np.average(self.tcp_read_speeds) * 10**3, np.max(self.tcp_read_speeds) * 10**3)) else: logging.info("TCP read speed (min/median/average/max): %.2f/%.2f/%.2f/%.2f Mbit/s" % (np.min(self.tcp_read_speeds), np.median(self.tcp_read_speeds), np.average(self.tcp_read_speeds), np.max(self.tcp_read_speeds))) if test_bus: logging.info("=== BUS transfer statistics ===") logging.info("BUS data error counter: %d" % self.total_bus_err_cnt) logging.info("BUS exception counter: %d" % self.bus_exception_cnt) logging.info("BUS read/write counter: read: %d, expected: %d" % (self.dut['REGISTERS'].BUS_WRITE_CNT, self.total_bus_read_write_cnt * 8)) if self.total_bus_read_write_cnt * 8 / 10.0**6 > 1000000: logging.info("Total amount transmitted: %.2f TB" % (self.total_bus_read_write_cnt * 8 / 10.0**12)) elif self.total_bus_read_write_cnt * 8 / 10.0**6 > 1000: logging.info("Total amount transmitted: %.2f GB" % (self.total_bus_read_write_cnt * 8 / 10.0**9)) else: logging.info("Total amount transmitted: %.2f MB" % (self.total_bus_read_write_cnt * 8 / 10.0**6)) total_bus_avg_read_speed = self.total_bus_read_write_cnt * 64 / (self.time_stop - self.time_start) / 10.0**6 if total_bus_avg_read_speed < 1.0: logging.info("Total average BUS read/write speed: %.2f kbit/s" % (total_bus_avg_read_speed * 10**3)) else: logging.info("Total average BUS read/write speed: %.2f Mbit/s" % (total_bus_avg_read_speed)) if self.bus_read_write_speeds: if np.average(self.bus_read_write_speeds) < 1.0: logging.info("BUS read/write speed (min/median/average/max): %.2f/%.2f/%.2f/%.2f kbit/s" % (np.min(self.bus_read_write_speeds) * 10**3, np.median(self.bus_read_write_speeds) * 10**3, np.average(self.bus_read_write_speeds) * 10**3, np.max(self.bus_read_write_speeds) * 10**3)) else: logging.info("BUS read/write speed (min/median/average/max): %.2f/%.2f/%.2f/%.2f Mbit/s" % (np.min(self.bus_read_write_speeds), np.median(self.bus_read_write_speeds), np.average(self.bus_read_write_speeds), np.max(self.bus_read_write_speeds))) # close DUT self.dut.close() def monitor(self): logging.info("Started Monitor thread") time_read = time.time() last_total_tcp_data_words_read = 0 last_total_bus_read_write_cnt = 0 while not self.stop_thread.wait(max(0.0, self.monitor_delay - time_read + time.time())): tmp_time_read = time.time() tmp_total_tcp_data_words_read = self.total_tcp_data_words_read tmp_total_bus_read_write_cnt = self.total_bus_read_write_cnt if self.test_tcp: tcp_read_speed = (tmp_total_tcp_data_words_read - last_total_tcp_data_words_read) * 32 / (tmp_time_read - time_read) / 10**6 if self.tcp_read_speeds is None: # add on second iteration self.tcp_read_speeds = [] else: self.tcp_read_speeds.append(tcp_read_speed) if tcp_read_speed < 1.0: logging.info("TCP read speed: %0.2f kbit/s" % (tcp_read_speed * 10**3)) else: logging.info("TCP read speed: %0.2f Mbit/s" % tcp_read_speed) if self.test_bus: bus_read_write_speed = (tmp_total_bus_read_write_cnt - last_total_bus_read_write_cnt) * 64 / (tmp_time_read - time_read) / 10**6 if self.bus_read_write_speeds is None: # add on second iteration self.bus_read_write_speeds = [] else: self.bus_read_write_speeds.append(bus_read_write_speed) if bus_read_write_speed < 1.0: logging.info("BUS read/write speed: %0.2f kbit/s" % (bus_read_write_speed * 10**3)) else: logging.info("BUS read/write speed: %0.2f Mbit/s" % bus_read_write_speed) time_read = tmp_time_read last_total_tcp_data_words_read = tmp_total_tcp_data_words_read last_total_bus_read_write_cnt = tmp_total_bus_read_write_cnt if self.total_bus_err_cnt > 10 or self.total_tcp_err_cnt > 10: self.stop_thread.set() logging.info("Stopping Monitor thread...") def tcp_read(self): logging.info("Started TCP thread") fifo_data_last_value = -1 fifo_was_empty = 0 time_read = time.time() while not self.stop_thread.wait(max(0.0, self.tcp_readout_delay - time_read + time.time())) or fifo_was_empty < 1: time_read = time.time() try: fifo_data = self.dut['SITCP_FIFO'].get_data() except Exception as e: logging.error(e) self.tcp_exception_cnt += 1 else: if fifo_data.shape[0]: self.total_tcp_data_words_read += fifo_data.shape[0] if fifo_data[0] != fifo_data_last_value + 1: logging.warning("TCP not increased by 1 between readouts") self.total_tcp_err_cnt += 1 err_cnt = np.count_nonzero(np.diff(fifo_data) != 1) if err_cnt: logging.warning("TCP data not increased by 1: errors=%d" % err_cnt) self.total_tcp_err_cnt += err_cnt fifo_data_last_value = fifo_data[-1] elif self.stop_thread.is_set(): fifo_was_empty += 1 if self.stop_thread.is_set(): time.sleep(max(0.0, self.tcp_readout_delay - time_read + time.time())) logging.info("Stopping TCP thread...") def bus_read_write(self): logging.info("Started BUS thread") time_read = time.time() while not self.stop_thread.wait(max(0.0, self.bus_readout_delay - time_read + time.time())): time_read = time.time() write_value = int(np.random.randint(2**64, size=None, dtype=np.uint64)) # random.randint(0, 2**64 - 1) try: self.dut['REGISTERS'].TEST_DATA = write_value except Exception as e: logging.error(e) self.bus_exception_cnt += 1 else: try: read_value = self.dut['REGISTERS'].TEST_DATA except Exception as e: logging.error(e) self.bus_exception_cnt += 1 else: self.total_bus_read_write_cnt += 1 if read_value != write_value: logging.warning("BUS data not correct: read: %s, expected: %s" % (array('B', struct.unpack("BBBBBBBB", struct.pack("Q", read_value))), array('B', struct.unpack("BBBBBBBB", struct.pack("Q", write_value))))) self.total_bus_err_cnt += 1 logging.info("Stopping BUS thread...")
class TestSimTimestampDiv(unittest.TestCase): def setUp(self): cocotb_compile_and_run([ os.path.join(os.path.dirname(__file__), 'test_SimTimestampDiv.v') ]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): self.chip['timestamp_div'].reset() self.chip['timestamp_div']["ENABLE"] = 1 self.chip['gpio'].reset() self.chip['fifo'].reset() ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 0) # trigger timestamp repeat = 16 width = 0x18 self.chip['PULSE_GEN'].set_delay(0x20 + 0x7) self.chip['PULSE_GEN'].set_width(width) self.chip['PULSE_GEN'].set_repeat(repeat) self.chip['PULSE_GEN'].start() while (not self.chip['PULSE_GEN'].is_done()): pass # get data from fifo ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 3 * 4 * repeat) ret = self.chip['fifo'].get_data() self.assertEqual(len(ret), 3 * repeat) for i, r in enumerate(ret): self.assertEqual(r & 0xF0000000, 0x50000000) self.assertEqual(r & 0xF000000, 0x1000000 * (3 - i % 3)) self.chip['timestamp_div']["ENABLE_TOT"] = 1 self.chip['PULSE_GEN'].start() while (not self.chip['PULSE_GEN'].is_done()): pass ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 3 * 4 * repeat) ret = self.chip['fifo'].get_data() self.assertEqual(len(ret), 3 * repeat) for i, r in enumerate(ret): self.assertEqual(r & 0xF0000000, 0x50000000) self.assertEqual(r & 0xF000000, 0x1000000 * (3 - i % 3)) if i % 3 == 0: self.assertEqual(r & 0xFFFF00, 0x100 * width) # ToT value def tearDown(self): time.sleep(2) self.chip.close() # let it close connection and stop simulator time.sleep(2) cocotb_compile_clean() time.sleep(2)
value = int(get_voltage_reading(dev)) if (max_value > 0): if max_value > value: step = 1 else: step = -1 else: if max_value > value: step = 1 else: step = -1 while True: value = int(get_voltage_reading(dev)) if value != max_value: dev.set_voltage(value + step) else: break if __name__ == "__main__": dut = Dut('sourcemeter.yaml') dut.init() dut['Sourcemeter'].on() #ramp_to(dut['Sourcemeter'], 15) #ramp_down(dut['Sourcemeter']) print status(dut['Sourcemeter'])
# ------------------------------------------------------------ # Copyright (c) All rights reserved # SiLab, Institute of Physics, University of Bonn # ------------------------------------------------------------ # import time from basil.dut import Dut import numpy as np chip = Dut("sram_test.yaml") chip.init() def test_sram(count=10000): i = 0 error = 0 for k in range(count): # chip['CONTROL']['COUNTER_EN'] = 1 # chip['CONTROL'].write() # chip['CONTROL']['COUNTER_EN'] = 0 # chip['CONTROL'].write() chip['pulse'].set_delay(1) chip['pulse'].set_width((k + 1) % 3000) chip['pulse'].start() ret = chip['fifo'].get_data()
class utils(): ''' Simple beam profile scan - Stores the measured current values and the corresponding coordinates - Has a debug mode which generates fake data ''' def __init__(self, debug=False, **kwargs): self.debug = debug self.devices = Dut('config.yaml') if self.debug is False: self.devices.init() if kwargs['xray_use_remote'] is True: self.xraymachine = Dut('xray.yaml') self.xraymachine.init() def init(self, x_range=0, y_range=0, z_height=False, stepsize=0, **kwargs): self.axis = { 'x': kwargs['address_x'], 'y': kwargs['address_y'], 'z': kwargs['address_z'] } self.invert = { 'x': kwargs['invert_x'], 'y': kwargs['invert_y'], 'z': kwargs['invert_z'] } self.x_range, self.y_range, self.z_height, self.stepsize = x_range, y_range, z_height, stepsize self.steps_per_mm = kwargs['steps_per_mm'] self.debug_motor_res = 0.1 self.debug_delay = 0 self.debug_pos_mm = {'x': 0, 'y': 0, 'z': 0} self.filename = os.path.join( kwargs['directory'], kwargs['filename'] + '_' + kwargs['distance'] + 'cm_' + str(x_range) + 'mm_' + str(y_range) + 'mm_' + str(stepsize).replace('.', 'd') + 'mm_' + str(kwargs['xray_voltage']) + 'kV_' + str(kwargs['xray_current']) + 'mA_' + datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S" + '.csv')) logger.info('Filename: ' + self.filename) fh = logging.FileHandler(self.filename[:-4] + '.log') fh.setLevel(logging.INFO) fh.setFormatter( logging.Formatter( '%(asctime)s [%(name)-10s] - %(levelname)-7s %(message)s')) if self.debug is False: fh.setLevel(logging.DEBUG) self.use_xray_control = kwargs['xray_use_remote'] self.voltage = kwargs['xray_voltage'] self.current = kwargs['xray_current'] if (kwargs['smu_use_bias'] is True and self.debug is False): self.init_smu(voltage=kwargs['smu_diode_bias'], current_limit=kwargs['smu_current_limit']) logger.addHandler(fh) return self.filename def init_smu(self, voltage=0, current_limit=0): logger.info(self.devices['SMU'].get_name()) self.devices['SMU'].source_volt() self.devices['SMU'].set_avg_en(1) self.devices['SMU'].set_avg_n(10) self.devices['SMU'].set_current_limit(current_limit) self.devices['SMU'].set_current_sense_range( 1E-6) # 1e-6 is the lowest possible range self.devices['SMU'].set_beeper(0) logger.debug(self.devices['SMU'].get_current_sense_range()) if (abs(voltage) <= 55): self.devices['SMU'].set_voltage(voltage) else: logger.exception('SMU Voltage %s out of range' % voltage) def smu_get_current(self, n=1): ''' Returns the mean and sigma of n consecutive measurements For a single measurement, leave n empty ''' rawdata = [] for _ in range(n): self.devices['SMU'].on() time.sleep(.1) rawdata.append(float(self.devices['SMU'].get_current())) self.devices['SMU'].off() time.sleep(.1) logger.debug(rawdata) if n > 1: return np.mean(rawdata), np.std(rawdata) else: return rawdata[0] def xray_control(self, voltage=0, current=0, shutter='close'): ''' Sets high voltage and current, operate the shutter If no values are given for voltage and current, the local_configuration values are used ''' if self.use_xray_control is False: logger.warning('X-ray control is not activated') return if self.voltage > 40: raise RuntimeError('Voltage above safe limit of 40 kV') if self.current > 50: raise RuntimeError('Current above safe limit of 50 mA') if voltage == 0 and current == 0: try: voltage = self.voltage current = self.current except RuntimeError as e: logger.error('X-ray voltage/current control failed. %s', e) if shutter == 'close': self.xraymachine["xray_tube"].close_shutter() if shutter == 'open': self.xraymachine["xray_tube"].open_shutter() self.xraymachine["xray_tube"].set_voltage(voltage) for _ in range(10): time.sleep(1) xray_v = self.xraymachine["xray_tube"].get_actual_voltage() logger.warning('X-ray voltage adjusing: %s kV' % xray_v) if xray_v == voltage: break if xray_v != voltage: logger.error('X-ray voltage is %s but expected %s' % (xray_v, voltage)) else: logger.info('X-ray voltage set to %s kV' % xray_v) self.xraymachine["xray_tube"].set_current(current) for _ in range(10): time.sleep(1) xray_i = self.xraymachine["xray_tube"].get_actual_current() logger.warning('X-ray current ramping up/down: %s mA' % xray_i) if xray_i == current: break if xray_i != current: logger.error('X-ray current is %s but expected %s' % (xray_i, current)) else: logger.info('X-ray current set to %s mA' % xray_i) def _ms_get_position(self, axis=None): for ax in axis: if self.debug is True: position_mm = self.debug_pos_mm[ax] position = position_mm * self.steps_per_mm else: position = int( self.devices['MS'].get_position(address=self.axis[ax])) # position = int(self._ms_write_read("TP", address=self.axis[ax])[2:-3]) position_mm = position / self.steps_per_mm logger.debug('Motor stage controller %s position: %s \t %.3f mm' % (ax, position, position_mm)) return position, position_mm def _ms_move_rel(self, axis=None, value=0, precision=0.02, wait=True): if self.invert[axis] is True: value = -value logger.debug('_ms_move_rel(axis=%s, value=%s, precision=%s)' % (axis, value, precision)) if self.debug is False: self.devices['MS'].move_relative(value * self.steps_per_mm, address=self.axis[axis]) if wait is True: self._wait_pos(axis=axis, target=self._ms_get_position(axis=axis)[1] + value) def _ms_move_abs(self, axis=None, value=0, precision=0.02, wait=True): if self.invert[axis] is True: value = -value logger.debug('_ms_move_abs(axis=%s, value=%s, precision=%s)' % (axis, value, precision)) if self.debug is False: self.devices['MS'].set_position(value * self.steps_per_mm, address=self.axis[axis]) if wait is True: self._wait_pos(axis=axis, target=value) def _ms_stop(self, axis=None): self.devices['MS']._write_command('AB', self.axis[axis]) def _wait_pos(self, axis=None, precision=0.02, target=0): logger.debug('_wait_pos(axis=%s, precision=%s, target=%s)' % (axis, precision, target)) logger.debug('Moving motor %s: %.2f mm -> %.2f mm' % (axis, self._ms_get_position(axis=axis)[1], target)) done = False pos_mm = 0 while done is False: if self.debug is True: e_pos = self.debug_pos_mm[axis] - target if abs(e_pos) > precision: self.debug_pos_mm[ axis] = self.debug_pos_mm[axis] - math.copysign( self.debug_motor_res, e_pos) pos_mm = self.debug_pos_mm[axis] logger.debug('Moving motor %s: %.3f -> %.3f' % (axis, pos_mm, target)) time.sleep(self.debug_delay) else: done = True pos = pos_mm * self.steps_per_mm else: pos, pos_mm = self._ms_get_position(axis=axis) logger.debug('Moving motor %s: %.2f mm -> %.2f mm' % (axis, pos_mm, target)) if abs(round(pos_mm, 2) - round(target, 2)) <= precision: done = True else: time.sleep(0.2) return pos, pos_mm def goto_end_position(self, axis=None, negative=True, wait=True): logger.debug('goto_end_position(axis=%s, negative=%s, wait=%s)' % (axis, negative, wait)) if negative is True: self.devices['MS']._write_command('FE1', self.axis[axis]) else: self.devices['MS']._write_command('FE0', self.axis[axis]) if wait is True: self._wait_pos(axis=axis, target=0) def goto_home_position(self, axis=[], wait=True): logger.info('Moving to home position') if self.debug is False: for ax in axis: self.devices['MS']._write_command('GH', self.axis[ax]) if wait is True: for ax in axis: self._wait_pos(ax) def set_home_position(self, axis=[]): for ax in axis: logger.warning('Set new home position for %s-axis)' % ax) self.devices['MS']._write_command('DH', self.axis[ax]) def step_scan(self, precision=0.02, wait=True): x_range, y_range, z_height, stepsize = self.x_range, self.y_range, self.z_height, self.stepsize logger.debug( 'step_scan(x_range=%s, y_range=%s, z_height=%s, stepsize=%s, precision=%s, wait=%s):' % (x_range, y_range, z_height, stepsize, precision, wait)) x_position = self._ms_get_position(axis='x')[1] y_position = self._ms_get_position(axis='y')[1] x_start = x_position - x_range / 2 x_stop = x_position + x_range / 2 y_start = y_position - y_range / 2 y_stop = y_position + y_range / 2 y_steps = int((y_stop - y_start) / stepsize) logger.info( 'Scanning range: x=%s mm, y=%s mm, z_height: %s, stepsize=%s mm' % (x_range, y_range, z_height, stepsize)) logger.debug( 'x_start=%s, x_stop=%s, y_start=%s, y_stop=%s, y_steps=%s):' % (x_start, x_stop, y_start, y_stop, y_steps)) self._ms_move_abs('x', value=x_start, wait=True) self._ms_move_abs('y', value=y_start, wait=True) if z_height is not False: self._ms_move_abs('z', value=z_height, wait=False) data = [] done = False while done is False: outerpbar = tqdm(total=self.y_range / self.stepsize, desc='row', position=0) # move y for indx_y, y_move in enumerate( np.arange(y_start, y_stop + stepsize, stepsize)): logger.debug('row %s of %s' % (indx_y, y_steps)) self._ms_move_abs('y', value=y_move, wait=True) if indx_y % 2: x_start_line = x_stop x_stop_line = x_start - stepsize stepsize_line = -stepsize else: x_start_line = x_start x_stop_line = x_stop + stepsize stepsize_line = stepsize data = [] innerpbar = tqdm(total=self.x_range / self.stepsize, desc='column', position=1) # move x for indx_x, x_move in enumerate( np.arange(x_start_line, x_stop_line, stepsize_line)): self._ms_move_abs('x', value=x_move, wait=True) if self.debug is False: time.sleep(0.1) current = self.smu_get_current() else: x0, y0, fwhm = 0, 0, (x_stop - x_start) / 3 current = np.exp(-4 * np.log(2) * ( (self.debug_pos_mm['x'] - x0)**2 + (self.debug_pos_mm['y'] - y0)**2) / fwhm**2) * 1e-6 data.append([round(x_move, 2), round(y_move, 2), current]) innerpbar.update() # write the last row and invert order for even rows if indx_y % 2: data.reverse() with open(self.filename, mode='a') as csv_file: file_writer = csv.writer(csv_file) for entr in data: file_writer.writerow(entr) csv_file.close() outerpbar.update(1) done = True
class TestSimSpi(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.getcwd() + '/test_SimSpi.v']) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): size = self.chip['spi'].get_size() self.chip['gpio'].reset() self.assertEqual(size, 16 * 8) self.chip['spi'].set_data(range(16)) ret = self.chip['spi'].get_data(size=16, addr=0) # to read back what was written self.assertEqual(ret.tolist(), range(16)) self.chip['spi'].set_data(range(16)) ret = self.chip['spi'].get_data(addr=0) # to read back what was written self.assertEqual(ret.tolist(), range(16)) self.chip['spi'].start() while(not self.chip['spi'].is_done()): pass ret = self.chip['spi'].get_data() # read back what was received (looped) self.assertEqual(ret.tolist(), range(16)) # ext_start self.chip['spi'].set_en(1) self.assertEqual(self.chip['spi'].get_en(), 1) self.chip['PULSE_GEN'].set_delay(1) self.chip['PULSE_GEN'].set_width(1+size) self.chip['PULSE_GEN'].set_repeat(1) self.assertEqual(self.chip['PULSE_GEN'].get_delay(), 1) self.assertEqual(self.chip['PULSE_GEN'].get_width(), 1+size) self.assertEqual(self.chip['PULSE_GEN'].get_repeat(), 1) self.chip['PULSE_GEN'].start() while(not self.chip['PULSE_GEN'].is_done()): pass ret = self.chip['spi'].get_data() # read back what was received (looped) self.assertEqual(ret.tolist(), range(16)) # spi_rx ret = self.chip['spi_rx'].get_en() self.assertEqual(ret, False) self.chip['spi_rx'].set_en(True) ret = self.chip['spi_rx'].get_en() self.assertEqual(ret, True) self.chip['spi'].start() while(not self.chip['spi'].is_done()): pass ret = self.chip['fifo'].get_fifo_size() self.assertEqual(ret, 32) ret = self.chip['fifo'].get_data() data0 = ret.astype(np.uint8) data1 = np.right_shift(ret, 8).astype(np.uint8) data = np.reshape(np.vstack((data1, data0)), -1, order='F') self.assertEqual(data.tolist(), range(16)) def test_dut_iter(self): conf = yaml.safe_load(cnfg_yaml) def iter_conf(): for item in conf['registers']: yield item for item in conf['hw_drivers']: yield item for item in conf['transfer_layer']: yield item for mod, mcnf in zip(self.chip, iter_conf()): self.assertEqual(mod.name, mcnf['name']) self.assertEqual(mod.__class__.__name__, mcnf['type']) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
# ------------------------------------------------------------ # Copyright (c) All rights reserved # SiLab, Institute of Physics, University of Bonn # ------------------------------------------------------------ # from basil.dut import Dut chip = Dut("mio3_eth_gpac.yaml") chip.init() chip['VDD'].set_current_limit(80, unit='mA') chip['VDD'].set_voltage(1.3, unit='V') chip['VDD'].set_enable(True) chip['CONTROL']['LED'] = 0xa5 chip['CONTROL'].write()
def scan(self, pix_list=((6, 20),), mask_steps=4, repeat_command=101, columns=[True] * 16, scan_range=[0, 1.2, 0.1], vthin1Dac=80, vthin2Dac=0, PrmpVbpDac=80, preCompVbnDac=50, mask_filename='', **kwargs): '''Scan loop This scan is to measure time walk. The charge injection can be driven by the GPAC or an external device. In the latter case the device is Agilent 33250a connected through serial port. The time walk and TOT are measured by a TDC module in the FPGA. The output is an .h5 file (data) and an .html file with plots. Parameters ---------- mask : int Number of mask steps. repeat : int Number of injections. ''' inj_factor = 1.0 INJ_LO = 0.0 try: dut = Dut(ScanBase.get_basil_dir(self) + '/examples/lab_devices/agilent33250a_pyserial.yaml') dut.init() logging.info('Connected to ' + str(dut['Pulser'].get_info())) except RuntimeError: INJ_LO = 0.2 inj_factor = 2.0 logging.info('External injector not connected. Switch to internal one') self.dut['INJ_LO'].set_voltage(INJ_LO, unit='V') self.dut['global_conf']['PrmpVbpDac'] = 80 # self.dut['global_conf']['vthin1Dac'] = 255 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['vffDac'] = 24 self.dut['global_conf']['PrmpVbnFolDac'] = 51 self.dut['global_conf']['vbnLccDac'] = 1 self.dut['global_conf']['compVbnDac'] = 25 self.dut['global_conf']['preCompVbnDac'] = 110 # 50 self.dut.write_global() self.dut['control']['RESET'] = 0b01 self.dut['control']['DISABLE_LD'] = 0 self.dut['control']['PIX_D_CONF'] = 0 self.dut['control'].write() self.dut['control']['CLK_OUT_GATE'] = 1 self.dut['control']['CLK_BX_GATE'] = 1 self.dut['control'].write() time.sleep(0.1) self.dut['control']['RESET'] = 0b11 self.dut['control'].write() self.dut['global_conf']['OneSr'] = 1 self.dut['global_conf']['TestHit'] = 0 self.dut['global_conf']['SignLd'] = 0 self.dut['global_conf']['InjEnLd'] = 0 self.dut['global_conf']['TDacLd'] = 0 self.dut['global_conf']['PixConfLd'] = 0 self.dut.write_global() self.dut['global_conf']['ColEn'][:] = bitarray.bitarray([True] * 16) # (columns) self.dut['global_conf']['ColSrEn'][:] = bitarray.bitarray([True] * 16) self.dut.write_global() self.dut['pixel_conf'].setall(False) self.dut.write_pixel() self.dut['global_conf']['InjEnLd'] = 1 self.dut.write_global() self.dut['global_conf']['InjEnLd'] = 0 mask_en = np.full([64, 64], False, dtype=np.bool) mask_tdac = np.full([64, 64], 16, dtype=np.uint8) for inx, col in enumerate(columns): if col: mask_en[inx * 4:(inx + 1) * 4, :] = True if mask_filename: logging.info('Using pixel mask from file: %s', mask_filename) with tb.open_file(mask_filename, 'r') as in_file_h5: mask_tdac = in_file_h5.root.scan_results.tdac_mask[:] mask_en = in_file_h5.root.scan_results.en_mask[:] self.dut.write_en_mask(mask_en) self.dut.write_tune_mask(mask_tdac) self.dut['global_conf']['OneSr'] = 1 self.dut.write_global() self.dut['inj'].set_delay(50000) # 1 zero more self.dut['inj'].set_width(1000) self.dut['inj'].set_repeat(repeat_command) self.dut['inj'].set_en(False) self.dut['trigger'].set_delay(400 - 4) self.dut['trigger'].set_width(16) self.dut['trigger'].set_repeat(1) self.dut['trigger'].set_en(False) logging.debug('Enable TDC') self.dut['tdc']['RESET'] = True self.dut['tdc']['EN_TRIGGER_DIST'] = True self.dut['tdc']['ENABLE_EXTERN'] = False self.dut['tdc']['EN_ARMING'] = False self.dut['tdc']['EN_INVERT_TRIGGER'] = False self.dut['tdc']['EN_INVERT_TDC'] = False self.dut['tdc']['EN_WRITE_TIMESTAMP'] = True scan_range = np.arange(scan_range[0], scan_range[1], scan_range[2]) / inj_factor scan_range = np.append(scan_range, 0.3 / inj_factor) scan_range = np.append(scan_range, 0.6 / inj_factor) scan_range = np.append(scan_range, 1.0 / inj_factor) self.pixel_list = pix_list p_counter = 0 for pix in pix_list: mask_en = np.full([64, 64], False, dtype=np.bool) mask_en[pix[0], pix[1]] = True self.dut.write_en_mask(mask_en) self.dut.write_inj_mask(mask_en) self.inj_charge = [] for idx, k in enumerate(scan_range): dut['Pulser'].set_voltage(INJ_LO, float(INJ_LO + k), unit='V') self.dut['INJ_HI'].set_voltage(float(INJ_LO + k), unit='V') self.inj_charge.append(float(k) * 1000.0 * analysis.cap_fac()) time.sleep(0.5) with self.readout(scan_param_id=idx + p_counter * len(scan_range)): logging.info('Scan Parameter: %f (%d of %d)', k, idx + 1, len(scan_range)) self.dut['tdc']['ENABLE'] = True self.dut['global_conf']['vthin1Dac'] = 255 self.dut['global_conf']['vthin2Dac'] = 0 self.dut['global_conf']['PrmpVbpDac'] = 80 self.dut['global_conf']['preCompVbnDac'] = 50 self.dut.write_global() time.sleep(0.1) self.dut['global_conf']['vthin1Dac'] = vthin1Dac self.dut['global_conf']['vthin2Dac'] = vthin2Dac self.dut['global_conf']['PrmpVbpDac'] = PrmpVbpDac self.dut['global_conf']['preCompVbnDac'] = preCompVbnDac self.dut.write_global() time.sleep(0.1) self.dut['inj'].start() while not self.dut['inj'].is_done(): pass while not self.dut['trigger'].is_done(): pass self.dut['tdc'].ENABLE = 0 p_counter += 1
class TestSimTlu(unittest.TestCase): def setUp(self): cocotb_compile_and_run([os.path.join(os.path.dirname(__file__), 'test_SimTlu.v')]) self.chip = Dut(cnfg_yaml) self.chip.init() def test_simple_trigger_veto(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 2 self.chip['tlu'].TRIGGER_VETO_SELECT = 2 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x07]) # trigger + veto self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 1) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 1) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) def test_simple_trigger_veto_disabled(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 2 self.chip['tlu'].TRIGGER_VETO_SELECT = 252 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x01]) # issue a second time, wait for reset self.chip['gpio'].set_data([0x07]) # trigger + veto self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 2) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 2) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) def test_simple_trigger_threshold(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 4 # select single pulse trigger self.chip['tlu'].TRIGGER_THRESHOLD = 1 # at least two clock cycles # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x01]) # issue a second time, wait for reset self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 2) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 2) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_THRESHOLD = 2 # at least two clock cycles self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 0) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 0) def test_simple_trigger_max_triggers(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].MAX_TRIGGERS = 2 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 2 self.chip['tlu'].TRIGGER_VETO_SELECT = 252 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU self.chip['gpio'].set_data([0x03]) # trigger self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertEqual(self.chip['sram'].get_fifo_int_size(), 2) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 2) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 0) self.assertEqual(data[1], 0x80000000 + 1) def test_simple_trigger(self): self.chip['tlu'].TRIGGER_COUNTER = 10 self.chip['tlu'].TRIGGER_MODE = 0 self.chip['tlu'].TRIGGER_SELECT = 1 self.chip['tlu'].TRIGGER_VETO_SELECT = 0 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU readings = 0 while(self.chip['sram'].get_fifo_int_size() < 4 and readings < 1000): readings += 1 # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertGreaterEqual(self.chip['sram'].get_fifo_int_size(), 4) self.assertGreaterEqual(self.chip['tlu'].TRIGGER_COUNTER, 14) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000 + 10) self.assertEqual(data[1], 0x80000000 + 11) self.assertEqual(data[2], 0x80000000 + 12) self.assertEqual(data[3], 0x80000000 + 13) def test_tlu_trigger_handshake(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 3 self.chip['tlu'].TRIGGER_VETO_SELECT = 255 self.chip['tlu'].EN_TLU_VETO = 0 # self.chip['tlu'].DATA_FORMAT = 2 # self.chip['tlu'].TRIGGER_LOW_TIMEOUT = 5 # self.chip['tlu'].TRIGGER_HANDSHAKE_ACCEPT_WAIT_CYCLES = 0 # self.chip['tlu'].HANDSHAKE_BUSY_VETO_WAIT_CYCLES = 0 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) readings = 0 while(self.chip['sram'].get_fifo_int_size() < 4 and readings < 1000): readings += 1 # self.chip['CONTROL']['ENABLE'] = 0 self.chip['gpio'].set_data([0x00]) self.assertGreaterEqual(self.chip['sram'].get_fifo_int_size(), 4) self.assertGreaterEqual(self.chip['tlu'].TRIGGER_COUNTER, 4) self.assertGreaterEqual(self.chip['tlu'].CURRENT_TLU_TRIGGER_NUMBER, 3) data = self.chip['sram'].get_data() self.assertEqual(data[0], 0x80000000) self.assertEqual(data[1], 0x80000001) self.assertEqual(data[2], 0x80000002) self.assertEqual(data[3], 0x80000003) def test_tlu_trigger_handshake_veto(self): self.chip['tlu'].TRIGGER_COUNTER = 0 self.chip['tlu'].TRIGGER_MODE = 3 self.chip['tlu'].TRIGGER_VETO_SELECT = 1 self.chip['tlu'].EN_TLU_VETO = 1 # self.chip['CONTROL']['ENABLE'] = 1 self.chip['gpio'].set_data([0x01]) # ext enable trigger/TLU readings = 0 while(self.chip['sram'].get_fifo_int_size() == 0 and readings < 1000): readings += 1 self.assertEqual(self.chip['sram'].get_fifo_int_size(), 0) self.assertEqual(self.chip['tlu'].TRIGGER_COUNTER, 0) self.assertEqual(self.chip['tlu'].CURRENT_TLU_TRIGGER_NUMBER, 0) def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()
class TestSimFifo8to32(unittest.TestCase): def __init__(self, testname, tb='test_SimFifo8to32.v', bus_drv='basil.utils.sim.BasilBusDriver', bus_split=False): super(TestSimFifo8to32, self).__init__(testname) self._test_tb = tb self._sim_bus = bus_drv self._bus_split_def = () if bus_split is not False: if bus_split == 'sbus': self._bus_split_def = ("BASIL_SBUS", ) elif bus_split == 'top': self._bus_split_def = ("BASIL_TOPSBUS", ) def setUp(self): cocotb_compile_and_run( sim_files=[os.path.join(os.path.dirname(__file__), self._test_tb)], sim_bus=self._sim_bus, extra_defines=self._bus_split_def) self.chip = Dut(cnfg_yaml) self.chip.init() def test_io(self): for i in range(4): self.chip['INTF'].write(0x1000, [i]) data = [] iterations = 1000 i = 0 while not len(data) == 1: if i >= iterations: break data.extend(self.chip['FIFO'].get_data()) i += 1 assert data[0] == 50462976 self.chip['INTF'].write(0x1000, [4, 5, 6, 7]) data = [] iterations = 1000 i = 0 while not len(data) == 1: if i >= iterations: break data.extend(self.chip['FIFO'].get_data()) i += 1 assert data[0] == 117835012 self.chip['INTF'].write(0x1000, range(8)) data = [] iterations = 1000 i = 0 while not len(data) == 2: if i >= iterations: break data.extend(self.chip['FIFO'].get_data()) i += 1 assert data[0] == 50462976 assert data[1] == 117835012 def tearDown(self): self.chip.close() # let it close connection and stop simulator cocotb_compile_clean()