├── .github └── workflows │ └── regression-tests.yml ├── .gitignore ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── VERSION ├── basil ├── HL │ ├── FEI4AdapterCard.py │ ├── FEI4QuadModuleAdapterCard.py │ ├── FadcConf.py │ ├── GPAC.py │ ├── HardwareLayer.py │ ├── JtagGpio.py │ ├── JtagMaster.py │ ├── MIO_PLL.py │ ├── NTCRegister.py │ ├── RegisterHardwareLayer.py │ ├── SensirionBridgeDevice.py │ ├── SentioProber.py │ ├── SignatoneProber.py │ ├── SussProber.py │ ├── XPT.py │ ├── __init__.py │ ├── agilent33250a.py │ ├── agilent_33250a.yaml │ ├── agilent_e3644a.yaml │ ├── arduino_base.py │ ├── arduino_env_readout.py │ ├── arduino_ntc_readout.py │ ├── arduino_relay_board.py │ ├── arduino_serial_to_i2c.py │ ├── binder_mk53.py │ ├── binder_mk56.py │ ├── bram_fifo.py │ ├── bronkhorst_elflow.py │ ├── cmd_seq.py │ ├── debyeflex3003.py │ ├── fadc_rx.py │ ├── fast_spi_rx.py │ ├── fei4_rx.py │ ├── gpio.py │ ├── hp4284a.py │ ├── hp_4284a.yaml │ ├── hp_81104a.yaml │ ├── i2c.py │ ├── iseg_hv.py │ ├── julabo1000F.py │ ├── julaboF32HD.py │ ├── julaboFP50.py │ ├── keithley6517a.py │ ├── keithley_2000.yaml │ ├── keithley_2001.yaml │ ├── keithley_2400.yaml │ ├── keithley_2410.yaml │ ├── keithley_2450.yaml │ ├── keithley_2460.yaml │ ├── keithley_2470.yaml │ ├── keithley_2602a.yaml │ ├── keithley_2634b.yaml │ ├── keithley_6517a.yaml │ ├── m26_rx.py │ ├── mercury.py │ ├── pulse_gen.py │ ├── rs_hmp4040.py │ ├── rs_hmp4040.yaml │ ├── scpi.py │ ├── scpi_sim_device.yaml │ ├── sensirion_ekh4.py │ ├── sensirion_sht85.py │ ├── seq_gen.py │ ├── seq_rec.py │ ├── si570.py │ ├── sitcp_fifo.py │ ├── spi.py │ ├── sram_fifo.py │ ├── tdc_s3.py │ ├── tektronix_oscilloscope.py │ ├── tektronix_oscilloscope.yaml │ ├── tektronix_tds3034b.py │ ├── timestamp.py │ ├── tlu.py │ ├── tti_ql355tp.py │ ├── tti_ql355tp.yaml │ ├── weiss_labevent.py │ └── weiss_sb22.py ├── RL │ ├── FunctionalRegister.py │ ├── RegisterLayer.py │ ├── StdRegister.py │ ├── TrackRegister.py │ └── __init__.py ├── TL │ ├── Dummy.py │ ├── SensirionSensorBridge.py │ ├── Serial.py │ ├── SiSim.py │ ├── SiTcp.py │ ├── SiTransferLayer.py │ ├── SiUart.py │ ├── SiUsb.py │ ├── SiUsb3.py │ ├── Socket.py │ ├── TransferLayer.py │ ├── Visa.py │ └── __init__.py ├── __init__.py ├── dut.py ├── firmware │ ├── arduino │ │ ├── EnvironmentReadout │ │ │ ├── EnvironmentReadout.ino │ │ │ └── Readme.rst │ │ ├── NTCReadout │ │ │ ├── NTCReadout.ino │ │ │ └── README.rst │ │ ├── RelayBoard │ │ │ ├── README.rst │ │ │ └── RelayBoard.ino │ │ └── SerialToI2C │ │ │ ├── README.rst │ │ │ └── SerialToI2C.ino │ └── modules │ │ ├── LICENSE.txt │ │ ├── README.rst │ │ ├── bram_fifo │ │ ├── README.rst │ │ ├── bram_fifo.v │ │ └── bram_fifo_core.v │ │ ├── chipscope │ │ ├── chipscope_icon.xco │ │ ├── chipscope_icon.xise │ │ ├── chipscope_ila.xco │ │ └── chipscope_ila.xise │ │ ├── cmd_seq │ │ ├── README.rst │ │ ├── cmd_seq.v │ │ └── cmd_seq_core.v │ │ ├── fast_spi_rx │ │ ├── README.rst │ │ ├── fast_spi_rx.v │ │ └── fast_spi_rx_core.v │ │ ├── fei4_rx │ │ ├── README.rst │ │ ├── decode_8b10b.v │ │ ├── fei4_rx.v │ │ ├── fei4_rx_core.v │ │ ├── rec_sync.v │ │ ├── receiver_logic.v │ │ └── sync_master.v │ │ ├── fx3_if │ │ └── FX3_IF.v │ │ ├── gpac_adc_rx │ │ ├── README.rst │ │ ├── gpac_adc_iobuf.v │ │ ├── gpac_adc_rx.v │ │ └── gpac_adc_rx_core.v │ │ ├── gpio │ │ ├── README.rst │ │ ├── gpio.v │ │ ├── gpio_core.v │ │ └── gpio_sbus.v │ │ ├── i2c │ │ ├── README.rst │ │ ├── i2c.v │ │ └── i2c_core.v │ │ ├── includes │ │ └── log2func.v │ │ ├── jtag_master │ │ ├── README.rst │ │ ├── jtag_master.v │ │ └── jtag_master_core.v │ │ ├── m26_rx │ │ ├── README.rst │ │ ├── m26_rx.v │ │ ├── m26_rx_ch.v │ │ └── m26_rx_core.v │ │ ├── pulse_gen │ │ ├── README.rst │ │ ├── pulse_gen.v │ │ └── pulse_gen_core.v │ │ ├── rrp_arbiter │ │ ├── README.rst │ │ └── rrp_arbiter.v │ │ ├── seq_gen │ │ ├── README.rst │ │ ├── seq_gen.v │ │ └── seq_gen_core.v │ │ ├── seq_rec │ │ ├── README.rst │ │ ├── seq_rec.v │ │ └── seq_rec_core.v │ │ ├── spi │ │ ├── README.rst │ │ ├── blk_mem_gen_8_to_1_2k.v │ │ ├── spi.v │ │ └── spi_core.v │ │ ├── sram_fifo │ │ ├── sram_fifo.v │ │ └── sram_fifo_core.v │ │ ├── tb │ │ ├── silbusb.sv │ │ ├── silbusb.v │ │ └── uartlib.v │ │ ├── tdc_s3 │ │ ├── README.rst │ │ ├── tdc_s3.v │ │ └── tdc_s3_core.v │ │ ├── timestamp │ │ ├── README.rst │ │ ├── timestamp.v │ │ └── timestamp_core.v │ │ ├── tlu │ │ ├── README.rst │ │ ├── tlu_controller.v │ │ ├── tlu_controller_core.v │ │ └── tlu_controller_fsm.v │ │ ├── uart │ │ ├── README.rst │ │ ├── uart.v │ │ └── uart_master.v │ │ └── utils │ │ ├── 3_stage_synchronizer.v │ │ ├── BUFG_sim.v │ │ ├── CG_MOD_neg.v │ │ ├── CG_MOD_pos.v │ │ ├── DCM_sim.v │ │ ├── IBUFDS_sim.v │ │ ├── IBUFGDS_sim.v │ │ ├── IDDR_s3.v │ │ ├── IDDR_s3_noibuf.v │ │ ├── IDDR_s6.v │ │ ├── IDDR_sim.v │ │ ├── OBUFDS_sim.v │ │ ├── ODDR_s3.v │ │ ├── ODDR_s6.v │ │ ├── ODDR_sim.v │ │ ├── RAMB16_S1_S2_sim.v │ │ ├── RAMB16_S1_S9_sim.v │ │ ├── README.rst │ │ ├── bus_to_ip.v │ │ ├── cdc_pulse_sync.v │ │ ├── cdc_pulse_sync_cnt.v │ │ ├── cdc_reset_sync.v │ │ ├── cdc_syncfifo.v │ │ ├── clock_divider.v │ │ ├── clock_multiplier.v │ │ ├── ddr_des.v │ │ ├── fifo_32_to_8.v │ │ ├── fifo_64_to_16.v │ │ ├── fifo_8_to_32.v │ │ ├── fifo_8_to_64.v │ │ ├── flag_domain_crossing.v │ │ ├── fx2_to_bus.v │ │ ├── generic_fifo.v │ │ ├── pulse_gen_rising.v │ │ ├── ramb_8_to_n.v │ │ ├── rbcp_to_bus.v │ │ ├── reset_gen.v │ │ ├── rgmii_io.v │ │ ├── sbus_to_ip.v │ │ ├── simple_arbiter.v │ │ └── tcp_to_bus.v └── utils │ ├── BitLogic.py │ ├── DataManipulation.py │ ├── USBBinds.py │ ├── __init__.py │ ├── sim │ ├── BasilBusDriver.py │ ├── BasilSbusDriver.py │ ├── Protocol.py │ ├── SiLibUsb.py │ ├── SiLibUsbBusDriver.py │ ├── Test.py │ ├── __init__.py │ └── utils.py │ └── utils.py ├── docs ├── Makefile ├── _static │ ├── MIO.jpg │ ├── MIO_GPAC_DUT.png │ ├── WaveDrom_load.js │ ├── basil_layers.png │ ├── lx9_fei4_a.jpg │ ├── lx9_fei4_b.jpg │ ├── spi_example.png │ ├── spi_example_timing.png │ └── theme_overrides.css ├── conf.py ├── examples.rst ├── firmware.rst ├── hardware.rst ├── index.rst ├── introduction.rst ├── make.bat ├── modules.rst ├── requirements.txt └── software.rst ├── examples ├── MIO │ ├── ise │ │ ├── .gitignore │ │ └── example.xise │ ├── src │ │ ├── example.v │ │ └── mio.ucf │ └── tb │ │ ├── example.py │ │ ├── example.yaml │ │ └── test_SimExample.py ├── MMC3 │ ├── mmc3.srcs │ │ ├── constrs_1 │ │ │ └── mmc3.xdc │ │ └── sources_1 │ │ │ ├── mmc3_constants.v │ │ │ └── mmc3_top.v │ └── mmc3.xpr ├── bdaq │ ├── .gitignore │ ├── Readme.md │ ├── bdaq53_eth.py │ ├── bdaq53_eth.yaml │ ├── firmware │ │ ├── src │ │ │ ├── SiTCP.xdc │ │ │ ├── bdaq53.xdc │ │ │ ├── bdaq53_eth.v │ │ │ └── bdaq53_eth_core.v │ │ └── vivado │ │ │ ├── Makefile │ │ │ └── run.tcl │ └── test │ │ ├── bdaq53_eth_tb.v │ │ └── test_bdaq53_eth.py ├── lab_devices │ ├── MotorStage.py │ ├── ProbeStation.py │ ├── SentioProber.py │ ├── SentioProber_config.yaml │ ├── SignatoneProber.yaml │ ├── WeissLabEvent_socket.yaml │ ├── WeissSB22_pyserial.yaml │ ├── agilent33250a_pyserial.yaml │ ├── arduino_ntc_readout.py │ ├── arduino_ntc_readout.yaml │ ├── arduino_relay_board.py │ ├── arduino_relay_board.yaml │ ├── arduino_serial_to_i2c.py │ ├── arduino_serial_to_i2c.yaml │ ├── binderMK53_pyserial.yaml │ ├── binderMK56_socket.yaml │ ├── bronkhorstELFLOW_pyserial.yaml │ ├── bronkhorsteflow.py │ ├── hp_4284a_pyvisa.yaml │ ├── hp_81104a_pyvisa.yaml │ ├── iseg_shq.py │ ├── iseg_shq.yaml │ ├── julabo1000F_pyserial.yaml │ ├── julaboF32HD.py │ ├── julaboF32HD.yaml │ ├── julaboFP50.py │ ├── julaboFP50_pyserial.yaml │ ├── keithley2000_pyvisa.yaml │ ├── keithley2400_pyserial.yaml │ ├── keithley2400_pyvisa.yaml │ ├── keithley2410_pyserial.yaml │ ├── keithley2410_pyvisa.yaml │ ├── keithley2450_pyvisa.yaml │ ├── keithley2634b.yaml │ ├── keithley6517a.py │ ├── keithley6517a_pyvisa.yaml │ ├── mercury_pyserial.yaml │ ├── rs_hmp4040.yaml │ ├── rs_hmp4040_pyvisa.yaml │ ├── scpi_devices.py │ ├── sensirionEKH4_pyserial.yaml │ ├── sensirionSHT85.yaml │ ├── suss_pa_200.yaml │ ├── tektronixOscilloscope_pyvisa.yaml │ ├── tektronix_oscilloscope_tds3034b.py │ ├── tektronix_tds_3034b.yaml │ ├── temperature_control.py │ ├── temperature_sensors.py │ ├── ttiql355tp.yaml │ ├── ttiql355tp_pyvisa.yaml │ ├── xray_tube.py │ └── xray_tube_pyserial.yaml ├── lx9 │ ├── device │ │ ├── ise │ │ │ ├── .gitignore │ │ │ ├── lx9.xise │ │ │ └── top.bit │ │ └── src │ │ │ ├── top.ucf │ │ │ └── top.v │ └── host │ │ ├── lx9.py │ │ └── lx9.yaml ├── mio3_eth_gpac │ ├── README.md │ ├── firmware │ │ ├── src │ │ │ ├── mio3_eth_gpac.v │ │ │ └── mio3_eth_gpac.xdc │ │ └── vivado │ │ │ └── mio3_eth_gpac.xpr │ ├── mio3_eth_gpac.py │ └── mio3_eth_gpac.yaml ├── mio_pixel │ ├── firmware │ │ ├── ise │ │ │ ├── .gitignore │ │ │ └── pixel.xise │ │ └── src │ │ │ ├── clk_gen.v │ │ │ ├── pixel.ucf │ │ │ └── pixel.v │ ├── pixel.py │ ├── pixel.yaml │ └── tests │ │ ├── tb.v │ │ └── test_Sim_mio_pixel.py ├── mio_sram_test │ ├── firmware │ │ ├── ise │ │ │ ├── .gitignore │ │ │ └── sram_test.xise │ │ └── src │ │ │ ├── mio.ucf │ │ │ └── sram_test.v │ ├── sram_test.py │ ├── sram_test.yaml │ └── tests │ │ ├── tb.v │ │ └── test_Sim.py ├── mmc3_eth │ ├── Readme.md │ ├── firmware │ │ ├── src │ │ │ ├── mmc3.xdc │ │ │ ├── mmc3_eth.v │ │ │ └── mmc3_eth_core.v │ │ └── vivado │ │ │ └── mmc3_eth.xpr │ ├── mmc3_eth.py │ ├── mmc3_eth.yaml │ └── test │ │ ├── mmc3_eth_tb.v │ │ └── test_mmc3_eth.py ├── register_example │ ├── simple_register_example.py │ └── simple_register_example.yaml └── test_eth │ ├── firmware_test_eth │ ├── src │ │ ├── SiTCP.xdc │ │ ├── SiTCP │ │ │ └── .gitignore │ │ ├── mmc3.xdc │ │ └── test_eth.v │ └── vivado │ │ └── test_eth.xpr │ └── test_eth.py ├── requirements.txt ├── setup.cfg ├── setup.py └── tests ├── formatting.yaml ├── jtag_tap.v ├── test_BitLogic.py ├── test_RegisterHardwareLayer.py ├── test_RegisterHardwareLayer.yaml ├── test_RegisterHardwareLayer_configuration.yaml ├── test_SimAdcRx.py ├── test_SimAdcRx.v ├── test_SimCmdSeq.py ├── test_SimCmdSeq.v ├── test_SimFifo8to32.py ├── test_SimFifo8to32.v ├── test_SimGpio.py ├── test_SimGpio.v ├── test_SimI2c.py ├── test_SimI2c.v ├── test_SimJtagGpio.py ├── test_SimJtagGpio.v ├── test_SimJtagMaster.py ├── test_SimJtagMaster.v ├── test_SimM26.py ├── test_SimM26.v ├── test_SimSCPIFormatting.py ├── test_SimScpi.py ├── test_SimSeq.py ├── test_SimSeq.v ├── test_SimSpi.py ├── test_SimSpi.v ├── test_SimTdc.py ├── test_SimTdc.v ├── test_SimTimestamp.py ├── test_SimTimestamp.v ├── test_SimTlu.py ├── test_SimTlu.v └── test_StdRegister.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *~ 5 | *.swp 6 | *.py~ 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # icarus verilog 30 | host/tests/Makefile 31 | *.vvp 32 | 33 | #docs 34 | docs/_build 35 | *.vcd 36 | tests/results.xml 37 | examples/lx9/device/src/SiTCP 38 | 39 | # PyDev files 40 | .project 41 | .pydevproject 42 | .vcd 43 | 44 | # Mac 45 | .DS_Store 46 | tests/qverilog.log 47 | tests/work 48 | results.xml 49 | 50 | firmware/modules/chipscope/* 51 | !firmware/modules/chipscope/*.xise 52 | !firmware/modules/chipscope/*.xco 53 | 54 | examples/mmc3_eth/firmware/vivado/* 55 | !examples/mmc3_eth/firmware/vivado/*.xpr 56 | examples/mmc3_eth/firmware/src/SiTCP/* 57 | 58 | examples/mio3_eth_gpac/firmware/vivado/* 59 | !examples/mio3_eth_gpac/firmware/vivado/*.xpr 60 | examples/mio3_eth_gpac/firmware/src/SiTCP/* 61 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2018 SiLab, Institute of Physics, University of Bonn 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 26 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.* VERSION LICENSE.txt requirements.txt 2 | recursive-include docs * 3 | recursive-include examples * 4 | recursive-include basil/firmware * 5 | recursive-include tests * 6 | recursive-include basil *.yaml 7 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 3.3.0 2 | -------------------------------------------------------------------------------- /basil/HL/FadcConf.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | 7 | import logging 8 | 9 | from basil.HL.RegisterHardwareLayer import HardwareLayer 10 | 11 | 12 | logger = logging.getLogger(__name__) 13 | 14 | 15 | class FadcConf(HardwareLayer): 16 | 17 | def __init__(self, intf, conf): 18 | super(FadcConf, self).__init__(intf, conf) 19 | 20 | def init(self): 21 | super(FadcConf, self).init() 22 | logger.info("Initializing FADC Configuration...") 23 | 24 | self._intf.set_data([0x00, 0x10]) # RESET ADC 25 | self._intf.start() 26 | while not self._intf.is_done(): 27 | pass 28 | 29 | self._intf.set_data([0x02, 0x07]) # SET 16 bit mode 30 | self._intf.start() 31 | while not self._intf.is_done(): 32 | pass 33 | 34 | self._intf.set_data([0x03, 0x00]) # PATTERN OFF 35 | self._intf.start() 36 | while not self._intf.is_done(): 37 | pass 38 | 39 | def enable_pattern(self, pattern): 40 | self._intf.set_data([0x03, 0x80 | ((pattern & 0x3f00) >> 8)]) 41 | self._intf.start() 42 | while not self._intf.is_done(): 43 | pass 44 | 45 | self._intf.set_data([0x04, pattern & 0xff]) 46 | self._intf.start() 47 | while not self._intf.is_done(): 48 | pass 49 | -------------------------------------------------------------------------------- /basil/HL/SensirionBridgeDevice.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Copyright (c) All rights reserved 3 | # SiLab, Institute of Physics, University of Bonn 4 | # ------------------------------------------------------------ 5 | # 6 | 7 | from basil.HL.RegisterHardwareLayer import HardwareLayer 8 | from basil.TL.SensirionSensorBridge import TimeoutError 9 | 10 | 11 | class SensirionBridgeI2CDevice(HardwareLayer): 12 | ''' 13 | Driver for I2C devices connected to a Sensirion Sensor Bridge. 14 | The device has to be connected to one of the two ports of the Sensirion Sensor Bridge. 15 | ''' 16 | 17 | def __init__(self, intf, conf): 18 | super(SensirionBridgeI2CDevice, self).__init__(intf, conf) 19 | self.TimeoutError = TimeoutError 20 | 21 | def init(self, address): 22 | super(SensirionBridgeI2CDevice, self).init() 23 | 24 | self.port = self._intf.bridge_ports[self._init.get('bridgePort', 'one')] 25 | 26 | self.address = address 27 | 28 | self.power_on() 29 | 30 | def _read(self, command, read_n_bytes=0, timeout_us=100e3): 31 | return self._intf.read_i2c(device=self.device, port=self.port, address=self.address, 32 | command=command, read_n_bytes=read_n_bytes, timeout_us=timeout_us) 33 | 34 | def _write(self, command): 35 | self._intf.write_i2c(device=self.device, port=self.port, address=self.address, command=command) 36 | 37 | def printInformation(self): 38 | self._intf.print_i2c_device_information(device=self.device) 39 | 40 | def power_on(self): 41 | self.device = self._intf.setup_i2c_device(bridge_port=self.port, **self._init) 42 | 43 | def power_off(self): 44 | if hasattr(self, 'device'): 45 | self._intf.disable_i2c_device(self.device, bridge_port=self.port) 46 | 47 | def __del__(self): 48 | self.close() 49 | 50 | def close(self): 51 | self.power_off() 52 | super(SensirionBridgeI2CDevice, self).close() 53 | -------------------------------------------------------------------------------- /basil/HL/SignatoneProber.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | import re 9 | from basil.HL.RegisterHardwareLayer import HardwareLayer 10 | 11 | 12 | class SignatoneProber(HardwareLayer): 13 | ''' 14 | Implements functions to steer a Signatone probe station such as the one of lal in2p3 in Paris. 15 | ''' 16 | 17 | def __init__(self, intf, conf): 18 | super(SignatoneProber, self).__init__(intf, conf) 19 | 20 | def goto_die(self, index_x, index_y): 21 | ''' Move chuck to wafer map chip index''' 22 | index_x = abs(index_x) * -1 23 | index_y = abs(index_y) * -1 24 | self._intf.write('MOVECR %d, %d' % (index_x, index_y)) 25 | 26 | def goto_next_die(self): 27 | ''' Move chuck to next die from wafer map''' 28 | self._intf.write('NEXT') 29 | 30 | def goto_first_die(self): 31 | ''' Move chuck to first die from wafer map''' 32 | self._intf.write('TOFIRSTSITE') 33 | 34 | def get_die(self): 35 | ''' Get chip index ''' 36 | reply = '' 37 | for n in range(10): 38 | if reply == '0:' or reply == '': 39 | reply = self._intf.query('GETCR') 40 | else: 41 | break 42 | 43 | reply = re.sub(r'[a-zA-Z]', r'', reply) 44 | values = reply.split(',') 45 | 46 | return (int(values[0]), int(values[1])) 47 | 48 | def contact(self): 49 | ''' Move chuck to contact z position''' 50 | self._intf.write('ZCHUCKUP') 51 | 52 | def separate(self): 53 | ''' Move chuck to separation z position''' 54 | self._intf.write('ZCHUCKDOWN') 55 | 56 | def load(self): 57 | ''' Move chuck to load z position''' 58 | self._intf.write('LOADWAFER') 59 | 60 | def get_id(self): 61 | ''' Get id ''' 62 | return self._intf.query('*IDN?') 63 | -------------------------------------------------------------------------------- /basil/HL/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/basil/HL/__init__.py -------------------------------------------------------------------------------- /basil/HL/agilent33250a.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.scpi import scpi 9 | 10 | 11 | class agilent33250a(scpi): 12 | '''Interface for Agilent 33250A Function/Arbitrary Waveform Generator implementing additional functionality. 13 | ''' 14 | 15 | def __init__(self, intf, conf): 16 | super(agilent33250a, self).__init__(intf, conf) 17 | 18 | def set_repeat(self, repeat): 19 | raise NotImplementedError("set_repeat() not implemented") 20 | 21 | def get_repeat(self, repeat): 22 | raise NotImplementedError("get_repeat() not implemented") 23 | 24 | def set_voltage(self, low, high=0.75, unit='mV'): 25 | if unit == 'raw': 26 | raw_low, raw_high = low, high 27 | elif unit == 'V': 28 | raw_low, raw_high = low, high 29 | elif unit == 'mV': 30 | raw_low, raw_high = low * 0.001, high * 0.001 31 | else: 32 | raise TypeError("Invalid unit type.") 33 | self.set_voltage_high(raw_high) 34 | self.set_voltage_low(raw_low) 35 | 36 | def get_voltage(self, channel, unit='mV'): 37 | raw_low, raw_high = float(self.get_voltage_low()), float(self.get_voltage_high()) 38 | if unit == 'raw': 39 | return raw_low, raw_high 40 | elif unit == 'V': 41 | return raw_low, raw_high 42 | elif unit == 'mV': 43 | return raw_low * 1000, raw_high * 1000 44 | else: 45 | raise TypeError("Invalid unit type.") 46 | 47 | def set_en(self, enable): # TODO: bad naming 48 | self.set_burst(1) if enable else self.set_burst(0) 49 | 50 | def get_en(self): # TODO: bad naming 51 | return self.get_burst() == 1 52 | 53 | def get_info(self): 54 | return self.get_name() 55 | -------------------------------------------------------------------------------- /basil/HL/agilent_e3644a.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Agilent Technologies E3644A Power Supply. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier: Agilent Technologies,E3644A 5 | get_voltage: MEAS:VOLT:DC? 6 | get_current: MEAS:CURR:DC? 7 | set_enable: OUTP:STAT 8 | get_enable: OUTP:STAT? 9 | -------------------------------------------------------------------------------- /basil/HL/arduino_relay_board.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.arduino_base import ArduinoBase 9 | 10 | 11 | class RelayBoard(ArduinoBase): 12 | ''' 13 | Implement functions to control the Arduino digital IO using the Basil Arduino firmware. 14 | ''' 15 | 16 | CMDS = { 17 | 'read': 'R', 18 | 'write': 'W', 19 | 'delay': 'D' 20 | } 21 | 22 | ERRORS = { 23 | 'error': "Serial transmission error" # Custom return code for unsuccesful serial communciation 24 | } 25 | 26 | def __init__(self, intf, conf): 27 | super(RelayBoard, self).__init__(intf, conf) 28 | 29 | def set_output(self, channel, value): 30 | if value == 'ON': 31 | value = 1 32 | elif value == 'OFF': 33 | value = 0 34 | 35 | if value != 0 and value != 1: 36 | raise ValueError('The value for the output has to be ON, OFF, 0 or 1') 37 | 38 | if channel == 'ALL': 39 | channel = 99 # All channels are internally channel 99 40 | 41 | if channel < 2 or (channel > 13 and channel != 99): 42 | raise ValueError('Arduino supports only 14 IOs and pins 0 and 1 are blocked by Serial communication. %d is out of range.' % channel) 43 | 44 | ret = self.query(self.create_command(self.CMDS['write'], channel, value)) 45 | 46 | error = False 47 | if channel == 99 and int(ret) != value * 1111111111: 48 | error = True 49 | elif channel != 99 and ret[channel - 2] != str(value): 50 | error = True 51 | 52 | if error: 53 | raise RuntimeError('Got no or wrong response from Arduino!') 54 | 55 | def get_state(self): 56 | return self.query(self.create_command(self.CMDS['read'])) 57 | -------------------------------------------------------------------------------- /basil/HL/fast_spi_rx.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.RegisterHardwareLayer import RegisterHardwareLayer 9 | 10 | 11 | class fast_spi_rx(RegisterHardwareLayer): 12 | '''Fast SPI interface 13 | ''' 14 | 15 | _registers = {'RESET': {'descr': {'addr': 0, 'size': 8, 'properties': ['writeonly']}}, 16 | 'VERSION': {'descr': {'addr': 0, 'size': 8, 'properties': ['ro']}}, 17 | 'EN': {'descr': {'addr': 2, 'size': 1, 'offset': 0}}, 18 | 'LOST_COUNT': {'descr': {'addr': 3, 'size': 8, 'properties': ['ro']}}} 19 | _require_version = "==0" 20 | 21 | def __init__(self, intf, conf): 22 | super(fast_spi_rx, self).__init__(intf, conf) 23 | 24 | def reset(self): 25 | '''Soft reset the module.''' 26 | self.RESET = 0 27 | 28 | def set_en(self, value): 29 | self.EN = value 30 | 31 | def get_en(self): 32 | return self.EN 33 | 34 | def get_lost_count(self): 35 | return self.LOST_COUNT 36 | -------------------------------------------------------------------------------- /basil/HL/fei4_rx.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | 9 | from basil.HL.RegisterHardwareLayer import RegisterHardwareLayer 10 | 11 | 12 | class fei4_rx(RegisterHardwareLayer): 13 | '''FEI4 receiver controller interface for fei4_rx FPGA module 14 | ''' 15 | 16 | _registers = {'RESET': {'descr': {'addr': 0, 'size': 8, 'properties': ['writeonly']}}, 17 | 'RX_RESET': {'descr': {'addr': 1, 'size': 8, 'properties': ['writeonly']}}, 18 | 'VERSION': {'descr': {'addr': 0, 'size': 8, 'properties': ['ro']}}, 19 | 'READY': {'descr': {'addr': 2, 'size': 1, 'properties': ['ro']}}, 20 | 'INVERT_RX': {'descr': {'addr': 2, 'size': 1, 'offset': 1}}, 21 | 'ENABLE_RX': {'descr': {'addr': 2, 'size': 1, 'offset': 2}}, 22 | 'FIFO_SIZE': {'default': 0, 'descr': {'addr': 3, 'size': 16, 'properties': ['ro']}}, 23 | 'DECODER_ERROR_COUNTER': {'descr': {'addr': 5, 'size': 8, 'properties': ['ro']}}, 24 | 'LOST_DATA_COUNTER': {'descr': {'addr': 6, 'size': 8, 'properties': ['ro']}}} 25 | _require_version = "==3" 26 | 27 | def __init__(self, intf, conf): 28 | super(fei4_rx, self).__init__(intf, conf) 29 | 30 | def reset(self): 31 | self.RESET = 0 32 | 33 | def rx_reset(self): 34 | self.RX_RESET = 0 35 | 36 | def is_done(self): 37 | return self.is_ready 38 | 39 | @property 40 | def is_ready(self): 41 | return self.READY 42 | 43 | def set_invert_rx(self, value): 44 | self.INVERT_RX = value 45 | 46 | def get_invert_rx(self): 47 | return self.INVERT_RX 48 | 49 | def get_fifo_size(self): 50 | return self.FIFO_SIZE 51 | 52 | def get_decoder_error_counter(self): 53 | return self.DECODER_ERROR_COUNTER 54 | 55 | def get_lost_data_counter(self): 56 | return self.LOST_DATA_COUNTER 57 | -------------------------------------------------------------------------------- /basil/HL/gpio.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.RegisterHardwareLayer import RegisterHardwareLayer 9 | 10 | 11 | class gpio(RegisterHardwareLayer): 12 | '''GPIO interface 13 | ''' 14 | 15 | def __init__(self, intf, conf): 16 | 17 | self._registers = {'RESET': {'descr': {'addr': 0, 'size': 8, 'properties': ['writeonly']}}, 18 | 'VERSION': {'descr': {'addr': 0, 'size': 8, 'properties': ['ro']}}} 19 | self._require_version = "==0" 20 | 21 | self._size = 8 22 | if 'size' in conf.keys(): 23 | self._size = conf['size'] 24 | 25 | io_bytes = int(((self._size - 1) / 8) + 1) 26 | 27 | self._registers['INPUT'] = {'descr': {'addr': 1, 'size': io_bytes, 'properties': ['ro', 'byte_array']}} 28 | self._registers['OUTPUT'] = {'descr': {'addr': 2 + io_bytes - 1, 'size': io_bytes, 'properties': ['byte_array']}} 29 | self._registers['OUTPUT_EN'] = {'descr': {'addr': 3 + 2 * (io_bytes - 1), 'size': io_bytes, 'properties': ['byte_array']}} 30 | # __init__() after updating register 31 | super(gpio, self).__init__(intf, conf) 32 | 33 | def init(self): 34 | super(gpio, self).init() 35 | if 'output_en' in self._init: 36 | self.OUTPUT_EN = self._init['output_en'] 37 | 38 | def reset(self): 39 | '''Soft reset the module.''' 40 | self.RESET = 0 41 | 42 | def set_output_en(self, value): 43 | self.OUTPUT_EN = value 44 | 45 | def get_output_en(self): 46 | return self.OUTPUT_EN 47 | 48 | def set_data(self, value): 49 | self.OUTPUT = value 50 | 51 | def get_data(self): 52 | return self.INPUT 53 | -------------------------------------------------------------------------------- /basil/HL/hp_4284a.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Hewlett Packard LCR meter. 2 | # Only GPIB shows working communication with this device! 3 | open_correction: CORR:OPEN 4 | short_correction: CORR:SHOR 5 | trigger: TRIG 6 | set_trigger_mode: TRIG:SOUR 7 | get_trigger_mode: TRIG:SOUR? 8 | set_ac_voltage: VOLT 9 | get_ac_voltage: VOLT? 10 | set_frequency: FREQ 11 | get_frequency: FREQ? 12 | set_meas_func: FUNC:IMP 13 | get_meas_func: FUNC:IMP? 14 | get_value: FETC? 15 | -------------------------------------------------------------------------------- /basil/HL/hp_81104a.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Hewlett Packard Pulse-/ Pattern Generator. 2 | # Only GPIB shows working communication with this device! 3 | identifier : HEWLETT-PACKARD,HP81104A 4 | 5 | channel 1: 6 | on : OUTP1:NORM:STAT ON 7 | off : OUTP1:NORM:STAT OFF 8 | 9 | channel 2: 10 | on : OUTP2:NORM:STAT ON 11 | off : OUTP2:NORM:STAT OFF 12 | 13 | on : OUTP1:NORM:STAT ON 14 | off : OUTP1:NORM:STAT OFF 15 | 16 | set_frequency : FREQ 17 | get_frequency : FREQ? 18 | -------------------------------------------------------------------------------- /basil/HL/julaboF32HD.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | import logging 9 | import time 10 | 11 | from basil.HL.RegisterHardwareLayer import HardwareLayer 12 | 13 | 14 | logger = logging.getLogger(__name__) 15 | 16 | 17 | class julaboF32HD(HardwareLayer): 18 | ''' Driver for the Julabo F32-HD chiller. 19 | A simple protocol via RS 232 serial port is used with 4800 baud rate. 20 | ''' 21 | 22 | def __init__(self, intf, conf): 23 | super(julaboF32HD, self).__init__(intf, conf) 24 | self.pre_time = time.time() 25 | 26 | def init(self): 27 | super(julaboF32HD, self).init() 28 | 29 | def read(self): 30 | ret = self._intf.read() 31 | if len(ret) < 2 or ret[-2:] != "\r\n": 32 | logger.warning("read() termination error") 33 | return ret[:-2] 34 | 35 | def write(self, cmd): 36 | if time.time() - self.pre_time < 1.0: 37 | time.sleep(1.0) 38 | self._intf.write(str(cmd)) 39 | self.pre_time = time.time() 40 | 41 | def get_identifier(self): 42 | ''' Read identifier 43 | ''' 44 | self.write("version") 45 | ret = self.read() 46 | return ret 47 | 48 | def start_thermostat(self, start=True): 49 | ''' Start chiller 50 | ''' 51 | if start is True: 52 | self.write("out_mode_05 1") 53 | else: 54 | self.write("out_mode_05 0") 55 | 56 | def stop_thermostat(self): 57 | ''' Stop chiller 58 | ''' 59 | self.start_thermostat(False) 60 | 61 | def get_status(self): 62 | ''' Get status 63 | ''' 64 | self.write("status") 65 | ret = self.read() 66 | logger.debug("status:{:s}".format(ret)) 67 | try: 68 | tmp = ret.split(" ", 1) 69 | status = int(tmp[0]) 70 | status_str = tmp[1:] 71 | except (ValueError, AttributeError): 72 | logger.warning("get_status() wrong format: {}".format(repr(ret))) 73 | status = -99 74 | status_str = ret 75 | return status, status_str 76 | -------------------------------------------------------------------------------- /basil/HL/keithley_2000.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2000 Multimeter. 2 | # Do not expect the Keithley 2000 to work over serial! 3 | # Only GPIB shows working communication with this device! 4 | identifier : KEITHLEY INSTRUMENTS INC.,MODEL 2000 5 | get_current : MEAS:CURR? 6 | get_voltage : MEAS:VOLT? 7 | set_NPLC_dc_voltage : SENS:VOLT:DC:NPLC 8 | get_NPLC_dc_voltage : SENS:VOLT:DC:NPLC? 9 | -------------------------------------------------------------------------------- /basil/HL/keithley_2001.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2001 Multimeter. 2 | # Only GPIB is possible with this device! 3 | identifier : KEITHLEY INSTRUMENTS INC.,MODEL 2001 4 | get_current : MEAS:CURR? 5 | get_voltage : MEAS:VOLT? 6 | get_channels : ROUT:CLOSE:STAT? 7 | 8 | # If the multi channel switcher card Model 2000-SCAN Scanner Card 9 | # is installed the following works for voltage measurements 10 | channel 1: 11 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@1);:MEAS:VOLT? 12 | channel 2: 13 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@2);:MEAS:VOLT? 14 | channel 3: 15 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@3);:MEAS:VOLT? 16 | channel 4: 17 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@4);:MEAS:VOLT? 18 | channel 5: 19 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@5);:MEAS:VOLT? 20 | channel 6: 21 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@6);:MEAS:VOLT? 22 | channel 7: 23 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@7);:MEAS:VOLT? 24 | channel 8: 25 | get_voltage : ROUT:OPEN ALL;:ROUT:CLOS (@8);:MEAS:VOLT? 26 | -------------------------------------------------------------------------------- /basil/HL/keithley_2400.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2400 Sourcemeter. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier : KEITHLEY INSTRUMENTS INC.,MODEL 2400 5 | 6 | on : OUTP ON 7 | off : OUTP OFF 8 | get_on: OUTP? 9 | get_source_current: SOUR:CURR? 10 | get_current : SENSE:FUNC 'CURR';:READ? 11 | set_current : SOUR:CURR 12 | get_source_voltage: SOUR:VOLT? 13 | set_voltage : SOUR:VOLT 14 | get_voltage : SENSE:FUNC 'VOLT';:READ? 15 | set_current_limit : SENS:CURR:PROT 16 | get_current_limit : SENS:CURR:PROT? 17 | set_voltage_limit : SENS:VOLT:PROT 18 | get_voltage_limit : SENS:VOLT:PROT? 19 | source_volt : SOUR:FUNC VOLT 20 | source_current : SOUR:FUNC CURR 21 | get_source_mode : SOUR:FUNC? 22 | set_autorange : SOUR:CURR:RANG:AUTO ON 23 | set_voltage_range : SOUR:VOLT:RANGE 24 | get_autorange : SOUR:CURR:RANG:AUTO? 25 | four_wire_on: SYST:RSEN ON 26 | four_wire_off: SYST:RSEN OFF 27 | get_remote_sense: SYST:RSEN ? 28 | # Special keyword for formatting query results to allow direct conversions to numeric types (e.g. float(get_current())) 29 | __scpi_query_fmt: 30 | fmt_sep: ',' 31 | fmt_method: 32 | get_voltage: '{0}' 33 | get_current: '{1}' 34 | -------------------------------------------------------------------------------- /basil/HL/keithley_2410.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2410 Sourcemeter. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier : KEITHLEY INSTRUMENTS INC.,MODEL 2410 5 | on : OUTP ON 6 | off : OUTP OFF 7 | get_on: OUTP? 8 | get_current : SENSE:FUNC 'CURR';:READ? 9 | set_current : SOUR:CURR 10 | set_voltage : SOUR:VOLT 11 | get_voltage : SENSE:FUNC 'VOLT';:READ? 12 | set_current_limit : SENS:CURR:PROT 13 | get_current_limit : SENS:CURR:PROT? 14 | set_voltage_limit : SENS:VOLT:PROT 15 | get_voltage_limit : SENS:VOLT:PROT? 16 | source_volt : SOUR:FUNC VOLT 17 | source_current : SOUR:FUNC CURR 18 | get_source_mode : SOUR:FUNC? 19 | get_source_voltage: SOUR:VOLT? 20 | set_current_autorange : SOUR:CURR:RANG:AUTO ON 21 | get_current_autorange : SOUR:CURR:RANG:AUTO? 22 | set_voltage_range: SOUR:VOLT:RANGE 23 | four_wire_on: SYST:RSEN ON 24 | four_wire_off: SYST:RSEN OFF 25 | get_remote_sense: SYST:RSEN? 26 | set_current_sense_range: SENS:CURR:RANGE 27 | get_current_sense_range: SENS:CURR:RANGE? 28 | get_reading: READ? 29 | set_current_nlpc: SENS:CURR:NPLC 30 | # Special keyword for formatting query results to allow direct conversions to numeric types (e.g. float(get_current())) 31 | __scpi_query_fmt: 32 | fmt_sep: ',' 33 | fmt_method: 34 | get_voltage: '{0}' 35 | get_current: '{1}' 36 | -------------------------------------------------------------------------------- /basil/HL/keithley_2450.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2450 Sourcemeter. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier : KEITHLEY INSTRUMENTS,MODEL 2450 5 | 6 | on : OUTP ON 7 | off : OUTP OFF 8 | get_current : SENSE:FUNC 'CURR';:READ? 9 | set_current : SOUR:CURR 10 | set_voltage : SOUR:VOLT 11 | get_voltage : SENSE:FUNC 'VOLT';:READ? 12 | set_current_limit : SENS:CURR:PROT 13 | get_current_limit : SENS:CURR:PROT? 14 | set_voltage_limit : SENS:VOLT:PROT 15 | get_voltage_limit : SENS:VOLT:PROT? 16 | source_volt : SOUR:FUNC VOLT 17 | source_current : SOUR:FUNC CURR 18 | get_source_mode : SOUR:FUNC? 19 | set_autorange : SOUR:CURR:RANG:AUTO ON 20 | set_voltage_range : SOUR:VOLT:RANGE 21 | get_autorange : SOUR:CURR:RANG:AUTO? 22 | four_wire_on: SYST:RSEN ON 23 | four_wire_off: SYST:RSEN OFF 24 | get_remote_sense: SYST:RSEN ? 25 | -------------------------------------------------------------------------------- /basil/HL/keithley_2460.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2460 Sourcemeter. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier : KEITHLEY INSTRUMENTS,MODEL 2460 5 | 6 | on : OUTP ON 7 | off : OUTP OFF 8 | get_current : SENSE:FUNC 'CURR';:READ? 9 | set_current : SOUR:CURR 10 | set_voltage : SOUR:VOLT 11 | get_voltage : SENSE:FUNC 'VOLT';:READ? 12 | set_current_limit : SENS:CURR:PROT 13 | get_current_limit : SENS:CURR:PROT? 14 | set_voltage_limit : SENS:VOLT:PROT 15 | get_voltage_limit : SENS:VOLT:PROT? 16 | source_volt : SOUR:FUNC VOLT 17 | source_current : SOUR:FUNC CURR 18 | get_source_mode : SOUR:FUNC? 19 | set_autorange : SOUR:CURR:RANG:AUTO ON 20 | set_voltage_range : SOUR:VOLT:RANGE 21 | get_autorange : SOUR:CURR:RANG:AUTO? 22 | four_wire_on: SYST:RSEN ON 23 | four_wire_off: SYST:RSEN OFF 24 | get_remote_sense: SYST:RSEN ? 25 | -------------------------------------------------------------------------------- /basil/HL/keithley_2470.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2470 Sourcemeter. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier : KEITHLEY INSTRUMENTS,MODEL 2470 5 | 6 | on : OUTP ON 7 | off : OUTP OFF 8 | get_current : SENSE:FUNC 'CURR';:READ? 9 | set_current : SOUR:CURR 10 | set_voltage : SOUR:VOLT 11 | get_voltage : SENSE:FUNC 'VOLT';:READ? 12 | set_current_limit : SOUR:VOLT:ILIM 13 | get_current_limit : SOUR:VOLT:ILIM? 14 | set_voltage_limit : SOUR:CURR:VLIM 15 | get_voltage_limit : SOUR:CURR:VLIM? 16 | source_volt : SOUR:FUNC VOLT 17 | source_current : SOUR:FUNC CURR 18 | get_source_mode : SOUR:FUNC? 19 | set_autorange : SOUR:CURR:RANG:AUTO ON 20 | set_voltage_range : SOUR:VOLT:RANGE 21 | get_autorange : SOUR:CURR:RANG:AUTO? 22 | four_wire_on: SYST:RSEN ON 23 | four_wire_off: SYST:RSEN OFF 24 | get_remote_sense: SYST:RSEN ? 25 | # Special keyword for formatting query results to allow direct conversions to numeric types (e.g. float(get_current())) 26 | __scpi_query_fmt: 27 | fmt_sep: ',' 28 | fmt_method: 29 | get_voltage: '{0}' 30 | get_current: '{0}' 31 | -------------------------------------------------------------------------------- /basil/HL/keithley_2602a.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Keithley 2602A Sourcemeter. 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # Just the very basic commands are implemented here. 4 | identifier : Keithley Instruments Inc., Model 2602A 5 | 6 | channel 1: 7 | reset : smua.reset() 8 | on : smua.source.output = 1 9 | off : smua.source.output = 0 10 | source_current : smua.source.func = smua.OUTPUT_DCAMPS 11 | source_volt : smua.source.func = smua.OUTPUT_DCVOLTS 12 | set_voltage_limit : smua.source.limitv = 13 | set_current_limit : smua.source.limiti = 14 | set_voltage_range : smua.source.rangev = 15 | set_current_range : smua.source.rangei = 16 | set_current : smua.source.leveli = 17 | get_current : print(smua.measure.i()) 18 | set_voltage : smua.source.levelv = 19 | get_voltage : print(smua.measure.v()) 20 | set_mode_measure_current_A : display.smua.measure.func = display.MEASURE_DCAMPS 21 | four_wire_on : smua.sense = smua.SENSE_REMOTE 22 | four_wire_off : smua.sense = smua.SENSE_LOCAL 23 | 24 | channel 2: 25 | reset : smub.reset() 26 | on : smub.source.output = 1 27 | off : smub.source.output = 0 28 | source_current : smub.source.func = smub.OUTPUT_DCAMPS 29 | source_volt : smub.source.func = smub.OUTPUT_DCVOLTS 30 | set_voltage_range : smub.source.rangev = 31 | set_current_range : smub.source.rangei = 32 | set_voltage_limit : smub.source.limitv = 33 | set_current_limit : smub.source.limiti = 34 | set_current : smub.source.leveli = 35 | get_current : print(smub.measure.i()) 36 | set_voltage : smub.source.levelv = 37 | get_voltage : print(smub.measure.v()) 38 | set_mode_measure_current : display.smub.measure.func = display.MEASURE_DCAMPS 39 | four_wire_on : smub.sense = smub.SENSE_REMOTE 40 | four_wire_off : smub.sense = smub.SENSE_LOCAL 41 | 42 | #on : smua.source.output = 1 43 | #off : smua.source.output = 0 44 | #get_current : print(smua.measure.i()) 45 | #set_voltage : smua.source.levelv = 46 | #get_voltage : print(smua.measure.v()) 47 | #set_mode_measure_current : display.smua.measure.func = display.MEASURE_DCAMPS 48 | -------------------------------------------------------------------------------- /basil/HL/m26_rx.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.RegisterHardwareLayer import RegisterHardwareLayer 9 | 10 | 11 | class m26_rx(RegisterHardwareLayer): 12 | '''Mimosa 26 RX interface 13 | ''' 14 | 15 | _registers = {'RESET': {'descr': {'addr': 0, 'size': 8, 'properties': ['writeonly']}}, 16 | 'VERSION': {'descr': {'addr': 0, 'size': 8, 'properties': ['ro']}}, 17 | 'EN': {'descr': {'addr': 1, 'size': 1, 'offset': 0}}, 18 | 'TIMESTAMP_HEADER': {'descr': {'addr': 1, 'size': 1, 'offset': 1}}, 19 | 'LOST_COUNT': {'descr': {'addr': 2, 'size': 8, 'properties': ['ro']}}, 20 | 'INVALID_DATA_COUNT': {'descr': {'addr': 3, 'size': 8, 'properties': ['ro']}}} 21 | _require_version = "==2" 22 | 23 | def __init__(self, intf, conf): 24 | super(m26_rx, self).__init__(intf, conf) 25 | 26 | def reset(self): 27 | '''Soft reset the module.''' 28 | self.RESET = 0 29 | 30 | def set_en(self, value): 31 | self.EN = value 32 | 33 | def get_en(self): 34 | return self.EN 35 | 36 | def get_lost_count(self): 37 | return self.LOST_COUNT 38 | -------------------------------------------------------------------------------- /basil/HL/rs_hmp4040.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the Rohde & Schwarz PS 2 | # set_ function expect a parameter, get_ function return a parameter. 3 | # !!! identifier changes from unit to unit. Has to be adjusted when using a new device !!! 4 | identifier : HAMEG,HMP4040,105773,HW50020001/SW2.51 5 | on : OUTP ON 6 | off : OUTP OFF 7 | set_channel: INST:NSEL 8 | get_channel: INST:NSEL? 9 | set_voltage : VOLT 10 | set_current : CURR 11 | get_voltage : MEAS:VOLT? 12 | get_current : MEAS:CURR? 13 | get_target_voltage: VOLT? 14 | get_target_current: CURR? 15 | set_ovp: VOLT:PROT 16 | get_ovp: VOLT:PROT? 17 | 18 | -------------------------------------------------------------------------------- /basil/HL/scpi_sim_device.yaml: -------------------------------------------------------------------------------- 1 | # Device description for a simulated device for SCPI HL + VISA TL test. 2 | identifier : "LSG Serial #1234" 3 | get_name : "?IDN" # overwrite default SCPI 4 | set_on : "!OUT" 5 | get_on : "?OUT" 6 | get_frequency : "?FREQ" 7 | -------------------------------------------------------------------------------- /basil/HL/tdc_s3.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.RegisterHardwareLayer import RegisterHardwareLayer 9 | 10 | 11 | class tdc_s3(RegisterHardwareLayer): 12 | '''TDC controller interface 13 | ''' 14 | 15 | _registers = {'RESET': {'descr': {'addr': 0, 'size': 8, 'properties': ['writeonly']}}, 16 | 'VERSION': {'descr': {'addr': 0, 'size': 8, 'properties': ['ro']}}, 17 | 'ENABLE': {'descr': {'addr': 1, 'size': 1, 'offset': 0}}, 18 | 'ENABLE_EXTERN': {'descr': {'addr': 1, 'size': 1, 'offset': 1}}, 19 | 'EN_ARMING': {'descr': {'addr': 1, 'size': 1, 'offset': 2}}, 20 | 'EN_WRITE_TIMESTAMP': {'descr': {'addr': 1, 'size': 1, 'offset': 3}}, 21 | 'EN_TRIGGER_DIST': {'descr': {'addr': 1, 'size': 1, 'offset': 4}}, 22 | 'EN_NO_WRITE_TRIG_ERR': {'descr': {'addr': 1, 'size': 1, 'offset': 5}}, 23 | 'EN_INVERT_TDC': {'descr': {'addr': 1, 'size': 1, 'offset': 6}}, 24 | 'EN_INVERT_TRIGGER': {'descr': {'addr': 1, 'size': 1, 'offset': 7}}, 25 | 'EVENT_COUNTER': {'descr': {'addr': 2, 'size': 32, 'properties': ['ro']}}, 26 | 'LOST_DATA_COUNTER': {'descr': {'addr': 6, 'size': 8, 'properties': ['ro']}}} 27 | _require_version = "==2" 28 | 29 | def __init__(self, intf, conf): 30 | super(tdc_s3, self).__init__(intf, conf) 31 | 32 | def reset(self): 33 | self.RESET = 0 34 | 35 | def get_lost_data_counter(self): 36 | return self.LOST_DATA_COUNTER 37 | 38 | def set_en(self, value): 39 | self.ENABLE = value 40 | 41 | def get_en(self): 42 | return self.ENABLE 43 | 44 | def set_en_extern(self, value): 45 | self.ENABLE_EXTERN = value 46 | 47 | def get_en_extern(self): 48 | return self.ENABLE_EXTERN 49 | 50 | def set_arming(self, value): 51 | self.EN_ARMING = value 52 | 53 | def get_arming(self): 54 | return self.EN_ARMING 55 | 56 | def set_write_timestamp(self, value): 57 | self.EN_WRITE_TIMESTAMP = value 58 | 59 | def get_write_timestamp(self): 60 | return self.EN_WRITE_TIMESTAMP 61 | 62 | def get_event_counter(self): 63 | return self.EVENT_COUNTER 64 | -------------------------------------------------------------------------------- /basil/HL/timestamp.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.HL.RegisterHardwareLayer import RegisterHardwareLayer 9 | 10 | 11 | class timestamp(RegisterHardwareLayer): 12 | '''Implement timestamp driver. 13 | ''' 14 | 15 | def __init__(self, intf, conf): 16 | self._registers = {'RESET': {'descr': {'addr': 0, 'size': 8, 'properties': ['writeonly']}}, 17 | 'VERSION': {'descr': {'addr': 0, 'size': 8, 'properties': ['ro']}}, 18 | 'ENABLE': {'descr': {'addr': 2, 'size': 1, 'offset': 0}}, 19 | 'EXT_TIMESTAMP': {'descr': {'addr': 2, 'size': 1, 'offset': 1}}, 20 | 'ENABLE_EXTERN': {'descr': {'addr': 2, 'size': 1, 'offset': 2}}, 21 | 'LOST_COUNT': {'descr': {'addr': 3, 'size': 8}}, 22 | } 23 | self._require_version = "==2" 24 | 25 | super(timestamp, self).__init__(intf, conf) 26 | 27 | def init(self): 28 | super(timestamp, self).init() 29 | 30 | def reset(self): 31 | '''Soft reset the module.''' 32 | self.RESET = 0 33 | -------------------------------------------------------------------------------- /basil/HL/tti_ql355tp.yaml: -------------------------------------------------------------------------------- 1 | # Device description for the TTi QL355 Power Supply. 2 | identifier : QL355TP 3 | on : OPALL 1 4 | off : OPALL 0 5 | reset_trip : TRIPRST 6 | channel 1: 7 | on : OP1 1 8 | off : OP1 0 9 | get_on : OP1? 10 | get_current : I1O? 11 | set_current_limit : I1 12 | get_current_limit : I1? 13 | set_ocp : OCP1 14 | get_ocp : OCP1? 15 | set_voltage : V1 16 | get_voltage : V1O? 17 | set_ovp : OVP1 18 | get_ovp : OVP1? 19 | channel 2: 20 | on : OP2 1 21 | off : OP2 0 22 | get_on : OP2? 23 | get_current : I2O? 24 | set_current_limit : I2 25 | get_current_limit : I2? 26 | set_ocp : OCP2 27 | get_ocp : OCP2? 28 | set_voltage : V2 29 | get_voltage : V2O? 30 | set_ovp : OVP2 31 | get_ovp : OVP2? 32 | channel 3: 33 | on : OP3 1 34 | off : OP3 0 35 | get_on : OP3? 36 | get_current : I3O? 37 | set_voltage : V3 38 | get_voltage : V3O? 39 | -------------------------------------------------------------------------------- /basil/RL/FunctionalRegister.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.RL.RegisterLayer import RegisterLayer 9 | 10 | 11 | class FunctionalRegister(RegisterLayer): 12 | 13 | def __init__(self, driver, conf): 14 | RegisterLayer.__init__(self, driver, conf) 15 | -------------------------------------------------------------------------------- /basil/RL/RegisterLayer.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | try: 9 | from collections.abc import Callable # noqa 10 | except ImportError: 11 | from collections import Callable # noqa 12 | 13 | from basil.dut import Base 14 | 15 | 16 | class RegisterLayer(Base): 17 | def __init__(self, driver, conf): 18 | super(RegisterLayer, self).__init__(conf) 19 | self._drv = driver 20 | 21 | def init(self): 22 | super(RegisterLayer, self).init() 23 | 24 | def __getattr__(self, name): 25 | if not self.is_initialized: # this test allows attributes to be set in the __init__ method 26 | raise AttributeError("'%s' has no attribute '%s'" % (self.__class__.__name__, name)) 27 | else: 28 | attr = getattr(self._drv, name) 29 | # for compatibility with RegisterHardwareLayer: 30 | # prevent wrting to a register twice 31 | if not isinstance(attr, Callable): 32 | return attr 33 | 34 | def method(*args, **kargs): 35 | arg = () 36 | if 'arg_names' in self._conf: 37 | for i in range(len(args)): 38 | kargs[self._conf['arg_names'][i]] = args[i] 39 | else: 40 | arg = args 41 | 42 | if 'arg_add' in self._conf: 43 | for argn in self._conf['arg_add']: 44 | kargs[argn] = self._conf['arg_add'][argn] 45 | 46 | return attr(*arg, **kargs) 47 | 48 | return method 49 | 50 | def __setattr__(self, name, value): 51 | if not self.is_initialized: # this test allows attributes to be set in the __init__ method 52 | super(RegisterLayer, self).__setattr__(name, value) 53 | else: 54 | try: 55 | setattr(self._drv, name, value) 56 | except Exception: 57 | super(RegisterLayer, self).__setattr__(name, value) 58 | -------------------------------------------------------------------------------- /basil/RL/TrackRegister.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from bitarray import bitarray 9 | 10 | from basil.utils import utils 11 | from basil.RL.RegisterLayer import RegisterLayer 12 | 13 | from six.moves import range 14 | 15 | 16 | class TrackRegister(RegisterLayer): 17 | '''Tracking register 18 | ''' 19 | 20 | def __init__(self, driver, conf): 21 | RegisterLayer.__init__(self, driver, conf) 22 | self._tracks = dict() 23 | 24 | for track in self._conf['tracks']: 25 | bv = bitarray(self._conf["seq_size"]) 26 | bv.setall(False) 27 | self._tracks[track['name']] = bv 28 | 29 | def __getitem__(self, items): 30 | if items in self._tracks: 31 | return self._tracks[items] 32 | else: 33 | raise ValueError('Item does not exist') 34 | 35 | def __setitem__(self, key, value): 36 | self._tracks[key] = value 37 | 38 | def clear(self): 39 | 'Clear tracks in memory - all zero' 40 | for track in self._tracks: 41 | self._tracks[track].setall(False) 42 | 43 | def write(self, size=-1): 44 | if size == -1: 45 | size = self._conf["seq_size"] 46 | 47 | bv = bitarray(self._conf["seq_width"] * size) 48 | for i in range(size): 49 | for track in self._conf['tracks']: 50 | bit = 0 51 | if self._conf["seq_width"] >= 8: 52 | bit = i * self._conf["seq_width"] + self._conf["seq_width"] - 1 - track['position'] 53 | elif self._conf["seq_width"] == 4: 54 | if i % 2 == 0: 55 | bit = (i + 1) * self._conf["seq_width"] + self._conf["seq_width"] - 1 - track['position'] 56 | else: 57 | bit = (i - 1) * self._conf["seq_width"] + self._conf["seq_width"] - 1 - track['position'] 58 | else: 59 | raise NotImplementedError("To be implemented.") 60 | bv[bit] = self._tracks[track['name']][i] 61 | 62 | ba = utils.bitarray_to_byte_array(bv) 63 | ba = ba[::-1] 64 | # TODO: this probably has to be done different way 65 | self._drv.set_data(ba) 66 | -------------------------------------------------------------------------------- /basil/RL/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/basil/RL/__init__.py -------------------------------------------------------------------------------- /basil/TL/Dummy.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | import logging 9 | import array 10 | 11 | from basil.TL.SiTransferLayer import SiTransferLayer 12 | 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | class Dummy(SiTransferLayer): 17 | '''Dummy device 18 | ''' 19 | 20 | def __init__(self, conf): 21 | self.mem = {} # dummy memory dict, keys are addresses, values are of type int 22 | super(Dummy, self).__init__(conf) 23 | 24 | def init(self): 25 | super(Dummy, self).init() 26 | logger.debug( 27 | "Dummy SiTransferLayer.init configuration: %s" % str(self._conf)) 28 | if 'mem' in self._init: 29 | if isinstance(self._init['mem'], dict): 30 | self.mem = self._init['mem'] 31 | else: 32 | self.mem = {i: j for i, j in enumerate(self._init['mem'])} 33 | else: 34 | self.mem = {} 35 | 36 | def write(self, addr, data): 37 | '''Write to dummy memory 38 | 39 | Parameters 40 | ---------- 41 | addr : int 42 | The register address. 43 | data : list, tuple 44 | Data (byte array) to be written. 45 | 46 | Returns 47 | ------- 48 | nothing 49 | ''' 50 | logger.debug( 51 | "Dummy SiTransferLayer.write addr: %s data: %s" % (hex(addr), data)) 52 | for curr_addr, d in enumerate(data, start=addr): 53 | self.mem[curr_addr] = array.array('B', [d])[0] # write int 54 | 55 | def read(self, addr, size): 56 | ''' 57 | Parameters 58 | ---------- 59 | addr : int 60 | The register address. 61 | size : int 62 | Length of data to be read (number of bytes). 63 | 64 | Returns 65 | ------- 66 | array : array 67 | Data (byte array) read from memory. Returns 0 for each byte if it hasn't been written to. 68 | ''' 69 | logger.debug("Dummy SiTransferLayer.read addr: %s size: %s" % (hex(addr), size)) 70 | return array.array('B', [self.mem[curr_addr] if curr_addr in self.mem else 0 for curr_addr in range(addr, addr + size)]) 71 | -------------------------------------------------------------------------------- /basil/TL/SiTransferLayer.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.TL.TransferLayer import TransferLayer 9 | 10 | 11 | class SiTransferLayer(TransferLayer): 12 | '''Multiplexing Transfer Layer implements abstract methods to access 13 | hardware with multiple endpoints. 14 | On error ``raise IOError``. 15 | ''' 16 | 17 | def __init__(self, conf): 18 | super(SiTransferLayer, self).__init__(conf) 19 | 20 | def init(self): 21 | '''Initialize and connect to hardware. 22 | ''' 23 | super(SiTransferLayer, self).init() 24 | 25 | def read(self, addr, size): 26 | '''Read access. 27 | 28 | :param addr: start transfer address 29 | :type addr: int 30 | :param size: size of transfer 31 | :type size: int 32 | :returns: data byte array 33 | :rtype: array.array('B') 34 | 35 | ''' 36 | pass 37 | 38 | def write(self, addr, data): 39 | '''Write access. 40 | 41 | :param addr: start transfer address 42 | :type addr: int 43 | :param data: array/list of bytes 44 | :type data: iterable 45 | :rtype: None 46 | 47 | ''' 48 | pass 49 | -------------------------------------------------------------------------------- /basil/TL/Socket.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | 4 | from basil.TL.TransferLayer import TransferLayer 5 | 6 | 7 | class Socket(TransferLayer): 8 | ''' 9 | General direct socket TL implementation. 10 | Used for TCP/IP based direct communication with devices. 11 | Commands are handled including encoding, read and write termination. 12 | ''' 13 | 14 | def __init__(self, conf): 15 | super(Socket, self).__init__(conf) 16 | 17 | def init(self): 18 | ''' 19 | Create socket object and connect to specified ip address and port. 20 | ''' 21 | super(Socket, self).init() 22 | self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 23 | 24 | self.encoding = self._init.get('encoding', 'utf-8') 25 | self.write_termination = self._init.get('write_termination', '').encode(self.encoding).decode('unicode_escape') 26 | self.read_termination = self._init.get('read_termination', self.write_termination).encode(self.encoding).decode('unicode_escape') 27 | self.query_delay = self._init.get('query_delay', 0) 28 | self.handle_as_byte = self._init.get('handle_as_byte', False) 29 | 30 | address = self._init.get('address') 31 | port = self._init.get('port') 32 | 33 | self._sock.connect((address, port)) 34 | 35 | def close(self): 36 | super(Socket, self).close() 37 | self._sock.close() 38 | 39 | def write(self, data): 40 | if isinstance(data, bytes): 41 | cmd = data 42 | else: 43 | cmd = data.encode(self.encoding) 44 | cmd += self.write_termination.encode(self.encoding) 45 | if not self.handle_as_byte: 46 | cmd.decode('unicode_escape') 47 | self._sock.send(cmd) 48 | 49 | def read(self, buffer_size=1): 50 | ret = self._sock.recv(buffer_size) 51 | if not self.handle_as_byte: 52 | return ret.split(self.read_termination.encode(self.encoding))[:-1] 53 | return ret 54 | 55 | def query(self, data, buffer_size=1): 56 | self.write(data) 57 | time.sleep(self.query_delay) 58 | return self.read(buffer_size) 59 | -------------------------------------------------------------------------------- /basil/TL/TransferLayer.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | from basil.dut import Base 9 | 10 | 11 | class TransferLayer(Base): 12 | '''Transfer Layer implements minimum API needed access to hardware. 13 | On error ``raise IOError``. 14 | ''' 15 | 16 | def __init__(self, conf): 17 | super(TransferLayer, self).__init__(conf) 18 | 19 | def init(self): 20 | '''Initialize and connect to hardware. 21 | ''' 22 | super(TransferLayer, self).init() 23 | 24 | def read(self): 25 | '''Read access. 26 | 27 | :rtype: None 28 | ''' 29 | raise NotImplementedError("read() not implemented") 30 | 31 | def write(self, data): 32 | '''Write access. 33 | 34 | :param data: array/list of bytes 35 | :type data: iterable 36 | :rtype: None 37 | 38 | ''' 39 | raise NotImplementedError("write() not implemented") 40 | -------------------------------------------------------------------------------- /basil/TL/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/basil/TL/__init__.py -------------------------------------------------------------------------------- /basil/__init__.py: -------------------------------------------------------------------------------- 1 | from importlib.metadata import version, PackageNotFoundError 2 | import collections 3 | import yaml 4 | 5 | 6 | __version__ = None # required for initial installation 7 | 8 | try: 9 | __version__ = version("basil_daq") 10 | except PackageNotFoundError: 11 | __version__ = "(local)" 12 | 13 | 14 | # Have OrderedDict 15 | def dict_representer(dumper, data): 16 | return dumper.represent_dict(data.items()) 17 | 18 | 19 | def dict_constructor(loader, node): 20 | return collections.OrderedDict(loader.construct_pairs(node)) 21 | 22 | 23 | yaml.add_representer(collections.OrderedDict, dict_representer) 24 | yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, dict_constructor) 25 | -------------------------------------------------------------------------------- /basil/firmware/arduino/EnvironmentReadout/Readme.rst: -------------------------------------------------------------------------------- 1 | ====================================== 2 | Arduino Firmware for Environment Readout (temperature, humidity/pressure) 3 | ====================================== 4 | 5 | Arduino Nano firmware to read out NTCs via the 8 analog input pins A0 to A7 and the internal (multiplexed) ADC. 6 | 7 | NTC inputs require a voltage divider configuration, supplied with the 3.3 V Arduino rail.The voltage drop over the NTC is the input to the analog pin. 8 | The conversion from ADC value to degree Celsius can take place in the firmware. 9 | 10 | Additionally, a pure analog read out is possible for processing of humidity and pressure sensors. 11 | -------------------------------------------------------------------------------- /basil/firmware/arduino/NTCReadout/README.rst: -------------------------------------------------------------------------------- 1 | ====================================== 2 | Arduino Firmware for NTC Readout 3 | ====================================== 4 | 5 | Arduino Nano firmware to read out NTCs via the 8 analog input pins A0 to A7 and the internal (multiplexed) ADC. 6 | The REF and 3V3 need to be connected on the Arduino. 7 | Each input requires a voltage divider configuration, supplied with the 3.3 V Arduino rail. 8 | The voltage drop over the NTC is the input to the analog pin. 9 | The conversion from ADC value to degree Celsius takes place in the firmware. 10 | -------------------------------------------------------------------------------- /basil/firmware/arduino/RelayBoard/README.rst: -------------------------------------------------------------------------------- 1 | ====================================== 2 | Arduino Firmware for SiLab Relay Board 3 | ====================================== 4 | 5 | Simple firmware for Arduino to take commands on serial port via USB and switch DigitalIO pins on and off accordingly. 6 | So far, all pins get initialized as LOW outputs, because of compatibility with 8 channel relay card. 7 | -------------------------------------------------------------------------------- /basil/firmware/arduino/SerialToI2C/README.rst: -------------------------------------------------------------------------------- 1 | ====================================== 2 | Arduino Firmware for I2C over Serial 3 | ====================================== 4 | 5 | Arduino Nano firmware to write and read an I2C bus over the Arduinos serial interface. 6 | The lines reqired by I2C are GND, VCC(3v3 or 5V), SDA (A4) and SCL (A5). 7 | The firmware receives read/write commands over serial, accesses the I2C bus and answers the 8 | results over serial. 9 | -------------------------------------------------------------------------------- /basil/firmware/modules/bram_fifo/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **bram_fifo** - data FIFO (BRAM) 4 | ===================================== 5 | 6 | Data FIFO implemented based on internal BRAM memory. 7 | Can be continuously pooled for data. 8 | -------------------------------------------------------------------------------- /basil/firmware/modules/chipscope/chipscope_icon.xco: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # Xilinx Core Generator version 14.2 4 | # Date: Wed Sep 11 09:29:34 2013 5 | # 6 | ############################################################## 7 | # 8 | # This file contains the customisation parameters for a 9 | # Xilinx CORE Generator IP GUI. It is strongly recommended 10 | # that you do not manually alter this file as it may cause 11 | # unexpected and unsupported behavior. 12 | # 13 | ############################################################## 14 | # 15 | # Generated from component: xilinx.com:ip:chipscope_icon:1.06.a 16 | # 17 | ############################################################## 18 | # 19 | # BEGIN Project Options 20 | SET addpads = false 21 | SET asysymbol = true 22 | SET busformat = BusFormatAngleBracketNotRipped 23 | SET createndf = false 24 | SET designentry = Verilog 25 | SET device = xc3s1000 26 | SET devicefamily = spartan3 27 | SET flowvendor = Other 28 | SET formalverification = false 29 | SET foundationsym = false 30 | SET implementationfiletype = Ngc 31 | SET package = fg320 32 | SET removerpms = false 33 | SET simulationfiles = Structural 34 | SET speedgrade = -5 35 | SET verilogsim = true 36 | SET vhdlsim = false 37 | # END Project Options 38 | # BEGIN Select 39 | SELECT ICON_(ChipScope_Pro_-_Integrated_Controller) family Xilinx,_Inc. 1.06.a 40 | # END Select 41 | # BEGIN Parameters 42 | CSET component_name=chipscope_icon 43 | CSET constraint_type=external 44 | CSET enable_jtag_bufg=true 45 | CSET example_design=false 46 | CSET number_control_ports=1 47 | CSET use_ext_bscan=false 48 | CSET use_softbscan=false 49 | CSET use_unused_bscan=false 50 | CSET user_scan_chain=USER1 51 | # END Parameters 52 | # BEGIN Extra information 53 | MISC pkg_timestamp=2012-07-21T03:11:48Z 54 | # END Extra information 55 | GENERATE 56 | # CRC: 3c6d10d6 57 | -------------------------------------------------------------------------------- /basil/firmware/modules/cmd_seq/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **cmd_seq** - cmd generator (FE-I4) 4 | ===================================== 5 | 6 | Generate arbitrary single bit data stream and clock (mainly to generate FE-I4 commands). Supports hardware loops and Manchester data encoding. 7 | 8 | -------------------------------------------------------------------------------- /basil/firmware/modules/cmd_seq/cmd_seq.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module cmd_seq #( 11 | parameter BASEADDR = 32'h0000, 12 | parameter HIGHADDR = 32'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter OUTPUTS = 1, 15 | parameter CMD_MEM_SIZE = 2048 16 | ) ( 17 | input wire BUS_CLK, 18 | input wire BUS_RST, 19 | input wire [ABUSWIDTH-1:0] BUS_ADD, 20 | inout wire [7:0] BUS_DATA, 21 | input wire BUS_RD, 22 | input wire BUS_WR, 23 | 24 | output wire [OUTPUTS-1:0] CMD_CLK_OUT, 25 | input wire CMD_CLK_IN, 26 | input wire CMD_EXT_START_FLAG, 27 | output wire CMD_EXT_START_ENABLE, 28 | output wire [OUTPUTS-1:0] CMD_DATA, 29 | output wire CMD_READY, 30 | output wire CMD_START_FLAG 31 | ); 32 | 33 | wire IP_RD, IP_WR; 34 | wire [ABUSWIDTH-1:0] IP_ADD; 35 | wire [7:0] IP_DATA_IN; 36 | wire [7:0] IP_DATA_OUT; 37 | 38 | bus_to_ip #( 39 | .BASEADDR(BASEADDR), 40 | .HIGHADDR(HIGHADDR), 41 | .ABUSWIDTH(ABUSWIDTH) 42 | ) i_bus_to_ip ( 43 | .BUS_RD(BUS_RD), 44 | .BUS_WR(BUS_WR), 45 | .BUS_ADD(BUS_ADD), 46 | .BUS_DATA(BUS_DATA), 47 | 48 | .IP_RD(IP_RD), 49 | .IP_WR(IP_WR), 50 | .IP_ADD(IP_ADD), 51 | .IP_DATA_IN(IP_DATA_IN), 52 | .IP_DATA_OUT(IP_DATA_OUT) 53 | ); 54 | 55 | 56 | cmd_seq_core #( 57 | .CMD_MEM_SIZE(CMD_MEM_SIZE), 58 | .ABUSWIDTH(ABUSWIDTH), 59 | .OUTPUTS(OUTPUTS) 60 | ) i_cmd_seq_core ( 61 | .BUS_CLK(BUS_CLK), 62 | .BUS_RST(BUS_RST), 63 | .BUS_ADD(IP_ADD), 64 | .BUS_DATA_IN(IP_DATA_IN), 65 | .BUS_RD(IP_RD), 66 | .BUS_WR(IP_WR), 67 | .BUS_DATA_OUT(IP_DATA_OUT), 68 | 69 | .CMD_CLK_OUT(CMD_CLK_OUT), 70 | .CMD_CLK_IN(CMD_CLK_IN), 71 | .CMD_EXT_START_FLAG(CMD_EXT_START_FLAG), 72 | .CMD_EXT_START_ENABLE(CMD_EXT_START_ENABLE), 73 | .CMD_DATA(CMD_DATA), 74 | .CMD_READY(CMD_READY), 75 | .CMD_START_FLAG(CMD_START_FLAG) 76 | ); 77 | 78 | endmodule 79 | -------------------------------------------------------------------------------- /basil/firmware/modules/fast_spi_rx/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **fast_spi_rx** - fast spi receiver 4 | ===================================== 5 | 6 | Allows continuous serial data receive. Received data are propagated to FIFO data interface. 7 | -------------------------------------------------------------------------------- /basil/firmware/modules/fast_spi_rx/fast_spi_rx.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module fast_spi_rx #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | 15 | parameter IDENTIFIER = 4'b0001 16 | ) ( 17 | input wire BUS_CLK, 18 | input wire [ABUSWIDTH-1:0] BUS_ADD, 19 | inout wire [7:0] BUS_DATA, 20 | input wire BUS_RST, 21 | input wire BUS_WR, 22 | input wire BUS_RD, 23 | 24 | input wire SCLK, 25 | input wire SDI, 26 | input wire SEN, 27 | 28 | input wire FIFO_READ, 29 | output wire FIFO_EMPTY, 30 | output wire [31:0] FIFO_DATA 31 | 32 | ); 33 | 34 | wire IP_RD, IP_WR; 35 | wire [ABUSWIDTH-1:0] IP_ADD; 36 | wire [7:0] IP_DATA_IN; 37 | wire [7:0] IP_DATA_OUT; 38 | 39 | bus_to_ip #( 40 | .BASEADDR(BASEADDR), 41 | .HIGHADDR(HIGHADDR), 42 | .ABUSWIDTH(ABUSWIDTH) 43 | ) i_bus_to_ip ( 44 | .BUS_RD(BUS_RD), 45 | .BUS_WR(BUS_WR), 46 | .BUS_ADD(BUS_ADD), 47 | .BUS_DATA(BUS_DATA), 48 | 49 | .IP_RD(IP_RD), 50 | .IP_WR(IP_WR), 51 | .IP_ADD(IP_ADD), 52 | .IP_DATA_IN(IP_DATA_IN), 53 | .IP_DATA_OUT(IP_DATA_OUT) 54 | ); 55 | 56 | fast_spi_rx_core #( 57 | .ABUSWIDTH(ABUSWIDTH), 58 | .IDENTIFIER(IDENTIFIER) 59 | ) i_fast_spi_rx_core ( 60 | .BUS_CLK(BUS_CLK), 61 | .BUS_RST(BUS_RST), 62 | .BUS_ADD(IP_ADD), 63 | .BUS_DATA_IN(IP_DATA_IN), 64 | .BUS_RD(IP_RD), 65 | .BUS_WR(IP_WR), 66 | .BUS_DATA_OUT(IP_DATA_OUT), 67 | 68 | .SCLK(SCLK), 69 | .SDI(SDI), 70 | .SEN(SEN), 71 | 72 | .FIFO_READ(FIFO_READ), 73 | .FIFO_EMPTY(FIFO_EMPTY), 74 | .FIFO_DATA(FIFO_DATA) 75 | ); 76 | 77 | endmodule 78 | -------------------------------------------------------------------------------- /basil/firmware/modules/fei4_rx/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **fei4_rx** - FE-I4 data receiver 4 | ===================================== 5 | 6 | Allows continuous data recording from FE-I4. Received data are propagated to FIFO data interface. 7 | Implements auto synchronization and data error monitoring. 8 | -------------------------------------------------------------------------------- /basil/firmware/modules/gpac_adc_rx/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **gpac_adc_rx** - ADC receiver (GPAC) 4 | ===================================== 5 | 6 | Received data are propagated to FIFO data interface. 7 | -------------------------------------------------------------------------------- /basil/firmware/modules/gpac_adc_rx/gpac_adc_rx.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module gpac_adc_rx #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | 15 | parameter [1:0] ADC_ID = 0, 16 | parameter [0:0] HEADER_ID = 0 17 | ) ( 18 | input wire ADC_ENC, 19 | input wire [13:0] ADC_IN, 20 | 21 | input wire ADC_SYNC, 22 | input wire ADC_TRIGGER, 23 | 24 | input wire FIFO_READ, 25 | output wire FIFO_EMPTY, 26 | output wire [31:0] FIFO_DATA, 27 | 28 | input wire BUS_CLK, 29 | input wire BUS_RST, 30 | input wire [ABUSWIDTH-1:0] BUS_ADD, 31 | inout wire [7:0] BUS_DATA, 32 | input wire BUS_RD, 33 | input wire BUS_WR, 34 | 35 | output wire LOST_ERROR 36 | ); 37 | 38 | wire IP_RD, IP_WR; 39 | wire [ABUSWIDTH-1:0] IP_ADD; 40 | wire [7:0] IP_DATA_IN; 41 | wire [7:0] IP_DATA_OUT; 42 | 43 | bus_to_ip #( 44 | .BASEADDR(BASEADDR), 45 | .HIGHADDR(HIGHADDR) , 46 | .ABUSWIDTH(ABUSWIDTH) 47 | ) i_bus_to_ip ( 48 | .BUS_RD(BUS_RD), 49 | .BUS_WR(BUS_WR), 50 | .BUS_ADD(BUS_ADD), 51 | .BUS_DATA(BUS_DATA), 52 | 53 | .IP_RD(IP_RD), 54 | .IP_WR(IP_WR), 55 | .IP_ADD(IP_ADD), 56 | .IP_DATA_IN(IP_DATA_IN), 57 | .IP_DATA_OUT(IP_DATA_OUT) 58 | ); 59 | 60 | gpac_adc_rx_core #( 61 | .ADC_ID(ADC_ID), 62 | .HEADER_ID(HEADER_ID), 63 | .ABUSWIDTH(ABUSWIDTH) 64 | ) i_gpac_adc_rx_core ( 65 | .BUS_CLK(BUS_CLK), 66 | .BUS_RST(BUS_RST), 67 | .BUS_ADD(IP_ADD), 68 | .BUS_DATA_IN(IP_DATA_IN), 69 | .BUS_RD(IP_RD), 70 | .BUS_WR(IP_WR), 71 | .BUS_DATA_OUT(IP_DATA_OUT), 72 | 73 | .ADC_ENC(ADC_ENC), 74 | .ADC_IN(ADC_IN), 75 | 76 | .ADC_SYNC(ADC_SYNC), 77 | .ADC_TRIGGER(ADC_TRIGGER), 78 | 79 | .FIFO_READ(FIFO_READ), 80 | .FIFO_EMPTY(FIFO_EMPTY), 81 | .FIFO_DATA(FIFO_DATA), 82 | .LOST_ERROR(LOST_ERROR) 83 | ); 84 | 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /basil/firmware/modules/gpio/gpio.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module gpio #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter IO_WIDTH = 8, 15 | parameter IO_DIRECTION = 0, 16 | parameter IO_TRI = 0 17 | ) ( 18 | input wire BUS_CLK, 19 | input wire BUS_RST, 20 | input wire [ABUSWIDTH-1:0] BUS_ADD, 21 | inout wire [7:0] BUS_DATA, 22 | input wire BUS_RD, 23 | input wire BUS_WR, 24 | 25 | inout wire [IO_WIDTH-1:0] IO 26 | ); 27 | 28 | wire IP_RD, IP_WR; 29 | wire [ABUSWIDTH-1:0] IP_ADD; 30 | wire [7:0] IP_DATA_IN; 31 | wire [7:0] IP_DATA_OUT; 32 | 33 | bus_to_ip #( 34 | .BASEADDR(BASEADDR), 35 | .HIGHADDR(HIGHADDR), 36 | .ABUSWIDTH(ABUSWIDTH) 37 | ) bus_to_ip ( 38 | .BUS_RD(BUS_RD), 39 | .BUS_WR(BUS_WR), 40 | .BUS_ADD(BUS_ADD), 41 | .BUS_DATA(BUS_DATA), 42 | 43 | .IP_RD(IP_RD), 44 | .IP_WR(IP_WR), 45 | .IP_ADD(IP_ADD), 46 | .IP_DATA_IN(IP_DATA_IN), 47 | .IP_DATA_OUT(IP_DATA_OUT) 48 | ); 49 | 50 | gpio_core #( 51 | .ABUSWIDTH(ABUSWIDTH), 52 | .IO_WIDTH(IO_WIDTH), 53 | .IO_DIRECTION(IO_DIRECTION), 54 | .IO_TRI(IO_TRI) 55 | ) core ( 56 | .BUS_CLK(BUS_CLK), 57 | .BUS_RST(BUS_RST), 58 | .BUS_ADD(IP_ADD), 59 | .BUS_DATA_IN(IP_DATA_IN), 60 | .BUS_DATA_OUT(IP_DATA_OUT), 61 | .BUS_RD(IP_RD), 62 | .BUS_WR(IP_WR), 63 | 64 | .IO(IO) 65 | ); 66 | 67 | endmodule 68 | -------------------------------------------------------------------------------- /basil/firmware/modules/gpio/gpio_sbus.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module gpio_sbus #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter IO_WIDTH = 8, 15 | parameter IO_DIRECTION = 0, 16 | parameter IO_TRI = 0 17 | ) ( 18 | input wire BUS_CLK, 19 | input wire BUS_RST, 20 | input wire [ABUSWIDTH-1:0] BUS_ADD, 21 | input wire [7:0] BUS_DATA_IN, 22 | output wire [7:0] BUS_DATA_OUT, 23 | input wire BUS_RD, 24 | input wire BUS_WR, 25 | 26 | inout wire [IO_WIDTH-1:0] IO 27 | 28 | ); 29 | 30 | 31 | wire IP_RD, IP_WR; 32 | wire [ABUSWIDTH-1:0] IP_ADD; 33 | wire [7:0] IP_DATA_IN; 34 | wire [7:0] IP_DATA_OUT; 35 | 36 | sbus_to_ip #( 37 | .BASEADDR(BASEADDR), 38 | .HIGHADDR(HIGHADDR), 39 | .ABUSWIDTH(ABUSWIDTH) 40 | ) sbus_to_ip ( 41 | .BUS_CLK(BUS_CLK), 42 | .BUS_RD(BUS_RD), 43 | .BUS_WR(BUS_WR), 44 | .BUS_ADD(BUS_ADD), 45 | .BUS_DATA_IN(BUS_DATA_IN), 46 | .BUS_DATA_OUT(BUS_DATA_OUT), 47 | .IP_RD(IP_RD), 48 | .IP_WR(IP_WR), 49 | .IP_ADD(IP_ADD), 50 | .IP_DATA_IN(IP_DATA_IN), 51 | .IP_DATA_OUT(IP_DATA_OUT) 52 | ); 53 | 54 | 55 | gpio_core #( 56 | .ABUSWIDTH(ABUSWIDTH), 57 | .IO_WIDTH(IO_WIDTH), 58 | .IO_DIRECTION(IO_DIRECTION), 59 | .IO_TRI(IO_TRI) 60 | ) core ( 61 | .BUS_CLK(BUS_CLK), 62 | .BUS_RST(BUS_RST), 63 | .BUS_ADD(IP_ADD), 64 | .BUS_DATA_IN(IP_DATA_IN), 65 | .BUS_DATA_OUT(IP_DATA_OUT), 66 | .BUS_RD(IP_RD), 67 | .BUS_WR(IP_WR), 68 | 69 | .IO(IO) 70 | ); 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /basil/firmware/modules/i2c/i2c.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module i2c #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter MEM_BYTES = 1, 15 | parameter IGNORE_ACK = 0 16 | ) ( 17 | input wire BUS_CLK, 18 | input wire BUS_RST, 19 | input wire [ABUSWIDTH-1:0] BUS_ADD, 20 | inout wire [7:0] BUS_DATA, 21 | input wire BUS_RD, 22 | input wire BUS_WR, 23 | 24 | input wire I2C_CLK, 25 | inout wire I2C_SDA, 26 | inout wire I2C_SCL 27 | ); 28 | 29 | wire IP_RD, IP_WR; 30 | wire [ABUSWIDTH-1:0] IP_ADD; 31 | wire [7:0] IP_DATA_IN; 32 | wire [7:0] IP_DATA_OUT; 33 | 34 | bus_to_ip #( 35 | .BASEADDR(BASEADDR), 36 | .HIGHADDR(HIGHADDR), 37 | .ABUSWIDTH(ABUSWIDTH) 38 | ) i_bus_to_ip ( 39 | .BUS_RD(BUS_RD), 40 | .BUS_WR(BUS_WR), 41 | .BUS_ADD(BUS_ADD), 42 | .BUS_DATA(BUS_DATA), 43 | 44 | .IP_RD(IP_RD), 45 | .IP_WR(IP_WR), 46 | .IP_ADD(IP_ADD), 47 | .IP_DATA_IN(IP_DATA_IN), 48 | .IP_DATA_OUT(IP_DATA_OUT) 49 | ); 50 | 51 | 52 | i2c_core #( 53 | .ABUSWIDTH(ABUSWIDTH), 54 | .MEM_BYTES(MEM_BYTES), 55 | .IGNORE_ACK(IGNORE_ACK) 56 | ) i_i2c_core ( 57 | .BUS_CLK(BUS_CLK), 58 | .BUS_RST(BUS_RST), 59 | .BUS_ADD(IP_ADD), 60 | .BUS_DATA_IN(IP_DATA_IN), 61 | .BUS_RD(IP_RD), 62 | .BUS_WR(IP_WR), 63 | .BUS_DATA_OUT(IP_DATA_OUT), 64 | 65 | .I2C_CLK(I2C_CLK), 66 | .I2C_SDA(I2C_SDA), 67 | .I2C_SCL(I2C_SCL) 68 | ); 69 | 70 | 71 | endmodule 72 | -------------------------------------------------------------------------------- /basil/firmware/modules/includes/log2func.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | 8 | `ifdef _IVERILOG_ 9 | `define CLOG2 $clog2 10 | `else 11 | function integer clog2; 12 | input integer value; 13 | reg [31:0] shifted; 14 | integer res; 15 | begin 16 | if (value < 2) 17 | clog2 = value; 18 | else 19 | begin 20 | shifted = value-1; 21 | for (res=0; shifted>0; res=res+1) 22 | shifted = shifted>>1; 23 | clog2 = res; 24 | end 25 | end 26 | endfunction 27 | 28 | `define CLOG2 clog2 29 | `endif 30 | -------------------------------------------------------------------------------- /basil/firmware/modules/jtag_master/jtag_master.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module jtag_master #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter MEM_BYTES = 2 15 | ) ( 16 | input wire BUS_CLK, 17 | input wire BUS_RST, 18 | input wire [ABUSWIDTH-1:0] BUS_ADD, 19 | inout wire [7:0] BUS_DATA, 20 | input wire BUS_RD, 21 | input wire BUS_WR, 22 | 23 | input wire JTAG_CLK, 24 | 25 | output wire TCK, // TCK 26 | input wire TDO, // TDO 27 | output wire TDI, // TDI 28 | output wire TMS, // TMS 29 | 30 | output wire SEN, 31 | output wire SLD 32 | ); 33 | 34 | 35 | wire IP_RD, IP_WR; 36 | wire [ABUSWIDTH-1:0] IP_ADD; 37 | wire [7:0] IP_DATA_IN; 38 | wire [7:0] IP_DATA_OUT; 39 | 40 | // Module to map basil bus address to jtag_spi_core internal address 41 | bus_to_ip #( 42 | .BASEADDR(BASEADDR), 43 | .HIGHADDR(HIGHADDR), 44 | .ABUSWIDTH(ABUSWIDTH) 45 | ) i_bus_to_ip ( 46 | .BUS_RD(BUS_RD), 47 | .BUS_WR(BUS_WR), 48 | .BUS_ADD(BUS_ADD), 49 | .BUS_DATA(BUS_DATA), 50 | 51 | .IP_RD(IP_RD), 52 | .IP_WR(IP_WR), 53 | .IP_ADD(IP_ADD), 54 | .IP_DATA_IN(IP_DATA_IN), 55 | .IP_DATA_OUT(IP_DATA_OUT) 56 | ); 57 | 58 | jtag_master_core #( 59 | .ABUSWIDTH(ABUSWIDTH), 60 | .MEM_BYTES(MEM_BYTES) 61 | ) i_jtag_master_core ( 62 | .BUS_CLK(BUS_CLK), 63 | .BUS_RST(BUS_RST), 64 | .BUS_ADD(IP_ADD), 65 | .BUS_DATA_IN(IP_DATA_IN), 66 | .BUS_RD(IP_RD), 67 | .BUS_WR(IP_WR), 68 | .BUS_DATA_OUT(IP_DATA_OUT), 69 | 70 | .JTAG_CLK(JTAG_CLK), 71 | 72 | .TCK(TCK), 73 | .TDO(TDO), 74 | .TDI(TDI), 75 | .TMS(TMS), 76 | 77 | .SEN(SEN), 78 | .SLD(SLD) 79 | ); 80 | 81 | endmodule 82 | -------------------------------------------------------------------------------- /basil/firmware/modules/m26_rx/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **m26_rx** - MIMOSA26 data receiver 4 | ===================================== 5 | 6 | Allows continuous data recording from MIMOSA26. Received data are propagated to FIFO data interface. 7 | Implements error monitoring. 8 | -------------------------------------------------------------------------------- /basil/firmware/modules/m26_rx/m26_rx.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module m26_rx #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter HEADER = 0, 15 | parameter IDENTIFIER = 0 16 | ) ( 17 | input wire BUS_CLK, 18 | input wire [ABUSWIDTH-1:0] BUS_ADD, 19 | inout wire [7:0] BUS_DATA, 20 | input wire BUS_RST, 21 | input wire BUS_WR, 22 | input wire BUS_RD, 23 | 24 | input wire CLK_RX, 25 | input wire MKD_RX, 26 | input wire [1:0] DATA_RX, 27 | 28 | input wire FIFO_READ, 29 | output wire FIFO_EMPTY, 30 | output wire [31:0] FIFO_DATA, 31 | 32 | input wire [31:0] TIMESTAMP, 33 | 34 | output wire LOST_ERROR, 35 | output wire INVALID, 36 | output wire INVALID_FLAG 37 | ); 38 | 39 | wire IP_RD, IP_WR; 40 | wire [ABUSWIDTH-1:0] IP_ADD; 41 | wire [7:0] IP_DATA_IN; 42 | wire [7:0] IP_DATA_OUT; 43 | 44 | bus_to_ip #( 45 | .BASEADDR(BASEADDR), 46 | .HIGHADDR(HIGHADDR), 47 | .ABUSWIDTH(ABUSWIDTH) 48 | ) i_bus_to_ip ( 49 | .BUS_RD(BUS_RD), 50 | .BUS_WR(BUS_WR), 51 | .BUS_ADD(BUS_ADD), 52 | .BUS_DATA(BUS_DATA), 53 | 54 | .IP_RD(IP_RD), 55 | .IP_WR(IP_WR), 56 | .IP_ADD(IP_ADD), 57 | .IP_DATA_IN(IP_DATA_IN), 58 | .IP_DATA_OUT(IP_DATA_OUT) 59 | ); 60 | 61 | m26_rx_core #( 62 | .ABUSWIDTH(ABUSWIDTH), 63 | .IDENTIFIER(IDENTIFIER), 64 | .HEADER(HEADER) 65 | ) i_m26_rx_core ( 66 | .BUS_CLK(BUS_CLK), 67 | .BUS_RST(BUS_RST), 68 | .BUS_ADD(IP_ADD), 69 | .BUS_DATA_IN(IP_DATA_IN), 70 | .BUS_RD(IP_RD), 71 | .BUS_WR(IP_WR), 72 | .BUS_DATA_OUT(IP_DATA_OUT), 73 | 74 | .CLK_RX(CLK_RX), 75 | .MKD_RX(MKD_RX), 76 | .DATA_RX(DATA_RX), 77 | 78 | .FIFO_READ(FIFO_READ), 79 | .FIFO_EMPTY(FIFO_EMPTY), 80 | .FIFO_DATA(FIFO_DATA), 81 | 82 | .TIMESTAMP(TIMESTAMP), 83 | 84 | .LOST_ERROR(LOST_ERROR), 85 | .INVALID(INVALID), 86 | .INVALID_FLAG(INVALID_FLAG) 87 | ); 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /basil/firmware/modules/pulse_gen/pulse_gen.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module pulse_gen #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16 14 | ) ( 15 | input wire BUS_CLK, 16 | input wire BUS_RST, 17 | input wire [ABUSWIDTH-1:0] BUS_ADD, 18 | inout wire [7:0] BUS_DATA, 19 | input wire BUS_RD, 20 | input wire BUS_WR, 21 | 22 | input wire PULSE_CLK, 23 | input wire EXT_START, 24 | output wire PULSE 25 | ); 26 | 27 | wire IP_RD, IP_WR; 28 | wire [ABUSWIDTH-1:0] IP_ADD; 29 | wire [7:0] IP_DATA_IN; 30 | wire [7:0] IP_DATA_OUT; 31 | 32 | bus_to_ip #( 33 | .BASEADDR(BASEADDR), 34 | .HIGHADDR(HIGHADDR), 35 | .ABUSWIDTH(ABUSWIDTH) 36 | ) i_bus_to_ip ( 37 | .BUS_RD(BUS_RD), 38 | .BUS_WR(BUS_WR), 39 | .BUS_ADD(BUS_ADD), 40 | .BUS_DATA(BUS_DATA), 41 | 42 | .IP_RD(IP_RD), 43 | .IP_WR(IP_WR), 44 | .IP_ADD(IP_ADD), 45 | .IP_DATA_IN(IP_DATA_IN), 46 | .IP_DATA_OUT(IP_DATA_OUT) 47 | ); 48 | 49 | pulse_gen_core #( 50 | .ABUSWIDTH(ABUSWIDTH) 51 | ) i_pulse_gen_core ( 52 | .BUS_CLK(BUS_CLK), 53 | .BUS_RST(BUS_RST), 54 | .BUS_ADD(IP_ADD), 55 | .BUS_DATA_IN(IP_DATA_IN), 56 | .BUS_RD(IP_RD), 57 | .BUS_WR(IP_WR), 58 | .BUS_DATA_OUT(IP_DATA_OUT), 59 | 60 | .PULSE_CLK(PULSE_CLK), 61 | .EXT_START(EXT_START), 62 | .PULSE(PULSE) 63 | ); 64 | 65 | endmodule 66 | -------------------------------------------------------------------------------- /basil/firmware/modules/seq_gen/seq_gen.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module seq_gen #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | 15 | parameter MEM_BYTES = 16384, 16 | parameter OUT_BITS = 8 17 | ) ( 18 | input wire BUS_CLK, 19 | input wire BUS_RST, 20 | input wire [ABUSWIDTH-1:0] BUS_ADD, 21 | inout wire [7:0] BUS_DATA, 22 | input wire BUS_RD, 23 | input wire BUS_WR, 24 | 25 | input wire SEQ_EXT_START, 26 | input wire SEQ_CLK, 27 | output wire [OUT_BITS-1:0] SEQ_OUT 28 | ); 29 | 30 | wire IP_RD, IP_WR; 31 | wire [ABUSWIDTH-1:0] IP_ADD; 32 | wire [7:0] IP_DATA_IN; 33 | wire [7:0] IP_DATA_OUT; 34 | 35 | bus_to_ip #( 36 | .BASEADDR(BASEADDR), 37 | .HIGHADDR(HIGHADDR), 38 | .ABUSWIDTH(ABUSWIDTH) 39 | ) i_bus_to_ip ( 40 | .BUS_RD(BUS_RD), 41 | .BUS_WR(BUS_WR), 42 | .BUS_ADD(BUS_ADD), 43 | .BUS_DATA(BUS_DATA), 44 | 45 | .IP_RD(IP_RD), 46 | .IP_WR(IP_WR), 47 | .IP_ADD(IP_ADD), 48 | .IP_DATA_IN(IP_DATA_IN), 49 | .IP_DATA_OUT(IP_DATA_OUT) 50 | ); 51 | 52 | seq_gen_core #( 53 | .ABUSWIDTH(ABUSWIDTH), 54 | .MEM_BYTES(MEM_BYTES), 55 | .OUT_BITS(OUT_BITS) 56 | ) i_seq_gen_core ( 57 | .BUS_CLK(BUS_CLK), 58 | .BUS_RST(BUS_RST), 59 | .BUS_ADD(IP_ADD), 60 | .BUS_DATA_IN(IP_DATA_IN), 61 | .BUS_RD(IP_RD), 62 | .BUS_WR(IP_WR), 63 | .BUS_DATA_OUT(IP_DATA_OUT), 64 | 65 | .SEQ_EXT_START(SEQ_EXT_START), 66 | .SEQ_CLK(SEQ_CLK), 67 | .SEQ_OUT(SEQ_OUT) 68 | ); 69 | 70 | endmodule 71 | -------------------------------------------------------------------------------- /basil/firmware/modules/seq_rec/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ============================ 3 | **seq_rec** - data recorder 4 | ============================ 5 | 6 | Simple module that allow recording arbitrary data vector. 7 | 8 | **Unit test/Example:** 9 | `test_SimSeq.v `_ 10 | `test_SimSeq.py `_ 11 | -------------------------------------------------------------------------------- /basil/firmware/modules/seq_rec/seq_rec.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module seq_rec #( 11 | parameter BASEADDR = 0, 12 | parameter HIGHADDR = 0, 13 | parameter ABUSWIDTH = 16, 14 | parameter MEM_BYTES = 2*1024, 15 | parameter IN_BITS = 8 16 | ) ( 17 | input wire BUS_CLK, 18 | input wire BUS_RST, 19 | input wire [ABUSWIDTH-1:0] BUS_ADD, 20 | inout wire [7:0] BUS_DATA, 21 | input wire BUS_RD, 22 | input wire BUS_WR, 23 | 24 | input wire SEQ_CLK, 25 | input wire [IN_BITS-1:0] SEQ_IN, 26 | input wire SEQ_EXT_START 27 | ); 28 | 29 | wire IP_RD, IP_WR; 30 | wire [ABUSWIDTH-1:0] IP_ADD; 31 | wire [7:0] IP_DATA_IN; 32 | wire [7:0] IP_DATA_OUT; 33 | 34 | bus_to_ip #( 35 | .BASEADDR(BASEADDR), 36 | .HIGHADDR(HIGHADDR), 37 | .ABUSWIDTH(ABUSWIDTH) 38 | ) bus_to_ip ( 39 | .BUS_RD(BUS_RD), 40 | .BUS_WR(BUS_WR), 41 | .BUS_ADD(BUS_ADD), 42 | .BUS_DATA(BUS_DATA), 43 | 44 | .IP_RD(IP_RD), 45 | .IP_WR(IP_WR), 46 | .IP_ADD(IP_ADD), 47 | .IP_DATA_IN(IP_DATA_IN), 48 | .IP_DATA_OUT(IP_DATA_OUT) 49 | ); 50 | 51 | seq_rec_core #( 52 | .ABUSWIDTH(ABUSWIDTH), 53 | .MEM_BYTES(MEM_BYTES), 54 | .IN_BITS(IN_BITS) 55 | ) seq_rec_core ( 56 | .BUS_CLK(BUS_CLK), 57 | .BUS_RST(BUS_RST), 58 | .BUS_ADD(IP_ADD), 59 | .BUS_DATA_IN(IP_DATA_IN), 60 | .BUS_RD(IP_RD), 61 | .BUS_WR(IP_WR), 62 | .BUS_DATA_OUT(IP_DATA_OUT), 63 | .SEQ_CLK(SEQ_CLK), 64 | .SEQ_IN(SEQ_IN), 65 | .SEQ_EXT_START(SEQ_EXT_START) 66 | ); 67 | 68 | endmodule 69 | -------------------------------------------------------------------------------- /basil/firmware/modules/spi/blk_mem_gen_8_to_1_2k.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module blk_mem_gen_8_to_1_2k ( 11 | CLKA, CLKB, DOUTA, DOUTB, WEA, WEB, ADDRA, ADDRB, DINA, DINB 12 | ); 13 | 14 | input wire CLKA; 15 | input wire CLKB; 16 | output wire [7 : 0] DOUTA; 17 | output wire [0 : 0] DOUTB; 18 | input wire [0 : 0] WEA; 19 | input wire [0 : 0] WEB; 20 | input wire [10 : 0] ADDRA; 21 | input wire [13 : 0] ADDRB; 22 | input wire [7 : 0] DINA; 23 | input wire [0 : 0] DINB; 24 | 25 | RAMB16_S1_S9 dpram ( 26 | .CLKA(CLKB), 27 | .CLKB(CLKA), 28 | .ENB(1'b1), 29 | .WEA(WEB), 30 | .WEB(WEA), 31 | .ENA(1'b1), 32 | .SSRA(1'b0), 33 | .SSRB(1'b0), 34 | .DIPB(1'b0), 35 | .ADDRA(ADDRB), 36 | .ADDRB(ADDRA), 37 | .DIA(DINB), 38 | .DIB(DINA), 39 | .DOA(DOUTB), 40 | .DOB(DOUTA), 41 | .DOPB() 42 | ); 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /basil/firmware/modules/spi/spi.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module spi #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter MEM_BYTES = 2 15 | ) ( 16 | input wire BUS_CLK, 17 | input wire BUS_RST, 18 | input wire [ABUSWIDTH-1:0] BUS_ADD, 19 | inout wire [7:0] BUS_DATA, 20 | input wire BUS_RD, 21 | input wire BUS_WR, 22 | 23 | input wire SPI_CLK, 24 | 25 | output wire SCLK, 26 | input wire SDO, 27 | output wire SDI, 28 | input wire EXT_START, 29 | 30 | output wire SEN, 31 | output wire SLD 32 | ); 33 | 34 | 35 | wire IP_RD, IP_WR; 36 | wire [ABUSWIDTH-1:0] IP_ADD; 37 | wire [7:0] IP_DATA_IN; 38 | wire [7:0] IP_DATA_OUT; 39 | 40 | bus_to_ip #( 41 | .BASEADDR(BASEADDR), 42 | .HIGHADDR(HIGHADDR), 43 | .ABUSWIDTH(ABUSWIDTH) 44 | ) i_bus_to_ip ( 45 | .BUS_RD(BUS_RD), 46 | .BUS_WR(BUS_WR), 47 | .BUS_ADD(BUS_ADD), 48 | .BUS_DATA(BUS_DATA), 49 | 50 | .IP_RD(IP_RD), 51 | .IP_WR(IP_WR), 52 | .IP_ADD(IP_ADD), 53 | .IP_DATA_IN(IP_DATA_IN), 54 | .IP_DATA_OUT(IP_DATA_OUT) 55 | ); 56 | 57 | 58 | spi_core #( 59 | .ABUSWIDTH(ABUSWIDTH), 60 | .MEM_BYTES(MEM_BYTES) 61 | ) i_spi_core ( 62 | .BUS_CLK(BUS_CLK), 63 | .BUS_RST(BUS_RST), 64 | .BUS_ADD(IP_ADD), 65 | .BUS_DATA_IN(IP_DATA_IN), 66 | .BUS_RD(IP_RD), 67 | .BUS_WR(IP_WR), 68 | .BUS_DATA_OUT(IP_DATA_OUT), 69 | 70 | .SPI_CLK(SPI_CLK), 71 | 72 | .SCLK(SCLK), 73 | .SDO(SDO), 74 | .SDI(SDI), 75 | .EXT_START(EXT_START), 76 | 77 | .SEN(SEN), 78 | .SLD(SLD) 79 | ); 80 | 81 | endmodule 82 | -------------------------------------------------------------------------------- /basil/firmware/modules/timestamp/timestamp.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module timestamp #( 11 | parameter BASEADDR = 16'h0000, 12 | parameter HIGHADDR = 16'h0000, 13 | parameter ABUSWIDTH = 16, 14 | parameter IDENTIFIER = 4'b0001 15 | ) ( 16 | input wire BUS_CLK, 17 | input wire [ABUSWIDTH-1:0] BUS_ADD, 18 | inout wire [7:0] BUS_DATA, 19 | input wire BUS_RST, 20 | input wire BUS_WR, 21 | input wire BUS_RD, 22 | 23 | input wire CLK, 24 | input wire DI, 25 | input wire [63:0] EXT_TIMESTAMP, 26 | output wire [63:0] TIMESTAMP_OUT, 27 | input wire EXT_ENABLE, 28 | 29 | input wire FIFO_READ, 30 | output wire FIFO_EMPTY, 31 | output wire [31:0] FIFO_DATA 32 | 33 | ); 34 | 35 | wire IP_RD, IP_WR; 36 | wire [ABUSWIDTH-1:0] IP_ADD; 37 | wire [7:0] IP_DATA_IN; 38 | wire [7:0] IP_DATA_OUT; 39 | 40 | bus_to_ip #( 41 | .BASEADDR(BASEADDR), 42 | .HIGHADDR(HIGHADDR), 43 | .ABUSWIDTH(ABUSWIDTH) 44 | ) i_bus_to_ip ( 45 | .BUS_RD(BUS_RD), 46 | .BUS_WR(BUS_WR), 47 | .BUS_ADD(BUS_ADD), 48 | .BUS_DATA(BUS_DATA), 49 | 50 | .IP_RD(IP_RD), 51 | .IP_WR(IP_WR), 52 | .IP_ADD(IP_ADD), 53 | .IP_DATA_IN(IP_DATA_IN), 54 | .IP_DATA_OUT(IP_DATA_OUT) 55 | ); 56 | 57 | timestamp_core #( 58 | .ABUSWIDTH(ABUSWIDTH), 59 | .IDENTIFIER(IDENTIFIER) 60 | ) i_timestamp_core ( 61 | .BUS_CLK(BUS_CLK), 62 | .BUS_RST(BUS_RST), 63 | .BUS_ADD(IP_ADD), 64 | .BUS_DATA_IN(IP_DATA_IN), 65 | .BUS_RD(IP_RD), 66 | .BUS_WR(IP_WR), 67 | .BUS_DATA_OUT(IP_DATA_OUT), 68 | 69 | .CLK(CLK), 70 | .DI(DI), 71 | .TIMESTAMP_OUT(TIMESTAMP_OUT), 72 | .EXT_TIMESTAMP(EXT_TIMESTAMP), 73 | .EXT_ENABLE(EXT_ENABLE), 74 | 75 | .FIFO_READ(FIFO_READ), 76 | .FIFO_EMPTY(FIFO_EMPTY), 77 | .FIFO_DATA(FIFO_DATA) 78 | ); 79 | 80 | endmodule 81 | -------------------------------------------------------------------------------- /basil/firmware/modules/uart/README.rst: -------------------------------------------------------------------------------- 1 | 2 | ===================================== 3 | **uart** - UART slave 4 | ===================================== 5 | 6 | Provides UART to basil interface. 7 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/3_stage_synchronizer.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | // synchronizing asynchronous signals/flags, prevents metastable events 11 | 12 | module three_stage_synchronizer #( 13 | parameter WIDTH = 1 14 | ) ( 15 | input wire CLK, 16 | input wire [WIDTH-1:0] IN, 17 | output wire [WIDTH-1:0] OUT 18 | ); 19 | 20 | (* ASYNC_REG = "TRUE" *) reg [WIDTH-1:0] out_d_ff_1; 21 | (* ASYNC_REG = "TRUE" *) reg [WIDTH-1:0] out_d_ff_2; 22 | (* ASYNC_REG = "TRUE" *) reg [WIDTH-1:0] out_d_ff_3; 23 | 24 | always @(posedge CLK) // first stage 25 | begin 26 | out_d_ff_1 <= IN; 27 | end 28 | 29 | always @(posedge CLK) // second stage 30 | begin 31 | out_d_ff_2 <= out_d_ff_1; 32 | end 33 | 34 | always @(posedge CLK) // third stage 35 | begin 36 | out_d_ff_3 <= out_d_ff_2; 37 | end 38 | 39 | assign OUT = out_d_ff_3; 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/BUFG_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module BUFG ( 12 | input wire I, 13 | output wire O 14 | ); 15 | 16 | assign O = I; 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/CG_MOD_neg.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module CG_MOD_neg ( 12 | ck_in, 13 | enable, 14 | ck_out 15 | ); 16 | 17 | input ck_in,enable; 18 | output ck_out; 19 | reg enl; 20 | 21 | // verilator lint_off LATCH 22 | always @(ck_in or enable) 23 | if (ck_in) 24 | enl = enable; 25 | // verilator lint_on LATCH 26 | 27 | assign ck_out = ck_in | ~enl; 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/CG_MOD_pos.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module CG_MOD_pos ( 12 | input wire ck_in, 13 | input wire enable, 14 | output wire ck_out 15 | ); 16 | 17 | wire ck_inb; 18 | reg enl; 19 | 20 | assign ck_inb = ~ck_in; 21 | 22 | // verilator lint_off LATCH 23 | always @(ck_inb or enable) 24 | if (ck_inb) 25 | enl = enable; 26 | // verilator lint_on LATCH 27 | 28 | assign ck_out = ck_in & enl; 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/IBUFDS_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module IBUFDS #( 11 | parameter DIFF_TERM = "TRUE", 12 | parameter IOSTANDARD = "LVDS_25" 13 | ) ( 14 | output wire O, 15 | input wire I, IB 16 | ); 17 | 18 | assign O = I && !IB; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/IBUFGDS_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module IBUFGDS #( 11 | parameter DIFF_TERM = "TRUE", 12 | parameter IOSTANDARD = "LVDS_25" 13 | ) ( 14 | output wire O, 15 | input wire I, IB 16 | ); 17 | 18 | assign O = I && !IB; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/IDDR_s3.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module IDDR ( 12 | output wire Q1, Q2, 13 | input wire C, CE, D, R, S 14 | ); 15 | 16 | IFDDRRSE IFDDRRSE_inst ( 17 | .Q0(Q1), 18 | .Q1(Q2), 19 | .C0(C), 20 | .C1(~C), 21 | .CE(CE), 22 | .D(D), 23 | .R(R), 24 | .S(S) 25 | ); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/IDDR_s3_noibuf.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module IDDR ( 12 | output wire Q1, Q2, 13 | input wire C, CE, D, R, S 14 | ); 15 | 16 | FDRSE F0 ( 17 | .C(C), 18 | .CE(CE), 19 | .R(R), 20 | .D(D), 21 | .S(S), 22 | .Q(Q1) 23 | ); 24 | defparam F0.INIT = 1'b0; 25 | 26 | FDRSE F1 ( 27 | .C(~C), 28 | .CE(CE), 29 | .R(R), 30 | .D(D), 31 | .S(S), 32 | .Q(Q2) 33 | ); 34 | defparam F1.INIT = "0"; 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/IDDR_s6.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module IDDR ( 12 | output wire Q1, Q2, 13 | input wire C, CE, D, R, S 14 | ); 15 | 16 | IDDR2 IDDR2_inst ( 17 | .Q0(Q1), 18 | .Q1(Q2), 19 | .C0(C), 20 | .C1(~C), 21 | .CE(CE), 22 | .D(D), 23 | .R(R), 24 | .S(S) 25 | ); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/IDDR_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module IDDR ( 12 | output reg Q1, Q2, 13 | input wire C, CE, D, R, S 14 | ); 15 | 16 | 17 | always @(posedge C) begin 18 | if (R==1'b1) 19 | Q1 <= 1'b0; 20 | else if (S==1'b1) 21 | Q1 <= 1'b1; 22 | else if (CE) 23 | if (D==1'b1) 24 | Q1 <= 1'b1; 25 | else if (D==1'b0) 26 | Q1 <= 1'b0; 27 | end 28 | 29 | 30 | always @(negedge C) 31 | begin 32 | if (R==1'b1) 33 | Q2 <= 1'b0; 34 | else if (S==1'b1) 35 | Q2 <= 1'b1; 36 | else if (CE) 37 | if (D==1'b1) 38 | Q2 <= 1'b1; 39 | else if (D==1'b0) 40 | Q2 <= 1'b0; 41 | end 42 | 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/OBUFDS_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | module OBUFDS #( 11 | parameter IOSTANDARD = "LVDS_25" 12 | ) ( 13 | output wire O, OB, 14 | input wire I 15 | ); 16 | 17 | assign O = I; 18 | assign OB = !I; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/ODDR_s3.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module ODDR ( 12 | input wire D1, D2, 13 | input wire C, CE, R, S, 14 | output wire Q 15 | ); 16 | 17 | OFDDRRSE OFDDRRSE_INST ( 18 | .CE(CE), 19 | .C0(C), 20 | .C1(~C), 21 | .D0(D1), 22 | .D1(D2), 23 | .R(R), 24 | .S(S), 25 | .Q(Q) 26 | ); 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/ODDR_s6.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module ODDR ( 12 | input wire D1, D2, 13 | input wire C, CE, R, S, 14 | output wire Q 15 | ); 16 | 17 | ODDR2 ODDR2_inst ( 18 | .Q(Q), 19 | .C0(C), 20 | .C1(~C), 21 | .CE(CE), 22 | .D0(D1), 23 | .D1(D2), 24 | .R(R), 25 | .S(S) 26 | ); 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/ODDR_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module ODDR ( 12 | input wire D1, D2, 13 | input wire C, CE, R, S, 14 | output wire Q 15 | ); 16 | 17 | reg Q1, Q2; 18 | 19 | always @(posedge C) 20 | Q1 <= D1; 21 | 22 | always @(negedge C) 23 | Q2 <= D2; 24 | 25 | assign Q = C ? Q1 & CE : Q2 & CE; 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/RAMB16_S1_S2_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module RAMB16_S1_S2 ( 12 | CLKA, CLKB, ENB, WEA, WEB, ENA, SSRA, SSRB, DIPB, ADDRA, ADDRB, DIA, DIB, DOA, DOB, DOPB 13 | ); 14 | input wire CLKA; 15 | input wire CLKB; 16 | output reg [1 : 0] DOB; 17 | output reg [0 : 0] DOA; 18 | input wire [0 : 0] WEA; 19 | input wire [0 : 0] WEB; 20 | input wire [12 : 0] ADDRB; 21 | input wire [13 : 0] ADDRA; 22 | input wire [1 : 0] DIB; 23 | input wire [0 : 0] DIA; 24 | 25 | input wire ENB; 26 | input wire ENA; 27 | input wire SSRA; 28 | input wire SSRB; 29 | input wire DIPB; 30 | output wire DOPB; 31 | 32 | parameter WIDTHA = 1; 33 | parameter SIZEA = 16384; 34 | parameter ADDRWIDTHA = 14; 35 | parameter WIDTHB = 2; 36 | parameter SIZEB = SIZEA/2; 37 | parameter ADDRWIDTHB = 13; 38 | 39 | `define max(a,b) (a) > (b) ? (a) : (b) 40 | `define min(a,b) (a) < (b) ? (a) : (b) 41 | 42 | `include "../includes/log2func.v" 43 | 44 | localparam maxSIZE = `max(SIZEA, SIZEB); 45 | localparam maxWIDTH = `max(WIDTHA, WIDTHB); 46 | localparam minWIDTH = `min(WIDTHA, WIDTHB); 47 | localparam RATIO = maxWIDTH / minWIDTH; 48 | localparam log2RATIO = `CLOG2(RATIO); 49 | 50 | reg [minWIDTH-1:0] RAM [0:maxSIZE-1]; 51 | 52 | always @(posedge CLKA) 53 | if (WEA) 54 | RAM[ADDRA] <= DIA; 55 | else 56 | DOA <= RAM[ADDRA]; 57 | 58 | genvar i; 59 | generate for (i = 0; i < RATIO; i = i+1) 60 | begin: portA 61 | localparam [log2RATIO-1:0] lsbaddr = i; 62 | always @(posedge CLKB) 63 | if (WEB) 64 | RAM[{ADDRB, lsbaddr}] <= DIB[(i+1)*minWIDTH-1:i*minWIDTH]; 65 | else 66 | DOB[(i+1)*minWIDTH-1:i*minWIDTH] <= RAM[{ADDRB, lsbaddr}]; 67 | end 68 | endgenerate 69 | 70 | endmodule 71 | 72 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/RAMB16_S1_S9_sim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module RAMB16_S1_S9 ( 12 | CLKA, CLKB, ENB, WEA, WEB, ENA, SSRA, SSRB, DIPB, ADDRA, ADDRB, DIA, DIB, DOA, DOB, DOPB 13 | ); 14 | input wire CLKA; 15 | input wire CLKB; 16 | output reg [7 : 0] DOB; 17 | output reg [0 : 0] DOA; 18 | input wire [0 : 0] WEA; 19 | input wire [0 : 0] WEB; 20 | input wire [10 : 0] ADDRB; 21 | input wire [13 : 0] ADDRA; 22 | input wire [7 : 0] DIB; 23 | input wire [0 : 0] DIA; 24 | 25 | input wire ENB; 26 | input wire ENA; 27 | input wire SSRA; 28 | input wire SSRB; 29 | input wire DIPB; 30 | output wire DOPB; 31 | 32 | parameter WIDTHA = 1; 33 | parameter SIZEA = 16384; 34 | parameter ADDRWIDTHA = 14; 35 | parameter WIDTHB = 8; 36 | parameter SIZEB = 2048; 37 | parameter ADDRWIDTHB = 11; 38 | 39 | `define max(a,b) (a) > (b) ? (a) : (b) 40 | `define min(a,b) (a) < (b) ? (a) : (b) 41 | 42 | `include "../includes/log2func.v" 43 | 44 | localparam maxSIZE = `max(SIZEA, SIZEB); 45 | localparam maxWIDTH = `max(WIDTHA, WIDTHB); 46 | localparam minWIDTH = `min(WIDTHA, WIDTHB); 47 | localparam RATIO = maxWIDTH / minWIDTH; 48 | localparam log2RATIO = `CLOG2(RATIO); 49 | 50 | reg [minWIDTH-1:0] RAM [0:maxSIZE-1]; 51 | 52 | always @(posedge CLKA) 53 | if (WEA) 54 | RAM[ADDRA] <= DIA; 55 | else 56 | DOA <= RAM[ADDRA]; 57 | 58 | genvar i; 59 | generate for (i = 0; i < RATIO; i = i+1) 60 | begin: portA 61 | localparam [log2RATIO-1:0] lsbaddr = i; 62 | always @(posedge CLKB) 63 | if (WEB) 64 | RAM[{ADDRB, lsbaddr}] <= DIB[(i+1)*minWIDTH-1:i*minWIDTH]; 65 | else 66 | DOB[(i+1)*minWIDTH-1:i*minWIDTH] <= RAM[{ADDRB, lsbaddr}]; 67 | end 68 | endgenerate 69 | 70 | endmodule 71 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/README.rst: -------------------------------------------------------------------------------- 1 | 2 | =========================== 3 | **utils** 4 | =========================== 5 | 6 | Various Verilog modules used by basil. 7 | 8 | - 3_stage_synchronizer 9 | - bus_to_ip 10 | - cdc_pulse_sync 11 | - cdc_pulse_sync_cnt 12 | - cdc_syncfifo 13 | - CG_MOD_neg 14 | - CG_MOD_pos 15 | - clock_divider 16 | - ddr_des 17 | - fifo_32_to_8 18 | - flag_domain_crossing 19 | - flag_domain_crossing_ce 20 | - generic_fifo 21 | - IDDR_s3 22 | - IDDR_sim 23 | - ODDR_s3 24 | - pulse_gen_rising 25 | - RAMB16_S1_S2_sim 26 | - RAMB16_S1_S9_sim 27 | - rbcp_to_bus 28 | - reset_gen 29 | - simple_arbiter 30 | - three_stage_synchronizer_ce -------------------------------------------------------------------------------- /basil/firmware/modules/utils/bus_to_ip.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module bus_to_ip 12 | #( 13 | parameter BASEADDR = 0, 14 | parameter HIGHADDR = 0, 15 | parameter ABUSWIDTH = 16, 16 | parameter DBUSWIDTH = 8 17 | ) 18 | ( 19 | input wire BUS_RD, 20 | input wire BUS_WR, 21 | input wire [ABUSWIDTH-1:0] BUS_ADD, 22 | inout wire [DBUSWIDTH-1:0] BUS_DATA, 23 | 24 | output wire IP_RD, 25 | output wire IP_WR, 26 | output wire [ABUSWIDTH-1:0] IP_ADD, 27 | output wire [DBUSWIDTH-1:0] IP_DATA_IN, 28 | input wire [DBUSWIDTH-1:0] IP_DATA_OUT 29 | ); 30 | 31 | wire CS; 32 | /* verilator lint_off UNSIGNED */ 33 | assign CS = (BUS_ADD >= BASEADDR && BUS_ADD <= HIGHADDR); 34 | /* verilator lint_on UNSIGNED */ 35 | 36 | assign IP_ADD = CS ? BUS_ADD - BASEADDR : {ABUSWIDTH{1'b0}}; 37 | assign IP_RD = CS ? BUS_RD : 1'b0; 38 | assign IP_WR = CS ? BUS_WR: 1'b0; 39 | 40 | assign IP_DATA_IN = BUS_DATA; 41 | 42 | assign BUS_DATA = (CS && BUS_WR) ? {DBUSWIDTH{1'bz}} : (CS ? IP_DATA_OUT : {DBUSWIDTH{1'bz}}); 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/cdc_pulse_sync.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | // Closed loop solution 11 | 12 | module cdc_pulse_sync ( 13 | input wire clk_in, 14 | input wire pulse_in, 15 | input wire clk_out, 16 | output wire pulse_out 17 | ); 18 | 19 | wire aq_sync; 20 | 21 | reg [1:0] in_pre_sync; 22 | always @(posedge clk_in) begin 23 | in_pre_sync[0] <= pulse_in; 24 | in_pre_sync[1] <= in_pre_sync[0]; 25 | end 26 | 27 | wire pulse_in_flag; 28 | assign pulse_in_flag = !in_pre_sync[1] && in_pre_sync[0]; 29 | 30 | reg in_sync_pulse; 31 | initial in_sync_pulse = 0; // works only in FPGA 32 | always @(posedge clk_in) begin 33 | if (aq_sync) 34 | in_sync_pulse <= 0; 35 | else if (pulse_in_flag) 36 | in_sync_pulse <= 1; 37 | end 38 | 39 | (* ASYNC_REG = "TRUE" *) reg out_sync_ff_1; 40 | (* ASYNC_REG = "TRUE" *) reg out_sync_ff_2; 41 | reg out_sync_ff_3; 42 | always @(posedge clk_out) begin 43 | out_sync_ff_1 <= in_sync_pulse; 44 | out_sync_ff_2 <= out_sync_ff_1; 45 | out_sync_ff_3 <= out_sync_ff_2; 46 | end 47 | 48 | assign pulse_out = !out_sync_ff_3 && out_sync_ff_2; 49 | 50 | (* ASYNC_REG = "TRUE" *) reg aq_sync_ff_1; 51 | (* ASYNC_REG = "TRUE" *) reg aq_sync_ff_2; 52 | always @(posedge clk_in) begin 53 | aq_sync_ff_1 <= out_sync_ff_2; 54 | aq_sync_ff_2 <= aq_sync_ff_1; 55 | end 56 | 57 | assign aq_sync = aq_sync_ff_2; 58 | 59 | endmodule 60 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/cdc_pulse_sync_cnt.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module cdc_pulse_sync_cnt ( 12 | input clk_in, 13 | input pulse_in, 14 | input clk_out, 15 | output pulse_out 16 | ); 17 | 18 | reg [7:0] sync_cnt; 19 | always @(posedge clk_in) begin 20 | if(pulse_in) 21 | sync_cnt <= 120; 22 | else if(sync_cnt != 100) 23 | sync_cnt <= sync_cnt + 1; 24 | end 25 | 26 | (* ASYNC_REG = "TRUE" *) reg out_sync_ff_1; 27 | (* ASYNC_REG = "TRUE" *) reg out_sync_ff_2; 28 | reg out_sync_ff_3; 29 | always @(posedge clk_out) begin 30 | out_sync_ff_1 <= sync_cnt[7]; 31 | out_sync_ff_2 <= out_sync_ff_1; 32 | out_sync_ff_3 <= out_sync_ff_2; 33 | end 34 | 35 | assign pulse_out = !out_sync_ff_3 && out_sync_ff_2; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/cdc_reset_sync.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | // Closed loop solution 11 | 12 | module cdc_reset_sync ( 13 | input wire clk_in, 14 | input wire pulse_in, 15 | input wire clk_out, 16 | output wire pulse_out 17 | ); 18 | 19 | wire aq_sync; 20 | 21 | reg [1:0] in_pre_sync; 22 | always @(posedge clk_in) begin 23 | in_pre_sync[0] <= pulse_in; 24 | in_pre_sync[1] <= in_pre_sync[0]; 25 | end 26 | 27 | reg in_sync_pulse; 28 | initial in_sync_pulse = 0; // works only in FPGA 29 | always @(posedge clk_in) begin 30 | if (in_pre_sync[1]) 31 | in_sync_pulse <= 1; 32 | else if (aq_sync) 33 | in_sync_pulse <= 0; 34 | end 35 | 36 | (* ASYNC_REG = "TRUE" *) reg out_sync_ff_1; 37 | (* ASYNC_REG = "TRUE" *) reg out_sync_ff_2; 38 | always @(posedge clk_out) begin 39 | out_sync_ff_1 <= in_sync_pulse; 40 | out_sync_ff_2 <= out_sync_ff_1; 41 | end 42 | 43 | assign pulse_out = out_sync_ff_2; 44 | 45 | (* ASYNC_REG = "TRUE" *) reg aq_sync_ff_1; 46 | (* ASYNC_REG = "TRUE" *) reg aq_sync_ff_2; 47 | always @(posedge clk_in) begin 48 | aq_sync_ff_1 <= out_sync_ff_2; 49 | aq_sync_ff_2 <= aq_sync_ff_1; 50 | end 51 | 52 | assign aq_sync = aq_sync_ff_2; 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/clock_multiplier.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps / 1ps 2 | 3 | module clock_multiplier #( 4 | parameter MULTIPLIER = 4 5 | ) ( 6 | input wire CLK, 7 | output reg CLOCK 8 | ); 9 | 10 | integer time_prev,time_diff; 11 | initial begin 12 | time_prev = 0; 13 | forever begin 14 | @(posedge CLK) 15 | time_diff = $time - time_prev; 16 | time_prev = $time; 17 | end 18 | end 19 | 20 | initial begin 21 | CLOCK = 0; 22 | forever begin 23 | @(posedge CLK) 24 | CLOCK = 1; 25 | repeat(MULTIPLIER*2-1) 26 | #(time_diff/(MULTIPLIER*2)) CLOCK = !CLOCK; 27 | end 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/ddr_des.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module ddr_des #( 12 | parameter CLKDV = 4 13 | ) ( 14 | input wire CLK2X, 15 | input wire CLK, 16 | input wire WCLK, 17 | input wire IN, 18 | output reg [CLKDV*4-1:0] OUT, 19 | output wire [1:0] OUT_FAST 20 | ); 21 | 22 | wire [1:0] DDRQ; 23 | IDDR IDDR_inst ( 24 | .Q1(DDRQ[1]), // 1-bit output for positive edge of clock 25 | .Q2(DDRQ[0]), // 1-bit output for negative edge of clock 26 | .C(CLK2X), // 1-bit clock input 27 | .CE(1'b1), // 1-bit clock enable input 28 | .D(IN), // 1-bit DDR data input 29 | .R(1'b0), // 1-bit reset 30 | .S(1'b0) // 1-bit set 31 | ); 32 | 33 | assign OUT_FAST = DDRQ; 34 | 35 | reg [1:0] DDRQ_DLY; 36 | 37 | always @(posedge CLK2X) 38 | DDRQ_DLY[1:0] <= DDRQ[1:0]; 39 | 40 | reg [3:0] DDRQ_DATA; 41 | always @(posedge CLK2X) 42 | DDRQ_DATA[3:0] <= {DDRQ_DLY[1:0], DDRQ[1:0]}; 43 | 44 | reg [3:0] DDRQ_DATA_BUF; 45 | always @(posedge CLK2X) 46 | DDRQ_DATA_BUF[3:0] <= DDRQ_DATA[3:0]; 47 | 48 | reg [3:0] DATA_IN; 49 | always @(posedge CLK) 50 | DATA_IN[3:0] <= DDRQ_DATA_BUF[3:0]; 51 | 52 | reg [CLKDV*4-1:0] DATA_IN_SR; 53 | always @(posedge CLK) 54 | DATA_IN_SR <= {DATA_IN_SR[CLKDV*4-5:0],DATA_IN[3:0]}; 55 | 56 | always @(posedge WCLK) 57 | OUT <= DATA_IN_SR; 58 | 59 | endmodule 60 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/fifo_32_to_8.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module fifo_32_to_8 #( 12 | parameter DEPTH = 1024*4 13 | ) ( 14 | input wire CLK, 15 | input wire RST, 16 | input wire WRITE, 17 | input wire READ, 18 | input wire [31:0] DATA_IN, 19 | output wire FULL, 20 | output wire EMPTY, 21 | output wire [7:0] DATA_OUT 22 | ); 23 | 24 | reg [1:0] byte_cnt; 25 | wire FIFO_EMPTY, READ_FIFO; 26 | wire [31:0] FIFO_DATA_OUT; 27 | 28 | assign EMPTY = byte_cnt==0 & FIFO_EMPTY; 29 | assign READ_FIFO = (byte_cnt==0 & !FIFO_EMPTY && READ); 30 | 31 | gerneric_fifo #( 32 | .DATA_SIZE(32), 33 | .DEPTH(DEPTH) 34 | ) fifo_i ( 35 | .clk(CLK), 36 | .reset(RST), 37 | .write(WRITE), 38 | .read(READ_FIFO), 39 | .data_in(DATA_IN), 40 | .full(FULL), 41 | .empty(FIFO_EMPTY), 42 | .data_out(FIFO_DATA_OUT), 43 | .size() 44 | ); 45 | 46 | always @(posedge CLK) 47 | if(RST) 48 | byte_cnt <= 0; 49 | else if (READ) 50 | byte_cnt <= byte_cnt + 1; 51 | 52 | reg [31:0] DATA_BUF; 53 | always @(posedge CLK) 54 | if(READ_FIFO) 55 | DATA_BUF <= FIFO_DATA_OUT; 56 | 57 | wire [7:0] FIFO_DATA_OUT_BYTE [3:0]; 58 | assign FIFO_DATA_OUT_BYTE[0] = FIFO_DATA_OUT[7:0]; 59 | assign FIFO_DATA_OUT_BYTE[1] = DATA_BUF[15:8]; 60 | assign FIFO_DATA_OUT_BYTE[2] = DATA_BUF[23:16]; 61 | assign FIFO_DATA_OUT_BYTE[3] = DATA_BUF[31:24]; 62 | assign DATA_OUT = FIFO_DATA_OUT_BYTE[byte_cnt]; 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/fifo_64_to_16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module fifo_64_to_16 #( 12 | parameter DEPTH = 1024*4 13 | ) ( 14 | input wire CLK, 15 | input wire RST, 16 | input wire WRITE, 17 | input wire READ, 18 | input wire [63:0] DATA_IN, 19 | output wire FULL, 20 | output wire EMPTY, 21 | output wire [15:0] DATA_OUT 22 | ); 23 | 24 | reg [1:0] byte_cnt; 25 | wire FIFO_EMPTY, READ_FIFO; 26 | wire [63:0] FIFO_DATA_OUT; 27 | 28 | assign EMPTY = byte_cnt==0 & FIFO_EMPTY; 29 | assign READ_FIFO = (byte_cnt==0 & !FIFO_EMPTY && READ); 30 | 31 | gerneric_fifo #( 32 | .DATA_SIZE(64), 33 | .DEPTH(DEPTH) 34 | ) fifo_i ( 35 | .clk(CLK), 36 | .reset(RST), 37 | .write(WRITE), 38 | .read(READ_FIFO), 39 | .data_in(DATA_IN), 40 | .full(FULL), 41 | .empty(FIFO_EMPTY), 42 | .data_out(FIFO_DATA_OUT), 43 | .size() 44 | ); 45 | 46 | always @(posedge CLK) 47 | if(RST) 48 | byte_cnt <= 0; 49 | else if (READ) 50 | byte_cnt <= byte_cnt + 1; 51 | 52 | reg [63:0] DATA_BUF; 53 | always @(posedge CLK) 54 | if(READ_FIFO) 55 | DATA_BUF <= FIFO_DATA_OUT; 56 | 57 | wire [15:0] FIFO_DATA_OUT_BYTE [3:0]; 58 | assign FIFO_DATA_OUT_BYTE[0] = FIFO_DATA_OUT[15:0]; 59 | assign FIFO_DATA_OUT_BYTE[1] = DATA_BUF[31:16]; 60 | assign FIFO_DATA_OUT_BYTE[2] = DATA_BUF[47:32]; 61 | assign FIFO_DATA_OUT_BYTE[3] = DATA_BUF[63:48]; 62 | assign DATA_OUT = FIFO_DATA_OUT_BYTE[byte_cnt]; 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/flag_domain_crossing.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | // synchronize flag (signal lasts just one clock cycle) to new clock domain (CLK_B) 11 | 12 | module flag_domain_crossing( 13 | input wire CLK_A, 14 | input wire CLK_B, 15 | input wire FLAG_IN_CLK_A, 16 | output wire FLAG_OUT_CLK_B 17 | ); 18 | 19 | 20 | reg FLAG_TOGGLE_CLK_A; 21 | initial FLAG_TOGGLE_CLK_A = 0; 22 | always @(posedge CLK_A) 23 | begin 24 | if (FLAG_IN_CLK_A) 25 | begin 26 | FLAG_TOGGLE_CLK_A <= ~FLAG_TOGGLE_CLK_A; 27 | end 28 | end 29 | 30 | (* ASYNC_REG = "TRUE" *) reg flag_out_d_ff_1; 31 | (* ASYNC_REG = "TRUE" *) reg flag_out_d_ff_2; 32 | reg flag_out_d_ff_3; 33 | 34 | always @(posedge CLK_B) // first stage 35 | begin 36 | flag_out_d_ff_1 <= FLAG_TOGGLE_CLK_A; 37 | end 38 | 39 | always @(posedge CLK_B) // second stage 40 | begin 41 | flag_out_d_ff_2 <= flag_out_d_ff_1; 42 | end 43 | 44 | always @(posedge CLK_B) 45 | begin 46 | flag_out_d_ff_3 <= flag_out_d_ff_2; 47 | end 48 | 49 | assign FLAG_OUT_CLK_B = (flag_out_d_ff_3 ^ flag_out_d_ff_2); // XOR 50 | 51 | endmodule 52 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/fx2_to_bus.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module fx2_to_bus #( 12 | parameter WIDTH = 16 // 16 bit bus from FX2 13 | ) ( 14 | input wire [WIDTH-1:0] ADD, 15 | input wire RD_B, // neg active, two clock cycles 16 | input wire WR_B, // neg active 17 | 18 | input wire BUS_CLK, // FCLK 19 | output wire [WIDTH-1:0] BUS_ADD, 20 | output wire BUS_RD, 21 | output wire BUS_WR, 22 | output wire CS_FPGA 23 | ); 24 | 25 | // remove offset from FX2 26 | assign BUS_ADD = ADD - 16'h4000; 27 | 28 | // chip select FPGA 29 | assign CS_FPGA = ~ADD[15] & ADD[14]; 30 | 31 | // generate read strobe which one clock cycle long 32 | // this is very important to prevent corrupted data 33 | reg RD_B_FF; 34 | always @(posedge BUS_CLK) begin 35 | RD_B_FF <= RD_B; 36 | end 37 | assign BUS_RD = ~RD_B & RD_B_FF; 38 | 39 | assign BUS_WR = ~WR_B; 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/pulse_gen_rising.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module pulse_gen_rising ( 12 | input wire clk_in, 13 | input wire in, 14 | output wire out 15 | ); 16 | 17 | reg ff; 18 | always @(posedge clk_in) 19 | ff <= in; 20 | 21 | assign out = !ff && in; 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/rbcp_to_bus.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module rbcp_to_bus ( 12 | input wire BUS_RST, 13 | input wire BUS_CLK, 14 | 15 | input wire RBCP_ACT, 16 | input wire [31:0] RBCP_ADDR, 17 | input wire [7:0] RBCP_WD, 18 | input wire RBCP_WE, 19 | input wire RBCP_RE, 20 | output reg RBCP_ACK, 21 | output wire [7:0] RBCP_RD, 22 | 23 | output wire BUS_WR, 24 | output wire BUS_RD, 25 | output wire [31:0] BUS_ADD, 26 | inout wire [7:0] BUS_DATA 27 | 28 | //FUTURE 29 | //input wire BUS_ACK_REQ 30 | //input wire BUS_ACK 31 | ); 32 | 33 | always @(posedge BUS_CLK) begin 34 | if(BUS_RST) 35 | RBCP_ACK <= 0; 36 | else begin 37 | if (RBCP_ACK == 1) 38 | RBCP_ACK <= 0; 39 | else 40 | RBCP_ACK <= RBCP_WE | RBCP_RE; 41 | end 42 | end 43 | 44 | assign BUS_ADD = RBCP_ADDR; 45 | assign BUS_WR = RBCP_WE & RBCP_ACT; 46 | assign BUS_RD = RBCP_RE & RBCP_ACT; 47 | 48 | assign BUS_DATA = BUS_WR ? RBCP_WD[7:0]: 8'bz; 49 | assign RBCP_RD[7:0] = BUS_WR ? 8'bz : BUS_DATA; 50 | 51 | /* 52 | wire [35:0] control_bus; 53 | chipscope_icon ichipscope_icon 54 | ( 55 | .CONTROL0(control_bus) 56 | ); 57 | 58 | chipscope_ila ichipscope_ila 59 | ( 60 | .CONTROL(control_bus), 61 | .CLK(BUS_CLK), 62 | .TRIG0({BUS_ADD[7:0], RBCP_ACK, RBCP_WD, RBCP_RD, BUS_RD, BUS_WR}) 63 | 64 | ); 65 | */ 66 | 67 | endmodule 68 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/reset_gen.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | 11 | module reset_gen #( 12 | parameter CNT = 8'd128 13 | ) ( 14 | CLK, 15 | RST 16 | ); 17 | 18 | input wire CLK; 19 | output wire RST; 20 | 21 | reg [7:0] rst_cnt; 22 | 23 | initial rst_cnt = CNT; 24 | 25 | always @(posedge CLK) 26 | if(rst_cnt != 0) 27 | rst_cnt <= rst_cnt -1; 28 | 29 | assign RST = (rst_cnt != 0 ); 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/sbus_to_ip.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | 8 | module sbus_to_ip 9 | #( 10 | parameter BASEADDR = 0, 11 | parameter HIGHADDR = 0, 12 | parameter ABUSWIDTH = 16, 13 | parameter DBUSWIDTH = 8 14 | ) 15 | ( 16 | input wire BUS_CLK, 17 | input wire BUS_RD, 18 | input wire BUS_WR, 19 | input wire [ABUSWIDTH-1:0] BUS_ADD, 20 | input wire [DBUSWIDTH-1:0] BUS_DATA_IN, 21 | output wire [DBUSWIDTH-1:0] BUS_DATA_OUT, 22 | 23 | output wire IP_RD, 24 | output wire IP_WR, 25 | output wire [ABUSWIDTH-1:0] IP_ADD, 26 | output wire [DBUSWIDTH-1:0] IP_DATA_IN, 27 | input wire [DBUSWIDTH-1:0] IP_DATA_OUT 28 | ); 29 | 30 | wire CS; 31 | /* verilator lint_off UNSIGNED */ 32 | assign CS = (BUS_ADD >= BASEADDR && BUS_ADD <= HIGHADDR); 33 | /* verilator lint_on UNSIGNED */ 34 | 35 | assign IP_ADD = CS ? BUS_ADD - BASEADDR : {ABUSWIDTH{1'b0}}; 36 | assign IP_RD = CS ? BUS_RD : 1'b0; 37 | assign IP_WR = CS ? BUS_WR: 1'b0; 38 | 39 | assign IP_DATA_IN = BUS_DATA_IN; 40 | 41 | reg CS_PREV; 42 | 43 | always@(posedge BUS_CLK) begin 44 | CS_PREV <= CS; 45 | end 46 | 47 | assign BUS_DATA_OUT = (CS_PREV ? IP_DATA_OUT : {DBUSWIDTH{1'b0}}); 48 | 49 | endmodule 50 | -------------------------------------------------------------------------------- /basil/firmware/modules/utils/simple_arbiter.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ps/1ps 8 | `default_nettype none 9 | 10 | // 'base' is a one hot signal indicating the first request 11 | // that should be considered for a grant. Followed by higher 12 | // indexed requests, then wrapping around. 13 | // NOTE: Ff there is more than one request at time, 14 | // this arbiter will finish all requests by the first request, 15 | // and then go on with higher indexed request request. 16 | 17 | module arbiter ( 18 | req, grant, base 19 | ); 20 | 21 | parameter WIDTH = 16; 22 | 23 | input wire [WIDTH-1:0] req; 24 | output wire [WIDTH-1:0] grant; 25 | input wire [WIDTH-1:0] base; 26 | 27 | wire [2*WIDTH-1:0] double_req = {req,req}; 28 | wire [2*WIDTH-1:0] double_grant = double_req & ~(double_req-base); 29 | assign grant = double_grant[WIDTH-1:0] | double_grant[2*WIDTH-1:WIDTH]; 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /basil/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/basil/utils/__init__.py -------------------------------------------------------------------------------- /basil/utils/sim/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/basil/utils/sim/__init__.py -------------------------------------------------------------------------------- /docs/_static/MIO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/MIO.jpg -------------------------------------------------------------------------------- /docs/_static/MIO_GPAC_DUT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/MIO_GPAC_DUT.png -------------------------------------------------------------------------------- /docs/_static/WaveDrom_load.js: -------------------------------------------------------------------------------- 1 | 2 | var body = document.getElementsByTagName("body")[0]; 3 | body.addEventListener("load", WaveDrom.ProcessAll(), false); -------------------------------------------------------------------------------- /docs/_static/basil_layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/basil_layers.png -------------------------------------------------------------------------------- /docs/_static/lx9_fei4_a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/lx9_fei4_a.jpg -------------------------------------------------------------------------------- /docs/_static/lx9_fei4_b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/lx9_fei4_b.jpg -------------------------------------------------------------------------------- /docs/_static/spi_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/spi_example.png -------------------------------------------------------------------------------- /docs/_static/spi_example_timing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/docs/_static/spi_example_timing.png -------------------------------------------------------------------------------- /docs/_static/theme_overrides.css: -------------------------------------------------------------------------------- 1 | 2 | html body div.wy-nav-content { 3 | max-width: 100% 4 | } -------------------------------------------------------------------------------- /docs/examples.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | Examples 3 | ############ 4 | 5 | Example of project can be found in `examples folder `_. 6 | 7 | For more usecases check also `tests folder `_. 8 | 9 | spi 10 | ------- 11 | 12 | An example shows how to create a simple spi interface. 13 | 14 | .. image:: _static/spi_example.png 15 | 16 | Instantiate a verilog spi module in the firmware verilog code. 17 | 18 | .. code-block:: verilog 19 | 20 | localparam SPI_BASEADDR = 32'h1000; 21 | localparam SPI_HIGHADDR = 32'h1FFF; 22 | 23 | spi 24 | #( 25 | .BASEADDR(SPI_BASEADDR), 26 | .HIGHADDR(SPI_HIGHADDR), 27 | .MEM_BYTES(4) 28 | ) i_spi 29 | ( 30 | .BUS_CLK(BUS_CLK), 31 | .BUS_RST(BUS_RST), 32 | .BUS_ADD(BUS_ADD), 33 | .BUS_DATA(BUS_DATA), 34 | .BUS_RD(BUS_RD), 35 | .BUS_WR(BUS_WR), 36 | 37 | .SPI_CLK(SPI_CLK), 38 | 39 | .SCLK(SCLK), 40 | .SDI(SDI), 41 | .SDO(SDO), 42 | .SEN(SEN), 43 | .SLD(SLD) 44 | ); 45 | 46 | Create a configuration file. 47 | 48 | .. code-block:: yaml 49 | 50 | transfer_layer: 51 | - name : intf 52 | type : SiSim 53 | 54 | hw_drivers: 55 | - name : spi 56 | type : spi 57 | interface : intf 58 | base_addr : 0x1000 59 | mem_bytes : 2 60 | 61 | - name : CNT 62 | type : StdRegister 63 | hw_driver : spi 64 | size : 16 65 | fields: 66 | - name : EN 67 | size : 1 68 | offset : 15 69 | - name : OUT 70 | size : 15 71 | offset : 14 72 | 73 | Write control program. 74 | 75 | .. code-block:: python 76 | 77 | dut = Dut('spi.yaml') 78 | dut.init() 79 | 80 | dut['CNT']['EN'] = 1 81 | dut['CNT']['OUT'] = 0x00f0 82 | dut['CNT'].write() 83 | dut['CNT'].start() 84 | 85 | while not dut['CNT'].is_ready(): 86 | pass 87 | 88 | Result of simulation: 89 | 90 | .. image:: _static/spi_example_timing.png 91 | 92 | 93 | A workin example can be seen in tests/test_SimSpi.py. 94 | 95 | gpio 96 | ------- 97 | 98 | TBD. 99 | 100 | 101 | -------------------------------------------------------------------------------- /docs/firmware.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | Firmware 3 | ############ 4 | 5 | FPGA firmware consists of very simple single master bus definition and set of standard modules used by DAQ systems. 6 | 7 | Typical firmware consists of basil bus connecting all modules. Control modules witch provide configuration to DUT (like SPI/GPIO) and data taking modules (like data receivers). Received data (32 bit) are stored in the FIFO (large extremal memory) and can be continuously pulled from host application. Data from different modules are identified by source codding in 32bit data words. 8 | 9 | .. blockdiag:: 10 | 11 | diagram { 12 | 13 | Interface <-> SPI [color = "blue"]; 14 | Interface <-> GPIO [color = "blue"]; 15 | Interface <-> RX [color = "blue", label = "bus"]; 16 | Interface <-> TDC [color = "blue"]; 17 | Interface <-> FIFO [color = "blue"]; 18 | TDC -> Arbiter [color = "green", label = "data"]; 19 | RX -> Arbiter [color = "green"]; 20 | Arbiter -> FIFO [color = "green"]; 21 | 22 | Arbiter -> FIFO [folded]; 23 | } 24 | 25 | basil bus 26 | ========= 27 | 28 | single write 29 | .. raw:: html 30 | 31 | 40 | 41 | 42 | single read 43 | .. raw:: html 44 | 45 | 54 | 55 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | 2 | basil 3 | ================================= 4 | 5 | Basil is a modular readout framework intended to allow simple and fast data acquisition systems (DAQ) design. It consists of different hardware components, FPGA firmware modulus and a Python based contol software. 6 | 7 | Contents: 8 | 9 | .. toctree:: 10 | 11 | introduction 12 | hardware 13 | firmware 14 | software 15 | modules 16 | examples 17 | 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | * :ref:`modindex` 24 | * :ref:`search` 25 | -------------------------------------------------------------------------------- /docs/introduction.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | Introduction 3 | ############ 4 | 5 | Basil is a modular readout framework intended to allow simple and fast data acquisition systems (DAQ) design. It consists of different hardware components, FPGA firmware modulus and a Python based control software. 6 | 7 | Features 8 | =========================== 9 | 10 | Firmware: 11 | - very simple single master `bus definition`_ 12 | - multiple `basic modules `_ (ex. SPI, SEQ) 13 | - multiple `interfaces `_ (UART, USB2, USB3, Ethernet) 14 | Software: 15 | - layer structure following hardware 16 | - generation based on yaml file 17 | - register abstract layer (RAL) 18 | - simulator interface allows software test against simulated RTL (thanks to `cocotb `_ ) 19 | 20 | 21 | .. _`bus definition`: firmware.html#basil-bus 22 | 23 | Installation 24 | ======================== 25 | 26 | From host folder run: 27 | 28 | .. code-block:: bash 29 | 30 | python setup.py install 31 | 32 | or 33 | 34 | .. code-block:: bash 35 | 36 | pip install -e "git+https://github.com/SiLab-Bonn/basil.git#egg=basil&subdirectory=host" 37 | 38 | 39 | Simulation 40 | ======================== 41 | 42 | Thank to `Chris Higgs `_ basil has a simulation interface (SiSim) with allow communication with simulator as if talking to real hardware. 43 | 44 | To make simulation one need: 45 | - verilog simulator (ex. `Icarus `_ ) 46 | - `cocotb `_ library 47 | - set interface type to SiSim 48 | 49 | Basil unit tests make extensive use of this feature. See tests folder. 50 | 51 | License 52 | ===================== 53 | 54 | If not stated otherwise. 55 | 56 | Host Software: 57 | The host software is distributed under the BSD 3-Clause (“BSD New” or “BSD Simplified”) License. 58 | 59 | FPGA Firmware: 60 | The FPGA software is distributed under the GNU Lesser General Public License, version 3.0 (LGPLv3). 61 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinxcontrib-blockdiag 2 | sphinx_rtd_theme 3 | bitarray 4 | pyyaml 5 | -------------------------------------------------------------------------------- /docs/software.rst: -------------------------------------------------------------------------------- 1 | ############ 2 | Software 3 | ############ 4 | 5 | The software framework has a modular structure that reflects the firmware and adds extra layers to make hardware interface user friendly. It loosely follows Register Abstract Layer (RAL) concepts. All the layers are automatically created based on yaml configuration file. 6 | 7 | .. image:: _static/basil_layers.png 8 | 9 | Yaml configuration file 10 | ======================= 11 | 12 | TBD 13 | 14 | Transfer Layer (TL) 15 | ==================== 16 | 17 | Implements communication interface like UART, USB, Ethernet or Simulation. 18 | Every TL interface implements 2 functions: 19 | 20 | .. automodule:: basil.TL.TransferLayer 21 | 22 | .. autoclass:: TransferLayer 23 | :members: 24 | 25 | Hardware Layer (HL) 26 | ==================== 27 | 28 | Implements drivers for basil modules and external devices. Drivers can reference other drivers within HL. 29 | 30 | 31 | Register Layer (RL) 32 | =================== 33 | 34 | Implements Register Level Abstraction. Allow to user/control software to work on DUT registers without taking thinking about underlying levels. 35 | 36 | -------------------------------------------------------------------------------- /examples/MIO/ise/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !.gitignore 4 | !*.xise 5 | 6 | -------------------------------------------------------------------------------- /examples/MIO/src/example.v: -------------------------------------------------------------------------------- 1 | 2 | `timescale 1ps / 1ps 3 | `default_nettype none 4 | 5 | module example ( 6 | input wire FCLK_IN, 7 | 8 | //full speed 9 | inout wire [7:0] BUS_DATA, 10 | input wire [15:0] ADD, 11 | input wire RD_B, 12 | input wire WR_B, 13 | 14 | //high speed 15 | inout wire [7:0] FD, 16 | input wire FREAD, 17 | input wire FSTROBE, 18 | input wire FMODE, 19 | 20 | //debug 21 | output wire [15:0] DEBUG_D, 22 | 23 | output wire LED1, 24 | output wire LED2, 25 | output wire LED3, 26 | output wire LED4, 27 | output wire LED5, 28 | 29 | inout wire FPGA_BUTTON, 30 | 31 | inout wire SDA, 32 | inout wire SCL 33 | ); 34 | 35 | wire [15:0] BUS_ADD; 36 | wire BUS_CLK, BUS_RD, BUS_WR, BUS_RST; 37 | 38 | assign BUS_CLK = FCLK_IN; 39 | fx2_to_bus i_fx2_to_bus ( 40 | .ADD(ADD), 41 | .RD_B(RD_B), 42 | .WR_B(WR_B), 43 | 44 | .BUS_CLK(BUS_CLK), 45 | .BUS_ADD(BUS_ADD), 46 | .BUS_RD(BUS_RD), 47 | .BUS_WR(BUS_WR), 48 | .CS_FPGA() 49 | ); 50 | 51 | reset_gen i_reset_gen ( 52 | .CLK(BUS_CLK), 53 | .RST(BUS_RST) 54 | ); 55 | 56 | //MODULE ADREESSES 57 | localparam GPIO_BASEADDR = 16'h0000; 58 | localparam GPIO_HIGHADDR = 16'h000f; 59 | 60 | // USER MODULES // 61 | wire [1:0] GPIO_NOT_USED; 62 | gpio #( 63 | .BASEADDR(GPIO_BASEADDR), 64 | .HIGHADDR(GPIO_HIGHADDR), 65 | 66 | .IO_WIDTH(8), 67 | .IO_DIRECTION(8'h1f) // 3 MSBs are input the rest output 68 | ) i_gpio ( 69 | .BUS_CLK(BUS_CLK), 70 | .BUS_RST(BUS_RST), 71 | .BUS_ADD(BUS_ADD), 72 | .BUS_DATA(BUS_DATA), 73 | .BUS_RD(BUS_RD), 74 | .BUS_WR(BUS_WR), 75 | .IO({FPGA_BUTTON, GPIO_NOT_USED, LED5, LED4, LED3, LED2, LED1}) 76 | ); 77 | 78 | assign GPIO_NOT_USED = {LED2, LED1}; 79 | 80 | //For simulation 81 | initial begin 82 | $dumpfile("mio_example.vcd"); 83 | $dumpvars(0); 84 | end 85 | 86 | assign SDA = 1'bz; 87 | assign SCL = 1'bz; 88 | assign DEBUG_D = 16'ha5a5; 89 | 90 | `ifdef COCOTB_SIM 91 | assign FPGA_BUTTON = 0; 92 | `endif 93 | 94 | endmodule 95 | -------------------------------------------------------------------------------- /examples/MIO/tb/example.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Copyright (c) All rights reserved 3 | # SiLab, Institute of Physics, University of Bonn 4 | # ------------------------------------------------------------ 5 | # 6 | 7 | import time 8 | from basil.dut import Dut 9 | 10 | chip = Dut("example.yaml") 11 | chip.init() 12 | 13 | for i in range(5): 14 | chip['GPIO_LED']['LED'] = 0x01 << i 15 | chip['GPIO_LED'].write() 16 | time.sleep(1) 17 | -------------------------------------------------------------------------------- /examples/MIO/tb/example.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | transfer_layer: 9 | - name : INTF 10 | type : SiUsb 11 | init: 12 | avoid_download : True 13 | bit_file : ../ise/example.bit 14 | 15 | hw_drivers: 16 | - name : GPIO_DRV 17 | type : gpio 18 | interface : INTF 19 | base_addr : 0x10000 20 | size : 8 21 | 22 | registers: 23 | - name : GPIO_LED 24 | type : StdRegister 25 | hw_driver : GPIO_DRV 26 | size : 8 27 | fields: 28 | - name : LED 29 | size : 5 30 | offset : 4 31 | -------------------------------------------------------------------------------- /examples/MIO/tb/test_SimExample.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Copyright (c) All rights reserved 3 | # SiLab, Institute of Physics, University of Bonn 4 | # ------------------------------------------------------------ 5 | # 6 | 7 | import unittest 8 | import os 9 | import yaml 10 | 11 | from basil.dut import Dut 12 | from basil.utils.sim.utils import cocotb_compile_and_run, cocotb_compile_clean, get_basil_dir 13 | 14 | 15 | class TestExampleMIO(unittest.TestCase): 16 | def setUp(self): 17 | fw_path = os.path.join(get_basil_dir(), 'firmware/modules') 18 | cocotb_compile_and_run([ 19 | os.path.join(fw_path, 'gpio/gpio.v'), 20 | os.path.join(fw_path, 'gpio/gpio_core.v'), 21 | os.path.join(fw_path, 'utils/reset_gen.v'), 22 | os.path.join(fw_path, 'utils/bus_to_ip.v'), 23 | os.path.join(fw_path, 'utils/fx2_to_bus.v'), 24 | os.path.join(os.path.dirname(__file__), '../src/example.v')], 25 | top_level='example', 26 | sim_bus='basil.utils.sim.SiLibUsbBusDriver' 27 | ) 28 | 29 | with open(os.path.join(os.path.dirname(__file__), 'example.yaml'), 'r') as f: 30 | cnfg = yaml.safe_load(f) 31 | 32 | # change to simulation interface 33 | cnfg['transfer_layer'][0]['type'] = 'SiSim' 34 | 35 | self.chip = Dut(cnfg) 36 | self.chip.init() 37 | 38 | def test_gpio(self): 39 | ret = self.chip['GPIO_LED'].get_data() 40 | self.assertEqual([0], ret) 41 | 42 | self.chip['GPIO_LED']['LED'] = 0x01 43 | self.chip['GPIO_LED'].write() 44 | 45 | ret = self.chip['GPIO_LED'].get_data() 46 | self.assertEqual([0x21], ret) 47 | 48 | self.chip['GPIO_LED']['LED'] = 0x02 49 | self.chip['GPIO_LED'].write() 50 | 51 | ret = self.chip['GPIO_LED'].get_data() 52 | self.assertEqual([0x42], ret) 53 | 54 | self.chip['GPIO_LED']['LED'] = 0x03 55 | self.chip['GPIO_LED'].write() 56 | 57 | ret = self.chip['GPIO_LED'].get_data() 58 | self.assertEqual([0x63], ret) 59 | 60 | def tearDown(self): 61 | self.chip.close() # let it close connection and stop simulator 62 | cocotb_compile_clean() 63 | 64 | 65 | if __name__ == '__main__': 66 | unittest.main() 67 | -------------------------------------------------------------------------------- /examples/MMC3/mmc3.srcs/sources_1/mmc3_constants.v: -------------------------------------------------------------------------------- 1 | // ------- MODULE ADREESSES ------- // 2 | 3 | parameter CMD_BASEADDR = 32'h0000; 4 | parameter CMD_HIGHADDR = 32'h0800-1; 5 | 6 | parameter LED_GPIO_BASE = 32'h1000; 7 | 8 | parameter FIFO_BASEADDR = 32'h8100; 9 | parameter FIFO_HIGHADDR = 32'h8200-1; 10 | 11 | parameter RX4_BASEADDR = 32'h8300; 12 | parameter RX4_HIGHADDR = 32'h8400-1; 13 | 14 | parameter RX3_BASEADDR = 32'h8400; 15 | parameter RX3_HIGHADDR = 32'h8500-1; 16 | 17 | parameter RX2_BASEADDR = 32'h8500; 18 | parameter RX2_HIGHADDR = 32'h8600-1; 19 | 20 | parameter RX1_BASEADDR = 32'h8600; 21 | parameter RX1_HIGHADDR = 32'h8700-1; 22 | 23 | parameter FIFO_BASEADDR_DATA = 32'h8000_0000; 24 | parameter FIFO_HIGHADDR_DATA = 32'h9000_0000; -------------------------------------------------------------------------------- /examples/bdaq/.gitignore: -------------------------------------------------------------------------------- 1 | test/sim_build/ 2 | test/Makefile 3 | firmware/vivado/designs 4 | firmware/vivado/output 5 | firmware/vivado/reports 6 | firmware/SiTCP 7 | 8 | *.log 9 | *.history -------------------------------------------------------------------------------- /examples/bdaq/Readme.md: -------------------------------------------------------------------------------- 1 | # Ethernet example for the BDAQ53 hardware 2 | This example shows how to control a GPIO module and how to receive data via the Ethernet interface. 3 | 1. Data transfer is started by setting a bit [0] in the GPIO. 4 | 2. FPGA starts to send data from a 32 bit counter through a BRAM FIFO. 5 | 3. The Python script checks the received data and counts the transferred bytes during a given time period. 6 | 4. At the end, the average data rate is printed and the FPGA data source is stopped by clearing bit [0]. 7 | 8 | ## Build script 9 | To build this example firmware, navigate to `firmware/vivado` and start the process using the Makefile 10 | ```terminal 11 | cd firmware/vivado 12 | make 13 | ``` 14 | `make download`, `make synthesize` and `make clean` can be used to call the sub-tasks individually. 15 | 16 | The firmware makes use of the free SiTcp Ethernet module ([GitHub][url1]). 17 | You can find further build instructions in the *Firmware section* of the ([bdaq53 readme][url2]). 18 | 19 | [url1]: https://github.com/BeeBeansTechnologies/SiTCP_Netlist_for_Kintex7 20 | [url2]: https://gitlab.cern.ch/silab/bdaq53#firmware 21 | 22 | ## Test 23 | A test for CocoTB is available under `test` -------------------------------------------------------------------------------- /examples/bdaq/bdaq53_eth.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # SiTCP throughput test 3 | # Reads data for a couple of seconds and displays the data rate 4 | # 5 | # Copyright (c) All rights reserved 6 | # SiLab, Physics Institute, University of Bonn 7 | # ------------------------------------------------------------ 8 | # 9 | import logging 10 | import time 11 | 12 | import numpy as np 13 | 14 | from basil.dut import Dut 15 | 16 | 17 | chip = Dut("bdaq53_eth.yaml") 18 | chip.init() 19 | 20 | chip['CONTROL']['EN'] = 0 21 | chip['CONTROL'].write() 22 | 23 | logging.info("Starting data test ...") 24 | 25 | chip['CONTROL']['EN'] = 1 26 | chip['CONTROL'].write() 27 | 28 | start = 0 29 | 30 | for i in range(10): 31 | time.sleep(1) 32 | 33 | fifo_data = chip['FIFO'].get_data() 34 | data_size = len(fifo_data) 35 | data_gen = np.linspace(start, data_size - 1 + start, data_size, dtype=np.int32) 36 | 37 | comp = (fifo_data == data_gen) 38 | logging.info("%s: %.2f Mbits checked. OK?: %s" % (i, float(32 * data_size) / pow(10, 6), comp.all())) 39 | start += data_size 40 | 41 | chip['CONTROL']['EN'] = 0 # stop data source 42 | chip['CONTROL'].write() 43 | 44 | logging.info("Starting speed test ...") 45 | 46 | testduration = 10 47 | total_len = 0 48 | tick = 0 49 | tick_old = 0 50 | start_time = time.time() 51 | 52 | chip['CONTROL']['EN'] = 1 53 | chip['CONTROL'].write() 54 | 55 | while time.time() - start_time < testduration: 56 | data = chip['FIFO'].get_data() 57 | total_len += len(data) * 4 * 8 58 | time.sleep(0.01) 59 | tick = int(time.time() - start_time) 60 | if tick != tick_old: 61 | logging.info("Time: %f s" % (time.time() - start_time)) 62 | tick_old = tick 63 | 64 | chip['CONTROL']['EN'] = 0x0 # stop data source 65 | chip['CONTROL'].write() 66 | 67 | logging.info("Bytes received: %s, average data rate: %s Mbit/s" % (total_len, round((total_len / 1e6 / testduration), 2))) 68 | -------------------------------------------------------------------------------- /examples/bdaq/bdaq53_eth.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Physics Institute, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | transfer_layer: 9 | - name : intf 10 | type : SiTcp 11 | init: 12 | ip : "192.168.10.16" 13 | udp_port : 4660 14 | tcp_port : 24 15 | tcp_connection : True 16 | 17 | hw_drivers: 18 | - name : GPIO_DRV 19 | type : gpio 20 | interface : intf 21 | base_addr : 0x1000 22 | size : 8 23 | 24 | - name : FIFO 25 | type : sitcp_fifo 26 | interface : intf 27 | base_addr : 0x200000000 28 | base_data_addr : 0x100000000 29 | 30 | registers: 31 | - name : CONTROL 32 | type : StdRegister 33 | hw_driver : GPIO_DRV 34 | size : 8 35 | fields: 36 | - name : EN 37 | size : 1 38 | offset : 0 39 | -------------------------------------------------------------------------------- /examples/bdaq/firmware/src/bdaq53_eth_core.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Physics Institute, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ns / 1ps 8 | 9 | module bdaq53_eth_core( 10 | input wire RESET_N, 11 | 12 | // clocks from PLL clock buffers 13 | input wire BUS_CLK, 14 | input wire PLL_LOCKED, 15 | 16 | input wire BUS_RST, 17 | input wire [31:0] BUS_ADD, 18 | inout wire [7:0] BUS_DATA, 19 | input wire BUS_RD, 20 | input wire BUS_WR, 21 | 22 | input wire FIFO_READY, 23 | output reg FIFO_VALID, 24 | output reg [31:0] FIFO_DATA, 25 | 26 | output wire [7:0] GPIO 27 | ); 28 | 29 | 30 | /* ------- MODULE ADREESSES ------- */ 31 | localparam GPIO_BASEADDR = 32'h1000; 32 | localparam GPIO_HIGHADDR = 32'h101f; 33 | 34 | 35 | /* ------- USER MODULES ------- */ 36 | gpio #( 37 | .BASEADDR(GPIO_BASEADDR), 38 | .HIGHADDR(GPIO_HIGHADDR), 39 | .ABUSWIDTH(32), 40 | .IO_WIDTH(8), 41 | .IO_DIRECTION(8'hff) 42 | ) i_gpio_rx ( 43 | .BUS_CLK(BUS_CLK), 44 | .BUS_RST(BUS_RST), 45 | .BUS_ADD(BUS_ADD), 46 | .BUS_DATA(BUS_DATA[7:0]), 47 | .BUS_RD(BUS_RD), 48 | .BUS_WR(BUS_WR), 49 | .IO(GPIO) 50 | ); 51 | 52 | wire EN; 53 | assign EN = GPIO[0]; 54 | 55 | reg [31:0] FIFO_DATA_REG = 0; 56 | 57 | always @(posedge BUS_CLK) 58 | if(EN) begin 59 | if(FIFO_READY) begin 60 | FIFO_DATA <= FIFO_DATA_REG; 61 | FIFO_DATA_REG <= FIFO_DATA_REG + 1; 62 | FIFO_VALID <= 1; 63 | end 64 | end 65 | else begin 66 | FIFO_DATA_REG <= 0; 67 | FIFO_VALID <= 0; 68 | end 69 | 70 | endmodule 71 | -------------------------------------------------------------------------------- /examples/bdaq/firmware/vivado/Makefile: -------------------------------------------------------------------------------- 1 | # Targets 2 | .PHONY: all clean 3 | 4 | # Run the main process 5 | all: download synthesize 6 | 7 | # Download SiTCP to the base directory 8 | download: 9 | @echo "Downloading SiTCP library" 10 | @python -c "from basil.utils import utils; utils.get_si_tcp('..')" 11 | 12 | # Start synthesis 13 | synthesize: 14 | @echo "Starting firmware synthesis" 15 | vivado -mode batch -source run.tcl -notrace 16 | 17 | # Clean generated files 18 | clean: 19 | @echo "Removing generated Vivado files" 20 | rm -f *.log *.jou *.str 21 | rm -rf designs reports output .Xil .ngc2edfcache ipcore.* 22 | -------------------------------------------------------------------------------- /examples/lab_devices/MotorStage.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' This script shows how to use a Motor Stage 9 | ''' 10 | 11 | import time 12 | from basil.dut import Dut 13 | 14 | dut = Dut('mercury_pyserial.yaml') 15 | dut.init() 16 | 17 | # setup (for c-862) 18 | # needed if mercury is connected the first time after power up 19 | # MN Motor=on 20 | # LL: switch logic active low (hardware) 21 | 22 | dut["MotorStage"].motor_on(address=1) 23 | time.sleep(0.1) 24 | dut["MotorStage"].LL(address=1) 25 | time.sleep(0.1) 26 | 27 | # move to absolute position 10000: 28 | # dut["MotorStage"].set_position(10000, address=1, wait=True) 29 | 30 | # get position: 31 | # print(dut["MotorStage"].get_position(address=1)) 32 | 33 | # move relative 10000: 34 | dut["MotorStage"].move_relative(10000, address=1, wait=True) 35 | 36 | # finding edge example: 37 | # dut["MotorStage"].find_edge(1,address=1) # 0 or 1 indicates direction of movement 38 | 39 | # abort any movement abruptly: 40 | # dut["MotorStage"].abort(address=1) 41 | -------------------------------------------------------------------------------- /examples/lab_devices/ProbeStation.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' This script shows how to use a Suss or Signatone Probe station. 9 | 10 | BTW: 11 | For the PA-200 it is not forseen to be able to communicate with the prober bench software 12 | when running on the host PC without using the propriatary and not documented network interface dll. 13 | 14 | A work around is to use the Suss RS232 interface that is in place to connect to another 15 | client PC. To be able to use the Probe station directly with BASIL on the host PC via RS232 a virtual 16 | comport has to be created connecting the real comport (that is set in the RS232 Interface 17 | application, pbrs232.exe) to a virtual one. 18 | This virtual one is then used to steer the probe station within BASIL. 19 | ''' 20 | 21 | 22 | from basil.dut import Dut 23 | 24 | dut = Dut('suss_pa_200.yaml') 25 | dut.init() 26 | print(dut['SussProber'].get_position()) 27 | print(dut['SussProber'].get_die()) 28 | 29 | dut2 = Dut('SignatoneProber.yaml') 30 | dut2.init() 31 | print(dut2['SignatoneProber'].get_position()) 32 | print(dut2['SignatoneProber'].get_die()) 33 | -------------------------------------------------------------------------------- /examples/lab_devices/SentioProber.py: -------------------------------------------------------------------------------- 1 | from basil.dut import Dut 2 | import os 3 | import sys 4 | 5 | print(os.path.dirname(sys.executable)) 6 | # Sentio Prober Control 7 | dut = Dut('SentioProber_config.yaml') 8 | dut.init() 9 | 10 | # print(dut['Prober'].separate()) 11 | print(dut['Prober'].set_position(160000, -40000)) 12 | # print(dut['Prober'].move_position(100,-50)) 13 | # print(dut['Prober'].get_position()) 14 | # print(dut['Prober'].goto_next_die()) 15 | # print(dut['Prober'].get_die()) 16 | # print(dut['Prober'].goto_first_die()) 17 | # print(dut['Prober'].contact()) 18 | # print(dut['Prober'].load()) # DO NOT USE 19 | # print(dut['Prober'].separate()) 20 | -------------------------------------------------------------------------------- /examples/lab_devices/SentioProber_config.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : ProberSocket 3 | type : Visa 4 | init : 5 | resource_name : "TCPIP0::169.254.119.108::35555::SOCKET" 6 | backend : "@py" 7 | read_termination : "\n" 8 | write_termination : "\n" 9 | timeout: 10000.0 10 | # query_delay: 5 11 | 12 | hw_drivers: 13 | - name : Prober 14 | type : SentioProber 15 | interface : ProberSocket -------------------------------------------------------------------------------- /examples/lab_devices/SignatoneProber.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa 3 | type : Visa 4 | init : 5 | resource_name : "TCPIP0::169.254.55.86::9090::SOCKET" 6 | backend : "@py" 7 | read_termination : "" 8 | timeout: 2.0 9 | 10 | hw_drivers: 11 | - name : Prober 12 | type : SignatoneProber 13 | interface : Visa 14 | -------------------------------------------------------------------------------- /examples/lab_devices/WeissLabEvent_socket.yaml: -------------------------------------------------------------------------------- 1 | 2 | transfer_layer: 3 | - name : Socket 4 | type : Socket 5 | init : 6 | address : '192.168.10.2' 7 | port : 2049 8 | query_delay : 0.0 9 | encoding : 'ascii' 10 | write_termination : '\r' 11 | read_termination : '\r\n' 12 | 13 | hw_drivers: 14 | - name : Climatechamber 15 | type : weiss_labevent 16 | interface : Socket 17 | 18 | -------------------------------------------------------------------------------- /examples/lab_devices/WeissSB22_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : COM6 6 | read_termination : "\x03" 7 | baudrate : 9600 8 | 9 | hw_drivers: 10 | - name : ClimateChamber 11 | type : weiss_sb22 12 | interface : Serial_sb22 13 | init : 14 | address : 1 15 | min_temp : -30 16 | max_temp : 25 17 | min_humidity : 0 18 | max_humidity : 99 19 | -------------------------------------------------------------------------------- /examples/lab_devices/agilent33250a_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | read_termination : "\n" 7 | baudrate : 57600 8 | dsrdtr : True 9 | timeout : 2 10 | 11 | hw_drivers: 12 | - name : Pulser 13 | type : agilent33250a 14 | interface : Serial 15 | init : 16 | device : Agilent 33250a 17 | -------------------------------------------------------------------------------- /examples/lab_devices/arduino_ntc_readout.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB1 6 | baudrate : 115200 7 | timeout: 2 8 | read_termination: "\r\n" # Needs to be double-quoted string for YAML to parse this correctly 9 | write_termination: "\n" # Needs to be double-quoted string for YAML to parse this correctly 10 | 11 | hw_drivers: 12 | - name : NTCReadout 13 | type : arduino_ntc_readout 14 | interface : Serial 15 | init : 16 | ntc_limits : [-55, 120] 17 | -------------------------------------------------------------------------------- /examples/lab_devices/arduino_relay_board.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' Example how to use the digital IO of the Arduino board. 9 | ''' 10 | 11 | import time 12 | 13 | from basil.dut import Dut 14 | 15 | dut = Dut('arduino_relay_board.yaml') 16 | dut.init() 17 | 18 | time.sleep(2) # Wait for Arduino to reset 19 | 20 | print(f"Communication delay after command to Arduino is {dut['RelayBoard'].communication_delay} ms") 21 | dut['RelayBoard'].communication_delay = 5 # Set delay between two commands to 5 milli seconds 22 | print(f"Communication delay after command to Arduino is {dut['RelayBoard'].communication_delay} ms") 23 | 24 | print(f"State of RelayBoard is: {dut['RelayBoard'].get_state()}") 25 | 26 | for i in range(2, 12): 27 | print(f"Switching on channel {i}") 28 | dut['RelayBoard'].set_output(channel=i, value='ON') 29 | print(f"State of RelayBoard is: {dut['RelayBoard'].get_state()}") 30 | 31 | print("Switching off all channels") 32 | dut['RelayBoard'].set_output(channel='ALL', value='OFF') 33 | print(f"State of RelayBoard is: {dut['RelayBoard'].get_state()}") 34 | -------------------------------------------------------------------------------- /examples/lab_devices/arduino_relay_board.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB1 6 | baudrate : 115200 7 | timeout: 2 8 | read_termination : "\r\n" 9 | write_termination : "\n" 10 | 11 | hw_drivers: 12 | - name : RelayBoard 13 | type : arduino_relay_board 14 | interface : Serial 15 | -------------------------------------------------------------------------------- /examples/lab_devices/arduino_serial_to_i2c.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' Example how to use the SerialToI2C Arduino interface. 9 | ''' 10 | 11 | import time 12 | 13 | from basil.dut import Dut 14 | 15 | dut = Dut('arduino_serial_to_i2c.yaml') 16 | dut.init() 17 | 18 | time.sleep(2) # Allow tranfer layer to initialize / arduino to boot 19 | 20 | print(f"Communication delay after command to Arduino is {dut['SerialToI2C'].communication_delay} ms") 21 | dut['SerialToI2C'].communication_delay = 5 # Set delay between two commands to 5 milli seconds 22 | print(f"Communication delay after command to Arduino is {dut['SerialToI2C'].communication_delay} ms") 23 | 24 | print(f"I2C bus address to write to is {dut['SerialToI2C'].i2c_address}") 25 | dut['SerialToI2C'].i2c_address = 0x20 # Set I2C address 26 | print(f"I2C bus address to write to is {dut['SerialToI2C'].i2c_address}") 27 | 28 | dut['SerialToI2C'].check_i2c_connection() # Check if connection is established on I2C bus with given address 29 | dut['SerialToI2C'].read_register(reg=0x00) # Read register 0x00 at adress dut['SerialToI2C'].i2c_address 30 | dut['SerialToI2C'].write_register(reg=0x00, data=0x00) # Write 0 to register 0x00 at adress dut['SerialToI2C'].i2c_address 31 | -------------------------------------------------------------------------------- /examples/lab_devices/arduino_serial_to_i2c.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB1 6 | baudrate : 115200 7 | timeout: 1 8 | read_termination: "\r\n" 9 | write_termination: "\n" 10 | 11 | hw_drivers: 12 | - name : SerialToI2C 13 | type : arduino_serial_to_i2c 14 | interface : Serial 15 | -------------------------------------------------------------------------------- /examples/lab_devices/binderMK53_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : COM5 6 | read_termination : "" 7 | baudrate : 9600 8 | 9 | hw_drivers: 10 | - name : Climatechamber 11 | type : binder_mk53 12 | interface : Serial 13 | init : 14 | address : 1 15 | min_temp : 15 16 | max_temp : 25 17 | -------------------------------------------------------------------------------- /examples/lab_devices/binderMK56_socket.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name: Socket 3 | type: Socket 4 | init: 5 | address: '192.168.10.2' 6 | port: 10001 7 | query_delay: 1 8 | write_termination: '' 9 | read_termination: '' 10 | handle_as_byte: True 11 | 12 | hw_drivers: 13 | - name : Climatechamber 14 | type : binder_mk56 15 | interface : Socket 16 | init : 17 | address : 1 18 | min_temp : 15 19 | max_temp : 25 20 | -------------------------------------------------------------------------------- /examples/lab_devices/bronkhorstELFLOW_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | write_termination : "\r\n" 7 | read_termination : "\r\n" 8 | baudrate : 38400 9 | timeout : 2.0 10 | 11 | hw_drivers: 12 | - name : hot_n2 13 | type : bronkhorst_elflow 14 | interface : Serial 15 | -------------------------------------------------------------------------------- /examples/lab_devices/bronkhorsteflow.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' This script shows how to use EFLOW 9 | ''' 10 | 11 | from basil.dut import Dut 12 | 13 | dut = Dut('bronkhorstELFLOW_pyserial.yaml') 14 | dut.init() 15 | 16 | # setting set point 17 | dut["hot_n2"].set_mode(0) 18 | dut["hot_n2"].set_setpoint(10000) 19 | dut["hot_n2"].set_mode(0) 20 | print("setpoint", dut["hot_n2"].get_setpoint()) 21 | 22 | # controlling valve 23 | dut["hot_n2"].set_mode(20) 24 | 25 | # measuring flow rate 26 | # print("Flow",dut["hot_n2"].get_flow()) 27 | 28 | # Measuring of valve opening in % 29 | valve = dut["hot_n2"].get_valve_output() 30 | print("Valve opened in %", valve) 31 | -------------------------------------------------------------------------------- /examples/lab_devices/hp_4284a_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa_lcr 3 | type : Visa 4 | init : 5 | resource_name : GPIB0::17::INSTR 6 | 7 | hw_drivers: 8 | - name : LCRMeter 9 | type : hp4284a 10 | interface : Visa_lcr 11 | init : 12 | device : HP 4284A 13 | -------------------------------------------------------------------------------- /examples/lab_devices/hp_81104a_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa_sm 3 | type : Visa 4 | init : 5 | resource_name : GPIB0::1::INSTR 6 | 7 | hw_drivers: 8 | - name : ClockGenerator 9 | type : scpi 10 | interface : Visa_sm 11 | init : 12 | device : HP 81104A 13 | -------------------------------------------------------------------------------- /examples/lab_devices/iseg_shq.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' Example how to use the Arduino as NTC readout. 9 | ''' 10 | 11 | from basil.dut import Dut 12 | 13 | dut = Dut('iseg_shq.yaml') 14 | dut.init() 15 | 16 | # Set PSU channel 17 | dut['SHQ'].set_current_channel(1) 18 | 19 | # Set voltage ramp speed in V/s 20 | dut['SHQ'].set_ramp_speed(2) 21 | 22 | # Set autostart to True in order to automatically start voltage change when new voltage is set 23 | dut['SHQ'].set_autostart(True) 24 | 25 | # Set voltage to +-30 volts; requires hardware polarity change 26 | polarity = dut['SHQ'].get_polarity() 27 | 28 | dut['SHQ'].set_high_voltage(15 * polarity) # Set high voltage; hv_on() / hv_off() 29 | dut['SHQ'].set_voltage_limit(20 * polarity) # Set software-side voltage limit 30 | dut['SHQ'].set_voltage(10 * polarity) # Set voltage 31 | 32 | dut['SHQ'].set_current_trip(10) # Set current trip in mA 33 | dut['SHQ'].set_current_trip(10000, resolution="muA") # Set current trip in µA 34 | 35 | # Disable autostart 36 | dut['SHQ'].set_autostart(False) 37 | 38 | # Read back the voltage that is measured at the output 39 | print(dut['SHQ'].get_voltage()) 40 | 41 | # Read back the current that is measured at the output 42 | print(dut['SHQ'].get_current()) 43 | 44 | # Read back the software-side voltage limit 45 | print(dut['SHQ'].get_voltage_limit()) 46 | 47 | # Read back the hardware-side voltage-limit 48 | print(dut['SHQ'].get_hardware_voltage_limit()) 49 | 50 | # Read back the voltage that is set to be the output 51 | print(dut['SHQ'].get_source_voltage()) 52 | 53 | # Read back the current trip (default is mA range) 54 | print(dut['SHQ'].get_current_trip()) 55 | 56 | # Read back the current trip in mA 57 | print(dut['SHQ'].get_current_trip(resolution="mA")) 58 | 59 | # Read back the current trip in µA 60 | print(dut['SHQ'].get_current_trip("muA")) 61 | 62 | # Print the module description 63 | print(dut['SHQ'].get_module_description()) 64 | 65 | # Print the module description 66 | print(dut['SHQ'].get_identifier()) 67 | -------------------------------------------------------------------------------- /examples/lab_devices/iseg_shq.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | baudrate : 9600 7 | timeout: 2 8 | read_termination : "\r\n" 9 | write_termination : "\r\n" 10 | 11 | hw_drivers: 12 | - name : SHQ 13 | type : iseg_hv 14 | interface : Serial 15 | init : 16 | # high_voltage : 15 # Set HV to be 15 V 17 | # v_lim : 100 # Set software-side voltage limit to be 100 V 18 | n_channel : 1 # Set number of channels the ISEG HV PS has 19 | channel : 1 # Set channel number 20 | autostart : True # Set autostart to True in order to automatically start voltage change when new voltage is set 21 | -------------------------------------------------------------------------------- /examples/lab_devices/julabo1000F_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyACM0 6 | read_termination : "\r\n" 7 | write_termination : "\r" 8 | 9 | hw_drivers: 10 | - name : chiller 11 | type : julabo1000F 12 | interface : Serial 13 | init: 14 | device: julabo 1000F 15 | -------------------------------------------------------------------------------- /examples/lab_devices/julaboF32HD.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' Example how to use the chiller. 9 | ''' 10 | 11 | from basil.dut import Dut 12 | 13 | dut = Dut('julaboF32HD.yaml') 14 | dut.init() 15 | print("ID: {}".format(dut["chiller"].get_identifier())) 16 | print("Status: {}".format(dut["chiller"].get_status())) 17 | 18 | # start 19 | # set menu->confiuration->setpoint->rs232 20 | dut["chiller"].start_thermostat() 21 | dut["chiller"].get_status() 22 | -------------------------------------------------------------------------------- /examples/lab_devices/julaboF32HD.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB5 6 | read_termination : "\r\n" 7 | write_termination : "\r" 8 | baudrate : 4800 9 | timeout : 2.0 10 | parity : "N" ### serial.PARITY_NONE 11 | xonxoff : True ### software handshake on 12 | rtscts : False 13 | dsrdtr : False 14 | 15 | 16 | hw_drivers: 17 | - name : chiller 18 | type : julaboF32HD 19 | interface : Serial 20 | -------------------------------------------------------------------------------- /examples/lab_devices/julaboFP50.py: -------------------------------------------------------------------------------- 1 | from basil.dut import Dut 2 | 3 | dut = Dut('julaboFP50_pyserial.yaml') 4 | dut.init() 5 | 6 | 7 | # turn on: 8 | # dut["chiller"].start_chiller() 9 | 10 | # dut["chiller"].set_temp(15) # set temp 11 | 12 | print("Status: {}".format(dut["chiller"].get_status())) 13 | 14 | # turn off: 15 | # dut["chiller"].stop_chiller() 16 | -------------------------------------------------------------------------------- /examples/lab_devices/julaboFP50_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | read_termination : "\r\n" 7 | write_termination : "\r\n" 8 | baudrate : 9600 9 | timeout : 5.0 10 | parity : "N" ### serial.PARITY_NONE 11 | xonxoff : True # software handshake on 12 | rtscts : False 13 | dsrdtr : False 14 | 15 | 16 | hw_drivers: 17 | - name : chiller 18 | type : julaboFP50 19 | interface : Serial 20 | init: 21 | device: julabo FP50 22 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2000_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa 3 | type : Visa 4 | init : 5 | resource_name : GPIB0::5::INSTR 6 | 7 | hw_drivers: 8 | - name : Multimeter 9 | type : scpi 10 | interface : Visa 11 | init : 12 | device : Keithley 2000 13 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2400_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | read_termination : "\r" 7 | baudrate : 19200 8 | 9 | hw_drivers: 10 | - name : Sourcemeter 11 | type : scpi 12 | interface : Serial 13 | init : 14 | device : Keithley 2400 15 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2400_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa 3 | type : Visa 4 | init : 5 | resource_name : ASRL/dev/ttyUSB0 6 | read_termination : "\r" 7 | baud_rate : 19200 8 | backend : "@py" 9 | 10 | hw_drivers: 11 | - name : Sourcemeter 12 | type : scpi 13 | interface : Visa 14 | init : 15 | device : Keithley 2400 16 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2410_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | read_termination : "\r" 7 | baudrate : 19200 8 | 9 | hw_drivers: 10 | - name : Sourcemeter 11 | type : scpi 12 | interface : Serial 13 | init : 14 | device : Keithley 2410 15 | enable_formatting : true # Device-specific formatting 16 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2410_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa 3 | type : Visa 4 | init : 5 | resource_name : ASRLCOM3 6 | read_termination : "\r" 7 | baud_rate : 19200 8 | backend : "@py" 9 | 10 | hw_drivers: 11 | - name : Sourcemeter 12 | type : scpi 13 | interface : Visa 14 | init : 15 | device : Keithley 2410 16 | enable_formatting : true # Device-specific formatting 17 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2450_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | # example for connection of keithley 2450 via TCP/IP or usbtmc 2 | # For usbtmc use USB0::::::::0:INSTR 3 | 4 | transfer_layer: 5 | - name : Visa 6 | type : Visa 7 | init : 8 | # resource_name : TCPIP::131.220.165.164::INSTR 9 | resource_name : USB0::1510::9296::04039405::0::INSTR 10 | backend : "@py" 11 | query_delay : 0.1 12 | # read_termination : "\n" 13 | # open_timeout : 2 14 | 15 | hw_drivers: 16 | - name : Sourcemeter 17 | type : scpi 18 | interface : Visa 19 | init : 20 | device : Keithley 2450 21 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley2634b.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name: Serial 3 | type: Serial 4 | init: 5 | port: /dev/ttyUSB5 6 | read_termination: "\r\n" 7 | baudrate: 19200 8 | timeout: 5 9 | 10 | hw_drivers: 11 | - name: Sourcemeter1 12 | type: scpi 13 | interface: Serial 14 | init: 15 | device: Keithley 2634B -------------------------------------------------------------------------------- /examples/lab_devices/keithley6517a.py: -------------------------------------------------------------------------------- 1 | ################################################### 2 | # This is an example for keithley6517a electrometer 3 | # Last Modified: Do 09 Jun 2022 12:21:44 CEST 4 | ################################################### 5 | 6 | # Manual https://download.tek.com/manual/6517A_900_01C.pdf 7 | 8 | import time 9 | from basil.dut import Dut 10 | 11 | ################## 12 | # Initialisation # 13 | ################## 14 | 15 | dut = Dut('keithley6517a_pyvisa.yaml') 16 | dut.init() 17 | 18 | ######################### 19 | # End of Initialisation # 20 | ######################### 21 | 22 | 23 | def current_measurement(): 24 | # Use electrometer to measure current with configuration of fig 2-9, p.2-11 of manual 25 | 26 | # Connect the internal meter to the voltage source as shwon in fig 2-9 27 | dut['EMeter'].connect_meter() 28 | 29 | # Setup the electrometer for current measurement 30 | dut['EMeter'].setup_current_measurement(current_range=2e-10, # Also 'MIN'/'MAX' e.g. 20e-12/12e-3 A or any number in between or None for autorange 31 | voltage_range='MIN', # Also 'MIN'/'MAX' e.g. 100/1000 V or any number in between 32 | current_limit=1e-10, # Current limit for protection DUT 33 | filter=('REP', 5)) # Average filter to apply e.g. REPeat measurement 5 times andy yield average 34 | # Turn the output on 35 | dut['EMeter'].on() 36 | 37 | # Loop over voltages 38 | for i in range(5): 39 | dut['Emeter'].set_voltage(i) 40 | time.sleep(1) # Bias voltage needs time to settle for precise measurement -> maybe needs to be increased 41 | print(f"{dut['EMeter'].get_current()} A @ {i} V") 42 | 43 | # Ramp down 44 | for j in range(4, -1, -1): 45 | dut['Emeter'].set_voltage(j) 46 | 47 | # Turn the output off 48 | dut['EMeter'].off() 49 | 50 | 51 | if __name__ == '__main__': 52 | current_measurement() 53 | -------------------------------------------------------------------------------- /examples/lab_devices/keithley6517a_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | ################################################# 2 | # An example for setting up the remote connection 3 | # Last Modified: Mi 08 Jun 2022 11:23:21 CEST 4 | ################################################# 5 | 6 | transfer_layer: 7 | - name: electrometer 8 | type: Visa 9 | init: 10 | # using serial-USB adapter 11 | # resource_name: ASRLCOM6 # example for windows system 12 | resource_name: ASRL/dev/ttyUSB0 # example for linux system 13 | timeout : 2000 # Needed because of sleeps in between write in subclass of keithley6517a TL 14 | read_termination: "\n" 15 | baud_rate: 19200 16 | backend: '@py' 17 | hw_drivers: 18 | - name: EMeter 19 | type: keithley6517a 20 | interface: electrometer 21 | init: 22 | device: keithley 6517a 23 | -------------------------------------------------------------------------------- /examples/lab_devices/mercury_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : COM10 6 | read_termination : "\x03" 7 | baudrate : 9600 8 | timeout : 0.1 9 | 10 | hw_drivers: 11 | - name : MotorStage 12 | type : mercury 13 | interface : Serial 14 | -------------------------------------------------------------------------------- /examples/lab_devices/rs_hmp4040.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name: Visa 3 | type: Visa 4 | init: 5 | resource_name: ASRL/dev/ttyUSB2::INSTR 6 | read_termination: "\r\n" 7 | baud_rate: 38400 8 | backend: "@py" 9 | 10 | hw_drivers: 11 | - name: LVPowersupply1 12 | type: rs_hmp4040 13 | interface: Visa 14 | init: 15 | device : rs_hmp4040 -------------------------------------------------------------------------------- /examples/lab_devices/rs_hmp4040_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa 3 | type : Visa 4 | init : 5 | resource_name : ASRL/dev/ttyUSB2 6 | read_termination : "\r\n" 7 | baud_rate : 9600 8 | backend : "@py" 9 | hw_drivers: 10 | - name : PowerSupply 11 | type : scpi 12 | interface : Visa 13 | init : 14 | device : rs_hmp4040 -------------------------------------------------------------------------------- /examples/lab_devices/scpi_devices.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' Example how to use different laboratory devices (Sourcemeter, pulsers, etc.) that understand SCPI. 9 | The language (SCPI) is independent of the interface (TCP, RS232, GPIB, USB, etc.). The interfaces 10 | can be choosen by an appropriate transportation layer (TL). This can be a VISA TL and 11 | a Serial TL at the moment. VISA TL is recommendet since it gives you access to almost 12 | all laboratory devices (> 90%) over TCP, RS232, USB, GPIB (Windows only so far). 13 | ''' 14 | 15 | 16 | from basil.dut import Dut 17 | 18 | # Talk to a Keithley device via serial port using pySerial 19 | dut = Dut('keithley2400_pyserial.yaml') 20 | dut.init() 21 | print(dut['Sourcemeter'].get_name()) 22 | 23 | # Talk to a Keithley device via serial port using VISA with Serial interface 24 | dut = Dut('keithley2400_pyvisa.yaml') 25 | dut.init() 26 | print(dut['Sourcemeter'].get_name()) 27 | # Some additional implemented methods for this device 28 | print(dut['Sourcemeter'].get_voltage()) 29 | dut['Sourcemeter'].off() 30 | dut['Sourcemeter'].set_voltage(3.14159) 31 | dut['Sourcemeter'].set_current_limit(.9265) 32 | 33 | # Example of a SCPI device implementing more specialized functions (e.g. unit conversion) via extra class definitions 34 | dut = Dut('agilent33250a_pyserial.yaml') 35 | dut.init() 36 | print(dut['Pulser'].get_info()) 37 | # Some additional implemented methods for this device 38 | dut['Pulser'].set_voltage(0., 1., unit='V') 39 | print("{}{}".format(dut['Pulser'].get_voltage(0, unit='mV'), 'mV')) 40 | 41 | # Example for device with multiple channels 42 | dut = Dut('ttiql355tp.yaml') 43 | dut.init() 44 | print(dut['PowerSupply'].get_name()) 45 | print(dut['PowerSupply'].get_voltage(channel=1)) 46 | 47 | # Talk to a Keithley device via GPIB using NI VISA 48 | dut = Dut('keithley2000_pyvisa.yaml') 49 | dut.init() 50 | print(dut['Multimeter'].get_name()) 51 | 52 | # Talk to a Tektronix mixed signal oscilloscope via TCPIP, USB 53 | dut = Dut('tektronixMSO4104B_pyvisa.yaml') 54 | dut.init() 55 | print(dut['Oscilloscope'].get_name()) 56 | print(dut['Oscilloscope'].get_data(channel=1)) 57 | -------------------------------------------------------------------------------- /examples/lab_devices/sensirionEKH4_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : COM16 6 | read_termination : "" 7 | baudrate : 115200 8 | timeout : 2.0 9 | 10 | hw_drivers: 11 | - name : Thermohygrometer 12 | type : sensirion_ekh4 13 | interface : Serial 14 | -------------------------------------------------------------------------------- /examples/lab_devices/sensirionSHT85.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : SensorBridge 3 | type : SensirionSensorBridge 4 | init : 5 | port : /dev/ttyUSB3 6 | baudrate : 460800 7 | 8 | hw_drivers: 9 | - name : Thermohygrometer 10 | type : sensirion_sht85 11 | interface : SensorBridge 12 | init : 13 | bridgePort : one # one or two 14 | voltage : 3.3 # min:2.15, typ:3.3, max:5.5 15 | frequency : 400000 # 400kHz default 1MHz max 16 | repeatability : "low" # low (0.15°C 0.21%RH), medium (0.08°C 0.15%RH), high (0.04°C 0.08%RH) 17 | -------------------------------------------------------------------------------- /examples/lab_devices/suss_pa_200.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : COM2 6 | read_termination : "\r" 7 | baudrate : 9600 8 | 9 | hw_drivers: 10 | - name : SussProber 11 | type : SussProber 12 | interface : Serial 13 | -------------------------------------------------------------------------------- /examples/lab_devices/tektronixOscilloscope_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is valid for the following oscilloscopes: MSO54, MSO4104b, MSO4034 2 | transfer_layer: 3 | - name : Visa 4 | type : Visa 5 | init : 6 | resource_name : TCPIP::131.220.167.109 7 | encoding: 'ascii' 8 | backend : "@py" 9 | #resource_name : USB0::0x0699::0x0409::C010877::INSTR # (works with NI VISA backend + USB + Windows 7) 10 | 11 | hw_drivers: 12 | - name : Oscilloscope 13 | type : tektronix_oscilloscope 14 | interface : Visa 15 | init : 16 | device : Tektronix Oscilloscope 17 | -------------------------------------------------------------------------------- /examples/lab_devices/tektronix_oscilloscope_tds3034b.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | # INFO: You might be able to ping the oscilloscope at the displayed IP. This does for some reason not 8 | # mean, that you will be able to run this script without errors like: 9 | # pyvisa.errors.VisaIOError: VI_ERROR_RSRC_NFOUND (-1073807343): Insufficient location information or the requested device or resource is not present in the system. 10 | # 11 | # If such an error occures, reboot the oscilloscope 12 | # 13 | 14 | from basil.dut import Dut 15 | import numpy as np 16 | import matplotlib.pyplot as plt 17 | 18 | dut = Dut('tektronix_tds_3034b.yaml') 19 | dut.init() 20 | 21 | # Control settings of the oscilloscope 22 | dut['Oscilloscope'].set_vertical_scale('5.0E-2', channel=1) 23 | dut['Oscilloscope'].set_vertical_position('0', channel=1) 24 | dut['Oscilloscope'].set_vertical_offset('0.0E0', channel=1) 25 | dut['Oscilloscope'].set_trigger_source(channel=1) 26 | dut['Oscilloscope'].set_trigger_level(1e-2) 27 | dut['Oscilloscope'].set_trigger_mode('AUTO') 28 | 29 | # Taking a measurement 30 | meas_waveform = dut['Oscilloscope'].get_waveform(channel=1) 31 | CH_id = meas_waveform[0] 32 | CH_data = meas_waveform[1] 33 | CH_xscale = meas_waveform[2] 34 | CH_yscale = meas_waveform[3] 35 | CH_time = np.linspace(0, CH_xscale[0] * len(CH_data), len(CH_data)) 36 | 37 | # Plot the data 38 | plt.figure(figsize=(16, 9)) 39 | plt.scatter(CH_time, CH_data, label='CH' + str(CH_id)) 40 | plt.ylim(-4 * CH_yscale[0], 4 * CH_yscale[0]) 41 | plt.xlabel('Time $t$ / s') 42 | plt.ylabel('Voltage U / V') 43 | plt.grid() 44 | plt.legend() 45 | plt.show() 46 | -------------------------------------------------------------------------------- /examples/lab_devices/tektronix_tds_3034b.yaml: -------------------------------------------------------------------------------- 1 | #This configuration is valid for the following oscilloscopes: Tektronix TDS3034B 2 | transfer_layer: 3 | - name : Visa 4 | type : Visa 5 | init : 6 | resource_name : TCPIP0::10.42.0.48::INSTR 7 | encoding: 'ascii' 8 | backend : "@py" 9 | 10 | hw_drivers: 11 | - name : Oscilloscope 12 | type : tektronix_tds3034b 13 | interface : Visa 14 | init : 15 | device : tektronix oscilloscope -------------------------------------------------------------------------------- /examples/lab_devices/temperature_control.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' 9 | This script shows how to set temperature using a Binder MK 53 climate chamber. 10 | For the communication with the Binder MK 53 also a serial TL has to be used (http://www.binder-world.com). 11 | The newer Weiss Labevent climatechamber uses a direct TCP/IP connection. 12 | ''' 13 | 14 | 15 | from basil.dut import Dut 16 | 17 | # Binder MK 53 control 18 | dut = Dut('binderMK53_pyserial.yaml') 19 | dut.init() 20 | print(dut['Climatechamber'].get_temperature()) 21 | print(dut['Climatechamber'].get_door_open()) 22 | print(dut['Climatechamber'].get_mode()) 23 | temperature_target = dut['Climatechamber'].get_temperature_target() 24 | dut['Climatechamber'].set_temperature(temperature_target) 25 | 26 | # New Weiss Labevent control 27 | dut = Dut('WeissLabEvent_socket.yaml') 28 | dut.init() 29 | dut['Climatechamber'].start_manual_mode() 30 | dut['Climatechamber'].set_temperature(20) 31 | dut['Climatechamber'].set_air_dryer(True) # Make sure the air dryer is turned on 32 | print(dut['Climatechamber'].get_temperature()) 33 | -------------------------------------------------------------------------------- /examples/lab_devices/temperature_sensors.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | ''' 9 | This script shows how to read temperature/humidity with Sensirion sensors. 10 | Some Sensirion sensors are read using the Sensirion EK-H4 multiplexer box from the evaluation kit. A serial TL has to be used 11 | (http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_EK-H4_Datasheet_V3.pdf). 12 | The Sensirion SHT85 sensor is read using the Sensirion Sensor Bridge. 13 | ''' 14 | 15 | 16 | import time 17 | from basil.dut import Dut 18 | 19 | # Sensirion EK-H4 sensor readout 20 | dut = Dut('sensirionEKH4_pyserial.yaml') 21 | dut.init() 22 | print(dut['Thermohygrometer'].get_temperature()) 23 | print(dut['Thermohygrometer'].get_humidity()) 24 | print(dut['Thermohygrometer'].get_dew_point()) 25 | 26 | # Sensirion SHT85 sensor readout 27 | dut = Dut('sensirionSHT85.yaml') 28 | dut.init() 29 | sensor = dut['Thermohygrometer'] 30 | sensor.printInformation() 31 | for action in sensor.enable_heater, sensor.disable_heater: 32 | action() 33 | for _ in range(10): 34 | time.sleep(1) 35 | print(sensor.get_temperature_and_humidity(), sensor.get_dew_point()) 36 | with sensor.asynchronous(measurments_per_second=1) as a: 37 | for _ in range(10): 38 | time.sleep(.8) 39 | T, RH = a.read() 40 | if T is not None: 41 | print(T, RH, sensor.to_dew_point(T, RH)) 42 | else: 43 | print("No data available") 44 | sensor.power_off() 45 | -------------------------------------------------------------------------------- /examples/lab_devices/ttiql355tp.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB1 6 | read_termination : "\r\n" 7 | write_termination : "\n" 8 | baudrate : 19200 9 | timeout : 2.0 10 | xonxoff : True 11 | parity : N 12 | stopbits : 1 13 | bytesize : 8 14 | 15 | hw_drivers: 16 | - name : PowerSupply 17 | type : tti_ql355tp 18 | interface : Serial 19 | -------------------------------------------------------------------------------- /examples/lab_devices/ttiql355tp_pyvisa.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Visa 3 | type : Visa 4 | init : 5 | resource_name : ASRL6::INSTR 6 | backend : "@py" 7 | 8 | hw_drivers: 9 | - name : PowerSupply 10 | type : scpi 11 | interface : Visa 12 | init : 13 | device : TTi QL355TP 14 | -------------------------------------------------------------------------------- /examples/lab_devices/xray_tube.py: -------------------------------------------------------------------------------- 1 | import time 2 | from basil.dut import Dut 3 | 4 | # Initialize x-ray tube 5 | devices = Dut('xray_tube_pyserial.yaml') 6 | devices.init() 7 | 8 | # Set high voltage and current 9 | devices["xray_tube"].set_voltage(10) # 40 kV 10 | devices["xray_tube"].set_current(50) # 50 mA 11 | print(devices["xray_tube"].get_actual_voltage()) # in kV 12 | print(devices["xray_tube"].get_actual_current()) # in mA 13 | 14 | devices["xray_tube"].set_high_voltage_on() # Turn on HV 15 | devices["xray_tube"].set_timer(dur=3600) # 3600 s 16 | devices["xray_tube"].activate_timer() # Activate the timer (clock symbol on display) 17 | devices["xray_tube"].open_shutter() # Starts actual irradiation (and timer, if set) 18 | 19 | time.sleep(10) 20 | # Print remaining irradiation time in seconds 21 | print(devices["xray_tube"].get_actual_time()) 22 | 23 | # Print status of HV (bit 6 of status word 0) 24 | print(devices["xray_tube"].get_status(0)[1]) 25 | -------------------------------------------------------------------------------- /examples/lab_devices/xray_tube_pyserial.yaml: -------------------------------------------------------------------------------- 1 | transfer_layer: 2 | - name : Serial 3 | type : Serial 4 | init : 5 | port : /dev/ttyUSB0 6 | read_termination : "\r" 7 | baudrate : 9600 8 | timeout : 2.0 9 | 10 | hw_drivers: 11 | - name : xray_tube 12 | type : debyeflex3003 13 | interface : Serial 14 | -------------------------------------------------------------------------------- /examples/lx9/device/ise/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !.gitignore 4 | !*.xise 5 | !*.bit 6 | -------------------------------------------------------------------------------- /examples/lx9/device/ise/top.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiLab-Bonn/basil/91efcd01f6b25646d4d8df6a90c9dbcdf7635c9c/examples/lx9/device/ise/top.bit -------------------------------------------------------------------------------- /examples/mio3_eth_gpac/README.md: -------------------------------------------------------------------------------- 1 | ### MIO3 hardware example with Ethernet and GPAC 2 | 3 | This example shows how to control a GPIO and GPAC module. 4 | 5 | The firmware makes use of the free SiTcp Ethernet module ([general website][url1], [community website with downloads and documentation][url2]). 6 | 7 | [url1]: https://translate.google.de/translate?hl=de&sl=ja&tl=en&u=http%3A%2F%2Fresearch.kek.jp%2Fpeople%2Fuchida%2Ftechnologies%2FSiTCP%2F 8 | 9 | [url2]: https://sitcp.bbtech.co.jp/ 10 | 11 | -------------------------------------------------------------------------------- /examples/mio3_eth_gpac/mio3_eth_gpac.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Copyright (c) All rights reserved 3 | # SiLab, Institute of Physics, University of Bonn 4 | # ------------------------------------------------------------ 5 | # 6 | 7 | from basil.dut import Dut 8 | 9 | chip = Dut("mio3_eth_gpac.yaml") 10 | chip.init() 11 | 12 | chip['VDD'].set_current_limit(80, unit='mA') 13 | chip['VDD'].set_voltage(1.3, unit='V') 14 | chip['VDD'].set_enable(True) 15 | 16 | chip['CONTROL']['LED'] = 0xa5 17 | 18 | chip['CONTROL'].write() 19 | -------------------------------------------------------------------------------- /examples/mio3_eth_gpac/mio3_eth_gpac.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | transfer_layer: 9 | - name : INTF 10 | type : SiTcp 11 | init: 12 | ip : "192.168.10.16" 13 | udp_port : 4660 14 | tcp_port : 24 15 | tcp_connection : True 16 | 17 | hw_drivers: 18 | - name : GPIO_DRV 19 | type : gpio 20 | interface : INTF 21 | base_addr : 0x1000 22 | size : 32 23 | 24 | - name : I2C 25 | type : i2c 26 | interface : INTF 27 | base_addr : 0x2000 28 | 29 | - name : GPAC 30 | type : GPAC 31 | hw_driver : I2C 32 | base_addr : 0x00000 33 | init: 34 | no_calibration : False 35 | 36 | registers: 37 | - name : CONTROL 38 | type : StdRegister 39 | hw_driver : GPIO_DRV 40 | size : 8 41 | fields: 42 | - name : LED 43 | size : 8 44 | offset : 7 45 | 46 | - name : VDD 47 | type : FunctionalRegister 48 | hw_driver : GPAC 49 | arg_names : [ value ] 50 | arg_add : { 'channel': 'PWR0'} 51 | -------------------------------------------------------------------------------- /examples/mio_pixel/firmware/ise/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !.gitignore 4 | !*.xise 5 | 6 | -------------------------------------------------------------------------------- /examples/mio_sram_test/firmware/ise/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !.gitignore 4 | !*.xise 5 | 6 | -------------------------------------------------------------------------------- /examples/mio_sram_test/sram_test.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | transfer_layer: 9 | - name : USB 10 | type : SiUsb 11 | init: 12 | #avoid_download : True 13 | bit_file : ./firmware/ise/sram_test.bit 14 | 15 | hw_drivers: 16 | - name : GPIO_CONTROL_DRV 17 | type : gpio 18 | interface : USB 19 | base_addr : 0x10000 20 | size : 8 21 | 22 | - name : GPIO_PATTERN_DRV 23 | type : gpio 24 | interface : USB 25 | base_addr : 0x10010 26 | size : 32 27 | 28 | - name : FIFO 29 | type : sram_fifo 30 | interface : USB 31 | base_addr : 0x10020 32 | base_data_addr: 0x0001000000000000 33 | 34 | - name : PULSE 35 | type : pulse_gen 36 | interface : USB 37 | base_addr : 0x10030 38 | 39 | registers: 40 | - name : CONTROL 41 | type : StdRegister 42 | hw_driver : GPIO_CONTROL_DRV 43 | size : 8 44 | fields: 45 | - name : COUNTER_EN 46 | size : 1 47 | offset : 0 48 | - name : PATTERN_EN 49 | size : 1 50 | offset : 1 51 | - name : COUNTER_DIRECT 52 | size : 1 53 | offset : 2 54 | 55 | - name : PATTERN 56 | type : StdRegister 57 | hw_driver : GPIO_PATTERN_DRV 58 | size : 32 59 | -------------------------------------------------------------------------------- /examples/mio_sram_test/tests/tb.v: -------------------------------------------------------------------------------- 1 | 2 | `timescale 1ps / 1ps 3 | `default_nettype none 4 | 5 | module tb ( 6 | 7 | input wire FCLK_IN, 8 | 9 | //full speed 10 | inout wire [7:0] BUS_DATA, 11 | input wire [15:0] ADD, 12 | input wire RD_B, 13 | input wire WR_B, 14 | 15 | //high speed 16 | inout wire [7:0] FD, 17 | input wire FREAD, 18 | input wire FSTROBE, 19 | input wire FMODE 20 | 21 | ); 22 | 23 | 24 | //SRAM 25 | wire [19:0] SRAM_A; 26 | wire [15:0] SRAM_IO; 27 | wire SRAM_BHE_B; 28 | wire SRAM_BLE_B; 29 | wire SRAM_CE1_B; 30 | wire SRAM_OE_B; 31 | wire SRAM_WE_B; 32 | 33 | wire [4:0] LED; 34 | wire SDA; 35 | wire SCL; 36 | 37 | sram_test dut(.FCLK_IN(FCLK_IN), 38 | .BUS_DATA(BUS_DATA), .ADD(ADD), .RD_B(RD_B), .WR_B(WR_B), 39 | .FD(FD), .FREAD(FREAD), .FSTROBE(FSTROBE), .FMODE(FMODE), 40 | .SRAM_A(SRAM_A), .SRAM_IO(SRAM_IO), .SRAM_BHE_B(SRAM_BHE_B), .SRAM_BLE_B(SRAM_BLE_B), .SRAM_CE1_B(SRAM_CE1_B), .SRAM_OE_B(SRAM_OE_B), .SRAM_WE_B(SRAM_WE_B), 41 | .LED(LED), .SDA(SDA), .SCL(SCL) ); 42 | 43 | defparam dut.i_out_fifo.DEPTH = 21'h100; 44 | 45 | /// SRAM 46 | reg [15:0] sram [1048576-1:0]; 47 | always @(negedge SRAM_WE_B) 48 | sram[SRAM_A] <= SRAM_IO; 49 | 50 | assign SRAM_IO = !SRAM_OE_B ? sram[SRAM_A] : 16'hzzzz; 51 | 52 | initial begin 53 | $dumpfile("sram_test.vcd"); 54 | $dumpvars(0); 55 | end 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /examples/mmc3_eth/Readme.md: -------------------------------------------------------------------------------- 1 | ### Ethernet example for the MMC3 hardware 2 | 3 | This example shows how to control a GPIO module and how to receive data via the Ethernet interface. 4 | 5 | The firmware makes use of the free SiTcp Ethernet module ([SiTCP netlist on Github][url1]). Put the extracted files in */firmware/src/SiTCP*. 6 | 7 | [url1]: https://github.com/BeeBeansTechnologies/SiTCP_Netlist_for_Kintex7 8 | 9 | 1. Data transfer is started by setting a bit [0] in the GPIO. 10 | 2. FPGA starts to send data from a 32 bit counter, as fast as possible through a FIFO. 11 | 3. Python receives the data and counts bytes during a given time period. 12 | 4. At the end, the average data rate is printed and the FPGA data source is stopped by clearing bit [0]. 13 | 14 | Test for CocoTB available in */firmware/test* 15 | -------------------------------------------------------------------------------- /examples/mmc3_eth/firmware/src/mmc3_eth_core.v: -------------------------------------------------------------------------------- 1 | /** 2 | * ------------------------------------------------------------ 3 | * Copyright (c) All rights reserved 4 | * SiLab, Institute of Physics, University of Bonn 5 | * ------------------------------------------------------------ 6 | */ 7 | `timescale 1ns / 1ps 8 | 9 | module mmc3_eth_core ( 10 | input wire RESET_N, 11 | 12 | // clocks from PLL clock buffers 13 | input wire BUS_CLK, CLK125TX, CLK125TX90, CLK125RX, 14 | input wire PLL_LOCKED, 15 | 16 | input wire BUS_RST, 17 | input wire [31:0] BUS_ADD, 18 | inout wire [31:0] BUS_DATA, 19 | input wire BUS_RD, 20 | input wire BUS_WR, 21 | output wire BUS_BYTE_ACCESS, 22 | 23 | input wire fifo_empty, 24 | input wire fifo_full, 25 | input wire FIFO_NEXT, 26 | output wire FIFO_WRITE, 27 | output wire [31:0] FIFO_DATA, 28 | 29 | output wire [7:0] GPIO 30 | ); 31 | 32 | 33 | /* ------- MODULE ADREESSES ------- */ 34 | localparam GPIO_BASEADDR = 32'h1000; 35 | localparam GPIO_HIGHADDR = 32'h101f; 36 | 37 | 38 | /* ------- USER MODULES ------- */ 39 | gpio #( 40 | .BASEADDR(GPIO_BASEADDR), 41 | .HIGHADDR(GPIO_HIGHADDR), 42 | .ABUSWIDTH(32), 43 | .IO_WIDTH(8), 44 | .IO_DIRECTION(8'hff) 45 | ) i_gpio_rx ( 46 | .BUS_CLK(BUS_CLK), 47 | .BUS_RST(BUS_RST), 48 | .BUS_ADD(BUS_ADD), 49 | .BUS_DATA(BUS_DATA[7:0]), 50 | .BUS_RD(BUS_RD), 51 | .BUS_WR(BUS_WR), 52 | .IO(GPIO) 53 | ); 54 | wire EN; 55 | assign EN = GPIO[0]; 56 | 57 | reg [31:0] datasource; 58 | reg fifo_write; 59 | assign FIFO_WRITE = !fifo_full & EN; 60 | reg [31:0] fifo_data_out; 61 | assign FIFO_DATA = fifo_data_out; 62 | 63 | 64 | always @(posedge BUS_CLK) 65 | if(!EN) 66 | fifo_data_out <= 0; 67 | else if(FIFO_WRITE) 68 | fifo_data_out <= fifo_data_out + 1; 69 | 70 | endmodule 71 | -------------------------------------------------------------------------------- /examples/mmc3_eth/mmc3_eth.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # SiTCP throughput test 3 | # Reads data for a couple of seconds and displays the data rate 4 | # 5 | # Copyright (c) All rights reserved 6 | # SiLab, Institute of Physics, University of Bonn 7 | # ------------------------------------------------------------ 8 | # 9 | import logging 10 | import time 11 | 12 | import numpy as np 13 | 14 | from basil.dut import Dut 15 | 16 | 17 | chip = Dut("mmc3_eth.yaml") 18 | chip.init() 19 | 20 | chip['CONTROL']['EN'] = 0 21 | chip['CONTROL'].write() 22 | 23 | logging.info("Starting data test ...") 24 | 25 | chip['CONTROL']['EN'] = 1 26 | chip['CONTROL'].write() 27 | 28 | start = 0 29 | for i in range(10): 30 | 31 | time.sleep(1) 32 | 33 | fifo_data = chip['FIFO'].get_data() 34 | data_size = len(fifo_data) 35 | data_gen = np.linspace(start, data_size - 1 + start, data_size, dtype=np.int32) 36 | 37 | comp = (fifo_data == data_gen) 38 | logging.info(str((i, " OK?:", comp.all(), float(32 * data_size) / pow(10, 6), "Mbit"))) 39 | start += data_size 40 | 41 | chip['CONTROL']['EN'] = 0 # stop data source 42 | chip['CONTROL'].write() 43 | 44 | logging.info("Starting speed test ...") 45 | 46 | testduration = 10 47 | total_len = 0 48 | tick = 0 49 | tick_old = 0 50 | start_time = time.time() 51 | 52 | chip['CONTROL']['EN'] = 1 53 | chip['CONTROL'].write() 54 | 55 | while time.time() - start_time < testduration: 56 | data = chip['FIFO'].get_data() 57 | total_len += len(data) * 4 * 8 58 | time.sleep(0.01) 59 | tick = int(time.time() - start_time) 60 | if tick != tick_old: 61 | logging.info("Time: %f s" % (time.time() - start_time)) 62 | tick_old = tick 63 | 64 | chip['CONTROL']['EN'] = 0x0 # stop data source 65 | chip['CONTROL'].write() 66 | 67 | logging.info(str(('Bytes received:', total_len, ' data rate:', round((total_len / 1e6 / testduration), 2), ' Mbits/s'))) 68 | -------------------------------------------------------------------------------- /examples/mmc3_eth/mmc3_eth.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | transfer_layer: 9 | - name : INTF 10 | type : SiTcp 11 | init: 12 | ip : "192.168.10.16" 13 | udp_port : 4660 14 | tcp_port : 24 15 | tcp_connection : True 16 | 17 | hw_drivers: 18 | - name : GPIO_DRV 19 | type : gpio 20 | interface : INTF 21 | base_addr : 0x1000 22 | size : 8 23 | 24 | - name : FIFO 25 | type : sitcp_fifo 26 | interface : INTF 27 | base_addr : 0x200000000 28 | base_data_addr : 0x100000000 29 | 30 | registers: 31 | - name : CONTROL 32 | type : StdRegister 33 | hw_driver : GPIO_DRV 34 | size : 8 35 | fields: 36 | - name : EN 37 | size : 1 38 | offset : 0 39 | -------------------------------------------------------------------------------- /examples/register_example/simple_register_example.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------ 2 | # Copyright (c) All rights reserved 3 | # SiLab, Institute of Physics, University of Bonn 4 | # ------------------------------------------------------------ 5 | # 6 | 7 | 8 | from basil.dut import Dut 9 | 10 | chip = Dut("simple_register_example.yaml") 11 | 12 | print(chip['TEST']) 13 | print(chip['REG']) 14 | 15 | # chip['REG'][0] = 1 16 | chip['REG']['VPULSE'][5] = 1 17 | # chip['REG']['VPULSE'] = 1 18 | 19 | # chip['REG']['COLUMN'][0] = 1 # does not work yet 20 | # chip['REG'][0] = 1 # does not work yet 21 | 22 | chip['REG']['COLUMN'][0]['EnR'] = 1 23 | chip['REG']['COLUMN'][0]['DACR'] = 3 24 | 25 | chip['REG']['VINJECT'] = 3 26 | print(chip['REG']) 27 | 28 | chip['REG']['VINJECT'][0] = 1 29 | print(chip['REG']) 30 | 31 | print('VINJECT {}'.format(str(chip['REG']['VINJECT']))) 32 | -------------------------------------------------------------------------------- /examples/register_example/simple_register_example.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) SILAB , Physics Institute of Bonn University 4 | # ------------------------------------------------------------ 5 | # 6 | # SVN revision information: 7 | # $Rev:: 36 $: 8 | # $Author:: themperek $: 9 | # $Date:: 2013-09-12 12:16:59 #$: 10 | # 11 | --- 12 | name : SimpleExample 13 | version : 0.01 14 | 15 | transfer_layer: 16 | - name : usb 17 | type : Dummy 18 | board_id : -1 19 | 20 | hw_drivers: 21 | - name : spi_module 22 | type : spi 23 | interface : usb 24 | base_addr : 0x10000 25 | mem_bytes : 2 26 | 27 | registers: 28 | - name : TEST 29 | type : StdRegister 30 | hw_driver : spi_module 31 | size : 3 32 | 33 | - name : REG 34 | type : StdRegister 35 | hw_driver : spi_module 36 | size : 20 37 | fields : 38 | - name : VINJECT 39 | size : 6 40 | offset : 19 41 | bit_order: [5,4,3,1,0,2] 42 | - name : VPULSE 43 | size : 6 44 | offset : 13 45 | - name : EN 46 | size : 2 47 | offset : 7 48 | - name : COLUMN 49 | offset : 5 50 | size : 3 51 | repeat : 2 52 | fields : 53 | - name : EnR 54 | size : 1 55 | offset : 2 56 | - name : DACR 57 | size : 2 58 | offset : 1 59 | -------------------------------------------------------------------------------- /examples/test_eth/firmware_test_eth/src/SiTCP/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | pyyaml 3 | bitarray>=2.0.0 4 | GitPython 5 | six 6 | ruamel.yaml -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.rst 3 | 4 | [flake8] 5 | ignore = E501,E902,W503,W605,W504 6 | # max-line-length = 160 7 | 8 | [tool:pytest] 9 | markers = 10 | verilator 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | from os import path, walk 3 | 4 | author = 'Tomasz Hemperek, Jens Janssen, David-Leon Pohl' 5 | author_email = 'hemperek@uni-bonn.de, janssen@physik.uni-bonn.de, pohl@physik.uni-bonn.de' 6 | maintainer = 'Yannick Dieter, Christian Bespin' 7 | maintainer_email = 'dieter@physik.uni-bonn.de, bespin@physik.uni-bonn.de' 8 | 9 | # https://packaging.python.org/guides/single-sourcing-package-version/ 10 | # Use 11 | # import get_distribution 12 | # get_distribution('package_name').version 13 | # to programmatically access a version number. 14 | # Also add 15 | # include VERSION 16 | # MANIFEST.in 17 | with open('VERSION') as version_file: 18 | version = version_file.read().strip() 19 | 20 | # Requirements for core functionality from requirements.txt 21 | # Also add 22 | # include requirements.txt 23 | # MANIFEST.in 24 | with open('requirements.txt') as f: 25 | install_requires = f.read().splitlines() 26 | 27 | 28 | def package_files(directory): 29 | paths = [] 30 | for (fpath, directories, filenames) in walk(directory): 31 | for filename in filenames: 32 | paths.append(path.join('..', fpath, filename)) 33 | return paths 34 | 35 | 36 | setup( 37 | name='basil_daq', 38 | version=version, 39 | python_requires='>=3.8', 40 | description='Basil - a data acquisition and system testing framework', 41 | url='https://github.com/SiLab-Bonn/basil', 42 | license='BSD 3-Clause ("BSD New" or "BSD Simplified") License', 43 | long_description='Basil is a modular data acquisition system and system testing framework in Python.\nIt also provides generic FPGA firmware modules for different hardware platforms and drivers for wide range of lab appliances.', 44 | install_requires=install_requires, 45 | author=author, 46 | author_email=author_email, 47 | maintainer=maintainer, 48 | maintainer_email=maintainer_email, 49 | packages=find_packages(), 50 | include_package_data=True, # accept all data files and directories matched by MANIFEST.in or found in source control 51 | package_data={'': ['*.yaml'], 'basil': package_files('basil/firmware')}, 52 | platforms='any' 53 | ) 54 | -------------------------------------------------------------------------------- /tests/formatting.yaml: -------------------------------------------------------------------------------- 1 | spec: "1.1" 2 | devices: 3 | device 1: 4 | eom: 5 | ASRL INSTR: 6 | q: "\r\n" 7 | r: "\n" 8 | USB INSTR: 9 | q: "\n" 10 | r: "\n" 11 | TCPIP INSTR: 12 | q: "\n" 13 | r: "\n" 14 | GPIB INSTR: 15 | q: "\n" 16 | r: "\n" 17 | dialogues: 18 | - q: "*IDN?" 19 | r: "KEITHLEY INSTRUMENTS INC.,MODEL 2410" 20 | properties: 21 | selected_channel: 22 | default: 'VOLT' 23 | setter: 24 | q: "SENSE:FUNC '{}'" 25 | channels: 26 | type1: 27 | ids: ['VOLT'] 28 | can_select: False 29 | properties: 30 | value: 31 | default: 1.0 32 | getter: 33 | q: ':READ?' 34 | r: '-5.124E-05,+1.789E-10,+1.001E37,1.001E5' 35 | 36 | resources: 37 | ASRL1::INSTR: 38 | device: device 1 39 | -------------------------------------------------------------------------------- /tests/test_RegisterHardwareLayer.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | name : RegisterHardwareLayer 9 | version : 0.01 10 | 11 | transfer_layer: 12 | - name : dummy_tl 13 | type : Dummy 14 | 15 | hw_drivers: 16 | - name : test_register 17 | type : test_RegisterHardwareLayer 18 | interface : dummy_tl 19 | base_addr : 0x0 20 | -------------------------------------------------------------------------------- /tests/test_RegisterHardwareLayer_configuration.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | test_register: 9 | REG1 : 257 10 | REG2 : 1 11 | REG3 : 2 12 | # REG4_RO : 3 13 | REG5_WO : 5 14 | -------------------------------------------------------------------------------- /tests/test_SimI2c.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | import unittest 9 | import os 10 | 11 | from basil.dut import Dut 12 | from basil.utils.sim.utils import cocotb_compile_and_run, cocotb_compile_clean 13 | 14 | cnfg_yaml = """ 15 | transfer_layer: 16 | - name : INTF 17 | type : SiSim 18 | init: 19 | host : localhost 20 | port : 12345 21 | 22 | hw_drivers: 23 | 24 | - name : i2c 25 | type : i2c 26 | interface : INTF 27 | base_addr : 0x1000 28 | 29 | registers: 30 | 31 | - name : CONTROL 32 | type : StdRegister 33 | hw_driver : i2c 34 | size : 8 35 | fields: 36 | - name : OUT 37 | size : 8 38 | offset : 7 39 | """ 40 | 41 | 42 | class TestSimS2C(unittest.TestCase): 43 | def setUp(self): 44 | cocotb_compile_and_run([os.path.join(os.path.dirname(__file__), 'test_SimI2c.v')]) 45 | 46 | self.chip = Dut(cnfg_yaml) 47 | self.chip.init() 48 | 49 | def test_i2c(self): 50 | data = [0x85, 0x81, 0xa5, 0x91] 51 | self.chip['i2c'].write(0x92, data) 52 | 53 | ret = self.chip['i2c'].get_data(4) 54 | self.assertEqual(ret.tolist(), data) 55 | 56 | self.chip['i2c'].write(0x92, data[0:1]) 57 | 58 | self.chip['i2c'].set_data([0, 1, 2, 3]) 59 | 60 | ret = self.chip['i2c'].read(0x92, 3) 61 | self.assertEqual(ret.tolist(), data[1:]) 62 | 63 | self.chip['i2c'].write(0x92, range(16)) 64 | self.chip['i2c'].write(0x92, [0]) 65 | ret = self.chip['i2c'].read(0x92, 15) 66 | self.assertEqual(ret.tolist(), list(range(16))[1:]) 67 | 68 | # no ack/no such device 69 | exept = False 70 | try: 71 | self.chip['i2c'].write(0x55, data) 72 | except IOError: 73 | exept = True 74 | 75 | self.assertEqual(exept, True) 76 | 77 | def tearDown(self): 78 | self.chip.close() # let it close connection and stop simulator 79 | cocotb_compile_clean() 80 | 81 | 82 | if __name__ == '__main__': 83 | unittest.main() 84 | -------------------------------------------------------------------------------- /tests/test_SimSCPIFormatting.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import yaml 3 | import os 4 | from basil.dut import Dut 5 | 6 | k2410def_yaml = os.path.join(os.path.dirname(__file__), "formatting.yaml") 7 | 8 | cnfg_yaml = f''' 9 | transfer_layer: 10 | - name : Visa 11 | type : Visa 12 | init : 13 | resource_name : ASRL1::INSTR 14 | read_termination : "\\n" 15 | write_termination : "\\r\\n" 16 | backend : "{k2410def_yaml}@sim" 17 | 18 | hw_drivers: 19 | - name : Sourcemeter 20 | type : scpi 21 | interface : Visa 22 | init : 23 | device : Keithley 2410 24 | enable_formatting: true 25 | ''' 26 | 27 | 28 | class TestSimScpi(unittest.TestCase): 29 | 30 | def setUp(self): 31 | self.cfg = yaml.safe_load(cnfg_yaml) 32 | self.device = Dut(self.cfg) 33 | self.device.init() 34 | # Check that formatting is present 35 | self.assertTrue(self.device['Sourcemeter'].has_formatting) 36 | # Check that formatting is enabled after init 37 | self.assertTrue(self.device['Sourcemeter'].formatting_enabled) 38 | 39 | def tearDown(self): 40 | self.device.close() 41 | 42 | def test_read_voltage(self): 43 | voltage = self.device['Sourcemeter'].get_voltage() 44 | self.assertEqual(voltage, '-5.124E-05') 45 | 46 | def test_read_voltage_unformatted(self): 47 | # Check that formatting is enabled 48 | self.assertTrue(self.device['Sourcemeter'].formatting_enabled) 49 | # Disable formatting 50 | self.device['Sourcemeter'].disable_formatting() 51 | voltage = self.device['Sourcemeter'].get_voltage().split(',')[0] 52 | self.assertEqual(voltage, '-5.124E-05') 53 | # Check that formatting is disabled 54 | self.assertFalse(self.device['Sourcemeter'].formatting_enabled) 55 | # Enable formatting 56 | self.device['Sourcemeter'].enable_formatting() 57 | 58 | 59 | if __name__ == '__main__': 60 | unittest.main() 61 | -------------------------------------------------------------------------------- /tests/test_SimScpi.py: -------------------------------------------------------------------------------- 1 | # 2 | # ------------------------------------------------------------ 3 | # Copyright (c) All rights reserved 4 | # SiLab, Institute of Physics, University of Bonn 5 | # ------------------------------------------------------------ 6 | # 7 | 8 | import unittest 9 | import yaml 10 | 11 | from basil.dut import Dut 12 | 13 | cnfg_yaml = ''' 14 | transfer_layer: 15 | - name : Visa 16 | type : Visa 17 | init : 18 | resource_name : ASRL1::INSTR 19 | read_termination : "\\n" 20 | write_termination : "\\r\\n" 21 | backend : "@sim" 22 | 23 | hw_drivers: 24 | - name : Pulser 25 | type : scpi 26 | interface : Visa 27 | init : 28 | device : scpi sim device 29 | ''' 30 | 31 | 32 | class TestSimScpi(unittest.TestCase): 33 | 34 | def setUp(self): 35 | self.cfg = yaml.safe_load(cnfg_yaml) 36 | self.device = Dut(self.cfg) 37 | self.device.init() 38 | 39 | def tearDown(self): 40 | self.device.close() 41 | 42 | def test_read(self): 43 | self.assertEqual(self.device['Pulser'].get_frequency(), '100.00') 44 | 45 | def test_write(self): 46 | self.device['Pulser'].set_on(1) 47 | self.assertEqual(self.device['Pulser'].get_on(), 'OK') 48 | 49 | def test_invalid_parameter(self): 50 | with self.assertRaises(ValueError): 51 | self.device['Pulser'].set_on(1, 2) 52 | 53 | def test_exception(self): 54 | with self.assertRaises(ValueError): 55 | self.device['Pulser'].unknown_function() 56 | 57 | 58 | if __name__ == '__main__': 59 | unittest.main() 60 | --------------------------------------------------------------------------------