如何捕获后门路径信号的跳变?

电子说

1.2w人已加入

描述

使用后门方式测量时钟频率的需求来源更多是SOC验证的场景,由于SOC的规模较大,一次编译时间成本较高,在N个小时级别。如果采用前门方式,比如编写测量频率的module或者interface,一旦有新的测量需求则就需要TB重新连接时钟信号,重新编译环境。

此前的一篇文章,提出了一个问题:如何后门准确地捕获到信号地跳变沿?

如何捕获后门路径信号的跳变?

高电平

如果无法精确捕获到信号地跳变沿,那么也就无法"精确地"测量出时钟地频率。容易想到的办法,是可以使用如下的方法进行测量:

 

bit dut_value=1
//step1:找到信号低电平
while(dut_value) begin
hdl_read("xxx",dut_value)
#N
end

//step2:找到高电平,作为测量的第一个上升沿时刻
bit dut_value=0
//找到信号低电平
while(!dut_value) begin
hdl_read("xxx",dut_value)
#N
end

//step3: 找到低电平,作为下降沿
...
//step4: 找到高电平,作为测量的第二个上升沿。记录此时的仿真时间,减去step2的仿真时间,得到时钟周期
...

 

上述的代码需要考虑如下问题:

时钟频率,时钟频率的大小决定了两次后门读取的间隔,即上述代码中的#N,这也是后门方式测不准的来源。

timescale,dut信号的timescale和后门测量所在的scope的timescale可能并不一致。

那怎么解决测不准的问题?

第一次意识到这个问题,作者也曾一度陷入苦思冥想,始终找不到完美的解决办法。曾经也想过用#1step来进行step级别的delay,但也由于仿真器的差异、环境结构的差异,表现不够稳定。虽然已过去了近一年的时间,工作也换了新的公司,还好对此的思考没有停止。

最近终于开发出了clock_probe_pkg,一个可以使用后门方式,精确测量时钟频率的package。

请看下面的demo:

 

`timescale 1ps/1ps
module tb;
  import clock_probe_pkg::*;
  reg clk1,clk2,clk3;
  
  initial begin
      clk1=0;
      clk2=0;
      clk3=0;
    fork
      forever begin #11; clk1 = ~clk1; end
      forever begin #17; clk2 = ~clk2; end
      forever begin #19; clk3 = ~clk3; end
    join_none
  end
  initial begin
    real freq1,freq2,freq3;
    #100;
    get_clock_freq("tb.clk1",freq1);
    get_clock_freq("tb.clk2",freq2);
    get_clock_freq("tb.clk3",freq3);
    $display("freq1=%f, freq2=%f, freq3=%f",freq1,freq2,freq3);
    $finish();
  end
endmodule

 

仿真结果如下:

 

clock_probe_pkg: get clock hier :tb,2
clock_probe_pkg: get clock scope timeunit: -12
clock_probe_pkg: @110.000000 tb.clk1 = 0,0
clock_probe_pkg: @121.000000 tb.clk1 = 1,1
clock_probe_pkg: @132.000000 tb.clk1 = 0,2
probe clock freq done, freq=45454.545455 @0
clock_probe_pkg: get clock hier :tb,2
clock_probe_pkg: get clock scope timeunit: -12
clock_probe_pkg: @153.000000 tb.clk2 = 1,0
clock_probe_pkg: @170.000000 tb.clk2 = 0,1
clock_probe_pkg: @187.000000 tb.clk2 = 1,2
probe clock freq done, freq=29411.764706 @0
clock_probe_pkg: get clock hier :tb,2
clock_probe_pkg: get clock scope timeunit: -12
clock_probe_pkg: @209.000000 tb.clk3 = 1,0
clock_probe_pkg: @228.000000 tb.clk3 = 0,1
clock_probe_pkg: @247.000000 tb.clk3 = 1,2
probe clock freq done, freq=26315.789474 @0
freq1=45454.545455, freq2=29411.764706, freq3=26315.789474
$finish called from file "testbench.sv", line 26.
$finish at simulation time                  266

 

clock_probe_pkg可以自动识别时钟信号所在scope的timescale,而且仅有一个接口,方便使用。get_clock_freq:

 

task get_clock_freq(string path, output real x_freq);
...
endtask

 

第一个参数为字符串类型的时钟信号的后门路径,第二个参数即为返回的时钟频率,单位为MHz。

clock_probe_pkg也是目前作者能找到的"完美"解决方案。虽然这个需求非常小众,可能也不一定能完全满足需求,可能后续还会更好的解决方案,但这个尝试的过程,作者觉得仍然是有意义的尝试,因为:

真理存在于寻求过程之中。

审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分