-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added timer SDK and its respective example (#554)
- Loading branch information
1 parent
64caf68
commit 322f466
Showing
3 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_ */ |