[Pkg-electronics-commits] [iverilog] 01/08: Imported Upstream version 0.9.7

أحمد المحمودي (Ahmed El-Mahmoudy) aelmahmoudy at sabily.org
Sat Aug 24 13:25:39 UTC 2013


This is an automated email from the git hooks/post-receive script.

aelmahmoudy-guest pushed a commit to branch master
in repository iverilog.

commit 6edb507dd6ba21094afb3e5fce150a3c79821169
Author: أحمد المحمودي (Ahmed El-Mahmoudy) <aelmahmoudy at sabily.org>
Date:   Sat Aug 24 14:16:54 2013 +0200

    Imported Upstream version 0.9.7
---
 Makefile.in             |    2 +-
 configure               |  271 +++++++------
 driver/cfparse_misc.h   |    5 +-
 elab_expr.cc            |    9 +
 elab_lval.cc            |   49 ++-
 elaborate.cc            |   13 +-
 examples/des.v          | 1035 -----------------------------------------------
 ivlpp/Makefile.in       |    4 +-
 parse.y                 |   80 ++--
 pform.cc                |   25 +-
 pform.h                 |    3 +-
 svector.h               |    6 +-
 t-dll-analog.cc         |    5 +-
 t-dll-proc.cc           |    5 +-
 tgt-fpga/Makefile.in    |    2 +-
 tgt-null/Makefile.in    |    2 +-
 tgt-stub/Makefile.in    |    2 +-
 tgt-verilog/Makefile.in |    2 +-
 tgt-vhdl/Makefile.in    |    2 +-
 tgt-vhdl/stmt.cc        |    2 +
 tgt-vvp/Makefile.in     |    2 +-
 verilog.spec            |    4 +-
 version_base.h          |    2 +-
 version_tag.h           |    2 +-
 vpi/fstapi.c            |  423 ++++++++++++++-----
 vpi/fstapi.h            |  108 ++++-
 vpi/lxt2_write.c        |    2 +-
 vpi/sys_display.c       |   34 +-
 vpi_user.h              |   19 +
 vvp/array.cc            |   13 +-
 vvp/concat.cc           |   30 ++
 vvp/slab.h              |    5 +-
 vvp/vpi_const.cc        |    8 +-
 vvp/vpi_priv.h          |    2 +-
 vvp/vpi_signal.cc       |    7 +-
 vvp/vpi_vthr_vector.cc  |    4 +-
 vvp/vvp_net.cc          |   51 ++-
 vvp/vvp_net.h           |   63 +--
 38 files changed, 869 insertions(+), 1434 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 1aabdae..fa17967 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -186,7 +186,7 @@ ifeq (@WIN32@,yes)
 ivl at EXEEXT@: $O $(srcdir)/ivl.def
 	$(CXX) -o ivl at EXEEXT@ $O $(dllib) @EXTRALIBS@
 	$(DLLTOOL) --dllname ivl at EXEEXT@ --def $(srcdir)/ivl.def \
-	 	--output-lib libivl.a --output-exp ivl.exp
+		--output-lib libivl.a --output-exp ivl.exp
 	$(CXX) $(LDFLAGS) -o ivl at EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
 else
 ivl at EXEEXT@: $O
diff --git a/configure b/configure
index 98f6a8f..25abc01 100755
--- a/configure
+++ b/configure
@@ -1,11 +1,9 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68.
+# Generated by GNU Autoconf 2.69.
 #
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -134,6 +132,31 @@ export LANGUAGE
 # CDPATH.
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
   as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
@@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
 else
   exitcode=1; echo positional parameters were not saved.
 fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -212,21 +236,25 @@ IFS=$as_save_IFS
 
 
       if test "x$CONFIG_SHELL" != x; then :
-  # We cannot yet assume a decent shell, so we have to provide a
-	# neutralization value for shells without unset; and this also
-	# works around shells that cannot unset nonexistent variables.
-	# Preserve -v and -x to the replacement shell.
-	BASH_ENV=/dev/null
-	ENV=/dev/null
-	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-	export CONFIG_SHELL
-	case $- in # ((((
-	  *v*x* | *x*v* ) as_opts=-vx ;;
-	  *v* ) as_opts=-v ;;
-	  *x* ) as_opts=-x ;;
-	  * ) as_opts= ;;
-	esac
-	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
 fi
 
     if test x$as_have_required = xno; then :
@@ -328,6 +356,14 @@ $as_echo X"$as_dir" |
 
 
 } # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -449,6 +485,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
   chmod +x "$as_me.lineno" ||
     { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
   # original and so on.  Autoconf is especially sensitive to this).
@@ -483,16 +523,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -504,28 +544,8 @@ else
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-	test -d "$1/.";
-      else
-	case $1 in #(
-	-*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -1165,8 +1185,6 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used" >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1410,9 +1428,9 @@ test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 configure
-generated by GNU Autoconf 2.68
+generated by GNU Autoconf 2.69
 
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1884,7 +1902,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -1900,7 +1919,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -1926,7 +1946,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -1942,7 +1963,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -1976,7 +1998,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -2072,7 +2095,7 @@ $as_echo "$ac_try_echo"; } >&5
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
-	 $as_test_x conftest$ac_exeext
+	 test -x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
@@ -2239,7 +2262,7 @@ $as_echo "$ac_try_echo"; } >&5
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
-	 $as_test_x conftest$ac_exeext
+	 test -x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
@@ -2329,7 +2352,7 @@ This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.68.  Invocation command line was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
 
@@ -2813,7 +2836,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2853,7 +2876,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2906,7 +2929,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -2947,7 +2970,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
@@ -3005,7 +3028,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3049,7 +3072,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3495,8 +3518,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdarg.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -3733,7 +3755,7 @@ main ()
   return 0;
 }
 _ACEOF
-for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
 do
   CC="$ac_save_CC $ac_arg"
   if ac_fn_c_try_compile "$LINENO"; then :
@@ -3792,7 +3814,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3836,7 +3858,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CXX="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4038,7 +4060,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4078,7 +4100,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4130,7 +4152,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_LD="${ac_tool_prefix}ld"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4170,7 +4192,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_LD="ld"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4222,7 +4244,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_AR="${ac_tool_prefix}ar"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4262,7 +4284,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_AR="ar"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4314,7 +4336,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4354,7 +4376,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DLLTOOL="dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4406,7 +4428,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4446,7 +4468,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_STRIP="strip"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4498,7 +4520,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_WINDRES="${ac_tool_prefix}windres"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4538,7 +4560,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_WINDRES="windres"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4591,7 +4613,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_XGPERF="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4634,7 +4656,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_MAN="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4677,7 +4699,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_PS2PDF="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4720,7 +4742,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_GIT="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4774,7 +4796,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_LEX="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4824,7 +4846,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_YACC="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5040,7 +5062,7 @@ do
     for ac_prog in grep ggrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+      as_fn_executable_p "$ac_path_GREP" || continue
 # Check for GNU ac_path_GREP and select it if it is found.
   # Check for GNU $ac_path_GREP
 case `"$ac_path_GREP" --version 2>&1` in
@@ -5106,7 +5128,7 @@ do
     for ac_prog in egrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+      as_fn_executable_p "$ac_path_EGREP" || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
 case `"$ac_path_EGREP" --version 2>&1` in
@@ -6158,23 +6180,20 @@ else
 /* end confdefs.h.  */
 $ac_includes_default
 int
-find_stack_direction ()
+find_stack_direction (int *addr, int depth)
 {
-  static char *addr = 0;
-  auto char dummy;
-  if (addr == 0)
-    {
-      addr = &dummy;
-      return find_stack_direction ();
-    }
-  else
-    return (&dummy > addr) ? 1 : -1;
+  int dir, dummy = 0;
+  if (! addr)
+    addr = &dummy;
+  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+  return dir + dummy;
 }
 
 int
-main ()
+main (int argc, char **argv)
 {
-  return find_stack_direction () < 0;
+  return find_stack_direction (0, argc + !argv + 20) < 0;
 }
 _ACEOF
 if ac_fn_cxx_try_run "$LINENO"; then :
@@ -6460,7 +6479,7 @@ case $as_dir/ in #((
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
 	  if test $ac_prog = install &&
 	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
@@ -7798,16 +7817,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -7867,28 +7886,16 @@ else
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-	test -d "$1/.";
-      else
-	case $1 in #(
-	-*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -7910,7 +7917,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # values after options handling.
 ac_log="
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.68.  Invocation command line was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -7972,10 +7979,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.68,
+configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -8064,7 +8071,7 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
   \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
diff --git a/driver/cfparse_misc.h b/driver/cfparse_misc.h
index 708d79f..cadfdff 100644
--- a/driver/cfparse_misc.h
+++ b/driver/cfparse_misc.h
@@ -1,8 +1,7 @@
 #ifndef __cfparse_misc_H
 #define __cfparse_misc_H
 /*
- * Copyright (c) 2001-2009 Picture Elements, Inc.
- *    Stephen Williams (steve at picturel.com)
+ * Copyright (c) 2001-2009 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -17,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 /*
diff --git a/elab_expr.cc b/elab_expr.cc
index 59f8464..47b4eb4 100644
--- a/elab_expr.cc
+++ b/elab_expr.cc
@@ -1562,6 +1562,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
 	   of the function being called. The scope of the called
 	   function is elaborated when the definition is elaborated. */
 
+      unsigned parm_errors = 0;
       unsigned missing_parms = 0;
       for (unsigned idx = 0 ;  idx < parms.count() ;  idx += 1) {
 	    PExpr*tmp = parms_[idx];
@@ -1570,6 +1571,11 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
 						   def->port(idx)->data_type(),
 						   def->port(idx)->vector_width(),
 						   tmp);
+		  if (parms[idx] == 0) {
+			parm_errors += 1;
+			continue;
+		  }
+
 		  if (NetEEvent*evt = dynamic_cast<NetEEvent*> (parms[idx])) {
 			cerr << evt->get_fileline() << ": error: An event '"
 			     << evt->event()->name() << "' can not be a user "
@@ -1595,8 +1601,11 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
 	    cerr << get_fileline() << ":      : Verilog doesn't allow "
 		 << "passing empty parameters to functions." << endl;
 	    des->errors += 1;
+	    return 0;
       }
 
+      if (parm_errors > 0)
+	    return 0;
 
 	/* Look for the return value signal for the called
 	   function. This return value is a magic signal in the scope
diff --git a/elab_lval.cc b/elab_lval.cc
index cb7bfd2..86ec0b2 100644
--- a/elab_lval.cc
+++ b/elab_lval.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2010 Stephen Williams (steve at icarus.com)
+ * Copyright (c) 2000-2013 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -336,6 +336,7 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
       ivl_assert(*this, index_tail.lsb == 0);
 
       NetNet*reg = lv->sig();
+      assert(reg);
 
 	// These are not used, but they need to have a default value.
       ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
@@ -350,8 +351,20 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
       long lsb = 0;
 
       if (NetEConst*index_con = dynamic_cast<NetEConst*> (mux)) {
-	    lsb = index_con->value().as_long();
-	    mux = 0;
+	      // The index has a constant defined value.
+	    if (index_con->value().is_defined()) {
+		  lsb = index_con->value().as_long();
+		  mux = 0;
+	      // The index is undefined.
+	    } else {
+		  cerr << get_fileline() << ": warning: L-value bit select of "
+		       << reg->name();
+		  if (reg->array_dimensions() > 0) cerr << "[]";
+		  cerr << " has an undefined index." << endl;
+
+		  lv->set_part(new NetEConst(verinum(verinum::Vx)), 1);
+		  return true;
+	    }
       }
 
       if (mux) {
@@ -393,14 +406,21 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
       long msb, lsb;
       bool parts_defined_flag;
       bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag);
-      if (!flag)
-	    return false;
-
-      ivl_assert(*this, parts_defined_flag);
+      if (!flag) return false;
 
       NetNet*reg = lv->sig();
       assert(reg);
 
+      if (! parts_defined_flag) {
+	    cerr << get_fileline() << ": warning: L-value part select of "
+	         << reg->name();
+	    if (reg->array_dimensions() > 0) cerr << "[]";
+	    cerr << " has an undefined index." << endl;
+	    lv->set_part(new NetEConst(verinum(verinum::Vx)), 1);
+	    return true;
+      }
+
+
       if (msb == reg->msb() && lsb == reg->lsb()) {
 
 	      /* Part select covers the entire vector. Simplest case. */
@@ -517,17 +537,10 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
 			}
 		  }
 	    } else {
-		  if (warn_ob_select) {
-			cerr << get_fileline() << ": warning: " << reg->name();
-			if (reg->array_dimensions() > 0) cerr << "[]";
-			cerr << "['bx";
-			if (use_sel == index_component_t::SEL_IDX_UP) {
-			      cerr << "+:";
-			} else {
-			      cerr << "-:";
-			}
-			cerr << wid << "] is always outside vector." << endl;
-		  }
+		  cerr << get_fileline() << ": warning: L-value indexed part "
+		       << "select of " << reg->name();
+		  if (reg->array_dimensions() > 0) cerr << "[]";
+		  cerr << " has an undefined base." << endl;
 	    }
       } else {
 	      /* Correct the mux for the range of the vector. */
diff --git a/elaborate.cc b/elaborate.cc
index 9c5512a..ec436b9 100644
--- a/elaborate.cc
+++ b/elaborate.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2012 Stephen Williams (steve at icarus.com)
+ * Copyright (c) 1998-2013 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -189,11 +189,12 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
 	    need_driver_flag = false;
       }
 
-	/* When we are given a non-default strength value and if the
-	 * drive source is a bit, part or indexed select we need to
-	 * add a driver (BUFZ) to convey the strength information. */
+	/* When we are given a non-default strength value and if the drive
+	 * source is a bit, part, indexed select or concatenation we need
+	 * to add a driver (BUFZ) to convey the strength information. */
       if ((drive0 != Link::STRONG || drive1 != Link::STRONG) &&
-          (dynamic_cast<NetESelect*>(rval_expr))) {
+          ((dynamic_cast<NetESelect*>(rval_expr)) ||
+	   (dynamic_cast<NetEConcat*>(rval_expr)))) {
 	    need_driver_flag = true;
       }
 
@@ -1858,6 +1859,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
 	    if (pins[idx] == 0)
 		  continue;
 
