On 8/16/2016 3:05 AM, kristoff wrote:
> Hi Rickman,
>
>
>
> On 16-08-16 07:29, rickman wrote:
>>> Question.
>>> How much jitter can one expect on a SPI-interface between a MPU (in a
>>> breadboard) and a FPGA connected with jumper-wires?
>
>> I'm not sure why you are asking about jitter in relation to jumper
>> wires. Jitter is a function of the driver.
>
> Sorry, I meant ringing, not jitter.
>
>
>> Using jumper wires is not a
>> good idea as this will introduce ringing and can cause extra clock edges
>> which a Schmitt trigger can't fix.
>
> Well, it's the setup I have. A STM32F1 on a broadboard talking to a FPGA
> on a devboard.
>
>
> Now, for sake of just the VHDL exercise, I can of course run the SPI
> interface at a lower speed but the figure of "maximum bitrate for SPI:
> 12 Mbps" in the STM32F1 spec did get me thinking.
This is a signal integrity issue. You may do just fine with it, but the
only way to tell for sure is to scope it and see what you have. You
would likely do well to use a ribbon cable and put a ground wire between
every signal wire and the next. This helps to lower the impedance of
the signal wires (less ringing) as well as reduce the coupling between
them (less induced noise).
In the end you may have to reduce your edge rate which may require a
slower clock speed. I know FPGAs typically have edge rate control. The
only signal that is crucial is the clock. You may do well to use a
series terminating resistor, but I'm not sure how well that will work
with the varying impedance along your signal path. A trial won't hurt.
>> SPI is fast enough that the clock edges have to be fast enough to cause
>> ringing if your traces are very long and not properly terminated.
>
> Which is probably the case here. :-)
>
>
> I'll do a test this evening.
>
>
>
>>> Also,
>>> The two FPGA boards I have (xula2-LX9 and no-name EP4CE10) are clocked
>>> at 12 and 50 Mhz; I guess that is not really enough to process SPI at 12
>>> Mbps.
>>
>> Again, I'm not sure of what you are asking. A 50 MHz clock should be
>> fast enough to sample a 12 MHz clock and data reliably. I designed a
>> digital phase locked loop that resyncs to the edges of the data to
>> sample a data stream with the internal clock at 4x the data rate. That
>> would be 48 MHz in your case.
>
> OK, as said, I'm just starting out on VHDL and at this point, I just do
> edge-detection based on the system clock (50 Mhz) and a "last bit was 1,
> new bit is 0" circuit.
>
> My idea was to create a low-pass filter with a moving-window average.
I'm not sure how much filtering you can apply effectively. You have a
sample rate that is twice your Nyquist rate with only two values of
input, 0 and 1. A filter is going to be pretty messy or complicated.
I'd stick to a simple state machine and focus on dealing with the SI
issues in the hardware rather than trying to filter stuff in the FPGA.
In other words, keep the noise out of the FPGA to begin with.
>>> Can I conclude that I need to use a PLL to speed up the clock for this
>>> particular part of the FPGA? So this would be a part of the FPGA with
>>> its own clock-domain. Correct?
>>
>> I wouldn't. Just sample the clock and collect the data when
>> appropriate. Or you can run the interface directly from the SPI clock
>> (I'm assuming your FPGA is a slave). When the /SS signal is deasserted,
>> use that to trigger a transfer of the data word to your other clock
>> domain (12 or 50 MHz) and use the data. Appropriate clock domain
>> crossing circuits should be used.
If the FPGA is a slave with a 50 MHz clock, you should be able to do
something simple. First, use the SPI clock to capture the bit in a FF
on the correct edge. This will be stable for a full SPI clock cycle
some time after that edge. Sampling the 12 MHz clock will produce a
sequence like "001100110011..." with an extra 0 or 1 on occasion. If
you just look for the right edge "01" or "10" and wait one more clock
cycle to sample the output of the data captured in the FF. This will
give the output of that FF plenty of time to settle so you aren't
dealing with a changing value as you clock it into the 50 MHz domain.
(optional)
MOSI +------+ +------+
-->>----| D Q |---------| D Q |---->>-- Stable Data
| | | |
| | +----| CE |
SCLK | | | | |
-->>----|> | | +--|> |
+------+ | | +------+
| |
+-)------------------------+
| |
| _____ |
+---)---------------\ \ |
SCLK +------+ | | +------+ ) & )--+-->>-- Rising
-->>----| D Q |--+---)--| D Q |----O/____/ Edge Detect
| | | | |
| | | | |
50CLK | | | | |
+---|> | +--|> |
| +------+ | +------+
+-----------------+--------------<<-- 50 MHz Clock
The MISO data will come from a FF clocked by the 50 MHz signal enabled
by the appropriate edge detect. Be mindful of the one cycle of 50 MHz
clock jitter you will see in the MISO signal, but this shouldn't be a
problem unless the MCU has tight timing specs. You may not need the
MOSI sync FF (the one clocked by the SCLK signal) if you have a decent
timing window so the MOSI data can go directly into the FF enabled by
the edge detect.
If the SPI port has to respond in the same transaction to a command
being sent, closing the loop may be a bit tricky with timing. I had to
do that in an SPI like design once and I ended up with 15 ns to get a
result out.
If you are concerned about metastability you will want to be sure the
path from the first FF sampling the SCLK signal has some extra slack to
*all* destinations or add a Ff in front of this one. It only take a
small number of ns of slack to resolve metastability to a very
microscopic possibility.
>>> I read somewhere that I then need to use a FIFO to communicate with the
>>> parts of the FPGA running at the normal clock-rate. Is this correct?
>>> (I think I've seen code on
opencores.org which does this).
>>
>> Not sure what you mean by "normal clock rate". But in no case do you
>> need a FIFO unless the interface is running at a much higher rate than
>> the system clock (I assume what you mean by "normal clock") with the
>> data arriving in bursts that are too fast for the system clock to accept.
>>
>> Is your 50 MHz clock your system clock?
>
>
> yes. 50 Mhz is my system-clock (at least on the Altera board). (that is
> what I called the "normal" clock, my appologies if I do not always use
> the correct jargon).
>
>
> As mentioned in my message to John, this started out as just a small
> VHDL exercise, i.e. implement a SPI slave.
> Now, every time, all kind of other stuff turns up (in this case,
> different clock domains) which makes the exercise much more interesting.
>
> I need to do some research on the "clock domain crossing circuits" you
> mention.
Or see above a workable circuit. Be sure to consider the specifics of
your interface timing to decide exactly what clock cycle to sample the
input data or the change the output data.
> That's indeed what I had in mind, but this is the first time I would
>
>
>
>>> What clock-rate would one need to interface with a SPI-interface at 12
>>> Mbps?
>
>> 50 MHz should work just fine. Think of analyzing the sampled clock as a
>> finite state machine.
>
> Thx! :-)
>
>
>
> Cheerio! Kr. Bonne.
--
Rick C