VHDL SPI Slave question

Status
Not open for further replies.

hithesh123

Full Member level 6
Joined
Nov 21, 2009
Messages
324
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,298
Location
lax
Visit site
Activity points
3,548
I am using SPI clk to clock-in data. The SPI Master toggles data on rising edge and sample data on falling edge.
From the slave side, I am sampling data on rising edge and loading data on the rising edge. The SPI clock is a slightly delayed version of the external SPI clk due to synchronizer.
The data coming in is 16bits, with first 8 bits give the read/write bit and address. The last 8 bits are the data.
All the logic is done in one process under rising_edge(sclk).

Instead of sampling & loading data on rising edge, can I do sample/load on 2 edges - rising and falling?
This means 2 process, right?
 

That wouldnt work in an FPGA, as you can only sample on a single clock edge.
Its also not a great idea to use the sclk as a clock. Much more reliable to run a fast system clock (say 200 mhz) and sample it like you would any other asynchronous signal.
 
I discourage you from using the SPI clock as the FPGA's system clock.
The signal quality and jitter will be very questinable.

This is the correct way to achieve the functionallity you want on an FPGA:

1. Use a system clock that is much higher then the SPI clock.
2. Create flags of the SPI clock's rising and falling edges.
3. Use the flags as enables to your shift registers.

With this approach, you'll be still using a single (high quality) clock edge.
 

I want to do it this way. But how do I create Flags of the SPI clock's rising and falling edges.

Also - If I use the serial clock after running it thru a dual rank synchronizer, wouldn't it be significantly reliable.
 

rising edge detect is easy. Compare the synchronised version of the clock to a registered version. If they are different, you have an edge:

current = '0' and reg = '1' = falling edge
current = '1' and reg = '0' = rising edge
 

The synchronizer is required in front of the edge flag generation, using a delay chain of 3 FFs in total.
Code:
signal sck_m : std_logic_vector(0 to 2);
signal sck_rise, sck_fall : std_logic; 
...
process (reset,clk)
begin
  if reset = '1' then
    sck_m <= "000";
    sck_rise <= '0';  
    sck_fall <= '0';
  elsif rising_edge(clk) then
    sck_m <= sck & sck_m(0 to 1);
  end if;
end;
sck_rise <= sck_m(1) AND NOT sck_m(2);   
sck_fall <= NOT sck_m(1) AND sck_m(2);
 

So basically, I have to use sck_rise and sck_fall as enables to clock-in serial data?

Code:
if rising_edge(clk) then
   if sck_rise='1' then
     sdata<=sdata(6 downto 0) & sdi;
   elsif sck_fall='1'; then
     sdo<=sdata(7)
   end if;
end if;
 

If I use the serial clock after running it thru a dual rank synchronizer, wouldn't it be significantly reliable.
You want to use your double synchronized SCLK as a system clock ??
You have to be familiar with FPGA architecture to understand why that's a bad idea.
Manufacturers go long ways to ensure that their clock signals are balanced (reach all FFs at the same time). They dedicate special pins for the clock signals (global pins). These pins connect to special nets (global nets).
You suggest to take a weak DFF output (that doesn't go into a global net) and treat it as if it was a proper clock...I'm not saying that it won't work - it just isn't the correct solution.
 
Yes, that's the suggestion.

Why use a 3-bit synchronizer for the sclk edge detection. Why not 2-bit.

- - - Updated - - -


Thanks. But what if I buffer the sclk signal using a Global clock buffer or a low skew buffer in the FPGA.
 

The first 2 bits provide the synchronization.
The 3rd DFF provides means to detect edges.
 

But what if I buffer the sclk signal using a Global clock buffer or a low skew buffer in the FPGA.
The problem isn't if you can use sclk as a clock. That's well possible. The problem is about having multiple clock domains in your design and how to handle domain crossing.

I already mentioned different options to process serial data with an external clock in post #6 of your previous thread. https://www.edaboard.com/threads/308165/#post1318987
 

Thanks. But what if I buffer the sclk signal using a Global clock buffer or a low skew buffer in the FPGA.
Why?? What are the benefits of such an approach??
Why not simply detect the SCLK edges and use them as enables for your block??
 

Another problem when using the SCLK is that it is generated by the master, and I think it has the power to stop the clock. That wont do your design much good...
 

Another problem when using the SCLK is that it is generated by the master, and I think it has the power to stop the clock. That wont do your design much good...
I presume, the OP didn't intend to use SCK as the system clock. He considered to use it as a second clock which involves the discussed domain crossing problems.

Furthermore, I understood that he considered to 1. synchronize the SPI clock the system clock and 2. use the synchronized signal as clock. But this would make no sense at all.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…