+	    probe_expr_width(des, scope, pins[idx]);
 	    NetExpr*expr_tmp = elab_and_eval(des, scope, pins[idx], 1, 1);
 	    if (expr_tmp == 0) {
 		  cerr << "internal error: Expression too complicated "
@@ -3761,6 +3763,7 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
 {
       assert(scope);
 
+      probe_expr_width(des, scope, expr_);
       NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
       if (expr == 0) {
 	    cerr << get_fileline() << ": Unable to elaborate"
diff --git a/examples/des.v b/examples/des.v
deleted file mode 100644
index 59cd0d3..0000000
--- a/examples/des.v
+++ /dev/null
@@ -1,1035 +0,0 @@
-//
-//      Name:                   testbench1.vhdl
-//
-//      Author:                 Chris Eilbeck, chris at yordas.demon.co.uk
-//
-//      Purpose:                VHDL testbench for a DES encryptor.
-//
-//      IP Status:              Free use is hereby granted for all civil use including personal, educational and commercial use.
-//                                      The use of this code for military, diplomatic or governmental purposes is specifically forbidden.
-//
-//      Warranty:               There is absolutely no warranty given with this code.  You accept all responsibility for the use
-//                                      of this code and any damage so caused.
-//
-//      Vers Info:              v0.1 14/11/1998 - Creation.
-//				     14/11/1999 - Converted to Verilog (ajb)
-//
-
-module top;
-
-reg clk;
-reg [1:64] pt, key;
-wire [1:64] ct;
-integer i;
-
-des des(pt, key, ct, clk);
-
-initial
-begin
-$dumpfile("des.vcd");
-$dumpvars(0, top);
-
-key = 64'h0000000000000000;
-pt  = 64'h0000000000000000;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'hffffffffffffffff;
-pt  = 64'hffffffffffffffff;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h3000000000000000;
-pt  = 64'h1000000000000001;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h1111111111111111;
-pt  = 64'h1111111111111111;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h0123456789abcdef;
-pt  = 64'h1111111111111111;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h1111111111111111;
-pt  = 64'h0123456789abcdef;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h0000000000000000;
-pt  = 64'h0000000000000000;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'hfedcba9876543210;
-pt  = 64'h0123456789abcdef;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h7ca110454a1a6e57;
-pt  = 64'h01a1d6d039776742;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h0131d9619dc1376e;
-pt  = 64'h5cd54ca83def57da;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h07a1133e4a0b2686;
-pt  = 64'h0248d43806f67172;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h3849674c2602319e;
-pt  = 64'h51454b582ddf440a;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h04b915ba43feb5b6;
-pt  = 64'h42fd443059577fa2;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h0113b970fd34f2ce;
-pt  = 64'h059b5e0851cf143a;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h0170f175468fb5e6;
-pt  = 64'h0756d8e0774761d2;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h43297fad38e373fe;
-pt  = 64'h762514b829bf486a;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h07a7137045da2a16;
-pt  = 64'h3bdd119049372802;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h04689104c2fd3b2f;
-pt  = 64'h26955f6835af609a;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h37d06bb516cb7546;
-pt  = 64'h164d5e404f275232;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h1f08260d1ac2465e;
-pt  = 64'h6b056e18759f5cca;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h584023641aba6176;
-pt  = 64'h004bd6ef09176062;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-key = 64'h025816164629b007;
-pt  = 64'h480d39006ee762f2;
-for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end
-
-/*
-int testkeys[]= // key, pt, ct
-{
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8ca64de9, 0xc1b123a7,
-0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7359b216, 0x3e4edc58,
-0x30000000, 0x00000000, 0x10000000, 0x00000001, 0x958e6e62, 0x7a05557b,
-0x11111111, 0x11111111, 0x11111111, 0x11111111, 0xf40379ab, 0x9e0ec533,
-0x01234567, 0x89abcdef, 0x11111111, 0x11111111, 0x17668dfc, 0x7292532d,
-0x11111111, 0x11111111, 0x01234567, 0x89abcdef, 0x8a5ae1f8, 0x1ab8f2dd,
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8ca64de9, 0xc1b123a7,
-0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef, 0xed39d950, 0xfa74bcc4,
-0x7ca11045, 0x4a1a6e57, 0x01a1d6d0, 0x39776742, 0x690f5b0d, 0x9a26939b,
-0x0131d961, 0x9dc1376e, 0x5cd54ca8, 0x3def57da, 0x7a389d10, 0x354bd271,
-0x07a1133e, 0x4a0b2686, 0x0248d438, 0x06f67172, 0x868ebb51, 0xcab4599a,
-0x3849674c, 0x2602319e, 0x51454b58, 0x2ddf440a, 0x7178876e, 0x01f19b2a,
-0x04b915ba, 0x43feb5b6, 0x42fd4430, 0x59577fa2, 0xaf37fb42, 0x1f8c4095,
-0x0113b970, 0xfd34f2ce, 0x059b5e08, 0x51cf143a, 0x86a560f1, 0x0ec6d85b,
-0x0170f175, 0x468fb5e6, 0x0756d8e0, 0x774761d2, 0x0cd3da02, 0x0021dc09,
-0x43297fad, 0x38e373fe, 0x762514b8, 0x29bf486a, 0xea676b2c, 0xb7db2b7a,
-0x07a71370, 0x45da2a16, 0x3bdd1190, 0x49372802, 0xdfd64a81, 0x5caf1a0f,
-0x04689104, 0xc2fd3b2f, 0x26955f68, 0x35af609a, 0x5c513c9c, 0x4886c088,
-0x37d06bb5, 0x16cb7546, 0x164d5e40, 0x4f275232, 0x0a2aeeae, 0x3ff4ab77,
-0x1f08260d, 0x1ac2465e, 0x6b056e18, 0x759f5cca, 0xef1bf03e, 0x5dfa575a,
-0x58402364, 0x1aba6176, 0x004bd6ef, 0x09176062, 0x88bf0db6, 0xd70dee56,
-0x02581616, 0x4629b007, 0x480d3900, 0x6ee762f2, 0xa1f99155, 0x41020b56,
-0x49793ebc, 0x79b3258f, 0x437540c8, 0x698f3cfa, 0x6fbf1caf, 0xcffd0556,
-0x4fb05e15, 0x15ab73a7, 0x072d43a0, 0x77075292, 0x2f22e49b, 0xab7ca1ac,
-0x49e95d6d, 0x4ca229bf, 0x02fe5577, 0x8117f12a, 0x5a6b612c, 0xc26cce4a,
-0x018310dc, 0x409b26d6, 0x1d9d5c50, 0x18f728c2, 0x5f4c038e, 0xd12b2e41,
-0x1c587f1c, 0x13924fef, 0x30553228, 0x6d6f295a, 0x63fac0d0, 0x34d9f793,
-0x01010101, 0x01010101, 0x01234567, 0x89abcdef, 0x617b3a0c, 0xe8f07100,
-0x1f1f1f1f, 0x0e0e0e0e, 0x01234567, 0x89abcdef, 0xdb958605, 0xf8c8c606,
-0xe0fee0fe, 0xf1fef1fe, 0x01234567, 0x89abcdef, 0xedbfd1c6, 0x6c29ccc7,
-0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x355550b2, 0x150e2451,
-0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xcaaaaf4d, 0xeaf1dbae,
-0x01234567, 0x89abcdef, 0x00000000, 0x00000000, 0xd5d44ff7, 0x20683d0d,
-0xfedcba98, 0x76543210, 0xffffffff, 0xffffffff, 0x2a2bb008, 0xdf97c2f2,
-};
-*/
-
-end
-
-endmodule
-
-module des(pt, key, ct, clk);
-input	[1:64] pt;
-input	[1:64] key;
-output	[1:64] ct;
-input	clk;
-wire	[1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
-wire	[1:32] l0x,l1x,l2x,l3x,l4x,l5x,l6x,l7x,l8x,l9x,l10x,l11x,l12x,l13x,l14x,l15x,l16x;
-wire	[1:32] r0x,r1x,r2x,r3x,r4x,r5x,r6x,r7x,r8x,r9x,r10x,r11x,r12x,r13x,r14x,r15x,r16x;
-
-keysched keysched(key, k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x);
-ip ip(pt, l0x, r0x);
-roundfunc round1(clk, l0x, r0x, l1x, r1x, k1x);
-roundfunc round2(clk, l1x, r1x, l2x, r2x, k2x);
-roundfunc round3(clk, l2x, r2x, l3x, r3x, k3x);
-roundfunc round4(clk, l3x, r3x, l4x, r4x, k4x);
-roundfunc round5(clk, l4x, r4x, l5x, r5x, k5x);
-roundfunc round6(clk, l5x, r5x, l6x, r6x, k6x);
-roundfunc round7(clk, l6x, r6x, l7x, r7x, k7x);
-roundfunc round8(clk, l7x, r7x, l8x, r8x, k8x);
-roundfunc round9(clk, l8x, r8x, l9x, r9x, k9x);
-roundfunc round10(clk, l9x, r9x, l10x, r10x, k10x);
-roundfunc round11(clk, l10x, r10x, l11x, r11x, k11x);
-roundfunc round12(clk, l11x, r11x, l12x, r12x, k12x);
-roundfunc round13(clk, l12x, r12x, l13x, r13x, k13x);
-roundfunc round14(clk, l13x, r13x, l14x, r14x, k14x);
-roundfunc round15(clk, l14x, r14x, l15x, r15x, k15x);
-roundfunc round16(clk, l15x, r15x, l16x, r16x, k16x);
-fp fp(r16x, l16x, ct);
-
-endmodule
-
-
-module pc1(key, c0x, d0x);
-input	[1:64] key;
-output	[1:28] c0x, d0x;
-wire	[1:56] XX;
-
-assign XX[1]=key[57]; assign  XX[2]=key[49]; assign  XX[3]=key[41]; assign  XX[4]=key[33]; assign  XX[5]=key[25]; assign  XX[6]=key[17]; assign  XX[7]=key[9];
-assign XX[8]=key[1]; assign  XX[9]=key[58]; assign  XX[10]=key[50]; assign XX[11]=key[42]; assign XX[12]=key[34]; assign XX[13]=key[26]; assign XX[14]=key[18];
-assign XX[15]=key[10]; assign XX[16]=key[2]; assign  XX[17]=key[59]; assign XX[18]=key[51]; assign XX[19]=key[43]; assign XX[20]=key[35]; assign XX[21]=key[27];
-assign XX[22]=key[19]; assign XX[23]=key[11]; assign XX[24]=key[3]; assign  XX[25]=key[60]; assign XX[26]=key[52]; assign XX[27]=key[44]; assign XX[28]=key[36];
-assign XX[29]=key[63]; assign XX[30]=key[55]; assign XX[31]=key[47]; assign XX[32]=key[39]; assign XX[33]=key[31]; assign XX[34]=key[23]; assign XX[35]=key[15];
-assign XX[36]=key[7]; assign  XX[37]=key[62]; assign XX[38]=key[54]; assign XX[39]=key[46]; assign XX[40]=key[38]; assign XX[41]=key[30]; assign XX[42]=key[22];
-assign XX[43]=key[14]; assign XX[44]=key[6]; assign  XX[45]=key[61]; assign XX[46]=key[53]; assign XX[47]=key[45]; assign XX[48]=key[37]; assign XX[49]=key[29];
-assign XX[50]=key[21]; assign XX[51]=key[13]; assign XX[52]=key[5]; assign  XX[53]=key[28]; assign XX[54]=key[20]; assign XX[55]=key[12]; assign XX[56]=key[4];
-
-assign c0x=XX[1:28]; assign d0x=XX[29:56];
-
-endmodule
-
-
-module pc2(c,d,k);
-input	[1:28] c,d;
-output	[1:48] k;
-wire	[1:56] YY;
-
-        assign YY[1:28]=c;         assign YY[29:56]=d;
-
-        assign k[1]=YY[14];   assign k[2]=YY[17];   assign k[3]=YY[11];   assign k[4]=YY[24];   assign k[5]=YY[1];    assign k[6]=YY[5];
-        assign k[7]=YY[3];    assign k[8]=YY[28];   assign k[9]=YY[15];   assign k[10]=YY[6];   assign k[11]=YY[21];  assign k[12]=YY[10];
-        assign k[13]=YY[23];  assign k[14]=YY[19];  assign k[15]=YY[12];  assign k[16]=YY[4];   assign k[17]=YY[26];  assign k[18]=YY[8];
-        assign k[19]=YY[16];  assign k[20]=YY[7];   assign k[21]=YY[27];  assign k[22]=YY[20];  assign k[23]=YY[13];  assign k[24]=YY[2];
-        assign k[25]=YY[41];  assign k[26]=YY[52];  assign k[27]=YY[31];  assign k[28]=YY[37];  assign k[29]=YY[47];  assign k[30]=YY[55];
-        assign k[31]=YY[30];  assign k[32]=YY[40];  assign k[33]=YY[51];  assign k[34]=YY[45];  assign k[35]=YY[33];  assign k[36]=YY[48];
-        assign k[37]=YY[44];  assign k[38]=YY[49];  assign k[39]=YY[39];  assign k[40]=YY[56];  assign k[41]=YY[34];  assign k[42]=YY[53];
-        assign k[43]=YY[46];  assign k[44]=YY[42];  assign k[45]=YY[50];  assign k[46]=YY[36];  assign k[47]=YY[29];  assign k[48]=YY[32];
-endmodule
-
-
-module rol1(o, i);
-output	[1:28] o;
-input	[1:28] i;
-
-assign o={i[2:28],i[1]};
-
-endmodule
-
-
-module rol2(o, i);
-output	[1:28] o;
-input	[1:28] i;
-
-assign o={i[3:28],i[1:2]};
-endmodule
-
-
-module keysched(key,k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x);
-input	[1:64] key;
-output	[1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
-wire	[1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x;
-wire	[1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x;
-
-pc1 pc1(key, c0x, d0x);
-
-rol1 rc1(c1x, c0x); rol1 rd1(d1x, d0x);
-rol1 rc2(c2x, c1x); rol1 rd2(d2x, d1x);
-rol2 rc3(c3x, c2x); rol2 rd3(d3x, d2x);
-rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
-rol2 rc5(c5x, c4x); rol2 rd5(d5x, d4x);
-rol2 rc6(c6x, c5x); rol2 rd6(d6x, d5x);
-rol2 rc7(c7x, c6x); rol2 rd7(d7x, d6x);
-rol2 rc8(c8x, c7x); rol2 rd8(d8x, d7x);
-rol1 rc9(c9x, c8x); rol1 rd9(d9x, d8x);
-rol2 rca(c10x, c9x); rol2 rda(d10x, d9x);
-rol2 rcb(c11x, c10x); rol2 rdb(d11x, d10x);
-rol2 rcc(c12x, c11x); rol2 rdc(d12x, d11x);
-rol2 rcd(c13x, c12x); rol2 rdd(d13x, d12x);
-rol2 rce(c14x, c13x); rol2 rde(d14x, d13x);
-rol2 rcf(c15x, c14x); rol2 rdf(d15x, d14x);
-rol1 rcg(c16x, c15x); rol1 rdg(d16x, d15x);
-
-
-pc2 pc2x1(c1x,d1x,k1x);
-pc2 pc2x2(c2x,d2x,k2x);
-pc2 pc2x3(c3x,d3x,k3x);
-pc2 pc2x4(c4x,d4x,k4x);
-pc2 pc2x5(c5x,d5x,k5x);
-pc2 pc2x6(c6x,d6x,k6x);
-pc2 pc2x7(c7x,d7x,k7x);
-pc2 pc2x8(c8x,d8x,k8x);
-pc2 pc2x9(c9x,d9x,k9x);
-pc2 pc2x10(c10x,d10x,k10x);
-pc2 pc2x11(c11x,d11x,k11x);
-pc2 pc2x12(c12x,d12x,k12x);
-pc2 pc2x13(c13x,d13x,k13x);
-pc2 pc2x14(c14x,d14x,k14x);
-pc2 pc2x15(c15x,d15x,k15x);
-pc2 pc2x16(c16x,d16x,k16x);
-
-endmodule
-
-
-module s1(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-				6'b000000 :	so=4'he;
-				6'b000010 :	so=4'h4;
-				6'b000100 :	so=4'hd;
-				6'b000110 :	so=4'h1;
-				6'b001000 :	so=4'h2;
-				6'b001010 :	so=4'hf;
-				6'b001100 :	so=4'hb;
-				6'b001110 :	so=4'h8;
-				6'b010000 :	so=4'h3;
-				6'b010010 :	so=4'ha;
-				6'b010100 :	so=4'h6;
-				6'b010110 :	so=4'hc;
-				6'b011000 :	so=4'h5;
-				6'b011010 :	so=4'h9;
-				6'b011100 :	so=4'h0;
-				6'b011110 :	so=4'h7;
-				6'b000001 :	so=4'h0;
-				6'b000011 :	so=4'hf;
-				6'b000101 :	so=4'h7;
-				6'b000111 :	so=4'h4;
-				6'b001001 :	so=4'he;
-				6'b001011 :	so=4'h2;
-				6'b001101 :	so=4'hd;
-				6'b001111 :	so=4'h1;
-				6'b010001 :	so=4'ha;
-				6'b010011 :	so=4'h6;
-				6'b010101 :	so=4'hc;
-				6'b010111 :	so=4'hb;
-				6'b011001 :	so=4'h9;
-				6'b011011 :	so=4'h5;
-				6'b011101 :	so=4'h3;
-				6'b011111 :	so=4'h8;
-				6'b100000 :	so=4'h4;
-				6'b100010 :	so=4'h1;
-				6'b100100 :	so=4'he;
-				6'b100110 :	so=4'h8;
-				6'b101000 :	so=4'hd;
-				6'b101010 :	so=4'h6;
-				6'b101100 :	so=4'h2;
-				6'b101110 :	so=4'hb;
-				6'b110000 :	so=4'hf;
-				6'b110010 :	so=4'hc;
-				6'b110100 :	so=4'h9;
-				6'b110110 :	so=4'h7;
-				6'b111000 :	so=4'h3;
-				6'b111010 :	so=4'ha;
-				6'b111100 :	so=4'h5;
-				6'b111110 :	so=4'h0;
-				6'b100001 :	so=4'hf;
-				6'b100011 :	so=4'hc;
-				6'b100101 :	so=4'h8;
-				6'b100111 :	so=4'h2;
-				6'b101001 :	so=4'h4;
-				6'b101011 :	so=4'h9;
-				6'b101101 :	so=4'h1;
-				6'b101111 :	so=4'h7;
-				6'b110001 :	so=4'h5;
-				6'b110011 :	so=4'hb;
-				6'b110101 :	so=4'h3;
-				6'b110111 :	so=4'he;
-				6'b111001 :	so=4'ha;
-				6'b111011 :	so=4'h0;
-				6'b111101 :	so=4'h6;
-				default         so=4'hd;
-			endcase
-endmodule
-
-
-module s2(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'hf;
-                                6'b000010 :        so=4'h1;
-                                6'b000100 :        so=4'h8;
-                                6'b000110 :        so=4'he;
-                                6'b001000 :        so=4'h6;
-                                6'b001010 :        so=4'hb;
-                                6'b001100 :        so=4'h3;
-                                6'b001110 :        so=4'h4;
-                                6'b010000 :        so=4'h9;
-                                6'b010010 :        so=4'h7;
-                                6'b010100 :        so=4'h2;
-                                6'b010110 :        so=4'hd;
-                                6'b011000 :        so=4'hc;
-                                6'b011010 :        so=4'h0;
-                                6'b011100 :        so=4'h5;
-                                6'b011110 :        so=4'ha;
-                                6'b000001 :        so=4'h3;
-                                6'b000011 :        so=4'hd;
-                                6'b000101 :        so=4'h4;
-                                6'b000111 :        so=4'h7;
-                                6'b001001 :        so=4'hf;
-                                6'b001011 :        so=4'h2;
-                                6'b001101 :        so=4'h8;
-                                6'b001111 :        so=4'he;
-                                6'b010001 :        so=4'hc;
-                                6'b010011 :        so=4'h0;
-                                6'b010101 :        so=4'h1;
-                                6'b010111 :        so=4'ha;
-                                6'b011001 :        so=4'h6;
-                                6'b011011 :        so=4'h9;
-                                6'b011101 :        so=4'hb;
-                                6'b011111 :        so=4'h5;
-                                6'b100000 :        so=4'h0;
-                                6'b100010 :        so=4'he;
-                                6'b100100 :        so=4'h7;
-                                6'b100110 :        so=4'hb;
-                                6'b101000 :        so=4'ha;
-                                6'b101010 :        so=4'h4;
-                                6'b101100 :        so=4'hd;
-                                6'b101110 :        so=4'h1;
-                                6'b110000 :        so=4'h5;
-                                6'b110010 :        so=4'h8;
-                                6'b110100 :        so=4'hc;
-                                6'b110110 :        so=4'h6;
-                                6'b111000 :        so=4'h9;
-                                6'b111010 :        so=4'h3;
-                                6'b111100 :        so=4'h2;
-                                6'b111110 :        so=4'hf;
-                                6'b100001 :        so=4'hd;
-                                6'b100011 :        so=4'h8;
-                                6'b100101 :        so=4'ha;
-                                6'b100111 :        so=4'h1;
-                                6'b101001 :        so=4'h3;
-                                6'b101011 :        so=4'hf;
-                                6'b101101 :        so=4'h4;
-                                6'b101111 :        so=4'h2;
-                                6'b110001 :        so=4'hb;
-                                6'b110011 :        so=4'h6;
-                                6'b110101 :        so=4'h7;
-                                6'b110111 :        so=4'hc;
-                                6'b111001 :        so=4'h0;
-                                6'b111011 :        so=4'h5;
-                                6'b111101 :        so=4'he;
-                                default            so=4'h9;
-			endcase
-endmodule
-
-
-module s3(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'ha;
-                                6'b000010 :        so=4'h0;
-                                6'b000100 :        so=4'h9;
-                                6'b000110 :        so=4'he;
-                                6'b001000 :        so=4'h6;
-                                6'b001010 :        so=4'h3;
-                                6'b001100 :        so=4'hf;
-                                6'b001110 :        so=4'h5;
-                                6'b010000 :        so=4'h1;
-                                6'b010010 :        so=4'hd;
-                                6'b010100 :        so=4'hc;
-                                6'b010110 :        so=4'h7;
-                                6'b011000 :        so=4'hb;
-                                6'b011010 :        so=4'h4;
-                                6'b011100 :        so=4'h2;
-                                6'b011110 :        so=4'h8;
-                                6'b000001 :        so=4'hd;
-                                6'b000011 :        so=4'h7;
-                                6'b000101 :        so=4'h0;
-                                6'b000111 :        so=4'h9;
-                                6'b001001 :        so=4'h3;
-                                6'b001011 :        so=4'h4;
-                                6'b001101 :        so=4'h6;
-                                6'b001111 :        so=4'ha;
-                                6'b010001 :        so=4'h2;
-                                6'b010011 :        so=4'h8;
-                                6'b010101 :        so=4'h5;
-                                6'b010111 :        so=4'he;
-                                6'b011001 :        so=4'hc;
-                                6'b011011 :        so=4'hb;
-                                6'b011101 :        so=4'hf;
-                                6'b011111 :        so=4'h1;
-                                6'b100000 :        so=4'hd;
-                                6'b100010 :        so=4'h6;
-                                6'b100100 :        so=4'h4;
-                                6'b100110 :        so=4'h9;
-                                6'b101000 :        so=4'h8;
-                                6'b101010 :        so=4'hf;
-                                6'b101100 :        so=4'h3;
-                                6'b101110 :        so=4'h0;
-                                6'b110000 :        so=4'hb;
-                                6'b110010 :        so=4'h1;
-                                6'b110100 :        so=4'h2;
-                                6'b110110 :        so=4'hc;
-                                6'b111000 :        so=4'h5;
-                                6'b111010 :        so=4'ha;
-                                6'b111100 :        so=4'he;
-                                6'b111110 :        so=4'h7;
-                                6'b100001 :        so=4'h1;
-                                6'b100011 :        so=4'ha;
-                                6'b100101 :        so=4'hd;
-                                6'b100111 :        so=4'h0;
-                                6'b101001 :        so=4'h6;
-                                6'b101011 :        so=4'h9;
-                                6'b101101 :        so=4'h8;
-                                6'b101111 :        so=4'h7;
-                                6'b110001 :        so=4'h4;
-                                6'b110011 :        so=4'hf;
-                                6'b110101 :        so=4'he;
-                                6'b110111 :        so=4'h3;
-                                6'b111001 :        so=4'hb;
-                                6'b111011 :        so=4'h5;
-                                6'b111101 :        so=4'h2;
-                                default            so=4'hc;
-			endcase
-endmodule
-
-
-module s4(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'h7;
-                                6'b000010 :        so=4'hd;
-                                6'b000100 :        so=4'he;
-                                6'b000110 :        so=4'h3;
-                                6'b001000 :        so=4'h0;
-                                6'b001010 :        so=4'h6;
-                                6'b001100 :        so=4'h9;
-                                6'b001110 :        so=4'ha;
-                                6'b010000 :        so=4'h1;
-                                6'b010010 :        so=4'h2;
-                                6'b010100 :        so=4'h8;
-                                6'b010110 :        so=4'h5;
-                                6'b011000 :        so=4'hb;
-                                6'b011010 :        so=4'hc;
-                                6'b011100 :        so=4'h4;
-                                6'b011110 :        so=4'hf;
-                                6'b000001 :        so=4'hd;
-                                6'b000011 :        so=4'h8;
-                                6'b000101 :        so=4'hb;
-                                6'b000111 :        so=4'h5;
-                                6'b001001 :        so=4'h6;
-                                6'b001011 :        so=4'hf;
-                                6'b001101 :        so=4'h0;
-                                6'b001111 :        so=4'h3;
-                                6'b010001 :        so=4'h4;
-                                6'b010011 :        so=4'h7;
-                                6'b010101 :        so=4'h2;
-                                6'b010111 :        so=4'hc;
-                                6'b011001 :        so=4'h1;
-                                6'b011011 :        so=4'ha;
-                                6'b011101 :        so=4'he;
-                                6'b011111 :        so=4'h9;
-                                6'b100000 :        so=4'ha;
-                                6'b100010 :        so=4'h6;
-                                6'b100100 :        so=4'h9;
-                                6'b100110 :        so=4'h0;
-                                6'b101000 :        so=4'hc;
-                                6'b101010 :        so=4'hb;
-                                6'b101100 :        so=4'h7;
-                                6'b101110 :        so=4'hd;
-                                6'b110000 :        so=4'hf;
-                                6'b110010 :        so=4'h1;
-                                6'b110100 :        so=4'h3;
-                                6'b110110 :        so=4'he;
-                                6'b111000 :        so=4'h5;
-                                6'b111010 :        so=4'h2;
-                                6'b111100 :        so=4'h8;
-                                6'b111110 :        so=4'h4;
-                                6'b100001 :        so=4'h3;
-                                6'b100011 :        so=4'hf;
-                                6'b100101 :        so=4'h0;
-                                6'b100111 :        so=4'h6;
-                                6'b101001 :        so=4'ha;
-                                6'b101011 :        so=4'h1;
-                                6'b101101 :        so=4'hd;
-                                6'b101111 :        so=4'h8;
-                                6'b110001 :        so=4'h9;
-                                6'b110011 :        so=4'h4;
-                                6'b110101 :        so=4'h5;
-                                6'b110111 :        so=4'hb;
-                                6'b111001 :        so=4'hc;
-                                6'b111011 :        so=4'h7;
-                                6'b111101 :        so=4'h2;
-                                default            so=4'he;
-			endcase
-endmodule
-
-
-module s5(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'h2;
-                                6'b000010 :        so=4'hc;
-                                6'b000100 :        so=4'h4;
-                                6'b000110 :        so=4'h1;
-                                6'b001000 :        so=4'h7;
-                                6'b001010 :        so=4'ha;
-                                6'b001100 :        so=4'hb;
-                                6'b001110 :        so=4'h6;
-                                6'b010000 :        so=4'h8;
-                                6'b010010 :        so=4'h5;
-                                6'b010100 :        so=4'h3;
-                                6'b010110 :        so=4'hf;
-                                6'b011000 :        so=4'hd;
-                                6'b011010 :        so=4'h0;
-                                6'b011100 :        so=4'he;
-                                6'b011110 :        so=4'h9;
-                                6'b000001 :        so=4'he;
-                                6'b000011 :        so=4'hb;
-                                6'b000101 :        so=4'h2;
-                                6'b000111 :        so=4'hc;
-                                6'b001001 :        so=4'h4;
-                                6'b001011 :        so=4'h7;
-                                6'b001101 :        so=4'hd;
-                                6'b001111 :        so=4'h1;
-                                6'b010001 :        so=4'h5;
-                                6'b010011 :        so=4'h0;
-                                6'b010101 :        so=4'hf;
-                                6'b010111 :        so=4'ha;
-                                6'b011001 :        so=4'h3;
-                                6'b011011 :        so=4'h9;
-                                6'b011101 :        so=4'h8;
-                                6'b011111 :        so=4'h6;
-                                6'b100000 :        so=4'h4;
-                                6'b100010 :        so=4'h2;
-                                6'b100100 :        so=4'h1;
-                                6'b100110 :        so=4'hb;
-                                6'b101000 :        so=4'ha;
-                                6'b101010 :        so=4'hd;
-                                6'b101100 :        so=4'h7;
-                                6'b101110 :        so=4'h8;
-                                6'b110000 :        so=4'hf;
-                                6'b110010 :        so=4'h9;
-                                6'b110100 :        so=4'hc;
-                                6'b110110 :        so=4'h5;
-                                6'b111000 :        so=4'h6;
-                                6'b111010 :        so=4'h3;
-                                6'b111100 :        so=4'h0;
-                                6'b111110 :        so=4'he;
-                                6'b100001 :        so=4'hb;
-                                6'b100011 :        so=4'h8;
-                                6'b100101 :        so=4'hc;
-                                6'b100111 :        so=4'h7;
-                                6'b101001 :        so=4'h1;
-                                6'b101011 :        so=4'he;
-                                6'b101101 :        so=4'h2;
-                                6'b101111 :        so=4'hd;
-                                6'b110001 :        so=4'h6;
-                                6'b110011 :        so=4'hf;
-                                6'b110101 :        so=4'h0;
-                                6'b110111 :        so=4'h9;
-                                6'b111001 :        so=4'ha;
-                                6'b111011 :        so=4'h4;
-                                6'b111101 :        so=4'h5;
-                                default            so=4'h3;
-			endcase
-endmodule
-
-
-module s6(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'hc;
-                                6'b000010 :        so=4'h1;
-                                6'b000100 :        so=4'ha;
-                                6'b000110 :        so=4'hf;
-                                6'b001000 :        so=4'h9;
-                                6'b001010 :        so=4'h2;
-                                6'b001100 :        so=4'h6;
-                                6'b001110 :        so=4'h8;
-                                6'b010000 :        so=4'h0;
-                                6'b010010 :        so=4'hd;
-                                6'b010100 :        so=4'h3;
-                                6'b010110 :        so=4'h4;
-                                6'b011000 :        so=4'he;
-                                6'b011010 :        so=4'h7;
-                                6'b011100 :        so=4'h5;
-                                6'b011110 :        so=4'hb;
-                                6'b000001 :        so=4'ha;
-                                6'b000011 :        so=4'hf;
-                                6'b000101 :        so=4'h4;
-                                6'b000111 :        so=4'h2;
-                                6'b001001 :        so=4'h7;
-                                6'b001011 :        so=4'hc;
-                                6'b001101 :        so=4'h9;
-                                6'b001111 :        so=4'h5;
-                                6'b010001 :        so=4'h6;
-                                6'b010011 :        so=4'h1;
-                                6'b010101 :        so=4'hd;
-                                6'b010111 :        so=4'he;
-                                6'b011001 :        so=4'h0;
-                                6'b011011 :        so=4'hb;
-                                6'b011101 :        so=4'h3;
-                                6'b011111 :        so=4'h8;
-                                6'b100000 :        so=4'h9;
-                                6'b100010 :        so=4'he;
-                                6'b100100 :        so=4'hf;
-                                6'b100110 :        so=4'h5;
-                                6'b101000 :        so=4'h2;
-                                6'b101010 :        so=4'h8;
-                                6'b101100 :        so=4'hc;
-                                6'b101110 :        so=4'h3;
-                                6'b110000 :        so=4'h7;
-                                6'b110010 :        so=4'h0;
-                                6'b110100 :        so=4'h4;
-                                6'b110110 :        so=4'ha;
-                                6'b111000 :        so=4'h1;
-                                6'b111010 :        so=4'hd;
-                                6'b111100 :        so=4'hb;
-                                6'b111110 :        so=4'h6;
-                                6'b100001 :        so=4'h4;
-                                6'b100011 :        so=4'h3;
-                                6'b100101 :        so=4'h2;
-                                6'b100111 :        so=4'hc;
-                                6'b101001 :        so=4'h9;
-                                6'b101011 :        so=4'h5;
-                                6'b101101 :        so=4'hf;
-                                6'b101111 :        so=4'ha;
-                                6'b110001 :        so=4'hb;
-                                6'b110011 :        so=4'he;
-                                6'b110101 :        so=4'h1;
-                                6'b110111 :        so=4'h7;
-                                6'b111001 :        so=4'h6;
-                                6'b111011 :        so=4'h0;
-                                6'b111101 :        so=4'h8;
-                                default            so=4'hd;
-			endcase
-endmodule
-
-
-module s7(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'h4;
-                                6'b000010 :        so=4'hb;
-                                6'b000100 :        so=4'h2;
-                                6'b000110 :        so=4'he;
-                                6'b001000 :        so=4'hf;
-                                6'b001010 :        so=4'h0;
-                                6'b001100 :        so=4'h8;
-                                6'b001110 :        so=4'hd;
-                                6'b010000 :        so=4'h3;
-                                6'b010010 :        so=4'hc;
-                                6'b010100 :        so=4'h9;
-                                6'b010110 :        so=4'h7;
-                                6'b011000 :        so=4'h5;
-                                6'b011010 :        so=4'ha;
-                                6'b011100 :        so=4'h6;
-                                6'b011110 :        so=4'h1;
-                                6'b000001 :        so=4'hd;
-                                6'b000011 :        so=4'h0;
-                                6'b000101 :        so=4'hb;
-                                6'b000111 :        so=4'h7;
-                                6'b001001 :        so=4'h4;
-                                6'b001011 :        so=4'h9;
-                                6'b001101 :        so=4'h1;
-                                6'b001111 :        so=4'ha;
-                                6'b010001 :        so=4'he;
-                                6'b010011 :        so=4'h3;
-                                6'b010101 :        so=4'h5;
-                                6'b010111 :        so=4'hc;
-                                6'b011001 :        so=4'h2;
-                                6'b011011 :        so=4'hf;
-                                6'b011101 :        so=4'h8;
-                                6'b011111 :        so=4'h6;
-                                6'b100000 :        so=4'h1;
-                                6'b100010 :        so=4'h4;
-                                6'b100100 :        so=4'hb;
-                                6'b100110 :        so=4'hd;
-                                6'b101000 :        so=4'hc;
-                                6'b101010 :        so=4'h3;
-                                6'b101100 :        so=4'h7;
-                                6'b101110 :        so=4'he;
-                                6'b110000 :        so=4'ha;
-                                6'b110010 :        so=4'hf;
-                                6'b110100 :        so=4'h6;
-                                6'b110110 :        so=4'h8;
-                                6'b111000 :        so=4'h0;
-                                6'b111010 :        so=4'h5;
-                                6'b111100 :        so=4'h9;
-                                6'b111110 :        so=4'h2;
-                                6'b100001 :        so=4'h6;
-                                6'b100011 :        so=4'hb;
-                                6'b100101 :        so=4'hd;
-                                6'b100111 :        so=4'h8;
-                                6'b101001 :        so=4'h1;
-                                6'b101011 :        so=4'h4;
-                                6'b101101 :        so=4'ha;
-                                6'b101111 :        so=4'h7;
-                                6'b110001 :        so=4'h9;
-                                6'b110011 :        so=4'h5;
-                                6'b110101 :        so=4'h0;
-                                6'b110111 :        so=4'hf;
-                                6'b111001 :        so=4'he;
-                                6'b111011 :        so=4'h2;
-                                6'b111101 :        so=4'h3;
-                                default            so=4'hc;
-			endcase
-endmodule
-
-
-module s8(clk, b, so);
-input	clk;
-input	[1:6] b;
-output	[1:4] so;
-reg	[1:4] so;
-
-	always @(posedge clk)
-		casex(b)
-                                6'b000000 :        so=4'hd;
-                                6'b000010 :        so=4'h2;
-                                6'b000100 :        so=4'h8;
-                                6'b000110 :        so=4'h4;
-                                6'b001000 :        so=4'h6;
-                                6'b001010 :        so=4'hf;
-                                6'b001100 :        so=4'hb;
-                                6'b001110 :        so=4'h1;
-                                6'b010000 :        so=4'ha;
-                                6'b010010 :        so=4'h9;
-                                6'b010100 :        so=4'h3;
-                                6'b010110 :        so=4'he;
-                                6'b011000 :        so=4'h5;
-                                6'b011010 :        so=4'h0;
-                                6'b011100 :        so=4'hc;
-                                6'b011110 :        so=4'h7;
-                                6'b000001 :        so=4'h1;
-                                6'b000011 :        so=4'hf;
-                                6'b000101 :        so=4'hd;
-                                6'b000111 :        so=4'h8;
-                                6'b001001 :        so=4'ha;
-                                6'b001011 :        so=4'h3;
-                                6'b001101 :        so=4'h7;
-                                6'b001111 :        so=4'h4;
-                                6'b010001 :        so=4'hc;
-                                6'b010011 :        so=4'h5;
-                                6'b010101 :        so=4'h6;
-                                6'b010111 :        so=4'hb;
-                                6'b011001 :        so=4'h0;
-                                6'b011011 :        so=4'he;
-                                6'b011101 :        so=4'h9;
-                                6'b011111 :        so=4'h2;
-                                6'b100000 :        so=4'h7;
-                                6'b100010 :        so=4'hb;
-                                6'b100100 :        so=4'h4;
-                                6'b100110 :        so=4'h1;
-                                6'b101000 :        so=4'h9;
-                                6'b101010 :        so=4'hc;
-                                6'b101100 :        so=4'he;
-                                6'b101110 :        so=4'h2;
-                                6'b110000 :        so=4'h0;
-                                6'b110010 :        so=4'h6;
-                                6'b110100 :        so=4'ha;
-                                6'b110110 :        so=4'hd;
-                                6'b111000 :        so=4'hf;
-                                6'b111010 :        so=4'h3;
-                                6'b111100 :        so=4'h5;
-                                6'b111110 :        so=4'h8;
-                                6'b100001 :        so=4'h2;
-                                6'b100011 :        so=4'h1;
-                                6'b100101 :        so=4'he;
-                                6'b100111 :        so=4'h7;
-                                6'b101001 :        so=4'h4;
-                                6'b101011 :        so=4'ha;
-                                6'b101101 :        so=4'h8;
-                                6'b101111 :        so=4'hd;
-                                6'b110001 :        so=4'hf;
-                                6'b110011 :        so=4'hc;
-                                6'b110101 :        so=4'h9;
-                                6'b110111 :        so=4'h0;
-                                6'b111001 :        so=4'h3;
-                                6'b111011 :        so=4'h5;
-                                6'b111101 :        so=4'h6;
-                                default            so=4'hb;
-			endcase
-endmodule
-
-
-module ip(pt, l0x, r0x);
-input	[1:64] pt;
-output	[1:32] l0x, r0x;
-
-assign l0x[1]=pt[58];         assign l0x[2]=pt[50];         assign l0x[3]=pt[42];         assign l0x[4]=pt[34];
-assign l0x[5]=pt[26];         assign l0x[6]=pt[18];         assign l0x[7]=pt[10];         assign l0x[8]=pt[2];
-assign l0x[9]=pt[60];         assign l0x[10]=pt[52];        assign l0x[11]=pt[44];        assign l0x[12]=pt[36];
-assign l0x[13]=pt[28];        assign l0x[14]=pt[20];        assign l0x[15]=pt[12];        assign l0x[16]=pt[4];
-assign l0x[17]=pt[62];        assign l0x[18]=pt[54];        assign l0x[19]=pt[46];        assign l0x[20]=pt[38];
-assign l0x[21]=pt[30];        assign l0x[22]=pt[22];        assign l0x[23]=pt[14];        assign l0x[24]=pt[6];
-assign l0x[25]=pt[64];        assign l0x[26]=pt[56];        assign l0x[27]=pt[48];        assign l0x[28]=pt[40];
-assign l0x[29]=pt[32];        assign l0x[30]=pt[24];        assign l0x[31]=pt[16];        assign l0x[32]=pt[8];
-
-assign r0x[1]=pt[57];         assign r0x[2]=pt[49];         assign r0x[3]=pt[41];         assign r0x[4]=pt[33];
-assign r0x[5]=pt[25];         assign r0x[6]=pt[17];         assign r0x[7]=pt[9];          assign r0x[8]=pt[1];
-assign r0x[9]=pt[59];         assign r0x[10]=pt[51];        assign r0x[11]=pt[43];        assign r0x[12]=pt[35];
-assign r0x[13]=pt[27];        assign r0x[14]=pt[19];        assign r0x[15]=pt[11];        assign r0x[16]=pt[3];
-assign r0x[17]=pt[61];        assign r0x[18]=pt[53];        assign r0x[19]=pt[45];        assign r0x[20]=pt[37];
-assign r0x[21]=pt[29];        assign r0x[22]=pt[21];        assign r0x[23]=pt[13];        assign r0x[24]=pt[5];
-assign r0x[25]=pt[63];        assign r0x[26]=pt[55];        assign r0x[27]=pt[47];        assign r0x[28]=pt[39];
-assign r0x[29]=pt[31];        assign r0x[30]=pt[23];        assign r0x[31]=pt[15];        assign r0x[32]=pt[7];
-
-endmodule
-
-
-module xp(ri, e);
-input [1:32] ri;
-output [1:48] e;
-
-assign e[1]=ri[32];   assign e[2]=ri[1];    assign e[3]=ri[2];    assign e[4]=ri[3];    assign e[5]=ri[4];    assign e[6]=ri[5];    assign e[7]=ri[4];    assign e[8]=ri[5];
-assign e[9]=ri[6];    assign e[10]=ri[7];   assign e[11]=ri[8];   assign e[12]=ri[9];   assign e[13]=ri[8];   assign e[14]=ri[9];   assign e[15]=ri[10];  assign e[16]=ri[11];
-assign e[17]=ri[12];  assign e[18]=ri[13];  assign e[19]=ri[12];  assign e[20]=ri[13];  assign e[21]=ri[14];  assign e[22]=ri[15];  assign e[23]=ri[16];  assign e[24]=ri[17];
-assign e[25]=ri[16];  assign e[26]=ri[17];  assign e[27]=ri[18];  assign e[28]=ri[19];  assign e[29]=ri[20];  assign e[30]=ri[21];  assign e[31]=ri[20];  assign e[32]=ri[21];
-assign e[33]=ri[22];  assign e[34]=ri[23];  assign e[35]=ri[24];  assign e[36]=ri[25];  assign e[37]=ri[24];  assign e[38]=ri[25];  assign e[39]=ri[26];  assign e[40]=ri[27];
-assign e[41]=ri[28];  assign e[42]=ri[29];  assign e[43]=ri[28];  assign e[44]=ri[29];  assign e[45]=ri[30];  assign e[46]=ri[31];  assign e[47]=ri[32];  assign e[48]=ri[1];
-
-endmodule
-
-
-module desxor1(e,b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x,k);
-input	[1:48] e;
-output	[1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x;
-input	[1:48] k;
-wire	[1:48] XX;
-
-assign         XX = k ^ e;
-assign        b1x = XX[1:6];
-assign        b2x = XX[7:12];
-assign        b3x = XX[13:18];
-assign        b4x = XX[19:24];
-assign        b5x = XX[25:30];
-assign        b6x = XX[31:36];
-assign        b7x = XX[37:42];
-assign        b8x = XX[43:48];
-
-endmodule
-
-
-module pp(so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x,ppo);
-input	[1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x;
-output	[1:32] ppo;
-wire	[1:32] XX;
-
-        assign XX[1:4]=so1x;       assign XX[5:8]=so2x;       assign XX[9:12]=so3x;      assign XX[13:16]=so4x;
-        assign XX[17:20]=so5x;     assign XX[21:24]=so6x;     assign XX[25:28]=so7x;     assign XX[29:32]=so8x;
-
-        assign ppo[1]=XX[16];         assign ppo[2]=XX[7];          assign ppo[3]=XX[20];         assign ppo[4]=XX[21];
-        assign ppo[5]=XX[29];         assign ppo[6]=XX[12];         assign ppo[7]=XX[28];         assign ppo[8]=XX[17];
-        assign ppo[9]=XX[1];          assign ppo[10]=XX[15];        assign ppo[11]=XX[23];        assign ppo[12]=XX[26];
-        assign ppo[13]=XX[5];         assign ppo[14]=XX[18];        assign ppo[15]=XX[31];        assign ppo[16]=XX[10];
-        assign ppo[17]=XX[2];         assign ppo[18]=XX[8];         assign ppo[19]=XX[24];        assign ppo[20]=XX[14];
-        assign ppo[21]=XX[32];        assign ppo[22]=XX[27];        assign ppo[23]=XX[3];         assign ppo[24]=XX[9];
-        assign ppo[25]=XX[19];        assign ppo[26]=XX[13];        assign ppo[27]=XX[30];        assign ppo[28]=XX[6];
-        assign ppo[29]=XX[22];        assign ppo[30]=XX[11];        assign ppo[31]=XX[4];         assign ppo[32]=XX[25];
-
-endmodule
-
-
-module desxor2(d,l,q);
-input	[1:32] d,l;
-output	[1:32] q;
-
-assign q = d ^ l;
-
-endmodule
-
-
-module roundfunc(clk, li, ri, lo, ro, k);
-input	clk;
-input	[1:32] li, ri;
-input	[1:48] k;
-output	[1:32] lo, ro;
-
-wire	[1:48] e;
-wire	[1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x;
-wire	[1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x;
-wire	[1:32] ppo;
-
-xp xp(ri, e);
-desxor1 desxor1(e, b1x, b2x, b3x, b4x, b5x, b6x, b7x, b8x, k);
-s1 s1(clk, b1x, so1x);
-s2 s2(clk, b2x, so2x);
-s3 s3(clk, b3x, so3x);
-s4 s4(clk, b4x, so4x);
-s5 s5(clk, b5x, so5x);
-s6 s6(clk, b6x, so6x);
-s7 s7(clk, b7x, so7x);
-s8 s8(clk, b8x, so8x);
-pp pp(so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x, ppo);
-desxor2 desxor2(ppo, li, ro);
-
-assign lo=ri;
-
-endmodule
-
-
-module fp(l,r,ct);
-input	[1:32] l,r;
-output	[1:64] ct;
-
-	assign ct[1]=r[8];	assign ct[2]=l[8];	assign ct[3]=r[16];	assign ct[4]=l[16];	assign ct[5]=r[24];	assign ct[6]=l[24];	assign ct[7]=r[32];	assign ct[8]=l[32];
-	assign ct[9]=r[7];	assign ct[10]=l[7];	assign ct[11]=r[15];	assign ct[12]=l[15];	assign ct[13]=r[23];	assign ct[14]=l[23];	assign ct[15]=r[31];	assign ct[16]=l[31];
-	assign ct[17]=r[6];	assign ct[18]=l[6];	assign ct[19]=r[14];	assign ct[20]=l[14];	assign ct[21]=r[22];	assign ct[22]=l[22];	assign ct[23]=r[30];	assign ct[24]=l[30];
-	assign ct[25]=r[5];	assign ct[26]=l[5];	assign ct[27]=r[13];	assign ct[28]=l[13];	assign ct[29]=r[21];	assign ct[30]=l[21];	assign ct[31]=r[29];	assign ct[32]=l[29];
-	assign ct[33]=r[4];	assign ct[34]=l[4];	assign ct[35]=r[12];	assign ct[36]=l[12];	assign ct[37]=r[20];	assign ct[38]=l[20];	assign ct[39]=r[28];	assign ct[40]=l[28];
-	assign ct[41]=r[3];	assign ct[42]=l[3];	assign ct[43]=r[11];	assign ct[44]=l[11];	assign ct[45]=r[19];	assign ct[46]=l[19];	assign ct[47]=r[27];	assign ct[48]=l[27];
-	assign ct[49]=r[2];	assign ct[50]=l[2];	assign ct[51]=r[10];	assign ct[52]=l[10];	assign ct[53]=r[18];	assign ct[54]=l[18];	assign ct[55]=r[26];	assign ct[56]=l[26];
-	assign ct[57]=r[1];	assign ct[58]=l[1];	assign ct[59]=r[9];	assign ct[60]=l[9];	assign ct[61]=r[17];	assign ct[62]=l[17];	assign ct[63]=r[25];	assign ct[64]=l[25];
-
-endmodule
-
-
diff --git a/ivlpp/Makefile.in b/ivlpp/Makefile.in
index a26ee0c..f546c25 100644
--- a/ivlpp/Makefile.in
+++ b/ivlpp/Makefile.in
@@ -3,9 +3,7 @@
 #    and/or modify it in source code form under the terms of the GNU
 #    Library General Public License as published by the Free Software
 #    Foundation; either version 2 of the License, or (at your option)
-#    any later version. In order to redistribute the software in
-#    binary form, you will need a Picture Elements Binary Software
-#    License.
+#    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
diff --git a/parse.y b/parse.y
index fcbecce..edfc53c 100644
--- a/parse.y
+++ b/parse.y
@@ -2093,7 +2093,6 @@ module_item
 			yyerror(@6, "sorry: net delays not supported.");
 			delete $6;
 		  }
-		  if ($1) delete $1;
 		}
 
   /* Very similar to the rule above, but this takes a list of
@@ -2140,58 +2139,55 @@ module_item
 		  delete $4;
 		}
 
-	| port_type signed_opt range_opt delay3_opt list_of_identifiers ';'
-		{ pform_set_port_type(@1, $5, $3, $2, $1);
-		}
+  | attribute_list_opt port_type signed_opt range_opt delay3_opt list_of_identifiers ';'
+      { pform_set_port_type(@2, $6, $4, $3, $2, $1); }
 
   /* The next two rules handle Verilog 2001 statements of the form:
        input wire signed [h:l] <list>;
      This creates the wire and sets the port type all at once. */
 
-	| port_type net_type signed_opt range_opt list_of_identifiers ';'
-		{ pform_makewire(@1, $4, $3, $5, $2, $1, IVL_VT_NO_TYPE, 0,
-		                 SR_BOTH);
-		}
+  | attribute_list_opt port_type net_type signed_opt range_opt list_of_identifiers ';'
+      { pform_makewire(@2, $5, $4, $6, $3, $2, IVL_VT_NO_TYPE, $1, SR_BOTH); }
 
-	| K_output var_type signed_opt range_opt list_of_port_identifiers ';'
-		{ list<pair<perm_string,PExpr*> >::const_iterator pp;
-		  list<perm_string>*tmp = new list<perm_string>;
-		  for (pp = $5->begin(); pp != $5->end(); pp++) {
-			tmp->push_back((*pp).first);
-		  }
-		  pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT,
-		                 IVL_VT_NO_TYPE, 0, SR_BOTH);
-		  for (pp = $5->begin(); pp != $5->end(); pp++) {
-			if ((*pp).second) {
-			      pform_make_reginit(@1, (*pp).first, (*pp).second);
-			}
-		  }
-		  delete $5;
-		}
+  | attribute_list_opt K_output var_type signed_opt range_opt list_of_port_identifiers ';'
+      { list<pair<perm_string,PExpr*> >::const_iterator pp;
+	list<perm_string>*tmp = new list<perm_string>;
+	for (pp = $6->begin(); pp != $6->end(); ++ pp ) {
+	      tmp->push_back((*pp).first);
+	}
+	pform_makewire(@2, $5, $4, tmp, $3, NetNet::POUTPUT,
+		       IVL_VT_NO_TYPE, $1, SR_BOTH);
+	for (pp = $6->begin(); pp != $6->end(); ++ pp ) {
+	      if ((*pp).second) {
+		   pform_make_reginit(@2, (*pp).first, (*pp).second);
+	      }
+	}
+	delete $6;
+      }
 
   /* var_type declaration (reg variables) cannot be input or output,
      because the port declaration implies an external driver, which
      cannot be attached to a reg. These rules catch that error early. */
 
-	| K_input var_type signed_opt range_opt list_of_identifiers ';'
-		{ pform_makewire(@1, $4, $3, $5, $2, NetNet::PINPUT,
-				 IVL_VT_NO_TYPE, 0);
-		  yyerror(@2, "error: reg variables cannot be inputs.");
-		}
+  | attribute_list_opt K_input var_type signed_opt range_opt list_of_identifiers ';'
+      { pform_makewire(@2, $5, $4, $6, $3, NetNet::PINPUT,
+		       IVL_VT_NO_TYPE, $1);
+	yyerror(@3, "error: reg variables cannot be inputs.");
+      }
 
-	| K_inout var_type signed_opt range_opt list_of_identifiers ';'
-		{ pform_makewire(@1, $4, $3, $5, $2, NetNet::PINOUT,
-				 IVL_VT_NO_TYPE, 0);
-		  yyerror(@2, "error: reg variables cannot be inouts.");
-		}
+  | attribute_list_opt K_inout var_type signed_opt range_opt list_of_identifiers ';'
+      { pform_makewire(@2, $5, $4, $6, $3, NetNet::PINOUT,
+		       IVL_VT_NO_TYPE, $1);
+	yyerror(@3, "error: reg variables cannot be inouts.");
+      }
 
-	| port_type signed_opt range_opt delay3_opt error ';'
-		{ yyerror(@1, "error: Invalid variable list"
-			  " in port declaration.");
-		  if ($3) delete $3;
-		  if ($4) delete $4;
-		  yyerrok;
-		}
+  | attribute_list_opt port_type signed_opt range_opt delay3_opt error ';'
+      { yyerror(@2, "error: Invalid variable list in port declaration.");
+	if ($1) delete $1;
+	if ($4) delete $4;
+	if ($5) delete $5;
+	yyerrok;
+      }
 
   /* Maybe this is a discipline declaration? If so, then the lexor
      will see the discipline name as an identifier. We match it to the
@@ -2636,7 +2632,7 @@ var_type
 	;
 
 param_type
-  : 
+  :
       { param_active_range = 0;
 	param_active_signed = false;
 	param_active_type = IVL_VT_LOGIC;
@@ -2687,7 +2683,7 @@ param_type
       }
   ;
 
-  /* parameter and localparam assignment lists are broken into 
+  /* parameter and localparam assignment lists are broken into
      separate BNF so that I can call slightly different parameter
      handling code. localparams parse the same as parameters, they
      just behave differently when someone tries to override them. */
diff --git a/pform.cc b/pform.cc
index 6f3f2f4..3dc8d1e 100644
--- a/pform.cc
+++ b/pform.cc
@@ -1094,7 +1094,8 @@ static void pform_set_net_range(perm_string name,
 				const svector<PExpr*>*range,
 				bool signed_flag,
 				ivl_variable_type_t dt,
-				PWSRType rt)
+				PWSRType rt,
+				svector<named_pexpr_t*>*attr)
 {
       PWire*cur = pform_get_wire_in_scope(name);
       if (cur == 0) {
@@ -1117,6 +1118,13 @@ static void pform_set_net_range(perm_string name,
 
       if (dt != IVL_VT_NO_TYPE)
 	    cur->set_data_type(dt);
+
+      if (attr) {
+	    for (unsigned idx = 0 ;  idx < attr->count() ;  idx += 1) {
+		  named_pexpr_t*tmp = (*attr)[idx];
+		  cur->attributes[tmp->name] = tmp->parm;
+	    }
+      }
 }
 
 void pform_set_net_range(list<perm_string>*names,
@@ -1131,7 +1139,7 @@ void pform_set_net_range(list<perm_string>*names,
 		 ; cur != names->end()
 		 ; cur ++ ) {
 	    perm_string txt = *cur;
-	    pform_set_net_range(txt, range, signed_flag, dt, rt);
+	    pform_set_net_range(txt, range, signed_flag, dt, rt, 0);
       }
 
       delete names;
@@ -1614,13 +1622,15 @@ void pform_makewire(const vlltype&li,
 	    pform_makewire(li, txt, type, pt, dt, attr);
 	    /* This has already been done for real variables. */
 	    if (dt != IVL_VT_REAL) {
-		  pform_set_net_range(txt, range, signed_flag, dt, rt);
+		  pform_set_net_range(txt, range, signed_flag, dt, rt, 0);
 	    }
       }
 
       delete names;
       if (range)
 	    delete range;
+      if (attr)
+	    delete attr;
 }
 
 /*
@@ -1645,7 +1655,7 @@ void pform_makewire(const vlltype&li,
 	    /* This has already been done for real variables. */
 	    if (dt != IVL_VT_REAL) {
 		  pform_set_net_range(first->name, range, signed_flag, dt,
-		                      SR_NET);
+		                      SR_NET, 0);
 	    }
 
 	    PWire*cur = pform_get_wire_in_scope(first->name);
@@ -2044,7 +2054,8 @@ void pform_set_port_type(const struct vlltype&li,
 			 list<perm_string>*names,
 			 svector<PExpr*>*range,
 			 bool signed_flag,
-			 NetNet::PortType pt)
+			 NetNet::PortType pt,
+			 svector<named_pexpr_t*>*attr)
 {
       for (list<perm_string>::iterator cur = names->begin()
 		 ; cur != names->end()
@@ -2052,12 +2063,14 @@ void pform_set_port_type(const struct vlltype&li,
 	    perm_string txt = *cur;
 	    pform_set_port_type(txt, pt, li.text, li.first_line);
 	    pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE,
-	                        SR_PORT);
+	                        SR_PORT, attr);
       }
 
       delete names;
       if (range)
 	    delete range;
+      if (attr)
+	    delete attr;
 }
 
 static void pform_set_reg_integer(perm_string name)
diff --git a/pform.h b/pform.h
index c61c2f1..0887dd2 100644
--- a/pform.h
+++ b/pform.h
@@ -254,7 +254,8 @@ extern void pform_set_port_type(const struct vlltype&li,
 				list<perm_string>*names,
 				svector<PExpr*>*range,
 				bool signed_flag,
-				NetNet::PortType);
+				NetNet::PortType,
+				svector<named_pexpr_t*>*attr);
 extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
 				const char*file, unsigned lineno);
 
diff --git a/svector.h b/svector.h
index 8681e51..2a99cde 100644
--- a/svector.h
+++ b/svector.h
@@ -7,9 +7,7 @@
  *    and/or modify it in source code form 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. In order to redistribute the software in
- *    binary form, you will need a Picture Elements Binary Software
- *    License.
+ *    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
@@ -18,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 # include  "config.h"
diff --git a/t-dll-analog.cc b/t-dll-analog.cc
index 7d37be0..4989833 100644
--- a/t-dll-analog.cc
+++ b/t-dll-analog.cc
@@ -5,8 +5,7 @@
  *    and/or modify it in source code form 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.will need a Picture Elements Binary Software
- *    License.
+ *    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
@@ -15,7 +14,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 # include "config.h"
diff --git a/t-dll-proc.cc b/t-dll-proc.cc
index c0581a6..260ba7f 100644
--- a/t-dll-proc.cc
+++ b/t-dll-proc.cc
@@ -5,8 +5,7 @@
  *    and/or modify it in source code form 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.will need a Picture Elements Binary Software
- *    License.
+ *    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
@@ -15,7 +14,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 # include "config.h"
diff --git a/tgt-fpga/Makefile.in b/tgt-fpga/Makefile.in
index a3c5aa6..c8963a8 100644
--- a/tgt-fpga/Makefile.in
+++ b/tgt-fpga/Makefile.in
@@ -64,7 +64,7 @@ endif
 
 
 fpga.tgt: $O $(TGTDEPLIBS)
-	$(CC) @shared@ -o $@ $O $(TGTLDFLAGS)
+	$(CC) @shared@ -o $@ $O $(LDFLAGS) $(TGTLDFLAGS)
 
 iverilog-fpga.ps: $(srcdir)/iverilog-fpga.man
 	man -t $(srcdir)/iverilog-fpga.man > iverilog-fpga.ps
diff --git a/tgt-null/Makefile.in b/tgt-null/Makefile.in
index 70881a7..27d69b4 100644
--- a/tgt-null/Makefile.in
+++ b/tgt-null/Makefile.in
@@ -61,7 +61,7 @@ endif
 
 
 null.tgt: $O $(TGTDEPLIBS)
-	$(CC) @shared@ -o $@ $O $(TGTLDFLAGS)
+	$(CC) @shared@ -o $@ $O $(LDFLAGS) $(TGTLDFLAGS)
 
 clean:
 	rm -rf *.o dep null.tgt
diff --git a/tgt-stub/Makefile.in b/tgt-stub/Makefile.in
index 81cec67..77c8a61 100644
--- a/tgt-stub/Makefile.in
+++ b/tgt-stub/Makefile.in
@@ -62,7 +62,7 @@ endif
 
 
 stub.tgt: $O $(TGTDEPLIBS)
-	$(CC) @shared@ -o $@ $O $(TGTLDFLAGS)
+	$(CC) @shared@ -o $@ $O $(LDFLAGS) $(TGTLDFLAGS)
 
 clean:
 	rm -rf *.o dep stub.tgt
diff --git a/tgt-verilog/Makefile.in b/tgt-verilog/Makefile.in
index 75d39bf..e9f576e 100644
--- a/tgt-verilog/Makefile.in
+++ b/tgt-verilog/Makefile.in
@@ -57,7 +57,7 @@ else
 endif
 
 verilog.tgt: $O $(TGTDEPLIBS)
-	$(CC) @shared@ -o $@ $O $(TGTLDFLAGS)
+	$(CC) @shared@ -o $@ $O $(LDFLAGS) $(TGTLDFLAGS)
 
 clean:
 	rm -rf *.o dep verilog.tgt
diff --git a/tgt-vhdl/Makefile.in b/tgt-vhdl/Makefile.in
index ea04ee9..613acf0 100644
--- a/tgt-vhdl/Makefile.in
+++ b/tgt-vhdl/Makefile.in
@@ -61,7 +61,7 @@ else
 endif
 
 vhdl.tgt: $O $(TGTDEPLIBS)
-	$(CXX) @shared@ -o $@ $O $(TGTLDFLAGS)
+	$(CXX) @shared@ -o $@ $O $(LDFLAGS) $(TGTLDFLAGS)
 
 Makefile: $(srcdir)/Makefile.in ../config.status
 	cd ..; ./config.status --file=tgt-vhdl/$@
diff --git a/tgt-vhdl/stmt.cc b/tgt-vhdl/stmt.cc
index c03572a..a3fa969 100644
--- a/tgt-vhdl/stmt.cc
+++ b/tgt-vhdl/stmt.cc
@@ -280,6 +280,8 @@ void make_assignment(vhdl_procedural *proc, stmt_container *container,
    if (ivl_expr_type(rval) == IVL_EX_TERNARY) {
       rhs = translate_expr(ivl_expr_oper2(rval));
       rhs2 = translate_expr(ivl_expr_oper3(rval));
+      if (rhs2 == NULL)
+         return;
    }
    else
       rhs = translate_expr(rval);
diff --git a/tgt-vvp/Makefile.in b/tgt-vvp/Makefile.in
index eb52a63..0bbca1d 100644
--- a/tgt-vvp/Makefile.in
+++ b/tgt-vvp/Makefile.in
@@ -66,7 +66,7 @@ endif
 
 
 vvp.tgt: $O $(TGTDEPLIBS)
-	$(CC) @shared@ -o $@ $O $(TGTLDFLAGS)
+	$(CC) @shared@ -o $@ $O $(LDFLAGS) $(TGTLDFLAGS)
 
 vvp.conf: $(srcdir)/vvp.conf.in Makefile
 	echo 'flag:VVP_EXECUTABLE=$(bindir)/vvp$(suffix)' | cat $(srcdir)/vvp.conf.in - > vvp.conf
diff --git a/verilog.spec b/verilog.spec
index a1296ab..a87cf97 100644
--- a/verilog.spec
+++ b/verilog.spec
@@ -1,6 +1,6 @@
 #norootforbuild
 #
-%define rev_date 20120905
+%define rev_date 20130819
 # Normally, the suff-ix is %nil, meaning the suffix is to not be used.
 # But if the builder wants to make a suffixed package, he may set this
 # to a value (i.e. -test) to cause suffixes to be put in all the right
@@ -10,7 +10,7 @@
 #
 Summary: Icarus Verilog
 Name: verilog%{suff}
-Version: 0.9.6
+Version: 0.9.7
 Release: 0
 License: GPL
 Group: Productivity/Scientific/Electronics
diff --git a/version_base.h b/version_base.h
index 8cf81ee..4447c24 100644
--- a/version_base.h
+++ b/version_base.h
@@ -5,7 +5,7 @@
  */
 # define VERSION_MAJOR1  0
 # define VERSION_MAJOR2  9
-# define VERSION_MINOR   6
+# define VERSION_MINOR   7
 # define VERSION_EXTRA   ""
 
 /* This is a concatenation of MAJOR1.MAJOR2 that is used by
diff --git a/version_tag.h b/version_tag.h
index 2d95f12..240ca64 100644
--- a/version_tag.h
+++ b/version_tag.h
@@ -1,3 +1,3 @@
 #ifndef VERSION_TAG
-#define VERSION_TAG "v0_9_6"
+#define VERSION_TAG "v0_9_7"
 #endif
diff --git a/vpi/fstapi.c b/vpi/fstapi.c
index d23b843..3ffb321 100644
--- a/vpi/fstapi.c
+++ b/vpi/fstapi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2012 Tony Bybell.
+ * Copyright (c) 2009-2013 Tony Bybell.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -62,6 +62,7 @@ void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t ha
 
 #define FST_WRITER_STR 			"fstWriter"
 #define FST_ID_NAM_SIZ 			(512)
+#define FST_ID_NAM_ATTR_SIZ		(65536+4096)
 #define FST_DOUBLE_ENDTEST 		(2.7182818284590452354)
 #define FST_HDR_SIM_VERSION_SIZE 	(128)
 #define FST_HDR_DATE_SIZE 		(120)
@@ -84,8 +85,10 @@ void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t ha
 
 #ifdef __MINGW32__
 #include <io.h>
-/* #define ftello ftell */
-/* #define fseeko fseek */
+#ifndef HAVE_FSEEKO
+#define ftello ftell
+#define fseeko fseek
+#endif
 #endif
 
 
@@ -171,7 +174,6 @@ return(pnt);
  */
 #ifdef FST_DO_MISALIGNED_OPS
 #define fstGetUint32(x) (*(uint32_t *)(x))
-#define fstWriterSetUint32(x,y) (*(uint32_t *)(x)) = (y)
 #else
 static uint32_t fstGetUint32(unsigned char *mem)
 {
@@ -185,17 +187,6 @@ buf[3] = mem[3];
 
 return(*(uint32_t *)buf);
 }
-
-
-static void fstWriterSetUint32(unsigned char *mem, uint32_t u32)
-{
-unsigned char *buf = (unsigned char *)(&u32);
-
-mem[0] = buf[0];
-mem[1] = buf[1];
-mem[2] = buf[2];
-mem[3] = buf[3];
-}
 #endif
 
 
@@ -541,9 +532,28 @@ size_t fst_break_add_size;
 size_t fst_huge_break_size;
 
 fstHandle next_huge_break;
+
+unsigned fseek_failed : 1;
 };
 
 
+static int fstWriterFseeko(struct fstWriterContext *xc, FILE *stream, off_t offset, int whence)
+{
+int rc = fseeko(stream, offset, whence);
+
+if(rc<0)
+	{
+	xc->fseek_failed = 1;
+#ifdef FST_DEBUG
+	fprintf(stderr, "Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence);
+	perror("Why");
+#endif
+	}
+
+return(rc);
+}
+
+
 static uint32_t fstWriterUint32WithVarint32(struct fstWriterContext *xc, uint32_t *u, uint32_t v, const void *dbuf, uint32_t siz)
 {
 unsigned char *buf = xc->vchg_mem + xc->vchg_siz;
@@ -683,15 +693,15 @@ off_t curpos = ftello(xc->handle);
 fflush(xc->hier_handle);
 
 /* write out intermediate header */
-fseeko(xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET);
+fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET);
 fstWriterUint64(xc->handle, xc->firsttime);
 fstWriterUint64(xc->handle, xc->curtime);
-fseeko(xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET);
+fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET);
 fstWriterUint64(xc->handle, xc->numscopes);
 fstWriterUint64(xc->handle, xc->numsigs);
 fstWriterUint64(xc->handle, xc->maxhandle);
 fstWriterUint64(xc->handle, xc->secnum);
-fseeko(xc->handle, curpos, SEEK_SET);
+fstWriterFseeko(xc, xc->handle, curpos, SEEK_SET);
 fflush(xc->handle);
 
 /* do mappings */
@@ -1332,7 +1342,7 @@ fstWriterUint64(xc->handle, endpos-indxpos);		/* write delta index position at v
 /*emit time changes for block */
 fflush(xc->tchn_handle);
 tlen = ftello(xc->tchn_handle);
-fseeko(xc->tchn_handle, 0, SEEK_SET);
+fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET);
 
 tmem = fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0);
 if(tmem)
@@ -1358,19 +1368,19 @@ if(tmem)
 	}
 
 xc->tchn_cnt = xc->tchn_idx = 0;
-fseeko(xc->tchn_handle, 0, SEEK_SET);
+fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET);
 fstFtruncate(fileno(xc->tchn_handle), 0);
 
 /* write block trailer */
 endpos = ftello(xc->handle);
-fseeko(xc->handle, xc->section_start, SEEK_SET);
+fstWriterFseeko(xc, xc->handle, xc->section_start, SEEK_SET);
 fstWriterUint64(xc->handle, endpos - xc->section_start); 	/* write block length */
-fseeko(xc->handle, 8, SEEK_CUR);				/* skip begin time */
+fstWriterFseeko(xc, xc->handle, 8, SEEK_CUR);				/* skip begin time */
 fstWriterUint64(xc->handle, xc->curtime); 			/* write end time for section */
 fstWriterUint64(xc->handle, unc_memreq);			/* amount of buffer memory required in reader for full traversal */
 fflush(xc->handle);
 
-fseeko(xc->handle, xc->section_start-1, SEEK_SET);		/* write out FST_BL_VCDATA over FST_BL_SKIP */
+fstWriterFseeko(xc, xc->handle, xc->section_start-1, SEEK_SET);		/* write out FST_BL_VCDATA over FST_BL_SKIP */
 
 #ifndef FST_DYNAMIC_ALIAS_DISABLE
 fputc(FST_BL_VCDATA_DYN_ALIAS, xc->handle);
@@ -1380,7 +1390,7 @@ fputc(FST_BL_VCDATA, xc->handle);
 
 fflush(xc->handle);
 
-fseeko(xc->handle, endpos, SEEK_SET);				/* seek to end of file */
+fstWriterFseeko(xc, xc->handle, endpos, SEEK_SET);				/* seek to end of file */
 
 xc2->section_header_truncpos = endpos;				/* cache in case of need to truncate */
 if(xc->dump_size_limit)
@@ -1464,7 +1474,7 @@ if(xc->parallel_enabled)
 
 	xc->tchn_cnt = xc->tchn_idx = 0;
 	xc->tchn_handle = tmpfile();
-	fseeko(xc->tchn_handle, 0, SEEK_SET);
+	fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET);
 	fstFtruncate(fileno(xc->tchn_handle), 0);
 
 	xc->section_header_only = 0;
@@ -1530,7 +1540,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 	if(xc->section_header_only && xc->section_header_truncpos && (xc->vchg_siz <= 1) && (!xc->is_initial_time))
 		{
 		fstFtruncate(fileno(xc->handle), xc->section_header_truncpos);
-		fseeko(xc->handle, xc->section_header_truncpos, SEEK_SET);
+		fstWriterFseeko(xc, xc->handle, xc->section_header_truncpos, SEEK_SET);
 		xc->section_header_only = 0;
 		}
 		else
@@ -1581,10 +1591,10 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 		fstFwrite((destlen != tlen) ? dmem : tmem, destlen, 1, xc->handle);
 		fflush(xc->handle);
 
-		fseeko(xc->handle, fixup_offs, SEEK_SET);
+		fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET);
 		fputc(FST_BL_GEOM, xc->handle);			/* actual tag */
 
-		fseeko(xc->handle, 0, SEEK_END);		/* move file pointer to end for any section adds */
+		fstWriterFseeko(xc, xc->handle, 0, SEEK_END);		/* move file pointer to end for any section adds */
 		fflush(xc->handle);
 
 		free(dmem);
@@ -1614,14 +1624,14 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 			}
 
 		eos = ftello(xc->handle);
-		fseeko(xc->handle, bpos, SEEK_SET);
+		fstWriterFseeko(xc, xc->handle, bpos, SEEK_SET);
 		fstWriterUint64(xc->handle, eos - bpos);		
 		fflush(xc->handle);
 
-		fseeko(xc->handle, fixup_offs, SEEK_SET);
+		fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET);
 		fputc(FST_BL_BLACKOUT, xc->handle);	/* actual tag */
 
-		fseeko(xc->handle, 0, SEEK_END);	/* move file pointer to end for any section adds */
+		fstWriterFseeko(xc, xc->handle, 0, SEEK_END);	/* move file pointer to end for any section adds */
 		fflush(xc->handle);
 		}
 
@@ -1646,7 +1656,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 		zhandle = gzdopen(zfd, "wb4");
 		if(zhandle)
 			{
-			fseeko(xc->hier_handle, 0, SEEK_SET);
+			fstWriterFseeko(xc, xc->hier_handle, 0, SEEK_SET);
 			for(hl = 0; hl < xc->hier_file_len; hl += FST_GZIO_LEN)
 				{
 				unsigned len = ((xc->hier_file_len - hl) > FST_GZIO_LEN) ? FST_GZIO_LEN : (xc->hier_file_len - hl);
@@ -1661,16 +1671,16 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 			}
 		free(mem);
 
-		fseeko(xc->handle, 0, SEEK_END);
+		fstWriterFseeko(xc, xc->handle, 0, SEEK_END);
 		eos = ftello(xc->handle);
-		fseeko(xc->handle, hlen, SEEK_SET);
+		fstWriterFseeko(xc, xc->handle, hlen, SEEK_SET);
 		fstWriterUint64(xc->handle, eos - hlen);
 		fflush(xc->handle);
 
-		fseeko(xc->handle, fixup_offs, SEEK_SET);
+		fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET);
 		fputc(FST_BL_HIER, xc->handle);		/* actual tag */
 
-		fseeko(xc->handle, 0, SEEK_END);	/* move file pointer to end for any section adds */
+		fstWriterFseeko(xc, xc->handle, 0, SEEK_END);	/* move file pointer to end for any section adds */
 		fflush(xc->handle);
 
 #ifndef __MINGW32__
@@ -1681,10 +1691,10 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 		}
 
 	/* finalize out header */
-	fseeko(xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET);
 	fstWriterUint64(xc->handle, xc->firsttime);
 	fstWriterUint64(xc->handle, xc->curtime);
-	fseeko(xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET);
 	fstWriterUint64(xc->handle, xc->numscopes);
 	fstWriterUint64(xc->handle, xc->numsigs);
 	fstWriterUint64(xc->handle, xc->maxhandle);
@@ -1716,7 +1726,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 				int zfd;
 				char gz_membuf[FST_GZIO_LEN];
 
-				fseeko(xc->handle, 0, SEEK_END);
+				fstWriterFseeko(xc, xc->handle, 0, SEEK_END);
 				uclen = ftello(xc->handle);
 
 				fputc(FST_BL_ZWRAPPER, fp);
@@ -1724,7 +1734,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 				fstWriterUint64(fp, uclen);
 				fflush(fp);
 
-				fseeko(xc->handle, 0, SEEK_SET);
+				fstWriterFseeko(xc, xc->handle, 0, SEEK_SET);
 				zfd = dup(fileno(fp));
 				dsth = gzdopen(zfd, "wb4");
 				if(dsth)
@@ -1741,9 +1751,9 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 					{
 					close(zfd);
 					}
-				fseeko(fp, 0, SEEK_END);
+				fstWriterFseeko(xc, fp, 0, SEEK_END);
 				offpnt = ftello(fp);
-				fseeko(fp, 1, SEEK_SET);
+				fstWriterFseeko(xc, fp, 1, SEEK_SET);
 				fstWriterUint64(fp, offpnt - 1);
 				fclose(fp);
 				fclose(xc->handle); xc->handle = NULL; 
@@ -1804,12 +1814,12 @@ if(xc)
 	off_t fpos = ftello(xc->handle);
 	int len = strlen(dat);
 
-	fseeko(xc->handle, FST_HDR_OFFS_DATE, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_DATE, SEEK_SET);
 	memset(s, 0, FST_HDR_DATE_SIZE);
 	memcpy(s, dat, (len < FST_HDR_DATE_SIZE) ? len : FST_HDR_DATE_SIZE);
 	fstFwrite(s, FST_HDR_DATE_SIZE, 1, xc->handle);
 	fflush(xc->handle);
-	fseeko(xc->handle, fpos, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET);
 	}
 }
 
