Skip to content

Commit

Permalink
[sival,clkmgr] Add test for chip_sw_clkmgr_jitter_cycle_measurements …
Browse files Browse the repository at this point in the history
…testpoint

Fixes lowRISC#20230

Signed-off-by: Guillermo Maturana <[email protected]>
  • Loading branch information
matutem committed Nov 7, 2023
1 parent 7551807 commit 2d783ae
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 19 deletions.
9 changes: 4 additions & 5 deletions hw/top_earlgrey/data/ip/chip_clkmgr_testplan.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,9 @@
{
name: chip_sw_clkmgr_jitter_cycle_measurements
desc: '''Verify jitter via clock cycle measurements after calibration.
The clock count thresholds should need to be set wider than when jitter is disabled.
The clock count thresholds for main clk need to be set wider than when jitter is disabled.
SiVal: This is only useful on real silicon.
Can be done after clock calibration.
This test can use chip_sw_ast_clk_outputs with an option to turn jitter on.
Should be done after clock calibration.
'''
stage: V3
si_stage: SV3
Expand All @@ -252,8 +251,8 @@
"CLKMGR.MEAS_CTRL.MAIN",
"CLKMGR.MEAS_CTRL.USB",
]
tests: []
bazel: []
tests: ["chip_sw_clkmgr_jitter_frequency"]
bazel: ["//sw/device/tests:clkmgr_jitter_frequency_test_fpga_cw310_test_rom"]
}
{
name: chip_sw_clkmgr_extended_range
Expand Down
6 changes: 6 additions & 0 deletions hw/top_earlgrey/dv/chip_sim_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,12 @@
en_run_modes: ["sw_test_mode_test_rom"]
run_opts: ["+calibrate_usb_clk=1"]
}
{
name: chip_sw_clkmgr_jitter_frequency
uvm_test_seq: chip_sw_base_vseq
sw_images: ["//sw/device/tests:clkmgr_jitter_frequency_test:1:new_rules"]
en_run_modes: ["sw_test_mode_test_rom"]
}
{
name: chip_sw_clkmgr_jitter
uvm_test_seq: chip_sw_base_vseq
Expand Down
35 changes: 21 additions & 14 deletions sw/device/lib/testing/clkmgr_testutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ static expected_count_info_t kNoJitterCountInfos[kDifClkmgrMeasureClockUsb + 1];
// The expected counts when jitter is enabled.
static expected_count_info_t kJitterCountInfos[kDifClkmgrMeasureClockUsb + 1];

// Notice the expected variability is set to somewhat less than the added
// variability of the AON and the measured clock.

// The expected variability as a percentage. The AST guarantees 3% for all
// clocks, including the AON, so this sets the effective variability to 5%.
// clocks, including the AON, so the effective variability is set to 5%.
static uint32_t kVariabilityPercentage = 5;

// The expected variability when jitter is enabled as a percentage. The AST
// guarantees 10% for jittery clocks and 3% for the AON clock, so the
// effective variability is set to 12%.
static uint32_t kJitterVariabilityPercentage = 12;

// Compute the variability for a given number of cycles, adding an extra cycle
// for synchronizers.
static inline uint32_t get_count_variability(uint32_t cycles,
Expand Down Expand Up @@ -104,23 +112,22 @@ void initialize_expected_counts(void) {
.variability = get_count_variability(
kDeviceUsbCount, kVariabilityPercentage)};

// If jitter is enabled the low threshold should be up to 20% lower, so
// the variability is set to 0.1 * max_count, and count as max - 0.1 * max.
// When jitter is enabled only the main clk is affected: the low threshold
// should be up to 20% lower, so the expected count is set to 0.9 max, and
// the variability is set per kJitterVariabilityPercentage.
kJitterCountInfos[kDifClkmgrMeasureClockIo] =
(expected_count_info_t){.count = kDeviceIoCount - kDeviceIoCount / 10,
.variability = kDeviceIoCount / 10};
kJitterCountInfos[kDifClkmgrMeasureClockIoDiv2] = (expected_count_info_t){
.count = kDeviceIoDiv2Count - kDeviceIoDiv2Count / 10,
.variability = kDeviceIoDiv2Count / 10};
kJitterCountInfos[kDifClkmgrMeasureClockIoDiv4] = (expected_count_info_t){
.count = kDeviceIoDiv4Count - kDeviceIoDiv4Count / 10,
.variability = kDeviceIoDiv4Count};
kNoJitterCountInfos[kDifClkmgrMeasureClockIo];
kJitterCountInfos[kDifClkmgrMeasureClockIoDiv2] =
kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv2];
kJitterCountInfos[kDifClkmgrMeasureClockIoDiv4] =
kNoJitterCountInfos[kDifClkmgrMeasureClockIoDiv4];
kJitterCountInfos[kDifClkmgrMeasureClockMain] =
(expected_count_info_t){.count = kDeviceCpuCount - kDeviceCpuCount / 10,
.variability = kDeviceCpuCount / 10};
.variability = get_count_variability(
kDeviceCpuCount - kDeviceCpuCount / 10,
kJitterVariabilityPercentage)};
kJitterCountInfos[kDifClkmgrMeasureClockUsb] =
(expected_count_info_t){.count = kDeviceUsbCount - kDeviceUsbCount / 10,
.variability = kDeviceUsbCount / 10};
kNoJitterCountInfos[kDifClkmgrMeasureClockUsb];
}

