Makefiles for Xilinx FPGA / CPLD Projects

Date:
03/25/2007
Categories:
appnote,
obsolete
Authors:
Organization:

Description

Makefiles for Xilinx FPGA/CPLD Projects



MAKEFILES FOR XILINX FPGA/CPLD PROJECTS

These makefiles were created so that you can develop a Xilinx project using the WebPACK/ISE GUI, but then use a makefile to automate the build process once the development work is done.

Several makefiles will be described:

Xilinx Rules Makefile

This makefile contains the rules that move the HDL files through the synthesizer, place & route and bitstream generation processes to produce the final bitstream file.

Project Makefile

This makefile resides in the WebPACK/ISE project directory and uses the Xilinx rules makefile to create the bitstream for the project.

Directory Makefile

This makefile creates bitstreams for a number WebPACK/ISE projects by calling the project makefile in each of the project subdirectories.

Xilinx Rules Makefile

The xilinx_rules.mk file contains the variable definitions and rules that perform the bulk of the operations for creating an FPGA or CPLD configuration bitstream. The rules encode the process flow for an FPGA:

     (.vhd,.ver)-->[XST]-->(.ngc,.ucf)-->[NGDBUILD]-->(.ngd,.pcf)-->[MAP]-->(.ncd,.pcf)--> ...
                ... -->[PAR]-->(.ncd)-->[BITGEN]-->(.bit)

and the process flow for a CPLD:

     (.vhd,.ver)-->[XST]-->(.ngc,.ucf)-->[NGDBUILD]-->(.ngd)-->[CPLDFIT]-->(.vm6)--> ...
                ... -->[HPREP6]-->(.jed)-->[IMPACT]-->(.svf)

xilinx_rules.mk is not used directly. It is included in the main makefile of a WebPACK/ISE project. xilinx_rules.mk is usually placed in the /usr/local/include directory so that make can find it when needed.

The xilinx_rules.mk file is shown below. xilinx_rules.mk uses several Perl script files (get_option_values.pl, set_option_values.pl, and get_project_files.pl) and these are also shown.

