#!/bin/bash

#-----------------------------------------------------------
# $Id$
#-----------------------------------------------------------

#-----[ variable ]------------------------------------------

declare    test_ko="Test KO";
declare    test_ok="Test OK";
declare    tmp="${MORPHEO_HOME}/tmp/SelfTest";
declare    path="${MORPHEO_TOPLEVEL}/IPs/systemC/processor/Morpheo/";

declare -a directory=(
    "Common"

    "Behavioural"
    "Behavioural/Configuration"
    "Behavioural/Custom"

    "Behavioural/Generic/Counter"
    "Behavioural/Generic/Priority"
    "Behavioural/Generic/Queue_Control"                                 
    "Behavioural/Generic/Queue"                                 
    "Behavioural/Generic/RegisterFile/RegisterFile_Monolithic"  
    "Behavioural/Generic/RegisterFile/RegisterFile_Multi_Banked"
    "Behavioural/Generic/RegisterFile"                          
    "Behavioural/Generic/Select/Select_Priority_Fixed"           
    "Behavioural/Generic/Select"                                
    "Behavioural/Generic/Shifter"                               
    "Behavioural/Generic/Sort"                                  
    "Behavioural/Generic/Victim/Victim_Pseudo_LRU"              
    "Behavioural/Generic/Victim"                                

    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Execute_loop_Glue"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Functionnal_unit/Operation"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Functionnal_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit/Read_queue"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit/Reservation_station"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Write_unit/Write_unit/Execute_queue"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Write_unit/Write_unit/Write_queue"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Write_unit/Write_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Write_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Network/Execution_unit_to_Write_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Network/Read_unit_to_Execution_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Network"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Register_unit/Register_unit_Glue"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop/Register_unit"
    "Behavioural/Core/Multi_Execute_loop/Execute_loop"
    "Behavioural/Core/Multi_Execute_loop"

    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Issue_queue"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/OOO_Engine_Glue"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Reexecute_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Load_Store_pointer_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Dependency_checking_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Free_List_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Register_Address_Translation_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Register_translation_unit_Glue"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Stat_List_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Rename_unit_Glue"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Rename_select"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Special_Register_unit"
    "Behavioural/Core/Multi_OOO_Engine/OOO_Engine"
    "Behavioural/Core/Multi_OOO_Engine"
    
    "Behavioural/Core/Multi_Front_end/Front_end/Context_State"
    "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod/Instruction"
    "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod"
    "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod_queue"
    "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit"
    "Behavioural/Core/Multi_Front_end/Front_end/Front_end_Glue"
    "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Address_management"
    "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Ifetch_queue"
    "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Ifetch_unit_Glue"
    "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Branch_Target_Buffer/Branch_Target_Buffer_Glue"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Branch_Target_Buffer/Branch_Target_Buffer_Register"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Branch_Target_Buffer"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Direction_Glue"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction"
#   "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Meta_Predictor_Glue"
#   "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Two_Level_Branch_Predictor/Two_Level_Branch_Predictor_Glue"
#   "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Two_Level_Branch_Predictor/Branch_History_Table"
#   "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Two_Level_Branch_Predictor/Pattern_History_Table"
#   "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor/Two_Level_Branch_Predictor"
#   "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Direction/Meta_Predictor"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Prediction_unit_Glue"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Return_Address_Stack"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table"
    "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit"
    "Behavioural/Core/Multi_Front_end/Front_end"
    "Behavioural/Core/Multi_Front_end"

    "Behavioural/Core/Icache_Access"
    "Behavioural/Core/Dcache_Access"

    "Behavioural/Core/Core_Glue"
    "Behavioural/Core"

    "TopLevel"
    );
                                           

#-----[ usage ]---------------------------------------------
function usage ()
{
    echo "Usage          : ${0} action";
    echo "Arguments      : ";
    echo " * action";
    echo "   * test      : test all component";
    echo '                 for each component, create file in ${MORPHEO_HOME}/tmp/';
    echo "   * test_all  : same as test, but don't stop at the first error";
    echo "   * res       : list test's resultat";
    echo "   * list      : list test's resultat";
    echo "   * clean     : erase file in ${MORPHEO_HOME}/tmp/ directory";
    echo "   * clean_all : clean all component";
    echo "   * help      : print this message";
    echo "";
    echo "Notes          : ";
    echo " * Morpheo environment must be positionned";
    exit;
}

#-----[ main ]----------------------------------------------
function main ()
{
    # Test operand
    if test ${#} -ne 1; then
	usage ${*};
    fi;

    if test -z ${MORPHEO_TOPLEVEL}; then
	usage ${*};
    fi;

    if test ! -d ${tmp}; then
	mkdir -p ${tmp};
    fi;

    nb_cpu=$(cat /proc/cpuinfo |grep -c processor);
    pwd=${PWD};
    case ${1} in
	"test" | "test_all")
	    for i in ${directory[@]}; do
		component=$(basename ${i});
		dir="${path}/${i}/SelfTest";

		if test -d "${dir}"; then
		    # have previous test ok ?
		    declare -i make_test=1;
		    
		    if test -f ${tmp}/${component}; then
			res_test=$(cat ${tmp}/${component});
			if test "${test_ok}" = "${res_test}"; then
			    make_test=0;
			fi;
		    fi;

		    if test ${make_test} -eq 1; then
			cd ${dir};
			make config;
			make -j${nb_cpu} execute;
			case ${?} in
			    "0")
				echo ${test_ok} > ${tmp}/"${component}";
				;;
			    *)

				echo ${test_ko} > ${tmp}/"${component}";
				echo "";
				echo "${component} : ${test_ko}";
				echo "";
				if test ${1} = "test"; then
				    exit 1;
				fi;
				;;
			esac;
		    fi;
		else
		    echo "${component} have not SelfTest directory.";
		fi;

		cd ${pwd};
	    done;
	    ;;

	"res")
	    for i in ${tmp}/*; do
		if test -f ${i}; then
		    component=$(basename ${i});
		    res_test=$(cat ${i});

		    
		    case "${res_test}" in
			"${test_ok}") color=32; 
			    ;;
			"${test_ko}") color=31; 
			    ;;
			*)            color=39; 
			    ;;
		    esac
		    echo "[1;${color}m${res_test} - ${component}[1;0m";
		fi;
	    done;
	    ;;

	"list")
	    for i in ${directory[@]}; do
		component=$(basename ${i});
		echo "${i}";
	    done;
	    ;;

	"clean")
	    rm -r ${tmp};
	    ;;
	    
	"clean_all")
	    for i in ${directory[@]}; do
		component=$(basename ${i});

		cd ${path}/${i};

                if test -f "Makefile"; then
		    make clean;
		    dir="SelfTest";
                    
		    if test -d ${dir}; then
		        cd ${dir};
		        make clean;
		    else
		        echo "${component} have not SelfTest directory.";
		    fi;
		    cd ${pwd};
                fi;
	    done;
	    ;;

	"help")
	    usage ${*};
	    ;;
	*)
	    usage ${*};
    esac
}

#-----[ Body ]----------------------------------------------
main ${*};

