1.6.4.1. General Purpose I/O
The Quartus® Prime software does not automatically generate the I/O timing constraints for the Generic Serial Flash Interface Intel® FPGA IP file. To enable the SPI pin interface using the general purpose I/O pins, you must manually enter the timing constraints. Follow the timing guidelines and examples to ensure that the Timing Analyzer analyzes the I/O timing correctly.
- Constrain the input clock of the Generic Serial Flash Interface Intel® FPGA IP. Example:
#************************************************************** # Create Clock #************************************************************** #constrain the base clock using create_clock, this is typically a clock coming into the device on an input clock pin #here, clk_clk is a 10ns clock with a 50 percent duty cycle, where the first rising edge occurs at 0ns applied to port clk_clk create_clock -name {clk_clk} -period 10.000 -waveform { 0.000 5.00 } [get_ports {clk_clk}]
- Create a timing constraint to dclk, which is the SPI output clock from Generic Serial Flash Interface Intel® FPGA IP. The maximum SPI clock is half of the input clock. Example:
#************************************************************** # Create Generated Clock #************************************************************** #constrain the generated clock dclk. The input clock of GSFI IP is used and created a counter logic to generate a slower DCLK that is used as SPI clock #here, we set the maximum dclk, which is half of the input clk_clk #refer to the GSFI UG, and you find that the maximum SPI clock baud-rate divisor is 2. create_generated_clock -name {dclk_int} -source [get_ports {clk_clk}] -divide_by 2 [get_pins {u0|intel_generic_serial_flash_interface_top_0|intel_generic_serial_flash_interface_top_0|qspi_inf_inst|flash_clk_reg|q}] create_generated_clock -name {dclk} -source [get_pins {u0|intel_generic_serial_flash_interface_top_0|intel_generic_serial_flash_interface_top_0|qspi_inf_inst|flash_clk_reg|q}] [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_dclk}]
- Set a multicycle path to change the setup and hold clock relationship between the input clock and the SPI clock. Example:
Note: The multicycle path is different in Quartus® Prime Pro Edition and Quartus® Prime Standard Edition.
- In Quartus® Prime Pro Edition:
#************************************************************** # Set Multicycle Path #************************************************************** # For a divide by 2 DCLK # SPI lactched data on rising edge dclk and FPGA driven data output on rising edge clk_clk set_multicycle_path -setup -start -from [get_clocks {clk_clk}] -to [get_clocks {dclk}] 2 set_multicycle_path -hold -start -from [get_clocks {clk_clk}] -to [get_clocks {dclk}] 1 # SPI driven data on falling edge of dclk and FPGA latched data on failing edge of clk_clk set_multicycle_path -setup -end -from [get_clocks {dclk}] -to [get_clocks {clk_clk}] 2 set_multicycle_path -hold -end -from [get_clocks {dclk}] -to [get_clocks {clk_clk}] 1
- Quartus® Prime Standard Edition:
#************************************************************** # Set Multicycle Path #************************************************************** # For a divide by 2 DCLK # SPI lactched data on rising edge dclk and FPGA driven data output on rising edge clk_clk set_multicycle_path -setup -start -from [get_clocks {clk_clk}] -to [get_clocks {dclk}] 2 set_multicycle_path -hold -start -from [get_clocks {clk_clk}] -to [get_clocks {dclk}] 1 # SPI driven data on falling edge of dclk and FPGA latched data on second rising edge of clk_clk set_multicycle_path -setup -end -from [get_clocks {dclk}] -to [get_clocks {clk_clk}] 1 set_multicycle_path -hold -end -from [get_clocks {dclk}] -to [get_clocks {clk_clk}] 1
- In Quartus® Prime Pro Edition:
- Set the input and output delays for the quad serial peripheral interface (QSPI) IO pin. Example:
#************************************************************** # Set Input Delay #************************************************************** #$input_delay is determined by Tco values and board parameters (outside of FPGA) #$input_delay_max = data_trace_max - clk_trace_min + ext_tco_max #$input_delay_min = data_trace_min - clk_trace_max + ext_tco_min set_input_delay -clock { dclk } -max -clock_fall -add_delay $input_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[0]}] set_input_delay -clock { dclk } -min -clock_fall -add_delay $input_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[0]}] set_input_delay -clock { dclk } -max -clock_fall -add_delay $input_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[1]}] set_input_delay -clock { dclk } -min -clock_fall -add_delay $input_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[1]}] set_input_delay -clock { dclk } -max -clock_fall -add_delay $input_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[2]}] set_input_delay -clock { dclk } -min -clock_fall -add_delay $input_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[2]}] set_input_delay -clock { dclk } -max -clock_fall -add_delay $input_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[3]}] set_input_delay -clock { dclk } -min -clock_fall -add_delay $input_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[3]}]
#************************************************************** # Set Output Delay #************************************************************** #$output_delay is determined by Th and Tsu values and board parameters (outside of FPGA) #$output_delay_max = data_trace_max + Tsu - clk_trace_min #$output_delay_min = data_trace_min - Th - clk_trace_max set_output_delay -clock { dclk } -max -add_delay $output_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[0]}] set_output_delay -clock { dclk } -min -add_delay $output_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[0]}] set_output_delay -clock { dclk } -max -add_delay $output_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[1]}] set_output_delay -clock { dclk } -min -add_delay $output_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[1]}] set_output_delay -clock { dclk } -max -add_delay $output_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[2]}] set_output_delay -clock { dclk } -min -add_delay $output_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[2]}] set_output_delay -clock { dclk } -max -add_delay $output_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[3]}] set_output_delay -clock { dclk } -min -add_delay $output_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_data[3]}] set_output_delay -clock { dclk } -max -add_delay $output_delay_max [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_ncs}] set_output_delay -clock { dclk } -min -add_delay $output_delay_min [get_ports {intel_generic_serial_flash_interface_top_0_qspi_pins_ncs}]