changeset 79545:176f1495425c

New file.
author Dan Nicolaescu <dann@ics.uci.edu>
date Sat, 08 Dec 2007 17:58:56 +0000
parents 83e5f9b12104
children 0413a70bb454
files etc/NEWS lisp/ChangeLog lisp/progmodes/verilog-mode.el
diffstat 3 files changed, 10342 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Sat Dec 08 12:40:12 2007 +0000
+++ b/etc/NEWS	Sat Dec 08 17:58:56 2007 +0000
@@ -88,6 +88,8 @@
 
 ** The new package vera-mode.el provides a major mode for editing Vera files.
 
+** The new package verilog-mode.el provides a major mode for editing Verilog files.
+
 ** The new package socks.el implements the SOCKS v5 protocol.
 
 ** VC
--- a/lisp/ChangeLog	Sat Dec 08 12:40:12 2007 +0000
+++ b/lisp/ChangeLog	Sat Dec 08 17:58:56 2007 +0000
@@ -1,3 +1,8 @@
+2007-12-08  Michael McNamara <mac@verilog.com>
+	    Wilson Snyder <wsnyder@wsnyder.org>
+
+	* progmodes/verilog-mode.el: New file.
+
 2007-12-08  Eli Zaretskii  <eliz@fencepost.gnu.org>
 
 	* international/latexenc.el (latexenc-find-file-coding-system): If
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/progmodes/verilog-mode.el	Sat Dec 08 17:58:56 2007 +0000
@@ -0,0 +1,10335 @@
+;; verilog-mode.el --- major mode for editing verilog source in Emacs
+;;
+;; $Id: verilog-mode.el 377 2007-12-07 17:21:25Z wsnyder $
+
+;; Copyright (C) 1996-2007 Free Software Foundation, Inc.
+
+;; Author: Michael McNamara (mac@verilog.com)
+;;  http://www.verilog.com
+;;
+;; AUTO features, signal, modsig; by: Wilson Snyder
+;;	(wsnyder@wsnyder.org)
+;;	http://www.veripool.com
+;; Keywords: languages
+
+;; This program is free software; you can redistribute it and/or modify
+;; it 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.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; This mode borrows heavily from the Pascal-mode and the cc-mode of emacs
+
+;; USAGE
+;; =====
+
+;; A major mode for editing Verilog HDL source code. When you have
+;; entered Verilog mode, you may get more info by pressing C-h m. You
+;; may also get online help describing various functions by: C-h f
+;; <Name of function you want described>
+
+;; KNOWN BUGS / BUG REPORTS
+;; =======================
+
+;; Verilog is a rapidly evolving language, and hence this mode is
+;; under continuous development. Hence this is beta code, and likely
+;; has bugs. Please report any and all bugs to me at mac@verilog.com.
+;; Please use verilog-submit-bug-report to submit a report; type C-c
+;; C-b to invoke this and as a result I will have a much easier time
+;; of reproducing the bug you find, and hence fixing it.
+
+;; INSTALLING THE MODE
+;; ===================
+
+;; An older version of this mode may be already installed as a part of
+;; your environment, and one method of updating would be to update
+;; your emacs environment.  Sometimes this is difficult for local
+;; political/control reasons, and hence you can always install a
+;; private copy (or even a shared copy) which overrides the system
+;; default.
+
+;; You can get step by step help in installing this file by going to
+;; <http://www.verilog.com/emacs_install.html>
+
+;; The short list of installation instructions are: To set up
+;; automatic verilog mode, put this file in your load path, and put
+;; the following in code (please un comment it first!) in your
+;; .emacs, or in your site's site-load.el
+
+; (autoload 'verilog-mode "verilog-mode" "Verilog mode" t )
+; (setq auto-mode-alist (cons  '("\\.v\\'" . verilog-mode) auto-mode-alist))
+; (setq auto-mode-alist (cons  '("\\.dv\\'" . verilog-mode) auto-mode-alist))
+
+;; If you want to customize Verilog mode to fit your needs better,
+;; you may add these lines (the values of the variables presented
+;; here are the defaults). Note also that if you use an emacs that
+;; supports custom, it's probably better to use the custom menu to
+;; edit these.
+;;
+;; Be sure to examine at the help for verilog-auto, and the other
+;; verilog-auto-* functions for some major coding time savers.
+;;
+; ;; User customization for Verilog mode
+; (setq verilog-indent-level             3
+;       verilog-indent-level-module      3
+;       verilog-indent-level-declaration 3
+;       verilog-indent-level-behavioral  3
+;       verilog-indent-level-directive   1
+;       verilog-case-indent              2
+;       verilog-auto-newline             t
+;       verilog-auto-indent-on-newline   t
+;       verilog-tab-always-indent        t
+;       verilog-auto-endcomments         t
+;       verilog-minimum-comment-distance 40
+;       verilog-indent-begin-after-if    t
+;       verilog-auto-lineup              '(all)
+;       verilog-highlight-p1800-keywords nil
+;	verilog-linter			 "my_lint_shell_command"
+;	)
+
+;; 
+
+;;; History:
+;;
+;; 
+;;; Code:
+
+(provide 'verilog-mode)
+
+;; This variable will always hold the version number of the mode
+(defconst verilog-mode-version (substring "$$Revision: 377 $$" 12 -3)
+  "Version of this verilog mode.")
+(defconst verilog-mode-release-date (substring "$$Date: 2007-12-07 12:21:25 -0500 (Fri, 07 Dec 2007) $$" 8 -3)
+  "Version of this verilog mode.")
+
+(defun verilog-version ()
+  "Inform caller of the version of this file."
+  (interactive)
+  (message (concat "Using verilog-mode version " verilog-mode-version) ))
+
+;; Insure we have certain packages, and deal with it if we don't
+(if (fboundp 'eval-when-compile)
+    (eval-when-compile
+      (require 'verilog-mode)
+      (condition-case nil
+          (require 'imenu)
+        (error nil))
+      (condition-case nil
+	  (require 'reporter)
+        (error nil))
+      (condition-case nil
+          (require 'easymenu)
+        (error nil))
+      (condition-case nil
+          (require 'regexp-opt)
+        (error nil))
+      (condition-case nil
+	  (load "skeleton") ;; bug in 19.28 through 19.30 skeleton.el, not provided.
+        (error nil))
+      (condition-case nil
+	  (require 'vc)
+        (error nil))
+      (condition-case nil
+          (if (fboundp 'when)
+	      nil ;; fab
+	    (defmacro when (var &rest body)
+	      (` (cond ( (, var) (,@ body))))))
+        (error nil))
+      (condition-case nil
+          (if (fboundp 'unless)
+	      nil ;; fab
+	    (defmacro unless (var &rest body)
+	      (` (if (, var) nil (,@ body)))))
+        (error nil))
+      (condition-case nil
+          (if (fboundp 'store-match-data)
+	      nil ;; fab
+	    (defmacro store-match-data (&rest args) nil))
+        (error nil))
+      (condition-case nil
+	  (if (boundp 'current-menubar)
+	      nil ;; great
+	    (progn
+	     (defmacro set-buffer-menubar (&rest args) nil)
+	     (defmacro add-submenu (&rest args) nil))
+	    )
+	(error nil))
+      (condition-case nil
+	  (if (fboundp 'zmacs-activate-region)
+	      nil ;; great
+	    (defmacro zmacs-activate-region (&rest args) nil))
+	(error nil))
+      (condition-case nil
+	  (if (fboundp 'char-before)
+	      nil ;; great
+	    (defmacro char-before (&rest body)
+	      (` (char-after (1- (point))))))
+	(error nil))
+      ;; Requires to define variables that would be "free" warnings
+      (condition-case nil
+	  (require 'font-lock)
+	(error nil))
+      (condition-case nil
+	  (require 'compile)
+	(error nil))
+      (condition-case nil
+	  (require 'custom)
+	(error nil))
+      (condition-case nil
+	  (require 'dinotrace)
+	(error nil))
+      (condition-case nil
+	  (if (fboundp 'dinotrace-unannotate-all)
+	      nil ;; great
+	    (defun dinotrace-unannotate-all (&rest args) nil))
+	(error nil))
+      (condition-case nil
+	  (if (fboundp 'customize-apropos)
+	      nil ;; great
+	    (defun customize-apropos (&rest args) nil))
+	(error nil))
+      (condition-case nil
+	  (if (fboundp 'match-string-no-properties)
+	      nil ;; great
+	    (defsubst match-string-no-properties (num &optional string)
+	      "Return string of text matched by last search, without text properties.
+NUM specifies which parenthesized expression in the last regexp.
+ Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
+Zero means the entire text matched by the whole regexp or whole string.
+STRING should be given if the last search was by `string-match' on STRING."
+	      (if (match-beginning num)
+		  (if string
+		      (let ((result
+			     (substring string (match-beginning num) (match-end num))))
+			(set-text-properties 0 (length result) nil result)
+			result)
+		    (buffer-substring-no-properties (match-beginning num)
+						    (match-end num)
+						    (current-buffer)
+						    )))))
+	(error nil))
+      (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
+	  nil ;; We've got what we needed
+	;; We have the old custom-library, hack around it!
+	(defmacro defgroup (&rest args)  nil)
+	(defmacro customize (&rest args)
+	  (message "Sorry, Customize is not available with this version of emacs"))
+	(defmacro defcustom (var value doc &rest args)
+	  (` (defvar (, var) (, value) (, doc))))
+	)
+      (if (fboundp 'defface)
+	  nil ; great!
+	(defmacro defface (var value doc &rest args)
+	  (` (make-face (, var))))
+	)
+
+      (if (and (featurep 'custom) (fboundp 'customize-group))
+	  nil ;; We've got what we needed
+	;; We have an intermediate custom-library, hack around it!
+	(defmacro customize-group (var &rest args)
+	  (`(customize (, var) )))
+	)
+
+      ))
+;; Provide a regular expression optimization routine, using regexp-opt
+;; if provided by the user's elisp libraries
+(eval-and-compile
+  (if (fboundp 'regexp-opt)
+      ;; regexp-opt is defined, does it take 3 or 2 arguments?
+      (if (fboundp 'function-max-args)
+	  (case (function-max-args `regexp-opt)
+	    ( 3 ;; It takes 3
+	      (condition-case nil	; Hide this defun from emacses
+					;with just a two input regexp
+		  (defun verilog-regexp-opt (a b)
+		    "Deal with differing number of required arguments for  `regexp-opt'.
+         Call 'regexp-opt' on A and B."
+		    (regexp-opt a b 't)
+		    )
+		(error nil))
+	      )
+	      ( 2 ;; It takes 2
+	      (defun verilog-regexp-opt (a b)
+		"Call 'regexp-opt' on A and B."
+		(regexp-opt a b))
+	      )
+	    ( t nil))
+	;; We can't tell; assume it takes 2
+	(defun verilog-regexp-opt (a b)
+	  "Call 'regexp-opt' on A and B."
+	  (regexp-opt a b))
+	)
+    ;; There is no regexp-opt, provide our own
+    (defun verilog-regexp-opt (strings &optional paren shy)
+      (let ((open (if paren "\\(" "")) (close (if paren "\\)" "")))
+	(concat open (mapconcat 'regexp-quote strings "\\|") close)))
+    ))
+
+(eval-when-compile
+  (defun verilog-regexp-words (a)
+    "Call 'regexp-opt' with word delimiters."
+    (concat "\\<" (verilog-regexp-opt a t) "\\>")))
+
+(defun verilog-regexp-words (a)
+  "Call 'regexp-opt' with word delimiters for the words A."
+  (concat "\\<" (verilog-regexp-opt a t) "\\>"))
+
+(defun verilog-customize ()
+  "Link to customize screen for Verilog."
+  (interactive)
+  (customize-group 'verilog-mode))
+
+(defun verilog-font-customize ()
+  "Link to customize fonts used for Verilog."
+  (interactive)
+  (customize-apropos "font-lock-*" 'faces))
+
+(defgroup verilog-mode nil
+  "Facilitates easy editing of Verilog source text"
+  :group 'languages)
+
+; (defgroup verilog-mode-fonts nil
+;   "Facilitates easy customization fonts used in Verilog source text"
+;   :link '(customize-apropos "font-lock-*" 'faces)
+;  :group 'verilog-mode)
+
+(defgroup verilog-mode-indent nil
+  "Customize indentation and highlighting of verilog source text"
+  :group 'verilog-mode)
+
+(defgroup verilog-mode-actions nil
+  "Customize actions on verilog source text"
+  :group 'verilog-mode)
+
+(defgroup verilog-mode-auto nil
+  "Customize AUTO actions when expanding verilog source text"
+  :group 'verilog-mode)
+
+(defcustom verilog-linter
+  "echo 'No verilog-linter set, see \"M-x describe-variable verilog-linter\"'"
+  "*Unix program and arguments to call to run a lint checker on verilog source.
+Depending on the `verilog-set-compile-command', this may be invoked when
+you type \\[compile].  When the compile completes, \\[next-error] will take
+you to the next lint error."
+  :type 'string
+  :group 'verilog-mode-actions)
+
+(defcustom verilog-coverage
+  "echo 'No verilog-coverage set, see \"M-x describe-variable verilog-coverage\"'"
+  "*Program and arguments to use to annotate for coverage verilog source.
+Depending on the `verilog-set-compile-command', this may be invoked when
+you type \\[compile].  When the compile completes, \\[next-error] will take
+you to the next lint error."
+  :type 'string
+  :group 'verilog-mode-actions)
+
+(defcustom verilog-simulator
+  "echo 'No verilog-simulator set, see \"M-x describe-variable verilog-simulator\"'"
+  "*Program and arguments to use to interpret verilog source.
+Depending on the `verilog-set-compile-command', this may be invoked when
+you type \\[compile].  When the compile completes, \\[next-error] will take
+you to the next lint error."
+  :type 'string
+  :group 'verilog-mode-actions)
+
+(defcustom verilog-compiler
+  "echo 'No verilog-compiler set, see \"M-x describe-variable verilog-compiler\"'"
+  "*Program and arguments to use to compile verilog source.
+Depending on the `verilog-set-compile-command', this may be invoked when
+you type \\[compile].  When the compile completes, \\[next-error] will take
+you to the next lint error."
+  :type 'string
+  :group 'verilog-mode-actions)
+
+(defvar verilog-tool 'verilog-linter
+  "Which tool to use for building compiler-command.
+Either nil, `verilog-linter, `verilog-coverage, `verilog-simulator, or
+`verilog-compiler.  Alternatively use the \"Choose Compilation Action\"
+menu.  See `verilog-set-compile-command' for more information.")
+
+(defcustom verilog-highlight-translate-off nil
+  "*Non-nil means background-highlight code excluded from translation.
+That is, all code between \"// synopsys translate_off\" and
+\"// synopsys translate_on\" is highlighted using a different background color
+\(face `verilog-font-lock-translate-off-face').
+
+Note: This will slow down on-the-fly fontification (and thus editing).
+
+Note: Activate the new setting in a Verilog buffer by re-fontifying it (menu
+entry \"Fontify Buffer\").  XEmacs: turn off and on font locking."
+  :type 'boolean
+  :group 'verilog-mode-indent)
+
+(defcustom verilog-indent-level 3
+  "*Indentation of Verilog statements with respect to containing block."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-indent-level-module 3
+  "*Indentation of Module level Verilog statements.  (eg always, initial)
+Set to 0 to get initial and always statements lined up on the left side of
+your screen."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-indent-level-declaration 3
+  "*Indentation of declarations with respect to containing block.
+Set to 0 to get them list right under containing block."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-indent-declaration-macros nil
+  "*How to treat macro expansions in a declaration.
+If nil, indent as:
+	input [31:0] a;
+	input        `CP;
+	output       c;
+If non nil, treat as:
+	input [31:0] a;
+	input `CP    ;
+	output       c;"
+  :group 'verilog-mode-indent
+  :type 'boolean)
+
+(defcustom verilog-indent-lists t
+  "*How to treat indenting items in a list.
+If t (the default), indent as:
+	always @( posedge a or
+	          reset ) begin
+
+If nil, treat as:
+	always @( posedge a or
+	   reset ) begin"
+  :group 'verilog-mode-indent
+  :type 'boolean)
+
+(defcustom verilog-indent-level-behavioral 3
+  "*Absolute indentation of first begin in a task or function block.
+Set to 0 to get such code to start at the left side of the screen."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-indent-level-directive 1
+  "*Indentation to add to each level of `ifdef declarations.
+Set to 0 to have all directives start at the left side of the screen."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-cexp-indent 2
+  "*Indentation of Verilog statements split across lines."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-case-indent 2
+  "*Indentation for case statements."
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-auto-newline t
+  "*True means automatically newline after semicolons."
+  :group 'verilog-mode-indent
+  :type 'boolean)
+
+(defcustom verilog-auto-indent-on-newline t
+  "*True means automatically indent line after newline."
+  :group 'verilog-mode-indent
+  :type 'boolean)
+
+(defcustom verilog-tab-always-indent t
+  "*True means TAB should always re-indent the current line.
+Nil means TAB will only reindent when at the beginning of the line."
+  :group 'verilog-mode-indent
+  :type 'boolean)
+
+(defcustom verilog-tab-to-comment nil
+  "*True means TAB moves to the right hand column in preparation for a comment."
+  :group 'verilog-mode-actions
+  :type 'boolean)
+
+(defcustom verilog-indent-begin-after-if t
+  "*If true, indent begin statements following if, else, while, for and repeat.
+Otherwise, line them up."
+  :group 'verilog-mode-indent
+  :type 'boolean )
+
+
+(defcustom verilog-align-ifelse nil
+  "*If true, align `else' under matching `if'.
+Otherwise else is lined up with first character on line holding matching if."
+  :group 'verilog-mode-indent
+  :type 'boolean )
+
+(defcustom verilog-minimum-comment-distance 10
+  "*Minimum distance (in lines) between begin and end required before a comment.
+Setting this variable to zero results in every end acquiring a comment; the
+default avoids too many redundant comments in tight quarters"
+  :group 'verilog-mode-indent
+  :type 'integer)
+
+(defcustom verilog-auto-lineup '(declaration)
+  "*Algorithm for lining up statements on multiple lines.
+
+If this list contains the symbol 'all', then all line ups described below
+are done.
+
+If this list contains the symbol 'declaration', then declarations are lined up
+with any preceding declarations, taking into account widths and the like, so
+for example the code:
+	reg [31:0] a;
+	reg b;
+would become
+	reg [31:0] a;
+	reg        b;
+
+If this list contains the symbol 'assignment', then assignments are lined up
+with any preceding assignments, so for example the code
+	a_long_variable = b + c;
+	d = e + f;
+would become
+	a_long_variable = b + c;
+	d               = e + f;"
+
+;; The following is not implemented:
+;If this list contains the symbol 'case', then case items are lined up
+;with any preceding case items, so for example the code
+;	case (a) begin
+;	 a_long_state : a = 3;
+;	 b: a = 4;
+;	endcase
+;would become
+;	case (a) begin
+;	 a_long_state : a = 3;
+;	 b            : a = 4;
+;	endcase
+;
+
+  :group 'verilog-mode-indent
+  :type 'list )
+
+(defcustom verilog-highlight-p1800-keywords nil
+  "*If true highlight words newly reserved by IEEE-1800 in
+verilog-font-lock-p1800-face in order to gently suggest changing where
+these words are used as variables to something else.  Nil means highlight
+these words as appropriate for the SystemVerilog IEEE-1800 standard.  Note
+that changing this will require restarting emacs to see the effect as font
+color choices are cached by emacs"
+  :group 'verilog-mode-indent
+  :type 'boolean)
+
+(defcustom verilog-auto-endcomments t
+  "*True means insert a comment /* ... */ after 'end's.
+The name of the function or case will be set between the braces."
+  :group 'verilog-mode-actions
+  :type 'boolean )
+
+(defcustom verilog-auto-read-includes nil
+  "*True means to automatically read includes before AUTOs.
+This will do a `verilog-read-defines' and `verilog-read-includes' before
+each AUTO expansion.  This makes it easier to embed defines and includes,
+but can result in very slow reading times if there are many or large
+include files."
+  :group 'verilog-mode-actions
+  :type 'boolean )
+
+(defcustom verilog-auto-save-policy nil
+  "*Non-nil indicates action to take when saving a Verilog buffer with AUTOs.
+A value of `force' will always do a \\[verilog-auto] automatically if
+needed on every save.  A value of `detect' will do \\[verilog-auto]
+automatically when it thinks necessary.  A value of `ask' will query the
+user when it thinks updating is needed.
+
+You should not rely on the 'ask or 'detect policies, they are safeguards
+only.  They do not detect when AUTOINSTs need to be updated because a
+sub-module's port list has changed."
+  :group 'verilog-mode-actions
+  :type '(choice (const nil) (const ask) (const detect) (const force)))
+
+(defcustom verilog-auto-star-expand t
+  "*Non-nil indicates to expand a SystemVerilog .* instance ports.
+They will be expanded in the same way as if there was a AUTOINST in the
+instantiation.  See also `verilog-auto-star' and `verilog-auto-star-save'."
+  :group 'verilog-mode-actions
+  :type 'boolean)
+
+(defcustom verilog-auto-star-save nil
+  "*Non-nil indicates to save to disk SystemVerilog .* instance expansions.
+Nil indicates direct connections will be removed before saving.  Only
+meaningful to those created due to `verilog-auto-star-expand' being set.
+
+Instead of setting this, you may want to use /*AUTOINST*/, which will
+always be saved."
+  :group 'verilog-mode-actions
+  :type 'boolean)
+
+(defvar verilog-auto-update-tick nil
+  "Modification tick at which autos were last performed.")
+
+(defvar verilog-auto-last-file-locals nil
+  "Text from file-local-variables during last evaluation.")
+
+(defvar verilog-error-regexp-add-didit nil)
+(defvar verilog-error-regexp nil)
+(setq verilog-error-regexp-add-didit nil
+ verilog-error-regexp
+  '(
+	; SureLint
+;;    ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 2)
+	; Most SureFire tools
+    ("\\(WARNING\\|ERROR\\|INFO\\)[^:]*: \\([^,]+\\), \\(line \\|\\)\\([0-9]+\\):" 2 4 )
+    ("\
+\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
+:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 2 5)
+        ; xsim
+	; Error! in file /homes/mac/Axis/Xsim/test.v at line 13		[OBJ_NOT_DECLARED]
+    ("\\(Error\\|Warning\\).*in file (\\([^ \t]+\\) at line *\\([0-9]+\\))" 2 3)
+	; vcs
+    ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 3)
+    ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 2)
+    ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 3)
+    ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 2)
+        ; Verilator
+    ("%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4)
+    ("%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4)
+       ; vxl
+    ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 3)
+    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\([0-9]+\\):.*$" 1 2)	       ; vxl
+    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+line[ \t]+\\([0-9]+\\):.*$" 1 2)
+        ; nc-verilog
+    (".*\\*[WE],[0-9A-Z]+ (\\([^ \t,]+\\),\\([0-9]+\\)|" 1 2)
+       ; Leda
+    ("In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\[\\(Warning\\|Error\\|Failure\\)\\][^\n]*" 1 2)
+    )
+;  "*List of regexps for verilog compilers, like verilint. See compilation-error-regexp-alist for the formatting."
+)
+
+(defvar verilog-error-font-lock-keywords
+  '(
+    ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 bold t)
+    ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 2 bold t)
+
+    ("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 2 bold t)
+    ("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 3 bold t)
+
+    ("\
+\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
+:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 bold t)
+    ("\
+\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
+:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 bold t)
+
+    ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 bold t)
+    ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 3 bold t)
+
+    ("%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 bold t)
+    ("%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 4 bold t)
+
+    ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
+    ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
+
+    ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
+    ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 3 bold t)
+
+    ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 bold t)
+    ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
+       ; vxl
+    ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
+    ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
+
+    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\([0-9]+\\):.*$" 1 bold t)
+    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\([0-9]+\\):.*$" 2 bold t)
+
+    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+line[ \t]+\\([0-9]+\\):.*$" 1 bold t)
+    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+line[ \t]+\\([0-9]+\\):.*$" 2 bold t)
+        ; nc-verilog
+    (".*[WE],[0-9A-Z]+ (\\([^ \t,]+\\),\\([0-9]+\\)|" 1 bold t)
+    (".*[WE],[0-9A-Z]+ (\\([^ \t,]+\\),\\([0-9]+\\)|" 2 bold t)
+       ; Leda
+    ("In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\[\\(Warning\\|Error\\|Failure\\)\\][^\n]*" 1 bold t)
+    ("In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\[\\(Warning\\|Error\\|Failure\\)\\][^\n]*" 2 bold t)
+    )
+  "*Keywords to also highlight in Verilog *compilation* buffers."
+  )
+
+(defcustom verilog-library-flags '("")
+  "*List of standard Verilog arguments to use for /*AUTOINST*/.
+These arguments are used to find files for `verilog-auto', and match
+the flags accepted by a standard Verilog-XL simulator.
+
+    -f filename     Reads more `verilog-library-flags' from the filename.
+    +incdir+dir     Adds the directory to `verilog-library-directories'.
+    -Idir           Adds the directory to `verilog-library-directories'.
+    -y dir          Adds the directory to `verilog-library-directories'.
+    +libext+.v      Adds the extensions to `verilog-library-extensions'.
+    -v filename     Adds the filename to `verilog-library-files'.
+
+    filename        Adds the filename to `verilog-library-files'.
+                    This is not recommended, -v is a better choice.
+
+You might want these defined in each file; put at the *END* of your file
+something like:
+
+    // Local Variables:
+    // verilog-library-flags:(\"-y dir -y otherdir\")
+    // End:
+
+Verilog-mode attempts to detect changes to this local variable, but they
+are only insured to be correct when the file is first visited. Thus if you
+have problems, use \\[find-alternate-file] RET to have these take effect.
+
+See also the variables mentioned above."
+  :group 'verilog-mode-auto
+  :type '(repeat string))
+
+(defcustom verilog-library-directories '(".")
+  "*List of directories when looking for files for /*AUTOINST*/.
+The directory may be relative to the current file, or absolute.
+Environment variables are also expanded in the directory names.
+Having at least the current directory is a good idea.
+
+You might want these defined in each file; put at the *END* of your file
+something like:
+
+    // Local Variables:
+    // verilog-library-directories:(\".\" \"subdir\" \"subdir2\")
+    // End:
+
+Verilog-mode attempts to detect changes to this local variable, but they
+are only insured to be correct when the file is first visited. Thus if you
+have problems, use \\[find-alternate-file] RET to have these take effect.
+
+See also `verilog-library-flags', `verilog-library-files'
+and `verilog-library-extensions'."
+  :group 'verilog-mode-auto
+  :type '(repeat file))
+
+(defcustom verilog-library-files '()
+  "*List of files to search for modules when looking for AUTOINST files.
+This is a complete path, usually to a technology file with many standard
+cells defined in it.
+
+You might want these defined in each file; put at the *END* of your file
+something like:
+
+    // Local Variables:
+    // verilog-library-files:(\"/some/path/technology.v\" \"/some/path/tech2.v\")
+    // End:
+
+Verilog-mode attempts to detect changes to this local variable, but they
+are only insured to be correct when the file is first visited. Thus if you
+have problems, use \\[find-alternate-file] RET to have these take effect.
+
+See also `verilog-library-flags', `verilog-library-directories'."
+  :group 'verilog-mode-auto
+  :type '(repeat directory))
+
+(defcustom verilog-library-extensions '(".v")
+  "*List of extensions to use when looking for files for /*AUTOINST*/.
+See also `verilog-library-flags', `verilog-library-directories'."
+  :type '(repeat string)
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-active-low-regexp nil
+  "*If set, treat signals matching this regexp as active low.
+This is used for AUTORESET and AUTOTIEOFF.  For proper behavior,
+you will probably also need `verilog-auto-reset-widths' set."
+  :group 'verilog-mode-auto
+  :type 'string)
+
+(defcustom verilog-auto-sense-include-inputs nil
+  "*If true, AUTOSENSE should include all inputs.
+If nil, only inputs that are NOT output signals in the same block are
+included."
+  :type 'boolean
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-auto-sense-defines-constant nil
+  "*If true, AUTOSENSE should assume all defines represent constants.
+When true, the defines will not be included in sensitivity lists.  To
+maintain compatibility with other sites, this should be set at the bottom
+of each verilog file that requires it, rather than being set globally."
+  :type 'boolean
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-auto-reset-widths t
+  "*If true, AUTORESET should determine the width of signals.
+This is then used to set the width of the zero (32'h0 for example).  This
+is required by some lint tools that aren't smart enough to ignore widths of
+the constant zero.  This may result in ugly code when parameters determine
+the MSB or LSB of a signal inside a AUTORESET."
+  :type 'boolean
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-assignment-delay ""
+  "*Text used for delays in delayed assignments.  Add a trailing space if set."
+  :type 'string
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-auto-inst-vector t
+  "*If true, when creating default ports with AUTOINST, use bus subscripts.
+If nil, skip the subscript when it matches the entire bus as declared in
+the module (AUTOWIRE signals always are subscripted, you must manually
+declare the wire to have the subscripts removed.)  Nil may speed up some
+simulators, but is less general and harder to read, so avoid."
+  :group 'verilog-mode-auto
+  :type 'boolean )
+
+(defcustom verilog-auto-inst-template-numbers nil
+  "*If true, when creating templated ports with AUTOINST, add a comment.
+The comment will add the line number of the template that was used for that
+port declaration.  Setting this aids in debugging, but nil is suggested for
+regular use to prevent large numbers of merge conflicts."
+  :group 'verilog-mode-auto
+  :type 'boolean )
+
+(defvar verilog-auto-inst-column 40
+  "Column number for first part of auto-inst.")
+
+(defcustom verilog-auto-input-ignore-regexp nil
+  "*If set, when creating AUTOINPUT list, ignore signals matching this regexp.
+See the \\[verilog-faq] for examples on using this."
+  :group 'verilog-mode-auto
+  :type 'string )
+
+(defcustom verilog-auto-inout-ignore-regexp nil
+  "*If set, when creating AUTOINOUT list, ignore signals matching this regexp.
+See the \\[verilog-faq] for examples on using this."
+  :group 'verilog-mode-auto
+  :type 'string )
+
+(defcustom verilog-auto-output-ignore-regexp nil
+  "*If set, when creating AUTOOUTPUT list, ignore signals matching this regexp.
+See the \\[verilog-faq] for examples on using this."
+  :group 'verilog-mode-auto
+  :type 'string )
+
+(defcustom verilog-auto-unused-ignore-regexp nil
+  "*If set, when creating AUTOUNUSED list, ignore signals matching this regexp.
+See the \\[verilog-faq] for examples on using this."
+  :group 'verilog-mode-auto
+  :type 'string )
+
+(defcustom verilog-typedef-regexp nil
+  "*If non-nil, regular expression that matches Verilog-2001 typedef names.
+For example, \"_t$\" matches typedefs named with _t, as in the C language."
+  :group 'verilog-mode-auto
+  :type 'string )
+
+(defcustom verilog-mode-hook   'verilog-set-compile-command
+  "*Hook (List of functions) run after verilog mode is loaded."
+  :type 'hook
+  :group 'verilog-mode)
+
+(defcustom verilog-auto-hook nil
+  "*Hook run after `verilog-mode' updates AUTOs."
+  :type 'hook
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-before-auto-hook nil
+  "*Hook run before `verilog-mode' updates AUTOs."
+  :type 'hook
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-delete-auto-hook nil
+  "*Hook run after `verilog-mode' deletes AUTOs."
+  :type 'hook
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-before-delete-auto-hook nil
+  "*Hook run before `verilog-mode' deletes AUTOs."
+  :type 'hook
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-getopt-flags-hook nil
+  "*Hook run after `verilog-getopt-flags' determines the Verilog option lists."
+  :type 'hook
+  :group 'verilog-mode-auto)
+
+(defcustom verilog-before-getopt-flags-hook nil
+  "*Hook run before `verilog-getopt-flags' determines the Verilog option lists."
+  :type 'hook
+  :group 'verilog-mode-auto)
+
+(defvar verilog-imenu-generic-expression
+  '((nil "^\\s-*\\(\\(m\\(odule\\|acromodule\\)\\)\\|primitive\\)\\s-+\\([a-zA-Z0-9_.:]+\\)" 4)
+    ("*Vars*" "^\\s-*\\(reg\\|wire\\)\\s-+\\(\\|\\[[^]]+\\]\\s-+\\)\\([A-Za-z0-9_]+\\)" 3))
+  "Imenu expression for Verilog-mode.  See `imenu-generic-expression'.")
+
+;;
+;; provide a verilog-header function.
+;; Customization variables:
+;;
+(defvar verilog-date-scientific-format nil
+  "*If non-nil, dates are written in scientific format (e.g.  1997/09/17).
+If nil, in European format (e.g.  17.09.1997).  The brain-dead American
+format (e.g.  09/17/1997) is not supported.")
+
+(defvar verilog-company nil
+  "*Default name of Company for verilog header.
+If set will become buffer local.")
+
+(defvar verilog-project nil
+  "*Default name of Project for verilog header.
+If set will become buffer local.")
+
+(define-abbrev-table 'verilog-mode-abbrev-table ())
+
+(defvar verilog-mode-map ()
+  "Keymap used in Verilog mode.")
+(if verilog-mode-map
+    ()
+  (setq verilog-mode-map (make-sparse-keymap))
+  (define-key verilog-mode-map ";"        'electric-verilog-semi)
+  (define-key verilog-mode-map [(control 59)]    'electric-verilog-semi-with-comment)
+  (define-key verilog-mode-map ":"        'electric-verilog-colon)
+  ;;(define-key verilog-mode-map "="        'electric-verilog-equal)
+  (define-key verilog-mode-map "\`"       'electric-verilog-tick)
+  (define-key verilog-mode-map "\t"       'electric-verilog-tab)
+  (define-key verilog-mode-map "\r"       'electric-verilog-terminate-line)
+  ;; backspace/delete key bindings
+  (define-key verilog-mode-map [backspace]    'backward-delete-char-untabify)
+  (unless (boundp 'delete-key-deletes-forward) ; XEmacs variable
+    (define-key verilog-mode-map [delete]       'delete-char)
+    (define-key verilog-mode-map [(meta delete)] 'kill-word))
+  (define-key verilog-mode-map "\M-\C-b"  'electric-verilog-backward-sexp)
+  (define-key verilog-mode-map "\M-\C-f"  'electric-verilog-forward-sexp)
+  (define-key verilog-mode-map "\M-\r"    `electric-verilog-terminate-and-indent)
+  (define-key verilog-mode-map "\M-\t"    'verilog-complete-word)
+  (define-key verilog-mode-map "\M-?"     'verilog-show-completions)
+  (define-key verilog-mode-map [(meta control h)] 'verilog-mark-defun)
+  (define-key verilog-mode-map "\C-c\`"   'verilog-lint-off)
+  (define-key verilog-mode-map "\C-c\*"   'verilog-delete-auto-star-implicit)
+  (define-key verilog-mode-map "\C-c\C-r" 'verilog-label-be)
+  (define-key verilog-mode-map "\C-c\C-i" 'verilog-pretty-declarations)
+  (define-key verilog-mode-map "\C-c="    'verilog-pretty-expr)
+  (define-key verilog-mode-map "\C-c\C-b" 'verilog-submit-bug-report)
+  (define-key verilog-mode-map "\M-*"     'verilog-star-comment)
+  (define-key verilog-mode-map "\C-c\C-c" 'verilog-comment-region)
+  (define-key verilog-mode-map "\C-c\C-u" 'verilog-uncomment-region)
+  (define-key verilog-mode-map "\M-\C-a"  'verilog-beg-of-defun)
+  (define-key verilog-mode-map "\M-\C-e"  'verilog-end-of-defun)
+  (define-key verilog-mode-map "\C-c\C-d" 'verilog-goto-defun)
+  (define-key verilog-mode-map "\C-c\C-k" 'verilog-delete-auto)
+  (define-key verilog-mode-map "\C-c\C-a" 'verilog-auto)
+  (define-key verilog-mode-map "\C-c\C-s" 'verilog-auto-save-compile)
+  (define-key verilog-mode-map "\C-c\C-z" 'verilog-inject-auto)
+  (define-key verilog-mode-map "\C-c\C-e" 'verilog-expand-vector)
+  (define-key verilog-mode-map "\C-c\C-h" 'verilog-header)
+  )
+
+;; menus
+(defvar verilog-xemacs-menu
+  '("Verilog"
+    ("Choose Compilation Action"
+     ["None"
+      (progn
+	(setq verilog-tool nil)
+	(verilog-set-compile-command))
+      :style radio
+      :selected (equal verilog-tool nil)]
+     ["Lint"
+      (progn
+	(setq verilog-tool 'verilog-linter)
+	(verilog-set-compile-command))
+      :style radio
+      :selected (equal verilog-tool `verilog-linter)]
+     ["Coverage"
+      (progn
+	(setq verilog-tool 'verilog-coverage)
+	(verilog-set-compile-command))
+      :style radio
+      :selected (equal verilog-tool `verilog-coverage)]
+     ["Simulator"
+      (progn
+	(setq verilog-tool 'verilog-simulator)
+	(verilog-set-compile-command))
+      :style radio
+      :selected (equal verilog-tool `verilog-simulator)]
+     ["Compiler"
+      (progn
+	(setq verilog-tool 'verilog-compiler)
+	(verilog-set-compile-command))
+      :style radio
+      :selected (equal verilog-tool `verilog-compiler)]
+     )
+    ("Move"
+     ["Beginning of function"		verilog-beg-of-defun t]
+     ["End of function"			verilog-end-of-defun t]
+     ["Mark function"			verilog-mark-defun t]
+     ["Goto function/module"		verilog-goto-defun t]
+     ["Move to beginning of block"	electric-verilog-backward-sexp t]
+     ["Move to end of block"		electric-verilog-forward-sexp t]
+     )
+    ("Comments"
+     ["Comment Region"			verilog-comment-region t]
+     ["UnComment Region"			verilog-uncomment-region t]
+     ["Multi-line comment insert"	verilog-star-comment t]
+     ["Lint error to comment"		verilog-lint-off t]
+     )
+    "----"
+    ["Compile"				compile t]
+    ["AUTO, Save, Compile"		verilog-auto-save-compile t]
+    ["Next Compile Error"		next-error t]
+    ["Ignore Lint Warning at point"	verilog-lint-off t]
+    "----"
+    ["Line up declarations around point"	verilog-pretty-declarations t]
+    ["Line up equations around point"		verilog-pretty-expr t]
+    ["Redo/insert comments on every end"	verilog-label-be t]
+    ["Expand [x:y] vector line"		verilog-expand-vector t]
+    ["Insert begin-end block"		verilog-insert-block t]
+    ["Complete word"			verilog-complete-word t]
+    "----"
+    ["Recompute AUTOs"			verilog-auto t]
+    ["Kill AUTOs"			verilog-delete-auto t]
+    ["Inject AUTOs"			verilog-inject-auto t]
+    ("AUTO Help..."
+     ["AUTO General"			(describe-function 'verilog-auto) t]
+     ["AUTO Library Flags"		(describe-variable 'verilog-library-flags) t]
+     ["AUTO Library Path"		(describe-variable 'verilog-library-directories) t]
+     ["AUTO Library Files"		(describe-variable 'verilog-library-files) t]
+     ["AUTO Library Extensions"		(describe-variable 'verilog-library-extensions) t]
+     ["AUTO `define Reading"		(describe-function 'verilog-read-defines) t]
+     ["AUTO `include Reading"		(describe-function 'verilog-read-includes) t]
+     ["AUTOARG"				(describe-function 'verilog-auto-arg) t]
+     ["AUTOASCIIENUM"			(describe-function 'verilog-auto-ascii-enum) t]
+     ["AUTOINOUTMODULE"			(describe-function 'verilog-auto-inout-module) t]
+     ["AUTOINOUT"			(describe-function 'verilog-auto-inout) t]
+     ["AUTOINPUT"			(describe-function 'verilog-auto-input) t]
+     ["AUTOINST"			(describe-function 'verilog-auto-inst) t]
+     ["AUTOINST (.*)"			(describe-function 'verilog-auto-star) t]
+     ["AUTOINSTPARAM"			(describe-function 'verilog-auto-inst-param) t]
+     ["AUTOOUTPUT"			(describe-function 'verilog-auto-output) t]
+     ["AUTOOUTPUTEVERY"			(describe-function 'verilog-auto-output-every) t]
+     ["AUTOREG"				(describe-function 'verilog-auto-reg) t]
+     ["AUTOREGINPUT"			(describe-function 'verilog-auto-reg-input) t]
+     ["AUTORESET"			(describe-function 'verilog-auto-reset) t]
+     ["AUTOSENSE"			(describe-function 'verilog-auto-sense) t]
+     ["AUTOTIEOFF"			(describe-function 'verilog-auto-tieoff) t]
+     ["AUTOUNUSED"			(describe-function 'verilog-auto-unused) t]
+     ["AUTOWIRE"			(describe-function 'verilog-auto-wire) t]
+     )
+    "----"
+    ["Submit bug report"		verilog-submit-bug-report t]
+    ["Version and FAQ"			verilog-faq t]
+    ["Customize Verilog Mode..."	verilog-customize t]
+    ["Customize Verilog Fonts & Colors"	verilog-font-customize t]
+    )
+  "Emacs menu for VERILOG mode."
+  )
+(defvar verilog-statement-menu
+  '("Statements"
+    ["Header"		verilog-sk-header  t]
+    ["Comment"		verilog-sk-comment t]
+    "----"
+    ["Module"		verilog-sk-module t]
+    ["Primitive"	verilog-sk-primitive t]
+    "----"
+    ["Input"		verilog-sk-input t]
+    ["Output"		verilog-sk-output t]
+    ["Inout"		verilog-sk-inout t]
+    ["Wire"		verilog-sk-wire t]
+    ["Reg"		verilog-sk-reg t]
+    ["Define thing under point as a register" verilog-sk-define-signal t]
+    "----"
+    ["Initial"		verilog-sk-initial t]
+    ["Always"		verilog-sk-always t]
+    ["Function"		verilog-sk-function t]
+    ["Task"		verilog-sk-task t]
+    ["Specify"		verilog-sk-specify t]
+    ["Generate"		verilog-sk-generate t]
+    "----"
+    ["Begin"		verilog-sk-begin t]
+    ["If"		verilog-sk-if t]
+    ["(if) else"	verilog-sk-else-if t]
+    ["For"		verilog-sk-for t]
+    ["While"		verilog-sk-while t]
+    ["Fork"		verilog-sk-fork t]
+    ["Repeat"		verilog-sk-repeat t]
+    ["Case"		verilog-sk-case t]
+    ["Casex"		verilog-sk-casex t]
+    ["Casez"		verilog-sk-casez t]
+    )
+  "Menu for statement templates in Verilog."
+  )
+
+(easy-menu-define verilog-menu verilog-mode-map "Menu for Verilog mode"
+		  verilog-xemacs-menu)
+(easy-menu-define verilog-stmt-menu verilog-mode-map "Menu for statement templates in Verilog."
+		  verilog-statement-menu)
+
+(defvar verilog-mode-abbrev-table nil
+  "Abbrev table in use in Verilog-mode buffers.")
+
+(define-abbrev-table 'verilog-mode-abbrev-table ())
+
+;; compilation program
+(defun verilog-set-compile-command ()
+  "Function to compute shell command to compile verilog.
+
+This reads `verilog-tool' and sets `compile-command'.  This specifies the
+program that executes when you type \\[compile] or
+\\[verilog-auto-save-compile].
+
+By default `verilog-tool' uses a Makefile if one exists in the current
+directory.  If not, it is set to the `verilog-linter', `verilog-coverage',
+`verilog-simulator', or `verilog-compiler' variables, as selected with the
+Verilog -> \"Choose Compilation Action\" menu.
+
+You should set `verilog-tool' or the other variables to the path and
+arguments for your Verilog simulator.  For example:
+    \"vcs -p123 -O\"
+or a string like:
+    \"(cd /tmp; surecov %s)\".
+
+In the former case, the path to the current buffer is concat'ed to the
+value of `verilog-tool'; in the later, the path to the current buffer is
+substituted for the %s.
+
+Where __FILE__ appears in the string, the buffer-file-name of the current
+buffer, without the directory portion, will be substituted."
+  (interactive)
+  (cond
+   ((or (file-exists-p "makefile")	;If there is a makefile, use it
+	(file-exists-p "Makefile"))
+    (make-local-variable 'compile-command)
+    (setq compile-command "make "))
+   (t
+    (make-local-variable 'compile-command)
+    (setq compile-command
+	  (if verilog-tool
+	      (if (string-match "%s" (eval verilog-tool))
+		  (format (eval verilog-tool) (or buffer-file-name ""))
+		(concat (eval verilog-tool) " " (or buffer-file-name "")))
+	    ""))))
+  (verilog-modify-compile-command))
+
+(defun verilog-modify-compile-command ()
+  "Replace meta-information in `compile-command'.
+Where __FILE__ appears in the string, the current buffer's file-name,
+without the directory portion, will be substituted."
+  (when (and
+	 (stringp compile-command)
+	 (string-match "\\b__FILE__\\b" compile-command))
+    (make-local-variable 'compile-command)
+    (setq compile-command
+	  (verilog-string-replace-matches
+	   "\\b__FILE__\\b" (file-name-nondirectory (buffer-file-name))
+	   t t compile-command))))
+
+(defun verilog-error-regexp-add ()
+  "Add the messages to the `compilation-error-regexp-alist'.
+Called by `compilation-mode-hook'.  This allows \\[next-error] to find the errors."
+  (if (not verilog-error-regexp-add-didit)
+      (progn
+	(setq verilog-error-regexp-add-didit t)
+	(setq-default compilation-error-regexp-alist
+		      (append verilog-error-regexp
+			      (default-value 'compilation-error-regexp-alist)))
+	;; Could be buffer local at this point; maybe also in let; change all three
+	(setq compilation-error-regexp-alist (default-value 'compilation-error-regexp-alist))
+	(set (make-local-variable 'compilation-error-regexp-alist)
+	     (default-value 'compilation-error-regexp-alist))
+	)))
+
+(add-hook 'compilation-mode-hook 'verilog-error-regexp-add)
+
+(defconst verilog-directive-re
+  ;; "`case" "`default" "`define" "`define" "`else" "`endfor" "`endif"
+  ;; "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
+  ;; "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
+  ;; "`time_scale" "`undef" "`while"
+  "\\<`\\(case\\|def\\(ault\\|ine\\(\\)?\\)\\|e\\(lse\\|nd\\(for\\|if\\|protect\\|switch\\|while\\)\\)\\|for\\(mat\\)?\\|i\\(f\\(def\\|ndef\\)?\\|nclude\\)\\|let\\|protect\\|switch\\|time\\(_scale\\|scale\\)\\|undef\\|while\\)\\>")
+
+(defconst verilog-directive-begin
+  "\\<`\\(for\\|i\\(f\\|fdef\\|fndef\\)\\|switch\\|while\\)\\>")
+
+(defconst verilog-directive-middle
+  "\\<`\\(else\\|default\\|case\\)\\>")
+
+(defconst verilog-directive-end
+  "`\\(endfor\\|endif\\|endswitch\\|endwhile\\)\\>")
+
+(defconst verilog-directive-re-1
+  (concat "[ \t]*"  verilog-directive-re))
+
+;;
+;; Regular expressions used to calculate indent, etc.
+;;
+(defconst verilog-symbol-re      "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>")
+(defconst verilog-case-re        "\\(\\<case[xz]?\\>\\|\\<randcase\\>\\)")
+;; Want to match
+;; aa :
+;; aa,bb :
+;; a[34:32] :
+;; a,
+;;   b :
+
+(defconst verilog-no-indent-begin-re
+  "\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\|always_comb\\|always_ff\\|always_latch\\)\\>")
+
+(defconst verilog-ends-re
+  ;; Parenthesis indicate type of keyword found
+  (concat
+   "\\(\\<else\\>\\)\\|"		; 1
+   "\\(\\<if\\>\\)\\|"			; 2
+   "\\(\\<end\\>\\)\\|"			; 3
+   "\\(\\<endcase\\>\\)\\|"		; 4
+   "\\(\\<endfunction\\>\\)\\|"		; 5
+   "\\(\\<endtask\\>\\)\\|"		; 6
+   "\\(\\<endspecify\\>\\)\\|"		; 7
+   "\\(\\<endtable\\>\\)\\|"		; 8
+   "\\(\\<endgenerate\\>\\)\\|"         ; 9
+   "\\(\\<join\\(_any\\|_none\\)?\\>\\)\\|" ; 10
+   "\\(\\<endclass\\>\\)\\|"            ; 11
+   "\\(\\<endgroup\\>\\)"               ; 12
+   ))
+
+(defconst verilog-auto-end-comment-lines-re
+  ;; Matches to names in this list cause auto-end-commentation
+  (concat "\\("
+	  verilog-directive-re "\\)\\|\\("
+	  (eval-when-compile
+	    (verilog-regexp-words
+	     `( "begin"
+		"else"
+		"end"
+		"endcase"
+		"endclass"
+		"endclocking"
+		"endgroup"
+		"endfunction"
+		"endmodule"
+		"endprogram"
+		"endprimitive"
+		"endinterface"
+		"endpackage"
+		"endsequence"
+		"endspecify"
+		"endtable"
+		"endtask"
+		"join"
+		"join_any"
+		"join_none"
+		"module"
+		"macromodule"
+		"primitive"
+		"interface"
+		"package")))
+	  "\\)"))
+
+;;; NOTE: verilog-leap-to-head expects that verilog-end-block-re and
+;;; verilog-end-block-ordered-re matches exactly the same strings.
+(defconst verilog-end-block-ordered-re
+  ;; Parenthesis indicate type of keyword found
+  (concat "\\(\\<endcase\\>\\)\\|" ; 1
+	  "\\(\\<end\\>\\)\\|"     ; 2
+	  "\\(\\<end"              ; 3, but not used
+	  "\\("                    ; 4, but not used
+	  "\\(function\\)\\|"      ; 5
+	  "\\(task\\)\\|"          ; 6
+	  "\\(module\\)\\|"        ; 7
+	  "\\(primitive\\)\\|"     ; 8
+	  "\\(interface\\)\\|"     ; 9
+	  "\\(package\\)\\|"       ; 10
+	  "\\(class\\)\\|"         ; 11
+          "\\(group\\)\\|"         ; 12
+          "\\(program\\)\\|"	   ; 13
+          "\\(sequence\\)\\|"	   ; 14
+	  "\\(clocking\\)\\|"      ; 15
+	  "\\)\\>\\)"))
+(defconst verilog-end-block-re
+  (eval-when-compile
+    (verilog-regexp-words
+
+     `("end"  ;; closes begin
+       "endcase" ;; closes any of case, casex casez or randcase
+       "join" "join_any" "join_none" ;; closes fork
+       "endclass"
+       "endtable"
+       "endspecify"
+       "endfunction"
+       "endgenerate"
+       "endtask"
+       "endgroup"
+       "endproperty"
+       "endinterface"
+       "endpackage"
+       "endprogram"
+       "endsequence"
+       "endclocking"
+       )
+     )))
+
+
+(defconst verilog-endcomment-reason-re
+  ;; Parenthesis indicate type of keyword found
+  (concat
+   "\\(\\<fork\\>\\)\\|"
+   "\\(\\<begin\\>\\)\\|"
+   "\\(\\<if\\>\\)\\|"
+   "\\(\\<clocking\\>\\)\\|"
+   "\\(\\<else\\>\\)\\|"
+   "\\(\\<end\\>.*\\<else\\>\\)\\|"
+   "\\(\\<task\\>\\)\\|"
+   "\\(\\<function\\>\\)\\|"
+   "\\(\\<initial\\>\\)\\|"
+   "\\(\\<interface\\>\\)\\|"
+   "\\(\\<package\\>\\)\\|"
+   "\\(\\<final\\>\\)\\|"
+   "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
+   "\\(\\<always_comb\\>\\(\[ \t\]*@\\)?\\)\\|"
+   "\\(\\<always_ff\\>\\(\[ \t\]*@\\)?\\)\\|"
+   "\\(\\<always_latch\\>\\(\[ \t\]*@\\)?\\)\\|"
+   "\\(@\\)\\|"
+   "\\(\\<while\\>\\)\\|"
+   "\\(\\<for\\(ever\\|each\\)?\\>\\)\\|"
+   "\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|"
+   "#"))
+
+(defconst verilog-named-block-re  "begin[ \t]*:")
+
+;; These words begin a block which can occur inside a module which should be indented,
+;; and closed with the respective word from the end-block list
+
+(defconst verilog-beg-block-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `("begin"
+       "case" "casex" "casez" "randcase"
+       "clocking"
+       "generate"
+       "fork"
+       "function"
+       "property"
+       "specify"
+       "table"
+       "task"
+       ))))
+;; These are the same words, in a specific order in the regular
+;; expression so that matching will work nicely for
+;; verilog-forward-sexp and verilog-calc-indent
+
+(defconst verilog-beg-block-re-ordered
+  ( concat "\\<"
+	   "\\(begin\\)"		;1
+	   "\\|\\(randcase\\|\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?\\)" ; 2
+;;	   "\\|\\(randcase\\|case[xz]?\\)" ; 2
+	   "\\|\\(fork\\)"		;3
+	   "\\|\\(class\\)"		;4
+	   "\\|\\(table\\)"		;5
+	   "\\|\\(specify\\)"		;6
+	   "\\|\\(function\\)"		;7
+	   "\\|\\(task\\)"		;8
+	   "\\|\\(generate\\)"		;9
+	   "\\|\\(covergroup\\)"	;10
+	   "\\|\\(property\\)"		;11
+	   "\\|\\(\\(rand\\)?sequence\\)"  ;12
+	   "\\|\\(clocking\\)"          ;13
+	   "\\>"))
+
+(defconst verilog-end-block-ordered-rry
+  [ "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)"
+    "\\(\\<randcase\\>\\|\\<case[xz]?\\>\\)\\|\\(\\<endcase\\>\\)"
+    "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)"
+    "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)"
+    "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)"
+    "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)"
+    "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)"
+    "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)"
+    "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)"
+    "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)"
+    "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)"
+    "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)"
+    "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)"
+    ] )
+
+(defconst verilog-nameable-item-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `("begin"
+       "fork"
+       "join" "join_any" "join_none"
+       "end"
+       "endcase"
+       "endconfig"
+       "endclass"
+       "endclocking"
+       "endfunction"
+       "endgenerate"
+       "endmodule"
+       "endprimative"
+       "endinterface"
+       "endpackage"
+       "endspecify"
+       "endtable"
+       "endtask" )
+     )))
+
+(defconst verilog-declaration-opener
+  (eval-when-compile
+    (verilog-regexp-words
+     `("module" "begin" "task" "function"))))
+
+(defconst verilog-declaration-prefix-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       ;; port direction
+       "inout" "input" "output" "ref" 
+       ;; changeableness
+       "const" "static" "protected" "local"
+       ;; parameters
+       "localparam" "parameter" "var" 
+       ;; type creation
+       "typedef"
+       ))))
+(defconst verilog-declaration-core-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       ;; integer_atom_type
+       "byte" "shortint" "int" "longint" "integer" "time"
+       ;; integer_vector_type
+       "bit" "logic" "reg"
+       ;; non_integer_type
+       "shortreal" "real" "realtime"
+       ;; net_type
+       "supply0" "supply1" "tri" "triand" "trior" "trireg" "tri0" "tri1" "uwire" "wire" "wand" "wor"
+       ;; misc
+       "string" "event" "chandle" "virtual" "enum" "genvar"
+       "struct" "union"
+       ;; builtin classes
+       "mailbox" "semaphore" 
+       ))))
+(defconst verilog-declaration-re 
+  (concat "\\(" verilog-declaration-prefix-re "\\s-*\\)?" verilog-declaration-core-re))
+(defconst verilog-range-re "\\(\\[[^]]*\\]\\s-*\\)+")
+(defconst verilog-optional-signed-re "\\s-*\\(signed\\)?")
+(defconst verilog-optional-signed-range-re
+  (concat
+   "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?"))
+(defconst verilog-macroexp-re "`\\sw+")
+
+(defconst verilog-delay-re "#\\s-*\\(\\([0-9_]+\\('s?[hdxbo][0-9a-fA-F_xz]+\\)?\\)\\|\\(([^()]*)\\)\\|\\(\\sw+\\)\\)")
+(defconst verilog-declaration-re-2-no-macro
+  (concat "\\s-*" verilog-declaration-re
+	  "\\s-*\\(\\(" verilog-optional-signed-range-re "\\)\\|\\(" verilog-delay-re "\\)"
+	  "\\)?"))
+(defconst verilog-declaration-re-2-macro
+  (concat "\\s-*" verilog-declaration-re
+	  "\\s-*\\(\\(" verilog-optional-signed-range-re "\\)\\|\\(" verilog-delay-re "\\)"
+	  "\\|\\(" verilog-macroexp-re "\\)"
+	  "\\)?"))
+(defconst verilog-declaration-re-1-macro
+  (concat "^" verilog-declaration-re-2-macro))
+
+(defconst verilog-declaration-re-1-no-macro (concat "^" verilog-declaration-re-2-no-macro))
+
+(defconst verilog-defun-re
+  (eval-when-compile (verilog-regexp-words `("macromodule" "module" "class" "program" "interface" "package" "primitive" "config"))))
+(defconst verilog-end-defun-re
+  (eval-when-compile (verilog-regexp-words `("endmodule" "endclass" "endprogram" "endinterface" "endpackage" "endprimitive" "endconfig"))))
+(defconst verilog-zero-indent-re
+  (concat verilog-defun-re "\\|" verilog-end-defun-re))
+
+(defconst verilog-behavioral-block-beg-re
+  (concat "\\(\\<initial\\>\\|\\<final\\>\\|\\<always\\>\\|\\<always_comb\\>\\|\\<always_ff\\>\\|"
+	  "\\<always_latch\\>\\|\\<function\\>\\|\\<task\\>\\)"))
+
+(defconst verilog-indent-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       "{"
+       "always" "always_latch" "always_ff" "always_comb"
+       "begin" "end"
+;       "unique" "priority"
+       "case" "casex" "casez" "randcase" "endcase"
+       "class" "endclass"
+       "clocking" "endclocking"
+       "config" "endconfig"
+       "covergroup" "endgroup"
+       "fork" "join" "join_any" "join_none"
+       "function" "endfunction"
+       "final"
+       "generate" "endgenerate"
+       "initial"
+       "interface" "endinterface"
+       "module" "macromodule" "endmodule"
+       "package" "endpackage"
+       "primitive" "endprimative"
+       "program" "endprogram"
+       "property" "endproperty"
+       "sequence" "randsequence" "endsequence"
+       "specify" "endspecify"
+       "table" "endtable"
+       "task" "endtask"
+       "`case"
+       "`default"
+       "`define" "`undef"
+       "`if" "`ifdef" "`ifndef" "`else" "`endif"
+       "`while" "`endwhile"
+       "`for" "`endfor"
+       "`format"
+       "`include"
+       "`let"
+       "`protect" "`endprotect"
+       "`switch" "`endswitch"
+       "`timescale"
+       "`time_scale"
+       ))))
+
+(defconst verilog-defun-level-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       "module" "macromodule" "primitive" "class" "program" "initial" "final" "always" "always_comb"
+       "always_ff" "always_latch" "endtask" "endfunction" "interface" "package"
+       "config"))))
+
+(defconst verilog-defun-level-not-generate-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       "module" "macromodule" "primitive" "class" "program" "interface" "package" "config"))))
+
+(defconst verilog-cpp-level-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       "endmodule" "endprimitive" "endinterface" "endpackage" "endprogram" "endclass"
+       ))))
+(defconst verilog-extended-case-re "\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?")
+(defconst verilog-extended-complete-re
+  (concat "\\(\\<extern\\s-+\\|\\<virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)"
+	  "\\|\\(\\<typedef\\>\\s-+\\)*\\(\\<struct\\>\\|\\<union\\>\\|\\<class\\>\\)"
+	  "\\|" verilog-extended-case-re ))
+(defconst verilog-basic-complete-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       "always" "assign" "always_latch" "always_ff" "always_comb" "constraint"
+       "import" "initial" "final" "module" "macromodule" "repeat" "randcase" "while"
+       "if" "for" "forever" "foreach" "else" "parameter" "do"
+       ))))
+(defconst verilog-complete-reg
+  (concat
+   verilog-extended-complete-re
+   "\\|"
+   verilog-basic-complete-re))
+
+(defconst verilog-end-statement-re
+  (concat "\\(" verilog-beg-block-re "\\)\\|\\("
+	  verilog-end-block-re "\\)"))
+
+(defconst verilog-endcase-re
+  (concat verilog-case-re "\\|"
+	  "\\(endcase\\)\\|"
+	  verilog-defun-re
+	  ))
+
+(defconst verilog-exclude-str-start "/* -----\\/----- EXCLUDED -----\\/-----"
+  "String used to mark beginning of excluded text.")
+(defconst verilog-exclude-str-end " -----/\\----- EXCLUDED -----/\\----- */"
+  "String used to mark end of excluded text.")
+(defconst verilog-preprocessor-re
+  (eval-when-compile
+    (verilog-regexp-words
+     `(
+       "`define" "`include" "`ifdef" "`ifndef" "`if" "`endif" "`else"
+       ))))
+
+(defconst verilog-keywords
+  '( "`case" "`default" "`define" "`else" "`endfor" "`endif"
+     "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
+     "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
+     "`time_scale" "`undef" "`while"
+
+     "after" "alias" "always" "always_comb" "always_ff" "always_latch" "and"
+     "assert" "assign" "assume" "automatic" "before" "begin" "bind"
+     "bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte"
+     "case" "casex" "casez" "cell" "chandle" "class" "clocking" "cmos"
+     "config" "const" "constraint" "context" "continue" "cover"
+     "covergroup" "coverpoint" "cross" "deassign" "default" "defparam"
+     "design" "disable" "dist" "do" "edge" "else" "end" "endcase"
+     "endclass" "endclocking" "endconfig" "endfunction" "endgenerate"
+     "endgroup" "endinterface" "endmodule" "endpackage" "endprimitive"
+     "endprogram" "endproperty" "endspecify" "endsequence" "endtable"
+     "endtask" "enum" "event" "expect" "export" "extends" "extern"
+     "final" "first_match" "for" "force" "foreach" "forever" "fork"
+     "forkjoin" "function" "generate" "genvar" "highz0" "highz1" "if"
+     "iff" "ifnone" "ignore_bins" "illegal_bins" "import" "incdir"
+     "include" "initial" "inout" "input" "inside" "instance" "int"
+     "integer" "interface" "intersect" "join" "join_any" "join_none"
+     "large" "liblist" "library" "local" "localparam" "logic"
+     "longint" "macromodule" "mailbox" "matches" "medium" "modport" "module"
+     "nand" "negedge" "new" "nmos" "nor" "noshowcancelled" "not"
+     "notif0" "notif1" "null" "or" "output" "package" "packed"
+     "parameter" "pmos" "posedge" "primitive" "priority" "program"
+     "property" "protected" "pull0" "pull1" "pulldown" "pullup"
+     "pulsestyle_onevent" "pulsestyle_ondetect" "pure" "rand" "randc"
+     "randcase" "randsequence" "rcmos" "real" "realtime" "ref" "reg"
+     "release" "repeat" "return" "rnmos" "rpmos" "rtran" "rtranif0"
+     "rtranif1" "scalared" "semaphore" "sequence" "shortint" "shortreal"
+     "showcancelled" "signed" "small" "solve" "specify" "specparam"
+     "static" "string" "strong0" "strong1" "struct" "super" "supply0"
+     "supply1" "table" "tagged" "task" "this" "throughout" "time"
+     "timeprecision" "timeunit" "tran" "tranif0" "tranif1" "tri"
+     "tri0" "tri1" "triand" "trior" "trireg" "type" "typedef" "union"
+     "unique" "unsigned" "use" "uwire" "var" "vectored" "virtual" "void"
+     "wait" "wait_order" "wand" "weak0" "weak1" "while" "wildcard"
+     "wire" "with" "within" "wor" "xnor" "xor"
+ )
+ "List of Verilog keywords.")
+
+
+(defconst verilog-emacs-features
+  ;; Documentation at the bottom
+  (let ((major (and (boundp 'emacs-major-version)
+		    emacs-major-version))
+	(minor (and (boundp 'emacs-minor-version)
+		    emacs-minor-version))
+	flavor comments flock-syntax)
+    ;; figure out version numbers if not already discovered
+    (and (or (not major) (not minor))
+	 (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
+	 (setq major (string-to-int (substring emacs-version
+					       (match-beginning 1)
+					       (match-end 1)))
+	       minor (string-to-int (substring emacs-version
+					       (match-beginning 2)
+					       (match-end 2)))))
+    (if (not (and major minor))
+	(error "Cannot figure out the major and minor version numbers"))
+    ;; calculate the major version
+    (cond
+     ((= major 4)  (setq major 'v18))	;Epoch 4
+     ((= major 18) (setq major 'v18))	;Emacs 18
+     ((= major 19) (setq major 'v19	;Emacs 19
+			 flavor (if (or (string-match "Lucid" emacs-version)
+					(string-match "XEmacs" emacs-version))
+				    'XEmacs 'FSF)))
+     ((> major 19) (setq major 'v20
+			 flavor (if (or (string-match "Lucid" emacs-version)
+					(string-match "XEmacs" emacs-version))
+				    'XEmacs 'FSF)))
+     ;; I don't know
+     (t (error "Cannot recognize major version number: %s" major)))
+    ;; XEmacs 19 uses 8-bit modify-syntax-entry flags, as do all
+    ;; patched Emacs 19, Emacs 18, Epoch 4's.  Only Emacs 19 uses a
+    ;; 1-bit flag.  Let's be as smart as we can about figuring this
+    ;; out.
+    (if (or (eq major 'v20) (eq major 'v19))
+	(let ((table (copy-syntax-table)))
+	  (modify-syntax-entry ?a ". 12345678" table)
+	  (cond
+	   ;; XEmacs pre 20 and Emacs pre 19.30 use vectors for syntax tables.
+	   ((vectorp table)
+	    (if (= (logand (lsh (aref table ?a) -16) 255) 255)
+		(setq comments '8-bit)
+	      (setq comments '1-bit)))
+	   ;; XEmacs 20 is known to be 8-bit
+	   ((eq flavor 'XEmacs) (setq comments '8-bit))
+	   ;; Emacs 19.30 and beyond are known to be 1-bit
+	   ((eq flavor 'FSF) (setq comments '1-bit))
+	   ;; Don't know what this is
+	   (t (error "Couldn't figure out syntax table format"))
+	   ))
+      ;; Emacs 18 has no support for dual comments
+      (setq comments 'no-dual-comments))
+    ;; determine whether to use old or new font lock syntax
+    ;; We can assume 8-bit syntax table emacsen support new syntax, otherwise
+    ;; look for version > 19.30
+    (setq flock-syntax
+        (if (or (equal comments '8-bit)
+                (equal major 'v20)
+                (and (equal major 'v19) (> minor 30)))
+            'flock-syntax-after-1930
+          'flock-syntax-before-1930))
+    ;; lets do some minimal sanity checking.
+    (if (or
+	 ;; Emacs before 19.6 had bugs
+	 (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
+	 ;; Emacs 19 before 19.21 has known bugs
+	 (and (eq major 'v19) (eq flavor 'FSF) (< minor 21))
+	 )
+	(with-output-to-temp-buffer "*verilog-mode warnings*"
+	  (print (format
+  "The version of Emacs that you are running, %s,
+has known bugs in its syntax parsing routines which will affect the
+performance of verilog-mode. You should strongly consider upgrading to the
+latest available version.  verilog-mode may continue to work, after a
+fashion, but strange indentation errors could be encountered."
+		     emacs-version))))
+    ;; Emacs 18, with no patch is not too good
+    (if (and (eq major 'v18) (eq comments 'no-dual-comments))
+	(with-output-to-temp-buffer "*verilog-mode warnings*"
+	  (print (format
+  "The version of Emacs 18 you are running, %s,
+has known deficiencies in its ability to handle the dual verilog
+(and C++) comments, (e.g. the // and /* */ comments). This will
+not be much of a problem for you if you only use the /* */ comments,
+but you really should strongly consider upgrading to one of the latest
+Emacs 19's.  In Emacs 18, you may also experience performance degradations.
+Emacs 19 has some new built-in routines which will speed things up for you.
+Because of these inherent problems, verilog-mode is not supported
+on emacs-18."
+			    emacs-version))))
+    ;; Emacs 18 with the syntax patches are no longer supported
+    (if (and (eq major 'v18) (not (eq comments 'no-dual-comments)))
+	(with-output-to-temp-buffer "*verilog-mode warnings*"
+	  (print (format
+  "You are running a syntax patched Emacs 18 variant.  While this should
+work for you, you may want to consider upgrading to Emacs 19.
+The syntax patches are no longer supported either for verilog-mode."))))
+    (list major comments flock-syntax))
+  "A list of features extant in the Emacs you are using.
+There are many flavors of Emacs out there, each with different
+features supporting those needed by `verilog-mode'.  Here's the current
+supported list, along with the values for this variable:
+
+ Vanilla Emacs 18/Epoch 4:   (v18 no-dual-comments flock-syntax-before-1930)
+ Emacs 18/Epoch 4 (patch2):  (v18 8-bit flock-syntax-after-1930)
+ XEmacs (formerly Lucid) 19: (v19 8-bit flock-syntax-after-1930)
+ XEmacs 20:                  (v20 8-bit flock-syntax-after-1930)
+ Emacs 19.1-19.30:           (v19 8-bit flock-syntax-before-1930)
+ Emacs 19.31-19.xx:          (v19 8-bit flock-syntax-after-1930)
+ Emacs20        :            (v20 1-bit flock-syntax-after-1930).")
+
+(defconst verilog-comment-start-regexp "//\\|/\\*"
+  "Dual comment value for `comment-start-regexp'.")
+
+(defun verilog-populate-syntax-table (table)
+  "Populate the syntax TABLE."
+  (modify-syntax-entry ?\\ "\\" table)
+  (modify-syntax-entry ?+ "." table)
+  (modify-syntax-entry ?- "." table)
+  (modify-syntax-entry ?= "." table)
+  (modify-syntax-entry ?% "." table)
+  (modify-syntax-entry ?< "." table)
+  (modify-syntax-entry ?> "." table)
+  (modify-syntax-entry ?& "." table)
+  (modify-syntax-entry ?| "." table)
+  (modify-syntax-entry ?` "w" table)
+  (modify-syntax-entry ?_ "w" table)
+  (modify-syntax-entry ?\' "." table)
+)
+
+(defun verilog-setup-dual-comments (table)
+  "Set up TABLE to handle block and line style comments."
+  (cond
+   ((memq '8-bit verilog-emacs-features)
+    ;; XEmacs (formerly Lucid) has the best implementation
+    (modify-syntax-entry ?/  ". 1456" table)
+    (modify-syntax-entry ?*  ". 23"   table)
+    (modify-syntax-entry ?\n "> b"    table)
+    )
+   ((memq '1-bit verilog-emacs-features)
+    ;; Emacs 19 does things differently, but we can work with it
+    (modify-syntax-entry ?/  ". 124b" table)
+    (modify-syntax-entry ?*  ". 23"   table)
+    (modify-syntax-entry ?\n "> b"    table)
+    )
+   ))
+
+(defvar verilog-mode-syntax-table nil
+  "Syntax table used in `verilog-mode' buffers.")
+
+(defconst verilog-font-lock-keywords nil
+  "Default highlighting for Verilog mode.")
+
+(defconst verilog-font-lock-keywords-1 nil
+  "Subdued level highlighting for Verilog mode.")
+
+(defconst verilog-font-lock-keywords-2 nil
+  "Medium level highlighting for Verilog mode.
+See also `verilog-font-lock-extra-types'.")
+
+(defconst verilog-font-lock-keywords-3 nil
+  "Gaudy level highlighting for Verilog mode.
+See also `verilog-font-lock-extra-types'.")
+(defvar  verilog-font-lock-translate-off-face
+  'verilog-font-lock-translate-off-face
+  "Font to use for translated off regions.")
+(defface verilog-font-lock-translate-off-face
+  '((((class color)
+      (background light))
+     (:background "gray90" :italic t ))
+    (((class color)
+      (background dark))
+     (:background "gray10" :italic t ))
+    (((class grayscale) (background light))
+     (:foreground "DimGray" :italic t))
+    (((class grayscale) (background dark))
+     (:foreground "LightGray" :italic t))
+    (t (:italis t)))
+  "Font lock mode face used to background highlight translate-off regions."
+  :group 'font-lock-highlighting-faces)
+
+(defvar verilog-font-lock-p1800-face
+  'verilog-font-lock-p1800-face
+  "Font to use for p1800 keywords.")
+(defface verilog-font-lock-p1800-face
+  '((((class color)
+      (background light))
+     (:foreground "DarkOrange3" :bold t ))
+    (((class color)
+      (background dark))
+     (:foreground "orange1" :bold t ))
+    (t (:italic t)))
+  "Font lock mode face used to highlight P1800 keywords."
+  :group 'font-lock-highlighting-faces)
+
+(defvar verilog-font-lock-ams-face
+  'verilog-font-lock-ams-face
+  "Font to use for Analog/Mixed Signal keywords.")
+(defface verilog-font-lock-ams-face
+  '((((class color)
+      (background light))
+     (:foreground "Purple" :bold t ))
+    (((class color)
+      (background dark))
+     (:foreground "orange1" :bold t ))
+    (t (:italic t)))
+  "Font lock mode face used to highlight AMS keywords."
+  :group 'font-lock-highlighting-faces)
+
+(let* ((verilog-type-font-keywords
+	(eval-when-compile
+	  (verilog-regexp-opt
+	   '(
+	     "and" "bit" "buf" "bufif0" "bufif1" "cmos" "defparam"
+	     "event" "genvar" "inout" "input" "integer" "localparam"
+	     "logic" "mailbox" "nand" "nmos" "not" "notif0" "notif1" "or"
+	     "output" "parameter" "pmos" "pull0" "pull1" "pullup"
+	     "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran"
+	     "rtranif0" "rtranif1" "semaphore" "signed" "struct" "supply"
+	     "supply0" "supply1" "time" "tran" "tranif0" "tranif1"
+	     "tri" "tri0" "tri1" "triand" "trior" "trireg" "typedef"
+	     "uwire" "vectored" "wand" "wire" "wor" "xnor" "xor"
+	     ) nil  )))
+
+       (verilog-pragma-keywords
+	(eval-when-compile
+	  (verilog-regexp-opt
+	   '("surefire" "synopsys" "rtl_synthesis" "verilint" ) nil
+	    )))
+
+       (verilog-p1800-keywords
+	(eval-when-compile
+	  (verilog-regexp-opt
+	   '("alias" "assert" "assume" "automatic" "before" "bind"
+	     "bins" "binsof" "break" "byte" "cell" "chandle" "class"
+	     "clocking" "config" "const" "constraint" "context" "continue"
+	     "cover" "covergroup" "coverpoint" "cross" "deassign" "design"
+	     "dist" "do" "edge" "endclass" "endclocking" "endconfig"
+	     "endgroup" "endprogram" "endproperty" "endsequence" "enum"
+	     "expect" "export" "extends" "extern" "first_match" "foreach"
+	     "forkjoin" "genvar" "highz0" "highz1" "ifnone" "ignore_bins"
+	     "illegal_bins" "import" "incdir" "include" "inside" "instance"
+	     "int" "intersect" "large" "liblist" "library" "local" "longint"
+	     "matches" "medium" "modport" "new" "noshowcancelled" "null"
+	     "packed" "program" "property" "protected" "pull0" "pull1"
+	     "pulsestyle_onevent" "pulsestyle_ondetect" "pure" "rand" "randc"
+	     "randcase" "randsequence" "ref" "release" "return" "scalared"
+	     "sequence" "shortint" "shortreal" "showcancelled" "small" "solve"
+	     "specparam" "static" "string" "strong0" "strong1" "struct"
+	     "super" "tagged" "this" "throughout" "timeprecision" "timeunit"
+	     "type" "union" "unsigned" "use" "var" "virtual" "void"
+	     "wait_order" "weak0" "weak1" "wildcard" "with" "within"
+	     ) nil )))
+
+       (verilog-ams-keywords
+	(eval-when-compile
+	  (verilog-regexp-opt
+	   '("above" "abs" "absdelay" "acos" "acosh" "ac_stim"
+	     "aliasparam" "analog" "analysis" "asin" "asinh" "atan" "atan2" "atanh"
+	     "branch" "ceil" "connectmodule" "connectrules" "cos" "cosh" "ddt"
+	     "ddx" "discipline" "driver_update" "enddiscipline" "endconnectrules"
+	     "endnature" "endparamset" "exclude" "exp" "final_step" "flicker_noise"
+	     "floor" "flow" "from" "ground" "hypot" "idt" "idtmod" "inf"
+	     "initial_step" "laplace_nd" "laplace_np" "laplace_zd" "laplace_zp"
+	     "last_crossing" "limexp" "ln" "log" "max" "min" "nature"
+	     "net_resolution" "noise_table" "paramset" "potential" "pow" "sin"
+	     "sinh" "slew" "sqrt" "tan" "tanh" "timer" "transition" "white_noise"
+	     "wreal" "zi_nd" "zi_np" "zi_zd" ) nil )))
+
+       (verilog-font-keywords
+	(eval-when-compile
+	  (verilog-regexp-opt
+	   '(
+	     "assign" "begin" "case" "casex" "casez" "randcase" "deassign"
+	     "default" "disable" "else" "end" "endcase" "endfunction"
+	     "endgenerate" "endinterface" "endmodule" "endprimitive"
+	     "endspecify" "endtable" "endtask" "final" "for" "force" "return" "break"
+	     "continue" "forever" "fork" "function" "generate" "if" "iff" "initial"
+	     "interface" "join" "join_any" "join_none" "macromodule" "module" "negedge"
+	     "package" "endpackage" "always" "always_comb" "always_ff"
+	     "always_latch" "posedge" "primitive" "priority" "release"
+	     "repeat" "specify" "table" "task" "unique" "wait" "while"
+	     "class" "program" "endclass" "endprogram"
+	     ) nil  ))))
+
+  (setq verilog-font-lock-keywords
+	(list
+	 ;; Fontify all builtin keywords
+	 (concat "\\<\\(" verilog-font-keywords "\\|"
+		       ;; And user/system tasks and functions
+		       "\\$[a-zA-Z][a-zA-Z0-9_\\$]*"
+		       "\\)\\>")
+	 ;; Fontify all types
+	 (cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>")
+	       'font-lock-type-face)
+	 ;; Fontify IEEE-P1800 keywords appropriately
+	 (if verilog-highlight-p1800-keywords
+	     (cons (concat "\\<\\(" verilog-p1800-keywords "\\)\\>")
+		   'verilog-font-lock-p1800-face)
+	   (cons (concat "\\<\\(" verilog-p1800-keywords "\\)\\>")
+		 'font-lock-type-face))
+	 ;; Fontify Verilog-AMS keywords
+	 (cons (concat "\\<\\(" verilog-ams-keywords "\\)\\>")
+	       'verilog-font-lock-ams-face)
+	 ))
+
+  (setq verilog-font-lock-keywords-1
+	(append verilog-font-lock-keywords
+		(list
+		 ;; Fontify module definitions
+		 (list
+		  "\\<\\(\\(macro\\)?module\\|primitive\\|class\\|program\\|interface\\|package\\|task\\)\\>\\s-*\\(\\sw+\\)"
+		  '(1 font-lock-keyword-face)
+		  '(3 font-lock-function-name-face 'prepend))
+		 ;; Fontify function definitions
+		 (list
+		  (concat "\\<function\\>\\s-+\\(integer\\|real\\(time\\)?\\|time\\)\\s-+\\(\\sw+\\)" )
+		       '(1 font-lock-keyword-face)
+		       '(3 font-lock-reference-face prepend)
+		       )
+		 '("\\<function\\>\\s-+\\(\\[[^]]+\\]\\)\\s-+\\(\\sw+\\)"
+		   (1 font-lock-keyword-face)
+		   (2 font-lock-reference-face append)
+		   )
+		 '("\\<function\\>\\s-+\\(\\sw+\\)"
+		   1 'font-lock-reference-face append)
+		 )))
+
+  (setq verilog-font-lock-keywords-2
+	(append verilog-font-lock-keywords-1
+		(list
+		 ;; Fontify pragmas
+		 (concat "\\(//\\s-*" verilog-pragma-keywords "\\s-.*\\)")
+		 ;; Fontify escaped names
+		 '("\\(\\\\\\S-*\\s-\\)"  0 font-lock-function-name-face)
+		 ;; Fontify macro definitions/ uses
+		 '("`\\s-*[A-Za-z][A-Za-z0-9_]*" 0 (if (boundp 'font-lock-preprocessor-face)
+						       'font-lock-preprocessor-face
+						     'font-lock-type-face))
+		 ;; Fontify delays/numbers
+		 '("\\(@\\)\\|\\(#\\s-*\\(\\(\[0-9_.\]+\\('s?[hdxbo][0-9a-fA-F_xz]*\\)?\\)\\|\\(([^()]+)\\|\\sw+\\)\\)\\)"
+		   0 font-lock-type-face append)
+		 ;; Fontify instantiation names
+		 '("\\([A-Za-z][A-Za-z0-9_]+\\)\\s-*(" 1 font-lock-function-name-face)
+
+		 )))
+
+  (setq verilog-font-lock-keywords-3
+	(append verilog-font-lock-keywords-2
+		(when verilog-highlight-translate-off
+		  (list
+		   ;; Fontify things in translate off regions
+		   '(verilog-match-translate-off (0 'verilog-font-lock-translate-off-face prepend))
+		   )))
+  )
+  )
+
+
+
+(defun verilog-inside-comment-p ()
+  "Check if point inside a nested comment."
+  (save-excursion
+    (let ((st-point (point)) hitbeg)
+      (or (search-backward "//" (verilog-get-beg-of-line) t)
+	  (if (progn
+		;; This is for tricky case //*, we keep searching if /* is proceeded by // on same line
+		(while (and (setq hitbeg (search-backward "/*" nil t))
+			    (progn (forward-char 1) (search-backward "//" (verilog-get-beg-of-line) t))))
+		hitbeg)
+	      (not (search-forward "*/" st-point t)))))))
+
+(defun verilog-declaration-end ()
+  (search-forward ";"))
+
+(defun verilog-point-text (&optional pointnum)
+  "Return text describing where POINTNUM or current point is (for errors).
+Use filename, if current buffer being edited shorten to just buffer name."
+  (concat (or (and (equal (window-buffer (selected-window)) (current-buffer))
+		   (buffer-name))
+	      buffer-file-name
+	      (buffer-name))
+	  ":" (int-to-string (count-lines (point-min) (or pointnum (point))))))
+
+(defun electric-verilog-backward-sexp ()
+  "Move backward over a sexp."
+  (interactive)
+  ;; before that see if we are in a comment
+  (verilog-backward-sexp)
+)
+(defun electric-verilog-forward-sexp ()
+  "Move backward over a sexp."
+  (interactive)
+  ;; before that see if we are in a comment
+  (verilog-forward-sexp)
+)
+;;;used by hs-minor-mode
+(defun verilog-forward-sexp-function (arg)
+  (if (< arg 0)
+      (verilog-backward-sexp)
+    (verilog-forward-sexp)))
+
+
+(defun verilog-backward-sexp ()
+  (let ((reg)
+	(elsec 1)
+	(found nil)
+	(st (point))
+	)
+    (if (not (looking-at "\\<"))
+	(forward-word -1))
+    (cond
+     ((verilog-skip-backward-comment-or-string)
+      )
+     ((looking-at "\\<else\\>")
+      (setq reg (concat
+		 verilog-end-block-re
+		 "\\|\\(\\<else\\>\\)"
+		 "\\|\\(\\<if\\>\\)"
+		 ))
+      (while (and (not found)
+		  (verilog-re-search-backward reg nil 'move))
+	(cond
+	 ((match-end 1) ; matched verilog-end-block-re
+	; try to leap back to matching outward block by striding across
+	; indent level changing tokens then immediately
+	; previous line governs indentation.
+	  (verilog-leap-to-head))
+	 ((match-end 2) ; else, we're in deep
+	  (setq elsec (1+ elsec)))
+	 ((match-end 3) ; found it
+	  (setq elsec (1- elsec))
+	  (if (= 0 elsec)
+	      ;; Now previous line describes syntax
+	      (setq found 't)
+	    ))
+	 )
+	)
+      )
+     ((looking-at verilog-end-block-re)
+      (verilog-leap-to-head))
+     ((looking-at "\\(endmodule\\>\\)\\|\\(\\<endprimitive\\>\\)\\|\\(\\<endclass\\>\\)\\|\\(\\<endprogram\\>\\)\\|\\(\\<endinterface\\>\\)\\|\\(\\<endpackage\\>\\)")
+      (cond
+       ((match-end 1)
+	(verilog-re-search-backward "\\<\\(macro\\)?module\\>" nil 'move))
+       ((match-end 2)
+	(verilog-re-search-backward "\\<primitive\\>" nil 'move))
+       ((match-end 3)
+	(verilog-re-search-backward "\\<class\\>" nil 'move))
+       ((match-end 4)
+	(verilog-re-search-backward "\\<program\\>" nil 'move))
+       ((match-end 5)
+	(verilog-re-search-backward "\\<interface\\>" nil 'move))
+       ((match-end 6)
+	(verilog-re-search-backward "\\<package\\>" nil 'move))
+       (t
+	(goto-char st)
+	(backward-sexp 1))))
+     (t
+      (goto-char st)
+      (backward-sexp))
+     ) ;; cond
+    ))
+
+(defun verilog-forward-sexp ()
+  (let ((reg)
+	(md 2)
+	(st (point)))
+    (if (not (looking-at "\\<"))
+	(forward-word -1))
+    (cond
+     ((verilog-skip-forward-comment-or-string)
+      (verilog-forward-syntactic-ws)
+      )
+     ((looking-at verilog-beg-block-re-ordered);; begin|case|fork|class|table|specify|function|task|generate|covergroup|property|sequence|clocking
+      (cond
+       ((match-end 1) ; end
+	;; Search forward for matching begin
+	(setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
+       ((match-end 2) ; endcase
+	;; Search forward for matching case
+	(setq reg "\\(\\<randcase\\>\\|\\(\\<unique\\>\\s-+\\|\\<priority\\>\\s-+\\)?\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
+	)
+       ((match-end 3) ; join
+	;; Search forward for matching fork
+	(setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
+       ((match-end 4) ; endclass
+	;; Search forward for matching class
+	(setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
+       ((match-end 5) ; endtable
+	;; Search forward for matching table
+	(setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
+       ((match-end 6) ; endspecify
+	;; Search forward for matching specify
+	(setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
+       ((match-end 7) ; endfunction
+	;; Search forward for matching function
+	(setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
+       ((match-end 8) ; endtask
+	;; Search forward for matching task
+	(setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
+       ((match-end 9) ; endgenerate
+	;; Search forward for matching generate
+	(setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
+       ((match-end 10) ; endgroup
+	;; Search forward for matching covergroup
+	(setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
+       ((match-end 11) ; endproperty
+	;; Search forward for matching property
+	(setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
+       ((match-end 12) ; endsequence
+	;; Search forward for matching sequence
+	(setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" )
+	(setq md 3) ; 3 to get to endsequence in the reg above
+	)
+       ((match-end 13) ; endclocking
+	;; Search forward for matching clocking
+	(setq reg "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)" ))
+       )
+      (if (forward-word 1)
+	  (catch 'skip
+	    (let ((nest 1))
+	      (while (verilog-re-search-forward reg nil 'move)
+		(cond
+		 ((match-end md) ; the closer in reg, so we are climbing out
+		  (setq nest (1- nest))
+		  (if (= 0 nest) ; we are out!
+		      (throw 'skip 1)))
+		 ((match-end 1) ; the opener in reg, so we are deeper now
+		  (setq nest (1+ nest)))))
+	      )))
+      )
+     ((looking-at (concat
+		   "\\(\\<\\(macro\\)?module\\>\\)\\|"
+		   "\\(\\<primitive\\>\\)\\|"
+		   "\\(\\<class\\>\\)\\|"
+		   "\\(\\<program\\>\\)\\|"
+		   "\\(\\<interface\\>\\)\\|"
+		   "\\(\\<package\\>\\)"))
+      (cond
+       ((match-end 1)
+	(verilog-re-search-forward "\\<endmodule\\>" nil 'move))
+       ((match-end 2)
+	(verilog-re-search-forward "\\<endprimitive\\>" nil 'move))
+       ((match-end 3)
+	(verilog-re-search-forward "\\<endclass\\>" nil 'move))
+       ((match-end 4)
+	(verilog-re-search-forward "\\<endprogram\\>" nil 'move))
+       ((match-end 5)
+	(verilog-re-search-forward "\\<endinterface\\>" nil 'move))
+       ((match-end 6)
+	(verilog-re-search-forward "\\<endpackage\\>" nil 'move))
+       (t
+	(goto-char st)
+	(if (= (following-char) ?\) )
+	    (forward-char 1)
+	  (forward-sexp 1)))))
+     (t
+      (goto-char st)
+      (if (= (following-char) ?\) )
+	  (forward-char 1)
+	(forward-sexp 1)))
+     ) ;; cond
+    ))
+
+(defun verilog-declaration-beg ()
+  (verilog-re-search-backward verilog-declaration-re (bobp) t))
+
+;;
+;;  Macros
+;;
+
+(defsubst verilog-string-replace-matches (from-string to-string fixedcase literal string)
+  "Replace occurrences of FROM-STRING with TO-STRING.
+FIXEDCASE and LITERAL as in `replace-match`.  STRING is what to replace.
+The case (verilog-string-replace-matches \"o\" \"oo\" nil nil \"foobar\")
+will break, as the o's continuously replace.  xa -> x works ok though."
+  ;; Hopefully soon to a emacs built-in
+  (let ((start 0))
+    (while (string-match from-string string start)
+      (setq string (replace-match to-string fixedcase literal string)
+	    start (min (length string) (match-end 0))))
+    string))
+
+(defsubst verilog-string-remove-spaces (string)
+  "Remove spaces surrounding STRING."
+  (save-match-data
+    (setq string (verilog-string-replace-matches "^\\s-+" "" nil nil string))
+    (setq string (verilog-string-replace-matches "\\s-+$" "" nil nil string))
+    string))
+
+(defsubst verilog-re-search-forward (REGEXP BOUND NOERROR)
+  ; checkdoc-params: (REGEXP BOUND NOERROR)
+  "Like `re-search-forward', but skips over match in comments or strings."
+  (store-match-data '(nil nil))
+  (while (and
+	  (re-search-forward REGEXP BOUND NOERROR)
+	  (and (verilog-skip-forward-comment-or-string)
+	       (progn
+		 (store-match-data '(nil nil))
+		 (if BOUND
+		     (< (point) BOUND)
+		   t)
+		 ))))
+  (match-end 0))
+
+(defsubst verilog-re-search-backward (REGEXP BOUND NOERROR)
+  ; checkdoc-params: (REGEXP BOUND NOERROR)
+  "Like `re-search-backward', but skips over match in comments or strings."
+  (store-match-data '(nil nil))
+  (while (and
+	  (re-search-backward REGEXP BOUND NOERROR)
+	  (and (verilog-skip-backward-comment-or-string)
+	       (progn
+		 (store-match-data '(nil nil))
+		 (if BOUND
+		     (> (point) BOUND)
+		   t)
+		 ))))
+  (match-end 0))
+
+(defsubst verilog-re-search-forward-quick (regexp bound noerror)
+  "Like `verilog-re-search-forward', including use of REGEXP BOUND and NOERROR,
+but trashes match data and is faster for REGEXP that doesn't match often.
+This may at some point use text properties to ignore comments,
+so there may be a large up front penalty for the first search."
+  (let (pt)
+    (while (and (not pt)
+		(re-search-forward regexp bound noerror))
+      (if (not (verilog-inside-comment-p))
+	  (setq pt (match-end 0))))
+    pt))
+
+(defsubst verilog-re-search-backward-quick (regexp bound noerror)
+  ; checkdoc-params: (REGEXP BOUND NOERROR)
+  "Like `verilog-re-search-backward', including use of REGEXP BOUND and NOERROR,
+but trashes match data and is faster for REGEXP that doesn't match often.
+This may at some point use text properties to ignore comments,
+so there may be a large up front penalty for the first search."
+  (let (pt)
+    (while (and (not pt)
+		(re-search-backward regexp bound noerror))
+      (if (not (verilog-inside-comment-p))
+	  (setq pt (match-end 0))))
+    pt))
+
+(defsubst verilog-get-beg-of-line (&optional arg)
+  (save-excursion
+    (beginning-of-line arg)
+    (point)))
+
+(defsubst verilog-get-end-of-line (&optional arg)
+  (save-excursion
+    (end-of-line arg)
+    (point)))
+
+(defsubst verilog-within-string ()
+  (save-excursion
+    (nth 3 (parse-partial-sexp (verilog-get-beg-of-line) (point)))))
+
+(require 'font-lock)
+(defvar verilog-need-fld 1)
+(defvar font-lock-defaults-alist nil)	;In case we are XEmacs
+
+(defun verilog-font-lock-init ()
+  "Initialize fontification."
+  ;; highlight keywords and standardized types, attributes, enumeration
+  ;; values, and subprograms
+  (setq verilog-font-lock-keywords-3
+	(append verilog-font-lock-keywords-2
+		(when verilog-highlight-translate-off
+		  (list
+		   ;; Fontify things in translate off regions
+		   '(verilog-match-translate-off (0 'verilog-font-lock-translate-off-face prepend))
+		   ))
+	)
+  )
+  (put 'verilog-mode 'font-lock-defaults
+       '((verilog-font-lock-keywords
+	  verilog-font-lock-keywords-1
+	  verilog-font-lock-keywords-2
+	  verilog-font-lock-keywords-3
+	  )
+	 nil ;; nil means highlight strings & comments as well as keywords
+	 nil ;; nil means keywords must match case
+	 nil ;; syntax table handled elsewhere
+	 verilog-beg-of-defun ;; function to move to beginning of reasonable region to highlight
+	 ))
+  (if verilog-need-fld
+      (let ((verilog-mode-defaults
+	     '((verilog-font-lock-keywords
+		verilog-font-lock-keywords-1
+		verilog-font-lock-keywords-2
+		verilog-font-lock-keywords-3
+		)
+	       nil ;; nil means highlight strings & comments as well as keywords
+	       nil ;; nil means keywords must match case
+	       nil ;; syntax table handled elsewhere
+	       verilog-beg-of-defun ;; function to move to beginning of reasonable region to highlight
+	       )))
+	(setq font-lock-defaults-alist
+	      (append
+	       font-lock-defaults-alist
+	       (list (cons 'verilog-mode  verilog-mode-defaults))))
+	(setq verilog-need-fld 0))))
+
+;; initialize fontification for Verilog Mode
+(verilog-font-lock-init)
+;; start up message
+(defconst verilog-startup-message-lines
+  '("Please use \\[verilog-submit-bug-report] to report bugs."
+    "Visit http://www.verilog.com to check for updates"
+    ))
+(defconst verilog-startup-message-displayed t)
+(defun verilog-display-startup-message ()
+  (if (not verilog-startup-message-displayed)
+      (if (sit-for 5)
+	  (let ((lines verilog-startup-message-lines))
+	    (message "verilog-mode version %s, released %s; type \\[describe-mode] for help"
+		     verilog-mode-version verilog-mode-release-date)
+	    (setq verilog-startup-message-displayed t)
+	    (while (and (sit-for 4) lines)
+	      (message (substitute-command-keys (car lines)))
+	      (setq lines (cdr lines)))))
+    (message "")))
+;;
+;;
+;;  Mode
+;;
+(defvar verilog-which-tool 1)
+;;###autoload
+(defun verilog-mode ()
+  "Major mode for editing Verilog code.
+\\<verilog-mode-map>
+See \\[describe-function] verilog-auto (\\[verilog-auto]) for details on how
+AUTOs can improve coding efficiency.
+
+Use \\[verilog-faq] for a pointer to frequently asked questions.
+
+NEWLINE, TAB indents for Verilog code.
+Delete converts tabs to spaces as it moves back.
+
+Supports highlighting.
+
+Turning on Verilog mode calls the value of the variable `verilog-mode-hook'
+with no args, if that value is non-nil.
+
+Variables controlling indentation/edit style:
+
+ variable `verilog-indent-level'      (default 3)
+   Indentation of Verilog statements with respect to containing block.
+ `verilog-indent-level-module'        (default 3)
+   Absolute indentation of Module level Verilog statements.
+   Set to 0 to get initial and always statements lined up
+   on the left side of your screen.
+ `verilog-indent-level-declaration'   (default 3)
+   Indentation of declarations with respect to containing block.
+   Set to 0 to get them list right under containing block.
+ `verilog-indent-level-behavioral'    (default 3)
+   Indentation of first begin in a task or function block
+   Set to 0 to get such code to lined up underneath the task or function keyword
+ `verilog-indent-level-directive'     (default 1)
+   Indentation of `ifdef/`endif blocks
+ `verilog-cexp-indent'              (default 1)
+   Indentation of Verilog statements broken across lines i.e.:
+      if (a)
+        begin
+ `verilog-case-indent'              (default 2)
+   Indentation for case statements.
+ `verilog-auto-newline'             (default nil)
+   Non-nil means automatically newline after semicolons and the punctuation
+   mark after an end.
+ `verilog-auto-indent-on-newline'   (default t)
+   Non-nil means automatically indent line after newline
+ `verilog-tab-always-indent'        (default t)
+   Non-nil means TAB in Verilog mode should always reindent the current line,
+   regardless of where in the line point is when the TAB command is used.
+ `verilog-indent-begin-after-if'    (default t)
+   Non-nil means to indent begin statements following a preceding
+   if, else, while, for and repeat statements, if any.  otherwise,
+   the begin is lined up with the preceding token.  If t, you get:
+      if (a)
+         begin // amount of indent based on `verilog-cexp-indent'
+   otherwise you get:
+      if (a)
+      begin
+ `verilog-auto-endcomments'         (default t)
+   Non-nil means a comment /* ... */ is set after the ends which ends
+   cases, tasks, functions and modules.
+   The type and name of the object will be set between the braces.
+ `verilog-minimum-comment-distance' (default 10)
+   Minimum distance (in lines) between begin and end required before a comment
+   will be inserted.  Setting this variable to zero results in every
+   end acquiring a comment; the default avoids too many redundant
+   comments in tight quarters.
+ `verilog-auto-lineup'              (default `(all))
+   List of contexts where auto lineup of code should be done.
+
+Variables controlling other actions:
+
+ `verilog-linter'                   (default surelint)
+   Unix program to call to run the lint checker.  This is the default
+   command for \\[compile-command] and \\[verilog-auto-save-compile].
+
+See \\[customize] for the complete list of variables.
+
+AUTO expansion functions are, in part:
+
+    \\[verilog-auto]  Expand AUTO statements.
+    \\[verilog-delete-auto]  Remove the AUTOs.
+    \\[verilog-inject-auto]  Insert AUTOs for the first time.
+
+Some other functions are:
+
+    \\[verilog-complete-word]    Complete word with appropriate possibilities.
+    \\[verilog-mark-defun]  Mark function.
+    \\[verilog-beg-of-defun]  Move to beginning of current function.
+    \\[verilog-end-of-defun]  Move to end of current function.
+    \\[verilog-label-be]  Label matching begin ... end, fork ... join, etc statements.
+
+    \\[verilog-comment-region]  Put marked area in a comment.
+    \\[verilog-uncomment-region]  Uncomment an area commented with \\[verilog-comment-region].
+    \\[verilog-insert-block]  Insert begin ... end;.
+    \\[verilog-star-comment]    Insert /* ... */.
+
+    \\[verilog-sk-always]  Insert a always @(AS) begin .. end block.
+    \\[verilog-sk-begin]  Insert a begin .. end block.
+    \\[verilog-sk-case]  Insert a case block, prompting for details.
+    \\[verilog-sk-for]  Insert a for (...) begin .. end block, prompting for details.
+    \\[verilog-sk-generate]  Insert a generate .. endgenerate block.
+    \\[verilog-sk-header]  Insert a nice header block at the top of file.
+    \\[verilog-sk-initial]  Insert an initial begin .. end block.
+    \\[verilog-sk-fork]  Insert a fork begin .. end .. join block.
+    \\[verilog-sk-module]  Insert a module .. (/*AUTOARG*/);.. endmodule block.
+    \\[verilog-sk-primitive]  Insert a primitive .. (.. );.. endprimitive block.
+    \\[verilog-sk-repeat]  Insert a repeat (..) begin .. end block.
+    \\[verilog-sk-specify]  Insert a specify .. endspecify block.
+    \\[verilog-sk-task]  Insert a task .. begin .. end endtask block.
+    \\[verilog-sk-while]  Insert a while (...) begin .. end block, prompting for details.
+    \\[verilog-sk-casex]  Insert a casex (...) item: begin.. end endcase block, prompting for details.
+    \\[verilog-sk-casez]  Insert a casez (...) item: begin.. end endcase block, prompting for details.
+    \\[verilog-sk-if]  Insert an if (..) begin .. end block.
+    \\[verilog-sk-else-if]  Insert an else if (..) begin .. end block.
+    \\[verilog-sk-comment]  Insert a comment block.
+    \\[verilog-sk-assign]  Insert an assign .. = ..; statement.
+    \\[verilog-sk-function]  Insert a function .. begin .. end endfunction block.
+    \\[verilog-sk-input]  Insert an input declaration, prompting for details.
+    \\[verilog-sk-output]  Insert an output declaration, prompting for details.
+    \\[verilog-sk-state-machine]  Insert a state machine definition, prompting for details.
+    \\[verilog-sk-inout]  Insert an inout declaration, prompting for details.
+    \\[verilog-sk-wire]  Insert a wire declaration, prompting for details.
+    \\[verilog-sk-reg]  Insert a register declaration, prompting for details.
+    \\[verilog-sk-define-signal]  Define signal under point as a register at the top of the module.
+
+All key bindings can be seen in a Verilog-buffer with \\[describe-bindings].
+Key bindings specific to `verilog-mode-map' are:
+
+\\{verilog-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map verilog-mode-map)
+  (setq major-mode 'verilog-mode)
+  (setq mode-name "Verilog")
+  (setq local-abbrev-table verilog-mode-abbrev-table)
+  (setq verilog-mode-syntax-table (make-syntax-table))
+  (verilog-populate-syntax-table verilog-mode-syntax-table)
+  ;; add extra comment syntax
+  (verilog-setup-dual-comments verilog-mode-syntax-table)
+  (set-syntax-table verilog-mode-syntax-table)
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'verilog-indent-line-relative)
+  (setq comment-indent-function 'verilog-comment-indent)
+  (make-local-variable 'parse-sexp-ignore-comments)
+  (setq parse-sexp-ignore-comments nil)
+  (make-local-variable 'comment-start)
+  (make-local-variable 'comment-end)
+  (make-local-variable 'comment-multi-line)
+  (make-local-variable 'comment-start-skip)
+  (setq comment-start "// "
+	comment-end ""
+	comment-start-skip "/\\*+ *\\|// *"
+	comment-multi-line nil)
+  ;; Set up for compilation
+  (setq verilog-which-tool 1)
+  (setq verilog-tool 'verilog-linter)
+  (verilog-set-compile-command)
+  (when (boundp 'hack-local-variables-hook)  ;; Also modify any file-local-variables
+    (add-hook 'hack-local-variables-hook 'verilog-modify-compile-command t))
+
+  ;; Setting up menus
+  (if (featurep 'xemacs)
+      (progn
+        (if (and current-menubar
+                 (not (assoc "Verilog" current-menubar)))
+            (progn
+	      ;; (set-buffer-menubar (copy-sequence current-menubar))
+              (add-submenu nil verilog-xemacs-menu)
+              (add-submenu nil verilog-stmt-menu)
+	      )
+	  )
+	))
+  ;; Stuff for GNU emacs
+  (make-local-variable 'font-lock-defaults)
+  ;;------------------------------------------------------------
+  ;; now hook in 'verilog-colorize-include-files (eldo-mode.el&spice-mode.el)
+  ;; all buffer local:
+  (make-local-hook 'font-lock-mode-hook)
+  (make-local-hook 'font-lock-after-fontify-buffer-hook); doesn't exist in emacs 20
+  (add-hook 'font-lock-mode-hook 'verilog-colorize-include-files-buffer t t)
+  (add-hook 'font-lock-after-fontify-buffer-hook 'verilog-colorize-include-files-buffer t t) ; not in emacs 20
+  (make-local-hook 'after-change-functions)
+  (add-hook 'after-change-functions 'verilog-colorize-include-files t t)
+
+  ;; Tell imenu how to handle verilog.
+  (make-local-variable 'imenu-generic-expression)
+  (setq imenu-generic-expression verilog-imenu-generic-expression)
+  ;; hideshow support
+  (unless (assq 'verilog-mode hs-special-modes-alist)
+    (setq hs-special-modes-alist
+	  (cons '(verilog-mode-mode  "\\<begin\\>" "\\<end\\>" nil
+			     verilog-forward-sexp-function)
+		hs-special-modes-alist)))
+  ;; Display version splash information.
+  (verilog-display-startup-message)
+
+  ;; Stuff for autos
+  (add-hook 'write-contents-hooks 'verilog-auto-save-check) ; already local
+;;  (verilog-auto-reeval-locals t)   ; Save locals in case user changes them
+;;  (verilog-getopt-flags)
+  (run-hooks 'verilog-mode-hook))
+
+
+;;
+;;  Electric functions
+;;
+(defun electric-verilog-terminate-line (&optional arg)
+  "Terminate line and indent next line.
+With optional ARG, remove existing end of line comments."
+  (interactive)
+  ;; before that see if we are in a comment
+  (let ((state
+	 (save-excursion
+	   (parse-partial-sexp (point-min) (point)))))
+    (cond
+     ((nth 7 state)			; Inside // comment
+      (if (eolp)
+	  (progn
+	    (delete-horizontal-space)
+	    (newline))
+	(progn
+	  (newline)
+	  (insert-string "// ")
+	  (beginning-of-line)))
+      (verilog-indent-line))
+     ((nth 4 state)			; Inside any comment (hence /**/)
+      (newline)
+      (verilog-more-comment))
+     ((eolp)
+       ;; First, check if current line should be indented
+       (if (save-excursion
+             (delete-horizontal-space)
+	     (beginning-of-line)
+	     (skip-chars-forward " \t")
+	     (if (looking-at verilog-auto-end-comment-lines-re)
+		 (let ((indent-str (verilog-indent-line)))
+		   ;; Maybe we should set some endcomments
+		   (if verilog-auto-endcomments
+		       (verilog-set-auto-endcomments indent-str arg))
+		   (end-of-line)
+		   (delete-horizontal-space)
+		   (if arg
+		       ()
+		     (newline))
+		   nil)
+	       (progn
+		 (end-of-line)
+		 (delete-horizontal-space)
+		 't
+		 )
+	       )
+	     )
+	   ;; see if we should line up assignments
+	   (progn
+	     (if (or (memq 'all verilog-auto-lineup)
+		     (memq 'assignments verilog-auto-lineup))
+		 (verilog-pretty-expr)
+	       )
+	     (newline)
+	     )
+	 (forward-line 1)
+	 )
+       ;; Indent next line
+       (if verilog-auto-indent-on-newline
+	   (verilog-indent-line))
+       )
+     (t
+      (newline))
+     )))
+
+(defun electric-verilog-terminate-and-indent ()
+  "Insert a newline and indent for the next statement."
+  (interactive)
+  (electric-verilog-terminate-line 1))
+
+(defun electric-verilog-semi ()
+  "Insert `;' character and reindent the line."
+  (interactive)
+  (insert last-command-char)
+
+  (if (or (verilog-in-comment-or-string-p)
+	  (verilog-in-escaped-name-p))
+      ()
+    (save-excursion
+      (beginning-of-line)
+      (verilog-forward-ws&directives)
+      (verilog-indent-line)
+      )
+    (if (and verilog-auto-newline
+	     (not (verilog-parenthesis-depth)))
+	(electric-verilog-terminate-line))))
+
+(defun electric-verilog-semi-with-comment ()
+  "Insert `;' character, reindent the line and indent for comment."
+  (interactive)
+  (insert "\;")
+  (save-excursion
+    (beginning-of-line)
+    (verilog-indent-line))
+  (indent-for-comment))
+
+(defun electric-verilog-colon ()
+  "Insert `:' and do all indentations except line indent on this line."
+  (interactive)
+  (insert last-command-char)
+  ;; Do nothing if within string.
+  (if (or
+       (verilog-within-string)
+       (not (verilog-in-case-region-p)))
+      ()
+    (save-excursion
+      (let ((p (point))
+	    (lim (progn (verilog-beg-of-statement) (point))))
+	(goto-char p)
+	(verilog-backward-case-item lim)
+	(verilog-indent-line)))
+;;    (let ((verilog-tab-always-indent nil))
+;;      (verilog-indent-line))
+    ))
+
+;;(defun electric-verilog-equal ()
+;;  "Insert `=', and do indentation if within block."
+;;  (interactive)
+;;  (insert last-command-char)
+;; Could auto line up expressions, but not yet
+;;  (if (eq (car (verilog-calculate-indent)) 'block)
+;;      (let ((verilog-tab-always-indent nil))
+;;	(verilog-indent-command)))
+;;  )
+
+(defun electric-verilog-tick ()
+  "Insert back-tick, and indent to column 0 if this is a CPP directive."
+  (interactive)
+  (insert last-command-char)
+  (save-excursion
+    (if (progn
+	  (beginning-of-line)
+	  (looking-at verilog-directive-re-1))
+	(verilog-indent-line))))
+
+(defun electric-verilog-tab ()
+  "Function called when TAB is pressed in Verilog mode."
+  (interactive)
+  ;; If verilog-tab-always-indent, indent the beginning of the line.
+  (if (or verilog-tab-always-indent
+	  (save-excursion
+	    (skip-chars-backward " \t")
+	    (bolp)))
+      (let* ((oldpnt (point))
+	     (boi-point
+	      (save-excursion
+		(beginning-of-line)
+		(skip-chars-forward " \t")
+		(verilog-indent-line)
+		(back-to-indentation)
+		(point))))
+        (if (< (point) boi-point)
+            (back-to-indentation)
+	  (cond ((not verilog-tab-to-comment))
+		((not (eolp))
+		 (end-of-line))
+		(t
+		 (indent-for-comment)
+		 (when (and (eolp) (= oldpnt (point)))
+					; kill existing comment
+		   (beginning-of-line)
+		   (re-search-forward comment-start-skip oldpnt 'move)
+		   (goto-char (match-beginning 0))
+		   (skip-chars-backward " \t")
+		   (kill-region (point) oldpnt)
+		   ))))
+	)
+    (progn (insert "\t"))))
+
+
+
+;;
+;; Interactive functions
+;;
+
+(defun verilog-indent-buffer ()
+  "Indent-region the entire buffer as Verilog code.
+To call this from the command line, see \\[verilog-batch-indent]."
+  (interactive)
+  (verilog-mode)
+  (indent-region (point-min) (point-max) nil))
+
+(defun verilog-insert-block ()
+  "Insert Verilog begin ... end; block in the code with right indentation."
+  (interactive)
+  (verilog-indent-line)
+  (insert "begin")
+  (electric-verilog-terminate-line)
+  (save-excursion
+    (electric-verilog-terminate-line)
+    (insert "end")
+    (beginning-of-line)
+    (verilog-indent-line)))
+
+(defun verilog-star-comment ()
+  "Insert Verilog star comment at point."
+  (interactive)
+  (verilog-indent-line)
+  (insert "/*")
+  (save-excursion
+    (newline)
+    (insert " */"))
+  (newline)
+  (insert " * "))
+
+(defun verilog-insert-indices (MAX)
+  "Insert a set of indices at into the rectangle.
+The upper left corner is defined by the current point.  Indices always
+begin with 0 and extend to the MAX - 1.  If no prefix arg is given, the
+user is prompted for a value.  The indices are surrounded by square brackets
+[].  For example, the following code with the point located after the first
+'a' gives:
+
+    a = b                           a[  0] = b
+    a = b                           a[  1] = b
+    a = b                           a[  2] = b
+    a = b                           a[  3] = b
+    a = b   ==> insert-indices ==>  a[  4] = b
+    a = b                           a[  5] = b
+    a = b                           a[  6] = b
+    a = b                           a[  7] = b
+    a = b                           a[  8] = b"
+
+  (interactive "NMAX?")
+  (save-excursion
+  (let ((n 0))
+    (while (< n MAX)
+      (save-excursion
+      (insert (format "[%3d]" n)))
+      (next-line 1)
+      (setq n (1+ n))))))
+
+
+(defun verilog-generate-numbers (MAX)
+  "Insert a set of generated numbers into a rectangle.
+The upper left corner is defined by point.  The numbers are padded to three
+digits, starting with 000 and extending to (MAX - 1).  If no prefix argument
+is supplied, then the user is prompted for the MAX number.  consider the
+following code fragment:
+
+    buf buf                           buf buf000
+    buf buf                           buf buf001
+    buf buf                           buf buf002
+    buf buf                           buf buf003
+    buf buf   ==> insert-indices ==>  buf buf004
+    buf buf                           buf buf005
+    buf buf                           buf buf006
+    buf buf                           buf buf007
+    buf buf                           buf buf008"
+
+  (interactive "NMAX?")
+  (save-excursion
+  (let ((n 0))
+    (while (< n MAX)
+      (save-excursion
+      (insert (format "%3.3d" n)))
+      (next-line 1)
+      (setq n (1+ n))))))
+
+(defun verilog-mark-defun ()
+  "Mark the current verilog function (or procedure).
+This puts the mark at the end, and point at the beginning."
+  (interactive)
+  (push-mark (point))
+  (verilog-end-of-defun)
+  (push-mark (point))
+  (verilog-beg-of-defun)
+  (zmacs-activate-region))
+
+(defun verilog-comment-region (start end)
+  ; checkdoc-params: (start end)
+  "Put the region into a Verilog comment.
+The comments that are in this area are \"deformed\":
+`*)' becomes `!(*' and `}' becomes `!{'.
+These deformed comments are returned to normal if you use
+\\[verilog-uncomment-region] to undo the commenting.
+
+The commented area starts with `verilog-exclude-str-start', and ends with
+`verilog-exclude-str-end'.  But if you change these variables,
+\\[verilog-uncomment-region] won't recognize the comments."
+  (interactive "r")
+  (save-excursion
+    ;; Insert start and endcomments
+    (goto-char end)
+    (if (and (save-excursion (skip-chars-forward " \t") (eolp))
+	     (not (save-excursion (skip-chars-backward " \t") (bolp))))
+	(forward-line 1)
+      (beginning-of-line))
+    (insert verilog-exclude-str-end)
+    (setq end (point))
+    (newline)
+    (goto-char start)
+    (beginning-of-line)
+    (insert verilog-exclude-str-start)
+    (newline)
+    ;; Replace end-comments within commented area
+    (goto-char end)
+    (save-excursion
+      (while (re-search-backward "\\*/" start t)
+	(replace-match "*-/" t t)))
+    (save-excursion
+      (let ((s+1 (1+ start)))
+	(while (re-search-backward "/\\*" s+1 t)
+	  (replace-match "/-*" t t))))
+    ))
+
+(defun verilog-uncomment-region ()
+  "Uncomment a commented area; change deformed comments back to normal.
+This command does nothing if the pointer is not in a commented
+area.  See also `verilog-comment-region'."
+  (interactive)
+  (save-excursion
+    (let ((start (point))
+	  (end (point)))
+      ;; Find the boundaries of the comment
+      (save-excursion
+	(setq start (progn (search-backward verilog-exclude-str-start nil t)
+			   (point)))
+	(setq end (progn (search-forward verilog-exclude-str-end nil t)
+			 (point))))
+      ;; Check if we're really inside a comment
+      (if (or (equal start (point)) (<= end (point)))
+	  (message "Not standing within commented area.")
+	(progn
+	  ;; Remove endcomment
+	  (goto-char end)
+	  (beginning-of-line)
+	  (let ((pos (point)))
+	    (end-of-line)
+	    (delete-region pos (1+ (point))))
+	  ;; Change comments back to normal
+	  (save-excursion
+	    (while (re-search-backward "\\*-/" start t)
+	      (replace-match "*/" t t)))
+	  (save-excursion
+	    (while (re-search-backward "/-\\*" start t)
+	      (replace-match "/*" t t)))
+	  ;; Remove start comment
+	  (goto-char start)
+	  (beginning-of-line)
+	  (let ((pos (point)))
+	    (end-of-line)
+	    (delete-region pos (1+ (point)))))))))
+
+(defun verilog-beg-of-defun ()
+  "Move backward to the beginning of the current function or procedure."
+  (interactive)
+  (verilog-re-search-backward verilog-defun-re nil 'move))
+
+(defun verilog-end-of-defun ()
+  "Move forward to the end of the current function or procedure."
+  (interactive)
+  (verilog-re-search-forward verilog-end-defun-re nil 'move))
+
+(defun verilog-get-beg-of-defun (&optional warn)
+  (save-excursion
+    (cond ((verilog-re-search-forward-quick verilog-defun-re nil t)
+	   (point))
+	  (t
+	   (error "%s: Can't find module beginning" (verilog-point-text))
+	   (point-max)))))
+(defun verilog-get-end-of-defun (&optional warn)
+  (save-excursion
+    (cond ((verilog-re-search-forward-quick verilog-end-defun-re nil t)
+	   (point))
+	  (t
+	   (error "%s: Can't find endmodule" (verilog-point-text))
+	   (point-max)))))
+
+(defun verilog-label-be (&optional arg)
+  "Label matching begin ... end, fork ... join and case ... endcase statements.
+With ARG, first kill any existing labels."
+  (interactive)
+  (let ((cnt 0)
+	(oldpos (point))
+	(b (progn
+	     (verilog-beg-of-defun)
+	     (point-marker)))
+	(e (progn
+	     (verilog-end-of-defun)
+	     (point-marker)))
+	)
+    (goto-char (marker-position b))
+    (if (> (- e b) 200)
+	(message  "Relabeling module..."))
+    (while (and
+	    (> (marker-position e) (point))
+	    (verilog-re-search-forward
+	     (concat
+	      "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\|\\(interface\\)\\|\\(package\\)\\|\\(case\\)\\)?\\>"
+	      "\\|\\(`endif\\)\\|\\(`else\\)")
+	     nil 'move))
+      (goto-char (match-beginning 0))
+      (let ((indent-str (verilog-indent-line)))
+	(verilog-set-auto-endcomments indent-str 't)
+	(end-of-line)
+	(delete-horizontal-space)
+	)
+      (setq cnt (1+ cnt))
+      (if (= 9 (% cnt 10))
+	  (message "%d..." cnt))
+      )
+    (goto-char oldpos)
+    (if (or
+	 (> (- e b) 200)
+	 (> cnt 20))
+	(message  "%d lines auto commented" cnt))
+    ))
+
+(defun verilog-beg-of-statement ()
+  "Move backward to beginning of statement."
+  (interactive)
+  ;; Move back token by token until we see the end
+  ;; of some ealier line.
+  (while
+      ;; If the current point does not begin a new
+      ;; statement, as in the character ahead of us is a ';', or SOF
+      ;; or the string after us unambiguosly starts a statement,
+      ;; or the token before us unambiguously ends a statement,
+      ;; then move back a token and test again.
+      (not (or
+	    (bolp)
+	    (= (preceding-char) ?\;)
+	    (not (or
+		  (looking-at "\\<")
+		  (forward-word -1)))
+	    (and
+	     (looking-at verilog-extended-complete-re)
+	     (not (save-excursion
+		    (verilog-backward-token)
+		    (looking-at verilog-extended-complete-re)))
+	     )
+	    (looking-at verilog-basic-complete-re)
+	    (save-excursion
+	      (verilog-backward-token)
+	      (or
+	       (looking-at verilog-end-block-re)
+	       (looking-at verilog-preprocessor-re)))
+	    ))
+    (verilog-backward-syntactic-ws)
+    (verilog-backward-token))
+  ;; Now point is where the previous line ended.
+  (verilog-forward-syntactic-ws))
+
+(defun verilog-beg-of-statement-1 ()
+  "Move backward to beginning of statement."
+  (interactive)
+  (let ((pt (point)))
+
+    (while (and (not (looking-at verilog-complete-reg))
+		(setq pt (point))
+		(verilog-backward-token)
+		(not (looking-at verilog-complete-reg))
+		(verilog-backward-syntactic-ws)
+		(setq pt (point))
+		(not (bolp))
+		(not (= (preceding-char) ?\;))))
+    (goto-char pt)
+    (verilog-forward-ws&directives)))
+
+(defun verilog-end-of-statement ()
+  "Move forward to end of current statement."
+  (interactive)
+  (let ((nest 0) pos)
+    (or (looking-at verilog-beg-block-re)
+	;; Skip to end of statement
+	(setq pos (catch 'found
+		    (while t
+		      (forward-sexp 1)
+		      (verilog-skip-forward-comment-or-string)
+		      (cond ((looking-at "[ \t]*;")
+			     (skip-chars-forward "^;")
+			     (forward-char 1)
+			     (throw 'found (point)))
+			    ((save-excursion
+			       (forward-sexp -1)
+			       (looking-at verilog-beg-block-re))
+			     (goto-char (match-beginning 0))
+			     (throw 'found nil))
+			    ((looking-at "[ \t]*)")
+			     (throw 'found (point)))			     
+			    ((eobp)
+			     (throw 'found (point))))))))
+    (if (not pos)
+	;; Skip a whole block
+	(catch 'found
+	  (while t
+	    (verilog-re-search-forward verilog-end-statement-re nil 'move)
+	    (setq nest (if (match-end 1)
+			   (1+ nest)
+			 (1- nest)))
+	    (cond ((eobp)
+		   (throw 'found (point)))
+		  ((= 0 nest)
+		   (throw 'found (verilog-end-of-statement))))))
+      pos)))
+
+(defun verilog-in-case-region-p ()
+  "Return TRUE if in a case region;
+more specifically, point @ in the line foo : @ begin"
+  (interactive)
+  (save-excursion
+    (if (and
+	 (progn (verilog-forward-syntactic-ws)
+		(looking-at "\\<begin\\>"))
+	 (progn (verilog-backward-syntactic-ws)
+		(= (preceding-char) ?\:)))
+	(catch 'found
+	  (let ((nest 1))
+	    (while t
+	      (verilog-re-search-backward
+	       (concat "\\(\\<module\\>\\)\\|\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|"
+		       "\\(\\<endcase\\>\\)\\>")
+	       nil 'move)
+	      (cond
+	       ((match-end 3)
+		(setq nest (1+ nest)))
+	       ((match-end 2)
+		(if (= nest 1)
+		(throw 'found 1))
+		(setq nest (1- nest)))
+	       (t
+		(throw 'found (= nest 0)))
+	       ))))
+      nil)))
+(defun verilog-in-struct-region-p ()
+  "Return TRUE if in a struct region;
+more specifically, in a list after a struct|union keyword"
+  (interactive)
+  (save-excursion
+    (let* ((state (parse-partial-sexp (point-min) (point)))
+	   (depth (nth 0 state)))
+      (if depth
+	  (progn (backward-up-list depth)
+		 (verilog-beg-of-statement)
+		 (looking-at "\\<typedef\\>?\\s-*\\<struct\\|union\\>")
+		 )
+	)
+      )
+    )
+  )
+
+(defun verilog-in-generate-region-p ()
+  "Return TRUE if in a generate region;
+more specifically, after a generate and before an endgenerate"
+  (interactive)
+  (let ((lim (save-excursion (verilog-beg-of-defun)  (point)))
+	(nest 1)
+	)
+    (save-excursion
+      (while (and
+	      (/= nest 0)
+	      (verilog-re-search-backward "\\<\\(generate\\)\\|\\(endgenerate\\)\\>" lim 'move)
+	      (cond
+	       ((match-end 1) ; generate
+		(setq nest (1- nest)))
+	       ((match-end 2) ; endgenerate
+		(setq nest (1+ nest)))
+	       ))
+	))
+    (= nest 0) )) ; return nest
+
+(defun verilog-in-fork-region-p ()
+  "Return true if between a fork and join."
+  (interactive)
+  (let ((lim (save-excursion (verilog-beg-of-defun)  (point)))
+	(nest 1)
+	)
+    (save-excursion
+      (while (and
+	      (/= nest 0)
+	      (verilog-re-search-backward "\\<\\(fork\\)\\|\\(join\\(_any\\|_none\\)?\\)\\>" lim 'move)
+	      (cond
+	       ((match-end 1) ; fork
+		(setq nest (1- nest)))
+	       ((match-end 2) ; join
+		(setq nest (1+ nest)))
+	       ))
+	))
+    (= nest 0) )) ; return nest
+
+(defun verilog-backward-case-item (lim)
+  "Skip backward to nearest enclosing case item.
+Limit search to point LIM."
+  (interactive)
+  (let ((str 'nil)
+	(lim1
+	 (progn
+	   (save-excursion
+	     (verilog-re-search-backward verilog-endcomment-reason-re
+					 lim 'move)
+	     (point)))))
+    ;; Try to find the real :
+    (if (save-excursion (search-backward ":" lim1 t))
+	(let ((colon 0)
+	      b e )
+	  (while
+	      (and
+	       (< colon 1)
+	       (verilog-re-search-backward "\\(\\[\\)\\|\\(\\]\\)\\|\\(:\\)"
+					   lim1 'move))
+	    (cond
+	     ((match-end 1) ;; [
+	      (setq colon (1+ colon))
+	      (if (>= colon 0)
+		  (error "%s: unbalanced [" (verilog-point-text))))
+	     ((match-end 2) ;; ]
+	      (setq colon (1- colon)))
+
+	     ((match-end 3) ;; :
+	      (setq colon (1+ colon)))
+	     ))
+	  ;; Skip back to beginning of case item
+	  (skip-chars-backward "\t ")
+	  (verilog-skip-backward-comment-or-string)
+	  (setq e (point))
+	  (setq b
+		(progn
+		  (if
+		      (verilog-re-search-backward
+		       "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
+		      (progn
+			(cond
+			 ((match-end 1)
+			  (goto-char (match-end 1))
+			  (verilog-forward-ws&directives)
+			  (if (looking-at "(")
+			      (progn
+				(forward-sexp)
+				(verilog-forward-ws&directives)))
+			  (point))
+			 (t
+			  (goto-char (match-end 0))
+			  (verilog-forward-ws&directives)
+			  (point))
+			 ))
+		    (error "Malformed case item")
+		    )))
+	  (setq str (buffer-substring b e))
+	  (if
+	      (setq e
+		    (string-match
+		     "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
+	      (setq str (concat (substring str 0 e) "...")))
+	  str)
+      'nil)))
+
+
+;;
+;; Other functions
+;;
+
+(defun kill-existing-comment ()
+  "Kill auto comment on this line."
+  (save-excursion
+    (let* (
+	   (e (progn
+		(end-of-line)
+		(point)))
+	   (b (progn
+		(beginning-of-line)
+		(search-forward "//" e t))))
+      (if b
+	  (delete-region (- b 2) e)))))
+
+(defconst verilog-directive-nest-re
+  (concat "\\(`else\\>\\)\\|"
+	  "\\(`endif\\>\\)\\|"
+	  "\\(`if\\>\\)\\|"
+	  "\\(`ifdef\\>\\)\\|"
+	  "\\(`ifndef\\>\\)"))
+(defun verilog-set-auto-endcomments (indent-str kill-existing-comment)
+  "Add ending comment with given INDENT-STR.
+With KILL-EXISTING-COMMENT, remove what was there before.
+Insert `// case: 7 ' or `// NAME ' on this line if appropriate.
+Insert `// case expr ' if this line ends a case block.
+Insert `// ifdef FOO ' if this line ends code conditional on FOO.
+Insert `// NAME ' if this line ends a function, task, module, primitive or interface named NAME."
+  (save-excursion
+    (cond
+     (; Comment close preprocessor directives
+      (and
+       (looking-at "\\(`endif\\)\\|\\(`else\\)")
+       (or  kill-existing-comment
+	    (not (save-excursion
+		   (end-of-line)
+		   (search-backward "//" (verilog-get-beg-of-line) t)))))
+      (let ((nest 1) b e
+	    m
+	    (else (if (match-end 2) "!" " "))
+	    )
+	(end-of-line)
+	(if kill-existing-comment
+	    (kill-existing-comment))
+	(delete-horizontal-space)
+	(save-excursion
+	  (backward-sexp 1)
+	  (while (and (/= nest 0)
+		      (verilog-re-search-backward verilog-directive-nest-re nil 'move))
+	    (cond
+	     ((match-end 1) ; `else
+	      (if (= nest 1)
+		  (setq else "!")))
+	     ((match-end 2) ; `endif
+	      (setq nest (1+ nest)))
+	     ((match-end 3) ; `if
+	      (setq nest (1- nest)))
+	     ((match-end 4) ; `ifdef
+	      (setq nest (1- nest)))
+	     ((match-end 5) ; `ifndef
+	      (setq nest (1- nest)))
+	     ))
+	  (if (match-end 0)
+	      (setq
+	       m (buffer-substring
+		  (match-beginning 0)
+		  (match-end 0))
+	       b (progn
+		   (skip-chars-forward "^ \t")
+		   (verilog-forward-syntactic-ws)
+		   (point))
+	       e (progn
+		   (skip-chars-forward "a-zA-Z0-9_")
+		   (point)
+		   ))))
+	(if b
+	    (if (> (count-lines (point) b) verilog-minimum-comment-distance)
+		(insert (concat " // " else m " " (buffer-substring b e))))
+	  (progn
+	    (insert " // unmatched `else or `endif")
+	    (ding 't))
+	  )))
+
+     (; Comment close case/class/function/task/module and named block
+      (and (looking-at "\\<end")
+	   (or kill-existing-comment
+	       (not (save-excursion
+		      (end-of-line)
+		      (search-backward "//" (verilog-get-beg-of-line) t)))))
+      (let ((type (car indent-str)))
+	(unless (eq type 'declaration)
+	  (unless (looking-at (concat "\\(" verilog-end-block-ordered-re "\\)[ \t]*:")) ;; ignore named ends
+	    (if (looking-at verilog-end-block-ordered-re)
+	      (cond
+	       (;- This is a case block; search back for the start of this case
+		(match-end 1) ;; of verilog-end-block-ordered-re
+
+		(let ((err 't)
+		      (str "UNMATCHED!!"))
+		  (save-excursion
+		    (verilog-leap-to-head)
+		    (cond
+		     ((looking-at "\\<randcase\\>")
+		      (setq str "randcase")
+		      (setq err nil)
+		      )
+		     ((match-end 0)
+		      (goto-char (match-end 1))
+		      (if nil
+			  (let (s f)
+			    (setq s (match-beginning 1))
+			    (setq f (progn (end-of-line)
+					   (point)))
+			    (setq str  (buffer-substring s f)))
+			(setq err nil))
+		      (setq str (concat (buffer-substring (match-beginning 1) (match-end 1))
+					" "
+					(verilog-get-expr))))))
+		  (end-of-line)
+		  (if kill-existing-comment
+		      (kill-existing-comment))
+		  (delete-horizontal-space)
+		  (insert (concat " // " str ))
+		  (if err (ding 't))
+		  ))
+
+	       (;- This is a begin..end block
+		(match-end 2) ;; of verilog-end-block-ordered-re
+		(let ((str " // UNMATCHED !!")
+		      (err 't)
+		      (here (point))
+		      there
+		      cntx
+		      )
+		  (save-excursion
+		    (verilog-leap-to-head)
+		    (setq there (point))
+		    (if (not (match-end 0))
+			(progn
+			  (goto-char here)
+			  (end-of-line)
+			  (if kill-existing-comment
+			      (kill-existing-comment))
+			  (delete-horizontal-space)
+			  (insert str)
+			  (ding 't)
+			  )
+		      (let ((lim
+			     (save-excursion (verilog-beg-of-defun) (point)))
+			    (here (point))
+			    )
+			(cond
+			 (;-- handle named block differently
+			  (looking-at verilog-named-block-re)
+			  (search-forward ":")
+			  (setq there (point))
+			  (setq str (verilog-get-expr))
+			  (setq err nil)
+			  (setq str (concat " // block: " str )))
+
+			 ((verilog-in-case-region-p) ;-- handle case item differently
+			  (goto-char here)
+			  (setq str (verilog-backward-case-item lim))
+			  (setq there (point))
+			  (setq err nil)
+			  (setq str (concat " // case: " str )))
+
+			 (;- try to find "reason" for this begin
+			  (cond
+			   (;
+			    (eq here (progn
+				       (verilog-backward-token)
+				       (verilog-beg-of-statement-1)
+				       (point)))
+			    (setq err nil)
+			    (setq str ""))
+			   ((looking-at verilog-endcomment-reason-re)
+			    (setq there (match-end 0))
+			    (setq cntx (concat
+					(buffer-substring (match-beginning 0) (match-end 0)) " "))
+			    (cond
+			     (;- begin
+			      (match-end 2)
+			      (setq err nil)
+			      (save-excursion
+				(if (and (verilog-continued-line)
+					 (looking-at "\\<repeat\\>\\|\\<wait\\>\\|\\<always\\>"))
+				    (progn
+				      (goto-char (match-end 0))
+				      (setq there (point))
+				      (setq str
+					    (concat " // "
+						    (buffer-substring (match-beginning 0) (match-end 0)) " "
+						    (verilog-get-expr))))
+				  (setq str ""))))
+
+			     (;- else
+			      (match-end 4)
+			      (let ((nest 0)
+				    ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)")
+				    )
+				(catch 'skip
+				  (while (verilog-re-search-backward reg nil 'move)
+				    (cond
+				     ((match-end 1) ; begin
+				      (setq nest (1- nest)))
+				     ((match-end 2)                       ; end
+				      (setq nest (1+ nest)))
+				     ((match-end 3)
+				      (if (= 0 nest)
+					  (progn
+					    (goto-char (match-end 0))
+					    (setq there (point))
+					    (setq err nil)
+					    (setq str (verilog-get-expr))
+					    (setq str (concat " // else: !if" str ))
+					    (throw 'skip 1))
+					)))
+				    ))))
+
+			     (;- end else
+			      (match-end 5)
+			      (goto-char there)
+			      (let ((nest 0)
+				    ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)")
+				    )
+				(catch 'skip
+				  (while (verilog-re-search-backward reg nil 'move)
+				    (cond
+				     ((match-end 1) ; begin
+				      (setq nest (1- nest)))
+				     ((match-end 2)                       ; end
+				      (setq nest (1+ nest)))
+				     ((match-end 3)
+				      (if (= 0 nest)
+					  (progn
+					    (goto-char (match-end 0))
+					    (setq there (point))
+					    (setq err nil)
+					    (setq str (verilog-get-expr))
+					    (setq str (concat " // else: !if" str ))
+					    (throw 'skip 1))
+					)))
+				    ))))
+
+			     (;- task/function/initial et cetera
+			      t
+			      (match-end 0)
+			      (goto-char (match-end 0))
+			      (setq there (point))
+			      (setq err nil)
+			      (setq str (verilog-get-expr))
+			      (setq str (concat " // " cntx str )))
+
+			     (;-- otherwise...
+			      (setq str " // auto-endcomment confused "))
+			     ))
+
+			   ((and
+			     (verilog-in-case-region-p) ;-- handle case item differently
+			     (progn
+			       (setq there (point))
+			       (goto-char here)
+			       (setq str (verilog-backward-case-item lim))))
+			    (setq err nil)
+			    (setq str (concat " // case: " str )))
+
+			   ((verilog-in-fork-region-p)
+			    (setq err nil)
+			    (setq str " // fork branch" ))
+
+			   ((looking-at "\\<end\\>")
+			    ;; HERE
+			    (forward-word 1)
+			    (verilog-forward-syntactic-ws)
+			    (setq err nil)
+			    (setq str (verilog-get-expr))
+			    (setq str (concat " // " cntx str )))
+
+			   ))))
+		      (goto-char here)
+		      (end-of-line)
+		      (if kill-existing-comment
+			  (kill-existing-comment))
+		      (delete-horizontal-space)
+		      (if (or err
+			      (> (count-lines here there) verilog-minimum-comment-distance))
+			  (insert str))
+		      (if err (ding 't))
+		      ))))
+	       (;- this is endclass, which can be nested
+		(match-end 11) ;; of verilog-end-block-ordered-re
+		;;(goto-char there)
+		(let ((nest 0)
+		      ( reg "\\<\\(class\\)\\|\\(endclass\\)\\|\\(package\\|primitive\\|\\(macro\\)?module\\)\\>")
+		      string
+		      )
+		  (save-excursion
+		    (catch 'skip
+		      (while (verilog-re-search-backward reg nil 'move)
+			(cond
+			 ((match-end 3)	; endclass
+			  (ding 't)
+			  (setq string "unmatched endclass")
+			  (throw 'skip 1))
+
+			 ((match-end 2)	; endclass
+			  (setq nest (1+ nest)))
+
+			 ((match-end 1) ; class
+			  (setq nest (1- nest))
+			  (if (< nest 0)
+			      (progn
+				(goto-char (match-end 0))
+				(let (b e)
+				  (setq b (progn
+					    (skip-chars-forward "^ \t")
+					    (verilog-forward-ws&directives)
+					    (point))
+					e (progn
+					    (skip-chars-forward "a-zA-Z0-9_")
+					    (point)))
+				  (setq string (buffer-substring b e)))
+				(throw 'skip 1))))
+			 ))))
+		  (end-of-line)
+		  (insert (concat " // " string )))
+		)
+
+	       (;- this is end{function,generate,task,module,primitive,table,generate}
+		;- which can not be nested.
+		t
+		(let (string reg (width nil))
+		  (end-of-line)
+		  (if kill-existing-comment
+		      (save-match-data
+		       (kill-existing-comment)))
+		  (delete-horizontal-space)
+		  (backward-sexp)
+		  (cond
+		   ((match-end 5) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
+		    (setq width "\\(\\s-*\\(\\[[^]]*\\]\\)\\|\\(real\\(time\\)?\\)\\|\\(integer\\)\\|\\(time\\)\\)?")
+		    )
+		   ((match-end 6) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)"))
+		   ((match-end 7) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>"))
+		   ((match-end 8) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<primitive\\>\\)\\|\\(\\<\\(endprimitive\\|package\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 9) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<interface\\>\\)\\|\\(\\<\\(endinterface\\|package\\|primitive\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 10) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<package\\>\\)\\|\\(\\<\\(endpackage\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 11) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<class\\>\\)\\|\\(\\<\\(endclass\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 12) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<\\(endcovergroup\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 13) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<program\\>\\)\\|\\(\\<\\(endprogram\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 14) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<\\(endsequence\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
+		   ((match-end 15) ;; of verilog-end-block-ordered-re
+		    (setq reg "\\(\\<clocking\\>\\)\\|\\<endclocking\\>"))
+
+		   (t (error "Problem in verilog-set-auto-endcomments"))
+		   )
+		  (let (b e)
+		    (save-excursion
+		      (verilog-re-search-backward reg nil 'move)
+		      (cond
+		       ((match-end 1)
+			(setq b (progn
+				  (skip-chars-forward "^ \t")
+				  (verilog-forward-ws&directives)
+				  (if (and width (looking-at width))
+				      (progn
+					(goto-char (match-end 0))
+					(verilog-forward-ws&directives)
+					))
+				  (point))
+			      e (progn
+				  (skip-chars-forward "a-zA-Z0-9_")
+				  (point)))
+			(setq string (buffer-substring b e)))
+		       (t
+			(ding 't)
+			(setq string "unmatched end(function|task|module|primitive|interface|package|class|clocking)")))))
+		  (end-of-line)
+		  (insert (concat " // " string )))
+		))))))))))
+
+(defun verilog-get-expr()
+  "Grab expression at point, e.g, case ( a | b & (c ^d))"
+  (let* ((b (progn
+	      (verilog-forward-syntactic-ws)
+	      (skip-chars-forward " \t")
+	      (point)))
+	 (e (let ((par 1))
+	      (cond
+	       ((looking-at "@")
+		(forward-char 1)
+		(verilog-forward-syntactic-ws)
+		(if (looking-at "(")
+		    (progn
+		      (forward-char 1)
+		      (while (and (/= par 0)
+				  (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
+			(cond
+			 ((match-end 1)
+			  (setq par (1+ par)))
+			 ((match-end 2)
+			  (setq par (1- par)))))))
+		(point))
+	       ((looking-at "(")
+		(forward-char 1)
+		(while (and (/= par 0)
+			    (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
+		  (cond
+		   ((match-end 1)
+		    (setq par (1+ par)))
+		   ((match-end 2)
+		    (setq par (1- par)))))
+		(point))
+	       ((looking-at "\\[")
+		(forward-char 1)
+		(while (and (/= par 0)
+			    (verilog-re-search-forward "\\(\\[\\)\\|\\(\\]\\)" nil 'move))
+		  (cond
+		   ((match-end 1)
+		    (setq par (1+ par)))
+		   ((match-end 2)
+		    (setq par (1- par)))))
+		(verilog-forward-syntactic-ws)
+		(skip-chars-forward "^ \t\n\f")
+		(point))
+	       ((looking-at "/[/\\*]")
+		b)
+	       ('t
+		(skip-chars-forward "^: \t\n\f")
+		(point)
+		))))
+	 (str (buffer-substring b e)))
+    (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
+	(setq str (concat (substring str 0 e) "...")))
+    str))
+
+(defun verilog-expand-vector ()
+  "Take a signal vector on the current line and expand it to multiple lines.
+Useful for creating tri's and other expanded fields."
+  (interactive)
+  (verilog-expand-vector-internal "[" "]"))
+
+(defun verilog-expand-vector-internal (bra ket)
+  "Given BRA, the start brace and KET, the end brace, expand one line into many lines."
+  (save-excursion
+    (forward-line 0)
+    (let ((signal-string (buffer-substring (point)
+					   (progn
+					     (end-of-line) (point)))))
+      (if (string-match (concat "\\(.*\\)"
+				(regexp-quote bra)
+				"\\([0-9]*\\)\\(:[0-9]*\\|\\)\\(::[0-9---]*\\|\\)"
+				(regexp-quote ket)
+				"\\(.*\\)$") signal-string)
+	  (let* ((sig-head (match-string 1 signal-string))
+		 (vec-start (string-to-int (match-string 2 signal-string)))
+		 (vec-end (if (= (match-beginning 3) (match-end 3))
+			      vec-start
+			    (string-to-int (substring signal-string (1+ (match-beginning 3)) (match-end 3)))))
+		 (vec-range (if (= (match-beginning 4) (match-end 4))
+				1
+			      (string-to-int (substring signal-string (+ 2 (match-beginning 4)) (match-end 4)))))
+		 (sig-tail (match-string 5 signal-string))
+		 vec)
+	    ;; Decode vectors
+	    (setq vec nil)
+	    (if (< vec-range 0)
+		(let ((tmp vec-start))
+		  (setq vec-start vec-end
+			vec-end tmp
+			vec-range (- vec-range))))
+	    (if (< vec-end vec-start)
+		(while (<= vec-end vec-start)
+		  (setq vec (append vec (list vec-start)))
+		  (setq vec-start (- vec-start vec-range)))
+	      (while (<= vec-start vec-end)
+		(setq vec (append vec (list vec-start)))
+		(setq vec-start (+ vec-start vec-range))))
+	    ;;
+	    ;; Delete current line
+	    (delete-region (point) (progn (forward-line 0) (point)))
+	    ;;
+	    ;; Expand vector
+	    (while vec
+	      (insert (concat sig-head bra (int-to-string (car vec)) ket sig-tail "\n"))
+	      (setq vec (cdr vec)))
+	    (delete-char -1)
+	    ;;
+	    )))))
+
+(defun verilog-strip-comments ()
+  "Strip all comments from the verilog code."
+  (interactive)
+  (goto-char (point-min))
+  (while (re-search-forward "//" nil t)
+    (if (verilog-within-string)
+	(re-search-forward "\"" nil t)
+      (if (verilog-in-star-comment-p)
+	  (re-search-forward "\*/" nil t)
+	(let ((bpt (- (point) 2)))
+	  (end-of-line)
+	  (delete-region bpt (point))))))
+    ;;
+  (goto-char (point-min))
+  (while (re-search-forward "/\\*" nil t)
+    (if (verilog-within-string)
+	(re-search-forward "\"" nil t)
+      (let ((bpt (- (point) 2)))
+	(re-search-forward "\\*/")
+	(delete-region bpt (point))))))
+
+(defun verilog-one-line ()
+  "Convert structural verilog instances to occupy one line."
+  (interactive)
+  (goto-char (point-min))
+  (while (re-search-forward "\\([^;]\\)[ \t]*\n[ \t]*" nil t)
+	(replace-match "\\1 " nil nil)))
+
+(defun verilog-linter-name ()
+  "Return name of linter, either surelint or verilint."
+  (let ((compile-word1 (verilog-string-replace-matches "\\s .*$" "" nil nil
+						       compile-command))
+	(lint-word1    (verilog-string-replace-matches "\\s .*$" "" nil nil
+						       verilog-linter)))
+    (cond ((equal compile-word1 "surelint") `surelint)
+	  ((equal compile-word1 "verilint") `verilint)
+	  ((equal lint-word1 "surelint")    `surelint)
+	  ((equal lint-word1 "verilint")    `verilint)
+	  (t `surelint))))  ;; back compatibility
+
+(defun verilog-lint-off ()
+  "Convert a Verilog linter warning line into a disable statement.
+For example:
+	pci_bfm_null.v, line  46: Unused input: pci_rst_
+becomes a comment for the appropriate tool.
+
+The first word of the `compile-command' or `verilog-linter'
+variables are used to determine which product is being used.
+
+See \\[verilog-surelint-off] and \\[verilog-verilint-off]."
+  (interactive)
+  (let ((linter (verilog-linter-name)))
+    (cond ((equal linter `surelint)
+	   (verilog-surelint-off))
+	  ((equal linter `verilint)
+	   (verilog-verilint-off))
+	  (t (error "Linter name not set")))))
+
+(defun verilog-surelint-off ()
+  "Convert a SureLint warning line into a disable statement.
+Run from Verilog source window; assumes there is a *compile* buffer
+with point set appropriately.
+
+For example:
+	WARNING [STD-UDDONX]: xx.v, line 8: output out is never assigned.
+becomes:
+	// surefire lint_line_off UDDONX"
+  (interactive)
+  (save-excursion
+    (switch-to-buffer compilation-last-buffer)
+    (beginning-of-line)
+    (when
+	(looking-at "\\(INFO\\|WARNING\\|ERROR\\) \\[[^-]+-\\([^]]+\\)\\]: \\([^,]+\\), line \\([0-9]+\\): \\(.*\\)$")
+      (let* ((code (match-string 2))
+	     (file (match-string 3))
+	     (line (match-string 4))
+	     (buffer (get-file-buffer file))
+	     dir filename)
+	(unless buffer
+	  (progn
+	    (setq buffer
+		  (and (file-exists-p file)
+		       (find-file-noselect file)))
+	    (or buffer
+		(let* ((pop-up-windows t))
+		  (let ((name (expand-file-name
+			       (read-file-name
+				(format "Find this error in: (default %s) "
+					file)
+				dir file t))))
+		    (if (file-directory-p name)
+			(setq name (expand-file-name filename name)))
+		    (setq buffer
+			  (and (file-exists-p name)
+			       (find-file-noselect name))))))))
+	(switch-to-buffer buffer)
+	(goto-line (string-to-number line))
+	(end-of-line)
+	(catch 'already
+	  (cond
+	   ((verilog-in-slash-comment-p)
+	    (re-search-backward "//")
+	    (cond
+	     ((looking-at "// surefire lint_off_line ")
+	      (goto-char (match-end 0))
+	      (let ((lim (save-excursion (end-of-line) (point))))
+		(if (re-search-forward code lim 'move)
+		    (throw 'already t)
+		  (insert-string (concat " " code)))))
+	     (t
+	      )))
+	   ((verilog-in-star-comment-p)
+	    (re-search-backward "/\*")
+	    (insert-string (format " // surefire lint_off_line %6s" code ))
+	    )
+	   (t
+	    (insert-string (format " // surefire lint_off_line %6s" code ))
+	    )))))))
+
+(defun verilog-verilint-off ()
+  "Convert a Verilint warning line into a disable statement.
+
+For example:
+	(W240)  pci_bfm_null.v, line  46: Unused input: pci_rst_
+becomes:
+	//Verilint 240 off // WARNING: Unused input"
+  (interactive)
+  (save-excursion
+    (beginning-of-line)
+    (when (looking-at "\\(.*\\)([WE]\\([0-9A-Z]+\\)).*,\\s +line\\s +[0-9]+:\\s +\\([^:\n]+\\):?.*$")
+      (replace-match (format
+		      ;; %3s makes numbers 1-999 line up nicely
+		      "\\1//Verilint %3s off // WARNING: \\3"
+		      (match-string 2)))
+      (beginning-of-line)
+      (verilog-indent-line))))
+
+(defun verilog-auto-save-compile ()
+  "Update automatics with \\[verilog-auto], save the buffer, and compile."
+  (interactive)
+  (verilog-auto)	; Always do it for safety
+  (save-buffer)
+  (compile compile-command))
+
+
+
+;;
+;; Batch
+;;
+
+(defmacro verilog-batch-error-wrapper (&rest body)
+  "Execute BODY and add error prefix to any errors found.
+This lets programs calling batch mode to easily extract error messages."
+  (` (condition-case err
+	 (progn (,@ body))
+       (error
+	(error "%%Error: %s%s" (error-message-string err)
+	       (if (featurep 'xemacs) "\n" ""))))))  ;; xemacs forgets to add a newline
+
+(defun verilog-batch-execute-func (funref)
+  "Internal processing of a batch command, running FUNREF on all command arguments."
+  (verilog-batch-error-wrapper
+   ;; General globals needed
+   (setq make-backup-files nil)
+   (setq-default make-backup-files nil)
+   (setq enable-local-variables t)
+   (setq enable-local-eval t)
+   ;; Make sure any sub-files we read get proper mode
+   (setq default-major-mode `verilog-mode)
+   ;; Ditto files already read in
+   (mapcar '(lambda (buf)
+	      (when (buffer-file-name buf)
+		(save-excursion
+		  (set-buffer buf)
+		  (verilog-mode))))
+	   (buffer-list))
+   ;; Process the files
+   (mapcar '(lambda (buf)
+	      (when (buffer-file-name buf)
+		(save-excursion
+		  (if (not (file-exists-p (buffer-file-name buf)))
+		      (error (concat "File not found: " (buffer-file-name buf))))
+		  (message (concat "Processing " (buffer-file-name buf)))
+		  (set-buffer buf)
+		  (funcall funref)
+		  (save-buffer))))
+	   (buffer-list))))
+
+(defun verilog-batch-auto ()
+  "For use with --batch, perform automatic expansions as a stand-alone tool.
+This sets up the appropriate Verilog-Mode environment, updates automatics
+with \\[verilog-auto] on all command-line files, and saves the buffers.
+For proper results, multiple filenames need to be passed on the command
+line in bottom-up order."
+  (unless noninteractive
+    (error "Use verilog-batch-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
+  (verilog-batch-execute-func `verilog-auto))
+
+(defun verilog-batch-delete-auto ()
+  "For use with --batch, perform automatic deletion as a stand-alone tool.
+This sets up the appropriate Verilog-Mode environment, deletes automatics
+with \\[verilog-delete-auto] on all command-line files, and saves the buffers."
+  (unless noninteractive
+    (error "Use verilog-batch-delete-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
+  (verilog-batch-execute-func `verilog-delete-auto))
+
+(defun verilog-batch-inject-auto ()
+  "For use with --batch, perform automatic injection as a stand-alone tool.
+This sets up the appropriate Verilog-Mode environment, injects new automatics
+with \\[verilog-inject-auto] on all command-line files, and saves the buffers.
+For proper results, multiple filenames need to be passed on the command
+line in bottom-up order."
+  (unless noninteractive
+    (error "Use verilog-batch-inject-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
+  (verilog-batch-execute-func `verilog-inject-auto))
+
+(defun verilog-batch-indent ()
+  "For use with --batch, reindent an a entire file as a stand-alone tool.
+This sets up the appropriate Verilog-Mode environment, calls
+\\[verilog-indent-buffer] on all command-line files, and saves the buffers."
+  (unless noninteractive
+    (error "Use verilog-batch-indent only with --batch"))  ;; Otherwise we'd mess up buffer modes
+  (verilog-batch-execute-func `verilog-indent-buffer))
+
+
+;;
+;; Indentation
+;;
+(defconst verilog-indent-alist
+  '((block       . (+ ind verilog-indent-level))
+    (case        . (+ ind verilog-case-indent))
+    (cparenexp   . (+ ind verilog-indent-level))
+    (cexp        . (+ ind verilog-cexp-indent))
+    (defun       . verilog-indent-level-module)
+    (declaration . verilog-indent-level-declaration)
+    (directive   . (verilog-calculate-indent-directive))
+    (tf          . verilog-indent-level)
+    (behavioral  . (+ verilog-indent-level-behavioral verilog-indent-level-module))
+    (statement   . ind)
+    (cpp         . 0)
+    (comment     . (verilog-comment-indent))
+    (unknown     . 3)
+    (string      . 0)))
+
+(defun verilog-continued-line-1 (lim)
+  "Return true if this is a continued line.
+Set point to where line starts.  Limit search to point LIM."
+  (let ((continued 't))
+    (if (eq 0 (forward-line -1))
+	(progn
+	  (end-of-line)
+	  (verilog-backward-ws&directives lim)
+	  (if (bobp)
+	      (setq continued nil)
+	    (setq continued (verilog-backward-token))))
+      (setq continued nil))
+    continued))
+
+(defun verilog-calculate-indent ()
+  "Calculate the indent of the current Verilog line.
+Examine previous lines.  Once a line is found that is definitive as to the
+type of the current line, return that lines' indent level and its
+type.  Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
+  (save-excursion
+    (let* ((starting_position (point))
+	   (par 0)
+	   (begin (looking-at "[ \t]*begin\\>"))
+	   (lim (save-excursion (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)" nil t)))
+	   (type (catch 'nesting
+		   ;; Keep working backwards until we can figure out
+		   ;; what type of statement this is.
+		   ;; Basically we need to figure out
+		   ;; 1) if this is a continuation of the previous line;
+		   ;; 2) are we in a block scope (begin..end)
+
+		   ;; if we are in a comment, done.
+		   (if (verilog-in-star-comment-p)
+		       (throw 'nesting 'comment))
+
+		   ;; if we have a directive, done.
+		   (if (save-excursion (beginning-of-line) (looking-at verilog-directive-re-1))
+		       (throw 'nesting 'directive))
+
+		   ;; unless we are in the newfangled coverpoint or constraint blocks
+		   ;; if we are in a parenthesized list, and the user likes to indent these, return.
+		   (if (and
+			verilog-indent-lists
+			(not (verilog-in-coverage))
+			(verilog-in-paren))
+		       (progn (setq par 1)
+			      (throw 'nesting 'block))
+		     )
+
+		   ;; See if we are continuing a previous line
+		   (while t
+		     ;; trap out if we crawl off the top of the buffer
+		     (if (bobp) (throw 'nesting 'cpp))
+
+		     (if (verilog-continued-line-1 lim)
+			 (let ((sp (point)))
+			   (if (and
+				(not (looking-at verilog-complete-reg))
+				(verilog-continued-line-1 lim))
+			       (progn (goto-char sp)
+				      (throw 'nesting 'cexp))
+
+			     (goto-char sp))
+
+			   (if (and begin
+				    (not verilog-indent-begin-after-if)
+				    (looking-at verilog-no-indent-begin-re))
+			       (progn
+				 (beginning-of-line)
+				 (skip-chars-forward " \t")
+				 (throw 'nesting 'statement))
+			     (progn
+			       (throw 'nesting 'cexp))))
+		       ;; not a continued line
+		       (goto-char starting_position))
+
+		     (if (looking-at "\\<else\\>")
+			 ;; search back for governing if, striding across begin..end pairs
+			 ;; appropriately
+			 (let ((elsec 1))
+			   (while (verilog-re-search-backward verilog-ends-re nil 'move)
+			     (cond
+			      ((match-end 1) ; else, we're in deep
+			       (setq elsec (1+ elsec)))
+			      ((match-end 2) ; if
+			       (setq elsec (1- elsec))
+			       (if (= 0 elsec)
+				   (if verilog-align-ifelse
+				       (throw 'nesting 'statement)
+				     (progn ;; back up to first word on this line
+				       (beginning-of-line)
+				       (verilog-forward-syntactic-ws)
+				       (throw 'nesting 'statement)))))
+			      (t ; endblock
+				; try to leap back to matching outward block by striding across
+				; indent level changing tokens then immediately
+				; previous line governs indentation.
+			       (let (( reg) (nest 1))
+;;	 verilog-ends =>  else|if|end|join(_any|_none|)|endcase|endclass|endtable|endspecify|endfunction|endtask|endgenerate|endgroup
+				 (cond
+				  ((match-end 3) ; end
+				   ;; Search back for matching begin
+				   (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
+				  ((match-end 4) ; endcase
+				   ;; Search back for matching case
+				   (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
+				  ((match-end 5) ; endfunction
+				   ;; Search back for matching function
+				   (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
+				  ((match-end 6) ; endtask
+				   ;; Search back for matching task
+				   (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
+				  ((match-end 7) ; endspecify
+				   ;; Search back for matching specify
+				   (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
+				  ((match-end 8) ; endtable
+				   ;; Search back for matching table
+				   (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
+				  ((match-end 9) ; endgenerate
+				   ;; Search back for matching generate
+				   (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
+				  ((match-end 10) ; joins
+				   ;; Search back for matching fork
+				   (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|none\\)?\\>\\)" ))
+				  ((match-end 11) ; class
+				   ;; Search back for matching class
+				   (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
+				  ((match-end 12) ; covergroup
+				   ;; Search back for matching covergroup
+				   (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
+				  )
+				 (catch 'skip
+				   (while (verilog-re-search-backward reg nil 'move)
+				     (cond
+				      ((match-end 1) ; begin
+				       (setq nest (1- nest))
+				       (if (= 0 nest)
+					   (throw 'skip 1)))
+				      ((match-end 2) ; end
+				       (setq nest (1+ nest)))))
+				   )
+				 ))
+			      ))))
+		     (throw 'nesting (verilog-calc-1))
+		     )
+		   );; catch nesting
+		 );; type
+	   )
+      ;; Return type of block and indent level.
+      (if (not type)
+	  (setq type 'cpp))
+      (if (> par 0)			; Unclosed Parenthesis
+	  (list 'cparenexp par)
+	(cond
+	  ((eq type 'case)
+	   (list type (verilog-case-indent-level)))
+	  ((eq type 'statement)
+	   (list type (current-column)))
+	  ((eq type 'defun)
+	   (list type 0))
+	  (t
+	   (list type (verilog-current-indent-level)))))
+      )))
+(defun verilog-wai ()
+  "Show matching nesting block for debugging."
+  (interactive)
+  (save-excursion
+    (let ((nesting (verilog-calc-1)))
+      (message "You are at nesting %s" nesting))))
+
+(defun verilog-calc-1 ()
+  (catch 'nesting
+    (while (verilog-re-search-backward (concat "\\({\\|}\\|" verilog-indent-re "\\)") nil 'move)
+      (cond
+       ((equal (char-after) ?\{)
+	(if (verilog-at-constraint-p)
+	    (throw 'nesting 'block)
+	  ))
+       ((equal (char-after) ?\})
+
+	(let ((there (verilog-at-close-constraint-p)))
+	  (if there (goto-char there))))
+
+       ((looking-at verilog-beg-block-re-ordered)
+	(cond
+	 ((match-end 2)  ; *sigh* could be "unique case" or "priority casex"
+	  (let ((here (point)))
+	    (verilog-beg-of-statement)
+	    (if (looking-at verilog-extended-case-re)
+		(throw 'nesting 'case)
+	      (goto-char here)))
+	  (throw 'nesting 'case))
+
+	 ;; need to consider typedef struct here...
+	 ((looking-at "\\<class\\|struct\\|function\\|task\\|property\\>")
+					; *sigh* These words have an optional prefix:
+					; extern {virtual|protected}? function a();
+					; assert property (p_1);
+	                                ; typedef class foo;
+					; and we don't want to confuse this with
+					; function a();
+	                                ; property
+					; ...
+					; endfunction
+	  (let ((here (point)))
+	    (save-excursion
+	      (verilog-beg-of-statement)
+	      (if (= (point) here)
+		  (throw 'nesting 'block))
+	      )))
+	 (t              (throw 'nesting 'block))))
+
+       ((looking-at verilog-end-block-re)
+	(verilog-leap-to-head)
+	(if (verilog-in-case-region-p)
+	    (progn
+	      (verilog-leap-to-case-head)
+	      (if (looking-at verilog-case-re)
+		  (throw 'nesting 'case)))))
+
+       ((looking-at (if (verilog-in-generate-region-p)
+			verilog-defun-level-not-generate-re
+		      verilog-defun-level-re))
+	(throw 'nesting 'defun))
+
+       ((looking-at verilog-cpp-level-re)
+	(throw 'nesting 'cpp))
+
+       ((bobp)
+	(throw 'nesting 'cpp))
+       ))
+    (throw 'nesting 'cpp)
+    )
+  )
+
+(defun verilog-calculate-indent-directive ()
+  "Return indentation level for directive.
+For speed, the searcher looks at the last directive, not the indent
+of the appropriate enclosing block."
+  (let ((base -1)	;; Indent of the line that determines our indentation
+	(ind 0)	        ;; Relative offset caused by other directives (like `endif on same line as `else)
+	)
+    ;; Start at current location, scan back for another directive
+
+    (save-excursion
+      (beginning-of-line)
+      (while (and (< base 0)
+		  (verilog-re-search-backward verilog-directive-re nil t))
+	(cond ((save-excursion (skip-chars-backward " \t") (bolp))
+	       (setq base (current-indentation))
+	       ))
+	(cond ((and (looking-at verilog-directive-end) (< base 0))  ;; Only matters when not at BOL
+	       (setq ind (- ind verilog-indent-level-directive)))
+	      ((and (looking-at verilog-directive-middle) (>= base 0))  ;; Only matters when at BOL
+	       (setq ind (+ ind verilog-indent-level-directive)))
+	      ((looking-at verilog-directive-begin)
+	       (setq ind (+ ind verilog-indent-level-directive)))))
+      ;; Adjust indent to starting indent of critical line
+      (setq ind (max 0 (+ ind base))))
+
+    (save-excursion
+      (beginning-of-line)
+      (skip-chars-forward " \t")
+      (cond ((or (looking-at verilog-directive-middle)
+		 (looking-at verilog-directive-end))
+	     (setq ind (max 0 (- ind verilog-indent-level-directive))))))
+   ind))
+
+(defun verilog-leap-to-case-head ()
+  (let ((nest 1))
+    (while (/= 0 nest)
+      (verilog-re-search-backward "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" nil 'move)
+      (cond
+       ((match-end 1)
+	(setq nest (1- nest)))
+       ((match-end 2)
+	(setq nest (1+ nest)))
+       ((bobp)
+	(ding 't)
+	(setq nest 0))))))
+
+(defun verilog-leap-to-head ()
+  "Move point to the head of this block; jump from end to matching begin,
+from endcase to matching case, and so on."
+  (let ((reg nil)
+	snest
+	(nest 1))
+    (cond
+     ((looking-at "\\<end\\>")
+      ;; 1: Search back for matching begin
+      (setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|"
+			"\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))
+     ((looking-at "\\<endcase\\>")
+      ;; 2: Search back for matching case
+      (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>\\)\\|\\(\\<endcase\\>\\)" ))
+     ((looking-at "\\<join\\(_any\\|_none\\)?\\>")
+      ;; 3: Search back for matching fork
+      (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
+     ((looking-at "\\<endclass\\>")
+      ;; 4: Search back for matching class
+      (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
+     ((looking-at "\\<endtable\\>")
+      ;; 5: Search back for matching table
+      (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
+     ((looking-at "\\<endspecify\\>")
+      ;; 6: Search back for matching specify
+      (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
+     ((looking-at "\\<endfunction\\>")
+      ;; 7: Search back for matching function
+      (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
+     ((looking-at "\\<endgenerate\\>")
+      ;; 8: Search back for matching generate
+      (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
+     ((looking-at "\\<endtask\\>")
+      ;; 9: Search back for matching task
+      (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
+     ((looking-at "\\<endgroup\\>")
+      ;; 10: Search back for matching covergroup
+      (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
+     ((looking-at "\\<endproperty\\>")
+      ;; 11: Search back for matching property
+      (setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
+     ((looking-at "\\<endinterface\\>")
+      ;; 12: Search back for matching interface
+      (setq reg "\\(\\<interface\\>\\)\\|\\(\\<endinterface\\>\\)" ))
+     ((looking-at "\\<endsequence\\>")
+      ;; 12: Search back for matching sequence
+      (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" ))
+     ((looking-at "\\<endclocking\\>")
+      ;; 12: Search back for matching clocking
+      (setq reg "\\(\\<clocking\\)\\|\\(\\<endclocking\\>\\)" ))
+     )
+    (if reg
+	(catch 'skip
+	  (let (sreg)
+	    (while (verilog-re-search-backward reg nil 'move)
+	      (cond
+	       ((match-end 1) ; begin
+		(setq nest (1- nest))
+		(if (= 0 nest)
+		    ;; Now previous line describes syntax
+		    (throw 'skip 1))
+		(if (and snest
+			 (= snest nest))
+		    (setq reg sreg)))
+	       ((match-end 2) ; end
+		(setq nest (1+ nest)))
+	       ((match-end 3)
+		;; endcase, jump to case
+		(setq snest nest)
+		(setq nest (1+ nest))
+		(setq sreg reg)
+		(setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
+	       ((match-end 4)
+		;; join, jump to fork
+		(setq snest nest)
+		(setq nest (1+ nest))
+		(setq sreg reg)
+		(setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
+	       )))))))
+
+(defun verilog-continued-line ()
+  "Return true if this is a continued line.
+Set point to where line starts"
+  (let ((continued 't))
+    (if (eq 0 (forward-line -1))
+	(progn
+	  (end-of-line)
+	  (verilog-backward-ws&directives)
+	  (if (bobp)
+	      (setq continued nil)
+	    (while (and continued
+			(save-excursion
+			  (skip-chars-backward " \t")
+			  (not (bolp))))
+	    (setq continued (verilog-backward-token))
+	    ) ;; while
+	    ))
+      (setq continued nil))
+    continued))
+
+(defun verilog-backward-token ()
+  "Step backward token, returning true if we are now at an end of line token."
+  (interactive)
+  (verilog-backward-syntactic-ws)
+  (cond
+   ((bolp)
+    nil)
+   (;-- Anything ending in a ; is complete
+    (= (preceding-char) ?\;)
+    nil)
+   (; If a "}" is prefixed by a ";", then this is a complete statement
+    ; i.e.: constraint foo { a = b; }
+    (= (preceding-char) ?\})
+    (progn
+      (backward-char)
+      (verilog-at-close-constraint-p))
+    )
+   (;-- constraint foo { a = b }
+    ;   is a complete statement. *sigh*
+    (= (preceding-char) ?\{)
+    (progn
+      (backward-char)
+      (not (verilog-at-constraint-p)))
+    )
+   (;-- Could be 'case (foo)' or 'always @(bar)' which is complete
+    ;   also could be simply '@(foo)'
+    ;   or foo u1 #(a=8)
+    ;            (b, ... which ISN'T complete
+    ;;;; Do we need this???
+    (= (preceding-char) ?\))
+    (progn
+      (backward-char)
+      (backward-up-list 1)
+      (verilog-backward-syntactic-ws)
+      (let ((back (point)))
+	(forward-word -1)
+	(cond
+	 ((looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|case\\(\\|[xz]\\)\\|for\\(\\|each\\|ever\\)\\|i\\(f\\|nitial\\)\\|repeat\\|while\\)\\>")
+	  (not (looking-at "\\<randcase\\>\\|\\<case[xz]?\\>[^:]")))
+	 (t
+	  (goto-char back)
+	  (cond
+	   ((= (preceding-char) ?\@)
+	    (backward-char)
+	    (save-excursion
+	      (verilog-backward-token)
+	      (not (looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|initial\\|while\\)\\>"))))
+	   ((= (preceding-char) ?\#)
+	    (backward-char)
+	    )
+	   (t t))
+	  )))))
+
+   (;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete
+    t
+    (forward-word -1)
+    (cond
+     ((looking-at "\\<else\\>")
+      t)
+     ((looking-at verilog-indent-re)
+      nil)
+     (t
+      (let
+	  ((back (point)))
+	(verilog-backward-syntactic-ws)
+	(cond
+	 ((= (preceding-char) ?\:)
+	  (backward-char)
+	  (verilog-backward-syntactic-ws)
+	  (backward-sexp)
+	  (if (looking-at verilog-nameable-item-re )
+	      nil
+	    t)
+	  )
+	 ((= (preceding-char) ?\#)
+	  (backward-char)
+	  t)
+	 ((= (preceding-char) ?\`)
+	  (backward-char)
+	  t)
+
+	 (t
+	  (goto-char back)
+	  t)
+	 )))))))
+
+(defun verilog-backward-syntactic-ws (&optional bound)
+  "Backward skip over syntactic whitespace for Emacs 19.
+Optional BOUND limits search."
+  (save-restriction
+    (let* ((bound (or bound (point-min))) (here bound) )
+      (if (< bound (point))
+	  (progn
+	    (narrow-to-region bound (point))
+	    (while (/= here (point))
+	      (setq here (point))
+	      (verilog-skip-backward-comments)
+	      )))
+      ))
+  t)
+
+(defun verilog-forward-syntactic-ws (&optional bound)
+  "Forward skip over syntactic whitespace for Emacs 19.
+Optional BOUND limits search."
+  (save-restriction
+    (let* ((bound (or bound (point-max)))
+	   (here bound)
+	   )
+      (if (> bound (point))
+	  (progn
+	    (narrow-to-region (point) bound)
+	    (while (/= here (point))
+	      (setq here (point))
+	      (forward-comment (buffer-size))
+	      )))
+      )))
+
+(defun verilog-backward-ws&directives (&optional bound)
+  "Backward skip over syntactic whitespace and compiler directives for Emacs 19.
+Optional BOUND limits search."
+  (save-restriction
+    (let* ((bound (or bound (point-min)))
+	   (here bound)
+	   (p nil) )
+      (if (< bound (point))
+	  (progn
+	    (let ((state
+		   (save-excursion
+		     (parse-partial-sexp (point-min) (point)))))
+	      (cond
+	       ((nth 7 state) ;; in // comment
+		(verilog-re-search-backward "//" nil 'move)
+                (skip-chars-backward "/"))
+	       ((nth 4 state) ;; in /* */ comment
+		(verilog-re-search-backward "/\*" nil 'move))))
+	    (narrow-to-region bound (point))
+	    (while (/= here (point))
+	      (setq here (point))
+	      (verilog-skip-backward-comments)
+	      (setq p
+		    (save-excursion
+		      (beginning-of-line)
+		      (cond
+		       ((verilog-within-translate-off)
+			(verilog-back-to-start-translate-off (point-min)))
+		       ((looking-at verilog-directive-re-1)
+			(point))
+		       (t
+			nil))))
+	      (if p (goto-char p))
+	      )))
+      )))
+
+(defun verilog-forward-ws&directives (&optional bound)
+  "Forward skip over syntactic whitespace and compiler directives for Emacs 19.
+Optional BOUND limits search."
+  (save-restriction
+    (let* ((bound (or bound (point-max)))
+	   (here bound)
+	   jump
+	   )
+      (if (> bound (point))
+	  (progn
+	    (let ((state
+		   (save-excursion
+		     (parse-partial-sexp (point-min) (point)))))
+	      (cond
+	       ((nth 7 state) ;; in // comment
+		(verilog-re-search-forward "//" nil 'move))
+	       ((nth 4 state) ;; in /* */ comment
+		(verilog-re-search-forward "/\*" nil 'move))))
+	    (narrow-to-region (point) bound)
+	    (while (/= here (point))
+	      (setq here (point)
+		    jump nil)
+	      (forward-comment (buffer-size))
+	      (save-excursion
+		(beginning-of-line)
+		(if (looking-at verilog-directive-re-1)
+		    (setq jump t)))
+	      (if jump
+		  (beginning-of-line 2))
+	      )))
+      )))
+
+(defun verilog-in-comment-p ()
+ "Return true if in a star or // comment."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (or (nth 4 state) (nth 7 state))))
+
+(defun verilog-in-star-comment-p ()
+ "Return true if in a star comment."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (and
+    (nth 4 state)			; t if in a comment of style a // or b /**/
+	(not
+	 (nth 7 state)			; t if in a comment of style b /**/
+	 ))))
+
+(defun verilog-in-slash-comment-p ()
+ "Return true if in a slash comment."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (nth 7 state)))
+
+(defun verilog-in-comment-or-string-p ()
+ "Return true if in a string or comment."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (or (nth 3 state) (nth 4 state) (nth 7 state)))) ; Inside string or comment)
+
+(defun verilog-in-escaped-name-p ()
+ "Return true if in an escaped name."
+ (save-excursion
+   (backward-char)
+   (skip-chars-backward "^ \t\n\f")
+   (if (equal (char-after (point) ) ?\\ )
+       t
+     nil)))
+
+(defun verilog-in-paren ()
+ "Return true if in a parenthetical expression."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (> (nth 0 state) 0 )))
+
+(defun verilog-in-coverage ()
+ "Return true if in a constraint or coverpoint expression."
+ (interactive)
+ (save-excursion
+   (if (verilog-in-paren)
+       (progn
+	 (backward-up-list 1)
+	 (verilog-at-constraint-p)
+	 )
+     nil)))
+(defun verilog-at-close-constraint-p ()
+  "If at the } that closes a constraint or covergroup, return true."
+  (if (and
+       (equal (char-after) ?\})
+       (verilog-in-paren))
+
+      (save-excursion
+	(verilog-backward-ws&directives)
+	(if (equal (char-before) ?\;)
+	    (point)
+	  nil))))
+
+(defun verilog-at-constraint-p ()
+  "If at the { of a constraint or coverpoint definition, return true, moving point to constraint."
+  (if (save-excursion
+	(and
+	 (equal (char-after) ?\{)
+	 (forward-list)
+	 (progn (backward-char 1)
+		(verilog-backward-ws&directives)
+		(equal (char-before) ?\;))
+	 ))
+      ;; maybe
+      (verilog-re-search-backward "\\<constraint\\|coverpoint\\|cross\\>" nil 'move)
+    ;; not
+    nil
+    )
+  )
+
+(defun verilog-parenthesis-depth ()
+ "Return non zero if in parenthetical-expression."
+ (save-excursion
+   (nth 1 (parse-partial-sexp (point-min) (point)))))
+
+
+(defun verilog-skip-forward-comment-or-string ()
+ "Return true if in a string or comment."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (cond
+    ((nth 3 state)			;Inside string
+     (goto-char (nth 3 state))
+     t)
+    ((nth 7 state)			;Inside // comment
+     (forward-line 1)
+     t)
+    ((nth 4 state)			;Inside any comment (hence /**/)
+     (search-forward "*/"))
+    (t
+     nil))))
+
+(defun verilog-skip-backward-comment-or-string ()
+ "Return true if in a string or comment."
+ (let ((state
+	(save-excursion
+	  (parse-partial-sexp (point-min) (point)))))
+   (cond
+    ((nth 3 state)			;Inside string
+     (search-backward "\"")
+     t)
+    ((nth 7 state)			;Inside // comment
+     (search-backward "//")
+     (skip-chars-backward "/")
+     t)
+    ((nth 4 state)			;Inside /* */ comment
+     (search-backward "/*")
+     t)
+    (t
+     nil))))
+
+(defun verilog-skip-backward-comments ()
+ "Return true if a comment was skipped."
+ (let ((more t))
+   (while more
+     (setq more
+	   (let ((state
+		  (save-excursion
+		    (parse-partial-sexp (point-min) (point)))))
+	     (cond
+	      ((nth 7 state)			;Inside // comment
+	       (search-backward "//")
+	       (skip-chars-backward "/")
+	       (skip-chars-backward " \t\n\f")
+	       t)
+	      ((nth 4 state)			;Inside /* */ comment
+	       (search-backward "/*")
+	       (skip-chars-backward " \t\n\f")
+	       t)
+	      ((and (not (bobp))
+		    (= (char-before) ?\/)
+		    (= (char-before (1- (point))) ?\*)
+		    )
+	       (goto-char (- (point) 2))
+	       t)
+	      (t
+	       (skip-chars-backward " \t\n\f")
+	       nil)))))))
+
+(defun verilog-skip-forward-comment-p ()
+  "If in comment, move to end and return true."
+  (let (state)
+    (progn
+      (setq state
+	    (save-excursion
+	      (parse-partial-sexp (point-min) (point))))
+      (cond
+       ((nth 3 state)
+	t)
+       ((nth 7 state)			;Inside // comment
+	(end-of-line)
+	(forward-char 1)
+	t)
+       ((nth 4 state)			;Inside any comment
+	t)
+       (t
+	nil)))))
+
+(defun verilog-indent-line-relative ()
+  "Cheap version of indent line.
+Only look at a few lines to determine indent level."
+  (interactive)
+  (let ((indent-str)
+	(sp (point)))
+    (if (looking-at "^[ \t]*$")
+	(cond  ;- A blank line; No need to be too smart.
+	 ((bobp)
+	  (setq indent-str (list 'cpp 0)))
+	 ((verilog-continued-line)
+	  (let ((sp1 (point)))
+	    (if (verilog-continued-line)
+		(progn (goto-char sp)
+		       (setq indent-str (list 'statement (verilog-current-indent-level))))
+	      (goto-char sp1)
+	      (setq indent-str (list 'block (verilog-current-indent-level)))))
+	  (goto-char sp))
+	 ((goto-char sp)
+	  (setq indent-str (verilog-calculate-indent))))
+      (progn (skip-chars-forward " \t")
+	     (setq indent-str (verilog-calculate-indent))))
+    (verilog-do-indent indent-str)))
+
+(defun verilog-indent-line ()
+  "Indent for special part of code."
+  (verilog-do-indent (verilog-calculate-indent)))
+
+(defun verilog-do-indent (indent-str)
+  (let ((type (car indent-str))
+	(ind (car (cdr indent-str))))
+    (cond
+     (; handle continued exp
+      (eq type 'cexp)
+      (let ((here (point)))
+	(verilog-backward-syntactic-ws)
+	(cond
+	 ((or
+	   (= (preceding-char) ?\,)
+	   (= (preceding-char) ?\])
+	   (save-excursion
+	     (verilog-beg-of-statement-1)
+	     (looking-at verilog-declaration-re)))
+	  (let* ( fst
+		  (val
+		   (save-excursion
+		     (backward-char 1)
+		     (verilog-beg-of-statement-1)
+		     (setq fst (point))
+		     (if (looking-at verilog-declaration-re)
+			 (progn ;; we have multiple words
+			   (goto-char (match-end 0))
+			   (skip-chars-forward " \t")
+			   (cond
+			    ((and verilog-indent-declaration-macros
+				  (= (following-char) ?\`))
+			     (progn
+			       (forward-char 1)
+			       (forward-word 1)
+			       (skip-chars-forward " \t")))
+			    ((= (following-char) ?\[)
+			     (progn
+			       (forward-char 1)
+			       (backward-up-list -1)
+			       (skip-chars-forward " \t")))
+			    )
+			   (current-column))
+		       (progn
+			 (goto-char fst)
+			 (+ (current-column) verilog-cexp-indent))
+		       ))))
+	    (goto-char here)
+	    (indent-line-to val))
+	  )
+	 ((= (preceding-char) ?\) )
+	  (goto-char here)
+	  (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
+	    (indent-line-to val)))
+	 (t
+	  (goto-char here)
+	  (let ((val))
+	    (verilog-beg-of-statement-1)
+	    (if (and (< (point) here)
+		     (verilog-re-search-forward "=[ \\t]*" here 'move))
+		(setq val (current-column))
+	      (setq val (eval (cdr (assoc type verilog-indent-alist)))))
+	    (goto-char here)
+	    (indent-line-to val)))
+	 )))
+
+     (; handle inside parenthetical expressions
+      (eq type 'cparenexp)
+      (let ((val (save-excursion
+		   (backward-up-list 1)
+		   (forward-char 1)
+		   (skip-chars-forward " \t")
+		   (current-column))))
+	(indent-line-to val)
+	(if (and (not (verilog-in-struct-region-p))
+		 (looking-at verilog-declaration-re))
+	    (verilog-indent-declaration ind))
+	))
+
+     (;-- Handle the ends
+      (or
+       (looking-at verilog-end-block-re )
+       (verilog-at-close-constraint-p))
+      (let ((val (if (eq type 'statement)
+		     (- ind verilog-indent-level)
+		   ind)))
+	(indent-line-to val)))
+
+     (;-- Case -- maybe line 'em up
+      (and (eq type 'case) (not (looking-at "^[ \t]*$")))
+      (progn
+	(cond
+	 ((looking-at "\\<endcase\\>")
+	  (indent-line-to ind))
+	 (t
+	  (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
+	    (indent-line-to val))))))
+
+     (;-- defun
+      (and (eq type 'defun)
+	   (looking-at verilog-zero-indent-re))
+      (indent-line-to 0))
+
+     (;-- declaration
+      (and (or
+	    (eq type 'defun)
+	    (eq type 'block))
+	   (looking-at verilog-declaration-re))
+      (verilog-indent-declaration ind))
+
+     (;-- Everything else
+      t
+      (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
+	(indent-line-to val)))
+     )
+    (if (looking-at "[ \t]+$")
+	(skip-chars-forward " \t"))
+    indent-str				; Return indent data
+    ))
+
+(defun verilog-current-indent-level ()
+  "Return the indent-level the current statement has."
+  (save-excursion
+    (let (par-pos)
+      (beginning-of-line)
+      (setq par-pos (verilog-parenthesis-depth))
+      (while par-pos
+	(goto-char par-pos)
+	(beginning-of-line)
+	(setq par-pos (verilog-parenthesis-depth)))
+      (skip-chars-forward " \t")
+      (current-column))))
+
+(defun verilog-case-indent-level ()
+  "Return the indent-level the current statement has.
+Do not count named blocks or case-statements."
+  (save-excursion
+    (skip-chars-forward " \t")
+    (cond
+     ((looking-at verilog-named-block-re)
+      (current-column))
+     ((and (not (looking-at verilog-case-re))
+	   (looking-at "^[^:;]+[ \t]*:"))
+      (verilog-re-search-forward ":" nil t)
+      (skip-chars-forward " \t")
+      (current-column))
+     (t
+      (current-column)))))
+
+(defun verilog-indent-comment ()
+  "Indent current line as comment."
+  (let* ((stcol
+	  (cond
+	   ((verilog-in-star-comment-p)
+	    (save-excursion
+	      (re-search-backward "/\\*" nil t)
+	      (1+(current-column))))
+	   (comment-column
+	     comment-column )
+	   (t
+	    (save-excursion
+	      (re-search-backward "//" nil t)
+	      (current-column)))
+	   )))
+    (indent-line-to stcol)
+    stcol))
+
+(defun verilog-more-comment ()
+  "Make more comment lines like the previous."
+  (let* ((star 0)
+	 (stcol
+	  (cond
+	   ((verilog-in-star-comment-p)
+	    (save-excursion
+	      (setq star 1)
+	      (re-search-backward "/\\*" nil t)
+	      (1+(current-column))))
+	   (comment-column
+	    comment-column )
+	   (t
+	    (save-excursion
+	      (re-search-backward "//" nil t)
+	      (current-column)))
+	   )))
+    (progn
+      (indent-to stcol)
+      (if (and star
+	       (save-excursion
+		 (forward-line -1)
+		 (skip-chars-forward " \t")
+		 (looking-at "\*")))
+	  (insert "* ")))))
+
+(defun verilog-comment-indent (&optional arg)
+  "Return the column number the line should be indented to.
+ARG is ignored, for `comment-indent-function' compatibility."
+  (cond
+   ((verilog-in-star-comment-p)
+    (save-excursion
+      (re-search-backward "/\\*" nil t)
+      (1+(current-column))))
+   ( comment-column
+     comment-column )
+   (t
+    (save-excursion
+      (re-search-backward "//" nil t)
+      (current-column)))))
+
+;;
+
+(defun verilog-pretty-declarations ()
+  "Line up declarations around point."
+  (interactive)
+  (save-excursion
+    (if (progn
+	  (verilog-beg-of-statement-1)
+	  (looking-at verilog-declaration-re))
+	(let* ((m1 (make-marker))
+	       (e) (r)
+	       (here (point))
+	       ;; Start of declaration range
+	       (start
+		(progn
+		  (verilog-beg-of-statement-1)
+		  (while (looking-at verilog-declaration-re)
+		    (beginning-of-line)
+		    (setq e (point))
+		    (verilog-backward-syntactic-ws)
+		    (backward-char)
+		    (verilog-beg-of-statement-1)) ;Ack, need to grok `define
+		  e))
+	       ;; End of declaration range
+	       (end
+		(progn
+		  (goto-char here)
+		  (verilog-end-of-statement)
+		  (setq e (point))	;Might be on last line
+		  (verilog-forward-syntactic-ws)
+		  (while (looking-at verilog-declaration-re)
+		    (beginning-of-line)
+		    (verilog-end-of-statement)
+		    (setq e (point))
+		    (verilog-forward-syntactic-ws))
+		  e))
+	       (edpos (set-marker (make-marker) end))
+	       (ind)
+	       (base-ind
+		(progn
+		  (goto-char start)
+		  (verilog-do-indent (verilog-calculate-indent))
+		  (verilog-forward-ws&directives)
+		  (current-column)))
+	       )
+	  (goto-char end)
+	  (goto-char start)
+	  (if (> (- end start) 100)
+	      (message "Lining up declarations..(please stand by)"))
+	  ;; Get the beginning of line indent first
+	  (while (progn (setq e (marker-position edpos))
+			(< (point) e))
+	    (cond
+	     ( (save-excursion (skip-chars-backward " \t")
+			       (bolp))
+	       (verilog-forward-ws&directives)
+	       (indent-line-to base-ind)
+	       (verilog-forward-ws&directives)
+	       (verilog-re-search-forward "[ \t\n\f]" e 'move)
+	       )
+	     (t
+	      (just-one-space)
+	      (verilog-re-search-forward "[ \t\n\f]" e 'move)
+	      )
+	     )
+	    )
+	    ;;(forward-line))
+	  ;; Now find biggest prefix
+	  (setq ind (verilog-get-lineup-indent start edpos))
+	  ;; Now indent each line.
+	  (goto-char start)
+	  (while (progn (setq e (marker-position edpos))
+			(setq r (- e (point)))
+			(> r 0))
+	    (setq e (point))
+	    (message "%d" r)
+	    (cond
+	     ((or (and verilog-indent-declaration-macros
+		       (looking-at verilog-declaration-re-1-macro))
+		  (looking-at verilog-declaration-re-1-no-macro))
+	      (let ((p (match-end 0)))
+		(set-marker m1 p)
+		(if (verilog-re-search-forward "[[#`]" p 'move)
+		    (progn
+		      (forward-char -1)
+		      (just-one-space)
+		      (goto-char (marker-position m1))
+		      (just-one-space)
+		      (indent-to ind))
+		  (progn
+		    (just-one-space)
+		    (indent-to ind))
+		  )))
+	     ((verilog-continued-line-1 start)
+	      (goto-char e)
+	      (indent-line-to ind))
+	     (t		; Must be comment or white space
+	      (goto-char e)
+	      (verilog-forward-ws&directives)
+	      (forward-line -1))
+	     )
+	    (forward-line 1))
+	  (message "")))))
+
+(defun verilog-pretty-expr (&optional myre)
+  "Line up expressions around point."
+  (interactive "sRegular Expression: ((<|:)?=) ")
+  (save-excursion
+    (if (or (eq myre nil)
+	    (string-equal myre ""))
+	(setq myre "\\(<\\|:\\)?="))
+;    (setq myre (concat "\\(^[^;" myre "]*\\)\\([" myre "]\\)"))
+    (setq myre (concat "\\(^[^;#:?=]*\\)\\([" myre "]\\)"))
+    (beginning-of-line)
+    (if (and (not (looking-at (concat "^\\s-*" verilog-complete-reg)))
+	     (looking-at myre))
+	(let* ((here (point))
+	       (e) (r)
+	       (start
+		(progn
+		  (beginning-of-line)
+		  (setq e (point))
+		  (verilog-backward-syntactic-ws)
+		  (beginning-of-line)
+		  (while (and (not (looking-at (concat "^\\s-*" verilog-complete-reg)))
+			      (looking-at myre)
+			      (not (bobp))
+			      )
+		    (setq e (point))
+		    (verilog-backward-syntactic-ws)
+		    (beginning-of-line)
+		    ) ;Ack, need to grok `define
+		  e))
+	       (end
+		(progn
+		  (goto-char here)
+		  (end-of-line)
+		  (setq e (point))	;Might be on last line
+		  (verilog-forward-syntactic-ws)
+		  (beginning-of-line)
+		  (while (and (not(looking-at (concat "^\\s-*" verilog-complete-reg)))
+			      (looking-at myre))
+		    (end-of-line)
+		    (setq e (point))
+		    (verilog-forward-syntactic-ws)
+		    (beginning-of-line)
+		    )
+		  e))
+	       (edpos (set-marker (make-marker) end))
+	       (ind)
+	       )
+	  (goto-char start)
+	  (verilog-do-indent (verilog-calculate-indent))
+	  (if (> (- end start) 100)
+	      (message "Lining up expressions..(please stand by)"))
+
+	  ;; Set indent to minimum throughout region
+	  (while (< (point) (marker-position edpos))
+	    (beginning-of-line)
+	    (verilog-just-one-space myre)
+	    (end-of-line)
+	    (verilog-forward-syntactic-ws)
+	    )
+
+	  ;; Now find biggest prefix
+	  (setq ind (verilog-get-lineup-indent-2 myre start edpos))
+
+	  ;; Now indent each line.
+	  (goto-char start)
+	  (while (progn (setq e (marker-position edpos))
+			(setq r (- e (point)))
+			(> r 0))
+	    (setq e (point))
+	    (message "%d" r)
+	    (cond
+	     ((looking-at myre)
+	      (goto-char (match-end 1))
+	      (if (eq (char-after) ?=)
+		  (indent-to (1+ ind))	; line up the = of the <= with surrounding =
+		(indent-to ind)
+		)
+	      )
+	     ((verilog-continued-line-1 start)
+	      (goto-char e)
+	      (indent-line-to ind))
+	     (t		; Must be comment or white space
+	      (goto-char e)
+	      (verilog-forward-ws&directives)
+	      (forward-line -1))
+	     )
+	    (forward-line 1))
+	  (message "")
+	  ))))
+
+(defun verilog-just-one-space (myre)
+  "Remove extra spaces around regular expression MYRE."
+  (interactive)
+  (if (and (not(looking-at verilog-complete-reg))
+	   (looking-at myre))
+      (let ((p1 (match-end 1))
+	    (p2 (match-end 2)))
+	(progn
+	  (goto-char p2)
+	  (if (looking-at "\\s-") (just-one-space) )
+	  (goto-char p1)
+	  (forward-char -1)
+	  (if (looking-at "\\s-") (just-one-space))
+	  )
+	))
+  (message ""))
+
+(defun verilog-indent-declaration (baseind)
+  "Indent current lines as declaration.
+Line up the variable names based on previous declaration's indentation.
+BASEIND is the base indent to offset everything."
+  (interactive)
+  (let ((pos (point-marker))
+	(lim (save-excursion
+	       ;; (verilog-re-search-backward verilog-declaration-opener nil 'move)
+	       (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)\\|\\(\\<task\\>\\)" nil 'move)
+	       (point)))
+	(ind)
+	(val)
+	(m1 (make-marker))
+	)
+    (setq val (+ baseind (eval (cdr (assoc 'declaration verilog-indent-alist)))))
+    (indent-line-to val)
+
+    ;; Use previous declaration (in this module) as template.
+    (if (or (memq 'all verilog-auto-lineup)
+	    (memq 'declaration verilog-auto-lineup))
+	(if (verilog-re-search-backward 
+	     (or (and verilog-indent-declaration-macros
+		      verilog-declaration-re-1-macro)
+		 verilog-declaration-re-1-no-macro) lim t)
+	    (progn
+	      (goto-char (match-end 0))
+	      (skip-chars-forward " \t")
+	      (setq ind (current-column))
+	      (goto-char pos)
+	      (setq val (+ baseind (eval (cdr (assoc 'declaration verilog-indent-alist)))))
+	      (indent-line-to val)
+	      (if (and verilog-indent-declaration-macros
+		       (looking-at verilog-declaration-re-2-macro))
+		  (let ((p (match-end 0)))
+		    (set-marker m1 p)
+		    (if (verilog-re-search-forward "[[#`]" p 'move)
+			(progn
+			  (forward-char -1)
+			  (just-one-space)
+			  (goto-char (marker-position m1))
+			  (just-one-space)
+			  (indent-to ind)
+			  )
+		      (if (/= (current-column) ind)
+			  (progn
+			    (just-one-space)
+			    (indent-to ind))
+			)))
+		(if (looking-at verilog-declaration-re-2-no-macro)
+		    (let ((p (match-end 0)))
+		      (set-marker m1 p)
+		      (if (verilog-re-search-forward "[[`#]" p 'move)
+			  (progn
+			    (forward-char -1)
+			    (just-one-space)
+			    (goto-char (marker-position m1))
+			    (just-one-space)
+			    (indent-to ind))
+			(if (/= (current-column) ind)
+			    (progn
+			      (just-one-space)
+			      (indent-to ind))
+			  )))
+		  )))
+	  )
+      )
+    (goto-char pos)
+    )
+  )
+
+(defun verilog-get-lineup-indent (b edpos)
+  "Return the indent level that will line up several lines within the region.
+Region is defined by B and EDPOS."
+  (save-excursion
+    (let ((ind 0) e)
+      (goto-char b)
+      ;; Get rightmost position
+      (while (progn (setq e (marker-position edpos))
+		    (< (point) e))
+	(if (verilog-re-search-forward 
+	     (or (and verilog-indent-declaration-macros
+		      verilog-declaration-re-1-macro)
+		 verilog-declaration-re-1-no-macro) e 'move)
+	    (progn
+	      (goto-char (match-end 0))
+	      (verilog-backward-syntactic-ws)
+	      (if (> (current-column) ind)
+		  (setq ind (current-column)))
+	      (goto-char (match-end 0)))))
+      (if (> ind 0)
+	  (1+ ind)
+	;; No lineup-string found
+	(goto-char b)
+	(end-of-line)
+	(skip-chars-backward " \t")
+	(1+ (current-column))))))
+
+(defun verilog-get-lineup-indent-2 (myre b edpos)
+  "Return the indent level that will line up several lines within the region."
+  (save-excursion
+    (let ((ind 0) e)
+      (goto-char b)
+      ;; Get rightmost position
+      (while (progn (setq e (marker-position edpos))
+		    (< (point) e))
+	(if (verilog-re-search-forward myre e 'move)
+	    (progn
+	      (goto-char (match-end 0))
+	      (verilog-backward-syntactic-ws)
+	      (if (> (current-column) ind)
+		  (setq ind (current-column)))
+	      (goto-char (match-end 0)))))
+      (if (> ind 0)
+	  (1+ ind)
+	;; No lineup-string found
+	(goto-char b)
+	(end-of-line)
+	(skip-chars-backward " \t")
+	(1+ (current-column))))))
+
+(defun verilog-comment-depth (type val)
+  "A useful mode debugging aide.  TYPE and VAL are comments for insertion."
+  (save-excursion
+    (let
+	((b (prog2
+		(beginning-of-line)
+		(point-marker)
+	      (end-of-line)))
+	 (e (point-marker)))
+      (if (re-search-backward " /\\* \[#-\]# \[a-zA-Z\]+ \[0-9\]+ ## \\*/" b t)
+	  (progn
+	    (replace-match " /* -#  ## */")
+	    (end-of-line))
+	(progn
+	  (end-of-line)
+	  (insert " /* ##  ## */"))))
+    (backward-char 6)
+    (insert
+     (format "%s %d" type val))))
+
+;; 
+;;
+;; Completion
+;;
+(defvar verilog-str nil)
+(defvar verilog-all nil)
+(defvar verilog-pred nil)
+(defvar verilog-buffer-to-use nil)
+(defvar verilog-flag nil)
+(defvar verilog-toggle-completions nil
+  "*True means \\<verilog-mode-map>\\[verilog-complete-word] should try all possible completions one by one.
+Repeated use of \\[verilog-complete-word] will show you all of them.
+Normally, when there is more than one possible completion,
+it displays a list of all possible completions.")
+
+
+(defvar verilog-type-keywords
+  '(
+    "and" "buf" "bufif0" "bufif1" "cmos" "defparam" "inout" "input"
+    "integer" "localparam" "logic" "mailbox" "nand" "nmos" "nor" "not" "notif0"
+    "notif1" "or" "output" "parameter" "pmos" "pull0" "pull1" "pullup"
+    "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran" "rtranif0"
+    "rtranif1" "semaphore" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1"
+    "triand" "trior" "trireg" "wand" "wire" "wor" "xnor" "xor"
+    )
+  "*Keywords for types used when completing a word in a declaration or parmlist.
+\(eg.  integer, real, reg...)")
+
+(defvar verilog-cpp-keywords
+  '("module" "macromodule" "primitive" "timescale" "define" "ifdef" "ifndef" "else"
+    "endif")
+  "*Keywords to complete when at first word of a line in declarative scope.
+\(eg.  initial, always, begin, assign.)
+The procedures and variables defined within the Verilog program
+will be completed runtime and should not be added to this list.")
+
+(defvar verilog-defun-keywords
+  (append
+   '(
+     "always" "always_comb" "always_ff" "always_latch" "assign"
+     "begin" "end" "generate" "endgenerate" "module" "endmodule"
+     "specify" "endspecify" "function" "endfunction" "initial" "final"
+     "task" "endtask" "primitive" "endprimitive"
+     )
+   verilog-type-keywords)
+  "*Keywords to complete when at first word of a line in declarative scope.
+\(eg.  initial, always, begin, assign.)
+The procedures and variables defined within the Verilog program
+will be completed runtime and should not be added to this list.")
+
+(defvar verilog-block-keywords
+  '(
+    "begin" "break" "case" "continue" "else" "end" "endfunction"
+    "endgenerate" "endinterface" "endpackage" "endspecify" "endtask"
+    "for" "fork" "if" "join" "join_any" "join_none" "repeat" "return"
+    "while")
+  "*Keywords to complete when at first word of a line in behavioral scope.
+\(eg.  begin, if, then, else, for, fork.)
+The procedures and variables defined within the Verilog program
+will be completed runtime and should not be added to this list.")
+
+(defvar verilog-tf-keywords
+  '("begin" "break" "fork" "join" "join_any" "join_none" "case" "end" "endtask" "endfunction" "if" "else" "for" "while" "repeat")
+  "*Keywords to complete when at first word of a line in a task or function.
+\(eg.  begin, if, then, else, for, fork.)
+The procedures and variables defined within the Verilog program
+will be completed runtime and should not be added to this list.")
+
+(defvar verilog-case-keywords
+  '("begin" "fork" "join" "join_any" "join_none" "case" "end" "endcase" "if" "else" "for" "repeat")
+  "*Keywords to complete when at first word of a line in case scope.
+\(eg.  begin, if, then, else, for, fork.)
+The procedures and variables defined within the Verilog program
+will be completed runtime and should not be added to this list.")
+
+(defvar verilog-separator-keywords
+  '("else" "then" "begin")
+  "*Keywords to complete when NOT standing at the first word of a statement.
+\(eg.  else, then.)
+Variables and function names defined within the
+Verilog program are completed runtime and should not be added to this list.")
+
+(defun verilog-string-diff (str1 str2)
+  "Return index of first letter where STR1 and STR2 differs."
+  (catch 'done
+    (let ((diff 0))
+      (while t
+	(if (or (> (1+ diff) (length str1))
+		(> (1+ diff) (length str2)))
+	    (throw 'done diff))
+	(or (equal (aref str1 diff) (aref str2 diff))
+	    (throw 'done diff))
+	(setq diff (1+ diff))))))
+
+;; Calculate all possible completions for functions if argument is `function',
+;; completions for procedures if argument is `procedure' or both functions and
+;; procedures otherwise.
+
+(defun verilog-func-completion (type)
+  "Build regular expression for module/task/function names.
+TYPE is 'module, 'tf for task or function, or t if unknown."
+  (if (string= verilog-str "")
+      (setq verilog-str "[a-zA-Z_]"))
+  (let ((verilog-str (concat (cond
+			     ((eq type 'module) "\\<\\(module\\)\\s +")
+			     ((eq type 'tf) "\\<\\(task\\|function\\)\\s +")
+			     (t "\\<\\(task\\|function\\|module\\)\\s +"))
+			    "\\<\\(" verilog-str "[a-zA-Z0-9_.]*\\)\\>"))
+	match)
+
+    (if (not (looking-at verilog-defun-re))
+	(verilog-re-search-backward verilog-defun-re nil t))
+    (forward-char 1)
+
+    ;; Search through all reachable functions
+    (goto-char (point-min))
+    (while (verilog-re-search-forward verilog-str (point-max) t)
+      (progn (setq match (buffer-substring (match-beginning 2)
+					   (match-end 2)))
+	     (if (or (null verilog-pred)
+		     (funcall verilog-pred match))
+		 (setq verilog-all (cons match verilog-all)))))
+    (if (match-beginning 0)
+	(goto-char (match-beginning 0)))))
+
+(defun verilog-get-completion-decl (end)
+  "Macro for searching through current declaration (var, type or const)
+for matches of `str' and adding the occurrence tp `all' through point END."
+  (let ((re (or (and verilog-indent-declaration-macros
+		     verilog-declaration-re-2-macro)
+		verilog-declaration-re-2-no-macro))
+	decl-end match)
+    ;; Traverse lines
+    (while (and (< (point) end)
+		(verilog-re-search-forward re end t))
+      ;; Traverse current line
+      (setq decl-end (save-excursion (verilog-declaration-end)))
+      (while (and (verilog-re-search-forward verilog-symbol-re decl-end t)
+		  (not (match-end 1)))
+	(setq match (buffer-substring (match-beginning 0) (match-end 0)))
+	(if (string-match (concat "\\<" verilog-str) match)
+	    (if (or (null verilog-pred)
+		    (funcall verilog-pred match))
+		(setq verilog-all (cons match verilog-all)))))
+      (forward-line 1)
+      )
+    )
+  verilog-all
+  )
+
+(defun verilog-type-completion ()
+  "Calculate all possible completions for types."
+  (let ((start (point))
+	goon)
+    ;; Search for all reachable type declarations
+    (while (or (verilog-beg-of-defun)
+	       (setq goon (not goon)))
+      (save-excursion
+	(if (and (< start (prog1 (save-excursion (verilog-end-of-defun)
+						 (point))
+			    (forward-char 1)))
+		 (verilog-re-search-forward
+		  "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
+		  start t)
+		 (not (match-end 1)))
+	    ;; Check current type declaration
+	    (verilog-get-completion-decl start))))))
+
+(defun verilog-var-completion ()
+  "Calculate all possible completions for variables (or constants)."
+  (let ((start (point)))
+    ;; Search for all reachable var declarations
+    (verilog-beg-of-defun)
+    (save-excursion
+      ;; Check var declarations
+      (verilog-get-completion-decl start))))
+
+(defun verilog-keyword-completion (keyword-list)
+  "Give list of all possible completions of keywords in KEYWORD-LIST."
+  (mapcar '(lambda (s)
+	     (if (string-match (concat "\\<" verilog-str) s)
+		 (if (or (null verilog-pred)
+			 (funcall verilog-pred s))
+		     (setq verilog-all (cons s verilog-all)))))
+	  keyword-list))
+
+
+(defun verilog-completion (verilog-str verilog-pred verilog-flag)
+  "Function passed to `completing-read', `try-completion' or `all-completions'.
+Called to get completion on VERILOG-STR.  If VERILOG-PRED is non-nil, it
+must be a function to be called for every match to check if this should
+really be a match.  If VERILOG-FLAG is t, the function returns a list of all
+possible completions.  If VERILOG-FLAG is nil it returns a string, the
+longest possible completion, or t if STR is an exact match.  If VERILOG-FLAG
+is 'lambda, the function returns t if STR is an exact match, nil
+otherwise."
+  (save-excursion
+    (let ((verilog-all nil))
+      ;; Set buffer to use for searching labels. This should be set
+      ;; within functions which use verilog-completions
+      (set-buffer verilog-buffer-to-use)
+
+      ;; Determine what should be completed
+      (let ((state (car (verilog-calculate-indent))))
+	(cond ((eq state 'defun)
+	       (save-excursion (verilog-var-completion))
+	       (verilog-func-completion 'module)
+	       (verilog-keyword-completion verilog-defun-keywords))
+
+	      ((eq state 'behavioral)
+	       (save-excursion (verilog-var-completion))
+	       (verilog-func-completion 'module)
+	       (verilog-keyword-completion verilog-defun-keywords))
+
+	      ((eq state 'block)
+	       (save-excursion (verilog-var-completion))
+	       (verilog-func-completion 'tf)
+	       (verilog-keyword-completion verilog-block-keywords))
+
+	      ((eq state 'case)
+	       (save-excursion (verilog-var-completion))
+	       (verilog-func-completion 'tf)
+	       (verilog-keyword-completion verilog-case-keywords))
+
+	      ((eq state 'tf)
+	       (save-excursion (verilog-var-completion))
+	       (verilog-func-completion 'tf)
+	       (verilog-keyword-completion verilog-tf-keywords))
+
+	      ((eq state 'cpp)
+	       (save-excursion (verilog-var-completion))
+	       (verilog-keyword-completion verilog-cpp-keywords))
+
+	      ((eq state 'cparenexp)
+	       (save-excursion (verilog-var-completion)))
+
+	      (t;--Anywhere else
+	       (save-excursion (verilog-var-completion))
+	       (verilog-func-completion 'both)
+	       (verilog-keyword-completion verilog-separator-keywords))))
+
+      ;; Now we have built a list of all matches. Give response to caller
+      (verilog-completion-response))))
+
+(defun verilog-completion-response ()
+  (cond ((or (equal verilog-flag 'lambda) (null verilog-flag))
+	 ;; This was not called by all-completions
+	 (if (null verilog-all)
+	     ;; Return nil if there was no matching label
+	     nil
+	   ;; Get longest string common in the labels
+	   (let* ((elm (cdr verilog-all))
+		  (match (car verilog-all))
+		  (min (length match))
+		  tmp)
+	     (if (string= match verilog-str)
+		 ;; Return t if first match was an exact match
+		 (setq match t)
+	       (while (not (null elm))
+		 ;; Find longest common string
+		 (if (< (setq tmp (verilog-string-diff match (car elm))) min)
+		     (progn
+		       (setq min tmp)
+		       (setq match (substring match 0 min))))
+		 ;; Terminate with match=t if this is an exact match
+		 (if (string= (car elm) verilog-str)
+		     (progn
+		       (setq match t)
+		       (setq elm nil))
+		   (setq elm (cdr elm)))))
+	     ;; If this is a test just for exact match, return nil ot t
+	     (if (and (equal verilog-flag 'lambda) (not (equal match 't)))
+		 nil
+	       match))))
+	;; If flag is t, this was called by all-completions. Return
+	;; list of all possible completions
+	(verilog-flag
+	 verilog-all)))
+
+(defvar verilog-last-word-numb 0)
+(defvar verilog-last-word-shown nil)
+(defvar verilog-last-completions nil)
+
+(defun verilog-complete-word ()
+  "Complete word at current point.
+\(See also `verilog-toggle-completions', `verilog-type-keywords',
+and `verilog-separator-keywords'.)"
+  (interactive)
+  (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
+	 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
+	 (verilog-str (buffer-substring b e))
+	 ;; The following variable is used in verilog-completion
+	 (verilog-buffer-to-use (current-buffer))
+	 (allcomp (if (and verilog-toggle-completions
+			   (string= verilog-last-word-shown verilog-str))
+		      verilog-last-completions
+		    (all-completions verilog-str 'verilog-completion)))
+	 (match (if verilog-toggle-completions
+		    "" (try-completion
+			verilog-str (mapcar '(lambda (elm)
+					      (cons elm 0)) allcomp)))))
+    ;; Delete old string
+    (delete-region b e)
+
+    ;; Toggle-completions inserts whole labels
+    (if verilog-toggle-completions
+	(progn
+	  ;; Update entry number in list
+	  (setq verilog-last-completions allcomp
+		verilog-last-word-numb
+		(if (>= verilog-last-word-numb (1- (length allcomp)))
+		    0
+		  (1+ verilog-last-word-numb)))
+	  (setq verilog-last-word-shown (elt allcomp verilog-last-word-numb))
+	  ;; Display next match or same string if no match was found
+	  (if (not (null allcomp))
+	      (insert "" verilog-last-word-shown)
+	    (insert "" verilog-str)
+	    (message "(No match)")))
+      ;; The other form of completion does not necessarily do that.
+
+      ;; Insert match if found, or the original string if no match
+      (if (or (null match) (equal match 't))
+	  (progn (insert "" verilog-str)
+		 (message "(No match)"))
+	(insert "" match))
+      ;; Give message about current status of completion
+      (cond ((equal match 't)
+	     (if (not (null (cdr allcomp)))
+		 (message "(Complete but not unique)")
+	       (message "(Sole completion)")))
+	    ;; Display buffer if the current completion didn't help
+	    ;; on completing the label.
+	    ((and (not (null (cdr allcomp))) (= (length verilog-str)
+						(length match)))
+	     (with-output-to-temp-buffer "*Completions*"
+	       (display-completion-list allcomp))
+	     ;; Wait for a key press. Then delete *Completion*  window
+	     (momentary-string-display "" (point))
+	     (delete-window (get-buffer-window (get-buffer "*Completions*")))
+	     )))))
+
+(defun verilog-show-completions ()
+  "Show all possible completions at current point."
+  (interactive)
+  (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
+	 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
+	 (verilog-str (buffer-substring b e))
+	 ;; The following variable is used in verilog-completion
+	 (verilog-buffer-to-use (current-buffer))
+	 (allcomp (if (and verilog-toggle-completions
+			   (string= verilog-last-word-shown verilog-str))
+		      verilog-last-completions
+		    (all-completions verilog-str 'verilog-completion))))
+    ;; Show possible completions in a temporary buffer.
+    (with-output-to-temp-buffer "*Completions*"
+      (display-completion-list allcomp))
+    ;; Wait for a key press. Then delete *Completion*  window
+    (momentary-string-display "" (point))
+    (delete-window (get-buffer-window (get-buffer "*Completions*")))))
+
+
+(defun verilog-get-default-symbol ()
+  "Return symbol around current point as a string."
+  (save-excursion
+    (buffer-substring (progn
+			(skip-chars-backward " \t")
+			(skip-chars-backward "a-zA-Z0-9_")
+			(point))
+		      (progn
+			(skip-chars-forward "a-zA-Z0-9_")
+			(point)))))
+
+(defun verilog-build-defun-re (str &optional arg)
+  "Return function/task/module starting with STR as regular expression.
+With optional second ARG non-nil, STR is the complete name of the instruction."
+  (if arg
+      (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "\\)\\>")
+    (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "[a-zA-Z0-9_]*\\)\\>")))
+
+(defun verilog-comp-defun (verilog-str verilog-pred verilog-flag)
+  "Function passed to `completing-read', `try-completion' or `all-completions'.
+Returns a completion on any function name based on VERILOG-STR prefix.  If
+VERILOG-PRED is non-nil, it must be a function to be called for every match
+to check if this should really be a match.  If VERILOG-FLAG is t, the
+function returns a list of all possible completions.  If it is nil it
+returns a string, the longest possible completion, or t if VERILOG-STR is
+an exact match.  If VERILOG-FLAG is 'lambda, the function returns t if
+VERILOG-STR is an exact match, nil otherwise."
+  (save-excursion
+    (let ((verilog-all nil)
+	  match)
+
+      ;; Set buffer to use for searching labels. This should be set
+      ;; within functions which use verilog-completions
+      (set-buffer verilog-buffer-to-use)
+
+      (let ((verilog-str verilog-str))
+	;; Build regular expression for functions
+	(if (string= verilog-str "")
+	    (setq verilog-str (verilog-build-defun-re "[a-zA-Z_]"))
+	  (setq verilog-str (verilog-build-defun-re verilog-str)))
+	(goto-char (point-min))
+
+	;; Build a list of all possible completions
+	(while (verilog-re-search-forward verilog-str nil t)
+	  (setq match (buffer-substring (match-beginning 2) (match-end 2)))
+	  (if (or (null verilog-pred)
+		  (funcall verilog-pred match))
+	      (setq verilog-all (cons match verilog-all)))))
+
+      ;; Now we have built a list of all matches. Give response to caller
+      (verilog-completion-response))))
+
+(defun verilog-goto-defun ()
+  "Move to specified Verilog module/task/function.
+The default is a name found in the buffer around point.
+If search fails, other files are checked based on
+`verilog-library-flags'."
+  (interactive)
+  (let* ((default (verilog-get-default-symbol))
+	 ;; The following variable is used in verilog-comp-function
+	 (verilog-buffer-to-use (current-buffer))
+	 (label (if (not (string= default ""))
+		    ;; Do completion with default
+		    (completing-read (concat "Label: (default " default ") ")
+				     'verilog-comp-defun nil nil "")
+		  ;; There is no default value. Complete without it
+		  (completing-read "Label: "
+				   'verilog-comp-defun nil nil "")))
+	 pt)
+    ;; If there was no response on prompt, use default value
+    (if (string= label "")
+	(setq label default))
+    ;; Goto right place in buffer if label is not an empty string
+    (or (string= label "")
+	(progn
+	  (save-excursion
+	    (goto-char (point-min))
+	    (setq pt (re-search-forward (verilog-build-defun-re label t) nil t)))
+	  (when pt
+	    (goto-char pt)
+	    (beginning-of-line))
+	  pt)
+	(verilog-goto-defun-file label)
+	)))
+
+;; Eliminate compile warning
+(eval-when-compile
+  (if (not (boundp 'occur-pos-list))
+      (defvar occur-pos-list nil "Backward compatibility occur positions.")))
+
+(defun verilog-showscopes ()
+  "List all scopes in this module."
+  (interactive)
+  (let ((buffer (current-buffer))
+	(linenum 1)
+	(nlines 0)
+	(first 1)
+	(prevpos (point-min))
+        (final-context-start (make-marker))
+	(regexp "\\(module\\s-+\\w+\\s-*(\\)\\|\\(\\w+\\s-+\\w+\\s-*(\\)")
+	)
+    (with-output-to-temp-buffer "*Occur*"
+      (save-excursion
+	(message (format "Searching for %s ..." regexp))
+	;; Find next match, but give up if prev match was at end of buffer.
+	(while (and (not (= prevpos (point-max)))
+		    (verilog-re-search-forward regexp nil t))
+	  (goto-char (match-beginning 0))
+	  (beginning-of-line)
+	  (save-match-data
+            (setq linenum (+ linenum (count-lines prevpos (point)))))
+	  (setq prevpos (point))
+	  (goto-char (match-end 0))
+	  (let* ((start (save-excursion
+			  (goto-char (match-beginning 0))
+			  (forward-line (if (< nlines 0) nlines (- nlines)))
+			  (point)))
+		 (end (save-excursion
+			(goto-char (match-end 0))
+			(if (> nlines 0)
+			    (forward-line (1+ nlines))
+			    (forward-line 1))
+			(point)))
+		 (tag (format "%3d" linenum))
+		 (empty (make-string (length tag) ?\ ))
+		 tem)
+	    (save-excursion
+	      (setq tem (make-marker))
+	      (set-marker tem (point))
+	      (set-buffer standard-output)
+	      (setq occur-pos-list (cons tem occur-pos-list))
+	      (or first (zerop nlines)
+		  (insert "--------\n"))
+	      (setq first nil)
+	      (insert-buffer-substring buffer start end)
+	      (backward-char (- end start))
+	      (setq tem (if (< nlines 0) (- nlines) nlines))
+	      (while (> tem 0)
+		(insert empty ?:)
+		(forward-line 1)
+		(setq tem (1- tem)))
+	      (let ((this-linenum linenum))
+		(set-marker final-context-start
+			    (+ (point) (- (match-end 0) (match-beginning 0))))
+		(while (< (point) final-context-start)
+		  (if (null tag)
+		      (setq tag (format "%3d" this-linenum)))
+		  (insert tag ?:)))))))
+      (set-buffer-modified-p nil))))
+
+
+;; Highlight helper functions
+(defconst verilog-directive-regexp "\\(translate\\|coverage\\|lint\\)_")
+(defun verilog-within-translate-off ()
+  "Return point if within translate-off region, else nil."
+  (and (save-excursion
+	 (re-search-backward
+	  (concat "//\\s-*.*\\s-*" verilog-directive-regexp "\\(on\\|off\\)\\>")
+	  nil t))
+       (equal "off" (match-string 2))
+       (point)))
+
+(defun verilog-start-translate-off (limit)
+  "Return point before translate-off directive if before LIMIT, else nil."
+  (when (re-search-forward
+	  (concat "//\\s-*.*\\s-*" verilog-directive-regexp "off\\>")
+	  limit t)
+    (match-beginning 0)))
+
+(defun verilog-back-to-start-translate-off (limit)
+  "Return point before translate-off directive if before LIMIT, else nil."
+  (when (re-search-backward
+	  (concat "//\\s-*.*\\s-*" verilog-directive-regexp "off\\>")
+	  limit t)
+    (match-beginning 0)))
+
+(defun verilog-end-translate-off (limit)
+  "Return point after translate-on directive if before LIMIT, else nil."
+
+  (re-search-forward (concat
+		      "//\\s-*.*\\s-*" verilog-directive-regexp "on\\>") limit t))
+
+(defun verilog-match-translate-off (limit)
+  "Match a translate-off block, setting `match-data' and returning t, else nil.
+Bound search by LIMIT."
+  (when (< (point) limit)
+    (let ((start (or (verilog-within-translate-off)
+		     (verilog-start-translate-off limit)))
+	  (case-fold-search t))
+      (when start
+	(let ((end (or (verilog-end-translate-off limit) limit)))
+	  (set-match-data (list start end))
+	  (goto-char end))))))
+
+(defun verilog-font-lock-match-item (limit)
+  "Match, and move over, any declaration item after point.
+Bound search by LIMIT.  Adapted from
+`font-lock-match-c-style-declaration-item-and-skip-to-next'."
+  (condition-case nil
+      (save-restriction
+	(narrow-to-region (point-min) limit)
+	;; match item
+	(when (looking-at "\\s-*\\([a-zA-Z]\\w*\\)")
+	  (save-match-data
+	    (goto-char (match-end 1))
+	    ;; move to next item
+	    (if (looking-at "\\(\\s-*,\\)")
+		(goto-char (match-end 1))
+	      (end-of-line) t))))
+    (error nil)))
+
+
+;; Added by Subbu Meiyappan for Header
+
+(defun verilog-header ()
+  "Insert a standard Verilog file header."
+  (interactive)
+  (let ((start (point)))
+  (insert "\
+//-----------------------------------------------------------------------------
+// Title         : <title>
+// Project       : <project>
+//-----------------------------------------------------------------------------
+// File          : <filename>
+// Author        : <author>
+// Created       : <credate>
+// Last modified : <moddate>
+//-----------------------------------------------------------------------------
+// Description :
+// <description>
+//-----------------------------------------------------------------------------
+// Copyright (c) <copydate> by <company> This model is the confidential and
+// proprietary property of <company> and the possession or use of this
+// file requires a written license from <company>.
+//------------------------------------------------------------------------------
+// Modification history :
+// <modhist>
+//-----------------------------------------------------------------------------
+
+")
+    (goto-char start)
+    (search-forward "<filename>")
+    (replace-match (buffer-name) t t)
+    (search-forward "<author>") (replace-match "" t t)
+    (insert (user-full-name))
+    (insert "  <" (user-login-name) "@" (system-name) ">")
+    (search-forward "<credate>") (replace-match "" t t)
+    (insert-date)
+    (search-forward "<moddate>") (replace-match "" t t)
+    (insert-date)
+    (search-forward "<copydate>") (replace-match "" t t)
+    (insert-year)
+    (search-forward "<modhist>") (replace-match "" t t)
+    (insert-date)
+    (insert " : created")
+    (goto-char start)
+    (let (string)
+      (setq string (read-string "title: "))
+      (search-forward "<title>")
+      (replace-match string t t)
+      (setq string (read-string "project: " verilog-project))
+      (make-variable-buffer-local 'verilog-project)
+      (setq verilog-project string)
+      (search-forward "<project>")
+      (replace-match string t t)
+      (setq string (read-string "Company: " verilog-company))
+      (make-variable-buffer-local 'verilog-company)
+      (setq verilog-company string)
+      (search-forward "<company>")
+      (replace-match string t t)
+      (search-forward "<company>")
+      (replace-match string t t)
+      (search-forward "<company>")
+      (replace-match string t t)
+      (search-backward "<description>")
+      (replace-match "" t t)
+      )))
+
+;; verilog-header Uses the insert-date function
+
+(defun insert-date ()
+  "Insert date from the system."
+  (interactive)
+  (let ((timpos))
+    (setq timpos (point))
+    (if verilog-date-scientific-format
+	(shell-command  "date \"+@%Y/%m/%d\"" t)
+      (shell-command  "date \"+@%d.%m.%Y\"" t))
+    (search-forward "@")
+    (delete-region timpos (point))
+    (end-of-line))
+    (delete-char 1))
+
+(defun insert-year ()
+  "Insert year from the system."
+  (interactive)
+  (let ((timpos))
+    (setq timpos (point))
+    (shell-command  "date \"+@%Y\"" t)
+    (search-forward "@")
+    (delete-region timpos (point))
+    (end-of-line))
+  (delete-char 1))
+
+
+;;
+;; Signal list parsing
+;;
+
+;; Elements of a signal list
+(defsubst verilog-sig-name (sig)
+  (car sig))
+(defsubst verilog-sig-bits (sig)
+  (nth 1 sig))
+(defsubst verilog-sig-comment (sig)
+  (nth 2 sig))
+(defsubst verilog-sig-memory (sig)
+  (nth 3 sig))
+(defsubst verilog-sig-enum (sig)
+  (nth 4 sig))
+(defsubst verilog-sig-signed (sig)
+  (nth 5 sig))
+(defsubst verilog-sig-type (sig)
+  (nth 6 sig))
+(defsubst verilog-sig-multidim (sig)
+  (nth 7 sig))
+(defsubst verilog-sig-multidim-string (sig)
+  (if (verilog-sig-multidim sig)
+      (let ((str "") (args (verilog-sig-multidim sig)))
+	(while args
+	  (setq str (concat str (car args)))
+	  (setq args (cdr args)))
+	str)))
+(defsubst verilog-sig-width (sig)
+  (verilog-make-width-expression (verilog-sig-bits sig)))
+
+(defsubst verilog-alw-get-inputs (sigs)
+  (nth 2 sigs))
+(defsubst verilog-alw-get-outputs (sigs)
+  (nth 0 sigs))
+(defsubst verilog-alw-get-uses-delayed (sigs)
+  (nth 3 sigs))
+
+(defun verilog-signals-not-in (in-list not-list)
+  "Return list of signals in IN-LIST that aren't also in NOT-LIST,
+and also remove any duplicates in IN-LIST.
+Signals must be in standard (base vector) form."
+  (let (out-list)
+    (while in-list
+      (if (not (or (assoc (car (car in-list)) not-list)
+		   (assoc (car (car in-list)) out-list)))
+	  (setq out-list (cons (car in-list) out-list)))
+      (setq in-list (cdr in-list)))
+    (nreverse out-list)))
+;;(verilog-signals-not-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" "")))
+
+(defun verilog-signals-in (in-list other-list)
+  "Return list of signals in IN-LIST that are also in OTHER-LIST.
+Signals must be in standard (base vector) form."
+  (let (out-list)
+    (while in-list
+      (if (assoc (car (car in-list)) other-list)
+	  (setq out-list (cons (car in-list) out-list)))
+      (setq in-list (cdr in-list)))
+    (nreverse out-list)))
+;;(verilog-signals-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" "")))
+
+(defun verilog-signals-memory (in-list)
+  "Return list of signals in IN-LIST that are memoried (multidimensional)."
+  (let (out-list)
+    (while in-list
+      (if (nth 3 (car in-list))
+	  (setq out-list (cons (car in-list) out-list)))
+      (setq in-list (cdr in-list)))
+    out-list))
+;;(verilog-signals-memory '(("A" nil nil "[3:0]")) '(("B" nil nil nil)))
+
+(defun verilog-signals-sort-compare (a b)
+  "Compare signal A and B for sorting."
+  (string< (car a) (car b)))
+
+(defun verilog-signals-not-params (in-list)
+  "Return list of signals in IN-LIST that aren't parameters or numeric constants."
+  (let (out-list)
+    (while in-list
+      (unless (boundp (intern (concat "vh-" (car (car in-list)))))
+	(setq out-list (cons (car in-list) out-list)))
+      (setq in-list (cdr in-list)))
+    (nreverse out-list)))
+
+(defun verilog-signals-combine-bus (in-list)
+  "Return a list of signals in IN-LIST, with busses combined.
+Duplicate signals are also removed.  For example A[2] and A[1] become A[2:1]."
+  (let (combo buswarn
+	out-list
+	sig highbit lowbit		; Temp information about current signal
+	sv-name sv-highbit sv-lowbit	; Details about signal we are forming
+	sv-comment sv-memory sv-enum sv-signed sv-type sv-multidim sv-busstring
+	bus)
+    ;; Shove signals so duplicated signals will be adjacent
+    (setq in-list (sort in-list `verilog-signals-sort-compare))
+    (while in-list
+      (setq sig (car in-list))
+      ;; No current signal; form from existing details
+      (unless sv-name
+	(setq sv-name    (verilog-sig-name sig)
+	      sv-highbit nil
+	      sv-busstring nil
+	      sv-comment (verilog-sig-comment sig)
+	      sv-memory  (verilog-sig-memory sig)
+	      sv-enum    (verilog-sig-enum sig)
+	      sv-signed  (verilog-sig-signed sig)
+	      sv-type    (verilog-sig-type sig)
+	      sv-multidim (verilog-sig-multidim sig)
+	      combo ""
+	      buswarn ""
+	      ))
+      ;; Extract bus details
+      (setq bus (verilog-sig-bits sig))
+      (cond ((and bus
+		  (or (and (string-match "\\[\\([0-9]+\\):\\([0-9]+\\)\\]" bus)
+			   (setq highbit (string-to-int (match-string 1 bus))
+				 lowbit  (string-to-int (match-string 2 bus))))
+		      (and (string-match "\\[\\([0-9]+\\)\\]" bus)
+			   (setq highbit (string-to-int (match-string 1 bus))
+				 lowbit  highbit))))
+	     ;; Combine bits in bus
+	     (if sv-highbit
+		 (setq sv-highbit (max highbit sv-highbit)
+		       sv-lowbit  (min lowbit  sv-lowbit))
+	       (setq sv-highbit highbit
+		     sv-lowbit  lowbit)))
+	    (bus
+	     ;; String, probably something like `preproc:0
+	     (setq sv-busstring bus)))
+      ;; Peek ahead to next signal
+      (setq in-list (cdr in-list))
+      (setq sig (car in-list))
+      (cond ((and sig (equal sv-name (verilog-sig-name sig)))
+	     ;; Combine with this signal
+	     (when (and sv-busstring (not (equal sv-busstring (verilog-sig-bits sig))))
+	       (when nil  ;; Debugging
+		 (message (concat "Warning, can't merge into single bus "
+				  sv-name bus
+				  ", the AUTOs may be wrong")))
+	       (setq buswarn ", Couldn't Merge"))
+	     (if (verilog-sig-comment sig) (setq combo ", ..."))
+	     (setq sv-memory (or sv-memory (verilog-sig-memory sig))
+		   sv-enum   (or sv-enum   (verilog-sig-enum sig))
+		   sv-signed (or sv-signed (verilog-sig-signed sig))
+                   sv-type   (or sv-type   (verilog-sig-type sig))
+                   sv-multidim (or sv-multidim (verilog-sig-multidim sig))))
+	    ;; Doesn't match next signal, add to queue, zero in prep for next
+	    ;; Note sig may also be nil for the last signal in the list
+	    (t
+	     (setq out-list
+		   (cons (list sv-name
+			       (or sv-busstring
+				   (if sv-highbit
+				       (concat "[" (int-to-string sv-highbit) ":" (int-to-string sv-lowbit) "]")))
+			       (concat sv-comment combo buswarn)
+			       sv-memory sv-enum sv-signed sv-type sv-multidim)
+			 out-list)
+		   sv-name nil)))
+      )
+    ;;
+    out-list))
+
+(defun verilog-sig-tieoff (sig &optional no-width)
+  "Return tieoff expression for given SIGNAL, with appropriate width.
+Ignore width if optional NO-WIDTH is set."
+  (let* ((width (if no-width nil (verilog-sig-width sig))))
+    (concat
+     (if (and verilog-active-low-regexp
+	      (string-match verilog-active-low-regexp (verilog-sig-name sig)))
+	 "~" "")
+     (cond ((not width)
+	    "0")
+	   ((string-match "^[0-9]+$" width)
+	    (concat width (if (verilog-sig-signed sig) "'sh0" "'h0")))
+	   (t
+	    (concat "{" width "{1'b0}}"))))))
+
+;;
+;; Port/Wire/Etc Reading
+;;
+
+(defun verilog-read-inst-backward-name ()
+  "Internal.  Move point back to beginning of inst-name."
+    (verilog-backward-open-paren)
+    (let (done)
+      (while (not done)
+	(verilog-re-search-backward-quick "\\()\\|\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil)  ; ] isn't word boundary
+	(cond ((looking-at ")")
+	       (verilog-backward-open-paren))
+	      (t (setq done t)))))
+    (while (looking-at "\\]")
+      (verilog-backward-open-bracket)
+      (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil))
+    (skip-chars-backward "a-zA-Z0-9`_$"))
+
+(defun verilog-read-inst-module ()
+  "Return module_name when point is inside instantiation."
+  (save-excursion
+    (verilog-read-inst-backward-name)
+    ;; Skip over instantiation name
+    (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|)\\)" nil nil)  ; ) isn't word boundary
+    ;; Check for parameterized instantiations
+    (when (looking-at ")")
+      (verilog-backward-open-paren)
+      (verilog-re-search-backward-quick "\\b[a-zA-Z0-9`_\$]" nil nil))
+    (skip-chars-backward "a-zA-Z0-9'_$")
+    (looking-at "[a-zA-Z0-9`_\$]+")
+    ;; Important: don't use match string, this must work with emacs 19 font-lock on
+    (buffer-substring-no-properties (match-beginning 0) (match-end 0))))
+
+(defun verilog-read-inst-name ()
+  "Return instance_name when point is inside instantiation."
+  (save-excursion
+    (verilog-read-inst-backward-name)
+    (looking-at "[a-zA-Z0-9`_\$]+")
+    ;; Important: don't use match string, this must work with emacs 19 font-lock on
+    (buffer-substring-no-properties (match-beginning 0) (match-end 0))))
+
+(defun verilog-read-module-name ()
+  "Return module name when after its ( or ;."
+  (save-excursion
+    (re-search-backward "[(;]")
+    (verilog-re-search-backward-quick "\\b[a-zA-Z0-9`_\$]" nil nil)
+    (skip-chars-backward "a-zA-Z0-9`_$")
+    (looking-at "[a-zA-Z0-9`_\$]+")
+    ;; Important: don't use match string, this must work with emacs 19 font-lock on
+    (buffer-substring-no-properties (match-beginning 0) (match-end 0))))
+
+(defun verilog-read-auto-params (num-param &optional max-param)
+  "Return parameter list inside auto.
+Optional NUM-PARAM and MAX-PARAM check for a specific number of parameters."
+  (let ((olist))
+    (save-excursion
+      ;; /*AUTOPUNT("parameter", "parameter")*/
+      (search-backward "(")
+      (while (looking-at "(?\\s *\"\\([^\"]*\\)\"\\s *,?")
+	(setq olist (cons (match-string 1) olist))
+	(goto-char (match-end 0))))
+    (or (eq nil num-param)
+	(<= num-param (length olist))
+	(error "%s: Expected %d parameters" (verilog-point-text) num-param))
+    (if (eq max-param nil) (setq max-param num-param))
+    (or (eq nil max-param)
+	(>= max-param (length olist))
+	(error "%s: Expected <= %d parameters" (verilog-point-text) max-param))
+    (nreverse olist)))
+
+(defun verilog-read-decls ()
+  "Compute signal declaration information for the current module at point.
+Return a array of [outputs inouts inputs wire reg assign const]."
+  (let ((end-mod-point (or (verilog-get-end-of-defun t) (point-max)))
+	(functask 0) (paren 0) (sig-paren 0)
+	sigs-in sigs-out sigs-inout sigs-wire sigs-reg sigs-assign sigs-const sigs-gparam
+	vec expect-signal keywd newsig rvalue enum io signed typedefed multidim)
+    (save-excursion
+      (verilog-beg-of-defun)
+      (setq sigs-const (verilog-read-auto-constants (point) end-mod-point))
+      (while (< (point) end-mod-point)
+	;;(if dbg (setq dbg (cons (format "Pt %s  Vec %s   Kwd'%s'\n" (point) vec keywd) dbg)))
+	(cond
+	 ((looking-at "//")
+	  (if (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
+	      (setq enum (match-string 1)))
+	  (search-forward "\n"))
+	 ((looking-at "/\\*")
+	  (forward-char 2)
+	  (if (looking-at "[^*]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
+	      (setq enum (match-string 1)))
+	  (or (search-forward "*/")
+	      (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
+	 ((looking-at "(\\*")
+	  (forward-char 2)
+	  (or (looking-at "\\s-*)")   ; It's a "always @ (*)"
+	      (search-forward "*)")
+	      (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
+	 ((eq ?\" (following-char))
+	  (or (re-search-forward "[^\\]\"" nil t)	;; don't forward-char first, since we look for a non backslash first
+	      (error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
+	 ((eq ?\; (following-char))
+	  (setq vec nil  io nil  expect-signal nil  newsig nil  paren 0  rvalue nil)
+	  (forward-char 1))
+	 ((eq ?= (following-char))
+	  (setq rvalue t  newsig nil)
+	  (forward-char 1))
+	 ((and (or rvalue sig-paren)
+	       (cond ((and (eq ?, (following-char))
+			   (eq paren sig-paren))
+		      (setq rvalue nil)
+		      (forward-char 1)
+		      t)
+		     ;; ,'s can occur inside {} & funcs
+		     ((looking-at "[{(]")
+		      (setq paren (1+ paren))
+		      (forward-char 1)
+		      t)
+		     ((looking-at "[})]")
+		      (setq paren (1- paren))
+		      (forward-char 1)
+		      (when (< paren sig-paren)
+			(setq expect-signal nil))   ; ) that ends variables inside v2k arg list
+		      t)
+		     )))
+	 ((looking-at "\\s-*\\(\\[[^]]+\\]\\)")
+	  (goto-char (match-end 0))
+	  (cond (newsig	; Memory, not just width.  Patch last signal added's memory (nth 3)
+		 (setcar (cdr (cdr (cdr newsig))) (match-string 1)))
+		(vec ;; Multidimensional
+		 (setq multidim (cons vec multidim))
+		 (setq vec (verilog-string-replace-matches
+			    "\\s-+" "" nil nil (match-string 1))))
+		(t ;; Bit width
+		 (setq vec (verilog-string-replace-matches
+			    "\\s-+" "" nil nil (match-string 1))))))
+	 ;; Normal or escaped identifier -- note we remember the \ if escaped
+	 ((looking-at "\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
+	  (goto-char (match-end 0))
+	  (setq keywd (match-string 1))
+	  (when (string-match "^\\\\" keywd)
+	    (setq keywd (concat keywd " ")))  ;; Escaped ID needs space at end
+	  (cond ((equal keywd "input")
+		 (setq vec nil enum nil  rvalue nil  newsig nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+		       expect-signal 'sigs-in  io t))
+		((equal keywd "output")
+		 (setq vec nil enum nil  rvalue nil  newsig nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+		       expect-signal 'sigs-out  io t))
+		((equal keywd "inout")
+		 (setq vec nil enum nil  rvalue nil  newsig nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+		       expect-signal 'sigs-inout  io t))
+		((or (equal keywd "wire")
+		     (equal keywd "tri")
+		     (equal keywd "tri0")
+		     (equal keywd "tri1"))
+		 (unless io (setq vec nil  enum nil  rvalue nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+				  expect-signal 'sigs-wire)))
+		((or (equal keywd "reg")
+		     (equal keywd "trireg"))
+		 (unless io (setq vec nil  enum nil  rvalue nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+				  expect-signal 'sigs-reg)))
+		((equal keywd "assign")
+		 (setq vec nil  enum nil  rvalue nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+		       expect-signal 'sigs-assign))
+		((or (equal keywd "supply0")
+		     (equal keywd "supply1")
+		     (equal keywd "supply")
+		     (equal keywd "localparam"))
+		 (unless io (setq vec nil  enum nil  rvalue nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+				  expect-signal 'sigs-const)))
+		((or (equal keywd "parameter"))
+		 (unless io (setq vec nil  enum nil  rvalue nil  signed nil  typedefed nil  multidim nil  sig-paren paren
+				  expect-signal 'sigs-gparam)))
+		((equal keywd "signed")
+		 (setq signed "signed"))
+		((or (equal keywd "function")
+		     (equal keywd "task"))
+		 (setq functask (1+ functask)))
+		((or (equal keywd "endfunction")
+		     (equal keywd "endtask"))
+		 (setq functask (1- functask)))
+		((or (equal keywd "`ifdef")
+		     (equal keywd "`ifndef"))
+		 (setq rvalue t))
+		((verilog-typedef-name-p keywd)
+		 (setq typedefed keywd))
+		((and expect-signal
+		      (eq functask 0)
+		      (not rvalue)
+		      (eq paren sig-paren)
+		      (not (member keywd verilog-keywords)))
+		 ;; Add new signal to expect-signal's variable
+		 (setq newsig (list keywd vec nil nil enum signed typedefed multidim))
+		 (set expect-signal (cons newsig
+					  (symbol-value expect-signal))))))
+	 (t
+	  (forward-char 1)))
+	(skip-syntax-forward " "))
+      ;; Return arguments
+      (vector (nreverse sigs-out)
+	      (nreverse sigs-inout)
+	      (nreverse sigs-in)
+	      (nreverse sigs-wire)
+	      (nreverse sigs-reg)
+	      (nreverse sigs-assign)
+	      (nreverse sigs-const)
+	      (nreverse sigs-gparam)
+	      ))))
+
+(defvar sigs-in nil) ; Prevent compile warning
+(defvar sigs-inout nil) ; Prevent compile warning
+(defvar sigs-out nil) ; Prevent compile warning
+
+(defun verilog-read-sub-decls-sig (submodi comment port sig vec multidim)
+  "For verilog-read-sub-decls-line, add a signal."
+  (let (portdata)
+    (when sig
+      (setq port (verilog-symbol-detick-denumber port))
+      (setq sig  (verilog-symbol-detick-denumber sig))
+      (if sig (setq sig  (verilog-string-replace-matches "^[---+~!|&]+" "" nil nil sig)))
+      (if vec (setq vec  (verilog-symbol-detick-denumber vec)))
+      (if multidim (setq multidim  (mapcar `verilog-symbol-detick-denumber multidim)))
+      (unless (or (not sig)
+		  (equal sig ""))  ;; Ignore .foo(1'b1) assignments
+	(cond ((setq portdata (assoc port (verilog-modi-get-inouts submodi)))
+	       (setq sigs-inout (cons (list sig vec (concat "To/From " comment) nil nil
+					    (verilog-sig-signed portdata)
+					    (verilog-sig-type portdata)
+					    multidim)
+				      sigs-inout)))
+	      ((setq portdata (assoc port (verilog-modi-get-outputs submodi)))
+	       (setq sigs-out   (cons (list sig vec (concat "From " comment) nil nil
+					    (verilog-sig-signed portdata)
+					    (verilog-sig-type portdata)
+					    multidim)
+				      sigs-out)))
+	      ((setq portdata (assoc port (verilog-modi-get-inputs submodi)))
+	       (setq sigs-in    (cons (list sig vec (concat "To " comment) nil nil
+					    (verilog-sig-signed portdata)
+					    (verilog-sig-type portdata)
+					    multidim)
+				      sigs-in)))
+	      ;; (t  -- warning pin isn't defined.)   ; Leave for lint tool
+	      )))))
+
+(defun verilog-read-sub-decls-line (submodi comment)
+  "For read-sub-decls, read lines of port defs until none match anymore.
+Return the list of signals found, using submodi to look up each port."
+  (let (done port sig vec multidim)
+    (save-excursion
+      (forward-line 1)
+      (while (not done)
+	;; Get port name
+	(cond ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*(\\s-*")
+	       (setq port (match-string 1))
+	       (goto-char (match-end 0)))
+	      ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*(\\s-*")
+	       (setq port (concat (match-string 1) " ")) ;; escaped id's need trailing space
+	       (goto-char (match-end 0)))
+	      ((looking-at "\\s-*\\.[^(]*(")
+	       (setq port nil) ;; skip this line
+	       (goto-char (match-end 0)))
+	      (t
+	       (setq port nil  done t))) ;; Unknown, ignore rest of line
+	;; Get signal name
+	(when port
+	  (setq multidim nil)
+	  (cond ((looking-at "\\(\\\\[^ \t\n\f]*\\)\\s-*)")
+		 (setq sig (concat (match-string 1) " ") ;; escaped id's need trailing space
+		       vec nil))
+		; We intentionally ignore (non-escaped) signals with .s in them
+		; this prevents AUTOWIRE etc from noticing hierarchical sigs.
+		((looking-at "\\([^[({).]*\\)\\s-*)")
+		 (setq sig (verilog-string-remove-spaces (match-string 1))
+		       vec nil))
+		((looking-at "\\([^[({).]*\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*)")
+		 (setq sig (verilog-string-remove-spaces (match-string 1))
+		       vec (match-string 2)))
+		((looking-at "\\([^[({).]*\\)\\s-*/\\*\\(\\[[^*]+\\]\\)\\*/\\s-*)")
+		 (setq sig (verilog-string-remove-spaces (match-string 1))
+		       vec nil)
+		 (let ((parse (match-string 2)))
+		   (while (string-match "^\\(\\[[^]]+\\]\\)\\(.*\\)$" parse)
+		     (when vec (setq multidim (cons vec multidim)))
+		     (setq vec (match-string 1 parse))
+		     (setq parse (match-string 2 parse)))))
+		((looking-at "{\\(.*\\)}.*\\s-*)")
+		 (let ((mlst (split-string (match-string 1) ","))
+		       mstr)
+		   (while (setq mstr (pop mlst))
+		     ;;(unless noninteractive (message "sig: %s " mstr))
+		     (cond
+		      ((string-match "\\(['`a-zA-Z0-9_$]+\\)\\s-*$" mstr)
+		       (setq sig (verilog-string-remove-spaces (match-string 1 mstr))
+			     vec nil)
+		       ;;(unless noninteractive (message "concat sig1: %s %s" mstr (match-string 1 mstr)))
+		       )
+		      ((string-match "\\([^[({).]+\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*" mstr)
+		       (setq sig (verilog-string-remove-spaces (match-string 1 mstr))
+			     vec (match-string 2 mstr))
+		       ;;(unless noninteractive (message "concat sig2: '%s' '%s' '%s'" mstr (match-string 1 mstr) (match-string 2 mstr)))
+		       )
+		      (t
+		       (setq sig nil)))
+		     ;; Process signals
+		     (verilog-read-sub-decls-sig submodi comment port sig vec multidim))))
+		(t
+		 (setq sig nil)))
+	  ;; Process signals
+	  (verilog-read-sub-decls-sig submodi comment port sig vec multidim))
+	;;
+	(forward-line 1)))))
+
+(defun verilog-read-sub-decls ()
+  "Internally parse signals going to modules under this module.
+Return a array of [ outputs inouts inputs ] signals for modules that are
+instantiated in this module.  For example if declare A A (.B(SIG)) and SIG
+is a output, then SIG will be included in the list.
+
+This only works on instantiations created with /*AUTOINST*/ converted by
+\\[verilog-auto-inst].  Otherwise, it would have to read in the whole
+component library to determine connectivity of the design.
+
+One work around for this problem is to manually create // Inputs and //
+Outputs comments above subcell signals, for example:
+
+	module1 instance1x (
+	    // Outputs
+	    .out (out),
+	    // Inputs
+	    .in  (in));"
+  (save-excursion
+    (let ((end-mod-point (verilog-get-end-of-defun t))
+	  st-point end-inst-point
+	  ;; below 3 modified by verilog-read-sub-decls-line
+	  sigs-out sigs-inout sigs-in)
+      (verilog-beg-of-defun)
+      (while (re-search-forward "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-mod-point t)
+	(save-excursion
+	  (goto-char (match-beginning 0))
+	  (unless (verilog-inside-comment-p)
+	    ;; Attempt to snarf a comment
+	    (let* ((submod (verilog-read-inst-module))
+		   (inst (verilog-read-inst-name))
+		   (comment (concat inst " of " submod ".v")) submodi)
+	      (when (setq submodi (verilog-modi-lookup submod t))
+		;; This could have used a list created by verilog-auto-inst
+		;; However I want it to be runnable even on user's manually added signals
+		(verilog-backward-open-paren)
+		(setq end-inst-point (save-excursion (forward-sexp 1) (point))
+		      st-point (point))
+		(while (re-search-forward "\\s *(?\\s *// Outputs" end-inst-point t)
+		  (verilog-read-sub-decls-line submodi comment)) ;; Modifies sigs-out
+		(goto-char st-point)
+		(while (re-search-forward "\\s *// Inouts" end-inst-point t)
+		  (verilog-read-sub-decls-line submodi comment)) ;; Modifies sigs-inout
+		(goto-char st-point)
+		(while (re-search-forward "\\s *// Inputs" end-inst-point t)
+		  (verilog-read-sub-decls-line submodi comment)) ;; Modifies sigs-in
+		)))))
+      ;; Combine duplicate bits
+      ;;(setq rr (vector sigs-out sigs-inout sigs-in))
+      (vector (verilog-signals-combine-bus (nreverse sigs-out))
+	      (verilog-signals-combine-bus (nreverse sigs-inout))
+	      (verilog-signals-combine-bus (nreverse sigs-in))))))
+
+(defun verilog-read-inst-pins ()
+  "Return a array of [ pins ] for the current instantiation at point.
+For example if declare A A (.B(SIG)) then B will be included in the list."
+  (save-excursion
+    (let ((end-mod-point (point))	;; presume at /*AUTOINST*/ point
+	  pins pin)
+      (verilog-backward-open-paren)
+      (while (re-search-forward "\\.\\([^(,) \t\n\f]*\\)\\s-*" end-mod-point t)
+	(setq pin (match-string 1))
+	(unless (verilog-inside-comment-p)
+	  (setq pins (cons (list pin) pins))
+	  (when (looking-at "(")
+	    (forward-sexp 1))))
+      (vector pins))))
+
+(defun verilog-read-arg-pins ()
+  "Return a array of [ pins ] for the current argument declaration at point."
+  (save-excursion
+    (let ((end-mod-point (point))	;; presume at /*AUTOARG*/ point
+	  pins pin)
+      (verilog-backward-open-paren)
+      (while (re-search-forward "\\([a-zA-Z0-9$_.%`]+\\)" end-mod-point t)
+	(setq pin (match-string 1))
+	(unless (verilog-inside-comment-p)
+	  (setq pins (cons (list pin) pins))))
+      (vector pins))))
+
+(defun verilog-read-auto-constants (beg end-mod-point)
+  "Return a list of AUTO_CONSTANTs used in the region from BEG to END-MOD-POINT."
+  ;; Insert new
+  (save-excursion
+    (let (sig-list tpl-end-pt)
+      (goto-char beg)
+      (while (re-search-forward "\\<AUTO_CONSTANT" end-mod-point t)
+	(if (not (looking-at "\\s *("))
+	    (error "%s: Missing () after AUTO_CONSTANT" (verilog-point-text)))
+	(search-forward "(" end-mod-point)
+	(setq tpl-end-pt (save-excursion
+			   (backward-char 1)
+			   (forward-sexp 1)   ;; Moves to paren that closes argdecl's
+			   (backward-char 1)
+			   (point)))
+	(while (re-search-forward "\\s-*\\([\"a-zA-Z0-9$_.%`]+\\)\\s-*,*" tpl-end-pt t)
+	  (setq sig-list (cons (list (match-string 1) nil nil) sig-list))))
+      sig-list)))
+
+(defun verilog-read-auto-lisp (start end)
+  "Look for and evaluate a AUTO_LISP between START and END."
+  (save-excursion
+    (goto-char start)
+    (while (re-search-forward "\\<AUTO_LISP(" end t)
+      (backward-char)
+      (let* ((beg-pt (prog1 (point)
+		       (forward-sexp 1)))	;; Closing paren
+	     (end-pt (point)))
+	(eval-region beg-pt end-pt nil)))))
+
+(eval-when-compile
+  ;; These are passed in a let, not global
+  (if (not (boundp 'sigs-in))
+      (defvar sigs-in nil) (defvar sigs-out nil)
+      (defvar got-sig nil) (defvar got-rvalue nil) (defvar uses-delayed nil)))
+
+(defun verilog-read-always-signals-recurse
+  (exit-keywd rvalue ignore-next)
+  "Recursive routine for parentheses/bracket matching.
+EXIT-KEYWD is expression to stop at, nil if top level.
+RVALUE is true if at right hand side of equal.
+IGNORE-NEXT is true to ignore next token, fake from inside case statement."
+  (let* ((semi-rvalue (equal "endcase" exit-keywd)) ;; true if after a ; we are looking for rvalue
+	 keywd last-keywd sig-tolk sig-last-tolk gotend got-sig got-rvalue end-else-check)
+    ;;(if dbg (setq dbg (concat dbg (format "Recursion %S %S %S\n" exit-keywd rvalue ignore-next))))
+    (while (not (or (eobp) gotend))
+      (cond
+       ((looking-at "//")
+	(search-forward "\n"))
+       ((looking-at "/\\*")
+	(or (search-forward "*/")
+	    (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
+       ((looking-at "(\\*")
+	(or (looking-at "(\\*\\s-*)")   ; It's a "always @ (*)"
+	    (search-forward "*)")
+	    (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
+       (t (setq keywd (buffer-substring-no-properties
+		       (point)
+		       (save-excursion (when (eq 0 (skip-chars-forward "a-zA-Z0-9$_.%`"))
+					 (forward-char 1))
+				       (point)))
+		sig-last-tolk sig-tolk
+		sig-tolk nil)
+	  ;;(if dbg (setq dbg (concat dbg (format "\tPt=%S %S\trv=%S in=%S ee=%S\n" (point) keywd rvalue ignore-next end-else-check))))
+	  (cond
+	   ((equal keywd "\"")
+	    (or (re-search-forward "[^\\]\"" nil t)
+		(error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
+	   ;; else at top level loop, keep parsing
+	   ((and end-else-check (equal keywd "else"))
+	    ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else %s\n" keywd))))
+	    ;; no forward movement, want to see else in lower loop
+	    (setq end-else-check nil))
+	   ;; End at top level loop
+	   ((and end-else-check (looking-at "[^ \t\n\f]"))
+	    ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else-other %s\n" keywd))))
+	    (setq gotend t))
+	   ;; Final statement?
+	   ((and exit-keywd (equal keywd exit-keywd))
+	    (setq gotend t)
+	    (forward-char (length keywd)))
+	   ;; Standard tokens...
+	   ((equal keywd ";")
+	    (setq ignore-next nil  rvalue semi-rvalue)
+	    ;; Final statement at top level loop?
+	    (when (not exit-keywd)
+	      ;;(if dbg (setq dbg (concat dbg (format "\ttop-end-check %s\n" keywd))))
+	      (setq end-else-check t))
+	    (forward-char 1))
+	   ((equal keywd "'")
+	    (if (looking-at "'s?[hdxbo][0-9a-fA-F_xz? \t]*")
+		(goto-char (match-end 0))
+	      (forward-char 1)))
+	   ((equal keywd ":")	;; Case statement, begin/end label, x?y:z
+	    (cond ((equal "endcase" exit-keywd)  ;; case x: y=z; statement next
+		   (setq ignore-next nil rvalue nil))
+		  ((equal "?" exit-keywd)  ;; x?y:z rvalue
+		   ) ;; NOP
+		  (got-sig	;; label: statement
+		   (setq ignore-next nil rvalue semi-rvalue got-sig nil))
+		  ((not rvalue)	;; begin label
+		   (setq ignore-next t rvalue nil)))
+	    (forward-char 1))
+	   ((equal keywd "=")
+	    (if (eq (char-before) ?< )
+		(setq uses-delayed 1))
+	    (setq ignore-next nil rvalue t)
+	    (forward-char 1))
+	   ((equal keywd "?")
+	    (forward-char 1)
+	    (verilog-read-always-signals-recurse ":" rvalue nil))
+	   ((equal keywd "[")
+	    (forward-char 1)
+	    (verilog-read-always-signals-recurse "]" t nil))
+	   ((equal keywd "(")
+	    (forward-char 1)
+	    (cond (sig-last-tolk	;; Function call; zap last signal
+		   (setq got-sig nil)))
+	    (cond ((equal last-keywd "for")
+		   (verilog-read-always-signals-recurse ";" nil nil)
+		   (verilog-read-always-signals-recurse ";" t nil)
+		   (verilog-read-always-signals-recurse ")" nil nil))
+		  (t (verilog-read-always-signals-recurse ")" t nil))))
+	   ((equal keywd "begin")
+	    (skip-syntax-forward "w_")
+	    (verilog-read-always-signals-recurse "end" nil nil)
+	    ;;(if dbg (setq dbg (concat dbg (format "\tgot-end %s\n" exit-keywd))))
+	    (setq ignore-next nil  rvalue semi-rvalue)
+	    (if (not exit-keywd) (setq end-else-check t)))
+	   ((or (equal keywd "case")
+		(equal keywd "casex")
+		(equal keywd "casez"))
+	    (skip-syntax-forward "w_")
+	    (verilog-read-always-signals-recurse "endcase" t nil)
+	    (setq ignore-next nil  rvalue semi-rvalue)
+	    (if (not exit-keywd) (setq gotend t)))	;; top level begin/end
+	   ((string-match "^[$`a-zA-Z_]" keywd)	;; not exactly word constituent
+	    (cond ((or (equal keywd "`ifdef")
+		       (equal keywd "`ifndef"))
+		   (setq ignore-next t))
+		  ((or ignore-next
+		       (member keywd verilog-keywords)
+		       (string-match "^\\$" keywd))	;; PLI task
+		   (setq ignore-next nil))
+		  (t
+		   (setq keywd (verilog-symbol-detick-denumber keywd))
+		   (when got-sig
+		     (if got-rvalue (setq sigs-in (cons got-sig sigs-in))
+		       (setq sigs-out (cons got-sig sigs-out)))
+		     ;;(if dbg (setq dbg (concat dbg (format "\t\tgot-sig=%S rv=%S\n" got-sig got-rvalue))))
+		     )
+		   (setq got-rvalue rvalue
+			 got-sig (if (or (not keywd)
+					 (assoc keywd (if got-rvalue sigs-in sigs-out)))
+				     nil (list keywd nil nil))
+			 sig-tolk t)))
+	    (skip-chars-forward "a-zA-Z0-9$_.%`"))
+	   (t
+	    (forward-char 1)))
+	  ;; End of non-comment token
+	  (setq last-keywd keywd)
+	  ))
+      (skip-syntax-forward " "))
+    ;; Append the final pending signal
+    (when got-sig
+      (if got-rvalue (setq sigs-in (cons got-sig sigs-in))
+	(setq sigs-out (cons got-sig sigs-out)))
+      ;;(if dbg (setq dbg (concat dbg (format "\t\tgot-sig=%S rv=%S\n" got-sig got-rvalue))))
+      (setq got-sig nil))
+    ;;(if dbg (setq dbg (concat dbg (format "ENDRecursion %s\n" exit-keywd))))
+    ))
+
+(defun verilog-read-always-signals ()
+  "Parse always block at point and return list of (outputs inout inputs)."
+  ;; Insert new
+  (save-excursion
+    (let* (;;(dbg "")
+	   sigs-in sigs-out
+	   uses-delayed)	;; Found signal/rvalue; push if not function
+      (search-forward ")")
+      (verilog-read-always-signals-recurse nil nil nil)
+      ;;(if dbg (save-excursion (set-buffer (get-buffer-create "*vl-dbg*")) (delete-region (point-min) (point-max)) (insert dbg) (setq dbg "")))
+      ;; Return what was found
+      (list sigs-out nil sigs-in uses-delayed))))
+
+(defun verilog-read-instants ()
+  "Parse module at point and return list of ( ( file instance ) ... )."
+  (verilog-beg-of-defun)
+  (let* ((end-mod-point (verilog-get-end-of-defun t))
+	 (state nil)
+	 (instants-list nil))
+    (save-excursion
+      (while (< (point) end-mod-point)
+	;; Stay at level 0, no comments
+	(while (progn
+		 (setq state (parse-partial-sexp (point) end-mod-point 0 t nil))
+		 (or (> (car state) 0)	; in parens
+		     (nth 5 state)		; comment
+		     ))
+	  (forward-line 1))
+	(beginning-of-line)
+	(if (looking-at "^\\s-*\\([a-zA-Z0-9`_$]+\\)\\s-+\\([a-zA-Z0-9`_$]+\\)\\s-*(")
+	    ;;(if (looking-at "^\\(.+\\)$")
+	    (let ((module (match-string 1))
+		  (instant (match-string 2)))
+	      (if (not (member module verilog-keywords))
+		  (setq instants-list (cons (list module instant) instants-list)))))
+	(forward-line 1)
+	))
+    instants-list))
+
+
+(defun verilog-read-auto-template (module)
+  "Look for a auto_template for the instantiation of the given MODULE.
+If found returns the signal name connections.  Return REGEXP and
+list of ( (signal_name connection_name)... )"
+  (save-excursion
+    ;; Find beginning
+    (let ((tpl-regexp "\\([0-9]+\\)")
+	  (lineno 0)
+	  (templateno 0)
+	  tpl-sig-list tpl-wild-list tpl-end-pt rep)
+      (cond ((or
+	       (re-search-backward (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)
+	       (progn
+		 (goto-char (point-min))
+		 (re-search-forward (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)))
+	     (goto-char (match-end 0))
+	     ;; Parse "REGEXP"
+	     ;; We reserve @"..." for future lisp expressions that evaluate once-per-AUTOINST
+	     (when (looking-at "\\s-*\"\\([^\"]*)\\)\"")
+	       (setq tpl-regexp (match-string 1))
+	       (goto-char (match-end 0)))
+	     (search-forward "(")
+	     ;; Parse lines in the template
+	     (when verilog-auto-inst-template-numbers
+	       (save-excursion
+		 (goto-char (point-min))
+		 (while (search-forward "AUTO_TEMPLATE" nil t)
+		   (setq templateno (1+ templateno)))))
+	     (setq tpl-end-pt (save-excursion
+				(backward-char 1)
+				(forward-sexp 1)   ;; Moves to paren that closes argdecl's
+				(backward-char 1)
+				(point)))
+	     ;;
+	     (while (< (point) tpl-end-pt)
+	       (cond ((looking-at "\\s-*\\.\\([a-zA-Z0-9`_$]+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
+		      (setq tpl-sig-list (cons (list
+						(match-string-no-properties 1)
+						(match-string-no-properties 2)
+						templateno lineno)
+					       tpl-sig-list))
+		      (goto-char (match-end 0)))
+		     ;; Regexp form??
+		     ((looking-at
+		       ;; Regexp bug in xemacs disallows ][ inside [], and wants + last
+		       "\\s-*\\.\\(\\([a-zA-Z0-9`_$+@^.*?|---]+\\|[][]\\|\\\\[()|]\\)+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
+		      (setq rep (match-string-no-properties 3))
+		      (goto-char (match-end 0))
+		      (setq tpl-wild-list
+			    (cons (list
+				   (concat "^"
+					   (verilog-string-replace-matches "@" "\\\\([0-9]+\\\\)" nil nil
+									   (match-string 1))
+					   "$")
+				   rep
+				   templateno lineno)
+				  tpl-wild-list)))
+		     ((looking-at "[ \t\f]+")
+		      (goto-char (match-end 0)))
+		     ((looking-at "\n")
+		      (setq lineno (1+ lineno))
+		      (goto-char (match-end 0)))
+		     ((looking-at "//")
+		      (search-forward "\n"))
+		     ((looking-at "/\\*")
+		      (forward-char 2)
+		      (or (search-forward "*/")
+			  (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
+		     (t
+		      (error "%s: AUTO_TEMPLATE parsing error: %s"
+			     (verilog-point-text)
+			     (progn (looking-at ".*$") (match-string 0))))
+		     ))
+	     ;; Return
+	     (vector tpl-regexp
+		     (list tpl-sig-list tpl-wild-list)))
+	    ;; If no template found
+	    (t (vector tpl-regexp nil))))))
+;;(progn (find-file "auto-template.v") (verilog-read-auto-template "ptl_entry"))
+
+(defun verilog-set-define (defname defvalue &optional buffer enumname)
+  "Set the definition DEFNAME to the DEFVALUE in the given BUFFER.
+Optionally associate it with the specified enumeration ENUMNAME."
+  (save-excursion
+    (set-buffer (or buffer (current-buffer)))
+    (let ((mac (intern (concat "vh-" defname))))
+      ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
+      ;; Need to define to a constant if no value given
+      (set (make-variable-buffer-local mac)
+	   (if (equal defvalue "") "1" defvalue)))
+    (if enumname
+	(let ((enumvar (intern (concat "venum-" enumname))))
+	  ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
+	  (make-variable-buffer-local enumvar)
+	  (add-to-list enumvar defname)))
+    ))
+
+(defun verilog-read-defines (&optional filename recurse subcall)
+  "Read `defines and parameters for the current file, or optional FILENAME.
+If the filename is provided, `verilog-library-flags' will be used to
+resolve it.  If optional RECURSE is non-nil, recurse through `includes.
+
+Parameters must be simple assignments to constants, or have their own
+\"parameter\" label rather than a list of parameters.  Thus:
+
+    parameter X = 5, Y = 10;	// Ok
+    parameter X = {1'b1, 2'h2};	// Ok
+    parameter X = {1'b1, 2'h2}, Y = 10;	// Bad, make into 2 parameter lines
+
+Defines must be simple text substitutions, one on a line, starting
+at the beginning of the line.  Any ifdefs or multiline comments around the
+define are ignored.
+
+Defines are stored inside Emacs variables using the name vh-{definename}.
+
+This function is useful for setting vh-* variables.  The file variables
+feature can be used to set defines that `verilog-mode' can see; put at the
+*END* of your file something like:
+
+    // Local Variables:
+    // vh-macro:\"macro_definition\"
+    // End:
+
+If macros are defined earlier in the same file and you want their values,
+you can read them automatically (provided `enable-local-eval' is on):
+
+    // Local Variables:
+    // eval:(verilog-read-defines)
+    // eval:(verilog-read-defines \"group_standard_includes.v\")
+    // End:
+
+Note these are only read when the file is first visited, you must use
+\\[find-alternate-file] RET  to have these take effect after editing them!
+
+If you want to disable the \"Process `eval' or hook local variables\"
+warning message, you need to add to your .emacs file:
+
+    (setq enable-local-eval t)"
+  (let ((origbuf (current-buffer)))
+    (save-excursion
+      (unless subcall (verilog-getopt-flags))
+      (when filename
+	(let ((fns (verilog-library-filenames filename (buffer-file-name))))
+	  (if fns
+	      (set-buffer (find-file-noselect (car fns)))
+	    (error (concat (verilog-point-text)
+			   ": Can't find verilog-read-defines file: " filename)))))
+      (when recurse
+	(goto-char (point-min))
+	(while (re-search-forward "^\\s-*`include\\s-+\\([^ \t\n\f]+\\)" nil t)
+	  (let ((inc (verilog-string-replace-matches "\"" "" nil nil (match-string-no-properties 1))))
+	    (unless (verilog-inside-comment-p)
+	      (verilog-read-defines inc recurse t)))))
+      ;; Read `defines
+      ;; note we don't use verilog-re... it's faster this way, and that
+      ;; function has problems when comments are at the end of the define
+      (goto-char (point-min))
+      (while (re-search-forward "^\\s-*`define\\s-+\\([a-zA-Z0-9_$]+\\)\\s-+\\(.*\\)$" nil t)
+	(let ((defname (match-string-no-properties 1))
+	      (defvalue (match-string-no-properties 2)))
+	  (setq defvalue (verilog-string-replace-matches "\\s-*/[/*].*$" "" nil nil defvalue))
+	  (verilog-set-define defname defvalue origbuf)))
+      ;; Hack: Read parameters
+      (goto-char (point-min))
+      (while (re-search-forward
+	      "^\\s-*\\(parameter\\|localparam\\)\\(\\(\\s-*\\[[^]]*\\]\\|\\)\\s-+\\([a-zA-Z0-9_$]+\\)\\s-*=\\s-*\\([^;,]*\\),?\\|\\)\\s-*" nil t)
+	(let ((var (match-string-no-properties 4))
+	      (val (match-string-no-properties 5))
+	      enumname)
+	  ;; The primary way of getting defines is verilog-read-decls
+	  ;; However, that isn't called yet for included files, so we'll add another scheme
+	  (if (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
+	      (setq enumname (match-string-no-properties 1)))
+	  (if var
+	    (verilog-set-define var val origbuf enumname))
+	  (forward-comment 999)
+	  (while (looking-at "\\s-*,?\\s-*\\([a-zA-Z0-9_$]+\\)\\s-*=\\s-*\\([^;,]*\\),?\\s-*")
+	    (verilog-set-define (match-string-no-properties 1) (match-string-no-properties 2) origbuf enumname)
+	    (goto-char (match-end 0))
+	    (forward-comment 999))))
+      )))
+
+(defun verilog-read-includes ()
+  "Read `includes for the current file.
+This will find all of the `includes which are at the beginning of lines,
+ignoring any ifdefs or multiline comments around them.
+`verilog-read-defines' is then performed on the current and each included
+file.
+
+It is often useful put at the *END* of your file something like:
+
+    // Local Variables:
+    // eval:(verilog-read-defines)
+    // eval:(verilog-read-includes)
+    // End:
+
+Note includes are only read when the file is first visited, you must use
+\\[find-alternate-file] RET  to have these take effect after editing them!
+
+It is good to get in the habit of including all needed files in each .v
+file that needs it, rather than waiting for compile time.  This will aid
+this process, Verilint, and readability.  To prevent defining the same
+variable over and over when many modules are compiled together, put a test
+around the inside each include file:
+
+foo.v (a include):
+	`ifdef _FOO_V	// include if not already included
+	`else
+	`define _FOO_V
+	... contents of file
+	`endif // _FOO_V"
+;;slow:  (verilog-read-defines nil t))
+  (save-excursion
+    (verilog-getopt-flags)
+    (goto-char (point-min))
+    (while (re-search-forward "^\\s-*`include\\s-+\\([^ \t\n\f]+\\)" nil t)
+      (let ((inc (verilog-string-replace-matches "\"" "" nil nil (match-string 1))))
+	(verilog-read-defines inc nil t)))))
+
+(defun verilog-read-signals (&optional start end)
+  "Return a simple list of all possible signals in the file.
+Bounded by optional region from START to END.  Overly aggressive but fast.
+Some macros and such are also found and included.  For dinotrace.el"
+  (let (sigs-all keywd)
+    (progn;save-excursion
+      (goto-char (or start (point-min)))
+      (setq end (or end (point-max)))
+      (while (re-search-forward "[\"/a-zA-Z_.%`]" end t)
+	(forward-char -1)
+	(cond
+	 ((looking-at "//")
+	  (search-forward "\n"))
+	 ((looking-at "/\\*")
+	  (search-forward "*/"))
+	 ((looking-at "(\\*")
+	  (or (looking-at "(\\*\\s-*)")   ; It's a "always @ (*)"
+	      (search-forward "*)")))
+	 ((eq ?\" (following-char))
+	  (re-search-forward "[^\\]\""))	;; don't forward-char first, since we look for a non backslash first
+	 ((looking-at "\\s-*\\([a-zA-Z0-9$_.%`]+\\)")
+	  (goto-char (match-end 0))
+	  (setq keywd (match-string-no-properties 1))
+	  (or (member keywd verilog-keywords)
+	      (member keywd sigs-all)
+	      (setq sigs-all (cons keywd sigs-all))))
+	 (t (forward-char 1)))
+	)
+      ;; Return list
+      sigs-all)))
+
+;;
+;; Argument file parsing
+;;
+
+(defun verilog-getopt (arglist)
+  "Parse -f, -v etc arguments in ARGLIST list or string."
+  (unless (listp arglist) (setq arglist (list arglist)))
+  (let ((space-args '())
+	arg next-param)
+    ;; Split on spaces, so users can pass whole command lines
+    (while arglist
+      (setq arg (car arglist)
+	    arglist (cdr arglist))
+      (while (string-match "^\\([^ \t\n\f]+\\)[ \t\n\f]*\\(.*$\\)" arg)
+	(setq space-args (append space-args
+				 (list (match-string-no-properties 1 arg))))
+	(setq arg (match-string 2 arg))))
+    ;; Parse arguments
+    (while space-args
+      (setq arg (car space-args)
+	    space-args (cdr space-args))
+      (cond
+       ;; Need another arg
+       ((equal arg "-f")
+	(setq next-param arg))
+       ((equal arg "-v")
+	(setq next-param arg))
+       ((equal arg "-y")
+	(setq next-param arg))
+       ;; +libext+(ext1)+(ext2)...
+       ((string-match "^\\+libext\\+\\(.*\\)" arg)
+	(setq arg (match-string 1 arg))
+	(while (string-match "\\([^+]+\\)\\+?\\(.*\\)" arg)
+	  (verilog-add-list-unique `verilog-library-extensions
+				   (match-string 1 arg))
+	  (setq arg (match-string 2 arg))))
+       ;;
+       ((or (string-match "^-D\\([^+=]*\\)[+=]\\(.*\\)" arg)	;; -Ddefine=val
+	    (string-match "^-D\\([^+=]*\\)\\(\\)" arg)	;; -Ddefine
+	    (string-match "^\\+define\\([^+=]*\\)[+=]\\(.*\\)" arg)	;; +define+val
+	    (string-match "^\\+define\\([^+=]*\\)\\(\\)" arg))		;; +define+define
+	(verilog-set-define (match-string 1 arg) (match-string 2 arg)))
+       ;;
+       ((or (string-match "^\\+incdir\\+\\(.*\\)" arg)	;; +incdir+dir
+	    (string-match "^-I\\(.*\\)" arg))	;; -Idir
+	(verilog-add-list-unique `verilog-library-directories
+				 (match-string 1 arg)))
+       ;; Ignore
+       ((equal "+librescan" arg))
+       ((string-match "^-U\\(.*\\)" arg))	;; -Udefine
+       ;; Second parameters
+       ((equal next-param "-f")
+	(setq next-param nil)
+	(verilog-getopt-file arg))
+       ((equal next-param "-v")
+	(setq next-param nil)
+	(verilog-add-list-unique `verilog-library-files arg))
+       ((equal next-param "-y")
+	(setq next-param nil)
+	(verilog-add-list-unique `verilog-library-directories arg))
+       ;; Filename
+       ((string-match "^[^-+]" arg)
+	(verilog-add-list-unique `verilog-library-files arg))
+       ;; Default - ignore; no warning
+       )
+      )
+    )
+  )
+;;(verilog-getopt (list "+libext+.a+.b" "+incdir+foodir" "+define+a+aval" "-f" "otherf" "-v" "library" "-y" "dir"))
+
+(defun verilog-getopt-file (filename)
+  "Read verilog options from the specified FILENAME."
+  (save-excursion
+    (let ((fns (verilog-library-filenames filename (buffer-file-name)))
+	  (orig-buffer (current-buffer))
+	  line)
+      (if fns
+	  (set-buffer (find-file-noselect (car fns)))
+	(error (concat (verilog-point-text)
+		       "Can't find verilog-getopt-file -f file: " filename)))
+      (goto-char (point-min))
+      (while (not (eobp))
+	(setq line (buffer-substring (point)
+				     (save-excursion (end-of-line) (point))))
+	(forward-line 1)
+	(when (string-match "//" line)
+	  (setq line (substring line 0 (match-beginning 0))))
+	(save-excursion
+	  (set-buffer orig-buffer)  ; Variables are buffer-local, so need right context.
+	  (verilog-getopt line))))))
+
+(defun verilog-getopt-flags ()
+  "Convert `verilog-library-flags' into standard library variables."
+  ;; If the flags are local, then all the outputs should be local also
+  (when (local-variable-p `verilog-library-flags (current-buffer))
+    (make-variable-buffer-local 'verilog-library-extensions)
+    (make-variable-buffer-local 'verilog-library-directories)
+    (make-variable-buffer-local 'verilog-library-files)
+    (make-variable-buffer-local 'verilog-library-flags))
+  ;; Allow user to customize
+  (run-hooks 'verilog-before-getopt-flags-hook)
+  ;; Process arguments
+  (verilog-getopt verilog-library-flags)
+  ;; Allow user to customize
+  (run-hooks 'verilog-getopt-flags-hook))
+
+(defun verilog-add-list-unique (varref object)
+  "Append to VARREF list the given OBJECT,
+unless it is already a member of the variable's list"
+  (unless (member object (symbol-value varref))
+    (set varref (append (symbol-value varref) (list object))))
+  varref)
+;;(progn (setq l '()) (verilog-add-list-unique `l "a") (verilog-add-list-unique `l "a") l)
+
+
+;;
+;; Module name lookup
+;;
+
+(defun verilog-module-inside-filename-p (module filename)
+  "Return point if MODULE is specified inside FILENAME, else nil.
+Allows version control to check out the file if need be."
+  (and (or (file-exists-p filename)
+	   (and
+	    (condition-case nil
+		(fboundp 'vc-backend)
+	      (error nil))
+	    (vc-backend filename)))
+       (let (pt)
+	 (save-excursion
+	   (set-buffer (find-file-noselect filename))
+	   (goto-char (point-min))
+	   (while (and
+		   ;; It may be tempting to look for verilog-defun-re, don't, it slows things down a lot!
+		   (verilog-re-search-forward-quick "\\<module\\>" nil t)
+		   (verilog-re-search-forward-quick "[(;]" nil t))
+	     (if (equal module (verilog-read-module-name))
+		 (setq pt (point))))
+	   pt))))
+
+(defun verilog-is-number (symbol)
+  "Return true if SYMBOL is number-like."
+  (or (string-match "^[0-9 \t:]+$" symbol)
+      (string-match "^[---]*[0-9]+$" symbol)
+      (string-match "^[0-9 \t]+'s?[hdxbo][0-9a-fA-F_xz? \t]*$" symbol)
+      ))
+
+(defun verilog-symbol-detick (symbol wing-it)
+  "Return a expanded SYMBOL name without any defines.
+If the variable vh-{symbol} is defined, return that value.
+If undefined, and WING-IT, return just SYMBOL without the tick, else nil."
+  (while (and symbol (string-match "^`" symbol))
+    (setq symbol (substring symbol 1))
+    (setq symbol
+	  (if (boundp (intern (concat "vh-" symbol)))
+	      ;; Emacs has a bug where boundp on a buffer-local
+	      ;; variable in only one buffer returns t in another.
+	      ;; This can confuse, so check for nil.
+	      (let ((val (eval (intern (concat "vh-" symbol)))))
+		(if (eq val nil)
+		    (if wing-it symbol nil)
+		  val))
+	    (if wing-it symbol nil))))
+  symbol)
+;;(verilog-symbol-detick "`mod" nil)
+
+(defun verilog-symbol-detick-denumber (symbol)
+  "Return SYMBOL with defines converted and any numbers dropped to nil."
+  (when (string-match "^`" symbol)
+    ;; This only will work if the define is a simple signal, not
+    ;; something like a[b].  Sorry, it should be substituted into the parser
+    (setq symbol
+	  (verilog-string-replace-matches
+	   "\[[^0-9: \t]+\]" "" nil nil
+	   (or (verilog-symbol-detick symbol nil)
+	       (if verilog-auto-sense-defines-constant
+		   "0"
+		 symbol)))))
+  (if (verilog-is-number symbol)
+      nil
+    symbol))
+
+(defun verilog-symbol-detick-text (text)
+  "Return TEXT with any without any known defines.
+If the variable vh-{symbol} is defined, substitute that value."
+  (let ((ok t) symbol val)
+    (while (and ok (string-match "`\\([a-zA-Z0-9_]+\\)" text))
+      (setq symbol (match-string 1 text))
+      (message symbol)
+      (cond ((and
+	      (boundp (intern (concat "vh-" symbol)))
+	      ;; Emacs has a bug where boundp on a buffer-local
+	      ;; variable in only one buffer returns t in another.
+	      ;; This can confuse, so check for nil.
+	      (setq val (eval (intern (concat "vh-" symbol)))))
+	     (setq text (replace-match val nil nil text)))
+	    (t (setq ok nil)))))
+  text)
+;;(progn (setq vh-mod "`foo" vh-foo "bar") (verilog-symbol-detick-text "bar `mod `undefed"))
+
+(defun verilog-expand-dirnames (&optional dirnames)
+  "Return a list of existing directories given a list of wildcarded DIRNAMES.
+Or, just the existing dirnames themselves if there are no wildcards."
+  (interactive)
+  (unless dirnames (error "`verilog-library-directories' should include at least '.'"))
+  (setq dirnames (reverse dirnames))	; not nreverse
+  (let ((dirlist nil)
+	pattern dirfile dirfiles dirname root filename rest)
+    (while dirnames
+      (setq dirname (substitute-in-file-name (car dirnames))
+	    dirnames (cdr dirnames))
+      (cond ((string-match (concat "^\\(\\|[/\\]*[^*?]*[/\\]\\)"  ;; root
+				   "\\([^/\\]*[*?][^/\\]*\\)"	  ;; filename with *?
+				   "\\(.*\\)")			  ;; rest
+			   dirname)
+	     (setq root (match-string 1 dirname)
+		   filename (match-string 2 dirname)
+		   rest (match-string 3 dirname)
+		   pattern filename)
+	     ;; now replace those * and ? with .+ and .
+	     ;; use ^ and /> to get only whole file names
+	     ;;verilog-string-replace-matches
+	     (setq pattern (verilog-string-replace-matches "[*]" ".+" nil nil pattern)
+		   pattern (verilog-string-replace-matches "[?]" "." nil nil pattern)
+
+		   ;; Unfortunately allows abc/*/rtl to match abc/rtl
+		   ;; because abc/.. shows up in dirfiles.  Solutions welcome.
+		   dirfiles (if (file-directory-p root)	; Ignore version control external
+				(directory-files root t pattern nil)))
+	     (while dirfiles
+	       (setq dirfile (expand-file-name (concat (car dirfiles) rest))
+		     dirfiles (cdr dirfiles))
+	       (if (file-directory-p dirfile)
+		   (setq dirlist (cons dirfile dirlist))))
+	     )
+	    ;; Defaults
+	    (t
+	     (if (file-directory-p dirname)
+		 (setq dirlist (cons dirname dirlist))))
+	    ))
+    dirlist))
+;;(verilog-expand-dirnames (list "." ".." "nonexist" "../*" "/home/wsnyder/*/v"))
+
+(defun verilog-library-filenames (filename current &optional check-ext)
+  "Return a search path to find the given FILENAME name.
+Uses the CURRENT filename, `verilog-library-directories' and
+`verilog-library-extensions' variables to build the path.
+With optional CHECK-EXT also check `verilog-library-extensions'."
+  (let ((ckdir (verilog-expand-dirnames verilog-library-directories))
+	fn outlist)
+    (while ckdir
+      (let ((ckext (if check-ext verilog-library-extensions `(""))))
+	(while ckext
+	  (setq fn (expand-file-name
+		    (concat filename (car ckext))
+		    (expand-file-name (car ckdir) (file-name-directory current))))
+	  (if (file-exists-p fn)
+	      (setq outlist (cons fn outlist)))
+	  (setq ckext (cdr ckext))))
+      (setq ckdir (cdr ckdir)))
+    (nreverse outlist)))
+
+(defun verilog-module-filenames (module current)
+  "Return a search path to find the given MODULE name.
+Uses the CURRENT filename, `verilog-library-extensions',
+`verilog-library-directories' and `verilog-library-files'
+variables to build the path."
+  ;; Return search locations for it
+  (append (list current)		; first, current buffer
+	  (verilog-library-filenames module current t)
+	  verilog-library-files))	; finally, any libraries
+
+;;
+;; Module Information
+;;
+;; Many of these functions work on "modi" a module information structure
+;; A modi is:  [module-name-string file-name begin-point]
+
+(defvar verilog-cache-enabled t
+  "If true, enable caching of signals, etc.  Set to nil for debugging to make things SLOW!")
+
+(defvar verilog-modi-cache-list nil
+  "Cache of ((Module Function) Buf-Tick Buf-Modtime Func-Returns)...
+For speeding up verilog-modi-get-* commands.
+Buffer-local.")
+
+(defvar verilog-modi-cache-preserve-tick nil
+  "Modification tick after which the cache is still considered valid.
+Use verilog-preserve-cache's to set")
+(defvar verilog-modi-cache-preserve-buffer nil
+  "Modification tick after which the cache is still considered valid.
+Use verilog-preserve-cache's to set")
+
+(defun verilog-modi-current ()
+  "Return the modi structure for the module currently at point."
+  (let* (name pt)
+    ;; read current module's name
+    (save-excursion
+      (verilog-re-search-backward-quick verilog-defun-re nil nil)
+      (verilog-re-search-forward-quick "(" nil nil)
+      (setq name (verilog-read-module-name))
+      (setq pt (point)))
+    ;; return
+    (vector name (or (buffer-file-name) (current-buffer)) pt)))
+
+(defvar verilog-modi-lookup-last-mod nil "Cache of last module looked up.")
+(defvar verilog-modi-lookup-last-modi nil "Cache of last modi returned.")
+(defvar verilog-modi-lookup-last-current nil "Cache of last `current-buffer' looked up.")
+(defvar verilog-modi-lookup-last-tick nil "Cache of last `buffer-modified-tick' looked up.")
+
+(defun verilog-modi-lookup (module allow-cache &optional ignore-error)
+  "Find the file and point at which MODULE is defined.
+If ALLOW-CACHE is set, check and remember cache of previous lookups.
+Return modi if successful, else print message unless IGNORE-ERROR is true."
+  (let* ((current (or (buffer-file-name) (current-buffer))))
+    (cond ((and verilog-modi-lookup-last-modi
+		verilog-cache-enabled
+		allow-cache
+		(equal verilog-modi-lookup-last-mod module)
+		(equal verilog-modi-lookup-last-current current)
+		(equal verilog-modi-lookup-last-tick (buffer-modified-tick)))
+	   ;; ok as is
+	   )
+	  (t (let* ((realmod (verilog-symbol-detick module t))
+		    (orig-filenames (verilog-module-filenames realmod current))
+		    (filenames orig-filenames)
+		    pt)
+	       (while (and filenames (not pt))
+		 (if (not (setq pt (verilog-module-inside-filename-p realmod (car filenames))))
+		     (setq filenames (cdr filenames))))
+	       (cond (pt (setq verilog-modi-lookup-last-modi
+			       (vector realmod (car filenames) pt)))
+		     (t (setq verilog-modi-lookup-last-modi nil)
+			(or ignore-error
+			    (error (concat (verilog-point-text)
+					   ": Can't locate " module " module definition"
+					   (if (not (equal module realmod))
+					       (concat " (Expanded macro to " realmod ")")
+					     "")
+					   "\n    Check the verilog-library-directories variable."
+					   "\n    I looked in (if not listed, doesn't exist):\n\t"
+					   (mapconcat 'concat orig-filenames "\n\t")))))
+		     )
+	       (setq verilog-modi-lookup-last-mod module
+		     verilog-modi-lookup-last-current current
+		     verilog-modi-lookup-last-tick (buffer-modified-tick)))))
+    verilog-modi-lookup-last-modi
+    ))
+
+(defsubst verilog-modi-name (modi)
+  (aref modi 0))
+(defsubst verilog-modi-file-or-buffer (modi)
+  (aref modi 1))
+(defsubst verilog-modi-point (modi)
+  (aref modi 2))
+
+(defun verilog-modi-filename (modi)
+  "Filename of MODI, or name of buffer if its never been saved."
+  (if (bufferp (verilog-modi-file-or-buffer modi))
+      (or (buffer-file-name (verilog-modi-file-or-buffer modi))
+	  (buffer-name (verilog-modi-file-or-buffer modi)))
+    (verilog-modi-file-or-buffer modi)))
+
+(defun verilog-modi-goto (modi)
+  "Move point/buffer to specified MODI."
+  (or modi (error "Passed unfound modi to goto, check earlier"))
+  (set-buffer (if (bufferp (verilog-modi-file-or-buffer modi))
+		  (verilog-modi-file-or-buffer modi)
+		(find-file-noselect (verilog-modi-file-or-buffer modi))))
+  (or (equal major-mode `verilog-mode)	;; Put into verilog mode to get syntax
+      (verilog-mode))
+  (goto-char (verilog-modi-point modi)))
+
+(defun verilog-goto-defun-file (module)
+  "Move point to the file at which a given MODULE is defined."
+  (interactive "sGoto File for Module: ")
+  (let* ((modi (verilog-modi-lookup module nil)))
+    (when modi
+      (verilog-modi-goto modi)
+      (switch-to-buffer (current-buffer)))))
+
+(defun verilog-modi-cache-results (modi function)
+  "Run on MODI the given FUNCTION.  Locate the module in a file.
+Cache the output of function so next call may have faster access."
+  (let (func-returns fass)
+    (save-excursion
+      (verilog-modi-goto modi)
+      (if (and (setq fass (assoc (list (verilog-modi-name modi) function)
+				 verilog-modi-cache-list))
+	       ;; Destroy caching when incorrect; Modified or file changed
+	       (not (and verilog-cache-enabled
+			 (or (equal (buffer-modified-tick) (nth 1 fass))
+			     (and verilog-modi-cache-preserve-tick
+				  (<= verilog-modi-cache-preserve-tick  (nth 1 fass))
+				  (equal  verilog-modi-cache-preserve-buffer (current-buffer))))
+			 (equal (visited-file-modtime) (nth 2 fass)))))
+	  (setq verilog-modi-cache-list nil
+		fass nil))
+      (cond (fass
+	     ;; Found
+	     (setq func-returns (nth 3 fass)))
+	    (t
+	     ;; Read from file
+	     ;; Clear then restore any hilighting to make emacs19 happy
+	     (let ((fontlocked (when (and (boundp 'font-lock-mode)
+					  font-lock-mode)
+				 (font-lock-mode nil)
+				 t)))
+	       (setq func-returns (funcall function))
+	       (when fontlocked (font-lock-mode t)))
+	     ;; Cache for next time
+	     (make-variable-buffer-local 'verilog-modi-cache-list)
+	     (setq verilog-modi-cache-list
+		   (cons (list (list (verilog-modi-name modi) function)
+			       (buffer-modified-tick)
+			       (visited-file-modtime)
+			       func-returns)
+			 verilog-modi-cache-list)))
+	    ))
+      ;;
+      func-returns))
+
+(defun verilog-modi-cache-add (modi function element sig-list)
+  "Add function return results to the module cache.
+Update MODI's cache for given FUNCTION so that the return ELEMENT of that
+function now contains the additional SIG-LIST parameters."
+  (let (fass)
+    (save-excursion
+      (verilog-modi-goto modi)
+      (if (setq fass (assoc (list (verilog-modi-name modi) function)
+			    verilog-modi-cache-list))
+	  (let ((func-returns (nth 3 fass)))
+	    (aset func-returns element
+		  (append sig-list (aref func-returns element))))))))
+
+(defmacro verilog-preserve-cache (&rest body)
+  "Execute the BODY forms, allowing cache preservation within BODY.
+This means that changes to the buffer will not result in the cache being
+flushed.  If the changes affect the modsig state, they must call the
+modsig-cache-add-* function, else the results of later calls may be
+incorrect.  Without this, changes are assumed to be adding/removing signals
+and invalidating the cache."
+  `(let ((verilog-modi-cache-preserve-tick (buffer-modified-tick))
+	 (verilog-modi-cache-preserve-buffer (current-buffer)))
+     (progn ,@body)))
+
+(defsubst verilog-modi-get-decls (modi)
+  (verilog-modi-cache-results modi 'verilog-read-decls))
+
+(defsubst verilog-modi-get-sub-decls (modi)
+  (verilog-modi-cache-results modi 'verilog-read-sub-decls))
+
+;; Signal reading for given module
+;; Note these all take modi's - as returned from the verilog-modi-current function
+(defsubst verilog-modi-get-outputs (modi)
+  (aref (verilog-modi-get-decls modi) 0))
+(defsubst verilog-modi-get-inouts (modi)
+  (aref (verilog-modi-get-decls modi) 1))
+(defsubst verilog-modi-get-inputs (modi)
+  (aref (verilog-modi-get-decls modi) 2))
+(defsubst verilog-modi-get-wires (modi)
+  (aref (verilog-modi-get-decls modi) 3))
+(defsubst verilog-modi-get-regs (modi)
+  (aref (verilog-modi-get-decls modi) 4))
+(defsubst verilog-modi-get-assigns (modi)
+  (aref (verilog-modi-get-decls modi) 5))
+(defsubst verilog-modi-get-consts (modi)
+  (aref (verilog-modi-get-decls modi) 6))
+(defsubst verilog-modi-get-gparams (modi)
+  (aref (verilog-modi-get-decls modi) 7))
+(defsubst verilog-modi-get-sub-outputs (modi)
+  (aref (verilog-modi-get-sub-decls modi) 0))
+(defsubst verilog-modi-get-sub-inouts (modi)
+  (aref (verilog-modi-get-sub-decls modi) 1))
+(defsubst verilog-modi-get-sub-inputs (modi)
+  (aref (verilog-modi-get-sub-decls modi) 2))
+
+
+(defun verilog-signals-matching-enum (in-list enum)
+  "Return all signals in IN-LIST matching the given ENUM."
+  (let (out-list)
+    (while in-list
+      (if (equal (verilog-sig-enum (car in-list)) enum)
+	  (setq out-list (cons (car in-list) out-list)))
+      (setq in-list (cdr in-list)))
+    ;; New scheme
+    (let* ((enumvar (intern (concat "venum-" enum)))
+	   (enumlist (and (boundp enumvar) (eval enumvar))))
+      (while enumlist
+	(add-to-list 'out-list (list (car enumlist)))
+	(setq enumlist (cdr enumlist))))
+    (nreverse out-list)))
+
+(defun verilog-signals-not-matching-regexp (in-list regexp)
+  "Return all signals in IN-LIST not matching the given REGEXP, if non-nil."
+  (if (not regexp)
+      in-list
+    (let (out-list)
+      (while in-list
+	(if (not (string-match regexp (verilog-sig-name (car in-list))))
+	    (setq out-list (cons (car in-list) out-list)))
+	(setq in-list (cdr in-list)))
+      (nreverse out-list))))
+
+;; Combined
+(defun verilog-modi-get-signals (modi)
+  (append
+   (verilog-modi-get-outputs modi)
+   (verilog-modi-get-inouts modi)
+   (verilog-modi-get-inputs modi)
+   (verilog-modi-get-wires modi)
+   (verilog-modi-get-regs modi)
+   (verilog-modi-get-assigns modi)
+   (verilog-modi-get-consts modi)
+   (verilog-modi-get-gparams modi)))
+
+(defun verilog-modi-get-ports (modi)
+  (append
+   (verilog-modi-get-outputs modi)
+   (verilog-modi-get-inouts modi)
+   (verilog-modi-get-inputs modi)))
+
+(defsubst verilog-modi-cache-add-outputs (modi sig-list)
+  (verilog-modi-cache-add modi 'verilog-read-decls 0 sig-list))
+(defsubst verilog-modi-cache-add-inouts (modi sig-list)
+  (verilog-modi-cache-add modi 'verilog-read-decls 1 sig-list))
+(defsubst verilog-modi-cache-add-inputs (modi sig-list)
+  (verilog-modi-cache-add modi 'verilog-read-decls 2 sig-list))
+(defsubst verilog-modi-cache-add-wires (modi sig-list)
+  (verilog-modi-cache-add modi 'verilog-read-decls 3 sig-list))
+(defsubst verilog-modi-cache-add-regs (modi sig-list)
+  (verilog-modi-cache-add modi 'verilog-read-decls 4 sig-list))
+
+(defun verilog-signals-from-signame (signame-list)
+  "Return signals in standard form from SIGNAME-LIST, a simple list of signal names."
+  (mapcar (function (lambda (name) (list name nil nil)))
+	  signame-list))
+
+;;
+;; Auto creation utilities
+;;
+
+(defun verilog-auto-search-do (search-for func)
+  "Search for the given auto text SEARCH-FOR, and perform FUNC where it occurs."
+  (goto-char (point-min))
+  (while (search-forward search-for nil t)
+    (if (not (save-excursion
+	       (goto-char (match-beginning 0))
+	       (verilog-inside-comment-p)))
+	(funcall func))))
+
+(defun verilog-auto-re-search-do (search-for func)
+  "Search for the given auto text SEARCH-FOR, and perform FUNC where it occurs."
+  (goto-char (point-min))
+  (while (re-search-forward search-for nil t)
+    (if (not (save-excursion
+	       (goto-char (match-beginning 0))
+	       (verilog-inside-comment-p)))
+	(funcall func))))
+
+(defun verilog-insert-one-definition (sig type indent-pt)
+  "Print out a definition for SIGNAL of the given TYPE,
+with appropriate INDENT-PT indentation."
+  (indent-to indent-pt)
+  (insert type)
+  (when (verilog-sig-signed sig)
+    (insert " " (verilog-sig-signed sig)))
+  (when (verilog-sig-multidim sig)
+    (insert " " (verilog-sig-multidim-string sig)))
+  (when (verilog-sig-bits sig)
+    (insert " " (verilog-sig-bits sig)))
+  (indent-to (max 24 (+ indent-pt 16)))
+  (unless (= (char-syntax (preceding-char)) ?\  )
+    (insert " "))  ; Need space between "]name" if indent-to did nothing
+  (insert (verilog-sig-name sig)))
+
+(defun verilog-insert-definition (sigs direction indent-pt v2k &optional dont-sort)
+  "Print out a definition for a list of SIGS of the given DIRECTION,
+with appropriate INDENT-PT indentation.  If V2K, use Verilog 2001 I/O
+format.  Sort unless DONT-SORT.  DIRECTION is normally wire/reg/output."
+  (or dont-sort
+      (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
+  (while sigs
+    (let ((sig (car sigs)))
+      (verilog-insert-one-definition
+       sig
+       ;; Want "type x" or "output type x", not "wire type x"
+       (cond ((verilog-sig-type sig)
+	      (concat
+	       (if (not (equal direction "wire"))
+		   (concat direction " "))
+	       (verilog-sig-type sig)))
+	     (t direction))
+       indent-pt)
+      (insert (if v2k "," ";"))
+      (if (or (not (verilog-sig-comment sig))
+	      (equal "" (verilog-sig-comment sig)))
+	  (insert "\n")
+	(indent-to (max 48 (+ indent-pt 40)))
+	(insert (concat "// " (verilog-sig-comment sig) "\n")))
+      (setq sigs (cdr sigs)))))
+
+(eval-when-compile
+  (if (not (boundp 'indent-pt))
+      (defvar indent-pt nil "Local used by insert-indent")))
+
+(defun verilog-insert-indent (&rest stuff)
+  "Indent to position stored in local `indent-pt' variable, then insert STUFF.
+Presumes that any newlines end a list element."
+  (let ((need-indent t))
+    (while stuff
+      (if need-indent (indent-to indent-pt))
+      (setq need-indent nil)
+      (insert (car stuff))
+      (setq need-indent (string-match "\n$" (car stuff))
+	    stuff (cdr stuff)))))
+;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n"))
+
+(defun verilog-repair-open-comma ()
+  "If backwards-from-point is other than a open parenthesis insert comma."
+  (save-excursion
+    (verilog-backward-syntactic-ws)
+    (when (save-excursion
+	    (backward-char 1)
+	    (and (not (looking-at "[(,]"))
+		 (progn
+		   (verilog-re-search-backward "[(`]" nil t)
+		   (looking-at "("))))
+    (insert ","))))
+
+(defun verilog-repair-close-comma ()
+  "If point is at a comma followed by a close parenthesis, fix it.
+This repairs those mis-inserted by a AUTOARG."
+  ;; It would be much nicer if Verilog allowed extra commas like Perl does!
+  (save-excursion
+    (verilog-forward-close-paren)
+    (backward-char 1)
+    (verilog-backward-syntactic-ws)
+    (backward-char 1)
+    (when (looking-at ",")
+      (delete-char 1))))
+
+(defun verilog-get-list (start end)
+  "Return the elements of a comma separated list between START and END."
+  (interactive)
+  (let ((my-list (list))
+	my-string)
+    (save-excursion
+      (while (< (point) end)
+	(when (re-search-forward "\\([^,{]+\\)" end t)
+	  (setq my-string (verilog-string-remove-spaces (match-string 1)))
+	  (setq my-list (nconc my-list (list my-string) ))
+	  (goto-char (match-end 0))))
+      my-list)))
+
+(defun verilog-make-width-expression (range-exp)
+  "Return an expression calculating the length of a range [x:y] in RANGE-EXP."
+  ;; strip off the []
+  (cond ((not range-exp)
+	 "1")
+	(t
+	 (if (string-match "^\\[\\(.*\\)\\]$" range-exp)
+	     (setq range-exp (match-string 1 range-exp)))
+	 (cond ((not range-exp)
+		"1")
+	       ((string-match "^\\s *\\([0-9]+\\)\\s *:\\s *\\([0-9]+\\)\\s *$" range-exp)
+		(int-to-string (1+ (abs (- (string-to-int (match-string 1 range-exp))
+					   (string-to-int (match-string 2 range-exp)))))))
+	       ((string-match "^\\(.*\\)\\s *:\\s *\\(.*\\)\\s *$" range-exp)
+		(concat "(1+(" (match-string 1 range-exp)
+			")"
+			(if (equal "0" (match-string 2 range-exp))  ;; Don't bother with -(0)
+			    ""
+			  (concat "-(" (match-string 2 range-exp) ")"))
+			")"))
+	       (t nil)))))
+;;(verilog-make-width-expression "`A:`B")
+
+(defun verilog-typedef-name-p (variable-name)
+  "Return true if the VARIABLE-NAME is a type definition."
+  (when verilog-typedef-regexp
+    (string-match verilog-typedef-regexp variable-name)))
+
+;;
+;; Auto deletion
+;;
+
+(defun verilog-delete-autos-lined ()
+  "Delete autos that occupy multiple lines, between begin and end comments."
+  (let ((pt (point)))
+    (forward-line 1)
+    (when (and
+	   (looking-at "\\s-*// Beginning")
+	   (search-forward "// End of automatic" nil t))
+      ;; End exists
+      (end-of-line)
+      (delete-region pt (point))
+      (forward-line 1))
+  ))
+
+(defun verilog-forward-close-paren ()
+  "Find the close parenthesis that match the current point,
+ignore other close parenthesis with matching open parens"
+  (let ((parens 1))
+    (while (> parens 0)
+      (unless (verilog-re-search-forward-quick "[()]" nil t)
+	(error "%s: Mismatching ()" (verilog-point-text)))
+      (cond ((= (preceding-char) ?\( )
+	     (setq parens (1+ parens)))
+	    ((= (preceding-char) ?\) )
+	     (setq parens (1- parens)))))))
+
+(defun verilog-backward-open-paren ()
+  "Find the open parenthesis that match the current point,
+ignore other open parenthesis with matching close parens"
+  (let ((parens 1))
+    (while (> parens 0)
+      (unless (verilog-re-search-backward-quick "[()]" nil t)
+	(error "%s: Mismatching ()" (verilog-point-text)))
+      (cond ((= (following-char) ?\) )
+	     (setq parens (1+ parens)))
+	    ((= (following-char) ?\( )
+	     (setq parens (1- parens)))))))
+
+(defun verilog-backward-open-bracket ()
+  "Find the open bracket that match the current point,
+ignore other open bracket with matching close bracket"
+  (let ((parens 1))
+    (while (> parens 0)
+      (unless (verilog-re-search-backward-quick "[][]" nil t)
+	(error "%s: Mismatching []" (verilog-point-text)))
+      (cond ((= (following-char) ?\] )
+	     (setq parens (1+ parens)))
+	    ((= (following-char) ?\[ )
+	     (setq parens (1- parens)))))))
+
+(defun verilog-delete-to-paren ()
+  "Delete the automatic inst/sense/arg created by autos.
+Deletion stops at the matching end parenthesis."
+  (delete-region (point)
+		 (save-excursion
+		   (verilog-backward-open-paren)
+		   (forward-sexp 1)   ;; Moves to paren that closes argdecl's
+		   (backward-char 1)
+		   (point))))
+
+(defun verilog-auto-star-safe ()
+  "Return if a .* AUTOINST is safe to delete or expand.
+It was created by the AUTOS themselves, or by the user."
+  (and verilog-auto-star-expand
+       (looking-at "[ \t\n\f,]*\\([)]\\|// \\(Outputs\\|Inouts\\|Inputs\\)\\)")))
+
+(defun verilog-delete-auto-star-all ()
+  "Delete a .* AUTOINST, if it is safe."
+  (when (verilog-auto-star-safe)
+    (verilog-delete-to-paren)))
+
+(defun verilog-delete-auto-star-implicit ()
+  "Delete all .* implicit connections created by `verilog-auto-star'.
+This function will be called automatically at save unless
+`verilog-auto-star-save' is set, any non-templated expanded pins will be
+removed."
+  (interactive)
+  (let (paren-pt indent have-close-paren)
+    (save-excursion
+      (goto-char (point-min))
+      ;; We need to match these even outside of comments.
+      ;; For reasonable performance, we don't check if inside comments, sorry.
+      (while (re-search-forward "// Implicit \\.\\*" nil t)
+	(setq paren-pt (point))
+	(beginning-of-line)
+	(setq have-close-paren
+	      (save-excursion
+		(when (search-forward ");" paren-pt t)
+		  (setq indent (current-indentation))
+		  t)))
+	(delete-region (point) (+ 1 paren-pt))  ; Nuke line incl CR
+	(when have-close-paren
+	  ;; Delete extra commentary
+	  (save-excursion
+	    (while (progn
+		     (forward-line -1)
+		     (looking-at "\\s *//\\s *\\(Outputs\\|Inouts\\|Inputs\\)\n"))
+	      (delete-region (match-beginning 0) (match-end 0))))
+	  ;; If it is simple, we can put the ); on the same line as the last text
+	  (let ((rtn-pt (point)))
+	    (save-excursion
+	      (while (progn (backward-char 1)
+			    (looking-at "[ \t\n\f]")))
+	      (when (looking-at ",")
+		(delete-region (+ 1 (point)) rtn-pt))))
+	  (when (bolp)
+	    (indent-to indent))
+	  (insert ");\n")
+	  ;; Still need to kill final comma - always is one as we put one after the .*
+	  (re-search-backward ",")
+	  (delete-char 1))))))
+
+(defun verilog-delete-auto ()
+  "Delete the automatic outputs, regs, and wires created by \\[verilog-auto].
+Use \\[verilog-auto] to re-insert the updated AUTOs.
+
+The hooks `verilog-before-delete-auto-hook' and `verilog-delete-auto-hook' are
+called before and after this function, respectively."
+  (interactive)
+  (save-excursion
+    (if (buffer-file-name)
+	(find-file-noselect (buffer-file-name)))	;; To check we have latest version
+    ;; Allow user to customize
+    (run-hooks 'verilog-before-delete-auto-hook)
+
+    ;; Remove those that have multi-line insertions
+    (verilog-auto-re-search-do "/\\*AUTO\\(OUTPUTEVERY\\|CONCATCOMMENT\\|WIRE\\|REG\\|DEFINEVALUE\\|REGINPUT\\|INPUT\\|OUTPUT\\|INOUT\\|RESET\\|TIEOFF\\|UNUSED\\)\\*/"
+			       'verilog-delete-autos-lined)
+    ;; Remove those that have multi-line insertions with parameters
+    (verilog-auto-re-search-do "/\\*AUTO\\(INOUTMODULE\\|ASCIIENUM\\)([^)]*)\\*/"
+			       'verilog-delete-autos-lined)
+    ;; Remove those that are in parenthesis
+    (verilog-auto-re-search-do "/\\*\\(AS\\|AUTO\\(ARG\\|CONCATWIDTH\\|INST\\|INSTPARAM\\|SENSE\\)\\)\\*/"
+			       'verilog-delete-to-paren)
+    ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
+    (verilog-auto-re-search-do "\\.\\*"
+			       'verilog-delete-auto-star-all)
+    ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
+    (goto-char (point-min))
+    (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)[ \tLT0-9]*$" nil t)
+      (replace-match ""))
+
+    ;; Final customize
+    (run-hooks 'verilog-delete-auto-hook)))
+
+;;
+;; Auto inject
+;;
+
+(defun verilog-inject-auto ()
+  "Examine legacy non-AUTO code and insert AUTOs in appropriate places.
+
+Any always @ blocks with sensitivity lists that match computed lists will
+be replaced with /*AS*/ comments.
+
+Any cells will get /*AUTOINST*/ added to the end of the pin list.  Pins with
+have identical names will be deleted.
+
+Argument lists will not be deleted, /*AUTOARG*/ will only be inserted to
+support adding new ports.  You may wish to delete older ports yourself.
+
+For example:
+
+	module ex_inject (i, o);
+	  input i;
+	  input j;
+	  output o;
+	  always @ (i or j)
+	     o = i | j;
+	  cell cell (.foobar(baz),
+		     .j(j));
+	endmodule
+
+Typing \\[verilog-inject-auto] will make this into:
+
+	module ex_inject (i, o/*AUTOARG*/
+	  // Inputs
+	  j);
+	  input i;
+	  output o;
+	  always @ (/*AS*/i or j)
+	     o = i | j;
+	  cell cell (.foobar(baz),
+		     /*AUTOINST*/
+		     // Outputs
+		     .j(j));
+	endmodule"
+  (interactive)
+  (verilog-auto t))
+
+(defun verilog-inject-arg ()
+  "Inject AUTOARG into new code.  See `verilog-inject-auto'."
+  ;; Presume one module per file.
+  (save-excursion
+    (goto-char (point-min))
+    (while (verilog-re-search-forward-quick "\\<module\\>" nil t)
+      (let ((endmodp (save-excursion
+		       (verilog-re-search-forward-quick "\\<endmodule\\>" nil t)
+		       (point))))
+	;; See if there's already a comment .. inside a comment so not verilog-re-search
+	(when (not (re-search-forward "/\\*AUTOARG\\*/" endmodp t))
+	  (verilog-re-search-forward-quick ";" nil t)
+	  (backward-char 1)
+	  (verilog-backward-syntactic-ws)
+	  (backward-char 1) ; Moves to paren that closes argdecl's
+	  (when (looking-at ")")
+	    (insert "/*AUTOARG*/")))))))
+
+(defun verilog-inject-sense ()
+  "Inject AUTOSENSE into new code.  See `verilog-inject-auto'."
+  (save-excursion
+    (goto-char (point-min))
+    (while (verilog-re-search-forward-quick "\\<always\\s *@\\s *(" nil t)
+      (let ((start-pt (point))
+	    (modi (verilog-modi-current))
+	    pre-sigs
+	    got-sigs)
+	(backward-char 1)
+	(forward-sexp 1)
+	(backward-char 1) ;; End )
+	(when (not (verilog-re-search-backward "/\\*\\(AUTOSENSE\\|AS\\)\\*/" start-pt t))
+	  (setq pre-sigs (verilog-signals-from-signame
+			  (verilog-read-signals start-pt (point)))
+		got-sigs (verilog-auto-sense-sigs modi nil))
+	  (when (not (or (verilog-signals-not-in pre-sigs got-sigs)  ; Both are equal?
+			 (verilog-signals-not-in got-sigs pre-sigs)))
+	    (delete-region start-pt (point))
+	    (insert "/*AS*/")))))))
+
+(defun verilog-inject-inst ()
+  "Inject AUTOINST into new code.  See `verilog-inject-auto'."
+  (save-excursion
+    (goto-char (point-min))
+    ;; It's hard to distinguish modules; we'll instead search for pins.
+    (while (verilog-re-search-forward-quick "\\.\\s *[a-zA-Z0-9`_\$]+\\s *(\\s *[a-zA-Z0-9`_\$]+\\s *)" nil t)
+      (verilog-backward-open-paren) ;; Inst start
+      (cond
+       ((= (preceding-char) ?\#)  ;; #(...) parameter section, not pin.  Skip.
+	(forward-char 1)
+	(verilog-forward-close-paren)) ;; Parameters done
+       (t
+	(forward-char 1)
+	(let ((indent-pt (+ (current-column)))
+	      (end-pt (save-excursion (verilog-forward-close-paren) (point))))
+	  (cond ((verilog-re-search-forward "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-pt t)
+		 (goto-char end-pt)) ;; Already there, continue search with next instance
+		(t
+		 ;; Delete identical interconnect
+		 (let ((case-fold-search nil))  ;; So we don't convert upper-to-lower, etc
+		   (while (verilog-re-search-forward "\\.\\s *\\([a-zA-Z0-9`_\$]+\\)*\\s *(\\s *\\1\\s *)\\s *" end-pt t)
+		     (delete-region (match-beginning 0) (match-end 0))
+		     (setq end-pt (- end-pt (- (match-end 0) (match-beginning 0)))) ;; Keep it correct
+		     (while (or (looking-at "[ \t\n\f,]+")
+				(looking-at "//[^\n]*"))
+		       (delete-region (match-beginning 0) (match-end 0))
+		       (setq end-pt (- end-pt (- (match-end 0) (match-beginning 0)))))))
+		 (verilog-forward-close-paren)
+		 (backward-char 1)
+		 ;; Not verilog-re-search, as we don't want to strip comments
+		 (while (re-search-backward "[ \t\n\f]+" (- (point) 1) t)
+		   (delete-region (match-beginning 0) (match-end 0)))
+		 (insert "\n")
+		 (indent-to indent-pt)
+		 (insert "/*AUTOINST*/")))))))))
+
+;;
+;; Auto save
+;;
+
+(defun verilog-auto-save-check ()
+  "On saving see if we need auto update."
+  (cond ((not verilog-auto-save-policy)) ; disabled
+	((not (save-excursion
+		(save-match-data
+		  (let ((case-fold-search nil))
+		    (goto-char (point-min))
+		    (re-search-forward "AUTO" nil t))))))
+	((eq verilog-auto-save-policy 'force)
+	 (verilog-auto))
+	((not (buffer-modified-p)))
+	((eq verilog-auto-update-tick (buffer-modified-tick))) ; up-to-date
+	((eq verilog-auto-save-policy 'detect)
+	 (verilog-auto))
+	(t
+	 (when (yes-or-no-p "AUTO statements not recomputed, do it now? ")
+	   (verilog-auto))
+	 ;; Don't ask again if didn't update
+	 (set (make-local-variable 'verilog-auto-update-tick) (buffer-modified-tick))
+	 ))
+  (when (not verilog-auto-star-save)
+    (verilog-delete-auto-star-implicit))
+  nil)	;; Always return nil -- we don't write the file ourselves
+
+(defun verilog-auto-read-locals ()
+  "Return file local variable segment at bottom of file."
+  (save-excursion
+    (goto-char (point-max))
+    (if (re-search-backward "Local Variables:" nil t)
+	(buffer-substring-no-properties (point) (point-max))
+      "")))
+
+(defun verilog-auto-reeval-locals (&optional force)
+  "Read file local variable segment at bottom of file if it has changed.
+If FORCE, always reread it."
+  (make-variable-buffer-local 'verilog-auto-last-file-locals)
+  (let ((curlocal (verilog-auto-read-locals)))
+    (when (or force (not (equal verilog-auto-last-file-locals curlocal)))
+      (setq verilog-auto-last-file-locals curlocal)
+      ;; Note this may cause this function to be recursively invoked.
+      ;; The above when statement will prevent it from recursing forever.
+      (hack-local-variables)
+      t)))
+
+;;
+;; Auto creation
+;;
+
+(defun verilog-auto-arg-ports (sigs message indent-pt)
+  "Print a list of ports for a AUTOINST.
+Takes SIGS list, adds MESSAGE to front and inserts each at INDENT-PT."
+  (when sigs
+    (insert "\n")
+    (indent-to indent-pt)
+    (insert message)
+    (insert "\n")
+    (let ((space ""))
+      (indent-to indent-pt)
+      (while sigs
+	(cond ((> (+ 2 (current-column) (length (verilog-sig-name (car sigs)))) fill-column)
+	       (insert "\n")
+	       (indent-to indent-pt))
+	      (t (insert space)))
+	(insert (verilog-sig-name (car sigs)) ",")
+	(setq sigs (cdr sigs)
+	      space " ")))))
+
+(defun verilog-auto-arg ()
+  "Expand AUTOARG statements.
+Replace the argument declarations at the beginning of the
+module with ones automatically derived from input and output
+statements.  This can be dangerous if the module is instantiated
+using position-based connections, so use only name-based when
+instantiating the resulting module.  Long lines are split based
+on the `fill-column', see \\[set-fill-column].
+
+Limitations:
+  Concatenation and outputting partial busses is not supported.
+
+  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+
+For example:
+
+	module ex_arg (/*AUTOARG*/);
+	  input i;
+	  output o;
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_arg (/*AUTOARG*/
+	  // Outputs
+	  o,
+	  // Inputs
+	  i
+	);
+	  input i;
+	  output o;
+	endmodule
+
+Any ports declared between the ( and /*AUTOARG*/ are presumed to be
+predeclared and are not redeclared by AUTOARG.  AUTOARG will make a
+conservative guess on adding a comma for the first signal, if you have any
+ifdefs or complicated expressions before the AUTOARG you will need to
+choose the comma yourself.
+
+Avoid declaring ports manually, as it makes code harder to maintain."
+  (save-excursion
+    (let ((modi (verilog-modi-current))
+	  (skip-pins (aref (verilog-read-arg-pins) 0)))
+      (verilog-repair-open-comma)
+      (verilog-auto-arg-ports (verilog-signals-not-in
+			       (verilog-modi-get-outputs modi)
+			       skip-pins)
+			      "// Outputs"
+			      verilog-indent-level-declaration)
+      (verilog-auto-arg-ports (verilog-signals-not-in
+			       (verilog-modi-get-inouts modi)
+			       skip-pins)
+			      "// Inouts"
+			      verilog-indent-level-declaration)
+      (verilog-auto-arg-ports (verilog-signals-not-in
+			       (verilog-modi-get-inputs modi)
+			       skip-pins)
+			      "// Inputs"
+			      verilog-indent-level-declaration)
+      (verilog-repair-close-comma)
+      (unless (eq (char-before) ?/ )
+	(insert "\n"))
+      (indent-to verilog-indent-level-declaration)
+      )))
+
+(defun verilog-auto-inst-port-map (port-st)
+  nil)
+
+(defvar vector-skip-list nil) ; Prevent compile warning
+(defvar vl-cell-type nil "See `verilog-auto-inst'.") ; Prevent compile warning
+(defvar vl-cell-name nil "See `verilog-auto-inst'.") ; Prevent compile warning
+(defvar vl-name  nil "See `verilog-auto-inst'.") ; Prevent compile warning
+(defvar vl-width nil "See `verilog-auto-inst'.") ; Prevent compile warning
+(defvar vl-dir   nil "See `verilog-auto-inst'.") ; Prevent compile warning
+
+(defun verilog-auto-inst-port (port-st indent-pt tpl-list tpl-num for-star)
+  "Print out a instantiation connection for this PORT-ST.
+Insert to INDENT-PT, use template TPL-LIST.
+@ are instantiation numbers, replaced with TPL-NUM.
+@\"(expression @)\" are evaluated, with @ as a variable."
+  (let* ((port (verilog-sig-name port-st))
+	 (tpl-ass (or (assoc port (car tpl-list))
+		      (verilog-auto-inst-port-map port-st)))
+	 ;; vl-* are documented for user use
+	 (vl-name (verilog-sig-name port-st))
+	 (vl-width (verilog-sig-width port-st))
+	 (vl-bits (if (or verilog-auto-inst-vector
+			  (not (assoc port vector-skip-list))
+			  (not (equal (verilog-sig-bits port-st)
+				      (verilog-sig-bits (assoc port vector-skip-list)))))
+		      (or (verilog-sig-bits port-st) "")
+		    ""))
+	 ;; Default if not found
+	 (tpl-net (if (verilog-sig-multidim port-st)
+		      (concat port "/*" (verilog-sig-multidim-string port-st)
+			      vl-bits "*/")
+		    (concat port vl-bits)))
+	 (case-fold-search nil))
+    ;; Find template
+    (cond (tpl-ass	    ; Template of exact port name
+	   (setq tpl-net (nth 1 tpl-ass)))
+	  ((nth 1 tpl-list) ; Wildcards in template, search them
+	   (let ((wildcards (nth 1 tpl-list)))
+	     (while wildcards
+	       (when (string-match (nth 0 (car wildcards)) port)
+		 (setq tpl-ass (car wildcards)  ; so allow @ parsing
+		       tpl-net (replace-match (nth 1 (car wildcards))
+					      t nil port)))
+	       (setq wildcards (cdr wildcards))))))
+    ;; Parse Templated variable
+    (when tpl-ass
+      ;; Evaluate @"(lispcode)"
+      (when (string-match "@\".*[^\\]\"" tpl-net)
+	(while (string-match "@\"\\(\\([^\\\"]*\\(\\\\.\\)*\\)*\\)\"" tpl-net)
+	  (setq tpl-net
+		(concat
+		 (substring tpl-net 0 (match-beginning 0))
+		 (save-match-data
+		   (let* ((expr (match-string 1 tpl-net))
+			  (value
+			   (progn
+			     (setq expr (verilog-string-replace-matches "\\\\\"" "\"" nil nil expr))
+			     (setq expr (verilog-string-replace-matches "@" tpl-num nil nil expr))
+			     (prin1 (eval (car (read-from-string expr)))
+				    (lambda (ch) ())))))
+		     (if (numberp value) (setq value (number-to-string value)))
+		     value
+		     ))
+		 (substring tpl-net (match-end 0))))))
+      ;; Replace @ and [] magic variables in final output
+      (setq tpl-net (verilog-string-replace-matches "@" tpl-num nil nil tpl-net))
+      (setq tpl-net (verilog-string-replace-matches "\\[\\]" vl-bits nil nil tpl-net))
+      )
+    (indent-to indent-pt)
+    (insert "." port)
+    (indent-to verilog-auto-inst-column)
+    (insert "(" tpl-net "),")
+    (cond (tpl-ass
+	   (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
+			 verilog-auto-inst-column))
+	   (insert " // Templated")
+	   (when verilog-auto-inst-template-numbers
+	     (insert " T" (int-to-string (nth 2 tpl-ass))
+		     " L" (int-to-string (nth 3 tpl-ass)))))
+	  (for-star
+	   (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
+			 verilog-auto-inst-column))
+	   (insert " // Implicit .\*"))) ;For some reason the . or * must be escaped...
+    (insert "\n")))
+;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
+;;(x "incom[@\"(+ (* 8 @) 7)\":@\"(* 8 @)\"]")
+;;(x ".out (outgo[@\"(concat (+ (* 8 @) 7) \\\":\\\" ( * 8 @))\"]));")
+
+(defun verilog-auto-inst-first ()
+  "Insert , etc before first ever port in this instant, as part of \\[verilog-auto-inst]."
+  ;; Do we need a trailing comma?
+  ;; There maybe a ifdef or something similar before us.  What a mess.  Thus
+  ;; to avoid trouble we only insert on preceeding ) or *.
+  ;; Insert first port on new line
+  (insert "\n")  ;; Must insert before search, so point will move forward if insert comma
+  (save-excursion
+    (verilog-re-search-backward "[^ \t\n\f]" nil nil)
+    (when (looking-at ")\\|\\*")  ;; Generally don't insert, unless we are fairly sure
+      (forward-char 1)
+      (insert ","))))
+
+(defun verilog-auto-star ()
+  "Expand SystemVerilog .* pins, as part of \\[verilog-auto].
+
+If `verilog-auto-star-expand' is set, .* pins are treated if they were
+AUTOINST statements, otherwise they are ignored.  For safety, Verilog-Mode
+will also ignore any .* that are not last in your pin list (this prevents
+it from deleting pins following the .* when it expands the AUTOINST.)
+
+On writing your file, unless `verilog-auto-star-save' is set, any
+non-templated expanded pins will be removed.  You may do this at any time
+with \\[verilog-delete-auto-star-implicit].
+
+If you are converting a module to use .* for the first time, you may wish
+to use \\[verilog-inject-auto] and then replace the created AUTOINST with .*.
+
+See `verilog-auto-inst' for examples, templates, and more information."
+  (when (verilog-auto-star-safe)
+    (verilog-auto-inst)))
+
+(defun verilog-auto-inst ()
+  "Expand AUTOINST statements, as part of \\[verilog-auto].
+Replace the pin connections to an instantiation with ones
+automatically derived from the module header of the instantiated netlist.
+
+If `verilog-auto-star-expand' is set, also expand SystemVerilog .* ports,
+and delete them before saving unless `verilog-auto-star-save' is set.
+See `verilog-auto-star' for more information.
+
+Limitations:
+  Module names must be resolvable to filenames by adding a
+  `verilog-library-extensions', and being found in the same directory, or
+  by changing the variable `verilog-library-flags' or
+  `verilog-library-directories'.  Macros `modname are translated through the
+  vh-{name} Emacs variable, if that is not found, it just ignores the `.
+
+  In templates you must have one signal per line, ending in a ), or ));,
+  and have proper () nesting, including a final ); to end the template.
+
+  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+
+  SystemVerilog multidimmensional input/output has only experimental support.
+
+For example, first take the submodule inst.v:
+
+	module inst (o,i)
+	   output [31:0] o;
+	   input i;
+	   wire [31:0] o = {32{i}};
+	endmodule
+
+This is then used in a upper level module:
+
+	module ex_inst (o,i)
+	   output o;
+	   input i;
+	   inst inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_inst (o,i)
+	   output o;
+	   input i;
+	   inst inst (/*AUTOINST*/
+		      // Outputs
+		      .ov			(ov[31:0]),
+		      // Inputs
+		      .i			(i));
+	endmodule
+
+Where the list of inputs and outputs came from the inst module.
+
+Exceptions:
+
+  Unless you are instantiating a module multiple times, or the module is
+  something trivial like a adder, DO NOT CHANGE SIGNAL NAMES ACROSS HIERARCHY.
+  It just makes for unmaintainable code.  To sanitize signal names, try
+  vrename from http://www.veripool.com
+
+  When you need to violate this suggestion there are two ways to list
+  exceptions, placing them before the AUTOINST, or using templates.
+
+  Any ports defined before the /*AUTOINST*/ are not included in the list of
+  automatics.  This is similar to making a template as described below, but
+  is restricted to simple connections just like you normally make.  Also note
+  that any signals before the AUTOINST will only be picked up by AUTOWIRE if
+  you have the appropriate // Input or // Output comment, and exactly the
+  same line formatting as AUTOINST itself uses.
+
+	inst inst (// Inputs
+		   .i		(my_i_dont_mess_with_it),
+		   /*AUTOINST*/
+		   // Outputs
+		   .ov		(ov[31:0]));
+
+
+Templates:
+
+  For multiple instantiations based upon a single template, create a
+  commented out template:
+
+	/* instantiating_module_name AUTO_TEMPLATE (
+		.sig3	(sigz[]),
+		);
+	*/
+
+  Templates go ABOVE the instantiation(s).  When a instantiation is
+  expanded `verilog-mode' simply searches up for the closest template.
+  Thus you can have multiple templates for the same module, just alternate
+  between the template for a instantiation and the instantiation itself.
+
+  The module name must be the same as the name of the module in the
+  instantiation name, and the code \"AUTO_TEMPLATE\" must be in these exact
+  words and capitalized.  Only signals that must be different for each
+  instantiation need to be listed.
+
+  Inside a template, a [] in a connection name (with nothing else inside
+  the brackets) will be replaced by the same bus subscript as it is being
+  connected to, or the [] will be removed if it is a single bit signal.
+  Generally it is a good idea to do this for all connections in a template,
+  as then they will work for any width signal, and with AUTOWIRE.  See
+  PTL_BUS becoming PTL_BUSNEW below.
+
+  If you have a complicated template, set `verilog-auto-inst-template-numbers'
+  to see which regexps are matching.  Don't leave that mode set after
+  debugging is completed though, it will result in lots of extra differences
+  and merge conflicts.
+
+  For example:
+
+	/* psm_mas AUTO_TEMPLATE (
+		.ptl_bus	(ptl_busnew[]),
+		);
+	*/
+	psm_mas ms2m (/*AUTOINST*/);
+
+  Typing \\[verilog-auto] will make this into:
+
+	psm_mas ms2m (/*AUTOINST*/
+	    // Outputs
+	    .NotInTemplate	(NotInTemplate),
+	    .ptl_bus		(ptl_busnew[3:0]),  // Templated
+	    ....
+
+@ Templates:
+
+  It is common to instantiate a cell multiple times, so templates make it
+  trivial to substitute part of the cell name into the connection name.
+
+	/* cell_type AUTO_TEMPLATE <optional \"REGEXP\"> (
+		.sig1	(sigx[@]),
+		.sig2	(sigy[@\"(% (+ 1 @) 4)\"]),
+		);
+	*/
+
+  If no regular expression is provided immediately after the AUTO_TEMPLATE
+  keyword, then the @ character in any connection names will be replaced
+  with the instantiation number; the first digits found in the cell's
+  instantiation name.
+
+  If a regular expression is provided, the @ character will be replaced
+  with the first \(\) grouping that matches against the cell name.  Using a
+  regexp of \"\\([0-9]+\\)\" provides identical values for @ as when no
+  regexp is provided.  If you use multiple layers of parenthesis,
+  \"test\\([^0-9]+\\)_\\([0-9]+\\)\" would replace @ with non-number
+  characters after test and before _, whereas
+  \"\\(test\\([a-z]+\\)_\\([0-9]+\\)\\)\" would replace @ with the entire
+  match.
+
+  For example:
+
+	/* psm_mas AUTO_TEMPLATE (
+		.ptl_mapvalidx		(ptl_mapvalid[@]),
+		.ptl_mapvalidp1x	(ptl_mapvalid[@\"(% (+ 1 @) 4)\"]),
+		);
+	*/
+	psm_mas ms2m (/*AUTOINST*/);
+
+  Typing \\[verilog-auto] will make this into:
+
+	psm_mas ms2m (/*AUTOINST*/
+	    // Outputs
+	    .ptl_mapvalidx		(ptl_mapvalid[2]),
+	    .ptl_mapvalidp1x		(ptl_mapvalid[3]));
+
+  Note the @ character was replaced with the 2 from \"ms2m\".
+
+  Alternatively, using a regular expression for @:
+
+	/* psm_mas AUTO_TEMPLATE \"_\\([a-z]+\\)\" (
+		.ptl_mapvalidx		(@_ptl_mapvalid),
+		.ptl_mapvalidp1x	(ptl_mapvalid_@),
+		);
+	*/
+	psm_mas ms2_FOO (/*AUTOINST*/);
+	psm_mas ms2_BAR (/*AUTOINST*/);
+
+  Typing \\[verilog-auto] will make this into:
+
+	psm_mas ms2_FOO (/*AUTOINST*/
+	    // Outputs
+	    .ptl_mapvalidx		(FOO_ptl_mapvalid),
+	    .ptl_mapvalidp1x		(ptl_mapvalid_FOO));
+	psm_mas ms2_BAR (/*AUTOINST*/
+	    // Outputs
+	    .ptl_mapvalidx		(BAR_ptl_mapvalid),
+	    .ptl_mapvalidp1x		(ptl_mapvalid_BAR));
+
+
+Regexp Templates:
+
+  A template entry of the form
+
+	    .pci_req\\([0-9]+\\)_l	(pci_req_jtag_[\\1]),
+
+  will apply a Emacs style regular expression search for any port beginning
+  in pci_req followed by numbers and ending in _l and connecting that to
+  the pci_req_jtag_[] net, with the bus subscript coming from what matches
+  inside the first set of \\( \\).  Thus pci_req2_l becomes pci_req_jtag_[2].
+
+  Since \\([0-9]+\\) is so common and ugly to read, a @ in the port name
+  does the same thing. (Note a @ in the connection/replacement text is
+  completely different -- still use \\1 there!)  Thus this is the same as
+  the above template:
+
+	    .pci_req@_l		(pci_req_jtag_[\\1]),
+
+  Here's another example to remove the _l, useful when naming conventions
+  specify _ alone to mean active low.  Note the use of [] to keep the bus
+  subscript:
+
+	    .\\(.*\\)_l		(\\1_[]),
+
+Lisp Templates:
+
+  First any regular expression template is expanded.
+
+  If the syntax @\"( ... )\" is found in a connection, the expression in
+  quotes will be evaluated as a Lisp expression, with @ replaced by the
+  instantiation number.  The MAPVALIDP1X example above would put @+1 modulo
+  4 into the brackets.  Quote all double-quotes inside the expression with
+  a leading backslash (\\\").  There are special variables defined that are
+  useful in these Lisp functions:
+
+	vl-name        Name portion of the input/output port
+	vl-bits        Bus bits portion of the input/output port ('[2:0]')
+	vl-width       Width of the input/output port ('3' for [2:0])
+                       May be a (...) expression if bits isn't a constant.
+	vl-dir         Direction of the pin input/output/inout.
+	vl-cell-type   Module name/type of the cell ('psm_mas')
+	vl-cell-name   Instance name of the cell ('ms2m')
+
+  Normal Lisp variables may be used in expressions.  See
+  `verilog-read-defines' which can set vh-{definename} variables for use
+  here.  Also, any comments of the form:
+
+	/*AUTO_LISP(setq foo 1)*/
+
+  will evaluate any Lisp expression inside the parenthesis between the
+  beginning of the buffer and the point of the AUTOINST.  This allows
+  functions to be defined or variables to be changed between instantiations.
+
+  Note that when using lisp expressions errors may occur when @ is not a
+  number, you may need to use the standard Emacs Lisp functions
+  `number-to-string' and `string-to-number'.
+
+  After the evaluation is completed, @ substitution and [] substitution
+  occur."
+  (save-excursion
+    ;; Find beginning
+    (let* ((pt (point))
+	   (for-star (save-excursion (backward-char 2) (looking-at "\\.\\*")))
+	   (indent-pt (save-excursion (verilog-backward-open-paren)
+				      (1+ (current-column))))
+	   (verilog-auto-inst-column (max verilog-auto-inst-column
+					  (+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
+	   (modi (verilog-modi-current))
+	   (vector-skip-list (unless verilog-auto-inst-vector
+			       (verilog-modi-get-signals modi)))
+	   submod submodi inst skip-pins tpl-list tpl-num did-first)
+      ;; Find module name that is instantiated
+      (setq submod  (verilog-read-inst-module)
+	    inst (verilog-read-inst-name)
+	    vl-cell-type submod
+	    vl-cell-name inst
+	    skip-pins (aref (verilog-read-inst-pins) 0))
+
+      ;; Parse any AUTO_LISP() before here
+      (verilog-read-auto-lisp (point-min) pt)
+
+      ;; Lookup position, etc of submodule
+      ;; Note this may raise an error
+      (when (setq submodi (verilog-modi-lookup submod t))
+	;; If there's a number in the instantiation, it may be a argument to the
+	;; automatic variable instantiation program.
+	(let* ((tpl-info (verilog-read-auto-template submod))
+	       (tpl-regexp (aref tpl-info 0)))
+	  (setq tpl-num (if (string-match tpl-regexp inst)
+			    (match-string 1 inst)
+			  "")
+		tpl-list (aref tpl-info 1)))
+	;; Find submodule's signals and dump
+	(let ((sig-list (verilog-signals-not-in
+			 (verilog-modi-get-outputs submodi)
+			 skip-pins))
+	      (vl-dir "output"))
+	  (when sig-list
+	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
+	    (indent-to indent-pt)
+	    (insert "// Outputs\n")	;; Note these are searched for in verilog-read-sub-decls
+	    (mapcar (function (lambda (port)
+				(verilog-auto-inst-port port indent-pt tpl-list tpl-num for-star)))
+		    sig-list)))
+	(let ((sig-list (verilog-signals-not-in
+			 (verilog-modi-get-inouts submodi)
+			 skip-pins))
+	      (vl-dir "inout"))
+	  (when sig-list
+	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
+	    (indent-to indent-pt)
+	    (insert "// Inouts\n")
+	    (mapcar (function (lambda (port)
+				(verilog-auto-inst-port port indent-pt tpl-list tpl-num for-star)))
+		    sig-list)))
+	(let ((sig-list (verilog-signals-not-in
+			 (verilog-modi-get-inputs submodi)
+			 skip-pins))
+	      (vl-dir "input"))
+	  (when sig-list
+	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
+	    (indent-to indent-pt)
+	    (insert "// Inputs\n")
+	    (mapcar (function (lambda (port)
+				(verilog-auto-inst-port port indent-pt tpl-list tpl-num for-star)))
+		    sig-list)))
+	;; Kill extra semi
+	(save-excursion
+	  (cond (did-first
+		 (re-search-backward "," pt t)
+		 (delete-char 1)
+		 (insert ");")
+		 (search-forward "\n")	;; Added by inst-port
+		 (delete-backward-char 1)
+		 (if (search-forward ")" nil t) ;; From user, moved up a line
+		     (delete-backward-char 1))
+		 (if (search-forward ";" nil t) ;; Don't error if user had syntax error and forgot it
+		     (delete-backward-char 1))
+		 )))
+	))))
+
+(defun verilog-auto-inst-param ()
+  "Expand AUTOINSTPARAM statements, as part of \\[verilog-auto].
+Replace the parameter connections to an instantiation with ones
+automatically derived from the module header of the instantiated netlist.
+
+See \\[verilog-auto-inst] for limitations, and templates to customize the
+output.
+
+For example, first take the submodule inst.v:
+
+	module inst (o,i)
+	   parameter PAR;
+	endmodule
+
+This is then used in a upper level module:
+
+	module ex_inst (o,i)
+	   parameter PAR;
+	   inst #(/*AUTOINSTPARAM*/)
+		inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_inst (o,i)
+	   output o;
+	   input i;
+	   inst (/*AUTOINSTPARAM*/
+		 // Parameters
+		 .PAR			(PAR));
+		inst (/*AUTOINST*/);
+	endmodule
+
+Where the list of parameter connections come from the inst module.
+
+Templates:
+
+  You can customize the parameter connections using AUTO_TEMPLATEs,
+  just as you would with \\[verilog-auto-inst]."
+  (save-excursion
+    ;; Find beginning
+    (let* ((pt (point))
+	   (indent-pt (save-excursion (verilog-backward-open-paren)
+				      (1+ (current-column))))
+	   (verilog-auto-inst-column (max verilog-auto-inst-column
+					  (+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
+	   (modi (verilog-modi-current))
+	   (vector-skip-list (unless verilog-auto-inst-vector
+			       (verilog-modi-get-signals modi)))
+	   submod submodi inst skip-pins tpl-list tpl-num did-first)
+      ;; Find module name that is instantiated
+      (setq submod (save-excursion
+		     ;; Get to the point where AUTOINST normally is to read the module
+		     (verilog-re-search-forward-quick "[(;]" nil nil)
+		     (verilog-read-inst-module))
+	    inst   (save-excursion
+		     ;; Get to the point where AUTOINST normally is to read the module
+		     (verilog-re-search-forward-quick "[(;]" nil nil)
+		     (verilog-read-inst-name))
+	    vl-cell-type submod
+	    vl-cell-name inst
+	    skip-pins (aref (verilog-read-inst-pins) 0))
+
+      ;; Parse any AUTO_LISP() before here
+      (verilog-read-auto-lisp (point-min) pt)
+
+      ;; Lookup position, etc of submodule
+      ;; Note this may raise an error
+      (when (setq submodi (verilog-modi-lookup submod t))
+	;; If there's a number in the instantiation, it may be a argument to the
+	;; automatic variable instantiation program.
+	(let* ((tpl-info (verilog-read-auto-template submod))
+	       (tpl-regexp (aref tpl-info 0)))
+	  (setq tpl-num (if (string-match tpl-regexp inst)
+			    (match-string 1 inst)
+			  "")
+		tpl-list (aref tpl-info 1)))
+	;; Find submodule's signals and dump
+	(let ((sig-list (verilog-signals-not-in
+			 (verilog-modi-get-gparams submodi)
+			 skip-pins))
+	      (vl-dir "parameter"))
+	  (when sig-list
+	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
+	    (indent-to indent-pt)
+	    (insert "// Parameters\n")	;; Note these are searched for in verilog-read-sub-decls
+	    (mapcar (function (lambda (port)
+				(verilog-auto-inst-port port indent-pt tpl-list tpl-num nil)))
+		    sig-list)))
+	;; Kill extra semi
+	(save-excursion
+	  (cond (did-first
+		 (re-search-backward "," pt t)
+		 (delete-char 1)
+		 (insert ")")
+		 (search-forward "\n")	;; Added by inst-port
+		 (delete-backward-char 1)
+		 (if (search-forward ")" nil t) ;; From user, moved up a line
+		     (delete-backward-char 1))
+		 )))
+	))))
+
+(defun verilog-auto-reg ()
+  "Expand AUTOREG statements, as part of \\[verilog-auto].
+Make reg statements for any output that isn't already declared,
+and isn't a wire output from a block.
+
+Limitations:
+  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
+
+  This does NOT work on memories, declare those yourself.
+
+An example:
+
+	module ex_reg (o,i)
+	   output o;
+	   input i;
+	   /*AUTOREG*/
+	   always o = i;
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_reg (o,i)
+	   output o;
+	   input i;
+	   /*AUTOREG*/
+	   // Beginning of automatic regs (for this module's undeclared outputs)
+	   reg			o;
+	   // End of automatics
+	   always o = i;
+	endmodule"
+  (save-excursion
+    ;; Point must be at insertion point.
+    (let* ((indent-pt (current-indentation))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-not-in
+		      (verilog-modi-get-outputs modi)
+		      (append (verilog-modi-get-wires modi)
+			      (verilog-modi-get-regs modi)
+			      (verilog-modi-get-assigns modi)
+			      (verilog-modi-get-consts modi)
+			      (verilog-modi-get-gparams modi)
+			      (verilog-modi-get-sub-outputs modi)
+			      (verilog-modi-get-sub-inouts modi)
+			      ))))
+      (forward-line 1)
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic regs (for this module's undeclared outputs)\n")
+	(verilog-insert-definition sig-list "reg" indent-pt nil)
+	(verilog-modi-cache-add-regs modi sig-list)
+	(verilog-insert-indent "// End of automatics\n"))
+      )))
+
+(defun verilog-auto-reg-input ()
+  "Expand AUTOREGINPUT statements, as part of \\[verilog-auto].
+Make reg statements instantiation inputs that aren't already declared.
+This is useful for making a top level shell for testing the module that is
+to be instantiated.
+
+Limitations:
+  This ONLY detects inputs of AUTOINSTants (see `verilog-read-sub-decls').
+
+  This does NOT work on memories, declare those yourself.
+
+An example (see `verilog-auto-inst' for what else is going on here):
+
+	module ex_reg_input (o,i)
+	   output o;
+	   input i;
+	   /*AUTOREGINPUT*/
+           inst inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_reg_input (o,i)
+	   output o;
+	   input i;
+	   /*AUTOREGINPUT*/
+	   // Beginning of automatic reg inputs (for undeclared ...
+	   reg [31:0]		iv;		// From inst of inst.v
+	   // End of automatics
+	   inst inst (/*AUTOINST*/
+		      // Outputs
+		      .o			(o[31:0]),
+		      // Inputs
+		      .iv			(iv));
+	endmodule"
+  (save-excursion
+    ;; Point must be at insertion point.
+    (let* ((indent-pt (current-indentation))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-combine-bus
+		      (verilog-signals-not-in
+		       (append (verilog-modi-get-sub-inputs modi)
+			       (verilog-modi-get-sub-inouts modi))
+		       (verilog-modi-get-signals modi)
+		       ))))
+      (forward-line 1)
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)\n")
+	(verilog-insert-definition sig-list "reg" indent-pt nil)
+	(verilog-modi-cache-add-regs modi sig-list)
+	(verilog-insert-indent "// End of automatics\n"))
+      )))
+
+(defun verilog-auto-wire ()
+  "Expand AUTOWIRE statements, as part of \\[verilog-auto].
+Make wire statements for instantiations outputs that aren't
+already declared.
+
+Limitations:
+  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls'),
+  and all busses must have widths, such as those from AUTOINST, or using []
+  in AUTO_TEMPLATEs.
+
+  This does NOT work on memories or SystemVerilog .name connections,
+  declare those yourself.
+
+  Verilog-mode will add \"Couldn't Merge\" comments to signals it cannot
+  determine how to bus together. This occurs when you have ports with
+  non-numeric or non-sequential bus subscripts. If Verilog-Mode
+  mis-guessed, you'll have to declare them yourself.
+
+An example (see `verilog-auto-inst' for what else is going on here):
+
+	module ex_wire (o,i)
+	   output o;
+	   input i;
+	   /*AUTOWIRE*/
+           inst inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_wire (o,i)
+	   output o;
+	   input i;
+	   /*AUTOWIRE*/
+	   // Beginning of automatic wires
+	   wire [31:0]		ov;	// From inst of inst.v
+	   // End of automatics
+	   inst inst (/*AUTOINST*/
+		      // Outputs
+		      .ov	(ov[31:0]),
+		      // Inputs
+		      .i	(i));
+	   wire o = | ov;
+	endmodule"
+  (save-excursion
+    ;; Point must be at insertion point.
+    (let* ((indent-pt (current-indentation))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-combine-bus
+		      (verilog-signals-not-in
+		       (append (verilog-modi-get-sub-outputs modi)
+			       (verilog-modi-get-sub-inouts modi))
+		       (verilog-modi-get-signals modi)
+		       ))))
+      (forward-line 1)
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic wires (for undeclared instantiated-module outputs)\n")
+	(verilog-insert-definition sig-list "wire" indent-pt nil)
+	(verilog-modi-cache-add-wires modi sig-list)
+	(verilog-insert-indent "// End of automatics\n")
+	(when nil	;; Too slow on huge modules, plus makes everyone's module change
+	  (beginning-of-line)
+	  (setq pnt (point))
+	  (verilog-pretty-declarations)
+	  (goto-char pnt)
+	  (verilog-pretty-expr "//")))
+      )))
+
+(defun verilog-auto-output ()
+  "Expand AUTOOUTPUT statements, as part of \\[verilog-auto].
+Make output statements for any output signal from an /*AUTOINST*/ that
+isn't a input to another AUTOINST.  This is useful for modules which
+only instantiate other modules.
+
+Limitations:
+  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
+
+  If placed inside the parenthesis of a module declaration, it creates
+  Verilog 2001 style, else uses Verilog 1995 style.
+
+  If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
+  instantiation, all bets are off.  (For example due to a AUTO_TEMPLATE).
+
+  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+
+  Signals matching `verilog-auto-output-ignore-regexp' are not included.
+
+An example (see `verilog-auto-inst' for what else is going on here):
+
+	module ex_output (ov,i)
+	   input i;
+	   /*AUTOOUTPUT*/
+	   inst inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_output (ov,i)
+	   input i;
+	   /*AUTOOUTPUT*/
+	   // Beginning of automatic outputs (from unused autoinst outputs)
+	   output [31:0]	ov;			// From inst of inst.v
+	   // End of automatics
+	   inst inst (/*AUTOINST*/
+		      // Outputs
+		      .ov			(ov[31:0]),
+		      // Inputs
+		      .i			(i));
+	endmodule"
+  (save-excursion
+    ;; Point must be at insertion point.
+    (let* ((indent-pt (current-indentation))
+	   (v2k  (verilog-in-paren))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-not-in
+		      (verilog-modi-get-sub-outputs modi)
+		      (append (verilog-modi-get-outputs modi)
+			      (verilog-modi-get-inouts modi)
+			      (verilog-modi-get-sub-inputs modi)
+			      (verilog-modi-get-sub-inouts modi)
+			      ))))
+      (setq sig-list (verilog-signals-not-matching-regexp
+		      sig-list verilog-auto-output-ignore-regexp))
+      (forward-line 1)
+      (when v2k (verilog-repair-open-comma))
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic outputs (from unused autoinst outputs)\n")
+	(verilog-insert-definition sig-list "output" indent-pt v2k)
+	(verilog-modi-cache-add-outputs modi sig-list)
+	(verilog-insert-indent "// End of automatics\n"))
+      (when v2k (verilog-repair-close-comma))
+      )))
+
+(defun verilog-auto-output-every ()
+  "Expand AUTOOUTPUTEVERY statements, as part of \\[verilog-auto].
+Make output statements for any signals that aren't primary inputs or
+outputs already.  This makes every signal in the design a output.  This is
+useful to get Synopsys to preserve every signal in the design, since it
+won't optimize away the outputs.
+
+An example:
+
+	module ex_output_every (o,i,tempa,tempb)
+	   output o;
+	   input i;
+	   /*AUTOOUTPUTEVERY*/
+	   wire tempa = i;
+	   wire tempb = tempa;
+	   wire o = tempb;
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_output_every (o,i,tempa,tempb)
+	   output o;
+	   input i;
+	   /*AUTOOUTPUTEVERY*/
+	   // Beginning of automatic outputs (every signal)
+	   output		tempb;
+	   output		tempa;
+	   // End of automatics
+	   wire tempa = i;
+	   wire tempb = tempa;
+	   wire o = tempb;
+	endmodule"
+  (save-excursion
+    ;;Point must be at insertion point
+    (let* ((indent-pt (current-indentation))
+	   (v2k  (verilog-in-paren))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-combine-bus
+		      (verilog-signals-not-in
+		       (verilog-modi-get-signals modi)
+		       (verilog-modi-get-ports modi)
+		       ))))
+      (forward-line 1)
+      (when v2k (verilog-repair-open-comma))
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic outputs (every signal)\n")
+	(verilog-insert-definition sig-list "output" indent-pt v2k)
+	(verilog-modi-cache-add-outputs modi sig-list)
+	(verilog-insert-indent "// End of automatics\n"))
+      (when v2k (verilog-repair-close-comma))
+      )))
+
+(defun verilog-auto-input ()
+  "Expand AUTOINPUT statements, as part of \\[verilog-auto].
+Make input statements for any input signal into an /*AUTOINST*/ that
+isn't declared elsewhere inside the module.  This is useful for modules which
+only instantiate other modules.
+
+Limitations:
+  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
+
+  If placed inside the parenthesis of a module declaration, it creates
+  Verilog 2001 style, else uses Verilog 1995 style.
+
+  If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
+  instantiation, all bets are off.  (For example due to a AUTO_TEMPLATE).
+
+  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+
+  Signals matching `verilog-auto-input-ignore-regexp' are not included.
+
+An example (see `verilog-auto-inst' for what else is going on here):
+
+	module ex_input (ov,i)
+	   output [31:0] ov;
+	   /*AUTOINPUT*/
+	   inst inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_input (ov,i)
+	   output [31:0] ov;
+	   /*AUTOINPUT*/
+	   // Beginning of automatic inputs (from unused autoinst inputs)
+	   input		i;			// From inst of inst.v
+	   // End of automatics
+	   inst inst (/*AUTOINST*/
+		      // Outputs
+		      .ov			(ov[31:0]),
+		      // Inputs
+		      .i			(i));
+	endmodule"
+  (save-excursion
+    (let* ((indent-pt (current-indentation))
+	   (v2k  (verilog-in-paren))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-not-in
+		      (verilog-modi-get-sub-inputs modi)
+		      (append (verilog-modi-get-inputs modi)
+			      (verilog-modi-get-inouts modi)
+			      (verilog-modi-get-wires modi)
+			      (verilog-modi-get-regs modi)
+			      (verilog-modi-get-consts modi)
+			      (verilog-modi-get-gparams modi)
+			      (verilog-modi-get-sub-outputs modi)
+			      (verilog-modi-get-sub-inouts modi)
+			      ))))
+      (setq sig-list (verilog-signals-not-matching-regexp
+		      sig-list verilog-auto-input-ignore-regexp))
+      (forward-line 1)
+      (when v2k (verilog-repair-open-comma))
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic inputs (from unused autoinst inputs)\n")
+	(verilog-insert-definition sig-list "input" indent-pt v2k)
+	(verilog-modi-cache-add-inputs modi sig-list)
+	(verilog-insert-indent "// End of automatics\n"))
+      (when v2k (verilog-repair-close-comma))
+      )))
+
+(defun verilog-auto-inout ()
+  "Expand AUTOINOUT statements, as part of \\[verilog-auto].
+Make inout statements for any inout signal in an /*AUTOINST*/ that
+isn't declared elsewhere inside the module.
+
+Limitations:
+  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
+
+  If placed inside the parenthesis of a module declaration, it creates
+  Verilog 2001 style, else uses Verilog 1995 style.
+
+  If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
+  instantiation, all bets are off.  (For example due to a AUTO_TEMPLATE).
+
+  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+
+  Signals matching `verilog-auto-inout-ignore-regexp' are not included.
+
+An example (see `verilog-auto-inst' for what else is going on here):
+
+	module ex_inout (ov,i)
+	   input i;
+	   /*AUTOINOUT*/
+	   inst inst (/*AUTOINST*/);
+	endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_inout (ov,i)
+	   input i;
+	   /*AUTOINOUT*/
+	   // Beginning of automatic inouts (from unused autoinst inouts)
+	   inout [31:0]	ov;			// From inst of inst.v
+	   // End of automatics
+	   inst inst (/*AUTOINST*/
+		      // Inouts
+		      .ov			(ov[31:0]),
+		      // Inputs
+		      .i			(i));
+	endmodule"
+  (save-excursion
+    ;; Point must be at insertion point.
+    (let* ((indent-pt (current-indentation))
+	   (v2k  (verilog-in-paren))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-not-in
+		      (verilog-modi-get-sub-inouts modi)
+		      (append (verilog-modi-get-outputs modi)
+			      (verilog-modi-get-inouts modi)
+			      (verilog-modi-get-inputs modi)
+			      (verilog-modi-get-sub-inputs modi)
+			      (verilog-modi-get-sub-outputs modi)
+			      ))))
+      (setq sig-list (verilog-signals-not-matching-regexp
+		      sig-list verilog-auto-inout-ignore-regexp))
+      (forward-line 1)
+      (when v2k (verilog-repair-open-comma))
+      (when sig-list
+	(verilog-insert-indent "// Beginning of automatic inouts (from unused autoinst inouts)\n")
+	(verilog-insert-definition sig-list "inout" indent-pt v2k)
+	(verilog-modi-cache-add-inouts modi sig-list)
+	(verilog-insert-indent "// End of automatics\n"))
+      (when v2k (verilog-repair-close-comma))
+      )))
+
+(defun verilog-auto-inout-module ()
+  "Expand AUTOINOUTMODULE statements, as part of \\[verilog-auto].
+Take input/output/inout statements from the specified module and insert
+into the current module.  This is useful for making null templates and
+shell modules which need to have identical I/O with another module.  Any
+I/O which are already defined in this module will not be redefined.
+
+Limitations:
+  If placed inside the parenthesis of a module declaration, it creates
+  Verilog 2001 style, else uses Verilog 1995 style.
+
+  Concatenation and outputting partial busses is not supported.
+
+  Module names must be resolvable to filenames.  See `verilog-auto-inst'.
+
+  Signals are not inserted in the same order as in the original module,
+  though they will appear to be in the same order to a AUTOINST
+  instantiating either module.
+
+An example:
+
+	module ex_shell (/*AUTOARG*/)
+	   /*AUTOINOUTMODULE(\"ex_main\")*/
+	endmodule
+
+	module ex_main (i,o,io)
+          input i;
+          output o;
+          inout io;
+        endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+	module ex_shell (/*AUTOARG*/i,o,io)
+	   /*AUTOINOUTMODULE(\"ex_main\")*/
+           // Beginning of automatic in/out/inouts (from specific module)
+           input i;
+           output o;
+           inout io;
+	   // End of automatics
+	endmodule"
+  (save-excursion
+    (let* ((submod (car (verilog-read-auto-params 1))) submodi)
+      ;; Lookup position, etc of co-module
+      ;; Note this may raise an error
+      (when (setq submodi (verilog-modi-lookup submod t))
+	(let* ((indent-pt (current-indentation))
+	       (v2k  (verilog-in-paren))
+	       (modi (verilog-modi-current))
+	       (sig-list-i  (verilog-signals-not-in
+			     (verilog-modi-get-inputs submodi)
+			     (append (verilog-modi-get-inputs modi))))
+	       (sig-list-o  (verilog-signals-not-in
+			     (verilog-modi-get-outputs submodi)
+			     (append (verilog-modi-get-outputs modi))))
+	       (sig-list-io (verilog-signals-not-in
+			     (verilog-modi-get-inouts submodi)
+			     (append (verilog-modi-get-inouts modi)))))
+	  (forward-line 1)
+	  (when v2k (verilog-repair-open-comma))
+	  (when (or sig-list-i sig-list-o sig-list-io)
+	    (verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n")
+	    ;; Don't sort them so a upper AUTOINST will match the main module
+	    (verilog-insert-definition sig-list-o  "output" indent-pt v2k t)
+	    (verilog-insert-definition sig-list-io "inout" indent-pt v2k t)
+	    (verilog-insert-definition sig-list-i  "input" indent-pt v2k t)
+	    (verilog-modi-cache-add-inputs modi sig-list-i)
+	    (verilog-modi-cache-add-outputs modi sig-list-o)
+	    (verilog-modi-cache-add-inouts modi sig-list-io)
+	    (verilog-insert-indent "// End of automatics\n"))
+	  (when v2k (verilog-repair-close-comma))
+	  )))))
+
+(defun verilog-auto-sense-sigs (modi presense-sigs)
+  "Return list of signals for current AUTOSENSE block."
+  (let* ((sigss (verilog-read-always-signals))
+	 (sig-list (verilog-signals-not-params
+		    (verilog-signals-not-in (verilog-alw-get-inputs sigss)
+					    (append (and (not verilog-auto-sense-include-inputs)
+							 (verilog-alw-get-outputs sigss))
+						    (verilog-modi-get-consts modi)
+						    (verilog-modi-get-gparams modi)
+						    presense-sigs)))))
+    sig-list))
+
+(defun verilog-auto-sense ()
+  "Expand AUTOSENSE statements, as part of \\[verilog-auto].
+Replace the always (/*AUTOSENSE*/) sensitivity list (/*AS*/ for short)
+with one automatically derived from all inputs declared in the always
+statement.  Signals that are generated within the same always block are NOT
+placed into the sensitivity list (see `verilog-auto-sense-include-inputs').
+Long lines are split based on the `fill-column', see \\[set-fill-column].
+
+Limitations:
+  Verilog does not allow memories (multidimensional arrays) in sensitivity
+  lists.  AUTOSENSE will thus exclude them, and add a /*memory or*/ comment.
+
+Constant signals:
+  AUTOSENSE cannot always determine if a `define is a constant or a signal
+  (it could be in a include file for example).  If a `define or other signal
+  is put into the AUTOSENSE list and is not desired, use the AUTO_CONSTANT
+  declaration anywhere in the module (parenthesis are required):
+
+	/* AUTO_CONSTANT ( `this_is_really_constant_dont_autosense_it ) */
+
+  Better yet, use a parameter, which will be understood to be constant
+  automatically.
+
+OOps!
+  If AUTOSENSE makes a mistake, please report it.  (First try putting
+  a begin/end after your always!) As a workaround, if a signal that
+  shouldn't be in the sensitivity list was, use the AUTO_CONSTANT above.
+  If a signal should be in the sensitivity list wasn't, placing it before
+  the /*AUTOSENSE*/ comment will prevent it from being deleted when the
+  autos are updated (or added if it occurs there already).
+
+An example:
+
+	   always @ (/*AUTOSENSE*/) begin
+	      /* AUTO_CONSTANT (`constant) */
+	      outin = ina | inb | `constant;
+	      out = outin;
+	   end
+
+Typing \\[verilog-auto] will make this into:
+
+	   always @ (/*AUTOSENSE*/ina or inb) begin
+	      /* AUTO_CONSTANT (`constant) */
+	      outin = ina | inb | `constant;
+	      out = outin;
+	   end"
+  (save-excursion
+    ;; Find beginning
+    (let* ((start-pt (save-excursion
+		       (verilog-re-search-backward "(" nil t)
+		       (point)))
+	   (indent-pt (save-excursion
+			(or (and (goto-char start-pt) (1+ (current-column)))
+			    (current-indentation))))
+	   (modi (verilog-modi-current))
+	   (sig-memories (verilog-signals-memory
+			  (append
+			   (verilog-modi-get-regs modi)
+			   (verilog-modi-get-wires modi))))
+	   sig-list not-first presense-sigs)
+      ;; Read signals in always, eliminate outputs from sense list
+      (setq presense-sigs (verilog-signals-from-signame
+			   (save-excursion
+			     (verilog-read-signals start-pt (point)))))
+      (setq sig-list (verilog-auto-sense-sigs modi presense-sigs))
+      (when sig-memories
+	(let ((tlen (length sig-list)))
+	  (setq sig-list (verilog-signals-not-in sig-list sig-memories))
+	  (if (not (eq tlen (length sig-list))) (insert " /*memory or*/ "))))
+      (if (and presense-sigs  ;; Add a "or" if not "(.... or /*AUTOSENSE*/"
+	       (save-excursion (goto-char (point))
+			       (verilog-re-search-backward "[a-zA-Z0-9$_.%`]+" start-pt t)
+			       (verilog-re-search-backward "\\s-" start-pt t)
+			       (while (looking-at "\\s-`endif")
+				 (verilog-re-search-backward "[a-zA-Z0-9$_.%`]+" start-pt t)
+				 (verilog-re-search-backward "\\s-" start-pt t))
+			       (not (looking-at "\\s-or\\b"))))
+	  (setq not-first t))
+      (setq sig-list (sort sig-list `verilog-signals-sort-compare))
+      (while sig-list
+	(cond ((> (+ 4 (current-column) (length (verilog-sig-name (car sig-list)))) fill-column) ;+4 for width of or
+	       (insert "\n")
+	       (indent-to indent-pt)
+	       (if not-first (insert "or ")))
+	      (not-first (insert " or ")))
+	(insert (verilog-sig-name (car sig-list)))
+	(setq sig-list (cdr sig-list)
+	      not-first t))
+      )))
+
+(defun verilog-auto-reset ()
+  "Expand AUTORESET statements, as part of \\[verilog-auto].
+Replace the /*AUTORESET*/ comment with code to initialize all
+registers set elsewhere in the always block.
+
+Limitations:
+  AUTORESET will not clear memories.
+
+  AUTORESET uses <= if there are any <= in the block, else it uses =.
+
+/*AUTORESET*/ presumes that any signals mentioned between the previous
+begin/case/if statement and the AUTORESET comment are being reset manually
+and should not be automatically reset.  This includes omitting any signals
+used on the right hand side of assignments.
+
+By default, AUTORESET will include the width of the signal in the autos,
+this is a recent change.  To control this behavior, see
+`verilog-auto-reset-widths'.
+
+AUTORESET ties signals to deasserted, which is presumed to be zero.
+Signals that match `verilog-active-low-regexp' will be deasserted by tieing
+them to a one.
+
+An example:
+
+    always @(posedge clk or negedge reset_l) begin
+        if (!reset_l) begin
+            c <= 1;
+            /*AUTORESET*/
+        end
+        else begin
+            a <= in_a;
+            b <= in_b;
+            c <= in_c;
+        end
+    end
+
+Typing \\[verilog-auto] will make this into:
+
+    always @(posedge core_clk or negedge reset_l) begin
+        if (!reset_l) begin
+            c <= 1;
+            /*AUTORESET*/
+            // Beginning of autoreset for uninitialized flops
+            a <= 0;
+            b <= 0;
+            // End of automatics
+        end
+        else begin
+            a <= in_a;
+            b <= in_b;
+            c <= in_c;
+        end
+    end"
+
+  (interactive)
+  (save-excursion
+    ;; Find beginning
+    (let* ((indent-pt (current-indentation))
+	   (modi (verilog-modi-current))
+	   (all-list (verilog-modi-get-signals modi))
+	   sigss sig-list prereset-sigs assignment-str)
+      ;; Read signals in always, eliminate outputs from reset list
+      (setq prereset-sigs (verilog-signals-from-signame
+			   (save-excursion
+			     (verilog-read-signals
+			      (save-excursion
+				(verilog-re-search-backward "\\(@\\|\\<begin\\>\\|\\<if\\>\\|\\<case\\>\\)" nil t)
+				(point))
+			      (point)))))
+      (save-excursion
+	(verilog-re-search-backward "@" nil t)
+        (setq sigss (verilog-read-always-signals)))
+      (setq assignment-str (if (verilog-alw-get-uses-delayed sigss)
+			       (concat " <= " verilog-assignment-delay)
+			     " = "))
+      (setq sig-list (verilog-signals-not-in (verilog-alw-get-outputs sigss)
+					     prereset-sigs))
+      (setq sig-list (sort sig-list `verilog-signals-sort-compare))
+      (when sig-list
+	(insert "\n");
+	(indent-to indent-pt)
+	(insert "// Beginning of autoreset for uninitialized flops\n");
+	(indent-to indent-pt)
+	(while sig-list
+	  (let ((sig (or (assoc (verilog-sig-name (car sig-list)) all-list) ;; As sig-list has no widths
+			 (car sig-list))))
+	    (insert (verilog-sig-name sig)
+		    assignment-str
+		    (verilog-sig-tieoff sig (not verilog-auto-reset-widths))
+		    ";\n")
+	    (indent-to indent-pt)
+	    (setq sig-list (cdr sig-list))))
+	(insert "// End of automatics"))
+      )))
+
+(defun verilog-auto-tieoff ()
+  "Expand AUTOTIEOFF statements, as part of \\[verilog-auto].
+Replace the /*AUTOTIEOFF*/ comment with code to wire-tie all unused output
+signals to deasserted.
+
+/*AUTOTIEOFF*/ is used to make stub modules; modules that have the same
+input/output list as another module, but no internals.  Specifically, it
+finds all outputs in the module, and if that input is not otherwise declared
+as a register or wire, creates a tieoff.
+
+AUTORESET ties signals to deasserted, which is presumed to be zero.
+Signals that match `verilog-active-low-regexp' will be deasserted by tieing
+them to a one.
+
+An example of making a stub for another module:
+
+    module FooStub (/*AUTOINST*/);
+	/*AUTOINOUTMODULE(\"Foo\")*/
+        /*AUTOTIEOFF*/
+        // verilator lint_off UNUSED
+        wire _unused_ok = &{1'b0,
+                            /*AUTOUNUSED*/
+                            1'b0};
+        // verilator lint_on  UNUSED
+    endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+    module FooStub (/*AUTOINST*/...);
+	/*AUTOINOUTMODULE(\"Foo\")*/
+        // Beginning of autotieoff
+        output [2:0] foo;
+        // End of automatics
+
+        /*AUTOTIEOFF*/
+        // Beginning of autotieoff
+        wire [2:0] foo = 3'b0;
+        // End of automatics
+        ...
+    endmodule"
+  (interactive)
+  (save-excursion
+    ;; Find beginning
+    (let* ((indent-pt (current-indentation))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-not-in
+		      (verilog-modi-get-outputs modi)
+		      (append (verilog-modi-get-wires modi)
+			      (verilog-modi-get-regs modi)
+			      (verilog-modi-get-assigns modi)
+			      (verilog-modi-get-consts modi)
+			      (verilog-modi-get-gparams modi)
+			      (verilog-modi-get-sub-outputs modi)
+			      (verilog-modi-get-sub-inouts modi)
+			      ))))
+      (when sig-list
+	(forward-line 1)
+	(verilog-insert-indent "// Beginning of automatic tieoffs (for this module's unterminated outputs)\n")
+	(setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare))
+	(verilog-modi-cache-add-wires modi sig-list)  ; Before we trash list
+	(while sig-list
+	  (let ((sig (car sig-list)))
+	    (verilog-insert-one-definition sig "wire" indent-pt)
+	    (indent-to (max 48 (+ indent-pt 40)))
+	    (insert "= " (verilog-sig-tieoff sig)
+		    ";\n")
+	    (setq sig-list (cdr sig-list))))
+	(verilog-insert-indent "// End of automatics\n")
+	))))
+
+(defun verilog-auto-unused ()
+  "Expand AUTOUNUSED statements, as part of \\[verilog-auto].
+Replace the /*AUTOUNUSED*/ comment with a comma separated list of all unused
+input and inout signals.
+
+/*AUTOUNUSED*/ is used to make stub modules; modules that have the same
+input/output list as another module, but no internals.  Specifically, it
+finds all inputs and inouts in the module, and if that input is not otherwise
+used, adds it to a comma separated list.
+
+The comma separated list is intended to be used to create a _unused_ok
+signal.  Using the exact name \"_unused_ok\" for name of the temporary
+signal is recommended as it will insure maximum forward compatibility, it
+also makes lint warnings easy to understand; ignore any unused warnings
+with \"unused\" in the signal name.
+
+To reduce simulation time, the _unused_ok signal should be forced to a
+constant to prevent wiggling.  The easiest thing to do is use a
+reduction-and with 1'b0 as shown.
+
+This way all unused signals are in one place, making it convenient to add
+your tool's specific pragmas around the assignment to disable any unused
+warnings.
+
+You can add signals you do not want included in AUTOUNUSED with
+`verilog-auto-unused-ignore-regexp'.
+
+An example of making a stub for another module:
+
+    module FooStub (/*AUTOINST*/);
+	/*AUTOINOUTMODULE(\"Foo\")*/
+        /*AUTOTIEOFF*/
+        // verilator lint_off UNUSED
+        wire _unused_ok = &{1'b0,
+                            /*AUTOUNUSED*/
+                            1'b0};
+        // verilator lint_on  UNUSED
+    endmodule
+
+Typing \\[verilog-auto] will make this into:
+
+        ...
+        // verilator lint_off UNUSED
+        wire _unused_ok = &{1'b0,
+                            /*AUTOUNUSED*/
+			    // Beginning of automatics
+			    unused_input_a,
+			    unused_input_b,
+			    unused_input_c,
+			    // End of automatics
+                            1'b0};
+        // verilator lint_on  UNUSED
+    endmodule"
+  (interactive)
+  (save-excursion
+    ;; Find beginning
+    (let* ((indent-pt (progn (search-backward "/*") (current-column)))
+	   (modi (verilog-modi-current))
+	   (sig-list (verilog-signals-not-in
+		      (append (verilog-modi-get-inputs modi)
+			      (verilog-modi-get-inouts modi))
+		      (append (verilog-modi-get-sub-inputs modi)
+			      (verilog-modi-get-sub-inouts modi)
+			      ))))
+      (setq sig-list (verilog-signals-not-matching-regexp
+		      sig-list verilog-auto-unused-ignore-regexp))
+      (when sig-list
+	(forward-line 1)
+	(verilog-insert-indent "// Beginning of automatic unused inputs\n")
+	(setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare))
+	(while sig-list
+	  (let ((sig (car sig-list)))
+	    (indent-to indent-pt)
+	    (insert (verilog-sig-name sig) ",\n")
+	    (setq sig-list (cdr sig-list))))
+	(verilog-insert-indent "// End of automatics\n")
+	))))
+
+(defun verilog-enum-ascii (signm elim-regexp)
+  "Convert a enum name SIGNM to a ascii string for insertion.
+Remove user provided prefix ELIM-REGEXP."
+  (or elim-regexp (setq elim-regexp "_ DONT MATCH IT_"))
+  (let ((case-fold-search t))
+    ;; All upper becomes all lower for readability
+    (downcase (verilog-string-replace-matches elim-regexp "" nil nil signm))))
+
+(defun verilog-auto-ascii-enum ()
+  "Expand AUTOASCIIENUM statements, as part of \\[verilog-auto].
+Create a register to contain the ASCII decode of a enumerated signal type.
+This will allow trace viewers to show the ASCII name of states.
+
+First, parameters are built into a enumeration using the synopsys enum
+comment.  The comment must be between the keyword and the symbol.
+(Annoying, but that's what Synopsys's dc_shell FSM reader requires.)
+
+Next, registers which that enum applies to are also tagged with the same
+enum.  Synopsys also suggests labeling state vectors, but `verilog-mode'
+doesn't care.
+
+Finally, a AUTOASCIIENUM command is used.
+
+  The first parameter is the name of the signal to be decoded.
+
+  The second parameter is the name to store the ASCII code into.  For the
+  signal foo, I suggest the name _foo__ascii, where the leading _ indicates
+  a signal that is just for simulation, and the magic characters _ascii
+  tell viewers like Dinotrace to display in ASCII format.
+
+  The final optional parameter is a string which will be removed from the
+  state names.
+
+An example:
+
+	//== State enumeration
+	parameter [2:0] // synopsys enum state_info
+			   SM_IDLE =  3'b000,
+			   SM_SEND =  3'b001,
+			   SM_WAIT1 = 3'b010;
+	//== State variables
+	reg [2:0]	/* synopsys enum state_info */
+			state_r;		/* synopsys state_vector state_r */
+	reg [2:0]	/* synopsys enum state_info */
+			state_e1;
+
+	//== ASCII state decoding
+
+	/*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
+
+Typing \\[verilog-auto] will make this into:
+
+	... same front matter ...
+
+	/*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
+	// Beginning of automatic ASCII enum decoding
+	reg [39:0]		state_ascii_r;		// Decode of state_r
+	always @(state_r) begin
+	   case ({state_r})
+		SM_IDLE:  state_ascii_r = \"idle \";
+		SM_SEND:  state_ascii_r = \"send \";
+		SM_WAIT1: state_ascii_r = \"wait1\";
+		default:  state_ascii_r = \"%Erro\";
+	   endcase
+	end
+	// End of automatics"
+  (save-excursion
+    (let* ((params (verilog-read-auto-params 2 3))
+	   (undecode-name (nth 0 params))
+	   (ascii-name (nth 1 params))
+	   (elim-regexp (nth 2 params))
+	   ;;
+	   (indent-pt (current-indentation))
+	   (modi (verilog-modi-current))
+	   ;;
+	   (sig-list-consts (append (verilog-modi-get-consts modi)
+				    (verilog-modi-get-gparams modi)))
+	   (sig-list-all  (append (verilog-modi-get-regs modi)
+				  (verilog-modi-get-outputs modi)
+				  (verilog-modi-get-inouts modi)
+				  (verilog-modi-get-inputs modi)
+				  (verilog-modi-get-wires modi)))
+	   ;;
+	   (undecode-sig (or (assoc undecode-name sig-list-all)
+			     (error "%s: Signal %s not found in design" (verilog-point-text) undecode-name)))
+	   (undecode-enum (or (verilog-sig-enum undecode-sig)
+			      (error "%s: Signal %s does not have a enum tag" (verilog-point-text) undecode-name)))
+	   ;;
+	   (enum-sigs (or (verilog-signals-matching-enum sig-list-consts undecode-enum)
+			  (error "%s: No state definitions for %s" (verilog-point-text) undecode-enum)))
+	   ;;
+	   (enum-chars 0)
+	   (ascii-chars 0))
+      ;;
+      ;; Find number of ascii chars needed
+      (let ((tmp-sigs enum-sigs))
+	(while tmp-sigs
+	  (setq enum-chars (max enum-chars (length (verilog-sig-name (car tmp-sigs))))
+		ascii-chars (max ascii-chars (length (verilog-enum-ascii
+						      (verilog-sig-name (car tmp-sigs))
+						      elim-regexp)))
+		tmp-sigs (cdr tmp-sigs))))
+      ;;
+      (forward-line 1)
+      (verilog-insert-indent "// Beginning of automatic ASCII enum decoding\n")
+      (let ((decode-sig-list (list (list ascii-name (format "[%d:0]" (- (* ascii-chars 8) 1))
+					 (concat "Decode of " undecode-name) nil nil))))
+	(verilog-insert-definition decode-sig-list "reg" indent-pt nil)
+	(verilog-modi-cache-add-regs modi decode-sig-list))
+      ;;
+      (verilog-insert-indent "always @(" undecode-name ") begin\n")
+      (setq indent-pt (+ indent-pt verilog-indent-level))
+      (indent-to indent-pt)
+      (insert "case ({" undecode-name "})\n")
+      (setq indent-pt (+ indent-pt verilog-case-indent))
+      ;;
+      (let ((tmp-sigs enum-sigs)
+	    (chrfmt (format "%%-%ds %s = \"%%-%ds\";\n" (1+ (max 8 enum-chars))
+			    ascii-name ascii-chars))
+	    (errname (substring "%Error" 0 (min 6 ascii-chars))))
+	(while tmp-sigs
+	  (verilog-insert-indent
+	   (format chrfmt (concat (verilog-sig-name (car tmp-sigs)) ":")
+		   (verilog-enum-ascii (verilog-sig-name (car tmp-sigs))
+				       elim-regexp)))
+	  (setq tmp-sigs (cdr tmp-sigs)))
+	(verilog-insert-indent (format chrfmt "default:" errname)))
+      ;;
+      (setq indent-pt (- indent-pt verilog-case-indent))
+      (verilog-insert-indent "endcase\n")
+      (setq indent-pt (- indent-pt verilog-indent-level))
+      (verilog-insert-indent "end\n"
+			     "// End of automatics\n")
+      )))
+
+(defun verilog-auto-templated-rel ()
+  "Replace Templated relative line numbers with absolute line numbers.
+Internal use only.  This hacks around the line numbers in AUTOINST Templates
+being different from the final output's line numbering."
+  (let ((templateno 0) (template-line (list 0)))
+    ;; Find line number each template is on
+    (goto-char (point-min))
+    (while (search-forward "AUTO_TEMPLATE" nil t)
+      (setq templateno (1+ templateno))
+      (setq template-line (cons (count-lines (point-min) (point)) template-line)))
+    (setq template-line (nreverse template-line))
+    ;; Replace T# L# with absolute line number
+    (goto-char (point-min))
+    (while (re-search-forward " Templated T\\([0-9]+\\) L\\([0-9]+\\)" nil t)
+      (replace-match (concat " Templated "
+			     (int-to-string (+ (nth (string-to-int (match-string 1))
+						    template-line)
+					       (string-to-int (match-string 2)))))
+		     t t))))
+
+
+;;
+;; Auto top level
+;;
+
+(defun verilog-auto (&optional inject)  ; Use verilog-inject-auto instead of passing a arg
+  "Expand AUTO statements.
+Look for any /*AUTO...*/ commands in the code, as used in
+instantiations or argument headers.  Update the list of signals
+following the /*AUTO...*/ command.
+
+Use \\[verilog-delete-auto] to remove the AUTOs.
+
+Use \\[verilog-inject-auto] to insert AUTOs for the first time.
+
+Use \\[verilog-faq] for a pointer to frequently asked questions.
+
+The hooks `verilog-before-auto-hook' and `verilog-auto-hook' are
+called before and after this function, respectively.
+
+For example:
+	module (/*AUTOARG*/)
+	/*AUTOINPUT*/
+	/*AUTOOUTPUT*/
+	/*AUTOWIRE*/
+	/*AUTOREG*/
+	somesub sub #(/*AUTOINSTPARAM*/) (/*AUTOINST*/);
+
+You can also update the AUTOs from the shell using:
+	emacs --batch  <filenames.v>  -f verilog-batch-auto
+Or fix indentation with:
+	emacs --batch  <filenames.v>  -f verilog-batch-indent
+Likewise, you can delete or inject AUTOs with:
+	emacs --batch  <filenames.v>  -f verilog-batch-delete-auto
+	emacs --batch  <filenames.v>  -f verilog-batch-inject-auto
+
+Using \\[describe-function], see also:
+    `verilog-auto-arg'          for AUTOARG module instantiations
+    `verilog-auto-ascii-enum'   for AUTOASCIIENUM enumeration decoding
+    `verilog-auto-inout-module' for AUTOINOUTMODULE copying i/o from elsewhere
+    `verilog-auto-inout'        for AUTOINOUT making hierarchy inouts
+    `verilog-auto-input'        for AUTOINPUT making hierarchy inputs
+    `verilog-auto-inst'         for AUTOINST instantiation pins
+    `verilog-auto-star'         for AUTOINST .* SystemVerilog pins
+    `verilog-auto-inst-param'   for AUTOINSTPARAM instantiation params
+    `verilog-auto-output'       for AUTOOUTPUT making hierarchy outputs
+    `verilog-auto-output-every' for AUTOOUTPUTEVERY making all outputs
+    `verilog-auto-reg'          for AUTOREG registers
+    `verilog-auto-reg-input'    for AUTOREGINPUT instantiation registers
+    `verilog-auto-reset'        for AUTORESET flop resets
+    `verilog-auto-sense'        for AUTOSENSE always sensitivity lists
+    `verilog-auto-tieoff'       for AUTOTIEOFF output tieoffs
+    `verilog-auto-unused'       for AUTOUNUSED unused inputs/inouts
+    `verilog-auto-wire'         for AUTOWIRE instantiation wires
+
+    `verilog-read-defines'      for reading `define values
+    `verilog-read-includes'     for reading `includes
+
+If you have bugs with these autos, try contacting the AUTOAUTHOR
+Wilson Snyder (wsnyder@wsnyder.org), and/or see http://www.veripool.com."
+  (interactive)
+  (unless noninteractive (message "Updating AUTOs..."))
+  (if (featurep 'dinotrace)
+      (dinotrace-unannotate-all))
+  (let ((oldbuf (if (not (buffer-modified-p))
+		    (buffer-string)))
+	;; Before version 20, match-string with font-lock returns a
+	;; vector that is not equal to the string.  IE if on "input"
+	;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
+	(fontlocked (when (and (boundp 'font-lock-mode)
+			       font-lock-mode)
+		      (font-lock-mode nil)
+		      t)))
+    (unwind-protect
+	(save-excursion
+	  ;; If we're not in verilog-mode, change syntax table so parsing works right
+	  (unless (eq major-mode `verilog-mode) (verilog-mode))
+	  ;; Allow user to customize
+	  (run-hooks 'verilog-before-auto-hook)
+	  ;; Try to save the user from needing to revert-file to reread file local-variables
+	  (verilog-auto-reeval-locals)
+	  (verilog-read-auto-lisp (point-min) (point-max))
+	  (verilog-getopt-flags)
+	  ;; These two may seem obvious to do always, but on large includes it can be way too slow
+	  (when verilog-auto-read-includes
+	    (verilog-read-includes)
+	    (verilog-read-defines nil nil t))
+	  ;; This particular ordering is important
+	  ;; INST: Lower modules correct, no internal dependencies, FIRST
+	  (verilog-preserve-cache
+	   ;; Clear existing autos else we'll be screwed by existing ones
+	   (verilog-delete-auto)
+	   ;; Injection if appropriate
+	   (when inject
+	     (verilog-inject-inst)
+	     (verilog-inject-sense)
+	     (verilog-inject-arg))
+	   ;;
+	   (verilog-auto-search-do "/*AUTOINSTPARAM*/" 'verilog-auto-inst-param)
+	   (verilog-auto-search-do "/*AUTOINST*/" 'verilog-auto-inst)
+	   (verilog-auto-search-do ".*" 'verilog-auto-star)
+	   ;; Doesn't matter when done, but combine it with a common changer
+	   (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
+	   (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
+	   ;; Must be done before autoin/out as creates a reg
+	   (verilog-auto-re-search-do "/\\*AUTOASCIIENUM([^)]*)\\*/" 'verilog-auto-ascii-enum)
+	   ;;
+	   ;; first in/outs from other files
+	   (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE([^)]*)\\*/" 'verilog-auto-inout-module)
+	   ;; next in/outs which need previous sucked inputs first
+	   (verilog-auto-search-do "/*AUTOOUTPUT*/" 'verilog-auto-output)
+	   (verilog-auto-search-do "/*AUTOINPUT*/" 'verilog-auto-input)
+	   (verilog-auto-search-do "/*AUTOINOUT*/" 'verilog-auto-inout)
+	   ;; Then tie off those in/outs
+	   (verilog-auto-search-do "/*AUTOTIEOFF*/" 'verilog-auto-tieoff)
+	   ;; Wires/regs must be after inputs/outputs
+	   (verilog-auto-search-do "/*AUTOWIRE*/" 'verilog-auto-wire)
+	   (verilog-auto-search-do "/*AUTOREG*/" 'verilog-auto-reg)
+	   (verilog-auto-search-do "/*AUTOREGINPUT*/" 'verilog-auto-reg-input)
+	   ;; outputevery needs AUTOOUTPUTs done first
+	   (verilog-auto-search-do "/*AUTOOUTPUTEVERY*/" 'verilog-auto-output-every)
+	   ;; After we've created all new variables
+	   (verilog-auto-search-do "/*AUTOUNUSED*/" 'verilog-auto-unused)
+	   ;; Must be after all inputs outputs are generated
+	   (verilog-auto-search-do "/*AUTOARG*/" 'verilog-auto-arg)
+	   ;; Fix line numbers (comments only)
+	   (verilog-auto-templated-rel)
+	   )
+	  ;;
+	  (run-hooks 'verilog-auto-hook)
+	  ;;
+	  (set (make-local-variable 'verilog-auto-update-tick) (buffer-modified-tick))
+	  ;;
+	  ;; If end result is same as when started, clear modified flag
+	  (cond ((and oldbuf (equal oldbuf (buffer-string)))
+		 (set-buffer-modified-p nil)
+		 (unless noninteractive (message "Updating AUTOs...done (no changes)")))
+		(t (unless noninteractive (message "Updating AUTOs...done")))))
+      ;; Unwind forms
+      (progn
+	;; Restore font-lock
+	(when fontlocked (font-lock-mode t)))
+      )))
+
+
+;;
+;; Skeleton based code insertion
+;;
+(defvar verilog-template-map nil
+  "Keymap used in Verilog mode for smart template operations.")
+
+(let ((verilog-mp (make-sparse-keymap)))
+  (define-key verilog-mp "a" 'verilog-sk-always)
+  (define-key verilog-mp "b" 'verilog-sk-begin)
+  (define-key verilog-mp "c" 'verilog-sk-case)
+  (define-key verilog-mp "f" 'verilog-sk-for)
+  (define-key verilog-mp "g" 'verilog-sk-generate)
+  (define-key verilog-mp "h" 'verilog-sk-header)
+  (define-key verilog-mp "i" 'verilog-sk-initial)
+  (define-key verilog-mp "j" 'verilog-sk-fork)
+  (define-key verilog-mp "m" 'verilog-sk-module)
+  (define-key verilog-mp "p" 'verilog-sk-primitive)
+  (define-key verilog-mp "r" 'verilog-sk-repeat)
+  (define-key verilog-mp "s" 'verilog-sk-specify)
+  (define-key verilog-mp "t" 'verilog-sk-task)
+  (define-key verilog-mp "w" 'verilog-sk-while)
+  (define-key verilog-mp "x" 'verilog-sk-casex)
+  (define-key verilog-mp "z" 'verilog-sk-casez)
+  (define-key verilog-mp "?" 'verilog-sk-if)
+  (define-key verilog-mp ":" 'verilog-sk-else-if)
+  (define-key verilog-mp "/" 'verilog-sk-comment)
+  (define-key verilog-mp "A" 'verilog-sk-assign)
+  (define-key verilog-mp "F" 'verilog-sk-function)
+  (define-key verilog-mp "I" 'verilog-sk-input)
+  (define-key verilog-mp "O" 'verilog-sk-output)
+  (define-key verilog-mp "S" 'verilog-sk-state-machine)
+  (define-key verilog-mp "=" 'verilog-sk-inout)
+  (define-key verilog-mp "W" 'verilog-sk-wire)
+  (define-key verilog-mp "R" 'verilog-sk-reg)
+  (define-key verilog-mp "D" 'verilog-sk-define-signal)
+  (setq verilog-template-map verilog-mp))
+
+;;
+;; Place the templates into Verilog Mode.  They may be inserted under any key.
+;; C-c C-t will be the default.  If you use templates a lot, you
+;; may want to consider moving the binding to another key in your .emacs
+;; file.
+;;
+;(define-key verilog-mode-map "\C-ct" verilog-template-map)
+(define-key verilog-mode-map "\C-c\C-t" verilog-template-map)
+
+;;; ---- statement skeletons ------------------------------------------
+
+(define-skeleton verilog-sk-prompt-condition
+  "Prompt for the loop condition."
+  "[condition]: " str )
+
+(define-skeleton verilog-sk-prompt-init
+  "Prompt for the loop init statement."
+  "[initial statement]: " str )
+
+(define-skeleton verilog-sk-prompt-inc
+  "Prompt for the loop increment statement."
+  "[increment statement]: " str )
+
+(define-skeleton verilog-sk-prompt-name
+  "Prompt for the name of something."
+  "[name]: " str)
+
+(define-skeleton verilog-sk-prompt-clock
+  "Prompt for the name of something."
+  "name and edge of clock(s): " str)
+
+(defvar verilog-sk-reset nil)
+(defun verilog-sk-prompt-reset ()
+  "Prompt for the name of a state machine reset."
+  (setq verilog-sk-reset (read-input "name of reset: " "rst")))
+
+
+(define-skeleton verilog-sk-prompt-state-selector
+  "Prompt for the name of a state machine selector."
+  "name of selector (eg {a,b,c,d}): " str )
+
+(define-skeleton verilog-sk-prompt-output
+  "Prompt for the name of something."
+  "output: " str)
+
+(define-skeleton verilog-sk-prompt-msb
+  "Prompt for least significant bit specification."
+  "msb:" str & ?: & (verilog-sk-prompt-lsb) | -1 )
+
+(define-skeleton verilog-sk-prompt-lsb
+  "Prompt for least significant bit specification."
+  "lsb:" str )
+
+(defvar verilog-sk-p nil)
+(define-skeleton verilog-sk-prompt-width
+  "Prompt for a width specification."
+  ()
+  (progn
+    (setq verilog-sk-p (point))
+    (verilog-sk-prompt-msb)
+    (if (> (point) verilog-sk-p) "] " " ")))
+
+(defun verilog-sk-header ()
+  "Insert a descriptive header at the top of the file."
+  (interactive "*")
+  (save-excursion
+    (goto-char (point-min))
+    (verilog-sk-header-tmpl)))
+
+(define-skeleton verilog-sk-header-tmpl
+  "Insert a comment block containing the module title, author, etc."
+  "[Description]: "
+  "//                              -*- Mode: Verilog -*-"
+  "\n// Filename        : " (buffer-name)
+  "\n// Description     : " str
+  "\n// Author          : " (user-full-name)
+  "\n// Created On      : " (current-time-string)
+  "\n// Last Modified By: ."
+  "\n// Last Modified On: ."
+  "\n// Update Count    : 0"
+  "\n// Status          : Unknown, Use with caution!"
+  "\n")
+
+(define-skeleton verilog-sk-module
+  "Insert a module definition."
+  ()
+  > "module " (verilog-sk-prompt-name) " (/*AUTOARG*/ ) ;" \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "endmodule" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-primitive
+  "Insert a task definition."
+  ()
+  > "primitive " (verilog-sk-prompt-name) " ( " (verilog-sk-prompt-output) ("input:" ", " str ) " );"\n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "endprimitive" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-task
+  "Insert a task definition."
+  ()
+  > "task " (verilog-sk-prompt-name) & ?; \n
+  > _ \n
+  > "begin" \n
+  > \n
+  > (- verilog-indent-level-behavioral) "end" \n
+  > (- verilog-indent-level-behavioral) "endtask" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-function
+  "Insert a function definition."
+  ()
+  > "function [" (verilog-sk-prompt-width) | -1 (verilog-sk-prompt-name) ?; \n
+  > _ \n
+  > "begin" \n
+  > \n
+  > (- verilog-indent-level-behavioral) "end" \n
+  > (- verilog-indent-level-behavioral) "endfunction" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-always
+  "Insert always block.  Uses the minibuffer to prompt
+for sensitivity list."
+  ()
+  > "always @ ( /*AUTOSENSE*/ ) begin\n"
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end" \n >
+  )
+
+(define-skeleton verilog-sk-initial
+  "Insert an initial block."
+  ()
+  > "initial begin\n"
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end" \n > )
+
+(define-skeleton verilog-sk-specify
+  "Insert specify block.  "
+  ()
+  > "specify\n"
+  > _ \n
+  > (- verilog-indent-level-behavioral) "endspecify" \n > )
+
+(define-skeleton verilog-sk-generate
+  "Insert generate block.  "
+  ()
+  > "generate\n"
+  > _ \n
+  > (- verilog-indent-level-behavioral) "endgenerate" \n > )
+
+(define-skeleton verilog-sk-begin
+  "Insert begin end block.  Uses the minibuffer to prompt for name"
+  ()
+  > "begin" (verilog-sk-prompt-name) \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end"
+)
+
+(define-skeleton verilog-sk-fork
+  "Insert an fork join block."
+  ()
+  > "fork\n"
+  > "begin" \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end" \n
+  > "begin" \n
+  > \n
+  > (- verilog-indent-level-behavioral) "end" \n
+  > (- verilog-indent-level-behavioral) "join" \n
+  > )
+
+
+(define-skeleton verilog-sk-case
+  "Build skeleton case statement, prompting for the selector expression,
+and the case items."
+  "[selector expression]: "
+  > "case (" str ") " \n
+  > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n )
+  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-casex
+  "Build skeleton casex statement, prompting for the selector expression,
+and the case items."
+  "[selector expression]: "
+  > "casex (" str ") " \n
+  > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n )
+  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-casez
+  "Build skeleton casez statement, prompting for the selector expression,
+and the case items."
+  "[selector expression]: "
+  > "casez (" str ") " \n
+  > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n )
+  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-if
+  "Insert a skeleton if statement."
+  > "if (" (verilog-sk-prompt-condition) & ")" " begin" \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end " \n )
+
+(define-skeleton verilog-sk-else-if
+  "Insert a skeleton else if statement."
+  > (verilog-indent-line) "else if ("
+  (progn (setq verilog-sk-p (point)) nil) (verilog-sk-prompt-condition) (if (> (point) verilog-sk-p) ") " -1 ) & " begin" \n
+  > _ \n
+  > "end" (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-datadef
+  "Common routine to get data definition"
+  ()
+  (verilog-sk-prompt-width) | -1 ("name (RET to end):" str ", ") -2 ";" \n)
+
+(define-skeleton verilog-sk-input
+  "Insert an input definition."
+  ()
+  > "input  [" (verilog-sk-datadef))
+
+(define-skeleton verilog-sk-output
+  "Insert an output definition."
+  ()
+  > "output [" (verilog-sk-datadef))
+
+(define-skeleton verilog-sk-inout
+  "Insert an inout definition."
+  ()
+  > "inout  [" (verilog-sk-datadef))
+
+(defvar verilog-sk-signal nil)
+(define-skeleton verilog-sk-def-reg
+  "Insert a reg definition."
+  ()
+  > "reg    [" (verilog-sk-prompt-width) | -1 verilog-sk-signal ";" \n (verilog-pretty-declarations) )
+
+(defun verilog-sk-define-signal ()
+  "Insert a definition of signal under point at top of module."
+  (interactive "*")
+  (let* (
+	 (sig-re "[a-zA-Z0-9_]*")
+	 (v1 (buffer-substring
+	       (save-excursion
+		 (skip-chars-backward sig-re)
+		 (point))
+	       (save-excursion
+		 (skip-chars-forward sig-re)
+		 (point))))
+	 )
+    (if (not (member v1 verilog-keywords))
+	(save-excursion
+	  (setq verilog-sk-signal v1)
+	  (verilog-beg-of-defun)
+	  (verilog-end-of-statement)
+	  (verilog-forward-syntactic-ws)
+	  (verilog-sk-def-reg)
+	  (message "signal at point is %s" v1))
+      (message "object at point (%s) is a keyword" v1))
+    )
+  )
+
+
+(define-skeleton verilog-sk-wire
+  "Insert a wire definition."
+  ()
+  > "wire   [" (verilog-sk-datadef))
+
+(define-skeleton verilog-sk-reg
+  "Insert a reg definition."
+  ()
+  > "reg   [" (verilog-sk-datadef))
+
+(define-skeleton verilog-sk-assign
+  "Insert a skeleton assign statement."
+  ()
+  > "assign " (verilog-sk-prompt-name) " = " _ ";" \n)
+
+(define-skeleton verilog-sk-while
+  "Insert a skeleton while loop statement."
+  ()
+  > "while ("  (verilog-sk-prompt-condition)  ") begin" \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-repeat
+  "Insert a skeleton repeat loop statement."
+  ()
+  > "repeat ("  (verilog-sk-prompt-condition)  ") begin" \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-for
+  "Insert a skeleton while loop statement."
+  ()
+  > "for ("
+  (verilog-sk-prompt-init) "; "
+  (verilog-sk-prompt-condition) "; "
+  (verilog-sk-prompt-inc)
+  ") begin" \n
+  > _ \n
+  > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
+
+(define-skeleton verilog-sk-comment
+  "Inserts three comment lines, making a display comment."
+  ()
+  > "/*\n"
+  > "* " _ \n
+  > "*/")
+
+(define-skeleton verilog-sk-state-machine
+  "Insert a state machine definition."
+  "Name of state variable: "
+  '(setq input "state")
+  > "// State registers for " str | -23 \n
+  '(setq verilog-sk-state str)
+  > "reg [" (verilog-sk-prompt-width) | -1 verilog-sk-state ", next_" verilog-sk-state ?; \n
+  '(setq input nil)
+  > \n
+  > "// State FF for " verilog-sk-state \n
+  > "always @ ( " (read-string "clock:" "posedge clk") " or " (verilog-sk-prompt-reset) " ) begin" \n
+  > "if ( " verilog-sk-reset " ) " verilog-sk-state " = 0; else" \n
+  > verilog-sk-state " = next_" verilog-sk-state ?; \n
+  > (- verilog-indent-level-behavioral) "end" (progn (electric-verilog-terminate-line) nil)
+  > \n
+  > "// Next State Logic for " verilog-sk-state \n
+  > "always @ ( /*AUTOSENSE*/ ) begin\n"
+  > "case (" (verilog-sk-prompt-state-selector) ") " \n
+  > ("case selector: " str ": begin" \n > "next_" verilog-sk-state " = " _ ";" \n > (- verilog-indent-level-behavioral) "end" \n )
+  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil)
+  > (- verilog-indent-level-behavioral) "end" (progn (electric-verilog-terminate-line) nil))
+
+;; Eliminate compile warning
+(eval-when-compile
+  (if (not (boundp 'mode-popup-menu))
+      (defvar mode-popup-menu nil "Compatibility with XEmacs.")))
+
+;; ---- add menu 'Statements' in Verilog mode (MH)
+(defun verilog-add-statement-menu ()
+  "Add the menu 'Statements' to the menu bar in Verilog mode."
+  (if (featurep 'xemacs)
+      (progn
+	(easy-menu-add verilog-stmt-menu)
+	(easy-menu-add verilog-menu)
+	(setq mode-popup-menu (cons "Verilog Mode" verilog-stmt-menu)))))
+
+(add-hook 'verilog-mode-hook 'verilog-add-statement-menu)
+
+
+
+;;
+;; Include file loading with mouse/return event
+;;
+;; idea & first impl.: M. Rouat (eldo-mode.el)
+;; second (emacs/xemacs) impl.: G. Van der Plas (spice-mode.el)
+
+(if (featurep 'xemacs)
+    (require 'overlay)
+  (require 'lucid)) ;; what else can we do ??
+
+(defconst verilog-include-file-regexp
+  "^`include\\s-+\"\\([^\n\"]*\\)\""
+  "Regexp that matches the include file.")
+
+(defvar verilog-mode-mouse-map nil
+  "Map containing mouse bindings for `verilog-mode'.")
+
+(if verilog-mode-mouse-map
+    ()
+  (let ((map (make-sparse-keymap))) ; as described in info pages, make a map
+    (set-keymap-parent map verilog-mode-map)
+    ;; mouse button bindings
+    (define-key map "\r"            'verilog-load-file-at-point)
+    (if (featurep 'xemacs)
+	(define-key map 'button2    'verilog-load-file-at-mouse);ffap-at-mouse ?
+      (define-key map [mouse-2]     'verilog-load-file-at-mouse))
+    (if (featurep 'xemacs)
+	(define-key map 'Sh-button2 'mouse-yank) ; you wanna paste don't you ?
+      (define-key map [S-mouse-2]   'mouse-yank-at-click))
+    (setq verilog-mode-mouse-map map))) ;; copy complete map now
+
+;; create set-extent-keymap procedure when it does not exist
+(eval-and-compile
+  (unless (fboundp 'set-extent-keymap)
+    (defun set-extent-keymap (extent keymap)
+      "fallback version of set-extent-keymap (for emacs 2[01])"
+      (set-extent-property extent 'local-map keymap))))
+
+(defun verilog-colorize-include-files (beg end old-len)
+  "This function colorizes included files when the mouse passes over them.
+Clicking on the middle-mouse button loads them in a buffer (as in dired)."
+  (save-excursion
+    (save-match-data
+      (let (end-point)
+	(goto-char end)
+	(setq end-point (verilog-get-end-of-line))
+	(goto-char beg)
+	(beginning-of-line)  ; scan entire line !
+	;; delete overlays existing on this line
+	(let ((overlays (overlays-in (point) end-point)))
+	  (while overlays
+	    (if (and
+		 (overlay-get (car overlays) 'detachable)
+		 (overlay-get (car overlays) 'verilog-include-file))
+		(delete-overlay (car overlays)))
+	    (setq overlays (cdr overlays)))) ; let
+	;; make new ones, could reuse deleted one ?
+	(while (search-forward-regexp verilog-include-file-regexp end-point t)
+	  (let (extent)
+	    (goto-char (match-beginning 1))
+	    (or (extent-at (point) (buffer-name) 'mouse-face) ;; not yet extended
+		(progn
+		  (setq extent (make-extent (match-beginning 1) (match-end 1)))
+		  (set-extent-property extent 'start-closed 't)
+		  (set-extent-property extent 'end-closed 't)
+		  (set-extent-property extent 'detachable 't)
+		  (set-extent-property extent 'verilog-include-file 't)
+		  (set-extent-property extent 'mouse-face 'highlight)
+		  (set-extent-keymap extent verilog-mode-mouse-map)))))))))
+
+
+(defun verilog-colorize-include-files-buffer ()
+  "Colorize a include file."
+  (interactive)
+  ;; delete overlays
+  (let ((overlays (overlays-in (point-min) (point-max))))
+    (while overlays
+      (if (and
+	   (overlay-get (car overlays) 'detachable)
+	   (overlay-get (car overlays) 'verilog-include-file))
+	  (delete-overlay (car overlays)))
+      (setq overlays (cdr overlays)))) ; let
+  ;; remake overlays
+  (verilog-colorize-include-files (point-min) (point-max) nil))
+
+;; ffap-at-mouse isn't useful for verilog mode. It uses library paths.
+;; so define this function to do more or less the same as ffap-at-mouse
+;; but first resolve filename...
+(defun verilog-load-file-at-mouse (event)
+  "Load file under button 2 click's EVENT.
+Files are checked based on `verilog-library-directories'."
+  (interactive "@e")
+  (save-excursion ;; implement a verilog specific ffap-at-mouse
+    (mouse-set-point event)
+    (beginning-of-line)
+    (if (looking-at verilog-include-file-regexp)
+	(if (and (car (verilog-library-filenames
+		       (match-string 1) (buffer-file-name)))
+		 (file-readable-p (car (verilog-library-filenames
+					(match-string 1) (buffer-file-name)))))
+	    (find-file (car (verilog-library-filenames
+			     (match-string 1) (buffer-file-name))))
+	  (progn
+	    (message
+	     "File '%s' isn't readable, use shift-mouse2 to paste in this field"
+	     (match-string 1))))
+      )))
+
+;; ffap isn't useable for verilog mode. It uses library paths.
+;; so define this function to do more or less the same as ffap
+;; but first resolve filename...
+(defun verilog-load-file-at-point ()
+  "Load file under point.
+Files are checked based on `verilog-library-directories'."
+  (interactive)
+  (save-excursion ;; implement a verilog specific ffap
+    (beginning-of-line)
+    (if (looking-at verilog-include-file-regexp)
+	(if (and
+	     (car (verilog-library-filenames
+		   (match-string 1) (buffer-file-name)))
+	     (file-readable-p (car (verilog-library-filenames
+				    (match-string 1) (buffer-file-name)))))
+	    (find-file (car (verilog-library-filenames
+			     (match-string 1) (buffer-file-name))))))
+      ))
+
+
+;;
+;; Bug reporting
+;;
+
+(defun verilog-faq ()
+  "Tell the user their current version, and where to get the FAQ etc."
+  (interactive)
+  (with-output-to-temp-buffer "*verilog-mode help*"
+    (princ (format "You are using verilog-mode %s\n" verilog-mode-version))
+    (princ "\n")
+    (princ "For new releases, see http://www.verilog.com\n")
+    (princ "\n")
+    (princ "For frequently asked questions, see http://www.veripool.com/verilog-mode-faq.html\n")
+    (princ "\n")
+    (princ "To submit a bug, use M-x verilog-submit-bug-report\n")
+    (princ "\n")))
+
+(defun verilog-submit-bug-report ()
+  "Submit via mail a bug report on verilog-mode.el."
+  (interactive)
+  (let ((reporter-prompt-for-summary-p t))
+    (reporter-submit-bug-report
+     "mac@verilog.com"
+     (concat "verilog-mode v" verilog-mode-version)
+     '(
+       verilog-align-ifelse
+       verilog-auto-endcomments
+       verilog-auto-hook
+       verilog-auto-indent-on-newline
+       verilog-auto-inst-vector
+       verilog-auto-inst-template-numbers
+       verilog-auto-lineup
+       verilog-auto-newline
+       verilog-auto-save-policy
+       verilog-auto-sense-defines-constant
+       verilog-auto-sense-include-inputs
+       verilog-before-auto-hook
+       verilog-case-indent
+       verilog-cexp-indent
+       verilog-compiler
+       verilog-coverage
+       verilog-highlight-translate-off
+       verilog-indent-begin-after-if
+       verilog-indent-declaration-macros
+       verilog-indent-level
+       verilog-indent-level-behavioral
+       verilog-indent-level-declaration
+       verilog-indent-level-directive
+       verilog-indent-level-module
+       verilog-indent-lists
+       verilog-library-flags
+       verilog-library-directories
+       verilog-library-extensions
+       verilog-library-files
+       verilog-linter
+       verilog-minimum-comment-distance
+       verilog-mode-hook
+       verilog-simulator
+       verilog-tab-always-indent
+       verilog-tab-to-comment
+       )
+     nil nil
+     (concat "Hi Mac,
+
+I want to report a bug.  I've read the `Bugs' section of `Info' on
+Emacs, so I know how to make a clear and unambiguous report.  To get
+to that Info section, I typed
+
+M-x info RET m " invocation-name " RET m bugs RET
+
+Before I go further, I want to say that Verilog mode has changed my life.
+I save so much time, my files are colored nicely, my co workers respect
+my coding ability... until now.  I'd really appreciate anything you
+could do to help me out with this minor deficiency in the product.
+
+If you have bugs with the AUTO functions, please CC the AUTOAUTHOR Wilson
+Snyder (wsnyder@wsnyder.org) and/or see http://www.veripool.com.
+You may also want to look at the Verilog-Mode FAQ, see
+http://www.veripool.com/verilog-mode-faq.html.
+
+To reproduce the bug, start a fresh Emacs via " invocation-name "
+-no-init-file -no-site-file'.  In a new buffer, in verilog mode, type
+the code included below.
+
+Given those lines, I expected [[Fill in here]] to happen;
+but instead, [[Fill in here]] happens!.
+
+== The code: =="))))
+
+;; Local Variables:
+;; checkdoc-permit-comma-termination-flag:t
+;; checkdoc-force-docstrings-flag:nil
+;; End:
+
+;;; verilog-mode.el ends here