#/*
#* Verilog Behavioral Simulator
#* Copyright (C) 1995 Lay Hoon Tho, Jimen Ching
#*
#* This program is free software; you can redistribute it and/or modify 
#* it under the terms of the GNU General Public License as published by
#* the Free Software Foundation; either version 2 of the License, or
#* (at your option) any later version.
#*
#* This program 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.
#*
#* Special Contributions:
#*
#* The authors of this software would like to thank the University of 
#* Hawaii, College of Engineering for the use of their computer 
#* facilities in the course of the development of this software.  Special 
#* thanks to Dr. Alex Quilici, who is the advisor for this project, and Dr. 
#* Michael Smith, who taught us how to use Verilog.  We would also like
#* to thank the College of Engineering for the knowledge we have gained
#* through their engineering curriculum.
#*
#* Authors:
#*	Lay Hoon Tho
#*		8, Jalan Setia 6 Chamek,
#*		Kluang, 86000 Johore,
#*		Malaysia
#*
#*	Jimen Ching
#*		2108 Citron St. Apt. #2
#*		Honolulu, HI 96826
#*		USA
#*		(jching@aloha.com)
#*/
# Makefile for VBS

# GCC 2.6.3 (older versions have trouble)
CC = gcc
C++ = g++

# Set the following debug flags
#   DEBUG_PAR .... Print creation of each object.
#   DEBUG_ST ..... Print symbol table contents.
#   DEBUG_INIT ... 'initial' statement is appended to time wheel.
#   DEBUG_TW ..... Print output on each time node.
#   DEBUG_MOD .... Notify when a module is parsed.
#   DEBUG_FUTR ... Time at which statement is appended to future.
#   DEBUG_NES .... Printout sequence information of nested blocks
#	(useful for debugging nested blocks).
#
DEBUGFLAG = -g
DEBUGGING =

# We use GNU tools.  Berkeley yacc and lex should work as well.
LEX = flex
YACC = bison -y -d

# C and C++ options.
#
# Do not use -ansi.  If -ansi is used with GCC, other things will break,
# like POSIX source.  Instead of defining these macros, let the GCC header
# files work it out themselves.
CFLAGS = -pipe -pedantic -Wall $(DEBUGFLAG)
LDFLAGS =
CCOPTIONS = -pipe -Wall $(DEBUGFLAG)
LDOPTIONS =

# Extra libraries and include directories.
EXTRALIBS =
EXTRAINCS = -I.

# Some system commands.  Change if your system's version is broken.
SHELL = /bin/sh
RM = rm -f
MV = mv

#
# NO NEED TO MODIFY BELOW THIS LINE!!!
#

# Project library objects and interface functions...
PLIBOBJS = String.o Bitvector.o Error.o Symtab.o

# Project objects
TOBJS = Setup.o Trigger.o Systask.o Display.o Eval.o

# Parser objects
PAROBJS = vbs_yacc.o vbs_lex.o
POBJS = intrface.o PTypes.o Main.o

LIBS = $(EXTRALIBS)

.SUFFIXES:
.SUFFIXES: .c .cc .o

.c.o:
	$(CC) $(CFLAGS) $(EXTRAINCS) $(DEBUGFLAGS) -c $< $(DEBUGGING)

.cc.o:
	$(C++) $(CCOPTIONS) $(EXTRAINCS) $(DEBUGFLAGS) -c $< $(DEBUGGING)

all:
	@echo ""
	@echo "Type 'make target', where target is one of"
	@echo "the targets below:"
	@echo ""
	@echo "     list-class ...... menu of class test targets"
	@echo "     list-v .......... menu of .v test targets"
	@echo "     vbs ............. compile simulator"
	@echo ""

list-class:
	@echo ""
	@echo "Test targets:"
	@echo "     str ............. test String class"
	@echo "     list ............ test List class"
	@echo "     bv .............. test BitVector class"
	@echo "     st .............. test Symbol Table class"
	@echo "     evnt ............ test Event class"
	@echo "     tw .............. test Time Wheel class"
	@echo "     types ........... test PTypes.h"
	@echo "     test-all ........ all the above tests"
	@echo "     clean-tests ..... clean above tests"
	@echo ""

