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

MAX10 constraining IO problems

Altera_Forum
Honored Contributor II
1,318 Views

Hello, 

I am fairly new to FPGA development and learning about constraining my system but am really struggling. My system 'works' at certain clock frequencies but change something and I have I/O glitches so I clearly haven't constrained the IO properly. 

I've read and tried to understand http://www.alterawiki.com/wiki/timequest_user_guide by Rysc and while that helped a lot I am struggling with generating the constraints. 

 

I've done quite a bit of googling to try to find examples or references I can use as a base but my system doesn't fit the normal source synchronous simple examples. 

 

Paint representation of the system: 

 

https://alteraforum.com/forum/attachment.php?attachmentid=14398&stc=1  

 

The system is an 8 bit 5v micro "host" and an 8-bit 5v processor unit "parasite" connected via the MAX10 FPGA which implements various FIFO buffers as well as the boot ROM (via user FLASH) for the parasite uP. For the curious both uPs are 6502 variants. The 2MHzE clock comes from the host via buffers. The 8MHz FPGA clock is unrelated to the 2MHz clock. The FPGA generates the output clock for the parasite CPU using the PLL again via buffers (delay). All signal lines are buffered with delays. 

 

I've tried to create the clocks but don't think I've got them defined right because TQ lists my clock input CLK_0n_p25 in the unconstrained inputs list. 

 

The CPUs address timing goes from falling to falling which I think I have OK. The CPU read (FPGA out) goes from falling edge so I think that is OK too. The CPU write (FPGA in) setup is from the rising edge and hold is falling edge. I can't work out how to constrain this. The PLL will be reprogramable at runtime to change the parasite clock frequency so I don't want to hard code magic numbers for periods into the constraints but istead do it properly from the correct edges. 

 

PLL[1] is the parasite CPU clock out skewed -5ns by the PLL. 

PLL[2] is the parasite CPU clock no skew for internal timing. 

 

I understand the setup errors I get as a result of the skewed clocks - I need to set up the multicycle paths between the clocks properly. 

 

SDC (it is in a bit of a state because I have hacked at it a lot to try to get it working/understand what I'm doing..) 

# needed? set_time_format -unit ns -decimal_places 3 # physical clocks create_clock -name clk_2MHzE -period 500 create_clock -name clk_8M_in -period 125 # derived create_generated_clock -name clk_flash -source -divide_by 16 # parasite clock at the pin create_generated_clock -name parasite_phi0_out -source }] # create external parasite cpu clock n ns delay create_generated_clock -name parasite_phi0_ext -source -offset 4.5 # virtual# create_clock -name host_2MHzE_ext -period 500# set_clock_latency -source -30 # set_clock_latency -source -5 # set_clock_latency seems to do nothing on virtual clocks create_generated_clock -name host_2MHzE_ext -source -offset -5 # name pll clocks create_generated_clock -name parasite_phi0 -source }] # pll derive_pll_clocks -create_base_clocks derive_clock_uncertainty # clock groups set_clock_groups -asynchronous -group -group -group -group cg|internal_pll_inst|altpll_component|auto_generated|pll1|clk parasite_phi0 parasite_phi0_out parasite_phi0_ext }] # # host i/o # HOST->FPGA addr : 100ns setup + 5ns board delay, 15ns hold 100+5 & 15-5 set_input_delay -clock { host_2MHzE_ext } -clock_fall -max 105 host_r_nw host_tube_n}] set_input_delay -clock { host_2MHzE_ext } -clock_fall -min 10 host_r_nw host_tube_n}] # HOST->FPGA data : (500-110)ns setup, 30ns hold + 5ns board delay. 390+5 & 30-5 set_input_delay -clock { host_2MHzE_ext } -clock_fall -max 395 }] set_input_delay -clock { host_2MHzE_ext } -clock_fall -min 25 }] # FPGA->HOST data : 60ns setup + 5ns board delay, 10ns hold. 65+5 & -10+5 set_output_delay -clock { host_2MHzE_ext } -clock_fall -max 70 }] set_output_delay -clock { host_2MHzE_ext } -clock_fall -min -5 }] # ## # parasite i/o # PARA->FPGA addr : ~12 setup, ~10ns hold, ? delay. originally measured set_input_delay -clock { parasite_phi0_ext } -clock_fall -max 12 parasite_r_nw}] set_input_delay -clock { parasite_phi0_ext } -clock_fall -min 0 parasite_r_nw}] # PARA->FPGA data : 5 setup, 10 hold, 3? delay. set_input_delay -clock { parasite_phi0_ext } -max 13 }] set_input_delay -clock { parasite_phi0_ext } -clock_fall -add_delay -min 0 }] # FPGA->PARA data : 10 setup, 10 hold. 3? delay 10+3 & -10+3 set_output_delay -clock { parasite_phi0_ext } -clock_fall -max 15 }] set_output_delay -clock { parasite_phi0_ext } -clock_fall -min -5 }] # # SRAM i/o # FPGA->SRAM wren : set_output_delay -clock { parasite_phi0 } -clock_fall -max 10 set_output_delay -clock { parasite_phi0 } -clock_fall -min 0  

 

So questions: 

1) Have I correctly created the 2MHz clock(s)? (TQ places my input pin CLK_0n_p25 on unconstrained input report) 

