#
# Makefile for Transaction Generator 2 (SCTG2)
#
export
##################################################
#
# Modify following if needed
#
# Check README for possible solutions if encountering
# compilation errors


# C++ compiler to use
CXX = g++


# Optimization level
OPT_LEVEL = -O3 


# Additional flags for c++ compiler
ADD_CXXFLAGS = -DNDEBUG -DBOOST_NO_RVALUE_REFERENCES -DBOOST_NO_STATIC_ASSERT 
# -DNDEBUG
# -DBOOST_NO_RVALUE_REFERENCES -DBOOST_NO_STATIC_ASSERT 


# Additional flags for c++ linker
ADD_LDFLAGS =


# Additional flags for Modelsim's sccom
ADD_SCCOM  = -DBOOST_NO_RVALUE_REFERENCES -DNDEBUG -nodbgsym


##################################################
#
# Location of header files and libraries
#
#  For Modelsim relative paths may work better
#

# Boost's header files
BOOST_INC     = ../../../../../../cygwin/boost_1_46_0/include
#BOOST_INC     = /boost_1_46_0/include


# Boost's libraries
BOOST_LIBS    = ../../../../../../cygwin/boost_1_46_0/lib
#BOOST_LIBS    = /boost_1_46_0/lib


# OSCI TLM headers
TLM_INC       = ../../../../../../cygwin/TLM-2009-07-15/include/tlm
#TLM_INC       = /TLM-2009-07-15/include/tlm


# SystemC header files
SC_INC        = ../../../../../../cygwin/systemc_2.2.0/include
#SC_INC        = /systemc_2.2.0/include


# SystemC library (libsystemc.a)
SC_LIB        = ../../../../../../cygwin/systemc_2.2.0/lib-cygwin
#SC_LIB        = /systemc_2.2.0/lib-cygwin


# Uncomment following to enable OCP-IP TLM model(s)
USE_OCP_TLM_KIT = -DSCTG_USE_OCPTLM


# OCP-IP TLM Kit header files
OCP_TLM_INC   = ../../../../../../cygwin/ocp_kit/include
#OCP_TLM_INC   = /ocp_kit/include



###################################################
#
# Uncomment and modify following to use Execution Monitor
# ASIO_FLAGS and ASIO_LINK depend on your system
#  refer to Boost.Asio documentation
# Examples are for 32-bit Windows XP with Cygwin
#  for Linux no are flags needed and remove -lws2_32
#
# set also JAVA_HOME to point JDK and ANT_HOME to Apache Ant's root
#  prior to running make if you wand to compile execution monitor
#  again
#

USE_EXECMON   = -DSCTG_USE_EXECMON
ASIO_FLAGS    = -D_WIN32_WINNT=0x0501 -D__USE_W32_SOCKETS
ASIO_LINK     = -lboost_system -lws2_32 



#
#
# From this point onward no modification should be needed
#
#

PWD = $(shell pwd)

# Package's internal paths
TG2_INC         = transaction_generator_2/include
MESH_INC        = hw_lib/mesh_2d/systemc
XBAR_INC        = hw_lib/crossbar/systemc
RING_INC        = hw_lib/ring/systemc
PKT_CODEC_INC   = hw_lib/packet_codec/systemc
FIFO_INC        = hw_lib/fifo/systemc
ADAPTER_INC     = hw_lib/adapters/systemc
SIMPLE_BUS_INC  = hw_lib/simple_bus/systemc
NOC_FACTORY_INC = hw_lib/noc_factory/systemc
ADM_INC         = adm

# Include paths for g++
INCLUDES = -I$(PWD)/$(TG2_INC) \
 -I$(BOOST_INC) \
 -I$(PWD)/$(ADAPTER_INC) \
 -I$(PWD)/$(MESH_INC) \
 -I$(PWD)/$(XBAR_INC) \
 -I$(PWD)/$(RING_INC) \
 -I$(PWD)/$(PKT_CODEC_INC) \
 -I$(PWD)/$(FIFO_INC) \
 -I$(PWD)/$(SIMPLE_BUS_INC) \
 -I$(TLM_INC) \
 -I$(SC_INC) \
 -I$(PWD)/$(NOC_FACTORY_INC) \
 -I$(OCP_TLM_INC) \
 -I$(PWD)/$(ADM_INC)

# Include paths for Modelsim's sccom 
#  It might be easier to use relative paths. Make 
#  sure that all paths are on the same drive as this 
#  package (for Windows + Cygwin) 
#
MODELSIM_INCS = -I$(TG2_INC) \
 -I$(BOOST_INC) \
 -I$(MESH_INC) \
 -I$(XBAR_INC) \
 -I$(RING_INC) \
 -I$(ADAPTER_INC) \
 -I$(PKT_CODEC_INC) \
 -I$(FIFO_INC) \
 -I$(SIMPLE_BUS_INC) \
 -I$(NOC_FACTORY_INC) \
 -I$(OCP_TLM_INC) \
 -I$(ADM_INC)

# target executable
TARGET  = sctg
# target DO-file for Modelsim
MSIM_DO = sctg.do


