Xilinx FPGA实现延时链

  之前有做一个输出100ps左右的延时链,当时找到一篇国外的论文,2015年的文章了。链接:《High-Resolution_Synthesizable_Digitally-Controlled_Delay_Lines》,根据论文的内容,要使输出的延时能够更加的准确,这里输出端保持不变,输入端走的是时钟的走线,这样做到了尽可能保证走线的时间一致,只跟原语CARRY4的单元延时有关。

  话不多说,直接上代码,由于没有更精确的设备进行测量延时,所以代码仅供参考。延时链校准论文有提及,由于缺少精密的测量工具,笔者就没进一步研究校准部分。

  1 module delay_chain
  2 #(
  3     parameter                BUF_TYPE        = "BUFG"          ,
  4     parameter                RESOLUTION      = "COARSE"        ,
  5     parameter                CARRY4_STAGE    = 16            
  6 )
  7 (
  8     input                    i_signal                          ,
  9     input    [9:0]           i_carry_num                       ,
 10     output                   o_signal                        
 11 );
 12 
 13     wire                            w_signal_buf               ;
 14     wire    [4*CARRY4_STAGE-1:0]    w_stage_buf                ;
 15 
 16 
 17     generate
 18         if(BUF_TYPE == "BUFR")
 19         begin:BUF1
 20             BUFR
 21             #(
 22                 .BUFR_DIVIDE           ( "BYPASS"                     ),
 23                 .SIM_DEVICE            ( "7SERIES"                    )
 24             )
 25             BUFR_inst
 26             (
 27                 .O                     ( w_signal_buf                 ),
 28                 .CE                    ( 1'b1                         ),
 29                 .CLR                   ( 1'b0                         ),
 30                 .I                     ( i_signal                     )
 31             );
 32         end
 33         else if(BUF_TYPE == "BUFH")
 34         begin:BUF2
 35             BUFH BUFH_inst
 36             (
 37                 .O                     ( w_signal_buf                  ),
 38                 .I                     ( i_signal                      )
 39             );
 40         end
 41         else
 42         begin:BUF3
 43             BUFG BUFG_inst
 44             (
 45                 .O                     ( w_signal_buf                  ),
 46                 .I                     ( i_signal                      )
 47             );
 48         end
 49     endgenerate
 50 
 51 
 52     integer           i;
 53     genvar            n;
 54     
 55     generate
 56         if(RESOLUTION == "COARSE")
 57         begin
 58             reg        [CARRY4_STAGE-1:0]        r_carry_sel;
 59             wire       [CARRY4_STAGE-1:0]        w_carry_sel;
 60             
 61             always@(*)
 62             begin
 63                 r_carry_sel = 'd0;
 64                 for(i = 0; i <= CARRY4_STAGE - 1; i = i + 1)
 65                     if(i_carry_num == i)
 66                         r_carry_sel[CARRY4_STAGE-1-i] = 1'b1;
 67             end
 68             assign w_carry_sel = ~r_carry_sel;
 69             
 70             for(n = 0; n <= CARRY4_STAGE - 1; n = n + 1)
 71             begin
 72                 if(n == 0)
 73                 begin:carry4_first
 74                     CARRY4 CARRY4_inst
 75                     (
 76                         .CO            ( w_stage_buf[3:0]            ),
 77                         .O             (                             ),
 78                         .CI            ( 1'b0                        ),
 79                         .CYINIT        ( 1'b0                        ),
 80                         .DI            ( {3'b000,w_signal_buf}       ),
 81                         .S             ( {3'b111,w_carry_sel[0]}     )
 82                     );
 83                 end
 84                 else
 85                 begin:carry4_X
 86                     CARRY4 CARRY4_inst
 87                     (
 88                         .CO            ( w_stage_buf[4*(n+1)-1:4*n]  ),
 89                         .O             (                             ),
 90                         .CI            ( w_stage_buf[4*n-1]          ),
 91                         .CYINIT        ( 1'b0                        ),
 92                         .DI            ( {3'b000,w_signal_buf}       ),
 93                         .S             ( {3'b111,w_carry_sel[n]}     )
 94                     );
 95                 end
 96             end
 97         end
 98         else
 99         begin
100             reg        [4*CARRY4_STAGE-1:0]        r_carry_sel;
101             wire       [4*CARRY4_STAGE-1:0]        w_carry_sel;
102             
103             always@(*)
104             begin
105                 r_carry_sel = 'd0;
106                 for(i = 0; i <= 4*CARRY4_STAGE - 1; i = i + 1)
107                     if(i_carry_num == i)
108                         r_carry_sel[4*CARRY4_STAGE-1-i] = 1'b1;
109             end
110             assign w_carry_sel = ~r_carry_sel;
111             
112             for(n = 0; n <= CARRY4_STAGE - 1; n = n + 1)
113             begin
114                 if(n == 0)
115                 begin:carry4_first
116                     CARRY4 CARRY4_inst
117                     (
118                         .CO                ( w_stage_buf[3:0]            ),
119                         .O                 (                             ),
120                         .CI                ( 1'b0                        ),
121                         .CYINIT            ( 1'b0                        ),
122                         .DI                ( {4{w_signal_buf}}           ),
123                         .S                 ( w_carry_sel[3:0]            )
124                     );
125                 end
126                 else
127                 begin:carry4_X
128                     CARRY4 CARRY4_inst
129                     (
130                         .CO                ( w_stage_buf[4*(n+1)-1:4*n]  ),
131                         .O                 (                             ),
132                         .CI                ( w_stage_buf[4*n-1]          ),
133                         .CYINIT            ( 1'b0                        ),
134                         .DI                ( {4{w_signal_buf}}           ),
135                         .S                 ( w_carry_sel[4*(n+1)-1:4*n]  )
136                     );
137                 end
138             end
139         end
140     endgenerate
141     
142     assign o_signal = w_stage_buf[4*CARRY4_STAGE - 1];
143     
144 endmodule

 

posted on 2026-01-19 21:58  Galois_V  阅读(2)  评论(0)    收藏  举报