xilinx_rules.mk

           #-------------------------------------------------------------------
            # Company : XESS Corp.
            # Engineer : Dave Vanden Bout
            # Creation Date : 05/16/2006
            # Copyright : 2005-2006, XESS Corp
            # Tool Versions : make 3.79.1, perl 5.8.8, WebPACK 8.1.03i
            #
            # Description:
            # This makefile contains the rules that move the HDL files through
            # the Xilinx WebPACK/ISE synthesizer, place & route and bitstream 
            # generation processes to produce the final bitstream file.
            #
            # Revision:
            # 1.0.3
            #
            # Additional Comments:
            # This file is normally included in another makefile using the
            # `include' directive. Usually this file is placed in the 
            # /usr/local/include directory so make can find it automatically.
            #
            # The makefile targets are:
            # config: Creates bit/svf file for FPGA/CPLD.
            # svf: Directly creates bit file for FPGA.
            # bit: Directly creates svf file for CPLD.
            # mcs: Creates Intel MCS file from bit file.
            # exo: Creates Motorola EXO file from bit file.
            # timing: Creates timing report for FPGA (not CPLD).
            # clean: Cleans temporary files created during build process.
            # distclean: Clean and also remove timing report.
            # maintainer-clean: Distclean and also remove bit/svf files.
            # nice: beautify the HDL source code
            #
            # 1.0.3:
            # Modified to support ISE9 project directory structure.
            # 1.0.2:
            # Added more file types for removal during cleaning.
            # 1.0.1:
            # Added 'nice' target.
            # 1.0.0
            # Initial revision.
            #-------------------------------------------------------------------
    
           #
            # Paths to utilities.
            #
    
           RM                 := erase /s /q
            RMDIR              := rmdir /s /q
            MKDIR              := mkdir
            ECHO               := echo
            EMACS              := /bin/emacs-21.3/bin/emacs
           UTILITY_DIR        := C:/BIN/
            SET_OPTION_VALUES  := perl $(UTILITY_DIR)set_option_values.pl
            GET_OPTION_VALUES  := perl $(UTILITY_DIR)get_option_values.pl
            GET_PROJECT_FILES  := perl $(UTILITY_DIR)get_project_files.pl
           #
            # Flags and option values that control the behavior of the Xilinx tools.
            # You can override these values in the makefile that includes this one.
            # Otherwise, the default values will be set as shown below.
            #
    
           DIR_SPACES  := $(subst /, ,$(CURDIR))
            DIR_NAME    := $(word $(words $(DIR_SPACES)), $(DIR_SPACES))
            DESIGN_NAME ?= $(DIR_NAME)
            TOP_NAME    ?= $(DESIGN_NAME)
           PART_TYPE        ?=            $(shell $(GET_OPTION_VALUES) $(DESIGN_NAME).npl DEVICE)
            PART_SPEED_GRADE ?= $(subst -,,$(shell $(GET_OPTION_VALUES) $(DESIGN_NAME).npl DEVSPEED))
            PART_PACKAGE     ?=            $(shell $(GET_OPTION_VALUES) $(DESIGN_NAME).npl DEVPKG)
            PART             ?= $(PART_TYPE)-$(PART_SPEED_GRADE)-$(PART_PACKAGE)
           IS_CPLD = $(findstring xc95,$(PART))
           INTSTYLE         ?= -intstyle silent      # call Xilinx tools in silent mode
            XST_FLAGS        ?= $(INTSTYLE)           # most synthesis flags are specified in the .xst file
            UCF_FILE         ?= $(DESIGN_NAME).ucf    # constraint/pin-assignment file
            NGDBUILD_FLAGS   ?= $(INTSTYLE) -dd _ngo  # ngdbuild flags
            NGDBUILD_FLAGS += $(if $(UCF_FILE),-uc,) $(UCF_FILE)         # append the UCF file option if it is specified
           MAP_FLAGS        ?= $(INTSTYLE) -cm area -pr b -k 4 -c 100 -tx off
            PAR_FLAGS        ?= $(INTSTYLE) -w -ol std -t 1
            TRCE_FLAGS       ?= $(INTSTYLE) -e 3 -l 3
            BITGEN_FLAGS     ?= $(INTSTYLE)           # most bitgen flags are specified in the .ut file
            PROMGEN_FLAGS    ?= -u 0                  # flags that control the MCS/EXO file generation
           CPLDFIT_FLAGS    ?= -ofmt vhdl -optimize speed -htmlrpt -loc on -slew fast -init low -inputs 54 -pterms 25 -unused float -power std -terminate keeper
            SIGNATURE        ?= $(DESIGN_NAME)        # JTAG-accessible signature stored in the CPLD
            HPREP6_FLAGS     ?= -s IEEE1149           # hprep flags
            HPREP6_FLAGS     += $(if $(SIGNATURE),-n,) $(SIGNATURE)  # append signature if it is specified
           ISE_VERSION ?= $(shell grep -m 1 -o -P "ISE\s*[0-9]+" %XILINX%/readme.txt | grep -m 1 -P -o "[0-9]+")
            ifeq ($(ISE_VERSION),6)
                    PROJNAV_DIR ?= __projnav
            else
            ifeq ($(ISE_VERSION),7)
                    PROJNAV_DIR ?= __projnav
            else
                    PROJNAV_DIR ?= .
            endif
            endif
           ifneq (,$(IS_CPLD))
                    XST_CPLD_OPTIONS_FILE ?= $(PROJNAV_DIR)/$(DESIGN_NAME).xst
                    IMPACT_OPTIONS_FILE   ?= _impact.cmd
                    XST_OPTIONS_FILE       = $(XST_CPLD_OPTIONS_FILE)
            else
                    XST_FPGA_OPTIONS_FILE ?= $(PROJNAV_DIR)/$(DESIGN_NAME).xst
                    BITGEN_OPTIONS_FILE   ?= $(DESIGN_NAME).ut
                    XST_OPTIONS_FILE       = $(XST_FPGA_OPTIONS_FILE)
            endif
           #
            # The following rules describe how to compile the design to an FPGA/CPLD.
            #
    
           ifeq ($(origin HDL_FILES),undefined)
              HDL_FILES       ?= $(shell $(GET_PROJECT_FILES) $(DESIGN_NAME).prj)
            endif
           %.nice: %.vhd
                    $(EMACS) -batch $< -f vhdl-beautify-buffer -f save-buffer
                    $(RM) $<~
           %.ngc: $(HDL_FILES) $(XST_OPTIONS_FILE)
                    -$(MKDIR) $(PROJNAV_DIR)
                    $(SET_OPTION_VALUES) $(XST_OPTIONS_FILE) 
                            "set -tmpdir $(PROJNAV_DIR)" 
                            "-lso $(DESIGN_NAME).lso" 
                            "-ifn $(DESIGN_NAME).prj" 
                            "-ofn $(DESIGN_NAME)" 
                            "-p $(PART)" 
                            "-top $(TOP_NAME)" 
                                    > $(PROJNAV_DIR)/tmp.xst
                    xst $(XST_FLAGS) -ifn $(PROJNAV_DIR)/tmp.xst -ofn $*.syr
           %.ngd: %.ngc %.ucf
                    ngdbuild $(NGDBUILD_FLAGS) -p $(PART) $*.ngc $*.ngd
           %_map.ncd %.pcf: %.ngd
                    map $(MAP_FLAGS) -p $(PART) -o $*_map.ncd $*.ngd $*.pcf
           %.ncd: %_map.ncd %.pcf
                    par $(PAR_FLAGS) $*_map.ncd $*.ncd $*.pcf
           %.bit: %.ncd $(BITGEN_OPTIONS_FILE)
                    bitgen $(BITGEN_FLAGS) -f $(BITGEN_OPTIONS_FILE) $*.ncd
           %.mcs: %.bit
                    promgen $(PROMGEN_FLAGS) $*.bit -p mcs
           %.exo: %.bit
                    promgen $(PROMGEN_FLAGS) $*.bit -p exo
           %.vm6: %.ngd
                    cpldfit $(CPLDFIT_FLAGS) -p $(PART) $*.ngd
           %.jed: %.vm6
                    hprep6 $(HPREP6_FLAGS) -i $*.vm6
           %.svf: %.jed $(IMPACT_OPTIONS_FILE)
                    $(SET_OPTION_VALUES) $(IMPACT_OPTIONS_FILE) 
                            "setCable -port svf -file \"$*.svf\"" 
                            "addDevice -position 1 -file \"$*.jed\"" 
                                    > impactcmd.txt
                    $(ECHO) "quit" >> impactcmd.txt
                    impact -batch impactcmd.txt
           # Use .config suffix to trigger creation of a bit/svf file
            # depending upon whether an FPGA/CPLD is the target device.
            %.config: $(if $(IS_CPLD),%.svf,%.bit) ;
    
           %.twr: %.ncd %.pcf
                    trce $(TRCE_FLAGS) $*.ncd -o $*.twr $*.pcf
           # Use .timing suffix to trigger timing report creation.
            %.timing: %.twr ;
    
           .PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.vm6 %.jed
           %.clean:
                    -$(RM) $*.stx $*.ucf.untf $*.mrp $*.nc1 $*.ngm $*.prm $*.lfp
                    -$(RM) $*.placed_ncd_tracker $*.routed_ncd_tracker
                    -$(RM) $*.pad_txt $*.twx *.log *.vhd~ $*.dhp $*.jhd $*.cel
                    -$(RM) $*.ngr $*.ngc $*.ngd $*.syr $*.bld $*.pcf
                    -$(RM) $*_map.mrp $*_map.ncd $*_map.ngm $*.ncd $*.pad
                    -$(RM) $*.par $*.xpi $*_pad.csv $*_pad.txt $*.drc $*.bgn
                    -$(RM) $*.xml $*_build.xml $*.rpt $*.gyd $*.mfd $*.pnx
                    -$(RM) $*.vm6 $*.jed $*.err $*.ER result.txt tmperr.err *.bak *.vhd~
                    -$(RM) impactcmd.txt
                    -$(RMDIR) xst _ngo $*_html __projnav
           %.distclean: %.clean
                    -$(RM) $*.twr
           %.maintainer-clean: %.distclean
                    -$(RM) $*.bit $*.svf $*.exo $*.mcs
           #
            # Default targets for FPGA/CPLD compilations.
            #
    
           config          : $(DESIGN_NAME).config
            bit             : $(DESIGN_NAME).bit
            svf             : $(DESIGN_NAME).svf
            mcs             : $(DESIGN_NAME).mcs
            exo             : $(DESIGN_NAME).exo
            timing          : $(DESIGN_NAME).timing
            clean           : $(DESIGN_NAME).clean
            distclean       : $(DESIGN_NAME).distclean
            maintainer-clean: $(DESIGN_NAME).maintainer-clean
            nice            : $(subst .vhd,.nice,$(HDL_FILES))

