Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

Designing a SPI slave

Hello everyone,

This is my 1st post on this forum, so I apologize if I'm doing some noob mistake, i.e. posting this question in the wrong place. I remember doing that in other forums :)

Anyways, I'm trying to add a SPI slave to my Cyclone IV VHDL design. It works, but looks like the SPI_CLK pin is very often clocking twice on a single rising edge. An ATXMEGA MCU is generating the signals as the master.

First thought was the speed of the rising slope, and so I shortened the wires on my prototype to reduce the load. It helped. The amount of double clocks reduced. But it's still happening, and the wires are pretty short already.

My question is: Should I be using a dedicated clock pin of the FPGA for the SPI_CLK? I've read that those dedicated clock pins indeed offer a lower load to the signal, but their main feature is being global and easily accessible to all flip flops.

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Well, I've made another post above this one, which contains images and hasn't been approved yet, but just to report:

    I've studied about synchronization chain, from the document Eng1 posted, as well as other pages about it that I found on Google, and created a 3-stage chain (3 just to be safe) within the same "IF rising_edge(CLK)" of all my code (is this ok?). Here's how it looks:

    
    IF rising_edge(CLK) THEN
    						
    	SPI_CLK_SYNC(0)<=SPI_CLK_SYNC(1);	
    	SPI_CLK_SYNC(1)<=SPI_CLK_SYNC(2);
    	SPI_CLK_SYNC(2)<=SPI_CLK;
    			
    	SPI_CS_SYNC(0)<=SPI_CS_SYNC(1);	
    	SPI_CS_SYNC(1)<=SPI_CS_SYNC(2);
    	SPI_CS_SYNC(2)<=SPI_CS;
    	(...)
    

    Since I want to detect edges of both the SPI_CLK and SPI_CS, I thought I'd have to synchronize both signals. Well... it worked perfectly!

    I'm very amazed about these FPGA phenomenons, and it'd take a long time for me to find out that this was the problem I was having if it weren't for you guys. Thank you both very much!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It is really amazing how bad things can go if the inputs are not sync'd up.

    I have found two stages to be adequate. You could use the third as your previous state.

    
    IF rising_edge(CLK) THEN
                            
        SPI_CLK_LAST<=SPI_CLK_SYNC(1);    
        SPI_CLK_SYNC(1)<=SPI_CLK_SYNC(2);
        SPI_CLK_SYNC(2)<=SPI_CLK;
    

    Also, synchronize every signal coming into the FPGA (SPI_MOSI, too) unless there is some good reason not to do so.