-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SDC: Handle input clock phase shift on clock generators #37
SDC: Handle input clock phase shift on clock generators #37
Conversation
On page 66 in https://www.xilinx.com/support/documentation/user_guides/ug472_7Series_Clocking.pdf are details on how the phase detector of a PLL works. Judging from that I conclude that the whole thing behaves as an "integrating regulator" so it can synchronize both phases and frequencies of CLKINn and CLKFB. I also think that just adding phases is wrong as the frequency of a PLL output may be different than of CLKINn. With that phases on both clocks have different meanings and cannot be added/compared directly. |
The PLL's output phase should be related to one of the input phases in some way. I agree that it isn't a straight summation isn't the right answer, but having the output clocks have no relation to the input phase is wrong too? The output of the VCO in a PLL matches the phase of the input clock. The PLL output registers can then be phase shifted as needed. See page 74 and eq 3-3, 3-4, 3-5. They are all speaking about shifting phase with respect to the input clock. |
So I think I understand the problem, and know half of the solution. Let's ignore frequency changes for a minute. If a 10 ns period, 0 deg 50% wave form enters a PLL that is the following create clock:
So the clock raises on If we apply a 270 degree phase shift to clk, it will be:
So the clock raises at So one bug that needs to be fixed is the waveform values need to be modulus the period. That still leaves the meaning of the phase relationship through a PLL when there is a frequency shift. I believe I know the answer, but want to think on it more. |
I've done some work, and I believe I understand how to relate the input clock phase and the output clock phase on the PLL. If the PLL output phase shift = 0 deg, then the rising edge of the output clock matches the rising edge of the VCO. When FBCLKOUT phase shift = 0, this implies that the VCO and input clock rising edge are phase matched. This means the rising edge of the input clock and the rising edge of the output clock should be equal given the following equation:
where N1 and N2 are some natural number (e.g. some integer >=0). If the PLL output phase shift != 0, the output clock is phase shifted per it's output frequency, with respect to the output phase shift = 0 case. So for example: If the input clock is 100 MHz, with a phase shift of 90 degree, that implies the following create clock:
An output clock of 200 MHz with an output phase shift of 0 should have a rising edge at 2.5 ns, so the create clock is:
An output clock of 200 MHz with an output phase shift of 90 deg would have a create clock of:
So I believe this is how to apply input phase to output phase:
@mkurc-ant / @tmichalak Do you disagree with anything here? I'm going to do some testing to figure out how to accommodate feedback phase shifts. |
Okay, looks like So I think the equations for the output clock wave forms are:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposed fix for PLL phase shifts
f075fea
to
3f957bd
Compare
@litghost All of the above makes sense. Thanks a lot for the analysis. Judging from it the only things missing in the original implementation were the |
Of course. Higher period -> more division. |
Why is the delay through a |
Should have a FIXME/TODO about the |
290114f
to
d0669c1
Compare
Added support for Regarding |
sdc-plugin/buffers.cc
Outdated
assert(RTLIL::unescape_id(cell->type) == "PLLE2_ADV"); | ||
|
||
FetchParams(cell); | ||
if (clkin1_period != input_clock_period) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a approx equal check, e.g. fabs(a - b) < max(a, b)*10*epsilon
. This prevents non-relevant rounding errors from triggering the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. However I am not sure what is meant by the 10
in 10*epsilon
.
I implemented it as fabs(a-b) < max(a, b) * kApproxEqualFactor
where the kApproxEqualFactor
is expressed in float, i.e. 0.01 means +/- 1%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, fixed.
For future developers I feel like this could benefit from a write up with a few diagrams (maybe wavedrom based)? |
Wavedrom looks awesome! |
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
775f2c7
to
c951536
Compare
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Opening this PR for discussion purposes.
For the initial version of the SDC plugin we had a discussion around phase shift and validation of the waveform.
In the current implementation we have a 1ns delay on BUFGs and clock synth's (like MMCM and PLL) output a clock with the computed frequency, and a phase shift equal to the phase specified. For example if the PLL input has a 20 degree phase shift, and the request to the PLL is to add another 45 degree phase shift, the output waveform will have a 65 degree phase shift.
However, this sometimes leads to sanity checks being raised:
Not sure how vivado handles these situations though.