Hi, everyone !
I'm working with EK-TM4C1294XL processor TIVA and my application need to have high speed processing.
Characteristics:
Processor: EK-TM4C1294XL
Application: Signal Processing
Compiler: CCS 6.01
Then Im build a code to power quality processing and I need to know time to processing each part of code. To execute this work Im using TIMER 1 like a instruction counter.
To execute this my code is
// Setup the timer for count
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(TIMER1_BASE, TIMER_A, g_ui32SysClock);
where g_ui32SysClock = 120MHz
Using Driverlib we find that instructions to start and stop timer is
Start insert:
HWREG(TIMER1_BASE + TIMER_O_TAILR) = g_ui32SysClock; // load timer count with 120M
HWREG(TIMER1_BASE + TIMER_O_CTL) |= TIMER_A & (TIMER_CTL_TAEN | TIMER_CTL_TBEN); // start the timer
Stop Timer:
HWREG(TIMER1_BASE + TIMER_O_CTL) &= ~(TIMER_A & (TIMER_CTL_TAEN | TIMER_CTL_TBEN)); // Stop the timer
value = HWREG(TIMER1_BASE + TIMER_O_TAR); // read value of timer after processing
printf("%d - %d\n", (g_ui32SysClock - value), j); // Print number of cycles of processing
This mode:
Inicialization code();
HWREG(TIMER1_BASE + TIMER_O_TAILR) = g_ui32SysClock; // load timer count with 120M
HWREG(TIMER1_BASE + TIMER_O_CTL) |= TIMER_A & (TIMER_CTL_TAEN | TIMER_CTL_TBEN); // start the timer
code to analyze time to processing ();
HWREG(TIMER1_BASE + TIMER_O_CTL) &= ~(TIMER_A & (TIMER_CTL_TAEN | TIMER_CTL_TBEN)); // Stop the timer
value = HWREG(TIMER1_BASE + TIMER_O_TAR); // read value of timer after processing
printf("%d - %d\n", (g_ui32SysClock - value), j); // Print number of cycles of processing
Until this point everything works well for example:
converted = REF_3_3_4096*data; Tiva execute float multiplication in 1 cycle machine.
but if I try execute the code below, the processor spent 15 machine cycles.
output[length] = Amplitude;
In my concept about processors this is wrong because in assembler this is a MOV instruction and this instruction is very fast.
I attached below all code. Can you help me understand why this processor spend too much time to execute this.
Thanks for your attention and best regards
(...)
#define NPPC 128
#define FUND 60
#define F_SAMPLE (FUND*NPPC)
uint32_t g_ui32SysClock;
// Global variables
#define PI 3.141592
const int MAX_LENGTH = (12*NPPC);
#define W0 ((PI * 2 * FUND) / F_SAMPLE)
float raw[MAX_LENGTH];
float output[MAX_LENGTH];
float fifo[NPPC];
float sine[NPPC];
float cossine[NPPC];
uint32_t length;
uint32_t g_ui32Flags;
volatile uint32_t data;
volatile int flagAvailableData = 0;
(...)
int main(void)
{
g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
length = 0;
(...)
// Setup the timer for count
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(TIMER1_BASE, TIMER_A, g_ui32SysClock);
TimerEnable(TIMER0_BASE, TIMER_A);
(...)
// Local variables
int Harmonic = 2;
float _2_NPPC = (float)((float)2/NPPC);
uint32_t value;
int i = 0, j = 1;
float Yc = 0, Ys = 0;
float converted;
float Amplitude;
float fifoOut;
float REF_3_3_4096 = (3.3/4096);
int TrigonometricPosition = 0;
int FifoPosition = 0;
i = 0;
while(1)
{
if(flagAvailableData == 1 && length < MAX_LENGTH)
{
// Enabling the timer
value = 0;
HWREG(TIMER1_BASE + TIMER_O_TAILR) = g_ui32SysClock;
HWREG(TIMER1_BASE + TIMER_O_CTL) |= TIMER_A & (TIMER_CTL_TAEN | TIMER_CTL_TBEN);
converted = REF_3_3_4096*data;
raw[length] = converted;
fifoOut = converted - fifo[FifoPosition];
fifo[FifoPosition] = converted;
Ys -= fifoOut * sine[TrigonometricPosition];
Yc += fifoOut * cossine[TrigonometricPosition];
Amplitude = ((Ys * Ys + Yc * Yc) * _2_NPPC);
// Measuring the number of cicles here, the result is 7.
output[length] = Amplitude;
// Measuring the number of cicles here, the result is 22. 15 cicles for a simple operation?
TrigonometricPosition += Harmonic;
if (TrigonometricPosition >= NPPC)
TrigonometricPosition = 0;
// Measuring the number of cicles here, the result is 72. 50 cicles for an if?
FifoPosition++;
if (FifoPosition >= NPPC)
FifoPosition = 0;
// Disabling the timer
HWREG(TIMER1_BASE + TIMER_O_CTL) &= ~(TIMER_A & (TIMER_CTL_TAEN | TIMER_CTL_TBEN));
value = HWREG(TIMER1_BASE + TIMER_O_TAR);
printf("%d - %d\n", (g_ui32SysClock - value), j);
j++;
(...)
}
}
}