I2C虚拟项目-test2


前言

基于代码和波形理解关于覆盖率相关的test内容,也增进了对I2C协议的认识。


1.rkv_i2c_master_address_cg_test

主体为rkv_i2c_master_address_cg_virt_seq,测试内容是,DUT作为master, 7bit/10bit寻址正确/错误的目标地址;以及DUT作为slave,配置从机地址。
分别设置7/10bit主机传输模式,每种模式下均设置了四个地址,检测正常和异常传输情况。正常情况下传输的数据均为8’b1111 0001,异常下数据为8’b1111 0010;正常情况下传输的地址为设定的四个地址(依次对应’h273, 'h333, 'h73, 'h1b3),异常传输的地址通过对正常下地址加1来完成(依次对应’h274, 'h334, 'h74, 'h1b4)。
在四种地址下,配置了IC_SAR寄存器。在这里插入图片描述在这里插入图片描述
在这里插入图片描述

  1. 访问0x00寄存器(IC_CON寄存器),写入‘h7d(111 1101),即配置IC_CON[0]为1,以启用DW_apb_i2c为master模式;配置IC_CON[2:1]为10,以设置速度模式为快速模式;**配置IC_CON[3]为1,以设置作为slave地址位宽为10bit;配置IC_CON[4]为1,以设置作为master地址位宽为10bit;**配置IC_CON[5]为1,打开restart;配置IC_CON[6]为1,以禁用slave模式;高位均置为0,IC_CON[7]为0表示无论是否被寻址到,都产生STOP DET中断;IC_CON[8]为0表示默认TX EMPTY中断行为;IC_CON[9]为0表示当RX_FIFO满时溢出;IC_CON[10]为0表示无论是不是master模式都产生STOP DET;

  2. 访问0x1c寄存器(IC_FS_SCL_HCNT寄存器),写入’hc8(十进制200);

  3. 访问0x20寄存器(IC_FS_SCL_LCNT寄存器),写入’hc8(十进制200);在这里插入图片描述7 bit address master![7bit address0

  4. 访问0x00寄存器(IC_CON控制寄存器),写入’h6d(110 1101),即配置IC_CON[0]为1,以启用DW_apb_i2c为master模式;配置IC_CON[2:1]为10,以设置速度模式为快速模式;**配置IC_CON[3]为1,以设置作为slave地址位宽为10bit;配置IC_CON[4]为0,以设置作为master地址位宽为7bit;**配置IC_CON[5]为1,打开restart;配置IC_CON[6]为1,以禁用slave模式;高位均置为0,IC_CON[7]为0表示无论是否被寻址到,都产生STOP DET中断;IC_CON[8]为0表示默认TX EMPTY中断行为;IC_CON[9]为0表示当RX_FIFO满时溢出;IC_CON[10]为0表示无论是不是master模式都产生STOP DET;

  5. 访问0x04寄存器**(IC_TAR目标地址寄存器),写入’h273**;

  6. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;

  7. 访问0x70寄存器(IC_STATUS寄存器),读取’h6(110),I2C处于被禁用状态;

  8. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf1(1111 0001);随后观测到I2C总线上依次出现START信号,地址字节(1110 011 0+ACK),数据字节(1111 0001+ACK),STOP信号

  9. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h0;

  10. 访问0x04寄存器**(IC_TAR目标地址寄存器),写入’h274**;

  11. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;

  12. 访问0x70寄存器(IC_STATUS寄存器),读取’h6(110),I2C处于被禁用状态;

  13. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf2(11110010),随后观测到I2C总线上依次出现RESTART信号,地址字节(1110 1000+NACK),STOP信号

  14. 且出现TX ABRT中断,访问0x80寄存器(IC_TX_ABRT_SOURCE发送中断源寄存器),读取到’h1,表明主机在7bit地址传输模式,且第一个7地址字节未被任何从机识别,与14步中的信息一致;

  15. 访问0x34寄存器,读取到’h750(111 0101 0000),第10、9、8、6、4bit为高,依次对应START, STOP, ACTIVITY, TX_ABRT, TX_EMPTY位中断;

  16. 访问0x54寄存器(TX ABRT中断清除寄存器),读取为’h1,清除TX_ABRT中断;

  17. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h0;
    至此,完成7bit下address[0]下的正常传输+异常传输;后面的address[3:1]传输步骤与其一样,除了地址的变化;完成7 bit addressing下的传输后,开始10 bit addressing的传输;

10 bit address master10 bit address[0]

  1. 访问0x00寄存器(IC_CON控制寄存器),写入’h6d(110 1101),即配置IC_CON[0]为1,以启用DW_apb_i2c为master模式;配置IC_CON[2:1]为10,以设置速度模式为快速模式;**配置IC_CON[3]为1,以设置作为slave地址位宽为10bit;配置IC_CON[4]为0,以设置作为master地址位宽为7bit;**配置IC_CON[5]为1,打开restart;配置IC_CON[6]为1,以禁用slave模式;高位均置为0,IC_CON[7]为0表示无论是否被寻址到,都产生STOP DET中断;IC_CON[8]为0表示默认TX EMPTY中断行为;IC_CON[9]为0表示当RX_FIFO满时溢出;IC_CON[10]为0表示无论是不是master模式都产生STOP DET;
  2. 访问0x04寄存器**(IC_TAR目标地址寄存器),写入’h273**;
  3. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  4. 访问0x70寄存器(IC_STATUS寄存器),读取’h6(110),I2C处于被禁用状态;
  5. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf1(1111 0001);随后观测到I2C总线上依次出现START信号,地址字节(1111 010 0+ACK/ 0111 0011+ACK),数据字节(1111 0001+ACK),STOP信号
  6. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h0;
  7. 访问0x04寄存器**(IC_TAR目标地址寄存器),写入’h274**;
  8. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  9. 访问0x70寄存器(IC_STATUS寄存器),读取’h6(110),I2C处于被禁用状态;
  10. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf2(1111 0010),随后观测到I2C总线上依次出现RESTART信号,地址字节(1111 0100+NACK),STOP信号
  11. 且出现TX ABRT中断,访问0x80寄存器(IC_TX_ABRT_SOURCE发送中断源寄存器),读取到’h2,表明主机在10 bit地址传输模式,且第一个10地址字节未被任何从机识别,与10步中的信息一致;
  12. 访问0x34寄存器,读取到’h750(111 0101 0000),第10、9、8、6、4bit为高,依次对应START, STOP, ACTIVITY, TX_ABRT, TX_EMPTY位中断;
  13. 访问0x54寄存器(TX ABRT中断清除寄存器),读取为’h1,清除TX_ABRT中断;
  14. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h0;
    至此,完成10bit下address[0]下的正常传输+异常传输;后面的address[3:1]传输步骤与其一样,除了地址的变化;
    代码如下
`uvm_do_on_with(apb_cfg_seq, 
                    p_sequencer.apb_mst_sqr,
                    {SPEED == 2;
                    IC_FS_SCL_HCNT == 200;
                    IC_FS_SCL_LCNT == 200;
                  })

    for(i=0;i<2;i++) begin
      `uvm_do_on_with(apb_cfg_seq, 
                    p_sequencer.apb_mst_sqr,
                    {
                    IC_10BITADDR_MASTER == i;//7 bit(0) or 10 bit(1)
                  })
      if(i == 1) cfg.i2c_cfg.slave_cfg[0].enable_10bit_addr = 1; 
      foreach(address[j]) begin//每种地址下需要重新配置
        cfg.i2c_cfg.slave_cfg[0].slave_address = address[j];
        env.i2c_slv.reconfigure_via_task(cfg.i2c_cfg.slave_cfg[0]);
     //正常传输  `uvm_do_on_with(apb_user_address_check_seq,p_sequencer.apb_mst_sqr,{ADDR == address[j];})
        
        `uvm_do_on_with(apb_write_packet_seq, 
                      p_sequencer.apb_mst_sqr,
                      {packet.size() == 1;
                      packet[0] == 8'b11110001;
                       })
        `uvm_do_on(i2c_slv_write_resp_seq,p_sequencer.i2c_slv_sqr)

  //异常传输      `uvm_do_on_with(apb_user_address_check_seq,p_sequencer.apb_mst_sqr,{ADDR == (address[j] + 1'b1);})

        `uvm_do_on_with(apb_write_packet_seq, 
                       p_sequencer.apb_mst_sqr,
                       {packet.size() == 1;
                         packet[0] == 8'b11110010;
                        })
        tx_abrt_check();

        rgm.IC_ENABLE.ENABLE.set(0);
        rgm.IC_ENABLE.update(status);
        #10us;
      end
   end

两种传输模式下的总结
在这里插入图片描述

完成了master模式下传输的测试,最后还对slave模式的地址进行了设置

  1. 访问0x08寄存器(IC_SAR从机地址寄存器),写入’h273,对应address[0];
  2. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  3. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h0;
  4. 访问0x08寄存器(IC_SAR从机地址寄存器),写入’h333,对应address[1];
  5. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  6. 重复步骤3-5,对address[2], address[3]进行写入(第一个地址没有对0X6c寄存器写入0是因为在前面的master模式下的传输,最后一步已经将其设置为0)
    在这里插入图片描述

在这里插入图片描述
关于此test的困惑点(暂时未解):
a. 在10bit address master模式下,错误传输的地址是在正确地址上加1得来的,但并未引起高两位的变化,那么为什么是在第一个地址字节就收到NACK?
b. IC_CON[3]配置始终为1,即slave地址位宽始终为10bit,要配置7bit下的地址不是应该将其置为0吗?

2.rkv_i2c_master_enabled_cg_test

在这里插入图片描述

在这里插入图片描述
part1:配置在这里插入图片描述

  1. 访问0x00寄存器(IC_CON寄存器),写入’h6d(110 1101),即配置IC_CON[0]为1,以启用DW_apb_i2c为master模式;配置IC_CON[2:1]为10,以设置速度模式为快速模式;**配置IC_CON[3]为1,以设置作为slave地址位宽为10bit;配置IC_CON[4]为0,以设置作为master地址位宽为7bit;**配置IC_CON[5]为1,打开restart;配置IC_CON[6]为1,以禁用slave模式;高位均置为0,IC_CON[7]为0表示无论是否被寻址到,都产生STOP DET中断;IC_CON[8]为0表示默认TX EMPTY中断行为;IC_CON[9]为0表示当RX_FIFO满时溢出;IC_CON[10]为0表示无论是不是master模式都产生STOP DET;

  2. 访问0x04寄存器(IC_TAR目标地址寄存器),写入’h333(11 0011 0011);

  3. 访问0x1c寄存器(IC_FS_SCL_HCNT快速高计数寄存器),写入’hc8(对应十进制200);

  4. 访问0x20寄存器(IC_FS_SCL_LCNT快速低计数寄存器),写入’hc8(对应十进制200);
    part2:禁止使能后再进行写操作
    在这里插入图片描述
    由于IC_ENABLE[0]上电默认为0,通过set修改期望值,使用update发现期望值和镜像值相同,所以没有观测到对0x6c寄存器的写操作;在对IC_DATA_CMD进行写操作前会先访问0x70寄存器通过mirror方法读取TX FIFO状态

  5. 访问0x70寄存器(IC_STATUS状态寄存器),读取到6(110),TX FIFO为空;

  6. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf0(1111 0000);

  7. 访问0x70寄存器(IC_STATUS状态寄存器),读取到6(110),TX FIFO为空;

part3:使能后进行写操作,在发送到I2C之前禁止使能在这里插入图片描述

  1. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  2. 访问0x70寄存器(IC_STATUS状态寄存器),读取到6(110),TX_FIFO为空;
  3. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf1(1111 0001);
  4. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h2(10),TX_FIFO非空;
  5. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf2(1111 0010);
  6. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h2(10),TX_FIFO非空;
  7. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h0(写入0后TX_FIFO和RX_FIFO都被刷新);
  8. 再访问0x70寄存器(IC_STATUS状态寄存器),所以读取到’h6(110),TX_FIFO变为空;
  9. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’h100(1 0000 0000),表示要读取数据0000 0000;
  10. 10μs后访问0x70寄存器(IC_STATUS状态寄存器),读取到’h6(110),TX_FIFO为空,I2C处于被禁用状态;
    part4:在数据接收时禁止使能在这里插入图片描述
  11. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  12. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h6(110),TX_FIFO为空,I2C处于被禁用状态;
  13. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’h100(1 0000 0000),表示要读取数据0000 0000(apb_noread1),将数据写入IC_dATA_CMD用于读操作时,DW_APB_I2C会忽略,当读取此寄存器时,数据位将返回在DW_APB_I2C接口上接收的数据;
  14. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h2(10),TX_FIFO非空;
  15. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’h100(1 0000 0000),表示要读取数据0000 0000(apb_noread2);
  16. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h2(10),TX_FIFO非空;
  17. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’h100(1 0000 0000),表示要读取数据0000 0000(apb_noread3);
  18. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h2(10),TX_FIFO非空;随后对此寄存器持续访问,直到I2C总线上观测到START信号,0x70寄存器读取值变为’h23(100011),表明master FSM处于activity状态,RX_FIFO为空,TX_FIFO非空非满;观测到总线0110 011 1+ACK(地址字节),0000 1111+ACK,接着发生RX_FULL中断,0x70寄存器读取值变为’h2f(101111),TX_FIFO为空,RX_FIFO不为空,表明数据发送完成,已经接收到数据;在这里插入图片描述
  19. 访问 0x6c寄存器(IC_ENABLE寄存器),写入’h0(RX_FIFO和TX_FIFO被刷新),此后会发生数据丢失,因为APB总线还没来得及从I2C上获取数据ENABLE就成为0,那么之后都无法把数据放进RX_FIFO;
  20. 访问0x70寄存器(IC_STATUS状态寄存器),读取到’h27(100111),表明master FSM处于activity状态,RX_FIFO为空,TX_FIFO为空;
    注释:持续访问0x70寄存器对应代码中的mirror操作,直到RX_FIFO非空。此阶段第一个读数据是0000 1111,后两个都是0。主机对最后一个0000 0000发送NACK,因为对于master receiver的7地址传输如下图
    在这里插入图片描述

part5:使能后进行写操作(正常传输过程)
在这里插入图片描述

  1. 访问0x6c寄存器(IC_ENABLE寄存器),写入’h1;
  2. 访问0x70寄存器,读取’h27(100111),表明master FSM处于activity状态,RX_FIFO为空,TX_FIFO为空;
  3. 访问0x10寄存器(IC_DATA_CMD寄存器),写入’hf1(1111 0001);
  4. 访问0x70寄存器读取值变为’h23(100011),表明master FSM处于activity状态,RX_FIFO为空,TX_FIFO非空非满;
    其间在I2C总线上观测到数据字节(0000 0000+ACK),随后发生RX_FULL中断,开始下一个数据字节(0000 0000)传送;
  5. 访问0x70寄存器读取值变为’h2f(101111),TX_FIFO为空,RX_FIFO不为空(接收到0000 0000),已经接收到数据;I2C上继续传输数据(0000 0000+NACK),
  6. 随后出现正常传输信号,RESTART信号,地址字节(0110 0110+ACK),数据字节(1111 0001+ACK),STOP信号;最后访问0x70寄存器,读取到’he(1110),表明RX_FIFO,TX_FIFO为空,master FSM处于idle状态。在这里插入图片描述

总结

关于覆盖率的测试用例十分复杂,因为要考虑各种异常场景,需要花时间理解了再学着写,加油呀!

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ann_xia66

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

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

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

打赏作者

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

抵扣说明:

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

余额充值