Requesting inforamtion regarding ti_clk / hi_clk

Hello,

(XEM3010-1500P)

We plan to clock our design from the host interface clock (hi_clk, ti_clk) to avoid domain clock crossing.

Since you don’t publish the board schematic, can you provide more details about that clock:

1.What is the right clock to use for a synchronous circuit that interface with the OK end points, ti_clk or hi_clk? (our experiments show that using hi_clk results in unstable data (clock skew?), ti_clk seems to work fine).

2.What may cause ti_clk to be gated or having other irregularities? (we plan to use it for a time sensitive application). For example, we noticed that disconnecting the USB 2.0 link stops ti_clk.
3.Does ti_clk derive from the on board 24MHz crystal? from some USB bus signal? We try to understand how dependable the source is.
4.What is the frequency, tolerance and duty cycle of the ti_clk?
5.Any reason why we should not use the ti_clk to clock our design?

Thanks,

Kam

Hi Kam-

TI_CLK and HI_CLK are really the same. They come from the Cypress USB device which uses the on-board 24 MHz crystal to generate the 48 MHz signal for the host interface. At the moment, they are tied together (within the host interface HDL module), but we wanted to leave open the option to disjoin them. Generally you should use TI_CLK since that’s the “target interface” clock. HI_CLK is “reserved” for the host interface, but again, they’re the same right now.

You may want to use a DCM if your application will use them a fair bit. The DCM will help minimize on-chip clock skew to the board-level signal.

To answer your questions:

  1. For pipes, use ti_clk. For triggers, you provide any clock you want. For wires, there is no clock since these are officially asynchronous signals. To synchronize data with them, you should do something like:
    xem->UpdateWireIns(); // Setup the wire in values
    xem->ActivateTriggerIn(xxx, xxx); // Latch the wire ins.

For wire signals, this accomplishes the same thing with very little performance penalty. The reliability factor is typically worth the penalty.

  1. Generally, the TI_CLK will only disappear if the device (USB micro) is placed in suspend mode by the host. If you’re having trouble with this occurring, please contact us ([email protected]) and we can try to figure out why this is happening.

  2. It is derived from the 24 MHz crystal by the USB microcontroller.

  3. The crystal is +/- 100ppm. output from the USB micro should be 45% to 55% duty cycle but you’ll typically see 50% pretty steady.

  4. Not really. But, if your design really is time sensitive (how time sensitive?), we would advise supplying a clock that meets your guidelines. The clock system on the XEM devices are good for digital systems, but they are not tightly constrained.

If you have constraints to meet with your clock, I would recommend supplying it externally. From your previous posts, it does not sound as though your design needs to transfer data to the PC very quickly. Is there a reason that the wire/trigger combination will not work for your application?

Also, users typically prefer to use pipes to transfer data to/from FIFOs in a synchronous manner. Is this what you’re doing?

TI_CLK and HI_CLK are really the same. They come from the Cypress USB >device which uses the on-board 24 MHz crystal to generate the 48 MHz >signal for the host interface. At the moment, they are tied together (within >the host interface HDL module), but we wanted to leave open the option to >disjoin them. Generally you should use TI_CLK since that’s the “target >interface” clock. HI_CLK is “reserved” for the host interface, but again, >they’re the same right now.

At one point I got unstable readings when I clock by circuit (fully synchronized, single clock) on hi_clk and it was solved when I switched to ti_clk. I tried to reproduce it now but could not. Maybe the flow add some buffer between them (??). Anyway, we are using ti_clk now and I believe this is safer.

You may want to use a DCM if your application will use them a fair bit. The >DCM will help minimize on-chip clock skew to the board-level signal.

Thanks for the pointer. Currently all of our I/O is asyncrhonous so the clock is used only within the chip.

To answer your questions:

  1. For pipes, use ti_clk. For triggers, you provide any clock you want. For >wires, there is no clock since these are officially asynchronous signals. To >synchronize data with them, you should do something like:
    xem->UpdateWireIns(); // Setup the wire in values
    xem->ActivateTriggerIn(xxx, xxx); // Latch the wire ins.

For wire signals, this accomplishes the same thing with very little >performance penalty. The reliability factor is typically worth the penalty.

