Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,643 Views

SPI slave clock crossing domain?

I have a question about synchronization between clock domains in SPI slave. 

I need to design a SPI slave module, which has SS (slave select), SCK (SPI clock), SDI (data in from master), SDO (Data out from SPI slave). Also, in SPI slave module, it has a system clock name CLK. 

In SPI slave module, it has two clock domains: SCK and CLK. Those clocks are asynchronous, and frequency of CLK is much faster than frequency of SCK (frequency of CLK is 200Mhz, frequency of SCK is maximum 20MHz). 

 

I am intending to use 2 D-FlipFlops to synchronize SS, SCK, SDI from SPI clock domain to system clock domain, and all processing of SPI logic is handled in system clock domain (edge detection, FSM,... will be done at system clock domain). 

 

Could anyone answer me the following question? 

1. Is it OK if I use 2 D-FFs for synchronizing SS, SCK, SDI separately (2 D-FFs for SS, 2 D-FFs for SCK, 2 D-FFs for SDI)? 

2. After synchronization, at system clock domain, is there any possibility that SS, SCK and SDI signal do not have the same format as original SPI transaction? 

For example 

At SPI clock domain: Original SPI transaction: SS (High) -> SS (Low) -> SCK and SDI are input (L-> H -> L -> ...) 

At system clock domain: after synchronization: SS (High) -> SCK and SDI are input (L-> H -> L -> ...) -> SS (Low) 

 

I ask question 2 because I use 2 D-FFs for synchronizing SS, SCK, SDI separately. During synchronization, SS meets a meta-stability problem, so SS comes lately compare to SCK and SDI. 

It means that at system clock domain, the SPI transaction is not same as SPI clock domain. 

 

I am a newbie of SPI design. So my question may be amateur. But I think it is a basic question for SPI slave design.
0 Kudos
8 Replies
Altera_Forum
Honored Contributor I
210 Views

If you're implementing and SPI slave in the FPGA, with such a high system clock frequency (200MHz) - then I recommend you treat SCK as a signal, not a clock. Use your system clock to shift SCK through a shift register, allowing you to detect the clock edges. You can then shift data into or out of your system based on the position of these edges and (of course) the state of SS. 

 

The only (slightly) tricky aspect of such a scheme is deciding when to drive SDO when the host is trying to read from your slave peripheral. However, with such a high system clock to SCK frequency ratio you will have ample time to detect the clock edges and prepare the appropriate data for driving back to the master. 

 

Cheers, 

Alex
Altera_Forum
Honored Contributor I
210 Views

Using separate synchronizers for the SPI input signals is basically O.K. Standard SPI timing has sufficient margin to allow for skew and jitter in the resampled signals.  

 

I would be however worried about the uncomfortable high 200 MHz system clock, which can work for simple digital logic but isn't well suited as general system clock in my view. I have implemented 20 MHz SPI slave units with more compatible 40 MHz system clock, running the SPI unit in the SCK domain with domain crossing data path.
Altera_Forum
Honored Contributor I
210 Views

 

--- Quote Start ---  

If you're implementing and SPI slave in the FPGA, with such a high system clock frequency (200MHz) - then I recommend you treat SCK as a signal, not a clock. Use your system clock to shift SCK through a shift register, allowing you to detect the clock edges. You can then shift data into or out of your system based on the position of these edges and (of course) the state of SS. 

 

The only (slightly) tricky aspect of such a scheme is deciding when to drive SDO when the host is trying to read from your slave peripheral. However, with such a high system clock to SCK frequency ratio you will have ample time to detect the clock edges and prepare the appropriate data for driving back to the master. 

 

Cheers, 

Alex 

--- Quote End ---  

 

 

Thanks Mr.a_x_h_75 for giving your opinion. 

 

I initially select high system clock frequency (200 MHz) for treating SCK as a signal purpose. My intention is to move all SPI slave signals (SS, SCK, SDI) from SPI clock domain to system clock domain, then I will treat the moved SPI signals as signals at system clock domain. At system clock domain, I will detect the edge(s) of SCK, then I will process all SPI processing at system clock domain. 

 