get_option_values.pl Perl Script

     #
      # Get selected option value from an options file of a Xilinx WebPACK/ISE project
      #
      $option_file = shift @ARGV;         # first argument is the option file name
      open(FILE,$option_file) || die $!;
      $option_name = $ARGV[0];            # second argument is the option name to search for
    
     # read lines from option file looking for the given option name
      while(<FILE>) {
        chop;
        /^$option_name\s+/ && print $';   # print out the value for the given option
      }
    

set_option_values.pl Perl Script

     #
      # Set option values in an options file of a Xilinx WebPACK/ISE project
      #
      $option_file = shift @ARGV;    # first argument is the option file name
      open(FILE,$option_file) || die $!;
      @options = <FILE>;             # read in all the options
      $options = join("",@options);  # join all options into one big string
    
     # remaining arguments are new option strings that will replace existing options
      foreach (@ARGV) {
        @option_fields = split(/\s+/,$_);  # split new option string into fields
        $option_value = pop @option_fields; # new option value is last field in the string
        $option_name = join(" ",@option_fields);  # option name is all the preceding fields
        $options =~ s/$option_name\s+.*/$option_name $option_value/gi;  # replace existing value with new value
      }
    
     print $options;  # print the updated option file
    

get_project_files.pl Perl Script

     #
      # Output a list of the files found in the .prj file of a Xilinx WebPACK/ISE project
      #
      open(PRJFILE,$ARGV[0]) || die $!;
      while(<PRJFILE>) {
        @fields = split(/\s+/,$_);
        $f = pop(@fields);  # file name is last field of each line
        $f =~ s/\"//g;  # remove any quotations around file names
        print " " . $f;
      }
    