@@ -1823,26 +1833,58 @@ if(xc && vers)
 	off_t fpos = ftello(xc->handle);
 	int len = strlen(vers);
 
-	fseeko(xc->handle, FST_HDR_OFFS_SIM_VERSION, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_SIM_VERSION, SEEK_SET);
 	memset(s, 0, FST_HDR_SIM_VERSION_SIZE);
 	memcpy(s, vers, (len < FST_HDR_SIM_VERSION_SIZE) ? len : FST_HDR_SIM_VERSION_SIZE);
 	fstFwrite(s, FST_HDR_SIM_VERSION_SIZE, 1, xc->handle);
 	fflush(xc->handle);
-	fseeko(xc->handle, fpos, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET);
+	}
+}
+
+
+static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ)
+{
+struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
+if(xc && comm)
+        {
+	char *s = strdup(comm);
+	char *sf = s;
+
+	while(*s)
+		{
+		if((*s == '\n') || (*s == '\r')) *s = ' ';
+		s++;
+		}
+
+	fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, 0);
+	free(sf);
 	}
 }
 
 
+void fstWriterSetComment(void *ctx, const char *comm)
+{
+fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT);
+}
+
+
+void fstWriterSetEnvVar(void *ctx, const char *envvar)
+{
+fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR);
+}
+
+
 void fstWriterSetTimescale(void *ctx, int ts)
 {
 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 if(xc)
         {
 	off_t fpos = ftello(xc->handle);
-	fseeko(xc->handle, FST_HDR_OFFS_TIMESCALE, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMESCALE, SEEK_SET);
 	fputc(ts & 255, xc->handle);
 	fflush(xc->handle);
-	fseeko(xc->handle, fpos, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET);
 	}
 }
 
