赞
踩
在前一篇博客中,介绍了如何设置input_delay。但是上一篇博客中所使用到的方法还是根据移相过后的时钟去对数据进行采样。在这篇博客中,将使用IDELAY CTRL 和IDELAY2原语对数据进行延时,在这基础上,对输入的数据尽心input_delay约束,最终让千兆网系统同样能够正常工作。
Xlinx的FPGA器件中,存在可以使用的延时资源IDELAY允许在输入引脚上对其进行延时,IDELAYCTRL的输入参考时钟可以来确定延迟的分辨率。
原语的Template 如下:
// IDELAYE2: Input Fixed or Variable Delay Element // Artix-7 // Xilinx HDL Language Template, version 2018.3 (* IODELAY_GROUP = <iodelay_group_name> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(0), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst ( .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output .DATAOUT(DATAOUT), // 1-bit output: Delayed data output .C(C), // 1-bit input: Clock input .CE(CE), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(CINVCTRL), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input .DATAIN(DATAIN), // 1-bit input: Internal delay data input .IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O .INC(INC), // 1-bit input: Increment / Decrement tap delay input .LD(LD), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(LDPIPEEN), // 1-bit input: Enable PIPELINE register to load data input .REGRST(REGRST) // 1-bit input: Active-high reset tap-delay input );
对于该原语的使用还需要参考手册中的内容: UG471
在我所使用FIXED模式,可以根据延时分辨率来具体设置延时的大小。也即属性中的IDELAY_VALUE。从它的注释中可以看出,延时等级可以有0~31。通过调整延时等级就可以来调整输入数据的延时的大小。
对于该原语,还有一个比较重要的就是参考时钟的频率,参考时钟的频率决定了延时分辨率的大小。
前面介绍了输入延时的原语IDELAY2,该原语必须配合IDELAYCTRL原语来使用,该原语需要输入参考时钟。
该原语的用法十分简单,只需要将输入的参考时钟和复位提供即可。
// IDELAYCTRL: IDELAYE2/ODELAYE2 Tap Delay Value Control
// Artix-7
(* IODELAY_GROUP = <iodelay_group_name> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
IDELAYCTRL IDELAYCTRL_inst (
.RDY(RDY), // 1-bit output: Ready output
.REFCLK(REFCLK), // 1-bit input: Reference clock input
.RST(RST) // 1-bit input: Active high reset input
);
首先在顶层模块中,例化IDELAYCTRL原语,需要给该模块提供一个200M的参考时钟。
rgmii_clk_shift inst_rgmii_clk_shift(
.clk_out1(clk_ref), // output clk_out1
.reset(~rst_n), // input reset
.locked(locked), // output locked
.clk_in1(sys_clk) // input clk_in1
);
IDELAYCTRL IDELAYCTRL_inst (
.RDY(), // 1-bit output: Ready output
.REFCLK(clk_ref), // 1-bit input: Reference clock input
.RST(~rst_n) // 1-bit input: Active high reset input
);
然后需要在rgmii_to_gmii模块中对数据进行延时:
generate genvar i; for(i = 0 ; i < 4 ; i = i + 1)begin IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(0), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst_data ( .CNTVALUEOUT(), // 5-bit output: Counter value output .DATAOUT(rgmii_rd_dd[i]), // 1-bit output: Delayed data output .C(1'b0), // 1-bit input: Clock input .CE(1'b0), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(5'd0), // 5-bit input: Counter value input .DATAIN(1'b0), // 1-bit input: Internal delay data input .IDATAIN(rgmii_rd[i]), // 1-bit input: Data input from the I/O .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input .LD(1'b0), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input ); IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_inst_data ( .Q1(gmii_rd[i]), // 1-bit output for positive edge of clock .Q2(gmii_rd[i+4]), // 1-bit output for negative edge of clock .C(rgmii_rxc), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(rgmii_rd_dd[i]), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(rst) // 1-bit set ); end endgenerate
IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(0), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst_ctl ( .CNTVALUEOUT(), // 5-bit output: Counter value output .DATAOUT(rgmii_rx_ctl_dd), // 1-bit output: Delayed data output .C(1'b0), // 1-bit input: Clock input .CE(1'b0), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(5'd0), // 5-bit input: Counter value input .DATAIN(1'b0), // 1-bit input: Internal delay data input .IDATAIN(rgmii_rx_ctl), // 1-bit input: Data input from the I/O .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input .LD(1'b0), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input ); IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_inst_ctrl ( .Q1(gmii_rx_dv), // 1-bit output for positive edge of clock .Q2(gmii_rx_err_r), // 1-bit output for negative edge of clock .C(rgmii_rxc), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(rgmii_rx_ctl_dd), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(rst) // 1-bit set );
这里设置的延时值DELAY_VALUE = 0.先进行一次综合,然后从查看时序报告。
从采样结果看,当前的采样值依旧是错误的。接下来打开时序分析工具,先对输入的数据进行input_delay确定输入数据与采样时钟需要满足的关系,然后再以这个关系为知道,来调整延时值。这里设置的input_delay和前一篇的博客的设置方法一致。综合完成后,可以看到保持时间出现了违例。
可以看到对于输入端口的数据,保持时间全部都出现了违例。保持时间违例,说明输入的数据的结束时间比要求的结束时间要小,因此,需要对数据进行增大延时处理。需要更改IDELAY2的DEALY_VALUE。由于IDELAY2的延时分辨率为 1/(322CLK_REF),因为参考时钟为200M,因此可以得到分辨率是0.078125ns。在这里将数据延时以满足保持时间,首先尝试延时1.2ns,需要设置的分辨率抽头系数为16。再次综合后,查看时序报告。
IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(16), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst_data ( .CNTVALUEOUT(), // 5-bit output: Counter value output .DATAOUT(rgmii_rd_dd[i]), // 1-bit output: Delayed data output .C(1'b0), // 1-bit input: Clock input .CE(1'b0), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(5'd0), // 5-bit input: Counter value input .DATAIN(1'b0), // 1-bit input: Internal delay data input .IDATAIN(rgmii_rd[i]), // 1-bit input: Data input from the I/O .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input .LD(1'b0), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input );
可以看到,调整延时值过后,已经能够正确采集到数据,并且,上位机也成功接收到数据。但是此时时序还是存在违例,但是,此时的违例信息,已经相较于没有更改之前,要好很多了。
可以看到依旧是保持时间不满足。因此还需要增大延时值。本次增加延时值为19。
经过本次调整后,建立时间和保持时间都满足了要求了哦。
参考:
V3学院时序分析课程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。