I am clocking my design on ti_clk so I presume it is safer to assume that wire in/out are synchronous on the positive edge of ti_clk, right? (that is, no need to latch with a triger in).

  1. Generally, the TI_CLK will only disappear if the device (USB micro) is >placed in suspend mode by the host. If you’re having trouble with this >occurring, please contact us ([email protected]) and we can try to >figure out why this is happening.

I am not sure what can cause the host to put the device in ‘suspend mode’. I am using a Ubuntu based Linux server. Hopefully it does not do that. I noticed it when I disconect the USB cable.

Since there is such advantage of using the ti_clk for user designs (everything is synchronous on the same clock), you may want to consider having the ti_clk running continiously. This can also be the first choice of user clock unless the user must have a differnt clock.

  1. It is derived from the 24 MHz crystal by the USB microcontroller.

  2. The crystal is +/- 100ppm. output from the USB micro should be 45% to >55% duty cycle but you’ll typically see 50% pretty steady.

Thanks, 100ppm should be good enough for us.

  1. Not really. But, if your design really is time sensitive (how time sensitive?), >we would advise supplying a clock that meets your guidelines. The clock >system on the XEM devices are good for digital systems, but they are not >tightly constrained.

We are using a very accurate 1PPS (pulse per second) time base so we can only about the monotonicity of the XEM3010 over a period of 1 sec (we compensate out basic inaccuracy of long time drift) so I think we should be
ok with the current ti_clk.

If you have constraints to meet with your clock, I would recommend >supplying it externally. From your previous posts, it does not sound as >though your design needs to transfer data to the PC very quickly. Is there a >reason that the wire/trigger combination will not work for your application?

It should work (though we don’t need it since we are clocking on ti_clk). However, you can write once a cross clock domain synchronous wire in/out and your users will reuse it many times (avoiding the extra trigger update, extra buffer in the FPGA, etc). Kind of work for you and simplicity for us :wink:

Also, users typically prefer to use pipes to transfer data to/from FIFOs in a >synchronous manner. Is this what you’re doing?

I followed your advice and Coregen’ed a FIFO (single clock, 32K * 16bit, with data count output). It seems to work very well and the board and the computer talks very efficently. 32K*16 was the max I could fit into the FPGA, probably we will need to make things a little bit more complicated and implement an SDRAM based FIFO for larger depth. We will base it on your SDRAM controller module unless you already have a design for a SDRAM based FIFO with count output (hint, hint ;-))

We currently have a working prototype that covers all the risky elements of the design (other than the SDRAM based FIFO). Overall the development was a pleasure and we enjoyed working with your HDL and host side abstractions of the USB communication. Next step is to get it to production quality.

Thanks for your help,

Kam

What is a good source for the Samtec BTE-040-01-F-D-A connectors? (currently samples, later hundrads).

Have you consider to sell samples as you do with the headers ?

Thanks,

Kam

Actually, we will start selling the lower-profile headers soon.

These Samtec headers come in five heights (completed assembly height from PCB to PCB). We use the non-adjustable side of the pair on the XEM3010.

Samtec provides a very easy service called “Sudden Samples” to get low quantities of almost any connector they sell. In higher volumes, they can be purchased through standard electronics distributors such as Avnet.

Kam-

After the release of our 1.3 firmware, we discovered a change that caused some stability problems with the host interface. We recently corrected this with 1.4 firmware (XEM3010). I don’t know if your stability problems were related to this change. It had to do with the relative timings between the data and clock used on the host interface.

To clarify on the Wire synchronization bit. Our abstraction does not define a clock for the wire updates. Therefore, logic to reliably transfer data from a wire’s clock domain to a user’s clock domain takes on little meaning. Within the context of the USB-based stuff, it has a bit more meaning due to the implementation, but we did not want the abstraction to be committed to any particular implementation.

There are two ways, I would envision reliable transfer of an asynchronous signal to a clock domain:

  1. Using the trigger method we have previously discussed. Since the wire update and trigger are properly sequenced, the wire data is guaranteed to be stable when the trigger arrives.

  2. Using sequential logic to detect a change in the state of the wire signals and latch the data on the clock domain once these signals have stabilized.

An interesting thing occurred to me – it would be possible to provide a fixed TriggerIn to the user’s hardware that is triggered any time WireIns are updated. This technique has two advantages:

A) It would not require an additional API call and therefore no additional USB transactions.

B) It does not “violate” the abstraction. The user logic is notified in the correct manner (using triggers which support safe clock domain transfer).