@@ -1897,10 +1939,10 @@ struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 if(xc)
         {
 	off_t fpos = ftello(xc->handle);
-	fseeko(xc->handle, FST_HDR_OFFS_TIMEZERO, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMEZERO, SEEK_SET);
 	fstWriterUint64(xc->handle, (xc->timezero = tim));
 	fflush(xc->handle);
-	fseeko(xc->handle, fpos, SEEK_SET);
+	fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET);
 	}
 }
 
@@ -1965,8 +2007,20 @@ return(0);
 }
 
 
+int fstWriterGetFseekFailed(void *ctx)
+{
+struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
+if(xc)
+        {
+        return(xc->fseek_failed != 0);
+        }
+
+return(0);
+}
+
+
 /*
- * writer scope/var creation
+ * writer attr/scope/var creation
  */
 fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
         uint32_t len, const char *nam, fstHandle aliasHandle)
@@ -1988,7 +2042,7 @@ if(xc && nam)
 	fputc(0, xc->hier_handle);
 	xc->hier_file_len += (nlen+3);
 
-	if((vt == FST_VT_VCD_REAL) || (vt == FST_VT_VCD_REAL_PARAMETER) || (vt == FST_VT_VCD_REALTIME))
+	if((vt == FST_VT_VCD_REAL) || (vt == FST_VT_VCD_REAL_PARAMETER) || (vt == FST_VT_VCD_REALTIME) || (vt == FST_VT_SV_SHORTREAL))
 		{
 		is_real = 1;
 		len = 8; /* recast number of bytes to that of what a double is */
@@ -2072,7 +2126,7 @@ void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
 {
 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 
-if(xc && scopename)
+if(xc)
 	{
 	fputc(FST_ST_VCD_SCOPE, xc->hier_handle);
 	if((scopetype < FST_ST_VCD_MODULE) || (scopetype > FST_ST_MAX)) { scopetype = FST_ST_VCD_MODULE; }
@@ -2108,6 +2162,54 @@ if(xc)
 }
 
 
+void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
+                const char *attrname, uint64_t arg)
+{
+struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
+
+if(xc)
+	{
+	fputc(FST_ST_GEN_ATTRBEGIN, xc->hier_handle);
+	if((attrtype < FST_AT_MISC) || (attrtype > FST_AT_MAX)) { attrtype = FST_AT_MISC; subtype = FST_MT_UNKNOWN; }
+	fputc(attrtype, xc->hier_handle);
+
+	switch(attrtype)
+		{
+		case FST_AT_ARRAY:	if((subtype < FST_AR_NONE) || (subtype > FST_AR_MAX)) subtype = FST_AR_NONE; break;
+		case FST_AT_ENUM:	if((subtype < FST_EV_SV_INTEGER) || (subtype > FST_EV_MAX)) subtype = FST_EV_SV_INTEGER; break;
+		case FST_AT_PACK:	if((subtype < FST_PT_NONE) || (subtype > FST_PT_MAX)) subtype = FST_PT_NONE; break;
+
+		case FST_AT_MISC:
+		default:		break;
+		}
+
+	fputc(subtype, xc->hier_handle);
+	fprintf(xc->hier_handle, "%s%c",
+		attrname ? attrname : "", 0);
+	
+	if(attrname)
+		{
+		xc->hier_file_len += strlen(attrname);
+		}
+
+	xc->hier_file_len += 4; /* FST_ST_GEN_ATTRBEGIN + type + subtype + string terminating zero */
+	xc->hier_file_len += fstWriterVarint(xc->hier_handle, arg);
+	}
+}
+
+
+void fstWriterSetAttrEnd(void *ctx)
+{
+struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
+
+if(xc)
+	{
+	fputc(FST_ST_GEN_ATTREND, xc->hier_handle);
+	xc->hier_file_len++;
+	}
+}
+
+
 /*
  * value and time change emission
  */
@@ -2366,14 +2468,33 @@ static const char *vartypes[] = {
 	"event", "integer", "parameter", "real", "real_parameter",
 	"reg", "supply0", "supply1", "time", "tri",
 	"triand", "trior", "trireg", "tri0", "tri1", 
-	"wand", "wire", "wor", "port", "array", "realtime",
-	"string"
+	"wand", "wire", "wor", "port", "sparray", "realtime",
+	"string",
+	"bit", "logic", "int", "shortint", "longint", "byte", "enum", "shortreal"
 	};
 
 static const char *modtypes[] = {
-	"module", "task", "function", "begin", "fork"
+	"module", "task", "function", "begin", "fork", "generate", "struct", "union", "class", "interface", "package", "program"
+	};
+
+static const char *attrtypes[] = {
+	"misc", "array", "enum", "class"
+	};
+
+static const char *arraytypes[] = {
+	"none", "unpacked", "packed", "sparse"
+	};
+
+static const char *enumvaluetypes[] = {
+	"integer", "bit", "logic", "int", "shortint", "longint", "byte",
+	"unsigned_integer", "unsigned_bit", "unsigned_logic", "unsigned_int", "unsigned_shortint", "unsigned_longint", "unsigned_byte"
+	};
+
+static const char *packtypes[] = {
+	"none", "unpacked", "packed", "tagged_packed"
 	};
 
+
 struct fstCurrHier
 {
 struct fstCurrHier *prev;
@@ -2455,9 +2576,27 @@ unsigned do_rewind : 1;
 char str_scope_nam[FST_ID_NAM_SIZ+1];
 char str_scope_comp[FST_ID_NAM_SIZ+1];
 
+unsigned fseek_failed : 1;
 };
 
 
+int fstReaderFseeko(struct fstReaderContext *xc, FILE *stream, off_t offset, int whence)
+{
+int rc = fseeko(stream, offset, whence);
+
+if(rc<0)
+	{
+	xc->fseek_failed = 1;
+#ifdef FST_DEBUG
+	fprintf(stderr, "Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence);
+	perror("Why");
+#endif
+	}
+
+return(rc);
+}
+
+
 /*
  * scope -> flat name handling
  */
@@ -2585,6 +2724,18 @@ return(0);
 }
 
 
+int fstReaderGetFseekFailed(void *ctx)
+{
+struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
+if(xc)
+        {
+        return(xc->fseek_failed != 0);
+        }
+
+return(0);
+}
+
+
 /*
  * iter mask manipulation util functions
  */
@@ -2896,7 +3047,7 @@ if(!xc->fh)
 	int zfd;
 
 	sprintf(fnam, "%s.hier_%d_%p", xc->filename, getpid(), (void *)xc);
-	fseeko(xc->f, xc->hier_pos, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, xc->hier_pos, SEEK_SET);
 	uclen = fstReaderUint64(xc->f);
 	fflush(xc->f);
 	zfd = dup(fileno(xc->f));
@@ -2950,7 +3101,7 @@ if(!xc->fh)
 	free(mem);
 	free(fnam);
 
-	fseeko(xc->f, offs_cache, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, offs_cache, SEEK_SET);
 	}
 
 return(pass_status);