2) How do I constrain the data IO from rising egde launch & falling edge latch? (this is not right in my SDC) 

3) My min parasite clock is 3MHz and max 25Mhz. How do I manage a variant since since the clock is currently derived from the PLL megafunction settings?  

 

Any help appreciated, I am vey confused at the moment. 

 

Thanks, 

Chris
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
267 Views

Your picture is way too small to see, so it's difficult to understand what is going where. Try going through this training to see if helps in setting this up. Then come back here if you're still having issues. 

 

https://www.altera.com/support/training/course/ocss1000.html
0 Kudos
Altera_Forum
Honored Contributor II
267 Views

Hello, 

 

Ok, I uploaded a PNG which seems to have been converted to a JPG thumbnail by the forum software. 

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=14400  

 

It is a confusing situation for a novice because all data and clock lines are buffered so there are delays on everything and I know I don't understand yet how to enter all the delays & external device setup/hold timings correctly in an SDC file. 

 

Thanks, I will go through that training. 

 

I have also discovered another Rysc tutorial on source synchronous connections which I am reading. http://www.alterawiki.com/wiki/source_synchronous_analysis_with_timequest
0 Kudos
Altera_Forum
Honored Contributor II
267 Views

Ok, I found and worked my way through the http://www.alterawiki.com/wiki/source_synchronous_analysis_with_timequest by Rysc and that helped a lot I think. I created a 1 bit test project with a 1 bit address, data in, data out & clock to explore the timing and delays. 

 

Since my data writes (FPGA->CPU falling edge latch) depend on the address read (CPU->FPGA rising edge latch) I thought this was similar to the DDR examples so I duplicated my min&max for rising and falling edges then set a false path between falling & falling. 

 

Transfers only occur to the falling edge so is this the correct approach or is there a better method? 

 

Do the min & max values for the non-transfer edges actually matter, I copied the correct edge values but should I set these to zero or something highly permissive? (If I leave these timings out I get warnings from timequest) 

 

create_generated_clock seems to happily create virtual clocks in Quartus Prime Lite 17.1. The clocks look OK in the TQ clock tree but Google found me some posts wrt Quartus II saying create_generated_clock does not do what you expect/work. 

 

Is create_generated_clock OK to use to make a virtual clock in QP 17.1? 

 

My system runs stably with the following SDC constraint file: 