CXXFLAGS = $(OPT_LEVEL) -DSC_INCLUDE_DYNAMIC_PROCESSES $(ASIO_FLAGS) $(USE_EXECMON) $(ADD_CXXFLAGS) $(USE_OCP_TLM_KIT)


SCCOM_OPTS = $(MODELSIM_INCS) $(OPT_LEVEL) -DSC_INCLUDE_DYNAMIC_PROCESSES -incr $(USE_EXECMON) -DSCTG_MIXED_LANGUAGE_SIM $(ADD_SCCOM) $(USE_OCP_TLM_KIT)


VCOM = vcom -check_synthesis


all: subs $(TARGET)


# See if all directory paths are valid
check_dir:
#	if test -d $(BOOST_INC)  ; then echo "  ok"; else echo "  Not found!"; fi
	./chk_dir.sh $(BOOST_INC) BOOST_INC
	./chk_dir.sh $(BOOST_LIBS) BOOST_LIBS
	./chk_dir.sh $(TLM_INC) TLM_INC
	./chk_dir.sh $(SC_INC) SC_INC
	./chk_dir.sh $(SC_LIB) SC_LIB
	./chk_dir.sh $(OCP_TLM_INC) OCP_TLM_INC


ifdef USE_EXECMON
ASIO = $(ASIO_LINK)
else
ASIO =
endif

ifdef USE_EXECMON
#all: bin/execution_monitor
#sccom: bin/execution_monitor


# Make this if you want to compile Execution Monitor again
#  Needs environment variables JAVA_HOME and ANT_HOME to be set
#  and of course Java JDK
execmon: bin/execution_monitor

bin/execution_monitor:
	cd java_tool_installer; ant -Dprefix=.. configure_all
	cd java_tool_installer; ant build_all
	cd java_tool_installer; ant install_all
endif

ifndef SC_LIB
SC_LIB = .
endif

#
# Call make on these subdirectories
# 
NOC_DIRS = hw_lib/mesh_2d/systemc \
           hw_lib/simple_bus/systemc \
           hw_lib/crossbar/systemc \
           hw_lib/ring/systemc

.PHONY: subs
subs:
	@for dir in $(NOC_DIRS); do $(MAKE) -C $$dir; done
	cd hw_lib/noc_factory/systemc; $(MAKE)
	cd transaction_generator_2; $(MAKE)

#
# Factory objects to be linked with SCTG2
#  Add to the list if you have additional NoCs to simulate
#
FACTORIES = \
          hw_lib/mesh_2d/systemc/sc_rtl_1/noc_factory_rtl1.o \
          hw_lib/mesh_2d/systemc/sc_rtl_2/noc_factory_rtl2.o \
          hw_lib/mesh_2d/systemc/sc_tlm_1/tlm_1_factory.o \
          hw_lib/mesh_2d/systemc/mesh_factory.o \
          hw_lib/crossbar/systemc/crossbar_factory.o \
          hw_lib/ring/systemc/ring_factory.o \
          hw_lib/simple_bus/systemc/sbus_factory.o \
          hw_lib/noc_factory/systemc/noc_factory.o

# Add this if using OCP-IP TLM Kit models
ifdef USE_OCP_TLM_KIT
FACTORIES += hw_lib/mesh_2d/systemc/sc_ocp_tl3_1/ocp_tl3_factory.o
endif


$(TARGET): $(FACTORIES) \
          transaction_generator_2/libsctg.a

$(TARGET):
	$(CXX) -o $(TARGET) $(ADD_LDFLAGS) $(CXXFLAGS) $(INCLUDES) \
          $(FACTORIES) \
          -L$(SC_LIB) \
          -lsystemc \
          -Ltransaction_generator_2 \
          -lsctg \
          -L$(BOOST_LIBS) \
          -lboost_program_options \
          $(ASIO)