list-v:
	@echo ""
	@echo "Test targets:"
	@echo "     test-arith ...... test arith .v files"
	@echo "     test-case ....... test case .v files"
	@echo "     test-comp ....... test comparison .v files"
	@echo "     test-evnt ....... test event .v files"
	@echo "     test-func ....... test functions .v files"
	@echo "     test-task ....... test tasks .v files"
	@echo "     test-mod ........ test module instantiation .v files"
	@echo "     test-ifstmt ..... test if statement .v files"
	@echo "     test-nested ..... test nested .v files"
	@echo "     test-range ...... test range .v files"
	@echo "     test-others ..... test all others .v files"
	@echo "     test-allv ....... test all of the above"
	@echo ""

vbs_lex.c: vbs.l intrface.h
	$(LEX) vbs.l
	@$(MV) lex.yy.c vbs_lex.c

# vbs_yacc.h is automatically created with vbs_yacc.c...
vbs_yacc.c: vbs.y intrface.h
	$(YACC) vbs.y
	@$(MV) y.tab.c vbs_yacc.c
	@$(MV) y.tab.h vbs_yacc.h

vbs: $(PLIBOBJS) $(TOBJS) $(PAROBJS) $(POBJS)
	$(C++) $(LDOPTIONS) -o $@ \
		$(PLIBOBJS) \
		$(TOBJS) \
		$(PAROBJS) $(POBJS) \
		$(LIBS)

clean-repository:
	@if [ -d ptrepository ]; then $(RM) -r ptrepository; fi

clean-tests:
	$(RM) tst teststr.o testlst.o testbv.o testst.o \
		testeq.o testtw.o testtypes.o tst

clean: clean-repository clean-tests
	$(RM) $(PLIBOBJS) \
		$(TOBJS) \
		$(PAROBJS) $(POBJS) \
		core a.out 

realclean: clean
	$(RM) vbs_yacc.h vbs_yacc.c vbs_lex.c vbs

#
# Test targets
#

test-allv: test-arith test-case test-comp test-evnt test-func test-task \
	test-mod test-ifstmt test-nested test-range test-others

test-arith: vbs
	@./vbs ../data/add.v
	@./vbs ../data/dividev1.v
	@./vbs ../data/dividev2.v
	@./vbs ../data/logand.v
	@./vbs ../data/logor.v
	@./vbs ../data/multv1.v
	@./vbs ../data/multv3.v
	@./vbs ../data/not.v
	@./vbs ../data/shift.v
	@./vbs ../data/sub.v

test-case: vbs
	@./vbs ../data/casestmt0.v
	@./vbs ../data/casestmt1.v
	@./vbs ../data/casestmt2.v

test-comp: vbs
	@./vbs ../data/andand.v
	@./vbs ../data/eqeq.v
	@./vbs ../data/invert.v
	@./vbs ../data/oror.v
	@./vbs ../data/relational.v

test-evnt: vbs
	@./vbs ../data/alwaysdelay.v
	@./vbs ../data/atident.v
	@./vbs ../data/delay.v
	@./vbs ../data/edgetrig.v
	@./vbs ../data/evntlst.v

test-func: vbs
	@./vbs ../data/function.v
	@./vbs ../data/function1.v
	@./vbs ../data/function2.v
	@./vbs ../data/function3.v
	@./vbs ../data/function4.v
	@./vbs ../data/function5.v

test-task: vbs
	@./vbs ../data/task.v
	@./vbs ../data/task1.v
	@./vbs ../data/task2.v

test-mod: vbs
	@./vbs ../data/module.v
	@./vbs ../data/module1.v
	@./vbs ../data/multv3a.v ../data/multv3a1.v

test-ifstmt: vbs
	@./vbs ../data/else.v
	@./vbs ../data/ifelseif.v
	@./vbs ../data/ifstmt.v

test-nested: vbs
	@./vbs ../data/nested.v
	@./vbs ../data/nested2.v
	@./vbs ../data/nested3.v

test-range: vbs
	@./vbs ../data/range.v
	@./vbs ../data/range2.v

test-others: vbs
	@./vbs ../data/bases.v
	@./vbs ../data/comment.v
	@./vbs ../data/comment2.v
	@./vbs ../data/counter.v
	@./vbs ../data/fmt.v
	@./vbs ../data/for.v

test-all: str list bv st evnt tw types

TYPESOBJS = $(PLIBOBJS) \
		$(TOBJS) \
		testtypes.o
testtypes.o: ../tests/testtypes.o
types: $(TYPESOBJS)
	@echo "Testing Parser Types classes"
	$(C++) $(LDOPTIONS) -o tst $(TYPESOBJS)
	if [ -x tst ]; then ./tst; fi

