diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..388a02e --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +Makefile +config.log +config.status +configure + +obj +autom4te.cache + +debian/xilprg +debian/*.substvars +debian/files + +*-stamp diff --git a/Makefile.in b/Makefile.in new file mode 100755 index 0000000..3a7512c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,112 @@ +PROJ = xilprg + +prefix = @prefix@ +CONFDIR = @datadir@/misc/ + +######################################## +# +VER_MJ := $(shell gawk '/VERSION_MAJOR/ {print $$3}' src/xilprg.h) +VER_MN := $(shell gawk '/VERSION_MINOR/ {print $$3}' src/xilprg.h) + +######################################## +# +IS_CYGWIN=$(shell uname | grep -i cygwin > /dev/null 2>&1 && echo yes || echo no) + +######################################## +# Directories + +SRC_DIR = src +ifeq ($(IS_CYGWIN),yes) +OBJ_DIR = obj/cygwin +else +OBJ_DIR = obj/linux +endif + +ifeq ($(IS_CYGWIN),yes) +BIN_EXT = .exe +else +BIN_EXT = +endif + +XILPRG_DIR = xilprg-$(VER_MJ).$(VER_MN) + +######################################## +# Compiler options + +SRCS = \ + $(SRC_DIR)/xilprg.cpp \ + $(SRC_DIR)/cmdline.cpp \ + $(SRC_DIR)/cmds.cpp \ + $(SRC_DIR)/utils.cpp \ + $(SRC_DIR)/vartable.cpp \ + $(SRC_DIR)/strtable.cpp \ + $(SRC_DIR)/prgfile.cpp \ + $(SRC_DIR)/chip.cpp \ + $(SRC_DIR)/parport.cpp \ + $(SRC_DIR)/cable.cpp \ + $(SRC_DIR)/digilent.cpp \ + $(SRC_DIR)/xilinx.cpp + +OBJS = $(addsuffix .o, \ + $(addprefix $(OBJ_DIR)/, \ + $(basename $(notdir $(SRCS))))) +TARG = $(OBJ_DIR)/$(PROJ)$(BIN_EXT) + +CC = g++ +LD = g++ + +CPFLAGS = -O3 -Wall -DCONFDIR=\"$(CONFDIR)\" +LDFLAGS = + +ifeq ($(IS_CYGWIN),yes) +LIBS = -lioperm -lreadline +else +LIBS = -lusb -lreadline +endif + +######################################## +# Rules + +all: mkdirs $(TARG) + +clean: + -rm -rf obj + +$(TARG) : $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + +mkdirs: + -mkdir -p $(OBJ_DIR) + +srctar: + tar -cjvf $(XILPRG_DIR)-src.tar.bz2 -C .. \ + $(XILPRG_DIR)/src \ + $(XILPRG_DIR)/makefile \ + $(XILPRG_DIR)/xilprg.dsp \ + $(XILPRG_DIR)/xilprg.dsw \ + $(XILPRG_DIR)/xilprg.conf \ + $(XILPRG_DIR)/readme.txt \ + $(XILPRG_DIR)/license.txt + +winbintar: + tar -cjvf $(XILPRG_DIR)-win32.tar.bz2 \ + xilprg.conf readme.txt license.txt \ + -C obj/win32/Release xilprg.exe + +linuxbintar: + tar -cjvf $(XILPRG_DIR)-linux.tar.bz2 \ + xilprg.conf readme.txt license.txt \ + -C obj/linux xilprg + +tar: srctar winbintar linuxbintar + +install: obj/linux/xilprg xilprg.conf + @mkdir -p $(DESTDIR)@bindir@ $(DESTDIR)$(CONFDIR) $(DESTDIR)@mandir@/man1 + install -m 4550 -g lpadmin -o root obj/linux/xilprg $(DESTDIR)@bindir@ + install -m 444 xilprg.conf $(DESTDIR)$(CONFDIR) + install -m 444 xilprg.1 $(DESTDIR)@mandir@/man1 + +# + +$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp + $(CC) -c $(CPFLAGS) $< -o $@ diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..458c157 --- /dev/null +++ b/configure.ac @@ -0,0 +1,6 @@ +AC_INIT(xilprg, 0.5, jepler@unpy.net) + +AC_PROG_MAKE_SET + +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..cc2e31d --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +xilprg (0.5-1) unstable; urgency=low + + * Initial release + + -- Jeff Epler Mon, 01 Sep 2008 21:33:01 -0500 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +4 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..d2bcf16 --- /dev/null +++ b/debian/control @@ -0,0 +1,12 @@ +Source: xilprg +Section: misc +Priority: extra +Maintainer: Jeff Epler +Build-Depends: libusb-dev + +Package: xilprg +Architecture: any +Depends: ${shlibs:Depends} +Section: misc +Description: Programmer for certain Xilinx devices using a JTAG interface + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..e452b74 --- /dev/null +++ b/debian/rules @@ -0,0 +1,31 @@ +#!/usr/bin/make -f + +build: build-stamp +build-stamp: + ./configure --prefix=/usr + $(MAKE) + touch build-stamp + +install: install-stamp +install-stamp: build + dh_testroot + $(MAKE) install DESTDIR=debian/xilprg + touch install-stamp + +clean: + if [ -f Makefile ]; then $(MAKE) clean; fi + rm -f Makefile config.log config.status *-stamp obj + dh_clean + +binary: install-stamp + dh_testroot + dh_shlibdeps + dh_installchangelogs + dh_installdocs xilinx.mk readme.txt + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +.PHONY: + build install clean diff --git a/makefile b/makefile deleted file mode 100755 index c381c55..0000000 --- a/makefile +++ /dev/null @@ -1,103 +0,0 @@ -PROJ = xilprg - -######################################## -# -VER_MJ := $(shell gawk '/VERSION_MAJOR/ {print $$3}' src/xilprg.h) -VER_MN := $(shell gawk '/VERSION_MINOR/ {print $$3}' src/xilprg.h) - -######################################## -# -IS_CYGWIN=$(shell uname | grep -i cygwin > /dev/null 2>&1 && echo yes || echo no) - -######################################## -# Directories - -SRC_DIR = src -ifeq ($(IS_CYGWIN),yes) -OBJ_DIR = obj/cygwin -else -OBJ_DIR = obj/linux -endif - -ifeq ($(IS_CYGWIN),yes) -BIN_EXT = .exe -else -BIN_EXT = -endif - -XILPRG_DIR = xilprg-$(VER_MJ).$(VER_MN) - -######################################## -# Compiler options - -SRCS = \ - $(SRC_DIR)/xilprg.cpp \ - $(SRC_DIR)/cmdline.cpp \ - $(SRC_DIR)/cmds.cpp \ - $(SRC_DIR)/utils.cpp \ - $(SRC_DIR)/vartable.cpp \ - $(SRC_DIR)/strtable.cpp \ - $(SRC_DIR)/prgfile.cpp \ - $(SRC_DIR)/chip.cpp \ - $(SRC_DIR)/parport.cpp \ - $(SRC_DIR)/cable.cpp \ - $(SRC_DIR)/digilent.cpp \ - $(SRC_DIR)/xilinx.cpp - -OBJS = $(addsuffix .o, \ - $(addprefix $(OBJ_DIR)/, \ - $(basename $(notdir $(SRCS))))) -TARG = $(OBJ_DIR)/$(PROJ)$(BIN_EXT) - -CC = g++ -LD = g++ - -CPFLAGS = -O3 -Wall -LDFLAGS = - -ifeq ($(IS_CYGWIN),yes) -LIBS = -lioperm -lreadline -else -LIBS = -lusb -lreadline -lncurses -endif - -######################################## -# Rules - -all: mkdirs $(TARG) - -clean: - -rm -rf $(OBJ_DIR) - -$(TARG) : $(OBJS) - $(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ - -mkdirs: - -mkdir -p $(OBJ_DIR) - -srctar: - tar -cjvf $(XILPRG_DIR)-src.tar.bz2 -C .. \ - $(XILPRG_DIR)/src \ - $(XILPRG_DIR)/makefile \ - $(XILPRG_DIR)/xilprg.dsp \ - $(XILPRG_DIR)/xilprg.dsw \ - $(XILPRG_DIR)/xilprg.conf \ - $(XILPRG_DIR)/readme.txt \ - $(XILPRG_DIR)/license.txt - -winbintar: - tar -cjvf $(XILPRG_DIR)-win32.tar.bz2 \ - xilprg.conf readme.txt license.txt \ - -C obj/win32/Release xilprg.exe - -linuxbintar: - tar -cjvf $(XILPRG_DIR)-linux.tar.bz2 \ - xilprg.conf readme.txt license.txt \ - -C obj/linux xilprg - -tar: srctar winbintar linuxbintar - -# - -$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp - $(CC) -c $(CPFLAGS) $< -o $@ diff --git a/readme.txt b/readme.txt index e954163..0b787cf 100755 --- a/readme.txt +++ b/readme.txt @@ -31,6 +31,8 @@ Program device: E.g.: program 1 c:\untitled.mcs program 2 download.bit + Common error: forgetting to erase a flash device before programming it + Read device: read [-bin|-mcs] pos file @@ -50,6 +52,7 @@ Supported cables: Xilinx Parallel III Win32: giveio.sys must be installed to enable user-mode I/O access! + Linux: program must be run as root Digilent USB Win32: Digilent driver must be installed! diff --git a/src/xilprg.cpp b/src/xilprg.cpp index efc6b10..bb8e623 100755 --- a/src/xilprg.cpp +++ b/src/xilprg.cpp @@ -135,6 +135,10 @@ chip* select_device_in_chain(int index) return g.dev_chain[index].dev; } +#ifndef CONFDIR +#define CONFDIR +#endif + int load_config_file() { int rc = -1, line_index = 0; @@ -148,7 +152,7 @@ int load_config_file() int id, mask; int ir_length; - f = fopen("xilprg.conf", "rt"); + f = fopen(CONFDIR "xilprg.conf", "rt"); if (f == NULL) { msgf(STR_FAILED_TO_OPEN_CONFIG_FILE); @@ -256,10 +260,10 @@ cleanup: return rc; } -int main() +int main(int argc, char **argv) { char line[1024]; - int rc = -1; + int rc = EXIT_FAILURE; process_command_line("version"); printf("\n"); @@ -270,14 +274,34 @@ int main() if (load_config_file()) goto cleanup; - do - { - if (prompt_read_line("xilprg> ", line, sizeof(line)) < 0) - break; + if(argc != 1) { + std::string line; + for(int i=1; i ", line, sizeof(line)) < 0) + break; + } + while (process_command_line(line) != CMDLINE_EXIT_PROGRAM); + rc = EXIT_SUCCESS; } - while (process_command_line(line) != CMDLINE_EXIT_PROGRAM); - - rc = 0; cleanup: diff --git a/xilinx.mk b/xilinx.mk new file mode 100644 index 0000000..a29c4a0 --- /dev/null +++ b/xilinx.mk @@ -0,0 +1,186 @@ +ifeq ($(XILINX),) + $(error "source ~/xilinx/settings.sh" to set env vars) +endif + +vpath %.o work_sim + +help : + @echo "This Makefile is NOT part of the EMC2 build system." + @echo "It uses the zero-cost (non-free) Xilinx Webpack tools" + @echo "to convert VHDL source into bitfiles for the FPGA." + @echo "The completed bitfiles are distributed with EMC2, and" + @echo "do not need to be recreated except to fix bugs or to" + @echo "make a custom FPGA configuration." + @echo "It also uses the Free Software programs GHDL and GtkWave" + @echo "to allow simulation of the FPGA logic." + +%.o : %.vhd + @echo "analysis: making $@" + @if [ ! -d ./work_sim ] ; then mkdir work_sim; fi + @rm -f $@ + @ghdl -a --ieee=synopsys -fexplicit --workdir=./work_sim $< + +%.bin : %.v %.o + @echo "elaboration: making $@" + @if [ ! -d ./work_sim ] ; then mkdir work_sim; fi + @rm -f $@ + @ghdl -e --ieee=synopsys -fexplicit --workdir=./work_sim -o $@\ + `grep -m 1 "entity .* is" $< | \ + sed -e 's/^.*entity *//' -e 's/ *is.*$$//'` + +%.bin : %.vhd %.o + @echo "elaboration: making $@" + @if [ ! -d ./work_sim ] ; then mkdir work_sim; fi + @rm -f $@ + @ghdl -e --ieee=synopsys -fexplicit --workdir=./work_sim -o $@\ + `grep -m 1 "entity .* is" $< | \ + sed -e 's/^.*entity *//' -e 's/ *is.*$$//'` + +%.ghw : %.bin + @echo "simulating: running $<" + @if [ ! -d ./work_sim ] ; then mkdir work_sim; fi + @rm -f $@ + ./$< --wave=$@ + +%.wave : %.ghw + @gtkwave $< $*.sav &>/dev/null + +%.vprj : + @echo "making $@" + @rm -f $@ + @for i in $(SOURCES); do echo '`include "'$$i'"'; done > $@ + +%.prj : + @echo "making $@" + @rm -f $@ + @for i in $(SOURCES); do echo $$i; done > $@ + +%.vscr : %.v + @echo "making $@" + @if [ ! -d ./tmp_syn ] ; then mkdir tmp_syn; fi + @echo "set -tmpdir ./tmp_syn" >$@ + @if [ ! -d ./work_syn ] ; then mkdir work_syn; fi + @echo "set -xsthdpdir ./work_syn" >>$@ + @echo "run" >>$@ + @echo "-ifmt Verilog -ifn $*.vprj" >>$@ + @echo "-vlgpath ." >> $@ + @echo "-vlgincdir ." >> $@ + @echo "-top $*" >>$@ + @echo "-ofmt NGC -ofn $*.ngc" >>$@ + @echo "-p $(DEVICE)" >>$@ + + +%.scr : %.vhd + @echo "making $@" + @if [ ! -d ./tmp_syn ] ; then mkdir tmp_syn; fi + @echo "set -tmpdir ./tmp_syn" >$@ + @if [ ! -d ./work_syn ] ; then mkdir work_syn; fi + @echo "set -xsthdpdir ./work_syn" >>$@ + @echo "run" >>$@ + @echo "-ifmt VHDL -ifn $*.prj" >>$@ + @echo "-top `grep -m 1 "entity .* is" $< | sed -e 's/^.*entity *//' -e 's/ *is.*$$//'`" >>$@ + @echo "-ofmt NGC -ofn $*.ngc" >>$@ + @echo "-p $(DEVICE)" >>$@ + +%.ngc %.log.syn : %.vprj %.vscr + @echo "Synthesis: making $@" + @xst -ifn $*.vscr -ofn $*.log.syn + +%.ngc %.log.syn : %.prj %.scr + @echo "Synthesis: making $@" + @xst -ifn $*.scr -ofn $*.log.syn + +# The .usage target is dependent on the output format of the Xilinx tools. +# If they change the text of their report, it will be necessary to change the +# search text, and possibly to use different strings for various versions. +%.usage : %.log.syn + @echo "Usage report:" + @cat $< | awk '/Selected Device/,/TIMING REPORT/' | head -n-3 >$@ + @cat $@ + +%.ngd %.log.ngd : %.ngc + @echo "NGDbuild: making $@ from $< with constraints from $(CONSTRAINTS)" + @ngdbuild -uc $(CONSTRAINTS) $< $@ + @mv $*.bld $*.log.ngd + +# The extensions .nad and .nbd are actually .ncd files - the toolchain +# uses .ncd for unplaced, placed-but-not-routed, and placed-and-routed files +# The makefile uses distinct extensions to keep the dependencies straight, +# and to preserve the intermediate files. + +%.nad : %.ngd + @echo "Mapping: making $@ (unplaced) from $^" + @map $< + @mv $*.ncd $*.nad + @mv $*.mrp $*.log.map + +%.nbd : %.nad + @echo "Placing: making $@ (unrouted) from $^" + @cp $*.nad raw.ncd + @par -nopad -r raw.ncd -w placed.ncd $*.pcf + @rm raw.ncd + @mv placed.ncd $*.nbd + @rm placed.unroutes + @rm placed.par + @rm placed.xpi + +%.ncd : %.nbd + @rm -f $@ + @cp $*.nbd placed.ncd + @echo "Routing: making $@ (finished) from $^" + @par -p placed.ncd -w $*.ncd $*.pcf + @rm placed.ncd + +%.bit : %.ncd + @echo "Bitgen: making $@ from $^" + @bitgen -w $*.ncd $*.bit $*.pcf + +%.mcs: %.bit + echo "setmode -promfile" > $@.impact + echo "setsubmode -pffserial" >> $@.impact + echo "addPromDevice -p 1 -name xcf02s" >> $@.impact + echo "addDesign -version 0 -name 0" >> $@.impact + echo "addDeviceChain -index 0" >> $@.impact + echo "addDevice -position 1 -file $<" >> $@.impact + echo "generate -format mcs -fillvalue FF -output $@" >> $@.impact + echo quit >> $@.impact + impact -batch $@.impact + rm -f $@.impact + +%.svf: %.bit + echo "setmode -bs" > $@.impact + echo "setCable -port svf -file $@" >> $@.impact + echo "addDevice -position 1 -file $<" >> $@.impact + echo quit >> $@.impact + impact -batch $@.impact + rm -f $*.impact + +test: $(TARGET).bit + xilprg program 1 $(TARGET).bit + +flash: $(TARGET).mcs + xilprg erase 2 ";" program -mcs 2 $(TARGET).mcs + +# a .fpga file is a bitfile with config ram info added + +.PRECIOUS : %.v %.vhd %.rspec %.vprj %.prj %.vscr %.scr %.ngc %.ngd %.nad %.nbd %.ncd %.bit %.o %.bin %.ghw %.log.syn %.log.ngd %.log.map + +.PHONY : clean clean_all test flash + +# because placed and routed .fpga files might represent many hours +# of work, 'make clean' doesn't remove them or their precursers, +# it only removes incidental files that are generated along the way +# if you truly want to remove everything, use 'make clean_all' +# if you want to redo only a single FPGA file, touch the +# corresponding .spec file +clean : + @rm -f *.scr *.o *.bin + @rm -f *.pad *_pad.csv *_pad.txt *.par *.unroutes + @rm -f *.ghw *.log.syn *.log.ngd *.log.map *.bgn *.drc *.ngm *.usage + @rm -f *_usage.xml *~ + +clean_all : + @rm -f *.prj *.scr *.ngc *.ngd *.nad *.nbd *.ncd *.o *.bin *.bit + @rm -f *.pad *_pad.csv *_pad.txt *.par *.unroutes *.xpi *.rspec *.fpga + @rm -f *.ghw *.log.syn *.log.ngd *.log.map *.bgn *.drc *.ngm *.usage + @rm -f *.pcf *.t *_usage.xml *~ *.vprj *.vscr diff --git a/xilprg.1 b/xilprg.1 new file mode 100644 index 0000000..8abf3ca --- /dev/null +++ b/xilprg.1 @@ -0,0 +1,63 @@ +.TH XILPRG "1" + +.SH NAME +xilprg \- Program xilinx FPGAs and Flash using JTAG interfaces + +.SH SYNOPSIS +.B xilprg [command] [; command ...] +If no commands are on the commandline, an interactive mode is entered. + +.SH COMMANDS +.SS help [command] +Shows help +.SS detect +Detects JTAG device chain +.SS cable {xil3 [ioaddr]|dusb} +Sets programmer cable +.SS chips +Prints supported devices +.SS program [-e] [-bit|-mcs|-bin] position file +Programs device, with optional erase (-e) before programming +.SS erase position +Erases device +.SS read position file +Read device content and saves in a file +.SS verify [-bit|-mcs|-bin] position file +Verifies device +.SS idcode position +Shows device IDCODE +.SS cd [dir] +Shows/changes current directory +.SS version +Shows version information +.SS exit +Exits program + +.SH FILES +.TP +\fBxilprg.conf\fR +Lists devices known to xilprg + +.SH Examples +To test a .bit file in the xc3s200 FPGA on the digilentinc "s3board", +.RS 4 +xilprg program 1 example.bit +.RE + +To replace the program in the xcf02s Platform Flash on the digilentinc +"s3board", +"s3board" +.RS 4 +xilprg program -e 2 example.bit +.RE +Without "-e" to erase, this command will leave the flash in a non-working +state. + +.SH COPYRIGHT +Copyright (c) 2006 Zoltan Csizmadia +All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version.