CTB frequency rounding, CTB frequency measurement, CTB frequency units (#1423)

* round CTB clocks to next closest possible value, added freq measurement

* added time for firmware to measrue actual value after frequency change

* add check for backwards compatibility

* change CTB and XCTB clock values to MHz, TODO: units and validation errors

* changed runclk command to use units and float, TODO: dbit, adcclk, why is everything called StringTo ?

* do the same for dbit and adcclk

* added tolerance to exptime, fixed test

* update default values in server defs

* added virtual check in Altera_PLL, update testcases

* change python and pyctbgui to accept and return floating point MHz

* update help and comments

* Dev/ctb clocks fix (#1434)

* introduced new type Hz, typetraits, String conversions, command generation (not yet generated)

* incorrect unit typo

* cmd generation and compiles

* default to MHz, removed space between units for consistency with timers, min and max checks for clks

* in python, but need to change the default to Hz again for clean code and intuition

* allow ints, doubles, implicit conversions

* dont allow raw ints, doubles and implicit conversions

* fixed tests

* added operators for Hz in python

* fix test for min clk for xilinx ctb

* fix test

* fix python tests

* fixed xilinx period and default clks

* test fix

* removed the 3 clock cycle check for ctb and implemented properly the max adc clk frq for altera ctb

* removing 3 clock cycle code from xilinx as well

* formatting

* loadpattern before 3 clk cycles code

* actualtime and measurement time to be implemented in 100ns already in fw

* fix tests

* pyzmq dependency forthe tests

* fixed pyctbgui for freq

* insert tolerance check again

* also added tolerance check for patwaittime

* formatting

* minor: rounding test

* removed Rep redundant in ToString for freq

* intro frequency unit enums, removed unnecessary template behavior for ToString with freq unit, switching from parsing string unit argument to the enum argument for ToString, adding parsing string to unit at CLI boundary

* minor, and binaries

* minor, default clk vals are 0 but set up at detector setup

* get frequency only for that unit

* tolerance process

* missed in previous commit

* some more changes to exptime and validations

* ctb is probably done

* periodleft and delayleft

* fixed xilinx freq conv as well

* fixed m3 bug, binaries

* xilinx: setup also done in stop server so that the clk is not 0

* missed a test marker

* binaries in

* review fixes, simpler validation of timers in ctb and xilinx ctb

* typo fix

* format

* fix tests

---------

Co-authored-by: Martin Mueller <martin.mueller@psi.ch>
Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
This commit is contained in:
Martin Mueller
2026-05-06 15:52:13 +02:00
committed by GitHub
co-authored by muelle_m1 maliakal_d
parent bb1a73d718
commit 0837de2a5a
57 changed files with 2239 additions and 706 deletions
@@ -11,7 +11,7 @@
#ifdef MYTHEN3D
extern enum TLogLevel trimmingPrint;
extern uint32_t clkDivider[];
extern int getFrequency(enum CLKINDEX ind);
#endif
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
extern uint32_t clkFrequency[];
@@ -277,6 +277,14 @@ int validate_getPatternWaitClocksAndInterval(char *message, int level,
*waittime = getPatternWaitClocks(level);
} else {
*waittime = getPatternWaitInterval(level);
if (*waittime == (uint64_t)-1) {
sprintf(
message,
"Cannot get pattern wait interval for level %d. runclk is 0.\n",
level);
LOG(logERROR, (message));
return FAIL;
}
}
return OK;
}
@@ -297,17 +305,17 @@ uint64_t getPatternWaitClocks(int level) {
uint64_t getPatternWaitInterval(int level) {
uint64_t numClocks = getPatternWaitClocks(level);
int runclk = 0;
uint32_t runclk = 0;
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
runclk = clkFrequency[RUN_CLK];
#elif MYTHEN3D
runclk = clkDivider[SYSTEM_C0];
runclk = getFrequency(SYSTEM_C0);
#endif
if (runclk == 0) {
LOG(logERROR, ("runclk is 0. Cannot divide by 0. Returning -1.\n"));
return -1;
}
return numClocks / (NS_TO_CLK_CYCLE * runclk);
return clocks_to_ns(numClocks, runclk);
}
int validate_setPatternWaitClocksAndInterval(char *message, int level,
@@ -321,27 +329,50 @@ int validate_setPatternWaitClocksAndInterval(char *message, int level,
return FAIL;
}
uint64_t retval = 0;
if (clocks) {
setPatternWaitClocks(level, waittime);
// validate result
retval = getPatternWaitClocks(level);
uint64_t retval = getPatternWaitClocks(level);
LOG(logDEBUG1, ("Pattern wait time in clocks (level:%d) retval: %d\n",
level, (long long int)retval));
} else {
setPatternWaitInterval(level, waittime);
// validate result
retval = getPatternWaitInterval(level);
LOG(logDEBUG1, ("Pattern wait time (level:%d) retval: %d\n", level,
(long long int)retval));
int ret = OK;
char mode[128];
memset(mode, 0, sizeof(mode));
sprintf(mode, "set pattern Loop %d wait time (clocks)", level);
validate64(&ret, message, waittime, retval, mode, DEC);
return ret;
}
int ret = OK;
char mode[128];
memset(mode, 0, sizeof(mode));
sprintf(mode, "set pattern Loop %d wait time", level);
validate64(&ret, message, waittime, retval, mode, DEC);
return ret;
// interval
setPatternWaitInterval(level, waittime);
// validate
uint32_t runclk = 0;
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
runclk = clkFrequency[RUN_CLK];
#elif MYTHEN3D
runclk = getFrequency(SYSTEM_C0);
#endif
uint64_t arg_clocks = ns_to_clocks(waittime, runclk);
uint64_t retval_clocks = getPatternWaitClocks(level);
if (arg_clocks != retval_clocks) {
sprintf(message,
"Failed to set pattern loop %d wait interval. Could not set "
"number of clocks to %lld, read %lld\n",
level, (long long int)arg_clocks, (long long int)retval_clocks);
LOG(logERROR, (message));
return FAIL;
}
// log rounding if any
uint64_t retval = getPatternWaitInterval(level);
if (waittime != retval) {
LOG(logWARNING, ("Rounding to %lld ns due to clock frequency\n",
(long long int)retval));
}
return OK;
}
void setPatternWaitClocks(int level, uint64_t t) {
@@ -375,13 +406,13 @@ void setPatternWaitInterval(int level, uint64_t t) {
#endif
("Setting Pattern Wait Time (level:%d) :%lld ns\n", level,
(long long int)t));
int runclk = 0;
uint32_t runclk = 0;
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
runclk = clkFrequency[RUN_CLK];
#elif MYTHEN3D
runclk = clkDivider[SYSTEM_C0];
runclk = getFrequency(SYSTEM_C0);
#endif
uint64_t numClocks = t * (NS_TO_CLK_CYCLE * runclk);
uint64_t numClocks = ns_to_clocks(t, runclk);
setPatternWaitClocks(level, numClocks);
}