scoreboard主要有两个export端口,分别连接apb_monitor和qspi_monitor,以及分别用来存储apb_txn和qspi_txn的tlm_fifo。还有多个数组,qspi_reg[int]关联数组用来模拟一个寄存器块,通过寄存器地址索引到具体数据,qspi_tx_fifo队列用来存储写进TX_FIFO寄存器的data数据,device_data[int]关联数组用来存储发送到device的数据,rdata_fifo队列用来存储从device端读来的数据。
根据接口传来的数据类型,可以分为两大部分,一部分是从apb_monitor端传来的apb_txn事务,此处收集的事务是apb总线上的,在数据的源端;另一部分是从qspi_monitor端传来的qspi_txn事务,此处收集的事务是qspi总线上的,在模块和device之间。
scoreboard的整体思路是对这两个类型的数据分别处理。
对于从apb端传来的事务,根据pwrite的值判断是读还是写寄存器,
如果是读,那么一般来说一定是从模块的RX_FIFO寄存器中读取数据(因为其他寄存器都是用来写,对模块进行传输设置,只有这个寄存器里面是存储从device端读来的数据),那么如果是从这个寄存器中读取数据,接着判断rdata_fifo(qspi_monitor此时已经将device端的读出的数据收集到,一般来说肯定是非空的)是否非空,是非空就将其中数据弹出,存入real_data数组,并将此数组数据与apb_txn中的pdata数据进行比较。
如果是写,通过将qspi_reg[transaction_apb.paddr]=transaction_apb.pdata放在循环的第一句,并且后面都是if判断语句,如果访问的是不满足所有if的寄存器,那么寄存器地址和数值都会被存入qspi_reg这个关联数组中,if判断条件一共有三个:
第一个判断是否是TX_FIFO寄存器,如果是,且pending标志位(用来表示是否soft_redet)为0,那么就直接将TX_FIFO的数据存入qspi_tx_fifo中,如果标志位为1,那么就将数据存入device_data数组中,同时将标志位置0。
第二个判断是否是CTRL寄存器且(cmd==programing或cmd_width=0)且(pdata[3]或pdata[1]=1),这两个pdata位分别表示Quad_SPI write和write。如果是,判断addr_width如果不是0,就将有效长度的数据地址提取出来,然后将有效数据(根据提取出来的地址以及第一个判断中放入qspi_tx_fifo的数据)存储到device_data数组中。如果判断addr_width是0,将地址置为默认值5aa5,并将qspi_is_write_busy标志位置1,然后将有效数据(根据提取出来的地址以及第一个判断中放入qspi_tx_fifo的数据)存储到device_data数组中。
第三个判断是否是CTRL寄存器且(soft_reset为1)且qspi_is_write_busy标志位为1。如果是,清空qspi_tx_fifo,清空device_data数组,将pending标志位置1(此处将此标志位置1的目的是在TX_FIFO写的时候,将数据存入device_data数组中,同时将标志位置0)。
对于从qspi端传来的事务,根据事务中的command命令,执行不同的操作,
如果是write_enable,那么如果与qspi_reg(由于apb端数据先行,qspi_reg在apb端设置寄存器时候就已经设置好了值)中命令不符,就报fatal。
如果是write_disable,那么如果与qspi_reg中命令不符,就报fatal。
如果是read_data,那么将从device读来的数据放进rdata_fifo,截取device_data的有效数据长度以及读来数据,进行比较。
如果是programing,那么。。。同上。。。然后将qspi_is_write_busy置0,。
如果是默认值,判断cmd_width为0且transaction_qspi.qspi_write为0(读),,如果addr_width为0,将laddr赋值默认值a55a,接着将transaction_qspi中的data数据存入到rdata_fifo数组中,然后判断device_data数据与transaction_qspi中数据是否一致。
总结:apb端向txfifo寄存器写数据,数据被存下为qspi_tx_fifo,然后Ctrl寄存器控制开始传输数据,存下的qspi_tx_fifo作为传输到device的数据被存到device_data中,此时qspi总线上写到device的数据被检测到,与先前存的device_data数据直接对比,结束后如果是从device读取数据,那么先前存的device_data数据保持不变,与读回来qspi总线上检测到的数据直接比较。
apb端向rxfifo读数据,而qspi总线上读到的数据已经被存到rdata_fifo的队列中,将队列中数据pop出来与apb总线检测的读出rxfifo寄存器的数据pdata比较。
难点:softreset,数据的比较。