@@ -2999,7 +3150,7 @@ if(xc->do_rewind)
 	{
 	xc->do_rewind = 0;
 	xc->current_handle = 0;
-	fseeko(xc->fh, 0, SEEK_SET);
+	fstReaderFseeko(xc, xc->fh, 0, SEEK_SET);
 	clearerr(xc->fh);
 	}
 
@@ -3032,6 +3183,25 @@ if(!(isfeof=feof(xc->fh)))
 			xc->hier.htyp = FST_HT_UPSCOPE;
 			break;
 
+		case FST_ST_GEN_ATTRBEGIN:
+			xc->hier.htyp = FST_HT_ATTRBEGIN;
+			xc->hier.u.attr.typ = fgetc(xc->fh);
+			xc->hier.u.attr.subtype = fgetc(xc->fh);
+			xc->hier.u.attr.name = pnt = xc->str_scope_nam;
+			while((ch = fgetc(xc->fh))) 
+				{
+				*(pnt++) = ch; 
+				}; /* scopename */
+			*pnt = 0;
+			xc->hier.u.attr.name_length = pnt - xc->hier.u.scope.name;
+
+			xc->hier.u.attr.arg = fstReaderVarint64(xc->fh);
+			break;
+
+		case FST_ST_GEN_ATTREND:
+			xc->hier.htyp = FST_HT_ATTREND;
+			break;
+
 		case FST_VT_VCD_EVENT:
 		case FST_VT_VCD_INTEGER:
 		case FST_VT_VCD_PARAMETER:
