mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-01-22 17:57:17 +01:00
Pattern unification & Matterhorn Changes (#1303)
* update ctb regDefs, included fill level of adc, transceiver and DBit fifos, added enable registers for cont. readout
* fix fifo fill level range bug
* updated ctb RegDefs, increased size of fifo fill level register
* added register to read the firmware git hash
* ctb: added altchip_id read register
* start with unification of pattern machinery for xctb, ctb, mythen
* udate addrs for d-server internal matterhorn startup
* update xctb reg defs
* move pattern loopdef start
* added zero trimbits to matterhorn config
* Revert "added zero trimbits to matterhorn config"
This reverts commit 7c347badd5.
* added adjustable clocks on Xilinx-CTB
* added support for fractional dividers of runclk
* XCTB: make frequencies adjustable from python gui
* update docs
* added support for patternstart command to XCTB
* XCTB: map pattern_ram directly into memory, removed rw strobe
* refactor Mythen pattern control addresses
* test altera ctb with common addresses, removed ifdefs
* change ordering of regdefs
* updated python help for dbitclk, adcclk and runclk (khz)
* xilinx: moved the wait for firmware to measure the actual frequency to the server side and removed it in the pyctbgui side
* will not be anymore in developer branch
* make format (exception RegisterDefs.h), rewrite XILINX PLL to have less consstants in the code
* bug: mixing && for &
---------
Co-authored-by: Martin Mueller <martin.mueller@psi.ch>
Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
This commit is contained in:
200
slsDetectorServers/slsDetectorServer/src/XILINX_PLL.c
Normal file
200
slsDetectorServers/slsDetectorServer/src/XILINX_PLL.c
Normal file
@@ -0,0 +1,200 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "XILINX_PLL.h"
|
||||
#include "arm64.h"
|
||||
#include "clogger.h"
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// https://docs.amd.com/r/en-US/pg065-clk-wiz/Register-Space (simplified, we
|
||||
// leave some things away)
|
||||
|
||||
// clang-format off
|
||||
#define XILINX_PLL_INPUT_FREQ (100000) // 100 MHz
|
||||
#define XILINX_PLL_MIN_FREQ (10000)
|
||||
#define XILINX_PLL_MAX_FREQ (250000)
|
||||
#define XILINX_PLL_MAX_CLK_DIV (256)
|
||||
#define XILINX_PLL_NUM_CLKS (7)
|
||||
#define XILINX_PLL_MAX_NUM_CLKS_FOR_GET (3)
|
||||
#define XILINX_PLL_STEP_SIZE (125)
|
||||
#define XILINX_PLL_HALF_STEP_SIZE (62)
|
||||
|
||||
#define XILINX_PLL_BASE_ADDR (0x0)
|
||||
#define XILINX_PLL_MEASURE_BASE_ADDR0 (0x1000) // added externally, not part of CLKWIZ core for clks 0 and 1
|
||||
#define XILINX_PLL_MEASURE_BASE_ADDR0_MAX_CLKS (2)
|
||||
#define XILINX_PLL_MEASURE_BASE_ADDR1 (0x2000) // for clks 2 to 6
|
||||
#define XILINX_PLL_MEASURE_WIDTH (8) // per clock
|
||||
|
||||
#define XILINX_PLL_RESET_REG (0x000)
|
||||
#define XILINX_PLL_RESET_VAL (0xA)
|
||||
|
||||
#define XILINX_PLL_STATUS_REG (0x004)
|
||||
#define XILINX_PLL_STATUS_LOCKED_OFST (0)
|
||||
#define XILINX_PLL_STATUS_LOCKED_MSK (0x00000001 << XILINX_PLL_STATUS_LOCKED_OFST)
|
||||
|
||||
#define XILINX_PLL_CLKCONFIG_REG (XILINX_PLL_BASE_ADDR + 0x200)
|
||||
#define XILINX_PLL_DIVCLK_DIVIDE_OFST (0)
|
||||
#define XILINX_PLL_DIVCLK_DIVIDE_MSK (0x000000FF << XILINX_PLL_DIVCLK_DIVIDE_OFST)
|
||||
#define XILINX_PLL_CLKFBOUT_MULT_OFST (8)
|
||||
#define XILINX_PLL_CLKFBOUT_MULT_MSK (0x000000FF << XILINX_PLL_CLKFBOUT_MULT_OFST)
|
||||
#define XILINX_PLL_CLKFBOUT_FRAC_OFST (16)
|
||||
#define XILINX_PLL_CLKFBOUT_FRAC_MSK (0x000003FF << XILINX_PLL_CLKFBOUT_FRAC_OFST)
|
||||
// The value from 0 to 875 representing the fractional multiplied by 1000
|
||||
#define XILINX_PLL_CLKFBOUT_FRAC_MAX_VAL (875)
|
||||
|
||||
|
||||
#define XILINX_PLL_CLKCONFIG_BASE_ADDR (XILINX_PLL_BASE_ADDR + 0x208)
|
||||
#define XILINX_PLL_CLKCONFIG_WIDTH (3 * 4) // per clock (7 clocks)
|
||||
|
||||
#define XILINX_PLL_CLK_DIV_REG_OFST (0)
|
||||
#define XILINX_PLL_CLK_DIV_DIVIDE_OFST (0)
|
||||
#define XILINX_PLL_CLK_DIV_DIVIDE_MSK (0x000000FF << XILINX_PLL_CLK_DIV_DIVIDE_OFST)
|
||||
#define XILINX_PLL_CLK_DIV_FRAC_OFST (8) // works on IDX 0 only
|
||||
#define XILINX_PLL_CLK_DIV_FRAC_MSK (0x000003FF << XILINX_PLL_CLK_DIV_FRAC_OFST)
|
||||
|
||||
#define XILINX_PLL_CLK_PHASE_REG_OFST (4) // signed num for +/- phase
|
||||
#define XILINX_PLL_CLK_PHASE_OFST (0)
|
||||
#define XILINX_PLL_CLK_PHASE_MSK (0x0000FFFF << XILINX_PLL_CLK_PHASE_OFST)
|
||||
|
||||
#define XILINX_PLL_CLK_DUTY_REG_OFST (8) // (in %) * 1000
|
||||
#define XILINX_PLL_CLK_DUTY_OFST (0)
|
||||
#define XILINX_PLL_CLK_DUTY_MSK (0x0000FFFF << XILINX_PLL_CLK_DUTY_OFST)
|
||||
|
||||
|
||||
|
||||
#define XILINX_PLL_LOAD_REG (0x25C)
|
||||
#define XILINX_PLL_LOAD_RECONFIGURE_OFST (0) // load and reconfigure state machine
|
||||
#define XILINX_PLL_LOAD_RECONFIGURE_MSK (0x00000001 << XILINX_PLL_LOAD_RECONFIGURE_OFST)
|
||||
#define XILINX_PLL_LOAD_FROM_REGS_OFST (1) // 0 for default values as compiled into firmware
|
||||
#define XILINX_PLL_LOAD_FROM_REGS_MSK (0x00000001 << XILINX_PLL_LOAD_FROM_REGS_OFST)
|
||||
|
||||
// clang-format on
|
||||
|
||||
// freq in kHz !!
|
||||
void XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq) {
|
||||
if (clk_index >= XILINX_PLL_NUM_CLKS) {
|
||||
LOG(logERROR, ("XILINX_PLL: Invalid clock index %d\n", clk_index));
|
||||
return;
|
||||
}
|
||||
if (freq < XILINX_PLL_MIN_FREQ || freq > XILINX_PLL_MAX_FREQ) {
|
||||
LOG(logERROR, ("XILINX_PLL: Frequency %d kHz is out of range\n", freq));
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate base clock frequency
|
||||
uint32_t global_reg = bus_r_csp2(XILINX_PLL_CLKCONFIG_REG);
|
||||
#ifdef VIRTUAL
|
||||
global_reg = 3073;
|
||||
#endif
|
||||
uint32_t clkfbout_mult = ((global_reg & XILINX_PLL_CLKFBOUT_MULT_MSK) >>
|
||||
XILINX_PLL_CLKFBOUT_MULT_OFST);
|
||||
uint32_t clkfbout_frac = ((global_reg & XILINX_PLL_CLKFBOUT_FRAC_MSK) >>
|
||||
XILINX_PLL_CLKFBOUT_FRAC_OFST);
|
||||
uint32_t divclk_divide = ((global_reg & XILINX_PLL_DIVCLK_DIVIDE_MSK) >>
|
||||
XILINX_PLL_DIVCLK_DIVIDE_OFST);
|
||||
uint32_t base_clk_freq = clkfbout_mult * XILINX_PLL_INPUT_FREQ;
|
||||
base_clk_freq += (clkfbout_frac * XILINX_PLL_INPUT_FREQ /
|
||||
XILINX_PLL_CLKFBOUT_FRAC_MAX_VAL);
|
||||
base_clk_freq /= divclk_divide;
|
||||
|
||||
// calcualte clock divider
|
||||
uint32_t clk_div = base_clk_freq / freq;
|
||||
if (clk_div < 1 || clk_div > XILINX_PLL_MAX_CLK_DIV) {
|
||||
LOG(logERROR,
|
||||
("XILINX_PLL: Invalid clock divider, need to change base clock\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t clk_div_frac = 0;
|
||||
// the first clock supports fractional division, increase the precision for
|
||||
// that one fractional divide is not allowed in fixed or dynamic phase shift
|
||||
// mode !!!!
|
||||
if (clk_index == 0) {
|
||||
float clk_div_frac_f =
|
||||
(float)base_clk_freq / freq - clk_div; // eg. 2.333 => 0.333
|
||||
clk_div_frac = (uint32_t)round(clk_div_frac_f * 1000); // 0.333 => 333
|
||||
clk_div_frac = ((clk_div_frac + XILINX_PLL_HALF_STEP_SIZE) /
|
||||
XILINX_PLL_STEP_SIZE) *
|
||||
XILINX_PLL_STEP_SIZE; // round to multiples of step size,
|
||||
// 333 = > 375
|
||||
if (clk_div_frac == 1000) {
|
||||
clk_div_frac = 0;
|
||||
clk_div++;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE, ("XILINX_PLL: Setting clock divider to %u.%u\n", clk_div,
|
||||
clk_div_frac));
|
||||
uint32_t clk_addr = XILINX_PLL_CLKCONFIG_BASE_ADDR +
|
||||
clk_index * XILINX_PLL_CLKCONFIG_WIDTH +
|
||||
XILINX_PLL_CLK_DIV_REG_OFST;
|
||||
uint32_t clk_config_val = ((clk_div << XILINX_PLL_CLK_DIV_DIVIDE_OFST) &
|
||||
XILINX_PLL_CLK_DIV_DIVIDE_MSK) |
|
||||
((clk_div_frac << XILINX_PLL_CLK_DIV_FRAC_OFST) &
|
||||
XILINX_PLL_CLK_DIV_FRAC_MSK);
|
||||
|
||||
bus_w_csp2(clk_addr, clk_config_val);
|
||||
XILINX_PLL_load();
|
||||
XILINX_PLL_waitForLock();
|
||||
|
||||
// wait for firmware to measure the actual frequency
|
||||
usleep(2 * 1000 * 1000);
|
||||
}
|
||||
|
||||
uint32_t XILINX_PLL_getFrequency(uint32_t clk_index) {
|
||||
if (clk_index >= XILINX_PLL_NUM_CLKS) {
|
||||
LOG(logERROR, ("XILINX_PLL: Invalid clock index %d\n", clk_index));
|
||||
return 0;
|
||||
}
|
||||
if (clk_index > XILINX_PLL_MAX_NUM_CLKS_FOR_GET) {
|
||||
LOG(logERROR,
|
||||
("XILINX_PLL: get frequency not implemented for this clock %d\n",
|
||||
clk_index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t base_addr = XILINX_PLL_MEASURE_BASE_ADDR0;
|
||||
if (clk_index >= XILINX_PLL_MEASURE_BASE_ADDR0_MAX_CLKS) {
|
||||
clk_index -= XILINX_PLL_MEASURE_BASE_ADDR0_MAX_CLKS;
|
||||
base_addr = XILINX_PLL_MEASURE_BASE_ADDR1;
|
||||
}
|
||||
uint32_t addr = base_addr + clk_index * XILINX_PLL_MEASURE_WIDTH;
|
||||
uint32_t counter_val = bus_r_csp2(addr);
|
||||
// Hz => round to nearest kHz
|
||||
uint32_t freq_kHz = (counter_val + 500) / 1000; // round to nearest kHz
|
||||
return freq_kHz;
|
||||
}
|
||||
|
||||
bool XILINX_PLL_isLocked() {
|
||||
uint32_t status = bus_r_csp2(XILINX_PLL_BASE_ADDR + XILINX_PLL_STATUS_REG);
|
||||
return ((status & XILINX_PLL_STATUS_LOCKED_MSK) >>
|
||||
XILINX_PLL_STATUS_LOCKED_OFST);
|
||||
}
|
||||
|
||||
void XILINX_PLL_reset() {
|
||||
bus_w_csp2(XILINX_PLL_BASE_ADDR + XILINX_PLL_RESET_REG,
|
||||
XILINX_PLL_RESET_VAL);
|
||||
}
|
||||
|
||||
void XILINX_PLL_load() {
|
||||
bus_w_csp2(
|
||||
XILINX_PLL_BASE_ADDR + XILINX_PLL_LOAD_REG,
|
||||
(XILINX_PLL_LOAD_RECONFIGURE_MSK | XILINX_PLL_LOAD_FROM_REGS_MSK));
|
||||
}
|
||||
|
||||
void XILINX_PLL_waitForLock() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
int timeout_us = 10 * 1000;
|
||||
int count = 500;
|
||||
while (count > 0) {
|
||||
usleep(timeout_us);
|
||||
if (XILINX_PLL_isLocked())
|
||||
return;
|
||||
count--;
|
||||
}
|
||||
LOG(logERROR, ("XILINX_PLL: Timeout waiting for PLL to lock (%d ms)\n",
|
||||
(count * timeout_us) / 1000));
|
||||
}
|
||||
@@ -13,11 +13,14 @@
|
||||
/* global variables */
|
||||
#define CSP0 (0xB0080000)
|
||||
#define CSP1 (0xB0050000) // udp
|
||||
#define MEM_SIZE_CSP0 (0x10000)
|
||||
#define CSP2 (0xA0000000)
|
||||
#define MEM_SIZE_CSP0 (0x20000)
|
||||
#define MEM_SIZE_CSP1 (0x2000) // smaller size for udp
|
||||
#define MEM_SIZE_CSP2 (0x4000)
|
||||
|
||||
u_int32_t *csp0base = 0;
|
||||
u_int32_t *csp1base = 0;
|
||||
u_int32_t *csp2base = 0;
|
||||
|
||||
void bus_w(u_int32_t offset, u_int32_t data) {
|
||||
volatile u_int32_t *ptr1;
|
||||
@@ -31,6 +34,18 @@ u_int32_t bus_r(u_int32_t offset) {
|
||||
return *ptr1;
|
||||
}
|
||||
|
||||
void bus_w_csp2(u_int32_t offset, u_int32_t data) {
|
||||
volatile u_int32_t *ptr1;
|
||||
ptr1 = (u_int32_t *)(csp2base + offset / (sizeof(u_int32_t)));
|
||||
*ptr1 = data;
|
||||
}
|
||||
|
||||
u_int32_t bus_r_csp2(u_int32_t offset) {
|
||||
volatile u_int32_t *ptr1;
|
||||
ptr1 = (u_int32_t *)(csp2base + offset / (sizeof(u_int32_t)));
|
||||
return *ptr1;
|
||||
}
|
||||
|
||||
uint64_t getU64BitReg(int aLSB, int aMSB) {
|
||||
uint64_t retval = bus_r(aMSB);
|
||||
retval = (retval << 32) | bus_r(aLSB);
|
||||
@@ -51,12 +66,12 @@ u_int32_t writeRegister(u_int32_t offset, u_int32_t data) {
|
||||
|
||||
int mapCSP0(void) {
|
||||
LOG(logINFO, ("Mapping memory\n"));
|
||||
u_int32_t csps[2] = {CSP0, CSP1};
|
||||
u_int32_t **cspbases[2] = {&csp0base, &csp1base};
|
||||
u_int32_t memsize[2] = {MEM_SIZE_CSP0, MEM_SIZE_CSP1};
|
||||
char names[2][10] = {"csp0base", "csp1base"};
|
||||
u_int32_t csps[3] = {CSP0, CSP1, CSP2};
|
||||
u_int32_t **cspbases[3] = {&csp0base, &csp1base, &csp2base};
|
||||
u_int32_t memsize[3] = {MEM_SIZE_CSP0, MEM_SIZE_CSP1, MEM_SIZE_CSP2};
|
||||
char names[3][10] = {"csp0base", "csp1base", "csp2base"};
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
// if not mapped
|
||||
if (*cspbases[i] == 0) {
|
||||
LOG(logINFO, ("\tMapping memory for %s\n", names[i]));
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
extern enum TLogLevel trimmingPrint;
|
||||
extern uint32_t clkDivider[];
|
||||
#endif
|
||||
#ifdef CHIPTESTBOARDD
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
extern uint32_t clkFrequency[];
|
||||
#endif
|
||||
|
||||
@@ -54,27 +54,12 @@ void initializePatternWord() {
|
||||
memset(virtual_pattern, 0, sizeof(virtual_pattern));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
uint64_t validate_readPatternIOControl() {
|
||||
#if defined(CHIPTESTBOARDD)
|
||||
return getU64BitReg(PATTERN_IO_CNTRL_LSB_REG, PATTERN_IO_CNTRL_MSB_REG);
|
||||
#elif defined(XILINX_CHIPTESTBOARDD)
|
||||
return (uint64_t)(bus_r(PINIOCTRLREG));
|
||||
#endif
|
||||
}
|
||||
|
||||
int validate_writePatternIOControl(char *message, uint64_t arg) {
|
||||
// validate input
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
if (arg > BIT32_MSK) {
|
||||
strcpy(message, "Could not set pattern IO Control. Must be 32 bit for "
|
||||
"this detector\n");
|
||||
LOG(logERROR, (message));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
writePatternIOControl(arg);
|
||||
|
||||
@@ -95,15 +80,9 @@ int validate_writePatternIOControl(char *message, uint64_t arg) {
|
||||
}
|
||||
|
||||
void writePatternIOControl(uint64_t word) {
|
||||
#ifdef CHIPTESTBOARDD
|
||||
LOG(logINFO,
|
||||
("Setting Pattern I/O Control: 0x%llx\n", (long long int)word));
|
||||
setU64BitReg(word, PATTERN_IO_CNTRL_LSB_REG, PATTERN_IO_CNTRL_MSB_REG);
|
||||
#elif defined(XILINX_CHIPTESTBOARDD)
|
||||
uint32_t val = (uint32_t)word;
|
||||
LOG(logINFO, ("Setting Pattern I/O Control: 0x%x\n", val));
|
||||
bus_w(PINIOCTRLREG, val);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -122,7 +101,7 @@ int validate_readPatternWord(char *message, int addr, uint64_t *word) {
|
||||
}
|
||||
|
||||
uint64_t readPatternWord(int addr) {
|
||||
#ifdef MYTHEN3D
|
||||
#if defined(MYTHEN3D) || defined(XILINX_CHIPTESTBOARDD)
|
||||
LOG(logDEBUG1, (" Reading Pattern Word (addr:0x%x)\n", addr));
|
||||
// the first word in RAM as base plus the offset of the word to write (addr)
|
||||
uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2;
|
||||
@@ -182,7 +161,7 @@ void writePatternWord(int addr, uint64_t word) {
|
||||
LOG(logDEBUG1, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr,
|
||||
(long long int)word));
|
||||
|
||||
#ifndef MYTHEN3D
|
||||
#ifdef CHIPTESTBOARDD
|
||||
uint32_t reg = PATTERN_CNTRL_REG;
|
||||
|
||||
// write word
|
||||
@@ -199,7 +178,6 @@ void writePatternWord(int addr, uint64_t word) {
|
||||
#ifdef VIRTUAL
|
||||
virtual_pattern[addr] = word;
|
||||
#endif
|
||||
// mythen
|
||||
#else
|
||||
// the first word in RAM as base plus the offset of the word to write (addr)
|
||||
uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2;
|
||||
@@ -223,29 +201,15 @@ int validate_getPatternWaitAddresses(char *message, int level, int *addr) {
|
||||
}
|
||||
|
||||
int getPatternWaitAddress(int level) {
|
||||
switch (level) {
|
||||
case 0:
|
||||
return ((bus_r(PATTERN_WAIT_0_ADDR_REG) & PATTERN_WAIT_0_ADDR_MSK) >>
|
||||
PATTERN_WAIT_0_ADDR_OFST);
|
||||
case 1:
|
||||
return ((bus_r(PATTERN_WAIT_1_ADDR_REG) & PATTERN_WAIT_1_ADDR_MSK) >>
|
||||
PATTERN_WAIT_1_ADDR_OFST);
|
||||
case 2:
|
||||
return ((bus_r(PATTERN_WAIT_2_ADDR_REG) & PATTERN_WAIT_2_ADDR_MSK) >>
|
||||
PATTERN_WAIT_2_ADDR_OFST);
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
return ((bus_r(PATTERN_WAIT_3_ADDR_REG) & PATTERN_WAIT_3_ADDR_MSK) >>
|
||||
PATTERN_WAIT_3_ADDR_OFST);
|
||||
case 4:
|
||||
return ((bus_r(PATTERN_WAIT_4_ADDR_REG) & PATTERN_WAIT_4_ADDR_MSK) >>
|
||||
PATTERN_WAIT_4_ADDR_OFST);
|
||||
case 5:
|
||||
return ((bus_r(PATTERN_WAIT_5_ADDR_REG) & PATTERN_WAIT_5_ADDR_MSK) >>
|
||||
PATTERN_WAIT_5_ADDR_OFST);
|
||||
#endif
|
||||
default:
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return -1;
|
||||
} else {
|
||||
return ((bus_r(PATTERN_LOOPDEF_BASE +
|
||||
(PATTERN_WAIT_ADDR_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET) &
|
||||
PATTERN_WAIT_ADDR_MSK) >>
|
||||
PATTERN_WAIT_ADDR_OFST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,35 +253,13 @@ void setPatternWaitAddress(int level, int addr) {
|
||||
LOG(logINFO,
|
||||
#endif
|
||||
("Setting Pattern Wait Address (level:%d, addr:0x%x)\n", level, addr));
|
||||
switch (level) {
|
||||
case 0:
|
||||
bus_w(PATTERN_WAIT_0_ADDR_REG,
|
||||
((addr << PATTERN_WAIT_0_ADDR_OFST) & PATTERN_WAIT_0_ADDR_MSK));
|
||||
break;
|
||||
case 1:
|
||||
bus_w(PATTERN_WAIT_1_ADDR_REG,
|
||||
((addr << PATTERN_WAIT_1_ADDR_OFST) & PATTERN_WAIT_1_ADDR_MSK));
|
||||
break;
|
||||
case 2:
|
||||
bus_w(PATTERN_WAIT_2_ADDR_REG,
|
||||
((addr << PATTERN_WAIT_2_ADDR_OFST) & PATTERN_WAIT_2_ADDR_MSK));
|
||||
break;
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
bus_w(PATTERN_WAIT_3_ADDR_REG,
|
||||
((addr << PATTERN_WAIT_3_ADDR_OFST) & PATTERN_WAIT_3_ADDR_MSK));
|
||||
break;
|
||||
case 4:
|
||||
bus_w(PATTERN_WAIT_4_ADDR_REG,
|
||||
((addr << PATTERN_WAIT_4_ADDR_OFST) & PATTERN_WAIT_4_ADDR_MSK));
|
||||
break;
|
||||
case 5:
|
||||
bus_w(PATTERN_WAIT_5_ADDR_REG,
|
||||
((addr << PATTERN_WAIT_5_ADDR_OFST) & PATTERN_WAIT_5_ADDR_MSK));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return;
|
||||
} else {
|
||||
bus_w(PATTERN_LOOPDEF_BASE + (PATTERN_WAIT_ADDR_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET,
|
||||
((addr << PATTERN_WAIT_ADDR_OFST) & PATTERN_WAIT_ADDR_MSK));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,39 +282,24 @@ int validate_getPatternWaitClocksAndInterval(char *message, int level,
|
||||
}
|
||||
|
||||
uint64_t getPatternWaitClocks(int level) {
|
||||
switch (level) {
|
||||
case 0:
|
||||
return getU64BitReg(PATTERN_WAIT_TIMER_0_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_0_MSB_REG);
|
||||
case 1:
|
||||
return getU64BitReg(PATTERN_WAIT_TIMER_1_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_1_MSB_REG);
|
||||
case 2:
|
||||
return getU64BitReg(PATTERN_WAIT_TIMER_2_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_2_MSB_REG);
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
return getU64BitReg(PATTERN_WAIT_TIMER_3_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_3_MSB_REG);
|
||||
case 4:
|
||||
return getU64BitReg(PATTERN_WAIT_TIMER_4_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_4_MSB_REG);
|
||||
case 5:
|
||||
return getU64BitReg(PATTERN_WAIT_TIMER_5_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_5_MSB_REG);
|
||||
#endif
|
||||
default:
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return -1;
|
||||
} else {
|
||||
return getU64BitReg(
|
||||
PATTERN_LOOPDEF_BASE + (PATTERN_WAIT_TIMER_LSB_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET,
|
||||
PATTERN_LOOPDEF_BASE + (PATTERN_WAIT_TIMER_MSB_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t getPatternWaitInterval(int level) {
|
||||
uint64_t numClocks = getPatternWaitClocks(level);
|
||||
int runclk = 0;
|
||||
#ifdef CHIPTESTBOARDD
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
runclk = clkFrequency[RUN_CLK];
|
||||
#elif XILINX_CHIPTESTBOARDD
|
||||
runclk = RUN_CLK;
|
||||
#elif MYTHEN3D
|
||||
runclk = clkDivider[SYSTEM_C0];
|
||||
#endif
|
||||
@@ -425,35 +352,18 @@ void setPatternWaitClocks(int level, uint64_t t) {
|
||||
#endif
|
||||
("Setting Pattern Wait Time in clocks (level:%d) :%lld\n", level,
|
||||
(long long int)t));
|
||||
switch (level) {
|
||||
case 0:
|
||||
setU64BitReg(t, PATTERN_WAIT_TIMER_0_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_0_MSB_REG);
|
||||
break;
|
||||
case 1:
|
||||
setU64BitReg(t, PATTERN_WAIT_TIMER_1_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_1_MSB_REG);
|
||||
break;
|
||||
case 2:
|
||||
setU64BitReg(t, PATTERN_WAIT_TIMER_2_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_2_MSB_REG);
|
||||
break;
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
setU64BitReg(t, PATTERN_WAIT_TIMER_3_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_3_MSB_REG);
|
||||
break;
|
||||
case 4:
|
||||
setU64BitReg(t, PATTERN_WAIT_TIMER_4_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_4_MSB_REG);
|
||||
break;
|
||||
case 5:
|
||||
setU64BitReg(t, PATTERN_WAIT_TIMER_5_LSB_REG,
|
||||
PATTERN_WAIT_TIMER_5_MSB_REG);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return;
|
||||
} else {
|
||||
return setU64BitReg(
|
||||
t,
|
||||
PATTERN_LOOPDEF_BASE + (PATTERN_WAIT_TIMER_LSB_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET,
|
||||
PATTERN_LOOPDEF_BASE + (PATTERN_WAIT_TIMER_MSB_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,12 +376,10 @@ void setPatternWaitInterval(int level, uint64_t t) {
|
||||
("Setting Pattern Wait Time (level:%d) :%lld ns\n", level,
|
||||
(long long int)t));
|
||||
int runclk = 0;
|
||||
#ifdef CHIPTESTBOARDD
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
runclk = clkFrequency[RUN_CLK];
|
||||
#elif XILINX_CHIPTESTBOARDD
|
||||
runclk = RUN_CLK;
|
||||
#elif MYTHEN3D
|
||||
runclk = clkDivider[SYSTEM_C0];
|
||||
runclk = clkDivider[SYSTEM_C0];
|
||||
#endif
|
||||
uint64_t numClocks = t * (1E-3 * runclk);
|
||||
setPatternWaitClocks(level, numClocks);
|
||||
@@ -491,23 +399,13 @@ int validate_getPatternLoopCycles(char *message, int level, int *numLoops) {
|
||||
}
|
||||
|
||||
int getPatternLoopCycles(int level) {
|
||||
switch (level) {
|
||||
case 0:
|
||||
return bus_r(PATTERN_LOOP_0_ITERATION_REG);
|
||||
case 1:
|
||||
return bus_r(PATTERN_LOOP_1_ITERATION_REG);
|
||||
case 2:
|
||||
return bus_r(PATTERN_LOOP_2_ITERATION_REG);
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
return bus_r(PATTERN_LOOP_3_ITERATION_REG);
|
||||
case 4:
|
||||
return bus_r(PATTERN_LOOP_4_ITERATION_REG);
|
||||
case 5:
|
||||
return bus_r(PATTERN_LOOP_5_ITERATION_REG);
|
||||
#endif
|
||||
default:
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return -1;
|
||||
} else {
|
||||
return bus_r(PATTERN_LOOPDEF_BASE +
|
||||
(PATTERN_LOOP_ITERATION_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,29 +444,13 @@ void setPatternLoopCycles(int level, int nLoop) {
|
||||
LOG(logINFO,
|
||||
#endif
|
||||
("Setting Pattern Loop Cycles(level:%d, nLoop:%d)\n", level, nLoop));
|
||||
switch (level) {
|
||||
case 0:
|
||||
bus_w(PATTERN_LOOP_0_ITERATION_REG, nLoop);
|
||||
break;
|
||||
case 1:
|
||||
bus_w(PATTERN_LOOP_1_ITERATION_REG, nLoop);
|
||||
break;
|
||||
case 2:
|
||||
bus_w(PATTERN_LOOP_2_ITERATION_REG, nLoop);
|
||||
break;
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
bus_w(PATTERN_LOOP_3_ITERATION_REG, nLoop);
|
||||
break;
|
||||
case 4:
|
||||
bus_w(PATTERN_LOOP_4_ITERATION_REG, nLoop);
|
||||
break;
|
||||
case 5:
|
||||
bus_w(PATTERN_LOOP_5_ITERATION_REG, nLoop);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return;
|
||||
} else {
|
||||
bus_w(PATTERN_LOOPDEF_BASE + (PATTERN_LOOP_ITERATION_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET,
|
||||
nLoop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,59 +521,22 @@ int validate_getPatternLoopAddresses(char *message, int level, int *startAddr,
|
||||
}
|
||||
|
||||
void getPatternLoopAddresses(int level, int *startAddr, int *stopAddr) {
|
||||
switch (level) {
|
||||
case 0:
|
||||
*startAddr =
|
||||
((bus_r(PATTERN_LOOP_0_ADDR_REG) & PATTERN_LOOP_0_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_0_ADDR_STRT_OFST);
|
||||
*stopAddr =
|
||||
((bus_r(PATTERN_LOOP_0_ADDR_REG) & PATTERN_LOOP_0_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_0_ADDR_STP_OFST);
|
||||
break;
|
||||
case 1:
|
||||
*startAddr =
|
||||
((bus_r(PATTERN_LOOP_1_ADDR_REG) & PATTERN_LOOP_1_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_1_ADDR_STRT_OFST);
|
||||
*stopAddr =
|
||||
((bus_r(PATTERN_LOOP_1_ADDR_REG) & PATTERN_LOOP_1_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_1_ADDR_STP_OFST);
|
||||
break;
|
||||
case 2:
|
||||
*startAddr =
|
||||
((bus_r(PATTERN_LOOP_2_ADDR_REG) & PATTERN_LOOP_2_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_2_ADDR_STRT_OFST);
|
||||
*stopAddr =
|
||||
((bus_r(PATTERN_LOOP_2_ADDR_REG) & PATTERN_LOOP_2_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_2_ADDR_STP_OFST);
|
||||
break;
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
*startAddr =
|
||||
((bus_r(PATTERN_LOOP_3_ADDR_REG) & PATTERN_LOOP_3_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_3_ADDR_STRT_OFST);
|
||||
*stopAddr =
|
||||
((bus_r(PATTERN_LOOP_3_ADDR_REG) & PATTERN_LOOP_3_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_3_ADDR_STP_OFST);
|
||||
break;
|
||||
case 4:
|
||||
*startAddr =
|
||||
((bus_r(PATTERN_LOOP_4_ADDR_REG) & PATTERN_LOOP_4_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_4_ADDR_STRT_OFST);
|
||||
*stopAddr =
|
||||
((bus_r(PATTERN_LOOP_4_ADDR_REG) & PATTERN_LOOP_4_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_4_ADDR_STP_OFST);
|
||||
break;
|
||||
case 5:
|
||||
*startAddr =
|
||||
((bus_r(PATTERN_LOOP_5_ADDR_REG) & PATTERN_LOOP_5_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_5_ADDR_STRT_OFST);
|
||||
*stopAddr =
|
||||
((bus_r(PATTERN_LOOP_5_ADDR_REG) & PATTERN_LOOP_5_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_5_ADDR_STP_OFST);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
*startAddr = -1;
|
||||
*stopAddr = -1;
|
||||
} else {
|
||||
*startAddr = ((bus_r(PATTERN_LOOPDEF_BASE +
|
||||
(PATTERN_LOOP_ADDR_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET) &
|
||||
PATTERN_LOOP_ADDR_STRT_MSK) >>
|
||||
PATTERN_LOOP_ADDR_STRT_OFST);
|
||||
*stopAddr = ((bus_r(PATTERN_LOOPDEF_BASE +
|
||||
(PATTERN_LOOP_ADDR_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET) &
|
||||
PATTERN_LOOP_ADDR_STP_MSK) >>
|
||||
PATTERN_LOOP_ADDR_STP_OFST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,53 +592,16 @@ void setPatternLoopAddresses(int level, int startAddr, int stopAddr) {
|
||||
("Setting Pattern Loop Address (level:%d, startaddr:0x%x, "
|
||||
"stopaddr:0x%x)\n",
|
||||
level, startAddr, stopAddr));
|
||||
switch (level) {
|
||||
case 0:
|
||||
bus_w(PATTERN_LOOP_0_ADDR_REG,
|
||||
((startAddr << PATTERN_LOOP_0_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_0_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_0_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_0_ADDR_STP_MSK));
|
||||
break;
|
||||
case 1:
|
||||
bus_w(PATTERN_LOOP_1_ADDR_REG,
|
||||
((startAddr << PATTERN_LOOP_1_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_1_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_1_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_1_ADDR_STP_MSK));
|
||||
break;
|
||||
case 2:
|
||||
bus_w(PATTERN_LOOP_2_ADDR_REG,
|
||||
((startAddr << PATTERN_LOOP_2_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_2_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_2_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_2_ADDR_STP_MSK));
|
||||
break;
|
||||
#ifndef MYTHEN3D
|
||||
case 3:
|
||||
bus_w(PATTERN_LOOP_3_ADDR_REG,
|
||||
((startAddr << PATTERN_LOOP_3_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_3_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_3_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_3_ADDR_STP_MSK));
|
||||
break;
|
||||
case 4:
|
||||
bus_w(PATTERN_LOOP_4_ADDR_REG,
|
||||
((startAddr << PATTERN_LOOP_4_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_4_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_4_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_4_ADDR_STP_MSK));
|
||||
break;
|
||||
case 5:
|
||||
bus_w(PATTERN_LOOP_5_ADDR_REG,
|
||||
((startAddr << PATTERN_LOOP_5_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_5_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_5_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_5_ADDR_STP_MSK));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (level < 0 || level >= MAX_LEVELS) {
|
||||
return;
|
||||
} else {
|
||||
bus_w(PATTERN_LOOPDEF_BASE + (PATTERN_LOOP_ADDR_WORD_OFST +
|
||||
level * PATTERN_LOOPDEF_NWORDS_OFST) *
|
||||
REG_OFFSET,
|
||||
((startAddr << PATTERN_LOOP_ADDR_STRT_OFST) &
|
||||
PATTERN_LOOP_ADDR_STRT_MSK) |
|
||||
((stopAddr << PATTERN_LOOP_ADDR_STP_OFST) &
|
||||
PATTERN_LOOP_ADDR_STP_MSK));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,6 +634,17 @@ void startPattern() {
|
||||
LOG(logINFOBLUE, ("Pattern done\n"));
|
||||
}
|
||||
#endif
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
void startPattern() {
|
||||
LOG(logINFOBLUE, ("Starting Pattern\n"));
|
||||
bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | START_F_MSK);
|
||||
usleep(1);
|
||||
while (bus_r(FLOW_CONTROL_REG) & RSM_BUSY_MSK) {
|
||||
usleep(1);
|
||||
}
|
||||
LOG(logINFOBLUE, ("Pattern done\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
char *getPatternFileName() { return clientPatternfile; }
|
||||
|
||||
|
||||
@@ -5798,7 +5798,7 @@ int set_clock_frequency(int file_des) {
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting clock (%d) frequency : %u\n", args[0], args[1]));
|
||||
|
||||
#if !defined(CHIPTESTBOARDD)
|
||||
#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
|
||||
@@ -5811,7 +5811,7 @@ int set_clock_frequency(int file_des) {
|
||||
case ADC_CLOCK:
|
||||
c = ADC_CLK;
|
||||
break;
|
||||
#ifdef CHIPTESTBOARDD
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
case DBIT_CLOCK:
|
||||
c = DBIT_CLK;
|
||||
break;
|
||||
@@ -5843,7 +5843,11 @@ int set_clock_frequency(int file_des) {
|
||||
int retval = getFrequency(c);
|
||||
LOG(logDEBUG1, ("retval %s: %d %s\n", modeName, retval,
|
||||
myDetectorType == GOTTHARD2 ? "Hz" : "MHz"));
|
||||
#if !defined( \
|
||||
XILINX_CHIPTESTBOARDD) // XCTB will give the actual frequency, which is not
|
||||
// 100% identical to the set frequency
|
||||
validate(&ret, mess, val, retval, modeName, DEC);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5861,13 +5865,14 @@ int get_clock_frequency(int file_des) {
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Getting clock (%d) frequency\n", arg));
|
||||
|
||||
#if !defined(CHIPTESTBOARDD) && !defined(GOTTHARD2D) && !defined(MYTHEN3D)
|
||||
#if !defined(CHIPTESTBOARDD) && !defined(GOTTHARD2D) && !defined(MYTHEN3D) && \
|
||||
!defined(XILINX_CHIPTESTBOARDD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
enum CLKINDEX c = 0;
|
||||
switch (arg) {
|
||||
#if defined(CHIPTESTBOARDD)
|
||||
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
|
||||
case ADC_CLOCK:
|
||||
c = ADC_CLK;
|
||||
break;
|
||||
@@ -7463,7 +7468,7 @@ int start_pattern(int file_des) {
|
||||
memset(mess, 0, sizeof(mess));
|
||||
|
||||
LOG(logDEBUG1, ("Starting Pattern\n"));
|
||||
#ifndef MYTHEN3D
|
||||
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
|
||||
Reference in New Issue
Block a user