I got your idea about SDO driving at system clock domain so that SPI master can detect data at SDO. 

 

Thanks.
Altera_Forum
Honored Contributor I
210 Views

 

--- Quote Start ---  

Using separate synchronizers for the SPI input signals is basically O.K. Standard SPI timing has sufficient margin to allow for skew and jitter in the resampled signals.  

--- Quote End ---  

 

 

Thanks Mr.FvM for this opinion. I got it. 

 

 

--- Quote Start ---  

I would be however worried about the uncomfortable high 200 MHz system clock, which can work for simple digital logic but isn't well suited as general system clock in my view. I have implemented 20 MHz SPI slave units with more compatible 40 MHz system clock, running the SPI unit in the SCK domain with domain crossing data path. 

--- Quote End ---  

 

 

I also have a little worry about system clock frequency (200 MHz). If I must select a high frequency for system clock so that it is just used for synchronizing SPI signals from SPI clock domain to system clock domain, this selection may not be suitable. 

 

As your information, your implementation has 2 clock domains separately: system clock domain ans SPI clock domain. The SPI logics are processed at SPI clock domain mainly. A domain crossing (synchronization) will be used if there is any data/control signal used between system clock domain and SPI clock domain. 

 

I will consider about your method of implementation in my design. 

 

Thanks.
Altera_Forum
Honored Contributor I
210 Views

I have done an SPI design using a 200MHz system clock in the past. It worked very well. IIRC, it was on a Virtex 4 

To answer the questions: 

1. Thats basically the only way to do it. 

2. There is enough margin to allow for this in SPI. At 200 MHz, a couple of clocks margin here or there is insignificant compared to the SCK
Altera_Forum
Honored Contributor I
210 Views

I agree, performing all operations using the 200MHz system clock should be fine especially given that the external SCLK is only 20MHz max. This allows you to avoid having to deal with clock crossings and like others have said with such a high system frequency that gives you many internal clocks of wiggle room.  

 

To time everything you could use a modulo counter running on the system domain then you determine which count values cause outputs to transition or inputs to be sampled on. This way if your timing is off you just change the counter thresholds to retime it. The counter can be used to generate the SCLK as well (if you have ever built a PWM it's the same idea). If your SCLK needs to be programmable then you would make these thresholds set with registers that you control with something outside of the core like a processor or whatever is running the show.
Altera_Forum
Honored Contributor I
210 Views

 

--- Quote Start ---  

I have done an SPI design using a 200MHz system clock in the past. It worked very well. IIRC, it was on a Virtex 4 

To answer the questions: 

1. Thats basically the only way to do it. 

2. There is enough margin to allow for this in SPI. At 200 MHz, a couple of clocks margin here or there is insignificant compared to the SCK 

--- Quote End ---  

 

 

Thanks Mr.Tricky for giving your opinion! 

 

 

--- Quote Start ---  

 

1. Thats basically the only way to do it. 

2. There is enough margin to allow for this in SPI. At 200 MHz, a couple of clocks margin here or there is insignificant compared to the SCK 

--- Quote End ---  

 

 

Your answers are very short, but they are clear and enough information that I need!
Altera_Forum
Honored Contributor I
210 Views

 

--- Quote Start ---  

I agree, performing all operations using the 200MHz system clock should be fine especially given that the external SCLK is only 20MHz max. This allows you to avoid having to deal with clock crossings and like others have said with such a high system frequency that gives you many internal clocks of wiggle room.  

--- Quote End ---  

 

 

I got it. 

 

 

--- Quote Start ---  

To time everything you could use a modulo counter running on the system domain then you determine which count values cause outputs to transition or inputs to be sampled on. This way if your timing is off you just change the counter thresholds to retime it. The counter can be used to generate the SCLK as well (if you have ever built a PWM it's the same idea). If your SCLK needs to be programmable then you would make these thresholds set with registers that you control with something outside of the core like a processor or whatever is running the show. 

--- Quote End ---  

 

 

Thanks Mr.BadOmen for this advice. I will consider this fact in my design if there is a need.