MyFPGA Forum

 找回密码
 注册
搜索
查看: 2654|回复: 1
打印 上一主题 下一主题

[系统相关] 【Altera soc 体验之旅】+延时链测试以及亚稳态...

[复制链接]
跳转到指定楼层
1#
发表于 2015-8-4 10:16:44 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 BOB_Sun 于 2015-8-4 10:29 编辑

[系统相关] 【Altera soc 体验之旅】+延时链测试以及亚稳态分析1

本文转自:http://bbs.eeworld.com.cn/thread-459454-1-1.html


延时链测试以及亚稳态分析

1.前言
  


图 1 静态时序分析的超前进位延时链信息

在上一篇(基于超前进位延时链的时间数字转换器)中,使用TimeQuest分析了延时链的cin到cout的延时为每两个延时单元延时45ps左右(图 1)。但是,对于一个测试的设计,还是要采取一些方法来测试实际的延时单元延时。此文借助SignalTap II工具来实现测试。具体思路是,输入信号的延时间隔除以延时链中边沿移动的延时单元个数求得每个延时单元的延时平均值。

2 延时链延时测试

图 2 长度为200的延时链测试原理图

2.1 时钟sysclk
  

图 3 时钟PLL配置

时钟sysclk的PLL的Verilog源程序如下:

