Programmable Logic FPGA Development: Interfaces to external SPI components

From Eugen Krassin* | Translated by AI 7 min Reading Time

The Serial Peripheral Interface is something like the bread and butter interface for connecting external components to a logic chip in electronics. This article shows what to consider when implementing a SPI in a Field Programmable Gate Array, or FPGA for short.

In FPGA circuit design, it's all about thoughtfully assembling the right puzzle pieces to achieve optimal function, performance, and space utilization. PLC2 offers a free basic webinar series for FPGA developers.(Image: Image: /  Pixabay)
In FPGA circuit design, it's all about thoughtfully assembling the right puzzle pieces to achieve optimal function, performance, and space utilization. PLC2 offers a free basic webinar series for FPGA developers.
(Image: Image: / Pixabay)

Eugen Krassin is the founder and trainer of the training center PLC2 GmbH - and a veteran of the Programmable Logic industry.

Different approaches can be utilized to implement an SPI interface in an FPGA - for instance, using one or two clock domains. This article illustrates how this can be done, as well as different strategies in the development and definition of timing constraints.

During the implementation of the SPI interface, two fundamentally different approaches to implementation were used. The first approach describes a concept with two clock domains (Two Clock Domain). The second approach implements the circuit with only one clock domain (Single Clock Domain).

Gallery
Gallery with 13 images

Implementation with two clock domains

The DAC AD7303 from Analog Devices serves as a typical representative of an SPI interface here. Figure 1 shows the timing diagram of the interface as well as the timing parameters. In this example, the SCLK frequency is chosen to be 30 MHz. Particular attention must be paid to the timing parameters t4, t5 and t6 when defining the timing requirements (timing constraints).

Figure 1: AD7303 Timing Diagram and Timing Requirements.
(Image:PLC2 GmbH)

For the implementation with two clock domains, two clocks, which do not necessarily have to be synchronous, are used. In the present case, the clocks are 120 MHz and 30 MHz. The sequence control is clocked at 120 MHz, while the actual SPI FSM is controlled at 30 MHz.

As can be seen from Image 2, a synchronization stage between the two clock domains is therefore necessary (if the two clock domains are synchronous to each other, the synchronization stage can be omitted). The implementation of the SPI interface with two clock domains is shown in Image 2.

Image 2: SPI interface implementation with two clock domains.
(Image:Image:)

Used parameters:

  • Input clock: 100 MHz

  • Internal clock CLK_120: 120 MHz

  • Internal clock CLK_30: 30 MHz

  • Generated clock dac_sck: 30 MHz

The PLL_120_30: The PLL generates two internal, phase-synchronous clocks CLK_120 and CLK_30 from the external clock CLK (100 MHz).

Module dac_sample_gen: The dac_sample_gen module generates the sample signal (convert) for the dac_fsm. The sample signal initiates the transmission of digital data to the DAC. The sample rate is set via sample_select [1:0] and is given in the table shown. The block diagram of dac_sample_gen is shown in Figure 3.

Table 1: The sample rate is set via sample_select [1:0].
(Image:PLC2 GmbH)
Image 3: Block diagram dac_sample_gen.
(Bild:PLC2 GmbH)

Control signal mode_select: The control signal mode_select generates either a square signal or a triangular signal as input data for the DAC.

Module sync_stage: The dac_sample_gen module operates with CLK_120. The control unit dac_fsm is part of the CLK_30 domain. The sync_stage module transports the convert signal from the CLK_120 domain to the CLK_30 domain. Corresponding signals from the dac_fsm are transferred from the CLK_30 domain to the CLK_120. The block diagram of sync_stage is shown in Figure 4.

Image: Block diagram of sync_stage.
(Image:Image: PLC2 GmbH)

Module dac_fsm: The module dac_fsm controls the generation of the control/data signals to the DAC. In order to meet the values of t4, t5 and t6 given in Image 1, dac_fsm operates on the falling edge of CLK_30. dac_fsm is implemented as a state machine as shown in Image 5.

Image 5: Flowchart of the dac_fsm state machine.
(Image:PLC2 GmbH)

Timing Constraints

1. Constraints for the CLK

create_clock -name {clk} -period 10 [get_ports clk]

2. Clock signals CLK_120 and CLK_30

The clock signals CLK_120 and CLK_30 do not need to be explicitly specified as they are automatically defined by the design software. These two clocks are also referred to as "automatically generated clock".

clk                                        10.000      {0.000 5.000}   P
dac_sclk 33.333 {0.000 16.667} P,G
clk_out1_pll_120_30 8.333 {0.000 4.167} P,G,A
clk_out2_pll_120_30 33.333 {0.000 16.667} P,G,A
clkfbout_pll_120_30 50.000 {0.000 25.000} P,G,A

Clock signal dac_clk

The signal connected to port dac_sck is a copy of the internal clock CLK_30. This signal is interpreted as a clock by the external DAC. Therefore, this signal must also be defined as a clock in order to correctly describe the time requirements t4, t5 and t6. This clock is a so-called "manually generated clock."

create_generated_clock -name {dac_sclk} -source [get_pins instance_dac_fsm/instance_dac_sclk/SCLK] -divide_by 1 -multiply_by 1 [get_pins instance_dac_fsm/instance_dac_sclk/Q]

4. Constraints for DAC Inputs/FPGA Outputs