@@ -3051,9 +3221,17 @@ if(!(isfeof=feof(xc->fh)))
 		case FST_VT_VCD_WIRE:
 		case FST_VT_VCD_WOR:
 		case FST_VT_VCD_PORT:
-		case FST_VT_VCD_ARRAY:
+		case FST_VT_VCD_SPARRAY:
 		case FST_VT_VCD_REALTIME:
 		case FST_VT_GEN_STRING:
+		case FST_VT_SV_BIT:
+		case FST_VT_SV_LOGIC:
+		case FST_VT_SV_INT:
+		case FST_VT_SV_SHORTINT:
+		case FST_VT_SV_LONGINT:
+		case FST_VT_SV_BYTE:
+		case FST_VT_SV_ENUM:
+		case FST_VT_SV_SHORTREAL:
 			xc->hier.htyp = FST_HT_VAR;
 
 			xc->hier.u.var.typ = tag;
@@ -3101,13 +3279,15 @@ return(!isfeof ? &xc->hier : NULL);
 int fstReaderProcessHier(void *ctx, FILE *fv)
 {
 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
-char str[FST_ID_NAM_SIZ+1];
+char *str;
 char *pnt;
 int ch, scopetype;
 int vartype;
 uint32_t len, alias;
-uint32_t maxvalpos=0;
+/* uint32_t maxvalpos=0; */
 int num_signal_dyn = 65536;
+int attrtype, subtype;
+uint64_t attrarg;
 
 if(!xc) return(0);
 
@@ -3121,6 +3301,8 @@ if(!xc->fh)
 		}
 	}
 
+str = malloc(FST_ID_NAM_ATTR_SIZ+1);
+
 if(fv)
 	{
 	char time_dimension[2] = {0, 0};
@@ -3178,7 +3360,7 @@ xc->signal_lens = malloc(num_signal_dyn*sizeof(uint32_t));
 free(xc->signal_typs);
 xc->signal_typs = malloc(num_signal_dyn*sizeof(unsigned char));
 
-fseeko(xc->fh, 0, SEEK_SET);
+fstReaderFseeko(xc, xc->fh, 0, SEEK_SET);
 while(!feof(xc->fh))
 	{
 	int tag = fgetc(xc->fh);
@@ -3186,6 +3368,7 @@ while(!feof(xc->fh))
 		{
 		case FST_ST_VCD_SCOPE:
 			scopetype = fgetc(xc->fh);
+			if((scopetype < FST_ST_VCD_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE;
 			pnt = str;
 			while((ch = fgetc(xc->fh))) 
 				{
@@ -3201,6 +3384,50 @@ while(!feof(xc->fh))
 			if(fv) fprintf(fv, "$upscope $end\n");
 			break;
 
+		case FST_ST_GEN_ATTRBEGIN:
+			attrtype = fgetc(xc->fh);
+			subtype = fgetc(xc->fh);
+			pnt = str;
+			while((ch = fgetc(xc->fh))) 
+				{
+				*(pnt++) = ch; 
+				}; /* attrname */
+			*pnt = 0;
+
+			attrarg = fstReaderVarint64(xc->fh);
+
+			if(fv)
+				{
+				switch(attrtype)
+					{
+					case FST_AT_ARRAY:	if((subtype < FST_AR_NONE) || (subtype > FST_AR_MAX)) subtype = FST_AR_NONE;
+								fprintf(fv, "$attrbegin %s %s %s %"PRId64" $end\n", attrtypes[attrtype], arraytypes[subtype], str, attrarg);
+								break;
+					case FST_AT_ENUM:	if((subtype < FST_EV_SV_INTEGER) || (subtype > FST_EV_MAX)) subtype = FST_EV_SV_INTEGER;
+								fprintf(fv, "$attrbegin %s %s %s %"PRId64" $end\n", attrtypes[attrtype], enumvaluetypes[subtype], str, attrarg);
+								break;
+					case FST_AT_PACK:	if((subtype < FST_PT_NONE) || (subtype > FST_PT_MAX)) subtype = FST_PT_NONE;
+								fprintf(fv, "$attrbegin %s %s %s %"PRId64" $end\n", attrtypes[attrtype], packtypes[subtype], str, attrarg);
+								break;
+					case FST_AT_MISC:	
+					default:		attrtype = FST_AT_MISC;
+								if(subtype == FST_MT_COMMENT)
+									{
+									fprintf(fv, "$comment\n\t%s\n$end\n", str);
+									}
+									else
+									{
+									fprintf(fv, "$attrbegin %s %02x %s %"PRId64" $end\n", attrtypes[attrtype], subtype, str, attrarg);
+									}
+								break;
+					}
+				}
+			break;
+
+		case FST_ST_GEN_ATTREND:
+			if(fv) fprintf(fv, "$attrend $end\n");
+			break;
+
 		case FST_VT_VCD_EVENT:
 		case FST_VT_VCD_INTEGER:
 		case FST_VT_VCD_PARAMETER:
@@ -3220,9 +3447,17 @@ while(!feof(xc->fh))
 		case FST_VT_VCD_WIRE:
 		case FST_VT_VCD_WOR:
 		case FST_VT_VCD_PORT:
-		case FST_VT_VCD_ARRAY:
+		case FST_VT_VCD_SPARRAY:
 		case FST_VT_VCD_REALTIME:
 		case FST_VT_GEN_STRING:
+		case FST_VT_SV_BIT:
+		case FST_VT_SV_LOGIC:
+		case FST_VT_SV_INT:
+		case FST_VT_SV_SHORTINT:
+		case FST_VT_SV_LONGINT:
+		case FST_VT_SV_BYTE:
+		case FST_VT_SV_ENUM:
+		case FST_VT_SV_SHORTREAL:
 			vartype = tag;
 			/* vardir = */ fgetc(xc->fh); /* unused in VCD reader, but need to advance read pointer */
 			pnt = str;
@@ -3245,15 +3480,15 @@ while(!feof(xc->fh))
 				xc->signal_lens[xc->maxhandle] = len;
 				xc->signal_typs[xc->maxhandle] = vartype;
 
-		                maxvalpos+=len;
+		                /* maxvalpos+=len; */
 				if(len > xc->longest_signal_value_len)
 					{
 					xc->longest_signal_value_len = len;
 					}
 
-				if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME))
+				if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME) || (vartype == FST_VT_SV_SHORTREAL))
 					{
-					len = 64;
+					len = (vartype != FST_VT_SV_SHORTREAL) ? 64 : 32;
 					xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL;
 					}
 				if(fv) 
@@ -3265,9 +3500,9 @@ while(!feof(xc->fh))
 				}
 				else
 				{
-				if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME))
+				if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME) || (vartype == FST_VT_SV_SHORTREAL))
 					{
-					len = 64;
+					len = (vartype != FST_VT_SV_SHORTREAL) ? 64 : 32;
 					xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL;
 					}
 				if(fv) 
@@ -3297,6 +3532,7 @@ xc->temp_signal_value_buf = malloc(xc->longest_signal_value_len + 1);
 
 xc->var_count = xc->maxhandle + xc->num_alias;
 
+free(str);
 return(1);
 }
 
@@ -3357,7 +3593,7 @@ if(sectype == FST_BL_ZWRAPPER)
 		}
 #endif
 
-	fseeko(xc->f, 1+8+8, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, 1+8+8, SEEK_SET);
 	fflush(xc->f);
 
 	zfd = dup(fileno(xc->f));
