Clocked ports, sampling on rising clock

Technical discussions around xCORE processors (e.g. xcore-200 & xcore.ai).
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

ale500 wrote:A have another question, the manual says that inputs can sample at 60MHz from an external clock... does it means that we can sample at higher frequencies from the 100 MHz reference clock ?
I think that it should be possible to sample at higher rates. If my understanding is right. instead of using the 100Mhz ref clock as default.

It is possible to sample with an external clock right?, but in the manual it says that an external clock will be sampled with the internal 400Mhz of the core.

Why was it said that the clock block is limited to 50?


I am confused... so Now I dont understand what would be the maximum possible sampling rate for an input. :-(

Wouldnt we be able to sample at at least 200Mhz if the internal sampling of the clock is 400?


ale500
Respected Member
Posts: 259
Joined: Thu Sep 16, 2010 9:15 am

Post by ale500 »

The IO clock is only 100 MHz, while it can be changed and raised we do not know how it affects i/o.

here is the test program and a trace of a small sample program that uses the 100 MHz reference clock with a buffered 8 bit port.

Code: Select all

/*
 ============================================================================
 Name        : xc1-prototype.xc
 Description : Prototype code for the XC-1 board 
 ============================================================================
 */

#include <xs1.h>
#include <platform.h>
#include <stdio.h>

on stdcore[0]: in buffered port:32 pDATA = XS1_PORT_8C;
on stdcore[0]: out port pCLK = XS1_PORT_1E;
on stdcore[0]: out port pCS = XS1_PORT_1F;

on stdcore[0]: clock clCLK = XS1_CLKBLK_REF;

void test_100MHz( void )
{
unsigned data0, data1, data2, data3;

    configure_in_port_no_ready(pDATA, clCLK);
    configure_out_port_no_ready(pCS, clCLK, 0);
    configure_port_clock_output(pCLK, clCLK);

    pCS <: 1;
    pCS <: 0;
    pDATA :> data0;
    pDATA :> data0;
    pDATA :> data0;
    pDATA :> data0;
    pCS <: 1;

    printf("%x %x %x %x", data0, data1, data2, data3);
}

int main(void)
{
    par
    {
        on stdcore[0]: test_100MHz();
    }
    return 0;
}

Code: Select all

0@0@0   A-.----000100e0 (test_100MHz         + 34) : mkmsk   r3(0x1), 0x1 @5593
0@0@0   A-.----000100e2 (test_100MHz         + 36) : out     res[r0(0x10400)], r3(0x1) @5597
0@0@0   A-.----000100e4 (test_100MHz         + 38) : ldc     r1(0x0), 0x0 @5601
0@0@0   A-.----000100e6 (test_100MHz         + 3a) : out     res[r0(0x10400)], r1(0x0) @5605
0@0@0   A-.----000100e8 (test_100MHz         + 3c) : ldw     r2(0x80200), dp[0x3] L[0x14b00] @5609
0@0@0   A-.----000100ec (test_100MHz         + 40) : setc    res[r2(0x80200)], 0x1 @5617
0@0@0   A-.----000100ee (test_100MHz         + 42) : in      r1(0x0), res[r2(0x80200)] @5621
0@0@0 P A-.----000100f0 (test_100MHz         + 44) : in      r1(0x0), res[r2(0x80200)] @5625
0@0@0   A-.----000100f0 (test_100MHz         + 44) : in      r1(0x0), res[r2(0x80200)] @5639
0@0@0 P A-.----000100f2 (test_100MHz         + 46) : in      r1(0x0), res[r2(0x80200)] @5643
0@0@0   A-.----000100f2 (test_100MHz         + 46) : in      r1(0x0), res[r2(0x80200)] @5655
0@0@0 P A-.----000100f4 (test_100MHz         + 48) : in      r1(0x0), res[r2(0x80200)] @5659
0@0@0   A-.----000100f4 (test_100MHz         + 48) : in      r1(0x0), res[r2(0x80200)] @5671
0@0@0   A-.----000100f6 (test_100MHz         + 4a) : out     res[r0(0x10400)], r3(0x1) @5675
Note how the thread is waiting for IO till the right cycle comes. the INs are thus 16 cycles apart (4 bytes at 100 MHz each). So, at least it seems to work... The question is now how the other threads affect this timing.
MaxFlashrom
Experienced Member
Posts: 82
Joined: Fri Nov 05, 2010 2:59 pm

Post by MaxFlashrom »

ale500 wrote:The IO clock is only 100 MHz, while it can be changed and raised we do not know how it affects i/o.

here is the test program and a trace of a small sample program that uses the 100 MHz reference clock with a buffered 8 bit port.

Note how the thread is waiting for IO till the right cycle comes. the INs are thus 16 cycles apart (4 bytes at 100 MHz each). So, at least it seems to work... The question is now how the other threads affect this timing.
The XMOS PLL/Clocking document appears to suggest that one is allowed to adjust the reference clock up to the system clock frequency(the specification of its upper bound) The reference clock clocks ports and timers. Raising the reference clock rate is only really of interest for buffered ports as processor in instructions take 10ns(4 cycles of system clock) so one could not perform ins faster than 100MHz like this. However, with buffered ports, if it works then individual bits of the port would be clocked in or out faster if one raised the reference clock frequency. This would allow faster buffered I/O.

One can test if raising the reference clock frequency works for timers by using a timer and timing say 100 NOPs, while keeping System clock normal. This would increase the timer resolution of timers at the cost not allowing such long delays. I have tested timing NOPs while raising the System clock frequency, keeping the reference clock at 100MHz and this works, telling one if one is running at 400MHz or 500MHz.

One can test if the faster buffered I/O works(with raised reference clock frequency) by performing several back-to-back in instructions on a buffered port, but remember if you're using a timer to time this, its frequency will be raised too. Giving the same timing value, so one would need to run previous test to confirm faster timer counting before having confidence in the result.

Other threads should not impact I/O timing, as far as I understand, Ins will be performed when the internal buffers are full.
I've not tested this stuff yet, I'd be interested if someone can confirm.(Warning this is somewhat undocumented and might make your hardware HOT) Incidentally I have overclocked(Sytem Clock) a 400MHz L1 at 500MHz(initially by mistake - XN file intented for C5) without ill effects. The processor was still very cool and the processor appeared to operate normally(This may not be reliable/may shortlen processor life/is not technically "in spec"/you may break stuff, but hey:
Live Fast! Burn Bright! Die Young!

Max.
ale500
Respected Member
Posts: 259
Joined: Thu Sep 16, 2010 9:15 am

Post by ale500 »

Using the code posted in the cited document (seen below) no change can be seen. Of course it could be that the simulator does not acknowledge the changes to the reference clock divider...

Code: Select all

#define REFDIV_REGNUM 8

write_sswitch_reg(get_core_id(), REFDIV_REGNUM, 0x01);
Edit: Bigger values, i.e. 5 have also no effect on the simulated instruction timing. Needs testing on real hardware :)
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm

Post by rubenc »

MaxFlashrom wrote: The XMOS PLL/Clocking document appears to suggest that one is allowed to adjust the reference clock up to the system clock frequency(the specification of its upper bound)
Wich will allow to adjust reference clock up to 400Mhz(default system clock) without actually overclocking it right?
MaxFlashrom wrote: The reference clock clocks ports and timers. Raising the reference clock rate is only really of interest for buffered ports as processor in instructions take 10ns(4 cycles of system clock) so one could not perform ins faster than 100MHz like this. However, with buffered ports, if it works then individual bits of the port would be clocked in or out faster if one raised the reference clock frequency. This would allow faster buffered I/O.
This would be great, because I am not aiming to make INs faster but just being able to capture the port content faster into the buffer.
MaxFlashrom wrote: Other threads should not impact I/O timing, as far as I understand, Ins will be performed when the internal buffers are full.
This means that each thread can have different reference clock?
MaxFlashrom wrote: I've not tested this stuff yet, I'd be interested if someone can confirm.
I will try to make some tests, and I will come back with the results. But how can I setup the reference clock to its 400mhz maximum?... not the system clock... I dont want to overclock.
ale500
Respected Member
Posts: 259
Joined: Thu Sep 16, 2010 9:15 am

Post by ale500 »

Try this (for 200 MHz):

Code: Select all

/*
============================================================================
Name        : xc1-prototype.xc
Description : Prototype code for the XC-1 board 
============================================================================
*/

#include <xs1.h>
#include <platform.h>
#include <stdio.h>

on stdcore[0]: in buffered port:32 pDATA = XS1_PORT_8C;
on stdcore[0]: out port pCLK = XS1_PORT_1E;
on stdcore[0]: out port pCS = XS1_PORT_1F;

on stdcore[0]: clock clCLK = XS1_CLKBLK_REF;
#define REFDIV_REGNUM 8

void test_100MHz( void )
{
unsigned data0, data1, data2, data3;

    write_sswitch_reg(get_core_id(), REFDIV_REGNUM, 0x01);
    configure_in_port_no_ready(pDATA, clCLK);
    configure_out_port_no_ready(pCS, clCLK, 0);
    configure_port_clock_output(pCLK, clCLK);

    pCS <: 1;
    pCS <: 0;
    pDATA :> data0;
    pDATA :> data1;
    pDATA :> data2;
    pDATA :> data3;
    pCS <: 1;

    printf("%x %x %x %x", data0, data1, data2, data3);
}

int main(void)
{
    par
    {
        on stdcore[0]: test_100MHz();
    }
    return 0;
}
And measure the width of the pulse on pCS.

The reference clock is for the whole xcore and does not belong to a particular thread.
MaxFlashrom
Experienced Member
Posts: 82
Joined: Fri Nov 05, 2010 2:59 pm

Post by MaxFlashrom »

MaxFlashrom wrote: The XMOS PLL/Clocking document appears to suggest that one is allowed to adjust the reference clock up to the system clock frequency(the specification of its upper bound)
rubenc wrote: Wich will allow to adjust reference clock up to 400Mhz(default system clock) without actually overclocking it right?
If it's not lying that would be the implication. Whether it works is another matter. In any case trying to sample signal changing faster than 100MHz ie clocking with a reference clock above 200MHz won't work if the pin is first sampled into the XS1 clock domain on the 400MHz system clock(as it is when clocking internal clock blocks. These may just be D-flip flops). If the ports are strictly clocked off the reference clock independently of the system clock this would also theoretically also only allow input at up to 200MHz(at 50% duty cycle) as one needs > 2 clocks / (cycle of sampled signal)
There may be more than one flip-flop in series there for reasons of metastability when sampling into the XS1 clock domain which may limit the sampling speed. When sampling a clock from an external pin, as you say, the data sheets says 60MHz which is rather less than (400MHz / 2)
MaxFlashrom wrote: The reference clock clocks ports and timers. Raising the reference clock rate is only really of interest for buffered ports as processor in instructions take 10ns(4 cycles of system clock) so one could not perform ins faster than 100MHz like this. However, with buffered ports, if it works then individual bits of the port would be clocked in or out faster if one raised the reference clock frequency. This would allow faster buffered I/O.
rubenc wrote: This would be great, because I am not aiming to make INs faster but just being able to capture the port content faster into the buffer.
MaxFlashrom wrote: Other threads should not impact I/O timing, as far as I understand, Ins will be performed when the internal buffers are full.
rubenc wrote: This means that each thread can have different reference clock?
No, there is only one reference clock.
MaxFlashrom wrote: I've not tested this stuff yet, I'd be interested if someone can confirm.
rubenc wrote: I will try to make some tests, and I will come back with the results. But how can I setup the reference clock to its 400mhz maximum?... not the system clock... I dont want to overclock.
You can try changing it in the XN file rather than writing to the registers directly.

See https://www.xmos.com/published/xs1-l-cl ... cy-control

Max.
ale500
Respected Member
Posts: 259
Joined: Thu Sep 16, 2010 9:15 am

Post by ale500 »

Using the code below I see that the reference clock can be effectively switched from 100 to 200 MHz.

At 100 MHz the pCS pin has high periods of 170 ns and low periods of 150 ns.
At 200 MHz the pCS pin has a high period of 100 ns then a low of 90, then a high of 80 then a low of 70 and then it starts over from 100 ns high.


Code: Select all

/*
 ============================================================================
 Name        : xc1-flashing-led.xc
 Description : Flashing LED program for the XC-1 board 
 ============================================================================
 */

#include <platform.h>
#include <xs1.h>
#include <stdio.h>

#define FLASH_PERIOD 20000000
#define REFDIV_REGNUM 8

on stdcore[0]:out port cled0 = PORT_CLOCKLED_0;
on stdcore[0]:out port cledG = PORT_CLOCKLED_SELG;
on stdcore[0]:out port cledR = PORT_CLOCKLED_SELR;

void blinkled(void) {
  timer tmr;
  unsigned ledGreen = 1;
  unsigned t;
  write_sswitch_reg(get_core_id(), REFDIV_REGNUM, 0x01);
  tmr :> t;
  while (1) {
    cledG <: ledGreen;
    cledR <: !ledGreen;
    cled0 <: 0x1;
    t += FLASH_PERIOD;
    tmr when timerafter(t) :> void;
    ledGreen = !ledGreen;
  }
  return 0;
}

/*
============================================================================
Name        : xc1-prototype.xc
Description : Prototype code for the XC-1 board
============================================================================
*/


on stdcore[2]: in buffered port:32 pDATA = XS1_PORT_8C;
on stdcore[2]: out port pCLK = XS1_PORT_1E;
on stdcore[2]: out port pCS = XS1_PORT_1F;
on stdcore[2]: out port pSlowCLK = XS1_PORT_1G;

on stdcore[2]: clock clCLK = XS1_CLKBLK_REF;
on stdcore[2]: clock slowCLK = XS1_CLKBLK_1;

void test_100MHz( void )
{
unsigned data0, data1, data2, data3;

	set_clock_div(slowCLK, 20);
    configure_port_clock_output(pSlowCLK, slowCLK);
    configure_in_port_no_ready(pDATA, clCLK);
    configure_out_port_no_ready(pCS, clCLK, 0);
    configure_port_clock_output(pCLK, clCLK);
    start_clock(slowCLK);

    while (1)
    {
    	pCS <: 0;
    	pDATA :> data0;
    	pDATA :> data1;
    	pDATA :> data2;
    	pDATA :> data3;
    	pCS <: 1;
		pDATA :> data0;
        pDATA :> data1;
        pDATA :> data2;
        pDATA :> data3;
    }
    printf("%x %x %x %x", data0, data1, data2, data3);
}

int main(void)
{

    par
    {
    	on stdcore[0]: blinkled();
        on stdcore[2]: test_100MHz();
    }
    return 0;
}
MaxFlashrom
Experienced Member
Posts: 82
Joined: Fri Nov 05, 2010 2:59 pm

Post by MaxFlashrom »

I have tried raising the reference clock and it does do exactly as expected.

Code: Select all

#define REFDIV_REGNUM 8
out buffered port:32 clk_out_port = XS1_PORT_1I;
void doFastOutputs()
{
	// write_sswitch_reg(get_core_id(), REFDIV_REGNUM, 0x01); // 200 MHz reference clock
	write_sswitch_reg(get_core_id(), REFDIV_REGNUM, 0x00); // 400 MHz reference clock

	while(1) {
		clk_out_port <: 0xaaaaaaaa;
	}
}

This makes a valiant attempt at outputting a 200MHz clock on PORT1I, ie. each bit is clocked out at 400MHz. The limits of my 'scope, its probe capacitance/ board capacitance where struggling to keep up though.

The port buffer should be emptied in 32 * 2.5ns = 80ns which is the time in which the processor executes 8 instructions(running on a 400MHZ core clock)
The assembler generated for the clock loop was rather less than optimal, but still fast enough to avoid output under-run. With shorter buffered port lengths this will be more critical.

Changing the loop to

Code: Select all

	while(1) {
		clk_out_port <: 0x0;
		clk_out_port <: 0xffffffff;
	}
outputs a nice 400/64 = 6.25MHz clock, as expected.

I haven't tested the effect on timers which should also be running faster. This is not really useful, though, as one can only input from timers at machine instruction intervals of 10ns so making them tick faster than this offers no benefit. Similarly a " tmr :> when timerafter" instruction may flag an event with greater resolution but can only be acted upon at the next instruction.

Max.
ale500
Respected Member
Posts: 259
Joined: Thu Sep 16, 2010 9:15 am

Post by ale500 »

Did you get the clock output in a pin, the reference clock ?