# 
# $Id$
# 
# [ Description ]
# 
# Makefile
# 

#-----[ Directory ]----------------------------------------
DIR_BIN				= bin
DIR_LIB				= ../lib
DIR_CFG_GEN			= configuration_generated
DIR_CFG_USER			= configuration
DIR_LOG				= log

#-----[ Variables ]----------------------------------------
CFG_FILE			= configuration.cfg

OBJECTS      			= $(OBJECTS_COMMON)

EXEC_PARAMS 			= $(SYSTEMC_EXEC_PARAMS_$(SIMULATOR))
EXEC_LOG			= $(patsubst $(DIR_CFG_GEN)/%.cfg,$(DIR_LOG)/%.exec.log,$(wildcard $(DIR_CFG_GEN)/*.cfg))	\
				  $(patsubst $(DIR_CFG_USER)/%.cfg,$(DIR_LOG)/%.exec.log,$(wildcard $(DIR_CFG_USER)/*.cfg))
EXEC				= soft

#-----[ Rules ]--------------------------------------------
.PRECIOUS			: $(DIR_BIN)/%.x $(DIR_LOG)/%.exec.log
.NOPARALLEL			: clean clean_all help

all_selftest   			: test_env $(DIR_OBJ) $(DIR_BIN) $(DIR_LOG)
				@$(MAKE) library
				@$(MAKE) $(DIR_BIN)/$(EXEC).x

execute				: all_selftest
				@$(MAKE) $(EXEC_LOG)

reconfig			:
				@$(MAKE) config_clean
				@$(MAKE) config

config_clean			:
				@$(RM) $(DIR_CFG_GEN)

config        			: $(DIR_CFG_GEN)
				@$(ECHO) "Generate configuration"
				@													\
				declare     NAME;											\
				declare -ai MIN ;											\
				declare -ai MAX ;											\
				declare -a  STEP; 											\
				declare -a  LINE; 											\
				declare -i  CPT=0;											\
				declare -ai PERIOD;											\
				declare -a  RANGE;											\
				declare -a  RANGE_LOCAL;										\
				declare -a  SIZE;											\
				PERIOD[0]=1;												\
																	\
				while $(READ) line; do											\
				        LINE=($$line);											\
																	\
					if $(TEST) $$CPT -eq 0; then 									\
						NAME=$${LINE[0]};									\
					else												\
						MIN[$$CPT]=$${LINE[0]};									\
						MAX[$$CPT]=$${LINE[1]};									\
						STEP[$$CPT]=$${LINE[2]};								\
						RANGE[$$CPT]=$$($(DIR_SCRIPT)/range.sh $${LINE[0]} $${LINE[1]} $${LINE[2]});		\
						RANGE_LOCAL=($${RANGE[$$CPT]});								\
						SIZE[$$CPT]=$${#RANGE_LOCAL[*]};							\
						PERIOD[$$CPT]=$$(($${PERIOD[$$(($$CPT-1))]}*$${SIZE[$$CPT]}));				\
					fi;												\
																	\
					CPT=$$(($$CPT+1));										\
				done < $(CFG_FILE);											\
																	\
				declare -i x;												\
				declare -a DATA;											\
				declare -ai ENUM_CONFIG=($$($(DIR_SCRIPT)/range.sh 0 $$(($${PERIOD[$$(($$CPT-1))]}-1))));		\
				declare -ai ENUM_PARAM=($$($(DIR_SCRIPT)/range.sh 1 $${#MIN[*]}));            				\
																	\
 				$(ECHO) " * they are $${#MIN[*]} parameters";								\
 				$(ECHO) " * generate $${PERIOD[$$(($$CPT-1))]} configurations";						\
																	\
				for i in $${ENUM_CONFIG[*]}; do										\
					x=$$i;												\
					for j in $${ENUM_PARAM[*]}; do									\
						RANGE_LOCAL=($${RANGE[$$j]});								\
						DATA[$$j]="$${RANGE_LOCAL[$$((($$x % $${SIZE[$$j]})))]} ";				\
						x=$$(($$x/$${SIZE[$$j]})); 								\
					done;												\
					$(ECHO) $${DATA[*]} > "$(DIR_CFG_GEN)/$${NAME}_$${i}.cfg";						\
					$(ECHO) "  - {$$i} $${DATA[*]}";								\
				done;

$(DIR_LOG)/%.exec.log		: $(DIR_CFG_GEN)/%.cfg $(DIR_BIN)/$(EXEC).x
				@$(ECHO) "Execute            : $*"
				@$(EXPORT) SYSTEMC=$(SYSTEMC_$(SIMULATOR)) ; $(VALGRIND) ./$(DIR_BIN)/$(EXEC).x $(EXEC_PARAMS) $* `$(CAT) $<` &> $@
				declare -i count=`$(GREP) -ch "Test KO" $@`;		\
				if $(TEST) $$count -eq 0;       			\
				then echo "                     $* ... OK";           	\
				else echo "                     $* ... KO"; exit 1;     \
				fi;

$(DIR_BIN)/%.x			: $(OBJECTS) $(HEADERS) $(DIR_LIB)
				@$(ECHO) "Linkage            : $*"
				$(CXX) $(LFLAGS) -o $@ $(OBJECTS) $(LIBS)

$(DIR_BIN)			:
				@$(ECHO) "Create directory   : $@"
				@$(MKDIR) $@

$(DIR_LOG)			:
				@$(ECHO) "Create directory   : $@"
				@$(MKDIR) $@

$(DIR_CFG_GEN)			:
				@$(ECHO) "Create directory   : $@"
				@$(MKDIR) $@

selftest_clean_all		: library_clean config_clean
				
selftest_clean			: 
				@$(RM) 	$(DIR_LOG)		\
					$(DIR_CFG_USER)/*~	\
					*.vhdl			\
					*.pos			\
					*.stat			\
					generated_by_systemcass \
					core*

selftest_help			:
				@$(ECHO) " -----[ Selftest ]-----------------------------------"
				@$(ECHO) ""
				@$(ECHO) " * all_selftest         : compile all c++ file and execute"
				@$(ECHO) " * execute              : execute all instance"
				@$(ECHO) " * config               : generate configuration with configuration's file" 
				@$(ECHO) " * reconfig             : regenerate configuration with configuration's file" 
				@$(ECHO) " * clean                : Erase all generate files"
				@$(ECHO) " * clean_all            : Clean + Erase all dependant library"
				@$(ECHO) " * help                 : print this text"
				@$(ECHO) ""

help				: 
				@$(MAKE) common_help  
				@$(MAKE) synthesis_help  
				@$(MAKE) selftest_help

clean				: 
				@$(MAKE) common_clean 
				@$(MAKE) synthesis_clean 
				@$(MAKE) selftest_clean

clean_all			: 
				@$(MAKE) clean 
				@$(MAKE) selftest_clean_all
