UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor haul
Visitor
14,098 Views
Registered: ‎11-01-2010

High speed SPI slave

Jump to solution

I want to create an SPI slave interface which can dump data into onboard RAM. The expected SCLK frequency is 66Mhz – 100Mhz, so I’m not sure if I can safely receive data by oversampling from the FPGA clock.*

 

My first thought was to use a coregen FIFO with independent clocks to handle putting stuff into block RAM, as well as the clock domain crossing issue, but the FIFO user guide warns that “The FIFO Generator is designed to work only with free-running write and read clocks. Xilinx does not recommend controlling the core by manipulating RD_CLK and WR_CLK”.**

 

Right now I’m thinking that the easiest robust solution is to accumulate 8 or 16 bits at a time (depending on my data width) in a shift register clocked off of SCLK, and then send that whole block over to the main fpga clock domain. Is there any reason I wouldn’t want to do that? Is a better/simple solution possible?

 

Also, is it possible to use some coregen block here?  I saw that the EDK has an SPI slave block, but I don’t know if I have access to that with just a webpack license, and the lowest SPI clock ratio available in slave mode is 4x, which means I’d have to be running at between 264Mhz and 400Mhz; I don’t think I can hit that.

 

*any chance that might work? If so, that seems like the easiest solution; I could just feed it through a synchronizer and oversample. But I think I’d need to clock substantially faster than SCLK for that to be reliable, and I don’t know if I can do that using the lowly xc3s200a-4ft256 chip that I’ve got.

 

EDIT: ** will this actually cause problems? Looking at the RTL for the FIFO, it seems like I might get stuck with 'EMPTY' asserted even after one word has been written into the FIFO, but that doesn't seem too bad for my application, where data will be written often (but not continuously).

Tags (4)
0 Kudos
1 Solution

Accepted Solutions
Teacher eteam00
Teacher
18,636 Views
Registered: ‎07-21-2009

Re: High speed SPI slave

Jump to solution

Haul,

 

As Gabor mentioned (and I failed to explicitly affirm in my previous post, since corrected), SPI input data should be sampled directly by the SPI input clock.  Using a fabric clock to sample the SPI input clock, and then sample the SPI input data using the fabric clock, would require a fabric clock frequency much higher than the SPI input clock frequency.  Think about this for a while, and consider (and compare) how you would implement direct sampling of SPI data with SPI clock.

 

As I mentioned before, deserialising the SPI input data is a small circuit, pretty straightforward.  You'll need to detect the deselect/initialise/terminate condition, but this isn't too difficult to figure out.  Once the SPI data has been deserialised and double-buffered, you have only one bit to synchronise to the fabric clock, and that is the extent (more or less) of the clock domain crossing synchronisation problem.  The one bit is simply a flag saying that a new 8-bit word is available for "processing".

 

Once you have straightened out the transition to fabric clock domain, you still have to filter SPI commands and addresses from SPI data.  You can do this before the FIFO or after the FIFO, your call.  You'll need enough FIFO width to include an address/data tag, plus a "terminate/deselect" flag for transaction framing, as your application demands.

 

To sum up:

  • 66+ MHz is too fast for "sampling" the SPI clock and SPI data with fabric clock
  • Deserialise using SPI clock, this keeps it simple
  • Clock domain crossing is at parallel (not serial) data rates, simple to implement
  • Don't forget Command/terminate detect and framing logic

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
9 Replies
Teacher eteam00
Teacher
14,073 Views
Registered: ‎07-21-2009

Re: High speed SPI slave

Jump to solution

Remember that the SPI clock is for a serial bit stream.  It would take a simple state machine clocked directly by the SPI input clock to deserialise the SPI data.  From there, you need to synchronise (clock domain crossing) from the SPI clock to the main fabric clock, which needs to be (at least) 1/8th the frequency of the SPI clock -- not very high speed at all.  Block RAM running at 15MHz or faster?  No problem-o.

 

Block RAM uses the fabric clock, the Block RAM enable (e.g. WRITE) is generated from the SPI-clocked SPI input state machine, fully synchronised (of course).

 

This assumes an 8-bit BRAM data port.  Bump the width to 16 bits and the fabric frequency requirements scale accordingly.

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Instructor
Instructor
14,065 Views
Registered: ‎08-14-2007

Re: High speed SPI slave

Jump to solution

I think Bob failed to mention that you really want to use the SPI clock as the deserializing

clock for your data.  For this sort of frequency you don't want to oversample the clock.  If

the clock is not continuous, you can still sample the deserialized data using another

system clock.  You might find that a hybrid approach will work best, using the SPI clock

to deserialize data and push it 8 bits at a time into the FIFO while the SPI chip select

is active, and then sampling the last 8-bit word with another clock only while the SPI chip

select is not active. 

-- Gabor
Visitor haul
Visitor
14,052 Views
Registered: ‎11-01-2010

Re: High speed SPI slave

Jump to solution

 

Thanks for the quick replies!

@eteam00 wrote:

Remember that the SPI clock is for a serial bit stream.  It would take a simple state machine to deserialise the SPI data.  From there, you need to synchronise (clock domain crossing) to the main fabric clock, which needs to be (at least) 