TWOBJS = String.o testtw.o
testtw.o: ../tests/testtw.o
tw: $(TWOBJS)
	@echo "Testing Time Wheel class"
	$(C++) $(LDOPTIONS) -o tst $(TWOBJS)
	if [ -x tst ]; then ./tst; fi

EQOBJS = String.o testeq.o
testeq.o: ../tests/testeq.o
evnt: $(EQOBJS)
	@echo "Testing Event Queue class"
	$(C++) $(LDOPTIONS) -o tst $(EQOBJS)
	if [ -x tst ]; then ./tst; fi

STOBJS = String.o Bitvector.o Error.o Symtab.o testst.o
testst.o: ../tests/testst.o
st: $(STOBJS)
	@echo "Testing Symbol Table class"
	$(C++) $(LDOPTIONS) -o tst $(STOBJS)
	if [ -x tst ]; then ./tst; fi

BVOBJS = String.o Bitvector.o testbv.o
testbv.o: ../tests/testbv.o
bv: $(BVOBJS)
	@echo "Testing BitVector class"
	$(C++) $(LDOPTIONS) -o tst $(BVOBJS)
	if [ -x tst ]; then ./tst; fi

LSTOBJS = String.o testlst.o
testlst.o: ../tests/testlst.o
list: $(LSTOBJS)
	@echo "Testing List class"
	$(C++) $(LDOPTIONS) -o tst $(LSTOBJS)
	if [ -x tst ]; then ./tst; fi

STROBJS = String.o teststr.o
teststr.o: ../tests/teststr.o
str: $(STROBJS)
	@echo "Testing String class"
	$(C++) $(LDOPTIONS) -o tst $(STROBJS)
	if [ -x tst ]; then ./tst; fi

## Dependencies (Don't Delete)
#
# Edit only after careful thought.  All dependencies are required.
# NOTE:  Always include object header files even if this header file
# is already included in another header file.

glo_h = intrface.h

# Basic classes
Bool_h = Bool.h
String_h = String.h
List_h = List.h
Error_h = Bool.h String.h Error.h
Bitvector_h = String.h Bitvector.h
Symtab_h = Bool.h String.h List.h Event.h Base.h Symtab.h
Base_h = Bool.h String.h List.h Bitvector.h Base.h
PExpr_h = Bool.h String.h Symtab.h Base.h PExpr.h
PTypes_h = Bool.h List.h Event.h Base.h PExpr.h PTypes.h
Systask_h = Bool.h String.h List.h Symtab.h Base.h PExpr.h Systask.h

# Template classes
Event_h = Bool.h List.h Event.h
TWheel_h = List.h TWheel.h

String.o: $(String_h)
Bitvector.o: $(Bool_h) $(String_h) $(Bitvecotr_h)
Symtab.o: $(Bool_h) $(String_h) $(List_h) $(Event_h) $(Error_h) \
	$(Base_h) $(Symtab_h)
Error.o: $(String_h) $(Error_h)

Display.o: $(Base_h) $(PExpr_h) $(PTypes_h)
Eval.o: $(Bool_h) $(Bitvector_h) $(Error_h) $(Symtab_h) \
	$(TWheel_h) $(Base_h) $(PExpr_h)
Setup.o: intrface.h $(glo_h) $(List_h) $(Error_h) $(Event_h) $(Symtab_h) \
	$(TWheel_h) $(Base_h) $(PExpr_h) $(PTypes_h) $(Systask_h)
Trigger.o: $(List_h) $(Error_h) $(Event_h) $(Symtab_h) $(TWheel_h) \
	$(Base_h) $(Systask_h) $(PExpr_h) $(PTypes_h)
Systask.o: $(glo_h) $(Bool_h) $(String_h) $(List_h) $(Error_h) $(Symtab_h) \
	$(TWheel_h) $(Base_h) $(Systask_h)
PTypes.o: intrface.h $(String_h) $(List_h) $(Base_h) $(PExpr_h) \
	$(PTypes_h) $(Systask_h)

Main.o: $(glo_h) $(Error_h)
intrface.o: intrface.h $(glo_h)
vbs_lex.o: $(glo_h)
vbs_yacc.o: $(glo_h)

# Test targets
teststr.o: $(String_h)
testlst.o: $(String_h) $(List_h)
testbv.o: $(Bitvector_h)
testst.o: $(String_h) $(Symtab_h)
testeq.o: $(String_h) $(Event_h)
testtw.o: $(String_h) $(TWheel_h)
testtypes.o: $(List_h) $(Base_h) $(PExpr_h) $(PTypes_h)
