This post contains the update of the controller allowing to drive
the internal parallel bus in the FPGA via JTAG interface
The previous version has been published in the post:
news:slrnhdho8...@wzab.nasz.dom posted to alt.sources
with the subject "FPGA internal bus controller driven by JTAG interface"
This version:
1. works with the SPARTAN6 family
2. provides better separation of the Python code which communicates
with the urjtag and with controller - all functionality is
now put into classes "urjtag" and "jtag_bus"
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.9).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `#!/bin/sh' line above, then type `sh FILE'.
#
lock_dir=_sh07564
# Made on 2010-08-03 21:20 CEST by <xl@wzab>.
# Source directory was `/tmp/jbus'.
#
# Existing files will *not* be overwritten, unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 3632 -rw-r--r-- bscan_top.vhd
# 3761 -rw-r--r-- jtag_bus3.py
# 9781 -rw-r--r-- jtag_bus_ctl_3.vhd
# 725 -rw-r--r-- system.ucf
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir ;;
esac
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
then shar_n= shar_c='
'
else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901
if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
test ! -f ${st1} && test -f ${f}; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
test ! -f ${st3} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$2 "$8"'
else
shar_touch=:
echo
${echo} 'WARNING: not restoring timestamps. Consider getting and
installing GNU `touch'\'', distributed in GNU coreutils...'
echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir} ; then :
else ${echo} "lock directory ${lock_dir} exists"
exit 1
fi
if mkdir ${lock_dir}
then ${echo} "x - created lock directory ${lock_dir}."
else ${echo} "x - failed to create lock directory ${lock_dir}."
exit 1
fi
# ============= bscan_top.vhd ==============
if test -f 'bscan_top.vhd' && test "$first_param" != -c; then
${echo} "x - SKIPPING bscan_top.vhd (file already exists)"
else
${echo} "x - extracting bscan_top.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'bscan_top.vhd' &&
-------------------------------------------------------------------------------
-- Title : JTAG<->BUS controller demo for SPARTAN6
-- Project :
-------------------------------------------------------------------------------
-- File : bscan_top.vhd
-- Author : Wojciech M. Zabolotny <wz...@ise.pw.edu.pl>
-- Company :
-- Created : 2007-12-31
-- Last update: 2010-08-03
-- Platform :
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
-- This file implements a simple entity with JTAG driven internal bus
-- allowing to control LEDs, read buttons, set two registers
-- and to read results of simple arithmetical operations
-------------------------------------------------------------------------------
-- Copyright (c) 2010
-- This is public domain code!!!
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-08-03 1.0 wzab Created
-------------------------------------------------------------------------------
X
X
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
X
entity lcd_test is
X
X port (
X led : out std_logic_vector(3 downto 0);
X switches : in std_logic_vector(3 downto 0);
X flash_oen : out std_logic;
X flash_wen : out std_logic;
X flash_cen : out std_logic);
X
end lcd_test;
X
architecture beh of lcd_test is
X
X component jtag_bus_ctl
X generic (
X d_width : integer;
X a_width : integer);
X port (
X din : in std_logic_vector((d_width-1) downto 0);
X dout : out std_logic_vector((d_width-1) downto 0);
X addr : out std_logic_vector((a_width-1) downto 0);
X nwr : out std_logic;
X nrd : out std_logic);
X end component;
X
X signal arg1, arg2, res1 : unsigned(7 downto 0);
X signal res2 : unsigned(15 downto 0);
X signal inputs, din, dout : std_logic_vector(7 downto 0);
X signal addr, leds : std_logic_vector(3 downto 0);
X signal nwr, nrd, rst_n : std_logic;
X
begin -- beh
X
X rst_n <= '1'; -- no reset, but you can provide one
X flash_cen <= '1';
X flash_wen <= '1';
X flash_oen <= '1';
X
X jtag_bus_ctl_1 : jtag_bus_ctl
X generic map (
X d_width => 8,
X a_width => 4)
X port map (
X din => din,
X dout => dout,
X addr => addr,
X nwr => nwr,
X nrd => nrd);
X
X -- Reading buttons, switches and registers
X process (addr, arg1, arg2, inputs, leds, res1, res2)
X begin -- process
X case addr is
X when x"1" => din <= std_logic_vector(arg1);
X when x"2" => din <= std_logic_vector(arg2);
X when x"3" => din <= leds & leds;
X when x"4" => din <= inputs;
X when x"5" => din <= std_logic_vector(res1);
X when x"6" => din <= std_logic_vector(res2(7 downto 0));
X when x"7" => din <= std_logic_vector(res2(15 downto 8));
X when others => null;
X end case;
X end process;
X
X -- Writing to registers
X p1 : process (nwr, rst_n)
X begin -- process p1
X if rst_n = '0' then -- asynchronous reset (active low)
X arg1 <= (others => '0');
X arg2 <= (others => '0');
X leds <= (others => '0');
X elsif nwr'event and nwr = '1' then -- rising clock edge
X case addr is
X when x"1" => arg1 <= unsigned(dout);
X when x"2" => arg2 <= unsigned(dout);
X when x"3" => leds <= dout(3 downto 0);
X when others => null;
X end case;
X end if;
X end process p1;
X
X res1 <= arg1+arg2;
X res2 <= arg1*arg2;
X inputs <= switches & switches;
X led <= leds;
end beh;
SHAR_EOF
(set 20 10 08 03 21 10 48 'bscan_top.vhd'
eval "${shar_touch}") && \
chmod 0644 'bscan_top.vhd'
if test $? -ne 0
then ${echo} "restore of bscan_top.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'bscan_top.vhd': 'MD5 check failed'
) << \SHAR_EOF
528aa53c62993a7107e4e9d96eb67756 bscan_top.vhd
SHAR_EOF
else
test `LC_ALL=C wc -c < 'bscan_top.vhd'` -ne 3632 && \
${echo} "restoration warning: size of 'bscan_top.vhd' is not 3632"
fi
fi
# ============= jtag_bus3.py ==============
if test -f 'jtag_bus3.py' && test "$first_param" != -c; then
${echo} "x - SKIPPING jtag_bus3.py (file already exists)"
else
${echo} "x - extracting jtag_bus3.py (text)"
sed 's/^X//' << 'SHAR_EOF' > 'jtag_bus3.py' &&
#!/usr/bin/python
import pexpect
import re
import time
X
# Utility function used to convert
# an integer into n-digit binary number
def uint2bin(val,ndigits):
X res=""
X i=ndigits
X while i:
X if val & 1:
X res='1'+res
X else:
X res='0'+res
X val>>=1
X i-=1
X return res
X
# Class urjtag provides communication with the "urjtag" program
# In my system "urjtag" program is just a script, which sets the PATH
# and runs the "jtag" binary
class urjtag:
X def __init__(self):
X self.p=pexpect.spawn("urjtag")
X self.p.expect("jtag>")
X self.p.delaybeforesend=0
X def cmd(self,line):
X self.p.sendline(line)
X self.p.expect("jtag>")
X if self.p.before.find("Error:")>=0:
X #res=-1
X raise BaseException("error")
X elif self.p.before.find("Unknown")>=0 or \
X self.p.before.find("unknown")>=0:
X #res=-2
X raise BaseException("unknown command or syntax error")
X #print self.p.before
X return self.p.before
X
# Class jtag_bus provide the real communication with the controller
# The constructor accepts: name of the cable, name of the part,
# number of the part in the chain (in the case if we have two or more
# identical chips in the chain), width of the address bus
# and width of the data bus.
class jtag_bus:
X def __init__(self,cable,part,index,a_width,d_width):
X self.u=urjtag()
X self.u.cmd("cable "+cable)
X #u.cmd("cable DLC5 ppdev /dev/parport0")
X s=self.u.cmd("detect")
X #Here we parse the output of the "detect" command,
X #Building the list of the parts
X parts=[]
X part_select=""
X finder=re.compile(r'.*Part\((?P<num>.*?)\):\s*(?P<name>\S*)', re.M)
X start=0
X while True:
X rs=finder.search(s,start)
X if not rs:
X break
X # We have found a new part, add it to the list of parts
X parts.append((rs.group('num'),rs.group('name')))
X start=rs.span()[1]
X # OK, so we set all the parts except the required one in the BYPASS
X # mode
X self.m_width=max(a_width,d_width)
X for p in parts:
X print p[1]
X if (p[1]==part) and (index == 1):
X print "Found!"
X part_select="part "+p[0]
X self.u.cmd(part_select)
X self.u.cmd("register BAR "+str(self.m_width+2))
X self.u.cmd("instruction BUSACC 000010 BAR")
X self.u.cmd("instruction BUSACC")
X self.u.cmd("shift ir")
X else:
X self.u.cmd("part "+p[0])
X self.u.cmd("instruction BYPASS")
X self.u.cmd("shift ir")
X if p[1]==part:
X index -= 1
X if part_select:
X self.u.cmd(part_select)
X else:
X raise BaseException("required chip not found!")
X # definition of simple read/write operations
X # (they do not use the possibility to receive data
X # during transfer of the next command)
X def jt_write(self,address,data):
X self.u.cmd("dr 11"+uint2bin(address,self.m_width)+" :: shift dr")
X self.u.cmd("dr 00"+uint2bin(data,self.m_width)+" :: shift dr")
X def jt_read(self,address):
X self.u.cmd("dr 10"+uint2bin(address,self.m_width)+" :: shift dr")
X self.u.cmd("dr 00"+(self.m_width)*"0"+" :: shift dr")
X return int(self.u.cmd("dr").split()[1],2)
X
#Main program, which shows how to use the controller with simple demo code
X
#build the controller interface object
jb=jtag_bus("xpc_ext","xc6slx16-csg324",1,4,8)
# Set LEDs
jb.jt_write(3,5)
#Write the arguments
jb.jt_write(1,13)
jb.jt_write(2,20)
#read back arguments
a1=jb.jt_read(1)
a2=jb.jt_read(2)
#read sum
print "arg1="+str(a1)+" arg2="+str(a2)
print "arg1+arg2="+str(jb.jt_read(5))
#read product bytes
b1=jb.jt_read(6)
b2=jb.jt_read(7)
print "arg1*arg2="+str(b1+256*b2)
X
SHAR_EOF
(set 20 10 08 03 21 07 18 'jtag_bus3.py'
eval "${shar_touch}") && \
chmod 0644 'jtag_bus3.py'
if test $? -ne 0
then ${echo} "restore of jtag_bus3.py failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'jtag_bus3.py': 'MD5 check failed'
) << \SHAR_EOF
f7d9014ce9a23d152028058ba8fc957d jtag_bus3.py
SHAR_EOF
else
test `LC_ALL=C wc -c < 'jtag_bus3.py'` -ne 3761 && \
${echo} "restoration warning: size of 'jtag_bus3.py' is not 3761"
fi
fi
# ============= jtag_bus_ctl_3.vhd ==============
if test -f 'jtag_bus_ctl_3.vhd' && test "$first_param" != -c; then
${echo} "x - SKIPPING jtag_bus_ctl_3.vhd (file already exists)"
else
${echo} "x - extracting jtag_bus_ctl_3.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'jtag_bus_ctl_3.vhd' &&
-------------------------------------------------------------------------------
-- Title : jtag_bus_ctl - interface between the JTAG and internal bus
-- Project :
-------------------------------------------------------------------------------
-- File : jtag_bus_ctl.vhd
-- Author : Wojciech M. Zabolotny
-- Company :
-- Created : 2009-10-13
-- Last update: 2010-08-03
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: This is implementation of the bus controller for Xilinx FPGAs
-- allowing you to access the internal bus via JTAG
-- The internal bus uses:
-- addr(a_width-1 downto 0) - address lines
-- dout(d_width-1 downto 0) - data to be written to register
-- on the internal bus
-- din(d_width-1 downto 0) - data read from the register on
-- on the internal bus
-- nrd - asynchronous read strobe
-- nwr - asynchronous write strobe
--
-- This implementation uses one JTAG instruction:
-- USER1 - dr length: max(2+a_width,1+d_width)
-- data transferred for this instruction may be:
-- (xxx: optional filler)
-- 10_xxx_address - READ command with address
-- 11_xxx_address - WRITE command with address
-- 00_xxx_data - DATA word to be written or dummy data in case
-- of read access - no change of address
-- THIS WORD MAY BE USED AFTER THE READ COMMAND
-- TO READ THE DATA WITHOUT ISSUING A NEW COMMAND
-- 01_xxx_data - DATA word to be written or dummy data in case
-- of read access - the access address gets
-- incremented afterwards!
--
-- Due to the way the JTAG works, the read data are transferred
-- when next command or data word is shifted through the dr register.
--
-- It is perfectly OK to issue the READ command, and then WRITE command
-- The read data will be transferred when WRITE command is transmitted.
--
-- The write command must be followed by the data command (you may
-- issue a few data commands in sequence generating a few writes
-- to the same address - useful for bit-banging procedures).
--
-- If you want to read data without issuing the next command - send
-- the DATA word 00_??? after the READ command. Please note, that
-- multiple DATA 00_??? words after the READ command do not allow
-- you to perform multiple reads! The first DATA word cancells
-- the READ mode to NOOP mode.
-- If you want to read the same address multiple times - you should
-- issue multiple READ commands with the same address (it does not
-- affects performance, as you always have to send new word to receive
-- the data)
--
-- If you want to read a few consecutive registers, then you
-- should issue the READ command with the address of the first
-- register, then multiple 01_???? DATA words to read data and
-- increase address, and finally 00_???? DATA word to receive
-- the value read from the last register without triggering a new
-- read operation.
--
-- If you want to write data to a few consecutive registers, then
-- you should issue the WRITE command with the address of the first
-- register and then multiple 01_???? DATA words. The last one
-- may be the 00_???? DATA word, but this is not necessary.
--
-- The strobes nrd and nwr are generated from the TAP controller states
-- so the JTAG frequency affects the length ofread/write pulses
-------------------------------------------------------------------------------
-- Copyright (c) 2009 Wojciech M. Zabolotny (wzab<at>ise.pw.edu.pl)
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009-10-13 1.0 wzab Created
-------------------------------------------------------------------------------
--
-- This program is PUBLIC DOMAIN code
-- You can do with it whatever you want, however NO WARRANTY of ANY KIND
-- is provided
--
X
X
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
library work;
X
entity jtag_bus_ctl is
X generic (
X d_width : integer := 8;
X a_width : integer := 8);
X port (
X din : in std_logic_vector((d_width-1) downto 0);
X dout : out std_logic_vector((d_width-1) downto 0);
X addr : out std_logic_vector((a_width-1) downto 0);
X nwr : out std_logic;
X nrd : out std_logic
X );
end jtag_bus_ctl;
X
architecture syn of jtag_bus_ctl is
X
X component BSCAN_SPARTAN6
X generic (
X JTAG_CHAIN : integer);
X port (
X CAPTURE : out std_ulogic;
X DRCK : out std_ulogic;
X RESET : out std_ulogic;
X RUNTEST : out std_ulogic;
X SEL : out std_ulogic;
X SHIFT : out std_ulogic;
X TCK : out std_ulogic;
X TDI : out std_ulogic;
X TMS : out std_ulogic;
X UPDATE : out std_ulogic;
X TDO : in std_ulogic);
X end component;
X
X signal jt_shift, jt_update, jt_tdi, jt_tdo, jt_tck, jt_tms, jt_drck,
X jt_capture, jt_sel, jt_reset : std_ulogic; -- := '0';
X
X function maximum(L, R : integer) return integer is
X begin
X if L > R then
X return L;
X else
X return R;
X end if;
X end;
X
X constant DR_SHIFT_LEN : integer := maximum(a_width+2, d_width+2);
X -- Register storing the access address and mode (read/write)
X signal dr_shift : std_logic_vector(DR_SHIFT_LEN-1 downto 0) := (others => '0');
X signal write_addr, read_addr : std_logic_vector(a_width-1 downto 0);
X -- Register storing the data
X signal write_cmd, read_cmd : std_logic := '0';
X
begin
X
X BSCAN_SPARTAN6_1 : BSCAN_SPARTAN6
X generic map (
X JTAG_CHAIN => 1)
X port map (
X CAPTURE => jt_CAPTURE,
X DRCK => jt_DRCK,
X RESET => jt_RESET,
X SEL => jt_SEL,
X SHIFT => jt_SHIFT,
X TCK => jt_TCK,
X TDI => jt_TDI,
X TMS => jt_TMS,
X UPDATE => jt_UPDATE,
X TDO => jt_TDO);
X
X
X -- Generate the read strobe for external bus
X nrd <= '0' when jt_capture = '1' and jt_sel = '1' and read_cmd = '1' else '1';
X -- Generate the write strobe for the external bus - when write_cmd, and this
X -- is the data word
X nwr <= '0' when jt_update = '1' and jt_sel = '1' and
X write_cmd = '1' and dr_shift(DR_SHIFT_LEN-1) = '0' else '1';
X
X dout <= dr_shift(d_width-1 downto 0);
X addr <= write_addr when write_cmd = '1' else read_addr;
X
X -- Load and shift data to dr_addr_and_mode register
X pjtag1 : process (jt_drck, jt_reset)
X begin -- process
X if jt_reset = '1' then
X dr_shift <= (others => '0');
X elsif jt_drck'event and jt_drck = '1' then -- falling clock edge - state
X if jt_shift = '0' then
X if read_cmd = '1' then
X -- Read the data
X dr_shift(d_width-1 downto 0) <= din;
X end if;
X else
X -- Transfer the read_addr to the write_addr
X -- this is necessary to avoid updating the write_addr
X -- at the begining or end of the write cycle in the autoincrement mode
X write_addr <= read_addr;
X -- Shift the register
X dr_shift(DR_SHIFT_LEN-1) <= jt_tdi;
X for i in 0 to DR_SHIFT_LEN-2 loop
X dr_shift(i) <= dr_shift(i+1);
X end loop; -- i
X end if;
X end if;
X end process pjtag1;
X
X pupd1a : process(jt_reset, jt_update)
X begin -- process
X if jt_reset = '1' then
X elsif jt_update'event and jt_update = '1' then
X if jt_sel = '1' then
X if dr_shift(DR_SHIFT_LEN-1 downto DR_SHIFT_LEN-2) = "10" then
X read_cmd <= '1';
X write_cmd <= '0';
X read_addr <= dr_shift(a_width-1 downto 0);
X elsif dr_shift(DR_SHIFT_LEN-1 downto DR_SHIFT_LEN-2) = "11" then
X -- Write access
X read_cmd <= '0';
X write_cmd <= '1'; -- We PREPARE to write
X read_addr <= dr_shift(a_width-1 downto 0);
X -- we can not write the write_addr here
X -- It will be updated from the read_addr in another process
X -- this is needed to implement the autoincrement mode!
X elsif dr_shift(DR_SHIFT_LEN-1 downto DR_SHIFT_LEN-2) = "00" then
X -- Data
X read_cmd <= '0'; -- Block further READs
X else
X -- "01" - This is the autoincrement mode! we should increment
X -- the address, but the write cycle is still active!
X -- to avoid problems with the hold time we update now only the read address
X read_addr <= write_addr+1;
X -- the write address will be updated later, when shifting the next word
X end if;
X end if;
X end if;
X end process pupd1a;
X
X -- No update process is needed! Our controller just generates the nwr pulse
X -- for internal logic
X
-- pupd1b : process(jt_reset, jt_update)
-- begin -- process
-- if jt_reset = '1' then
-- null;
-- elsif jt_update'event and jt_update = '0' then
-- if jt_sel1 = '1' then
-- null;
-- end if;
-- end if;
-- end process pupd1b;
X
X jt_TDO <= dr_shift(0);
X
end syn;
SHAR_EOF
(set 20 10 08 03 21 10 22 'jtag_bus_ctl_3.vhd'
eval "${shar_touch}") && \
chmod 0644 'jtag_bus_ctl_3.vhd'
if test $? -ne 0
then ${echo} "restore of jtag_bus_ctl_3.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'jtag_bus_ctl_3.vhd': 'MD5 check failed'
) << \SHAR_EOF
3c2674eccabf5d69b8c54a344ca763ac jtag_bus_ctl_3.vhd
SHAR_EOF
else
test `LC_ALL=C wc -c < 'jtag_bus_ctl_3.vhd'` -ne 9781 && \
${echo} "restoration warning: size of 'jtag_bus_ctl_3.vhd' is not 9781"
fi
fi
# ============= system.ucf ==============
if test -f 'system.ucf' && test "$first_param" != -c; then
${echo} "x - SKIPPING system.ucf (file already exists)"
else
${echo} "x - extracting system.ucf (text)"
sed 's/^X//' << 'SHAR_EOF' > 'system.ucf' &&
X
Net led<0> LOC = E13 | IOSTANDARD = LVCMOS25;
Net led<1> LOC = C14 | IOSTANDARD = LVCMOS25;
Net led<2> LOC = C4 | IOSTANDARD = LVCMOS25;
Net led<3> LOC = A4 | IOSTANDARD = LVCMOS25;
X
X
Net switches<0> LOC = P4 | IOSTANDARD = LVCMOS18;
Net switches<1> LOC = F6 | IOSTANDARD = LVCMOS18;
Net switches<2> LOC = E4 | IOSTANDARD = LVCMOS18;
Net switches<3> LOC = F5 | IOSTANDARD = LVCMOS18;
X
X
Net flash_wen LOC=M16;
Net flash_wen SLEW = SLOW;
Net flash_wen DRIVE = 4;
Net flash_wen IOSTANDARD = LVCMOS25;
X
Net flash_oen LOC=L18;
Net flash_oen SLEW = SLOW;
Net flash_oen DRIVE = 4;
Net flash_oen IOSTANDARD = LVCMOS25;
X
Net flash_cen LOC=L17;
Net flash_cen SLEW = SLOW;
Net flash_cen DRIVE = 4;
Net flash_cen IOSTANDARD = LVCMOS25;
SHAR_EOF
(set 20 10 08 03 21 11 26 'system.ucf'
eval "${shar_touch}") && \
chmod 0644 'system.ucf'
if test $? -ne 0
then ${echo} "restore of system.ucf failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'system.ucf': 'MD5 check failed'
) << \SHAR_EOF
47db46b93e57b01b0f5d1a761254df84 system.ucf
SHAR_EOF
else
test `LC_ALL=C wc -c < 'system.ucf'` -ne 725 && \
${echo} "restoration warning: size of 'system.ucf' is not 725"
fi
fi
if rm -fr ${lock_dir}
then ${echo} "x - removed lock directory ${lock_dir}."
else ${echo} "x - failed to remove lock directory ${lock_dir}."
exit 1
fi
exit 0