Project Makefile

The contents of the makefile file in the WebPACK/ISE project directory can be as simple as:

           include xilinx_rules.mk

You can also override variables in the xilinx_rules.mk file to change the behavior of the build process. For example, to target a different FPGA, you might use:

           PART = xc2s100-5-tq144
           include xilinx_rules.mk

Or if you don't want to use a constraint file, just give it an empty value like so:

           PART = xc2s100-5-tq144
            UCF_FILE =
           include xilinx_rules.mk

To build the FPGA or CPLD configuration bitstream, just type the command:

           make

or:

           make config

To generate the timing report for an FPGA design, use the command:

           make timing

To clean any temporary files created during the build process, use the command:

           make clean

You can also remove more of the intermediate files with the command:

           make distclean

And you can remove all of the above plus the configuration bitstream file with:

           make maintainer-clean

Directory Makefile

If you have a directory that contains several subdirectories, each of which contains a WebPACK/ISE project, then the following makefile will build the bitstream for each project. This makefile resides in the top-level directory and it activates the makefiles in each project subdirectory.

           projects := project1 project2 project3
           config          : $(projects:=.config)
            timing          : $(projects:=.timing)
            clean           : $(projects:=.clean)
            distclean       : $(projects:=.distclean)
            maintainer-clean: $(projects:=.maintainer-clean)
           $(projects:=.config):
                    $(MAKE) -C $(subst .config,,$@) $@
           $(projects:=.timing):
                    $(MAKE) -C $(subst .timing,,$@) $@
           # The next three rules cause make to enter each project directory
            # and clean the project to the selected level of cleanliness.
    
           $(projects:=.clean):
                    $(MAKE) -C $(subst .clean,,$@) $@
           $(projects:=.distclean):
                    $(MAKE) -C $(subst .distclean,,$@) $@
           $(projects:=.maintainer-clean):
                    $(MAKE) -C $(subst .maintainer-clean,,$@) $@

