next up previous contents
Next: C.2 vhdl-vl.h Up: C Tutorial: Using VHDL for FPGAs Previous: C Tutorial: Using VHDL for FPGAs

C.1 VHDL to FPGA Makefile

 

# -------------------------------------------------------------------
# Makefile for VHDL -> FPGA projects.
# Works with Synopsys 3.2b, Xilinx 5.1.0, Powerview 5.3
# Scott Harrington, Spring 1995
#
# MAKE is awesome.  You can learn just about everything you need to know
# about synthesizing FPGA projects from VHDL from this Makefile.
#
# What you need to provide:
#   .v files
#   .dcsh file
#   .cst file
# If you create an empty WORK directory, Synopsys will put many of its
# messy files there.
#
# The VHDL source code modules must be listed in the MODULES variable
# below, and the project variable P set to the project name.
# The project's .dcsh script is run through the Synopsys
# Design Compiler to synthesize the VHDL into a .sedif file for the
# Xilinx tools.  The .cst file gives Xilinx APR/PPR special pad
# placement information, if desired.
#
# Note that .vhd files are a bit schizophrenic here.  Depending on which
# target you choose you may end up with .vhd files in Synopsys format
# and maybe in Viewlogic format.  The differences
# are most easily reconciled by using C preprocessor directives.
# The bottom line is, be sure to only edit the .v files because the
# .vhd files are potentially clobbered every time you run make.
# To keep you from accidentally editing the .vhd files this makefile
# removes write permissions.  I suggest you use revision control for
# your .v files.
#
# USAGE
# make : same as make all
# make -n ... : show commands that would be run but don't run them
# make all : synthesize and make simulation file and bitfile
# make bitfile : synthesize and make FPGA bitfile
# make fullsim : make post-routing simulation files
# make quicksim : use Viewlogic VHDL analyzer for logic-level simulation only
# make .viewlogic_vhdl : just preprocess .v files into Viewlogic .vhd files
# make .synopsys_vhdl : just preprocess .v files into Synopsys .vhd files
# make tarfile : make a tar archive of your source files for safekeeping
# make hardcopy : print out all sources that have changed since last printing
#
# Note that fullsim and quicksim both result in a .vsm file.
#
# If you want to start a long make and log out, try
# nohup csh -c make ... >& make.log &
# and check the make.log file later.
#
# You may notice I don't have a cleanup target.  These tools produce far
# too many intermediate files to try to delete.  One way to clean up is:
# (1) make sure all your source files are represented in SOURCES,
# (2) make tarfile
# (3) delete everything but the tarfile (or move it to a whole new dir)
# (4) extract the tarfile in the clean directory
#
# I tend to use make's macro pattern-replacement feature pretty often.
# If you have a variable, say V_FILES=top.v proc.v sub.v
# and you use the assignment VHD_FILES=$(V_FILES:%.v=%.vhd)
# then the resulting value is VHD_FILES=top.vhd proc.vhd sub.vhd
# For extension replacement you can shorten it to $(V_FILES:.v=.vhd).
# Make defines some special variables: $@ is the current target, $? is the
# list of dependencies that were out of date.  See the make man page for
# more details.

# ------------------ VARIABLE SETTINGS SECTION ----------------------

# The top level project name must either be specified in the P variable
# below or on the make command line as in "make P=top" to use top.dcsh and
# create top.xnf, top.lca, top_delay.vsm, etc.  In any case, P should
# match the design name used in the .dcsh script.

P = boris
MODULES = boris natasha pointers

# Specify the desired Xilinx part type here.  Valid parts include
# 3042pc84-50, 3030pc84-50, 4005pc84-80, etc.  This should agree with
# whatever parttype you specify in your .dcsh scripts.

PART=3042PC84-50

V_FILES = $(MODULES:%=%.v)
VHD_FILES = $(V_FILES:.v=.vhd)
VLI_FILES = $(V_FILES:.v=.vli)
DCSH_FILES = $P.dcsh
SOURCES = $(V_FILES) $(DCSH_FILES) vhdl_syn.h vhdl_vl.h $P.cst Makefile

# Which files to print and what command to print with
# enscript -2Grt4 gives 2-up and 4-space-tab
# setenv PRINTER hp is the best way to tell enscript which printer to use

PRINTFILES = $(SOURCES)
LPR = enscript -2Grt4

# I like to use the C preprocessor to change VLBIT types to STD_LOGIC
# and to include other other compiler-specific VHDL code using #include,
# #ifdef, or #define in my .v files.  I prepend either vhdl_syn.h or
# vhdl_vl.h to every .v file before doing anything with it.
# On Duke's sun4 machines use /usr/lib/cpp, on solaris use
# /usr/ccs/lib/cpp.  The -P supresses line number information.
# I have tried gcc -E but it does C language syntax checking and
# therefore barfs on VHDL.

CPP:sh = if [ "$HOST_ARCH" = "sun4" ]; \
                then echo '/usr/lib/cpp -P'; \
                else echo '/usr/ccs/lib/cpp -P'; \
                fi

.SUFFIXES: .v .vhd .vli
.PHONEY: all bitfile fullsim quicksim tarfile hardcopy powerview_setup

