content
DDR-PLL in brief
The timing model of DDR-Direct was introduced before, that is, the ordinary timing model without PLL. This section focuses on the model with PLL. These two timing models are also introduced in the SDR sampling model, so the same There will be a timing model of the PLL, and the function of the PLL is the same. The clock can be offset, either positive or negative, corresponding to the increase and decrease of the clock delay.
During analysis, the default PCB data path delay Td_bd and PCB clock path delay Tc_bd are consistent, so when analyzing the clock and data states arriving at the FPGA pins, you only need to know the clock and data states of the pins in the upstream device , the clock and data of the FPGA can be constrained, and the phase relationship between the clock and the data can be analyzed.
The following is the timing diagram, which is analyzed in detail in DDR-Direct, so I won't introduce it here.
This timing model can be used in the case of input with PLL and without PLL. With PLL, when the phase shift of the sampling clock is positive, false path + Multicycle constraint is required, otherwise the analysis report will be incorrect.
Actual operation
This time, we still take a manual of a CMOS device from Sony as an example.
The clock frequency is 54Mhz, that is, the period is 18.519ns, and the half period is 9.259ns. It can be seen in the parameter table that the Max skew is 2ns. Therefore, it can be seen from the figure that the data when the first falling edge is used as the sampling edge is emitted by the previous rising edge. At this time, the arrow 1 in the figure points to The moment is the minimum value of the input delay, and the moment of arrow 2 is the maximum value of the input delay; similarly, when the first falling edge is used as the transmit edge to transmit data, the next rising edge is used as the sampling edge, and the input delay at this time is The maximum and minimum values are the times indicated by arrows 3 and 4, respectively.
It should be noted here that since the PLL is used to shift the phase of the clock, a new clock will be generated. Therefore, more operations should be performed on the timing constraint tool so that the timing tool can correctly identify it, so as not to give Incorrect timing report.
practical engineering
It is still an experimental project of DDR-Direct, and only needs to make a small change to the top-level file.
top level code
Comment out or delete the IDELAY2 primitive added in the previous section and instantiate the PLL with rx_clk as input and rx_clk_90 as output.
module top_ioddr(
input wire rx_clk,
input wire rx_ctrl,
input wire [3:0] rx_dat,
//tx
output wire tx_clk,
output wire [3:0] tx_d,
output wire tx_dv,
input wire sdrclk,
input wire [3:0] sdrdata,
input wire sdrden,
input wire sysclk,
output reg tout
);
wire RDY;
wire rst;
wire rx_clk_90;
wire rx_en;
wire [7:0] rx_data;
reg tx_en1,tx_en2;
reg [7:0] tx_data1,tx_data2;
wire sdrclk1;
assign rst =0;
//assign rx_clk_90 = rx_clk;
IDELAYCTRL IDELAYCTRL_inst (
.RDY(RDY), // 1-bit output: Ready output
.REFCLK(sysclk), // 1-bit input: Reference clock input
.RST(1'b0) // 1-bit input: Active high reset input
);
clk_wiz_0 clk_gen0
(
// Clock out ports
.clk_out1(rx_clk_90), // output clk_out1
// Clock in ports
.clk_in1(rx_clk)); // input clk_in1
assign sdrclk1 = sdrclk;
always @(posedge rx_clk_90 or posedge rst) begin
if (rst == 1'b1) begin
tx_data1 <= 'd0;
end
else if (rx_en == 1'b1) begin
tx_data1 <= rx_data+ rx_data -1;
end
end
always @(posedge rx_clk_90 or posedge rst) begin
if (rst == 1'b1) begin
tx_data2 <= 'd0;
end
else if (tx_en1 == 1'b1) begin
tx_data2 <= tx_data1+ tx_data1 -5;
end
end
always @(posedge rx_clk_90 ) begin
tx_en1 <= rx_en;
end
always @(posedge rx_clk_90 ) begin
tx_en2 <= tx_en1;
end
iddr_ctrl inst_iddr_ctrl
(
.rx_clk_90 (rx_clk_90),
.rst (rst),
.rx_dat (rx_dat),
.rx_ctrl (rx_ctrl),
.rx_en (rx_en),
.rx_data (rx_data)
);
oddr_ctrl inst_oddr_ctrl
(
.sclk (rx_clk_90),
.tx_dat (tx_data2),
.tx_en (tx_en2),
.tx_c (rx_clk_90),
.tx_data (tx_d),
.tx_dv (tx_dv),
.tx_clk (tx_clk)
);
//sdr clock domain
reg [3:0] sdrdata_r1,sdrdata_r2;
reg sdrden_r1,sdrden_r2;
always @(posedge sdrclk1 ) begin
{sdrdata_r2,sdrdata_r1} <= {sdrdata_r1,sdrdata};
end
always @(posedge sdrclk1 ) begin
{sdrden_r2,sdrden_r1} <= {sdrden_r1,sdrden};
end
always @(posedge sdrclk1) begin
if(sdrden_r2 == 1'b1) begin
tout <= (&sdrdata_r1)|(&sdrdata_r2);
end
else begin
tout <= (^sdrdata_r2);
end
end
endmodule
PLL configuration
Setting a phase shift of 30° to the right, which is 1/12 of a period, is about 1.543ns.
After placing and routing the project, you can open the routing design and edit the timing constraints.
Add clock constraints
Constrain rx_clk with a period of 18.518ns
Add input delay constraint
Four input delays need to be constrained, namely Max and Min on the rising edge and Max and Min on the falling edge.
Take the Max of the rising edge as an example, the maximum is 2ns
The Max of the falling edge is set to 2ns, and no overwrite is checked
Notice! When constraining the falling edge, the parameter indicated by the arrow in the figure needs to be checked, indicating whether this constraint will cover the previous constraint on the rising edge, because this experiment is DDR double-edge sampling, the rising and falling edges are both The transmission edge is also used as the sampling edge, so when defining the falling edge constraint, it is necessary to do the operation that does not cover the previous constraint, but the previous SDR does not need it.
A summary of input delay constraints is shown in the figure
CTRL+S Save point and open the XDC constraint file to see the constraint information just added
create_clock -period 18.518 -name sdrclk -waveform {0.000 9.259} [get_ports sdrclk]
set_input_delay -clock [get_clocks rx_clk] -rise -max 2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -rise -min -2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -clock_fall -fall -max -add_delay 2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -clock_fall -fall -min -add_delay -2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
As can be seen from the figure below, when the false path is not constrained to the timing, the constraint tool will put some unnecessary paths. After constraining the contents of the following table, there is no need to analyze the setup time between the rising edge and the rising edge. Yes, no hold time is required between the rising edge and the falling edge.
Add False Path
Add set false path in exceptions in timing constraints
Setup Time
First, make a false path for the setup time between the two rising edges. From is the rising edge of rx_clk, and To is the rising edge of the clock output by the PLL.
Falling edge is the same
And set it as the mark of the rising edge in the options
Hold Time
Then make a false path for the hold time, From is the rising edge of rx_clk, and To is the falling edge of the clock output by the PLL.
Another From is the falling edge of rx_clk, and To is the rising edge of the clock output by the PLL.
The mark set to hold time in options
Multicycle constraint
At this time, some erroneous timing reports will be avoided, but there are still some erroneous reports, such as the analysis of hold time between the rising edge of rx_clk and the rising edge of the clock output by the PLL (between L1r and C2r). At this time, you need to do another constraint Multicycle constraint.
Similarly, to add Multicycle to Exceptions, you need to shift the rising edge of the PLL to the left by one, that is, let C2r become C0r, and set it to -1.
The setting for the falling edge is the same. Not much to say.
The options are set to hold time.
After saving, you can see that there are false path and Multicycle constraint files in the XDC file
set_false_path -setup -rise_from [get_clocks rx_clk] -rise_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -setup -fall_from [get_clocks rx_clk] -fall_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -hold -rise_from [get_clocks rx_clk] -fall_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -hold -fall_from [get_clocks rx_clk] -rise_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_multicycle_path -hold -rise_from [get_clocks rx_clk] -rise_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]] -1
set_multicycle_path -hold -fall_from [get_clocks rx_clk] -fall_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]] -
Reload the timing report and you can see that the timing is violated. By looking at the timing report, it can be concluded that the timing report is correct. Only when the timing report is correct, it makes sense to do timing constraints. If the timing report is wrong, then the timing constraints are useless. The timing report is correct, even if it is a violation, it is not troublesome for us to adjust it. So learning to get timing tools to report correct timing is more important than knowing how to constrain!
report timing can see that there is a violation of the hold time
Solution
Now that the correct timing report is obtained, how to correct the timing can be achieved by using the phase shift function of the PLL. Since there is a violation of the hold time, it means that the delay of the clock is too large. You only need to phase the PLL to the left. Shift 60° to restore the timing to normal.
PLL configuration
Double-click to open the PLL configuration interface and change the phase shift to -60
Re-layout, since this time the PLL is phase-shifted to the left, the Flash Path and Multicycle set by the PLL that has just been shifted to the right are deleted, and then reload and report time to view the timing report.
problem found
At this time, you can see that the timing has returned to normal. But some margins are not normal
in build time
Rx_clk's rise to PLL's rise is wrong
Fall of rx_clk to fall of PLL is wrong
hold time
Fall of rx_clk to rise of PLL is wrong
Rx_clk's rise to PLL's fall is wrong
Add False Path
The setup time and hold time obtained in these four cases are wrong, so they need to be eliminated by false path.
Add four false paths
In addition, there is no need to add Multicycle, because when using PLL, Multicycle needs to be added for right phase shift, but not for left phase shift.
Reload can see that the correct timing is given, and the timing is back to normal.
Summarize
How to get the correct timing report is more important than how to solve the timing violation. Knowing the root of the problem can solve the problem better! When using PLL for timing optimization, pay attention to whether False Path and Multicycle need to be added, and how to add these constraints.