I2C项目

必定会有许多理解错误的地方,欢迎指正交流!!!

1.rkv_i2c_master_abrt_7b_addr_noack_test.sv

测试点:abrt_7b_addr_noack中断,并清除中断。

 apb_user_cfg_seq里面对寄存器模型的配置参数做约束,其父类对配置参数做声明及约束。这里用这个seq配置7位地址、TX_EMPTY_CTRL=1等参数。TX_EMPTY_CTRL=1表示TX_EMPTY中断不被mask掉(如果TX FIFO高于阈值时候会触发中断)。(TX_EMPTY_CTRL=1的作用是控制是否产生TX_EMPTY中断

apb_user_write_packet_seq里面将要写的数据包数据先set到寄存器模型,然后write到dut

i2c_slv_write_resp_seq里面对ACK\NACK位及数量进行约束。i2c协议传输时候,slave里通过nack_addr等参数数量判断是否应该回应ack及nack,此处直接将其赋值目的就是人为得让slave对写地址的回应为nack,从而可以触发write7bit地址 ,slave回应nack

apb_intr_wait_seq一直处于监听状态,dut数据实时mirror到IC_RAW_INTR_STAT寄存器模型,当IC_RAW_INTR_STAT中断状态寄存器里面的IC_TX_ABRT_INTR_ID中断位置1(表示i2c发送数据时候无法正常完成操作),则监听到中断,事务结束。

apb_intr_clear_seq负责将传入的中断对应的中断清除。此事务mirror更新IC_RAW_INTR_STAT中断状态寄存器模型与dut,将传入的中断对应的中断清除寄存器里面的对应位mirror更新,从而清除对应的IC_TX_ABRT_INTR_ID中断(直接读取dut中此值就可以清除中断)

apb_user_wait_empty_seq一直监听,并mirror更新IC_STATUS状态寄存器模型,当ACTIVITY=0(总线处于idle状态),且TFE=1(TX FIFO为空)且RFNE=0(RX FIFO为空),事务就结束。

2、rkv_i2c_master_abrt_10b_rd_norstrt_test.sv

测试点:abrt_10b_raddr_noack

apb_user_cfg_seq里面对寄存器模型的配置参数做约束,其父类对配置参数做声明及约束。配置为10位地址,IC_RESTART=0(禁止i2c主机产生restart)

apb_user_read_packet_seq里面将read命令写进dut的cmd中

i2c_slv_read_resp_seq里面是对read命令的回应,packet.size=1,8'b0101_0101就作为read的response

apb_user_wait_detect_abort_source_seq里面实时mirror监控dut的IC_RAW_INTR_STAT寄存器,如果其TX_ABRT域为1,就表示监控到TX_ABRT中断的产生。跳出监控,然后,mirror查看DUT的IC_TX_ABRT_SOURCE寄存器,某个域为1就表示某个中断触发了TX_ABRT的中断

apb_user_wait_empty_seq一直监听,并mirror更新IC_STATUS状态寄存器模型,当ACTIVITY=0(总线处于idle状态),且TFE=1(TX FIFO为空)且RFNE=0(RX FIFO为空),事务就结束。

 3、rkv_i2c_master_abrt_sbyte_norstrt_test.sv

测试点:abrt_sbyte_norstrt,start_byte回应nack

 apb_user_cfg_seq里面对寄存器模型的配置参数做约束,其父类对配置参数做声明及约束。配置为10位地址,IC_RESTART=0(禁止i2c主机产生restart),TX_EMPTY_CTRL=1(打开TX_EMPTY中断),SPECIAL=1(允许gener_call或者Start_byte),GC_OR_START=1(start_byte传输,=0表示gen_call)。

i2c_slv_write_resp_seq里面是对write的回应,按照正常协议回应。

apb_user_write_packet_seq里面write一个数据8'b0101_0101。

apb_intr_wait_seq一直处于监听状态,dut数据实时mirror到IC_RAW_INTR_STAT寄存器模型,当IC_RAW_INTR_STAT中断状态寄存器里面的IC_TX_ABRT_INTR_ID中断位置1(表示i2c发送数据时候无法正常完成操作),则监听到中断,事务结束。

mirror寄存器模型的IC_TX_ABRT_SOURCE,查看中断源

apb_intr_clear_seq负责将传入的中断对应的中断清除。此事务mirror更新IC_RAW_INTR_STAT中断状态寄存器模型与dut,将传入的中断对应的中断清除寄存器里面的对应位mirror更新,从而清除对应的IC_TX_ABRT_INTR_ID中断(直接读取dut中此值就可以清除中断)。

apb_user_wait_empty_seq一直监听,并mirror更新IC_STATUS状态寄存器模型,当ACTIVITY=0(总线处于idle状态),且TFE=1(TX FIFO为空)且RFNE=0(RX FIFO为空),事务就结束。

 4、rkv_i2c_master_abrt_txdata_noack_test.sv

测试点:abrt_txdata_noack

 apb_user_cfg_seq里面对寄存器模型的配置参数做约束,其父类对配置参数做声明及约束。配置为7位地址。

apb_user_write_packet_seq里面将要写的数据包数据先set到寄存器模型,然后write到dut。发送两个数据8'b1111_0000和8'b1111_0001。

i2c_slv_write_resp_seq里面对ACK\NACK位及数量进行约束。i2c协议传输时候,slave里通过nack_addr等参数数量判断是否应该回应ack及nack。此处设置nack_data=1表示对第一个数据data回应nack

apb_intr_wait_seq一直处于监听状态,dut数据实时mirror到IC_RAW_INTR_STAT寄存器模型,当IC_RAW_INTR_STAT中断状态寄存器里面的IC_TX_ABRT_INTR_ID中断位置1(表示i2c发送数据时候无法正常完成操作),则监听到中断,事务结束。

检查中断源是否正确

apb_intr_clear_seq负责将传入的中断对应的中断清除。此事务mirror更新IC_RAW_INTR_STAT中断状态寄存器模型与dut,将传入的中断对应的中断清除寄存器里面的对应位mirror更新,从而清除对应的IC_TX_ABRT_INTR_ID中断(直接读取dut中此值就可以清除中断)。

波形图中看到中断被清除,表示是正确的中断源触发的中断,也可以从info打印信息中看到中断源信息。

 5、rkv_i2c_master_activity_intr_output_test.sv

测试点:activity_intr_output

 apb_user_cfg_seq里面对寄存器模型的配置参数做约束,其父类对配置参数做声明及约束。配置为7位地址。

利用寄存区模型更新dut的寄存器值使得ACTIVITY/START_DET/STOP_DET中断打开(默认值为0,中断屏蔽)。

apb_user_write_packet_seq里面将要写的数据包数据先set到寄存器模型,然后write到dut。发送两个数据8'b1111_0000和8'b01010101。

i2c_slv_write_resp_seq里面对ACK\NACK位及数量进行约束。i2c协议传输时候,slave里通过nack_addr等参数数量判断是否应该回应ack及nack。这里正常回应ack。

apb_intr_wait_seq一直处于监听状态,dut数据实时mirror到IC_RAW_INTR_STAT寄存器模型,当IC_RAW_INTR_STAT中断状态寄存器里面的IC_ACTIVITY_INTR_ID中断位置1(表示i2c发送数据时候无法正常完成操作),则监听到中断,事务结束。(等待中断发生这里事务感觉可以没有,有的话,如果没监控到中断就会先挂起?有中断才会正常继续执行)

apb_intr_clear_seq负责将传入的中断对应的中断清除。此事务mirror更新IC_RAW_INTR_STAT中断状态寄存器模型与dut,将传入的中断对应的中断清除寄存器里面的对应位mirror更新,从而清除对应的IC_ACTIVITY_INTR_ID、IC_START_DET_INTR_ID、IC_STOP_DET_INCR_ID中断(直接读取dut中此值就可以清除中断)。

5、rkv_i2c_master_address_cg_test.sv

测试点:10bit_access\7bit_access,触发TX_ABRT_SOURCE中的ABRT_7B_ADDR_NACK和ABRT_10B_ADDR1_NACK

 

下图为配置master7位访问地址,slave的访问地址,将正确的slave的访问地址配置给dut,然后发送数据。

下图为I2C总线上数据发送

 下图为将dut中slave的地址更改为与cfg配置的地址不一样 的值

 下图为错误地址获得的回应为nack,并产生abrt中断

 下图为检查到中断源以后,清除abrt中断

 下图为将ENABLE置0,一次正确7bitaddr的ack与错误7bitaddr的nack并触发中断的整个过程结束。

 接下来继续剩下的几个地址,以及10bitaddr的各个地址的各种情况的访问。

 6、rkv_i2c_master_enabled_cg_test.sv

测试点:1、关闭I2C写数据。2、写数据,在I2C接收数据之前,关闭I2C。3、关闭i2c后,read数据。4、在读的过程中关闭I2C。正常写操作。

 

下图表示:关闭I2C,发送一个数据。打开I2C,发送两个数据,在I2C接收到数据之前关闭I2C(I2C接收数据需要用i2c_slv_write_resp_seq设置slave端的nack、ack,不发送此seq表示正常协议回复ack)。最后apb_noread_packet_seq表示发送一个读请求(正常来说,接下来要有一个read_resp_seq的事务回复一个数据,但是接下来实际上的操作是。。。第二个时序图)。

注:(时序图中有地方标注ENABLE默认值是0,所以再对其写0就不显示,理解有误,代码中所用为set()---update(),即先设置期望值,再更新,更新的时候,需要先判断dut中的ENABLE的值与寄存器模型中的值是否一致,如果一致,就更新(此时总线上才有对应的写操作),如果一致,那么就不用写更新(此时总线上没有写操作))。其他图中有此描述的亦如此。

 下图表示seq继续运行,10us以后

下图表示读过程中关闭I2C之前,成功读到一个正确的数据。最后一个时序图中间两个空数据为在下图之后的(i2c被禁用后读到空数据)

 

 回归正常操作

 

 整个过程时序图

 7、rkv_i2c_master_hs_master_code_test.sv

测试点:HIGHTSPEED_MODE

 

 下面是开始运行的波形,首先是两个寄存器的mirror(),将dut的值读出为寄存器模型的镜像值,然后分别对两个寄存器update和mirror(update是将寄存器的期望值与镜像值作对比,不同就写进dut,mirror是将dut的值读出与寄存器模型的值比较并更新寄存器模型的mirror值)。

 根据协议,HS模式下的串行数据传输格式复合标准模式I2C-BUS规范,HS模式只能在【启动条件(s)&8位主码(00001XXX)&nack】条件下启动。主码允许竞争获取总线权限的主设备在F\S模式进行仲裁和同步,同时也表明一个HS模式传输的开始。

 

 下图是等待总线数据传输结束(监控STATUS寄存器),寄存器值发生了变化,总线进入了idle。

 寄存器IC_HS_MADDR作用是用来保留I2C高速模式主代码的值(例子为00001000),其只有在i2c被禁用的时候才能写入。这里将其写入0(表示b000);1(表示b001);2(表示b010);3(表示b011);4(表示b100);5(表示b101);6(表示b110);7(表示b111)(图中标注错误前一个主代码是001,这里是000。每次修改MAR寄存器的值,都会对应不同的主代码)。每个主机都有独一无二的主代码,其主代码有效值为0-7,波形可见默认值为1?

8、rkv_i2c_master_rx_full_intr_test.sv

测试点:RX_FIFO_FULL中断

在最开始网cmd寄存器中写八次读请求,就是要求从i2c端获取8个数据。i2c端发送数据超过3个就会触发中断,因为在最开始设置了IC_RX_TL中的RX_TL的值为3。(RX_FIFO默认容量是8个以内)。

下图是I2C发送8个数据,在第四个发送成功时候,RX_FIFO中的数据超过了3个,从而触发RX_FIFO_FULL中断。

 下图是将从i2c端传进的8个数据,通过mirror()IC_DATA_CMD寄存器来将RX_FIFO中的数据一个一个得取出,直到成功取出第五个数据时候,RX_FIFO里数据从4变为3,RX_FIFO_FULL的中断在此时被立即清除。(可见只要dut寄存器被读(mirror也是读),就可以消耗数据)

 9、rkv_i2c_master_rx_over_intr_test.sv

测试点:rx_over_intr,RX_FIFO数据超出临界值(8个),溢出,触发中断。

 

 

 10、rkv_i2c_master_ss_cnt_test.sv

测试点:slow_speed模式不同速度

IC_FS_SPKLEN寄存器的作用是?

 

 

 11、rkv_i2c_master_start_byte_test.sv

测试点:

TX_EMPTY_CTRL控制是否产生TX_EMPTY中断,1表示产生。GC_OR_START置1表示使用start_byte命令;置0表示使用general_call命令,此时只能执行写入命令,否则将使IC_RAW_INTR_START寄存器第6位置1。

start_byte启动过程包括:启动条件(S)、启动字节(0000 0001)确认时钟脉冲(NACK)、重复启动条件(Sr)。

 12、rkv_i2c_master_timeout_cg_test.sv

 测试点:

13、rkv_i2c_master_tx_abrt_intr_test.sv

测试点:TX_ABRT中断

apb_write_nocheck_packet_seq这个seq的作用是在write数据的时候,不再监控TX_FIFO是否是满的,直接将数据写入。

seq中前面写了8个数据,然后将ENABLE.ABRT强行置1从而中断i2c传输,触发TX_ABRT中断。

下图是仿真图。

将ENABLE.ABRT置1,表示正在进行终止操作。读IC_RAW_INTR_STAT时候,读了一次就没再读,表示检测到了中断,已经结束了检测中断的事务。接下来中断信号才被拉高(原因是读IC_RAW_INTR_STAT时候,第一次就已经检测到中断,这里检测到的中断是和寄存器相关的,而相应的信号的拉高,dut内部还需要一点时间,所以在检测到中断以后才会有中断信号的拉高)。然后读取清除寄存器清除中断。

 14、rkv_i2c_master_tx_empty_intr_test.sv

测试点:TX_EMPTY中断

 下图波形中,每次都是先检测到中断寄存器的变化,再由intr的信号拉高,猜测就是dut内部从寄存器到将相应信号拉高需要一定的时间。

 15、rkv_i2c_master_tx_full_intr_test.sv

测试点:TX_FIFO_FULL状态

TX_FIFO容量是8,写8个数据刚好填满。

 到这里发现一个问题:发送单个数据的时候,TX_EMPTY中断的触发是在这个数据发送结束的时候触发,发送多个数据的时候, TX_EMPTY中断的触发是在倒数第二个数据发送完毕的时候触发。

参考:https://blog.csdn.net/SummerXRT/article/details/119257275

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值