To clarify, a question I have is if I can do both of those in one shot using a coregen FIFO with independent clocks, and feeding the SCLK to the write clock (with the appropriate adjustments for cpol/cpha), and using my main fabric clock as the read clock, setting the write width to 1, and the read width to whatever I want (say, 8).

 

0 Kudos
Teacher eteam00
Teacher
14,050 Views
Registered: ‎07-21-2009

Re: High speed SPI slave

Jump to solution

Haul,

 

Do you intend to use coregen to generate a 1-bit wide FIFO, with SPI data fed directly to the FIFO?  If so, I would recommend against this.  This makes a simple problem much more complex.  Do you have a compelling reason for doing this, which you haven't yet mentioned?

 

Have you ever implemented an SPI controller at the register level, either a master or a slave?

 

- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
0 Kudos
Visitor haul
Visitor
14,042 Views
Registered: ‎11-01-2010

Re: High speed SPI slave

Jump to solution

I don't have a compelling reason -- I was just wondering if that might be the "simplest" way to do it. At that output end, I'll need a FIFO anyway, since it's going to be talking to a device that's often stalled, and I was wondering if I could get the whole thing done in one block.

 

I've implemented a "real" master and a slave for simulation, to test the master that I'll be talking to. The slave is only about 15 lines of Verilog, but I've never implemented anything that requires doing clock-domain crossing, and I suppose I'm worried that I'll do something wrong there, which is why I was thinking it might be easier if the FIFO could "automatically" handle the clock-domain crossing. Also, in simulation I don't have to worry about meta-stability/noise on the inputs, and I've never dealt with "real" input from off-chip at anything but very low speed, so that's another thing I could see myself messing up.

0 Kudos
Teacher eteam00
Teacher
18,637 Views
Registered: ‎07-21-2009

Re: High speed SPI slave

Jump to solution

Haul,

 

As Gabor mentioned (and I failed to explicitly affirm in my previous post, since corrected), SPI input data should be sampled directly by the SPI input clock.  Using a fabric clock to sample the SPI input clock, and then sample the SPI input data using the fabric clock, would require a fabric clock frequency much higher than the SPI input clock frequency.  Think about this for a while, and consider (and compare) how you would implement direct sampling of SPI data with SPI clock.

 

As I mentioned before, deserialising the SPI input data is a small circuit, pretty straightforward.  You'll need to detect the deselect/initialise/terminate condition, but this isn't too difficult to figure out.  Once the SPI data has been deserialised and double-buffered, you have only one bit to synchronise to the fabric clock, and that is the extent (more or less) of the clock domain crossing synchronisation problem.  The one bit is simply a flag saying that a new 8-bit word is available for "processing".

 

Once you have straightened out the transition to fabric clock domain, you still have to filter SPI commands and addresses from SPI data.  You can do this before the FIFO or after the FIFO, your call.  You'll need enough FIFO width to include an address/data tag, plus a "terminate/deselect" flag for transaction framing, as your application demands.

 

To sum up:

  • 66+ MHz is too fast for "sampling" the SPI clock and SPI data with fabric clock
  • Deserialise using SPI clock, this keeps it simple
  • Clock domain crossing is at parallel (not serial) data rates, simple to implement
  • Don't forget Command/terminate detect and framing logic

 

-- Bob Elkind

SIGNATURE:
README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

Summary:
1. Read the manual or user guide. Have you read the manual? Can you find the manual?
2. Search the forums (and search the web) for similar topics.
3. Do not post the same question on multiple forums.
4. Do not post a new topic or question on someone else's thread, start a new thread!
5. Students: Copying code is not the same as learning to design.
6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please).
7. You are not charged extra fees for comments in your code.
8. I am not paid for forum posts. If I write a good post, then I have been good for nothing.
Visitor haul
Visitor
14,021 Views
Registered: ‎11-01-2010

Re: High speed SPI slave

Jump to solution

Thanks for the help. That was simpler than I expected: going from my non-synthesizable spi slave to a synthesizable spi slave that handles the clock-domain crossing only took about an hour and 50ish lines of Verilog.

 

I still wonder if it might have been even easier to just drop in a coregen block, though :-)

0 Kudos
Instructor
Instructor
14,014 Views
Registered: ‎08-14-2007

Re: High speed SPI slave

Jump to solution

There are two problems with "dropping a coregen block" that would make me avoid it:

 

1) it won't "sync up" to byte boundaries unless you are guaranteed to empty the FIFO

before a new SPI transfer starts (and give it a reset).

 

2) If the SPI clock is not continuous you can end up with data in the FIFO after the

SPI transaction comletes, but the flags will still show empty.

 

The logic to work around these is probably as least as complex as your "50ish

lines of Verilog" and would make the resulting design harder to understand.

 

Cheers,

Gabor

-- Gabor
Scholar ronnywebers
Scholar
5,639 Views
Registered: ‎10-10-2014

Re: High speed SPI slave

Jump to solution

@haul do you know of any example on the clock domain crossing part? I'm still puzzled on a decent but simple solution here. Did you do the crossing on the parallel buffer registers?

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos