I2C局部架构

I2C局部架构_第1张图片

与子系统集成时候,APB Slave接口的master为AHB2APB Bridge,I2C接口连接系统I2C总线。工作时候,先使用APB接口配置寄存器,决定I2C的工作模式,随后向指令寄存器写指令,使I2C进行数据传输操作。

 基本功能:

可以作为master发起数据传输。

可以作为slave响应其他master的传输请求。

可以工作在不同速度模式下,标准速度模式为100kb/s,快速模式为400kb/s,高速模式为3.4Mb/s。

实现串行和并行数据格式之间的转换。

支持10bit地址。

RX/TX_FIFO实现数据缓冲功能。

中断或者轮询操作模式。

接收CPU命令,配置工作状态。

内部结构:

TX_FIFO:接收CPU从APB总线上送来的并行数据,并加以保存。

TX_SHIFT:以SCL的速率吧TX_FIFO里面的并行数据一位一位的输出到I2C的SDA数据线上。

RX_FIFO:接收经过RX_SHIFT转换为并行的数据,并加以保存。

RX_SHIFT:以SCL的速率采样SDA数据线上的数据,并转化为并行数据送至RX_FIFO。

时钟产生器:当DW_APB_I2C作为master时候,根据目前的工作速度,输出合适的时钟频率到SCL信号线上。

Master/Slave FSM:控制DW_APB_I2C作为master/slave时工作的状态机。

中断产生:与中断寄存器里的值对应,实时反应DW_APB_I2C的中断情况,以便CPU做出相应的处理操作。

APB Slave接口:接收CPU的指令,由配置内部寄存器决定DW_APB_I2C的工作模式、发出指令使DW_APB_I2C进行数据传输、清除中断等功能。

I2C接口:与系统I2C总线连接。

寄存器模块:包括配置寄存器、指令寄存器、状态寄存器、中断寄存器。 

scordboard

I2C局部架构_第2张图片

 其有两个imp端口,用来与apb_master和i2c_slave的ana_port端口连接。从这两个端口传进来的数据通过两个write_任务将事务数据存入到apb_trans_observed和i2c_trans_observed数组。其中,存入i2c_trans_observed数组中是直接存入,如果是写,就将data数据同时存入write_data_observed数组,如果是读,就同时将data数据同时存入read_data_observed数组;存入apb_trans_observed的数据,前提条件是寄存器为IC_DATA_CMD(根据事务中传来的地址addr判断)且事务和寄存器命令都是write/read且寄存器模型里TX_FIFO没有满/RX_FIFO不是空。

reform中声明了一个寄存器模型暂存数据,当apb_trans_observed中有数据,就接收过来,并将其中的data数据放入本地暂存寄存器,如果事务中是write且寄存器模型中命令也是write,那么将暂存寄存器中数据写入write_data_expected中,如果事务中是read且寄存器模型中命令也是read,那么将暂存寄存器中数据写入read_data_expected中。

write的期望值数组和实际值数组中都有数据的时候就将它们分别弹出比较。在task compare中,用两个wait(.size>0)来等待两个对应的fifo中都有数据了,就立刻将数据弹出比较。

apb端读i个数据时候,将read控制命令和data(=0)数据write进dut的cmd寄存器中,将i个数据都write结束以后(此时i2端已经将数据发送到RX_FIFO中),mirror更新STATUS寄存器,将dut中STATUS寄存器的值读出并更新寄存器模型的镜像值和期望值,如果RXNE=1,表示RX_FIFO中有数据,那么就mirror将cmd中要读的数据read出来,monitor监控到以后,送进scoreboard,mirror以后,scoreboard里面的apb_write函数的if判断条件中的寄存器模型中的IC_STATUS_RFNE的期望值才等于dut中的值=1,if判断才会通过(mirror之前,即使RX_FIFO中有数据,if中判断条件也不会通过,因为dut中为1,寄存器模型中为0),数据才会被存入fifo中。

env

I2C局部架构_第3张图片

env中主要用来例化和连接配置等。例化apb_mst、i2c_mst、i2c_slv、virtual_sequencer、scordboard、reg_model、adapter、predictor、coverage_model等。进行配置cfg及接口的config传递配置。连接关系如图所示。

其中通过rgm寄存器模型访问DUT进行write/read时候,rgm产生sequence,产生uvm_reg_item(rw),经过adapter.reg2bus任务产生driver能够接受的transaction----bus_req,将产生的bus_seq交给apb_master的sequencer,然后driver得到它并驱动它,得到读取值,并将其放入rsp中,调用item_done,寄存器模型调用adapter.bus2reg将rsp中的读取值传递给rw,再将rw中的读数据返回给参考模型。当driver将读取值返回后,寄存器模型会更新寄存器的镜像值和期望值,这个是寄存器的auto_pretict功能,但是在环境中单独例化predictor以后,需要为这个predictor单独例化一个adapter,将predictor和apb_master的monitor的ap端口连接,设置predictor的adapter和map,将其与寄存器模型关联起来,在这种形式中,由apb_master的monitor将从总线上收集到的transaction交给predictor并经过adapter转化后交给寄存器模型,寄存器模型更新相应值。

base_virtual_sequence