const char *clkmgr_testutils_measurement_name(
Expand Down
19 changes: 19 additions & 0 deletions sw/device/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,25 @@ opentitan_test(
],
)

opentitan_test(
name = "clkmgr_jitter_frequency_test",
srcs = ["clkmgr_jitter_frequency_test.c"],
exec_env = EARLGREY_TEST_ENVS,
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:memory",
"//sw/device/lib/dif:base",
"//sw/device/lib/dif:clkmgr",
"//sw/device/lib/dif:pwrmgr",
"//sw/device/lib/dif:sensor_ctrl",
"//sw/device/lib/testing:aon_timer_testutils",
"//sw/device/lib/testing:clkmgr_testutils",
"//sw/device/lib/testing:pwrmgr_testutils",
"//sw/device/lib/testing:sensor_ctrl_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
],
)

opentitan_test(
name = "clkmgr_jitter_test",
srcs = ["clkmgr_jitter_test.c"],
Expand Down
70 changes: 70 additions & 0 deletions sw/device/tests/clkmgr_jitter_frequency_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/dif/dif_sensor_ctrl.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/aon_timer_testutils.h"
#include "sw/device/lib/testing/clkmgr_testutils.h"
#include "sw/device/lib/testing/pwrmgr_testutils.h"
#include "sw/device/lib/testing/sensor_ctrl_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"

OTTF_DEFINE_TEST_CONFIG();

/**
* This test measures clock counts with clkmgr frequency measurements and
* jitter enabled, performing 100 measurements per round, where a round is
* one AON clock cycle. Measurement errors (fast or slow clocks) are recorded
* as recoverable errors in clkmgr.
*
* This assumes clocks have been calibrated:
* - for silicon validation this means clocks are calibrated, which means SV1
* tasks are completed
* - for simulation it requires overriding the hardware behavior via plusargs
* so it runs with calibrated USB clock, or the USB clock frequency will be
* incorrect.
*/
enum {
kMeasurementsPerRound = 100,
};

static dif_clkmgr_t clkmgr;
static dif_pwrmgr_t pwrmgr;

bool test_main(void) {
dif_sensor_ctrl_t sensor_ctrl;

uint32_t delay_micros = 0;
CHECK_STATUS_OK(aon_timer_testutils_get_us_from_aon_cycles(
kMeasurementsPerRound, &delay_micros));

CHECK_DIF_OK(dif_clkmgr_init(
mmio_region_from_addr(TOP_EARLGREY_CLKMGR_AON_BASE_ADDR), &clkmgr));
CHECK_DIF_OK(dif_sensor_ctrl_init(
mmio_region_from_addr(TOP_EARLGREY_SENSOR_CTRL_AON_BASE_ADDR),
&sensor_ctrl));
CHECK_DIF_OK(dif_pwrmgr_init(
mmio_region_from_addr(TOP_EARLGREY_PWRMGR_AON_BASE_ADDR), &pwrmgr));

LOG_INFO("TEST: wait for ast init");
IBEX_SPIN_FOR(sensor_ctrl_ast_init_done(&sensor_ctrl), 1000);
LOG_INFO("TEST: done ast init");

CHECK(UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) == true);

CHECK_STATUS_OK(clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
&clkmgr, /*jitter_enabled=*/true, /*external_clk=*/false,
/*low_speed=*/false));
busy_spin_micros(delay_micros);

// check results
CHECK_STATUS_OK(clkmgr_testutils_check_measurement_counts(&clkmgr));
CHECK_STATUS_OK(clkmgr_testutils_disable_clock_counts(&clkmgr));

return true;
}

0 comments on commit 2d783ae

Please sign in to comment.