I2C中功能覆盖率的定义

本文详细介绍了I2C控制器的功能覆盖率采样,包括目标地址和从机地址、速度模式、7位和10位地址选择、重启条件、活动状态、使能状态、TX和RX FIFO状态、中断状态、中断清除、中断硬件输出和TXABRT中断源等。通过定义covergroup和使用特定的采样策略,确保了对I2C协议各种操作的全面覆盖和验证。
摘要由CSDN通过智能技术生成

目录

功能覆盖率包含哪些?

1.target_address_and_slave_address_cg

2.speed_modes_cg

3.bits7_or_bits10_addressing_cg 

4.restart_condition_cg

5.activity_cg

6.enabled_cg

7.tx_fifo_status_cg 

8.rx_fifo_status_cg

 9.interrupt_status_cg

10.interrupt_clear_cg 

11.interrupt_hardware_outputs_cg 

 12.interrupt_tx_abort_sources_cg

13.sda_control_cg

14.timeout_counter_cg

如何进行采样?


功能覆盖率包含哪些?

1.target_address_and_slave_address_cg

对于TAR和SAR寄存器中值的采样,分为10BIT和7BIT地址进行采样,采样时只关心高bit位就行,因为一般高bit位容易被截取,所以采用wildcard bins来进行定义,无关的bit位采用x来代替:

 covergroup target_address_and_slave_address_cg with function sample(bit[9:0]addr, string field);
    option.name = "target_address_and_slave_address_cg";
    TAR_BITS10: coverpoint addr[9:7] iff(field == "TAR"){
      wildcard bins range1 = {3'b1xx};
      wildcard bins range2 = {3'b0xx};
    }

    TAR_BITS7: coverpoint addr[6:0] iff(field == "TAR"){
      wildcard bins range1 = {7'b1xx_xxxx};
      wildcard bins range2 = {7'b0xx_xxxx};
    }

    SAR_BITS10: coverpoint addr[9:7] iff(field == "SAR"){
      wildcard bins range1 = {3'b1xx};
      wildcard bins range2 = {3'b0xx};
    }

    SAR_BITS7: coverpoint addr[6:0] iff(field == "SAR"){
      wildcard bins range1 = {7'b1xx_xxxx};
      wildcard bins range2 = {7'b0xx_xxxx};
    }

  endgroup

2.speed_modes_cg

对不同的速度模式进行采样,对应IC_CON[2:1]的SPEED域,还有对应的HCNT和LCNT,根据SSmode频率<=100Kb,FSmode<=400Kb,HSmode<=3.4Mb,来合理的设计边界的bin值,SSmode下:HCNT+LCNT>=100MHz/100Kb=1000

FSmode下:HCNT+LCNT>=100MHz/400Kb=250

HSmode下:HCNT+LCNT>=100MHz/3.4Mb~30

covergroup speed_modes_cg with function sample(bit[15:0] val, string field);
    option.name = "speed_modes_cg";
    SPEED: coverpoint val iff(field == "SPEED") {
      bins standard = {1};
      bins fast = {2};
      bins high = {3};
    }
    
    // In SS mode, the frequency of SCL is 0 - 100 Kbs
    // To ensure that there is no 0 rate in the actual situation and the sim
    // does not time out, we just test 50 - 100 Kbs
    // Refer to the period of i2c_clk 100 MHz
    // Fastest:
    // The count value is 100MHz / 100Kbs = 1000 = SS_SCL_HCNT + SS_SCL_LCNT
    // Slowest:
    // The count value is 100MHz / 50Kbs = 2000 = SS_SCL_HCNT + SS_SCL_LCNT
    SS_SCL_HCNT: coverpoint val iff(field == "SS_SCL_HCNT") {
      bins max = {[800:1000]};
      bins min = {[500:600]};
    }
    SS_SCL_LCNT: coverpoint val iff(field == "SS_SCL_LCNT") {
      bins max = {[800:1000]};
      bins min = {[500:600]};
    }

    // In FS mode, the frequency of SCL is <= 400 Kbs
    // To ensure frequency FS > SS, we just test 100 - 400 Kbs
    // Refer to the period of i2c_clk 100MHz
    // Fastest:
    // The count value is 100MHz / 400Kbs = 250 = FS_SCL_HCNT + FS_SCL_LCNT
    // Slowest:
    // The count value is 100MHz / 100Kbs = 1000 = FS_SCL_HCNT + FS_SCL_LCNT
    FS_SCL_HCNT: coverpoint val iff(field == "FS_SCL_HCNT") {
      bins max = {[400:500]};
      bins min = {[125:150]};
    }
    FS_SCL_LCNT: coverpoint val iff(field == "FS_SCL_LCNT") {
      bins max = {[400:500]};
      bins min = {[125:150]};
    }

    // In HS mode, the frequency of SCL is <= 3.4 Mbs
    // To ensure frequency of HS, we test 1 - 3.4 Mbs
    // Refer to the period of i2c_clk 100MHz
    // Fastest:
    // The count value is 100MHz / 3.4Mbs ~= 30 = HS_SCL_HCNT + HS_SCL_LCNT
    // Slowest:
    // The count value is 100MHz / 1Mbs = 100 = HS_SCL_HCNT + HS_SCL_LCNT
    HS_SCL_HCNT: coverpoint val iff(field == "HS_SCL_HCNT") {
      bins max = {[40:50]};
      bins min = {[15:20]};
    }
    HS_SCL_LCNT: coverpoint val iff(field == "HS_SCL_LCNT") {
      bins max = {[40:50]};
      bins min = {[15:20]};
    }

  endgroup

3.bits7_or_bits10_addressing_cg 

7bit地址和10bit地址的使能,对应的寄存器的域是IC_CON[4]IC_10BITADDR_MASTER。

covergroup bits7_or_bits10_addressing_cg with function sample(bit bits10);
    option.name = "bits7_or_bits10_addressing_cg";
    BITS7_OR_BITS10: coverpoint bits10{
      bins bits7  = {0};
      bins bits10 = {1};
    }
  endgroup

4.restart_condition_cg

restart的使能,对应寄存器域是IC_CON[5]IC_RESTART_EN。

covergroup restart_condition_cg with function sample(bit rt);
    option.name = "restart_condition_cg";
    RESTART: coverpoint rt {
      bins disabled = {0};
      bins enabled  = {1};
    }
  endgroup

5.activity_cg

I2C处于的状态,需要查看两个域,一个是IC_STATUS[0]ACTIVITY,一个是IC_STATUS[5]MST_ACTIVITY。

covergroup activity_cg with function sample(bit act, string field);
    option.name = "activity_cg";
    ACTIVITY: coverpoint act iff(field == "ACTIVITY") {
      bins idle = {0};
      bins busy = {1};
    }
    MST_ACTIVITY: coverpoint act iff(field == "MST_ACTIVITY") {
      bins idle = {0};
      bins busy = {1};
    }
  endgroup

6.enabled_cg

I2C的使能信号,需要查看两个寄存器的域,一个是控制寄存器IC_ENABLE[0]ENABLE,一个是状态寄存器IC_ENABLE_STATUS[0]IC_EN。

covergroup enabled_cg with function sample(bit en, string field);
    option.name = "enabled_cg";
    ENABLE_CTRL: coverpoint en iff(field == "ENABLE") {
      bins dis = {0};
      bins en = {1};
    }
    ENABLE_STATUS: coverpoint en iff(field == "IC_EN") {
      bins dis = {0};
      bins en = {1};
    }
  endgroup

7.tx_fifo_status_cg 

TX FIFO的状态通过状态寄存器IC_STATUS[1]TFNF和IC_STATUS[2]TFE来获取TX_FIFO是空还是满。

covergroup tx_fifo_status_cg with function sample(bit empty, bit nfull);
    option.name = "tx_fifo_status_cg";
    EMPTY: coverpoint empty {
      bins empty = {1};
      bins not_empty = {0};
    }
    NOT_FULL: coverpoint nfull {
      bins not_full = {1};
      bins full = {0};
    }
  endgroup

8.rx_fifo_status_cg

RX FIFO的状态通过状态寄存器IC_STATUS[3]RFNE和IC_STATUS[4]RFF来获取RX_FIFO是空还是满。 

covergroup rx_fifo_status_cg with function sample(bit full, bit nempty);
    option.name = "rx_fifo_status_cg";
    FULL: coverpoint full {
      bins full = {1};
      bins not_full = {0};
    }
    NOT_EMPTY: coverpoint nempty {
      bins not_empty = {1};
      bins empty = {0};
    }
  endgroup

 9.interrupt_status_cg

14个中断状态的检测,通过访问中断的状态寄存器IC_INTR_STAT来获取对应的中断。  

covergroup interrupt_status_cg with function sample(bit[13:0] stat);
    option.name = "interrupt_status_cg";
    STATUS: coverpoint stat{
      wildcard bins MASTER_ON_HOLD = {14'b1x_xxxx_xxxx_xxxx};   
      wildcard bins RESTART_DET    = {14'bx1_xxxx_xxxx_xxxx};   
      wildcard bins GEN_CALL	     = {14'bxx_1xxx_xxxx_xxxx};   
      wildcard bins START_DET		   = {14'bxx_x1xx_xxxx_xxxx};   
      wildcard bins STOP_DET		   = {14'bxx_xx1x_xxxx_xxxx};   
      wildcard bins ACTIVITY		   = {14'bxx_xxx1_xxxx_xxxx};   
      wildcard bins RX_DONE	   	   = {14'bxx_xxxx_1xxx_xxxx};   
      wildcard bins TX_ABRT	   	   = {14'bxx_xxxx_x1xx_xxxx};   
      wildcard bins RD_REQ	  	   = {14'bxx_xxxx_xx1x_xxxx};   
      wildcard bins TX_EMPTY		   = {14'bxx_xxxx_xxx1_xxxx};   
      wildcard bins TX_OVER	  	   = {14'bxx_xxxx_xxxx_1xxx};   
      wildcard bins RX_FULL	  	   = {14'bxx_xxxx_xxxx_x1xx};   
      wildcard bins RX_OVER	   	   = {14'bxx_xxxx_xxxx_xx1x};   
      wildcard bins RX_UNDER  	   = {14'bxx_xxxx_xxxx_xxx1};   
    }
  endgroup

10.interrupt_clear_cg 

对于中断的清除,采用对对应中断清除寄存器做读操作来进行,由于直接对寄存器的访问无法判断中断是否发生,所以需要在测试时,先判断中断是否发生,再进行中断的清除。

covergroup interrupt_clear_cg with function sample(bit clr, string field);
    option.name = "interrupt_clear_cg";
    CLR_INTR      : coverpoint clr iff(field == "CLR_INTR")      { bins clr = {1};}       
    CLR_RX_UNDER  : coverpoint clr iff(field == "CLR_RX_UNDER")  { bins clr = {1};}   
    CLR_RX_OVER   : coverpoint clr iff(field == "CLR_RX_OVER")   { bins clr = {1};}    
    CLR_TX_OVER   : coverpoint clr iff(field == "CLR_TX_OVER")   { bins clr = {1};}    
    CLR_RD_REQ    : coverpoint clr iff(field == "CLR_RD_REQ")    { bins clr = {1};}    
    CLR_TX_ABRT   : coverpoint clr iff(field == "CLR_TX_ABRT")   { bins clr = {1};}    
    CLR_RX_DONE   : coverpoint clr iff(field == "CLR_RX_DONE")   { bins clr = {1};}    
    CLR_ACTIVITY  : coverpoint clr iff(field == "CLR_ACTIVITY")  { bins clr = {1};}   
    CLR_STOP_DET  : coverpoint clr iff(field == "CLR_STOP_DET")  { bins clr = {1};}   
    CLR_START_DET : coverpoint clr iff(field == "CLR_START_DET") { bins clr = {1};}    
    CLR_GEN_CALL  : coverpoint clr iff(field == "CLR_GEN_CALL")  { bins clr = {1};}   
  endgroup

11.interrupt_hardware_outputs_cg 

中断输出的硬件信号,检查中断输出端口的信号是否都拉高过。

covergroup interrupt_hardware_outputs_cg with function sample(bit[IC_INTR_NUM-1:0] intr);
    option.name = "interrupt_hardware_outputs_cg";
    INTERRUPT: coverpoint intr{
      wildcard bins IC_RX_OVER_INTR_ID    = {12'bxxxx_xxxx_xxx1};
      wildcard bins IC_RX_UNDER_INTR_ID   = {12'bxxxx_xxxx_xx1x};
      wildcard bins IC_TX_OVER_INTR_ID    = {12'bxxxx_xxxx_x1xx};
      wildcard bins IC_TX_ABRT_INTR_ID    = {12'bxxxx_xxxx_1xxx};
      wildcard bins IC_RX_DONE_INTR_ID    = {12'bxxxx_xxx1_xxxx};
      wildcard bins IC_TX_EMPTY_INTR_ID   = {12'bxxxx_xx1x_xxxx};
      wildcard bins IC_ACTIVITY_INTR_ID   = {12'bxxxx_x1xx_xxxx};
      wildcard bins IC_STOP_DET_INTR_ID   = {12'bxxxx_1xxx_xxxx};
      wildcard bins IC_START_DET_INTR_ID  = {12'bxxx1_xxxx_xxxx};
      wildcard bins IC_RD_REQ_INTR_ID     = {12'bxx1x_xxxx_xxxx};
      wildcard bins IC_RX_FULL_INTR_ID    = {12'bx1xx_xxxx_xxxx};
      wildcard bins IC_GEN_CALL_INTR_ID   = {12'b1xxx_xxxx_xxxx};
    }
  endgroup

 12.interrupt_tx_abort_sources_cg

TX ABRT中断源的测试,对对应的IC_TX_ABRT_SOURCE进行访问。

covergroup interrupt_tx_abort_sources_cg with function sample(bit[16:0]src);
    option.name = "interrupt_tx_abort_sources_cg";
    ABORT_SOURCES: coverpoint src {
      wildcard bins ABRT_USER_ABRT	      = {17'b1_xxxx_xxxx_xxxx_xxxx};  
      wildcard bins ABRT_SLVRD_INTX	      = {17'bx_1xxx_xxxx_xxxx_xxxx};  
      wildcard bins ABRT_SLV_ARBLOST	    = {17'bx_x1xx_xxxx_xxxx_xxxx};  
      wildcard bins ABRT_SLVFLUSH_TXFIFO  = {17'bx_xx1x_xxxx_xxxx_xxxx};    
      wildcard bins ARB_LOST	            = {17'bx_xxx1_xxxx_xxxx_xxxx};  
      wildcard bins ABRT_MASTER_DIS	      = {17'bx_xxxx_1xxx_xxxx_xxxx};  
      wildcard bins ABRT_10B_RD_NORSTRT	  = {17'bx_xxxx_x1xx_xxxx_xxxx};  
      wildcard bins ABRT_SBYTE_NORSTRT    = {17'bx_xxxx_xx1x_xxxx_xxxx};  
      wildcard bins ABRT_HS_NORSTRT	      = {17'bx_xxxx_xxx1_xxxx_xxxx};  
      wildcard bins ABRT_SBYTE_ACKDET	    = {17'bx_xxxx_xxxx_1xxx_xxxx};  
      wildcard bins ABRT_HS_ACKDET	      = {17'bx_xxxx_xxxx_x1xx_xxxx};  
      wildcard bins ABRT_GCALL_READ	      = {17'bx_xxxx_xxxx_xx1x_xxxx};  
      wildcard bins ABRT_GCALL_NOACK	    = {17'bx_xxxx_xxxx_xxx1_xxxx};  
      wildcard bins ABRT_TXDATA_NOACK	    = {17'bx_xxxx_xxxx_xxxx_1xxx};  
      wildcard bins ABRT_10ADDR2_NOACK    = {17'bx_xxxx_xxxx_xxxx_x1xx}; 	
      wildcard bins ABRT_10ADDR1_NOACK	  = {17'bx_xxxx_xxxx_xxxx_xx1x};   
      wildcard bins ABRT_7B_ADDR_NOACK    = {17'bx_xxxx_xxxx_xxxx_xxx1};  
    }
  endgroup

13.sda_control_cg

SDA的建立时间和保持时间,访问控制寄存器IC_SDA_HOLD[15:0]IC_SDA_TX_HOLD和IC_SDA_HOLD[23:16]IC_SDA_RX_HOLD来获取作为transmitter和receiver的保持时间,保持时间发生在SCL拉低的器件,且保持时间最大不能超过SCL_LCNT-2。建立时间访问IC_SDA_SETUP[7:0]SDA_SETUP来获得。

covergroup sda_control_cg with function sample(bit[7:0]rxh, bit[15:0] txh, bit[7:0] stp, string field);
    option.name = "sda_control_cg";
    RX_HOLD: coverpoint rxh iff(field == "SDA_HOLD"){
      bins MAX = {[100:$]};
      bins NORMAL = {[10:99]};
      bins MIN = {[1:9]};
    }
    TX_HOLD: coverpoint txh iff(field == "SDA_HOLD"){
      bins MAX = {[100:$]};
      bins NORMAL = {[10:99]};
      bins MIN = {[1:9]};
    }
    SDA_SETUP: coverpoint stp iff(field == "SDA_SETUP") {
      bins MAX = {[100:$]};
      bins NORMAL = {[10:99]};
      bins MIN = {[1:9]};
    }
  endgroup

14.timeout_counter_cg

通过访问REG_TIMEOUT_RST[3:0]REG_TIMEOUT_RST_rw来获得。

covergroup timeout_counter_cg with function sample(bit[3:0] cnt);
    option.name = "timeout_counter_cg";
    TIMEOUT_COUNTER: coverpoint cnt {
      bins MAX = {[10:$]};
      bins NORMAL = {[4:9]};
      bins MIN = {[1:3]};
    }
  endgroup

如何进行采样?

首先是通过uvm_analysis_imp端口接收从APB、I2C的monitor监测到的数据,然后对write进来的lvc_apb_transfer进行判断,如果传输状态trans_status==ERROR,则直接return,否则利用使用get_reg_by_offset 函数通过寄存器地址得到对应的uvm_reg 指针,然后trigger前门访问的event。

在对reg采样的task do_sample_reg()中,要一直wait_trigger_data(tmp),等待event被触发,然后执行后面的操作。

通过get_name()来获得uvm_reg 指针所指向的寄存器的名称,然后采样,通过get()传入对应的阈值和域名。

对硬件信号的采样通过do_sample_signals()任务来实现,在intr信号发生改变时进行采样并传入intr信号值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值