Comments?

Thanks for the pointers. I will check with Samtex and Avnet (and also your site it case it will show up one day ;-)).

Actually, we will start selling the lower-profile headers soon.

These Samtec headers come in five heights (completed assembly height from >>PCB to PCB). We use the non-adjustable side of the pair on the XEM3010.

Samtec provides a very easy service called “Sudden Samples” to get low >>quantities of almost any connector they sell. In higher volumes, they can be >>purchased through standard electronics distributors such as Avnet.

After the release of our 1.3 firmware, we discovered a change that caused >>some stability problems with the host interface. We recently corrected this >>with 1.4 firmware (XEM3010). I don’t know if your stability problems were >>related to this change. It had to do with the relative timings between the >>data and clock used on the host interface.

Thanks. I am currently running 1.3. Will upgrade to 1.4. However, since I could not reproduce the problem, I will not be able confirm the fix.

To clarify on the Wire synchronization bit. Our abstraction does not define >>a clock for the wire updates. Therefore, logic to reliably transfer data from >>a wire’s clock domain to a user’s clock domain takes on little meaning. >>Within the context of the USB-based stuff, it has a bit more meaning due >>to the implementation, but we did not want the abstraction to be >>committed to any particular implementation.

There are two ways, I would envision reliable transfer of an asynchronous signal to a clock domain:

  1. Using the trigger method we have previously discussed. Since the wire >>update and trigger are properly sequenced, the wire data is guaranteed to >>be stable when the trigger arrives.

This would work though it require some ‘hassle’ (isuing the USB trigger in transaction, adding buffers on the user side, etc).

  1. Using sequential logic to detect a change in the state of the wire signals >>and latch the data on the clock domain once these signals have stabilized.

I am not sure how this will work. When the data stabalized, it is saved until when? What if it changes exactly when the wires are read ? What about wire ins ?

An interesting thing occurred to me – it would be possible to provide a >>fixed TriggerIn to the user’s hardware that is triggered any time WireIns >>are updated. This technique has two advantages:

A) It would not require an additional API call and therefore no additional >>USB transactions.

B) It does not “violate” the abstraction. The user logic is notified in the >>correct manner (using triggers which support safe clock domain transfer).

I think this would work. It is somewhat related to my question from May 19 in the other forum “…is there any singal available (it_control?) that indicates when the wires are sampled so I can freeze the value during this period?”.

Basically this will be a trigger, in the user clock domain(s), that will indicate that wire are going to be written or read. It will make sure that in each user clock domain (in case the user has multiple), all the in/out wires are read/written on the same user clock (alowing values wider than 16 bit by using multiple eps).

I would approach this issue from the user perspective. What will be the easiest, most intuitive, and with least hassle way for users to interface to wire in/out eps from their own clock domain(s).

My guess is that having a syncrhonized wire in/out ep close to the top of the list:

  1. It will have the same interface as the existing async wire in/out ep with the addition of a new input for user clock

  2. It does not require extra USB transaction or extra user buffer or logic.

  3. It will guarantee that all the syncronized wire in/out attached t the same user clock will be read / written on the same user clock edge (can you do that?)

If you can achive that, this would probably be the easiest appraoch from user perspective. Basically all the ep’s will have isolating ti_clk and usr_clk(s). I think will be a nice generalization of your abstraction (no more distinction between synchronous and asyncrhonous ep’s).

Does this make any sense?

Kam

Hi Kam-

While I would agree that some users want a synchronized wire type signal, the fact remains that asynchronous signals exist in digital designs and are certainly tolerable. The added cost to synchronize all of them is not necessarily required.

Case in point - all of our designs (internally and for clients) use wire ins/outs for many things. In only a few cases do we “wrap” the signal with a trigger.

The synchronous transfer is provided by pipes, so the framework certainly does not lack the capability. The trigger “wrapping” provided at the firmware level would be a convenience option. Having all wires turned synchronous to an arbitrary clock domain would add unnecessary overhead, in particular when the functionality is already present elsewhere.

Synchronizing async signals is a problem as old as logic, really, and the solution has always been to hit the nail with the smallest hammer that would do the job. Debouncing pushbuttons and switches mostly worked for those cases. For multi-bit signals, more elaborate schemes that looked at the signal conditions over time are employed.

Wires are “pseudo-synchronous”, so the problem is much simpler.