# -*- Makefile -*-
#*****************************************************************************
#
# DESCRIPTION: Verilator: Makefile for verilog source
#
# Code available from: https://verilator.org
#
#*****************************************************************************
#
# Copyright 2003-2020 by Wilson Snyder.  This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
# Verilator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
#****************************************************************************/

#### Start of system configuration section. ####

# Unfortunately configure uses relative paths, and this makefile is called
# from a level lower, so we need to move up if it's relative, not if absolute.
config_srcdir = @srcdir@
ifeq ($(config_srcdir),.)
 srcdir = ..
else  # Run an experiment
 ifeq ($(wildcard $(config_srcdir)/../Makefile_obj.in),)
   srcdir = $(config_srcdir)
 else
   srcdir = $(config_srcdir)/..
 endif
endif

incdir = $(srcdir)/../include
# Bldsrc may differ from srcdir if configure wan't run from the kit top
bldsrc = ..

# Programs
CC = @CC@
CXX = @CXX@
LINK = @CXX@
LEX = @LEX@
LFLAGS = -d
PERL = @PERL@
YACC = @YACC@

prefix = @prefix@

# Directory in which to install data across multiple architectures
datarootdir = @datarootdir@

# Directory in which to install package specific files
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@

# Compile options
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CPPFLAGS += @CPPFLAGS@
CFLAGS += @CFLAGS@
CXXFLAGS += @CXXFLAGS@
LDFLAGS += @LDFLAGS@
EXEEXT = @EXEEXT@
CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@
CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@
# Compiler flags that turn on extra warnings
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@

#### End of system configuration section. ####

VPATH += . $(bldsrc) $(srcdir)
TGT = ../../verilator_bin

#################
ifeq ($(VL_DEBUG),)
# Optimize
COPT = -O2
else
# Debug
COPT = -ggdb -DVL_DEBUG -D_GLIBCXX_DEBUG
# Debug & Profile:
#LDFLAGS += -pg -g
#COPT = -ggdb -pg -g
endif
#################

#LIBS += -ldl
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl

# -lfl not needed as Flex invoked with %nowrap option
# -lstdc++ needed for clang, believed harmless with gcc
LIBS = -lm -lstdc++

CPPFLAGS += -MMD
CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir) -I../../include
CPPFLAGS += -DYYDEBUG 	# Required to get nice error messages
#CPPFLAGS += -DVL_LEAK_CHECKS 	# If running valgrind or other hunting tool
CPPFLAGS += $(COPT)
CPPFLAGS += -MP # Only works on recent GCC versions
ifeq ($(CFG_WITH_CCWARN),yes)	# Local... Else don't burden users
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
#CPPFLAGS += -pedantic-errors
else
CPPFLAGS += $(CFG_CXXFLAGS_SRC)
endif

CPPFLAGSWALL   = $(CPPFLAGS)
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)

# Allow RPM builds to specify hardcoded data directories
# To do this:
ifeq ($(CFG_WITH_DEFENV),yes)
 CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
 CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
 CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\"
 CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\"
 ifeq ($(VERILATOR_ROOT),)	# Use what we're given, or intuit
  CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
 else
  CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\"
 endif
endif

HEADERS = $(wildcard V*.h v*.h)

ASTGEN = $(srcdir)/astgen
BISONPRE = $(srcdir)/bisonpre
FLEXFIX = $(srcdir)/flexfix
VLCOVGEN = $(srcdir)/vlcovgen

######################################################################
#### Top level

all: make_info $(TGT)

make_info:
	@echo "      Compile flags: " $(CXX) ${CFLAGS} ${CXXFLAGS} ${CPPFLAGS}

clean mostlyclean distclean maintainer-clean::
	-rm -f *.o *.d perlxsi.c *_gen_*
	-rm -f *__gen*
	-rm -f obj_* .objcache*

distclean maintainer-clean:: clean

maintainer-clean::

maintainer-copy::

#### Top executable

