2022-09-30 03:42:36 -05:00
import json
import cocotb
from cocotb . triggers import Timer , RisingEdge , ReadOnly
from cocotb_bus . monitors import Monitor
from cocotb . log import SimLogFormatter , SimTimeContextFilter
from cocotb . binary import BinaryValue
from math import ceil
from wb_models . housekeepingWB . HKmonitor import HKmonitor
from wb_models . housekeepingWB . HKSPImonitor import HKSPImonitor
from wb_models . housekeepingWB . HKSPImonitor import CSBmonitor
from wb_models . housekeepingWB . HK_models import HK_models
from cocotb_bus . scoreboard import Scoreboard
import logging
import fnmatch
import copy
from cocotb . result import TestFailure
2022-10-10 06:50:45 -05:00
from interfaces . common import Macros
2022-09-30 03:42:36 -05:00
class HK_whiteBox :
def __init__ ( self , dut , loggers = False ) :
self . dut = dut
self . hk_hdl = dut . uut . housekeeping
# self.hkspi_hdl = dut.uut.housekeeping.hkspi
self . clk = self . dut . uut . mprj_clock
self . reset = self . dut . uut . resetb
self . logger = loggers
self . load_js ( )
self . setupModels ( )
self . Monitors ( )
cocotb . scheduler . add ( self . reg_model_sb ( ) )
""" load json models """
def load_js ( self ) :
with open ( ' wb_models/housekeepingWB/housekeepingIF.json ' ) as f :
self . interface = json . load ( f )
with open ( ' wb_models/housekeepingWB/HK_regs.json ' ) as f :
self . reg_model = json . load ( f )
self . output_if = copy . deepcopy ( self . interface [ ' outputs ' ] )
""" " method to add the housekeeping monitors """
def Monitors ( self ) :
inputs = self . interface [ ' inputs ' ]
outputs = self . interface [ ' outputs ' ]
# wishbone
wishbone_mon_i = HKmonitor ( f " HKinputsMonitorwishbone " , self . hk_hdl , inputs [ ' wishbone ' ] , self . clk , self . reset , self . logger , callback = self . wb_models . wishbone_model )
wishbone_mon_o = HKmonitor ( f " HKoutputsMonitorwishbone " , self . hk_hdl , outputs [ ' wishbone ' ] , self . clk , self . reset , self . logger )
wishbone_sb = Scoreboard ( SB_name ( " wishbone_sb " ) , fail_immediately = False )
wishbone_sb . add_interface ( wishbone_mon_o , self . wb_models . exp_out_wb )
# system
system_mon_i = HKmonitor ( f " HKinputsMonitorsystem " , self . hk_hdl , inputs [ ' system ' ] , self . clk , self . reset , self . logger , callback = self . wb_models . system_model )
# UART
UART_mon_i = HKmonitor ( f " HKinputsMonitorUART " , self . hk_hdl , inputs [ ' UART ' ] , self . clk , self . reset , self . logger , callback = self . wb_models . UART_model )
UART_mon_o = HKmonitor ( f " HKoutputsMonitorUART " , self . hk_hdl , outputs [ ' UART ' ] , self . clk , self . reset , self . logger )
UART_sb = Scoreboard ( SB_name ( " UART_sb " ) , fail_immediately = False )
UART_sb . add_interface ( UART_mon_o , self . wb_models . exp_out_uart_rx )
# debug
debug_mon_i = HKmonitor ( f " HKinputsMonitordebug " , self . hk_hdl , inputs [ ' debug ' ] , self . clk , self . reset , self . logger , callback = self . wb_models . debug_model )
debug_mon_o = HKmonitor ( f " HKoutputsMonitordebug " , self . hk_hdl , outputs [ ' debug ' ] , self . clk , self . reset , self . logger )
debug_sb = Scoreboard ( SB_name ( " debug_sb " ) , fail_immediately = False )
debug_sb . add_interface ( debug_mon_o , self . wb_models . exp_out_debug )
# SPI
SPI_mon_i = HKSPImonitor ( f " HKinputsMonitorSPI " , self . hk_hdl , inputs [ ' SPI ' ] , self . clk , self . reset , self . logger , callback = self . wb_models . spi_model )
SPI_mon_o = HKSPImonitor ( f " HKoutputsMonitorSPI " , self . hk_hdl , outputs [ ' SPI ' ] , self . clk , self . reset , self . logger , input = False )
CSBmonitor ( f " HKCSBmonitor " , self . hk_hdl , outputs [ ' SPI ' ] , self . clk , self . reset , False , callback = self . wb_models . reset_spi_vals )
SPI_sb = Scoreboard ( SB_name ( " SPI_sb " ) , fail_immediately = False )
SPI_sb . add_interface ( SPI_mon_o , self . wb_models . exp_out_spi )
""" initialize all models needed """
def setupModels ( self ) :
with open ( ' wb_models/housekeepingWB/HK_regs.json ' ) as f :
self . reg_model = json . load ( f )
self . wb_models = HK_models ( self . reg_model , self . output_if , self . hk_hdl )
""" scoreboard for register model check the reg model with RTL every clock """
async def reg_model_sb ( self ) :
while True :
await RisingEdge ( self . clk )
for key , memory_block in self . reg_model . items ( ) :
if fnmatch . fnmatch ( key , " _* " ) :
continue
for reg_shift , reg in memory_block . items ( ) :
for field in reg :
if reg_shift == " base_addr " :
continue
RTL_reg_name = field [ 1 ]
if RTL_reg_name == None :
cocotb . log . debug ( f " [HK_whiteBox][reg_model_sb] register { field [ 1 ] } in { key } doesn ' t have a RTL register " )
continue
if isinstance ( field [ 1 ] , list ) :
RTL_name = field [ 1 ] [ 0 ]
first_index = int ( field [ 1 ] [ 1 ] )
second_index = int ( field [ 1 ] [ 2 ] )
if Macros [ ' GL ' ] :
if RTL_name in [ " mfgr_id " , " prod_id " , " mask_rev " , " mgmt_gpio_data " ] : continue #TODO: change with SDF only
if Macros [ ' GL ' ] :
if fnmatch . fnmatch ( RTL_name , " gpio_configure* " ) : continue #TODO: update gpio_configure and mgmt_gpio_data to get each bit in the SDF case
RTL_reg_path = self . hk_hdl . _id ( RTL_name , False )
size = RTL_reg_path . value . n_bits - 1
RTL_reg_val = RTL_reg_path . value [ size - first_index : size - second_index ]
else :
if field [ 1 ] in [ " pwr_ctrl_out " ] : continue #TODO: delete when reset value is spicified
RTL_reg_path = self . hk_hdl . _id ( field [ 1 ] , False )
RTL_reg_val = RTL_reg_path . value
if ( RTL_reg_val . integer != field [ 6 ] ) :
cocotb . log . error ( f ' [HK_whiteBox][reg_model_sb] mismatch in register { field [ 1 ] } in { key } expected val = { int ( field [ 6 ] ) } actual val = { int ( RTL_reg_val . binstr , 2 ) } ' )
else :
cocotb . log . debug ( f ' [HK_whiteBox][reg_model_sb] match in register { field [ 1 ] } in { key } expected val = { field [ 6 ] } actual val = { RTL_reg_val . integer } ' )
class SB_name :
def __init__ ( self , name ) - > None :
self . _name = name