.PHONY: clean
clean:
	@for dir in $(NOC_DIRS); do $(MAKE) clean -C $$dir; done
	cd hw_lib/noc_factory/systemc; $(MAKE) clean
	cd transaction_generator_2; $(MAKE) clean
	rm -f *.o *.exe $(TARGET) *~ $(MSIM_DO)
	rm -rf work_libs/*

#ifdef USE_EXECMON
#clean: clean_javas
#endif

.PHONY: clean_javas
clean_javas:
	cd java_tool_installer; ant clean_all
	cd java_tool_installer; ant uninstall_all
	cd java_tool_installer; ant uninstall_libs


#
# Rules for Modelsim
#

.PHONY: modelsim
modelsim: $(MSIM_DO)

$(MSIM_DO): modelsim_libs vcom sccom link

.PHONY: modelsim_libs
modelsim_libs:
	echo "# SCTG setup script for Modelsim" > $(MSIM_DO)
	echo vlib work_libs/lib_vhd  >> $(MSIM_DO)
	echo vlib work_libs/lib_sctg >> $(MSIM_DO)

VHDL_FILES = \
	hw_lib/fifo/vhd/fifo.vhd \
	hw_lib/fifo/vhd/multiclk_fifo.vhd \
	hw_lib/packet_codec/vhd/addr_lut_pkg.vhd \
	hw_lib/packet_codec/vhd/addr_lut.vhd \
	hw_lib/packet_codec/vhd/pkt_counter.vhd \
	hw_lib/packet_codec/vhd/pkt_dec.vhd \
	hw_lib/packet_codec/vhd/pkt_enc.vhd \
	hw_lib/packet_codec/vhd/pkt_enc_dec.vhd \
	hw_lib/packet_codec/vhd/enc_dec_1d.vhd \
	hw_lib/mesh_2d/vhd/mesh_router.vhd \
	hw_lib/mesh_2d/vhd/mesh_2d.vhd \
	hw_lib/mesh_2d/vhd/mesh_2d_with_pkt_codec_top.vhd \
        hw_lib/crossbar/vhd/allocator.vhd \
        hw_lib/crossbar/vhd/arbiter.vhd \
        hw_lib/crossbar/vhd/io_block.vhd \
        hw_lib/crossbar/vhd/switch_matrix.vhd \
        hw_lib/crossbar/vhd/crossbar.vhd \
        hw_lib/crossbar/vhd/crossbar_with_pkt_codec_top.vhd \
        hw_lib/ring/vhd/ring_router.vhd \
        hw_lib/ring/vhd/ring.vhd \
        hw_lib/ring/vhd/ring_with_pkt_codec_top.vhd

.PHONY: vcom
vcom: $(VHDL_FILES)
	echo $(VCOM) -work work_libs/lib_vhd $(VHDL_FILES) >> $(MSIM_DO)

SCCOM_SCTG_FILES = \
	adm/command_line.cc \
        transaction_generator_2/src/common.cc \
        transaction_generator_2/src/buffer.cc \
        transaction_generator_2/src/configuration.cc \
        transaction_generator_2/src/measure.cc \
        transaction_generator_2/src/event.cc \
        transaction_generator_2/src/trigger.cc \
        transaction_generator_2/src/resource_user.cc \
	transaction_generator_2/src/task.cc \
        transaction_generator_2/src/mem_area.cc \
        transaction_generator_2/src/resource.cc	\
        transaction_generator_2/src/processing_element.cc \
	transaction_generator_2/src/memory_model.cc \
        hw_lib/mesh_2d/systemc/mesh_factory.cc \
        hw_lib/simple_bus/systemc/sbus_factory.cc \
        hw_lib/crossbar/systemc/crossbar_factory.cc \
        hw_lib/ring/systemc/ring_factory.cc \
        hw_lib/noc_factory/systemc/noc_factory.cc \
        transaction_generator_2/src/main.cc \
        hw_lib/mesh_2d/systemc/sc_rtl_1/noc_factory_rtl1.cc \
        hw_lib/mesh_2d/systemc/sc_rtl_2/noc_factory_rtl2.cc \
        hw_lib/mesh_2d/systemc/sc_tlm_1/tlm_1_factory.cc \
        hw_lib/mesh_2d/systemc/sc_ocp_tl3_1/ocp_tl3_factory.cc 


SCCOM_LIB_VHD_FILES = \
       hw_lib/mesh_2d/systemc/vhd/noc_factory_vhd.cc \
       hw_lib/crossbar/systemc/vhd/crossbar_factory_vhd.cc \
       hw_lib/ring/systemc/vhd/ring_factory_vhd.cc


.PHONY: sccom_sctg
sccom_sctg: $(SCCOM_SCTG_FILES)
	echo sccom $(SCCOM_OPTS) -work work_libs/lib_sctg $(SCCOM_SCTG_FILES) | sed 's/\//\\\\/g' >> $(MSIM_DO)

.PHONY: sccom_lib_vhd
sccom_lib_vhd: $(SCCOM_LIB_VHD_FILES)
	echo sccom $(SCCOM_OPTS) -work work_libs/lib_vhd $(SCCOM_LIB_VHD_FILES) | sed 's/\//\\\\/g' >> $(MSIM_DO)


.PHONY: sccom
sccom: work_libs/cost_fuction.o sccom_sctg sccom_lib_vhd 


work_libs/cost_fuction.o: transaction_generator_2/src/cost_function.cc
	$(CXX) -c -fPIC -o work_libs/cost_function.o $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) transaction_generator_2/src/cost_function.cc

link:
	echo sccom -link -lib work_libs/lib_vhd -lib work_libs/lib_sctg -work work_libs/lib_sctg work_libs/cost_function.o | sed 's/\//\\\\/g' >> $(MSIM_DO)


#
# Use these to test simulation with Modelsim
#
sim_mesh:
	time vsim -novopt -lib work_libs/lib_sctg -L work_libs/lib_vhd -sc_arg "examples/test_mesh.xml" -t 1fs -c -do "run 100ms; quit -f" sc_main

sim_sbus:
	time vsim -lib work_libs/lib_sctg -L work_libs/lib_vhd -sc_arg "examples/test_sbus.xml" -t 1fs -c -do "run 100ms; quit -f" sc_main
