Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added timer SDK and its respective example #554

Merged
merged 3 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_ */
Loading