--- /dev/null
+;; 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"
+; )
+
+;; \f
+
+;;; History:
+;;
+;; \f
+;;; 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))
+\f
+
+;;
+;; 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"))))
+
+\f
+
+;;
+;; 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)))
+\f
+
+;;
+;; 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))
+
+\f
+
+;;
+;; 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))
+\f
+
+;;
+;; 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))))
+
+;; \f
+;;
+;; 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))
+
+\f
+;;
+;; 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)
+
+\f
+;;
+;; 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))
+\f
+;;
+;; 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)))
+\f
+;;
+;; 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)))
+\f
+;;
+;; 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*/")))))))))
+\f
+;;
+;; 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)))
+\f
+;;
+;; 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.
+\f
+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]));
+
+\f
+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
+ ....
+\f
+@ 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));
+
+\f
+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_[]),
+\f
+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.
+\f
+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))))
+
+\f
+;;
+;; 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)))
+ )))
+\f
+
+;;
+;; 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)
+
+\f
+
+;;
+;; 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