Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Nios instability

Hello,

I'm using nios II processor with a high_res_timer for different test before continuing my project.

The test i'm trying to do is to generate on a pin a square frequency with a 400µs period.

For that, I have a cyclone III development board with a Nios II/s CPU (clk_50Mhz) and a timer "high_res_timer" (clk_250MHz full featured with a Timeout period of 1s) and all others components I need to run the system.

In Nios II IDE, I change a hello world project en select the the "high_res_timer" as timestamp timer and type the following code :

#include <altera_avalon_pio_regs.h>

#include <sys/alt_timestamp.h>

int main()

{

while(1)

{

alt_timestamp_start();

while(alt_timestamp() < 50000)

{

IOWR_ALTERA_AVALON_PIO_DATA(SIGNAL, 0x00);

}

while((alt_timestamp() > 49999) && (alt_timestamp() < 100000))

{

IOWR_ALTERA_AVALON_PIO_DATA(SIGNAL, 0x01);

}

}

return 0;

}

after that, i check the signal with a scope, but the period isn't stable

any idea how to solve that ?

thanks in advance

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'm not exactly sure how that timer counts, but it looks as though there will be a variable number of clock cycles between when you detect the count > 100000 and then set it to zero.

    You either need to get the couter to reset itself, or use a free-running counter and use modulo arithmetic to detect when the count gets reset.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    thanks for your response dsl, unfortunately that doesn't help me

    I try to get the time for "every" functions in this way :

    while(1)

    {

    alt_timestamp_start();

    int t1 = alt_timestamp();

    IOWR_ALTERA_AVALON_PIO_DATA(SIGNAL, 0x00);

    int t2 = alt_timestamp();

    IOWR_ALTERA_AVALON_PIO_DATA(SIGNAL, 0x01);

    int t3 = alt_timestamp();

    printf("%u %u\n%u %u\n\n", t1, t2, t3, t4);

    t4 = alt_timestamp();

    }

    and here is what the consoles displays me :

    1164 3399

    5294 67155888

    1129 3074

    5014 317099

    1124 3054

    4944 440449

    1129 3119

    5034 440119

    1144 3074

    4994 443629

    so it proves me that" IOWR_ALTERA_AVALON_PIO_DATA(..., ...)" never takes the same amount of time

    someone know if it is possible to fix a constant time for this function or in general for a function ?

    thanks in advance

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I presume you are running code from SDRAM through the instruction cache.

    This will give differing timings dependant on whether the code is cache resident or not. The last three sets of values are fairly similar.

    To get guaranteed execution times you really need to execute code from dedicated instruction memory (avoiding I-cache issues). You also need to worry about the branch predictor if you want cycle-accurate counts.

    However any Avalon MM cycles may also vary by a few clocks - if the target (slave) is busy.

    For the above code, all the time is spent in the timestamp routines and in printf(). The IOWR are probably 3 clocks (depending on the timings of your slave).

    If you want to count clocks, add a 32bit up-counter to your own slave device clocked by sys_clk, and read that directly. None of the 'standard' timer stuff is really appropriate for high res timestamps.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What is the amount of instability you observe in the square wave?

    I have a similar situation for a 1kHz wave and have very good stability, far below 1us.

    I use IOWR_ALTERA_AVALON_PIO_DATA, too, so I think this is not your actual problem. I'd rather think it's due to alt_timestamp function or to your nios/sopc configuration (as DSL suggested). Infact, I don't use alt_timestamp but I have tried the following solutions, both achieving similar stability:

    - pio controlled in timer interrupt service

    - polling directly the timer count register until switching condition is achieved, in the same way you did through alt_timestamp.

    Cris
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The actual 'instability' is most likely caused by the amount of time the 'timestamp' value is above 100000.

    This error will accumulate over time.

    The error due to the 220 sys_clk cycles spent in alt_timestamp() would only cause jitter.

    (It is that long because the hardware is implemented as two 16bit counter registers ...)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    What is the amount of instability you observe in the square wave?

    I have a similar situation for a 1kHz wave and have very good stability, far below 1us.

    --- Quote End ---

    the period of my wave is between 380 and 430 µs, assuming that in the future i'll need a 40 ns precision, i'm looking for sommething which can control the time of some signals frome the nios to operate with different hardware module

    but how ? i don't know for moment ...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Since you said your Nios is operating at 50MHz (then with a 20ns clock period), a requirement of 40ns precision is a bit too tight, even if your Nios is FULLY dedicated to generate that signal; that means Nios must constantly poll the timer and MUST NOT perform any other task!!!

    The usual approach in such cases is to generate your signals with a hardware module: i.e. you simply set the sq wave frequency and duty cycle and the hardware does all the job.

    Cris
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    for information, i get a better stability now by changing some settings, now I use a nios II/f with a 125MHz, do you think it will be enough for the application i told you above SEILASER

    does someone know where i can get the following information :

    what is the maximum frequency for a nios II/f with the cyclone III ep3c120f780c7n, i found around 165MHz but for another cyclone III

    thanks in advance for your help
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    for information, i get a better stability now by changing some settings, now I use a nios II/f with a 125MHz

    --- Quote End ---

    I have not enough experience to suggest you which core is better in your case. Surely /f is better for complex code since relies on features like cache and branch prediction.

    On the other hand, it uses much more LEs so I suppose it possibly needs to run at a slight lower frequency than /e.

    --- Quote Start ---

    do you think it will be enough for the application i told you above

    --- Quote End ---

    As I told before, it could be enough, but your application must be devoted only and totally to poll the timer in order to get the exact switching time.

    That means your Nios can't do any other task. IMHO it's a very inefficient way to use a processor!

    --- Quote Start ---

    does someone know where i can get the following information : what is the maximum frequency for a nios II/f with the cyclone III ep3c120f780c7n

    --- Quote End ---

    I also tried to find a specification about nios fmax but never found a clear one. From what I understood it depends from your project timings.

    I pushed without problems a Nios II/f to 100MHz; I think you can go beyond if you are smart and if you know how to work with Quartus timing constraints.

    Cris