The times t4, t5 and t6 describe the setup / hold requirements for the external device. These requirements are described with the set_output_delay constraint.

set_output_delay -clock [get_clocks dac_sclk] -max 5 [get_ports {dac_sdata dac_sync}]
set_output_delay -clock [get_clocks dac_sclk] -min -4.5 [get_ports {dac_sdata dac_sync}]

Timing Analysis

The timing analysis confirms the proper implementation of the design.

The timing analysis confirms the proper implementation of the design.
(Image:Image:)

Guidance to Accelerate your Programmable Solution

Areas of application for programmable logic circuits are as diverse as the available solutions that can be developed with them. Whether FPGA, GPU, or Adaptive Computing SoC: Each technology has its justification but also requires explanation.The FPGA Conference Europe – as the most important platform in Europe for manufacturer- and technology-independent and application-crossing exchange between experts and developers – provides embedded developers with orientation and practical assistance.

(Bild: )

Implementation with a single clock domain.

The implementation of the single-clock SPI interface is shown in Figure 6.

Image: The implementation of the single-clock SPI interface.
(Image:PLC2 GmbH)

The concept of SPI implementation with a single clock domain is similar to implementation with two clock domains. To illustrate this, the PLL is not used. Also, the sync_stage module is not needed. Because of the single clock, the clock_generator module is needed to signal the falling edge of the dac_sck, which is used as the trigger condition for the state machine dac_fsm.

Subscribe to the newsletter now

Don't Miss out on Our Best Content

By clicking on „Subscribe to Newsletter“ I agree to the processing and use of my data according to the consent form (please expand for details) and accept the Terms of Use. For more information, please see our Privacy Policy. The consent declaration relates, among other things, to the sending of editorial newsletters by email and to data matching for marketing purposes with selected advertising partners (e.g., LinkedIn, Google, Meta)

Unfold for details of your consent

Module clock_generator: The module clock_generator shown in Figure 7 generates the clock signal dac_clk and the display of the falling edge of dac_sck. Figure 8 shows the relationship between dac_sclk and edge_low.

Image 7: Block diagram of the clock_generator module.
(Image:Image:)
Image: Relationship between dac_sclk and edge_low.
(Image:PLC2 GmbH)

The dac_fsm module for the single clock implementation: The dac_fsm module controls the generation of control/data signals to the DAC. To comply with the t4, t5 and t6 values given in Figure 1, dac_fsm always operates on the rising edge of CLK_120, but only when the edge_low signal is active. Dac_fsm is implemented as a state machine.

The state machine dac_fsm has the same structure as the state machine in the implementation of the solution with two clock domains. The only difference is the evaluation of the falling edge of dac_sck instead of using the clock clk_30.

Image 9: Structure of the dac_fsm state machine.
(Image:PLC2 GmbH)

After the convert signal has been recognized, the bit_count counter is loaded with the value 15. The serial data is output on the dac_sdata line with the rising edge of the CLK_120 clock signal whenever edge_low is active. After 16 data bits have been transferred, dac_fsm again signals readiness and waits for the next convert signal.


Timing Constraints for Single Clock Domain Implementation

1. Clock CLK 120

create clock -name CLK -period 8.333 [get_ports clk]

2. Clock dac_clk

The clock signal connected to the port dac_sck is generated by the clock_generator. The relationship between CLK_120 and dac_sck is divided by 4 (compare with Figure 7).

create_generated_clock -name {dac_sck} -source [get_ports clk_120] -divide_by 4 -multiply_by 1 [get_pins clock_gen_inst/toggle_reg/Q]

3. Constraints for DAC Inputs/FPGA Outputs

The timing parameters t4, t5, and t6 describe the setup/hold requirements for the external DAC AD7303. These requirements are described using the set_output_delay constraint. Due to the single clock domain, a multicycle constraint is also necessary.

set_multicycle_path -from [get_pins instance_dac_fsm/dac_sync_reg/Q] -to [get_ports dac_sync] -start 2
set_multicycle_path -from [get_pins instance_dac_fsm/dac_sync_reg/Q] -to [get_ports dac_sync] -start -hold 3
set_multicycle_path -from [get_pins { instance_dac_fsm/spi_sdata_i_reg/Q }] -to [get_ports dac_sdata] -start 2
set_multicycle_path -from [get_pins { instance_dac_fsm/spi_sdata_i_reg/Q}] -to [get_ports dac_sdata] -start -hold 3
set_output_delay -clock [get_clocks dac_sck] -max 5 [get_ports {dac_sdata dac_sync}]
set_output_delay -clock [get_clocks dac_sck] -min -4.5 [get_ports {dac_sdata dac_sync}]
Due to the single clock domain, a multicycle constraint is also necessary. See image 10.
(Image:PLC2 GmbH)

Timing Analysis

The timing analysis of the design with one clock domain shows the same results as the design with two clock domains.

The timing analysis confirms the proper implementation of the design.
(Image:PLC2 GmbH)

Summary

Both concepts can be used to implement low-speed SPI interfaces. However, the two-clock domain has an advantage in terms of power consumption, as part of the design runs at a lower speed. Also, the timing constraints are easier to specify. The single clock domain concept uses a single clock distribution network, which is an advantage as no synchronization stages are needed. Both project templates are available on request at info@plc2.de. (me)