@@ -3395,12 +3631,12 @@ if(sectype == FST_BL_ZWRAPPER)
 
 if(gzread_pass_status)
 	{
-	fseeko(xc->f, 0, SEEK_END);
+	fstReaderFseeko(xc, xc->f, 0, SEEK_END);
 	endfile = ftello(xc->f);
 
 	while(blkpos < endfile)
 		{
-		fseeko(xc->f, blkpos, SEEK_SET);
+		fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET);
 		
 		sectype = fgetc(xc->f);
 		seclen = fstReaderUint64(xc->f);
@@ -3409,6 +3645,11 @@ if(gzread_pass_status)
 			{
 			break;
 			}
+
+                if((hdr_incomplete) && (!seclen))
+                        {   
+                        break;
+                        }
 	
 		if(!hdr_seen && (sectype != FST_BL_HDR)) 
 			{
@@ -3768,7 +4009,7 @@ for(;;)
 	uint32_t *tc_head = NULL;
 	traversal_mem_offs = 0;
 
-	fseeko(xc->f, blkpos, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET);
 	
 	sectype = fgetc(xc->f);
 	seclen = fstReaderUint64(xc->f);
@@ -3830,7 +4071,7 @@ for(;;)
 	uint64_t tpval;
 	int ti;
 
-	fseeko(xc->f, blkpos + seclen - 24, SEEK_SET);
+	if(fstReaderFseeko(xc, xc->f, blkpos + seclen - 24, SEEK_SET) != 0) break;
 	tsec_uclen = fstReaderUint64(xc->f);
 	tsec_clen = fstReaderUint64(xc->f);
 	tsec_nitems = fstReaderUint64(xc->f);
@@ -3838,11 +4079,13 @@ for(;;)
 	printf("\ttime section unc: %d, com: %d (%d items)\n", 
 		(int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems);
 #endif		
+	if(tsec_clen > seclen) break; /* corrupted tsec_clen: by definition it can't be larger than size of section */
 	ucdata = malloc(tsec_uclen);
+	if(!ucdata) break; /* malloc fail as tsec_uclen out of range from corrupted file */
 	destlen = tsec_uclen;
 	sourcelen = tsec_clen;
 
-	fseeko(xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
+	fstReaderFseeko(xc, xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
 
 	if(tsec_uclen != tsec_clen)
 		{
@@ -3880,7 +4123,7 @@ for(;;)
 	free(ucdata);
 	}
 
-	fseeko(xc->f, blkpos+32, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, blkpos+32, SEEK_SET);
 
 	frame_uclen = fstReaderVarint64(xc->f);
 	frame_clen = fstReaderVarint64(xc->f);
@@ -4063,11 +4306,11 @@ for(;;)
 				}
 
 			free(mu);
-			fseeko(xc->f, -((off_t)frame_clen), SEEK_CUR);
+			fstReaderFseeko(xc, xc->f, -((off_t)frame_clen), SEEK_CUR);
 			}
 		}
 
-	fseeko(xc->f, (off_t)frame_clen, SEEK_CUR); /* skip past compressed data */
+	fstReaderFseeko(xc, xc->f, (off_t)frame_clen, SEEK_CUR); /* skip past compressed data */
 
 	vc_maxhandle = fstReaderVarint64(xc->f);
 	vc_start = ftello(xc->f);	/* points to '!' character */
@@ -4080,7 +4323,7 @@ for(;;)
 #endif
 
 	indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
-	fseeko(xc->f, indx_pntr, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET);
 	chain_clen = fstReaderUint64(xc->f);
 	indx_pos = indx_pntr - chain_clen;
 #ifdef FST_DEBUG
@@ -4088,7 +4331,7 @@ for(;;)
 #endif
 	chain_cmem = malloc(chain_clen);
 	if(!chain_cmem) goto block_err;
-	fseeko(xc->f, indx_pos, SEEK_SET);
+	fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET);
 	fstFread(chain_cmem, chain_clen, 1, xc->f);
 	
 	if(vc_maxhandle > vc_maxhandle_largest)
@@ -4175,7 +4418,7 @@ for(;;)
 				uint32_t skiplen;
 				uint32_t tdelta;
 	
-				fseeko(xc->f, vc_start + chain_table[i], SEEK_SET);
+				fstReaderFseeko(xc, xc->f, vc_start + chain_table[i], SEEK_SET);
 				val = fstReaderVarint32WithSkip(xc->f, &skiplen);
 				if(val)
 					{
@@ -4682,7 +4925,7 @@ xc->rvat_chain_pos_valid = 0;
 
 for(;;)
 	{
-	fseeko(xc->f, (prev_blkpos = blkpos), SEEK_SET);
+	fstReaderFseeko(xc, xc->f, (prev_blkpos = blkpos), SEEK_SET);
 
 	sectype = fgetc(xc->f);
 	seclen = fstReaderUint64(xc->f);
@@ -4707,7 +4950,7 @@ for(;;)
 		if((tim == end_tim) && (tim != xc->end_time))
 			{
 			off_t cached_pos = ftello(xc->f);
-			fseeko(xc->f, blkpos, SEEK_SET);
+			fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET);
 
 			sectype = fgetc(xc->f);
 			seclen = fstReaderUint64(xc->f);
@@ -4722,7 +4965,7 @@ for(;;)
 				}
 			beg_tim = beg_tim2;
 			end_tim = end_tim2;
-			fseeko(xc->f, cached_pos, SEEK_SET);
+			fstReaderFseeko(xc, xc->f, cached_pos, SEEK_SET);
 			}
 		break;
 		}
@@ -4756,7 +4999,7 @@ unsigned char *tpnt;
 uint64_t tpval;
 int ti;
 
-fseeko(xc->f, blkpos + seclen - 24, SEEK_SET);
+fstReaderFseeko(xc, xc->f, blkpos + seclen - 24, SEEK_SET);
 tsec_uclen = fstReaderUint64(xc->f);
 tsec_clen = fstReaderUint64(xc->f);
 tsec_nitems = fstReaderUint64(xc->f);
@@ -4768,7 +5011,7 @@ ucdata = malloc(tsec_uclen);
 destlen = tsec_uclen;
 sourcelen = tsec_clen;
 	
