[subexp-daq] Question on COUNTER_DIFF in crate.c

Hans Toshihide Törnqvist hans.tornqvist at chalmers.se
Fri Feb 16 15:39:42 CET 2024


Dear Günter,

On 2024-02-16 13:50, Weber, Guenter Dr. wrote:
> 
> Dear Håkan,
> 
> thank you. This explanation makes some sense.
> 
> Could you also explain the concept of "shadow module". What is it good for?

It's rather "shadow readout mode". The idea is to read data from a 
module continuously in parallel to conversion and buffering, instead of 
performing every task of acquisition in sequence where every task has to 
wait for all the others to finish.

The advantage is that this can significantly reduce the time where a 
module is unable to convert and buffer signals.

The potential disadvantage is that the data traffic on for example a VME 
backplane could induce noise in the analog measurement.

The non-shadow mode is the default and best tested mode, due to present 
module support, cooperation of modules in experiments, and historical 
reasons.

> Also I would like to point out that the implementation of readout_dt for 
> the V560 module that we used as a reference looks weird to us:
> 
> uint32_t
> caen_v560_readout_dt(structCrate*a_crate, structModule*a_module)
> {
>      (void)a_crate;
> LOGF(spam)(LOGL, NAME" readout_dt {");
> a_module->event_counter.value++;
> LOGF(spam)(LOGL, NAME" readout_dt(ctr=0x%08x) }",
> a_module->event_counter.value);
> return0;
> }
> 
> Here the counter is incremented every time the module is 'touched' by 
> the readout_dt function. In the loop that starts at line 1240 in crate.c 
> the function readout_dt is executed for the module until the test around 
> line 1270 is passed or the timeout around line 1280 happens. Thus an 
> initial mismatch between the (software) counter of module V560 and the 
> crate that prevents the loop from being existed at the first trial will 
> grow steadily as the module is accessed via readout_dt many, many times 
> until it runs into the timeout. What is this good for?

Nurdlib avoids resetting counters and instead latches and saves counter 
values (e.g. soft crate counters and module counters) during dead-time 
when counters should not change. After the first event, both counters 
must have incremented by 1. Any particular start value such as 0 or 1 
has no deeper meaning, it's the progression that is important.

Resetting tends to carry with it the idea of "after a reset, or setting 
something to 0, everything is fine". It moves the focus away from 
getting the complete logic correct, at least that is the feeling I get.

Now, to actually discuss your case :)
Are you seeing that the mismatch between the crate counter and the v560 
keeps increasing for new events? Or do you have such a problem with the 
dummy module? (I still did not find the slot to look at it...)

> To my (current) understanding it is pointless to try to mimic the 
> function of a true hardware counter within the module by a counter that 
> only exists in software. The better way would be to tell crate.c that 
> this module does not have such a counter so that the check is pointless. 
> Is this understanding correct? And if yes, how can I tell NURDLIB to 
> skip this check?

A software counter would be a consistency check of the implementation, 
but you are correct that it has little to do with the signals that are 
recorded. One can send the same random signal to different modules and 
verify correlation at some point after digitisation, and definitely no 
later than online monitoring while data is recorded.

I think it's possible to give the module counter a mask of 0. The 
counter check should in principle be:

mask = ctr_a_mask & ctr_b_mask;
ctr_a = ctr_a_raw - ctr_a_latch;
ctr_b = ctr_b_raw - ctr_b_latch;
if ( (ctr_a & mask) == (ctr_b & mask) ) { all good! }

If either mask is 0 the condition will always pass. There is maybe a 
better way to make this clear than built into the masking, but I would 
say that using a module without any kind of sync-check in 
event-per-event analysis is overall dangerous...

Hope that helps!

Best regards,
Hans

> Best greetings
> 
> Günter
> 
> 
> 
> ------------------------------------------------------------------------
> *Von:* subexp-daq <subexp-daq-bounces at lists.chalmers.se> im Auftrag von 
> Håkan T Johansson <f96hajo at chalmers.se>
> *Gesendet:* Freitag, 16. Februar 2024 13:25:59
> *An:* Discuss use of Nurdlib, TRLO II, drasi and UCESB.
> *Betreff:* Re: [subexp-daq] Question on COUNTER_DIFF in crate.c
> 
> Dear Günter,
> 
> I think Hans might have to correct me.
> 
> This is not exactly what this code does, but typically the modules have a
> trigger/event counter, which is incremented for each gate/common signal
> they receive on the front-panel.
> 
> When the readout is event-by-event, these counters are checked strictly by
> nurdlib, in order to detect cabling issues, double-triggers and so on.
> This is especially important for modules that have multi-event buffers,
> that otherwise easily can become desynchronised.  (It takes of course some
> time to read these counters, which contributes to the overall deadtime.
> But the amount of times this has 'saved' data-taking by detecting issues
> early make it very worthwhile.)
> 
> 
> What the code you refer to is doing is I think 'abusing' this a bit.
> There is typically some time (order of us) between the trigger, and when
> the signals have been digitised and the data becomes available.  Often,
> those counters are only updated after that is the case.  To me it looks
> like this function use the counters (which we anyhow want to check) to
> wait for the modules to have finished converting one event.
> 
> 
> Best regards,
> Håkan
> 
> 
> 
> 
> 
> On Fri, 16 Feb 2024, Weber, Guenter Dr. wrote:
> 
>> 
>> Dear friends,
>> 
>> 
>> we are now trying to add a new module into NURDLIB. At the beginning, we just want to have a 'software version' of the module, so no
>> hardware involved yet.
>> 
>> 
>> We are stuck with the following code in crate.c (line 1262 and following):
>> 
>> 
>>             diff_module = COUNTER_DIFF(*module->crate_counter,
>>                 module->event_counter, module->this_minus_crate);
>>             /* TODO: Clean this. */
>>             shadow_counter.value =
>>                 module->shadow.data_counter_value;
>>             shadow_counter.mask = module->event_counter.mask;
>>             diff_shadow = COUNTER_DIFF(*module->crate_counter,
>>                 shadow_counter, module->this_minus_crate);
>> 
>> 
>> As we understand, the idea here is to check with a call of readout_dt if the module's internal counter agrees with the counter of the
>> crate for the given module. Basicly when the crate thinks it has accessed the module n times, the module should report the same number of
>> access attempts. Is this understanding correct?
>> 
>> 
>> If yes, how exactly should the module increment it's internal counter? If this is done on readout_dt, a mismatch between the crate and the
>> internal counter occurs as soon as we stop the aquisition.
>> 
>> 
>> I can explain in more details, but maybe first you can explain to us what the whole idea behind this check is? To us it looks like also
>> the dummy module implementation will have problems with it.
>> 
>> 
>> 
>> 
>> Thank you very much!
>> 
>> 
>> 
>> 
>> Best greetings
>> 
>> Günter
>> 
>> 
>> 
>>
> 


More information about the subexp-daq mailing list