Skip to content

Commit

Permalink
Added timer SDK and its respective example (#554)
Browse files Browse the repository at this point in the history
  • Loading branch information
JuanSapriza authored Jul 18, 2024
1 parent 64caf68 commit 322f466
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 0 deletions.
56 changes: 56 additions & 0 deletions sw/applications/example_timer_sdk/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2024 EPFL
// Solderpad Hardware License, Version 2.1, see LICENSE.md for details.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// File: example_timer_sdk.c
// Author: Juan Sapriza
// Date: 15/07/2024
// Description: Example application to test the Timer SDK. Will count the time to execute a few short tasks.

#include <stdint.h>
#include <stdlib.h>
#include "core_v_mini_mcu.h"
#include "timer_sdk.h"
#include "x-heep.h"

/* By default, printfs are activated for FPGA and disabled for simulation. */
#define PRINTF_IN_FPGA 1
#define PRINTF_IN_SIM 0

#if TARGET_SIM && PRINTF_IN_SIM
#define PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
#elif PRINTF_IN_FPGA && !TARGET_SIM
#define PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
#else
#define PRINTF(...)
#endif

int main(){
uint8_t i = 0;
uint32_t cpu_cycles;

timer_init(); // Init the timer SDK
timer_start(); // Start counting the time
cpu_cycles = timer_stop(); // Stop counting the time
PRINTF("0 NOPs:\t%d cc\n\r", cpu_cycles );

timer_start();
asm volatile ("nop");
cpu_cycles = timer_stop();
PRINTF("1 NOP:\t%d cc\n\r", cpu_cycles );

timer_start();
asm volatile ("nop");
asm volatile ("nop");
cpu_cycles = timer_stop();
PRINTF("2 NOPs:\t%d cc\n\r", cpu_cycles );

timer_start();
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
cpu_cycles = timer_stop();
PRINTF("3 NOPs:\t%d cc\n\r", cpu_cycles );

return EXIT_SUCCESS;
}
73 changes: 73 additions & 0 deletions sw/device/lib/sdk/timer/timer_sdk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2023 EPFL and Politecnico di Torino.
// Solderpad Hardware License, Version 2.1, see LICENSE.md for details.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// File: timer_sdk.c
// Author: Michele Caon
// Date: 31/07/2023
// Description: Timer functions

#include <stdint.h>

#include "timer_sdk.h"
#include "csr.h"

/******************************/
/* ---- GLOBAL VARIABLES ---- */
/******************************/

// Timer value
uint32_t timer_value = 0;
uint32_t hw_timer_value = 0;

rv_timer_t timer;

rv_timer_config_t timer_cfg = {
.hart_count = RV_TIMER_PARAM_N_HARTS,
.comparator_count = RV_TIMER_PARAM_N_TIMERS,
};

mmio_region_t timer_base = {
.base = (void *)RV_TIMER_AO_START_ADDRESS,
};

rv_timer_tick_params_t tick_params;

/*************************************/
/* ---- FUNCTION IMPLEMENTATION ---- */
/*************************************/

// Initialize the hardware timer
void hw_timer_init()
{
// Initialize the timer
rv_timer_init(timer_base, timer_cfg, &timer);
rv_timer_approximate_tick_params(REFERENCE_CLOCK_Hz, REFERENCE_CLOCK_Hz, &tick_params);
rv_timer_set_tick_params(&timer, 0, tick_params);
rv_timer_counter_set_enabled(&timer, 0, true);
}

uint32_t hw_timer_get_cycles()
{
uint64_t cycle_count;
rv_timer_counter_read(&timer, 0, &cycle_count);
return (uint32_t)cycle_count;
}

void hw_timer_start()
{
hw_timer_value = -hw_timer_get_cycles();
}

uint32_t hw_timer_stop()
{
hw_timer_value += hw_timer_get_cycles();
return hw_timer_value;
}

// Initialize the timer
void timer_init()
{
// Enable MCYCLE counter
CSR_CLEAR_BITS(CSR_REG_MCOUNTINHIBIT, 0x1);
}
100 changes: 100 additions & 0 deletions sw/device/lib/sdk/timer/timer_sdk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2023 EPFL and Politecnico di Torino.
// Solderpad Hardware License, Version 2.1, see LICENSE.md for details.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// File: timer_sdk.h
// Authors: Michele Caon, Luigi Giuffrida
// Date: 31/07/2023
// Description: Execution time measurements utilities

#ifndef TIMER_SDK_H_
#define TIMER_SDK_H_

#include <stdint.h>

#include "csr.h"
#include "gpio.h"
#include "rv_timer.h"
#include "rv_timer_regs.h"
#include "core_v_mini_mcu.h"
#include "x-heep.h"

#define TICK_FREQ 1000000

/******************************/
/* ---- GLOBAL VARIABLES ---- */
/******************************/

// Timer value
extern uint32_t timer_value;
extern uint32_t hw_timer_value;

extern rv_timer_t timer;

/********************************/
/* ---- EXPORTED FUNCTIONS ---- */
/********************************/

/**
* @brief Initialize the hardware timer
*
*/
void hw_timer_init();

/**
* @brief Get the current value of the HW timer
*
* @return int64_t Current value of the HW timer
*/
uint32_t hw_timer_get_cycles();

/**
* @brief Start the HW timer
*
*/
void hw_timer_start();

/**
* @brief Stop the HW timer
*
* @return int64_t Elapsed time in clock cycles
*/
uint32_t hw_timer_stop();


/**
* @brief Initialize the timer
*
*/
void timer_init();

/**
* @brief Get the current value of the MCYCLE CSR
*
* @return int64_t Current value of the MCYCLE CSR
*/
inline uint32_t timer_get_cycles() {
uint32_t cycle_count;
CSR_READ(CSR_REG_MCYCLE, &cycle_count);
return cycle_count;
}

/**
* @brief Start the timer
*
*/
inline void timer_start() {
timer_value = -timer_get_cycles();
}

/**
* @brief Stop the timer
*
* @return int64_t Elapsed time in clock cycles
*/
inline uint32_t timer_stop() {
timer_value += timer_get_cycles();
return timer_value;
}

#endif /* TIMER_SDK_H_ */

0 comments on commit 322f466

Please sign in to comment.