# needed? set_time_format -unit ns -decimal_places 3 # physical clocks create_clock -name clk_2MHzE -period 500 create_clock -name clk_8M_in -period 125 # create on FPGA FLASH clock create_generated_clock -name clk_flash -source -divide_by 16 # parasite clock at the pin create_generated_clock -name parasite_phi0_out -source }] # create external parasite cpu clock 3ns rise & 6ns fall delay # create_generated_clock -name parasite_phi0_ext -source -offset 4.5 create_generated_clock -name parasite_phi0_ext -source -edges {1 2 3} -edge_shift {3 6 3} # create clock at host CPU # create_clock -name host_2MHzE_ext -period 500 create_generated_clock -name host_2MHzE_ext -source -offset -10 # name pll clocks create_generated_clock -name parasite_phi0 -source }] # create_generated_clock -name parasite_phi0_x3 -source }] # pll derive_pll_clocks -create_base_clocks derive_clock_uncertainty # clock groups set_clock_groups -asynchronous -group -group -group -group cg|internal_pll_inst|altpll_component|auto_generated|pll1|clk parasite_phi0 parasite_phi0_out parasite_phi0_ext }] # # host i/o # HOST->FPGA addr # setup: 140ns after falling edge (R6502) # hold: 15ns after falling edge (65C02) # buffer delay: 3ns - 5ns # max = 140+5, min = 15+3 set_input_delay -clock { host_2MHzE_ext } -clock_fall -max 145 host_r_nw host_tube_n}] set_input_delay -clock { host_2MHzE_ext } -clock_fall -min 18 host_r_nw host_tube_n}] # HOST->FPGA data # setup: 110ns after rising edge (65C02) # hold: 30ns after falling edge (65C02) # buffer delay: 3ns-5ns # max = 110+5, min = 30+3 set_input_delay -clock { host_2MHzE_ext } -clock_fall -max 110 }] set_input_delay -clock { host_2MHzE_ext } -clock_fall -min 33 }] set_input_delay -clock { host_2MHzE_ext } -add_delay -max 110 }] set_input_delay -clock { host_2MHzE_ext } -add_delay -min 33 }] set_false_path -from -to # FPGA->HOST data # setup: 60ns before falling edge (65C02) # hold: 10ns after falling edge (65C02) # buffer delay: 3ns-5ns # max = 60+5, min = -10+3 set_output_delay -clock { host_2MHzE_ext } -clock_fall -max 65 }] set_output_delay -clock { host_2MHzE_ext } -clock_fall -min -7 }] # # # # parasite i/o # PARA->FPGA addr # setup: 9ns after falling edge (R6502) # hold: 7ns after falling edge (65C02) # buffer delay: 3ns-4ns # max = 9+4, min = 7+3 set_input_delay -clock { parasite_phi0_ext } -clock_fall -max 13 parasite_r_nw}] set_input_delay -clock { parasite_phi0_ext } -clock_fall -min 10 parasite_r_nw}] # PARA->FPGA data # setup: 8ns after rising edge (measured) # hold: 6ns after falling edge (measured) # buffer delay: 3ns-5ns # max = 8+5, min = -6+3 set_input_delay -clock { parasite_phi0_ext } -clock_fall -max 13 }] set_input_delay -clock { parasite_phi0_ext } -clock_fall -min -3 }] set_input_delay -clock { parasite_phi0_ext } -add_delay -max 13 }] set_input_delay -clock { parasite_phi0_ext } -add_delay -min -3 }] set_false_path -fall_from }] -fall_to # FPGA->PARA data # setup: 10ns before falling edge (guess) # hold: 10ns after falling edge (guess) # buffer delay: 3ns-5ns # max = 10+5, min = -10+3 set_output_delay -clock { parasite_phi0_ext } -clock_fall -max 15 }] set_output_delay -clock { parasite_phi0_ext } -clock_fall -min -7 }] # # SRAM i/o # FPGA->SRAM addr : set_output_delay -clock { parasite_phi0 } -clock_fall -max 10 }] set_output_delay -clock { parasite_phi0 } -clock_fall -min 0 }] # FPGA->SRAM wren : set_output_delay -clock { parasite_phi0 } -clock_fall -max 10 set_output_delay -clock { parasite_phi0 } -clock_fall -min 0  

 

Since I want to reconfigure the PLL at runtime and I have the clocks being derived from the megafunction settings in the timing analysis, how do I define an alternate clock (say 3MHz) for the PLL outputs [1] & [2]? Do I also need to define a full set of alternate phi0 clocks? 

 

Thanks 

Chris
0 Kudos
Reply