amaranth
amaranth copied to clipboard
Support for generated clock constraints
We currently do not have a way to define an explicit relationship between a clock and another user-generated clock, derived from the former. The relationship would be expressed in terms of frequency division/multiplication, phase shift, and duty cycle.
Support would vary between toolchains:
- Vivado, Diamond, iCECube2 and Quartus have a
create_generated_clock
XDC/SDC constraint. - nextpnr-{ice40,ecp5} doesn't seem to implement generated clock constraints.
Also, unlike platform-level clocks, a generated clock could be local to a submodule and therefore not propagated to the top-level. We would need a way to retrieve its name in order to pass it as a constraint parameter.
FYI - We are working on making Yosys (through plugins -> https://github.com/SymbiFlow/yosys-symbiflow-plugins and https://github.com/SymbiFlow/yosys-symbiflow-plugins/issues/18) propagate SDC timing constraints through clock buffers (and generate derived timing constraints through things like PLLs) and then write out a new SDC file with the complete constraint set (against the generated json / blif names). As nextpnr uses Yosys as a front end, it might make it easier for nextpnr to support this type of thing?
Related to #425.
So actually, when you instantiate a PLL, the toolchain creates a generated clock automatically. create_generated_clock
is useful primarily in one case: when you have a clock mux. The SDC files can quickly get extremely unwieldy however, if you start stacking the muxes.
The proposal as stated would require an RFC, but a much more practical solution is to add a platform function that both instantiates a BUFGMUX
or whatever and adds the requisite constraints. This is a fairly niche use case though and it's a low priority to add something like that.