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;
}
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.
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
Is my PLL code wrong? Am I driving the simulator incorrectly? Or does the simulator not model these factors?