;; verilog-mode.el --- major mode for editing verilog source in Emacs
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2011 Free Software Foundation, Inc.
-;; Author: Michael McNamara (mac@verilog.com)
-;; http://www.verilog.com
+;; Author: Michael McNamara (mac@verilog.com),
+;; Wilson Snyder (wsnyder@wsnyder.org)
+;; Please see our web sites:
+;; http://www.verilog.com
+;; http://www.veripool.org
;;
-;; AUTO features, signal, modsig; by: Wilson Snyder
-;; (wsnyder@wsnyder.org)
-;; http://www.veripool.org
;; Keywords: languages
;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this
;; 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.
+;; has bugs. Please report any issues to the issue tracker at
+;; http://www.veripool.org/verilog-mode
;; 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.
;; .emacs, or in your site's site-load.el
; (autoload 'verilog-mode "verilog-mode" "Verilog mode" t )
-; (add-to-list 'auto-mode-alist '("\\.[ds]?v\\'" . verilog-mode))
+; (add-to-list 'auto-mode-alist '("\\.[ds]?vh?\\'" . verilog-mode))
+;; Be sure to examine at the help for verilog-auto, and the other
+;; verilog-auto-* functions for some major coding time savers.
+;;
;; If you want to customize Verilog mode to fit your needs better,
-;; you may add these lines (the values of the variables presented
+;; you may add the below 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.
+;; edit these. If working as a member of a large team these settings
+;; should be common across all users (in a site-start file), or set
+;; in Local Variables in every file. Otherwise, different people's
+;; AUTO expansion may result different whitespace changes.
;;
+; ;; Enable syntax highlighting of **all** languages
+; (global-font-lock-mode t)
+;
; ;; User customization for Verilog mode
; (setq verilog-indent-level 3
; verilog-indent-level-module 3
; verilog-auto-endcomments t
; verilog-minimum-comment-distance 40
; verilog-indent-begin-after-if t
-; verilog-auto-lineup '(all)
+; verilog-auto-lineup 'declarations
; verilog-highlight-p1800-keywords nil
; verilog-linter "my_lint_shell_command"
; )
;;; Code:
;; This variable will always hold the version number of the mode
-(defconst verilog-mode-version "436"
+(defconst verilog-mode-version "650"
"Version of this Verilog mode.")
-(defconst verilog-mode-release-date "2008-09-02-GNU"
+(defconst verilog-mode-release-date "2010-11-05-GNU"
"Release date of this Verilog mode.")
(defconst verilog-mode-release-emacs t
"If non-nil, this version of Verilog mode was released with Emacs itself.")
;; We have an intermediate custom-library, hack around it!
(defmacro customize-group (var &rest args)
`(customize ,var))
- ))
+ )
+
+ (unless (boundp 'inhibit-point-motion-hooks)
+ (defvar inhibit-point-motion-hooks nil))
+ (unless (boundp 'deactivate-mark)
+ (defvar deactivate-mark nil))
+ )
+ ;;
;; OK, do this stuff if we are NOT XEmacs:
(unless (featurep 'xemacs)
(unless (fboundp 'region-active-p)
;; Emacs.
(defalias 'verilog-regexp-opt 'regexp-opt)))
+(eval-and-compile
+ ;; Both xemacs and emacs
+ (condition-case nil
+ (unless (fboundp 'buffer-chars-modified-tick) ;; Emacs 22 added
+ (defmacro buffer-chars-modified-tick () (buffer-modified-tick)))
+ (error nil)))
+
(eval-when-compile
(defun verilog-regexp-words (a)
"Call 'regexp-opt' with word delimiters for the words A."
(concat "\\<" (verilog-regexp-opt a t) "\\>")))
+(defun verilog-regexp-words (a)
+ "Call 'regexp-opt' with word delimiters for the words A."
+ ;; The FAQ references this function, so user LISP sometimes calls it
+ (concat "\\<" (verilog-regexp-opt a t) "\\>"))
(defun verilog-easy-menu-filter (menu)
- "Filter a easy-menu-define to support new features."
+ "Filter `easy-menu-define' MENU to support new features."
(cond ((not (featurep 'xemacs))
menu) ;; GNU Emacs - passthru
;; Xemacs doesn't support :help. Strip it.
(defun verilog-booleanp (value)
"Return t if VALUE is boolean.
- This implements GNU Emacs 22.1's `booleanp' function in earlier Emacs.
- This function may be removed when Emacs 21 is no longer supported."
+This implements GNU Emacs 22.1's `booleanp' function in earlier Emacs.
+This function may be removed when Emacs 21 is no longer supported."
(or (equal value t) (equal value nil)))
+(defun verilog-insert-last-command-event ()
+ "Insert the `last-command-event'."
+ (insert (if (featurep 'xemacs)
+ ;; XEmacs 21.5 doesn't like last-command-event
+ last-command-char
+ ;; And GNU Emacs 22 has obsoleted last-command-char
+ last-command-event)))
+
(defalias 'verilog-syntax-ppss
(if (fboundp 'syntax-ppss) 'syntax-ppss
(lambda (&optional pos) (parse-partial-sexp (point-min) (or pos (point))))))
"Customize AUTO actions when expanding Verilog source text."
:group 'verilog-mode)
+(defvar verilog-debug nil
+ "If set, enable debug messages for `verilog-mode' internals.")
+
(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.
:group 'verilog-mode-actions)
;; We don't mark it safe, as it's used as a shell command
+(defcustom verilog-preprocessor
+ ;; Very few tools give preprocessed output, so we'll default to Verilog-Perl
+ "vppreproc __FLAGS__ __FILE__"
+ "*Program and arguments to use to preprocess Verilog source.
+This is invoked with `verilog-preprocess', and depending on the
+`verilog-set-compile-command', may also 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)
+;; We don't mark it safe, as it's used as a shell command
+
+(defvar verilog-preprocess-history nil
+ "History for `verilog-preprocess'.")
+
(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.")
+Either nil, `verilog-linter, `verilog-compiler,
+`verilog-coverage, `verilog-preprocessor, or `verilog-simulator.
+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.
;; Note we don't use :safe, as that would break on Emacsen before 22.0.
(put 'verilog-highlight-translate-off 'safe-local-variable 'verilog-booleanp)
+(defcustom verilog-auto-lineup 'declarations
+ "*Type of statements to lineup across multiple lines.
+If 'all' is selected, then all line ups described below are done.
+
+If 'declaration', then just declarations are lined up with any
+preceding declarations, taking into account widths and the like,
+so or example the code:
+ reg [31:0] a;
+ reg b;
+would become
+ reg [31:0] a;
+ reg b;
+
+If '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;
+
+In order to speed up editing, large blocks of statements are lined up
+only when a \\[verilog-pretty-expr] is typed; and large blocks of declarations
+are lineup only when \\[verilog-pretty-declarations] is typed."
+
+ :type '(radio (const :tag "Line up Assignments and Declarations" all)
+ (const :tag "Line up Assignment statements" assignments )
+ (const :tag "Line up Declarations" declarations)
+ (function :tag "Other"))
+ :group 'verilog-mode-indent )
+
(defcustom verilog-indent-level 3
"*Indentation of Verilog statements with respect to containing block."
:group 'verilog-mode-indent
:type 'integer)
(put 'verilog-minimum-comment-distance 'safe-local-variable 'integerp)
-(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)
-(put 'verilog-auto-lineup 'safe-local-variable 'listp)
-
(defcustom verilog-highlight-p1800-keywords nil
"*True means highlight words newly reserved by IEEE-1800.
These will appear in `verilog-font-lock-p1800-face' in order to gently
(defcustom verilog-highlight-grouping-keywords nil
"*True means highlight grouping keywords 'begin' and 'end' more dramatically.
-If false, these words are in the font-lock-type-face; if True then they are in
-`verilog-font-lock-ams-face'. Some find that special highlighting on these
+If false, these words are in the `font-lock-type-face'; if True then they are in
+`verilog-font-lock-ams-face'. Some find that special highlighting on these
grouping constructs allow the structure of the code to be understood at a glance."
:group 'verilog-mode-indent
:type 'boolean)
(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp)
+(defcustom verilog-highlight-modules nil
+ "*True means highlight module statements for `verilog-load-file-at-point'.
+When true, mousing over module names will allow jumping to the
+module definition. If false, this is not supported. Setting
+this is experimental, and may lead to bad performance."
+ :group 'verilog-mode-indent
+ :type 'boolean)
+(put 'verilog-highlight-modules 'safe-local-variable 'verilog-booleanp)
+
+(defcustom verilog-highlight-includes t
+ "*True means highlight module statements for `verilog-load-file-at-point'.
+When true, mousing over include file names will allow jumping to the
+file referenced. If false, this is not supported."
+ :group 'verilog-mode-indent
+ :type 'boolean)
+(put 'verilog-highlight-includes 'safe-local-variable 'verilog-booleanp)
+
(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."
:type 'boolean)
(put 'verilog-auto-endcomments 'safe-local-variable 'verilog-booleanp)
+(defcustom verilog-auto-ignore-concat nil
+ "*True means ignore signals in {...} concatenations for AUTOWIRE etc.
+This will exclude signals referenced as pin connections in {...}
+from AUTOWIRE, AUTOOUTPUT and friends. This flag should be set
+for backward compatibility only and not set in new designs; it
+may be removed in future versions."
+ :group 'verilog-mode-actions
+ :type 'boolean)
+(put 'verilog-auto-ignore-concat 'safe-local-variable 'verilog-booleanp)
+
(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
(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
+;;; Compile support
+(require 'compile)
+(defvar verilog-error-regexp-added nil)
+
+(defvar verilog-error-regexp-emacs-alist
'(
- ; SureLint
-;; ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 2)
- ; Most SureFire tools
- ("\\(WARNING\\|ERROR\\|INFO\\)[^:]*: \\([^,]+\\), \\(line \\|\\)\\([0-9]+\\):" 2 4 )
- ("\
+ (verilog-xl-1
+ "\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 3)
+ (verilog-xl-2
+ "([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 1 3)
+ (verilog-IES
+ ".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)" 2 3)
+ (verilog-surefire-1
+ "[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 2)
+ (verilog-surefire-2
+ "\\(WARNING\\|ERROR\\|INFO\\)[^:]*: \\([^,]+\\),\\s-+\\(line \\)?\\([0-9]+\\):" 2 4 )
+ (verilog-verbose
+ "\
\\([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)
+ (verilog-xsim
+ "\\(Error\\|Warning\\).*in file (\\([^ \t]+\\) at line *\\([0-9]+\\))" 2 3)
+ (verilog-vcs-1
+ "\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 3)
+ (verilog-vcs-2
+ "Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 2)
+ (verilog-vcs-3
+ "\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 3)
+ (verilog-vcs-4
+ "syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 2)
+ (verilog-verilator
+ "%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4)
+ (verilog-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."
-)
+ "List of regexps for Verilog compilers.
+See `compilation-error-regexp-alist' for the formatting. For Emacs 22+.")
+
+(defvar verilog-error-regexp-xemacs-alist
+ ;; Emacs form is '((v-tool "re" 1 2) ...)
+ ;; XEmacs form is '(verilog ("re" 1 2) ...)
+ ;; So we can just map from Emacs to Xemacs
+ (cons 'verilog (mapcar 'cdr verilog-error-regexp-emacs-alist))
+ "List of regexps for Verilog compilers.
+See `compilation-error-regexp-alist-alist' for the formatting. For XEmacs.")
(defvar verilog-error-font-lock-keywords
'(
+ ;; verilog-xl-1
+ ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
+ ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
+ ;; verilog-xl-2
+ ("([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]+\\):.*$" 3 bold t)
+ ;; verilog-IES (nc-verilog)
+ (".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)|" 2 bold t)
+ (".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)|" 3 bold t)
+ ;; verilog-surefire-1
("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 bold t)
("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 2 bold t)
-
+ ;; verilog-surefire-2
("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 2 bold t)
("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 3 bold t)
-
+ ;; verilog-verbose
("\
\\([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)
-
+ ;; verilog-vcs-1
("\\(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)
-
+ ;; verilog-vcs-2
("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
-
+ ;; verilog-vcs-3
("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 3 bold t)
-
+ ;; verilog-vcs-4
("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)
+ ;; verilog-verilator
+ (".*%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 bold t)
+ (".*%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 4 bold t)
+ ;; verilog-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.")
+ "*Keywords to also highlight in Verilog *compilation* buffers.
+Only used in XEmacs; GNU Emacs uses `verilog-error-regexp-emacs-alist'.")
(defcustom verilog-library-flags '("")
"*List of standard Verilog arguments to use for /*AUTOINST*/.
:type 'string)
(put 'verilog-assignment-delay 'safe-local-variable 'stringp)
+(defcustom verilog-auto-arg-sort nil
+ "*If set, AUTOARG signal names will be sorted, not in delaration order.
+Declaration order is advantageous with order based instantiations
+and is the default for backward compatibility. Sorted order
+reduces changes when declarations are moved around in a file, and
+it's bad practice to rely on order based instantiations anyhow."
+ :group 'verilog-mode-auto
+ :type 'boolean)
+(put 'verilog-auto-arg-sort 'safe-local-variable 'verilog-booleanp)
+
+(defcustom verilog-auto-inst-dot-name nil
+ "*If true, when creating ports with AUTOINST, use .name syntax.
+This will use \".port\" instead of \".port(port)\" when possible.
+This is only legal in SystemVerilog files, and will confuse older
+simulators. Setting `verilog-auto-inst-vector' to nil may also
+be desirable to increase how often .name will be used."
+ :group 'verilog-mode-auto
+ :type 'boolean)
+(put 'verilog-auto-inst-dot-name 'safe-local-variable 'verilog-booleanp)
+
(defcustom verilog-auto-inst-param-value nil
"*If set, AUTOINST will replace parameters with the parameter value.
If nil, leave parameters as symbolic names.
For example, imagine a submodule uses parameters to declare the size of its
inputs. This is then used by a upper module:
- module InstModule (o,i)
+ module InstModule (o,i);
parameter WIDTH;
input [WIDTH-1:0] i;
endmodule
:type 'string)
(put 'verilog-auto-output-ignore-regexp 'safe-local-variable 'stringp)
+(defcustom verilog-auto-tieoff-ignore-regexp nil
+ "*If set, when creating AUTOTIEOFF list, ignore signals matching this regexp.
+See the \\[verilog-faq] for examples on using this."
+ :group 'verilog-mode-auto
+ :type 'string)
+(put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable 'stringp)
+
(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."
(define-key map "\C-c\C-k" 'verilog-delete-auto)
(define-key map "\C-c\C-a" 'verilog-auto)
(define-key map "\C-c\C-s" 'verilog-auto-save-compile)
+ (define-key map "\C-c\C-p" 'verilog-preprocess)
(define-key map "\C-c\C-z" 'verilog-inject-auto)
(define-key map "\C-c\C-e" 'verilog-expand-vector)
(define-key map "\C-c\C-h" 'verilog-header)
:style radio
:selected (equal verilog-tool `verilog-compiler)
:help "When invoking compilation, compile Verilog source"]
+ ["Preprocessor"
+ (progn
+ (setq verilog-tool 'verilog-preprocessor)
+ (verilog-set-compile-command))
+ :style radio
+ :selected (equal verilog-tool `verilog-preprocessor)
+ :help "When invoking compilation, preprocess Verilog source, see also `verilog-preprocess'"]
)
("Move"
["Beginning of function" verilog-beg-of-defun
:help "Help on AUTOARG - declaring module port list"]
["AUTOASCIIENUM" (describe-function 'verilog-auto-ascii-enum)
:help "Help on AUTOASCIIENUM - creating ASCII for enumerations"]
- ["AUTOINOUTCOMP" (describe-function 'verilog-auto-inout-complement)
+ ["AUTOINOUTCOMP" (describe-function 'verilog-auto-inout-comp)
:help "Help on AUTOINOUTCOMP - copying complemented i/o from another file"]
["AUTOINOUTMODULE" (describe-function 'verilog-auto-inout-module)
:help "Help on AUTOINOUTMODULE - copying i/o from another file"]
+ ["AUTOINSERTLISP" (describe-function 'verilog-auto-insert-lisp)
+ :help "Help on AUTOINSERTLISP - insert text from a lisp function"]
["AUTOINOUT" (describe-function 'verilog-auto-inout)
:help "Help on AUTOINOUT - adding inouts from cells"]
["AUTOINPUT" (describe-function 'verilog-auto-input)
;; Macros
;;
+(defsubst verilog-within-string ()
+ (nth 3 (parse-partial-sexp (point-at-bol) (point))))
+
(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.
(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)))))
+(defsubst verilog-re-search-forward-substr (substr regexp bound noerror)
+ "Like `re-search-forward', but first search for SUBSTR constant.
+Then searched for the normal REGEXP (which contains SUBSTR), with given
+BOUND and NOERROR. The REGEXP must fit within a single line.
+This speeds up complicated regexp matches."
+ ;; Problem with overlap: search-forward BAR then FOOBARBAZ won't match.
+ ;; thus require matches to be on one line, and use beginning-of-line.
+ (let (done)
+ (while (and (not done)
+ (search-forward substr bound noerror))
+ (save-excursion
+ (beginning-of-line)
+ (setq done (re-search-forward regexp (point-at-eol) noerror)))
+ (unless (and (<= (match-beginning 0) (point))
+ (>= (match-end 0) (point)))
+ (setq done nil)))
+ (when done (goto-char done))
+ done))
+;;(verilog-re-search-forward-substr "-end" "get-end-of" nil t) ;;-end (test bait)
+
+(defsubst verilog-re-search-backward-substr (substr regexp bound noerror)
+ "Like `re-search-backward', but first search for SUBSTR constant.
+Then searched for the normal REGEXP (which contains SUBSTR), with given
+BOUND and NOERROR. The REGEXP must fit within a single line.
+This speeds up complicated regexp matches."
+ ;; Problem with overlap: search-backward BAR then FOOBARBAZ won't match.
+ ;; thus require matches to be on one line, and use beginning-of-line.
+ (let (done)
+ (while (and (not done)
+ (search-backward substr bound noerror))
+ (save-excursion
+ (end-of-line)
+ (setq done (re-search-backward regexp (point-at-bol) noerror)))
+ (unless (and (<= (match-beginning 0) (point))
+ (>= (match-end 0) (point)))
+ (setq done nil)))
+ (when done (goto-char done))
+ done))
+;;(verilog-re-search-backward-substr "-end" "get-end-of" nil t) ;;-end (test bait)
(defvar compile-command)
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.
+By default `verilog-tool' uses a Makefile if one exists in the
+current directory. If not, it is set to the `verilog-linter',
+`verilog-compiler', `verilog-coverage', `verilog-preprocessor',
+or `verilog-simulator' 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:
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."
+Where __FLAGS__ appears in the string `verilog-current-flags'
+will be substituted.
+
+Where __FILE__ appears in the string, the variable
+`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 "))
+ (set (make-local-variable '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 "")))
- ""))))
+ (set (make-local-variable '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-expand-command (command)
+ "Replace meta-information in COMMAND and return it.
+Where __FLAGS__ appears in the string `verilog-current-flags'
+will be substituted. Where __FILE__ appears in the string, the
+current buffer's file-name, without the directory portion, will
+be substituted."
+ (setq command (verilog-string-replace-matches
+ ;; Note \\b only works if under verilog syntax table
+ "\\b__FLAGS__\\b" (verilog-current-flags)
+ t t command))
+ (setq command (verilog-string-replace-matches
+ "\\b__FILE__\\b" (file-name-nondirectory
+ (or (buffer-file-name) ""))
+ t t command))
+ 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."
+ "Update `compile-command' using `verilog-expand-command'."
(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))))
+ (string-match "\\b\\(__FLAGS__\\|__FILE__\\)\\b" compile-command))
+ (set (make-local-variable 'compile-command)
+ (verilog-expand-command compile-command))))
-;; Following code only gets called from compilation-mode-hook.
-(defvar compilation-error-regexp-alist)
+(if (featurep 'xemacs)
+ ;; Following code only gets called from compilation-mode-hook on XEmacs to add error handling.
+ (defun verilog-error-regexp-add-xemacs ()
+ "Teach XEmacs about verilog errors.
+Called by `compilation-mode-hook'. This allows \\[next-error] to
+find the errors."
+ (interactive)
+ (if (boundp 'compilation-error-regexp-systems-alist)
+ (if (and
+ (not (equal compilation-error-regexp-systems-list 'all))
+ (not (member compilation-error-regexp-systems-list 'verilog)))
+ (push 'verilog compilation-error-regexp-systems-list)))
+ (if (boundp 'compilation-error-regexp-alist-alist)
+ (if (not (assoc 'verilog compilation-error-regexp-alist-alist))
+ (setcdr compilation-error-regexp-alist-alist
+ (cons verilog-error-regexp-xemacs-alist
+ (cdr compilation-error-regexp-alist-alist)))))
+ (if (boundp 'compilation-font-lock-keywords)
+ (progn
+ (set (make-local-variable 'compilation-font-lock-keywords)
+ verilog-error-font-lock-keywords)
+ (font-lock-set-defaults)))
+ ;; Need to re-run compilation-error-regexp builder
+ (if (fboundp 'compilation-build-compilation-error-regexp-alist)
+ (compilation-build-compilation-error-regexp-alist))
+ ))
-(defun verilog-error-regexp-add ()
- "Add the messages to the `compilation-error-regexp-alist'.
+;; Following code only gets called from compilation-mode-hook on Emacs to add error handling.
+(defun verilog-error-regexp-add-emacs ()
+ "Tell Emacs compile that we are Verilog.
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)
+ (interactive)
+ (if (boundp 'compilation-error-regexp-alist-alist)
+ (progn
+ (if (not (assoc 'verilog-xl-1 compilation-error-regexp-alist-alist))
+ (mapcar
+ (lambda (item)
+ (push (car item) compilation-error-regexp-alist)
+ (push item compilation-error-regexp-alist-alist)
+ )
+ verilog-error-regexp-emacs-alist)))))
+
+(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs))
+(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs))
(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\\)\\>")
+ (eval-when-compile
+ (verilog-regexp-words
+ '(
+ "`case" "`default" "`define" "`else" "`elsif" "`endfor" "`endif"
+ "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
+ "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
+ "`time_scale" "`undef" "`while" ))))
+
+(defconst verilog-directive-re-1
+ (concat "[ \t]*" verilog-directive-re))
(defconst verilog-directive-begin
"\\<`\\(for\\|i\\(f\\|fdef\\|fndef\\)\\|switch\\|while\\)\\>")
(defconst verilog-directive-middle
- "\\<`\\(else\\|default\\|case\\)\\>")
+ "\\<`\\(else\\|elsif\\|default\\|case\\)\\>")
(defconst verilog-directive-end
"`\\(endfor\\|endif\\|endswitch\\|endwhile\\)\\>")
-(defconst verilog-directive-re-1
- (concat "[ \t]*" verilog-directive-re))
+(defconst verilog-ovm-begin-re
+ (eval-when-compile
+ (verilog-regexp-opt
+ '(
+ "`ovm_component_utils_begin"
+ "`ovm_component_param_utils_begin"
+ "`ovm_field_utils_begin"
+ "`ovm_object_utils_begin"
+ "`ovm_object_param_utils_begin"
+ "`ovm_sequence_utils_begin"
+ "`ovm_sequencer_utils_begin"
+ ) nil )))
+
+(defconst verilog-ovm-end-re
+ (eval-when-compile
+ (verilog-regexp-opt
+ '(
+ "`ovm_component_utils_end"
+ "`ovm_field_utils_end"
+ "`ovm_object_utils_end"
+ "`ovm_sequence_utils_end"
+ "`ovm_sequencer_utils_end"
+ ) nil )))
+
+(defconst verilog-vmm-begin-re
+ (eval-when-compile
+ (verilog-regexp-opt
+ '(
+ "`vmm_data_member_begin"
+ "`vmm_env_member_begin"
+ "`vmm_scenario_member_begin"
+ "`vmm_subenv_member_begin"
+ "`vmm_xactor_member_begin"
+ ) nil ) ) )
+
+(defconst verilog-vmm-end-re
+ (eval-when-compile
+ (verilog-regexp-opt
+ '(
+ "`vmm_data_member_end"
+ "`vmm_env_member_end"
+ "`vmm_scenario_member_end"
+ "`vmm_subenv_member_end"
+ "`vmm_xactor_member_end"
+ ) nil ) ) )
+
+(defconst verilog-vmm-statement-re
+ (eval-when-compile
+ (verilog-regexp-opt
+ '(
+;; "`vmm_xactor_member_enum_array"
+ "`vmm_\\(data\\|env\\|scenario\\|subenv\\|xactor\\)_member_\\(scalar\\|string\\|enum\\|vmm_data\\|channel\\|xactor\\|subenv\\|user_defined\\)\\(_array\\)?"
+;; "`vmm_xactor_member_scalar_array"
+;; "`vmm_xactor_member_scalar"
+ ) nil )))
+
+(defconst verilog-ovm-statement-re
+ (eval-when-compile
+ (verilog-regexp-opt
+ '(
+ ;; Statements
+ "`DUT_ERROR"
+ "`MESSAGE"
+ "`dut_error"
+ "`message"
+ "`ovm_analysis_imp_decl"
+ "`ovm_blocking_get_imp_decl"
+ "`ovm_blocking_get_peek_imp_decl"
+ "`ovm_blocking_master_imp_decl"
+ "`ovm_blocking_peek_imp_decl"
+ "`ovm_blocking_put_imp_decl"
+ "`ovm_blocking_slave_imp_decl"
+ "`ovm_blocking_transport_imp_decl"
+ "`ovm_component_registry"
+ "`ovm_component_registry_param"
+ "`ovm_component_utils"
+ "`ovm_create"
+ "`ovm_create_seq"
+ "`ovm_declare_sequence_lib"
+ "`ovm_do"
+ "`ovm_do_seq"
+ "`ovm_do_seq_with"
+ "`ovm_do_with"
+ "`ovm_error"
+ "`ovm_fatal"
+ "`ovm_field_aa_int_byte"
+ "`ovm_field_aa_int_byte_unsigned"
+ "`ovm_field_aa_int_int"
+ "`ovm_field_aa_int_int_unsigned"
+ "`ovm_field_aa_int_integer"
+ "`ovm_field_aa_int_integer_unsigned"
+ "`ovm_field_aa_int_key"
+ "`ovm_field_aa_int_longint"
+ "`ovm_field_aa_int_longint_unsigned"
+ "`ovm_field_aa_int_shortint"
+ "`ovm_field_aa_int_shortint_unsigned"
+ "`ovm_field_aa_int_string"
+ "`ovm_field_aa_object_int"
+ "`ovm_field_aa_object_string"
+ "`ovm_field_aa_string_int"
+ "`ovm_field_aa_string_string"
+ "`ovm_field_array_int"
+ "`ovm_field_array_object"
+ "`ovm_field_array_string"
+ "`ovm_field_enum"
+ "`ovm_field_event"
+ "`ovm_field_int"
+ "`ovm_field_object"
+ "`ovm_field_queue_int"
+ "`ovm_field_queue_object"
+ "`ovm_field_queue_string"
+ "`ovm_field_sarray_int"
+ "`ovm_field_string"
+ "`ovm_field_utils"
+ "`ovm_file"
+ "`ovm_get_imp_decl"
+ "`ovm_get_peek_imp_decl"
+ "`ovm_info"
+ "`ovm_info1"
+ "`ovm_info2"
+ "`ovm_info3"
+ "`ovm_info4"
+ "`ovm_line"
+ "`ovm_master_imp_decl"
+ "`ovm_msg_detail"
+ "`ovm_non_blocking_transport_imp_decl"
+ "`ovm_nonblocking_get_imp_decl"
+ "`ovm_nonblocking_get_peek_imp_decl"
+ "`ovm_nonblocking_master_imp_decl"
+ "`ovm_nonblocking_peek_imp_decl"
+ "`ovm_nonblocking_put_imp_decl"
+ "`ovm_nonblocking_slave_imp_decl"
+ "`ovm_object_registry"
+ "`ovm_object_registry_param"
+ "`ovm_object_utils"
+ "`ovm_peek_imp_decl"
+ "`ovm_phase_func_decl"
+ "`ovm_phase_task_decl"
+ "`ovm_print_aa_int_object"
+ "`ovm_print_aa_string_int"
+ "`ovm_print_aa_string_object"
+ "`ovm_print_aa_string_string"
+ "`ovm_print_array_int"
+ "`ovm_print_array_object"
+ "`ovm_print_array_string"
+ "`ovm_print_object_queue"
+ "`ovm_print_queue_int"
+ "`ovm_print_string_queue"
+ "`ovm_put_imp_decl"
+ "`ovm_rand_send"
+ "`ovm_rand_send_with"
+ "`ovm_send"
+ "`ovm_sequence_utils"
+ "`ovm_slave_imp_decl"
+ "`ovm_transport_imp_decl"
+ "`ovm_update_sequence_lib"
+ "`ovm_update_sequence_lib_and_item"
+ "`ovm_warning"
+ "`static_dut_error"
+ "`static_message") nil )))
+
;;
;; 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,
;; b :
+(defconst verilog-label-re (concat verilog-symbol-re "\\s-*:\\s-*"))
+(defconst verilog-property-re
+ (concat "\\(" verilog-label-re "\\)?"
+ "\\(\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(assert\\)"))
+ ;; "\\(assert\\|assume\\|cover\\)\\s-+property\\>"
+
(defconst verilog-no-indent-begin-re
"\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\|always_comb\\|always_ff\\|always_latch\\)\\>")
(concat
"\\(\\<else\\>\\)\\|" ; 1
"\\(\\<if\\>\\)\\|" ; 2
- "\\(\\<end\\>\\)\\|" ; 3
+ "\\(\\<assert\\>\\)\\|" ; 3
+ "\\(\\<end\\>\\)\\|" ; 3.1
"\\(\\<endcase\\>\\)\\|" ; 4
"\\(\\<endfunction\\>\\)\\|" ; 5
"\\(\\<endtask\\>\\)\\|" ; 6
"\\(\\<endgenerate\\>\\)\\|" ; 9
"\\(\\<join\\(_any\\|_none\\)?\\>\\)\\|" ; 10
"\\(\\<endclass\\>\\)\\|" ; 11
- "\\(\\<endgroup\\>\\)" ; 12
+ "\\(\\<endgroup\\>\\)\\|" ; 12
+ ;; VMM
+ "\\(\\<`vmm_data_member_end\\>\\)\\|"
+ "\\(\\<`vmm_env_member_end\\>\\)\\|"
+ "\\(\\<`vmm_scenario_member_end\\>\\)\\|"
+ "\\(\\<`vmm_subenv_member_end\\>\\)\\|"
+ "\\(\\<`vmm_xactor_member_end\\>\\)\\|"
+ ;; OVM
+ "\\(\\<`ovm_component_utils_end\\>\\)\\|"
+ "\\(\\<`ovm_field_utils_end\\>\\)\\|"
+ "\\(\\<`ovm_object_utils_end\\>\\)\\|"
+ "\\(\\<`ovm_sequence_utils_end\\>\\)\\|"
+ "\\(\\<`ovm_sequencer_utils_end\\>\\)"
+
))
(defconst verilog-auto-end-comment-lines-re
"endprogram"
"endsequence"
"endclocking"
+ ;; OVM
+ "`ovm_component_utils_end"
+ "`ovm_field_utils_end"
+ "`ovm_object_utils_end"
+ "`ovm_sequence_utils_end"
+ "`ovm_sequencer_utils_end"
+ ;; VMM
+ "`vmm_data_member_end"
+ "`vmm_env_member_end"
+ "`vmm_scenario_member_end"
+ "`vmm_subenv_member_end"
+ "`vmm_xactor_member_end"
))))
(defconst verilog-endcomment-reason-re
;; Parenthesis indicate type of keyword found
(concat
- "\\(\\<fork\\>\\)\\|"
- "\\(\\<begin\\>\\)\\|"
+ "\\(\\<begin\\>\\)\\|" ; 1
+ "\\(\\<else\\>\\)\\|" ; 2
+ "\\(\\<end\\>\\s-+\\<else\\>\\)\\|" ; 3
+ "\\(\\<always_comb\\>\\(\[ \t\]*@\\)?\\)\\|" ; 4
+ "\\(\\<always_ff\\>\\(\[ \t\]*@\\)?\\)\\|" ; 5
+ "\\(\\<always_latch\\>\\(\[ \t\]*@\\)?\\)\\|" ; 6
+ "\\(\\<fork\\>\\)\\|" ; 7
+ "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
"\\(\\<if\\>\\)\\|"
+ verilog-property-re "\\|"
+ "\\(\\(" verilog-label-re "\\)?\\<assert\\>\\)\\|"
"\\(\\<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\\)?\\>\\)\\|"
"specify"
"table"
"task"
+ ;;; OVM
+ "`ovm_component_utils_begin"
+ "`ovm_component_param_utils_begin"
+ "`ovm_field_utils_begin"
+ "`ovm_object_utils_begin"
+ "`ovm_object_param_utils_begin"
+ "`ovm_sequence_utils_begin"
+ "`ovm_sequencer_utils_begin"
+ ;; VMM
+ "`vmm_data_member_begin"
+ "`vmm_env_member_begin"
+ "`vmm_scenario_member_begin"
+ "`vmm_subenv_member_begin"
+ "`vmm_xactor_member_begin"
))))
;; 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,3
"\\|\\(\\<table\\>\\)" ;7
"\\|\\(\\<specify\\>\\)" ;8
"\\|\\(\\<function\\>\\)" ;9
- "\\|\\(\\<task\\>\\)" ;10
- "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<task\\>\\)" ;11
- "\\|\\(\\<generate\\>\\)" ;15
- "\\|\\(\\<covergroup\\>\\)" ;16
- "\\|\\(\\(\\(\\<cover\\>\\s-+\\)\\|\\(\\<assert\\>\\s-+\\)\\)*\\<property\\>\\)" ;17
- "\\|\\(\\<\\(rand\\)?sequence\\>\\)" ;21
- "\\|\\(\\<clocking\\>\\)" ;22
+ "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<function\\>\\)" ;10
+ "\\|\\(\\<task\\>\\)" ;14
+ "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<task\\>\\)" ;15
+ "\\|\\(\\<generate\\>\\)" ;18
+ "\\|\\(\\<covergroup\\>\\)" ;16 20
+ "\\|\\(\\(\\(\\<cover\\>\\s-+\\)\\|\\(\\<assert\\>\\s-+\\)\\)*\\<property\\>\\)" ;17 21
+ "\\|\\(\\<\\(rand\\)?sequence\\>\\)" ;21 25
+ "\\|\\(\\<clocking\\>\\)" ;22 27
+ "\\|\\(\\<`ovm_[a-z_]+_begin\\>\\)" ;28
+ "\\|\\(\\<`vmm_[a-z_]+_member_begin\\>\\)"
+ ;;
+
))
(defconst verilog-end-block-ordered-rry
"endfunction"
"endgenerate"
"endmodule"
- "endprimative"
+ "endprimitive"
"endinterface"
"endpackage"
"endspecify"
(defconst verilog-behavioral-block-beg-re
(eval-when-compile (verilog-regexp-words `("initial" "final" "always" "always_comb" "always_latch" "always_ff"
"function" "task"))))
-
+(defconst verilog-coverpoint-re "\\w+\\s*:\\s*\\(coverpoint\\|cross\\constraint\\)" )
(defconst verilog-indent-re
(eval-when-compile
(verilog-regexp-words
"`case"
"`default"
"`define" "`undef"
- "`if" "`ifdef" "`ifndef" "`else" "`endif"
+ "`if" "`ifdef" "`ifndef" "`else" "`elsif" "`endif"
"`while" "`endwhile"
"`for" "`endfor"
"`format"
"`switch" "`endswitch"
"`timescale"
"`time_scale"
+ ;; OVM Begin tokens
+ "`ovm_component_utils_begin"
+ "`ovm_component_param_utils_begin"
+ "`ovm_field_utils_begin"
+ "`ovm_object_utils_begin"
+ "`ovm_object_param_utils_begin"
+ "`ovm_sequence_utils_begin"
+ "`ovm_sequencer_utils_begin"
+ ;; OVM End tokens
+ "`ovm_component_utils_end"
+ "`ovm_field_utils_end"
+ "`ovm_object_utils_end"
+ "`ovm_sequence_utils_end"
+ "`ovm_sequencer_utils_end"
+ ;; VMM Begin tokens
+ "`vmm_data_member_begin"
+ "`vmm_env_member_begin"
+ "`vmm_scenario_member_begin"
+ "`vmm_subenv_member_begin"
+ "`vmm_xactor_member_begin"
+ ;; VMM End tokens
+ "`vmm_data_member_end"
+ "`vmm_env_member_end"
+ "`vmm_scenario_member_end"
+ "`vmm_subenv_member_end"
+ "`vmm_xactor_member_end"
))))
+(defconst verilog-defun-level-not-generate-re
+ (eval-when-compile
+ (verilog-regexp-words
+ `( "module" "macromodule" "primitive" "class" "program"
+ "interface" "package" "config"))))
+
(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"))))
+ (append
+ `( "module" "macromodule" "primitive" "class" "program"
+ "interface" "package" "config")
+ `( "initial" "final" "always" "always_comb" "always_ff"
+ "always_latch" "endtask" "endfunction" )))))
-(defconst verilog-defun-level-not-generate-re
+(defconst verilog-defun-level-generate-only-re
(eval-when-compile
(verilog-regexp-words
- `(
- "module" "macromodule" "primitive" "class" "program" "interface" "package" "config"))))
+ `( "initial" "final" "always" "always_comb" "always_ff"
+ "always_latch" "endtask" "endfunction" ))))
(defconst verilog-cpp-level-re
(eval-when-compile
`(
"endmodule" "endprimitive" "endinterface" "endpackage" "endprogram" "endclass"
))))
-(defconst verilog-disable-fork-re "disable\\s-+fork")
+(defconst verilog-disable-fork-re "disable\\s-+fork\\>")
+(defconst verilog-fork-wait-re "fork\\s-+wait\\>")
(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\\>\\)"
+ (concat "\\(\\<extern\\s-+\\|\\<\\(\\<pure\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)"
"\\|\\(\\<typedef\\>\\s-+\\)*\\(\\<struct\\>\\|\\<union\\>\\|\\<class\\>\\)"
+ "\\|\\(\\<import\\>\\s-+\\)?\"DPI-C\"\\s-+\\(function\\>\\|task\\>\\)"
"\\|" verilog-extended-case-re ))
(defconst verilog-basic-complete-re
(eval-when-compile
`(
"always" "assign" "always_latch" "always_ff" "always_comb" "constraint"
"import" "initial" "final" "module" "macromodule" "repeat" "randcase" "while"
- "if" "for" "forever" "foreach" "else" "parameter" "do"
+ "if" "for" "forever" "foreach" "else" "parameter" "do" "localparam" "assert"
))))
(defconst verilog-complete-reg
(concat
verilog-end-block-re "\\)"))
(defconst verilog-endcase-re
- (concat verilog-case-re "\\|"
+ (concat verilog-extended-case-re "\\|"
"\\(endcase\\)\\|"
verilog-defun-re
))
"unique" "unsigned" "use" "uwire" "var" "vectored" "virtual" "void"
"wait" "wait_order" "wand" "weak0" "weak1" "while" "wildcard"
"wire" "with" "within" "wor" "xnor" "xor"
+ ;; 1800-2009
+ "accept_on" "checker" "endchecker" "eventually" "global" "implies"
+ "let" "nexttime" "reject_on" "restrict" "s_always" "s_eventually"
+ "s_nexttime" "s_until" "s_until_with" "strong" "sync_accept_on"
+ "sync_reject_on" "unique0" "until" "until_with" "untyped" "weak"
)
"List of Verilog keywords.")
"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"
+ "output" "parameter" "pmos" "pull0" "pull1" "pulldown" "pullup"
"rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran"
"rtranif0" "rtranif1" "semaphore" "signed" "struct" "supply"
"supply0" "supply1" "time" "tran" "tranif0" "tranif1"
'("surefire" "synopsys" "rtl_synthesis" "verilint" "leda" "0in") nil
)))
- (verilog-p1800-keywords
+ (verilog-1800-2005-keywords
(eval-when-compile
(verilog-regexp-opt
'("alias" "assert" "assume" "automatic" "before" "bind"
"wait_order" "weak0" "weak1" "wildcard" "with" "within"
) nil )))
+ (verilog-1800-2009-keywords
+ (eval-when-compile
+ (verilog-regexp-opt
+ '("accept_on" "checker" "endchecker" "eventually" "global"
+ "implies" "let" "nexttime" "reject_on" "restrict" "s_always"
+ "s_eventually" "s_nexttime" "s_until" "s_until_with" "strong"
+ "sync_accept_on" "sync_reject_on" "unique0" "until"
+ "until_with" "untyped" "weak" ) nil )))
+
(verilog-ams-keywords
(eval-when-compile
(verilog-regexp-opt
'font-lock-type-face))
(cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>")
'font-lock-type-face)
- ;; Fontify IEEE-P1800 keywords appropriately
+ ;; Fontify IEEE-1800-2005 keywords appropriately
+ (if verilog-highlight-p1800-keywords
+ (cons (concat "\\<\\(" verilog-1800-2005-keywords "\\)\\>")
+ 'verilog-font-lock-p1800-face)
+ (cons (concat "\\<\\(" verilog-1800-2005-keywords "\\)\\>")
+ 'font-lock-type-face))
+ ;; Fontify IEEE-1800-2009 keywords appropriately
(if verilog-highlight-p1800-keywords
- (cons (concat "\\<\\(" verilog-p1800-keywords "\\)\\>")
+ (cons (concat "\\<\\(" verilog-1800-2009-keywords "\\)\\>")
'verilog-font-lock-p1800-face)
- (cons (concat "\\<\\(" verilog-p1800-keywords "\\)\\>")
+ (cons (concat "\\<\\(" verilog-1800-2009-keywords "\\)\\>")
'font-lock-type-face))
;; Fontify Verilog-AMS keywords
(cons (concat "\\<\\(" verilog-ams-keywords "\\)\\>")
(list
(concat "\\<function\\>\\s-+\\(integer\\|real\\(time\\)?\\|time\\)\\s-+\\(\\sw+\\)" )
'(1 font-lock-keyword-face)
- '(3 font-lock-reference-face prepend))
+ '(3 font-lock-constant-face prepend))
'("\\<function\\>\\s-+\\(\\[[^]]+\\]\\)\\s-+\\(\\sw+\\)"
(1 font-lock-keyword-face)
- (2 font-lock-reference-face append))
+ (2 font-lock-constant-face append))
'("\\<function\\>\\s-+\\(\\sw+\\)"
- 1 'font-lock-reference-face append))))
+ 1 'font-lock-constant-face append))))
(setq verilog-font-lock-keywords-2
(append verilog-font-lock-keywords-1
'("\\(@\\)\\|\\(#\\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)
+ '("\\([A-Za-z][A-Za-z0-9_]*\\)\\s-*(" 1 font-lock-function-name-face)
)))
(setq verilog-font-lock-keywords-3
(0 'verilog-font-lock-translate-off-face prepend))
)))))
+;;
+;; Buffer state preservation
+
+(defmacro verilog-save-buffer-state (&rest body)
+ "Execute BODY forms, saving state around insignificant change.
+Changes in text properties like `face' or `syntax-table' are
+considered insignificant. This macro allows text properties to
+be changed, even in a read-only buffer.
+
+A change is considered significant if it affects the buffer text
+in any way that isn't completely restored again. Any
+user-visible changes to the buffer must not be within a
+`verilog-save-buffer-state'."
+ ;; From c-save-buffer-state
+ `(let* ((modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ before-change-functions
+ after-change-functions
+ deactivate-mark
+ buffer-file-name ; Prevent primitives checking
+ buffer-file-truename) ; for file modification
+ (unwind-protect
+ (progn ,@body)
+ (and (not modified)
+ (buffer-modified-p)
+ (set-buffer-modified-p nil)))))
+
+(defmacro verilog-save-no-change-functions (&rest body)
+ "Execute BODY forms, disabling all change hooks in BODY.
+For insigificant changes, see instead `verilog-save-buffer-state'."
+ `(let* ((inhibit-point-motion-hooks t)
+ before-change-functions
+ after-change-functions)
+ (progn ,@body)))
-(defun verilog-inside-comment-p ()
- "Check if point inside a nested comment."
+;;
+;; Comment detection and caching
+
+(defvar verilog-scan-cache-preserving nil
+ "If set, the specified buffer's comment properties are static.
+Buffer changes will be ignored. See `verilog-inside-comment-p'
+and `verilog-scan'.")
+
+(defvar verilog-scan-cache-tick nil
+ "Modification tick at which `verilog-scan' was last completed.")
+(make-variable-buffer-local 'verilog-scan-cache-tick)
+
+(defun verilog-scan-cache-ok-p ()
+ "Return t iff the scan cache is up to date."
+ (or (and verilog-scan-cache-preserving
+ (eq verilog-scan-cache-preserving (current-buffer))
+ verilog-scan-cache-tick)
+ (equal verilog-scan-cache-tick (buffer-chars-modified-tick))))
+
+(defmacro verilog-save-scan-cache (&rest body)
+ "Execute the BODY forms, allowing scan cache preservation within BODY.
+This requires that insertions must use `verilog-insert'."
+ ;; If the buffer is out of date, trash it, as we'll not check later the tick
+ ;; Note this must work properly if there's multiple layers of calls
+ ;; to verilog-save-scan-cache even with differing ticks.
+ `(progn
+ (unless (verilog-scan-cache-ok-p) ;; Must be before let
+ (setq verilog-scan-cache-tick nil))
+ (let* ((verilog-scan-cache-preserving (current-buffer)))
+ (progn ,@body))))
+
+(defun verilog-scan-region (beg end)
+ "Parse comments between BEG and END for `verilog-inside-comment-p'.
+This creates v-cmt properties where comments are in force."
+ ;; Why properties and not overlays? Overlays have much slower non O(1)
+ ;; lookup times.
+ ;; This function is warm - called on every verilog-insert
(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)))))))
+ (save-match-data
+ (verilog-save-buffer-state
+ (let (pt)
+ (goto-char beg)
+ (while (< (point) end)
+ (cond ((looking-at "//")
+ (setq pt (point))
+ (or (search-forward "\n" end t)
+ (goto-char end))
+ ;; "1+": The leading // or /* itself isn't considered as
+ ;; being "inside" the comment, so that a (search-backward)
+ ;; that lands at the start of the // won't mis-indicate
+ ;; it's inside a comment
+ (put-text-property (1+ pt) (point) 'v-cmt t))
+ ((looking-at "/\\*")
+ (setq pt (point))
+ (or (search-forward "*/" end t)
+ ;; No error - let later code indicate it so we can
+ ;; use inside functions on-the-fly
+ ;;(error "%s: Unmatched /* */, at char %d"
+ ;; (verilog-point-text) (point))
+ (goto-char end))
+ (put-text-property (1+ pt) (point) 'v-cmt t))
+ (t
+ (forward-char 1)
+ (if (re-search-forward "/[/*]" end t)
+ (backward-char 2)
+ (goto-char end))))))))))
+
+(defun verilog-scan ()
+ "Parse the buffer, marking all comments with properties.
+Also assumes any text inserted since `verilog-scan-cache-tick'
+either is ok to parse as a non-comment, or `verilog-insert' was used."
+ (unless (verilog-scan-cache-ok-p)
+ (save-excursion
+ (verilog-save-buffer-state
+ (when verilog-debug
+ (message "Scanning %s cache=%s cachetick=%S tick=%S" (current-buffer)
+ verilog-scan-cache-preserving verilog-scan-cache-tick
+ (buffer-chars-modified-tick)))
+ (remove-text-properties (point-min) (point-max) '(v-cmt nil))
+ (verilog-scan-region (point-min) (point-max))
+ (setq verilog-scan-cache-tick (buffer-chars-modified-tick))
+ (when verilog-debug (message "Scaning... done"))))))
+
+(defun verilog-inside-comment-p ()
+ "Check if point inside a comment.
+This may require a slow pre-parse of the buffer with `verilog-scan'
+to establish comment properties on all text."
+ ;; This function is very hot
+ (verilog-scan)
+ (get-text-property (point) 'v-cmt))
+
+(defun verilog-insert (&rest stuff)
+ "Insert STUFF arguments, tracking comments for `verilog-inside-comment-p'.
+Any insert that includes a comment must have the entire commente
+inserted using a single call to `verilog-insert'."
+ (let ((pt (point)))
+ (while stuff
+ (insert (car stuff))
+ (setq stuff (cdr stuff)))
+ (verilog-scan-region pt (point))))
+
+;; More searching
(defun verilog-declaration-end ()
(search-forward ";"))
(setq md 3) ;; ender is third item in regexp
)
((match-end 4)
- ;; might be "disable fork"
- (if (or
- (looking-at verilog-disable-fork-re)
- (and (looking-at "fork")
- (progn
- (forward-word -1)
- (looking-at verilog-disable-fork-re))))
- (progn
- (goto-char (match-end 0))
- (forward-word)
- (setq reg nil))
- (progn
- ;; Search forward for matching join
- (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))))
+ ;; might be "disable fork" or "fork wait"
+ (let
+ (here)
+ (if (looking-at verilog-fork-wait-re)
+ (progn ;; it is a fork wait; ignore it
+ (goto-char (match-end 0))
+ (setq reg nil))
+ (if (or
+ (looking-at verilog-disable-fork-re)
+ (and (looking-at "fork")
+ (progn
+ (setq here (point)) ;; sometimes a fork is just a fork
+ (forward-word -1)
+ (looking-at verilog-disable-fork-re))))
+ (progn ;; it is a disable fork; ignore it
+ (goto-char (match-end 0))
+ (forward-word 1)
+ (setq reg nil))
+ (progn ;; it is a nice simple fork
+ (goto-char here) ;; return from looking for "disable fork"
+ ;; Search forward for matching join
+ (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))))))
((match-end 6)
;; Search forward for matching endclass
(setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
-
+
((match-end 7)
;; Search forward for matching endtable
(setq reg "\\<endtable\\>" )
(setq reg "\\<endfunction\\>" )
(setq nest 'no))
((match-end 10)
+ ;; Search forward for matching endfunction
+ (setq reg "\\<endfunction\\>" )
+ (setq nest 'no))
+ ((match-end 14)
;; Search forward for matching endtask
(setq reg "\\<endtask\\>" )
(setq nest 'no))
- ((match-end 11)
+ ((match-end 15)
;; Search forward for matching endtask
(setq reg "\\<endtask\\>" )
(setq nest 'no))
- ((match-end 15)
+ ((match-end 19)
;; Search forward for matching endgenerate
(setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
- ((match-end 16)
+ ((match-end 20)
;; Search forward for matching endgroup
(setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
- ((match-end 17)
+ ((match-end 21)
;; Search forward for matching endproperty
(setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
- ((match-end 18)
+ ((match-end 25)
;; Search forward for matching endsequence
(setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" )
(setq md 3)) ; 3 to get to endsequence in the reg above
- ((match-end 19)
+ ((match-end 27)
;; Search forward for matching endclocking
(setq reg "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)" )))
(if (and reg
(forward-word 1))
(catch 'skip
- (if (eq nest 'yes)
- (let ((depth 1))
+ (if (eq nest 'yes)
+ (let ((depth 1)
+ here)
(while (verilog-re-search-forward reg nil 'move)
(cond
- ((match-end md) ; the closer in reg, so we are climbing out
+ ((match-end md) ; a closer in regular expression, so we are climbing out
(setq depth (1- depth))
(if (= 0 depth) ; we are out!
(throw 'skip 1)))
- ((match-end 1) ; the opener in reg, so we are deeper now
- (setq depth (1+ depth))))))
+ ((match-end 1) ; an opener in the r-e, so we are in deeper now
+ (setq here (point)) ; remember where we started
+ (goto-char (match-beginning 1))
+ (cond
+ ((looking-at verilog-fork-wait-re)
+ (goto-char (match-end 0))) ; false alarm
+ ((if (or
+ (looking-at verilog-disable-fork-re)
+ (and (looking-at "fork")
+ (progn
+ (forward-word -1)
+ (looking-at verilog-disable-fork-re))))
+ (progn ;; it is a disable fork; another false alarm
+ (goto-char (match-end 0)))
+ (progn ;; it is a simple fork (or has nothing to do with fork)
+ (goto-char here)
+ (setq depth (1+ depth))))))))))
(if (verilog-re-search-forward reg nil 'move)
(throw 'skip 1))))))
-
+
((looking-at (concat
"\\(\\<\\(macro\\)?module\\>\\)\\|"
"\\(\\<primitive\\>\\)\\|"
(defun verilog-declaration-beg ()
(verilog-re-search-backward verilog-declaration-re (bobp) t))
-(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))))))
- ;; FIXME: This XEmacs setting is redundant with the setting done later
- ;; for Emacs (because XEmacs obeys Emacs's setting as well).
- (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
- ;; Function to move to beginning of reasonable region to highlight
- verilog-beg-of-defun)))
-
-;; initialize fontification for Verilog Mode
-(verilog-font-lock-init)
-
;;
;;
;; Mode
;;
(defvar verilog-which-tool 1)
;;;###autoload
-(defun verilog-mode ()
+(define-derived-mode verilog-mode prog-mode "Verilog"
"Major mode for editing Verilog code.
\\<verilog-mode-map>
See \\[describe-function] verilog-auto (\\[verilog-auto]) for details on how
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))
+ `verilog-auto-lineup' (default 'declarations)
List of contexts where auto lineup of code should be done.
Variables controlling other actions:
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)
+ :abbrev-table verilog-mode-abbrev-table
(set (make-local-variable 'beginning-of-defun-function)
'verilog-beg-of-defun)
(set (make-local-variable 'end-of-defun-function)
'verilog-end-of-defun)
(set-syntax-table verilog-mode-syntax-table)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'verilog-indent-line-relative)
+ (set (make-local-variable '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 (make-local-variable 'parse-sexp-ignore-comments) nil)
+
+ (set (make-local-variable 'comment-start) "// ")
+ (set (make-local-variable 'comment-end) "")
+ (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|// *")
+ (set (make-local-variable 'comment-multi-line) nil)
;; Set up for compilation
(setq verilog-which-tool 1)
(setq verilog-tool 'verilog-linter)
verilog-font-lock-keywords-2
verilog-font-lock-keywords-3)
nil nil nil
- ,(if (functionp 'syntax-ppss)
- ;; verilog-beg-of-defun uses syntax-ppss, and syntax-ppss uses
- ;; font-lock-beginning-of-syntax-function, so
- ;; font-lock-beginning-of-syntax-function, can't use
+ ,(if (functionp 'syntax-ppss)
+ ;; verilog-beg-of-defun uses syntax-ppss, and syntax-ppss uses
+ ;; font-lock-beginning-of-syntax-function, so
+ ;; font-lock-beginning-of-syntax-function, can't use
;; verilog-beg-of-defun.
- nil
- 'verilog-beg-of-defun)))
+ nil
+ 'verilog-beg-of-defun)))
;;------------------------------------------------------------
- ;; now hook in 'verilog-colorize-include-files (eldo-mode.el&spice-mode.el)
+ ;; now hook in 'verilog-highlight-include-files (eldo-mode.el&spice-mode.el)
;; all buffer local:
- (when (featurep 'xemacs)
- (make-local-hook 'font-lock-mode-hook)
- (make-local-hook 'font-lock-after-fontify-buffer-hook); doesn't exist in Emacs
- (make-local-hook 'after-change-functions))
- (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
- (add-hook 'after-change-functions 'verilog-colorize-include-files t t)
+ (unless noninteractive ;; Else can't see the result, and change hooks are slow
+ (when (featurep 'xemacs)
+ (make-local-hook 'font-lock-mode-hook)
+ (make-local-hook 'font-lock-after-fontify-buffer-hook); doesn't exist in Emacs
+ (make-local-hook 'after-change-functions))
+ (add-hook 'font-lock-mode-hook 'verilog-highlight-buffer t t)
+ (add-hook 'font-lock-after-fontify-buffer-hook 'verilog-highlight-buffer t t) ; not in Emacs
+ (add-hook 'after-change-functions 'verilog-highlight-region t t))
;; Tell imenu how to handle Verilog.
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression verilog-imenu-generic-expression)
+ (set (make-local-variable 'imenu-generic-expression)
+ verilog-imenu-generic-expression)
;; Tell which-func-modes that imenu knows about verilog
(when (boundp 'which-function-modes)
(add-to-list 'which-func-modes 'verilog-mode))
hs-special-modes-alist))))
;; 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))
+ (add-hook 'write-contents-hooks 'verilog-auto-save-check nil 'local))
\f
;;
't)))
;; see if we should line up assignments
(progn
- (if (or (memq 'all verilog-auto-lineup)
- (memq 'assignments verilog-auto-lineup))
- (verilog-pretty-expr))
+ (if (or (eq 'all verilog-auto-lineup)
+ (eq 'assignments verilog-auto-lineup))
+ (verilog-pretty-expr t "\\(<\\|:\\)?=" ))
(newline))
(forward-line 1))
;; Indent next line
(defun electric-verilog-semi ()
"Insert `;' character and reindent the line."
(interactive)
- (insert last-command-event)
+ (verilog-insert-last-command-event)
(if (or (verilog-in-comment-or-string-p)
(verilog-in-escaped-name-p))
(defun electric-verilog-colon ()
"Insert `:' and do all indentations except line indent on this line."
(interactive)
- (insert last-command-event)
+ (verilog-insert-last-command-event)
;; Do nothing if within string.
(if (or
(verilog-within-string)
;;(defun electric-verilog-equal ()
;; "Insert `=', and do indentation if within block."
;; (interactive)
-;; (insert last-command-event)
+;; (verilog-insert-last-command-event)
;; Could auto line up expressions, but not yet
;; (if (eq (car (verilog-calculate-indent)) 'block)
;; (let ((verilog-tab-always-indent nil))
(defun electric-verilog-tick ()
"Insert back-tick, and indent to column 0 if this is a CPP directive."
(interactive)
- (insert last-command-event)
+ (verilog-insert-last-command-event)
(save-excursion
- (if (progn
- (beginning-of-line)
- (looking-at verilog-directive-re-1))
- (verilog-indent-line))))
+ (if (verilog-in-directive-p)
+ (verilog-indent-line))))
(defun electric-verilog-tab ()
"Function called when TAB is pressed in Verilog mode."
(skip-chars-backward " \t")
(kill-region (point) oldpnt)))))))
(t (progn (insert "\t")))))
-
+
\f
;;
(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)))))
+ (let (h)
+ (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 unambiguously starts a statement,
+ ;; or the token before us unambiguously ends a statement,
+ ;; then move back a token and test again.
+ (not (or
+ ;; stop if beginning of buffer
+ (bolp)
+ ;; stop if we find a ;
+ (= (preceding-char) ?\;)
+ ;; stop if we see a named coverpoint
+ (looking-at "\\w+\\W*:\\W*\\(coverpoint\\|cross\\|constraint\\)")
+ ;; keep going if we are in the middle of a word
+ (not (or (looking-at "\\<") (forward-word -1)))
+ ;; stop if we see an assertion (perhaps labled)
+ (and
+ (looking-at "\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)")
+ (progn
+ (setq h (point))
+ (save-excursion
+ (verilog-backward-token)
+ (if (looking-at verilog-label-re)
+ (setq h (point))))
+ (goto-char h)))
+ ;; stop if we see a complete reg, perhaps an extended one
+ (and
+ (looking-at verilog-complete-reg)
+ (let* ((p (point)))
+ (while (and (looking-at verilog-extended-complete-re)
+ (progn (setq p (point))
+ (verilog-backward-token)
+ (/= p (point)))))
+ (goto-char p)))
+ ;; stop if we see a complete reg (previous found extended ones)
+ (looking-at verilog-basic-complete-re)
+ ;; stop if previous token is an ender
+ (save-excursion
+ (verilog-backward-token)
+ (or
+ (looking-at verilog-end-block-re)
+ (looking-at verilog-preprocessor-re))))) ;; end of test
(verilog-backward-syntactic-ws)
(verilog-backward-token))
- ;; Now point is where the previous line ended.
- (verilog-forward-syntactic-ws))
+ ;; 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)
+ (if (verilog-in-comment-p)
+ (verilog-backward-syntactic-ws))
(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)))
+ (catch 'done
+ (while (not (looking-at verilog-complete-reg))
+ (setq pt (point))
+ (verilog-backward-syntactic-ws)
+ (if (or (bolp)
+ (= (preceding-char) ?\;)
+ (save-excursion
+ (verilog-backward-token)
+ (looking-at verilog-ends-re)))
+ (progn
+ (goto-char pt)
+ (throw 'done t))
+ (verilog-backward-token))))
+ (verilog-forward-syntactic-ws)))
+;
+; (while (and
+; (not (looking-at verilog-complete-reg))
+; (not (bolp))
+; (not (= (preceding-char) ?\;)))
+; (verilog-backward-token)
+; (verilog-backward-syntactic-ws)
+; (setq pt (point)))
+; (goto-char pt)
+; ;(verilog-forward-syntactic-ws)
(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)))
+ (cond
+ ((verilog-in-directive-p)
+ (forward-line 1)
+ (backward-char 1))
+
+ ((looking-at verilog-beg-block-re)
+ (verilog-forward-sexp))
+
+ ((equal (char-after) ?\})
+ (forward-char))
+
+ ;; Skip to end of statement
+ ((condition-case nil
+ (setq pos
+ (catch 'found
+ (while t
+ (forward-sexp 1)
+ (verilog-skip-forward-comment-or-string)
+ (if (eolp)
+ (forward-line 1))
+ (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)))
+ )))
+
+ )
+ (error nil))
+ (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.
(t
(throw 'found (= nest 0)))))))
nil)))
+(defun verilog-backward-up-list (arg)
+ "Like backward-up-list, but deal with comments."
+ (let (saved-psic parse-sexp-ignore-comments)
+ (setq parse-sexp-ignore-comments 1)
+ (backward-up-list arg)
+ (setq parse-sexp-ignore-comments saved-psic)
+ ))
+
(defun verilog-in-struct-region-p ()
"Return true if in a struct region.
More specifically, in a list after a struct|union keyword."
(let* ((state (verilog-syntax-ppss))
(depth (nth 0 state)))
(if depth
- (progn (backward-up-list depth)
+ (progn (verilog-backward-up-list depth)
(verilog-beg-of-statement)
(looking-at "\\<typedef\\>?\\s-*\\<struct\\|union\\>"))))))
"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))
+ (let ((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)))))))
+ (catch 'done
+ (while (and
+ (/= nest 0)
+ (verilog-re-search-backward
+ "\\<\\(module\\)\\|\\(generate\\)\\|\\(endgenerate\\)\\>" nil 'move)
+ (cond
+ ((match-end 1) ; module - we have crawled out
+ (throw 'done 1))
+ ((match-end 2) ; generate
+ (setq nest (1- nest)))
+ ((match-end 3) ; endgenerate
+ (setq nest (1+ nest))))))))
(= nest 0) )) ; return nest
(defun verilog-in-fork-region-p ()
"\\(`endif\\>\\)\\|"
"\\(`if\\>\\)\\|"
"\\(`ifdef\\>\\)\\|"
- "\\(`ifndef\\>\\)"))
+ "\\(`ifndef\\>\\)\\|"
+ "\\(`elsif\\>\\)"))
(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.
(or kill-existing-comment
(not (save-excursion
(end-of-line)
- (search-backward "//" (verilog-get-beg-of-line) t)))))
+ (search-backward "//" (point-at-bol) t)))))
(let ((nest 1) b e
m
(else (if (match-end 2) "!" " ")))
((match-end 4) ; `ifdef
(setq nest (1- nest)))
((match-end 5) ; `ifndef
- (setq nest (1- nest)))))
+ (setq nest (1- nest)))
+ ((match-end 6) ; `elsif
+ (if (= nest 1)
+ (progn
+ (setq else "!")
+ (setq nest 0))))))
(if (match-end 0)
(setq
m (buffer-substring
(if (> (count-lines (point) b) verilog-minimum-comment-distance)
(insert (concat " // " else m " " (buffer-substring b e))))
(progn
- (insert " // unmatched `else or `endif")
+ (insert " // unmatched `else, `elsif or `endif")
(ding 't)))))
(; Comment close case/class/function/task/module and named block
(or kill-existing-comment
(not (save-excursion
(end-of-line)
- (search-backward "//" (verilog-get-beg-of-line) t)))))
+ (search-backward "//" (point-at-bol) t)))))
(let ((type (car indent-str)))
(unless (eq type 'declaration)
(unless (looking-at (concat "\\(" verilog-end-block-ordered-re "\\)[ \t]*:")) ;; ignore named ends
((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))))))
+ ((looking-at "\\(\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?\\)")
+ (goto-char (match-end 0))
+ (setq str (concat (match-string 0) " " (verilog-get-expr)))
+ (setq err nil))
+ ))
(end-of-line)
(if kill-existing-comment
(verilog-kill-existing-comment))
(cond
(;
(eq here (progn
- (verilog-backward-token)
- (verilog-beg-of-statement-1)
+ ;; (verilog-backward-token)
+ (verilog-beg-of-statement)
(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)) " "))
+ (setq cntx (concat (match-string 0) " "))
(cond
(;- begin
- (match-end 2)
+ (match-end 1)
(setq err nil)
(save-excursion
(if (and (verilog-continued-line)
(goto-char (match-end 0))
(setq there (point))
(setq str
- (concat " // "
- (buffer-substring (match-beginning 0) (match-end 0)) " "
- (verilog-get-expr))))
+ (concat " // " (match-string 0) " " (verilog-get-expr))))
(setq str ""))))
(;- else
- (match-end 4)
+ (match-end 2)
(let ((nest 0)
- ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)"))
+ ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)\\|\\(assert\\)"))
(catch 'skip
(while (verilog-re-search-backward reg nil 'move)
(cond
(setq err nil)
(setq str (verilog-get-expr))
(setq str (concat " // else: !if" str ))
+ (throw 'skip 1))))
+ ((match-end 4)
+ (if (= 0 nest)
+ (progn
+ (goto-char (match-end 0))
+ (setq there (point))
+ (setq err nil)
+ (setq str (verilog-get-expr))
+ (setq str (concat " // else: !assert " str ))
(throw 'skip 1)))))))))
-
(;- end else
- (match-end 5)
+ (match-end 3)
(goto-char there)
(let ((nest 0)
- (reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)"))
+ (reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)\\|\\(assert\\)"))
(catch 'skip
(while (verilog-re-search-backward reg nil 'move)
(cond
(setq err nil)
(setq str (verilog-get-expr))
(setq str (concat " // else: !if" str ))
+ (throw 'skip 1))))
+ ((match-end 4)
+ (if (= 0 nest)
+ (progn
+ (goto-char (match-end 0))
+ (setq there (point))
+ (setq err nil)
+ (setq str (verilog-get-expr))
+ (setq str (concat " // else: !assert " str ))
(throw 'skip 1)))))))))
+ (; always_comb, always_ff, always_latch
+ (or (match-end 4) (match-end 5) (match-end 6))
+ (goto-char (match-end 0))
+ (setq there (point))
+ (setq err nil)
+ (setq str (concat " // " cntx )))
+
(;- 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 )))
+ (setq str (concat " // " cntx (verilog-get-expr))))
(;-- otherwise...
(setq str " // auto-endcomment confused "))))
(setq b (progn
(skip-chars-forward "^ \t")
(verilog-forward-ws&directives)
+ (if (looking-at "static\\|automatic")
+ (progn
+ (goto-char (match-end 0))
+ (verilog-forward-ws&directives)))
(if (and name-re (verilog-re-search-forward name-re nil 'move))
(progn
(goto-char (match-beginning 0))
(t (error "Linter name not set")))))
(defvar compilation-last-buffer)
+(defvar next-error-last-buffer)
(defun verilog-surelint-off ()
"Convert a SureLint warning line into a disable statement.
(and (file-exists-p name)
(find-file-noselect name))))))))
(switch-to-buffer buffer)
- (goto-line (string-to-number line))
+ (goto-char (point-min))
+ (forward-line (- (string-to-number line)))
(end-of-line)
(catch 'already
(cond
(cond
((looking-at "// surefire lint_off_line ")
(goto-char (match-end 0))
- (let ((lim (save-excursion (end-of-line) (point))))
+ (let ((lim (point-at-eol)))
(if (re-search-forward code lim 'move)
(throw 'already t)
(insert (concat " " code)))))
(save-buffer)
(compile compile-command))
+(defun verilog-preprocess (&optional command filename)
+ "Preprocess the buffer, similar to `compile', but leave output in Verilog-Mode.
+Takes optional COMMAND or defaults to `verilog-preprocessor', and
+FILENAME or defaults to `buffer-file-name`."
+ (interactive
+ (list
+ (let ((default (verilog-expand-command verilog-preprocessor)))
+ (set (make-local-variable `verilog-preprocessor)
+ (read-from-minibuffer "Run Preprocessor (like this): "
+ default nil nil
+ 'verilog-preprocess-history default)))))
+ (unless command (setq command (verilog-expand-command verilog-preprocessor)))
+ (let* ((fontlocked (and (boundp 'font-lock-mode) font-lock-mode))
+ (dir (file-name-directory (or filename buffer-file-name)))
+ (file (file-name-nondirectory (or filename buffer-file-name)))
+ (cmd (concat "cd " dir "; " command " " file)))
+ (with-output-to-temp-buffer "*Verilog-Preprocessed*"
+ (with-current-buffer (get-buffer "*Verilog-Preprocessed*")
+ (insert (concat "// " cmd "\n"))
+ (shell-command cmd "*Verilog-Preprocessed*")
+ (verilog-mode)
+ ;; Without this force, it takes a few idle seconds
+ ;; to get the color, which is very jarring
+ (when fontlocked (font-lock-fontify-buffer))))))
\f
;;
(defun verilog-batch-execute-func (funref)
"Internal processing of a batch command, running FUNREF on all command arguments."
(verilog-batch-error-wrapper
+ ;; Setting global variables like that is *VERY NASTY* !!! --Stef
+ ;; However, this function is called only when Emacs is being used as
+ ;; a standalone language instead of as an editor, so we'll live.
+ ;;
;; 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)
+ (setq-default major-mode 'verilog-mode)
;; Ditto files already read in
(mapc (lambda (buf)
(when (buffer-file-name buf)
- (save-excursion
- (set-buffer buf)
+ (with-current-buffer buf
(verilog-mode))))
(buffer-list))
;; Process the files
- (mapcar '(lambda (buf)
+ (mapcar (lambda (buf)
(when (buffer-file-name buf)
(save-excursion
(if (not (file-exists-p (buffer-file-name buf)))
(throw 'nesting 'comment))
;; if we have a directive, done.
- (if (save-excursion (beginning-of-line) (looking-at verilog-directive-re-1))
+ (if (save-excursion (beginning-of-line)
+ (and (looking-at verilog-directive-re-1)
+ (not (or (looking-at "[ \t]*`ovm_")
+ (looking-at "[ \t]*`vmm_")))))
(throw 'nesting 'directive))
+ ;; indent structs as if there were module level
+ (if (verilog-in-struct-p)
+ (throw 'nesting 'block))
;; 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))
+ verilog-indent-lists
+ (verilog-in-paren)
+ (not (verilog-in-coverage-p))
+ )
(progn (setq par 1)
- (throw 'nesting 'block)))
+ (throw 'nesting 'block)))
;; See if we are continuing a previous line
(while t
(beginning-of-line)
(verilog-forward-syntactic-ws)
(throw 'nesting 'statement)))))
+ ((match-end 3) ; assert block
+ (setq elsec (1- elsec))
+ (verilog-beg-of-statement) ;; doesn't get to beginning
+ (if (looking-at verilog-property-re)
+ (throw 'nesting 'statement) ; We don't need an endproperty for these
+ (throw 'nesting 'block) ;We still need a endproperty
+ ))
(t ; endblock
; try to leap back to matching outward block by striding across
; indent level changing tokens then immediately
(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
+ ((match-end 4) ; end
;; Search back for matching begin
(setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
- ((match-end 4) ; endcase
+ ((match-end 5) ; endcase
;; Search back for matching case
(setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
- ((match-end 5) ; endfunction
+ ((match-end 6) ; endfunction
;; Search back for matching function
(setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
- ((match-end 6) ; endtask
+ ((match-end 7) ; endtask
;; Search back for matching task
(setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
- ((match-end 7) ; endspecify
+ ((match-end 8) ; endspecify
;; Search back for matching specify
(setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
- ((match-end 8) ; endtable
+ ((match-end 9) ; endtable
;; Search back for matching table
(setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
- ((match-end 9) ; endgenerate
+ ((match-end 10) ; endgenerate
;; Search back for matching generate
(setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
- ((match-end 10) ; joins
+ ((match-end 11) ; joins
;; Search back for matching fork
(setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|none\\)?\\>\\)" ))
- ((match-end 11) ; class
+ ((match-end 12) ; class
;; Search back for matching class
(setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
- ((match-end 12) ; covergroup
+ ((match-end 13) ; covergroup
;; Search back for matching covergroup
(setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" )))
(catch 'skip
(setq type 'cpp))
(if (and
verilog-indent-lists
- (not (verilog-in-coverage))
+ (not(or (verilog-in-coverage-p)
+ (verilog-in-struct-p)))
(verilog-in-paren))
(setq depth 1)
(cond
(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 ((re (concat "\\({\\|}\\|" verilog-indent-re "\\)")))
+ (while (verilog-re-search-backward re nil 'move)
+ (catch 'continue
+ (cond
+ ((equal (char-after) ?\{)
+ (if (verilog-at-constraint-p)
+ (throw 'nesting 'block)))
- (let ((there (verilog-at-close-constraint-p)))
- (if there (goto-char there))))
+ ((equal (char-after) ?\})
+ (let ((there (verilog-at-close-constraint-p)))
+ (if there ;; we are at the } that closes a constraint. Find the { that opens it
+ (progn
+ (forward-char 1)
+ (backward-list 1)
+ (verilog-beg-of-statement)))))
- ((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))
-
- ((match-end 4) ; *sigh* could be "disable fork"
- (let ((here (point)))
- (verilog-beg-of-statement)
- (if (looking-at verilog-disable-fork-re)
- t ; is disable fork, this is a normal statement
- (progn ; or is fork, starts a new block
- (goto-char here)
- (throw 'nesting 'block)))))
-
-
- ;; need to consider typedef struct here...
- ((looking-at "\\<class\\|struct\\|function\\|task\\>")
+ ((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))
+
+ ((match-end 4) ; *sigh* could be "disable fork"
+ (let ((here (point)))
+ (verilog-beg-of-statement)
+ (if (or (looking-at verilog-disable-fork-re)
+ (looking-at verilog-fork-wait-re))
+ t ; this is a normal statement
+ (progn ; or is fork, starts a new block
+ (goto-char here)
+ (throw 'nesting 'block)))))
+
+ ((match-end 27) ; *sigh* might be a clocking declaration
+ (let ((here (point)))
+ (if (verilog-in-paren)
+ t ; this is a normal statement
+ (progn ; or is fork, starts a new block
+ (goto-char here)
+ (throw 'nesting 'block)))))
+
+ ;; need to consider typedef struct here...
+ ((looking-at "\\<class\\|struct\\|function\\|task\\>")
; *sigh* These words have an optional prefix:
; extern {virtual|protected}? function a();
; typedef class foo;
; property
; ...
; endfunction
- (verilog-beg-of-statement)
- (if (looking-at verilog-beg-block-re-ordered)
- (throw 'nesting 'block)
- (throw 'nesting 'defun)))
+ (verilog-beg-of-statement)
+ (if (looking-at verilog-beg-block-re-ordered)
+ (throw 'nesting 'block)
+ (throw 'nesting 'defun)))
- ((looking-at "\\<property\\>")
- ; *sigh*
+ ((looking-at "\\<property\\>")
+ ; *sigh*
; {assert|assume|cover} property (); are complete
+ ; and could also be labeled: - foo: assert property
; but
; property ID () ... needs end_property
- (verilog-beg-of-statement)
- (if (looking-at "\\(assert\\|assume\\|cover\\)\\s-+property\\>")
- (throw 'nesting 'statement) ; We don't need an endproperty for these
- (throw 'nesting 'block) ;We still need a endproperty
- ))
-
- (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)))))
+ (verilog-beg-of-statement)
+ (if (looking-at verilog-property-re)
+ (throw 'continue 'statement) ; We don't need an endproperty for these
+ (throw 'nesting 'block) ;We still need a endproperty
+ ))
- ((looking-at (if (verilog-in-generate-region-p)
- verilog-defun-level-not-generate-re
- verilog-defun-level-re))
- (throw 'nesting 'defun))
+ (t (throw 'nesting 'block))))
- ((looking-at verilog-cpp-level-re)
- (throw 'nesting 'cpp))
+ ((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-extended-case-re)
+ (throw 'nesting 'case)))))
- ((bobp)
- (throw 'nesting 'cpp))))
- (throw 'nesting 'cpp)))
+ ((looking-at verilog-defun-level-re)
+ (if (looking-at verilog-defun-level-generate-only-re)
+ (if (verilog-in-generate-region-p)
+ (throw 'continue 'foo) ; always block in a generate - keep looking
+ (throw 'nesting 'defun))
+ (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.
(defun verilog-leap-to-case-head ()
(let ((nest 1))
(while (/= 0 nest)
- (verilog-re-search-backward "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" nil 'move)
+ (verilog-re-search-backward
+ (concat
+ "\\(\\<randcase\\>\\|\\(\\<unique\\s-+\\|priority\\s-+\\)?\\<case[xz]?\\>\\)"
+ "\\|\\(\\<endcase\\>\\)" )
+ nil 'move)
(cond
((match-end 1)
+ (let ((here (point)))
+ (verilog-beg-of-statement)
+ (unless (looking-at verilog-extended-case-re)
+ (goto-char here)))
(setq nest (1- nest)))
- ((match-end 2)
+ ((match-end 3)
(setq nest (1+ nest)))
((bobp)
(ding 't)
(setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|"
"\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))
((looking-at "\\<endtask\\>")
- ;; 9: Search back for matching task
+ ;; 2: Search back for matching task
(setq reg "\\(\\<task\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<task\\>\\)")
(setq nesting 'no))
((looking-at "\\<endcase\\>")
- ;; 2: Search back for matching case
- (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>\\)\\|\\(\\<endcase\\>\\)" ))
+ (catch 'nesting
+ (verilog-leap-to-case-head) )
+ (setq reg nil) ; to force skip
+ )
+
((looking-at "\\<join\\(_any\\|_none\\)?\\>")
- ;; 3: Search back for matching fork
+ ;; 4: Search back for matching fork
(setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
((looking-at "\\<endclass\\>")
- ;; 4: Search back for matching class
+ ;; 5: Search back for matching class
(setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
((looking-at "\\<endtable\\>")
- ;; 5: Search back for matching table
+ ;; 6: Search back for matching table
(setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
((looking-at "\\<endspecify\\>")
- ;; 6: Search back for matching specify
+ ;; 7: Search back for matching specify
(setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
((looking-at "\\<endfunction\\>")
- ;; 7: Search back for matching function
- (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
+ ;; 8: Search back for matching function
+ (setq reg "\\(\\<function\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<function\\>\\)")
+ (setq nesting 'no))
+ ;;(setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
((looking-at "\\<endgenerate\\>")
;; 8: Search back for matching generate
(setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
((looking-at "\\<endproperty\\>")
;; 11: Search back for matching property
(setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
+ ((looking-at verilog-ovm-end-re)
+ ;; 12: Search back for matching sequence
+ (setq reg (concat "\\(" verilog-ovm-begin-re "\\|" verilog-ovm-end-re "\\)")))
+ ((looking-at verilog-vmm-end-re)
+ ;; 12: Search back for matching sequence
+ (setq reg (concat "\\(" verilog-vmm-begin-re "\\|" verilog-vmm-end-re "\\)")))
((looking-at "\\<endinterface\\>")
;; 12: Search back for matching interface
(setq reg "\\(\\<interface\\>\\)\\|\\(\\<endinterface\\>\\)" ))
(while (verilog-re-search-backward reg nil 'move)
(cond
((match-end 1) ; begin
- (setq nest (1- nest))
+ (if (looking-at "fork")
+ (let ((here (point)))
+ (verilog-beg-of-statement)
+ (unless (looking-at verilog-disable-fork-re)
+ (goto-char here)
+ (setq nest (1- nest))))
+ (setq nest (1- nest)))
(if (= 0 nest)
;; Now previous line describes syntax
(throw 'skip 1))
)))
;no nesting
(if (and
- (verilog-re-search-backward reg nil 'move)
+ (verilog-re-search-backward reg nil 'move)
(match-end 1)) ; task -> could be virtual and/or protected
(progn
(verilog-beg-of-statement)
continued))
(defun verilog-backward-token ()
- "Step backward token, returning true if we are now at an end of line token."
+ "Step backward token, returing true if this is a continued line."
(interactive)
(verilog-backward-syntactic-ws)
(cond
(= (preceding-char) ?\})
(progn
(backward-char)
- (verilog-at-close-constraint-p)))
+ (not(verilog-at-close-constraint-p))))
(;-- constraint foo { a = b }
; is a complete statement. *sigh*
(= (preceding-char) ?\{)
(progn
(backward-char)
(not (verilog-at-constraint-p))))
+ (;" string "
+ (= (preceding-char) ?\")
+ (backward-char)
+ (verilog-skip-backward-comment-or-string)
+ nil)
+
+ (; [3:4]
+ (= (preceding-char) ?\])
+ (backward-char)
+ (verilog-backward-open-bracket)
+ t)
+
(;-- Could be 'case (foo)' or 'always @(bar)' which is complete
; also could be simply '@(foo)'
; or foo u1 #(a=8)
(= (preceding-char) ?\))
(progn
(backward-char)
- (backward-up-list 1)
+ (verilog-backward-up-list 1)
(verilog-backward-syntactic-ws)
(let ((back (point)))
(forward-word -1)
(cond
+ ;;XX
((looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|case\\(\\|[xz]\\)\\|for\\(\\|each\\|ever\\)\\|i\\(f\\|nitial\\)\\|repeat\\|while\\)\\>")
(not (looking-at "\\<randcase\\>\\|\\<case[xz]?\\>[^:]")))
+ ((looking-at verilog-ovm-statement-re)
+ nil)
+ ((looking-at verilog-ovm-begin-re)
+ t)
+ ((looking-at verilog-ovm-end-re)
+ t)
+ ;; JBA find VMM macros
+ ((looking-at verilog-vmm-statement-re)
+ nil )
+ ((looking-at verilog-vmm-begin-re)
+ t)
+ ((looking-at verilog-vmm-end-re)
+ nil)
+ ;; JBA trying to catch macro lines with no ; at end
+ ((looking-at "\\<`")
+ nil)
(t
(goto-char back)
(cond
(;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete
t
(forward-word -1)
+ (while (= (preceding-char) ?\_)
+ (forward-word -1))
(cond
((looking-at "\\<else\\>")
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-backward-syntactic-ws ()
+ (verilog-skip-backward-comments)
+ (forward-comment (- (buffer-size))))
-(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-forward-syntactic-ws ()
+ (verilog-skip-forward-comment-p)
+ (forward-comment (buffer-size)))
(defun verilog-backward-ws&directives (&optional bound)
"Backward skip over syntactic whitespace and compiler directives for Emacs 19.
(save-excursion
(beginning-of-line)
(cond
- ((verilog-within-translate-off)
+ ((and verilog-highlight-translate-off
+ (verilog-within-translate-off))
(verilog-back-to-start-translate-off (point-min)))
((looking-at verilog-directive-re-1)
(point))
(let ((state (save-excursion (verilog-syntax-ppss))))
(cond
((nth 7 state) ;; in // comment
- (verilog-re-search-forward "//" nil 'move))
+ (end-of-line)
+ (forward-char 1)
+ (skip-chars-forward " \t\n\f")
+ )
((nth 4 state) ;; in /* */ comment
- (verilog-re-search-forward "/\*" nil 'move))))
+ (verilog-re-search-forward "\*\/\\s-*" nil 'move))))
(narrow-to-region (point) bound)
(while (/= here (point))
(setq here (point)
jump nil)
(forward-comment (buffer-size))
+ (and (looking-at "\\s-*(\\*.*\\*)\\s-*") ;; Attribute
+ (goto-char (match-end 0)))
(save-excursion
(beginning-of-line)
(if (looking-at verilog-directive-re-1)
(let ((state (save-excursion (verilog-syntax-ppss))))
(or (nth 3 state) (nth 4 state) (nth 7 state)))) ; Inside string or comment)
+(defun verilog-in-attribute-p ()
+ "Return true if point is in an attribute (* [] attribute *)."
+ (save-excursion
+ (verilog-re-search-backward "\\((\\*\\)\\|\\(\\*)\\)" nil 'move)
+ (numberp (match-beginning 1))))
+
(defun verilog-in-escaped-name-p ()
"Return true if in an escaped name."
(save-excursion
(if (equal (char-after (point) ) ?\\ )
t
nil)))
+(defun verilog-in-directive-p ()
+ "Return true if in a directive."
+ (save-excursion
+ (beginning-of-line)
+ (looking-at verilog-directive-re-1)))
(defun verilog-in-paren ()
"Return true if in a parenthetical expression."
(let ((state (save-excursion (verilog-syntax-ppss))))
(> (nth 0 state) 0 )))
-(defun verilog-in-coverage ()
+(defun verilog-in-struct-p ()
+ "Return true if in a struct declaration."
+ (interactive)
+ (save-excursion
+ (if (verilog-in-paren)
+ (progn
+ (verilog-backward-up-list 1)
+ (verilog-at-struct-p)
+ )
+ nil)))
+
+(defun verilog-in-coverage-p ()
"Return true if in a constraint or coverpoint expression."
(interactive)
(save-excursion
(if (verilog-in-paren)
(progn
- (backward-up-list 1)
+ (verilog-backward-up-list 1)
(verilog-at-constraint-p)
)
nil)))
;; not
nil))
+(defun verilog-at-struct-p ()
+ "If at the { of a struct, return true, moving point to struct."
+ (save-excursion
+ (if (and (equal (char-after) ?\{)
+ (verilog-backward-token))
+ (looking-at "\\<struct\\|union\\|packed\\|\\(un\\)?signed\\>")
+ nil)))
+
(defun verilog-parenthesis-depth ()
"Return non zero if in parenthetical-expression."
(save-excursion (nth 1 (verilog-syntax-ppss))))
(= (char-before) ?\/)
(= (char-before (1- (point))) ?\*))
(goto-char (- (point) 2))
- t)
+ t) ;; Let nth 4 state handle the rest
+ ((and (not (bobp))
+ (= (char-before) ?\))
+ (= (char-before (1- (point))) ?\*))
+ (goto-char (- (point) 2))
+ (if (search-backward "(*" nil t)
+ (progn
+ (skip-chars-backward " \t\n\f")
+ t)
+ (progn
+ (goto-char (+ (point) 2))
+ nil)))
(t
- (skip-chars-backward " \t\n\f")
- nil)))))))
+ (/= (skip-chars-backward " \t\n\f") 0))))))))
(defun verilog-skip-forward-comment-p ()
"If in comment, move to end and return true."
- (let (state)
- (progn
- (setq state (save-excursion (verilog-syntax-ppss)))
- (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)))))
+ (let* (h
+ (state (save-excursion (verilog-syntax-ppss)))
+ (skip (cond
+ ((nth 3 state) ;Inside string
+ t)
+ ((nth 7 state) ;Inside // comment
+ (end-of-line)
+ (forward-char 1)
+ t)
+ ((nth 4 state) ;Inside /* comment
+ (search-forward "*/")
+ t)
+ ((verilog-in-attribute-p) ;Inside (* attribute
+ (search-forward "*)" nil t)
+ t)
+ (t nil))))
+ (skip-chars-forward " \t\n\f")
+ (while
+ (cond
+ ((looking-at "\\/\\*")
+ (progn
+ (setq h (point))
+ (goto-char (match-end 0))
+ (if (search-forward "*/" nil t)
+ (progn
+ (skip-chars-forward " \t\n\f")
+ (setq skip 't))
+ (progn
+ (goto-char h)
+ nil))))
+ ((looking-at "(\\*")
+ (progn
+ (setq h (point))
+ (goto-char (match-end 0))
+ (if (search-forward "*)" nil t)
+ (progn
+ (skip-chars-forward " \t\n\f")
+ (setq skip 't))
+ (progn
+ (goto-char h)
+ nil))))
+ (t nil)))
+ skip))
(defun verilog-indent-line-relative ()
"Cheap version of indent line.
((= (following-char) ?\[)
(progn
(forward-char 1)
- (backward-up-list -1)
+ (verilog-backward-up-list -1)
(skip-chars-forward " \t"))))
(current-column))
(progn
(; 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)
- ))
-
+ (let* ( here
+ (val (save-excursion
+ (verilog-backward-up-list 1)
+ (forward-char 1)
+ (if verilog-indent-lists
+ (skip-chars-forward " \t")
+ (verilog-forward-syntactic-ws))
+ (setq here (point))
+ (current-column)))
+
+ (decl (save-excursion
+ (goto-char here)
+ (verilog-forward-syntactic-ws)
+ (setq here (point))
+ (looking-at verilog-declaration-re))))
+ (indent-line-to val)
+ (if decl
+ (verilog-pretty-declarations))))
+
(;-- Handle the ends
(or
(looking-at verilog-end-block-re )
(cond
((looking-at verilog-named-block-re)
(current-column))
- ((and (not (looking-at verilog-case-re))
+ ((and (not (looking-at verilog-extended-case-re))
(looking-at "^[^:;]+[ \t]*:"))
(verilog-re-search-forward ":" nil t)
(skip-chars-forward " \t")
;;
(defun verilog-pretty-declarations (&optional quiet)
- "Line up declarations around point."
+ "Line up declarations around point.
+Be verbose about progress unless optional QUIET set."
(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 (and (not quiet)
- (> (- 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))
- (unless quiet (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))
- (unless quiet (message ""))))))
-
-(defun verilog-pretty-expr (&optional quiet myre)
- "Line up expressions around point, or optional regexp MYRE."
- (interactive "sRegular Expression: ((<|:)?=) ")
- (save-excursion
- (if (or (eq myre nil)
- (string-equal myre ""))
- (setq myre "\\(<\\|:\\)?="))
- (setq myre (concat "\\(^[^;#<=>]*\\)\\(" myre "\\)"))
- (let ((rexp(concat "^\\s-*" verilog-complete-reg)))
- (beginning-of-line)
- (if (and (not (looking-at rexp ))
- (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 rexp ))
- (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 rexp ))
- (looking-at myre))
- (end-of-line)
- (setq e (point))
- (verilog-forward-syntactic-ws)
- (beginning-of-line)
+ (let* ((m1 (make-marker))
+ (e (point))
+ el
+ r
+ (here (point))
+ ind
+ start
+ startpos
+ end
+ endpos
+ base-ind
+ )
+ (save-excursion
+ (if (progn
+; (verilog-beg-of-statement-1)
+ (beginning-of-line)
+ (verilog-forward-syntactic-ws)
+ (and (not (verilog-in-directive-p)) ;; could have `define input foo
+ (looking-at verilog-declaration-re)))
+ (progn
+ (if (verilog-parenthesis-depth)
+ ;; in an argument list or parameter block
+ (setq el (verilog-backward-up-list -1)
+ start (progn
+ (goto-char e)
+ (verilog-backward-up-list 1)
+ (forward-line) ;; ignore ( input foo,
+ (verilog-re-search-forward verilog-declaration-re el 'move)
+ (goto-char (match-beginning 0))
+ (skip-chars-backward " \t")
+ (point))
+ startpos (set-marker (make-marker) start)
+ end (progn
+ (goto-char start)
+ (verilog-backward-up-list -1)
+ (forward-char -1)
+ (verilog-backward-syntactic-ws)
+ (point))
+ endpos (set-marker (make-marker) end)
+ base-ind (progn
+ (goto-char start)
+ (forward-char 1)
+ (skip-chars-forward " \t")
+ (current-column))
)
- e))
- (edpos (set-marker (make-marker) end))
- (ind)
- )
- (goto-char start)
- (verilog-do-indent (verilog-calculate-indent))
+ ;; in a declaration block (not in argument list)
+ (setq
+ start (progn
+ (verilog-beg-of-statement-1)
+ (while (and (looking-at verilog-declaration-re)
+ (not (bobp)))
+ (skip-chars-backward " \t")
+ (setq e (point))
+ (beginning-of-line)
+ (verilog-backward-syntactic-ws)
+ (backward-char)
+ (verilog-beg-of-statement-1))
+ e)
+ startpos (set-marker (make-marker) start)
+ 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)
+ (verilog-end-of-statement)
+ (setq e (point))
+ (verilog-forward-syntactic-ws))
+ e)
+ endpos (set-marker (make-marker) end)
+ base-ind (progn
+ (goto-char start)
+ (verilog-do-indent (verilog-calculate-indent))
+ (verilog-forward-ws&directives)
+ (current-column))))
+ ;; OK, start and end are set
+ (goto-char (marker-position startpos))
(if (and (not quiet)
(> (- 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)
+ (message "Lining up declarations..(please stand by)"))
+ ;; Get the beginning of line indent first
+ (while (progn (setq e (marker-position endpos))
+ (< (point) e))
+ (cond
+ ((save-excursion (skip-chars-backward " \t")
+ (bolp))
+ (verilog-forward-ws&directives)
+ (indent-line-to base-ind)
+ (verilog-forward-ws&directives)
+ (if (< (point) e)
+ (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-2 myre start edpos))
-
+ (setq ind (verilog-get-lineup-indent (marker-position startpos) endpos))
;; Now indent each line.
- (goto-char start)
- (while (progn (setq e (marker-position edpos))
+ (goto-char (marker-position startpos))
+ (while (progn (setq e (marker-position endpos))
(setq r (- e (point)))
(> r 0))
(setq e (point))
- (if (not quiet) (message "%d" r))
+ (unless quiet (message "%d" r))
+ ;;(verilog-do-indent (verilog-calculate-indent)))
+ (verilog-forward-ws&directives)
(cond
- ((looking-at myre)
- (goto-char (match-end 1))
- (if (not (verilog-parenthesis-depth)) ;; ignore parenthsized exprs
- (if (eq (char-after) ?=)
- (indent-to (1+ ind)) ; line up the = of the <= with surrounding =
- (indent-to ind)
- )))
- ((verilog-continued-line-1 start)
+ ((or (and verilog-indent-declaration-macros
+ (looking-at verilog-declaration-re-2-macro))
+ (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))
+ (progn
+ (just-one-space)
+ (indent-to ind)))))
+ ((verilog-continued-line-1 (marker-position startpos))
(goto-char e)
(indent-line-to ind))
+ ((verilog-in-struct-p)
+ ;; could have a declaration of a user defined item
+ (goto-char e)
+ (verilog-end-of-statement))
(t ; Must be comment or white space
(goto-char e)
(verilog-forward-ws&directives)
- (forward-line -1))
- )
+ (forward-line -1)))
(forward-line 1))
- (unless quiet (message ""))
- )))))
+ (unless quiet (message "")))))))
+
+(defun verilog-pretty-expr (&optional quiet myre)
+ "Line up expressions around point, optionally QUIET with regexp MYRE."
+ (interactive "i\nsRegular Expression: ((<|:)?=) ")
+ (save-excursion
+ (if (or (eq myre nil)
+ (string-equal myre ""))
+ (setq myre "\\(<\\|:\\)?="))
+ ;; want to match the first <= | := | =
+ (setq myre (concat "\\(^.*?\\)\\(" myre "\\)"))
+ (let ((rexp(concat "^\\s-*" verilog-complete-reg)))
+ (beginning-of-line)
+ (if (and (not (looking-at rexp ))
+ (looking-at myre)
+ (save-excursion
+ (goto-char (match-beginning 2))
+ (not (verilog-in-comment-or-string-p))))
+ (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 rexp ))
+ (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 rexp ))
+ (looking-at myre)
+ (progn
+ (end-of-line)
+ (not (eq e (point)))))
+ (setq e (point))
+ (verilog-forward-syntactic-ws)
+ (beginning-of-line)
+ )
+ e))
+ (endpos (set-marker (make-marker) end))
+ (ind)
+ )
+ (goto-char start)
+ (verilog-do-indent (verilog-calculate-indent))
+ (if (and (not quiet)
+ (> (- end start) 100))
+ (message "Lining up expressions..(please stand by)"))
+
+ ;; Set indent to minimum throughout region
+ (while (< (point) (marker-position endpos))
+ (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 endpos))
+
+ ;; Now indent each line.
+ (goto-char start)
+ (while (progn (setq e (marker-position endpos))
+ (setq r (- e (point)))
+ (> r 0))
+ (setq e (point))
+ (if (not quiet) (message "%d" r))
+ (cond
+ ((looking-at myre)
+ (goto-char (match-beginning 2))
+ (if (not (verilog-parenthesis-depth)) ;; ignore parenthesized exprs
+ (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))
+ (unless quiet (message ""))
+ )))))
(defun verilog-just-one-space (myre)
"Remove extra spaces around regular expression MYRE."
(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 (or (eq 'all verilog-auto-lineup)
+ (eq 'declarations verilog-auto-lineup))
(if (verilog-re-search-backward
(or (and verilog-indent-declaration-macros
verilog-declaration-re-1-macro)
;; No lineup-string found
(goto-char b)
(end-of-line)
- (skip-chars-backward " \t")
+ (verilog-backward-syntactic-ws)
+ ;;(skip-chars-backward " \t")
(1+ (current-column))))))
(defun verilog-get-lineup-indent-2 (myre b edpos)
(while (progn (setq e (marker-position edpos))
(< (point) e))
(if (and (verilog-re-search-forward myre e 'move)
- (not (verilog-parenthesis-depth))) ;; skip parenthsized exprs
+ (not (verilog-parenthesis-depth))) ;; skip parenthesized exprs
(progn
(goto-char (match-beginning 2))
(verilog-backward-syntactic-ws)
'(
"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"
+ "notif1" "or" "output" "parameter" "pmos" "pull0" "pull1" "pulldown" "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...)")
+\(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.)
+\(initial, always, begin, assign...)
The procedures and variables defined within the Verilog program
will be completed at runtime and should not be added to this list.")
)
verilog-type-keywords)
"*Keywords to complete when at first word of a line in declarative scope.
-\(Eg. initial, always, begin, assign.)
+\(initial, always, begin, assign...)
The procedures and variables defined within the Verilog program
will be completed at runtime and should not be added to this list.")
"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.)
+\(begin, if, then, else, for, fork...)
The procedures and variables defined within the Verilog program
will be completed at 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.)
+\(begin, if, then, else, for, fork.)
The procedures and variables defined within the Verilog program
will be completed at 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.)
+\(begin, if, then, else, for, fork...)
The procedures and variables defined within the Verilog program
will be completed at 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.)
+\(else, then, begin...)
Variables and function names defined within the Verilog program
will be completed at runtime and should not be added to this list.")
+(defvar verilog-gate-ios
+ ;; All these have an implied {"input"...} at the end
+ '(("and" "output")
+ ("buf" "output")
+ ("bufif0" "output")
+ ("bufif1" "output")
+ ("cmos" "output")
+ ("nand" "output")
+ ("nmos" "output")
+ ("nor" "output")
+ ("not" "output")
+ ("notif0" "output")
+ ("notif1" "output")
+ ("or" "output")
+ ("pmos" "output")
+ ("pulldown" "output")
+ ("pullup" "output")
+ ("rcmos" "output")
+ ("rnmos" "output")
+ ("rpmos" "output")
+ ("rtran" "inout" "inout")
+ ("rtranif0" "inout" "inout")
+ ("rtranif1" "inout" "inout")
+ ("tran" "inout" "inout")
+ ("tranif0" "inout" "inout")
+ ("tranif1" "inout" "inout")
+ ("xnor" "output")
+ ("xor" "output"))
+ "*Map of direction for each positional argument to each gate primitive.")
+
+(defvar verilog-gate-keywords (mapcar `car verilog-gate-ios)
+ "*Keywords for gate primitives.")
+
(defun verilog-string-diff (str1 str2)
"Return index of first letter where STR1 and STR2 differs."
(catch 'done
(defun verilog-keyword-completion (keyword-list)
"Give list of all possible completions of keywords in KEYWORD-LIST."
- (mapcar '(lambda (s)
+ (mapcar (lambda (s)
(if (string-match (concat "\\<" verilog-str) s)
(if (or (null verilog-pred)
(funcall verilog-pred s))
(all-completions verilog-str 'verilog-completion)))
(match (if verilog-toggle-completions
"" (try-completion
- verilog-str (mapcar '(lambda (elm)
+ verilog-str (mapcar (lambda (elm)
(cons elm 0)) allcomp)))))
;; Delete old string
(delete-region b e)
(verilog-completion-response))))
(defun verilog-goto-defun ()
- "Move to specified Verilog module/task/function.
+ "Move to specified Verilog module/interface/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'."
(verilog-buffer-to-use (current-buffer))
(label (if (not (string= default ""))
;; Do completion with default
- (completing-read (concat "Label: (default " default ") ")
+ (completing-read (concat "Goto-Label: (default "
+ default ") ")
'verilog-comp-defun nil nil "")
;; There is no default value. Complete without it
- (completing-read "Label: "
+ (completing-read "Goto-Label: "
'verilog-comp-defun nil nil "")))
pt)
+ ;; Make sure library paths are correct, in case need to resolve module
+ (verilog-auto-reeval-locals)
+ (verilog-getopt-flags)
;; If there was no response on prompt, use default value
(if (string= label "")
(setq label default))
;; Added by Subbu Meiyappan for Header
(defun verilog-header ()
- "Insert a standard Verilog file header."
+ "Insert a standard Verilog file header.
+See also `verilog-sk-header' for an alternative format."
(interactive)
(let ((start (point)))
(insert "\
(defun verilog-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))
+ (if verilog-date-scientific-format
+ (insert (format-time-string "%Y/%m/%d"))
+ (insert (format-time-string "%d.%m.%Y"))))
(defun verilog-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))
+ (insert (format-time-string "%Y")))
\f
;;
;;
;; Elements of a signal list
+(defsubst verilog-sig-new (name bits comment mem enum signed type multidim modport)
+ (list name bits comment mem enum signed type multidim modport))
(defsubst verilog-sig-name (sig)
(car sig))
(defsubst verilog-sig-bits (sig)
(setq str (concat str (car args)))
(setq args (cdr args)))
str)))
+(defsubst verilog-sig-modport (sig)
+ (nth 8 sig))
(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-new (outputs temps inputs delayed)
+ (list outputs temps inputs delayed))
(defsubst verilog-alw-get-outputs (sigs)
(nth 0 sigs))
+(defsubst verilog-alw-get-temps (sigs)
+ (nth 1 sigs))
+(defsubst verilog-alw-get-inputs (sigs)
+ (nth 2 sigs))
(defsubst verilog-alw-get-uses-delayed (sigs)
(nth 3 sigs))
+(defsubst verilog-modi-new (name fob pt type)
+ (vector name fob pt type))
+(defsubst verilog-modi-name (modi)
+ (aref modi 0))
+(defsubst verilog-modi-file-or-buffer (modi)
+ (aref modi 1))
+(defsubst verilog-modi-get-point (modi)
+ (aref modi 2))
+(defsubst verilog-modi-get-type (modi) ;; "module" or "interface"
+ (aref modi 3))
+(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 verilog-modi-current
+(defsubst verilog-decls-new (out inout in wires regs assigns consts gparams interfaces)
+ (vector out inout in wires regs assigns consts gparams interfaces))
+(defsubst verilog-decls-get-outputs (decls)
+ (aref decls 0))
+(defsubst verilog-decls-get-inouts (decls)
+ (aref decls 1))
+(defsubst verilog-decls-get-inputs (decls)
+ (aref decls 2))
+(defsubst verilog-decls-get-wires (decls)
+ (aref decls 3))
+(defsubst verilog-decls-get-regs (decls)
+ (aref decls 4))
+(defsubst verilog-decls-get-assigns (decls)
+ (aref decls 5))
+(defsubst verilog-decls-get-consts (decls)
+ (aref decls 6))
+(defsubst verilog-decls-get-gparams (decls)
+ (aref decls 7))
+(defsubst verilog-decls-get-interfaces (decls)
+ (aref decls 8))
+
+(defsubst verilog-subdecls-new (out inout in intf intfd)
+ (vector out inout in intf intfd))
+(defsubst verilog-subdecls-get-outputs (subdecls)
+ (aref subdecls 0))
+(defsubst verilog-subdecls-get-inouts (subdecls)
+ (aref subdecls 1))
+(defsubst verilog-subdecls-get-inputs (subdecls)
+ (aref subdecls 2))
+(defsubst verilog-subdecls-get-interfaces (subdecls)
+ (aref subdecls 3))
+(defsubst verilog-subdecls-get-interfaced (subdecls)
+ (aref subdecls 4))
+
(defun verilog-signals-not-in (in-list not-list)
"Return list of signals in IN-LIST that aren't also in NOT-LIST.
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)))
+ ;; This function is hot, so implemented as O(1)
+ (cond ((eval-when-compile (fboundp 'make-hash-table))
+ (let ((ht (make-hash-table :test 'equal :rehash-size 4.0))
+ out-list)
+ (while not-list
+ (puthash (car (car not-list)) t ht)
+ (setq not-list (cdr not-list)))
+ (while in-list
+ (when (not (gethash (car (car in-list)) ht))
+ (setq out-list (cons (car in-list) out-list))
+ (puthash (car (car in-list)) t ht))
+ (setq in-list (cdr in-list)))
+ (nreverse out-list)))
+ ;; Slower Fallback if no hash tables (pre Emacs 21.1/XEmacs 21.4)
+ (t
+ (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)
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
+ sv-modport
bus)
;; Shove signals so duplicated signals will be adjacent
(setq in-list (sort in-list `verilog-signals-sort-compare))
sv-signed (verilog-sig-signed sig)
sv-type (verilog-sig-type sig)
sv-multidim (verilog-sig-multidim sig)
+ sv-modport (verilog-sig-modport sig)
combo ""
buswarn ""))
;; Extract bus details
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))))
+ sv-multidim (or sv-multidim (verilog-sig-multidim sig))
+ sv-modport (or sv-modport (verilog-sig-modport 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
+ (cons (verilog-sig-new
+ 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-memory sv-enum sv-signed sv-type sv-multidim sv-modport)
+ out-list)
sv-name nil))))
;;
out-list))
(verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil))
(skip-chars-backward "a-zA-Z0-9`_$"))
+(defun verilog-read-inst-module-matcher ()
+ "Set match data 0 with module_name when point is inside instantiation."
+ (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))
+ ;; Caller assumes match-beginning/match-end is still set
+ )
+
(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))))
+ (verilog-read-inst-module-matcher)))
(defun verilog-read-inst-name ()
"Return instance_name when point is inside instantiation."
(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))))
+ (verilog-symbol-detick
+ (buffer-substring-no-properties (match-beginning 0) (match-end 0)) t)))
(defun verilog-read-inst-param-value ()
"Return list of parameters and values when point is inside instantiation."
"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)
+ (functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t)
+ in-modport
+ sigs-in sigs-out sigs-inout sigs-wire sigs-reg sigs-assign sigs-const
+ sigs-gparam sigs-intf
+ vec expect-signal keywd newsig rvalue enum io signed typedefed multidim
+ modport)
(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)))
+ ;;(if dbg (setq dbg (concat dbg (format "Pt %s Vec %s C%c Kwd'%s'\n" (point) vec (following-char) keywd))))
(cond
((looking-at "//")
(if (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
(search-forward "\n"))
((looking-at "/\\*")
(forward-char 2)
- (if (looking-at "[^*]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
+ (if (looking-at "[^\n]*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 @ (*)"
+ (or (looking-at "\\s-*)") ; It's an "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)
+ (setq vec nil io nil expect-signal nil newsig nil paren 0 rvalue nil
+ v2kargs-ok nil in-modport 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))))
+ ((and (eq ?, (following-char))
+ (eq paren sig-paren))
+ (setq rvalue nil)
+ (forward-char 1))
+ ;; ,'s can occur inside {} & funcs
+ ((looking-at "[{(]")
+ (setq paren (1+ paren))
+ (forward-char 1))
+ ((looking-at "[})]")
+ (setq paren (1- paren))
+ (forward-char 1)
+ (when (< paren sig-paren)
+ (setq expect-signal nil))) ; ) that ends variables inside v2k arg list
((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)))
+ (setcar (cdr (cdr (cdr newsig)))
+ (if (verilog-sig-memory newsig)
+ (concat (verilog-sig-memory newsig) (match-string 1))
+ (match-string 1))))
(vec ;; Multidimensional
(setq multidim (cons vec multidim))
(setq vec (verilog-string-replace-matches
((looking-at "\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
(goto-char (match-end 0))
(setq keywd (match-string 1))
- (when (string-match "^\\\\" keywd)
+ (when (string-match "^\\\\" (match-string 1))
(setq keywd (concat keywd " "))) ;; Escaped ID needs space at end
+ ;; Add any :: package names to same identifier
+ (while (looking-at "\\s-*::\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
+ (goto-char (match-end 0))
+ (setq keywd (concat keywd "::" (match-string 1)))
+ (when (string-match "^\\\\" (match-string 1))
+ (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))
+ expect-signal 'sigs-in io t modport nil))
((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))
+ expect-signal 'sigs-out io t modport nil))
((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"))
+ expect-signal 'sigs-inout io t modport nil))
+ ((equal keywd "parameter")
+ (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
+ expect-signal 'sigs-gparam io t modport nil))
+ ((member keywd '("wire" "tri" "tri0" "tri1" "triand" "trior" "wand" "wor"))
(unless io (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
- expect-signal 'sigs-wire)))
- ((member keywd (list "reg" "trireg"
- "byte" "shortint" "int" "longint" "integer" "time"
- "bit" "logic"))
+ expect-signal 'sigs-wire modport nil)))
+ ((member keywd '("reg" "trireg"
+ "byte" "shortint" "int" "longint" "integer" "time"
+ "bit" "logic"
+ "shortreal" "real" "realtime"
+ "string" "event" "chandle"))
(unless io (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
- expect-signal 'sigs-reg)))
+ expect-signal 'sigs-reg modport nil)))
((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")
- (equal keywd "genvar"))
+ expect-signal 'sigs-assign modport nil))
+ ((member keywd '("supply0" "supply1" "supply"
+ "localparam" "genvar"))
(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)))
+ expect-signal 'sigs-const modport nil)))
((equal keywd "signed")
(setq signed "signed"))
- ((or (equal keywd "function")
- (equal keywd "task"))
+ ((member keywd '("class" "clocking" "covergroup" "function"
+ "property" "randsequence" "sequence" "task"))
(setq functask (1+ functask)))
- ((or (equal keywd "endfunction")
- (equal keywd "endtask"))
+ ((member keywd '("endclass" "endclocking" "endgroup" "endfunction"
+ "endproperty" "endsequence" "endtask"))
(setq functask (1- functask)))
- ((or (equal keywd "`ifdef")
- (equal keywd "`ifndef"))
+ ((equal keywd "modport")
+ (setq in-modport t))
+ ;; Ifdef? Ignore name of define
+ ((member keywd '("`ifdef" "`ifndef" "`elsif"))
(setq rvalue t))
+ ;; Type?
((verilog-typedef-name-p keywd)
(setq typedefed keywd))
+ ;; Interface with optional modport in v2k arglist?
+ ;; Skip over parsing modport, and take the interface name as the type
+ ((and v2kargs-ok
+ (eq paren 1)
+ (not rvalue)
+ (looking-at "\\s-*\\(\\.\\(\\s-*[a-zA-Z`_$][a-zA-Z0-9`_$]*\\)\\|\\)\\s-*[a-zA-Z`_$][a-zA-Z0-9`_$]*"))
+ (when (match-end 2) (goto-char (match-end 2)))
+ (setq vec nil enum nil rvalue nil newsig nil signed nil typedefed keywd multidim nil sig-paren paren
+ expect-signal 'sigs-intf io t modport (match-string 2)))
+ ;; Ignore dotted LHS assignments: "assign foo.bar = z;"
+ ((looking-at "\\s-*\\.")
+ (goto-char (match-end 0))
+ (when (not rvalue)
+ (setq expect-signal nil)))
+ ;; New signal, maybe?
((and expect-signal
- (eq functask 0)
(not rvalue)
- (eq paren sig-paren)
+ (eq functask 0)
+ (not in-modport)
(not (member keywd verilog-keywords)))
;; Add new signal to expect-signal's variable
- (setq newsig (list keywd vec nil nil enum signed typedefed multidim))
+ (setq newsig (verilog-sig-new keywd vec nil nil enum signed typedefed multidim modport))
(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)))))
+ (verilog-decls-new (nreverse sigs-out)
+ (nreverse sigs-inout)
+ (nreverse sigs-in)
+ (nreverse sigs-wire)
+ (nreverse sigs-reg)
+ (nreverse sigs-assign)
+ (nreverse sigs-const)
+ (nreverse sigs-gparam)
+ (nreverse sigs-intf)))))
+
+(defvar verilog-read-sub-decls-in-interfaced nil
+ "For `verilog-read-sub-decls', process next signal as under interfaced block.")
+
+(defvar verilog-read-sub-decls-gate-ios nil
+ "For `verilog-read-sub-decls', gate IO pins remaining, nil if non-primitive.")
(eval-when-compile
;; Prevent compile warnings; these are let's, not globals
;; - we want a error when we are debugging this code if they are refed.
(defvar sigs-in)
(defvar sigs-inout)
- (defvar sigs-out))
-
-
-(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-decls-get-outputs (decls)
- (aref decls 0))
-(defsubst verilog-decls-get-inouts (decls)
- (aref decls 1))
-(defsubst verilog-decls-get-inputs (decls)
- (aref decls 2))
-(defsubst verilog-decls-get-wires (decls)
- (aref decls 3))
-(defsubst verilog-decls-get-regs (decls)
- (aref decls 4))
-(defsubst verilog-decls-get-assigns (decls)
- (aref decls 5))
-(defsubst verilog-decls-get-consts (decls)
- (aref decls 6))
-(defsubst verilog-decls-get-gparams (decls)
- (aref decls 7))
-(defsubst verilog-subdecls-get-outputs (subdecls)
- (aref subdecls 0))
-(defsubst verilog-subdecls-get-inouts (subdecls)
- (aref subdecls 1))
-(defsubst verilog-subdecls-get-inputs (subdecls)
- (aref subdecls 2))
-
+ (defvar sigs-out)
+ (defvar sigs-intf)
+ (defvar sigs-intfd))
(defun verilog-read-sub-decls-sig (submoddecls comment port sig vec multidim)
"For `verilog-read-sub-decls-line', add a signal."
- (let (portdata)
+ ;; sig eq t to indicate .name syntax
+ ;;(message "vrsds: %s(%S)" port sig)
+ (let ((dotname (eq sig t))
+ 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)))
+ (setq sig (if dotname port (verilog-symbol-detick-denumber 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-decls-get-inouts submoddecls)))
- (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-decls-get-outputs submoddecls)))
- (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-decls-get-inputs submoddecls)))
- (setq sigs-in (cons (list sig vec (concat "To " comment) nil nil
- (verilog-sig-signed portdata)
- (verilog-sig-type portdata)
- multidim)
- sigs-in)))
+ (cond ((or (setq portdata (assoc port (verilog-decls-get-inouts submoddecls)))
+ (equal "inout" verilog-read-sub-decls-gate-ios))
+ (setq sigs-inout
+ (cons (verilog-sig-new
+ sig
+ (if dotname (verilog-sig-bits portdata) vec)
+ (concat "To/From " comment)
+ (verilog-sig-memory portdata)
+ nil
+ (verilog-sig-signed portdata)
+ (verilog-sig-type portdata)
+ multidim nil)
+ sigs-inout)))
+ ((or (setq portdata (assoc port (verilog-decls-get-outputs submoddecls)))
+ (equal "output" verilog-read-sub-decls-gate-ios))
+ (setq sigs-out
+ (cons (verilog-sig-new
+ sig
+ (if dotname (verilog-sig-bits portdata) vec)
+ (concat "From " comment)
+ (verilog-sig-memory portdata)
+ nil
+ (verilog-sig-signed portdata)
+ (verilog-sig-type portdata)
+ multidim nil)
+ sigs-out)))
+ ((or (setq portdata (assoc port (verilog-decls-get-inputs submoddecls)))
+ (equal "input" verilog-read-sub-decls-gate-ios))
+ (setq sigs-in
+ (cons (verilog-sig-new
+ sig
+ (if dotname (verilog-sig-bits portdata) vec)
+ (concat "To " comment)
+ (verilog-sig-memory portdata)
+ nil
+ (verilog-sig-signed portdata)
+ (verilog-sig-type portdata)
+ multidim nil)
+ sigs-in)))
+ ((setq portdata (assoc port (verilog-decls-get-interfaces submoddecls)))
+ (setq sigs-intf
+ (cons (verilog-sig-new
+ sig
+ (if dotname (verilog-sig-bits portdata) vec)
+ (concat "To/From " comment)
+ (verilog-sig-memory portdata)
+ nil
+ (verilog-sig-signed portdata)
+ (verilog-sig-type portdata)
+ multidim nil)
+ sigs-intf)))
+ ((setq portdata (and verilog-read-sub-decls-in-interfaced
+ (or (assoc port (verilog-decls-get-regs submoddecls))
+ (assoc port (verilog-decls-get-wires submoddecls)))))
+ (setq sigs-intfd
+ (cons (verilog-sig-new
+ sig
+ (if dotname (verilog-sig-bits portdata) vec)
+ (concat "To/From " comment)
+ (verilog-sig-memory portdata)
+ nil
+ (verilog-sig-signed portdata)
+ (verilog-sig-type portdata)
+ multidim nil)
+ sigs-intf)))
;; (t -- warning pin isn't defined.) ; Leave for lint tool
)))))
+(defun verilog-read-sub-decls-expr (submoddecls comment port expr)
+ "For `verilog-read-sub-decls-line', parse a subexpression and add signals."
+ ;;(message "vrsde: '%s'" expr)
+ ;; Replace special /*[....]*/ comments inserted by verilog-auto-inst-port
+ (setq expr (verilog-string-replace-matches "/\\*\\(\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
+ ;; Remove front operators
+ (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
+ ;;
+ (cond
+ ;; {..., a, b} requires us to recurse on a,b
+ ;; To support {#{},{#{a,b}} we'll just split everything on [{},]
+ ((string-match "^\\s-*{\\(.*\\)}\\s-*$" expr)
+ (unless verilog-auto-ignore-concat
+ (let ((mlst (split-string (match-string 1 expr) "[{},]"))
+ mstr)
+ (while (setq mstr (pop mlst))
+ (verilog-read-sub-decls-expr submoddecls comment port mstr)))))
+ (t
+ (let (sig vec multidim)
+ ;; Remove leading reduction operators, etc
+ (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
+ ;;(message "vrsde-ptop: '%s'" expr)
+ (cond ;; Find \signal. Final space is part of escaped signal name
+ ((string-match "^\\s-*\\(\\\\[^ \t\n\f]+\\s-\\)" expr)
+ ;;(message "vrsde-s: '%s'" (match-string 1 expr))
+ (setq sig (match-string 1 expr)
+ expr (substring expr (match-end 0))))
+ ;; Find signal
+ ((string-match "^\\s-*\\([a-zA-Z_][a-zA-Z_0-9]*\\)" expr)
+ ;;(message "vrsde-s: '%s'" (match-string 1 expr))
+ (setq sig (verilog-string-remove-spaces (match-string 1 expr))
+ expr (substring expr (match-end 0)))))
+ ;; Find [vector] or [multi][multi][multi][vector]
+ (while (string-match "^\\s-*\\(\\[[^]]+\\]\\)" expr)
+ ;;(message "vrsde-v: '%s'" (match-string 1 expr))
+ (when vec (setq multidim (cons vec multidim)))
+ (setq vec (match-string 1 expr)
+ expr (substring expr (match-end 0))))
+ ;; If found signal, and nothing unrecognized, add the signal
+ ;;(message "vrsde-rem: '%s'" expr)
+ (when (and sig (string-match "^\\s-*$" expr))
+ (verilog-read-sub-decls-sig submoddecls comment port sig vec multidim))))))
+
(defun verilog-read-sub-decls-line (submoddecls comment)
- "For `verilog-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)
+ "For `verilog-read-sub-decls', read lines of port defs until none match.
+Inserts the list of signals found, using submodi to look up each port."
+ (let (done port)
(save-excursion
(forward-line 1)
(while (not done)
(cond ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*(\\s-*")
(setq port (match-string 1))
(goto-char (match-end 0)))
+ ;; .\escaped (
((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)))
+ ;; .name
+ ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*[,)/]")
+ (verilog-read-sub-decls-sig
+ submoddecls comment (match-string 1) t ; sig==t for .name
+ nil nil) ; vec multidim
+ (setq port nil))
+ ;; .\escaped_name
+ ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*[,)/]")
+ (verilog-read-sub-decls-sig
+ submoddecls comment (concat (match-string 1) " ") t ; sig==t for .name
+ nil nil) ; vec multidim
+ (setq port nil))
+ ;; random
((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
+ ;; Get signal name. Point is at the first-non-space after (
+ ;; We intentionally ignore (non-escaped) signals with .s in them
+ ;; this prevents AUTOWIRE etc from noticing hierarchical sigs.
(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 submoddecls comment port sig vec multidim))))
- (t
- (setq sig nil)))
- ;; Process signals
- (verilog-read-sub-decls-sig submoddecls comment port sig vec multidim))
+ (cond ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*)")
+ (verilog-read-sub-decls-sig
+ submoddecls comment port
+ (verilog-string-remove-spaces (match-string 1)) ; sig
+ nil nil)) ; vec multidim
+ ;;
+ ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*)")
+ (verilog-read-sub-decls-sig
+ submoddecls comment port
+ (verilog-string-remove-spaces (match-string 1)) ; sig
+ (match-string 2) nil)) ; vec multidim
+ ;; Fastpath was above looking-at's.
+ ;; For something more complicated invoke a parser
+ ((looking-at "[^)]+")
+ (verilog-read-sub-decls-expr
+ submoddecls comment port
+ (buffer-substring
+ (point) (1- (progn (search-backward "(") ; start at (
+ (forward-sexp 1) (point)))))))) ; expr
;;
(forward-line 1)))))
+(defun verilog-read-sub-decls-gate (submoddecls comment submod end-inst-point)
+ "For `verilog-read-sub-decls', read lines of UDP gate decl until none match.
+Inserts the list of signals found."
+ (save-excursion
+ (let ((iolist (cdr (assoc submod verilog-gate-ios))))
+ (while (< (point) end-inst-point)
+ ;; Get primitive's signal name, as will never have port, and no trailing )
+ (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))))
+ ;; On pins, parse and advance to next pin
+ ;; Looking at pin, but *not* an // Output comment, or ) to end the inst
+ ((looking-at "\\s-*[a-zA-Z0-9`_$({}\\\\][^,]*")
+ (goto-char (match-end 0))
+ (setq verilog-read-sub-decls-gate-ios (or (car iolist) "input")
+ iolist (cdr iolist))
+ (verilog-read-sub-decls-expr
+ submoddecls comment "primitive_port"
+ (match-string 0)))
+ (t
+ (forward-char 1)
+ (skip-syntax-forward " ")))))))
+
(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
(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)
+ sigs-out sigs-inout sigs-in sigs-intf sigs-intfd)
(verilog-beg-of-defun)
(while (verilog-re-search-forward "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-mod-point t)
(save-excursion
;; Attempt to snarf a comment
(let* ((submod (verilog-read-inst-module))
(inst (verilog-read-inst-name))
+ (subprim (member submod verilog-gate-keywords))
(comment (concat inst " of " submod ".v"))
submodi submoddecls)
- (when (setq submodi (verilog-modi-lookup submod t))
- (setq submoddecls (verilog-modi-get-decls submodi))
- ;; 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
+ (cond
+ (subprim
+ (setq submodi `primitive
+ submoddecls (verilog-decls-new nil nil nil nil nil nil nil nil nil)
+ comment (concat inst " of " submod))
(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 submoddecls comment)) ;; Modifies sigs-out
- (goto-char st-point)
- (while (re-search-forward "\\s *// Inouts" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-inout
- (goto-char st-point)
- (while (re-search-forward "\\s *// Inputs" end-inst-point t)
- (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-in
- )))))
+ (forward-char 1)
+ (verilog-read-sub-decls-gate submoddecls comment submod end-inst-point))
+ ;; Non-primitive
+ (t
+ (when (setq submodi (verilog-modi-lookup submod t))
+ (setq submoddecls (verilog-modi-get-decls submodi)
+ verilog-read-sub-decls-gate-ios nil)
+ (verilog-backward-open-paren)
+ (setq end-inst-point (save-excursion (forward-sexp 1) (point))
+ st-point (point))
+ ;; 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
+ (let ((verilog-read-sub-decls-in-interfaced t))
+ (while (re-search-forward "\\s *(?\\s *// Interfaced" end-inst-point t)
+ (verilog-read-sub-decls-line submoddecls comment))) ;; Modifies sigs-ifd
+ (goto-char st-point)
+ (while (re-search-forward "\\s *(?\\s *// Interfaces" end-inst-point t)
+ (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-out
+ (goto-char st-point)
+ (while (re-search-forward "\\s *(?\\s *// Outputs" end-inst-point t)
+ (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-out
+ (goto-char st-point)
+ (while (re-search-forward "\\s *(?\\s *// Inouts" end-inst-point t)
+ (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-inout
+ (goto-char st-point)
+ (while (re-search-forward "\\s *(?\\s *// Inputs" end-inst-point t)
+ (verilog-read-sub-decls-line submoddecls 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))))))
+ (verilog-subdecls-new
+ (verilog-signals-combine-bus (nreverse sigs-out))
+ (verilog-signals-combine-bus (nreverse sigs-inout))
+ (verilog-signals-combine-bus (nreverse sigs-in))
+ (verilog-signals-combine-bus (nreverse sigs-intf))
+ (verilog-signals-combine-bus (nreverse sigs-intfd))))))
(defun verilog-read-inst-pins ()
"Return an array of [ pins ] for the current instantiation at point.
(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."
+(defvar verilog-cache-has-lisp nil "True if any AUTO_LISP in buffer.")
+(make-variable-buffer-local 'verilog-cache-has-lisp)
+
+(defun verilog-read-auto-lisp-present ()
+ "Set `verilog-cache-has-lisp' if any AUTO_LISP in this buffer."
(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)))))
+ (setq verilog-cache-has-lisp (re-search-forward "\\<AUTO_LISP(" nil t))))
+
+(defun verilog-read-auto-lisp (start end)
+ "Look for and evaluate a AUTO_LISP between START and END.
+Must call `verilog-read-auto-lisp-present' before this function."
+ ;; This function is expensive for large buffers, so we cache if any AUTO_LISP exists
+ (when verilog-cache-has-lisp
+ (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
;; Prevent compile warnings; these are let's, not globals
;; - we want a error when we are debugging this code if they are refed.
(defvar sigs-in)
(defvar sigs-out)
- (defvar got-sig)
- (defvar got-rvalue)
+ (defvar sigs-temp)
(defvar uses-delayed)
(defvar vector-skip-list))
(defun verilog-read-always-signals-recurse
- (exit-keywd rvalue ignore-next)
+ (exit-keywd rvalue temp-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))))
+ keywd last-keywd sig-tolk sig-last-tolk gotend got-sig got-list end-else-check
+ ignore-next)
+ ;;(if dbg (setq dbg (concat dbg (format "Recursion %S %S %S\n" exit-keywd rvalue temp-next))))
(while (not (or (eobp) gotend))
(cond
((looking-at "//")
(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))))
+ ;;(if dbg (setq dbg (concat dbg (format "\tPt=%S %S\trv=%S in=%S ee=%S gs=%S\n" (point) keywd rvalue ignore-next end-else-check got-sig))))
(cond
((equal keywd "\"")
(or (re-search-forward "[^\\]\"" nil t)
(setq end-else-check t))
(forward-char 1))
((equal keywd "'")
- (if (looking-at "'s?[hdxbo][0-9a-fA-F_xz? \t]*")
+ (if (looking-at "'[sS]?[hdxboHDXBO]?[ \t]*[0-9a-fA-F_xzXZ?]+")
(goto-char (match-end 0))
(forward-char 1)))
((equal keywd ":") ;; Case statement, begin/end label, x?y:z
(setq ignore-next nil rvalue nil))
((equal "?" exit-keywd) ;; x?y:z rvalue
) ;; NOP
+ ((equal "]" exit-keywd) ;; [x:y] 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) ?< )
+ (if (and (eq (char-before) ?< )
+ (not rvalue))
(setq uses-delayed 1))
(setq ignore-next nil rvalue t)
(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)
+ ;; temp-next: Variables on LHS are lvalues, but generally we want
+ ;; to ignore them, assuming they are loop increments
+ (verilog-read-always-signals-recurse ";" nil t)
(verilog-read-always-signals-recurse ";" t nil)
(verilog-read-always-signals-recurse ")" nil nil))
(t (verilog-read-always-signals-recurse ")" t 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"))
+ ((member keywd '("case" "casex" "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"))
+ (cond ((member keywd '("`ifdef" "`ifndef" "`elsif"))
(setq ignore-next t))
((or ignore-next
(member keywd verilog-keywords)
(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))))
+ (set got-list (cons got-sig (symbol-value got-list)))
+ ;;(if dbg (setq dbg (concat dbg (format "\t\tgot-sig=%S got-list=%S\n" got-sig got-list))))
)
- (setq got-rvalue rvalue
+ (setq got-list (cond (temp-next 'sigs-temp)
+ (rvalue 'sigs-in)
+ (t 'sigs-out))
got-sig (if (or (not keywd)
- (assoc keywd (if got-rvalue sigs-in sigs-out)))
+ (assoc keywd (symbol-value got-list)))
nil (list keywd nil nil))
+ temp-next nil
sig-tolk t)))
(skip-chars-forward "a-zA-Z0-9$_.%`"))
(t
(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))))
+ ;;(if dbg (setq dbg (concat dbg (format "\t\tfinal got-sig=%S got-list=%s\n" got-sig got-list))))
+ (set got-list (cons got-sig (symbol-value got-list)))
(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
+ sigs-out sigs-temp sigs-in
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 "")))
+ ;;(if dbg (with-current-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))))
+ (verilog-alw-new sigs-out sigs-temp sigs-in uses-delayed))))
(defun verilog-read-instants ()
"Parse module at point and return list of ( ( file instance ) ... )."
(let ((tpl-regexp "\\([0-9]+\\)")
(lineno 0)
(templateno 0)
+ (pt (point))
tpl-sig-list tpl-wild-list tpl-end-pt rep)
+ ;; Note this search is expensive, as we hunt from mod-begin to point
+ ;; for every instantiation. Likewise in verilog-read-auto-lisp.
+ ;; So, we look first for an exact string rather than a slow regexp.
+ ;; Someday we may keep a cache of every template, but this would also
+ ;; need to record the relative position of each AUTOINST, as multiple
+ ;; templates exist for each module, and we're inserting lines.
(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)))
+ (verilog-re-search-backward-substr
+ "AUTO_TEMPLATE"
+ (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)
+ ;; Also try forward of this AUTOINST
+ ;; This is for historical support; this isn't speced as working
+ (progn
+ (goto-char pt)
+ (verilog-re-search-forward-substr
+ "AUTO_TEMPLATE"
+ (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-*\"\\([^\"]*)\\)\"")
+ ;; 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 "(")
(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)))
+ (with-current-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)
+ (set (make-local-variable 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)))))
+ (unless (boundp enumvar) (set enumvar nil))
+ (add-to-list (make-local-variable enumvar) defname)))))
(defun verilog-read-defines (&optional filename recurse subcall)
"Read `defines and parameters for the current file, or optional 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))))
+ (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
;; 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)
+ "^\\s-*\\(parameter\\|localparam\\)\\(\\s-*\\[[^]]*\\]\\)?\\s-+" nil t)
+ (let (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)
+ (verilog-set-define (match-string-no-properties 1)
+ (match-string-no-properties 2) origbuf enumname)
(goto-char (match-end 0))
(forward-comment 999)))))))
((or (string-match "^\\+incdir\\+\\(.*\\)" arg) ;; +incdir+dir
(string-match "^-I\\(.*\\)" arg)) ;; -Idir
(verilog-add-list-unique `verilog-library-directories
- (match-string 1 arg)))
+ (match-string 1 (substitute-in-file-name arg))))
;; Ignore
((equal "+librescan" arg))
((string-match "^-U\\(.*\\)" arg)) ;; -Udefine
;; Second parameters
((equal next-param "-f")
(setq next-param nil)
- (verilog-getopt-file arg))
+ (verilog-getopt-file (substitute-in-file-name arg)))
((equal next-param "-v")
(setq next-param nil)
- (verilog-add-list-unique `verilog-library-files arg))
+ (verilog-add-list-unique `verilog-library-files
+ (substitute-in-file-name arg)))
((equal next-param "-y")
(setq next-param nil)
- (verilog-add-list-unique `verilog-library-directories arg))
+ (verilog-add-list-unique `verilog-library-directories
+ (substitute-in-file-name arg)))
;; Filename
((string-match "^[^-+]" arg)
- (verilog-add-list-unique `verilog-library-files arg))
+ (verilog-add-list-unique `verilog-library-files
+ (substitute-in-file-name arg)))
;; Default - ignore; no warning
))))
;;(verilog-getopt (list "+libext+.a+.b" "+incdir+foodir" "+define+a+aval" "-f" "otherf" "-v" "library" "-y" "dir"))
": 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))))
+ (setq line (buffer-substring (point) (point-at-eol)))
(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.
+ (with-current-buffer orig-buffer ; Variables are buffer-local, so need right context.
(verilog-getopt line))))))
(defun verilog-getopt-flags ()
varref)
;;(progn (setq l '()) (verilog-add-list-unique `l "a") (verilog-add-list-unique `l "a") l)
+(defun verilog-current-flags ()
+ "Convert `verilog-library-flags' and similar variables to command line.
+Used for __FLAGS__ in `verilog-expand-command'."
+ (let ((cmd (mapconcat `concat verilog-library-flags " ")))
+ (when (equal cmd "")
+ (setq cmd (concat
+ "+libext+" (mapconcat `concat verilog-library-extensions "+")
+ (mapconcat (lambda (i) (concat " -y " i " +incdir+" i))
+ verilog-library-directories "")
+ (mapconcat (lambda (i) (concat " -v " i))
+ verilog-library-files ""))))
+ cmd))
+;;(verilog-current-flags)
+
\f
;;
;; Cached directory support
"Execute the BODY forms, allowing directory cache preservation within BODY.
This means that changes inside BODY made to the file system will not be
seen by the `verilog-dir-files' and related functions."
- `(let ((verilog-dir-cache-preserving t)
+ `(let ((verilog-dir-cache-preserving (current-buffer))
verilog-dir-cache-list
verilog-dir-cache-lib-filenames)
(progn ,@body)))
;;
(defun verilog-module-inside-filename-p (module filename)
- "Return point if MODULE is specified inside FILENAME, else nil.
+ "Return modi 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 (fboundp 'vc-backend)
(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))))
+ (let (modi type)
+ (with-current-buffer (find-file-noselect filename)
+ (save-excursion
+ (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\\|interface\\)\\>" nil t)
+ (setq type (match-string-no-properties 0))
+ (verilog-re-search-forward-quick "[(;]" nil t))
+ (if (equal module (verilog-read-module-name))
+ (setq modi (verilog-modi-new module filename (point) type))))
+ modi)))))
(defun verilog-is-number (symbol)
"Return true if SYMBOL is number-like."
(let ((ok t) symbol val)
(while (and ok (string-match "`\\([a-zA-Z0-9_]+\\)" text))
(setq symbol (match-string 1 text))
- (message symbol)
+ ;;(message symbol)
(cond ((and
(boundp (intern (concat "vh-" symbol)))
;; Emacs has a bug where boundp on a buffer-local
dirlist))
;;(verilog-expand-dirnames (list "." ".." "nonexist" "../*" "/home/wsnyder/*/v"))
-(defun verilog-library-filenames (filename current &optional check-ext)
+(defun verilog-library-filenames (filename &optional current check-ext)
"Return a search path to find the given FILENAME or module 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'."
+Uses the optional CURRENT filename or buffer-file-name, plus
+`verilog-library-directories' and `verilog-library-extensions'
+variables to build the path. With optional CHECK-EXT also check
+`verilog-library-extensions'."
+ (unless current (setq current (buffer-file-name)))
(unless verilog-dir-cache-preserving
(setq verilog-dir-cache-lib-filenames nil))
(let* ((cache-key (list filename current check-ext))
"Cache of ((Module Function) Buf-Tick Buf-Modtime Func-Returns)...
For speeding up verilog-modi-get-* commands.
Buffer-local.")
-
(make-variable-buffer-local 'verilog-modi-cache-list)
(defvar verilog-modi-cache-preserve-tick nil
(defvar verilog-modi-cache-preserve-buffer nil
"Modification tick after which the cache is still considered valid.
Use `verilog-preserve-modi-cache' to set it.")
+(defvar verilog-modi-cache-current-enable nil
+ "If true, allow caching `verilog-modi-current', set by let().")
+(defvar verilog-modi-cache-current nil
+ "Currently active `verilog-modi-current', if any, set by let().")
+(defvar verilog-modi-cache-current-max nil
+ "Current endmodule point for `verilog-modi-cache-current', if any.")
(defun verilog-modi-current ()
+ "Return the modi structure for the module currently at point, possibly cached."
+ (cond ((and verilog-modi-cache-current
+ (>= (point) (verilog-modi-get-point verilog-modi-cache-current))
+ (<= (point) verilog-modi-cache-current-max))
+ ;; Slow assertion, for debugging the cache:
+ ;;(or (equal verilog-modi-cache-current (verilog-modi-current-get)) (debug))
+ verilog-modi-cache-current)
+ (verilog-modi-cache-current-enable
+ (setq verilog-modi-cache-current (verilog-modi-current-get)
+ verilog-modi-cache-current-max
+ ;; The cache expires when we pass "endmodule" as then the
+ ;; current modi may change to the next module
+ ;; This relies on the AUTOs generally inserting, not deleting text
+ (save-excursion
+ (verilog-re-search-forward-quick verilog-end-defun-re nil nil)))
+ verilog-modi-cache-current)
+ (t
+ (verilog-modi-current-get))))
+
+(defun verilog-modi-current-get ()
"Return the modi structure for the module currently at point."
- (let* (name pt)
+ (let* (name type pt)
;; read current module's name
(save-excursion
(verilog-re-search-backward-quick verilog-defun-re nil nil)
+ (setq type (match-string-no-properties 0))
(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)))
+ ;; return modi - note this vector built two places
+ (verilog-modi-new name (or (buffer-file-name) (current-buffer)) pt type)))
-(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.")
+(defvar verilog-modi-lookup-cache nil "Hash of (modulename modi).")
+(make-variable-buffer-local 'verilog-modi-lookup-cache)
+(defvar verilog-modi-lookup-last-current nil "Cache of `current-buffer' at last lookup.")
+(defvar verilog-modi-lookup-last-tick nil "Cache of `buffer-chars-modified-tick' at last lookup.")
(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
+ (let* ((current (or (buffer-file-name) (current-buffer)))
+ modi)
+ ;; Check cache
+ ;;(message "verilog-modi-lookup: %s" module)
+ (cond ((and verilog-modi-lookup-cache
verilog-cache-enabled
allow-cache
- (equal verilog-modi-lookup-last-mod module)
+ (setq modi (gethash module verilog-modi-lookup-cache))
(equal verilog-modi-lookup-last-current current)
- (equal verilog-modi-lookup-last-tick (buffer-modified-tick)))
- ;; ok as is
- )
+ ;; Iff hit is in current buffer, then tick must match
+ (or (equal verilog-modi-lookup-last-tick (buffer-chars-modified-tick))
+ (not (equal current (verilog-modi-file-or-buffer modi)))))
+ ;;(message "verilog-modi-lookup: HIT %S" modi)
+ modi)
+ ;; Miss
(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))))
+ mif)
+ (while (and filenames (not mif))
+ (if (not (setq mif (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)
+ ;; mif has correct form to become later elements of modi
+ (cond (mif (setq modi mif))
+ (t (setq modi nil)
(or ignore-error
(error (concat (verilog-point-text)
": Can't locate " module " module definition"
"\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))
+ (when (eval-when-compile (fboundp 'make-hash-table))
+ (unless verilog-modi-lookup-cache
+ (setq verilog-modi-lookup-cache
+ (make-hash-table :test 'equal :rehash-size 4.0)))
+ (puthash module modi verilog-modi-lookup-cache))
+ (setq verilog-modi-lookup-last-current current
+ verilog-modi-lookup-last-tick (buffer-chars-modified-tick)))))
+ modi))
(defun verilog-modi-filename (modi)
"Filename of MODI, or name of buffer if it's never been saved."
(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)))
+ (goto-char (verilog-modi-get-point modi)))
(defun verilog-goto-defun-file (module)
"Move point to the file at which a given MODULE is defined."
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))
+ (or (equal (buffer-chars-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))))
(nth 3 fass))
(t
;; Read from file
- ;; Clear then restore any hilighting to make emacs19 happy
+ ;; Clear then restore any highlighting to make emacs19 happy
(let ((fontlocked (when (and (boundp 'font-lock-mode)
font-lock-mode)
(font-lock-mode 0)
;; Cache for next time
(setq verilog-modi-cache-list
(cons (list (list modi function)
- (buffer-modified-tick)
+ (buffer-chars-modified-tick)
(visited-file-modtime)
func-returns)
verilog-modi-cache-list))
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))
+ `(let ((verilog-modi-cache-preserve-tick (buffer-chars-modified-tick))
(verilog-modi-cache-preserve-buffer (current-buffer)))
(progn ,@body)))
(defun verilog-signals-matching-regexp (in-list regexp)
"Return all signals in IN-LIST matching the given REGEXP, if non-nil."
- (if (not regexp)
+ (if (or (not regexp) (equal regexp ""))
in-list
(let (out-list)
(while in-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)
+ (if (or (not regexp) (equal regexp ""))
in-list
(let (out-list)
(while in-list
(setq in-list (cdr in-list)))
(nreverse out-list))))
+(defun verilog-signals-matching-dir-re (in-list decl-type regexp)
+ "Return all signals in IN-LIST matching the given DECL-TYPE and REGEXP,
+if non-nil."
+ (if (or (not regexp) (equal regexp ""))
+ in-list
+ (let (out-list to-match)
+ (while in-list
+ ;; Note verilog-insert-one-definition matches on this order
+ (setq to-match (concat
+ decl-type
+ " " (verilog-sig-signed (car in-list))
+ " " (verilog-sig-multidim (car in-list))
+ (verilog-sig-bits (car in-list))))
+ (if (string-match regexp to-match)
+ (setq out-list (cons (car in-list) out-list)))
+ (setq in-list (cdr in-list)))
+ (nreverse out-list))))
+
;; Combined
(defun verilog-decls-get-signals (decls)
(append
"Print out a definition for SIG of the given TYPE,
with appropriate INDENT-PT indentation."
(indent-to indent-pt)
+ ;; Note verilog-signals-matching-dir-re matches on this order
(insert type)
+ (when (verilog-sig-modport sig)
+ (insert "." (verilog-sig-modport sig)))
(when (verilog-sig-signed sig)
(insert " " (verilog-sig-signed sig)))
(when (verilog-sig-multidim 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)))
+ (insert (verilog-sig-name sig))
+ (when (verilog-sig-memory sig)
+ (insert " " (verilog-sig-memory 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,
;; Want "type x" or "output type x", not "wire type x"
(cond ((verilog-sig-type sig)
(concat
- (if (not (equal direction "wire"))
+ (if (not (member direction '("wire" "interface")))
(concat direction " "))
(verilog-sig-type sig)))
(t direction))
(equal "" (verilog-sig-comment sig)))
(insert "\n")
(indent-to (max 48 (+ indent-pt 40)))
- (insert (concat "// " (verilog-sig-comment sig) "\n")))
+ (verilog-insert "// " (verilog-sig-comment sig) "\n"))
(setq sigs (cdr sigs)))))
(eval-when-compile
(while stuff
(if need-indent (indent-to indent-pt))
(setq need-indent nil)
- (insert (car stuff))
+ (verilog-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."
+ "Insert comma if previous argument is other than a open parenthesis or endif."
+ ;; We can't just search backward for ) as it might be inside another expression.
+ ;; Also want "`ifdef X input foo `endif" to just leave things to the human to deal with
(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 ","))))
+ (when (and (not (save-excursion ;; Not beginning (, or existing ,
+ (backward-char 1)
+ (looking-at "[(,]")))
+ (not (save-excursion ;; Not `endif, or user define
+ (backward-char 1)
+ (skip-chars-backward "[a-zA-Z0-9_`]")
+ (looking-at "`"))))
+ (insert ","))))
(defun verilog-repair-close-comma ()
"If point is at a comma followed by a close parenthesis, fix it.
(setq range-exp (match-string 1 range-exp)))
(cond ((not range-exp)
"1")
+ ;; [#:#] We can compute a numeric result
((string-match "^\\s *\\([0-9]+\\)\\s *:\\s *\\([0-9]+\\)\\s *$"
range-exp)
(int-to-string
(1+ (abs (- (string-to-number (match-string 1 range-exp))
(string-to-number (match-string 2 range-exp)))))))
+ ;; [PARAM-1:0] can just return PARAM
+ ((string-match "^\\s *\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s *-\\s *1\\s *:\\s *0\\s *$" range-exp)
+ (match-string 1 range-exp))
+ ;; [arbitrary] need math
((string-match "^\\(.*\\)\\s *:\\s *\\(.*\\)\\s *$" range-exp)
(concat "(1+(" (match-string 1 range-exp) ")"
(if (equal "0" (match-string 2 range-exp))
(while (string-match "(\\<\\([0-9A-Z-az_]+\\)\\>)" out)
(setq out (replace-match "\\1" nil nil out)))
(while (string-match "\\<\\([0-9]+\\)\\>\\s *\\+\\s *\\<\\([0-9]+\\)\\>" out)
- (setq out (replace-match
+ (setq out (replace-match
(int-to-string (+ (string-to-number (match-string 1 out))
(string-to-number (match-string 2 out))))
nil nil out)))
(while (string-match "\\<\\([0-9]+\\)\\>\\s *\\-\\s *\\<\\([0-9]+\\)\\>" out)
- (setq out (replace-match
+ (setq out (replace-match
(int-to-string (- (string-to-number (match-string 1 out))
(string-to-number (match-string 2 out))))
nil nil out))))
(delete-region pt (point))
(forward-line 1))))
+(defun verilog-delete-empty-auto-pair ()
+ "Delete begin/end auto pair at point, if empty."
+ (forward-line 0)
+ (when (looking-at (concat "\\s-*// Beginning of automatic.*\n"
+ "\\s-*// End of automatics\n"))
+ (delete-region (point) (save-excursion (forward-line 2) (point)))))
+
(defun verilog-forward-close-paren ()
"Find the close parenthesis that match the current point.
Ignore other close parenthesis with matching open parens."
"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\\)\\)")))
+ (looking-at "[ \t\n\f,]*\\([)]\\|// \\(Outputs\\|Inouts\\|Inputs\\|Interfaces\\)\\)")))
(defun verilog-delete-auto-star-all ()
"Delete a .* AUTOINST, if it is safe."
(save-excursion
(while (progn
(forward-line -1)
- (looking-at "\\s *//\\s *\\(Outputs\\|Inouts\\|Inputs\\)\n"))
+ (looking-at "\\s *//\\s *\\(Outputs\\|Inouts\\|Inputs\\|Interfaces\\)\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
(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, possibly with parameters
- (verilog-auto-re-search-do
- (concat "/\\*"
- (eval-when-compile
- (verilog-regexp-words
- `("AUTOASCIIENUM" "AUTOCONCATCOMMENT" "AUTODEFINEVALUE"
- "AUTOINOUT" "AUTOINOUTCOMP" "AUTOINOUTMODULE"
- "AUTOINPUT" "AUTOOUTPUT" "AUTOOUTPUTEVERY"
- "AUTOREG" "AUTOREGINPUT" "AUTORESET" "AUTOTIEOFF"
- "AUTOUNUSED" "AUTOWIRE")))
- "\\(\\|([^)]*)\\|(\"[^\"]*\")\\)" ; Optional parens or quoted parameter
- "\\*/")
- 'verilog-delete-autos-lined)
- ;; Remove those that are in parenthesis
- (verilog-auto-re-search-do
- (concat "/\\*"
- (eval-when-compile
- (verilog-regexp-words
- `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
- "AUTOSENSE")))
- "\\*/")
- '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 ""))
+ (verilog-save-no-change-functions
+ (verilog-save-scan-cache
+ ;; Allow user to customize
+ (run-hooks 'verilog-before-delete-auto-hook)
+
+ ;; Remove those that have multi-line insertions, possibly with parameters
+ (verilog-auto-re-search-do
+ (concat "/\\*"
+ (eval-when-compile
+ (verilog-regexp-words
+ `("AUTOASCIIENUM" "AUTOCONCATCOMMENT" "AUTODEFINEVALUE"
+ "AUTOINOUT" "AUTOINOUTCOMP" "AUTOINOUTMODULE"
+ "AUTOINPUT" "AUTOINSERTLISP" "AUTOOUTPUT" "AUTOOUTPUTEVERY"
+ "AUTOREG" "AUTOREGINPUT" "AUTORESET" "AUTOTIEOFF"
+ "AUTOUNUSED" "AUTOWIRE")))
+ ;; Optional parens or quoted parameter or .* for (((...)))
+ "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
+ "\\*/")
+ 'verilog-delete-autos-lined)
+ ;; Remove those that are in parenthesis
+ (verilog-auto-re-search-do
+ (concat "/\\*"
+ (eval-when-compile
+ (verilog-regexp-words
+ `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
+ "AUTOSENSE")))
+ "\\*/")
+ '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)))
+ ;; Final customize
+ (run-hooks 'verilog-delete-auto-hook)))))
\f
;;
;; Auto inject
(verilog-backward-syntactic-ws)
(backward-char 1) ; Moves to paren that closes argdecl's
(when (looking-at ")")
- (insert "/*AUTOARG*/")))))))
+ (verilog-insert "/*AUTOARG*/")))))))
(defun verilog-inject-sense ()
"Inject AUTOSENSE into new code. See `verilog-inject-auto'."
(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*/")))))))
+ (verilog-insert "/*AS*/")))))))
(defun verilog-inject-inst ()
"Inject AUTOINST into new code. See `verilog-inject-auto'."
;; 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*/")))))))))
+ (verilog-insert "\n")
+ (verilog-insert-indent "/*AUTOINST*/")))))))))
\f
;;
;; Auto save
((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-update-tick (buffer-chars-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))))
+ (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-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-reeval-locals (&optional force)
"Read file local variable segment at bottom of file if it has changed.
If FORCE, always reread it."
- (make-local-variable '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.
+ (set (make-local-variable 'verilog-auto-last-file-locals) curlocal)
+ ;; Note this may cause this function to be recursively invoked,
+ ;; because hack-local-variables may call (verilog-mode)
;; The above when statement will prevent it from recursing forever.
(hack-local-variables)
t)))
"Print a list of ports for a AUTOINST.
Takes SIGS list, adds MESSAGE to front and inserts each at INDENT-PT."
(when sigs
+ (when verilog-auto-arg-sort
+ (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
(insert "\n")
(indent-to indent-pt)
(insert message)
output o;
endmodule
+The argument declarations may be printed in declaration order to best suit
+order based instantiations, or alphabetically, based on the
+`verilog-auto-arg-sort' variable.
+
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
(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-modport 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
+(defvar vl-bits nil "See `verilog-auto-inst'.") ; Prevent compile warning
+(defvar vl-mbits nil "See `verilog-auto-inst'.") ; Prevent compile warning
(defun verilog-auto-inst-port (port-st indent-pt tpl-list tpl-num for-star par-values)
"Print out a instantiation connection for this PORT-ST.
;; vl-* are documented for user use
(vl-name (verilog-sig-name port-st))
(vl-width (verilog-sig-width port-st))
+ (vl-modport (verilog-sig-modport port-st))
+ (vl-mbits (if (verilog-sig-multidim port-st)
+ (verilog-sig-multidim-string port-st) ""))
(vl-bits (if (or verilog-auto-inst-vector
(not (assoc port vector-skip-list))
(not (equal (verilog-sig-bits port-st)
check-values (cdr check-values)))
(setq vl-bits (verilog-simplify-range-expression vl-bits))) ; Not in the loop for speed
;; Default net value if not found
- (setq tpl-net (if (verilog-sig-multidim port-st)
- (concat port "/*" (verilog-sig-multidim-string port-st)
- vl-bits "*/")
- (concat port vl-bits)))
+ (setq tpl-net (concat port
+ (if vl-modport (concat "." vl-modport) "")
+ (if (verilog-sig-multidim port-st)
+ (concat "/*" (verilog-sig-multidim-string port-st)
+ vl-bits "*/")
+ (concat vl-bits))))
;; Find template
(cond (tpl-ass ; Template of exact port name
(setq tpl-net (nth 1 tpl-ass)))
;; Insert it
(indent-to indent-pt)
(insert "." port)
- (indent-to verilog-auto-inst-column)
- (insert "(" tpl-net "),")
+ (unless (and verilog-auto-inst-dot-name
+ (equal port tpl-net))
+ (indent-to verilog-auto-inst-column)
+ (insert "(" tpl-net ")"))
+ (insert ",")
(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)))))
+ (if verilog-auto-inst-template-numbers
+ (verilog-insert " // Templated"
+ " T" (int-to-string (nth 2 tpl-ass))
+ " L" (int-to-string (nth 3 tpl-ass)))
+ (verilog-insert " // Templated")))
(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...
+ (verilog-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 @)\"]")
"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 *.
+ ;; to avoid trouble we only insert on preceding ) or *.
;; Insert first port on new line
(insert "\n") ;; Must insert before search, so point will move forward if insert comma
(save-excursion
(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.
+Replace the pin connections to an instantiation or interface
+declaration with ones automatically derived from the module or
+interface header of the instantiated item.
If `verilog-auto-star-expand' is set, also expand SystemVerilog .* ports,
and delete them before saving unless `verilog-auto-star-save' is set.
SystemVerilog multidimensional input/output has only experimental support.
+ SystemVerilog .name syntax is used if `verilog-auto-inst-dot-name' is set.
+
Parameters referenced by the instantiation will remain symbolic, unless
`verilog-auto-inst-param-value' is set.
+ Gate primitives (and/or) may have AUTOINST for the purpose of
+ AUTOWIRE declarations, etc. Gates are the only case when
+ position based connections are passed.
+
For example, first take the submodule InstModule.v:
- module InstModule (o,i)
+ module InstModule (o,i);
output [31:0] o;
input i;
wire [31:0] o = {32{i}};
This is then used in a upper level module:
- module ExampInst (o,i)
+ module ExampInst (o,i);
output o;
input i;
InstModule instName
Typing \\[verilog-auto] will make this into:
- module ExampInst (o,i)
+ module ExampInst (o,i);
output o;
input i;
InstModule instName
Unless you are instantiating a module multiple times, or the module is
something trivial like an adder, DO NOT CHANGE SIGNAL NAMES ACROSS HIERARCHY.
It just makes for unmaintainable code. To sanitize signal names, try
- vrename from http://www.veripool.org.
+ vrename from URL `http://www.veripool.org'.
When you need to violate this suggestion there are two ways to list
exceptions, placing them before the AUTOINST, or using templates.
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
+ 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:
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:
+ a leading backslash (\\\"...\\\"); or if the Lisp template is also a
+ regexp template backslash the backslash quote (\\\\\"...\\\\\").
+
+ 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-mbits Multidimensional array bits for port ('[2:0][3: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-dir Direction of the pin input/output/inout/interface.
+ vl-modport The modport, if an interface with a modport.
vl-cell-type Module name/type of the cell ('InstModule').
vl-cell-name Instance name of the cell ('instName').
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.
+ (See also `verilog-auto-insert-lisp' if you want the output from your
+ lisp function to be inserted.)
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."
+ occur.
+
+For more information see the \\[verilog-faq] and forums at URL
+`http://www.veripool.org'."
(save-excursion
;; Find beginning
(let* ((pt (point))
;; Lookup position, etc of submodule
;; Note this may raise an error
- (when (setq submodi (verilog-modi-lookup submod t))
+ (when (and (not (member submod verilog-gate-keywords))
+ (setq submodi (verilog-modi-lookup submod t)))
(setq submoddecls (verilog-modi-get-decls submodi))
;; If there's a number in the instantiation, it may be a argument to the
;; automatic variable instantiation program.
"")
tpl-list (aref tpl-info 1)))
;; Find submodule's signals and dump
+ (let ((sig-list (and (equal (verilog-modi-get-type submodi) "interface")
+ (verilog-signals-not-in
+ (append (verilog-decls-get-wires submoddecls)
+ (verilog-decls-get-regs submoddecls))
+ skip-pins)))
+ (vl-dir "interfaced"))
+ (when sig-list
+ (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
+ ;; Note these are searched for in verilog-read-sub-decls.
+ (verilog-insert-indent "// Interfaced\n")
+ (mapc (lambda (port)
+ (verilog-auto-inst-port port indent-pt
+ tpl-list tpl-num for-star par-values))
+ sig-list)))
+ (let ((sig-list (verilog-signals-not-in
+ (verilog-decls-get-interfaces submoddecls)
+ skip-pins))
+ (vl-dir "interface"))
+ (when sig-list
+ (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
+ ;; Note these are searched for in verilog-read-sub-decls.
+ (verilog-insert-indent "// Interfaces\n")
+ (mapc (lambda (port)
+ (verilog-auto-inst-port port indent-pt
+ tpl-list tpl-num for-star par-values))
+ sig-list)))
(let ((sig-list (verilog-signals-not-in
(verilog-decls-get-outputs submoddecls)
skip-pins))
(vl-dir "output"))
(when sig-list
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
- (indent-to indent-pt)
- ;; Note these are searched for in verilog-read-sub-decls.
- (insert "// Outputs\n")
+ (verilog-insert-indent "// Outputs\n")
(mapc (lambda (port)
(verilog-auto-inst-port port indent-pt
tpl-list tpl-num for-star par-values))
(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")
+ (verilog-insert-indent "// Inouts\n")
(mapc (lambda (port)
(verilog-auto-inst-port port indent-pt
tpl-list tpl-num for-star par-values))
(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")
+ (verilog-insert-indent "// Inputs\n")
(mapc (lambda (port)
(verilog-auto-inst-port port indent-pt
tpl-list tpl-num for-star par-values))
(delete-char 1)
(insert ");")
(search-forward "\n") ;; Added by inst-port
- (delete-backward-char 1)
+ (delete-char -1)
(if (search-forward ")" nil t) ;; From user, moved up a line
- (delete-backward-char 1))
+ (delete-char -1))
(if (search-forward ";" nil t) ;; Don't error if user had syntax error and forgot it
- (delete-backward-char 1)))))))))
+ (delete-char -1)))))))))
(defun verilog-auto-inst-param ()
"Expand AUTOINSTPARAM statements, as part of \\[verilog-auto].
For example, first take the submodule InstModule.v:
- module InstModule (o,i)
+ module InstModule (o,i);
parameter PAR;
endmodule
This is then used in a upper level module:
- module ExampInst (o,i)
+ module ExampInst (o,i);
parameter PAR;
InstModule #(/*AUTOINSTPARAM*/)
instName (/*AUTOINST*/);
Typing \\[verilog-auto] will make this into:
- module ExampInst (o,i)
+ module ExampInst (o,i);
output o;
input i;
InstModule #(/*AUTOINSTPARAM*/
(vl-dir "parameter"))
(when sig-list
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
- (indent-to indent-pt)
;; Note these are searched for in verilog-read-sub-decls.
- (insert "// Parameters\n")
+ (verilog-insert-indent "// Parameters\n")
(mapc (lambda (port)
(verilog-auto-inst-port port indent-pt
tpl-list tpl-num nil nil))
(delete-char 1)
(insert ")")
(search-forward "\n") ;; Added by inst-port
- (delete-backward-char 1)
+ (delete-char -1)
(if (search-forward ")" nil t) ;; From user, moved up a line
- (delete-backward-char 1)))))))))
+ (delete-char -1)))))))))
(defun verilog-auto-reg ()
"Expand AUTOREG statements, as part of \\[verilog-auto].
An example:
- module ExampReg (o,i)
+ module ExampReg (o,i);
output o;
input i;
/*AUTOREG*/
Typing \\[verilog-auto] will make this into:
- module ExampReg (o,i)
+ module ExampReg (o,i);
output o;
input i;
/*AUTOREG*/
(verilog-decls-get-assigns moddecls)
(verilog-decls-get-consts moddecls)
(verilog-decls-get-gparams moddecls)
+ (verilog-subdecls-get-interfaced modsubdecls)
(verilog-subdecls-get-outputs modsubdecls)
(verilog-subdecls-get-inouts modsubdecls)))))
(forward-line 1)
An example (see `verilog-auto-inst' for what else is going on here):
- module ExampRegInput (o,i)
+ module ExampRegInput (o,i);
output o;
input i;
/*AUTOREGINPUT*/
Typing \\[verilog-auto] will make this into:
- module ExampRegInput (o,i)
+ module ExampRegInput (o,i);
output o;
input i;
/*AUTOREGINPUT*/
An example (see `verilog-auto-inst' for what else is going on here):
- module ExampWire (o,i)
+ module ExampWire (o,i);
output o;
input i;
/*AUTOWIRE*/
Typing \\[verilog-auto] will make this into:
- module ExampWire (o,i)
+ module ExampWire (o,i);
output o;
input i;
/*AUTOWIRE*/
(setq pnt (point))
(verilog-pretty-declarations quiet)
(goto-char pnt)
- (verilog-pretty-expr "//"))))))
+ (verilog-pretty-expr t "//"))))))
(defun verilog-auto-output (&optional with-params)
"Expand AUTOOUTPUT statements, as part of \\[verilog-auto].
An example (see `verilog-auto-inst' for what else is going on here):
- module ExampOutput (ov,i)
+ module ExampOutput (ov,i);
input i;
/*AUTOOUTPUT*/
InstModule instName
Typing \\[verilog-auto] will make this into:
- module ExampOutput (ov,i)
+ module ExampOutput (ov,i);
input i;
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
An example:
- module ExampOutputEvery (o,i,tempa,tempb)
+ module ExampOutputEvery (o,i,tempa,tempb);
output o;
input i;
/*AUTOOUTPUTEVERY*/
Typing \\[verilog-auto] will make this into:
- module ExampOutputEvery (o,i,tempa,tempb)
+ module ExampOutputEvery (o,i,tempa,tempb);
output o;
input i;
/*AUTOOUTPUTEVERY*/
An example (see `verilog-auto-inst' for what else is going on here):
- module ExampInput (ov,i)
+ module ExampInput (ov,i);
output [31:0] ov;
/*AUTOINPUT*/
InstModule instName
Typing \\[verilog-auto] will make this into:
- module ExampInput (ov,i)
+ module ExampInput (ov,i);
output [31:0] ov;
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
(verilog-decls-get-regs moddecls)
(verilog-decls-get-consts moddecls)
(verilog-decls-get-gparams moddecls)
+ (verilog-subdecls-get-interfaced modsubdecls)
(verilog-subdecls-get-outputs modsubdecls)
(verilog-subdecls-get-inouts modsubdecls)))))
(when regexp
An example (see `verilog-auto-inst' for what else is going on here):
- module ExampInout (ov,i)
+ module ExampInout (ov,i);
input i;
/*AUTOINOUT*/
InstModule instName
Typing \\[verilog-auto] will make this into:
- module ExampInout (ov,i)
+ module ExampInout (ov,i);
input i;
/*AUTOINOUT*/
// Beginning of automatic inouts (from unused autoinst inouts)
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.
+For the complement of this function, see `verilog-auto-inout-comp'.
Limitations:
If placed inside the parenthesis of a module declaration, it creates
An example:
- module ExampShell (/*AUTOARG*/)
+ module ExampShell (/*AUTOARG*/);
/*AUTOINOUTMODULE(\"ExampMain\")*/
endmodule
- module ExampMain (i,o,io)
+ module ExampMain (i,o,io);
input i;
output o;
inout io;
Typing \\[verilog-auto] will make this into:
- module ExampShell (/*AUTOARG*/i,o,io)
+ module ExampShell (/*AUTOARG*/i,o,io);
/*AUTOINOUTMODULE(\"ExampMain\")*/
// Beginning of automatic in/out/inouts (from specific module)
output o;
signals matching the regular expression will be included. For example the
same expansion will result from only extracting signals starting with i:
- /*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/"
+ /*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/
+
+You may also provide an optional second regular expression, in
+which case only signals which have that pin direction and data
+type will be included. This matches against everything before
+the signal name in the declaration, for example against
+\"input\" (single bit), \"output logic\" (direction and type) or
+\"output [1:0]\" (direction and implicit type). You also
+probably want to skip spaces in your regexp.
+
+For example, the below will result in matching the output \"o\"
+against the previous example's module:
+
+ /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/"
(save-excursion
- (let* ((params (verilog-read-auto-params 1 2))
+ (let* ((params (verilog-read-auto-params 1 3))
(submod (nth 0 params))
(regexp (nth 1 params))
+ (direction-re (nth 2 params))
submodi)
;; Lookup position, etc of co-module
;; Note this may raise an error
(append (verilog-decls-get-outputs moddecls))))
(sig-list-io (verilog-signals-not-in
(verilog-decls-get-inouts submoddecls)
- (append (verilog-decls-get-inouts moddecls)))))
+ (append (verilog-decls-get-inouts moddecls))))
+ (sig-list-if (verilog-signals-not-in
+ (verilog-decls-get-interfaces submoddecls)
+ (append (verilog-decls-get-interfaces moddecls)))))
(forward-line 1)
- (when regexp
- (setq sig-list-i (verilog-signals-matching-regexp
- sig-list-i regexp)
- sig-list-o (verilog-signals-matching-regexp
- sig-list-o regexp)
- sig-list-io (verilog-signals-matching-regexp
- sig-list-io regexp)))
+ (setq sig-list-i (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-i regexp)
+ "input" direction-re)
+ sig-list-o (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-o regexp)
+ "output" direction-re)
+ sig-list-io (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-io regexp)
+ "inout" direction-re)
+ sig-list-if (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-if regexp)
+ "interface" direction-re))
(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")
(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-insert-definition sig-list-if "interface" 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)
and vice-versa.) This is useful for making test and stimulus
modules which need to have complementing I/O with another module.
Any I/O which are already defined in this module will not be
-redefined.
+redefined. For the complement of this function, see
+`verilog-auto-inout-module'.
Limitations:
If placed inside the parenthesis of a module declaration, it creates
An example:
- module ExampShell (/*AUTOARG*/)
+ module ExampShell (/*AUTOARG*/);
/*AUTOINOUTCOMP(\"ExampMain\")*/
endmodule
- module ExampMain (i,o,io)
+ module ExampMain (i,o,io);
input i;
output o;
inout io;
Typing \\[verilog-auto] will make this into:
- module ExampShell (/*AUTOARG*/i,o,io)
+ module ExampShell (/*AUTOARG*/i,o,io);
/*AUTOINOUTCOMP(\"ExampMain\")*/
// Beginning of automatic in/out/inouts (from specific module)
output i;
/*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
(verilog-auto-inout-module t))
+(defun verilog-auto-insert-lisp ()
+ "Expand AUTOINSERTLISP statements, as part of \\[verilog-auto].
+The Lisp code provided is called, and the Lisp code calls
+`insert` to insert text into the current file beginning on the
+line after the AUTOINSERTLISP.
+
+See also AUTO_LISP, which takes a Lisp expression and evaluates
+it during `verilog-auto-inst' but does not insert any text.
+
+An example:
+
+ module ExampInsertLisp;
+ /*AUTOINSERTLISP(my-verilog-insert-hello \"world\")*/
+ endmodule
+
+ // For this example we declare the function in the
+ // module's file itself. Often you'd define it instead
+ // in a site-start.el or .emacs file.
+ /*
+ Local Variables:
+ eval:
+ (defun my-verilog-insert-hello (who)
+ (insert (concat \"initial $write(\\\"hello \" who \"\\\");\\n\")))
+ End:
+ */
+
+Typing \\[verilog-auto] will call my-verilog-insert-hello and
+expand the above into:
+
+ // Beginning of automatic insert lisp
+ initial $write(\"hello world\");
+ // End of automatics
+
+You can also call an external program and insert the returned
+text:
+
+ /*AUTOINSERTLISP(insert (shell-command-to-string \"echo //hello\"))*/
+ // Beginning of automatic insert lisp
+ //hello
+ // End of automatics"
+ (save-excursion
+ ;; Point is at end of /*AUTO...*/
+ (let* ((indent-pt (current-indentation))
+ (cmd-end-pt (save-excursion (search-backward ")")
+ (forward-char)
+ (point))) ;; Closing paren
+ (cmd-beg-pt (save-excursion (goto-char cmd-end-pt)
+ (backward-sexp 1)
+ (point))) ;; Beginning paren
+ (cmd (buffer-substring-no-properties cmd-beg-pt cmd-end-pt)))
+ (forward-line 1)
+ ;; Some commands don't move point (like insert-file) so we always
+ ;; add the begin/end comments, then delete it if not needed
+ (verilog-insert-indent "// Beginning of automatic insert lisp\n")
+ (verilog-insert-indent "// End of automatics\n")
+ (forward-line -1)
+ (eval (read cmd))
+ (forward-line -1)
+ (setq verilog-scan-cache-tick nil) ;; Clear cache; inserted unknown text
+ (verilog-delete-empty-auto-pair))))
+
(defun verilog-auto-sense-sigs (moddecls presense-sigs)
"Return list of signals for current AUTOSENSE block."
(let* ((sigss (verilog-read-always-signals))
(verilog-signals-not-in (verilog-alw-get-inputs sigss)
(append (and (not verilog-auto-sense-include-inputs)
(verilog-alw-get-outputs sigss))
+ (verilog-alw-get-temps sigss)
(verilog-decls-get-consts moddecls)
(verilog-decls-get-gparams moddecls)
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 (not (eq tlen (length sig-list))) (verilog-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)
Limitations:
AUTORESET will not clear memories.
- AUTORESET uses <= if there are any <= in the block, else it uses =.
+ AUTORESET uses <= if there are any <= assignments 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
(concat " <= " verilog-assignment-delay)
" = "))
(setq sig-list (verilog-signals-not-in (verilog-alw-get-outputs sigss)
- prereset-sigs))
+ (append
+ (verilog-alw-get-temps 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");
+ (verilog-insert-indent "// 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
";\n")
(indent-to indent-pt)
(setq sig-list (cdr sig-list))))
- (insert "// End of automatics")))))
+ (verilog-insert "// End of automatics")))))
(defun verilog-auto-tieoff ()
"Expand AUTOTIEOFF statements, as part of \\[verilog-auto].
Signals that match `verilog-active-low-regexp' will be deasserted by tieing
them to a one.
+You can add signals you do not want included in AUTOTIEOFF with
+`verilog-auto-tieoff-ignore-regexp'.
+
An example of making a stub for another module:
module ExampStub (/*AUTOINST*/);
(verilog-decls-get-assigns moddecls)
(verilog-decls-get-consts moddecls)
(verilog-decls-get-gparams moddecls)
+ (verilog-subdecls-get-interfaced modsubdecls)
(verilog-subdecls-get-outputs modsubdecls)
(verilog-subdecls-get-inouts modsubdecls)))))
+ (setq sig-list (verilog-signals-not-matching-regexp
+ sig-list verilog-auto-tieoff-ignore-regexp))
(when sig-list
(forward-line 1)
(verilog-insert-indent "// Beginning of automatic tieoffs (for this module's unterminated outputs)\n")
Finally, a AUTOASCIIENUM command is used.
The first parameter is the name of the signal to be decoded.
+ If and only if the first parameter width is 2^(number of states
+ in enum) and does NOT match the width of the enum, the signal
+ is assumed to be a one hot decode. Otherwise, it's a normal
+ encoded state vector.
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
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
+ reg [2:0] /* synopsys enum state_info */
+ state_r; /* synopsys state_vector state_r */
+ reg [2:0] /* synopsys enum state_info */
+ state_e1;
/*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
(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-sigs (verilog-signals-not-in
+ (or (verilog-signals-matching-enum sig-list-consts undecode-enum)
+ (error "%s: No state definitions for %s" (verilog-point-text) undecode-enum))
+ nil))
;;
- (enum-chars 0)
+ (one-hot (and ;; width(enum) != width(sig)
+ (or (not (verilog-sig-bits (car enum-sigs)))
+ (not (equal (verilog-sig-width (car enum-sigs))
+ (verilog-sig-width undecode-sig))))
+ ;; count(enums) == width(sig)
+ (equal (number-to-string (length enum-sigs))
+ (verilog-sig-width undecode-sig))))
+ (enum-chars 0)
(ascii-chars 0))
;;
;; Find number of ascii chars needed
(setq indent-pt (+ indent-pt verilog-case-indent))
;;
(let ((tmp-sigs enum-sigs)
- (chrfmt (format "%%-%ds %s = \"%%-%ds\";\n" (1+ (max 8 enum-chars))
+ (chrfmt (format "%%-%ds %s = \"%%-%ds\";\n"
+ (+ (if one-hot 9 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)))
+ (concat
+ (format chrfmt
+ (concat (if one-hot "(")
+ (if one-hot (verilog-sig-width undecode-sig))
+ ;; We use a shift instead of var[index]
+ ;; so that a non-one hot value will show as error.
+ (if one-hot "'b1<<")
+ (verilog-sig-name (car tmp-sigs))
+ (if one-hot ")") ":")
+ (verilog-enum-ascii (verilog-sig-name (car tmp-sigs))
+ elim-regexp))))
(setq tmp-sigs (cdr tmp-sigs)))
(verilog-insert-indent (format chrfmt "default:" errname)))
;;
"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)))
+ (let ((templateno 0) (template-line (list 0)) (buf-line 1))
;; Find line number each template is on
+ ;; Count lines as we go, as otherwise it's O(n^2) to use count-lines
(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)))
+ (while (not (eobp))
+ (when (looking-at ".*AUTO_TEMPLATE")
+ (setq templateno (1+ templateno))
+ (setq template-line (cons buf-line template-line)))
+ (setq buf-line (1+ buf-line))
+ (forward-line 1))
(setq template-line (nreverse template-line))
;; Replace T# L# with absolute line number
(goto-char (point-min))
called before and after this function, respectively.
For example:
- module ModuleName (/*AUTOARG*/)
+ module ModuleName (/*AUTOARG*/);
/*AUTOINPUT*/
/*AUTOOUTPUT*/
/*AUTOWIRE*/
`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-insert-lisp' for AUTOINSERTLISP insert code from lisp function
`verilog-auto-inst' for AUTOINST instantiation pins
`verilog-auto-star' for AUTOINST .* SystemVerilog pins
`verilog-auto-inst-param' for AUTOINSTPARAM instantiation params
`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.org."
+If you have bugs with these autos, please file an issue at
+URL `http://www.veripool.org/verilog-mode' or contact the AUTOAUTHOR
+Wilson Snyder (wsnyder@wsnyder.org)."
(interactive)
(unless noninteractive (message "Updating AUTOs..."))
(if (fboundp 'dinotrace-unannotate-all)
(font-lock-mode 0)
t))
;; Cache directories; we don't write new files, so can't change
- (verilog-dir-cache-preserving 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)
- ;; From here on out, we can cache anything we read from disk
- (verilog-preserve-dir-cache
- ;; 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-modi-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-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
- (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
- (verilog-auto-re-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)
- (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP([^)]*)\\*/" 'verilog-auto-inout-comp)
- ;; next in/outs which need previous sucked inputs first
- (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((\"[^\"]*\")\\)\\*/"
- '(lambda () (verilog-auto-output t)))
- (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\*/" 'verilog-auto-output)
- (verilog-auto-re-search-do "/\\*AUTOINPUT\\((\"[^\"]*\")\\)\\*/"
- '(lambda () (verilog-auto-input t)))
- (verilog-auto-re-search-do "/\\*AUTOINPUT\\*/" 'verilog-auto-input)
- (verilog-auto-re-search-do "/\\*AUTOINOUT\\((\"[^\"]*\")\\)\\*/"
- '(lambda () (verilog-auto-inout t)))
- (verilog-auto-re-search-do "/\\*AUTOINOUT\\*/" 'verilog-auto-inout)
- ;; Then tie off those in/outs
- (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
- ;; Wires/regs must be after inputs/outputs
- (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
- (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
- (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
- ;; outputevery needs AUTOOUTPUTs done first
- (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\*/" 'verilog-auto-output-every)
- ;; After we've created all new variables
- (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
- ;; Must be after all inputs outputs are generated
- (verilog-auto-re-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))))))
+ (verilog-dir-cache-preserving t)
+ ;; Cache current module
+ (verilog-modi-cache-current-enable t)
+ (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
+ verilog-modi-cache-current)
+ (unwind-protect
+ ;; Disable change hooks for speed
+ ;; This let can't be part of above let; must restore
+ ;; after-change-functions before font-lock resumes
+ (verilog-save-no-change-functions
+ (verilog-save-scan-cache
+ (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-present)
+ (verilog-read-auto-lisp (point-min) (point-max))
+ (verilog-getopt-flags)
+ ;; From here on out, we can cache anything we read from disk
+ (verilog-preserve-dir-cache
+ ;; 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-modi-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))
+ ;;
+ ;; Do user inserts first, so their code can insert AUTOs
+ ;; We may provide a AUTOINSERTLISPLAST if another cleanup pass is needed
+ (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
+ 'verilog-auto-insert-lisp)
+ ;; Expand instances before need the signals the instances input/output
+ (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
+ (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
+ (verilog-auto-re-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)
+ (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP([^)]*)\\*/" 'verilog-auto-inout-comp)
+ ;; next in/outs which need previous sucked inputs first
+ (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((\"[^\"]*\")\\)\\*/"
+ (lambda () (verilog-auto-output t)))
+ (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\*/" 'verilog-auto-output)
+ (verilog-auto-re-search-do "/\\*AUTOINPUT\\((\"[^\"]*\")\\)\\*/"
+ (lambda () (verilog-auto-input t)))
+ (verilog-auto-re-search-do "/\\*AUTOINPUT\\*/" 'verilog-auto-input)
+ (verilog-auto-re-search-do "/\\*AUTOINOUT\\((\"[^\"]*\")\\)\\*/"
+ (lambda () (verilog-auto-inout t)))
+ (verilog-auto-re-search-do "/\\*AUTOINOUT\\*/" 'verilog-auto-inout)
+ ;; Then tie off those in/outs
+ (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
+ ;; Wires/regs must be after inputs/outputs
+ (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
+ (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
+ (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
+ ;; outputevery needs AUTOOUTPUTs done first
+ (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\*/" 'verilog-auto-output-every)
+ ;; After we've created all new variables
+ (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
+ ;; Must be after all inputs outputs are generated
+ (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
+ ;; Fix line numbers (comments only)
+ (when verilog-auto-inst-template-numbers
+ (verilog-auto-templated-rel))))
+ ;;
+ (run-hooks 'verilog-auto-hook)
+ ;;
+ (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-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"))))
+ ;; End of after-change protection
+ )))
+ ;; Unwind forms
+ (progn
+ ;; Restore font-lock
+ (when fontlocked (font-lock-mode t))))))
\f
;;
(if (> (point) verilog-sk-p) "] " " ")))
(defun verilog-sk-header ()
- "Insert a descriptive header at the top of the file."
+ "Insert a descriptive header at the top of the file.
+See also `verilog-header' for an alternative format."
(interactive "*")
(save-excursion
(goto-char (point-min))
"\n// Description : " str
"\n// Author : " (user-full-name)
"\n// Created On : " (current-time-string)
- "\n// Last Modified By: ."
- "\n// Last Modified On: ."
+ "\n// Last Modified By: " (user-full-name)
+ "\n// Last Modified On: " (current-time-string)
"\n// Update Count : 0"
"\n// Status : Unknown, Use with caution!"
"\n")
and the case items."
"[selector expression]: "
> "case (" str ") " \n
- > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \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
and the case items."
"[selector expression]: "
> "casex (" str ") " \n
- > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \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
and the case items."
"[selector expression]: "
> "casez (" str ") " \n
- > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \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
;; second (emacs/xemacs) impl.: G. Van der Plas (spice-mode.el)
(if (featurep 'xemacs)
- (require 'overlay)
- (require 'lucid)) ;; what else can we do ??
+ (require 'overlay))
(defconst verilog-include-file-regexp
"^`include\\s-+\"\\([^\n\"]*\\)\""
"Map containing mouse bindings for `verilog-mode'.")
-(defun verilog-colorize-include-files (beg end old-len)
- "This function colorizes included files when the mouse passes over them.
+(defun verilog-highlight-region (beg end old-len)
+ "Colorize included files and modules in the (changed?) region.
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 (ov)
- (goto-char (match-beginning 1))
- (setq ov (make-overlay (match-beginning 1) (match-end 1)))
- (overlay-put ov 'start-closed 't)
- (overlay-put ov 'end-closed 't)
- (overlay-put ov 'evaporate 't)
- (overlay-put ov 'verilog-include-file 't)
- (overlay-put ov 'mouse-face 'highlight)
- (overlay-put ov 'local-map verilog-mode-mouse-map)))))))
-
-
-(defun verilog-colorize-include-files-buffer ()
- "Colorize an include file."
+ (when (or verilog-highlight-includes
+ verilog-highlight-modules)
+ (save-excursion
+ (save-match-data ;; A query-replace may call this function - do not disturb
+ (verilog-save-buffer-state
+ (verilog-save-scan-cache
+ (let (end-point)
+ (goto-char end)
+ (setq end-point (point-at-eol))
+ (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)
+ (or (overlay-get (car overlays) 'verilog-include-file)
+ (overlay-get (car overlays) 'verilog-inst-module)))
+ (delete-overlay (car overlays)))
+ (setq overlays (cdr overlays))))
+ ;;
+ ;; make new include overlays
+ (when verilog-highlight-includes
+ (while (search-forward-regexp verilog-include-file-regexp end-point t)
+ (goto-char (match-beginning 1))
+ (let ((ov (make-overlay (match-beginning 1) (match-end 1))))
+ (overlay-put ov 'start-closed 't)
+ (overlay-put ov 'end-closed 't)
+ (overlay-put ov 'evaporate 't)
+ (overlay-put ov 'verilog-include-file 't)
+ (overlay-put ov 'mouse-face 'highlight)
+ (overlay-put ov 'local-map verilog-mode-mouse-map))))
+ ;;
+ ;; make new module overlays
+ (goto-char beg)
+ ;; This scanner is syntax-fragile, so don't get bent
+ (when verilog-highlight-modules
+ (condition-case nil
+ (while (verilog-re-search-forward "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-point t)
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (unless (verilog-inside-comment-p)
+ (verilog-read-inst-module-matcher) ;; sets match 0
+ (let* ((ov (make-overlay (match-beginning 0) (match-end 0))))
+ (overlay-put ov 'start-closed 't)
+ (overlay-put ov 'end-closed 't)
+ (overlay-put ov 'evaporate 't)
+ (overlay-put ov 'verilog-inst-module 't)
+ (overlay-put ov 'mouse-face 'highlight)
+ (overlay-put ov 'local-map verilog-mode-mouse-map)))))
+ (error nil)))
+ ;;
+ ;; Future highlights:
+ ;; variables - make an Occur buffer of where referenced
+ ;; pins - make an Occur buffer of the sig in the declaration module
+ )))))))
+
+(defun verilog-highlight-buffer ()
+ "Colorize included files and modules across the whole buffer."
+ ;; Invoked via verilog-mode calling font-lock then `font-lock-mode-hook'
(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))
+ ;; delete and remake overlays
+ (verilog-highlight-region (point-min) (point-max) nil))
+
+;; Deprecated, but was interactive, so we'll keep it around
+(defalias 'verilog-colorize-include-files-buffer 'verilog-highlight-buffer)
;; 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'."
+Files are checked based on `verilog-library-flags'."
(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)))))))
+ (verilog-load-file-at-point t)))
;; 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 ()
+(defun verilog-load-file-at-point (&optional warn)
"Load file under point.
-Files are checked based on `verilog-library-directories'."
+If WARN, throw warning if not found.
+Files are checked based on `verilog-library-flags'."
(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)))))
+ (let ((overlays (overlays-in (point) (point)))
+ hit)
+ (while (and overlays (not hit))
+ (when (overlay-get (car overlays) 'verilog-inst-module)
+ (verilog-goto-defun-file (buffer-substring
+ (overlay-start (car overlays))
+ (overlay-end (car overlays))))
+ (setq hit t))
+ (setq overlays (cdr overlays)))
+ ;; Include?
+ (beginning-of-line)
+ (when (and (not hit)
+ (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))))))))
-
+ (match-string 1) (buffer-file-name))))
+ (when warn
+ (message
+ "File '%s' isn't readable, use shift-mouse2 to paste in this field"
+ (match-string 1))))))))
;;
;; Bug reporting
(interactive)
(let ((reporter-prompt-for-summary-p t))
(reporter-submit-bug-report
- "mac@verilog.com"
+ "mac@verilog.com, wsnyder@wsnyder.org"
(concat "verilog-mode v" verilog-mode-version)
'(
+ verilog-active-low-regexp
verilog-align-ifelse
+ verilog-assignment-delay
+ verilog-auto-arg-sort
verilog-auto-endcomments
verilog-auto-hook
+ verilog-auto-ignore-concat
verilog-auto-indent-on-newline
- verilog-auto-inst-vector
+ verilog-auto-inout-ignore-regexp
+ verilog-auto-input-ignore-regexp
+ verilog-auto-inst-column
+ verilog-auto-inst-dot-name
+ verilog-auto-inst-param-value
verilog-auto-inst-template-numbers
+ verilog-auto-inst-vector
verilog-auto-lineup
verilog-auto-newline
+ verilog-auto-output-ignore-regexp
+ verilog-auto-read-includes
+ verilog-auto-reset-widths
verilog-auto-save-policy
verilog-auto-sense-defines-constant
verilog-auto-sense-include-inputs
+ verilog-auto-star-expand
+ verilog-auto-star-save
+ verilog-auto-unused-ignore-regexp
verilog-before-auto-hook
+ verilog-before-delete-auto-hook
+ verilog-before-getopt-flags-hook
verilog-case-indent
verilog-cexp-indent
verilog-compiler
verilog-coverage
+ verilog-delete-auto-hook
+ verilog-getopt-flags-hook
+ verilog-highlight-grouping-keywords
+ verilog-highlight-p1800-keywords
verilog-highlight-translate-off
verilog-indent-begin-after-if
verilog-indent-declaration-macros
verilog-indent-level-directive
verilog-indent-level-module
verilog-indent-lists
- verilog-library-flags
verilog-library-directories
verilog-library-extensions
verilog-library-files
+ verilog-library-flags
verilog-linter
verilog-minimum-comment-distance
verilog-mode-hook
+ verilog-preprocessor
verilog-simulator
verilog-tab-always-indent
verilog-tab-to-comment
+ verilog-typedef-regexp
)
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
+I want to report a bug.
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.org.
-You may also want to look at the Verilog-Mode FAQ, see
+I've taken a look at the Verilog-Mode FAQ at
http://www.veripool.org/verilog-mode-faq.html.
-To reproduce the bug, start a fresh Emacs via " invocation-name "
+And, I've considered filing the bug on the issue tracker at
+http://www.veripool.org/verilog-mode-bugs
+since I realize that public bugs are easier for you to track,
+and for others to search, but would prefer to email.
+
+So, 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.
;; checkdoc-force-docstrings-flag:nil
;; End:
-;; arch-tag: 87923725-57b3-41b5-9494-be21118c6a6f
;;; verilog-mode.el ends here