RAW_OBJS = \
	Verilator.o \
	V3Active.o \
	V3ActiveTop.o \
	V3Assert.o \
	V3AssertPre.o \
	V3Ast.o	\
	V3AstNodes.o	\
	V3Begin.o \
	V3Branch.o \
	V3Broken.o \
	V3CCtors.o \
	V3Case.o \
	V3Cast.o \
	V3Cdc.o \
	V3Changed.o \
	V3Clean.o \
	V3Clock.o \
	V3Combine.o \
	V3Config.o \
	V3Const__gen.o \
	V3Coverage.o \
	V3CoverageJoin.o \
	V3Dead.o \
	V3Delayed.o \
	V3Depth.o \
	V3DepthBlock.o \
	V3Descope.o \
	V3EmitC.o \
	V3EmitCInlines.o \
	V3EmitCSyms.o \
	V3EmitCMake.o \
	V3EmitMk.o \
	V3EmitV.o \
	V3EmitXml.o \
	V3Error.o \
	V3Expand.o \
	V3File.o \
	V3FileLine.o \
	V3Gate.o \
	V3GenClk.o \
	V3Graph.o \
	V3GraphAlg.o \
	V3GraphAcyc.o \
	V3GraphDfa.o \
	V3GraphPathChecker.o \
	V3GraphTest.o \
	V3Hashed.o \
	V3Inline.o \
	V3Inst.o \
	V3InstrCount.o \
	V3Life.o \
	V3LifePost.o \
	V3LinkCells.o \
	V3LinkDot.o \
	V3LinkJump.o \
	V3LinkLValue.o \
	V3LinkLevel.o \
	V3LinkParse.o \
	V3LinkResolve.o \
	V3Localize.o \
	V3Name.o \
	V3Number.o \
	V3Options.o \
	V3Order.o \
	V3Os.o \
	V3Param.o \
	V3Partition.o \
	V3PreShell.o \
	V3Premit.o \
	V3ProtectLib.o \
	V3Reloop.o \
	V3Scope.o \
	V3Scoreboard.o \
	V3Slice.o \
	V3Split.o \
	V3SplitAs.o \
	V3Stats.o \
	V3StatsReport.o \
	V3String.o \
	V3Subst.o \
	V3Table.o \
	V3Task.o \
	V3Trace.o \
	V3TraceDecl.o \
	V3Tristate.o \
	V3TSP.o \
	V3Undriven.o \
	V3Unknown.o \
	V3Unroll.o \
	V3Width.o \
	V3WidthSel.o \

# Non-concatable
NC_OBJS += \
	V3ParseImp.o \
	V3ParseGrammar.o \
	V3ParseLex.o \
	V3PreProc.o \

# verilator_coverage
VLCOV_OBJS = \
	VlcMain.o \

# verilator_replay
VLREPLAY_OBJS = \
	V3Error.o \
	VlrOptions.o \
	verilated_replay_common.o \
	VlrGenerator.o \
	VlrMain.o \

#### Linking

ifneq ($(VL_VLCOV),)
PREDEP_H =
OBJS += $(VLCOV_OBJS)
else ifneq ($(VL_VLREPLAY),)
PREDEP_H =
OBJS += $(VLREPLAY_OBJS)
# TODO -- do we already search for this in configure?
LIBS += -lz
# TODO -- do this for verilator_coverage as well
CXXFLAGS += -D_V3ERROR_NO_GLOBAL_=1
else
PREDEP_H = V3Ast__gen_classes.h
OBJS += $(RAW_OBJS) $(NC_OBJS)
endif

V3__CONCAT.cpp: $(addsuffix .cpp, $(basename $(RAW_OBJS)))
	$(PERL) $(srcdir)/../bin/verilator_includer $^ > $@

$(TGT): $(PREDEP_H) $(OBJS)
	@echo "      Linking $@..."
	-rm -rf $@ $@.exe
	${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}

V3Number_test: V3Number_test.o
	${LINK} ${LDFLAGS} -o $@ $^ ${LIBS}

#### Modules

%__gen.cpp:	%.cpp $(ASTGEN) V3Ast.h V3AstNodes.h
	$(PERL) $(ASTGEN) -I$(srcdir) $*.cpp

%.o:	%.cpp
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} -c $<
%.o:	%.c
	$(OBJCACHE) ${CC}  ${CFLAGS} ${CPPFLAGSWALL} -c $<
# TODO -- this seems terrible
verilated_replay_common.o:	../include/verilated_replay_common.cpp
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} -c $<

V3ParseLex.o:	V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $<

V3ParseGrammar.o:	V3ParseGrammar.cpp V3ParseBison.c
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $<

V3ParseImp.o:	V3ParseImp.cpp V3ParseBison.c
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $<

V3PreProc.o:	V3PreProc.cpp V3PreLex.yy.cpp
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $<

#### Generated files

# Target rule called before parallel build to make generated files
serial:: V3Ast__gen_classes.h V3ParseBison.c

serial_vlcov:: vlcovgen.d

vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
	$(PERL) $(VLCOVGEN) --srcdir $(srcdir)
	touch $@

V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
	$(PERL) $(ASTGEN) -I$(srcdir)  --classes

V3ParseBison.h: V3ParseBison.c

# Have only one output file in this rule to prevent parallel make issues
V3ParseBison.c: verilog.y $(BISONPRE)
	@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
	$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $<

V3Lexer_pregen.yy.cpp:	verilog.l V3ParseBison.h $(HEADERS)
	${LEX} --version
	${LEX} ${LFLAGS} -o$@ $<

V3Lexer.yy.cpp:	V3Lexer_pregen.yy.cpp $(FLEXFIX)
	$(PERL) $(FLEXFIX) V3Lexer <$< >$@

V3PreLex_pregen.yy.cpp:	V3PreLex.l $(HEADERS)
	${LEX} --version
	${LEX} ${LFLAGS} -o$@ $<

V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX)
	$(PERL) $(FLEXFIX) V3PreLex <$< >$@

.SUFFIXES:

######################################################################
######################################################################

DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif
