Accuracy of xsim with modified clock settings

Technical questions regarding the XTC tools and programming with XMOS.
brendangillatt
New User
Posts: 2
Joined: Thu Apr 25, 2024 9:46 am

Accuracy of xsim with modified clock settings

Post by brendangillatt »

Hi XMOS team,

I am developing an application that needs to support a configurable bit-rate parallel output port, on an XU316 series device.

To achieve the variable bit-rate, I am planning to modify the main PLL settings. There appears to be enough flexibility in this main PLL to maintain a nearly 100 MHz REFCLK and a nearly 600 MHz system clock, while generating the desired bit rate for my application.

However, I am having a little difficulty demonstrating a successful PLL switch in the XSIM simulator.

If I change the main PLL settings, I would expect that the CLKBLK0 (CLKBLK_REF) would also change in a similar fashion, since it is derived from the main PLL by default. However, if I run my example application in the simulator I do not see a change. I am fairly new to XMOS development, so I do not yet know if it is because I am incorrectly setting the PLL, or if it is because the XSIM simulator does not model a change in clocks.

I noticed in the docs for the XMOS tools, the following statement:
"The tools include a near cycle-accurate hardware simulator XSIM. XSIM simulates of entire XMOS device, and may also simulate certain external devices such as a QSPI flash memory."

Could you expand on what "near cycle-accurate" means in this context?

For reference, my code to run the test is below.

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <xcore/hwtimer.h>
#include <xcore/port.h>
#include <platform.h>
#include <xscope.h>
#include <xcore/chanend.h>

void main_pll_init(void)
{
    const uint32_t tileid = get_local_tile_id();

    // Register setting to disable PLL while we change settings.
    const uint32_t pll_ctrl_disable = 
        (1    << 31) | // Do not reset
        (0    << 30) | // Wait for lock
        (0    << 29) | // No boot from JTAG
        (1    << 28) | // PLL bypass
        (2    << 23) | // OD = 2 (/3)
        (2766 << 8)  | // F = 2766 (x2767)
        (54   << 0);   // R = 54 (/55)

    // Re-enable PLL
    const uint32_t pll_ctrl = 
        (1    << 31) | // Do not reset
        (0    << 30) | // Wait for lock
        (0    << 29) | // No boot from JTAG
        (0    << 28) | // No PLL bypass
        (2    << 23) | // OD = 2 (/3)
        (2766 << 8)  | // F = 2766 (x2767)
        (54   << 0);   // R = 54 (/55)

    write_sswitch_reg(tileid, XS1_SSWITCH_PLL_CTL_NUM, pll_ctrl_disable);

    hwtimer_t timer = hwtimer_alloc();
    {
        hwtimer_delay(timer, 100000); // 1ms with 100 MHz timer tick
    }
    hwtimer_free(timer);

    write_sswitch_reg(tileid, XS1_SSWITCH_PLL_CTL_NUM, pll_ctrl);
}

void main_t0(chanend_t c_xscope_host)
{
    clock_enable(XS1_CLKBLK_1);
    clock_start(XS1_CLKBLK_1);

    clock_enable(XS1_CLKBLK_2);
    clock_start(XS1_CLKBLK_2);

    clock_enable(XS1_CLKBLK_3);
    clock_start(XS1_CLKBLK_3);

    main_pll_init();

    hwtimer_t timer = hwtimer_alloc();
    hwtimer_delay(timer, 100000);
    hwtimer_free(timer);
}


void main_t1(chanend_t c_xscope_host)
{
    return;
}
This is designed to set the main PLL output to:

Code: Select all

Fcore = Fosc * (F+1)/2 * 1/(R+1) * 1/(OD+1)
Fcore = 24 Mhz * (2766+1)/2 * 1/(54+1) * 1/(2+1) = 201.2 MHz.
Note that in my real application, I will be setting OD = 0, which gives an Fcore of 603.7 MHz, but I wanted to make a larger change to the PLLs to make the change more visible in the simulation.

I then run this with xsim, and output to a VCD file:

Code: Select all

xsim --vcd-tracing '-o trace.vcd -pads -tile tile[0] -ports-detailed -clock-blocks -tile tile[1] -ports-detailed -tile tile[1] -clock-blocks' bin/Release/ap_clock_test.xe
When I open the output of the XSIM waveforms, I would expect to be able to see the tile[0]_ClkBlk0_fallEdge waveform change from having a roughly 10 ns period (100 MHz) to having a roughly 29.8 ns period (33.53 MHz). However, this does not appear to be happening.

Is my PLL code wrong? Am I driving the simulator incorrectly? Or does the simulator not model these factors?


Joe
Member++
Posts: 27
Joined: Sun Dec 13, 2009 1:12 am

Post by Joe »

As you've seen xsim certainly won't be able to handle dynamic changes to the PLL settings. I would think the relevant PLL settings would have to be set by specifying the tile clock you need in the XN file for the project, you could try specifying the exact frequency you need in there, you can specify in kHz or Hz if you need to and the tools should have a good effort at finding the right PLL settings automatically.

As a side note you will start to see increasing levels of clock jitter with such a high ref divider - The input to the phase frequency comparator will be 24MHz/55 = 436kHz which is quite a low frequency for the PLL loop filter to filter out so a lot of that PFC update noise will make it into the PLL output. Generally I try to keep the PFC frequency above about 1MHz. It should all still work though if your application isn't sensitive to the jitter.

Joe
brendangillatt
New User
Posts: 2
Joined: Thu Apr 25, 2024 9:46 am

Post by brendangillatt »

Joe,

Thank you for your quick and detailed response. That's saved me a lot of days of head-scratching!

Okay I think I can make do with the .xn file parameters for now and get the final bits of the PLL configured when I get hold of some hardware. Good point about about phase noise. My clock calculator shows that I have plenty of PLL options that achieve a reference frequency above 1 MHz. I'll be doing some more thorough evaluation of these parameters once I've de-risked the main concept.

Thanks again
Brendan