`timescale 1ns/10ps

module  sysclk_0002(



        // interface 'refclk'

        input wire refclk,



        // interface 'reset'

        input wire rst,



        // interface 'outclk0'

        output wire outclk_0,



        // interface 'outclk1'

        output wire outclk_1,



        // interface 'locked'

        output wire locked

);



        altera_pll #(

                .fractional_vco_multiplier("false"),

                .reference_clock_frequency("50.0 MHz"),

                .operation_mode("direct"),

                .number_of_clocks(2),

                .output_clock_frequency0("250.000000 MHz"),

                .phase_shift0("0 ps"),

                .duty_cycle0(50),

                .output_clock_frequency1("250.000000 MHz"),

                .phase_shift1("-2000 ps"),

                .duty_cycle1(50),

                .output_clock_frequency2("0 MHz"),

                .phase_shift2("0 ps"),

                .duty_cycle2(50),

                .output_clock_frequency3("0 MHz"),

                .phase_shift3("0 ps"),

                .duty_cycle3(50),

                .output_clock_frequency4("0 MHz"),

                .phase_shift4("0 ps"),

                .duty_cycle4(50),

                .output_clock_frequency5("0 MHz"),

                .phase_shift5("0 ps"),

                .duty_cycle5(50),

                .output_clock_frequency6("0 MHz"),

                .phase_shift6("0 ps"),

                .duty_cycle6(50),

                .output_clock_frequency7("0 MHz"),

                .phase_shift7("0 ps"),

                .duty_cycle7(50),

                .output_clock_frequency8("0 MHz"),

                .phase_shift8("0 ps"),

                .duty_cycle8(50),

                .output_clock_frequency9("0 MHz"),

                .phase_shift9("0 ps"),

                .duty_cycle9(50),

                .output_clock_frequency10("0 MHz"),

                .phase_shift10("0 ps"),

                .duty_cycle10(50),

                .output_clock_frequency11("0 MHz"),

                .phase_shift11("0 ps"),

                .duty_cycle11(50),

                .output_clock_frequency12("0 MHz"),

                .phase_shift12("0 ps"),

                .duty_cycle12(50),

                .output_clock_frequency13("0 MHz"),

                .phase_shift13("0 ps"),

                .duty_cycle13(50),

                .output_clock_frequency14("0 MHz"),

                .phase_shift14("0 ps"),

                .duty_cycle14(50),

                .output_clock_frequency15("0 MHz"),

                .phase_shift15("0 ps"),

                .duty_cycle15(50),

                .output_clock_frequency16("0 MHz"),

                .phase_shift16("0 ps"),

                .duty_cycle16(50),

                .output_clock_frequency17("0 MHz"),

                .phase_shift17("0 ps"),

                .duty_cycle17(50),

                .pll_type("General"),

                .pll_subtype("General")

        ) altera_pll_i (

                .rst        (rst),

                .outclk        ({outclk_1, outclk_0}),

                .locked        (locked),

                .fboutclk        ( ),

                .fbclk        (1'b0),

                .refclk        (refclk)

        );

endmodule



注意其中的红色加粗部分,参考时钟50MHz;时钟0和1均为250MHz,时钟1的相位超前时钟0 2000ps。时钟0为TDC系统的主时钟,时钟1驱动3位计数器n_counter计数。
2.2 n_counter计数器
源程序如下:

module n_counter

#(parameter WIDTH=63)

(

        input clock,

        input st1,

        output co

        );

        

   reg [WIDTH-1:0] n;

        always @(posedge clock )

        begin

                if(st1) n <= n + 1;

        end

   assign co = n[WIDTH-1];

endmodule



其中,计数器的最高位作为tdc的待测信号输入。当前系统的计数器长度设定为3。
2.3 do_in与add200
详细描述见上一篇(基于超前进位延时链的时间数字转换器)中的描述。
2.4 basic_register
源程序如下:

module basic_register

#(parameter N=100)

(

        input clk,

        input [N-1:0] sr_in,

        output reg [N-1:0] sr_out

);



        always @ (posedge clk)

        begin

                        sr_out <= sr_in;

        end



endmodule



该模块例化成一个200位的寄存器,用以保存add200的延时链输出信息。该寄存器组模块的加入,主要是为了解决,SignalTap II不能直接从add200采集数据。因为一旦直接从add200采集数据,Quartus II总是提示add200的逻辑锁定区域的大小不够。


2.5 ris_g 和encoder
详细内容见上一篇(基于超前进位延时链的时间数字转换器)中的描述。
2.6 SignalTap II测试结果

图 4 相位超前2ns的延时链输出

图 5 相位超前2.5ns的延时链输出数据

图 4图 5中的全1和全0输出对应延时链输入为0和1的情况。图 42处的F…FEC00和图 52处的F…FAC8720…040…0对应的是输入为1后,在紧邻输入上升沿后的时钟上升沿锁存延时链输出的数据。由于,两个数据分别是时钟1超前时钟0 2ns与2.5ns的情况,故两个数据中的1-0跳变处的位置之差对应的就是0.5ns延时差。
2.7 延时链的亚稳态分析
只有正确的识别延时链中的1-0边沿才能获得精确地延时链中延时单元的延时时间。理论上分析在输入的上升沿在延时链中传播后,利用寄存器锁存这一违反寄存器时序要求的传播边沿,必然会引起寄存器出现亚稳态现象。如图 42处的F…FEC00,边沿处的数据EC0对应的二进制码为111011010000。可见,原本应该是全1加全0模式的输出数据,在全1序列中出现了0,在全0序列中出现了1。

上一篇(基于超前进位延时链的时间数字转换器)中的描述边沿检测电路就是为了处理亚稳态现象,找到正确的唯一的边沿位置而提出的。利用该处理电路处理后得到的数据为0…0000000100000000,其中1为上升沿的位置。同样处理图 52处的F…FAC8720…040…0后的数据为0…010000000000000010000…0,数据表示延时链中的边沿有2处,很明显是错误的。针对于芯片的8输入LUT的结构(如 图6 所示),边沿检测电路的实现方法可重新调整为:

同理下降沿检测电路如公式所示。

图 42处的F…FEC00和图 52处的F…FAC8720…040…0经公式处理后为0…0010000000000000和0…00000010000000000000000000000…000000000000…0000。

图6  芯片的LUT的基本结构

计算,0.5ns对应的延时单元个数为90个,则可以测算出一个延时单元的延时为500/90=5.6ps。远小于静态时序分析的45ps。也就是说,250MHz的系统时钟,要求延时链的长度最小为8*90=720位,而不是现在的200位。下面的思路是去查看ChipPlanner视图中的详细走线情况,可详细的走线情况被Altera屏蔽了。期待Altera工程师给出正确的解读。

分析延时链锁存的亚稳态产生原因:
1) 在时钟条边沿锁存输入信号的跳变沿必然会违反触发器的建立与保持时间;
2) 延时链触发器组的时钟输入延时不可能做到完全一致;
3) Pll时钟的输出抖动;
4) 环境噪声;

由此,基于延时链结构的时间数字转换器的亚稳态现象是无法避免,只能通过边沿检测电路尽可能的消除。在利用公式处理的过程中,难免会出现边沿附近的误消除问题,这在一定程度上会影响最终的测量精度。为了提高测量精度,只有采用诸如平均测量等有效的测量手段和方法来提高测量精度。

3 1000位延时链的实现及测试

3.1 1000位延时链的实现

  

图 6 1000延时链实现的顶层原理图

(未完,跟贴中)

1.memorymap.png (61.27 KB, 下载次数: 847)

1.memorymap.png

C_HPS-FPGA.jpg (64.12 KB, 下载次数: 670)

C_HPS-FPGA.jpg

F_embedded.jpg (93.36 KB, 下载次数: 676)

F_embedded.jpg

QQ截图20150414155753.png (47 KB, 下载次数: 685)

QQ截图20150414155753.png

QQ截图20150414160834.png (242.42 KB, 下载次数: 679)

QQ截图20150414160834.png

QQ截图20150414163532.png (123.91 KB, 下载次数: 656)

QQ截图20150414163532.png
2#
 楼主| 发表于 2015-8-4 10:17:25 | 只看该作者
本帖最后由 BOB_Sun 于 2015-8-4 10:42 编辑

其中各模块的源程序如下:

顶层top_sch源程序:

module top_sch #(parameter WIDTH=1000)(

        clock,

        st1,

        st2,

        bi,

        s_o

);


input wire bi;

input wire        clock;

input wire        st1;

input wire        st2;

output wire        s_o;

wire        [WIDTH-1:0] SYNTHESIZED_WIRE_0;

wire        [WIDTH-1:0] SYNTHESIZED_WIRE_1;

wire        [WIDTH-1:0] SYNTHESIZED_WIRE_2;


add200        b2v_inst(

        .clock(clock),

        .data_a(SYNTHESIZED_WIRE_0),

        .dataa(SYNTHESIZED_WIRE_1),

        .result(SYNTHESIZED_WIRE_2));


o_add        b2v_inst2(

        .result(SYNTHESIZED_WIRE_2),

        .s_o(s_o));


l_add        b2v_inst3(

   .bi(bi),

        .clock(clock),

        .st1(st1),

        .result(SYNTHESIZED_WIRE_1));


r_add        b2v_inst4(

   .bi(bi),

        .clock(clock),

        .st1(st2),

        .result(SYNTHESIZED_WIRE_0));


Endmodule



L_add源程序:



module l_add #(parameter WIDTH=1000)(

        input clock,

        input st1,

        input bi,

        output reg [WIDTH-1:0] result);



        always @(posedge clock )

        begin

                if(st1) result <= result + bi;

        end



endmodule



r_add源程序:

module r_add #(parameter WIDTH=1000)(

        input clock,

        input st1,

        input bi,

        output reg [WIDTH-1:0] result);



        always @(posedge clock )

        begin

                if(st1) result <= result + bi;

        end

endmodule

add200源程序:


module add200 #(parameter WIDTH=1000) (

        clock,

        dataa,

        data_a,

        result);



        input          clock;

        input          [WIDTH-1:0]dataa,data_a;

        output        reg [WIDTH-1:0]  result;



        always @(posedge clock)

        begin

                 result <= dataa + data_a;

        end



endmodule


o_add源程序:


module o_add #(parameter WIDTH=1000)(

        input [WIDTH-1:0] result,

        output reg s_o);



        always @(result)

        begin

                 if(result > {{WIDTH/2{1'b1}},{WIDTH/2{1'b0}}}) s_o <= 1'b1; else s_o <= 1'b0;

        end


endmodule


其中l_add与r_add的程序做了微调,把加2的操作,改成了加输入引脚,这样避免了在综合时综合器的过度优化,得到一个完整的1000位加法器的适配结果。


3.2 1000位延时链的测试

图 7 1000位延时链生成的顶层原理图

图 7与 图 2结构类似,唯一的区别就是各个组件的数据处理宽度为1000位。SignalTap II的测试结果为:

图 8 时钟1超前时钟0 2ns

图 9时钟1超前时钟0 2.5ns


图 8图 9的1处是寄存器锁存的数据,2处为经过一个时钟周期(2.5ns)以后的数据,可见2.5ns对应的延时链长度远小于1000,但是为了保证延时链能正确捕获边沿要适当的留足延时链长度。延时链长度的增加加剧了寄存器亚稳态现象,剪短延时链长度有利于抑制亚稳态现象;但当为了提升测量精度,降低延时单元延时值时,有必须增加延时链长度,亚稳态和精度提升在延时链长度上的矛盾是不可调和的,需要设计者做出一个很好的折衷。
4 小结
现存的几个疑点,有待于进一步解决的有:
1) 静态时序分析的45ps左右的单个延时单元延时值和实际测量的出入很大;
2) 超长的延时链经寄存器锁存输出中的复杂的亚稳态现象处理;
3) 如何进一步提升测量精度;
4) TDC测量结果与Nios II CPU的数据传输通道。
(完)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|MyFPGA

GMT+8, 2024-4-26 04:40 , Processed in 0.044402 second(s), 17 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表