-fseeko(xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
+fstReaderFseeko(xc, xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
 if(tsec_uclen != tsec_clen)
 	{
 	cdata = malloc(tsec_clen);
@@ -4803,7 +5046,7 @@ for(ti=0;ti<tsec_nitems;ti++)
 free(ucdata);
 }
 
-fseeko(xc->f, blkpos+32, SEEK_SET);
+fstReaderFseeko(xc, xc->f, blkpos+32, SEEK_SET);
 
 frame_uclen = fstReaderVarint64(xc->f);
 frame_clen = fstReaderVarint64(xc->f);
@@ -4842,14 +5085,14 @@ printf("\tvc_maxhandle: %d\n", (int)xc->rvat_vc_maxhandle);
 #endif
 
 indx_pntr = blkpos + seclen - 24 -tsec_clen -8;
-fseeko(xc->f, indx_pntr, SEEK_SET);
+fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET);
 chain_clen = fstReaderUint64(xc->f);
 indx_pos = indx_pntr - chain_clen;
 #ifdef FST_DEBUG
 printf("\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen);
 #endif
 chain_cmem = malloc(chain_clen);
-fseeko(xc->f, indx_pos, SEEK_SET);
+fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET);
 fstFread(chain_cmem, chain_clen, 1, xc->f);
 	
 xc->rvat_chain_table = calloc((xc->rvat_vc_maxhandle+1), sizeof(off_t));
@@ -4944,7 +5187,7 @@ if(facidx != xc->rvat_chain_facidx)
 if(!xc->rvat_chain_mem)
 	{
 	uint32_t skiplen;
-	fseeko(xc->f, xc->rvat_vc_start + xc->rvat_chain_table[facidx], SEEK_SET);
+	fstReaderFseeko(xc, xc->f, xc->rvat_vc_start + xc->rvat_chain_table[facidx], SEEK_SET);
 	xc->rvat_chain_len = fstReaderVarint32WithSkip(xc->f, &skiplen);
 	if(xc->rvat_chain_len)
 		{
diff --git a/vpi/fstapi.h b/vpi/fstapi.h
index a324744..7c77ced 100644
--- a/vpi/fstapi.h
+++ b/vpi/fstapi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2012 Tony Bybell.
+ * Copyright (c) 2009-2013 Tony Bybell.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -59,9 +59,19 @@ enum fstScopeType {
     FST_ST_VCD_FUNCTION        = 2,
     FST_ST_VCD_BEGIN           = 3,
     FST_ST_VCD_FORK            = 4,
-    FST_ST_VCD_MAX             = 4,
+    FST_ST_VCD_GENERATE        = 5,
+    FST_ST_VCD_STRUCT          = 6,
+    FST_ST_VCD_UNION           = 7,
+    FST_ST_VCD_CLASS           = 8,
+    FST_ST_VCD_INTERFACE       = 9,
+    FST_ST_VCD_PACKAGE         = 10,
+    FST_ST_VCD_PROGRAM         = 11,
+    FST_ST_VCD_MAX             = 11,
 
-    FST_ST_MAX                 = 4,
+    FST_ST_MAX                 = 11,
+
+    FST_ST_GEN_ATTRBEGIN       = 252,
+    FST_ST_GEN_ATTREND         = 253,
 
     FST_ST_VCD_SCOPE           = 254,
     FST_ST_VCD_UPSCOPE         = 255
@@ -88,11 +98,21 @@ enum fstVarType {
     FST_VT_VCD_WIRE            = 16,
     FST_VT_VCD_WOR             = 17,
     FST_VT_VCD_PORT            = 18,
-    FST_VT_VCD_ARRAY           = 19,	/* used to define the rownum (index) port on the array */
+    FST_VT_VCD_SPARRAY         = 19,	/* used to define the rownum (index) port for a sparse array */
     FST_VT_VCD_REALTIME        = 20,
+
     FST_VT_GEN_STRING	       = 21,	/* generic string type   (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
 
-    FST_VT_VCD_MAX             = 21	/* end of VCD datatypes */
+    FST_VT_SV_BIT              = 22,
+    FST_VT_SV_LOGIC            = 23,
+    FST_VT_SV_INT              = 24,	/* declare as 31:0 */
+    FST_VT_SV_SHORTINT         = 25,	/* declare as 15:0 */
+    FST_VT_SV_LONGINT          = 26,	/* declare as 63:0 */
+    FST_VT_SV_BYTE             = 27,	/* declare as 7:0  */
+    FST_VT_SV_ENUM             = 28,	/* declare as appropriate type range */
+    FST_VT_SV_SHORTREAL        = 29,	/* declare and emit same as FST_VT_VCD_REAL */
+
+    FST_VT_VCD_MAX             = 29	/* end of VCD datatypes */
 };
 
 enum fstVarDir {
@@ -108,8 +128,64 @@ enum fstHierType {
     FST_HT_SCOPE       = 0,
     FST_HT_UPSCOPE     = 1,
     FST_HT_VAR         = 2,
+    FST_HT_ATTRBEGIN   = 3,
+    FST_HT_ATTREND     = 4,
+
+    FST_HT_MAX         = 4
+};
 
-    FST_HT_MAX         = 2
+enum fstAttrType {
+    FST_AT_MISC        = 0,
+    FST_AT_ARRAY       = 1,
+    FST_AT_ENUM        = 2,
+    FST_AT_PACK        = 3,
+
+    FST_AT_MAX         = 3
+};
+
+enum fstMiscType {
+    FST_MT_COMMENT     = 0,	/* self-contained: does not need matching FST_HT_ATTREND, use fstWriterSetComment() to emit */
+    FST_MT_ENVVAR      = 1,	/* self-contained: does not need matching FST_HT_ATTREND, use fstWriterSetEnvVar() to emit */
+    FST_MT_UNKNOWN     = 2,
+
+    FST_MT_MAX         = 2
+};
+
+enum fstArrayType {
+    FST_AR_NONE        = 0,
+    FST_AR_UNPACKED    = 1,
+    FST_AR_PACKED      = 2,
+    FST_AR_SPARSE      = 3,
+
+    FST_AR_MAX         = 3
+};
+
+enum fstEnumValueType {
+    FST_EV_SV_INTEGER           = 0,
+    FST_EV_SV_BIT               = 1,
+    FST_EV_SV_LOGIC             = 2,
+    FST_EV_SV_INT               = 3,
+    FST_EV_SV_SHORTINT          = 4,
+    FST_EV_SV_LONGINT           = 5,
+    FST_EV_SV_BYTE              = 6,
+    FST_EV_SV_UNSIGNED_INTEGER  = 7,
+    FST_EV_SV_UNSIGNED_BIT      = 8,
+    FST_EV_SV_UNSIGNED_LOGIC    = 9,
+    FST_EV_SV_UNSIGNED_INT      = 10,
+    FST_EV_SV_UNSIGNED_SHORTINT = 11,
+    FST_EV_SV_UNSIGNED_LONGINT  = 12,
+    FST_EV_SV_UNSIGNED_BYTE     = 13,
+
+    FST_EV_MAX                  = 13
+};
+
+enum fstPackType {
+    FST_PT_NONE          = 0,
+    FST_PT_UNPACKED      = 1,
+    FST_PT_PACKED        = 2,
+    FST_PT_TAGGED_PACKED = 3,
+
+    FST_PT_MAX           = 3
 };
 
 struct fstHier
@@ -119,7 +195,7 @@ unsigned char htyp;
 union {
 	/* if htyp == FST_HT_SCOPE */
 	struct fstHierScope {
-		unsigned char typ; /* FST_ST_VCD_MODULE ... FST_ST_VCD_FORK */
+		unsigned char typ; /* FST_ST_VCD_MODULE ... FST_ST_VCD_PROGRAM */
 		const char *name;
 		const char *component;
 		uint32_t name_length;		/* strlen(u.scope.name) */
@@ -128,7 +204,7 @@ union {
 
 	/* if htyp == FST_HT_VAR */
 	struct fstHierVar {
-		unsigned char typ; /* FST_VT_VCD_EVENT ... FST_VT_VCD_REALTIME */
+		unsigned char typ; /* FST_VT_VCD_EVENT ... FST_VT_GEN_STRING */
 		unsigned char direction; /* FST_VD_IMPLICIT ... FST_VD_INOUT */
 		const char *name;
 		uint32_t length;
@@ -136,6 +212,15 @@ union {
 		uint32_t name_length; /* strlen(u.var.name) */
 		unsigned is_alias : 1;
 		} var;
+
+	/* if htyp == FST_HT_ATTRBEGIN */
+	struct fstHierAttr {
+		unsigned char typ; /* FST_AT_MISC ... FST_AT_PACK */
+		unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
+		const char *name;
+		uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
+		uint32_t name_length; /* strlen(u.attr.name) */
+		} attr;
 	} u;
 };
 
@@ -151,11 +236,14 @@ void fstWriterSetRepackOnClose(void *ctx, int enable); 	/* type = 0 (none), 1 (l
 void fstWriterSetParallelMode(void *ctx, int enable);
 void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
 int fstWriterGetDumpSizeLimitReached(void *ctx);
+int fstWriterGetFseekFailed(void *ctx);
 
 void *fstWriterCreate(const char *nam, int use_compressed_hier);
 void fstWriterClose(void *ctx);
 void fstWriterSetDate(void *ctx, const char *dat);
 void fstWriterSetVersion(void *ctx, const char *vers);
+void fstWriterSetComment(void *ctx, const char *comm);
+void fstWriterSetEnvVar(void *ctx, const char *envvar);
 void fstWriterSetTimescale(void *ctx, int ts);
 void fstWriterSetTimescaleFromString(void *ctx, const char *s);
 void fstWriterSetTimezero(void *ctx, int64_t tim);
@@ -167,6 +255,9 @@ void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const v
 void fstWriterEmitDumpActive(void *ctx, int enable);
 void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
 void fstWriterFlushContext(void *ctx);
+void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
+                const char *attrname, uint64_t arg);
+void fstWriterSetAttrEnd(void *ctx);
 
 /*
  * reader functions
@@ -199,6 +290,7 @@ uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
 int fstReaderGetDoubleEndianMatchState(void *ctx);
 const char *fstReaderGetVersionString(void *ctx);
 const char *fstReaderGetDateString(void *ctx);
+int fstReaderGetFseekFailed(void *ctx);
 
 void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
 void fstReaderSetUnlimitedTimeRange(void *ctx);
diff --git a/vpi/lxt2_write.c b/vpi/lxt2_write.c
index 4af04ec..c53854d 100644
--- a/vpi/lxt2_write.c
+++ b/vpi/lxt2_write.c
@@ -2187,7 +2187,7 @@ void lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth)
 if(lt)
 	{
 	if(depth > 9) depth = 9;
-	sprintf(lt->zmode, "wb%d", depth);
+	sprintf(lt->zmode, "wb%u", depth);
 	}
 }
 
diff --git a/vpi/sys_display.c b/vpi/sys_display.c
index 21b6545..51b5ee1 100644
--- a/vpi/sys_display.c
+++ b/vpi/sys_display.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2012 Stephen Williams (steve at icarus.com)
+ * Copyright (c) 1999-2013 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -1023,6 +1023,10 @@ static char *get_display(unsigned int *rtnsz, const struct strobe_cb_info *info)
   return rtn;
 }
 
+#ifdef BR916_STOPGAP_FIX
+static char br916_hint_issued = 0;
+#endif
+
 static int sys_check_args(vpiHandle callh, vpiHandle argv, const PLI_BYTE8*name,
                           int no_auto, int is_monitor)
 {
@@ -1060,6 +1064,34 @@ static int sys_check_args(vpiHandle callh, vpiHandle argv, const PLI_BYTE8*name,
 	      case vpiIntegerVar:
 	      case vpiTimeVar:
 	      case vpiRealVar:
+#ifdef BR916_STOPGAP_FIX
+		    // no_auto implies either $strobe or $monitor
+	          if (no_auto) {
+		    switch (vpi_get(_vpiFromThr, arg)) {
+		      case _vpiVThr:
+		      case _vpiWord:
+		      case _vpiString:
+	                vpi_printf("SORRY: %s:%d: ",
+				   vpi_get_str(vpiFile, callh),
+	                           (int)vpi_get(vpiLineNo, callh));
+	                vpi_printf("currently only simple signals or constant "
+                                   "expressions may be passed to %s.\n", name);
+			if (!br916_hint_issued) {
+			      vpi_printf("NOTE: You can work around this by "
+			                 "assigning the desired expression "
+			                 "to an\n"
+			                 "      intermediate net (using a "
+			                 "continuous assignment) and passing "
+			                 "that net\n"
+			                 "      to %s.\n", name);
+			      br916_hint_issued = 1;
+			}
+	                ret = 1;
+		      default:
+			break;
+		    }
+		  }
+#endif
 	      case vpiSysFuncCall:
 		  break;
 
diff --git a/vpi_user.h b/vpi_user.h
index 38fc8c6..e003db3 100644
--- a/vpi_user.h
+++ b/vpi_user.h
@@ -584,6 +584,25 @@ extern void vpip_format_strength(char*str, s_vpi_value*value, unsigned bit);
 extern void vpip_set_return_value(int value);
 extern s_vpi_vecval vpip_calc_clog2(vpiHandle arg);
 
+/*
+ * Stopgap fix for br916. We need to reject any attempt to pass a thread
+ * variable to $strobe or $monitor. To do this, we use some private VPI
+ * properties that are normally only used by the VVP thread cleanup code.
+ * Normally the following definitions are provided by vvp/vpi_priv.h, but
+ * for the stopgap fix we need to make them more widely available.
+ */
+#define BR916_STOPGAP_FIX
+#ifdef BR916_STOPGAP_FIX
+#define _vpiFromThr 0x1000001
+#   define _vpiNoThr   0
+#   define _vpiString  1
+#   define _vpiVThr    2
+#   define _vpiWord    3
+#   define _vpi_at_PV  4
+#   define _vpi_at_A   5
+#   define _vpi_at_APV 6
+#endif
+
 EXTERN_C_END
 
 #endif
diff --git a/vvp/array.cc b/vvp/array.cc
index ee7a382..7fa3705 100644
--- a/vvp/array.cc
+++ b/vvp/array.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2010 Stephen Williams (steve at icarus.com)
+ * Copyright (c) 2007-2013 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -507,7 +507,7 @@ static int vpi_array_var_word_get(int code, vpiHandle ref)
 	  case vpiAutomatic:
 	    return (int) parent->scope->is_automatic;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
 	  case _vpiFromThr:
 	    return _vpiNoThr;
 #endif
@@ -699,7 +699,7 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref)
 	  case vpiAutomatic:
 	    return (int) parent->scope->is_automatic;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
 	  case _vpiFromThr:
 	    return _vpi_at_A;
 #endif
@@ -1011,6 +1011,8 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
 	    sig->is_netarray = 1;
 	    sig->within.parent = &array->base;
 	    sig->id.index = vpip_make_dec_const(addr + array->first_addr.value);
+	      // Now we know the data type, update the array signed_flag.
+	    array->signed_flag = sig->signed_flag;
 	    return;
       }
 
@@ -1023,6 +1025,8 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
 	    sig->is_netarray = 1;
 	    sig->within.parent = &array->base;
 	    sig->id.index = vpip_make_dec_const(addr + array->first_addr.value);
+	      // Now we know the data type, update the array signed_flag.
+	    array->signed_flag = true;
 	    return;
       }
 }
@@ -1080,6 +1084,9 @@ void compile_real_array(char*label, char*name, int last, int first,
 
 void compile_net_array(char*label, char*name, int last, int first)
 {
+	// At this point we don't know the array data type, so we
+	// initialise signed_flag to false. This will be corrected
+	// (if necessary) when we attach words to the array.
       vpiHandle obj = vpip_make_array(label, name, first, last, false);
 
       struct __vpiArray*arr = ARRAY_HANDLE(obj);
diff --git a/vvp/concat.cc b/vvp/concat.cc
index c4457dc..f8b63e8 100644
--- a/vvp/concat.cc
+++ b/vvp/concat.cc
@@ -64,6 +64,36 @@ void vvp_fun_concat::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
       vvp_send_vec4(port.ptr()->out, val_, 0);
 }
 
+void vvp_fun_concat::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
+                                  unsigned base, unsigned wid, unsigned vwid,
+                                  vvp_context_t)
+{
+      assert(bit.size() == wid);
+
+      unsigned pdx = port.port();
+
+      if (vwid != wid_[pdx]) {
+	    cerr << "internal error: port " << pdx
+		 << " expects wid=" << wid_[pdx]
+		 << ", got wid=" << vwid << endl;
+	    assert(0);
+      }
+
+      unsigned off = 0;
+      for (unsigned idx = 0 ;  idx < pdx ;  idx += 1)
+	    off += wid_[idx];
+
+      unsigned limit = off + wid_[pdx];
+
+      off += base;
+      for (unsigned idx = 0 ;  idx < wid ;  idx += 1) {
+            if (off+idx >= limit) break;
+	    val_.set_bit(off+idx, bit.value(idx));
+      }
+
+      vvp_send_vec4(port.ptr()->out, val_, 0);
+}
+
 void compile_concat(char*label, unsigned w0, unsigned w1,
 		    unsigned w2, unsigned w3,
 		    unsigned argc, struct symb_s*argv)
diff --git a/vvp/slab.h b/vvp/slab.h
index f3e2c0e..6869b1d 100644
--- a/vvp/slab.h
+++ b/vvp/slab.h
@@ -1,8 +1,7 @@
 #ifndef __slab_H
 #define __slab_H
 /*
- * Copyright (c) 2008 Picture Elements, Inc.
- *    Stephen Williams (steve at icarus.com)
+ * Copyright (c) 2008 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -17,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 
diff --git a/vvp/vpi_const.cc b/vvp/vpi_const.cc
index a7d13a2..22a72a6 100644
--- a/vvp/vpi_const.cc
+++ b/vvp/vpi_const.cc
@@ -51,7 +51,7 @@ static int string_get(int code, vpiHandle ref)
           case vpiAutomatic:
 	      return 0;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
           case _vpiFromThr:
 	      return _vpiNoThr;
 #endif
@@ -363,7 +363,7 @@ static int binary_get(int code, vpiHandle ref)
           case vpiAutomatic:
 	    return 0;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
           case _vpiFromThr:
 	      return _vpiNoThr;
 #endif
@@ -564,7 +564,7 @@ static int dec_get(int code, vpiHandle ref)
           case vpiAutomatic:
 	    return 0;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
           case _vpiFromThr:
 	      return _vpiNoThr;
 #endif
@@ -675,7 +675,7 @@ static int real_get(int code, vpiHandle ref)
           case vpiAutomatic:
 	    return 0;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
           case _vpiFromThr:
 	      return _vpiNoThr;
 #endif
diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h
index fdb15e0..e67928a 100644
--- a/vvp/vpi_priv.h
+++ b/vvp/vpi_priv.h
@@ -40,7 +40,7 @@
 /*
  * Private VPI properties that are only used in the cleanup code.
  */
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) && !defined(BR916_STOPGAP_FIX)
 #define _vpiFromThr 0x1000001
 #   define _vpiNoThr  0
 #   define _vpiVThr   1
diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc
index 8fa47dc..a486c89 100644
--- a/vvp/vpi_signal.cc
+++ b/vvp/vpi_signal.cc
@@ -557,6 +557,11 @@ static int signal_get(int code, vpiHandle ref)
           case vpiAutomatic:
             return (int) vpip_scope(rfp)->is_automatic;
 
+#ifdef BR916_STOPGAP_FIX
+	  case _vpiFromThr:
+	    return _vpiNoThr;
+#endif
+
 	  case _vpiNexusId:
 	    if (rfp->msb == rfp->lsb)
 		  return (int) (unsigned long) rfp->node;
@@ -1081,7 +1086,7 @@ static int PV_get(int code, vpiHandle ref)
         case vpiAutomatic:
             return vpi_get(vpiAutomatic, rfp->parent);
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
         case _vpiFromThr:
             return _vpi_at_PV;
 #endif
diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc
index f65d2de..b9c2206 100644
--- a/vvp/vpi_vthr_vector.cc
+++ b/vvp/vpi_vthr_vector.cc
@@ -93,7 +93,7 @@ static int vthr_vec_get(int code, vpiHandle ref)
 	  case vpiSize:
 	    return rfp->wid;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
 	  case _vpiFromThr:
 	    return _vpiVThr;
 #endif
@@ -504,7 +504,7 @@ static int vthr_word_get(int code, vpiHandle ref)
 	  case vpiConstType:
 	    return rfp->subtype;
 
-#ifdef CHECK_WITH_VALGRIND
+#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX)
 	  case _vpiFromThr:
 	    return _vpiWord;
 #endif
diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc
index cb43418..7cd5b52 100644
--- a/vvp/vvp_net.cc
+++ b/vvp/vvp_net.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2009 Stephen Williams (steve at icarus.com)
+ * Copyright (c) 2004-2013 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -2332,12 +2332,11 @@ ostream& operator<< (ostream&out, const vvp_vector2_t&that)
 vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
 {
       size_ = that.size_;
-      if (size_ <= PTR_THRESH) {
+      if (size_ <= sizeof(val_)) {
 	    memcpy(val_, that.val_, sizeof(val_));
       } else {
-	    ptr_ = new vvp_scalar_t[size_];
-	    for (unsigned idx = 0 ;  idx < size_ ;  idx += 1)
-		  ptr_[idx] = that.ptr_[idx];
+	    ptr_ = new unsigned char[size_];
+	    memcpy(ptr_, that.ptr_, size_);
       }
 }
 
@@ -2348,26 +2347,25 @@ vvp_vector8_t::vvp_vector8_t(const vvp_vector4_t&that,
       if (size_ == 0)
 	    return;
 
-      vvp_scalar_t*tmp;
-      if (size_ <= PTR_THRESH)
-	    tmp = new (val_) vvp_scalar_t[PTR_THRESH];
-      else
-	    tmp = ptr_ = new vvp_scalar_t[size_];
-
-      for (unsigned idx = 0 ;  idx < size_ ;  idx += 1)
-	    tmp[idx] = vvp_scalar_t (that.value(idx), str0, str1);
-
+      if (size_ <= sizeof(val_)) {
+	    ptr_ = 0; // Prefill all val_ bytes
+	    for (unsigned idx = 0 ; idx < size_ ; idx += 1)
+		  val_[idx] = vvp_scalar_t(that.value(idx),str0, str1).raw();
+      } else {
+	    ptr_ = new unsigned char[size_];
+	    for (unsigned idx = 0 ;  idx < size_ ;  idx += 1)
+		  ptr_[idx] = vvp_scalar_t(that.value(idx), str0, str1).raw();
+      }
 }
 
 vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
 {
 	// Assign to self.
-      if (this == &that || (size_ > PTR_THRESH && that.size_ > PTR_THRESH &&
-                            ptr_ == that.ptr_))
+      if (this == &that)
 	    return *this;
 
       if (size_ != that.size_) {
-	    if (size_ > PTR_THRESH)
+	    if (size_ > sizeof(val_))
 		  delete[]ptr_;
 	    size_ = 0;
       }
@@ -2377,7 +2375,7 @@ vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
 	    return *this;
       }
 
-      if (that.size_ <= PTR_THRESH) {
+      if (that.size_ <= sizeof(val_)) {
 	    size_ = that.size_;
 	    memcpy(val_, that.val_, sizeof(val_));
 	    return *this;
@@ -2385,11 +2383,10 @@ vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
 
       if (size_ == 0) {
 	    size_ = that.size_;
-	    ptr_ = new vvp_scalar_t[size_];
+	    ptr_ = new unsigned char[size_];
       }
 
-      for (unsigned idx = 0 ;  idx < size_ ;  idx += 1)
-	    ptr_[idx] = that.ptr_[idx];
+      memcpy(ptr_, that.ptr_, size_);
 
       return *this;
 }
@@ -2398,12 +2395,12 @@ vvp_vector8_t vvp_vector8_t::subvalue(unsigned base, unsigned wid) const
 {
       vvp_vector8_t tmp (wid);
 
-      vvp_scalar_t* tmp_ptr = tmp.size_<=PTR_THRESH? reinterpret_cast<vvp_scalar_t*>(tmp.val_) : tmp.ptr_;
-      const vvp_scalar_t* ptr = size_<=PTR_THRESH? reinterpret_cast<const vvp_scalar_t*>(val_) : ptr_;
+      unsigned char* tmp_ptr = tmp.size_ <= sizeof(val_) ? tmp.val_ : tmp.ptr_;
+      const unsigned char*use_ptr = size_ <= sizeof(val_) ? val_ : ptr_;
 
       unsigned idx = 0;
       while ((idx < wid) && (base+idx < size_)) {
-	    tmp_ptr[idx] = ptr[base+idx];
+	    tmp_ptr[idx] = use_ptr[base+idx];
 	    idx += 1;
       }
 
@@ -2415,8 +2412,10 @@ vvp_vector8_t part_expand(const vvp_vector8_t&that, unsigned wid, unsigned off)
       assert(off < wid);
       vvp_vector8_t tmp (wid);
 
-      vvp_scalar_t* tmp_ptr = tmp.size_<=vvp_vector8_t::PTR_THRESH? reinterpret_cast<vvp_scalar_t*>(tmp.val_) : tmp.ptr_;
-      const vvp_scalar_t* that_ptr = that.size_<=vvp_vector8_t::PTR_THRESH? reinterpret_cast<const vvp_scalar_t*>(that.val_) : that.ptr_;
+      unsigned char* tmp_ptr = tmp.size_<= sizeof(tmp.val_) ?
+                               tmp.val_ : tmp.ptr_;
+      const unsigned char* that_ptr = that.size_<= sizeof(that.val_) ?
+                                      that.val_ : that.ptr_;
 
       unsigned idx = off;
 
diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h
index 0ef7805..a54466f 100644
--- a/vvp/vvp_net.h
+++ b/vvp/vvp_net.h
@@ -1,7 +1,7 @@
 #ifndef __vvp_net_H
 #define __vvp_net_H
 /*
- * Copyright (c) 2004-2011 Stephen Williams (steve at icarus.com)
+ * Copyright (c) 2004-2013 Stephen Williams (steve at icarus.com)
  *
  *    This source code is free software; you can redistribute it
  *    and/or modify it in source code form under the terms of the GNU
@@ -682,7 +682,15 @@ class vvp_scalar_t {
       unsigned strength1() const;
 
       bool eeq(vvp_scalar_t that) const { return value_ == that.value_; }
-      bool is_hiz() const { return value_ == 0; }
+      bool is_hiz() const { return (value_ & 0x77) == 0; }
+
+    private:
+        // This class and the vvp_vector8_t class are closely related,
+        // so allow vvp_vector8_t access to the raw encoding so that
+        // it can do compact vectoring of vvp_scalar_t objects.
+      friend class vvp_vector8_t;
+      explicit vvp_scalar_t(unsigned char val) : value_(val) { }
+      unsigned char raw() const { return value_; }
 
     private:
       unsigned char value_;
@@ -718,7 +726,7 @@ inline vvp_scalar_t::vvp_scalar_t(vvp_bit4_t val, unsigned str0, unsigned str1)
 
 inline vvp_bit4_t vvp_scalar_t::value() const
 {
-      if (value_ == 0) {
+      if ((value_ & 0x77) == 0) {
 	    return BIT4_Z;
       } else switch (value_ & 0x88) {
 	  case 0x00:
@@ -789,14 +797,10 @@ class vvp_vector8_t {
       vvp_vector8_t& operator= (const vvp_vector8_t&that);
 
     private:
-	// This is the number of vvp_scalar_t objects we can keep in
-	// the val_ buffer. If the vector8 is bigger then this, then
-	// resort to allocations to get a larger buffer.
-      enum { PTR_THRESH = 8 };
       unsigned size_;
       union {
-	    vvp_scalar_t*ptr_;
-	    char val_[PTR_THRESH * sizeof(vvp_scalar_t)];
+	    unsigned char*ptr_;
+	    unsigned char val_[sizeof(void *)];
       };
 };
 
@@ -821,41 +825,43 @@ extern vvp_vector8_t resistive_reduction(const vvp_vector8_t&a);
      strength information in the process. */
 extern vvp_vector4_t reduce4(const vvp_vector8_t&that);
 extern vvp_vector8_t part_expand(const vvp_vector8_t&a, unsigned wid, unsigned off);
+
   /* Print a vector8 value to a stream. */
 extern ostream& operator<< (ostream&, const vvp_vector8_t&);
 
 inline vvp_vector8_t::vvp_vector8_t(unsigned size__)
 : size_(size__)
 {
-      if (size_ <= PTR_THRESH) {
-	    new (reinterpret_cast<void*>(val_)) vvp_scalar_t[PTR_THRESH];
+      if (size_ <= sizeof(val_)) {
+	    memset(val_, 0, sizeof(val_));
       } else {
-	    ptr_ = new vvp_scalar_t[size_];
+	    ptr_ = new unsigned char[size_];
+	    memset(ptr_, 0, size_);
       }
 }
 
 inline vvp_vector8_t::~vvp_vector8_t()
 {
-      if (size_ > PTR_THRESH)
+      if (size_ > sizeof(val_))
 	    delete[]ptr_;
 }
 
 inline vvp_scalar_t vvp_vector8_t::value(unsigned idx) const
 {
       assert(idx < size_);
-      if (size_ <= PTR_THRESH)
-	    return reinterpret_cast<const vvp_scalar_t*>(val_) [idx];
+      if (size_ <= sizeof(val_))
+	    return vvp_scalar_t(val_[idx]);
       else
-	    return ptr_[idx];
+	    return vvp_scalar_t(ptr_[idx]);
 }
 
 inline void vvp_vector8_t::set_bit(unsigned idx, vvp_scalar_t val)
 {
       assert(idx < size_);
-      if (size_ <= PTR_THRESH)
-	    reinterpret_cast<vvp_scalar_t*>(val_) [idx] = val;
+      if (size_ <= sizeof(val_))
+	    val_[idx] = val.raw();
       else
-	    ptr_[idx] = val;
+	    ptr_[idx] = val.raw();
 }
 
   // Exactly-equal for vvp_vector8_t is common and should be as tight
@@ -867,15 +873,11 @@ inline bool vvp_vector8_t::eeq(const vvp_vector8_t&that) const
       if (size_ == 0)
 	    return true;
 
-      if (size_ <= PTR_THRESH)
-	    return 0 == memcmp(val_, that.val_, sizeof(val_));
-
-      for (unsigned idx = 0 ;  idx < size_ ;  idx += 1) {
-	    if (! ptr_[idx] .eeq( that.ptr_[idx] ))
-		return false;
-      }
-
-      return true;
+      if (size_ <= sizeof(val_))
+	      // This is equivalent to memcmp(val_, that.val_, sizeof(val_))==0
+	    return ptr_ == that.ptr_;
+      else
+	    return memcmp(ptr_, that.ptr_, size_) == 0;
 }
 
 /*
@@ -1067,6 +1069,11 @@ class vvp_fun_concat  : public vvp_net_fun_t {
       void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
                      vvp_context_t context);
 
+	// Part select variants of above
+      void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
+			unsigned base, unsigned wid, unsigned vwid,
+                        vvp_context_t);
+
     private:
       unsigned wid_[4];
       vvp_vector4_t val_;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-electronics/iverilog.git



More information about the Pkg-electronics-commits mailing list