i2c_SLAVE

 driver:

driver通过I2C的接口与DUT相连,负责接收DUT通过接口传来的地址数据等读写信息并作出反应。将sequencer中传来的trans中的数据驱动到总线上并根据设置的ack和nack作出回应,将总线上写来的数据存到trans中并将其返回,整体思路如下图所示。有三个线程分别负责监控start的产生、stop的产生、数据的分析及回应。下图仅仅为数据分析线程。监控start产生的线程判断try_get旗语中的key是否是1 ,是的话,那么就表示这是start,如果是0,那么就是监控到restart;监控stop产生的线程里面将旗语的keyput回去,则表示全部结束。旗语负责线程同步,识别是start还是restart。

数据分析线程中,等待start或者restart的产生,然后收集总线上的第一个byte(8位)数据,接着casex分析第一个byte数据地址并分别作出回应。

如果是保留地址,那么就在i2c_if.SCL的上升沿后拉高sda_slave(拉高SDA)回应NACK。结束。

如果是general_call,将命令赋值给trans.cmd,回应ACK,接着收集第二个byte数据并回应ACK,然后收集总线上发送的SDA数据。(这里第二个byte数据的具体作用和含义需要更复杂的功能,在此处难以实现,因此验证中主机将第二个byte发送完毕后就发送STOP结束)

如果是START_BYTE,将start_flag标志置0后continue,接着从forever头开始执行,等待START。

如果是HS_MODE,按照协议回NACK,然后continue,接着从forever头开始执行,等待START。

如果是DEVICE_ID,回ACK,然后判断读写位是1还是0,是0 的话,continue,接着从forever头开始执行,等待START。是1的话,将device id的3byte值驱动到总线上。

如果是10bitADDR,先判断地址高两位是否一致,不一致则回复NACK,一致的话,回复ACK并判断读写位,是写,则接收第二byte数据判断是否匹配,不匹配则回复NACK,匹配的话,就回复ACK并释放总线,(如果是读,那么这里主机会产生RS,收集数据这里就不会执行)接收总线上传来的数据。是读,那么就直接将trans.data的数据驱动到总线上。

如果是7bitADDR,先判断地址匹配,不匹配回复NACK。匹配回复ACK,如果是写,释放总线,接收SDA上数据。如果是读,就将trans.data上的数据驱动到总线上。

线程执行顺序一般是监控START的线程先执行(其中为forever循环体,一直在监控,没有break),监控到START,然后分析数据线程执行,此线程中有break,可能提前终止,最后是监控STOP 的线程,当此线程执行时,里面会将收集到的mon_data都赋值给trans.data,并将旗语的key放回,return结束。三个线程有任意一个结束就disable全部结束。

i2c_SLAVE_第1张图片

monitor:

monitor的整体思路与driver,只是monitor中不必考虑ACK和NACK的回复,以及监控总线数据的时候,只需要关心cmd命令类型,以及data和addr,并将其收集在trans中后发送给scoreboard和coverage model。

你可能感兴趣的:(验证项目,网络)