2022-09-30 03:42:36 -05:00
import random
import cocotb
from cocotb . clock import Clock
import cocotb . log
2022-10-10 06:50:45 -05:00
import interfaces . caravel as caravel
from interfaces . logic_analyzer import LA
2022-09-30 03:42:36 -05:00
from wb_models . housekeepingWB . housekeepingWB import HK_whiteBox
2022-10-10 06:50:45 -05:00
import interfaces . common as common
2022-09-30 03:42:36 -05:00
import logging
2022-10-10 06:50:45 -05:00
from interfaces . cpu import RiskV
2022-09-30 03:42:36 -05:00
from cocotb . log import SimTimeContextFilter
from cocotb . log import SimLogFormatter
from tests . common_functions . Timeout import Timeout
import os
from cocotb . triggers import FallingEdge , RisingEdge , ClockCycles
""" configure the test log file location and log verbosity
configure the test clock
configure the test timeout
configure whitbox models
start up the test connecting power vdd to the design then reset and disable the CSB bit
return the caravel environmnet with clock and start up
"""
2022-10-01 04:52:30 -05:00
async def test_configure ( dut , timeout_cycles = 1000000 , clk = 25 , timeout_precision = 0.2 , num_error = 3 ) :
2022-09-30 03:42:36 -05:00
caravelEnv = caravel . Caravel_env ( dut )
Timeout ( caravelEnv . clk , timeout_cycles , timeout_precision )
if os . getenv ( ' ERRORMAX ' ) != ' None ' :
num_error = int ( os . getenv ( ' ERRORMAX ' ) )
cocotb . scheduler . add ( max_num_error ( num_error , caravelEnv . clk ) )
clock = Clock ( caravelEnv . clk , clk , units = " ns " ) # Create a 10ns period clock on port clk
cocotb . start_soon ( clock . start ( ) ) # Start the clock
await caravelEnv . start_up ( )
await ClockCycles ( caravelEnv . clk , 10 )
# HK_whiteBox(dut)
2022-10-01 04:52:30 -05:00
return caravelEnv , clock
2022-09-30 03:42:36 -05:00
class CallCounted :
""" Decorator to determine number of calls for a method """
def __init__ ( self , method ) :
self . method = method
self . counter = 0
def __call__ ( self , * args , * * kwargs ) :
self . counter + = 1
return self . method ( * args , * * kwargs )
def repot_test ( func ) :
async def wrapper_func ( * args , * * kwargs ) :
## configure logging
COCOTB_ANSI_OUTPUT = 0
TestName = func . __name__
cocotb . log . setLevel ( logging . INFO )
cocotb . log . error = CallCounted ( cocotb . log . error )
cocotb . log . critical = CallCounted ( cocotb . log . critical )
cocotb . log . warning = CallCounted ( cocotb . log . warning )
handler = logging . FileHandler ( f " sim/ { os . getenv ( ' RUNTAG ' ) } / { os . getenv ( ' SIM ' ) } - { TestName } / { TestName } .log " , mode = ' w ' )
handler . addFilter ( SimTimeContextFilter ( ) )
handler . setFormatter ( SimLogFormatter ( ) )
cocotb . log . addHandler ( handler )
## call test
await func ( * args , * * kwargs )
## report after finish simulation
msg = f ' with ( { cocotb . log . critical . counter } )criticals ( { cocotb . log . error . counter } )errors ( { cocotb . log . warning . counter } )warnings '
if cocotb . log . error . counter > 0 or cocotb . log . critical . counter > 0 :
raise cocotb . result . TestComplete ( f ' Test failed { msg } ' )
else :
raise cocotb . result . TestComplete ( f ' Test passed { msg } ' )
return retval
return wrapper_func
async def max_num_error ( num_error , clk ) :
while True :
await ClockCycles ( clk , 1 )
if cocotb . log . error . counter + cocotb . log . critical . counter > num_error :
msg = f ' Test failed with max number of errors { num_error } ( { cocotb . log . critical . counter } )criticals ( { cocotb . log . error . counter } )errors ( { cocotb . log . warning . counter } )warnings '
raise cocotb . result . TestFailure ( msg )
async def wait_reg1 ( cpu , caravelEnv , data ) :
while ( True ) :
if cpu . read_debug_reg1 ( ) == data :
return
await ClockCycles ( caravelEnv . clk , 10 )
async def wait_reg2 ( cpu , caravelEnv , data ) :
while ( True ) :
if cpu . read_debug_reg2 ( ) == data :
return
await ClockCycles ( caravelEnv . clk , 10 )