The following makefile is similar to the previous one but it also allows you to retarget the projects at a different type of FPGA or CPLD and use new options for the tools.

           FPGA_PART     := xc3s1000-4-ft256
            fpga_projects := project1 project2
           CPLD_PART     := xc9572xl-10-vq64
            cpld_projects := project3 project4
           export XST_CPLD_OPTIONS_FILE ?= $(CURDIR)/xst_cpld_options.xst
            export XST_FPGA_OPTIONS_FILE ?= $(CURDIR)/xst_fpga_options.xst
            export BITGEN_OPTIONS_FILE   ?= $(CURDIR)/bitgen_options.ut
            export IMPACT_OPTIONS_FILE   ?= $(CURDIR)/impact_options.txt
           config          : $(fpga_projects:=.config)           $(cpld_projects:=.config)
            timing          : $(fpga_projects:=.timing)
            clean           : $(fpga_projects:=.clean)            $(cpld_projects:=.clean)
            distclean       : $(fpga_projects:=.distclean)        $(cpld_projects:=.distclean)
            maintainer-clean: $(fpga_projects:=.maintainer-clean) $(cpld_projects:=.maintainer-clean)
           $(fpga_projects:=.config):
                    $(MAKE) -C $(subst .config,,$@) PART=$(FPGA_PART) $@
           $(cpld_projects:=.config):
                    $(MAKE) -C $(subst .config,,$@) PART=$(CPLD_PART) $@
           $(fpga_projects:=.timing):
                    $(MAKE) -C $(subst .timing,,$@) PART=$(FPGA_PART) $@
           # The next three rules cause make to enter each FPGA and CPLD project directory
            # and clean the project to the selected level of cleanliness.
    
           $(fpga_projects:=.clean) $(cpld_projects:=.clean):
                    $(MAKE) -C $(subst .clean,,$@) $@
           $(fpga_projects:=.distclean) $(cpld_projects:=.distclean):
                    $(MAKE) -C $(subst .distclean,,$@) $@
           $(fpga_projects:=.maintainer-clean) $(cpld_projects:=.maintainer-clean):
                    $(MAKE) -C $(subst .maintainer-clean,,$@) $@

To build the FPGA and CPLD configuration bitstreams for all the projects, just type the command:

           make

or:

           make config

To generate the timing reports for all the FPGA designs, use the command:

           make timing

To clean all the project subdirectories, use one of the commands:

           make clean
            make distclean
            make maintainer-clean

Environment

These makefiles were developed and tested using the following versions of software:

           GNU make          : 3.79.1 (version 3.77.1 does not work)
            Active State perl : 5.8.4, 5.8.8
            Xilinx WebPACK    : 6.3.03i, 8.1.03i

Source Files

You can download an example of a Xilinx project directory that uses these makefiles and perl scripts from /projects/XILINX_MAKEFILES.tar.gz .

Author

Dave Vanden Bout, X Engineering Software Systems Corp.

Send bug reports to bugs@xess.com.

Copyright and License

© 2005-2006 by X Engineering Software Systems Corporation.

These applications can be freely distributed and modified as long as you do not remove the attributions to the author or his employer.

History

03/26/2007 - Modified xilinx_rules.mk to support ISE9 project directory structure.

05/16/2006 - Added 'nice' feature to prettify VHDL source files.

05/16/2006 - Fixed get_project_files.pl to handle quotes in Xilinx ISE 8.1i .prj file.

05/05/2005 - Initial release.