I2C验证的时序特性问题

I2C通常支持三种速率模式:标准(100kb/s)/快速(400kb/s)/高速模式(3.4Mb/s)。CCI(Camera Control Interface)是为I2C的子集,仅支持标准和快速两种模式,相对速率较低。因此在采用CCI接口时,应考虑I2C的建立保持时间问题。

根据NXP发布的I2C官方文档,其时序特性要求如下图所示:
在这里插入图片描述
其中,标准模式下(快速模式同理),数据建立时间应至少为250ns保持时间根据注释3应至少为300ns,其他时间如START保持时间STOP建立时间等也有相应规定,由于验证的DUT是slave,因此driver在模拟I2C master时也需要符合规定。

首先分析I2C的建立保持时间检查问题,前仿本身是无法检查器件特性的,但由于I2C速率仅100kHz(标准模式下),而slave端采用的系统时钟域为37.5MHz,因此相当于要求了DUT在SCL时钟沿前后十多个sys clk都需要保持稳定不变。RTL设计在处理该问题时,配置了两个寄存器,分别控制SCL时钟沿前后数据信号(sdo_oen)建立和保持的sys clk数。最初的验证环境在monitor中对建立保持时间进行如下检查:

// cci_master_monitor.sv
begin
    @(negedge vif.scl);
    #cfg.t_hd_dat;
    if(vif.sdo_oen)
        `uvm_error(get_type_name(), $psprintf("sdo_oen enable early while ack after write))
    wait(vif.sdo_oen == 1);
    #cfg.t_su_dat;
    if(vif.scl ==1)
        `uvm_error(get_type_name(), $psprintf("sdo_oen enable didn't meet the setup time before posedge scl))
end

但是考虑到覆盖性和协议的复用性,在interface内采用SVA断言检查。由于不在时钟边沿,这里采用了立即断言:

// cci_master_interface.sv
logic       ref_scl, ref_sdoen;
realtime    t_su_dat_min = 250ns;
realtime    t_hd_dat_min = 300ns;

always@(negedge scl) begin  // setup time check
    @sdo_oen;
    ref_scl = scl;
    #t_su_dat_min;
    p_sudat: assert(scl == ref_scl)
    else `uvm_error("cci_mst_if", $psprintf("sda didn't meet the setup time before posedge scl, for the setup time is %t", t_su_dat_min))
end
    
always@(negedge scl) begin  // hold time check
    ref_sdoen = sdo_oen;
    #t_hd_dat_min;
    p_hddat: assert(sdo_oen == ref_sdoen)
    else `uvm_error("cci_mst_if", $psprintf("sda didn't meet the hold time after negedge scl, for the hold time is %t", t_hd_dat_min))
end

这里hold time的检查逻辑是(针对slave),在SCL下降沿后(slave不会在上升沿后即高电平发数据),最小规定保持时间后,输出值应保持不变;setup time的检查逻辑则是在数据输出后,在最小规定建立时间后,scl时钟应任未翻转。这里的检查可能仍不完整,但是此slave设计在每个scl clk内最多翻转一次,所以可以实现check。

另一个问题是driver对I2C master的时序模拟,I2C的典型时序图如下:
在这里插入图片描述

以标准模式(100kHz)为例,参考上表,首先需要确保正常工作时(即START后)每两个SCL下降沿(或上升沿)间周期为10μs,且每个周期高电平不低于4μs(tHIGH),低电平不低于4.7μs(tLOW)。START的保持时间应至少为4μs(tHD;STA),STOP的建立时间也应至少为4μs(tSU;STO);STOP到下一个START之间的保持时间应不低于4.7μs(tBUF),同样RESTART之前也应有至少4.7μs的保持时间(tSU;STA)。参考上述条件,driver可以在范围内做一些随机,这里以send bit为例:

// cci_master_driver.sv
task cci_master_driver::send_bit(bit dat, output realtime low_time);
    realtime    t_low_hd, t_low;

    vif.scl <= 0;
    
    t_low_hd = this.get_wait_time(cfg.t_hd_dat_max, cfg.t_hd_dat_min);  // (max,min)
    #t_low_hd;
    vif.sda <= dat;
    
    t_low = this.get_wait_time(cfg.scl_peri - cfg.t_high_min - t_low_hd, cfg.t_low_min - t_low_hd);
    #t_low;
    vif.scl <= 1;

    low_time = t_low_hd + t_low;
endtask

...
// call the task
this.send_bit(dat[7], t_low);
#(cfg.scl_peri - t_low);  // complete a cycle

在调用该task后,需要通过计算延时补足一个完整I2C周期。

另外需要注意的问题是,CCI对时序特性的要求和I2C有一些不一致,参考MIPI CSI-2(v1.2)官方文档对CCI的时序特性要求如下:
在这里插入图片描述
例如,标准模式下CCI要求START的保持时间(tHD;STA)为0.4μs,然后SCL可以翻转,而I2C要求至少为4μs。因此,未来如果移植CCI到I2C环境时,可能需要调整。

  • 6
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小破同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值