虚sequence,内含所有基本的sequence。首先要声明寄存器模型、接口vif、env、cfg、寄存器模型的状态和变量,然后声明所有element_sequence(这是基本的测试sequence)

 apb:

(rkv_apb_base_sequence):这个是apb_的seq的基本seq,所有apb_的seq继承与它,其没有声明在base_virtual_sequence中。里面声明rgm寄存器模型、data packet、后续需要配置用到的寄存器的域、寄存器状态和数据变量、更新寄存器的方法。

config_seq:其constraint约束中添加基本配置信息如SPEED、IC_10BITADDR_MASTER、IC_TAR、IC_FS_SCL_HCNT、IC_FS_SCL_LCNT、ENABLE、IC_TAR等寄存器域参数。body中检查到某个域被配置,就更新相应的寄存器模型。

write_packet_seq:其constrat约束中添加packet.size的大小约束。body中每次更新一个packet到寄存器模型之前,都需要mirror检查寄存器模型中TX_FIFO非满标志的寄存器,确定其非满,才将packet来set入DAT、RGM_WRITE来set入CMD。然后将期望值前门访问write进dut。

read_packet_seq:其constraint约束中添加packet.size的大小、NOT_EMPTY_THEN_READ约束。

body中每次更新一个packet,setRGM_READ和0到CMD和DAT域,然后将期望值前门访问write进dut。如果是NOT_EMPTY_THEN_READ,就需要mirror检查寄存器模型中RX_FIFO非空标志的寄存器,确定非空,就将DAT寄存器数据获取到packet中。

wait_empty_seq:其body任务中不断mirror检查寄存器状态,当寄存器的ACTIVITY==0(idle)且TFE==1(TX_FIFO为empty),循环结束,任务结束,事务结束。

intr_wait_seq:其constraint约束中添加intr_id(中断号)约束。body任务不断循环mirror检查IC_RAW_INTR_STAT寄存器状态,直到对应中断号的中断寄存器值变为1,就跳出循环,事务结束。

intr_clear_seq:其constraint约束中添加intr_id(中断号)约束。body任务mirror检查IC_RAW_INTR_STAT寄存器状态,根据传进来的intr_id来mirror检查对应中断清除寄存器(这里mirror时候会有寄存器的前门访问,一旦中断清除寄存器被访问,其对应中断就会被自动清除)。

noread_packet_seq:其constraint约束中添加packet.size的大小约束。

body中每次更新一个packet,setRGM_READ和0到CMD和DAT域,然后将期望值前门访问write进dut。也就是说这个read事务不从RX_FIFO中接收读取的数据。

user_write_nocheck_packet_seq:其constraint约束中添加packet.size的大小约束。

body任务将每个packet的数据和RGM_WRITE命令set到DAT和CMD寄存器,然后前门访问write到IC_DATA_CMD寄存器中。也就是说这个write事务不会管TX_FIFO是否为full,将所有数据都发送去寄存器。

user_address_check_seq:其constraint约束中添加addr约束。

body任务首先禁用IC_ENABLE,然后将传来的addr set到IC_TAR,再将IC_ENABLE置1,结束事务。

user_config_seq:与apb_config_seq基本一致,仅仅是多添加了一些后续可能用到的寄存器域。

user_read_packet_seq:其constraint约束中添加packet.size的大小,默认为1。

body任务中更新每个packet时候都先set RGM_READ进CMD,然后再将期望值前门访问write到IC_DATA_CMD寄存器。只发送出去read的命令,并没有接收读的数据。

user_read_rx_fifo_seq:其constraint约束中添加packet.size的大小,默认为1。

body任务中每次更新packet时候,都mirror检查IC_DATA_CMD寄存器。(这里应该是只将存入CMD寄存器的数据通过mirror将其释放,并不保存,从而消耗掉读数据)

user_wait_detect_abrt_source_seq:其body任务中不断循环mirror检查IC_RAW_INTR_STAT寄存器,如果寄存器中TX_ABRT==1,跳出循环。接着mirror检查IC_TX_ABRT_SOURCE寄存器,17个中断源哪个对应为1,就是触发了哪个中断。

user_wait_empty_seq:其body任务中不断mirror检查IC_STATUS寄存器状态,当寄存器的ACTIVITY==0(idle)且TFE==1(TX_FIFO为empty)且RFNE==0(RX_FIFO为empty),跳出循环,事务结束。

user_write_packet_seq:其constraint约束中添加packet.size的大小,默认为1。

body任务每次更新packet都先set packet和RGM_WRITE到DAT和CMD,然后将期望值通过前门访问write到IC_DATA_CMD寄存器。(这里写数据不管TX_FIFO中数据是否已经满了,直接写)

i2c:

i2c_slave_write_response_seq:其constraint约束中添加nack_addr、nack_data、nack_addr_count约束。

body任务关闭nack_addr。

i2c_slave_read_response_seq:其constraint约束中添加packet.size的大小、nack_addr、nack_data、nack_addr_count约束。

body任务里即有回应,又有packet赋值,读回应数据在这里发送。

必定有错,感谢指正。

(待总结补充。。。。。。)

你可能感兴趣的:(验证项目,经验分享)