# -*- tcl -*- # Clock constraints # Input master clock for all PLLs create_clock -name "clock_48" -period 20.834ns [get_ports {clock_48}] derive_pll_clocks # Handle both the RTC input clock and the internal workaround # The internal workaround clock should still be treated an asynchronous create_clock -name "rtc_32khz" -period 30517.578ns [get_ports {rtc_32khz}] create_clock -name "ctr_32khz" -period 30517.578ns [get_registers {ctr_32khz}] set_clock_groups -asynchronous -group {rtc_32khz} set_clock_groups -asynchronous -group {ctr_32khz} # Automatically calculate clock uncertainty to jitter and other effects. derive_clock_uncertainty # Don't report signaltap clock problems... set_false_path -to [get_registers sld_signaltap:*] # -------- PLL clock mappings -------- set sdram_out_clk [get_clocks {pll|*|clk[0]}] set sdram_clk [get_clocks {pll|*|clk[4]}] set sys_clk [get_clocks {pll|*|clk[1]}] set vid_clk [get_clocks {pll|*|clk[2]}] set flash_clk [get_clocks {pll|*|clk[3]}] set main_clocks [get_clocks {pll|*}] # Reset isn't actually a clock, but Quartus thinks it is create_generated_clock -name rst_n \ -source [get_nets {pll|*|*clk[1]}] \ [get_registers rst_n] # Reset is asynchronous with everything as far as we are concerned. set_clock_groups -asynchronous \ -group $main_clocks \ -group [get_clocks rst_n] # Anything that feeds into a synchronizer is by definition # asynchronous, but encode it as allowing multicycle of one # clock, to limit the possible skew (but it is of course not possible # to eliminate it...) set synchro_inputs [get_registers *|synchronizer:*|qreg0*] set_multicycle_path -from [all_clocks] -to $synchro_inputs \ -start -setup 2 set_multicycle_path -from [all_clocks] -to $synchro_inputs \ -start -hold 1 # -------- SDRAM I/O constraints -------- set sr_data_out [remove_from_collection [get_ports sr_*] sr_clk] set sr_data_in [get_ports sr_dq\[*\]] set_max_skew -to $sr_data_out 0.100ns set_input_delay -clock $sdram_clk 0.500ns $sr_data_in set_multicycle_path -from $sdram_clk -to $sdram_out_clk \ -start -setup 2 set_multicycle_path -from $sdram_clk -to $sdram_out_clk \ -start -hold 0 # -------- SPI ROM multicycle paths -------- # the load of the spi_data_ctr register happens no less than 2 target # clocks after datalen is loaded by the CPU set_multicycle_path -from [get_registers {spirom:*|datalen[*]}] \ -to [get_registers {spirom:*|spi_data_ctr[*]}] -end -setup 2 set_multicycle_path -from [get_registers {spirom:*|datalen[*]}] \ -to [get_registers {spirom:*|spi_data_ctr[*]}] -end -hold 1 # A load of romstart does not affect spi_cmd for a minimum of 3 target # clock cycles (in reality much more, since the CPU needs to # write datalen in order to start the transfer) set_multicycle_path -from [get_registers {spirom:*|romstart[*]}] \ -to [get_registers {spirom:*|spi_cmd[*]}] -end -setup 3 set_multicycle_path -from [get_registers {spirom:*|romstart[*]}] \ -to [get_registers {spirom:*|spi_cmd[*]}] -end -hold 2 # CS# going low to spi_clk_en is a minimum of one clock cycle, which allows # an extra clock cycle before spi_cmd needs to stop resetting set_multicycle_path -from [get_registers {spirom:*|spi_cs_n}] \ -to [get_registers {spirom:*|spi_cmd[*]}] -end -setup 2 set_multicycle_path -from [get_registers {spirom:*|spi_cs_n}] \ -to [get_registers {spirom:*|spi_cmd[*]}] -end -hold 1 # -------- CPU/fastmem multicycle paths -------- # We never read and write in the same clock cycle, thus there is a multicycle # path from the write enable register to anything in the CPU itself set_multicycle_path -from [get_keepers {fast_mem:fast_mem|*porta_we_reg*}] \ -to [get_keepers {picorv32:cpu|*}] -start -setup 2 set_multicycle_path -from [get_keepers {fast_mem:fast_mem|*porta_we_reg*}] \ -to [get_keepers {picorv32:cpu|*}] -start -hold 1