# -------------------- MAIN TARGET DEFINITIONS ----------------------

all: fullsim bitfile

bitfile: .synopsys_vhdl $P.bit

fullsim: .synopsys_vhdl xsimmake.out

quicksim: .viewlogic_vhdl powerview_setup $(VLI_FILES)

# ----------------- ARCHIVING AND PRINTING FILES --------------------

tarfile: $P.tar

$P.tar: $(SOURCES)
        @echo "Creating tar file of your source files."
        @echo "Type tar xvf $P.tar to extract."
        tar cvf $P.tar $(SOURCES)

hardcopy: .last_print

.last_print: $(PRINTFILES)
        $(LPR) $?
        touch .last_print

# ------------------- ENVIRONMENT SETUP CHECKS ----------------------

powerview_setup:
        @if [ "$$WDIR" = "" ]; then \
                echo "*** The WDIR variable was not found."; \
                echo "*** This must be set for command-line Powerview tools."; \
                false ; \
        fi

# ---------------------- VHDL PREPROCESSING -------------------------

# If the file .synopsys_vhdl exists, then the .vhd files were most
# recently processed with the synopsys header file.  If the file
# does not exist or the common header file has changed, recursively
# rebuild all the .vhd files.

.synopsys_vhdl: vhdl_syn.h
        @echo "*** Preprocessing VHDL files with Synopsys header file"
        rm -f .viewlogic_vhdl $(VHD_FILES)
        touch .synopsys_vhdl
        cp vhdl_syn.h .vhdl.h
        $(MAKE) $(VHD_FILES) P=$P

# If the file .viewlogic_vhdl exists, then the .vhd files were most
# recently processed with the viewlogic header file.

.viewlogic_vhdl: vhdl_vl.h
        @echo "*** Preprocessing VHDL files with Viewlogic header file"
        rm -f .synopsys_vhdl $(VHD_FILES)
        touch .viewlogic_vhdl
        cp vhdl_vl.h .vhdl.h
        $(MAKE) $(VHD_FILES) P=$P

# If the user has not explicitly defined separate vhdl_syn.h and
# vhdl_vl.h header files, create empty ones.

vhdl_syn.h:
        touch vhdl_syn.h

vhdl_vl.h:
        touch vhdl_vl.h

# The following two rules use a feature of make known as a dynamic dependency.
# The target macro actually contains multiple targets.  For each target,
# the macro $$@ used in the dependency list equals that target.  The
# colon/percent/equals stuff mutates the suffix of the $$@ target name
# into the suffix of the proper dependency.

$(VHD_FILES): $$(@:.vhd=.v)
        rm -f $@
        cat .vhdl.h $? | $(CPP) >$@
        chmod -w $@

$(VLI_FILES): $$(@:.vli=.vhd)
        vhdl $? -V
        @echo "$(@:.vli=.vsm) file now available for use with ViewSim."

# -------------------- SYNOPSYS VHDL COMPILER -----------------------

# We assume that you have created just one dc_shell script to compile
# all the VHDL sources and produce one sedif file of your whole
# hierarchy.  This is fine for small projects, but if you change one
# VHDL module, all the modules get recompiled, which may take a while
# for big projects.  To avoid this, make several .dcsh files that each
# compile a single VHDL module and write it as a Synopsys .db file.
# Then have another .dcsh file read all the .db files, ungroup, set
# pads, replace_fpga, and write the sedif file.  Add a makefile rule
# below for each .dcsh file with appropriate .db and .vhd targets and
# dependencies.

$P.sedif: $P.dcsh $(VHD_FILES) .synopsys_vhdl
        dc_shell -f $P.dcsh

# Example of how you could set up smarter .dcsh scripts for a big project:
#
#project.sedif: top.dcsh project.db module1.db module2.db
#       dc_shell -f top.dcsh
#
#project.db: project.dcsh project.vhd
#       dc_shell -f project.dcsh
#
#module1.db: module1.dcsh module1.vhd
#       dc_shell -f module1.dcsh
#
#module2.db: module2.dcsh module2.vhd
#       dc_shell -f module2.dcsh

# --------------------- XILINX MAPPING TOOLS ------------------------

# You should run XDM in this directory at some point before using
# this makefile.  While not necessary, it will save the command-line
# switches for each tool that XMAKE invokes in the file xdm.pro.
# Of particular importance is the -C design.cst option for APR when
# using XC3000 designs.  For XC4000 designs which use PPR this is not
# an issue becasue PPR is smart and uses <design_name>.cst instead of
# a hardcoded cst file.
# Another important switch if MAKEBITS -R if you want a .rbt rawbits
# file.

$P.bit + $P.lca + $P.map: $P.sedif $P.cst
        xmake -P$(PART) $P

# If the user hasn't created a constraint file (pin assignments), make
# an empty one.

$P.cst:
        touch $P.cst

# --------------- TIMING SIMULATION USING VIEWSIM -------------------

$P.vsm + xsimmake.out: $P.lca
        xsimmake -p $(PART) -f VFT $P.lca


Scott E. Harrington
Sat Apr 29 18:56:25 EDT 1995