Code and Notes
- https://gitlab.cern.ch/ehazen/l0mdt-daq-felix (submodule)
- https://github.com/eshazen/picoblaze-ebus (top level test with picoblaze on basys3)
Work Log
2022-06-20
Start writing daq_unit_tb
but not finished. Push to Git.
2022-06-07
Next step is to build a simulation tb for daq_unit
which contains the random generators and get it working. That way the sim can be compared with the basys3 hardware version.
2022-03-10
Working on picoblaze-ebus
top-level with l0mdt-daq-felix
submodule. Address table:
00000000 - GPIO/control 10000000 - rate meter for test \ these are connected together 0 - rate generator (at 20000000) 1 - MDT trigger rate 2 - MDT hit rate 3 - N/A 20000000 - rate generator for test / for basic checking, unrelated to L0MDT 30000000 - FELIX readout GPIO: Control regs 0 - trigger rate random threshold [1] 1 - hit rate random threshold [2] 2 - n/a 3 - n/a Status regs 4 - switches 5 - n/a Action regs 100 - bit 1: OcR bit 2: EcR Soft reset: output to 10, so command "O 10 0" FELIX: Address Read Write Notes 0..7 Data N/A 32-bit chunks, low-endian 8 "beef" + wr_addr wr_addr 10 bits 9 "cafe" + rd_addr rd_addr 10 bits A wr_ena wr_ena bit 0 only [1] - <value>/2**32 is probability of trigger in one BX [2] - <value>/2**32 is probability of tube hit in one clock Clock period is 100MHz for testing, BX period is 1/8 of that or 1/12.5MHz
2022-02-13
Andrew says to ignore ttc-core
submodule.
Need to figure out where to put in the TTC generator. Currently there is a ttc_commands
record originating in top_hal.vhd
originating in felix_decoder
. So for now we should make a ttc_commands
record which is of type l0mdt_ttc_rt
.
subtype bcid_t is unsigned(12-1 downto 0); subtype evid_t is unsigned(32-1 downto 0); subtype orid_t is unsigned(32-1 downto 0); type l0mdt_ttc_rt is record bcr : std_logic; ocr : std_logic; ecr : std_logic; l0a : std_logic; l1a : std_logic; bcid : bcid_t; evid : evid_t; orid : orid_t; end record l0mdt_ttc_rt;
Looking at the clocking. In top_clocking
there is framework_mmcm
which outputs clk320
and clk40
.
There's a record l0mdt_control_rt
as:
type l0mdt_control_rt is record clk : std_logic; rst : std_logic; bx : std_logic; end record l0mdt_control_rt;
The strobe bx
is generated by an instance of clock_strobe
in top_hal.vhd
.
2022-02-07
Working on random hit/trig generator. VHDL entity trig_gen.vhd generates random triggers at specified rate. Currently it generates one urand per clock at 100MHz, which requires two DSP48 in an Artix-7. Basys3 test project created and tested.
Also working on synthesizable ttc_eric.vhd which generates global TTC signals, including a map of LHC bunch structure.
Thinking about generating some semi-legit looking random MDT data. Here's the data format as of now:
- tdcpolmux2tar: - data_valid: [type : logic] - tdc: [type : tdc] # 1 - chanid: [type : unsigned , length : TDC_CHANID_LEN] # 5 - edgemode: [type : logic , length : TDC_EDGEMODE_LEN] # 2 - coarsetime: [type : unsigned , length : TDC_COARSETIME_LEN] # 12 - finetime: [type : unsigned , length : TDC_FINETIME_LEN] # 5 - pulsewidth: [type : unsigned , length : TDC_PULSEWIDTH_LEN] # 8 - csmid: [type : unsigned , length : TDCPOLMUX2TAR_CSMID_LEN] # 4 - tdcid: [type : unsigned , length : TDCPOLMUX2TAR_TDCID_LEN] # 5
2022-01-21
Thoughts on HW testing: Create a programmable random trigger/hit generator and simple control interface (picoblaze?) Build for some eval board or even a CM and test.
2022-01-17
Seems to be working, with a few caveats. For an 80MHz hit rate, 1MHz trigger rate, 32 WM. Compare against output of simulation check_daq.pl. There are a few errors; all seem to be off-by-one at the extreme end of the matching window. Not sure this is that important.
2022-01-11
First version synthesized. No constraints. 32 WM. Utilization:
This compares favorably with blackboard estimate! I've created a constraint file and trying to build with 320MHz clock now.
2022-01-07
Working on "toy" DAQ for resource comparison. Here's a detailed specification :)
Assumptions:
- One pipeline hit stream stream (aka PTSD) at ~320MHz feeds one FELIX fiber.
- Each "DAQ block" handles one such stream/fiber and operates independently of all others
- Inputs:
- Outputs:
- 230 bit FELIX data at pipeline clock, data valid
- Monitoring
- Various random error signals come out and could be connected somewhere
Given the first assumption the DAQ is conceptually very simple. Here are the VHDL entities:
wm
- single window match with FIFO
dispatch
- group of window matchers. Dispatcher for triggers, mux for output
format
- output formatter. Currently includes trigger FIFO. Outputs header, data, trailer words to FELIX with a few hits packed in each data word.
daq
- top level, includes one
dispatch
and oneformat
.
'2021-12-15
Investigating PicoBlaze? speed... if one would run at 320MHz it could be a useful tool for DAQ work.
Creating a simple test design in a xcvu3p-ffvc1517-1-i
device. Just the picoblaze, very short program,
and 4 each input and output ports decoded with 1 address bit per port.
Configured with 100MHz clock input, MMCM synthesizing 320MHz. Seems to have worked. Trying 400MHz. Nope. For 320MHz the reported WNS is 0.095ns. Ouch!
2021-12-01
Looking at the DAQ.
The submodule with the code is here: https://gitlab.cern.ch/tcpaiva/atlas-daq-core
It is included here: https://gitlab.cern.ch/atlas-tdaq-phase2-l0mdt-electronics/l0mdt-hdl-design/-/tree/devel/UserLogic/daq
Here is the hierarchy resulting from loading all the VHDL files into Vivado:
Top level is at UserLogic/ult/src/ult_daq.vhd
. Entity daq
takes as input arrays for each station (I, M, O, X) an mdt_polmux_bus_avt
which consists of tdcpolmux2tar_rt
which have csmid
, tdcid
and tdc_rt
.
- tdcpolmux2tar: - data_valid: [type : logic] - tdc: [type : tdc] # 1 - chanid: [type : unsigned , length : TDC_CHANID_LEN] # 5 - edgemode: [type : logic , length : TDC_EDGEMODE_LEN] # 2 - coarsetime: [type : unsigned , length : TDC_COARSETIME_LEN] # 12 - finetime: [type : unsigned , length : TDC_FINETIME_LEN] # 5 - pulsewidth: [type : unsigned , length : TDC_PULSEWIDTH_LEN] # 8 - csmid: [type : unsigned , length : TDCPOLMUX2TAR_CSMID_LEN] # 4 - tdcid: [type : unsigned , length : TDCPOLMUX2TAR_TDCID_LEN] # 5 # Total 42
Here we see loops over inner_tdc_hits
which is an array of 6 "streams" of input data (6x POLMUX presumably).
Output is felix_stream_bus_avt
, defined in {shared/types/common_types_pkg.vhd
as an array of felix_data_t
plus valid
. For some reason the felix_data_t
is 65 bits wide.
All the mess is in daq_branch.vhd
in UserLogic/daq/daq-core/src
.
This is very confusing code which Thiago is going to explain to us :)
Here it goes:
in UserLogic/ult/src/ult_daq.vhd: daq_streams(j) <= outputify( inner_er.o.f2e_bus(j)) (inner_er is daq_branch_ert) daq_branch_t is array of daq_stream_rt daq_stream_rt is (valid, bcid, daq_stream_data_t)
I give up!