#include "HardwareTaskSimulation.h"

#include "../../software/signal_processing/system/hardware_task.h"
#include <chrono>

#define REG_START_OFFSET 0
#define REG_STATE_OFFSET 1
#define REG_CYCLE_COUNT_OFFSET 2
#define REG_CONFIG_0_OFFSET 3

#define FREQ 200e6

HardwareTaskSimulation::HardwareTaskSimulation( task_function function )
    : state( 0 ),
      cycleCount( 0 ),
      function( function ) {
}

uint32_t HardwareTaskSimulation::read( uint32_t offset ) const {
    switch ( offset ) {
    case REG_STATE_OFFSET: return state;
    case REG_CYCLE_COUNT_OFFSET: return cycleCount;
    case REG_CONFIG_0_OFFSET: return config[ 0 ];
    }
    return static_cast< uint32_t >( -1 );
}

void HardwareTaskSimulation::write( uint32_t offset, uint32_t value ) {
    switch ( offset ) {
    case REG_START_OFFSET: start(); break;
    case REG_CONFIG_0_OFFSET: config[ 0 ] = value; break;
    }
}

void HardwareTaskSimulation::start() {
    using namespace std::chrono;
    auto start = high_resolution_clock::now();
    state = HARDWARE_TASK_RUNNING;
    function( config );
    state = HARDWARE_TASK_DONE;
    auto stop = high_resolution_clock::now();
    auto time = duration_cast< duration< double > >( stop - start );
    cycleCount = static_cast< uint32_t >( time.count() * FREQ );
}

