Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20829 Discussions

Constraining an SPI interface

Altera_Forum
Honored Contributor II
3,255 Views

Hello all, 

 

What is the proper way of constraining a 4-wire SPI master interface? I have several devices connected to my SPI bus, and fastest one can accecpt a SCLK up to 33 ns period, with setup and hold times of 5 ns. 

First off, I'm deriving my SCLK signal by dividing down (using fabric, not a PLL) the main clock (125 MHz core clock of the PCIe core) that drives my state machine that shifts out bit on the MOSI line (and in on the MISO line). 

First question: should I declare that SCLK as virtual or not? By looking at all the examples I found it looks like all the non-virtual clock must be generated by free-running oscillators and/or PLLs. 

Second question: using the app note 433, system-centric approach, if we consider all the trace delays for data and clock the same, it looks like I should be declaring those two output delays 

 

set_output_delay -clock my_spi_clk_virt -max 5.0 [get_ports MOSI] 

set_output_delay -clock my_spi_clk_virt -min -5.0 [get_ports MOSI] 

set_output_delay -clock my_spi_clk_virt -max 5.0 [get_ports SSn] 

set_output_delay -clock my_spi_clk_virt -min -5.0 [get_ports SSn] 

 

Anything wrong with this approach?  

Last question: how do I constrain the MISO port?  

 

Thanks!!
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
2,016 Views

 

--- Quote Start ---  

 

What is the proper way of constraining a 4-wire SPI master interface? 

 

--- Quote End ---  

 

Here's some notes I wrote up ... 

 

https://www.ovro.caltech.edu/~dwh/correlator/pdf/timequest_quad_spi_flash.pdf 

https://www.ovro.caltech.edu/~dwh/correlator/pdf/timequest_quad_spi_flash.zip 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
2,016 Views

Hi Dave, 

 

Your notes are great. They helped me a lot.  

There's something that I still need to understand though. 

 

This is how the constraints look for my SPI interface:  

 

 

# SPI Clocks max rate are a divided-by-4 version of system clock 

create_generated_clock -name hb_spi_clk_int -source [get_pins {u0|pcie_sv_hip_avmm_0|altera_s5_a2p|altpcie_hip_256_pipen1b|stratixv_hssi_gen3_pcie_hip|coreclkout}] -divide_by 4 -duty_cycle 50.0 [get_pins {peanuts|peanuts_main_system0|shared_subsytem|hb_shared_spi_bus|clock_div_calc|sclk_loc|q}] 

create_generated_clock -name hb_spi_clk -source [get_pins {peanuts|peanuts_main_system0|shared_subsytem|hb_shared_spi_bus|clock_div_calc|sclk_loc|q}] [get_ports {MEZZ_SER_CTRL1}] - MEZZ_SER_CTRL1 is the SPI_SCLK 

 

# Multi-cycle relationships  

set_multicycle_path -from [get_clocks {u0|pcie_sv_hip_avmm_0|altera_s5_a2p|altpcie_hip_256_pipen1b|stratixv_hssi_gen3_pcie_hip|coreclkout}] -to hb_spi_clk -start -hold 3 

set_multicycle_path -from [get_clocks {u0|pcie_sv_hip_avmm_0|altera_s5_a2p|altpcie_hip_256_pipen1b|stratixv_hssi_gen3_pcie_hip|coreclkout}] -to hb_spi_clk -start -setup 2 

set_multicycle_path -from hb_spi_clk -to [get_clocks {u0|pcie_sv_hip_avmm_0|altera_s5_a2p|altpcie_hip_256_pipen1b|stratixv_hssi_gen3_pcie_hip|coreclkout}] -end -setup 2 

set_multicycle_path -from hb_spi_clk -to [get_clocks {u0|pcie_sv_hip_avmm_0|altera_s5_a2p|altpcie_hip_256_pipen1b|stratixv_hssi_gen3_pcie_hip|coreclkout}] -end -hold 3 

 

# HB SPI Inputs 

set_input_delay -clock hb_spi_clk -max $spi_input_delay_max [get_ports MEZZ_SER_CTRL5] - MEZZ_SER_CTRL5 is the MISO signal 

set_input_delay -clock hb_spi_clk -min $spi_input_delay_min [get_ports MEZZ_SER_CTRL5] 

 

# HB SPI Outputs 

set_output_delay -clock hb_spi_clk -max $spi_output_delay_max [get_ports MEZZ_BK1_OUT14] - MEZZ_BK1_OUT14 is the SSn signal 

set_output_delay -clock hb_spi_clk -min $spi_output_delay_min [get_ports MEZZ_BK1_OUT14] 

set_output_delay -clock hb_spi_clk -max $spi_output_delay_max [get_ports MEZZ_BK4_OUT17] - MEZZ_BK4_OUT17 is the MOSI signal 

set_output_delay -clock hb_spi_clk -min $spi_output_delay_min [get_ports MEZZ_BK4_OUT17] 

 

 

TimeQuest reports that MEZZ_SER_CTRL1 port is still not fully constrained and reports a path between a spi_clk_enable signal (it gates the clock through combinatorial logic) and my core system clock (the PCI core clock, that I divide down to generate the serial clock). Attached a snapshot from the technolocy viewer.  

How am I supposed to constrain that path? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
2,016 Views

Given that you're gating the SPI clock, I suspect you need to create another generated clock, and use that in all of your timing constraints. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
2,016 Views

Any suggestion on how?  

I tried several ways but no one seems to work...
0 Kudos
Altera_Forum
Honored Contributor II
2,016 Views

 

--- Quote Start ---  

Any suggestion on how?  

I tried several ways but no one seems to work... 

--- Quote End ---  

 

Typically I start with the error message from TimeQuest and work out what signal it is complaining about. I'd start by using the signal name in the error and see if adding a generated clock helps. If it does, then I'd figure out a cleaner (more generic) way to determine the clock using the TimeQuest Tcl functions. 

 

Cheers, 

Dave
0 Kudos
Reply