Introduction
Having found multiple, sometimes conflicting or incomplete information on the internet and in some training classes about how to create timing constraints in SDC format correctly, I'd like to ask the EE community for help with some general clock generating structures I have encountered.
I know that there are differences on how one would implement a certain functionality on an ASIC or FPGA (I have worked with both), but I think there should be a general, correct way to constrain the timing of a given structure, independent of the underlying technology - please let me know if I'm wrong on that.
There are also some differences between different tools for implementation and timing analysis of different vendors (despite Synopsys offering a SDC parser source code), but I hope that they are mainly a syntax issue which can be looked up in the documentation.
Please also see the related question ASIC timing constraints via SDC: How to correctly specify a multiplexed clock?
Question
This is about the following ripple clock divider, which is part of the clkgen module which is a part of a larger design using the generating clocks:
The generation of clk0
seems to be relatively straight-forward:
create_clock [get_pins clkgen/clk0] -name baseclk -period 500
Though I am not so sure about the SDC commands for the generated, divided clocks clk2
, clk4
and clk8
: How should the source and target options be specified? My initial thought was that target is the output pin on the clock generating cell, source is as close to the target as possible:
create_generated_clock -name div2clk -source [get_pins clkgen/divA/clk] -divide_by 2 [get_pins clkgen/divA/q]
The source could also be the module's clock input pin:
create_generated_clock -name div2clk -source [get_pins clkgen/clk0] -divide_by 2 [get_pins clkgen/divA/q]
Or the previously defined source clock, as suggested here:
create_generated_clock -name div2clk -source [get_clocks baseclk] -divide_by 2 [get_pins clkgen/divA/q]
...which also raises the question if the source or the target options need to be something other than get_pins
, such as get_nets
, get_registers
or get_ports
.
To keep the example as general as possible, let's assume that the generated clocks clk2
, clk4
and clk8
could be driving other, potentially interacting (clock domain crossing) registers (not shown in the schematic).
I think the constraints for clk4
and clk8
should be obvious once we know how the clk2
constraint is written.
The X1 instance (a simple buffer) in the schematic is just a place-holder to highlight the issue of where in the clock propagation network the source option of the create_generated_clock
should be set, as automatic place&route tools are usually free to place buffers anywhere (such as between the divA1/q
and divB1/clk
pins).