1;; verilog-mode.el --- major mode for editing verilog source in Emacs
2
3;; Copyright (C) 1996-2012  Free Software Foundation, Inc.
4
5;; Author: Michael McNamara (mac@verilog.com),
6;;    Wilson Snyder (wsnyder@wsnyder.org)
7;; Please see our web sites:
8;;    http://www.verilog.com
9;;    http://www.veripool.org
10;;
11;; Keywords: languages
12
13;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this
14;; file on 19/3/2008, and the maintainer agreed that when a bug is
15;; filed in the Emacs bug reporting system against this file, a copy
16;; of the bug report be sent to the maintainer's email address.
17
18;;    This code supports Emacs 21.1 and later
19;;    And XEmacs 21.1 and later
20;;    Please do not make changes that break Emacs 21.  Thanks!
21;;
22;;
23
24;; This file is part of GNU Emacs.
25
26;; GNU Emacs is free software: you can redistribute it and/or modify
27;; it under the terms of the GNU General Public License as published by
28;; the Free Software Foundation, either version 3 of the License, or
29;; (at your option) any later version.
30
31;; GNU Emacs is distributed in the hope that it will be useful,
32;; but WITHOUT ANY WARRANTY; without even the implied warranty of
33;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34;; GNU General Public License for more details.
35
36;; You should have received a copy of the GNU General Public License
37;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
38
39;;; Commentary:
40
41;; This mode borrows heavily from the Pascal-mode and the cc-mode of Emacs
42
43;; USAGE
44;; =====
45
46;; A major mode for editing Verilog HDL source code.  When you have
47;; entered Verilog mode, you may get more info by pressing C-h m. You
48;; may also get online help describing various functions by: C-h f
49;; <Name of function you want described>
50
51;; KNOWN BUGS / BUG REPORTS
52;; =======================
53
54;; Verilog is a rapidly evolving language, and hence this mode is
55;; under continuous development.  Hence this is beta code, and likely
56;; has bugs.  Please report any issues to the issue tracker at
57;; http://www.veripool.org/verilog-mode
58;; Please use verilog-submit-bug-report to submit a report; type C-c
59;; C-b to invoke this and as a result I will have a much easier time
60;; of reproducing the bug you find, and hence fixing it.
61
62;; INSTALLING THE MODE
63;; ===================
64
65;; An older version of this mode may be already installed as a part of
66;; your environment, and one method of updating would be to update
67;; your Emacs environment.  Sometimes this is difficult for local
68;; political/control reasons, and hence you can always install a
69;; private copy (or even a shared copy) which overrides the system
70;; default.
71
72;; You can get step by step help in installing this file by going to
73;; <http://www.verilog.com/emacs_install.html>
74
75;; The short list of installation instructions are: To set up
76;; automatic Verilog mode, put this file in your load path, and put
77;; the following in code (please un comment it first!) in your
78;; .emacs, or in your site's site-load.el
79
80; (autoload 'verilog-mode "verilog-mode" "Verilog mode" t )
81; (add-to-list 'auto-mode-alist '("\\.[ds]?vh?\\'" . verilog-mode))
82
83;; Be sure to examine at the help for verilog-auto, and the other
84;; verilog-auto-* functions for some major coding time savers.
85;;
86;; If you want to customize Verilog mode to fit your needs better,
87;; you may add the below lines (the values of the variables presented
88;; here are the defaults). Note also that if you use an Emacs that
89;; supports custom, it's probably better to use the custom menu to
90;; edit these.  If working as a member of a large team these settings
91;; should be common across all users (in a site-start file), or set
92;; in Local Variables in every file.  Otherwise, different people's
93;; AUTO expansion may result different whitespace changes.
94;;
95; ;; Enable syntax highlighting of **all** languages
96; (global-font-lock-mode t)
97;
98; ;; User customization for Verilog mode
99; (setq verilog-indent-level             3
100;       verilog-indent-level-module      3
101;       verilog-indent-level-declaration 3
102;       verilog-indent-level-behavioral  3
103;       verilog-indent-level-directive   1
104;       verilog-case-indent              2
105;       verilog-auto-newline             t
106;       verilog-auto-indent-on-newline   t
107;       verilog-tab-always-indent        t
108;       verilog-auto-endcomments         t
109;       verilog-minimum-comment-distance 40
110;       verilog-indent-begin-after-if    t
111;       verilog-auto-lineup              'declarations
112;       verilog-highlight-p1800-keywords nil
113;	verilog-linter			 "my_lint_shell_command"
114;	)
115
116;;
117
118;;; History:
119;;
120;; See commit history at http://www.veripool.org/verilog-mode.html
121;; (This section is required to appease checkdoc.)
122
123;;; Code:
124
125;; This variable will always hold the version number of the mode
126(defconst verilog-mode-version (substring "$$Revision: 801 $$" 12 -3)
127  "Version of this Verilog mode.")
128(defconst verilog-mode-release-date (substring "$$Date: 2012-05-04 21:06:34 +0000 (Fri, 04 May 2012) $$" 8 -3)
129  "Release date of this Verilog mode.")
130(defconst verilog-mode-release-emacs nil
131  "If non-nil, this version of Verilog mode was released with Emacs itself.")
132
133(defun verilog-version ()
134  "Inform caller of the version of this file."
135  (interactive)
136  (message "Using verilog-mode version %s" verilog-mode-version))
137
138;; Insure we have certain packages, and deal with it if we don't
139;; Be sure to note which Emacs flavor and version added each feature.
140(eval-when-compile
141  ;; Provide stuff if we are XEmacs
142  (when (featurep 'xemacs)
143    (condition-case nil
144        (require 'easymenu)
145      (error nil))
146    (condition-case nil
147        (require 'regexp-opt)
148      (error nil))
149    ;; Bug in 19.28 through 19.30 skeleton.el, not provided.
150    (condition-case nil
151        (load "skeleton")
152      (error nil))
153    (condition-case nil
154        (if (fboundp 'when)
155            nil ;; fab
156          (defmacro when (cond &rest body)
157            (list 'if cond (cons 'progn body))))
158      (error nil))
159    (condition-case nil
160        (if (fboundp 'unless)
161            nil ;; fab
162          (defmacro unless (cond &rest body)
163            (cons 'if (cons cond (cons nil body)))))
164      (error nil))
165    (condition-case nil
166        (if (fboundp 'store-match-data)
167            nil ;; fab
168          (defmacro store-match-data (&rest args) nil))
169      (error nil))
170    (condition-case nil
171        (if (fboundp 'char-before)
172            nil ;; great
173          (defmacro char-before (&rest body)
174            (char-after (1- (point)))))
175      (error nil))
176    (condition-case nil
177        (if (fboundp 'when)
178            nil ;; fab
179          (defsubst point-at-bol (&optional N)
180            (save-excursion (beginning-of-line N) (point))))
181      (error nil))
182    (condition-case nil
183        (if (fboundp 'when)
184            nil ;; fab
185          (defsubst point-at-eol (&optional N)
186            (save-excursion (end-of-line N) (point))))
187      (error nil))
188    (condition-case nil
189        (require 'custom)
190      (error nil))
191    (condition-case nil
192        (if (fboundp 'match-string-no-properties)
193            nil ;; great
194          (defsubst match-string-no-properties (num &optional string)
195            "Return string of text matched by last search, without text properties.
196NUM specifies which parenthesized expression in the last regexp.
197 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
198Zero means the entire text matched by the whole regexp or whole string.
199STRING should be given if the last search was by `string-match' on STRING."
200            (if (match-beginning num)
201                (if string
202                    (let ((result
203                           (substring string
204				      (match-beginning num) (match-end num))))
205                      (set-text-properties 0 (length result) nil result)
206                      result)
207                  (buffer-substring-no-properties (match-beginning num)
208                                                  (match-end num)
209                                                  (current-buffer)))))
210	  )
211      (error nil))
212    (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
213        nil ;; We've got what we needed
214      ;; We have the old custom-library, hack around it!
215      (defmacro defgroup (&rest args)  nil)
216      (defmacro customize (&rest args)
217        (message
218	 "Sorry, Customize is not available with this version of Emacs"))
219      (defmacro defcustom (var value doc &rest args)
220        `(defvar ,var ,value ,doc))
221      )
222    (if (fboundp 'defface)
223        nil				; great!
224      (defmacro defface (var values doc &rest args)
225        `(make-face ,var))
226      )
227
228    (if (and (featurep 'custom) (fboundp 'customize-group))
229        nil ;; We've got what we needed
230      ;; We have an intermediate custom-library, hack around it!
231      (defmacro customize-group (var &rest args)
232        `(customize ,var))
233      )
234
235    (unless (boundp 'inhibit-point-motion-hooks)
236      (defvar inhibit-point-motion-hooks nil))
237    (unless (boundp 'deactivate-mark)
238      (defvar deactivate-mark nil))
239    )
240  ;;
241  ;; OK, do this stuff if we are NOT XEmacs:
242  (unless (featurep 'xemacs)
243    (unless (fboundp 'region-active-p)
244      (defmacro region-active-p ()
245	`(and transient-mark-mode mark-active))))
246  )
247
248;; Provide a regular expression optimization routine, using regexp-opt
249;; if provided by the user's elisp libraries
250(eval-and-compile
251  ;; The below were disabled when GNU Emacs 22 was released;
252  ;; perhaps some still need to be there to support Emacs 21.
253  (if (featurep 'xemacs)
254      (if (fboundp 'regexp-opt)
255          ;; regexp-opt is defined, does it take 3 or 2 arguments?
256          (if (fboundp 'function-max-args)
257              (let ((args (function-max-args `regexp-opt)))
258                (cond
259                 ((eq args 3) ;; It takes 3
260                  (condition-case nil	; Hide this defun from emacses
261					;with just a two input regexp
262                      (defun verilog-regexp-opt (a b)
263                        "Deal with differing number of required arguments for  `regexp-opt'.
264         Call 'regexp-opt' on A and B."
265                        (regexp-opt a b 't))
266                    (error nil))
267                  )
268                 ((eq args 2) ;; It takes 2
269                  (defun verilog-regexp-opt (a b)
270                    "Call 'regexp-opt' on A and B."
271                    (regexp-opt a b))
272                  )
273                 (t nil)))
274            ;; We can't tell; assume it takes 2
275            (defun verilog-regexp-opt (a b)
276              "Call 'regexp-opt' on A and B."
277              (regexp-opt a b))
278            )
279        ;; There is no regexp-opt, provide our own
280        (defun verilog-regexp-opt (strings &optional paren shy)
281          (let ((open (if paren "\\(" "")) (close (if paren "\\)" "")))
282            (concat open (mapconcat 'regexp-quote strings "\\|") close)))
283        )
284    ;; Emacs.
285    (defalias 'verilog-regexp-opt 'regexp-opt)))
286
287(eval-and-compile
288  ;; Both xemacs and emacs
289  (condition-case nil
290      (require 'diff) ;; diff-command and diff-switches
291    (error nil))
292  (condition-case nil
293      (require 'compile) ;; compilation-error-regexp-alist-alist
294    (error nil))
295  (condition-case nil
296      (unless (fboundp 'buffer-chars-modified-tick)  ;; Emacs 22 added
297	(defmacro buffer-chars-modified-tick () (buffer-modified-tick)))
298    (error nil))
299  ;; Added in Emacs 24.1
300  (condition-case nil
301      (unless (fboundp 'prog-mode)
302	(define-derived-mode prog-mode fundamental-mode "Prog"))
303    (error nil)))
304
305(eval-when-compile
306  (defun verilog-regexp-words (a)
307    "Call 'regexp-opt' with word delimiters for the words A."
308    (concat "\\<" (verilog-regexp-opt a t) "\\>")))
309(defun verilog-regexp-words (a)
310  "Call 'regexp-opt' with word delimiters for the words A."
311  ;; The FAQ references this function, so user LISP sometimes calls it
312  (concat "\\<" (verilog-regexp-opt a t) "\\>"))
313
314(defun verilog-easy-menu-filter (menu)
315  "Filter `easy-menu-define' MENU to support new features."
316  (cond ((not (featurep 'xemacs))
317	 menu) ;; GNU Emacs - passthru
318	;; XEmacs doesn't support :help.  Strip it.
319	;; Recursively filter the a submenu
320	((listp menu)
321	 (mapcar 'verilog-easy-menu-filter menu))
322	;; Look for [:help "blah"] and remove
323	((vectorp menu)
324	 (let ((i 0) (out []))
325	   (while (< i (length menu))
326	     (if (equal `:help (aref menu i))
327		 (setq i (+ 2 i))
328	       (setq out (vconcat out (vector (aref menu i)))
329		     i (1+ i))))
330	   out))
331	(t menu))) ;; Default - ok
332;;(verilog-easy-menu-filter
333;;  `("Verilog" ("MA" ["SAA" nil :help "Help SAA"] ["SAB" nil :help "Help SAA"])
334;;     "----" ["MB" nil :help "Help MB"]))
335
336(defun verilog-define-abbrev (table name expansion &optional hook)
337  "Filter `define-abbrev' TABLE NAME EXPANSION and call HOOK.
338Provides SYSTEM-FLAG in newer Emacs."
339  (condition-case nil
340      (define-abbrev table name expansion hook 0 t)
341    (error
342     (define-abbrev table name expansion hook))))
343
344(defun verilog-customize ()
345  "Customize variables and other settings used by Verilog-Mode."
346  (interactive)
347  (customize-group 'verilog-mode))
348
349(defun verilog-font-customize ()
350  "Customize fonts used by Verilog-Mode."
351  (interactive)
352  (if (fboundp 'customize-apropos)
353      (customize-apropos "font-lock-*" 'faces)))
354
355(defun verilog-booleanp (value)
356  "Return t if VALUE is boolean.
357This implements GNU Emacs 22.1's `booleanp' function in earlier Emacs.
358This function may be removed when Emacs 21 is no longer supported."
359  (or (equal value t) (equal value nil)))
360
361(defun verilog-insert-last-command-event ()
362  "Insert the `last-command-event'."
363  (insert (if (featurep 'xemacs)
364	      ;; XEmacs 21.5 doesn't like last-command-event
365	      last-command-char
366	    ;; And GNU Emacs 22 has obsoleted last-command-char
367	    last-command-event)))
368
369(defvar verilog-no-change-functions nil
370  "True if `after-change-functions' is disabled.
371Use of `syntax-ppss' may break, as ppss's cache may get corrupted.")
372
373(defvar verilog-in-hooks nil
374  "True when within a `verilog-run-hooks' block.")
375
376(defmacro verilog-run-hooks (&rest hooks)
377  "Run each hook in HOOKS using `run-hooks'.
378Set `verilog-in-hooks' during this time, to assist AUTO caches."
379  `(let ((verilog-in-hooks t))
380     (run-hooks ,@hooks)))
381
382(defun verilog-syntax-ppss (&optional pos)
383  (when verilog-no-change-functions
384    (if verilog-in-hooks
385	(verilog-scan-cache-flush)
386      ;; else don't let the AUTO code itself get away with flushing the cache,
387      ;; as that'll make things very slow
388      (backtrace)
389      (error "%s: Internal problem; use of syntax-ppss when cache may be corrupt"
390	     (verilog-point-text))))
391  (if (fboundp 'syntax-ppss)
392      (syntax-ppss pos)
393    (parse-partial-sexp (point-min) (or pos (point)))))
394
395(defgroup verilog-mode nil
396  "Major mode for Verilog source code."
397  :version "22.2"
398  :group 'languages)
399
400; (defgroup verilog-mode-fonts nil
401;   "Facilitates easy customization fonts used in Verilog source text"
402;   :link '(customize-apropos "font-lock-*" 'faces)
403;  :group 'verilog-mode)
404
405(defgroup verilog-mode-indent nil
406  "Customize indentation and highlighting of Verilog source text."
407  :group 'verilog-mode)
408
409(defgroup verilog-mode-actions nil
410  "Customize actions on Verilog source text."
411  :group 'verilog-mode)
412
413(defgroup verilog-mode-auto nil
414  "Customize AUTO actions when expanding Verilog source text."
415  :group 'verilog-mode)
416
417(defvar verilog-debug nil
418  "Non-nil means enable debug messages for `verilog-mode' internals.")
419
420(defvar verilog-warn-fatal nil
421  "Non-nil means `verilog-warn-error' warnings are fatal `error's.")
422
423(defcustom verilog-linter
424  "echo 'No verilog-linter set, see \"M-x describe-variable verilog-linter\"'"
425  "Unix program and arguments to call to run a lint checker on Verilog source.
426Depending on the `verilog-set-compile-command', this may be invoked when
427you type \\[compile].  When the compile completes, \\[next-error] will take
428you to the next lint error."
429  :type 'string
430  :group 'verilog-mode-actions)
431;; We don't mark it safe, as it's used as a shell command
432
433(defcustom verilog-coverage
434  "echo 'No verilog-coverage set, see \"M-x describe-variable verilog-coverage\"'"
435  "Program and arguments to use to annotate for coverage Verilog source.
436Depending on the `verilog-set-compile-command', this may be invoked when
437you type \\[compile].  When the compile completes, \\[next-error] will take
438you to the next lint error."
439  :type 'string
440  :group 'verilog-mode-actions)
441;; We don't mark it safe, as it's used as a shell command
442
443(defcustom verilog-simulator
444  "echo 'No verilog-simulator set, see \"M-x describe-variable verilog-simulator\"'"
445  "Program and arguments to use to interpret Verilog source.
446Depending on the `verilog-set-compile-command', this may be invoked when
447you type \\[compile].  When the compile completes, \\[next-error] will take
448you to the next lint error."
449  :type 'string
450  :group 'verilog-mode-actions)
451;; We don't mark it safe, as it's used as a shell command
452
453(defcustom verilog-compiler
454  "echo 'No verilog-compiler set, see \"M-x describe-variable verilog-compiler\"'"
455  "Program and arguments to use to compile Verilog source.
456Depending on the `verilog-set-compile-command', this may be invoked when
457you type \\[compile].  When the compile completes, \\[next-error] will take
458you to the next lint error."
459  :type 'string
460  :group 'verilog-mode-actions)
461;; We don't mark it safe, as it's used as a shell command
462
463(defcustom verilog-preprocessor
464  ;; Very few tools give preprocessed output, so we'll default to Verilog-Perl
465  "vppreproc __FLAGS__ __FILE__"
466  "Program and arguments to use to preprocess Verilog source.
467This is invoked with `verilog-preprocess', and depending on the
468`verilog-set-compile-command', may also be invoked when you type
469\\[compile].  When the compile completes, \\[next-error] will
470take you to the next lint error."
471  :type 'string
472  :group 'verilog-mode-actions)
473;; We don't mark it safe, as it's used as a shell command
474
475(defvar verilog-preprocess-history nil
476  "History for `verilog-preprocess'.")
477
478(defvar verilog-tool 'verilog-linter
479  "Which tool to use for building compiler-command.
480Either nil, `verilog-linter, `verilog-compiler,
481`verilog-coverage, `verilog-preprocessor, or `verilog-simulator.
482Alternatively use the \"Choose Compilation Action\" menu.  See
483`verilog-set-compile-command' for more information.")
484
485(defcustom verilog-highlight-translate-off nil
486  "Non-nil means background-highlight code excluded from translation.
487That is, all code between \"// synopsys translate_off\" and
488\"// synopsys translate_on\" is highlighted using a different background color
489\(face `verilog-font-lock-translate-off-face').
490
491Note: This will slow down on-the-fly fontification (and thus editing).
492
493Note: Activate the new setting in a Verilog buffer by re-fontifying it (menu
494entry \"Fontify Buffer\").  XEmacs: turn off and on font locking."
495  :type 'boolean
496  :group 'verilog-mode-indent)
497;; Note we don't use :safe, as that would break on Emacsen before 22.0.
498(put 'verilog-highlight-translate-off 'safe-local-variable 'verilog-booleanp)
499
500(defcustom verilog-auto-lineup 'declarations
501  "Type of statements to lineup across multiple lines.
502If 'all' is selected, then all line ups described below are done.
503
504If 'declaration', then just declarations are lined up with any
505preceding declarations, taking into account widths and the like,
506so or example the code:
507 	reg [31:0] a;
508 	reg b;
509would become
510 	reg [31:0] a;
511 	reg        b;
512
513If 'assignment', then assignments are lined up with any preceding
514assignments, so for example the code
515	a_long_variable <= b + c;
516	d = e + f;
517would become
518	a_long_variable <= b + c;
519	d                = e + f;
520
521In order to speed up editing, large blocks of statements are lined up
522only when a \\[verilog-pretty-expr] is typed; and large blocks of declarations
523are lineup only when \\[verilog-pretty-declarations] is typed."
524
525  :type '(radio (const :tag "Line up Assignments and Declarations" all)
526		(const :tag "Line up Assignment statements" assignments )
527		(const :tag "Line up Declarations" declarations)
528		(function :tag "Other"))
529  :group 'verilog-mode-indent )
530(put 'verilog-auto-lineup 'safe-local-variable
531     '(lambda (x) (memq x '(nil all assignments declarations))))
532
533(defcustom verilog-indent-level 3
534  "Indentation of Verilog statements with respect to containing block."
535  :group 'verilog-mode-indent
536  :type 'integer)
537(put 'verilog-indent-level 'safe-local-variable 'integerp)
538
539(defcustom verilog-indent-level-module 3
540  "Indentation of Module level Verilog statements (eg always, initial).
541Set to 0 to get initial and always statements lined up on the left side of
542your screen."
543  :group 'verilog-mode-indent
544  :type 'integer)
545(put 'verilog-indent-level-module 'safe-local-variable 'integerp)
546
547(defcustom verilog-indent-level-declaration 3
548  "Indentation of declarations with respect to containing block.
549Set to 0 to get them list right under containing block."
550  :group 'verilog-mode-indent
551  :type 'integer)
552(put 'verilog-indent-level-declaration 'safe-local-variable 'integerp)
553
554(defcustom verilog-indent-declaration-macros nil
555  "How to treat macro expansions in a declaration.
556If nil, indent as:
557	input [31:0] a;
558	input        `CP;
559	output       c;
560If non nil, treat as:
561	input [31:0] a;
562	input `CP    ;
563	output       c;"
564  :group 'verilog-mode-indent
565  :type 'boolean)
566(put 'verilog-indent-declaration-macros 'safe-local-variable 'verilog-booleanp)
567
568(defcustom verilog-indent-lists t
569  "How to treat indenting items in a list.
570If t (the default), indent as:
571	always @( posedge a or
572	          reset ) begin
573
574If nil, treat as:
575	always @( posedge a or
576	   reset ) begin"
577  :group 'verilog-mode-indent
578  :type 'boolean)
579(put 'verilog-indent-lists 'safe-local-variable 'verilog-booleanp)
580
581(defcustom verilog-indent-level-behavioral 3
582  "Absolute indentation of first begin in a task or function block.
583Set to 0 to get such code to start at the left side of the screen."
584  :group 'verilog-mode-indent
585  :type 'integer)
586(put 'verilog-indent-level-behavioral 'safe-local-variable 'integerp)
587
588(defcustom verilog-indent-level-directive 1
589  "Indentation to add to each level of `ifdef declarations.
590Set to 0 to have all directives start at the left side of the screen."
591  :group 'verilog-mode-indent
592  :type 'integer)
593(put 'verilog-indent-level-directive 'safe-local-variable 'integerp)
594
595(defcustom verilog-cexp-indent 2
596  "Indentation of Verilog statements split across lines."
597  :group 'verilog-mode-indent
598  :type 'integer)
599(put 'verilog-cexp-indent 'safe-local-variable 'integerp)
600
601(defcustom verilog-case-indent 2
602  "Indentation for case statements."
603  :group 'verilog-mode-indent
604  :type 'integer)
605(put 'verilog-case-indent 'safe-local-variable 'integerp)
606
607(defcustom verilog-auto-newline t
608  "Non-nil means automatically newline after semicolons."
609  :group 'verilog-mode-indent
610  :type 'boolean)
611(put 'verilog-auto-newline 'safe-local-variable 'verilog-booleanp)
612
613(defcustom verilog-auto-indent-on-newline t
614  "Non-nil means automatically indent line after newline."
615  :group 'verilog-mode-indent
616  :type 'boolean)
617(put 'verilog-auto-indent-on-newline 'safe-local-variable 'verilog-booleanp)
618
619(defcustom verilog-tab-always-indent t
620  "Non-nil means TAB should always re-indent the current line.
621A nil value means TAB will only reindent when at the beginning of the line."
622  :group 'verilog-mode-indent
623  :type 'boolean)
624(put 'verilog-tab-always-indent 'safe-local-variable 'verilog-booleanp)
625
626(defcustom verilog-tab-to-comment nil
627  "Non-nil means TAB moves to the right hand column in preparation for a comment."
628  :group 'verilog-mode-actions
629  :type 'boolean)
630(put 'verilog-tab-to-comment 'safe-local-variable 'verilog-booleanp)
631
632(defcustom verilog-indent-begin-after-if t
633  "Non-nil means indent begin statements following if, else, while, etc.
634Otherwise, line them up."
635  :group 'verilog-mode-indent
636  :type 'boolean)
637(put 'verilog-indent-begin-after-if 'safe-local-variable 'verilog-booleanp)
638
639(defcustom verilog-align-ifelse nil
640  "Non-nil means align `else' under matching `if'.
641Otherwise else is lined up with first character on line holding matching if."
642  :group 'verilog-mode-indent
643  :type 'boolean)
644(put 'verilog-align-ifelse 'safe-local-variable 'verilog-booleanp)
645
646(defcustom verilog-minimum-comment-distance 10
647  "Minimum distance (in lines) between begin and end required before a comment.
648Setting this variable to zero results in every end acquiring a comment; the
649default avoids too many redundant comments in tight quarters."
650  :group 'verilog-mode-indent
651  :type 'integer)
652(put 'verilog-minimum-comment-distance 'safe-local-variable 'integerp)
653
654(defcustom verilog-highlight-p1800-keywords nil
655  "Non-nil means highlight words newly reserved by IEEE-1800.
656These will appear in `verilog-font-lock-p1800-face' in order to gently
657suggest changing where these words are used as variables to something else.
658A nil value means highlight these words as appropriate for the SystemVerilog
659IEEE-1800 standard.  Note that changing this will require restarting Emacs
660to see the effect as font color choices are cached by Emacs."
661  :group 'verilog-mode-indent
662  :type 'boolean)
663(put 'verilog-highlight-p1800-keywords 'safe-local-variable 'verilog-booleanp)
664
665(defcustom verilog-highlight-grouping-keywords nil
666  "Non-nil means highlight grouping keywords 'begin' and 'end' more dramatically.
667If false, these words are in the `font-lock-type-face'; if True then they are in
668`verilog-font-lock-ams-face'.  Some find that special highlighting on these
669grouping constructs allow the structure of the code to be understood at a glance."
670  :group 'verilog-mode-indent
671  :type 'boolean)
672(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp)
673
674(defcustom verilog-highlight-modules nil
675  "Non-nil means highlight module statements for `verilog-load-file-at-point'.
676When true, mousing over module names will allow jumping to the
677module definition.  If false, this is not supported.  Setting
678this is experimental, and may lead to bad performance."
679  :group 'verilog-mode-indent
680  :type 'boolean)
681(put 'verilog-highlight-modules 'safe-local-variable 'verilog-booleanp)
682
683(defcustom verilog-highlight-includes t
684  "Non-nil means highlight module statements for `verilog-load-file-at-point'.
685When true, mousing over include file names will allow jumping to the
686file referenced.  If false, this is not supported."
687  :group 'verilog-mode-indent
688  :type 'boolean)
689(put 'verilog-highlight-includes 'safe-local-variable 'verilog-booleanp)
690
691(defcustom verilog-auto-declare-nettype nil
692  "Non-nil specifies the data type to use with `verilog-auto-input' etc.
693Set this to \"wire\" if the Verilog code uses \"`default_nettype
694none\".  Note using `default_nettype none isn't recommended practice; this
695mode is experimental."
696  :version "24.1"  ;; rev670
697  :group 'verilog-mode-actions
698  :type 'boolean)
699(put 'verilog-auto-declare-nettype 'safe-local-variable `stringp)
700
701(defcustom verilog-auto-wire-type nil
702  "Non-nil specifies the data type to use with `verilog-auto-wire' etc.
703Set this to \"logic\" for SystemVerilog code, or use `verilog-auto-logic'."
704  :version "24.1"  ;; rev673
705  :group 'verilog-mode-actions
706  :type 'boolean)
707(put 'verilog-auto-wire-type 'safe-local-variable `stringp)
708
709(defcustom verilog-auto-endcomments t
710  "Non-nil means insert a comment /* ... */ after 'end's.
711The name of the function or case will be set between the braces."
712  :group 'verilog-mode-actions
713  :type 'boolean)
714(put 'verilog-auto-endcomments 'safe-local-variable 'verilog-booleanp)
715
716(defcustom verilog-auto-delete-trailing-whitespace nil
717  "Non-nil means to `delete-trailing-whitespace' in `verilog-auto'."
718  :version "24.1"  ;; rev703
719  :group 'verilog-mode-actions
720  :type 'boolean)
721(put 'verilog-auto-delete-trailing-whitespace 'safe-local-variable 'verilog-booleanp)
722
723(defcustom verilog-auto-ignore-concat nil
724  "Non-nil means ignore signals in {...} concatenations for AUTOWIRE etc.
725This will exclude signals referenced as pin connections in {...}
726from AUTOWIRE, AUTOOUTPUT and friends.  This flag should be set
727for backward compatibility only and not set in new designs; it
728may be removed in future versions."
729  :group 'verilog-mode-actions
730  :type 'boolean)
731(put 'verilog-auto-ignore-concat 'safe-local-variable 'verilog-booleanp)
732
733(defcustom verilog-auto-read-includes nil
734  "Non-nil means to automatically read includes before AUTOs.
735This will do a `verilog-read-defines' and `verilog-read-includes' before
736each AUTO expansion.  This makes it easier to embed defines and includes,
737but can result in very slow reading times if there are many or large
738include files."
739  :group 'verilog-mode-actions
740  :type 'boolean)
741(put 'verilog-auto-read-includes 'safe-local-variable 'verilog-booleanp)
742
743(defcustom verilog-auto-save-policy nil
744  "Non-nil indicates action to take when saving a Verilog buffer with AUTOs.
745A value of `force' will always do a \\[verilog-auto] automatically if
746needed on every save.  A value of `detect' will do \\[verilog-auto]
747automatically when it thinks necessary.  A value of `ask' will query the
748user when it thinks updating is needed.
749
750You should not rely on the 'ask or 'detect policies, they are safeguards
751only.  They do not detect when AUTOINSTs need to be updated because a
752sub-module's port list has changed."
753  :group 'verilog-mode-actions
754  :type '(choice (const nil) (const ask) (const detect) (const force)))
755
756(defcustom verilog-auto-star-expand t
757  "Non-nil means to expand SystemVerilog .* instance ports.
758They will be expanded in the same way as if there was an AUTOINST in the
759instantiation.  See also `verilog-auto-star' and `verilog-auto-star-save'."
760  :group 'verilog-mode-actions
761  :type 'boolean)
762(put 'verilog-auto-star-expand 'safe-local-variable 'verilog-booleanp)
763
764(defcustom verilog-auto-star-save nil
765  "Non-nil means save to disk SystemVerilog .* instance expansions.
766A nil value indicates direct connections will be removed before saving.
767Only meaningful to those created due to `verilog-auto-star-expand' being set.
768
769Instead of setting this, you may want to use /*AUTOINST*/, which will
770always be saved."
771  :group 'verilog-mode-actions
772  :type 'boolean)
773(put 'verilog-auto-star-save 'safe-local-variable 'verilog-booleanp)
774
775(defvar verilog-auto-update-tick nil
776  "Modification tick at which autos were last performed.")
777
778(defvar verilog-auto-last-file-locals nil
779  "Text from file-local-variables during last evaluation.")
780
781(defvar verilog-diff-function 'verilog-diff-report
782  "Function to run when `verilog-diff-auto' detects differences.
783Function takes three arguments, the original buffer, the
784difference buffer, and the point in original buffer with the
785first difference.")
786
787;;; Compile support
788(require 'compile)
789(defvar verilog-error-regexp-added nil)
790
791(defvar verilog-error-regexp-emacs-alist
792  '(
793    (verilog-xl-1
794     "\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 3)
795    (verilog-xl-2
796     "([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 1 3)
797    (verilog-IES
798     ".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)" 2 3)
799    (verilog-surefire-1
800     "[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 2)
801    (verilog-surefire-2
802     "\\(WARNING\\|ERROR\\|INFO\\)[^:]*: \\([^,]+\\),\\s-+\\(line \\)?\\([0-9]+\\):" 2 4 )
803    (verilog-verbose
804     "\
805\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
806:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 2 5)
807    (verilog-xsim
808     "\\(Error\\|Warning\\).*in file (\\([^ \t]+\\) at line *\\([0-9]+\\))" 2 3)
809    (verilog-vcs-1
810     "\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 3)
811    (verilog-vcs-2
812     "Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 2)
813    (verilog-vcs-3
814     "\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 3)
815    (verilog-vcs-4
816     "syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 2)
817    (verilog-verilator
818     "%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4)
819    (verilog-leda
820     "^In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\(Warning\\|Error\\|Failure\\)[^\n]*" 1 2)
821    )
822  "List of regexps for Verilog compilers.
823See `compilation-error-regexp-alist' for the formatting.  For Emacs 22+.")
824
825(defvar verilog-error-regexp-xemacs-alist
826  ;; Emacs form is '((v-tool "re" 1 2) ...)
827  ;; XEmacs form is '(verilog ("re" 1 2) ...)
828  ;; So we can just map from Emacs to XEmacs
829  (cons 'verilog (mapcar 'cdr verilog-error-regexp-emacs-alist))
830  "List of regexps for Verilog compilers.
831See `compilation-error-regexp-alist-alist' for the formatting.  For XEmacs.")
832
833(defvar verilog-error-font-lock-keywords
834  '(
835    ;; verilog-xl-1
836    ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
837    ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
838    ;; verilog-xl-2
839    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 1 bold t)
840    ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 3 bold t)
841    ;; verilog-IES (nc-verilog)
842    (".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)|" 2 bold t)
843    (".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)|" 3 bold t)
844    ;; verilog-surefire-1
845    ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 bold t)
846    ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 2 bold t)
847    ;; verilog-surefire-2
848    ("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 2 bold t)
849    ("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 3 bold t)
850    ;; verilog-verbose
851    ("\
852\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
853:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 bold t)
854    ("\
855\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
856:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 bold t)
857    ;; verilog-vcs-1
858    ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 bold t)
859    ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 3 bold t)
860    ;; verilog-vcs-2
861    ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
862    ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
863    ;; verilog-vcs-3
864    ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
865    ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 3 bold t)
866    ;; verilog-vcs-4
867    ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 bold t)
868    ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
869    ;; verilog-verilator
870    (".*%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 bold t)
871    (".*%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 4 bold t)
872    ;; verilog-leda
873    ("^In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\(Warning\\|Error\\|Failure\\)[^\n]*" 1 bold t)
874    ("^In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\(Warning\\|Error\\|Failure\\)[^\n]*" 2 bold t)
875    )
876  "Keywords to also highlight in Verilog *compilation* buffers.
877Only used in XEmacs; GNU Emacs uses `verilog-error-regexp-emacs-alist'.")
878
879(defcustom verilog-library-flags '("")
880  "List of standard Verilog arguments to use for /*AUTOINST*/.
881These arguments are used to find files for `verilog-auto', and match
882the flags accepted by a standard Verilog-XL simulator.
883
884    -f filename     Reads more `verilog-library-flags' from the filename.
885    +incdir+dir     Adds the directory to `verilog-library-directories'.
886    -Idir           Adds the directory to `verilog-library-directories'.
887    -y dir          Adds the directory to `verilog-library-directories'.
888    +libext+.v      Adds the extensions to `verilog-library-extensions'.
889    -v filename     Adds the filename to `verilog-library-files'.
890
891    filename        Adds the filename to `verilog-library-files'.
892                    This is not recommended, -v is a better choice.
893
894You might want these defined in each file; put at the *END* of your file
895something like:
896
897    // Local Variables:
898    // verilog-library-flags:(\"-y dir -y otherdir\")
899    // End:
900
901Verilog-mode attempts to detect changes to this local variable, but they
902are only insured to be correct when the file is first visited.  Thus if you
903have problems, use \\[find-alternate-file] RET to have these take effect.
904
905See also the variables mentioned above."
906  :group 'verilog-mode-auto
907  :type '(repeat string))
908(put 'verilog-library-flags 'safe-local-variable 'listp)
909
910(defcustom verilog-library-directories '(".")
911  "List of directories when looking for files for /*AUTOINST*/.
912The directory may be relative to the current file, or absolute.
913Environment variables are also expanded in the directory names.
914Having at least the current directory is a good idea.
915
916You might want these defined in each file; put at the *END* of your file
917something like:
918
919    // Local Variables:
920    // verilog-library-directories:(\".\" \"subdir\" \"subdir2\")
921    // End:
922
923Verilog-mode attempts to detect changes to this local variable, but they
924are only insured to be correct when the file is first visited.  Thus if you
925have problems, use \\[find-alternate-file] RET to have these take effect.
926
927See also `verilog-library-flags', `verilog-library-files'
928and `verilog-library-extensions'."
929  :group 'verilog-mode-auto
930  :type '(repeat file))
931(put 'verilog-library-directories 'safe-local-variable 'listp)
932
933(defcustom verilog-library-files '()
934  "List of files to search for modules.
935AUTOINST will use this when it needs to resolve a module name.
936This is a complete path, usually to a technology file with many standard
937cells defined in it.
938
939You might want these defined in each file; put at the *END* of your file
940something like:
941
942    // Local Variables:
943    // verilog-library-files:(\"/some/path/technology.v\" \"/some/path/tech2.v\")
944    // End:
945
946Verilog-mode attempts to detect changes to this local variable, but they
947are only insured to be correct when the file is first visited.  Thus if you
948have problems, use \\[find-alternate-file] RET to have these take effect.
949
950See also `verilog-library-flags', `verilog-library-directories'."
951  :group 'verilog-mode-auto
952  :type '(repeat directory))
953(put 'verilog-library-files 'safe-local-variable 'listp)
954
955(defcustom verilog-library-extensions '(".v" ".sv")
956  "List of extensions to use when looking for files for /*AUTOINST*/.
957See also `verilog-library-flags', `verilog-library-directories'."
958  :type '(repeat string)
959  :group 'verilog-mode-auto)
960(put 'verilog-library-extensions 'safe-local-variable 'listp)
961
962(defcustom verilog-active-low-regexp nil
963  "If set, treat signals matching this regexp as active low.
964This is used for AUTORESET and AUTOTIEOFF.  For proper behavior,
965you will probably also need `verilog-auto-reset-widths' set."
966  :group 'verilog-mode-auto
967  :type 'string)
968(put 'verilog-active-low-regexp 'safe-local-variable 'stringp)
969
970(defcustom verilog-auto-sense-include-inputs nil
971  "Non-nil means AUTOSENSE should include all inputs.
972If nil, only inputs that are NOT output signals in the same block are
973included."
974  :group 'verilog-mode-auto
975  :type 'boolean)
976(put 'verilog-auto-sense-include-inputs 'safe-local-variable 'verilog-booleanp)
977
978(defcustom verilog-auto-sense-defines-constant nil
979  "Non-nil means AUTOSENSE should assume all defines represent constants.
980When true, the defines will not be included in sensitivity lists.  To
981maintain compatibility with other sites, this should be set at the bottom
982of each Verilog file that requires it, rather than being set globally."
983  :group 'verilog-mode-auto
984  :type 'boolean)
985(put 'verilog-auto-sense-defines-constant 'safe-local-variable 'verilog-booleanp)
986
987(defcustom verilog-auto-reset-blocking-in-non t
988  "Non-nil means AUTORESET will reset blocking statements.
989When true, AUTORESET will reset in blocking statements those
990signals which were assigned with blocking assignments (=) even in
991a block with non-blocking assignments (<=).
992
993If nil, all blocking assigned signals are ignored when any
994non-blocking assignment is in the AUTORESET block.  This allows
995blocking assignments to be used for temporary values and not have
996those temporaries reset.  See example in `verilog-auto-reset'."
997  :version "24.1"  ;; rev718
998  :type 'boolean
999  :group 'verilog-mode-auto)
1000(put 'verilog-auto-reset-blocking-in-non 'safe-local-variable 'verilog-booleanp)
1001
1002(defcustom verilog-auto-reset-widths t
1003  "True means AUTORESET should determine the width of signals.
1004This is then used to set the width of the zero (32'h0 for example).  This
1005is required by some lint tools that aren't smart enough to ignore widths of
1006the constant zero. This may result in ugly code when parameters determine
1007the MSB or LSB of a signal inside an AUTORESET.
1008
1009If nil, AUTORESET uses \"0\" as the constant.
1010
1011If 'unbased', AUTORESET used the unbased unsized literal \"'0\"
1012as the constant. This setting is strongly recommended for
1013SystemVerilog designs."
1014  :type 'boolean
1015  :group 'verilog-mode-auto)
1016(put 'verilog-auto-reset-widths 'safe-local-variable
1017     '(lambda (x) (memq x '(nil t unbased))))
1018
1019(defcustom verilog-assignment-delay ""
1020  "Text used for delays in delayed assignments.  Add a trailing space if set."
1021  :group 'verilog-mode-auto
1022  :type 'string)
1023(put 'verilog-assignment-delay 'safe-local-variable 'stringp)
1024
1025(defcustom verilog-auto-arg-sort nil
1026  "Non-nil means AUTOARG signal names will be sorted, not in declaration order.
1027Declaration order is advantageous with order based instantiations
1028and is the default for backward compatibility.  Sorted order
1029reduces changes when declarations are moved around in a file, and
1030it's bad practice to rely on order based instantiations anyhow.
1031
1032See also `verilog-auto-inst-sort'."
1033  :group 'verilog-mode-auto
1034  :type 'boolean)
1035(put 'verilog-auto-arg-sort 'safe-local-variable 'verilog-booleanp)
1036
1037(defcustom verilog-auto-inst-dot-name nil
1038  "Non-nil means when creating ports with AUTOINST, use .name syntax.
1039This will use \".port\" instead of \".port(port)\" when possible.
1040This is only legal in SystemVerilog files, and will confuse older
1041simulators.  Setting `verilog-auto-inst-vector' to nil may also
1042be desirable to increase how often .name will be used."
1043  :group 'verilog-mode-auto
1044  :type 'boolean)
1045(put 'verilog-auto-inst-dot-name 'safe-local-variable 'verilog-booleanp)
1046
1047(defcustom verilog-auto-inst-param-value nil
1048  "Non-nil means AUTOINST will replace parameters with the parameter value.
1049If nil, leave parameters as symbolic names.
1050
1051Parameters must be in Verilog 2001 format #(...), and if a parameter is not
1052listed as such there (as when the default value is acceptable), it will not
1053be replaced, and will remain symbolic.
1054
1055For example, imagine a submodule uses parameters to declare the size of its
1056inputs.  This is then used by an upper module:
1057
1058	module InstModule (o,i);
1059	   parameter WIDTH;
1060	   input [WIDTH-1:0] i;
1061	endmodule
1062
1063	module ExampInst;
1064	   InstModule
1065 	     #(PARAM(10))
1066	    instName
1067	     (/*AUTOINST*/
1068	      .i 	(i[PARAM-1:0]));
1069
1070Note even though PARAM=10, the AUTOINST has left the parameter as a
1071symbolic name.  If `verilog-auto-inst-param-value' is set, this will
1072instead expand to:
1073
1074	module ExampInst;
1075	   InstModule
1076 	     #(PARAM(10))
1077	    instName
1078	     (/*AUTOINST*/
1079	      .i 	(i[9:0]));"
1080  :group 'verilog-mode-auto
1081  :type 'boolean)
1082(put 'verilog-auto-inst-param-value 'safe-local-variable 'verilog-booleanp)
1083
1084(defcustom verilog-auto-inst-sort nil
1085  "Non-nil means AUTOINST signals will be sorted, not in declaration order.
1086Also affects AUTOINSTPARAM.  Declaration order is the default for
1087backward compatibility, and as some teams prefer signals that are
1088declared together to remain together.  Sorted order reduces
1089changes when declarations are moved around in a file.
1090
1091See also `verilog-auto-arg-sort'."
1092  :version "24.1"  ;; rev688
1093  :group 'verilog-mode-auto
1094  :type 'boolean)
1095(put 'verilog-auto-inst-sort 'safe-local-variable 'verilog-booleanp)
1096
1097(defcustom verilog-auto-inst-vector t
1098  "Non-nil means when creating default ports with AUTOINST, use bus subscripts.
1099If nil, skip the subscript when it matches the entire bus as declared in
1100the module (AUTOWIRE signals always are subscripted, you must manually
1101declare the wire to have the subscripts removed.)  Setting this to nil may
1102speed up some simulators, but is less general and harder to read, so avoid."
1103  :group 'verilog-mode-auto
1104  :type 'boolean)
1105(put 'verilog-auto-inst-vector 'safe-local-variable 'verilog-booleanp)
1106
1107(defcustom verilog-auto-inst-template-numbers nil
1108  "If true, when creating templated ports with AUTOINST, add a comment.
1109
1110If t, the comment will add the line number of the template that
1111was used for that port declaration.  This setting is suggested
1112only for debugging use, as regular use may cause a large numbers
1113of merge conflicts.
1114
1115If 'lhs', the comment will show the left hand side of the
1116AUTO_TEMPLATE rule that is matched.  This is less precise than
1117numbering (t) when multiple rules have the same pin name, but
1118won't merge conflict."
1119  :group 'verilog-mode-auto
1120  :type '(choice (const nil) (const t) (const lhs)))
1121(put 'verilog-auto-inst-template-numbers 'safe-local-variable
1122     '(lambda (x) (memq x '(nil t lhs))))
1123
1124(defcustom verilog-auto-inst-column 40
1125  "Indent-to column number for net name part of AUTOINST created pin."
1126  :group 'verilog-mode-indent
1127  :type 'integer)
1128(put 'verilog-auto-inst-column 'safe-local-variable 'integerp)
1129
1130(defcustom verilog-auto-inst-interfaced-ports t
1131  "Non-nil means include interfaced ports in AUTOINST expansions."
1132  :group 'verilog-mode-auto
1133  :type 'boolean)
1134(put 'verilog-auto-inst-interfaced-ports 'safe-local-variable 'verilog-booleanp)
1135
1136(defcustom verilog-auto-input-ignore-regexp nil
1137  "If set, when creating AUTOINPUT list, ignore signals matching this regexp.
1138See the \\[verilog-faq] for examples on using this."
1139  :group 'verilog-mode-auto
1140  :type 'string)
1141(put 'verilog-auto-input-ignore-regexp 'safe-local-variable 'stringp)
1142
1143(defcustom verilog-auto-inout-ignore-regexp nil
1144  "If set, when creating AUTOINOUT list, ignore signals matching this regexp.
1145See the \\[verilog-faq] for examples on using this."
1146  :group 'verilog-mode-auto
1147  :type 'string)
1148(put 'verilog-auto-inout-ignore-regexp 'safe-local-variable 'stringp)
1149
1150(defcustom verilog-auto-output-ignore-regexp nil
1151  "If set, when creating AUTOOUTPUT list, ignore signals matching this regexp.
1152See the \\[verilog-faq] for examples on using this."
1153  :group 'verilog-mode-auto
1154  :type 'string)
1155(put 'verilog-auto-output-ignore-regexp 'safe-local-variable 'stringp)
1156
1157(defcustom verilog-auto-template-warn-unused nil
1158  "Non-nil means report warning if an AUTO_TEMPLATE line is not used.
1159This feature is not supported before Emacs 21.1 or XEmacs 21.4."
1160  :group 'verilog-mode-auto
1161  :type 'boolean)
1162(put 'verilog-auto-template-warn-unused 'safe-local-variable 'verilog-booleanp)
1163
1164(defcustom verilog-auto-tieoff-declaration "wire"
1165  "Data type used for the declaration for AUTOTIEOFF.
1166If \"wire\" then create a wire, if \"assign\" create an
1167assignment, else the data type for variable creation."
1168  :version "24.1"  ;; rev713
1169  :group 'verilog-mode-auto
1170  :type 'string)
1171(put 'verilog-auto-tieoff-declaration 'safe-local-variable 'stringp)
1172
1173(defcustom verilog-auto-tieoff-ignore-regexp nil
1174  "If set, when creating AUTOTIEOFF list, ignore signals matching this regexp.
1175See the \\[verilog-faq] for examples on using this."
1176  :group 'verilog-mode-auto
1177  :type 'string)
1178(put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable 'stringp)
1179
1180(defcustom verilog-auto-unused-ignore-regexp nil
1181  "If set, when creating AUTOUNUSED list, ignore signals matching this regexp.
1182See the \\[verilog-faq] for examples on using this."
1183  :group 'verilog-mode-auto
1184  :type 'string)
1185(put 'verilog-auto-unused-ignore-regexp 'safe-local-variable 'stringp)
1186
1187(defcustom verilog-typedef-regexp nil
1188  "If non-nil, regular expression that matches Verilog-2001 typedef names.
1189For example, \"_t$\" matches typedefs named with _t, as in the C language."
1190  :group 'verilog-mode-auto
1191  :type 'string)
1192(put 'verilog-typedef-regexp 'safe-local-variable 'stringp)
1193
1194(defcustom verilog-mode-hook   'verilog-set-compile-command
1195  "Hook run after Verilog mode is loaded."
1196  :type 'hook
1197  :group 'verilog-mode)
1198
1199(defcustom verilog-auto-hook nil
1200  "Hook run after `verilog-mode' updates AUTOs."
1201  :group 'verilog-mode-auto
1202  :type 'hook)
1203
1204(defcustom verilog-before-auto-hook nil
1205  "Hook run before `verilog-mode' updates AUTOs."
1206  :group 'verilog-mode-auto
1207  :type 'hook)
1208
1209(defcustom verilog-delete-auto-hook nil
1210  "Hook run after `verilog-mode' deletes AUTOs."
1211  :group 'verilog-mode-auto
1212  :type 'hook)
1213
1214(defcustom verilog-before-delete-auto-hook nil
1215  "Hook run before `verilog-mode' deletes AUTOs."
1216  :group 'verilog-mode-auto
1217  :type 'hook)
1218
1219(defcustom verilog-getopt-flags-hook nil
1220  "Hook run after `verilog-getopt-flags' determines the Verilog option lists."
1221  :group 'verilog-mode-auto
1222  :type 'hook)
1223
1224(defcustom verilog-before-getopt-flags-hook nil
1225  "Hook run before `verilog-getopt-flags' determines the Verilog option lists."
1226  :group 'verilog-mode-auto
1227  :type 'hook)
1228
1229(defcustom verilog-before-save-font-hook nil
1230  "Hook run before `verilog-save-font-mods' removes highlighting."
1231  :group 'verilog-mode-auto
1232  :type 'hook)
1233
1234(defcustom verilog-after-save-font-hook nil
1235  "Hook run after `verilog-save-font-mods' restores highlighting."
1236  :group 'verilog-mode-auto
1237  :type 'hook)
1238
1239(defvar verilog-imenu-generic-expression
1240  '((nil "^\\s-*\\(\\(m\\(odule\\|acromodule\\)\\)\\|primitive\\)\\s-+\\([a-zA-Z0-9_.:]+\\)" 4)
1241    ("*Vars*" "^\\s-*\\(reg\\|wire\\)\\s-+\\(\\|\\[[^]]+\\]\\s-+\\)\\([A-Za-z0-9_]+\\)" 3))
1242  "Imenu expression for Verilog mode.  See `imenu-generic-expression'.")
1243
1244;;
1245;; provide a verilog-header function.
1246;; Customization variables:
1247;;
1248(defvar verilog-date-scientific-format nil
1249  "If non-nil, dates are written in scientific format (e.g.  1997/09/17).
1250If nil, in European format (e.g.  17.09.1997).  The brain-dead American
1251format (e.g.  09/17/1997) is not supported.")
1252
1253(defvar verilog-company nil
1254  "Default name of Company for Verilog header.
1255If set will become buffer local.")
1256(make-variable-buffer-local 'verilog-company)
1257
1258(defvar verilog-project nil
1259  "Default name of Project for Verilog header.
1260If set will become buffer local.")
1261(make-variable-buffer-local 'verilog-project)
1262
1263(defvar verilog-mode-map
1264  (let ((map (make-sparse-keymap)))
1265    (define-key map ";"        'electric-verilog-semi)
1266    (define-key map [(control 59)]    'electric-verilog-semi-with-comment)
1267    (define-key map ":"        'electric-verilog-colon)
1268    ;;(define-key map "="        'electric-verilog-equal)
1269    (define-key map "\`"       'electric-verilog-tick)
1270    (define-key map "\t"       'electric-verilog-tab)
1271    (define-key map "\r"       'electric-verilog-terminate-line)
1272    ;; backspace/delete key bindings
1273    (define-key map [backspace]    'backward-delete-char-untabify)
1274    (unless (boundp 'delete-key-deletes-forward) ; XEmacs variable
1275      (define-key map [delete]       'delete-char)
1276      (define-key map [(meta delete)] 'kill-word))
1277    (define-key map "\M-\C-b"  'electric-verilog-backward-sexp)
1278    (define-key map "\M-\C-f"  'electric-verilog-forward-sexp)
1279    (define-key map "\M-\r"    `electric-verilog-terminate-and-indent)
1280    (define-key map "\M-\t"    'verilog-complete-word)
1281    (define-key map "\M-?"     'verilog-show-completions)
1282    ;; Note \C-c and letter are reserved for users
1283    (define-key map "\C-c\`"   'verilog-lint-off)
1284    (define-key map "\C-c\*"   'verilog-delete-auto-star-implicit)
1285    (define-key map "\C-c\?"   'verilog-diff-auto)
1286    (define-key map "\C-c\C-r" 'verilog-label-be)
1287    (define-key map "\C-c\C-i" 'verilog-pretty-declarations)
1288    (define-key map "\C-c="    'verilog-pretty-expr)
1289    (define-key map "\C-c\C-b" 'verilog-submit-bug-report)
1290    (define-key map "\M-*"     'verilog-star-comment)
1291    (define-key map "\C-c\C-c" 'verilog-comment-region)
1292    (define-key map "\C-c\C-u" 'verilog-uncomment-region)
1293    (when (featurep 'xemacs)
1294      (define-key map [(meta control h)] 'verilog-mark-defun)
1295      (define-key map "\M-\C-a"  'verilog-beg-of-defun)
1296      (define-key map "\M-\C-e"  'verilog-end-of-defun))
1297    (define-key map "\C-c\C-d" 'verilog-goto-defun)
1298    (define-key map "\C-c\C-k" 'verilog-delete-auto)
1299    (define-key map "\C-c\C-a" 'verilog-auto)
1300    (define-key map "\C-c\C-s" 'verilog-auto-save-compile)
1301    (define-key map "\C-c\C-p" 'verilog-preprocess)
1302    (define-key map "\C-c\C-z" 'verilog-inject-auto)
1303    (define-key map "\C-c\C-e" 'verilog-expand-vector)
1304    (define-key map "\C-c\C-h" 'verilog-header)
1305    map)
1306  "Keymap used in Verilog mode.")
1307
1308;; menus
1309(easy-menu-define
1310  verilog-menu verilog-mode-map "Menu for Verilog mode"
1311  (verilog-easy-menu-filter
1312   '("Verilog"
1313     ("Choose Compilation Action"
1314      ["None"
1315       (progn
1316	 (setq verilog-tool nil)
1317	 (verilog-set-compile-command))
1318       :style radio
1319       :selected (equal verilog-tool nil)
1320       :help "When invoking compilation, use compile-command"]
1321      ["Lint"
1322       (progn
1323	 (setq verilog-tool 'verilog-linter)
1324	 (verilog-set-compile-command))
1325       :style radio
1326       :selected (equal verilog-tool `verilog-linter)
1327       :help "When invoking compilation, use lint checker"]
1328      ["Coverage"
1329       (progn
1330	 (setq verilog-tool 'verilog-coverage)
1331	 (verilog-set-compile-command))
1332       :style radio
1333       :selected (equal verilog-tool `verilog-coverage)
1334       :help "When invoking compilation, annotate for coverage"]
1335      ["Simulator"
1336       (progn
1337	 (setq verilog-tool 'verilog-simulator)
1338	 (verilog-set-compile-command))
1339       :style radio
1340       :selected (equal verilog-tool `verilog-simulator)
1341       :help "When invoking compilation, interpret Verilog source"]
1342      ["Compiler"
1343       (progn
1344	 (setq verilog-tool 'verilog-compiler)
1345	 (verilog-set-compile-command))
1346       :style radio
1347       :selected (equal verilog-tool `verilog-compiler)
1348       :help "When invoking compilation, compile Verilog source"]
1349      ["Preprocessor"
1350       (progn
1351	 (setq verilog-tool 'verilog-preprocessor)
1352	 (verilog-set-compile-command))
1353       :style radio
1354       :selected (equal verilog-tool `verilog-preprocessor)
1355       :help "When invoking compilation, preprocess Verilog source, see also `verilog-preprocess'"]
1356      )
1357     ("Move"
1358      ["Beginning of function"		verilog-beg-of-defun
1359       :keys "C-M-a"
1360       :help		"Move backward to the beginning of the current function or procedure"]
1361      ["End of function"		verilog-end-of-defun
1362       :keys "C-M-e"
1363       :help		"Move forward to the end of the current function or procedure"]
1364      ["Mark function"			verilog-mark-defun
1365       :keys "C-M-h"
1366       :help		"Mark the current Verilog function or procedure"]
1367      ["Goto function/module"		verilog-goto-defun
1368       :help		"Move to specified Verilog module/task/function"]
1369      ["Move to beginning of block"	electric-verilog-backward-sexp
1370       :help		"Move backward over one balanced expression"]
1371      ["Move to end of block"		electric-verilog-forward-sexp
1372       :help		"Move forward over one balanced expression"]
1373      )
1374     ("Comments"
1375      ["Comment Region"			verilog-comment-region
1376       :help		"Put marked area into a comment"]
1377      ["UnComment Region"		verilog-uncomment-region
1378       :help		"Uncomment an area commented with Comment Region"]
1379      ["Multi-line comment insert"	verilog-star-comment
1380       :help		"Insert Verilog /* */ comment at point"]
1381      ["Lint error to comment"		verilog-lint-off
1382       :help		"Convert a Verilog linter warning line into a disable statement"]
1383      )
1384     "----"
1385     ["Compile"				compile
1386      :help		"Perform compilation-action (above) on the current buffer"]
1387     ["AUTO, Save, Compile"		verilog-auto-save-compile
1388      :help		"Recompute AUTOs, save buffer, and compile"]
1389     ["Next Compile Error"		next-error
1390      :help		"Visit next compilation error message and corresponding source code"]
1391     ["Ignore Lint Warning at point"	verilog-lint-off
1392      :help		"Convert a Verilog linter warning line into a disable statement"]
1393     "----"
1394     ["Line up declarations around point"	verilog-pretty-declarations
1395      :help		"Line up declarations around point"]
1396     ["Line up equations around point"		verilog-pretty-expr
1397      :help		"Line up expressions around point"]
1398     ["Redo/insert comments on every end"	verilog-label-be
1399      :help		"Label matching begin ... end statements"]
1400     ["Expand [x:y] vector line"	verilog-expand-vector
1401      :help		"Take a signal vector on the current line and expand it to multiple lines"]
1402     ["Insert begin-end block"		verilog-insert-block
1403      :help		"Insert begin ... end"]
1404     ["Complete word"			verilog-complete-word
1405      :help		"Complete word at point"]
1406     "----"
1407     ["Recompute AUTOs"			verilog-auto
1408      :help		"Expand AUTO meta-comment statements"]
1409     ["Kill AUTOs"			verilog-delete-auto
1410      :help		"Remove AUTO expansions"]
1411     ["Diff AUTOs"			verilog-diff-auto
1412      :help		"Show differences in AUTO expansions"]
1413     ["Inject AUTOs"			verilog-inject-auto
1414      :help		"Inject AUTOs into legacy non-AUTO buffer"]
1415     ("AUTO Help..."
1416      ["AUTO General"			(describe-function 'verilog-auto)
1417       :help		"Help introduction on AUTOs"]
1418      ["AUTO Library Flags"		(describe-variable 'verilog-library-flags)
1419       :help		"Help on verilog-library-flags"]
1420      ["AUTO Library Path"		(describe-variable 'verilog-library-directories)
1421       :help		"Help on verilog-library-directories"]
1422      ["AUTO Library Files"		(describe-variable 'verilog-library-files)
1423       :help		"Help on verilog-library-files"]
1424      ["AUTO Library Extensions"	(describe-variable 'verilog-library-extensions)
1425       :help		"Help on verilog-library-extensions"]
1426      ["AUTO `define Reading"		(describe-function 'verilog-read-defines)
1427       :help		"Help on reading `defines"]
1428      ["AUTO `include Reading"		(describe-function 'verilog-read-includes)
1429       :help		"Help on parsing `includes"]
1430      ["AUTOARG"			(describe-function 'verilog-auto-arg)
1431       :help		"Help on AUTOARG - declaring module port list"]
1432      ["AUTOASCIIENUM"			(describe-function 'verilog-auto-ascii-enum)
1433       :help		"Help on AUTOASCIIENUM - creating ASCII for enumerations"]
1434      ["AUTOINOUTCOMP"			(describe-function 'verilog-auto-inout-comp)
1435       :help		"Help on AUTOINOUTCOMP - copying complemented i/o from another file"]
1436      ["AUTOINOUTIN"			(describe-function 'verilog-auto-inout-in)
1437       :help		"Help on AUTOINOUTCOMP - copying i/o from another file as all inputs"]
1438      ["AUTOINOUTMODULE"		(describe-function 'verilog-auto-inout-module)
1439       :help		"Help on AUTOINOUTMODULE - copying i/o from another file"]
1440      ["AUTOINSERTLISP"			(describe-function 'verilog-auto-insert-lisp)
1441       :help		"Help on AUTOINSERTLISP - insert text from a lisp function"]
1442      ["AUTOINOUT"			(describe-function 'verilog-auto-inout)
1443       :help		"Help on AUTOINOUT - adding inouts from cells"]
1444      ["AUTOINPUT"			(describe-function 'verilog-auto-input)
1445       :help		"Help on AUTOINPUT - adding inputs from cells"]
1446      ["AUTOINST"			(describe-function 'verilog-auto-inst)
1447       :help		"Help on AUTOINST - adding pins for cells"]
1448      ["AUTOINST (.*)"			(describe-function 'verilog-auto-star)
1449       :help		"Help on expanding Verilog-2001 .* pins"]
1450      ["AUTOINSTPARAM"			(describe-function 'verilog-auto-inst-param)
1451       :help		"Help on AUTOINSTPARAM - adding parameter pins to cells"]
1452      ["AUTOLOGIC"			(describe-function 'verilog-auto-logic)
1453       :help		"Help on AUTOLOGIC - declaring logic signals"]
1454      ["AUTOOUTPUT"			(describe-function 'verilog-auto-output)
1455       :help		"Help on AUTOOUTPUT - adding outputs from cells"]
1456      ["AUTOOUTPUTEVERY"		(describe-function 'verilog-auto-output-every)
1457       :help		"Help on AUTOOUTPUTEVERY - adding outputs of all signals"]
1458      ["AUTOREG"			(describe-function 'verilog-auto-reg)
1459       :help		"Help on AUTOREG - declaring registers for non-wires"]
1460      ["AUTOREGINPUT"			(describe-function 'verilog-auto-reg-input)
1461       :help		"Help on AUTOREGINPUT - declaring inputs for non-wires"]
1462      ["AUTORESET"			(describe-function 'verilog-auto-reset)
1463       :help		"Help on AUTORESET - resetting always blocks"]
1464      ["AUTOSENSE"			(describe-function 'verilog-auto-sense)
1465       :help		"Help on AUTOSENSE - sensitivity lists for always blocks"]
1466      ["AUTOTIEOFF"			(describe-function 'verilog-auto-tieoff)
1467       :help		"Help on AUTOTIEOFF - tying off unused outputs"]
1468      ["AUTOUNDEF"			(describe-function 'verilog-auto-undef)
1469       :help		"Help on AUTOUNDEF - undefine all local defines"]
1470      ["AUTOUNUSED"			(describe-function 'verilog-auto-unused)
1471       :help		"Help on AUTOUNUSED - terminating unused inputs"]
1472      ["AUTOWIRE"			(describe-function 'verilog-auto-wire)
1473       :help		"Help on AUTOWIRE - declaring wires for cells"]
1474      )
1475     "----"
1476     ["Submit bug report"		verilog-submit-bug-report
1477      :help		"Submit via mail a bug report on verilog-mode.el"]
1478     ["Version and FAQ"			verilog-faq
1479      :help		"Show the current version, and where to get the FAQ etc"]
1480     ["Customize Verilog Mode..."	verilog-customize
1481      :help		"Customize variables and other settings used by Verilog-Mode"]
1482     ["Customize Verilog Fonts & Colors"	verilog-font-customize
1483      :help		"Customize fonts used by Verilog-Mode."])))
1484
1485(easy-menu-define
1486  verilog-stmt-menu verilog-mode-map "Menu for statement templates in Verilog."
1487  (verilog-easy-menu-filter
1488   '("Statements"
1489     ["Header"		verilog-sk-header
1490      :help		"Insert a header block at the top of file"]
1491     ["Comment"		verilog-sk-comment
1492      :help		"Insert a comment block"]
1493     "----"
1494     ["Module"		verilog-sk-module
1495      :help		"Insert a module .. (/*AUTOARG*/);.. endmodule block"]
1496     ["OVM Class"	verilog-sk-ovm-class
1497      :help		"Insert an OVM class block"]
1498     ["UVM Class"	verilog-sk-uvm-class
1499      :help		"Insert an UVM class block"]
1500     ["Primitive"	verilog-sk-primitive
1501      :help		"Insert a primitive .. (.. );.. endprimitive block"]
1502     "----"
1503     ["Input"		verilog-sk-input
1504      :help		"Insert an input declaration"]
1505     ["Output"		verilog-sk-output
1506      :help		"Insert an output declaration"]
1507     ["Inout"		verilog-sk-inout
1508      :help		"Insert an inout declaration"]
1509     ["Wire"		verilog-sk-wire
1510      :help		"Insert a wire declaration"]
1511     ["Reg"		verilog-sk-reg
1512      :help		"Insert a register declaration"]
1513     ["Define thing under point as a register" verilog-sk-define-signal
1514      :help		"Define signal under point as a register at the top of the module"]
1515     "----"
1516     ["Initial"		verilog-sk-initial
1517      :help		"Insert an initial begin .. end block"]
1518     ["Always"		verilog-sk-always
1519      :help		"Insert an always @(AS) begin .. end block"]
1520     ["Function"	verilog-sk-function
1521      :help		"Insert a function .. begin .. end endfunction block"]
1522     ["Task"		verilog-sk-task
1523      :help		"Insert a task .. begin .. end endtask block"]
1524     ["Specify"		verilog-sk-specify
1525      :help		"Insert a specify .. endspecify block"]
1526     ["Generate"	verilog-sk-generate
1527      :help		"Insert a generate .. endgenerate block"]
1528     "----"
1529     ["Begin"		verilog-sk-begin
1530      :help		"Insert a begin .. end block"]
1531     ["If"		verilog-sk-if
1532      :help		"Insert an if (..) begin .. end block"]
1533     ["(if) else"	verilog-sk-else-if
1534      :help		"Insert an else if (..) begin .. end block"]
1535     ["For"		verilog-sk-for
1536      :help		"Insert a for (...) begin .. end block"]
1537     ["While"		verilog-sk-while
1538      :help		"Insert a while (...) begin .. end block"]
1539     ["Fork"		verilog-sk-fork
1540      :help		"Insert a fork begin .. end .. join block"]
1541     ["Repeat"		verilog-sk-repeat
1542      :help		"Insert a repeat (..) begin .. end block"]
1543     ["Case"		verilog-sk-case
1544      :help		"Insert a case block, prompting for details"]
1545     ["Casex"		verilog-sk-casex
1546      :help		"Insert a casex (...) item: begin.. end endcase block"]
1547     ["Casez"		verilog-sk-casez
1548      :help		"Insert a casez (...) item: begin.. end endcase block"])))
1549
1550(defvar verilog-mode-abbrev-table nil
1551  "Abbrev table in use in Verilog-mode buffers.")
1552
1553(define-abbrev-table 'verilog-mode-abbrev-table ())
1554(verilog-define-abbrev verilog-mode-abbrev-table "class" "" 'verilog-sk-ovm-class)
1555(verilog-define-abbrev verilog-mode-abbrev-table "always" "" 'verilog-sk-always)
1556(verilog-define-abbrev verilog-mode-abbrev-table "begin" nil `verilog-sk-begin)
1557(verilog-define-abbrev verilog-mode-abbrev-table "case" "" `verilog-sk-case)
1558(verilog-define-abbrev verilog-mode-abbrev-table "for" "" `verilog-sk-for)
1559(verilog-define-abbrev verilog-mode-abbrev-table "generate" "" `verilog-sk-generate)
1560(verilog-define-abbrev verilog-mode-abbrev-table "initial" "" `verilog-sk-initial)
1561(verilog-define-abbrev verilog-mode-abbrev-table "fork" "" `verilog-sk-fork)
1562(verilog-define-abbrev verilog-mode-abbrev-table "module" "" `verilog-sk-module)
1563(verilog-define-abbrev verilog-mode-abbrev-table "primitive" "" `verilog-sk-primitive)
1564(verilog-define-abbrev verilog-mode-abbrev-table "repeat" "" `verilog-sk-repeat)
1565(verilog-define-abbrev verilog-mode-abbrev-table "specify" "" `verilog-sk-specify)
1566(verilog-define-abbrev verilog-mode-abbrev-table "task" "" `verilog-sk-task)
1567(verilog-define-abbrev verilog-mode-abbrev-table "while" "" `verilog-sk-while)
1568(verilog-define-abbrev verilog-mode-abbrev-table "casex" "" `verilog-sk-casex)
1569(verilog-define-abbrev verilog-mode-abbrev-table "casez" "" `verilog-sk-casez)
1570(verilog-define-abbrev verilog-mode-abbrev-table "if" "" `verilog-sk-if)
1571(verilog-define-abbrev verilog-mode-abbrev-table "else if" "" `verilog-sk-else-if)
1572(verilog-define-abbrev verilog-mode-abbrev-table "assign" "" `verilog-sk-assign)
1573(verilog-define-abbrev verilog-mode-abbrev-table "function" "" `verilog-sk-function)
1574(verilog-define-abbrev verilog-mode-abbrev-table "input" "" `verilog-sk-input)
1575(verilog-define-abbrev verilog-mode-abbrev-table "output" "" `verilog-sk-output)
1576(verilog-define-abbrev verilog-mode-abbrev-table "inout" "" `verilog-sk-inout)
1577(verilog-define-abbrev verilog-mode-abbrev-table "wire" "" `verilog-sk-wire)
1578(verilog-define-abbrev verilog-mode-abbrev-table "reg" "" `verilog-sk-reg)
1579
1580;;
1581;;  Macros
1582;;
1583
1584(defsubst verilog-within-string ()
1585  (nth 3 (parse-partial-sexp (point-at-bol) (point))))
1586
1587(defsubst verilog-string-replace-matches (from-string to-string fixedcase literal string)
1588  "Replace occurrences of FROM-STRING with TO-STRING.
1589FIXEDCASE and LITERAL as in `replace-match`.  STRING is what to replace.
1590The case (verilog-string-replace-matches \"o\" \"oo\" nil nil \"foobar\")
1591will break, as the o's continuously replace.  xa -> x works ok though."
1592  ;; Hopefully soon to an Emacs built-in
1593  ;; Also note \ in the replacement prevent multiple replacements; IE
1594  ;;   (verilog-string-replace-matches "@" "\\\\([0-9]+\\\\)" nil nil "wire@_@")
1595  ;;   Gives "wire\([0-9]+\)_@" not "wire\([0-9]+\)_\([0-9]+\)"
1596  (let ((start 0))
1597    (while (string-match from-string string start)
1598      (setq string (replace-match to-string fixedcase literal string)
1599	    start (min (length string) (+ (match-beginning 0) (length to-string)))))
1600    string))
1601
1602(defsubst verilog-string-remove-spaces (string)
1603  "Remove spaces surrounding STRING."
1604  (save-match-data
1605    (setq string (verilog-string-replace-matches "^\\s-+" "" nil nil string))
1606    (setq string (verilog-string-replace-matches "\\s-+$" "" nil nil string))
1607    string))
1608
1609(defsubst verilog-re-search-forward (REGEXP BOUND NOERROR)
1610  ; checkdoc-params: (REGEXP BOUND NOERROR)
1611  "Like `re-search-forward', but skips over match in comments or strings."
1612  (let ((mdata '(nil nil)))  ;; So match-end will return nil if no matches found
1613    (while (and
1614	    (re-search-forward REGEXP BOUND NOERROR)
1615	    (setq mdata (match-data))
1616	    (and (verilog-skip-forward-comment-or-string)
1617		 (progn
1618		   (setq mdata '(nil nil))
1619		   (if BOUND
1620		       (< (point) BOUND)
1621		     t)))))
1622    (store-match-data mdata)
1623    (match-end 0)))
1624
1625(defsubst verilog-re-search-backward (REGEXP BOUND NOERROR)
1626  ; checkdoc-params: (REGEXP BOUND NOERROR)
1627  "Like `re-search-backward', but skips over match in comments or strings."
1628  (let ((mdata '(nil nil)))  ;; So match-end will return nil if no matches found
1629    (while (and
1630	    (re-search-backward REGEXP BOUND NOERROR)
1631	    (setq mdata (match-data))
1632	    (and (verilog-skip-backward-comment-or-string)
1633		 (progn
1634		   (setq mdata '(nil nil))
1635		   (if BOUND
1636		       (> (point) BOUND)
1637		     t)))))
1638    (store-match-data mdata)
1639    (match-end 0)))
1640
1641(defsubst verilog-re-search-forward-quick (regexp bound noerror)
1642  "Like `verilog-re-search-forward', including use of REGEXP BOUND and NOERROR,
1643but trashes match data and is faster for REGEXP that doesn't match often.
1644This uses `verilog-scan' and text properties to ignore comments,
1645so there may be a large up front penalty for the first search."
1646  (let (pt)
1647    (while (and (not pt)
1648		(re-search-forward regexp bound noerror))
1649      (if (verilog-inside-comment-or-string-p)
1650	  (re-search-forward "[/\"\n]" nil t) ;; Only way a comment or quote can end
1651	(setq pt (match-end 0))))
1652    pt))
1653
1654(defsubst verilog-re-search-backward-quick (regexp bound noerror)
1655  ; checkdoc-params: (REGEXP BOUND NOERROR)
1656  "Like `verilog-re-search-backward', including use of REGEXP BOUND and NOERROR,
1657but trashes match data and is faster for REGEXP that doesn't match often.
1658This uses `verilog-scan' and text properties to ignore comments,
1659so there may be a large up front penalty for the first search."
1660  (let (pt)
1661    (while (and (not pt)
1662		(re-search-backward regexp bound noerror))
1663      (if (verilog-inside-comment-or-string-p)
1664	  (re-search-backward "[/\"]" nil t) ;; Only way a comment or quote can begin
1665	(setq pt (match-beginning 0))))
1666    pt))
1667
1668(defsubst verilog-re-search-forward-substr (substr regexp bound noerror)
1669  "Like `re-search-forward', but first search for SUBSTR constant.
1670Then searched for the normal REGEXP (which contains SUBSTR), with given
1671BOUND and NOERROR.  The REGEXP must fit within a single line.
1672This speeds up complicated regexp matches."
1673  ;; Problem with overlap: search-forward BAR then FOOBARBAZ won't match.
1674  ;; thus require matches to be on one line, and use beginning-of-line.
1675  (let (done)
1676    (while (and (not done)
1677		(search-forward substr bound noerror))
1678      (save-excursion
1679	(beginning-of-line)
1680	(setq done (re-search-forward regexp (point-at-eol) noerror)))
1681      (unless (and (<= (match-beginning 0) (point))
1682		   (>= (match-end 0) (point)))
1683	(setq done nil)))
1684    (when done (goto-char done))
1685    done))
1686;;(verilog-re-search-forward-substr "-end" "get-end-of" nil t) ;;-end (test bait)
1687
1688(defsubst verilog-re-search-backward-substr (substr regexp bound noerror)
1689  "Like `re-search-backward', but first search for SUBSTR constant.
1690Then searched for the normal REGEXP (which contains SUBSTR), with given
1691BOUND and NOERROR.  The REGEXP must fit within a single line.
1692This speeds up complicated regexp matches."
1693  ;; Problem with overlap: search-backward BAR then FOOBARBAZ won't match.
1694  ;; thus require matches to be on one line, and use beginning-of-line.
1695  (let (done)
1696    (while (and (not done)
1697		(search-backward substr bound noerror))
1698      (save-excursion
1699	(end-of-line)
1700	(setq done (re-search-backward regexp (point-at-bol) noerror)))
1701      (unless (and (<= (match-beginning 0) (point))
1702		   (>= (match-end 0) (point)))
1703	(setq done nil)))
1704    (when done (goto-char done))
1705    done))
1706;;(verilog-re-search-backward-substr "-end" "get-end-of" nil t) ;;-end (test bait)
1707
1708(defun verilog-delete-trailing-whitespace ()
1709  "Delete trailing spaces or tabs, but not newlines nor linefeeds.
1710Also add missing final newline."
1711  ;; Similar to `delete-trailing-whitespace' but that's not present in XEmacs
1712  (save-excursion
1713    (goto-char (point-min))
1714    (while (re-search-forward "[ \t]+$" nil t)  ;; Not syntactic WS as no formfeed
1715      (replace-match "" nil nil))
1716    (goto-char (point-max))
1717    (unless (bolp) (insert "\n"))))
1718
1719(defvar compile-command)
1720
1721;; compilation program
1722(defun verilog-set-compile-command ()
1723  "Function to compute shell command to compile Verilog.
1724
1725This reads `verilog-tool' and sets `compile-command'.  This specifies the
1726program that executes when you type \\[compile] or
1727\\[verilog-auto-save-compile].
1728
1729By default `verilog-tool' uses a Makefile if one exists in the
1730current directory.  If not, it is set to the `verilog-linter',
1731`verilog-compiler', `verilog-coverage', `verilog-preprocessor',
1732or `verilog-simulator' variables, as selected with the Verilog ->
1733\"Choose Compilation Action\" menu.
1734
1735You should set `verilog-tool' or the other variables to the path and
1736arguments for your Verilog simulator.  For example:
1737    \"vcs -p123 -O\"
1738or a string like:
1739    \"(cd /tmp; surecov %s)\".
1740
1741In the former case, the path to the current buffer is concat'ed to the
1742value of `verilog-tool'; in the later, the path to the current buffer is
1743substituted for the %s.
1744
1745Where __FLAGS__ appears in the string `verilog-current-flags'
1746will be substituted.
1747
1748Where __FILE__ appears in the string, the variable
1749`buffer-file-name' of the current buffer, without the directory
1750portion, will be substituted."
1751  (interactive)
1752  (cond
1753   ((or (file-exists-p "makefile")	;If there is a makefile, use it
1754	(file-exists-p "Makefile"))
1755    (set (make-local-variable 'compile-command) "make "))
1756   (t
1757    (set (make-local-variable 'compile-command)
1758	 (if verilog-tool
1759	     (if (string-match "%s" (eval verilog-tool))
1760		 (format (eval verilog-tool) (or buffer-file-name ""))
1761	       (concat (eval verilog-tool) " " (or buffer-file-name "")))
1762	   ""))))
1763  (verilog-modify-compile-command))
1764
1765(defun verilog-expand-command (command)
1766  "Replace meta-information in COMMAND and return it.
1767Where __FLAGS__ appears in the string `verilog-current-flags'
1768will be substituted.  Where __FILE__ appears in the string, the
1769current buffer's file-name, without the directory portion, will
1770be substituted."
1771  (setq command	(verilog-string-replace-matches
1772		 ;; Note \\b only works if under verilog syntax table
1773		 "\\b__FLAGS__\\b" (verilog-current-flags)
1774		 t t command))
1775  (setq command	(verilog-string-replace-matches
1776		 "\\b__FILE__\\b" (file-name-nondirectory
1777				   (or (buffer-file-name) ""))
1778		 t t command))
1779  command)
1780
1781(defun verilog-modify-compile-command ()
1782  "Update `compile-command' using `verilog-expand-command'."
1783  (when (and
1784	 (stringp compile-command)
1785	 (string-match "\\b\\(__FLAGS__\\|__FILE__\\)\\b" compile-command))
1786    (set (make-local-variable 'compile-command)
1787	 (verilog-expand-command compile-command))))
1788
1789(if (featurep 'xemacs)
1790    ;; Following code only gets called from compilation-mode-hook on XEmacs to add error handling.
1791    (defun verilog-error-regexp-add-xemacs ()
1792      "Teach XEmacs about verilog errors.
1793Called by `compilation-mode-hook'.  This allows \\[next-error] to
1794find the errors."
1795      (interactive)
1796      (if (boundp 'compilation-error-regexp-systems-alist)
1797	  (if (and
1798	       (not (equal compilation-error-regexp-systems-list 'all))
1799	       (not (member compilation-error-regexp-systems-list 'verilog)))
1800	      (push 'verilog compilation-error-regexp-systems-list)))
1801      (if (boundp 'compilation-error-regexp-alist-alist)
1802	  (if (not (assoc 'verilog compilation-error-regexp-alist-alist))
1803	      (setcdr compilation-error-regexp-alist-alist
1804		      (cons verilog-error-regexp-xemacs-alist
1805			    (cdr compilation-error-regexp-alist-alist)))))
1806      (if (boundp 'compilation-font-lock-keywords)
1807	  (progn
1808	    (set (make-local-variable 'compilation-font-lock-keywords)
1809		 verilog-error-font-lock-keywords)
1810	    (font-lock-set-defaults)))
1811      ;; Need to re-run compilation-error-regexp builder
1812      (if (fboundp 'compilation-build-compilation-error-regexp-alist)
1813	  (compilation-build-compilation-error-regexp-alist))
1814      ))
1815
1816;; Following code only gets called from compilation-mode-hook on Emacs to add error handling.
1817(defun verilog-error-regexp-add-emacs ()
1818   "Tell Emacs compile that we are Verilog.
1819Called by `compilation-mode-hook'.  This allows \\[next-error] to
1820find the errors."
1821   (interactive)
1822   (if (boundp 'compilation-error-regexp-alist-alist)
1823       (progn
1824         (if (not (assoc 'verilog-xl-1 compilation-error-regexp-alist-alist))
1825             (mapcar
1826              (lambda (item)
1827                (push (car item) compilation-error-regexp-alist)
1828                (push item compilation-error-regexp-alist-alist)
1829                )
1830              verilog-error-regexp-emacs-alist)))))
1831
1832(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs))
1833(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs))
1834
1835(defconst verilog-directive-re
1836  (eval-when-compile
1837    (verilog-regexp-words
1838     '(
1839   "`case" "`default" "`define" "`else" "`elsif" "`endfor" "`endif"
1840   "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
1841   "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
1842   "`time_scale" "`undef" "`while" ))))
1843
1844(defconst verilog-directive-re-1
1845  (concat "[ \t]*"  verilog-directive-re))
1846
1847(defconst verilog-directive-begin
1848  "\\<`\\(for\\|i\\(f\\|fdef\\|fndef\\)\\|switch\\|while\\)\\>")
1849
1850(defconst verilog-directive-middle
1851  "\\<`\\(else\\|elsif\\|default\\|case\\)\\>")
1852
1853(defconst verilog-directive-end
1854  "`\\(endfor\\|endif\\|endswitch\\|endwhile\\)\\>")
1855
1856(defconst verilog-ovm-begin-re
1857  (eval-when-compile
1858    (verilog-regexp-opt
1859     '(
1860       "`ovm_component_utils_begin"
1861       "`ovm_component_param_utils_begin"
1862       "`ovm_field_utils_begin"
1863       "`ovm_object_utils_begin"
1864       "`ovm_object_param_utils_begin"
1865       "`ovm_sequence_utils_begin"
1866       "`ovm_sequencer_utils_begin"
1867       ) nil )))
1868
1869(defconst verilog-ovm-end-re
1870  (eval-when-compile
1871    (verilog-regexp-opt
1872     '(
1873       "`ovm_component_utils_end"
1874       "`ovm_field_utils_end"
1875       "`ovm_object_utils_end"
1876       "`ovm_sequence_utils_end"
1877       "`ovm_sequencer_utils_end"
1878       ) nil )))
1879
1880(defconst verilog-uvm-begin-re
1881  (eval-when-compile
1882    (verilog-regexp-opt
1883     '(
1884       "`uvm_component_utils_begin"
1885       "`uvm_component_param_utils_begin"
1886       "`uvm_field_utils_begin"
1887       "`uvm_object_utils_begin"
1888       "`uvm_object_param_utils_begin"
1889       "`uvm_sequence_utils_begin"
1890       "`uvm_sequencer_utils_begin"
1891       ) nil )))
1892
1893(defconst verilog-uvm-end-re
1894  (eval-when-compile
1895    (verilog-regexp-opt
1896     '(
1897       "`uvm_component_utils_end"
1898       "`uvm_field_utils_end"
1899       "`uvm_object_utils_end"
1900       "`uvm_sequence_utils_end"
1901       "`uvm_sequencer_utils_end"
1902       ) nil )))
1903
1904(defconst verilog-vmm-begin-re
1905  (eval-when-compile
1906    (verilog-regexp-opt
1907     '(
1908       "`vmm_data_member_begin"
1909       "`vmm_env_member_begin"
1910       "`vmm_scenario_member_begin"
1911       "`vmm_subenv_member_begin"
1912       "`vmm_xactor_member_begin"
1913       ) nil ) ) )
1914
1915(defconst verilog-vmm-end-re
1916  (eval-when-compile
1917    (verilog-regexp-opt
1918     '(
1919       "`vmm_data_member_end"
1920       "`vmm_env_member_end"
1921       "`vmm_scenario_member_end"
1922       "`vmm_subenv_member_end"
1923       "`vmm_xactor_member_end"
1924       ) nil ) ) )
1925
1926(defconst verilog-vmm-statement-re
1927  (eval-when-compile
1928    (verilog-regexp-opt
1929     '(
1930;;       "`vmm_xactor_member_enum_array"
1931       "`vmm_\\(data\\|env\\|scenario\\|subenv\\|xactor\\)_member_\\(scalar\\|string\\|enum\\|vmm_data\\|channel\\|xactor\\|subenv\\|user_defined\\)\\(_array\\)?"
1932;;       "`vmm_xactor_member_scalar_array"
1933;;       "`vmm_xactor_member_scalar"
1934       ) nil )))
1935
1936(defconst verilog-ovm-statement-re
1937  (eval-when-compile
1938    (verilog-regexp-opt
1939     '(
1940       ;; Statements
1941       "`DUT_ERROR"
1942       "`MESSAGE"
1943       "`dut_error"
1944       "`message"
1945       "`ovm_analysis_imp_decl"
1946       "`ovm_blocking_get_imp_decl"
1947       "`ovm_blocking_get_peek_imp_decl"
1948       "`ovm_blocking_master_imp_decl"
1949       "`ovm_blocking_peek_imp_decl"
1950       "`ovm_blocking_put_imp_decl"
1951       "`ovm_blocking_slave_imp_decl"
1952       "`ovm_blocking_transport_imp_decl"
1953       "`ovm_component_registry"
1954       "`ovm_component_registry_param"
1955       "`ovm_component_utils"
1956       "`ovm_create"
1957       "`ovm_create_seq"
1958       "`ovm_declare_sequence_lib"
1959       "`ovm_do"
1960       "`ovm_do_seq"
1961       "`ovm_do_seq_with"
1962       "`ovm_do_with"
1963       "`ovm_error"
1964       "`ovm_fatal"
1965       "`ovm_field_aa_int_byte"
1966       "`ovm_field_aa_int_byte_unsigned"
1967       "`ovm_field_aa_int_int"
1968       "`ovm_field_aa_int_int_unsigned"
1969       "`ovm_field_aa_int_integer"
1970       "`ovm_field_aa_int_integer_unsigned"
1971       "`ovm_field_aa_int_key"
1972       "`ovm_field_aa_int_longint"
1973       "`ovm_field_aa_int_longint_unsigned"
1974       "`ovm_field_aa_int_shortint"
1975       "`ovm_field_aa_int_shortint_unsigned"
1976       "`ovm_field_aa_int_string"
1977       "`ovm_field_aa_object_int"
1978       "`ovm_field_aa_object_string"
1979       "`ovm_field_aa_string_int"
1980       "`ovm_field_aa_string_string"
1981       "`ovm_field_array_int"
1982       "`ovm_field_array_object"
1983       "`ovm_field_array_string"
1984       "`ovm_field_enum"
1985       "`ovm_field_event"
1986       "`ovm_field_int"
1987       "`ovm_field_object"
1988       "`ovm_field_queue_int"
1989       "`ovm_field_queue_object"
1990       "`ovm_field_queue_string"
1991       "`ovm_field_sarray_int"
1992       "`ovm_field_string"
1993       "`ovm_field_utils"
1994       "`ovm_file"
1995       "`ovm_get_imp_decl"
1996       "`ovm_get_peek_imp_decl"
1997       "`ovm_info"
1998       "`ovm_info1"
1999       "`ovm_info2"
2000       "`ovm_info3"
2001       "`ovm_info4"
2002       "`ovm_line"
2003       "`ovm_master_imp_decl"
2004       "`ovm_msg_detail"
2005       "`ovm_non_blocking_transport_imp_decl"
2006       "`ovm_nonblocking_get_imp_decl"
2007       "`ovm_nonblocking_get_peek_imp_decl"
2008       "`ovm_nonblocking_master_imp_decl"
2009       "`ovm_nonblocking_peek_imp_decl"
2010       "`ovm_nonblocking_put_imp_decl"
2011       "`ovm_nonblocking_slave_imp_decl"
2012       "`ovm_object_registry"
2013       "`ovm_object_registry_param"
2014       "`ovm_object_utils"
2015       "`ovm_peek_imp_decl"
2016       "`ovm_phase_func_decl"
2017       "`ovm_phase_task_decl"
2018       "`ovm_print_aa_int_object"
2019       "`ovm_print_aa_string_int"
2020       "`ovm_print_aa_string_object"
2021       "`ovm_print_aa_string_string"
2022       "`ovm_print_array_int"
2023       "`ovm_print_array_object"
2024       "`ovm_print_array_string"
2025       "`ovm_print_object_queue"
2026       "`ovm_print_queue_int"
2027       "`ovm_print_string_queue"
2028       "`ovm_put_imp_decl"
2029       "`ovm_rand_send"
2030       "`ovm_rand_send_with"
2031       "`ovm_send"
2032       "`ovm_sequence_utils"
2033       "`ovm_slave_imp_decl"
2034       "`ovm_transport_imp_decl"
2035       "`ovm_update_sequence_lib"
2036       "`ovm_update_sequence_lib_and_item"
2037       "`ovm_warning"
2038       "`static_dut_error"
2039       "`static_message") nil )))
2040
2041(defconst verilog-uvm-statement-re
2042  (eval-when-compile
2043    (verilog-regexp-opt
2044     '(
2045       ;; Statements
2046       "`uvm_analysis_imp_decl"
2047       "`uvm_blocking_get_imp_decl"
2048       "`uvm_blocking_get_peek_imp_decl"
2049       "`uvm_blocking_master_imp_decl"
2050       "`uvm_blocking_peek_imp_decl"
2051       "`uvm_blocking_put_imp_decl"
2052       "`uvm_blocking_slave_imp_decl"
2053       "`uvm_blocking_transport_imp_decl"
2054       "`uvm_component_param_utils"
2055       "`uvm_component_registry"
2056       "`uvm_component_registry_param"
2057       "`uvm_component_utils"
2058       "`uvm_create"
2059       "`uvm_create_on"
2060       "`uvm_create_seq"		;; Undocumented in 1.1
2061       "`uvm_declare_p_sequencer"
2062       "`uvm_declare_sequence_lib"	;; Deprecated in 1.1
2063       "`uvm_do"
2064       "`uvm_do_callbacks"
2065       "`uvm_do_callbacks_exit_on"
2066       "`uvm_do_obj_callbacks"
2067       "`uvm_do_obj_callbacks_exit_on"
2068       "`uvm_do_on"
2069       "`uvm_do_on_pri"
2070       "`uvm_do_on_pri_with"
2071       "`uvm_do_on_with"
2072       "`uvm_do_pri"
2073       "`uvm_do_pri_with"
2074       "`uvm_do_seq"			;; Undocumented in 1.1
2075       "`uvm_do_seq_with"		;; Undocumented in 1.1
2076       "`uvm_do_with"
2077       "`uvm_error"
2078       "`uvm_error_context"
2079       "`uvm_fatal"
2080       "`uvm_fatal_context"
2081       "`uvm_field_aa_int_byte"
2082       "`uvm_field_aa_int_byte_unsigned"
2083       "`uvm_field_aa_int_enum"
2084       "`uvm_field_aa_int_int"
2085       "`uvm_field_aa_int_int_unsigned"
2086       "`uvm_field_aa_int_integer"
2087       "`uvm_field_aa_int_integer_unsigned"
2088       "`uvm_field_aa_int_key"
2089       "`uvm_field_aa_int_longint"
2090       "`uvm_field_aa_int_longint_unsigned"
2091       "`uvm_field_aa_int_shortint"
2092       "`uvm_field_aa_int_shortint_unsigned"
2093       "`uvm_field_aa_int_string"
2094       "`uvm_field_aa_object_int"
2095       "`uvm_field_aa_object_string"
2096       "`uvm_field_aa_string_int"
2097       "`uvm_field_aa_string_string"
2098       "`uvm_field_array_enum"
2099       "`uvm_field_array_int"
2100       "`uvm_field_array_object"
2101       "`uvm_field_array_string"
2102       "`uvm_field_enum"
2103       "`uvm_field_event"
2104       "`uvm_field_int"
2105       "`uvm_field_object"
2106       "`uvm_field_queue_enum"
2107       "`uvm_field_queue_int"
2108       "`uvm_field_queue_object"
2109       "`uvm_field_queue_string"
2110       "`uvm_field_real"
2111       "`uvm_field_sarray_enum"
2112       "`uvm_field_sarray_int"
2113       "`uvm_field_sarray_object"
2114       "`uvm_field_sarray_string"
2115       "`uvm_field_string"
2116       "`uvm_field_utils"
2117       "`uvm_file"		;; Undocumented in 1.1, use `__FILE__
2118       "`uvm_get_imp_decl"
2119       "`uvm_get_peek_imp_decl"
2120       "`uvm_info"
2121       "`uvm_info_context"
2122       "`uvm_line"		;; Undocumented in 1.1, use `__LINE__
2123       "`uvm_master_imp_decl"
2124       "`uvm_non_blocking_transport_imp_decl"	;; Deprecated in 1.1
2125       "`uvm_nonblocking_get_imp_decl"
2126       "`uvm_nonblocking_get_peek_imp_decl"
2127       "`uvm_nonblocking_master_imp_decl"
2128       "`uvm_nonblocking_peek_imp_decl"
2129       "`uvm_nonblocking_put_imp_decl"
2130       "`uvm_nonblocking_slave_imp_decl"
2131       "`uvm_nonblocking_transport_imp_decl"
2132       "`uvm_object_param_utils"
2133       "`uvm_object_registry"
2134       "`uvm_object_registry_param"	;; Undocumented in 1.1
2135       "`uvm_object_utils"
2136       "`uvm_pack_array"
2137       "`uvm_pack_arrayN"
2138       "`uvm_pack_enum"
2139       "`uvm_pack_enumN"
2140       "`uvm_pack_int"
2141       "`uvm_pack_intN"
2142       "`uvm_pack_queue"
2143       "`uvm_pack_queueN"
2144       "`uvm_pack_real"
2145       "`uvm_pack_sarray"
2146       "`uvm_pack_sarrayN"
2147       "`uvm_pack_string"
2148       "`uvm_peek_imp_decl"
2149       "`uvm_put_imp_decl"
2150       "`uvm_rand_send"
2151       "`uvm_rand_send_pri"
2152       "`uvm_rand_send_pri_with"
2153       "`uvm_rand_send_with"
2154       "`uvm_record_attribute"
2155       "`uvm_record_field"
2156       "`uvm_register_cb"
2157       "`uvm_send"
2158       "`uvm_send_pri"
2159       "`uvm_sequence_utils"		;; Deprecated in 1.1
2160       "`uvm_set_super_type"
2161       "`uvm_slave_imp_decl"
2162       "`uvm_transport_imp_decl"
2163       "`uvm_unpack_array"
2164       "`uvm_unpack_arrayN"
2165       "`uvm_unpack_enum"
2166       "`uvm_unpack_enumN"
2167       "`uvm_unpack_int"
2168       "`uvm_unpack_intN"
2169       "`uvm_unpack_queue"
2170       "`uvm_unpack_queueN"
2171       "`uvm_unpack_real"
2172       "`uvm_unpack_sarray"
2173       "`uvm_unpack_sarrayN"
2174       "`uvm_unpack_string"
2175       "`uvm_update_sequence_lib"		;; Deprecated in 1.1
2176       "`uvm_update_sequence_lib_and_item"	;; Deprecated in 1.1
2177       "`uvm_warning"
2178       "`uvm_warning_context") nil )))
2179
2180
2181;;
2182;; Regular expressions used to calculate indent, etc.
2183;;
2184(defconst verilog-symbol-re      "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>")
2185;; Want to match
2186;; aa :
2187;; aa,bb :
2188;; a[34:32] :
2189;; a,
2190;;   b :
2191(defconst verilog-assignment-operator-re
2192  (eval-when-compile
2193     (verilog-regexp-opt
2194      `(
2195	;; blocking assignment_operator
2196	"=" "+=" "-=" "*=" "/=" "%=" "&=" "|=" "^=" "<<=" ">>=" "<<<=" ">>>="
2197	;; non blocking assignment operator
2198	"<="
2199	;; comparison
2200	"==" "!=" "===" "!===" "<=" ">=" "==\?" "!=\?"
2201	;; event_trigger
2202	"->" "->>"
2203	;; property_expr
2204	"|->" "|=>"
2205	;; Is this a legal verilog operator?
2206	":="
2207	) 't
2208      )))
2209(defconst verilog-assignment-operation-re
2210  (concat
2211;     "\\(^\\s-*[A-Za-z0-9_]+\\(\\[\\([A-Za-z0-9_]+\\)\\]\\)*\\s-*\\)"
2212;     "\\(^\\s-*[^=<>+-*/%&|^:\\s-]+[^=<>+-*/%&|^\n]*?\\)"
2213     "\\(^.*?\\)" "\\B" verilog-assignment-operator-re "\\B" ))
2214
2215(defconst verilog-label-re (concat verilog-symbol-re "\\s-*:\\s-*"))
2216(defconst verilog-property-re
2217  (concat "\\(" verilog-label-re "\\)?"
2218	  "\\(\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(assert\\)"))
2219	  ;;  "\\(assert\\|assume\\|cover\\)\\s-+property\\>"
2220
2221(defconst verilog-no-indent-begin-re
2222  "\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\|always_comb\\|always_ff\\|always_latch\\)\\>")
2223
2224(defconst verilog-ends-re
2225  ;; Parenthesis indicate type of keyword found
2226  (concat
2227   "\\(\\<else\\>\\)\\|"		; 1
2228   "\\(\\<if\\>\\)\\|"			; 2
2229   "\\(\\<assert\\>\\)\\|"              ; 3
2230   "\\(\\<end\\>\\)\\|"			; 3.1
2231   "\\(\\<endcase\\>\\)\\|"		; 4
2232   "\\(\\<endfunction\\>\\)\\|"		; 5
2233   "\\(\\<endtask\\>\\)\\|"		; 6
2234   "\\(\\<endspecify\\>\\)\\|"		; 7
2235   "\\(\\<endtable\\>\\)\\|"		; 8
2236   "\\(\\<endgenerate\\>\\)\\|"         ; 9
2237   "\\(\\<join\\(_any\\|_none\\)?\\>\\)\\|" ; 10
2238   "\\(\\<endclass\\>\\)\\|"            ; 11
2239   "\\(\\<endgroup\\>\\)\\|"            ; 12
2240   ;; VMM
2241   "\\(\\<`vmm_data_member_end\\>\\)\\|"
2242   "\\(\\<`vmm_env_member_end\\>\\)\\|"
2243   "\\(\\<`vmm_scenario_member_end\\>\\)\\|"
2244   "\\(\\<`vmm_subenv_member_end\\>\\)\\|"
2245   "\\(\\<`vmm_xactor_member_end\\>\\)\\|"
2246   ;; OVM
2247   "\\(\\<`ovm_component_utils_end\\>\\)\\|"
2248   "\\(\\<`ovm_field_utils_end\\>\\)\\|"
2249   "\\(\\<`ovm_object_utils_end\\>\\)\\|"
2250   "\\(\\<`ovm_sequence_utils_end\\>\\)\\|"
2251   "\\(\\<`ovm_sequencer_utils_end\\>\\)"
2252   ;; UVM
2253   "\\(\\<`uvm_component_utils_end\\>\\)\\|"
2254   "\\(\\<`uvm_field_utils_end\\>\\)\\|"
2255   "\\(\\<`uvm_object_utils_end\\>\\)\\|"
2256   "\\(\\<`uvm_sequence_utils_end\\>\\)\\|"
2257   "\\(\\<`uvm_sequencer_utils_end\\>\\)"
2258   ))
2259
2260(defconst verilog-auto-end-comment-lines-re
2261  ;; Matches to names in this list cause auto-end-commenting
2262  (concat "\\("
2263	  verilog-directive-re "\\)\\|\\("
2264	  (eval-when-compile
2265	    (verilog-regexp-words
2266	     `( "begin"
2267		"else"
2268		"end"
2269		"endcase"
2270		"endclass"
2271		"endclocking"
2272		"endgroup"
2273		"endfunction"
2274		"endmodule"
2275		"endprogram"
2276		"endprimitive"
2277		"endinterface"
2278		"endpackage"
2279		"endsequence"
2280		"endspecify"
2281		"endtable"
2282		"endtask"
2283		"join"
2284		"join_any"
2285		"join_none"
2286		"module"
2287		"macromodule"
2288		"primitive"
2289		"interface"
2290		"package")))
2291	  "\\)"))
2292
2293;;; NOTE: verilog-leap-to-head expects that verilog-end-block-re and
2294;;; verilog-end-block-ordered-re matches exactly the same strings.
2295(defconst verilog-end-block-ordered-re
2296  ;; Parenthesis indicate type of keyword found
2297  (concat "\\(\\<endcase\\>\\)\\|" ; 1
2298	  "\\(\\<end\\>\\)\\|"     ; 2
2299	  "\\(\\<end"              ; 3, but not used
2300	  "\\("                    ; 4, but not used
2301	  "\\(function\\)\\|"      ; 5
2302	  "\\(task\\)\\|"          ; 6
2303	  "\\(module\\)\\|"        ; 7
2304	  "\\(primitive\\)\\|"     ; 8
2305	  "\\(interface\\)\\|"     ; 9
2306	  "\\(package\\)\\|"       ; 10
2307	  "\\(class\\)\\|"         ; 11
2308          "\\(group\\)\\|"         ; 12
2309          "\\(program\\)\\|"	   ; 13
2310          "\\(sequence\\)\\|"	   ; 14
2311	  "\\(clocking\\)\\|"      ; 15
2312	  "\\)\\>\\)"))
2313(defconst verilog-end-block-re
2314  (eval-when-compile
2315    (verilog-regexp-words
2316
2317     `("end"  ;; closes begin
2318       "endcase" ;; closes any of case, casex casez or randcase
2319       "join" "join_any" "join_none" ;; closes fork
2320       "endclass"
2321       "endtable"
2322       "endspecify"
2323       "endfunction"
2324       "endgenerate"
2325       "endtask"
2326       "endgroup"
2327       "endproperty"
2328       "endinterface"
2329       "endpackage"
2330       "endprogram"
2331       "endsequence"
2332       "endclocking"
2333       ;; OVM
2334       "`ovm_component_utils_end"
2335       "`ovm_field_utils_end"
2336       "`ovm_object_utils_end"
2337       "`ovm_sequence_utils_end"
2338       "`ovm_sequencer_utils_end"
2339       ;; UVM
2340       "`uvm_component_utils_end"
2341       "`uvm_field_utils_end"
2342       "`uvm_object_utils_end"
2343       "`uvm_sequence_utils_end"
2344       "`uvm_sequencer_utils_end"
2345       ;; VMM
2346       "`vmm_data_member_end"
2347       "`vmm_env_member_end"
2348       "`vmm_scenario_member_end"
2349       "`vmm_subenv_member_end"
2350       "`vmm_xactor_member_end"
2351       ))))
2352
2353
2354(defconst verilog-endcomment-reason-re
2355  ;; Parenthesis indicate type of keyword found
2356  (concat
2357   "\\(\\<begin\\>\\)\\|"		         ; 1
2358   "\\(\\<else\\>\\)\\|"		         ; 2
2359   "\\(\\<end\\>\\s-+\\<else\\>\\)\\|"	         ; 3
2360   "\\(\\<always_comb\\>\\(\[ \t\]*@\\)?\\)\\|"  ; 4
2361   "\\(\\<always_ff\\>\\(\[ \t\]*@\\)?\\)\\|"    ; 5
2362   "\\(\\<always_latch\\>\\(\[ \t\]*@\\)?\\)\\|" ; 6
2363   "\\(\\<fork\\>\\)\\|"			 ; 7
2364   "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
2365   "\\(\\<if\\>\\)\\|"
2366   verilog-property-re "\\|"
2367   "\\(\\(" verilog-label-re "\\)?\\<assert\\>\\)\\|"
2368   "\\(\\<clocking\\>\\)\\|"
2369   "\\(\\<task\\>\\)\\|"
2370   "\\(\\<function\\>\\)\\|"
2371   "\\(\\<initial\\>\\)\\|"
2372   "\\(\\<interface\\>\\)\\|"
2373   "\\(\\<package\\>\\)\\|"
2374   "\\(\\<final\\>\\)\\|"
2375   "\\(@\\)\\|"
2376   "\\(\\<while\\>\\)\\|"
2377   "\\(\\<for\\(ever\\|each\\)?\\>\\)\\|"
2378   "\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|"
2379   "#"))
2380
2381(defconst verilog-named-block-re  "begin[ \t]*:")
2382
2383;; These words begin a block which can occur inside a module which should be indented,
2384;; and closed with the respective word from the end-block list
2385
2386(defconst verilog-beg-block-re
2387  (eval-when-compile
2388    (verilog-regexp-words
2389     `("begin"
2390       "case" "casex" "casez" "randcase"
2391       "clocking"
2392       "generate"
2393       "fork"
2394       "function"
2395       "property"
2396       "specify"
2397       "table"
2398       "task"
2399       ;; OVM
2400       "`ovm_component_utils_begin"
2401       "`ovm_component_param_utils_begin"
2402       "`ovm_field_utils_begin"
2403       "`ovm_object_utils_begin"
2404       "`ovm_object_param_utils_begin"
2405       "`ovm_sequence_utils_begin"
2406       "`ovm_sequencer_utils_begin"
2407       ;; UVM
2408       "`uvm_component_utils_begin"
2409       "`uvm_component_param_utils_begin"
2410       "`uvm_field_utils_begin"
2411       "`uvm_object_utils_begin"
2412       "`uvm_object_param_utils_begin"
2413       "`uvm_sequence_utils_begin"
2414       "`uvm_sequencer_utils_begin"
2415       ;; VMM
2416       "`vmm_data_member_begin"
2417       "`vmm_env_member_begin"
2418       "`vmm_scenario_member_begin"
2419       "`vmm_subenv_member_begin"
2420       "`vmm_xactor_member_begin"
2421       ))))
2422;; These are the same words, in a specific order in the regular
2423;; expression so that matching will work nicely for
2424;; verilog-forward-sexp and verilog-calc-indent
2425(defconst verilog-beg-block-re-ordered
2426  ( concat "\\(\\<begin\\>\\)"		;1
2427	   "\\|\\(\\<randcase\\>\\|\\(\\<unique\\s-+\\|priority\\s-+\\)?case[xz]?\\>\\)" ; 2,3
2428	   "\\|\\(\\(\\<disable\\>\\s-+\\|\\<wait\\>\\s-+\\)?fork\\>\\)" ;4,5
2429	   "\\|\\(\\<class\\>\\)"		;6
2430	   "\\|\\(\\<table\\>\\)"		;7
2431	   "\\|\\(\\<specify\\>\\)"		;8
2432	   "\\|\\(\\<function\\>\\)"		;9
2433	   "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<function\\>\\)"	;10
2434	   "\\|\\(\\<task\\>\\)"		;14
2435	   "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<task\\>\\)"	;15
2436	   "\\|\\(\\<generate\\>\\)"		;18
2437	   "\\|\\(\\<covergroup\\>\\)"	;16 20
2438	   "\\|\\(\\(\\(\\<cover\\>\\s-+\\)\\|\\(\\<assert\\>\\s-+\\)\\)*\\<property\\>\\)"	;17 21
2439	   "\\|\\(\\<\\(rand\\)?sequence\\>\\)" ;21 25
2440	   "\\|\\(\\<clocking\\>\\)"          ;22 27
2441	   "\\|\\(\\<`[ou]vm_[a-z_]+_begin\\>\\)" ;28
2442           "\\|\\(\\<`vmm_[a-z_]+_member_begin\\>\\)"
2443	   ;;
2444	   ))
2445
2446(defconst verilog-end-block-ordered-rry
2447  [ "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)"
2448    "\\(\\<randcase\\>\\|\\<case[xz]?\\>\\)\\|\\(\\<endcase\\>\\)"
2449    "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)"
2450    "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)"
2451    "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)"
2452    "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)"
2453    "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)"
2454    "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)"
2455    "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)"
2456    "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)"
2457    "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)"
2458    "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)"
2459    "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)"
2460    ] )
2461
2462(defconst verilog-nameable-item-re
2463  (eval-when-compile
2464    (verilog-regexp-words
2465     `("begin"
2466       "fork"
2467       "join" "join_any" "join_none"
2468       "end"
2469       "endcase"
2470       "endconfig"
2471       "endclass"
2472       "endclocking"
2473       "endfunction"
2474       "endgenerate"
2475       "endmodule"
2476       "endprimitive"
2477       "endinterface"
2478       "endpackage"
2479       "endspecify"
2480       "endtable"
2481       "endtask" )
2482     )))
2483
2484(defconst verilog-declaration-opener
2485  (eval-when-compile
2486    (verilog-regexp-words
2487     `("module" "begin" "task" "function"))))
2488
2489(defconst verilog-declaration-prefix-re
2490  (eval-when-compile
2491    (verilog-regexp-words
2492     `(
2493       ;; port direction
2494       "inout" "input" "output" "ref"
2495       ;; changeableness
2496       "const" "static" "protected" "local"
2497       ;; parameters
2498       "localparam" "parameter" "var"
2499       ;; type creation
2500       "typedef"
2501       ))))
2502(defconst verilog-declaration-core-re
2503  (eval-when-compile
2504    (verilog-regexp-words
2505     `(
2506       ;; port direction (by themselves)
2507       "inout" "input" "output"
2508       ;; integer_atom_type
2509       "byte" "shortint" "int" "longint" "integer" "time"
2510       ;; integer_vector_type
2511       "bit" "logic" "reg"
2512       ;; non_integer_type
2513       "shortreal" "real" "realtime"
2514       ;; net_type
2515       "supply0" "supply1" "tri" "triand" "trior" "trireg" "tri0" "tri1" "uwire" "wire" "wand" "wor"
2516       ;; misc
2517       "string" "event" "chandle" "virtual" "enum" "genvar"
2518       "struct" "union"
2519       ;; builtin classes
2520       "mailbox" "semaphore"
2521       ))))
2522(defconst verilog-declaration-re
2523  (concat "\\(" verilog-declaration-prefix-re "\\s-*\\)?" verilog-declaration-core-re))
2524(defconst verilog-range-re "\\(\\[[^]]*\\]\\s-*\\)+")
2525(defconst verilog-optional-signed-re "\\s-*\\(signed\\)?")
2526(defconst verilog-optional-signed-range-re
2527  (concat
2528   "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?"))
2529(defconst verilog-macroexp-re "`\\sw+")
2530
2531(defconst verilog-delay-re "#\\s-*\\(\\([0-9_]+\\('s?[hdxbo][0-9a-fA-F_xz]+\\)?\\)\\|\\(([^()]*)\\)\\|\\(\\sw+\\)\\)")
2532(defconst verilog-declaration-re-2-no-macro
2533  (concat "\\s-*" verilog-declaration-re
2534	  "\\s-*\\(\\(" verilog-optional-signed-range-re "\\)\\|\\(" verilog-delay-re "\\)"
2535	  "\\)?"))
2536(defconst verilog-declaration-re-2-macro
2537  (concat "\\s-*" verilog-declaration-re
2538	  "\\s-*\\(\\(" verilog-optional-signed-range-re "\\)\\|\\(" verilog-delay-re "\\)"
2539	  "\\|\\(" verilog-macroexp-re "\\)"
2540	  "\\)?"))
2541(defconst verilog-declaration-re-1-macro
2542  (concat "^" verilog-declaration-re-2-macro))
2543
2544(defconst verilog-declaration-re-1-no-macro (concat "^" verilog-declaration-re-2-no-macro))
2545
2546(defconst verilog-defun-re
2547  (eval-when-compile (verilog-regexp-words `("macromodule" "module" "class" "program" "interface" "package" "primitive" "config"))))
2548(defconst verilog-end-defun-re
2549  (eval-when-compile (verilog-regexp-words `("endmodule" "endclass" "endprogram" "endinterface" "endpackage" "endprimitive" "endconfig"))))
2550(defconst verilog-zero-indent-re
2551  (concat verilog-defun-re "\\|" verilog-end-defun-re))
2552(defconst verilog-inst-comment-re
2553  (eval-when-compile (verilog-regexp-words `("Outputs" "Inouts" "Inputs" "Interfaces" "Interfaced"))))
2554
2555(defconst verilog-behavioral-block-beg-re
2556  (eval-when-compile (verilog-regexp-words `("initial" "final" "always" "always_comb" "always_latch" "always_ff"
2557					     "function" "task"))))
2558(defconst verilog-coverpoint-re "\\w+\\s*:\\s*\\(coverpoint\\|cross\\constraint\\)"  )
2559(defconst verilog-indent-re
2560  (eval-when-compile
2561    (verilog-regexp-words
2562     `(
2563       "{"
2564       "always" "always_latch" "always_ff" "always_comb"
2565       "begin" "end"
2566;       "unique" "priority"
2567       "case" "casex" "casez" "randcase" "endcase"
2568       "class" "endclass"
2569       "clocking" "endclocking"
2570       "config" "endconfig"
2571       "covergroup" "endgroup"
2572       "fork" "join" "join_any" "join_none"
2573       "function" "endfunction"
2574       "final"
2575       "generate" "endgenerate"
2576       "initial"
2577       "interface" "endinterface"
2578       "module" "macromodule" "endmodule"
2579       "package" "endpackage"
2580       "primitive" "endprimitive"
2581       "program" "endprogram"
2582       "property" "endproperty"
2583       "sequence" "randsequence" "endsequence"
2584       "specify" "endspecify"
2585       "table" "endtable"
2586       "task" "endtask"
2587       "virtual"
2588       "`case"
2589       "`default"
2590       "`define" "`undef"
2591       "`if" "`ifdef" "`ifndef" "`else" "`elsif" "`endif"
2592       "`while" "`endwhile"
2593       "`for" "`endfor"
2594       "`format"
2595       "`include"
2596       "`let"
2597       "`protect" "`endprotect"
2598       "`switch" "`endswitch"
2599       "`timescale"
2600       "`time_scale"
2601       ;; OVM Begin tokens
2602       "`ovm_component_utils_begin"
2603       "`ovm_component_param_utils_begin"
2604       "`ovm_field_utils_begin"
2605       "`ovm_object_utils_begin"
2606       "`ovm_object_param_utils_begin"
2607       "`ovm_sequence_utils_begin"
2608       "`ovm_sequencer_utils_begin"
2609       ;; OVM End tokens
2610       "`ovm_component_utils_end"
2611       "`ovm_field_utils_end"
2612       "`ovm_object_utils_end"
2613       "`ovm_sequence_utils_end"
2614       "`ovm_sequencer_utils_end"
2615       ;; UVM Begin tokens
2616       "`uvm_component_utils_begin"
2617       "`uvm_component_param_utils_begin"
2618       "`uvm_field_utils_begin"
2619       "`uvm_object_utils_begin"
2620       "`uvm_object_param_utils_begin"
2621       "`uvm_sequence_utils_begin"
2622       "`uvm_sequencer_utils_begin"
2623       ;; UVM End tokens
2624       "`uvm_component_utils_end"	;; Typo in spec, it's not uvm_component_end
2625       "`uvm_field_utils_end"
2626       "`uvm_object_utils_end"
2627       "`uvm_sequence_utils_end"
2628       "`uvm_sequencer_utils_end"
2629       ;; VMM Begin tokens
2630       "`vmm_data_member_begin"
2631       "`vmm_env_member_begin"
2632       "`vmm_scenario_member_begin"
2633       "`vmm_subenv_member_begin"
2634       "`vmm_xactor_member_begin"
2635       ;; VMM End tokens
2636       "`vmm_data_member_end"
2637       "`vmm_env_member_end"
2638       "`vmm_scenario_member_end"
2639       "`vmm_subenv_member_end"
2640       "`vmm_xactor_member_end"
2641       ))))
2642
2643(defconst verilog-defun-level-not-generate-re
2644  (eval-when-compile
2645    (verilog-regexp-words
2646     `( "module" "macromodule" "primitive" "class" "program"
2647	"interface" "package" "config"))))
2648
2649(defconst verilog-defun-level-re
2650  (eval-when-compile
2651    (verilog-regexp-words
2652     (append
2653      `( "module" "macromodule" "primitive" "class" "program"
2654	 "interface" "package" "config")
2655      `( "initial" "final" "always" "always_comb" "always_ff"
2656	 "always_latch" "endtask" "endfunction" )))))
2657
2658(defconst verilog-defun-level-generate-only-re
2659  (eval-when-compile
2660    (verilog-regexp-words
2661     `( "initial" "final" "always" "always_comb" "always_ff"
2662	"always_latch" "endtask" "endfunction" ))))
2663
2664(defconst verilog-cpp-level-re
2665  (eval-when-compile
2666    (verilog-regexp-words
2667     `(
2668       "endmodule" "endprimitive" "endinterface" "endpackage" "endprogram" "endclass"
2669       ))))
2670(defconst verilog-disable-fork-re "\\(disable\\|wait\\)\\s-+fork\\>")
2671(defconst verilog-extended-case-re "\\(\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?\\)")
2672(defconst verilog-extended-complete-re
2673  (concat "\\(\\(\\<extern\\s-+\\|\\<\\(\\<pure\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)\\)"
2674	  "\\|\\(\\(\\<typedef\\>\\s-+\\)*\\(\\<struct\\>\\|\\<union\\>\\|\\<class\\>\\)\\)"
2675	  "\\|\\(\\(\\<import\\>\\s-+\\)?\\(\"DPI-C\"\\s-+\\)?\\(\\<pure\\>\\s-+\\)?\\(function\\>\\|task\\>\\)\\)"
2676	  "\\|" verilog-extended-case-re ))
2677(defconst verilog-basic-complete-re
2678  (eval-when-compile
2679    (verilog-regexp-words
2680     `(
2681       "always" "assign" "always_latch" "always_ff" "always_comb" "constraint"
2682       "import" "initial" "final" "module" "macromodule" "repeat" "randcase" "while"
2683       "if" "for" "forever" "foreach" "else" "parameter" "do" "localparam" "assert"
2684       ))))
2685(defconst verilog-complete-reg
2686  (concat
2687   verilog-extended-complete-re "\\|\\(" verilog-basic-complete-re "\\)"))
2688
2689(defconst verilog-end-statement-re
2690  (concat "\\(" verilog-beg-block-re "\\)\\|\\("
2691	  verilog-end-block-re "\\)"))
2692
2693(defconst verilog-endcase-re
2694  (concat verilog-extended-case-re "\\|"
2695	  "\\(endcase\\)\\|"
2696	  verilog-defun-re
2697	  ))
2698
2699(defconst verilog-exclude-str-start "/* -----\\/----- EXCLUDED -----\\/-----"
2700  "String used to mark beginning of excluded text.")
2701(defconst verilog-exclude-str-end " -----/\\----- EXCLUDED -----/\\----- */"
2702  "String used to mark end of excluded text.")
2703(defconst verilog-preprocessor-re
2704  (eval-when-compile
2705    (verilog-regexp-words
2706     `(
2707       "`define" "`include" "`ifdef" "`ifndef" "`if" "`endif" "`else"
2708       ))))
2709
2710(defconst verilog-keywords
2711  '( "`case" "`default" "`define" "`else" "`endfor" "`endif"
2712     "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
2713     "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
2714     "`time_scale" "`undef" "`while"
2715
2716     "after" "alias" "always" "always_comb" "always_ff" "always_latch" "and"
2717     "assert" "assign" "assume" "automatic" "before" "begin" "bind"
2718     "bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte"
2719     "case" "casex" "casez" "cell" "chandle" "class" "clocking" "cmos"
2720     "config" "const" "constraint" "context" "continue" "cover"
2721     "covergroup" "coverpoint" "cross" "deassign" "default" "defparam"
2722     "design" "disable" "dist" "do" "edge" "else" "end" "endcase"
2723     "endclass" "endclocking" "endconfig" "endfunction" "endgenerate"
2724     "endgroup" "endinterface" "endmodule" "endpackage" "endprimitive"
2725     "endprogram" "endproperty" "endspecify" "endsequence" "endtable"
2726     "endtask" "enum" "event" "expect" "export" "extends" "extern"
2727     "final" "first_match" "for" "force" "foreach" "forever" "fork"
2728     "forkjoin" "function" "generate" "genvar" "highz0" "highz1" "if"
2729     "iff" "ifnone" "ignore_bins" "illegal_bins" "import" "incdir"
2730     "include" "initial" "inout" "input" "inside" "instance" "int"
2731     "integer" "interface" "intersect" "join" "join_any" "join_none"
2732     "large" "liblist" "library" "local" "localparam" "logic"
2733     "longint" "macromodule" "mailbox" "matches" "medium" "modport" "module"
2734     "nand" "negedge" "new" "nmos" "nor" "noshowcancelled" "not"
2735     "notif0" "notif1" "null" "or" "output" "package" "packed"
2736     "parameter" "pmos" "posedge" "primitive" "priority" "program"
2737     "property" "protected" "pull0" "pull1" "pulldown" "pullup"
2738     "pulsestyle_onevent" "pulsestyle_ondetect" "pure" "rand" "randc"
2739     "randcase" "randsequence" "rcmos" "real" "realtime" "ref" "reg"
2740     "release" "repeat" "return" "rnmos" "rpmos" "rtran" "rtranif0"
2741     "rtranif1" "scalared" "semaphore" "sequence" "shortint" "shortreal"
2742     "showcancelled" "signed" "small" "solve" "specify" "specparam"
2743     "static" "string" "strong0" "strong1" "struct" "super" "supply0"
2744     "supply1" "table" "tagged" "task" "this" "throughout" "time"
2745     "timeprecision" "timeunit" "tran" "tranif0" "tranif1" "tri"
2746     "tri0" "tri1" "triand" "trior" "trireg" "type" "typedef" "union"
2747     "unique" "unsigned" "use" "uwire" "var" "vectored" "virtual" "void"
2748     "wait" "wait_order" "wand" "weak0" "weak1" "while" "wildcard"
2749     "wire" "with" "within" "wor" "xnor" "xor"
2750     ;; 1800-2009
2751     "accept_on" "checker" "endchecker" "eventually" "global" "implies"
2752     "let" "nexttime" "reject_on" "restrict" "s_always" "s_eventually"
2753     "s_nexttime" "s_until" "s_until_with" "strong" "sync_accept_on"
2754     "sync_reject_on" "unique0" "until" "until_with" "untyped" "weak"
2755 )
2756 "List of Verilog keywords.")
2757
2758(defconst verilog-comment-start-regexp "//\\|/\\*"
2759  "Dual comment value for `comment-start-regexp'.")
2760
2761(defvar verilog-mode-syntax-table
2762  (let ((table (make-syntax-table)))
2763    ;; Populate the syntax TABLE.
2764    (modify-syntax-entry ?\\ "\\" table)
2765    (modify-syntax-entry ?+ "." table)
2766    (modify-syntax-entry ?- "." table)
2767    (modify-syntax-entry ?= "." table)
2768    (modify-syntax-entry ?% "." table)
2769    (modify-syntax-entry ?< "." table)
2770    (modify-syntax-entry ?> "." table)
2771    (modify-syntax-entry ?& "." table)
2772    (modify-syntax-entry ?| "." table)
2773    (modify-syntax-entry ?` "w" table)
2774    (modify-syntax-entry ?_ "w" table)
2775    (modify-syntax-entry ?\' "." table)
2776
2777    ;; Set up TABLE to handle block and line style comments.
2778    (if (featurep 'xemacs)
2779	(progn
2780	  ;; XEmacs (formerly Lucid) has the best implementation
2781	  (modify-syntax-entry ?/  ". 1456" table)
2782	  (modify-syntax-entry ?*  ". 23"   table)
2783	  (modify-syntax-entry ?\n "> b"    table))
2784      ;; Emacs does things differently, but we can work with it
2785      (modify-syntax-entry ?/  ". 124b" table)
2786      (modify-syntax-entry ?*  ". 23"   table)
2787      (modify-syntax-entry ?\n "> b"    table))
2788    table)
2789  "Syntax table used in Verilog mode buffers.")
2790
2791(defvar verilog-font-lock-keywords nil
2792  "Default highlighting for Verilog mode.")
2793
2794(defvar verilog-font-lock-keywords-1 nil
2795  "Subdued level highlighting for Verilog mode.")
2796
2797(defvar verilog-font-lock-keywords-2 nil
2798  "Medium level highlighting for Verilog mode.
2799See also `verilog-font-lock-extra-types'.")
2800
2801(defvar verilog-font-lock-keywords-3 nil
2802  "Gaudy level highlighting for Verilog mode.
2803See also `verilog-font-lock-extra-types'.")
2804
2805(defvar verilog-font-lock-translate-off-face
2806  'verilog-font-lock-translate-off-face
2807  "Font to use for translated off regions.")
2808(defface verilog-font-lock-translate-off-face
2809  '((((class color)
2810      (background light))
2811     (:background "gray90" :italic t ))
2812    (((class color)
2813      (background dark))
2814     (:background "gray10" :italic t ))
2815    (((class grayscale) (background light))
2816     (:foreground "DimGray" :italic t))
2817    (((class grayscale) (background dark))
2818     (:foreground "LightGray" :italic t))
2819    (t (:italis t)))
2820  "Font lock mode face used to background highlight translate-off regions."
2821  :group 'font-lock-highlighting-faces)
2822
2823(defvar verilog-font-lock-p1800-face
2824  'verilog-font-lock-p1800-face
2825  "Font to use for p1800 keywords.")
2826(defface verilog-font-lock-p1800-face
2827  '((((class color)
2828      (background light))
2829     (:foreground "DarkOrange3" :bold t ))
2830    (((class color)
2831      (background dark))
2832     (:foreground "orange1" :bold t ))
2833    (t (:italic t)))
2834  "Font lock mode face used to highlight P1800 keywords."
2835  :group 'font-lock-highlighting-faces)
2836
2837(defvar verilog-font-lock-ams-face
2838  'verilog-font-lock-ams-face
2839  "Font to use for Analog/Mixed Signal keywords.")
2840(defface verilog-font-lock-ams-face
2841  '((((class color)
2842      (background light))
2843     (:foreground "Purple" :bold t ))
2844    (((class color)
2845      (background dark))
2846     (:foreground "orange1" :bold t ))
2847    (t (:italic t)))
2848  "Font lock mode face used to highlight AMS keywords."
2849  :group 'font-lock-highlighting-faces)
2850
2851(defvar verilog-font-grouping-keywords-face
2852  'verilog-font-lock-grouping-keywords-face
2853  "Font to use for Verilog Grouping Keywords (such as begin..end).")
2854(defface verilog-font-lock-grouping-keywords-face
2855  '((((class color)
2856      (background light))
2857     (:foreground "red4" :bold t ))
2858    (((class color)
2859      (background dark))
2860     (:foreground "red4" :bold t ))
2861    (t (:italic t)))
2862  "Font lock mode face used to highlight verilog grouping keywords."
2863  :group 'font-lock-highlighting-faces)
2864
2865(let* ((verilog-type-font-keywords
2866	(eval-when-compile
2867	  (verilog-regexp-opt
2868	   '(
2869	     "and" "bit" "buf" "bufif0" "bufif1" "cmos" "defparam"
2870	     "event" "genvar" "inout" "input" "integer" "localparam"
2871	     "logic" "mailbox" "nand" "nmos" "not" "notif0" "notif1" "or"
2872	     "output" "parameter" "pmos" "pull0" "pull1" "pulldown" "pullup"
2873	     "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran"
2874	     "rtranif0" "rtranif1" "semaphore" "signed" "struct" "supply"
2875	     "supply0" "supply1" "time" "tran" "tranif0" "tranif1"
2876	     "tri" "tri0" "tri1" "triand" "trior" "trireg" "typedef"
2877	     "uwire" "vectored" "wand" "wire" "wor" "xnor" "xor"
2878	     ) nil  )))
2879
2880       (verilog-pragma-keywords
2881	(eval-when-compile
2882	  (verilog-regexp-opt
2883	   '("surefire" "auto" "synopsys" "rtl_synthesis" "verilint" "leda" "0in"
2884	     ) nil  )))
2885
2886       (verilog-1800-2005-keywords
2887	(eval-when-compile
2888	  (verilog-regexp-opt
2889	   '("alias" "assert" "assume" "automatic" "before" "bind"
2890	     "bins" "binsof" "break" "byte" "cell" "chandle" "class"
2891	     "clocking" "config" "const" "constraint" "context" "continue"
2892	     "cover" "covergroup" "coverpoint" "cross" "deassign" "design"
2893	     "dist" "do" "edge" "endclass" "endclocking" "endconfig"
2894	     "endgroup" "endprogram" "endproperty" "endsequence" "enum"
2895	     "expect" "export" "extends" "extern" "first_match" "foreach"
2896	     "forkjoin" "genvar" "highz0" "highz1" "ifnone" "ignore_bins"
2897	     "illegal_bins" "import" "incdir" "include" "inside" "instance"
2898	     "int" "intersect" "large" "liblist" "library" "local" "longint"
2899	     "matches" "medium" "modport" "new" "noshowcancelled" "null"
2900	     "packed" "program" "property" "protected" "pull0" "pull1"
2901	     "pulsestyle_onevent" "pulsestyle_ondetect" "pure" "rand" "randc"
2902	     "randcase" "randsequence" "ref" "release" "return" "scalared"
2903	     "sequence" "shortint" "shortreal" "showcancelled" "small" "solve"
2904	     "specparam" "static" "string" "strong0" "strong1" "struct"
2905	     "super" "tagged" "this" "throughout" "timeprecision" "timeunit"
2906	     "type" "union" "unsigned" "use" "var" "virtual" "void"
2907	     "wait_order" "weak0" "weak1" "wildcard" "with" "within"
2908	     ) nil )))
2909
2910       (verilog-1800-2009-keywords
2911	(eval-when-compile
2912	  (verilog-regexp-opt
2913	   '("accept_on" "checker" "endchecker" "eventually" "global"
2914	     "implies" "let" "nexttime" "reject_on" "restrict" "s_always"
2915	     "s_eventually" "s_nexttime" "s_until" "s_until_with" "strong"
2916	     "sync_accept_on" "sync_reject_on" "unique0" "until"
2917	     "until_with" "untyped" "weak" ) nil )))
2918
2919       (verilog-ams-keywords
2920	(eval-when-compile
2921	  (verilog-regexp-opt
2922	   '("above" "abs" "absdelay" "acos" "acosh" "ac_stim"
2923	     "aliasparam" "analog" "analysis" "asin" "asinh" "atan" "atan2" "atanh"
2924	     "branch" "ceil" "connectmodule" "connectrules" "cos" "cosh" "ddt"
2925	     "ddx" "discipline" "driver_update" "enddiscipline" "endconnectrules"
2926	     "endnature" "endparamset" "exclude" "exp" "final_step" "flicker_noise"
2927	     "floor" "flow" "from" "ground" "hypot" "idt" "idtmod" "inf"
2928	     "initial_step" "laplace_nd" "laplace_np" "laplace_zd" "laplace_zp"
2929	     "last_crossing" "limexp" "ln" "log" "max" "min" "nature"
2930	     "net_resolution" "noise_table" "paramset" "potential" "pow" "sin"
2931	     "sinh" "slew" "sqrt" "tan" "tanh" "timer" "transition" "white_noise"
2932	     "wreal" "zi_nd" "zi_np" "zi_zd" ) nil )))
2933
2934       (verilog-font-keywords
2935	(eval-when-compile
2936	  (verilog-regexp-opt
2937	   '(
2938	     "assign" "case" "casex" "casez" "randcase" "deassign"
2939	     "default" "disable" "else" "endcase" "endfunction"
2940	     "endgenerate" "endinterface" "endmodule" "endprimitive"
2941	     "endspecify" "endtable" "endtask" "final" "for" "force" "return" "break"
2942	     "continue" "forever" "fork" "function" "generate" "if" "iff" "initial"
2943	     "interface" "join" "join_any" "join_none" "macromodule" "module" "negedge"
2944	     "package" "endpackage" "always" "always_comb" "always_ff"
2945	     "always_latch" "posedge" "primitive" "priority" "release"
2946	     "repeat" "specify" "table" "task" "unique" "wait" "while"
2947	     "class" "program" "endclass" "endprogram"
2948	     ) nil  )))
2949
2950       (verilog-font-grouping-keywords
2951	(eval-when-compile
2952	  (verilog-regexp-opt
2953	   '( "begin" "end" ) nil  ))))
2954
2955  (setq verilog-font-lock-keywords
2956	(list
2957	 ;; Fontify all builtin keywords
2958	 (concat "\\<\\(" verilog-font-keywords "\\|"
2959		       ;; And user/system tasks and functions
2960              "\\$[a-zA-Z][a-zA-Z0-9_\\$]*"
2961              "\\)\\>")
2962	 ;; Fontify all types
2963	 (if verilog-highlight-grouping-keywords
2964	     (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
2965		   'verilog-font-lock-ams-face)
2966	   (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
2967		 'font-lock-type-face))
2968	 (cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>")
2969          'font-lock-type-face)
2970	 ;; Fontify IEEE-1800-2005 keywords appropriately
2971	 (if verilog-highlight-p1800-keywords
2972	     (cons (concat "\\<\\(" verilog-1800-2005-keywords "\\)\\>")
2973		   'verilog-font-lock-p1800-face)
2974	   (cons (concat "\\<\\(" verilog-1800-2005-keywords "\\)\\>")
2975		 'font-lock-type-face))
2976	 ;; Fontify IEEE-1800-2009 keywords appropriately
2977	 (if verilog-highlight-p1800-keywords
2978	     (cons (concat "\\<\\(" verilog-1800-2009-keywords "\\)\\>")
2979		   'verilog-font-lock-p1800-face)
2980	   (cons (concat "\\<\\(" verilog-1800-2009-keywords "\\)\\>")
2981		 'font-lock-type-face))
2982	 ;; Fontify Verilog-AMS keywords
2983	 (cons (concat "\\<\\(" verilog-ams-keywords "\\)\\>")
2984	       'verilog-font-lock-ams-face)))
2985
2986  (setq verilog-font-lock-keywords-1
2987	(append verilog-font-lock-keywords
2988		(list
2989		 ;; Fontify module definitions
2990		 (list
2991		  "\\<\\(\\(macro\\)?module\\|primitive\\|class\\|program\\|interface\\|package\\|task\\)\\>\\s-*\\(\\sw+\\)"
2992		  '(1 font-lock-keyword-face)
2993		  '(3 font-lock-function-name-face 'prepend))
2994		 ;; Fontify function definitions
2995		 (list
2996		  (concat "\\<function\\>\\s-+\\(integer\\|real\\(time\\)?\\|time\\)\\s-+\\(\\sw+\\)" )
2997		       '(1 font-lock-keyword-face)
2998		       '(3 font-lock-constant-face prepend))
2999		 '("\\<function\\>\\s-+\\(\\[[^]]+\\]\\)\\s-+\\(\\sw+\\)"
3000		   (1 font-lock-keyword-face)
3001		   (2 font-lock-constant-face append))
3002		 '("\\<function\\>\\s-+\\(\\sw+\\)"
3003		   1 'font-lock-constant-face append))))
3004
3005  (setq verilog-font-lock-keywords-2
3006	(append verilog-font-lock-keywords-1
3007		(list
3008		 ;; Fontify pragmas
3009		 (concat "\\(//\\s-*\\(" verilog-pragma-keywords "\\)\\s-.*\\)")
3010		 ;; Fontify escaped names
3011		 '("\\(\\\\\\S-*\\s-\\)"  0 font-lock-function-name-face)
3012		 ;; Fontify macro definitions/ uses
3013		 '("`\\s-*[A-Za-z][A-Za-z0-9_]*" 0 (if (boundp 'font-lock-preprocessor-face)
3014						       'font-lock-preprocessor-face
3015						     'font-lock-type-face))
3016		 ;; Fontify delays/numbers
3017		 '("\\(@\\)\\|\\(#\\s-*\\(\\(\[0-9_.\]+\\('s?[hdxbo][0-9a-fA-F_xz]*\\)?\\)\\|\\(([^()]+)\\|\\sw+\\)\\)\\)"
3018		   0 font-lock-type-face append)
3019		 ;; Fontify instantiation names
3020		 '("\\([A-Za-z][A-Za-z0-9_]*\\)\\s-*(" 1 font-lock-function-name-face)
3021		 )))
3022
3023  (setq verilog-font-lock-keywords-3
3024	(append verilog-font-lock-keywords-2
3025		(when verilog-highlight-translate-off
3026		  (list
3027		   ;; Fontify things in translate off regions
3028		   '(verilog-match-translate-off
3029		     (0 'verilog-font-lock-translate-off-face prepend))
3030		   )))))
3031
3032;;
3033;; Buffer state preservation
3034
3035(defmacro verilog-save-buffer-state (&rest body)
3036  "Execute BODY forms, saving state around insignificant change.
3037Changes in text properties like `face' or `syntax-table' are
3038considered insignificant.  This macro allows text properties to
3039be changed, even in a read-only buffer.
3040
3041A change is considered significant if it affects the buffer text
3042in any way that isn't completely restored again.  Any
3043user-visible changes to the buffer must not be within a
3044`verilog-save-buffer-state'."
3045  ;; From c-save-buffer-state
3046  `(let* ((modified (buffer-modified-p))
3047	  (buffer-undo-list t)
3048	  (inhibit-read-only t)
3049	  (inhibit-point-motion-hooks t)
3050	  (verilog-no-change-functions t)
3051	  before-change-functions
3052	  after-change-functions
3053	  deactivate-mark
3054	  buffer-file-name ; Prevent primitives checking
3055	  buffer-file-truename)	; for file modification
3056     (unwind-protect
3057	 (progn ,@body)
3058       (and (not modified)
3059	    (buffer-modified-p)
3060	    (set-buffer-modified-p nil)))))
3061
3062(defmacro verilog-save-no-change-functions (&rest body)
3063  "Execute BODY forms, disabling all change hooks in BODY.
3064For insignificant changes, see instead `verilog-save-buffer-state'."
3065  `(let* ((inhibit-point-motion-hooks t)
3066	  (verilog-no-change-functions t)
3067	  before-change-functions
3068	  after-change-functions)
3069     (progn ,@body)))
3070
3071(defvar verilog-save-font-mod-hooked nil
3072  "Local variable when inside a `verilog-save-font-mods' block.")
3073(make-variable-buffer-local 'verilog-save-font-mod-hooked)
3074
3075(defmacro verilog-save-font-mods (&rest body)
3076  "Execute BODY forms, disabling text modifications to allow performing BODY.
3077Includes temporary disabling of `font-lock' to restore the buffer
3078to full text form for parsing.  Additional actions may be specified with
3079`verilog-before-save-font-hook' and `verilog-after-save-font-hook'."
3080  ;; Before version 20, match-string with font-lock returns a
3081  ;; vector that is not equal to the string.  IE if on "input"
3082  ;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
3083  `(let* ((hooked (unless verilog-save-font-mod-hooked
3084		    (verilog-run-hooks 'verilog-before-save-font-hook)
3085		    t))
3086	  (verilog-save-font-mod-hooked t)
3087	  (fontlocked (when (and (boundp 'font-lock-mode) font-lock-mode)
3088			(font-lock-mode 0)
3089			t)))
3090     (unwind-protect
3091	   (progn ,@body)
3092	 ;; Unwind forms
3093	 (when fontlocked (font-lock-mode t))
3094	 (when hooked (verilog-run-hooks 'verilog-after-save-font-hook)))))
3095
3096;;
3097;; Comment detection and caching
3098
3099(defvar verilog-scan-cache-preserving nil
3100  "If set, the specified buffer's comment properties are static.
3101Buffer changes will be ignored.  See `verilog-inside-comment-or-string-p'
3102and `verilog-scan'.")
3103
3104(defvar verilog-scan-cache-tick nil
3105  "Modification tick at which `verilog-scan' was last completed.")
3106(make-variable-buffer-local 'verilog-scan-cache-tick)
3107
3108(defun verilog-scan-cache-flush ()
3109  "Flush the `verilog-scan' cache."
3110  (setq verilog-scan-cache-tick nil))
3111
3112(defun verilog-scan-cache-ok-p ()
3113  "Return t iff the scan cache is up to date."
3114  (or (and verilog-scan-cache-preserving
3115	   (eq verilog-scan-cache-preserving (current-buffer))
3116	   verilog-scan-cache-tick)
3117      (equal verilog-scan-cache-tick (buffer-chars-modified-tick))))
3118
3119(defmacro verilog-save-scan-cache (&rest body)
3120  "Execute the BODY forms, allowing scan cache preservation within BODY.
3121This requires that insertions must use `verilog-insert'."
3122  ;; If the buffer is out of date, trash it, as we'll not check later the tick
3123  ;; Note this must work properly if there's multiple layers of calls
3124  ;; to verilog-save-scan-cache even with differing ticks.
3125  `(progn
3126     (unless (verilog-scan-cache-ok-p)  ;; Must be before let
3127       (setq verilog-scan-cache-tick nil))
3128     (let* ((verilog-scan-cache-preserving (current-buffer)))
3129       (progn ,@body))))
3130
3131(defun verilog-scan-region (beg end)
3132  "Parse between BEG and END for `verilog-inside-comment-or-string-p'.
3133This creates v-cmts properties where comments are in force."
3134  ;; Why properties and not overlays?  Overlays have much slower non O(1)
3135  ;; lookup times.
3136  ;; This function is warm - called on every verilog-insert
3137  (save-excursion
3138    (save-match-data
3139      (verilog-save-buffer-state
3140       (let (pt)
3141	 (goto-char beg)
3142	 (while (< (point) end)
3143	   (cond ((looking-at "//")
3144		  (setq pt (point))
3145		  (or (search-forward "\n" end t)
3146		      (goto-char end))
3147		  ;; "1+": The leading // or /* itself isn't considered as
3148		  ;; being "inside" the comment, so that a (search-backward)
3149		  ;; that lands at the start of the // won't mis-indicate
3150		  ;; it's inside a comment.  Also otherwise it would be
3151		  ;; hard to find a commented out /*AS*/ vs one that isn't
3152		  (put-text-property (1+ pt) (point) 'v-cmts t))
3153		 ((looking-at "/\\*")
3154		  (setq pt (point))
3155		  (or (search-forward "*/" end t)
3156		      ;; No error - let later code indicate it so we can
3157		      ;; use inside functions on-the-fly
3158		      ;;(error "%s: Unmatched /* */, at char %d"
3159		      ;;       (verilog-point-text) (point))
3160		      (goto-char end))
3161		  (put-text-property (1+ pt) (point) 'v-cmts t))
3162		 ((looking-at "\"")
3163		  (setq pt (point))
3164		  (or (re-search-forward "[^\\]\"" end t)	;; don't forward-char first, since we look for a non backslash first
3165		      ;; No error - let later code indicate it so we can
3166		      (goto-char end))
3167		  (put-text-property (1+ pt) (point) 'v-cmts t))
3168		 (t
3169		  (forward-char 1)
3170		  (if (re-search-forward "[/\"]" end t)
3171		      (backward-char 1)
3172		    (goto-char end))))))))))
3173
3174(defun verilog-scan ()
3175  "Parse the buffer, marking all comments with properties.
3176Also assumes any text inserted since `verilog-scan-cache-tick'
3177either is ok to parse as a non-comment, or `verilog-insert' was used."
3178  ;; See also `verilog-scan-debug' and `verilog-scan-and-debug'
3179  (unless (verilog-scan-cache-ok-p)
3180    (save-excursion
3181      (verilog-save-buffer-state
3182	(when verilog-debug
3183	  (message "Scanning %s cache=%s cachetick=%S tick=%S" (current-buffer)
3184		   verilog-scan-cache-preserving verilog-scan-cache-tick
3185		   (buffer-chars-modified-tick)))
3186	(remove-text-properties (point-min) (point-max) '(v-cmts nil))
3187	(verilog-scan-region (point-min) (point-max))
3188	(setq verilog-scan-cache-tick (buffer-chars-modified-tick))
3189	(when verilog-debug (message "Scanning... done"))))))
3190
3191(defun verilog-scan-debug ()
3192  "For debugging, show with display face results of `verilog-scan'."
3193  (font-lock-mode 0)
3194  ;;(if dbg (setq dbg (concat dbg (format "verilog-scan-debug\n"))))
3195  (save-excursion
3196    (goto-char (point-min))
3197    (remove-text-properties (point-min) (point-max) '(face nil))
3198    (while (not (eobp))
3199      (cond ((get-text-property (point) 'v-cmts)
3200	     (put-text-property (point) (1+ (point)) `face 'underline)
3201	     ;;(if dbg (setq dbg (concat dbg (format "  v-cmts at %S\n" (point)))))
3202	     (forward-char 1))
3203	    (t
3204	     (goto-char (or (next-property-change (point)) (point-max))))))))
3205
3206(defun verilog-scan-and-debug ()
3207  "For debugging, run `verilog-scan' and `verilog-scan-debug'."
3208  (let (verilog-scan-cache-preserving
3209	verilog-scan-cache-tick)
3210    (goto-char (point-min))
3211    (verilog-scan)
3212    (verilog-scan-debug)))
3213
3214(defun verilog-inside-comment-or-string-p (&optional pos)
3215  "Check if optional point POS is inside a comment.
3216This may require a slow pre-parse of the buffer with `verilog-scan'
3217to establish comment properties on all text."
3218  ;; This function is very hot
3219  (verilog-scan)
3220  (if pos
3221      (and (>= pos (point-min))
3222	   (get-text-property pos 'v-cmts))
3223    (get-text-property (point) 'v-cmts)))
3224
3225(defun verilog-insert (&rest stuff)
3226  "Insert STUFF arguments, tracking for `verilog-inside-comment-or-string-p'.
3227Any insert that includes a comment must have the entire comment
3228inserted using a single call to `verilog-insert'."
3229  (let ((pt (point)))
3230    (while stuff
3231      (insert (car stuff))
3232      (setq stuff (cdr stuff)))
3233    (verilog-scan-region pt (point))))
3234
3235;; More searching
3236
3237(defun verilog-declaration-end ()
3238  (search-forward ";"))
3239
3240(defun verilog-point-text (&optional pointnum)
3241  "Return text describing where POINTNUM or current point is (for errors).
3242Use filename, if current buffer being edited shorten to just buffer name."
3243  (concat (or (and (equal (window-buffer (selected-window)) (current-buffer))
3244		   (buffer-name))
3245	      buffer-file-name
3246	      (buffer-name))
3247	  ":" (int-to-string (1+ (count-lines (point-min) (or pointnum (point)))))))
3248
3249(defun electric-verilog-backward-sexp ()
3250  "Move backward over one balanced expression."
3251  (interactive)
3252  ;; before that see if we are in a comment
3253  (verilog-backward-sexp))
3254
3255(defun electric-verilog-forward-sexp ()
3256  "Move forward over one balanced expression."
3257  (interactive)
3258  ;; before that see if we are in a comment
3259  (verilog-forward-sexp))
3260
3261;;;used by hs-minor-mode
3262(defun verilog-forward-sexp-function (arg)
3263  (if (< arg 0)
3264      (verilog-backward-sexp)
3265    (verilog-forward-sexp)))
3266
3267
3268(defun verilog-backward-sexp ()
3269  (let ((reg)
3270	(elsec 1)
3271	(found nil)
3272	(st (point)))
3273    (if (not (looking-at "\\<"))
3274	(forward-word -1))
3275    (cond
3276     ((verilog-skip-backward-comment-or-string))
3277     ((looking-at "\\<else\\>")
3278      (setq reg (concat
3279		 verilog-end-block-re
3280		 "\\|\\(\\<else\\>\\)"
3281		 "\\|\\(\\<if\\>\\)"))
3282      (while (and (not found)
3283		  (verilog-re-search-backward reg nil 'move))
3284	(cond
3285	 ((match-end 1) ; matched verilog-end-block-re
3286	; try to leap back to matching outward block by striding across
3287	; indent level changing tokens then immediately
3288	; previous line governs indentation.
3289	  (verilog-leap-to-head))
3290	 ((match-end 2) ; else, we're in deep
3291	  (setq elsec (1+ elsec)))
3292	 ((match-end 3) ; found it
3293	  (setq elsec (1- elsec))
3294	  (if (= 0 elsec)
3295	      ;; Now previous line describes syntax
3296	      (setq found 't))))))
3297     ((looking-at verilog-end-block-re)
3298      (verilog-leap-to-head))
3299     ((looking-at "\\(endmodule\\>\\)\\|\\(\\<endprimitive\\>\\)\\|\\(\\<endclass\\>\\)\\|\\(\\<endprogram\\>\\)\\|\\(\\<endinterface\\>\\)\\|\\(\\<endpackage\\>\\)")
3300      (cond
3301       ((match-end 1)
3302	(verilog-re-search-backward "\\<\\(macro\\)?module\\>" nil 'move))
3303       ((match-end 2)
3304	(verilog-re-search-backward "\\<primitive\\>" nil 'move))
3305       ((match-end 3)
3306	(verilog-re-search-backward "\\<class\\>" nil 'move))
3307       ((match-end 4)
3308	(verilog-re-search-backward "\\<program\\>" nil 'move))
3309       ((match-end 5)
3310	(verilog-re-search-backward "\\<interface\\>" nil 'move))
3311       ((match-end 6)
3312	(verilog-re-search-backward "\\<package\\>" nil 'move))
3313       (t
3314	(goto-char st)
3315	(backward-sexp 1))))
3316     (t
3317      (goto-char st)
3318      (backward-sexp)))))
3319
3320(defun verilog-forward-sexp ()
3321  (let ((reg)
3322	(md 2)
3323	(st (point))
3324	(nest 'yes))
3325    (if (not (looking-at "\\<"))
3326	(forward-word -1))
3327    (cond
3328     ((verilog-skip-forward-comment-or-string)
3329      (verilog-forward-syntactic-ws))
3330     ((looking-at verilog-beg-block-re-ordered)
3331      (cond
3332       ((match-end 1);
3333	;; Search forward for matching end
3334	(setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
3335       ((match-end 2)
3336	;; Search forward for matching endcase
3337	(setq reg "\\(\\<randcase\\>\\|\\(\\<unique\\>\\s-+\\|\\<priority\\>\\s-+\\)?\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
3338	(setq md 3) ;; ender is third item in regexp
3339	)
3340       ((match-end 4)
3341	;; might be "disable fork" or "wait fork"
3342	(let
3343	    (here)
3344	  (if (or
3345	       (looking-at verilog-disable-fork-re)
3346	       (and (looking-at "fork")
3347		    (progn
3348		      (setq here (point)) ;; sometimes a fork is just a fork
3349		      (forward-word -1)
3350		      (looking-at verilog-disable-fork-re))))
3351	      (progn ;; it is a disable fork; ignore it
3352		(goto-char (match-end 0))
3353		(forward-word 1)
3354		(setq reg nil))
3355	    (progn ;; it is a nice simple fork
3356	      (goto-char here)   ;; return from looking for "disable fork"
3357	      ;; Search forward for matching join
3358	      (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))))
3359       ((match-end 6)
3360	;; Search forward for matching endclass
3361	(setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
3362
3363       ((match-end 7)
3364	;; Search forward for matching endtable
3365	(setq reg "\\<endtable\\>" )
3366	(setq nest 'no))
3367      ((match-end 8)
3368       ;; Search forward for matching endspecify
3369       (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
3370      ((match-end 9)
3371       ;; Search forward for matching endfunction
3372       (setq reg "\\<endfunction\\>" )
3373       (setq nest 'no))
3374      ((match-end 10)
3375       ;; Search forward for matching endfunction
3376       (setq reg "\\<endfunction\\>" )
3377       (setq nest 'no))
3378      ((match-end 14)
3379       ;; Search forward for matching endtask
3380       (setq reg "\\<endtask\\>" )
3381       (setq nest 'no))
3382      ((match-end 15)
3383       ;; Search forward for matching endtask
3384       (setq reg "\\<endtask\\>" )
3385       (setq nest 'no))
3386      ((match-end 19)
3387       ;; Search forward for matching endgenerate
3388       (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
3389      ((match-end 20)
3390       ;; Search forward for matching endgroup
3391       (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
3392      ((match-end 21)
3393       ;; Search forward for matching endproperty
3394       (setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
3395      ((match-end 25)
3396       ;; Search forward for matching endsequence
3397       (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" )
3398       (setq md 3)) ; 3 to get to endsequence in the reg above
3399      ((match-end 27)
3400       ;; Search forward for matching endclocking
3401       (setq reg "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)" )))
3402      (if (and reg
3403	       (forward-word 1))
3404	  (catch 'skip
3405	    (if (eq nest 'yes)
3406		(let ((depth 1)
3407		      here)
3408		  (while (verilog-re-search-forward reg nil 'move)
3409		    (cond
3410		     ((match-end md) ; a closer in regular expression, so we are climbing out
3411		      (setq depth (1- depth))
3412		      (if (= 0 depth) ; we are out!
3413			  (throw 'skip 1)))
3414		     ((match-end 1) ; an opener in the r-e, so we are in deeper now
3415		      (setq here (point)) ; remember where we started
3416		      (goto-char (match-beginning 1))
3417		      (cond
3418		       ((if (or
3419			     (looking-at verilog-disable-fork-re)
3420			     (and (looking-at "fork")
3421				  (progn
3422				    (forward-word -1)
3423				    (looking-at verilog-disable-fork-re))))
3424			    (progn ;; it is a disable fork; another false alarm
3425			      (goto-char (match-end 0)))
3426			  (progn ;; it is a simple fork (or has nothing to do with fork)
3427			    (goto-char here)
3428			    (setq depth (1+ depth))))))))))
3429	      (if (verilog-re-search-forward reg nil 'move)
3430		  (throw 'skip 1))))))
3431
3432     ((looking-at (concat
3433		   "\\(\\<\\(macro\\)?module\\>\\)\\|"
3434		   "\\(\\<primitive\\>\\)\\|"
3435		   "\\(\\<class\\>\\)\\|"
3436		   "\\(\\<program\\>\\)\\|"
3437		   "\\(\\<interface\\>\\)\\|"
3438		   "\\(\\<package\\>\\)"))
3439      (cond
3440       ((match-end 1)
3441	(verilog-re-search-forward "\\<endmodule\\>" nil 'move))
3442       ((match-end 2)
3443	(verilog-re-search-forward "\\<endprimitive\\>" nil 'move))
3444       ((match-end 3)
3445	(verilog-re-search-forward "\\<endclass\\>" nil 'move))
3446       ((match-end 4)
3447	(verilog-re-search-forward "\\<endprogram\\>" nil 'move))
3448       ((match-end 5)
3449	(verilog-re-search-forward "\\<endinterface\\>" nil 'move))
3450       ((match-end 6)
3451	(verilog-re-search-forward "\\<endpackage\\>" nil 'move))
3452       (t
3453	(goto-char st)
3454	(if (= (following-char) ?\) )
3455	    (forward-char 1)
3456	  (forward-sexp 1)))))
3457     (t
3458      (goto-char st)
3459      (if (= (following-char) ?\) )
3460	  (forward-char 1)
3461	(forward-sexp 1))))))
3462
3463(defun verilog-declaration-beg ()
3464  (verilog-re-search-backward verilog-declaration-re (bobp) t))
3465
3466;;
3467;;
3468;;  Mode
3469;;
3470(defvar verilog-which-tool 1)
3471;;;###autoload
3472(define-derived-mode verilog-mode prog-mode "Verilog"
3473  "Major mode for editing Verilog code.
3474\\<verilog-mode-map>
3475See \\[describe-function] verilog-auto (\\[verilog-auto]) for details on how
3476AUTOs can improve coding efficiency.
3477
3478Use \\[verilog-faq] for a pointer to frequently asked questions.
3479
3480NEWLINE, TAB indents for Verilog code.
3481Delete converts tabs to spaces as it moves back.
3482
3483Supports highlighting.
3484
3485Turning on Verilog mode calls the value of the variable `verilog-mode-hook'
3486with no args, if that value is non-nil.
3487
3488Variables controlling indentation/edit style:
3489
3490 variable `verilog-indent-level'      (default 3)
3491   Indentation of Verilog statements with respect to containing block.
3492 `verilog-indent-level-module'        (default 3)
3493   Absolute indentation of Module level Verilog statements.
3494   Set to 0 to get initial and always statements lined up
3495   on the left side of your screen.
3496 `verilog-indent-level-declaration'   (default 3)
3497   Indentation of declarations with respect to containing block.
3498   Set to 0 to get them list right under containing block.
3499 `verilog-indent-level-behavioral'    (default 3)
3500   Indentation of first begin in a task or function block
3501   Set to 0 to get such code to lined up underneath the task or
3502   function keyword.
3503 `verilog-indent-level-directive'     (default 1)
3504   Indentation of `ifdef/`endif blocks.
3505 `verilog-cexp-indent'              (default 1)
3506   Indentation of Verilog statements broken across lines i.e.:
3507      if (a)
3508        begin
3509 `verilog-case-indent'              (default 2)
3510   Indentation for case statements.
3511 `verilog-auto-newline'             (default nil)
3512   Non-nil means automatically newline after semicolons and the punctuation
3513   mark after an end.
3514 `verilog-auto-indent-on-newline'   (default t)
3515   Non-nil means automatically indent line after newline.
3516 `verilog-tab-always-indent'        (default t)
3517   Non-nil means TAB in Verilog mode should always reindent the current line,
3518   regardless of where in the line point is when the TAB command is used.
3519 `verilog-indent-begin-after-if'    (default t)
3520   Non-nil means to indent begin statements following a preceding
3521   if, else, while, for and repeat statements, if any.  Otherwise,
3522   the begin is lined up with the preceding token.  If t, you get:
3523      if (a)
3524         begin // amount of indent based on `verilog-cexp-indent'
3525   otherwise you get:
3526      if (a)
3527      begin
3528 `verilog-auto-endcomments'         (default t)
3529   Non-nil means a comment /* ... */ is set after the ends which ends
3530   cases, tasks, functions and modules.
3531   The type and name of the object will be set between the braces.
3532 `verilog-minimum-comment-distance' (default 10)
3533   Minimum distance (in lines) between begin and end required before a comment
3534   will be inserted.  Setting this variable to zero results in every
3535   end acquiring a comment; the default avoids too many redundant
3536   comments in tight quarters.
3537 `verilog-auto-lineup'              (default 'declarations)
3538   List of contexts where auto lineup of code should be done.
3539
3540Variables controlling other actions:
3541
3542 `verilog-linter'                   (default surelint)
3543   Unix program to call to run the lint checker.  This is the default
3544   command for \\[compile-command] and \\[verilog-auto-save-compile].
3545
3546See \\[customize] for the complete list of variables.
3547
3548AUTO expansion functions are, in part:
3549
3550    \\[verilog-auto]  Expand AUTO statements.
3551    \\[verilog-delete-auto]  Remove the AUTOs.
3552    \\[verilog-inject-auto]  Insert AUTOs for the first time.
3553
3554Some other functions are:
3555
3556    \\[verilog-complete-word]    Complete word with appropriate possibilities.
3557    \\[verilog-mark-defun]  Mark function.
3558    \\[verilog-beg-of-defun]  Move to beginning of current function.
3559    \\[verilog-end-of-defun]  Move to end of current function.
3560    \\[verilog-label-be]  Label matching begin ... end, fork ... join, etc statements.
3561
3562    \\[verilog-comment-region]  Put marked area in a comment.
3563    \\[verilog-uncomment-region]  Uncomment an area commented with \\[verilog-comment-region].
3564    \\[verilog-insert-block]  Insert begin ... end.
3565    \\[verilog-star-comment]    Insert /* ... */.
3566
3567    \\[verilog-sk-always]  Insert an always @(AS) begin .. end block.
3568    \\[verilog-sk-begin]  Insert a begin .. end block.
3569    \\[verilog-sk-case]  Insert a case block, prompting for details.
3570    \\[verilog-sk-for]  Insert a for (...) begin .. end block, prompting for details.
3571    \\[verilog-sk-generate]  Insert a generate .. endgenerate block.
3572    \\[verilog-sk-header]  Insert a header block at the top of file.
3573    \\[verilog-sk-initial]  Insert an initial begin .. end block.
3574    \\[verilog-sk-fork]  Insert a fork begin .. end .. join block.
3575    \\[verilog-sk-module]  Insert a module .. (/*AUTOARG*/);.. endmodule block.
3576    \\[verilog-sk-ovm-class]  Insert an OVM Class block.
3577    \\[verilog-sk-uvm-class]  Insert an UVM Class block.
3578    \\[verilog-sk-primitive]  Insert a primitive .. (.. );.. endprimitive block.
3579    \\[verilog-sk-repeat]  Insert a repeat (..) begin .. end block.
3580    \\[verilog-sk-specify]  Insert a specify .. endspecify block.
3581    \\[verilog-sk-task]  Insert a task .. begin .. end endtask block.
3582    \\[verilog-sk-while]  Insert a while (...) begin .. end block, prompting for details.
3583    \\[verilog-sk-casex]  Insert a casex (...) item: begin.. end endcase block, prompting for details.
3584    \\[verilog-sk-casez]  Insert a casez (...) item: begin.. end endcase block, prompting for details.
3585    \\[verilog-sk-if]  Insert an if (..) begin .. end block.
3586    \\[verilog-sk-else-if]  Insert an else if (..) begin .. end block.
3587    \\[verilog-sk-comment]  Insert a comment block.
3588    \\[verilog-sk-assign]  Insert an assign .. = ..; statement.
3589    \\[verilog-sk-function]  Insert a function .. begin .. end endfunction block.
3590    \\[verilog-sk-input]  Insert an input declaration, prompting for details.
3591    \\[verilog-sk-output]  Insert an output declaration, prompting for details.
3592    \\[verilog-sk-state-machine]  Insert a state machine definition, prompting for details.
3593    \\[verilog-sk-inout]  Insert an inout declaration, prompting for details.
3594    \\[verilog-sk-wire]  Insert a wire declaration, prompting for details.
3595    \\[verilog-sk-reg]  Insert a register declaration, prompting for details.
3596    \\[verilog-sk-define-signal]  Define signal under point as a register at the top of the module.
3597
3598All key bindings can be seen in a Verilog-buffer with \\[describe-bindings].
3599Key bindings specific to `verilog-mode-map' are:
3600
3601\\{verilog-mode-map}"
3602  :abbrev-table verilog-mode-abbrev-table
3603  (set (make-local-variable 'beginning-of-defun-function)
3604       'verilog-beg-of-defun)
3605  (set (make-local-variable 'end-of-defun-function)
3606       'verilog-end-of-defun)
3607  (set-syntax-table verilog-mode-syntax-table)
3608  (set (make-local-variable 'indent-line-function)
3609       #'verilog-indent-line-relative)
3610  (setq comment-indent-function 'verilog-comment-indent)
3611  (set (make-local-variable 'parse-sexp-ignore-comments) nil)
3612  (set (make-local-variable 'comment-start) "// ")
3613  (set (make-local-variable 'comment-end) "")
3614  (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|// *")
3615  (set (make-local-variable 'comment-multi-line) nil)
3616  ;; Set up for compilation
3617  (setq verilog-which-tool 1)
3618  (setq verilog-tool 'verilog-linter)
3619  (verilog-set-compile-command)
3620  (when (boundp 'hack-local-variables-hook)  ;; Also modify any file-local-variables
3621    (add-hook 'hack-local-variables-hook 'verilog-modify-compile-command t))
3622
3623  ;; Setting up menus
3624  (when (featurep 'xemacs)
3625    (easy-menu-add verilog-stmt-menu)
3626    (easy-menu-add verilog-menu)
3627    (setq mode-popup-menu (cons "Verilog Mode" verilog-stmt-menu)))
3628
3629  ;; Stuff for GNU Emacs
3630  (set (make-local-variable 'font-lock-defaults)
3631       `((verilog-font-lock-keywords
3632	  verilog-font-lock-keywords-1
3633	  verilog-font-lock-keywords-2
3634	  verilog-font-lock-keywords-3)
3635         nil nil nil
3636	 ,(if (functionp 'syntax-ppss)
3637	      ;; verilog-beg-of-defun uses syntax-ppss, and syntax-ppss uses
3638	      ;; font-lock-beginning-of-syntax-function, so
3639	      ;; font-lock-beginning-of-syntax-function, can't use
3640              ;; verilog-beg-of-defun.
3641	      nil
3642	    'verilog-beg-of-defun)))
3643  ;;------------------------------------------------------------
3644  ;; now hook in 'verilog-highlight-include-files (eldo-mode.el&spice-mode.el)
3645  ;; all buffer local:
3646  (unless noninteractive  ;; Else can't see the result, and change hooks are slow
3647    (when (featurep 'xemacs)
3648      (make-local-hook 'font-lock-mode-hook)
3649      (make-local-hook 'font-lock-after-fontify-buffer-hook); doesn't exist in Emacs
3650      (make-local-hook 'after-change-functions))
3651    (add-hook 'font-lock-mode-hook 'verilog-highlight-buffer t t)
3652    (add-hook 'font-lock-after-fontify-buffer-hook 'verilog-highlight-buffer t t) ; not in Emacs
3653    (add-hook 'after-change-functions 'verilog-highlight-region t t))
3654
3655  ;; Tell imenu how to handle Verilog.
3656  (set (make-local-variable 'imenu-generic-expression)
3657       verilog-imenu-generic-expression)
3658  ;; Tell which-func-modes that imenu knows about verilog
3659  (when (and (boundp 'which-func-modes) (listp which-func-modes))
3660    (add-to-list 'which-func-modes 'verilog-mode))
3661  ;; hideshow support
3662  (when (boundp 'hs-special-modes-alist)
3663    (unless (assq 'verilog-mode hs-special-modes-alist)
3664      (setq hs-special-modes-alist
3665	    (cons '(verilog-mode-mode  "\\<begin\\>" "\\<end\\>" nil
3666				       verilog-forward-sexp-function)
3667		  hs-special-modes-alist))))
3668
3669  ;; Stuff for autos
3670  (add-hook 'write-contents-hooks 'verilog-auto-save-check nil 'local)
3671  ;; verilog-mode-hook call added by define-derived-mode
3672  )
3673
3674
3675;;
3676;;  Electric functions
3677;;
3678(defun electric-verilog-terminate-line (&optional arg)
3679  "Terminate line and indent next line.
3680With optional ARG, remove existing end of line comments."
3681  (interactive)
3682  ;; before that see if we are in a comment
3683  (let ((state (save-excursion (verilog-syntax-ppss))))
3684    (cond
3685     ((nth 7 state)			; Inside // comment
3686      (if (eolp)
3687	  (progn
3688	    (delete-horizontal-space)
3689	    (newline))
3690	(progn
3691	  (newline)
3692	  (insert "// ")
3693	  (beginning-of-line)))
3694      (verilog-indent-line))
3695     ((nth 4 state)			; Inside any comment (hence /**/)
3696      (newline)
3697      (verilog-more-comment))
3698     ((eolp)
3699       ;; First, check if current line should be indented
3700       (if (save-excursion
3701             (delete-horizontal-space)
3702	     (beginning-of-line)
3703	     (skip-chars-forward " \t")
3704	     (if (looking-at verilog-auto-end-comment-lines-re)
3705		 (let ((indent-str (verilog-indent-line)))
3706		   ;; Maybe we should set some endcomments
3707		   (if verilog-auto-endcomments
3708		       (verilog-set-auto-endcomments indent-str arg))
3709		   (end-of-line)
3710		   (delete-horizontal-space)
3711		   (if arg
3712		       ()
3713		     (newline))
3714		   nil)
3715	       (progn
3716		 (end-of-line)
3717		 (delete-horizontal-space)
3718		 't)))
3719	   ;; see if we should line up assignments
3720	   (progn
3721	     (if (or (eq 'all verilog-auto-lineup)
3722		     (eq 'assignments verilog-auto-lineup))
3723		 (verilog-pretty-expr t "\\(<\\|:\\)?=" ))
3724	     (newline))
3725	 (forward-line 1))
3726       ;; Indent next line
3727       (if verilog-auto-indent-on-newline
3728	   (verilog-indent-line)))
3729     (t
3730      (newline)))))
3731
3732(defun electric-verilog-terminate-and-indent ()
3733  "Insert a newline and indent for the next statement."
3734  (interactive)
3735  (electric-verilog-terminate-line 1))
3736
3737(defun electric-verilog-semi ()
3738  "Insert `;' character and reindent the line."
3739  (interactive)
3740  (verilog-insert-last-command-event)
3741
3742  (if (or (verilog-in-comment-or-string-p)
3743	  (verilog-in-escaped-name-p))
3744      ()
3745    (save-excursion
3746      (beginning-of-line)
3747      (verilog-forward-ws&directives)
3748      (verilog-indent-line))
3749    (if (and verilog-auto-newline
3750	     (not (verilog-parenthesis-depth)))
3751	(electric-verilog-terminate-line))))
3752
3753(defun electric-verilog-semi-with-comment ()
3754  "Insert `;' character, reindent the line and indent for comment."
3755  (interactive)
3756  (insert "\;")
3757  (save-excursion
3758    (beginning-of-line)
3759    (verilog-indent-line))
3760  (indent-for-comment))
3761
3762(defun electric-verilog-colon ()
3763  "Insert `:' and do all indentations except line indent on this line."
3764  (interactive)
3765  (verilog-insert-last-command-event)
3766  ;; Do nothing if within string.
3767  (if (or
3768       (verilog-within-string)
3769       (not (verilog-in-case-region-p)))
3770      ()
3771    (save-excursion
3772      (let ((p (point))
3773	    (lim (progn (verilog-beg-of-statement) (point))))
3774	(goto-char p)
3775	(verilog-backward-case-item lim)
3776	(verilog-indent-line)))
3777;;    (let ((verilog-tab-always-indent nil))
3778;;      (verilog-indent-line))
3779    ))
3780
3781;;(defun electric-verilog-equal ()
3782;;  "Insert `=', and do indentation if within block."
3783;;  (interactive)
3784;;  (verilog-insert-last-command-event)
3785;; Could auto line up expressions, but not yet
3786;;  (if (eq (car (verilog-calculate-indent)) 'block)
3787;;      (let ((verilog-tab-always-indent nil))
3788;;	(verilog-indent-command)))
3789;;  )
3790
3791(defun electric-verilog-tick ()
3792  "Insert back-tick, and indent to column 0 if this is a CPP directive."
3793  (interactive)
3794  (verilog-insert-last-command-event)
3795  (save-excursion
3796    (if (verilog-in-directive-p)
3797        (verilog-indent-line))))
3798
3799(defun electric-verilog-tab ()
3800  "Function called when TAB is pressed in Verilog mode."
3801  (interactive)
3802  ;; If verilog-tab-always-indent, indent the beginning of the line.
3803  (cond
3804   ;; The region is active, indent it.
3805   ((and (region-active-p)
3806	 (not (eq (region-beginning) (region-end))))
3807    (indent-region (region-beginning) (region-end) nil))
3808   ((or verilog-tab-always-indent
3809	(save-excursion
3810	  (skip-chars-backward " \t")
3811	  (bolp)))
3812    (let* ((oldpnt (point))
3813	   (boi-point
3814	    (save-excursion
3815	      (beginning-of-line)
3816	      (skip-chars-forward " \t")
3817	      (verilog-indent-line)
3818	      (back-to-indentation)
3819	      (point))))
3820      (if (< (point) boi-point)
3821	  (back-to-indentation)
3822	(cond ((not verilog-tab-to-comment))
3823	      ((not (eolp))
3824	       (end-of-line))
3825	      (t
3826	       (indent-for-comment)
3827	       (when (and (eolp) (= oldpnt (point)))
3828					; kill existing comment
3829		 (beginning-of-line)
3830		 (re-search-forward comment-start-skip oldpnt 'move)
3831		 (goto-char (match-beginning 0))
3832		 (skip-chars-backward " \t")
3833		 (kill-region (point) oldpnt)))))))
3834   (t (progn (insert "\t")))))
3835
3836
3837
3838;;
3839;; Interactive functions
3840;;
3841
3842(defun verilog-indent-buffer ()
3843  "Indent-region the entire buffer as Verilog code.
3844To call this from the command line, see \\[verilog-batch-indent]."
3845  (interactive)
3846  (verilog-mode)
3847  (indent-region (point-min) (point-max) nil))
3848
3849(defun verilog-insert-block ()
3850  "Insert Verilog begin ... end; block in the code with right indentation."
3851  (interactive)
3852  (verilog-indent-line)
3853  (insert "begin")
3854  (electric-verilog-terminate-line)
3855  (save-excursion
3856    (electric-verilog-terminate-line)
3857    (insert "end")
3858    (beginning-of-line)
3859    (verilog-indent-line)))
3860
3861(defun verilog-star-comment ()
3862  "Insert Verilog star comment at point."
3863  (interactive)
3864  (verilog-indent-line)
3865  (insert "/*")
3866  (save-excursion
3867    (newline)
3868    (insert " */"))
3869  (newline)
3870  (insert " * "))
3871
3872(defun verilog-insert-1 (fmt max)
3873  "Use format string FMT to insert integers 0 to MAX - 1.
3874Inserts one integer per line, at the current column.  Stops early
3875if it reaches the end of the buffer."
3876  (let ((col (current-column))
3877        (n 0))
3878    (save-excursion
3879      (while (< n max)
3880        (insert (format fmt n))
3881        (forward-line 1)
3882        ;; Note that this function does not bother to check for lines
3883        ;; shorter than col.
3884        (if (eobp)
3885            (setq n max)
3886          (setq n (1+ n))
3887          (move-to-column col))))))
3888
3889(defun verilog-insert-indices (max)
3890  "Insert a set of indices into a rectangle.
3891The upper left corner is defined by point.  Indices begin with 0
3892and extend to the MAX - 1.  If no prefix arg is given, the user
3893is prompted for a value.  The indices are surrounded by square
3894brackets \[].  For example, the following code with the point
3895located after the first 'a' gives:
3896
3897    a = b                           a[  0] = b
3898    a = b                           a[  1] = b
3899    a = b                           a[  2] = b
3900    a = b                           a[  3] = b
3901    a = b   ==> insert-indices ==>  a[  4] = b
3902    a = b                           a[  5] = b
3903    a = b                           a[  6] = b
3904    a = b                           a[  7] = b
3905    a = b                           a[  8] = b"
3906
3907  (interactive "NMAX: ")
3908  (verilog-insert-1 "[%3d]" max))
3909
3910(defun verilog-generate-numbers (max)
3911  "Insert a set of generated numbers into a rectangle.
3912The upper left corner is defined by point.  The numbers are padded to three
3913digits, starting with 000 and extending to (MAX - 1).  If no prefix argument
3914is supplied, then the user is prompted for the MAX number.  Consider the
3915following code fragment:
3916
3917    buf buf                             buf buf000
3918    buf buf                             buf buf001
3919    buf buf                             buf buf002
3920    buf buf                             buf buf003
3921    buf buf   ==> generate-numbers ==>  buf buf004
3922    buf buf                             buf buf005
3923    buf buf                             buf buf006
3924    buf buf                             buf buf007
3925    buf buf                             buf buf008"
3926
3927  (interactive "NMAX: ")
3928  (verilog-insert-1 "%3.3d" max))
3929
3930(defun verilog-mark-defun ()
3931  "Mark the current Verilog function (or procedure).
3932This puts the mark at the end, and point at the beginning."
3933  (interactive)
3934  (if (featurep 'xemacs)
3935      (progn
3936	(push-mark (point))
3937	(verilog-end-of-defun)
3938	(push-mark (point))
3939	(verilog-beg-of-defun)
3940	(if (fboundp 'zmacs-activate-region)
3941	    (zmacs-activate-region)))
3942    (mark-defun)))
3943
3944(defun verilog-comment-region (start end)
3945  ; checkdoc-params: (start end)
3946  "Put the region into a Verilog comment.
3947The comments that are in this area are \"deformed\":
3948`*)' becomes `!(*' and `}' becomes `!{'.
3949These deformed comments are returned to normal if you use
3950\\[verilog-uncomment-region] to undo the commenting.
3951
3952The commented area starts with `verilog-exclude-str-start', and ends with
3953`verilog-exclude-str-end'.  But if you change these variables,
3954\\[verilog-uncomment-region] won't recognize the comments."
3955  (interactive "r")
3956  (save-excursion
3957    ;; Insert start and endcomments
3958    (goto-char end)
3959    (if (and (save-excursion (skip-chars-forward " \t") (eolp))
3960	     (not (save-excursion (skip-chars-backward " \t") (bolp))))
3961	(forward-line 1)
3962      (beginning-of-line))
3963    (insert verilog-exclude-str-end)
3964    (setq end (point))
3965    (newline)
3966    (goto-char start)
3967    (beginning-of-line)
3968    (insert verilog-exclude-str-start)
3969    (newline)
3970    ;; Replace end-comments within commented area
3971    (goto-char end)
3972    (save-excursion
3973      (while (re-search-backward "\\*/" start t)
3974	(replace-match "*-/" t t)))
3975    (save-excursion
3976      (let ((s+1 (1+ start)))
3977	(while (re-search-backward "/\\*" s+1 t)
3978	  (replace-match "/-*" t t))))))
3979
3980(defun verilog-uncomment-region ()
3981  "Uncomment a commented area; change deformed comments back to normal.
3982This command does nothing if the pointer is not in a commented
3983area.  See also `verilog-comment-region'."
3984  (interactive)
3985  (save-excursion
3986    (let ((start (point))
3987	  (end (point)))
3988      ;; Find the boundaries of the comment
3989      (save-excursion
3990	(setq start (progn (search-backward verilog-exclude-str-start nil t)
3991			   (point)))
3992	(setq end (progn (search-forward verilog-exclude-str-end nil t)
3993			 (point))))
3994      ;; Check if we're really inside a comment
3995      (if (or (equal start (point)) (<= end (point)))
3996	  (message "Not standing within commented area.")
3997	(progn
3998	  ;; Remove endcomment
3999	  (goto-char end)
4000	  (beginning-of-line)
4001	  (let ((pos (point)))
4002	    (end-of-line)
4003	    (delete-region pos (1+ (point))))
4004	  ;; Change comments back to normal
4005	  (save-excursion
4006	    (while (re-search-backward "\\*-/" start t)
4007	      (replace-match "*/" t t)))
4008	  (save-excursion
4009	    (while (re-search-backward "/-\\*" start t)
4010	      (replace-match "/*" t t)))
4011	  ;; Remove start comment
4012	  (goto-char start)
4013	  (beginning-of-line)
4014	  (let ((pos (point)))
4015	    (end-of-line)
4016	    (delete-region pos (1+ (point)))))))))
4017
4018(defun verilog-beg-of-defun ()
4019  "Move backward to the beginning of the current function or procedure."
4020  (interactive)
4021  (verilog-re-search-backward verilog-defun-re nil 'move))
4022
4023(defun verilog-beg-of-defun-quick ()
4024  "Move backward to the beginning of the current function or procedure.
4025Uses `verilog-scan' cache."
4026  (interactive)
4027  (verilog-re-search-backward-quick verilog-defun-re nil 'move))
4028
4029(defun verilog-end-of-defun ()
4030  "Move forward to the end of the current function or procedure."
4031  (interactive)
4032  (verilog-re-search-forward verilog-end-defun-re nil 'move))
4033
4034(defun verilog-get-beg-of-defun (&optional warn)
4035  (save-excursion
4036    (cond ((verilog-re-search-forward-quick verilog-defun-re nil t)
4037	   (point))
4038	  (t
4039	   (error "%s: Can't find module beginning" (verilog-point-text))
4040	   (point-max)))))
4041(defun verilog-get-end-of-defun (&optional warn)
4042  (save-excursion
4043    (cond ((verilog-re-search-forward-quick verilog-end-defun-re nil t)
4044	   (point))
4045	  (t
4046	   (error "%s: Can't find endmodule" (verilog-point-text))
4047	   (point-max)))))
4048
4049(defun verilog-label-be (&optional arg)
4050  "Label matching begin ... end, fork ... join and case ... endcase statements.
4051With ARG, first kill any existing labels."
4052  (interactive)
4053  (let ((cnt 0)
4054	(oldpos (point))
4055	(b (progn
4056	     (verilog-beg-of-defun)
4057	     (point-marker)))
4058	(e (progn
4059	     (verilog-end-of-defun)
4060	     (point-marker))))
4061    (goto-char (marker-position b))
4062    (if (> (- e b) 200)
4063	(message  "Relabeling module..."))
4064    (while (and
4065	    (> (marker-position e) (point))
4066	    (verilog-re-search-forward
4067	     (concat
4068	      "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\|\\(interface\\)\\|\\(package\\)\\|\\(case\\)\\)?\\>"
4069	      "\\|\\(`endif\\)\\|\\(`else\\)")
4070	     nil 'move))
4071      (goto-char (match-beginning 0))
4072      (let ((indent-str (verilog-indent-line)))
4073	(verilog-set-auto-endcomments indent-str 't)
4074	(end-of-line)
4075	(delete-horizontal-space))
4076      (setq cnt (1+ cnt))
4077      (if (= 9 (% cnt 10))
4078	  (message "%d..." cnt)))
4079    (goto-char oldpos)
4080    (if (or
4081	 (> (- e b) 200)
4082	 (> cnt 20))
4083	(message  "%d lines auto commented" cnt))))
4084
4085(defun verilog-beg-of-statement ()
4086  "Move backward to beginning of statement."
4087  (interactive)
4088  ;; Move back token by token until we see the end
4089  ;; of some earlier line.
4090  (let (h)
4091    (while
4092	;; If the current point does not begin a new
4093	;; statement, as in the character ahead of us is a ';', or SOF
4094	;; or the string after us unambiguously starts a statement,
4095	;; or the token before us unambiguously ends a statement,
4096	;; then move back a token and test again.
4097	(not (or
4098          ;; stop if beginning of buffer
4099	      (bolp)
4100          ;; stop if we find a ;
4101	      (= (preceding-char) ?\;)
4102          ;; stop if we see a named coverpoint
4103	      (looking-at "\\w+\\W*:\\W*\\(coverpoint\\|cross\\|constraint\\)")
4104          ;; keep going if we are in the middle of a word
4105	      (not (or (looking-at "\\<") (forward-word -1)))
4106          ;; stop if we see an assertion (perhaps labeled)
4107	      (and
4108	       (looking-at "\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)")
4109	       (progn
4110             (setq h (point))
4111             (save-excursion
4112               (verilog-backward-token)
4113               (if (looking-at verilog-label-re)
4114                   (setq h (point))))
4115             (goto-char h)))
4116          ;; stop if we see an extended complete reg, perhaps a complete one
4117	      (and
4118           (looking-at verilog-complete-reg)
4119           (let* ((p (point)))
4120             (while (and (looking-at verilog-extended-complete-re)
4121                         (progn (setq p (point))
4122                                (verilog-backward-token)
4123                                (/= p (point)))))
4124             (goto-char p)))
4125          ;; stop if we see a complete reg (previous found extended ones)
4126	      (looking-at verilog-basic-complete-re)
4127          ;; stop if previous token is an ender
4128	      (save-excursion
4129            (verilog-backward-token)
4130            (or
4131             (looking-at verilog-end-block-re)
4132             (looking-at verilog-preprocessor-re))))) ;; end of test
4133    (verilog-backward-syntactic-ws)
4134    (verilog-backward-token))
4135    ;; Now point is where the previous line ended.
4136    (verilog-forward-syntactic-ws)))
4137
4138(defun verilog-beg-of-statement-1 ()
4139  "Move backward to beginning of statement."
4140  (interactive)
4141  (if (verilog-in-comment-p)
4142      (verilog-backward-syntactic-ws))
4143  (let ((pt (point)))
4144    (catch 'done
4145      (while (not (looking-at verilog-complete-reg))
4146        (setq pt (point))
4147        (verilog-backward-syntactic-ws)
4148        (if (or (bolp)
4149                (= (preceding-char) ?\;)
4150		(save-excursion
4151		  (verilog-backward-token)
4152		  (looking-at verilog-ends-re)))
4153            (progn
4154              (goto-char pt)
4155              (throw 'done t))
4156          (verilog-backward-token))))
4157    (verilog-forward-syntactic-ws)))
4158;
4159;    (while (and
4160;            (not (looking-at verilog-complete-reg))
4161;            (not (bolp))
4162;            (not (= (preceding-char) ?\;)))
4163;      (verilog-backward-token)
4164;      (verilog-backward-syntactic-ws)
4165;      (setq pt (point)))
4166;    (goto-char pt)
4167; ;(verilog-forward-syntactic-ws)
4168
4169(defun verilog-end-of-statement ()
4170  "Move forward to end of current statement."
4171  (interactive)
4172  (let ((nest 0) pos)
4173    (cond
4174     ((verilog-in-directive-p)
4175      (forward-line 1)
4176      (backward-char 1))
4177
4178     ((looking-at verilog-beg-block-re)
4179      (verilog-forward-sexp))
4180
4181     ((equal (char-after) ?\})
4182      (forward-char))
4183
4184      ;; Skip to end of statement
4185     ((condition-case nil
4186       (setq pos
4187             (catch 'found
4188               (while t
4189                 (forward-sexp 1)
4190                 (verilog-skip-forward-comment-or-string)
4191                 (if (eolp)
4192                     (forward-line 1))
4193                 (cond ((looking-at "[ \t]*;")
4194                        (skip-chars-forward "^;")
4195                        (forward-char 1)
4196                        (throw 'found (point)))
4197                       ((save-excursion
4198                          (forward-sexp -1)
4199                          (looking-at verilog-beg-block-re))
4200                        (goto-char (match-beginning 0))
4201                        (throw 'found nil))
4202                       ((looking-at "[ \t]*)")
4203                        (throw 'found (point)))
4204                       ((eobp)
4205                        (throw 'found (point)))
4206                       )))
4207
4208             )
4209       (error nil))
4210      (if (not pos)
4211          ;; Skip a whole block
4212          (catch 'found
4213            (while t
4214              (verilog-re-search-forward verilog-end-statement-re nil 'move)
4215              (setq nest (if (match-end 1)
4216                             (1+ nest)
4217                           (1- nest)))
4218              (cond ((eobp)
4219                     (throw 'found (point)))
4220                    ((= 0 nest)
4221                     (throw 'found (verilog-end-of-statement))))))
4222        pos)))))
4223
4224(defun verilog-in-case-region-p ()
4225  "Return true if in a case region.
4226More specifically, point @ in the line foo : @ begin"
4227  (interactive)
4228  (save-excursion
4229    (if (and
4230	 (progn (verilog-forward-syntactic-ws)
4231		(looking-at "\\<begin\\>"))
4232	 (progn (verilog-backward-syntactic-ws)
4233		(= (preceding-char) ?\:)))
4234	(catch 'found
4235	  (let ((nest 1))
4236	    (while t
4237	      (verilog-re-search-backward
4238	       (concat "\\(\\<module\\>\\)\\|\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|"
4239		       "\\(\\<endcase\\>\\)\\>")
4240	       nil 'move)
4241	      (cond
4242	       ((match-end 3)
4243		(setq nest (1+ nest)))
4244	       ((match-end 2)
4245		(if (= nest 1)
4246		(throw 'found 1))
4247		(setq nest (1- nest)))
4248	       (t
4249		(throw 'found (= nest 0)))))))
4250      nil)))
4251
4252(defun verilog-backward-up-list (arg)
4253  "Call `backward-up-list' ARG, ignoring comments."
4254  (let ((parse-sexp-ignore-comments t))
4255    (backward-up-list arg)))
4256
4257(defun verilog-forward-sexp-cmt (arg)
4258  "Call `forward-sexp' ARG, inside comments."
4259  (let ((parse-sexp-ignore-comments nil))
4260    (forward-sexp arg)))
4261
4262(defun verilog-forward-sexp-ign-cmt (arg)
4263  "Call `forward-sexp' ARG, ignoring comments."
4264  (let ((parse-sexp-ignore-comments t))
4265    (forward-sexp arg)))
4266
4267(defun verilog-in-generate-region-p ()
4268  "Return true if in a generate region.
4269More specifically, after a generate and before an endgenerate."
4270  (interactive)
4271  (let ((nest 1))
4272    (save-excursion
4273      (catch 'done
4274	(while (and
4275		(/= nest 0)
4276		(verilog-re-search-backward
4277		 "\\<\\(module\\)\\|\\(generate\\)\\|\\(endgenerate\\)\\>" nil 'move)
4278		(cond
4279		 ((match-end 1) ; module - we have crawled out
4280		  (throw 'done 1))
4281		 ((match-end 2) ; generate
4282		  (setq nest (1- nest)))
4283		 ((match-end 3) ; endgenerate
4284		  (setq nest (1+ nest))))))))
4285    (= nest 0) )) ; return nest
4286
4287(defun verilog-in-fork-region-p ()
4288  "Return true if between a fork and join."
4289  (interactive)
4290  (let ((lim (save-excursion (verilog-beg-of-defun)  (point)))
4291	(nest 1))
4292    (save-excursion
4293      (while (and
4294	      (/= nest 0)
4295	      (verilog-re-search-backward "\\<\\(fork\\)\\|\\(join\\(_any\\|_none\\)?\\)\\>" lim 'move)
4296	      (cond
4297	       ((match-end 1) ; fork
4298		(setq nest (1- nest)))
4299	       ((match-end 2) ; join
4300		(setq nest (1+ nest)))))))
4301    (= nest 0) )) ; return nest
4302
4303(defun verilog-backward-case-item (lim)
4304  "Skip backward to nearest enclosing case item.
4305Limit search to point LIM."
4306  (interactive)
4307  (let ((str 'nil)
4308	(lim1
4309	 (progn
4310	   (save-excursion
4311	     (verilog-re-search-backward verilog-endcomment-reason-re
4312					 lim 'move)
4313	     (point)))))
4314    ;; Try to find the real :
4315    (if (save-excursion (search-backward ":" lim1 t))
4316	(let ((colon 0)
4317	      b e )
4318	  (while
4319	      (and
4320	       (< colon 1)
4321	       (verilog-re-search-backward "\\(\\[\\)\\|\\(\\]\\)\\|\\(:\\)"
4322					   lim1 'move))
4323	    (cond
4324	     ((match-end 1) ;; [
4325	      (setq colon (1+ colon))
4326	      (if (>= colon 0)
4327		  (error "%s: unbalanced [" (verilog-point-text))))
4328	     ((match-end 2) ;; ]
4329	      (setq colon (1- colon)))
4330
4331	     ((match-end 3) ;; :
4332	      (setq colon (1+ colon)))))
4333	  ;; Skip back to beginning of case item
4334	  (skip-chars-backward "\t ")
4335	  (verilog-skip-backward-comment-or-string)
4336	  (setq e (point))
4337	  (setq b
4338		(progn
4339		  (if
4340		      (verilog-re-search-backward
4341		       "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
4342		      (progn
4343			(cond
4344			 ((match-end 1)
4345			  (goto-char (match-end 1))
4346			  (verilog-forward-ws&directives)
4347			  (if (looking-at "(")
4348			      (progn
4349				(forward-sexp)
4350				(verilog-forward-ws&directives)))
4351			  (point))
4352			 (t
4353			  (goto-char (match-end 0))
4354			  (verilog-forward-ws&directives)
4355			  (point))))
4356		    (error "Malformed case item"))))
4357	  (setq str (buffer-substring b e))
4358	  (if
4359	      (setq e
4360		    (string-match
4361		     "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
4362	      (setq str (concat (substring str 0 e) "...")))
4363	  str)
4364      'nil)))
4365
4366
4367;;
4368;; Other functions
4369;;
4370
4371(defun verilog-kill-existing-comment ()
4372  "Kill auto comment on this line."
4373  (save-excursion
4374    (let* (
4375	   (e (progn
4376		(end-of-line)
4377		(point)))
4378	   (b (progn
4379		(beginning-of-line)
4380		(search-forward "//" e t))))
4381      (if b
4382	  (delete-region (- b 2) e)))))
4383
4384(defconst verilog-directive-nest-re
4385  (concat "\\(`else\\>\\)\\|"
4386	  "\\(`endif\\>\\)\\|"
4387	  "\\(`if\\>\\)\\|"
4388	  "\\(`ifdef\\>\\)\\|"
4389	  "\\(`ifndef\\>\\)\\|"
4390	  "\\(`elsif\\>\\)"))
4391(defun verilog-set-auto-endcomments (indent-str kill-existing-comment)
4392  "Add ending comment with given INDENT-STR.
4393With KILL-EXISTING-COMMENT, remove what was there before.
4394Insert `// case: 7 ' or `// NAME ' on this line if appropriate.
4395Insert `// case expr ' if this line ends a case block.
4396Insert `// ifdef FOO ' if this line ends code conditional on FOO.
4397Insert `// NAME ' if this line ends a function, task, module,
4398primitive or interface named NAME."
4399  (save-excursion
4400    (cond
4401     (; Comment close preprocessor directives
4402      (and
4403       (looking-at "\\(`endif\\)\\|\\(`else\\)")
4404       (or  kill-existing-comment
4405	    (not (save-excursion
4406		   (end-of-line)
4407		   (search-backward "//" (point-at-bol) t)))))
4408      (let ((nest 1) b e
4409	    m
4410	    (else (if (match-end 2) "!" " ")))
4411	(end-of-line)
4412	(if kill-existing-comment
4413	    (verilog-kill-existing-comment))
4414	(delete-horizontal-space)
4415	(save-excursion
4416	  (backward-sexp 1)
4417	  (while (and (/= nest 0)
4418		      (verilog-re-search-backward verilog-directive-nest-re nil 'move))
4419	    (cond
4420	     ((match-end 1) ; `else
4421	      (if (= nest 1)
4422		  (setq else "!")))
4423	     ((match-end 2) ; `endif
4424	      (setq nest (1+ nest)))
4425	     ((match-end 3) ; `if
4426	      (setq nest (1- nest)))
4427	     ((match-end 4) ; `ifdef
4428	      (setq nest (1- nest)))
4429	     ((match-end 5) ; `ifndef
4430	      (setq nest (1- nest)))
4431	     ((match-end 6) ; `elsif
4432	      (if (= nest 1)
4433		  (progn
4434		    (setq else "!")
4435		    (setq nest 0))))))
4436	  (if (match-end 0)
4437	      (setq
4438	       m (buffer-substring
4439		  (match-beginning 0)
4440		  (match-end 0))
4441	       b (progn
4442		   (skip-chars-forward "^ \t")
4443		   (verilog-forward-syntactic-ws)
4444		   (point))
4445	       e (progn
4446		   (skip-chars-forward "a-zA-Z0-9_")
4447		   (point)))))
4448	(if b
4449	    (if (> (count-lines (point) b) verilog-minimum-comment-distance)
4450		(insert (concat " // " else m " " (buffer-substring b e))))
4451	  (progn
4452	    (insert " // unmatched `else, `elsif or `endif")
4453	    (ding 't)))))
4454
4455     (; Comment close case/class/function/task/module and named block
4456      (and (looking-at "\\<end")
4457	   (or kill-existing-comment
4458	       (not (save-excursion
4459		      (end-of-line)
4460		      (search-backward "//" (point-at-bol) t)))))
4461      (let ((type (car indent-str)))
4462	(unless (eq type 'declaration)
4463	  (unless (looking-at (concat "\\(" verilog-end-block-ordered-re "\\)[ \t]*:")) ;; ignore named ends
4464	    (if (looking-at verilog-end-block-ordered-re)
4465	      (cond
4466	       (;- This is a case block; search back for the start of this case
4467		(match-end 1) ;; of verilog-end-block-ordered-re
4468
4469		(let ((err 't)
4470		      (str "UNMATCHED!!"))
4471		  (save-excursion
4472		    (verilog-leap-to-head)
4473		    (cond
4474		     ((looking-at "\\<randcase\\>")
4475		      (setq str "randcase")
4476		      (setq err nil))
4477		     ((looking-at "\\(\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?\\)")
4478		      (goto-char (match-end 0))
4479		      (setq str (concat (match-string 0) " " (verilog-get-expr)))
4480		      (setq err nil))
4481		     ))
4482		  (end-of-line)
4483		  (if kill-existing-comment
4484		      (verilog-kill-existing-comment))
4485		  (delete-horizontal-space)
4486		  (insert (concat " // " str ))
4487		  (if err (ding 't))))
4488
4489	       (;- This is a begin..end block
4490		(match-end 2) ;; of verilog-end-block-ordered-re
4491		(let ((str " // UNMATCHED !!")
4492		      (err 't)
4493		      (here (point))
4494		      there
4495		      cntx)
4496		  (save-excursion
4497		    (verilog-leap-to-head)
4498		    (setq there (point))
4499		    (if (not (match-end 0))
4500			(progn
4501			  (goto-char here)
4502			  (end-of-line)
4503			  (if kill-existing-comment
4504			      (verilog-kill-existing-comment))
4505			  (delete-horizontal-space)
4506			  (insert str)
4507			  (ding 't))
4508		      (let ((lim
4509			     (save-excursion (verilog-beg-of-defun) (point)))
4510			    (here (point)))
4511			(cond
4512			 (;-- handle named block differently
4513			  (looking-at verilog-named-block-re)
4514			  (search-forward ":")
4515			  (setq there (point))
4516			  (setq str (verilog-get-expr))
4517			  (setq err nil)
4518			  (setq str (concat " // block: " str )))
4519
4520			 ((verilog-in-case-region-p) ;-- handle case item differently
4521			  (goto-char here)
4522			  (setq str (verilog-backward-case-item lim))
4523			  (setq there (point))
4524			  (setq err nil)
4525			  (setq str (concat " // case: " str )))
4526
4527			 (;- try to find "reason" for this begin
4528			  (cond
4529			   (;
4530			    (eq here (progn
4531				    ;;   (verilog-backward-token)
4532				       (verilog-beg-of-statement)
4533				       (point)))
4534			    (setq err nil)
4535			    (setq str ""))
4536			   ((looking-at verilog-endcomment-reason-re)
4537			    (setq there (match-end 0))
4538			    (setq cntx (concat (match-string 0) " "))
4539			    (cond
4540			     (;- begin
4541			      (match-end 1)
4542			      (setq err nil)
4543			      (save-excursion
4544				(if (and (verilog-continued-line)
4545					 (looking-at "\\<repeat\\>\\|\\<wait\\>\\|\\<always\\>"))
4546				    (progn
4547				      (goto-char (match-end 0))
4548				      (setq there (point))
4549				      (setq str
4550					    (concat " // " (match-string 0) " " (verilog-get-expr))))
4551				  (setq str ""))))
4552
4553			     (;- else
4554			      (match-end 2)
4555			      (let ((nest 0)
4556				    ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)\\|\\(assert\\)"))
4557				(catch 'skip
4558				  (while (verilog-re-search-backward reg nil 'move)
4559				    (cond
4560				     ((match-end 1) ; begin
4561				      (setq nest (1- nest)))
4562				     ((match-end 2)                       ; end
4563				      (setq nest (1+ nest)))
4564				     ((match-end 3)
4565				      (if (= 0 nest)
4566					  (progn
4567					    (goto-char (match-end 0))
4568					    (setq there (point))
4569					    (setq err nil)
4570					    (setq str (verilog-get-expr))
4571					    (setq str (concat " // else: !if" str ))
4572					    (throw 'skip 1))))
4573				     ((match-end 4)
4574				      (if (= 0 nest)
4575					  (progn
4576					    (goto-char (match-end 0))
4577					    (setq there (point))
4578					    (setq err nil)
4579					    (setq str (verilog-get-expr))
4580					    (setq str (concat " // else: !assert " str ))
4581					    (throw 'skip 1)))))))))
4582			     (;- end else
4583			      (match-end 3)
4584			      (goto-char there)
4585			      (let ((nest 0)
4586				    (reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)\\|\\(assert\\)"))
4587				(catch 'skip
4588				  (while (verilog-re-search-backward reg nil 'move)
4589				    (cond
4590				     ((match-end 1) ; begin
4591				      (setq nest (1- nest)))
4592				     ((match-end 2)                       ; end
4593				      (setq nest (1+ nest)))
4594				     ((match-end 3)
4595				      (if (= 0 nest)
4596					  (progn
4597					    (goto-char (match-end 0))
4598					    (setq there (point))
4599					    (setq err nil)
4600					    (setq str (verilog-get-expr))
4601					    (setq str (concat " // else: !if" str ))
4602					    (throw 'skip 1))))
4603				     ((match-end 4)
4604				      (if (= 0 nest)
4605					  (progn
4606					    (goto-char (match-end 0))
4607					    (setq there (point))
4608					    (setq err nil)
4609					    (setq str (verilog-get-expr))
4610					    (setq str (concat " // else: !assert " str ))
4611					    (throw 'skip 1)))))))))
4612
4613			     (; always_comb, always_ff, always_latch
4614			      (or (match-end 4) (match-end 5) (match-end 6))
4615			      (goto-char (match-end 0))
4616			      (setq there (point))
4617			      (setq err nil)
4618			      (setq str (concat " // " cntx )))
4619
4620			     (;- task/function/initial et cetera
4621			      t
4622			      (match-end 0)
4623			      (goto-char (match-end 0))
4624			      (setq there (point))
4625			      (setq err nil)
4626			      (setq str (concat " // " cntx (verilog-get-expr))))
4627
4628			     (;-- otherwise...
4629			      (setq str " // auto-endcomment confused "))))
4630
4631			   ((and
4632			     (verilog-in-case-region-p) ;-- handle case item differently
4633			     (progn
4634			       (setq there (point))
4635			       (goto-char here)
4636			       (setq str (verilog-backward-case-item lim))))
4637			    (setq err nil)
4638			    (setq str (concat " // case: " str )))
4639
4640			   ((verilog-in-fork-region-p)
4641			    (setq err nil)
4642			    (setq str " // fork branch" ))
4643
4644			   ((looking-at "\\<end\\>")
4645			    ;; HERE
4646			    (forward-word 1)
4647			    (verilog-forward-syntactic-ws)
4648			    (setq err nil)
4649			    (setq str (verilog-get-expr))
4650			    (setq str (concat " // " cntx str )))
4651
4652			   ))))
4653		      (goto-char here)
4654		      (end-of-line)
4655		      (if kill-existing-comment
4656			  (verilog-kill-existing-comment))
4657		      (delete-horizontal-space)
4658		      (if (or err
4659			      (> (count-lines here there) verilog-minimum-comment-distance))
4660			  (insert str))
4661		      (if err (ding 't))
4662		      ))))
4663	       (;- this is endclass, which can be nested
4664		(match-end 11) ;; of verilog-end-block-ordered-re
4665		;;(goto-char there)
4666		(let ((nest 0)
4667		      (reg "\\<\\(class\\)\\|\\(endclass\\)\\|\\(package\\|primitive\\|\\(macro\\)?module\\)\\>")
4668		      string)
4669		  (save-excursion
4670		    (catch 'skip
4671		      (while (verilog-re-search-backward reg nil 'move)
4672			(cond
4673			 ((match-end 3)	; endclass
4674			  (ding 't)
4675			  (setq string "unmatched endclass")
4676			  (throw 'skip 1))
4677
4678			 ((match-end 2)	; endclass
4679			  (setq nest (1+ nest)))
4680
4681			 ((match-end 1) ; class
4682			  (setq nest (1- nest))
4683			  (if (< nest 0)
4684			      (progn
4685				(goto-char (match-end 0))
4686				(let (b e)
4687				  (setq b (progn
4688					    (skip-chars-forward "^ \t")
4689					    (verilog-forward-ws&directives)
4690					    (point))
4691					e (progn
4692					    (skip-chars-forward "a-zA-Z0-9_")
4693					    (point)))
4694				  (setq string (buffer-substring b e)))
4695				(throw 'skip 1))))
4696			 ))))
4697		  (end-of-line)
4698		  (insert (concat " // " string ))))
4699
4700	       (;- this is end{function,generate,task,module,primitive,table,generate}
4701		;- which can not be nested.
4702		t
4703		(let (string reg (name-re nil))
4704		  (end-of-line)
4705		  (if kill-existing-comment
4706		      (save-match-data
4707		       (verilog-kill-existing-comment)))
4708		  (delete-horizontal-space)
4709		  (backward-sexp)
4710		  (cond
4711		   ((match-end 5) ;; of verilog-end-block-ordered-re
4712		    (setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
4713		    (setq name-re "\\w+\\s-*("))
4714		   ((match-end 6) ;; of verilog-end-block-ordered-re
4715		    (setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
4716		    (setq name-re "\\w+\\s-*("))
4717		   ((match-end 7) ;; of verilog-end-block-ordered-re
4718		    (setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>"))
4719		   ((match-end 8) ;; of verilog-end-block-ordered-re
4720		    (setq reg "\\(\\<primitive\\>\\)\\|\\(\\<\\(endprimitive\\|package\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4721		   ((match-end 9) ;; of verilog-end-block-ordered-re
4722		    (setq reg "\\(\\<interface\\>\\)\\|\\(\\<\\(endinterface\\|package\\|primitive\\|\\(macro\\)?module\\)\\>\\)"))
4723		   ((match-end 10) ;; of verilog-end-block-ordered-re
4724		    (setq reg "\\(\\<package\\>\\)\\|\\(\\<\\(endpackage\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4725		   ((match-end 11) ;; of verilog-end-block-ordered-re
4726		    (setq reg "\\(\\<class\\>\\)\\|\\(\\<\\(endclass\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4727		   ((match-end 12) ;; of verilog-end-block-ordered-re
4728		    (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<\\(endcovergroup\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4729		   ((match-end 13) ;; of verilog-end-block-ordered-re
4730		    (setq reg "\\(\\<program\\>\\)\\|\\(\\<\\(endprogram\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4731		   ((match-end 14) ;; of verilog-end-block-ordered-re
4732		    (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<\\(endsequence\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4733		   ((match-end 15) ;; of verilog-end-block-ordered-re
4734		    (setq reg "\\(\\<clocking\\>\\)\\|\\<endclocking\\>"))
4735
4736		   (t (error "Problem in verilog-set-auto-endcomments")))
4737		  (let (b e)
4738		    (save-excursion
4739		      (verilog-re-search-backward reg nil 'move)
4740		      (cond
4741		       ((match-end 1)
4742			(setq b (progn
4743				  (skip-chars-forward "^ \t")
4744				  (verilog-forward-ws&directives)
4745				  (if (looking-at "static\\|automatic")
4746				      (progn
4747					(goto-char (match-end 0))
4748					(verilog-forward-ws&directives)))
4749				  (if (and name-re (verilog-re-search-forward name-re nil 'move))
4750				      (progn
4751					(goto-char (match-beginning 0))
4752					(verilog-forward-ws&directives)))
4753				  (point))
4754			      e (progn
4755				  (skip-chars-forward "a-zA-Z0-9_")
4756				  (point)))
4757			(setq string (buffer-substring b e)))
4758		       (t
4759			(ding 't)
4760			(setq string "unmatched end(function|task|module|primitive|interface|package|class|clocking)")))))
4761		  (end-of-line)
4762		  (insert (concat " // " string )))
4763		))))))))))
4764
4765(defun verilog-get-expr()
4766  "Grab expression at point, e.g, case ( a | b & (c ^d))."
4767  (let* ((b (progn
4768	      (verilog-forward-syntactic-ws)
4769	      (skip-chars-forward " \t")
4770	      (point)))
4771	 (e (let ((par 1))
4772	      (cond
4773	       ((looking-at "@")
4774		(forward-char 1)
4775		(verilog-forward-syntactic-ws)
4776		(if (looking-at "(")
4777		    (progn
4778		      (forward-char 1)
4779		      (while (and (/= par 0)
4780				  (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
4781			(cond
4782			 ((match-end 1)
4783			  (setq par (1+ par)))
4784			 ((match-end 2)
4785			  (setq par (1- par)))))))
4786		(point))
4787	       ((looking-at "(")
4788		(forward-char 1)
4789		(while (and (/= par 0)
4790			    (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
4791		  (cond
4792		   ((match-end 1)
4793		    (setq par (1+ par)))
4794		   ((match-end 2)
4795		    (setq par (1- par)))))
4796		(point))
4797	       ((looking-at "\\[")
4798		(forward-char 1)
4799		(while (and (/= par 0)
4800			    (verilog-re-search-forward "\\(\\[\\)\\|\\(\\]\\)" nil 'move))
4801		  (cond
4802		   ((match-end 1)
4803		    (setq par (1+ par)))
4804		   ((match-end 2)
4805		    (setq par (1- par)))))
4806		(verilog-forward-syntactic-ws)
4807		(skip-chars-forward "^ \t\n\f")
4808		(point))
4809	       ((looking-at "/[/\\*]")
4810		b)
4811	       ('t
4812		(skip-chars-forward "^: \t\n\f")
4813		(point)))))
4814	 (str (buffer-substring b e)))
4815    (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
4816	(setq str (concat (substring str 0 e) "...")))
4817    str))
4818
4819(defun verilog-expand-vector ()
4820  "Take a signal vector on the current line and expand it to multiple lines.
4821Useful for creating tri's and other expanded fields."
4822  (interactive)
4823  (verilog-expand-vector-internal "[" "]"))
4824
4825(defun verilog-expand-vector-internal (bra ket)
4826  "Given BRA, the start brace and KET, the end brace, expand one line into many lines."
4827  (save-excursion
4828    (forward-line 0)
4829    (let ((signal-string (buffer-substring (point)
4830					   (progn
4831					     (end-of-line) (point)))))
4832      (if (string-match
4833	   (concat "\\(.*\\)"
4834		   (regexp-quote bra)
4835		   "\\([0-9]*\\)\\(:[0-9]*\\|\\)\\(::[0-9---]*\\|\\)"
4836		   (regexp-quote ket)
4837		   "\\(.*\\)$") signal-string)
4838	  (let* ((sig-head (match-string 1 signal-string))
4839		 (vec-start (string-to-number (match-string 2 signal-string)))
4840		 (vec-end (if (= (match-beginning 3) (match-end 3))
4841			      vec-start
4842			    (string-to-number
4843			     (substring signal-string (1+ (match-beginning 3))
4844					(match-end 3)))))
4845		 (vec-range
4846		  (if (= (match-beginning 4) (match-end 4))
4847		      1
4848		    (string-to-number
4849		     (substring signal-string (+ 2 (match-beginning 4))
4850				(match-end 4)))))
4851		 (sig-tail (match-string 5 signal-string))
4852		 vec)
4853	    ;; Decode vectors
4854	    (setq vec nil)
4855	    (if (< vec-range 0)
4856		(let ((tmp vec-start))
4857		  (setq vec-start vec-end
4858			vec-end tmp
4859			vec-range (- vec-range))))
4860	    (if (< vec-end vec-start)
4861		(while (<= vec-end vec-start)
4862		  (setq vec (append vec (list vec-start)))
4863		  (setq vec-start (- vec-start vec-range)))
4864	      (while (<= vec-start vec-end)
4865		(setq vec (append vec (list vec-start)))
4866		(setq vec-start (+ vec-start vec-range))))
4867	    ;;
4868	    ;; Delete current line
4869	    (delete-region (point) (progn (forward-line 0) (point)))
4870	    ;;
4871	    ;; Expand vector
4872	    (while vec
4873	      (insert (concat sig-head bra
4874			      (int-to-string (car vec)) ket sig-tail "\n"))
4875	      (setq vec (cdr vec)))
4876	    (delete-char -1)
4877	    ;;
4878	    )))))
4879
4880(defun verilog-strip-comments ()
4881  "Strip all comments from the Verilog code."
4882  (interactive)
4883  (goto-char (point-min))
4884  (while (re-search-forward "//" nil t)
4885    (if (verilog-within-string)
4886	(re-search-forward "\"" nil t)
4887      (if (verilog-in-star-comment-p)
4888	  (re-search-forward "\*/" nil t)
4889	(let ((bpt (- (point) 2)))
4890	  (end-of-line)
4891	  (delete-region bpt (point))))))
4892    ;;
4893  (goto-char (point-min))
4894  (while (re-search-forward "/\\*" nil t)
4895    (if (verilog-within-string)
4896	(re-search-forward "\"" nil t)
4897      (let ((bpt (- (point) 2)))
4898	(re-search-forward "\\*/")
4899	(delete-region bpt (point))))))
4900
4901(defun verilog-one-line ()
4902  "Convert structural Verilog instances to occupy one line."
4903  (interactive)
4904  (goto-char (point-min))
4905  (while (re-search-forward "\\([^;]\\)[ \t]*\n[ \t]*" nil t)
4906	(replace-match "\\1 " nil nil)))
4907
4908(defun verilog-linter-name ()
4909  "Return name of linter, either surelint or verilint."
4910  (let ((compile-word1 (verilog-string-replace-matches "\\s .*$" "" nil nil
4911						       compile-command))
4912	(lint-word1    (verilog-string-replace-matches "\\s .*$" "" nil nil
4913						       verilog-linter)))
4914    (cond ((equal compile-word1 "surelint") `surelint)
4915	  ((equal compile-word1 "verilint") `verilint)
4916	  ((equal lint-word1 "surelint")    `surelint)
4917	  ((equal lint-word1 "verilint")    `verilint)
4918	  (t `surelint))))  ;; back compatibility
4919
4920(defun verilog-lint-off ()
4921  "Convert a Verilog linter warning line into a disable statement.
4922For example:
4923	pci_bfm_null.v, line  46: Unused input: pci_rst_
4924becomes a comment for the appropriate tool.
4925
4926The first word of the `compile-command' or `verilog-linter'
4927variables is used to determine which product is being used.
4928
4929See \\[verilog-surelint-off] and \\[verilog-verilint-off]."
4930  (interactive)
4931  (let ((linter (verilog-linter-name)))
4932    (cond ((equal linter `surelint)
4933	   (verilog-surelint-off))
4934	  ((equal linter `verilint)
4935	   (verilog-verilint-off))
4936	  (t (error "Linter name not set")))))
4937
4938(defvar compilation-last-buffer)
4939(defvar next-error-last-buffer)
4940
4941(defun verilog-surelint-off ()
4942  "Convert a SureLint warning line into a disable statement.
4943Run from Verilog source window; assumes there is a *compile* buffer
4944with point set appropriately.
4945
4946For example:
4947	WARNING [STD-UDDONX]: xx.v, line 8: output out is never assigned.
4948becomes:
4949	// surefire lint_line_off UDDONX"
4950  (interactive)
4951  (let ((buff (if (boundp 'next-error-last-buffer)
4952                  next-error-last-buffer
4953                compilation-last-buffer)))
4954    (when (buffer-live-p buff)
4955      (save-excursion
4956        (switch-to-buffer buff)
4957        (beginning-of-line)
4958        (when
4959            (looking-at "\\(INFO\\|WARNING\\|ERROR\\) \\[[^-]+-\\([^]]+\\)\\]: \\([^,]+\\), line \\([0-9]+\\): \\(.*\\)$")
4960          (let* ((code (match-string 2))
4961                 (file (match-string 3))
4962                 (line (match-string 4))
4963                 (buffer (get-file-buffer file))
4964                 dir filename)
4965            (unless buffer
4966              (progn
4967                (setq buffer
4968                      (and (file-exists-p file)
4969                           (find-file-noselect file)))
4970                (or buffer
4971                    (let* ((pop-up-windows t))
4972                      (let ((name (expand-file-name
4973                                   (read-file-name
4974                                    (format "Find this error in: (default %s) "
4975                                            file)
4976                                    dir file t))))
4977                        (if (file-directory-p name)
4978                            (setq name (expand-file-name filename name)))
4979                        (setq buffer
4980                              (and (file-exists-p name)
4981                                   (find-file-noselect name))))))))
4982            (switch-to-buffer buffer)
4983            (goto-char (point-min))
4984            (forward-line (- (string-to-number line)))
4985            (end-of-line)
4986            (catch 'already
4987              (cond
4988               ((verilog-in-slash-comment-p)
4989                (re-search-backward "//")
4990                (cond
4991                 ((looking-at "// surefire lint_off_line ")
4992                  (goto-char (match-end 0))
4993                  (let ((lim (point-at-eol)))
4994                    (if (re-search-forward code lim 'move)
4995                        (throw 'already t)
4996                      (insert (concat " " code)))))
4997                 (t
4998                  )))
4999               ((verilog-in-star-comment-p)
5000                (re-search-backward "/\*")
5001                (insert (format " // surefire lint_off_line %6s" code )))
5002               (t
5003                (insert (format " // surefire lint_off_line %6s" code ))
5004                )))))))))
5005
5006(defun verilog-verilint-off ()
5007  "Convert a Verilint warning line into a disable statement.
5008
5009For example:
5010	(W240)  pci_bfm_null.v, line  46: Unused input: pci_rst_
5011becomes:
5012	//Verilint 240 off // WARNING: Unused input"
5013  (interactive)
5014  (save-excursion
5015    (beginning-of-line)
5016    (when (looking-at "\\(.*\\)([WE]\\([0-9A-Z]+\\)).*,\\s +line\\s +[0-9]+:\\s +\\([^:\n]+\\):?.*$")
5017      (replace-match (format
5018		      ;; %3s makes numbers 1-999 line up nicely
5019		      "\\1//Verilint %3s off // WARNING: \\3"
5020		      (match-string 2)))
5021      (beginning-of-line)
5022      (verilog-indent-line))))
5023
5024(defun verilog-auto-save-compile ()
5025  "Update automatics with \\[verilog-auto], save the buffer, and compile."
5026  (interactive)
5027  (verilog-auto)	; Always do it for safety
5028  (save-buffer)
5029  (compile compile-command))
5030
5031(defun verilog-preprocess (&optional command filename)
5032  "Preprocess the buffer, similar to `compile', but put output in Verilog-Mode.
5033Takes optional COMMAND or defaults to `verilog-preprocessor', and
5034FILENAME to find directory to run in, or defaults to `buffer-file-name`."
5035  (interactive
5036   (list
5037    (let ((default (verilog-expand-command verilog-preprocessor)))
5038      (set (make-local-variable `verilog-preprocessor)
5039	      (read-from-minibuffer "Run Preprocessor (like this): "
5040				     default nil nil
5041				      'verilog-preprocess-history default)))))
5042  (unless command (setq command (verilog-expand-command verilog-preprocessor)))
5043  (let* ((fontlocked (and (boundp 'font-lock-mode) font-lock-mode))
5044	  (dir (file-name-directory (or filename buffer-file-name)))
5045	   (cmd (concat "cd " dir "; " command)))
5046    (with-output-to-temp-buffer "*Verilog-Preprocessed*"
5047      (with-current-buffer (get-buffer "*Verilog-Preprocessed*")
5048	(insert (concat "// " cmd "\n"))
5049	(call-process shell-file-name nil t nil shell-command-switch cmd)
5050	(verilog-mode)
5051	;; Without this force, it takes a few idle seconds
5052	;; to get the color, which is very jarring
5053	(when fontlocked (font-lock-fontify-buffer))))))
5054
5055
5056;;
5057;; Batch
5058;;
5059
5060(defun verilog-warn (string &rest args)
5061  "Print a warning with `format' using STRING and optional ARGS."
5062  (apply 'message (concat "%%Warning: " string) args))
5063
5064(defun verilog-warn-error (string &rest args)
5065  "Call `error' using STRING and optional ARGS.
5066If `verilog-warn-fatal' is non-nil, call `verilog-warn' instead."
5067  (if verilog-warn-fatal
5068      (apply 'error string args)
5069    (apply 'verilog-warn string args)))
5070
5071(defmacro verilog-batch-error-wrapper (&rest body)
5072  "Execute BODY and add error prefix to any errors found.
5073This lets programs calling batch mode to easily extract error messages."
5074  `(let ((verilog-warn-fatal nil))
5075     (condition-case err
5076	 (progn ,@body)
5077       (error
5078	(error "%%Error: %s%s" (error-message-string err)
5079	       (if (featurep 'xemacs) "\n" ""))))))  ;; XEmacs forgets to add a newline
5080
5081(defun verilog-batch-execute-func (funref &optional no-save)
5082  "Internal processing of a batch command.
5083Runs FUNREF on all command arguments.
5084Save the result unless optional NO-SAVE is t."
5085  (verilog-batch-error-wrapper
5086   ;; Setting global variables like that is *VERY NASTY* !!!  --Stef
5087   ;; However, this function is called only when Emacs is being used as
5088   ;; a standalone language instead of as an editor, so we'll live.
5089   ;;
5090   ;; General globals needed
5091   (setq make-backup-files nil)
5092   (setq-default make-backup-files nil)
5093   (setq enable-local-variables t)
5094   (setq enable-local-eval t)
5095   ;; Make sure any sub-files we read get proper mode
5096   (setq-default major-mode 'verilog-mode)
5097   ;; Ditto files already read in
5098   (mapc (lambda (buf)
5099	   (when (buffer-file-name buf)
5100	     (with-current-buffer buf
5101	       (verilog-mode))))
5102	 (buffer-list))
5103   ;; Process the files
5104   (mapcar (lambda (buf)
5105	     (when (buffer-file-name buf)
5106	       (save-excursion
5107		 (if (not (file-exists-p (buffer-file-name buf)))
5108		     (error
5109		      (concat "File not found: " (buffer-file-name buf))))
5110		 (message (concat "Processing " (buffer-file-name buf)))
5111		 (set-buffer buf)
5112		 (funcall funref)
5113		 (unless no-save (save-buffer)))))
5114	   (buffer-list))))
5115
5116(defun verilog-batch-auto ()
5117  "For use with --batch, perform automatic expansions as a stand-alone tool.
5118This sets up the appropriate Verilog mode environment, updates automatics
5119with \\[verilog-auto] on all command-line files, and saves the buffers.
5120For proper results, multiple filenames need to be passed on the command
5121line in bottom-up order."
5122  (unless noninteractive
5123    (error "Use verilog-batch-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
5124  (verilog-batch-execute-func `verilog-auto))
5125
5126(defun verilog-batch-delete-auto ()
5127  "For use with --batch, perform automatic deletion as a stand-alone tool.
5128This sets up the appropriate Verilog mode environment, deletes automatics
5129with \\[verilog-delete-auto] on all command-line files, and saves the buffers."
5130  (unless noninteractive
5131    (error "Use verilog-batch-delete-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
5132  (verilog-batch-execute-func `verilog-delete-auto))
5133
5134(defun verilog-batch-diff-auto ()
5135  "For use with --batch, perform automatic differences as a stand-alone tool.
5136This sets up the appropriate Verilog mode environment, expand automatics
5137with \\[verilog-diff-auto] on all command-line files, and reports an error
5138if any differences are observed.  This is appropriate for adding to regressions
5139to insure automatics are always properly maintained."
5140  (unless noninteractive
5141    (error "Use verilog-batch-diff-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
5142  (verilog-batch-execute-func `verilog-diff-auto t))
5143
5144(defun verilog-batch-inject-auto ()
5145  "For use with --batch, perform automatic injection as a stand-alone tool.
5146This sets up the appropriate Verilog mode environment, injects new automatics
5147with \\[verilog-inject-auto] on all command-line files, and saves the buffers.
5148For proper results, multiple filenames need to be passed on the command
5149line in bottom-up order."
5150  (unless noninteractive
5151    (error "Use verilog-batch-inject-auto only with --batch"))  ;; Otherwise we'd mess up buffer modes
5152  (verilog-batch-execute-func `verilog-inject-auto))
5153
5154(defun verilog-batch-indent ()
5155  "For use with --batch, reindent an entire file as a stand-alone tool.
5156This sets up the appropriate Verilog mode environment, calls
5157\\[verilog-indent-buffer] on all command-line files, and saves the buffers."
5158  (unless noninteractive
5159    (error "Use verilog-batch-indent only with --batch"))  ;; Otherwise we'd mess up buffer modes
5160  (verilog-batch-execute-func `verilog-indent-buffer))
5161
5162
5163;;
5164;; Indentation
5165;;
5166(defconst verilog-indent-alist
5167  '((block       . (+ ind verilog-indent-level))
5168    (case        . (+ ind verilog-case-indent))
5169    (cparenexp   . (+ ind verilog-indent-level))
5170    (cexp        . (+ ind verilog-cexp-indent))
5171    (defun       . verilog-indent-level-module)
5172    (declaration . verilog-indent-level-declaration)
5173    (directive   . (verilog-calculate-indent-directive))
5174    (tf          . verilog-indent-level)
5175    (behavioral  . (+ verilog-indent-level-behavioral verilog-indent-level-module))
5176    (statement   . ind)
5177    (cpp         . 0)
5178    (comment     . (verilog-comment-indent))
5179    (unknown     . 3)
5180    (string      . 0)))
5181
5182(defun verilog-continued-line-1 (lim)
5183  "Return true if this is a continued line.
5184Set point to where line starts.  Limit search to point LIM."
5185  (let ((continued 't))
5186    (if (eq 0 (forward-line -1))
5187	(progn
5188	  (end-of-line)
5189	  (verilog-backward-ws&directives lim)
5190	  (if (bobp)
5191	      (setq continued nil)
5192	    (setq continued (verilog-backward-token))))
5193      (setq continued nil))
5194    continued))
5195
5196(defun verilog-calculate-indent ()
5197  "Calculate the indent of the current Verilog line.
5198Examine previous lines.  Once a line is found that is definitive as to the
5199type of the current line, return that lines' indent level and its type.
5200Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
5201  (save-excursion
5202    (let* ((starting_position (point))
5203	   (par 0)
5204	   (begin (looking-at "[ \t]*begin\\>"))
5205	   (lim (save-excursion (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)" nil t)))
5206	   (type (catch 'nesting
5207		   ;; Keep working backwards until we can figure out
5208		   ;; what type of statement this is.
5209		   ;; Basically we need to figure out
5210		   ;; 1) if this is a continuation of the previous line;
5211		   ;; 2) are we in a block scope (begin..end)
5212
5213		   ;; if we are in a comment, done.
5214		   (if (verilog-in-star-comment-p)
5215		       (throw 'nesting 'comment))
5216
5217		   ;; if we have a directive, done.
5218		   (if (save-excursion (beginning-of-line)
5219				       (and (looking-at verilog-directive-re-1)
5220					    (not (or (looking-at "[ \t]*`[ou]vm_")
5221                                 (looking-at "[ \t]*`vmm_")))))
5222		       (throw 'nesting 'directive))
5223           ;; indent structs as if there were module level
5224           (if (verilog-in-struct-p)
5225               (throw 'nesting 'block))
5226
5227	   ;; if we are in a parenthesized list, and the user likes to indent these, return.
5228	   ;; unless we are in the newfangled coverpoint or constraint blocks
5229	   (if (and
5230                verilog-indent-lists
5231                (verilog-in-paren)
5232                (not (verilog-in-coverage-p))
5233                )
5234	       (progn (setq par 1)
5235                      (throw 'nesting 'block)))
5236
5237	   ;; See if we are continuing a previous line
5238	   (while t
5239	     ;; trap out if we crawl off the top of the buffer
5240	     (if (bobp) (throw 'nesting 'cpp))
5241
5242	     (if (verilog-continued-line-1 lim)
5243		 (let ((sp (point)))
5244		   (if (and
5245			(not (looking-at verilog-complete-reg))
5246			(verilog-continued-line-1 lim))
5247		       (progn (goto-char sp)
5248			      (throw 'nesting 'cexp))
5249
5250		     (goto-char sp))
5251
5252		   (if (and begin
5253			    (not verilog-indent-begin-after-if)
5254			    (looking-at verilog-no-indent-begin-re))
5255		       (progn
5256			 (beginning-of-line)
5257			 (skip-chars-forward " \t")
5258			 (throw 'nesting 'statement))
5259		     (progn
5260		       (throw 'nesting 'cexp))))
5261	       ;; not a continued line
5262	       (goto-char starting_position))
5263
5264	     (if (looking-at "\\<else\\>")
5265		 ;; search back for governing if, striding across begin..end pairs
5266		 ;; appropriately
5267		 (let ((elsec 1))
5268		   (while (verilog-re-search-backward verilog-ends-re nil 'move)
5269		     (cond
5270		      ((match-end 1) ; else, we're in deep
5271		       (setq elsec (1+ elsec)))
5272		      ((match-end 2) ; if
5273		       (setq elsec (1- elsec))
5274		       (if (= 0 elsec)
5275			   (if verilog-align-ifelse
5276			       (throw 'nesting 'statement)
5277			     (progn ;; back up to first word on this line
5278			       (beginning-of-line)
5279			       (verilog-forward-syntactic-ws)
5280			       (throw 'nesting 'statement)))))
5281		      ((match-end 3) ; assert block
5282		       (setq elsec (1- elsec))
5283		       (verilog-beg-of-statement) ;; doesn't get to beginning
5284		       (if (looking-at verilog-property-re)
5285			   (throw 'nesting 'statement) ; We don't need an endproperty for these
5286			 (throw 'nesting 'block)	;We still need an endproperty
5287			 ))
5288		      (t ; endblock
5289					; try to leap back to matching outward block by striding across
5290					; indent level changing tokens then immediately
5291					; previous line governs indentation.
5292		       (let (( reg) (nest 1))
5293			 ;;	 verilog-ends =>  else|if|end|join(_any|_none|)|endcase|endclass|endtable|endspecify|endfunction|endtask|endgenerate|endgroup
5294			 (cond
5295			  ((match-end 4) ; end
5296			   ;; Search back for matching begin
5297			   (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
5298			  ((match-end 5) ; endcase
5299			   ;; Search back for matching case
5300			   (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
5301			  ((match-end 6) ; endfunction
5302			   ;; Search back for matching function
5303			   (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
5304			  ((match-end 7) ; endtask
5305			   ;; Search back for matching task
5306			   (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
5307			  ((match-end 8) ; endspecify
5308			   ;; Search back for matching specify
5309			   (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
5310			  ((match-end 9) ; endtable
5311			   ;; Search back for matching table
5312			   (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
5313			  ((match-end 10) ; endgenerate
5314			   ;; Search back for matching generate
5315			   (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
5316			  ((match-end 11) ; joins
5317			   ;; Search back for matching fork
5318			   (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|none\\)?\\>\\)" ))
5319			  ((match-end 12) ; class
5320			   ;; Search back for matching class
5321			   (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
5322			  ((match-end 13) ; covergroup
5323			   ;; Search back for matching covergroup
5324			   (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" )))
5325			 (catch 'skip
5326			   (while (verilog-re-search-backward reg nil 'move)
5327			     (cond
5328			      ((match-end 1) ; begin
5329			       (setq nest (1- nest))
5330			       (if (= 0 nest)
5331				   (throw 'skip 1)))
5332			      ((match-end 2) ; end
5333			       (setq nest (1+ nest)))))
5334			   )))))))
5335	     (throw 'nesting (verilog-calc-1)))
5336	   );; catch nesting
5337		 );; type
5338	   )
5339      ;; Return type of block and indent level.
5340      (if (not type)
5341	  (setq type 'cpp))
5342      (if (> par 0)			; Unclosed Parenthesis
5343	  (list 'cparenexp par)
5344	(cond
5345	  ((eq type 'case)
5346	   (list type (verilog-case-indent-level)))
5347	  ((eq type 'statement)
5348	   (list type (current-column)))
5349	  ((eq type 'defun)
5350	   (list type 0))
5351	  (t
5352	   (list type (verilog-current-indent-level))))))))
5353
5354(defun verilog-wai ()
5355  "Show matching nesting block for debugging."
5356  (interactive)
5357  (save-excursion
5358    (let* ((type (verilog-calc-1))
5359	   depth)
5360      ;; Return type of block and indent level.
5361      (if (not type)
5362	  (setq type 'cpp))
5363      (if (and
5364	   verilog-indent-lists
5365	   (not(or (verilog-in-coverage-p)
5366               (verilog-in-struct-p)))
5367	   (verilog-in-paren))
5368	  (setq depth 1)
5369	(cond
5370	  ((eq type 'case)
5371	   (setq depth (verilog-case-indent-level)))
5372	  ((eq type 'statement)
5373	   (setq depth (current-column)))
5374	  ((eq type 'defun)
5375	   (setq depth 0))
5376	  (t
5377	   (setq depth (verilog-current-indent-level)))))
5378      (message "You are at nesting %s depth %d" type depth))))
5379(defun verilog-calc-1 ()
5380  (catch 'nesting
5381    (let ((re (concat "\\({\\|}\\|" verilog-indent-re "\\)")))
5382      (while (verilog-re-search-backward re nil 'move)
5383	(catch 'continue
5384	  (cond
5385	   ((equal (char-after) ?\{)
5386	    (if (verilog-at-constraint-p)
5387		(throw 'nesting 'block)))
5388
5389	   ((equal (char-after) ?\})
5390	    (let ((there (verilog-at-close-constraint-p)))
5391	      (if there ;; we are at the } that closes a constraint.  Find the { that opens it
5392		  (progn
5393		    (forward-char 1)
5394		    (backward-list 1)
5395		    (verilog-beg-of-statement)))))
5396
5397	   ((looking-at verilog-beg-block-re-ordered)
5398	    (cond
5399	     ((match-end 2)  ; *sigh* could be "unique case" or "priority casex"
5400	      (let ((here (point)))
5401		(verilog-beg-of-statement)
5402		(if (looking-at verilog-extended-case-re)
5403		    (throw 'nesting 'case)
5404		  (goto-char here)))
5405	      (throw 'nesting 'case))
5406
5407	     ((match-end 4)  ; *sigh* could be "disable fork"
5408	      (let ((here (point)))
5409		(verilog-beg-of-statement)
5410		(if (looking-at verilog-disable-fork-re)
5411		    t ; this is a normal statement
5412		  (progn ; or is fork, starts a new block
5413		    (goto-char here)
5414		    (throw 'nesting 'block)))))
5415
5416	     ((match-end 27)  ; *sigh* might be a clocking declaration
5417	      (let ((here (point)))
5418		(if (verilog-in-paren)
5419		    t ; this is a normal statement
5420		  (progn ; or is fork, starts a new block
5421		    (goto-char here)
5422		    (throw 'nesting 'block)))))
5423
5424	     ;; need to consider typedef struct here...
5425	     ((looking-at "\\<class\\|struct\\|function\\|task\\>")
5426					; *sigh* These words have an optional prefix:
5427					; extern {virtual|protected}? function a();
5428	                                ; typedef class foo;
5429					; and we don't want to confuse this with
5430					; function a();
5431	                                ; property
5432					; ...
5433					; endfunction
5434	      (verilog-beg-of-statement)
5435	      (if (looking-at verilog-beg-block-re-ordered)
5436              (throw 'nesting 'block)
5437            (throw 'nesting 'defun)))
5438
5439         ;;
5440	     ((looking-at "\\<property\\>")
5441					; *sigh*
5442					;    {assert|assume|cover} property (); are complete
5443	                                ;   and could also be labeled: - foo: assert property
5444					; but
5445                                        ;    property ID () ... needs end_property
5446	      (verilog-beg-of-statement)
5447	      (if (looking-at verilog-property-re)
5448		  (throw 'continue 'statement) ; We don't need an endproperty for these
5449		(throw 'nesting 'block)	;We still need an endproperty
5450		))
5451
5452	     (t              (throw 'nesting 'block))))
5453
5454	   ((looking-at verilog-end-block-re)
5455	    (verilog-leap-to-head)
5456	    (if (verilog-in-case-region-p)
5457		(progn
5458		  (verilog-leap-to-case-head)
5459		  (if (looking-at verilog-extended-case-re)
5460		      (throw 'nesting 'case)))))
5461
5462	   ((looking-at verilog-defun-level-re)
5463	    (if (looking-at verilog-defun-level-generate-only-re)
5464		(if (verilog-in-generate-region-p)
5465		    (throw 'continue 'foo)  ; always block in a generate - keep looking
5466		  (throw 'nesting 'defun))
5467	      (throw 'nesting 'defun)))
5468
5469	   ((looking-at verilog-cpp-level-re)
5470	    (throw 'nesting 'cpp))
5471
5472	   ((bobp)
5473	    (throw 'nesting 'cpp)))))
5474
5475      (throw 'nesting 'cpp))))
5476
5477(defun verilog-calculate-indent-directive ()
5478  "Return indentation level for directive.
5479For speed, the searcher looks at the last directive, not the indent
5480of the appropriate enclosing block."
5481  (let ((base -1)	;; Indent of the line that determines our indentation
5482	(ind 0))        ;; Relative offset caused by other directives (like `endif on same line as `else)
5483    ;; Start at current location, scan back for another directive
5484
5485    (save-excursion
5486      (beginning-of-line)
5487      (while (and (< base 0)
5488		  (verilog-re-search-backward verilog-directive-re nil t))
5489	(cond ((save-excursion (skip-chars-backward " \t") (bolp))
5490	       (setq base (current-indentation))))
5491	(cond ((and (looking-at verilog-directive-end) (< base 0))  ;; Only matters when not at BOL
5492	       (setq ind (- ind verilog-indent-level-directive)))
5493	      ((and (looking-at verilog-directive-middle) (>= base 0))  ;; Only matters when at BOL
5494	       (setq ind (+ ind verilog-indent-level-directive)))
5495	      ((looking-at verilog-directive-begin)
5496	       (setq ind (+ ind verilog-indent-level-directive)))))
5497      ;; Adjust indent to starting indent of critical line
5498      (setq ind (max 0 (+ ind base))))
5499
5500    (save-excursion
5501      (beginning-of-line)
5502      (skip-chars-forward " \t")
5503      (cond ((or (looking-at verilog-directive-middle)
5504		 (looking-at verilog-directive-end))
5505	     (setq ind (max 0 (- ind verilog-indent-level-directive))))))
5506   ind))
5507
5508(defun verilog-leap-to-case-head ()
5509  (let ((nest 1))
5510    (while (/= 0 nest)
5511      (verilog-re-search-backward
5512       (concat
5513	"\\(\\<randcase\\>\\|\\(\\<unique\\s-+\\|priority\\s-+\\)?\\<case[xz]?\\>\\)"
5514	"\\|\\(\\<endcase\\>\\)" )
5515       nil 'move)
5516      (cond
5517       ((match-end 1)
5518	(let ((here (point)))
5519	  (verilog-beg-of-statement)
5520	  (unless (looking-at verilog-extended-case-re)
5521	    (goto-char here)))
5522	(setq nest (1- nest)))
5523       ((match-end 3)
5524	(setq nest (1+ nest)))
5525       ((bobp)
5526	(ding 't)
5527	(setq nest 0))))))
5528
5529(defun verilog-leap-to-head ()
5530  "Move point to the head of this block.
5531Jump from end to matching begin, from endcase to matching case, and so on."
5532  (let ((reg nil)
5533	snest
5534	(nesting 'yes)
5535	(nest 1))
5536    (cond
5537     ((looking-at "\\<end\\>")
5538      ;; 1: Search back for matching begin
5539      (setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|"
5540			"\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))
5541     ((looking-at "\\<endtask\\>")
5542      ;; 2: Search back for matching task
5543      (setq reg "\\(\\<task\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<task\\>\\)")
5544      (setq nesting 'no))
5545     ((looking-at "\\<endcase\\>")
5546      (catch 'nesting
5547	(verilog-leap-to-case-head) )
5548      (setq reg nil) ; to force skip
5549      )
5550
5551     ((looking-at "\\<join\\(_any\\|_none\\)?\\>")
5552      ;; 4: Search back for matching fork
5553      (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
5554     ((looking-at "\\<endclass\\>")
5555      ;; 5: Search back for matching class
5556      (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
5557     ((looking-at "\\<endtable\\>")
5558      ;; 6: Search back for matching table
5559      (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
5560     ((looking-at "\\<endspecify\\>")
5561      ;; 7: Search back for matching specify
5562      (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
5563     ((looking-at "\\<endfunction\\>")
5564      ;; 8: Search back for matching function
5565      (setq reg "\\(\\<function\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<function\\>\\)")
5566      (setq nesting 'no))
5567      ;;(setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
5568     ((looking-at "\\<endgenerate\\>")
5569      ;; 8: Search back for matching generate
5570      (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
5571     ((looking-at "\\<endgroup\\>")
5572      ;; 10: Search back for matching covergroup
5573      (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
5574     ((looking-at "\\<endproperty\\>")
5575      ;; 11: Search back for matching property
5576      (setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
5577     ((looking-at verilog-uvm-end-re)
5578      ;; 12: Search back for matching sequence
5579      (setq reg (concat "\\(" verilog-uvm-begin-re "\\|" verilog-uvm-end-re "\\)")))
5580     ((looking-at verilog-ovm-end-re)
5581      ;; 12: Search back for matching sequence
5582      (setq reg (concat "\\(" verilog-ovm-begin-re "\\|" verilog-ovm-end-re "\\)")))
5583     ((looking-at verilog-vmm-end-re)
5584      ;; 12: Search back for matching sequence
5585      (setq reg (concat "\\(" verilog-vmm-begin-re "\\|" verilog-vmm-end-re "\\)")))
5586     ((looking-at "\\<endinterface\\>")
5587      ;; 12: Search back for matching interface
5588      (setq reg "\\(\\<interface\\>\\)\\|\\(\\<endinterface\\>\\)" ))
5589     ((looking-at "\\<endsequence\\>")
5590      ;; 12: Search back for matching sequence
5591      (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" ))
5592     ((looking-at "\\<endclocking\\>")
5593      ;; 12: Search back for matching clocking
5594      (setq reg "\\(\\<clocking\\)\\|\\(\\<endclocking\\>\\)" )))
5595    (if reg
5596	(catch 'skip
5597	  (if (eq nesting 'yes)
5598	      (let (sreg)
5599		(while (verilog-re-search-backward reg nil 'move)
5600		  (cond
5601		   ((match-end 1) ; begin
5602		    (if (looking-at "fork")
5603			(let ((here (point)))
5604			  (verilog-beg-of-statement)
5605			  (unless (looking-at verilog-disable-fork-re)
5606			    (goto-char here)
5607			    (setq nest (1- nest))))
5608		      (setq nest (1- nest)))
5609		    (if (= 0 nest)
5610			;; Now previous line describes syntax
5611			(throw 'skip 1))
5612		    (if (and snest
5613			     (= snest nest))
5614			(setq reg sreg)))
5615		   ((match-end 2) ; end
5616		    (setq nest (1+ nest)))
5617		   ((match-end 3)
5618		    ;; endcase, jump to case
5619		    (setq snest nest)
5620		    (setq nest (1+ nest))
5621		    (setq sreg reg)
5622		    (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
5623		   ((match-end 4)
5624		    ;; join, jump to fork
5625		    (setq snest nest)
5626		    (setq nest (1+ nest))
5627		    (setq sreg reg)
5628		    (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
5629		   )))
5630	    ;no nesting
5631	    (if (and
5632		 (verilog-re-search-backward reg nil 'move)
5633		 (match-end 1)) ; task -> could be virtual and/or protected
5634		(progn
5635		  (verilog-beg-of-statement)
5636		  (throw 'skip 1))
5637	      (throw 'skip 1)))))))
5638
5639(defun verilog-continued-line ()
5640  "Return true if this is a continued line.
5641Set point to where line starts."
5642  (let ((continued 't))
5643    (if (eq 0 (forward-line -1))
5644	(progn
5645	  (end-of-line)
5646	  (verilog-backward-ws&directives)
5647	  (if (bobp)
5648	      (setq continued nil)
5649	    (while (and continued
5650			(save-excursion
5651			  (skip-chars-backward " \t")
5652			  (not (bolp))))
5653	    (setq continued (verilog-backward-token)))))
5654      (setq continued nil))
5655    continued))
5656
5657(defun verilog-backward-token ()
5658  "Step backward token, returning true if this is a continued line."
5659  (interactive)
5660  (verilog-backward-syntactic-ws)
5661  (cond
5662   ((bolp)
5663    nil)
5664   (;-- Anything ending in a ; is complete
5665    (= (preceding-char) ?\;)
5666    nil)
5667   (; If a "}" is prefixed by a ";", then this is a complete statement
5668    ; i.e.: constraint foo { a = b; }
5669    (= (preceding-char) ?\})
5670    (progn
5671      (backward-char)
5672      (not(verilog-at-close-constraint-p))))
5673   (;-- constraint foo { a = b }
5674    ;   is a complete statement. *sigh*
5675    (= (preceding-char) ?\{)
5676    (progn
5677      (backward-char)
5678      (not (verilog-at-constraint-p))))
5679   (;" string "
5680    (= (preceding-char) ?\")
5681    (backward-char)
5682    (verilog-skip-backward-comment-or-string)
5683    nil)
5684
5685   (; [3:4]
5686    (= (preceding-char) ?\])
5687    (backward-char)
5688    (verilog-backward-open-bracket)
5689    t)
5690
5691   (;-- Could be 'case (foo)' or 'always @(bar)' which is complete
5692    ;   also could be simply '@(foo)'
5693    ;   or foo u1 #(a=8)
5694    ;            (b, ... which ISN'T complete
5695    ;;;; Do we need this???
5696    (= (preceding-char) ?\))
5697    (progn
5698      (backward-char)
5699      (verilog-backward-up-list 1)
5700      (verilog-backward-syntactic-ws)
5701      (let ((back (point)))
5702	(forward-word -1)
5703	(cond
5704	 ;;XX
5705	 ((looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|case\\(\\|[xz]\\)\\|for\\(\\|each\\|ever\\)\\|i\\(f\\|nitial\\)\\|repeat\\|while\\)\\>")
5706	  (not (looking-at "\\<randcase\\>\\|\\<case[xz]?\\>[^:]")))
5707	 ((looking-at verilog-uvm-statement-re)
5708	  nil)
5709	 ((looking-at verilog-uvm-begin-re)
5710	  t)
5711	 ((looking-at verilog-uvm-end-re)
5712	  t)
5713	 ((looking-at verilog-ovm-statement-re)
5714	  nil)
5715	 ((looking-at verilog-ovm-begin-re)
5716	  t)
5717	 ((looking-at verilog-ovm-end-re)
5718	  t)
5719     ;; JBA find VMM macros
5720     ((looking-at verilog-vmm-statement-re)
5721      nil )
5722     ((looking-at verilog-vmm-begin-re)
5723      t)
5724     ((looking-at verilog-vmm-end-re)
5725      nil)
5726     ;; JBA trying to catch macro lines with no ; at end
5727     ((looking-at "\\<`")
5728      nil)
5729	 (t
5730	  (goto-char back)
5731	  (cond
5732	   ((= (preceding-char) ?\@)
5733	    (backward-char)
5734	    (save-excursion
5735	      (verilog-backward-token)
5736	      (not (looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|initial\\|while\\)\\>"))))
5737	   ((= (preceding-char) ?\#)
5738	    (backward-char))
5739	   (t t)))))))
5740
5741   (;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete
5742    t
5743    (forward-word -1)
5744    (while (= (preceding-char) ?\_)
5745      (forward-word -1))
5746    (cond
5747     ((looking-at "\\<else\\>")
5748      t)
5749     ((looking-at verilog-behavioral-block-beg-re)
5750      t)
5751     ((looking-at verilog-indent-re)
5752      nil)
5753     (t
5754      (let
5755	  ((back (point)))
5756	(verilog-backward-syntactic-ws)
5757	(cond
5758	 ((= (preceding-char) ?\:)
5759	  (backward-char)
5760	  (verilog-backward-syntactic-ws)
5761	  (backward-sexp)
5762	  (if (looking-at verilog-nameable-item-re )
5763	      nil
5764	    t))
5765	 ((= (preceding-char) ?\#)
5766	  (backward-char)
5767	  t)
5768	 ((= (preceding-char) ?\`)
5769	  (backward-char)
5770	  t)
5771
5772	 (t
5773	  (goto-char back)
5774	  t))))))))
5775
5776(defun verilog-backward-syntactic-ws ()
5777  "Move backwards putting point after first non-whitespace non-comment."
5778  (verilog-skip-backward-comments)
5779  (forward-comment (- (buffer-size))))
5780
5781(defun verilog-backward-syntactic-ws-quick ()
5782  "As with `verilog-backward-syntactic-ws' but use `verilog-scan' cache."
5783  (while (cond ((bobp)
5784		nil) ; Done
5785	       ((> (skip-syntax-backward " ") 0)
5786		t)
5787	       ((eq (preceding-char) ?\n)  ;; \n's terminate // so aren't space syntax
5788		(forward-char -1)
5789		t)
5790	       ((or (verilog-inside-comment-or-string-p (1- (point)))
5791		    (verilog-inside-comment-or-string-p (point)))
5792		(re-search-backward "[/\"]" nil t) ;; Only way a comment or quote can begin
5793		t))))
5794
5795(defun verilog-forward-syntactic-ws ()
5796  (verilog-skip-forward-comment-p)
5797  (forward-comment (buffer-size)))
5798
5799(defun verilog-backward-ws&directives (&optional bound)
5800  "Backward skip over syntactic whitespace and compiler directives for Emacs 19.
5801Optional BOUND limits search."
5802  (save-restriction
5803    (let* ((bound (or bound (point-min)))
5804	   (here bound)
5805	   (p nil) )
5806      (if (< bound (point))
5807	  (progn
5808	    (let ((state (save-excursion (verilog-syntax-ppss))))
5809	      (cond
5810	       ((nth 7 state) ;; in // comment
5811		(verilog-re-search-backward "//" nil 'move)
5812                (skip-chars-backward "/"))
5813	       ((nth 4 state) ;; in /* */ comment
5814		(verilog-re-search-backward "/\*" nil 'move))))
5815	    (narrow-to-region bound (point))
5816	    (while (/= here (point))
5817	      (setq here (point))
5818	      (verilog-skip-backward-comments)
5819	      (setq p
5820		    (save-excursion
5821		      (beginning-of-line)
5822		      (cond
5823		       ((and verilog-highlight-translate-off
5824			     (verilog-within-translate-off))
5825			(verilog-back-to-start-translate-off (point-min)))
5826		       ((looking-at verilog-directive-re-1)
5827			(point))
5828		       (t
5829			nil))))
5830	      (if p (goto-char p))))))))
5831
5832(defun verilog-forward-ws&directives (&optional bound)
5833  "Forward skip over syntactic whitespace and compiler directives for Emacs 19.
5834Optional BOUND limits search."
5835  (save-restriction
5836    (let* ((bound (or bound (point-max)))
5837	   (here bound)
5838	   jump)
5839      (if (> bound (point))
5840	  (progn
5841	    (let ((state (save-excursion (verilog-syntax-ppss))))
5842	      (cond
5843	       ((nth 7 state) ;; in // comment
5844		(end-of-line)
5845		(forward-char 1)
5846		(skip-chars-forward " \t\n\f")
5847		)
5848	       ((nth 4 state) ;; in /* */ comment
5849		(verilog-re-search-forward "\*\/\\s-*" nil 'move))))
5850	    (narrow-to-region (point) bound)
5851	    (while (/= here (point))
5852	      (setq here (point)
5853		    jump nil)
5854	      (forward-comment (buffer-size))
5855	      (and (looking-at "\\s-*(\\*.*\\*)\\s-*") ;; Attribute
5856		   (goto-char (match-end 0)))
5857	      (save-excursion
5858		(beginning-of-line)
5859		(if (looking-at verilog-directive-re-1)
5860		    (setq jump t)))
5861	      (if jump
5862		  (beginning-of-line 2))))))))
5863
5864(defun verilog-in-comment-p ()
5865 "Return true if in a star or // comment."
5866 (let ((state (save-excursion (verilog-syntax-ppss))))
5867   (or (nth 4 state) (nth 7 state))))
5868
5869(defun verilog-in-star-comment-p ()
5870 "Return true if in a star comment."
5871 (let ((state (save-excursion (verilog-syntax-ppss))))
5872   (and
5873    (nth 4 state)			; t if in a comment of style a // or b /**/
5874	(not
5875	 (nth 7 state)			; t if in a comment of style b /**/
5876	 ))))
5877
5878(defun verilog-in-slash-comment-p ()
5879 "Return true if in a slash comment."
5880 (let ((state (save-excursion (verilog-syntax-ppss))))
5881   (nth 7 state)))
5882
5883(defun verilog-in-comment-or-string-p ()
5884 "Return true if in a string or comment."
5885 (let ((state (save-excursion (verilog-syntax-ppss))))
5886   (or (nth 3 state) (nth 4 state) (nth 7 state)))) ; Inside string or comment)
5887
5888(defun verilog-in-attribute-p ()
5889 "Return true if point is in an attribute (* [] attribute *)."
5890 (save-match-data
5891   (save-excursion
5892     (verilog-re-search-backward "\\((\\*\\)\\|\\(\\*)\\)" nil 'move)
5893     (numberp (match-beginning 1)))))
5894
5895(defun verilog-in-parameter-p ()
5896 "Return true if point is in a parameter assignment #( p1=1, p2=5)."
5897 (save-match-data
5898   (save-excursion
5899     (verilog-re-search-backward "\\(#(\\)\\|\\()\\)" nil 'move)
5900     (numberp (match-beginning 1)))))
5901
5902(defun verilog-in-escaped-name-p ()
5903 "Return true if in an escaped name."
5904 (save-excursion
5905   (backward-char)
5906   (skip-chars-backward "^ \t\n\f")
5907   (if (equal (char-after (point) ) ?\\ )
5908       t
5909     nil)))
5910(defun verilog-in-directive-p ()
5911 "Return true if in a directive."
5912 (save-excursion
5913   (beginning-of-line)
5914   (looking-at verilog-directive-re-1)))
5915
5916(defun verilog-in-parenthesis-p ()
5917 "Return true if in a ( ) expression (but not { } or [ ])."
5918 (save-match-data
5919   (save-excursion
5920     (verilog-re-search-backward "\\((\\)\\|\\()\\)" nil 'move)
5921     (numberp (match-beginning 1)))))
5922
5923(defun verilog-in-paren ()
5924 "Return true if in a parenthetical expression.
5925May cache result using `verilog-syntax-ppss'."
5926 (let ((state (save-excursion (verilog-syntax-ppss))))
5927   (> (nth 0 state) 0 )))
5928
5929(defun verilog-in-paren-quick ()
5930 "Return true if in a parenthetical expression.
5931Always starts from `point-min', to allow inserts with hooks disabled."
5932 ;; The -quick refers to its use alongside the other -quick functions,
5933 ;; not that it's likely to be faster than verilog-in-paren.
5934 (let ((state (save-excursion (parse-partial-sexp (point-min) (point)))))
5935   (> (nth 0 state) 0 )))
5936
5937(defun verilog-in-struct-p ()
5938 "Return true if in a struct declaration."
5939 (interactive)
5940 (save-excursion
5941   (if (verilog-in-paren)
5942       (progn
5943	 (verilog-backward-up-list 1)
5944	 (verilog-at-struct-p)
5945	 )
5946     nil)))
5947
5948(defun verilog-in-coverage-p ()
5949 "Return true if in a constraint or coverpoint expression."
5950 (interactive)
5951 (save-excursion
5952   (if (verilog-in-paren)
5953       (progn
5954	 (verilog-backward-up-list 1)
5955	 (verilog-at-constraint-p)
5956	 )
5957     nil)))
5958(defun verilog-at-close-constraint-p ()
5959  "If at the } that closes a constraint or covergroup, return true."
5960  (if (and
5961       (equal (char-after) ?\})
5962       (verilog-in-paren))
5963
5964      (save-excursion
5965	(verilog-backward-ws&directives)
5966	(if (equal (char-before) ?\;)
5967	    (point)
5968	  nil))))
5969
5970(defun verilog-at-constraint-p ()
5971  "If at the { of a constraint or coverpoint definition, return true, moving point to constraint."
5972  (if (save-excursion
5973	(and
5974	 (equal (char-after) ?\{)
5975	 (forward-list)
5976	 (progn (backward-char 1)
5977		(verilog-backward-ws&directives)
5978		(equal (char-before) ?\;))))
5979      ;; maybe
5980      (verilog-re-search-backward "\\<constraint\\|coverpoint\\|cross\\>" nil 'move)
5981    ;; not
5982    nil))
5983
5984(defun verilog-at-struct-p ()
5985  "If at the { of a struct, return true, moving point to struct."
5986  (save-excursion
5987    (if (and (equal (char-after) ?\{)
5988             (verilog-backward-token))
5989        (looking-at "\\<struct\\|union\\|packed\\|\\(un\\)?signed\\>")
5990      nil)))
5991
5992(defun verilog-parenthesis-depth ()
5993 "Return non zero if in parenthetical-expression."
5994 (save-excursion (nth 1 (verilog-syntax-ppss))))
5995
5996
5997(defun verilog-skip-forward-comment-or-string ()
5998 "Return true if in a string or comment."
5999 (let ((state (save-excursion (verilog-syntax-ppss))))
6000   (cond
6001    ((nth 3 state)			;Inside string
6002     (search-forward "\"")
6003     t)
6004    ((nth 7 state)			;Inside // comment
6005     (forward-line 1)
6006     t)
6007    ((nth 4 state)			;Inside any comment (hence /**/)
6008     (search-forward "*/"))
6009    (t
6010     nil))))
6011
6012(defun verilog-skip-backward-comment-or-string ()
6013 "Return true if in a string or comment."
6014 (let ((state (save-excursion (verilog-syntax-ppss))))
6015   (cond
6016    ((nth 3 state)			;Inside string
6017     (search-backward "\"")
6018     t)
6019    ((nth 7 state)			;Inside // comment
6020     (search-backward "//")
6021     (skip-chars-backward "/")
6022     t)
6023    ((nth 4 state)			;Inside /* */ comment
6024     (search-backward "/*")
6025     t)
6026    (t
6027     nil))))
6028
6029(defun verilog-skip-backward-comments ()
6030 "Return true if a comment was skipped."
6031 (let ((more t))
6032   (while more
6033     (setq more
6034	   (let ((state (save-excursion (verilog-syntax-ppss))))
6035	     (cond
6036	      ((nth 7 state)			;Inside // comment
6037	       (search-backward "//")
6038	       (skip-chars-backward "/")
6039	       (skip-chars-backward " \t\n\f")
6040	       t)
6041	      ((nth 4 state)			;Inside /* */ comment
6042	       (search-backward "/*")
6043	       (skip-chars-backward " \t\n\f")
6044	       t)
6045	      ((and (not (bobp))
6046		    (= (char-before) ?\/)
6047		    (= (char-before (1- (point))) ?\*))
6048	       (goto-char (- (point) 2))
6049	       t) ;; Let nth 4 state handle the rest
6050	      ((and (not (bobp))
6051		    (= (char-before) ?\))
6052		    (= (char-before (1- (point))) ?\*))
6053	       (goto-char (- (point) 2))
6054	       (if (search-backward "(*" nil t)
6055		   (progn
6056		     (skip-chars-backward " \t\n\f")
6057		     t)
6058		 (progn
6059		   (goto-char (+ (point) 2))
6060		   nil)))
6061	      (t
6062	       (/= (skip-chars-backward " \t\n\f") 0))))))))
6063
6064(defun verilog-skip-forward-comment-p ()
6065  "If in comment, move to end and return true."
6066  (let* (h
6067	 (state (save-excursion (verilog-syntax-ppss)))
6068	 (skip (cond
6069		((nth 3 state)		;Inside string
6070		 t)
6071		((nth 7 state)		;Inside // comment
6072		 (end-of-line)
6073		 (forward-char 1)
6074		 t)
6075		((nth 4 state)		;Inside /* comment
6076		 (search-forward "*/")
6077		 t)
6078		((verilog-in-attribute-p)  ;Inside (* attribute
6079		 (search-forward "*)" nil t)
6080		 t)
6081		(t nil))))
6082    (skip-chars-forward " \t\n\f")
6083    (while
6084	(cond
6085	 ((looking-at "\\/\\*")
6086	  (progn
6087	    (setq h (point))
6088	    (goto-char (match-end 0))
6089	    (if (search-forward "*/" nil t)
6090		(progn
6091		  (skip-chars-forward " \t\n\f")
6092		  (setq skip 't))
6093	      (progn
6094		(goto-char h)
6095		nil))))
6096	 ((looking-at "(\\*")
6097	  (progn
6098	    (setq h (point))
6099	    (goto-char (match-end 0))
6100	    (if (search-forward "*)" nil t)
6101		(progn
6102		  (skip-chars-forward " \t\n\f")
6103		  (setq skip 't))
6104	      (progn
6105		(goto-char h)
6106		nil))))
6107	 (t nil)))
6108    skip))
6109
6110(defun verilog-indent-line-relative ()
6111  "Cheap version of indent line.
6112Only look at a few lines to determine indent level."
6113  (interactive)
6114  (let ((indent-str)
6115	(sp (point)))
6116    (if (looking-at "^[ \t]*$")
6117	(cond  ;- A blank line; No need to be too smart.
6118	 ((bobp)
6119	  (setq indent-str (list 'cpp 0)))
6120	 ((verilog-continued-line)
6121	  (let ((sp1 (point)))
6122	    (if (verilog-continued-line)
6123		(progn
6124		  (goto-char sp)
6125		  (setq indent-str
6126			(list 'statement (verilog-current-indent-level))))
6127	      (goto-char sp1)
6128	      (setq indent-str (list 'block (verilog-current-indent-level)))))
6129	  (goto-char sp))
6130	 ((goto-char sp)
6131	  (setq indent-str (verilog-calculate-indent))))
6132      (progn (skip-chars-forward " \t")
6133	     (setq indent-str (verilog-calculate-indent))))
6134    (verilog-do-indent indent-str)))
6135
6136(defun verilog-indent-line ()
6137  "Indent for special part of code."
6138  (verilog-do-indent (verilog-calculate-indent)))
6139
6140(defun verilog-do-indent (indent-str)
6141  (let ((type (car indent-str))
6142	(ind (car (cdr indent-str))))
6143    (cond
6144     (; handle continued exp
6145      (eq type 'cexp)
6146      (let ((here (point)))
6147	(verilog-backward-syntactic-ws)
6148	(cond
6149	 ((or
6150	   (= (preceding-char) ?\,)
6151	   (= (preceding-char) ?\])
6152	   (save-excursion
6153	     (verilog-beg-of-statement-1)
6154	     (looking-at verilog-declaration-re)))
6155	  (let* ( fst
6156		  (val
6157		   (save-excursion
6158		     (backward-char 1)
6159		     (verilog-beg-of-statement-1)
6160		     (setq fst (point))
6161		     (if (looking-at verilog-declaration-re)
6162			 (progn ;; we have multiple words
6163			   (goto-char (match-end 0))
6164			   (skip-chars-forward " \t")
6165			   (cond
6166			    ((and verilog-indent-declaration-macros
6167				  (= (following-char) ?\`))
6168			     (progn
6169			       (forward-char 1)
6170			       (forward-word 1)
6171			       (skip-chars-forward " \t")))
6172			    ((= (following-char) ?\[)
6173			     (progn
6174			       (forward-char 1)
6175			       (verilog-backward-up-list -1)
6176			       (skip-chars-forward " \t"))))
6177			   (current-column))
6178		       (progn
6179			 (goto-char fst)
6180			 (+ (current-column) verilog-cexp-indent))))))
6181	    (goto-char here)
6182	    (indent-line-to val)
6183	    (if (and (not verilog-indent-lists)
6184		     (verilog-in-paren))
6185		(verilog-pretty-declarations-auto))
6186	    ))
6187	 ((= (preceding-char) ?\) )
6188	  (goto-char here)
6189	  (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
6190	    (indent-line-to val)))
6191	 (t
6192	  (goto-char here)
6193	  (let ((val))
6194	    (verilog-beg-of-statement-1)
6195	    (if (and (< (point) here)
6196		     (verilog-re-search-forward "=[ \\t]*" here 'move))
6197		(setq val (current-column))
6198	      (setq val (eval (cdr (assoc type verilog-indent-alist)))))
6199	    (goto-char here)
6200	    (indent-line-to val))))))
6201
6202     (; handle inside parenthetical expressions
6203      (eq type 'cparenexp)
6204      (let* ( here
6205	      (val (save-excursion
6206		     (verilog-backward-up-list 1)
6207		     (forward-char 1)
6208             (if verilog-indent-lists
6209                 (skip-chars-forward " \t")
6210               (verilog-forward-syntactic-ws))
6211             (setq here (point))
6212             (current-column)))
6213
6214	      (decl (save-excursion
6215		      (goto-char here)
6216		      (verilog-forward-syntactic-ws)
6217		      (setq here (point))
6218		      (looking-at verilog-declaration-re))))
6219        (indent-line-to val)
6220        (if decl
6221            (verilog-pretty-declarations-auto))))
6222
6223     (;-- Handle the ends
6224      (or
6225       (looking-at verilog-end-block-re )
6226       (verilog-at-close-constraint-p))
6227      (let ((val (if (eq type 'statement)
6228		     (- ind verilog-indent-level)
6229		   ind)))
6230	(indent-line-to val)))
6231
6232     (;-- Case -- maybe line 'em up
6233      (and (eq type 'case) (not (looking-at "^[ \t]*$")))
6234      (progn
6235	(cond
6236	 ((looking-at "\\<endcase\\>")
6237	  (indent-line-to ind))
6238	 (t
6239	  (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
6240	    (indent-line-to val))))))
6241
6242     (;-- defun
6243      (and (eq type 'defun)
6244	   (looking-at verilog-zero-indent-re))
6245      (indent-line-to 0))
6246
6247     (;-- declaration
6248      (and (or
6249	    (eq type 'defun)
6250	    (eq type 'block))
6251	   (looking-at verilog-declaration-re))
6252      (verilog-indent-declaration ind))
6253
6254     (;-- Everything else
6255      t
6256      (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
6257	(indent-line-to val))))
6258
6259    (if (looking-at "[ \t]+$")
6260	(skip-chars-forward " \t"))
6261    indent-str				; Return indent data
6262    ))
6263
6264(defun verilog-current-indent-level ()
6265  "Return the indent-level of the current statement."
6266  (save-excursion
6267    (let (par-pos)
6268      (beginning-of-line)
6269      (setq par-pos (verilog-parenthesis-depth))
6270      (while par-pos
6271	(goto-char par-pos)
6272	(beginning-of-line)
6273	(setq par-pos (verilog-parenthesis-depth)))
6274      (skip-chars-forward " \t")
6275      (current-column))))
6276
6277(defun verilog-case-indent-level ()
6278  "Return the indent-level of the current statement.
6279Do not count named blocks or case-statements."
6280  (save-excursion
6281    (skip-chars-forward " \t")
6282    (cond
6283     ((looking-at verilog-named-block-re)
6284      (current-column))
6285     ((and (not (looking-at verilog-extended-case-re))
6286	   (looking-at "^[^:;]+[ \t]*:"))
6287      (verilog-re-search-forward ":" nil t)
6288      (skip-chars-forward " \t")
6289      (current-column))
6290     (t
6291      (current-column)))))
6292
6293(defun verilog-indent-comment ()
6294  "Indent current line as comment."
6295  (let* ((stcol
6296	  (cond
6297	   ((verilog-in-star-comment-p)
6298	    (save-excursion
6299	      (re-search-backward "/\\*" nil t)
6300	      (1+(current-column))))
6301	   (comment-column
6302	     comment-column )
6303	   (t
6304	    (save-excursion
6305	      (re-search-backward "//" nil t)
6306	      (current-column))))))
6307    (indent-line-to stcol)
6308    stcol))
6309
6310(defun verilog-more-comment ()
6311  "Make more comment lines like the previous."
6312  (let* ((star 0)
6313	 (stcol
6314	  (cond
6315	   ((verilog-in-star-comment-p)
6316	    (save-excursion
6317	      (setq star 1)
6318	      (re-search-backward "/\\*" nil t)
6319	      (1+(current-column))))
6320	   (comment-column
6321	    comment-column )
6322	   (t
6323	    (save-excursion
6324	      (re-search-backward "//" nil t)
6325	      (current-column))))))
6326    (progn
6327      (indent-to stcol)
6328      (if (and star
6329	       (save-excursion
6330		 (forward-line -1)
6331		 (skip-chars-forward " \t")
6332		 (looking-at "\*")))
6333	  (insert "* ")))))
6334
6335(defun verilog-comment-indent (&optional arg)
6336  "Return the column number the line should be indented to.
6337ARG is ignored, for `comment-indent-function' compatibility."
6338  (cond
6339   ((verilog-in-star-comment-p)
6340    (save-excursion
6341      (re-search-backward "/\\*" nil t)
6342      (1+(current-column))))
6343   ( comment-column
6344     comment-column )
6345   (t
6346    (save-excursion
6347      (re-search-backward "//" nil t)
6348      (current-column)))))
6349
6350;;
6351
6352(defun verilog-pretty-declarations-auto (&optional quiet)
6353  "Call `verilog-pretty-declarations' QUIET based on `verilog-auto-lineup'."
6354  (when (or (eq 'all verilog-auto-lineup)
6355	    (eq 'declarations verilog-auto-lineup))
6356    (verilog-pretty-declarations quiet)))
6357
6358(defun verilog-pretty-declarations (&optional quiet)
6359  "Line up declarations around point.
6360Be verbose about progress unless optional QUIET set."
6361  (interactive)
6362  (let* ((m1 (make-marker))
6363         (e (point))
6364	 el
6365         r
6366	 (here (point))
6367         ind
6368         start
6369         startpos
6370         end
6371         endpos
6372         base-ind
6373         )
6374    (save-excursion
6375      (if (progn
6376;          (verilog-beg-of-statement-1)
6377          (beginning-of-line)
6378          (verilog-forward-syntactic-ws)
6379          (and (not (verilog-in-directive-p))    ;; could have `define input foo
6380               (looking-at verilog-declaration-re)))
6381	  (progn
6382	    (if (verilog-parenthesis-depth)
6383		;; in an argument list or parameter block
6384		(setq el (verilog-backward-up-list -1)
6385		      start (progn
6386			      (goto-char e)
6387			      (verilog-backward-up-list 1)
6388			      (forward-line) ;; ignore ( input foo,
6389			      (verilog-re-search-forward verilog-declaration-re el 'move)
6390			      (goto-char (match-beginning 0))
6391			      (skip-chars-backward " \t")
6392			      (point))
6393		      startpos (set-marker (make-marker) start)
6394		      end (progn
6395			    (goto-char start)
6396			    (verilog-backward-up-list -1)
6397			    (forward-char -1)
6398			    (verilog-backward-syntactic-ws)
6399			    (point))
6400		      endpos (set-marker (make-marker) end)
6401		      base-ind (progn
6402				 (goto-char start)
6403                 (forward-char 1)
6404                 (skip-chars-forward " \t")
6405                 (current-column))
6406		      )
6407	      ;; in a declaration block (not in argument list)
6408	      (setq
6409	       start (progn
6410		       (verilog-beg-of-statement-1)
6411		       (while (and (looking-at verilog-declaration-re)
6412				   (not (bobp)))
6413			 (skip-chars-backward " \t")
6414			 (setq e (point))
6415			 (beginning-of-line)
6416			 (verilog-backward-syntactic-ws)
6417			 (backward-char)
6418			 (verilog-beg-of-statement-1))
6419		       e)
6420	       startpos (set-marker (make-marker) start)
6421	       end (progn
6422		     (goto-char here)
6423		     (verilog-end-of-statement)
6424		     (setq e (point))	;Might be on last line
6425		     (verilog-forward-syntactic-ws)
6426		     (while (looking-at verilog-declaration-re)
6427		       (verilog-end-of-statement)
6428		       (setq e (point))
6429		       (verilog-forward-syntactic-ws))
6430		     e)
6431	       endpos (set-marker (make-marker) end)
6432	       base-ind (progn
6433			  (goto-char start)
6434			  (verilog-do-indent (verilog-calculate-indent))
6435			  (verilog-forward-ws&directives)
6436			  (current-column))))
6437	    ;; OK, start and end are set
6438	    (goto-char (marker-position startpos))
6439	    (if (and (not quiet)
6440		     (> (- end start) 100))
6441		(message "Lining up declarations..(please stand by)"))
6442	    ;; Get the beginning of line indent first
6443	    (while (progn (setq e (marker-position endpos))
6444			  (< (point) e))
6445	      (cond
6446	       ((save-excursion (skip-chars-backward " \t")
6447				(bolp))
6448		 (verilog-forward-ws&directives)
6449		 (indent-line-to base-ind)
6450		 (verilog-forward-ws&directives)
6451		 (if (< (point) e)
6452		     (verilog-re-search-forward "[ \t\n\f]" e 'move)))
6453	       (t
6454		(just-one-space)
6455		(verilog-re-search-forward "[ \t\n\f]" e 'move)))
6456	      ;;(forward-line)
6457	      )
6458	    ;; Now find biggest prefix
6459	    (setq ind (verilog-get-lineup-indent (marker-position startpos) endpos))
6460	    ;; Now indent each line.
6461	    (goto-char (marker-position startpos))
6462	    (while (progn (setq e (marker-position endpos))
6463			  (setq r (- e (point)))
6464			  (> r 0))
6465	      (setq e (point))
6466	      (unless quiet (message "%d" r))
6467          ;;(verilog-do-indent (verilog-calculate-indent)))
6468	      (verilog-forward-ws&directives)
6469	      (cond
6470	       ((or (and verilog-indent-declaration-macros
6471			 (looking-at verilog-declaration-re-2-macro))
6472		    (looking-at verilog-declaration-re-2-no-macro))
6473		(let ((p (match-end 0)))
6474		  (set-marker m1 p)
6475		  (if (verilog-re-search-forward "[[#`]" p 'move)
6476		      (progn
6477			(forward-char -1)
6478			(just-one-space)
6479			(goto-char (marker-position m1))
6480			(just-one-space)
6481			(indent-to ind))
6482		    (progn
6483		      (just-one-space)
6484		      (indent-to ind)))))
6485	       ((verilog-continued-line-1 (marker-position startpos))
6486		(goto-char e)
6487		(indent-line-to ind))
6488	       ((verilog-in-struct-p)
6489		;; could have a declaration of a user defined item
6490		(goto-char e)
6491		(verilog-end-of-statement))
6492	       (t		; Must be comment or white space
6493		(goto-char e)
6494		(verilog-forward-ws&directives)
6495		(forward-line -1)))
6496	      (forward-line 1))
6497	    (unless quiet (message "")))))))
6498
6499(defun verilog-pretty-expr (&optional quiet myre)
6500  "Line up expressions around point, optionally QUIET with regexp MYRE ignored."
6501  (interactive)
6502  (if (not (verilog-in-comment-or-string-p))
6503      (save-excursion
6504        (let ( (rexp (concat "^\\s-*" verilog-complete-reg))
6505               (rexp1 (concat "^\\s-*" verilog-basic-complete-re)))
6506          (beginning-of-line)
6507          (if (and (not (looking-at rexp ))
6508                   (looking-at verilog-assignment-operation-re)
6509                   (save-excursion
6510                     (goto-char (match-end 2))
6511                     (and (not (verilog-in-attribute-p))
6512                          (not (verilog-in-parameter-p))
6513                          (not (verilog-in-comment-or-string-p)))))
6514              (let* ((here (point))
6515                     (e) (r)
6516                     (start
6517                      (progn
6518                        (beginning-of-line)
6519                        (setq e (point))
6520                        (verilog-backward-syntactic-ws)
6521                        (beginning-of-line)
6522                        (while (and (not (looking-at rexp1))
6523                                    (looking-at verilog-assignment-operation-re)
6524                                    (not (bobp))
6525                                    )
6526                          (setq e (point))
6527                          (verilog-backward-syntactic-ws)
6528                          (beginning-of-line)
6529                          ) ;Ack, need to grok `define
6530                        e))
6531                     (end
6532                      (progn
6533                        (goto-char here)
6534                        (end-of-line)
6535                        (setq e (point))	;Might be on last line
6536                        (verilog-forward-syntactic-ws)
6537                        (beginning-of-line)
6538                        (while (and
6539                                (not (looking-at rexp1 ))
6540                                (looking-at verilog-assignment-operation-re)
6541                                (progn
6542                                  (end-of-line)
6543                                  (not (eq e (point)))))
6544                          (setq e (point))
6545                          (verilog-forward-syntactic-ws)
6546                          (beginning-of-line)
6547                          )
6548                        e))
6549                     (endpos (set-marker (make-marker) end))
6550                     (ind)
6551                     )
6552                (goto-char start)
6553                (verilog-do-indent (verilog-calculate-indent))
6554                (if (and (not quiet)
6555                         (> (- end start) 100))
6556                    (message "Lining up expressions..(please stand by)"))
6557
6558                ;; Set indent to minimum throughout region
6559                (while (< (point) (marker-position endpos))
6560                  (beginning-of-line)
6561                  (verilog-just-one-space verilog-assignment-operation-re)
6562                  (beginning-of-line)
6563                  (verilog-do-indent (verilog-calculate-indent))
6564                  (end-of-line)
6565                  (verilog-forward-syntactic-ws)
6566                  )
6567
6568                ;; Now find biggest prefix
6569                (setq ind (verilog-get-lineup-indent-2 verilog-assignment-operation-re start endpos))
6570
6571                ;; Now indent each line.
6572                (goto-char start)
6573                (while (progn (setq e (marker-position endpos))
6574                              (setq r (- e (point)))
6575                              (> r 0))
6576                  (setq e (point))
6577                  (if (not quiet) (message "%d" r))
6578                  (cond
6579                   ((looking-at verilog-assignment-operation-re)
6580                    (goto-char (match-beginning 2))
6581                    (if (not (or (verilog-in-parenthesis-p) ;; leave attributes and comparisons alone
6582                                 (verilog-in-coverage-p)))
6583                        (if (eq (char-after) ?=)
6584                            (indent-to (1+ ind))	; line up the = of the <= with surrounding =
6585                          (indent-to ind)
6586                          ))
6587                    )
6588                   ((verilog-continued-line-1 start)
6589                    (goto-char e)
6590                    (indent-line-to ind))
6591                   (t		; Must be comment or white space
6592                    (goto-char e)
6593                    (verilog-forward-ws&directives)
6594                    (forward-line -1))
6595                   )
6596                  (forward-line 1))
6597                (unless quiet (message ""))
6598                ))))))
6599
6600(defun verilog-just-one-space (myre)
6601  "Remove extra spaces around regular expression MYRE."
6602  (interactive)
6603  (if (and (not(looking-at verilog-complete-reg))
6604	   (looking-at myre))
6605      (let ((p1 (match-end 1))
6606	    (p2 (match-end 2)))
6607	(progn
6608	  (goto-char p2)
6609	  (just-one-space)
6610	  (goto-char p1)
6611	  (just-one-space)))))
6612
6613(defun verilog-indent-declaration (baseind)
6614  "Indent current lines as declaration.
6615Line up the variable names based on previous declaration's indentation.
6616BASEIND is the base indent to offset everything."
6617  (interactive)
6618  (let ((pos (point-marker))
6619	(lim (save-excursion
6620	       ;; (verilog-re-search-backward verilog-declaration-opener nil 'move)
6621	       (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)\\|\\(\\<task\\>\\)" nil 'move)
6622	       (point)))
6623	(ind)
6624	(val)
6625	(m1 (make-marker)))
6626    (setq val
6627	  (+ baseind (eval (cdr (assoc 'declaration verilog-indent-alist)))))
6628    (indent-line-to val)
6629
6630    ;; Use previous declaration (in this module) as template.
6631    (if (or (eq 'all verilog-auto-lineup)
6632	    (eq 'declarations verilog-auto-lineup))
6633	(if (verilog-re-search-backward
6634	     (or (and verilog-indent-declaration-macros
6635		      verilog-declaration-re-1-macro)
6636		 verilog-declaration-re-1-no-macro) lim t)
6637	    (progn
6638	      (goto-char (match-end 0))
6639	      (skip-chars-forward " \t")
6640	      (setq ind (current-column))
6641	      (goto-char pos)
6642	      (setq val
6643		    (+ baseind
6644		       (eval (cdr (assoc 'declaration verilog-indent-alist)))))
6645	      (indent-line-to val)
6646	      (if (and verilog-indent-declaration-macros
6647		       (looking-at verilog-declaration-re-2-macro))
6648		  (let ((p (match-end 0)))
6649		    (set-marker m1 p)
6650		    (if (verilog-re-search-forward "[[#`]" p 'move)
6651			(progn
6652			  (forward-char -1)
6653			  (just-one-space)
6654			  (goto-char (marker-position m1))
6655			  (just-one-space)
6656			  (indent-to ind))
6657		      (if (/= (current-column) ind)
6658			  (progn
6659			    (just-one-space)
6660			    (indent-to ind)))))
6661		(if (looking-at verilog-declaration-re-2-no-macro)
6662		    (let ((p (match-end 0)))
6663		      (set-marker m1 p)
6664		      (if (verilog-re-search-forward "[[`#]" p 'move)
6665			  (progn
6666			    (forward-char -1)
6667			    (just-one-space)
6668			    (goto-char (marker-position m1))
6669			    (just-one-space)
6670			    (indent-to ind))
6671			(if (/= (current-column) ind)
6672			    (progn
6673			      (just-one-space)
6674			      (indent-to ind))))))))))
6675    (goto-char pos)))
6676
6677(defun verilog-get-lineup-indent (b edpos)
6678  "Return the indent level that will line up several lines within the region.
6679Region is defined by B and EDPOS."
6680  (save-excursion
6681    (let ((ind 0) e)
6682      (goto-char b)
6683      ;; Get rightmost position
6684      (while (progn (setq e (marker-position edpos))
6685		    (< (point) e))
6686	(if (verilog-re-search-forward
6687	     (or (and verilog-indent-declaration-macros
6688		      verilog-declaration-re-1-macro)
6689		 verilog-declaration-re-1-no-macro) e 'move)
6690	    (progn
6691	      (goto-char (match-end 0))
6692	      (verilog-backward-syntactic-ws)
6693	      (if (> (current-column) ind)
6694		  (setq ind (current-column)))
6695	      (goto-char (match-end 0)))))
6696      (if (> ind 0)
6697	  (1+ ind)
6698	;; No lineup-string found
6699	(goto-char b)
6700	(end-of-line)
6701	(verilog-backward-syntactic-ws)
6702	;;(skip-chars-backward " \t")
6703	(1+ (current-column))))))
6704
6705(defun verilog-get-lineup-indent-2 (myre b edpos)
6706  "Return the indent level that will line up several lines within the region."
6707  (save-excursion
6708    (let ((ind 0) e)
6709      (goto-char b)
6710      ;; Get rightmost position
6711      (while (progn (setq e (marker-position edpos))
6712		    (< (point) e))
6713	(if (and (verilog-re-search-forward myre e 'move)
6714		 (not (verilog-in-attribute-p))) ;; skip attribute exprs
6715	    (progn
6716	      (goto-char (match-beginning 2))
6717	      (verilog-backward-syntactic-ws)
6718	      (if (> (current-column) ind)
6719		  (setq ind (current-column)))
6720	      (goto-char (match-end 0)))
6721	  ))
6722      (if (> ind 0)
6723	  (1+ ind)
6724	;; No lineup-string found
6725	(goto-char b)
6726	(end-of-line)
6727	(skip-chars-backward " \t")
6728	(1+ (current-column))))))
6729
6730(defun verilog-comment-depth (type val)
6731  "A useful mode debugging aide.  TYPE and VAL are comments for insertion."
6732  (save-excursion
6733    (let
6734	((b (prog2
6735		(beginning-of-line)
6736		(point-marker)
6737	      (end-of-line)))
6738	 (e (point-marker)))
6739      (if (re-search-backward " /\\* \[#-\]# \[a-zA-Z\]+ \[0-9\]+ ## \\*/" b t)
6740	  (progn
6741	    (replace-match " /* -#  ## */")
6742	    (end-of-line))
6743	(progn
6744	  (end-of-line)
6745	  (insert " /* ##  ## */"))))
6746    (backward-char 6)
6747    (insert
6748     (format "%s %d" type val))))
6749
6750;;
6751;;
6752;; Completion
6753;;
6754(defvar verilog-str nil)
6755(defvar verilog-all nil)
6756(defvar verilog-pred nil)
6757(defvar verilog-buffer-to-use nil)
6758(defvar verilog-flag nil)
6759(defvar verilog-toggle-completions nil
6760  "True means \\<verilog-mode-map>\\[verilog-complete-word] should try all possible completions one by one.
6761Repeated use of \\[verilog-complete-word] will show you all of them.
6762Normally, when there is more than one possible completion,
6763it displays a list of all possible completions.")
6764
6765
6766(defvar verilog-type-keywords
6767  '(
6768    "and" "buf" "bufif0" "bufif1" "cmos" "defparam" "inout" "input"
6769    "integer" "localparam" "logic" "mailbox" "nand" "nmos" "nor" "not" "notif0"
6770    "notif1" "or" "output" "parameter" "pmos" "pull0" "pull1" "pulldown" "pullup"
6771    "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran" "rtranif0"
6772    "rtranif1" "semaphore" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1"
6773    "triand" "trior" "trireg" "wand" "wire" "wor" "xnor" "xor"
6774    )
6775  "Keywords for types used when completing a word in a declaration or parmlist.
6776\(integer, real, reg...)")
6777
6778(defvar verilog-cpp-keywords
6779  '("module" "macromodule" "primitive" "timescale" "define" "ifdef" "ifndef" "else"
6780    "endif")
6781  "Keywords to complete when at first word of a line in declarative scope.
6782\(initial, always, begin, assign...)
6783The procedures and variables defined within the Verilog program
6784will be completed at runtime and should not be added to this list.")
6785
6786(defvar verilog-defun-keywords
6787  (append
6788   '(
6789     "always" "always_comb" "always_ff" "always_latch" "assign"
6790     "begin" "end" "generate" "endgenerate" "module" "endmodule"
6791     "specify" "endspecify" "function" "endfunction" "initial" "final"
6792     "task" "endtask" "primitive" "endprimitive"
6793     )
6794   verilog-type-keywords)
6795  "Keywords to complete when at first word of a line in declarative scope.
6796\(initial, always, begin, assign...)
6797The procedures and variables defined within the Verilog program
6798will be completed at runtime and should not be added to this list.")
6799
6800(defvar verilog-block-keywords
6801  '(
6802    "begin" "break" "case" "continue" "else" "end" "endfunction"
6803    "endgenerate" "endinterface" "endpackage" "endspecify" "endtask"
6804    "for" "fork" "if" "join" "join_any" "join_none" "repeat" "return"
6805    "while")
6806  "Keywords to complete when at first word of a line in behavioral scope.
6807\(begin, if, then, else, for, fork...)
6808The procedures and variables defined within the Verilog program
6809will be completed at runtime and should not be added to this list.")
6810
6811(defvar verilog-tf-keywords
6812  '("begin" "break" "fork" "join" "join_any" "join_none" "case" "end" "endtask" "endfunction" "if" "else" "for" "while" "repeat")
6813  "Keywords to complete when at first word of a line in a task or function.
6814\(begin, if, then, else, for, fork.)
6815The procedures and variables defined within the Verilog program
6816will be completed at runtime and should not be added to this list.")
6817
6818(defvar verilog-case-keywords
6819  '("begin" "fork" "join" "join_any" "join_none" "case" "end" "endcase" "if" "else" "for" "repeat")
6820  "Keywords to complete when at first word of a line in case scope.
6821\(begin, if, then, else, for, fork...)
6822The procedures and variables defined within the Verilog program
6823will be completed at runtime and should not be added to this list.")
6824
6825(defvar verilog-separator-keywords
6826  '("else" "then" "begin")
6827  "Keywords to complete when NOT standing at the first word of a statement.
6828\(else, then, begin...)
6829Variables and function names defined within the Verilog program
6830will be completed at runtime and should not be added to this list.")
6831
6832(defvar verilog-gate-ios
6833  ;; All these have an implied {"input"...} at the end
6834  '(("and"	"output")
6835    ("buf"	"output")
6836    ("bufif0"	"output")
6837    ("bufif1"	"output")
6838    ("cmos"	"output")
6839    ("nand"	"output")
6840    ("nmos"	"output")
6841    ("nor"	"output")
6842    ("not"	"output")
6843    ("notif0"	"output")
6844    ("notif1"	"output")
6845    ("or"	"output")
6846    ("pmos"	"output")
6847    ("pulldown"	"output")
6848    ("pullup"	"output")
6849    ("rcmos"	"output")
6850    ("rnmos"	"output")
6851    ("rpmos"	"output")
6852    ("rtran"	"inout" "inout")
6853    ("rtranif0"	"inout" "inout")
6854    ("rtranif1"	"inout" "inout")
6855    ("tran"	"inout" "inout")
6856    ("tranif0"	"inout" "inout")
6857    ("tranif1"	"inout" "inout")
6858    ("xnor"	"output")
6859    ("xor"	"output"))
6860  "Map of direction for each positional argument to each gate primitive.")
6861
6862(defvar verilog-gate-keywords (mapcar `car verilog-gate-ios)
6863  "Keywords for gate primitives.")
6864
6865(defun verilog-string-diff (str1 str2)
6866  "Return index of first letter where STR1 and STR2 differs."
6867  (catch 'done
6868    (let ((diff 0))
6869      (while t
6870	(if (or (> (1+ diff) (length str1))
6871		(> (1+ diff) (length str2)))
6872	    (throw 'done diff))
6873	(or (equal (aref str1 diff) (aref str2 diff))
6874	    (throw 'done diff))
6875	(setq diff (1+ diff))))))
6876
6877;; Calculate all possible completions for functions if argument is `function',
6878;; completions for procedures if argument is `procedure' or both functions and
6879;; procedures otherwise.
6880
6881(defun verilog-func-completion (type)
6882  "Build regular expression for module/task/function names.
6883TYPE is 'module, 'tf for task or function, or t if unknown."
6884  (if (string= verilog-str "")
6885      (setq verilog-str "[a-zA-Z_]"))
6886  (let ((verilog-str (concat (cond
6887			     ((eq type 'module) "\\<\\(module\\)\\s +")
6888			     ((eq type 'tf) "\\<\\(task\\|function\\)\\s +")
6889			     (t "\\<\\(task\\|function\\|module\\)\\s +"))
6890			    "\\<\\(" verilog-str "[a-zA-Z0-9_.]*\\)\\>"))
6891	match)
6892
6893    (if (not (looking-at verilog-defun-re))
6894	(verilog-re-search-backward verilog-defun-re nil t))
6895    (forward-char 1)
6896
6897    ;; Search through all reachable functions
6898    (goto-char (point-min))
6899    (while (verilog-re-search-forward verilog-str (point-max) t)
6900      (progn (setq match (buffer-substring (match-beginning 2)
6901					   (match-end 2)))
6902	     (if (or (null verilog-pred)
6903		     (funcall verilog-pred match))
6904		 (setq verilog-all (cons match verilog-all)))))
6905    (if (match-beginning 0)
6906	(goto-char (match-beginning 0)))))
6907
6908(defun verilog-get-completion-decl (end)
6909  "Macro for searching through current declaration (var, type or const)
6910for matches of `str' and adding the occurrence tp `all' through point END."
6911  (let ((re (or (and verilog-indent-declaration-macros
6912		     verilog-declaration-re-2-macro)
6913		verilog-declaration-re-2-no-macro))
6914	decl-end match)
6915    ;; Traverse lines
6916    (while (and (< (point) end)
6917		(verilog-re-search-forward re end t))
6918      ;; Traverse current line
6919      (setq decl-end (save-excursion (verilog-declaration-end)))
6920      (while (and (verilog-re-search-forward verilog-symbol-re decl-end t)
6921		  (not (match-end 1)))
6922	(setq match (buffer-substring (match-beginning 0) (match-end 0)))
6923	(if (string-match (concat "\\<" verilog-str) match)
6924	    (if (or (null verilog-pred)
6925		    (funcall verilog-pred match))
6926		(setq verilog-all (cons match verilog-all)))))
6927      (forward-line 1)))
6928  verilog-all)
6929
6930(defun verilog-type-completion ()
6931  "Calculate all possible completions for types."
6932  (let ((start (point))
6933	goon)
6934    ;; Search for all reachable type declarations
6935    (while (or (verilog-beg-of-defun)
6936	       (setq goon (not goon)))
6937      (save-excursion
6938	(if (and (< start (prog1 (save-excursion (verilog-end-of-defun)
6939						 (point))
6940			    (forward-char 1)))
6941		 (verilog-re-search-forward
6942		  "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
6943		  start t)
6944		 (not (match-end 1)))
6945	    ;; Check current type declaration
6946	    (verilog-get-completion-decl start))))))
6947
6948(defun verilog-var-completion ()
6949  "Calculate all possible completions for variables (or constants)."
6950  (let ((start (point)))
6951    ;; Search for all reachable var declarations
6952    (verilog-beg-of-defun)
6953    (save-excursion
6954      ;; Check var declarations
6955      (verilog-get-completion-decl start))))
6956
6957(defun verilog-keyword-completion (keyword-list)
6958  "Give list of all possible completions of keywords in KEYWORD-LIST."
6959  (mapcar (lambda (s)
6960	    (if (string-match (concat "\\<" verilog-str) s)
6961		(if (or (null verilog-pred)
6962			(funcall verilog-pred s))
6963		    (setq verilog-all (cons s verilog-all)))))
6964	  keyword-list))
6965
6966
6967(defun verilog-completion (verilog-str verilog-pred verilog-flag)
6968  "Function passed to `completing-read', `try-completion' or `all-completions'.
6969Called to get completion on VERILOG-STR.  If VERILOG-PRED is non-nil, it
6970must be a function to be called for every match to check if this should
6971really be a match.  If VERILOG-FLAG is t, the function returns a list of
6972all possible completions.  If VERILOG-FLAG is nil it returns a string,
6973the longest possible completion, or t if VERILOG-STR is an exact match.
6974If VERILOG-FLAG is 'lambda, the function returns t if VERILOG-STR is an
6975exact match, nil otherwise."
6976  (save-excursion
6977    (let ((verilog-all nil))
6978      ;; Set buffer to use for searching labels. This should be set
6979      ;; within functions which use verilog-completions
6980      (set-buffer verilog-buffer-to-use)
6981
6982      ;; Determine what should be completed
6983      (let ((state (car (verilog-calculate-indent))))
6984	(cond ((eq state 'defun)
6985	       (save-excursion (verilog-var-completion))
6986	       (verilog-func-completion 'module)
6987	       (verilog-keyword-completion verilog-defun-keywords))
6988
6989	      ((eq state 'behavioral)
6990	       (save-excursion (verilog-var-completion))
6991	       (verilog-func-completion 'module)
6992	       (verilog-keyword-completion verilog-defun-keywords))
6993
6994	      ((eq state 'block)
6995	       (save-excursion (verilog-var-completion))
6996	       (verilog-func-completion 'tf)
6997	       (verilog-keyword-completion verilog-block-keywords))
6998
6999	      ((eq state 'case)
7000	       (save-excursion (verilog-var-completion))
7001	       (verilog-func-completion 'tf)
7002	       (verilog-keyword-completion verilog-case-keywords))
7003
7004	      ((eq state 'tf)
7005	       (save-excursion (verilog-var-completion))
7006	       (verilog-func-completion 'tf)
7007	       (verilog-keyword-completion verilog-tf-keywords))
7008
7009	      ((eq state 'cpp)
7010	       (save-excursion (verilog-var-completion))
7011	       (verilog-keyword-completion verilog-cpp-keywords))
7012
7013	      ((eq state 'cparenexp)
7014	       (save-excursion (verilog-var-completion)))
7015
7016	      (t;--Anywhere else
7017	       (save-excursion (verilog-var-completion))
7018	       (verilog-func-completion 'both)
7019	       (verilog-keyword-completion verilog-separator-keywords))))
7020
7021      ;; Now we have built a list of all matches. Give response to caller
7022      (verilog-completion-response))))
7023
7024(defun verilog-completion-response ()
7025  (cond ((or (equal verilog-flag 'lambda) (null verilog-flag))
7026	 ;; This was not called by all-completions
7027	 (if (null verilog-all)
7028	     ;; Return nil if there was no matching label
7029	     nil
7030	   ;; Get longest string common in the labels
7031	   (let* ((elm (cdr verilog-all))
7032		  (match (car verilog-all))
7033		  (min (length match))
7034		  tmp)
7035	     (if (string= match verilog-str)
7036		 ;; Return t if first match was an exact match
7037		 (setq match t)
7038	       (while (not (null elm))
7039		 ;; Find longest common string
7040		 (if (< (setq tmp (verilog-string-diff match (car elm))) min)
7041		     (progn
7042		       (setq min tmp)
7043		       (setq match (substring match 0 min))))
7044		 ;; Terminate with match=t if this is an exact match
7045		 (if (string= (car elm) verilog-str)
7046		     (progn
7047		       (setq match t)
7048		       (setq elm nil))
7049		   (setq elm (cdr elm)))))
7050	     ;; If this is a test just for exact match, return nil ot t
7051	     (if (and (equal verilog-flag 'lambda) (not (equal match 't)))
7052		 nil
7053	       match))))
7054	;; If flag is t, this was called by all-completions. Return
7055	;; list of all possible completions
7056	(verilog-flag
7057	 verilog-all)))
7058
7059(defvar verilog-last-word-numb 0)
7060(defvar verilog-last-word-shown nil)
7061(defvar verilog-last-completions nil)
7062
7063(defun verilog-complete-word ()
7064  "Complete word at current point.
7065\(See also `verilog-toggle-completions', `verilog-type-keywords',
7066and `verilog-separator-keywords'.)"
7067  (interactive)
7068  (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
7069	 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
7070	 (verilog-str (buffer-substring b e))
7071	 ;; The following variable is used in verilog-completion
7072	 (verilog-buffer-to-use (current-buffer))
7073	 (allcomp (if (and verilog-toggle-completions
7074			   (string= verilog-last-word-shown verilog-str))
7075		      verilog-last-completions
7076		    (all-completions verilog-str 'verilog-completion)))
7077	 (match (if verilog-toggle-completions
7078		    "" (try-completion
7079			verilog-str (mapcar (lambda (elm)
7080					      (cons elm 0)) allcomp)))))
7081    ;; Delete old string
7082    (delete-region b e)
7083
7084    ;; Toggle-completions inserts whole labels
7085    (if verilog-toggle-completions
7086	(progn
7087	  ;; Update entry number in list
7088	  (setq verilog-last-completions allcomp
7089		verilog-last-word-numb
7090		(if (>= verilog-last-word-numb (1- (length allcomp)))
7091		    0
7092		  (1+ verilog-last-word-numb)))
7093	  (setq verilog-last-word-shown (elt allcomp verilog-last-word-numb))
7094	  ;; Display next match or same string if no match was found
7095	  (if (not (null allcomp))
7096	      (insert "" verilog-last-word-shown)
7097	    (insert "" verilog-str)
7098	    (message "(No match)")))
7099      ;; The other form of completion does not necessarily do that.
7100
7101      ;; Insert match if found, or the original string if no match
7102      (if (or (null match) (equal match 't))
7103	  (progn (insert "" verilog-str)
7104		 (message "(No match)"))
7105	(insert "" match))
7106      ;; Give message about current status of completion
7107      (cond ((equal match 't)
7108	     (if (not (null (cdr allcomp)))
7109		 (message "(Complete but not unique)")
7110	       (message "(Sole completion)")))
7111	    ;; Display buffer if the current completion didn't help
7112	    ;; on completing the label.
7113	    ((and (not (null (cdr allcomp))) (= (length verilog-str)
7114						(length match)))
7115	     (with-output-to-temp-buffer "*Completions*"
7116	       (display-completion-list allcomp))
7117	     ;; Wait for a key press. Then delete *Completion*  window
7118	     (momentary-string-display "" (point))
7119	     (delete-window (get-buffer-window (get-buffer "*Completions*")))
7120	     )))))
7121
7122(defun verilog-show-completions ()
7123  "Show all possible completions at current point."
7124  (interactive)
7125  (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
7126	 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
7127	 (verilog-str (buffer-substring b e))
7128	 ;; The following variable is used in verilog-completion
7129	 (verilog-buffer-to-use (current-buffer))
7130	 (allcomp (if (and verilog-toggle-completions
7131			   (string= verilog-last-word-shown verilog-str))
7132		      verilog-last-completions
7133		    (all-completions verilog-str 'verilog-completion))))
7134    ;; Show possible completions in a temporary buffer.
7135    (with-output-to-temp-buffer "*Completions*"
7136      (display-completion-list allcomp))
7137    ;; Wait for a key press. Then delete *Completion*  window
7138    (momentary-string-display "" (point))
7139    (delete-window (get-buffer-window (get-buffer "*Completions*")))))
7140
7141
7142(defun verilog-get-default-symbol ()
7143  "Return symbol around current point as a string."
7144  (save-excursion
7145    (buffer-substring (progn
7146			(skip-chars-backward " \t")
7147			(skip-chars-backward "a-zA-Z0-9_")
7148			(point))
7149		      (progn
7150			(skip-chars-forward "a-zA-Z0-9_")
7151			(point)))))
7152
7153(defun verilog-build-defun-re (str &optional arg)
7154  "Return function/task/module starting with STR as regular expression.
7155With optional second ARG non-nil, STR is the complete name of the instruction."
7156  (if arg
7157      (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "\\)\\>")
7158    (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "[a-zA-Z0-9_]*\\)\\>")))
7159
7160(defun verilog-comp-defun (verilog-str verilog-pred verilog-flag)
7161  "Function passed to `completing-read', `try-completion' or `all-completions'.
7162Returns a completion on any function name based on VERILOG-STR prefix.  If
7163VERILOG-PRED is non-nil, it must be a function to be called for every match
7164to check if this should really be a match.  If VERILOG-FLAG is t, the
7165function returns a list of all possible completions.  If it is nil it
7166returns a string, the longest possible completion, or t if VERILOG-STR is
7167an exact match.  If VERILOG-FLAG is 'lambda, the function returns t if
7168VERILOG-STR is an exact match, nil otherwise."
7169  (save-excursion
7170    (let ((verilog-all nil)
7171	  match)
7172
7173      ;; Set buffer to use for searching labels. This should be set
7174      ;; within functions which use verilog-completions
7175      (set-buffer verilog-buffer-to-use)
7176
7177      (let ((verilog-str verilog-str))
7178	;; Build regular expression for functions
7179	(if (string= verilog-str "")
7180	    (setq verilog-str (verilog-build-defun-re "[a-zA-Z_]"))
7181	  (setq verilog-str (verilog-build-defun-re verilog-str)))
7182	(goto-char (point-min))
7183
7184	;; Build a list of all possible completions
7185	(while (verilog-re-search-forward verilog-str nil t)
7186	  (setq match (buffer-substring (match-beginning 2) (match-end 2)))
7187	  (if (or (null verilog-pred)
7188		  (funcall verilog-pred match))
7189	      (setq verilog-all (cons match verilog-all)))))
7190
7191      ;; Now we have built a list of all matches. Give response to caller
7192      (verilog-completion-response))))
7193
7194(defun verilog-goto-defun ()
7195  "Move to specified Verilog module/interface/task/function.
7196The default is a name found in the buffer around point.
7197If search fails, other files are checked based on
7198`verilog-library-flags'."
7199  (interactive)
7200  (let* ((default (verilog-get-default-symbol))
7201	 ;; The following variable is used in verilog-comp-function
7202	 (verilog-buffer-to-use (current-buffer))
7203	 (label (if (not (string= default ""))
7204		    ;; Do completion with default
7205		    (completing-read (concat "Goto-Label: (default "
7206					     default ") ")
7207				     'verilog-comp-defun nil nil "")
7208		  ;; There is no default value. Complete without it
7209		  (completing-read "Goto-Label: "
7210				   'verilog-comp-defun nil nil "")))
7211	 pt)
7212    ;; Make sure library paths are correct, in case need to resolve module
7213    (verilog-auto-reeval-locals)
7214    (verilog-getopt-flags)
7215    ;; If there was no response on prompt, use default value
7216    (if (string= label "")
7217	(setq label default))
7218    ;; Goto right place in buffer if label is not an empty string
7219    (or (string= label "")
7220	(progn
7221	  (save-excursion
7222	    (goto-char (point-min))
7223	    (setq pt
7224		  (re-search-forward (verilog-build-defun-re label t) nil t)))
7225	  (when pt
7226	    (goto-char pt)
7227	    (beginning-of-line))
7228	  pt)
7229	(verilog-goto-defun-file label))))
7230
7231;; Eliminate compile warning
7232(defvar occur-pos-list)
7233
7234(defun verilog-showscopes ()
7235  "List all scopes in this module."
7236  (interactive)
7237  (let ((buffer (current-buffer))
7238	(linenum 1)
7239	(nlines 0)
7240	(first 1)
7241	(prevpos (point-min))
7242        (final-context-start (make-marker))
7243	(regexp "\\(module\\s-+\\w+\\s-*(\\)\\|\\(\\w+\\s-+\\w+\\s-*(\\)"))
7244    (with-output-to-temp-buffer "*Occur*"
7245      (save-excursion
7246	(message (format "Searching for %s ..." regexp))
7247	;; Find next match, but give up if prev match was at end of buffer.
7248	(while (and (not (= prevpos (point-max)))
7249		    (verilog-re-search-forward regexp nil t))
7250	  (goto-char (match-beginning 0))
7251	  (beginning-of-line)
7252	  (save-match-data
7253            (setq linenum (+ linenum (count-lines prevpos (point)))))
7254	  (setq prevpos (point))
7255	  (goto-char (match-end 0))
7256	  (let* ((start (save-excursion
7257			  (goto-char (match-beginning 0))
7258			  (forward-line (if (< nlines 0) nlines (- nlines)))
7259			  (point)))
7260		 (end (save-excursion
7261			(goto-char (match-end 0))
7262			(if (> nlines 0)
7263			    (forward-line (1+ nlines))
7264			    (forward-line 1))
7265			(point)))
7266		 (tag (format "%3d" linenum))
7267		 (empty (make-string (length tag) ?\ ))
7268		 tem)
7269	    (save-excursion
7270	      (setq tem (make-marker))
7271	      (set-marker tem (point))
7272	      (set-buffer standard-output)
7273	      (setq occur-pos-list (cons tem occur-pos-list))
7274	      (or first (zerop nlines)
7275		  (insert "--------\n"))
7276	      (setq first nil)
7277	      (insert-buffer-substring buffer start end)
7278	      (backward-char (- end start))
7279	      (setq tem (if (< nlines 0) (- nlines) nlines))
7280	      (while (> tem 0)
7281		(insert empty ?:)
7282		(forward-line 1)
7283		(setq tem (1- tem)))
7284	      (let ((this-linenum linenum))
7285		(set-marker final-context-start
7286			    (+ (point) (- (match-end 0) (match-beginning 0))))
7287		(while (< (point) final-context-start)
7288		  (if (null tag)
7289		      (setq tag (format "%3d" this-linenum)))
7290		  (insert tag ?:)))))))
7291      (set-buffer-modified-p nil))))
7292
7293
7294;; Highlight helper functions
7295(defconst verilog-directive-regexp "\\(translate\\|coverage\\|lint\\)_")
7296(defun verilog-within-translate-off ()
7297  "Return point if within translate-off region, else nil."
7298  (and (save-excursion
7299	 (re-search-backward
7300	  (concat "//\\s-*.*\\s-*" verilog-directive-regexp "\\(on\\|off\\)\\>")
7301	  nil t))
7302       (equal "off" (match-string 2))
7303       (point)))
7304
7305(defun verilog-start-translate-off (limit)
7306  "Return point before translate-off directive if before LIMIT, else nil."
7307  (when (re-search-forward
7308	  (concat "//\\s-*.*\\s-*" verilog-directive-regexp "off\\>")
7309	  limit t)
7310    (match-beginning 0)))
7311
7312(defun verilog-back-to-start-translate-off (limit)
7313  "Return point before translate-off directive if before LIMIT, else nil."
7314  (when (re-search-backward
7315	  (concat "//\\s-*.*\\s-*" verilog-directive-regexp "off\\>")
7316	  limit t)
7317    (match-beginning 0)))
7318
7319(defun verilog-end-translate-off (limit)
7320  "Return point after translate-on directive if before LIMIT, else nil."
7321
7322  (re-search-forward (concat
7323		      "//\\s-*.*\\s-*" verilog-directive-regexp "on\\>") limit t))
7324
7325(defun verilog-match-translate-off (limit)
7326  "Match a translate-off block, setting `match-data' and returning t, else nil.
7327Bound search by LIMIT."
7328  (when (< (point) limit)
7329    (let ((start (or (verilog-within-translate-off)
7330		     (verilog-start-translate-off limit)))
7331	  (case-fold-search t))
7332      (when start
7333	(let ((end (or (verilog-end-translate-off limit) limit)))
7334	  (set-match-data (list start end))
7335	  (goto-char end))))))
7336
7337(defun verilog-font-lock-match-item (limit)
7338  "Match, and move over, any declaration item after point.
7339Bound search by LIMIT.  Adapted from
7340`font-lock-match-c-style-declaration-item-and-skip-to-next'."
7341  (condition-case nil
7342      (save-restriction
7343	(narrow-to-region (point-min) limit)
7344	;; match item
7345	(when (looking-at "\\s-*\\([a-zA-Z]\\w*\\)")
7346	  (save-match-data
7347	    (goto-char (match-end 1))
7348	    ;; move to next item
7349	    (if (looking-at "\\(\\s-*,\\)")
7350		(goto-char (match-end 1))
7351	      (end-of-line) t))))
7352    (error nil)))
7353
7354
7355;; Added by Subbu Meiyappan for Header
7356
7357(defun verilog-header ()
7358  "Insert a standard Verilog file header.
7359See also `verilog-sk-header' for an alternative format."
7360  (interactive)
7361  (let ((start (point)))
7362  (insert "\
7363//-----------------------------------------------------------------------------
7364// Title         : <title>
7365// Project       : <project>
7366//-----------------------------------------------------------------------------
7367// File          : <filename>
7368// Author        : <author>
7369// Created       : <credate>
7370// Last modified : <moddate>
7371//-----------------------------------------------------------------------------
7372// Description :
7373// <description>
7374//-----------------------------------------------------------------------------
7375// Copyright (c) <copydate> by <company> This model is the confidential and
7376// proprietary property of <company> and the possession or use of this
7377// file requires a written license from <company>.
7378//------------------------------------------------------------------------------
7379// Modification history :
7380// <modhist>
7381//-----------------------------------------------------------------------------
7382
7383")
7384    (goto-char start)
7385    (search-forward "<filename>")
7386    (replace-match (buffer-name) t t)
7387    (search-forward "<author>") (replace-match "" t t)
7388    (insert (user-full-name))
7389    (insert "  <" (user-login-name) "@" (system-name) ">")
7390    (search-forward "<credate>") (replace-match "" t t)
7391    (verilog-insert-date)
7392    (search-forward "<moddate>") (replace-match "" t t)
7393    (verilog-insert-date)
7394    (search-forward "<copydate>") (replace-match "" t t)
7395    (verilog-insert-year)
7396    (search-forward "<modhist>") (replace-match "" t t)
7397    (verilog-insert-date)
7398    (insert " : created")
7399    (goto-char start)
7400    (let (string)
7401      (setq string (read-string "title: "))
7402      (search-forward "<title>")
7403      (replace-match string t t)
7404      (setq string (read-string "project: " verilog-project))
7405      (setq verilog-project string)
7406      (search-forward "<project>")
7407      (replace-match string t t)
7408      (setq string (read-string "Company: " verilog-company))
7409      (setq verilog-company string)
7410      (search-forward "<company>")
7411      (replace-match string t t)
7412      (search-forward "<company>")
7413      (replace-match string t t)
7414      (search-forward "<company>")
7415      (replace-match string t t)
7416      (search-backward "<description>")
7417      (replace-match "" t t))))
7418
7419;; verilog-header Uses the verilog-insert-date function
7420
7421(defun verilog-insert-date ()
7422  "Insert date from the system."
7423  (interactive)
7424  (if verilog-date-scientific-format
7425      (insert (format-time-string "%Y/%m/%d"))
7426    (insert (format-time-string "%d.%m.%Y"))))
7427
7428(defun verilog-insert-year ()
7429  "Insert year from the system."
7430  (interactive)
7431  (insert (format-time-string "%Y")))
7432
7433
7434;;
7435;; Signal list parsing
7436;;
7437
7438;; Elements of a signal list
7439;; Unfortunately we use 'assoc' on this, so can't be a vector
7440(defsubst verilog-sig-new (name bits comment mem enum signed type multidim modport)
7441  (list name bits comment mem enum signed type multidim modport))
7442(defsubst verilog-sig-name (sig)
7443  (car sig))
7444(defsubst verilog-sig-bits (sig)
7445  (nth 1 sig))
7446(defsubst verilog-sig-comment (sig)
7447  (nth 2 sig))
7448(defsubst verilog-sig-memory (sig)
7449  (nth 3 sig))
7450(defsubst verilog-sig-enum (sig)
7451  (nth 4 sig))
7452(defsubst verilog-sig-signed (sig)
7453  (nth 5 sig))
7454(defsubst verilog-sig-type (sig)
7455  (nth 6 sig))
7456(defsubst verilog-sig-type-set (sig type)
7457  (setcar (nthcdr 6 sig) type))
7458(defsubst verilog-sig-multidim (sig)
7459  (nth 7 sig))
7460(defsubst verilog-sig-multidim-string (sig)
7461  (if (verilog-sig-multidim sig)
7462      (let ((str "") (args (verilog-sig-multidim sig)))
7463	(while args
7464	  (setq str (concat str (car args)))
7465	  (setq args (cdr args)))
7466	str)))
7467(defsubst verilog-sig-modport (sig)
7468  (nth 8 sig))
7469(defsubst verilog-sig-width (sig)
7470  (verilog-make-width-expression (verilog-sig-bits sig)))
7471
7472(defsubst verilog-alw-new (outputs-del outputs-imm temps inputs)
7473  (vector outputs-del outputs-imm temps inputs))
7474(defsubst verilog-alw-get-outputs-delayed (sigs)
7475  (aref sigs 0))
7476(defsubst verilog-alw-get-outputs-immediate (sigs)
7477  (aref sigs 1))
7478(defsubst verilog-alw-get-temps (sigs)
7479  (aref sigs 2))
7480(defsubst verilog-alw-get-inputs (sigs)
7481  (aref sigs 3))
7482(defsubst verilog-alw-get-uses-delayed (sigs)
7483  (aref sigs 0))
7484
7485(defsubst verilog-modi-new (name fob pt type)
7486  (vector name fob pt type))
7487(defsubst verilog-modi-name (modi)
7488  (aref modi 0))
7489(defsubst verilog-modi-file-or-buffer (modi)
7490  (aref modi 1))
7491(defsubst verilog-modi-get-point (modi)
7492  (aref modi 2))
7493(defsubst verilog-modi-get-type (modi) ;; "module" or "interface"
7494  (aref modi 3))
7495(defsubst verilog-modi-get-decls (modi)
7496  (verilog-modi-cache-results modi 'verilog-read-decls))
7497(defsubst verilog-modi-get-sub-decls (modi)
7498  (verilog-modi-cache-results modi 'verilog-read-sub-decls))
7499
7500;; Signal reading for given module
7501;; Note these all take modi's - as returned from verilog-modi-current
7502(defsubst verilog-decls-new (out inout in vars unuseds assigns consts gparams interfaces)
7503  (vector out inout in vars unuseds assigns consts gparams interfaces))
7504(defsubst verilog-decls-get-outputs (decls)
7505  (aref decls 0))
7506(defsubst verilog-decls-get-inouts (decls)
7507  (aref decls 1))
7508(defsubst verilog-decls-get-inputs (decls)
7509  (aref decls 2))
7510(defsubst verilog-decls-get-vars (decls)
7511  (aref decls 3))
7512;;(defsubst verilog-decls-get-unused (decls)
7513;;  (aref decls 4))
7514(defsubst verilog-decls-get-assigns (decls)
7515  (aref decls 5))
7516(defsubst verilog-decls-get-consts (decls)
7517  (aref decls 6))
7518(defsubst verilog-decls-get-gparams (decls)
7519  (aref decls 7))
7520(defsubst verilog-decls-get-interfaces (decls)
7521  (aref decls 8))
7522
7523(defsubst verilog-subdecls-new (out inout in intf intfd)
7524  (vector out inout in intf intfd))
7525(defsubst verilog-subdecls-get-outputs (subdecls)
7526  (aref subdecls 0))
7527(defsubst verilog-subdecls-get-inouts (subdecls)
7528  (aref subdecls 1))
7529(defsubst verilog-subdecls-get-inputs (subdecls)
7530  (aref subdecls 2))
7531(defsubst verilog-subdecls-get-interfaces (subdecls)
7532  (aref subdecls 3))
7533(defsubst verilog-subdecls-get-interfaced (subdecls)
7534  (aref subdecls 4))
7535
7536(defun verilog-signals-from-signame (signame-list)
7537  "Return signals in standard form from SIGNAME-LIST, a simple list of names."
7538  (mapcar (lambda (name) (verilog-sig-new name nil nil nil nil nil nil nil nil))
7539	  signame-list))
7540
7541(defun verilog-signals-not-in (in-list not-list)
7542  "Return list of signals in IN-LIST that aren't also in NOT-LIST.
7543Also remove any duplicates in IN-LIST.
7544Signals must be in standard (base vector) form."
7545  ;; This function is hot, so implemented as O(1)
7546  (cond ((eval-when-compile (fboundp 'make-hash-table))
7547	 (let ((ht (make-hash-table :test 'equal :rehash-size 4.0))
7548	       out-list)
7549	   (while not-list
7550	     (puthash (car (car not-list)) t ht)
7551	     (setq not-list (cdr not-list)))
7552	   (while in-list
7553	     (when (not (gethash (verilog-sig-name (car in-list)) ht))
7554	       (setq out-list (cons (car in-list) out-list))
7555	       (puthash (verilog-sig-name (car in-list)) t ht))
7556	     (setq in-list (cdr in-list)))
7557	   (nreverse out-list)))
7558	;; Slower Fallback if no hash tables (pre Emacs 21.1/XEmacs 21.4)
7559	(t
7560	 (let (out-list)
7561	   (while in-list
7562	     (if (not (or (assoc (verilog-sig-name (car in-list)) not-list)
7563			  (assoc (verilog-sig-name (car in-list)) out-list)))
7564		 (setq out-list (cons (car in-list) out-list)))
7565	     (setq in-list (cdr in-list)))
7566	   (nreverse out-list)))))
7567;;(verilog-signals-not-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" "")))
7568
7569(defun verilog-signals-memory (in-list)
7570  "Return list of signals in IN-LIST that are memorized (multidimensional)."
7571  (let (out-list)
7572    (while in-list
7573      (if (nth 3 (car in-list))
7574	  (setq out-list (cons (car in-list) out-list)))
7575      (setq in-list (cdr in-list)))
7576    out-list))
7577;;(verilog-signals-memory '(("A" nil nil "[3:0]")) '(("B" nil nil nil)))
7578
7579(defun verilog-signals-sort-compare (a b)
7580  "Compare signal A and B for sorting."
7581  (string< (verilog-sig-name a) (verilog-sig-name b)))
7582
7583(defun verilog-signals-not-params (in-list)
7584  "Return list of signals in IN-LIST that aren't parameters or numeric constants."
7585  (let (out-list)
7586    (while in-list
7587      (unless (boundp (intern (concat "vh-" (verilog-sig-name (car in-list)))))
7588	(setq out-list (cons (car in-list) out-list)))
7589      (setq in-list (cdr in-list)))
7590    (nreverse out-list)))
7591
7592(defun verilog-signals-with (func in-list)
7593  "Return IN-LIST with only signals where FUNC passed each signal is true."
7594  (let (out-list)
7595    (while in-list
7596      (when (funcall func (car in-list))
7597	(setq out-list (cons (car in-list) out-list)))
7598      (setq in-list (cdr in-list)))
7599    (nreverse out-list)))
7600
7601(defun verilog-signals-combine-bus (in-list)
7602  "Return a list of signals in IN-LIST, with buses combined.
7603Duplicate signals are also removed.  For example A[2] and A[1] become A[2:1]."
7604  (let (combo buswarn
7605	out-list
7606	sig highbit lowbit		; Temp information about current signal
7607	sv-name sv-highbit sv-lowbit	; Details about signal we are forming
7608	sv-comment sv-memory sv-enum sv-signed sv-type sv-multidim sv-busstring
7609	sv-modport
7610	bus)
7611    ;; Shove signals so duplicated signals will be adjacent
7612    (setq in-list (sort in-list `verilog-signals-sort-compare))
7613    (while in-list
7614      (setq sig (car in-list))
7615      ;; No current signal; form from existing details
7616      (unless sv-name
7617	(setq sv-name    (verilog-sig-name sig)
7618	      sv-highbit nil
7619	      sv-busstring nil
7620	      sv-comment (verilog-sig-comment sig)
7621	      sv-memory  (verilog-sig-memory sig)
7622	      sv-enum    (verilog-sig-enum sig)
7623	      sv-signed  (verilog-sig-signed sig)
7624	      sv-type    (verilog-sig-type sig)
7625	      sv-multidim (verilog-sig-multidim sig)
7626	      sv-modport  (verilog-sig-modport sig)
7627	      combo ""
7628	      buswarn ""))
7629      ;; Extract bus details
7630      (setq bus (verilog-sig-bits sig))
7631      (setq bus (and bus (verilog-simplify-range-expression bus)))
7632      (cond ((and bus
7633		  (or (and (string-match "\\[\\([0-9]+\\):\\([0-9]+\\)\\]" bus)
7634			   (setq highbit (string-to-number (match-string 1 bus))
7635				 lowbit  (string-to-number
7636					  (match-string 2 bus))))
7637		      (and (string-match "\\[\\([0-9]+\\)\\]" bus)
7638			   (setq highbit (string-to-number (match-string 1 bus))
7639				 lowbit  highbit))))
7640	     ;; Combine bits in bus
7641	     (if sv-highbit
7642		 (setq sv-highbit (max highbit sv-highbit)
7643		       sv-lowbit  (min lowbit  sv-lowbit))
7644	       (setq sv-highbit highbit
7645		     sv-lowbit  lowbit)))
7646	    (bus
7647	     ;; String, probably something like `preproc:0
7648	     (setq sv-busstring bus)))
7649      ;; Peek ahead to next signal
7650      (setq in-list (cdr in-list))
7651      (setq sig (car in-list))
7652      (cond ((and sig (equal sv-name (verilog-sig-name sig)))
7653	     ;; Combine with this signal
7654	     (when (and sv-busstring
7655			(not (equal sv-busstring (verilog-sig-bits sig))))
7656	       (when nil  ;; Debugging
7657		 (message (concat "Warning, can't merge into single bus "
7658				  sv-name bus
7659				  ", the AUTOs may be wrong")))
7660	       (setq buswarn ", Couldn't Merge"))
7661	     (if (verilog-sig-comment sig) (setq combo ", ..."))
7662	     (setq sv-memory (or sv-memory (verilog-sig-memory sig))
7663		   sv-enum   (or sv-enum   (verilog-sig-enum sig))
7664		   sv-signed (or sv-signed (verilog-sig-signed sig))
7665                   sv-type   (or sv-type   (verilog-sig-type sig))
7666                   sv-multidim (or sv-multidim (verilog-sig-multidim sig))
7667                   sv-modport  (or sv-modport  (verilog-sig-modport sig))))
7668	    ;; Doesn't match next signal, add to queue, zero in prep for next
7669	    ;; Note sig may also be nil for the last signal in the list
7670	    (t
7671	     (setq out-list
7672		   (cons (verilog-sig-new
7673			  sv-name
7674			  (or sv-busstring
7675			      (if sv-highbit
7676				  (concat "[" (int-to-string sv-highbit) ":"
7677					  (int-to-string sv-lowbit) "]")))
7678			  (concat sv-comment combo buswarn)
7679			  sv-memory sv-enum sv-signed sv-type sv-multidim sv-modport)
7680			 out-list)
7681		   sv-name nil))))
7682    ;;
7683    out-list))
7684
7685(defun verilog-sig-tieoff (sig)
7686  "Return tieoff expression for given SIG, with appropriate width.
7687Tieoff value uses `verilog-active-low-regexp' and
7688`verilog-auto-reset-widths'."
7689  (concat
7690   (if (and verilog-active-low-regexp
7691	    (string-match verilog-active-low-regexp (verilog-sig-name sig)))
7692       "~" "")
7693   (cond ((not verilog-auto-reset-widths)
7694	  "0")
7695	 ((equal verilog-auto-reset-widths 'unbased)
7696	  "'0")
7697	 ;; Else presume verilog-auto-reset-widths is true
7698	 (t
7699	  (let* ((width (verilog-sig-width sig)))
7700	    (if (string-match "^[0-9]+$" width)
7701		(concat width (if (verilog-sig-signed sig) "'sh0" "'h0"))
7702	      (concat "{" width "{1'b0}}")))))))
7703
7704;;
7705;; Dumping
7706;;
7707
7708(defun verilog-decls-princ (decls)
7709  "For debug, dump the `verilog-read-decls' structure DECLS."
7710  (verilog-signals-princ (verilog-decls-get-outputs decls)
7711			 "Outputs:\n" "  ")
7712  (verilog-signals-princ (verilog-decls-get-inouts decls)
7713			 "Inout:\n" "  ")
7714  (verilog-signals-princ (verilog-decls-get-inputs decls)
7715			 "Inputs:\n" "  ")
7716  (verilog-signals-princ (verilog-decls-get-vars decls)
7717			 "Vars:\n" "  ")
7718  (verilog-signals-princ (verilog-decls-get-assigns decls)
7719			 "Assigns:\n" "  ")
7720  (verilog-signals-princ (verilog-decls-get-consts decls)
7721			 "Consts:\n" "  ")
7722  (verilog-signals-princ (verilog-decls-get-gparams decls)
7723			 "Gparams:\n" "  ")
7724  (verilog-signals-princ (verilog-decls-get-interfaces decls)
7725			 "Interfaces:\n" "  ")
7726  (princ "\n"))
7727
7728(defun verilog-signals-princ (signals &optional header prefix)
7729  "For debug, dump internal SIGNALS structures, with HEADER and PREFIX."
7730  (when signals
7731    (princ header)
7732    (while signals
7733      (let ((sig (car signals)))
7734	(setq signals (cdr signals))
7735	(princ prefix)
7736	(princ "\"") (princ (verilog-sig-name sig)) (princ "\"")
7737	(princ "  bits=") (princ (verilog-sig-bits sig))
7738	(princ "  cmt=") (princ (verilog-sig-comment sig))
7739	(princ "  mem=") (princ (verilog-sig-memory sig))
7740	(princ "  enum=") (princ (verilog-sig-enum sig))
7741	(princ "  sign=") (princ (verilog-sig-signed sig))
7742	(princ "  type=") (princ (verilog-sig-type sig))
7743	(princ "  dim=") (princ (verilog-sig-multidim sig))
7744	(princ "  modp=") (princ (verilog-sig-modport sig))
7745	(princ "\n")))))
7746
7747;;
7748;; Port/Wire/Etc Reading
7749;;
7750
7751(defun verilog-read-inst-backward-name ()
7752  "Internal.  Move point back to beginning of inst-name."
7753    (verilog-backward-open-paren)
7754    (let (done)
7755      (while (not done)
7756	(verilog-re-search-backward-quick "\\()\\|\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil)  ; ] isn't word boundary
7757	(cond ((looking-at ")")
7758	       (verilog-backward-open-paren))
7759	      (t (setq done t)))))
7760    (while (looking-at "\\]")
7761      (verilog-backward-open-bracket)
7762      (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil))
7763    (skip-chars-backward "a-zA-Z0-9`_$"))
7764
7765(defun verilog-read-inst-module-matcher ()
7766  "Set match data 0 with module_name when point is inside instantiation."
7767  (verilog-read-inst-backward-name)
7768  ;; Skip over instantiation name
7769  (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|)\\)" nil nil)  ; ) isn't word boundary
7770  ;; Check for parameterized instantiations
7771  (when (looking-at ")")
7772    (verilog-backward-open-paren)
7773    (verilog-re-search-backward-quick "\\b[a-zA-Z0-9`_\$]" nil nil))
7774  (skip-chars-backward "a-zA-Z0-9'_$")
7775  (looking-at "[a-zA-Z0-9`_\$]+")
7776  ;; Important: don't use match string, this must work with Emacs 19 font-lock on
7777  (buffer-substring-no-properties (match-beginning 0) (match-end 0))
7778  ;; Caller assumes match-beginning/match-end is still set
7779  )
7780
7781(defun verilog-read-inst-module ()
7782  "Return module_name when point is inside instantiation."
7783  (save-excursion
7784    (verilog-read-inst-module-matcher)))
7785
7786(defun verilog-read-inst-name ()
7787  "Return instance_name when point is inside instantiation."
7788  (save-excursion
7789    (verilog-read-inst-backward-name)
7790    (looking-at "[a-zA-Z0-9`_\$]+")
7791    ;; Important: don't use match string, this must work with Emacs 19 font-lock on
7792    (buffer-substring-no-properties (match-beginning 0) (match-end 0))))
7793
7794(defun verilog-read-module-name ()
7795  "Return module name when after its ( or ;."
7796  (save-excursion
7797    (re-search-backward "[(;]")
7798    ;; Due to "module x import y (" we must search for declaration begin
7799    (verilog-re-search-backward-quick verilog-defun-re nil nil)
7800    (goto-char (match-end 0))
7801    (verilog-re-search-forward-quick "\\b[a-zA-Z0-9`_\$]+" nil nil)
7802    ;; Important: don't use match string, this must work with Emacs 19 font-lock on
7803    (verilog-symbol-detick
7804     (buffer-substring-no-properties (match-beginning 0) (match-end 0)) t)))
7805
7806(defun verilog-read-inst-param-value ()
7807  "Return list of parameters and values when point is inside instantiation."
7808  (save-excursion
7809    (verilog-read-inst-backward-name)
7810    ;; Skip over instantiation name
7811    (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|)\\)" nil nil)  ; ) isn't word boundary
7812    ;; If there are parameterized instantiations
7813    (when (looking-at ")")
7814      (let ((end-pt (point))
7815	    params
7816	    param-name paren-beg-pt param-value)
7817	(verilog-backward-open-paren)
7818	(while (verilog-re-search-forward-quick "\\." end-pt t)
7819	  (verilog-re-search-forward-quick "\\([a-zA-Z0-9`_\$]\\)" nil nil)
7820	  (skip-chars-backward "a-zA-Z0-9'_$")
7821	  (looking-at "[a-zA-Z0-9`_\$]+")
7822	  (setq param-name (buffer-substring-no-properties
7823			    (match-beginning 0) (match-end 0)))
7824	  (verilog-re-search-forward-quick "(" nil nil)
7825	  (setq paren-beg-pt (point))
7826	  (verilog-forward-close-paren)
7827	  (setq param-value (verilog-string-remove-spaces
7828			     (buffer-substring-no-properties
7829			      paren-beg-pt (1- (point)))))
7830	  (setq params (cons (list param-name param-value) params)))
7831	params))))
7832
7833(defun verilog-read-auto-params (num-param &optional max-param)
7834  "Return parameter list inside auto.
7835Optional NUM-PARAM and MAX-PARAM check for a specific number of parameters."
7836  (let ((olist))
7837    (save-excursion
7838      ;; /*AUTOPUNT("parameter", "parameter")*/
7839      (backward-sexp 1)
7840      (while (looking-at "(?\\s *\"\\([^\"]*\\)\"\\s *,?")
7841	(setq olist (cons (match-string 1) olist))
7842	(goto-char (match-end 0))))
7843    (or (eq nil num-param)
7844	(<= num-param (length olist))
7845	(error "%s: Expected %d parameters" (verilog-point-text) num-param))
7846    (if (eq max-param nil) (setq max-param num-param))
7847    (or (eq nil max-param)
7848	(>= max-param (length olist))
7849	(error "%s: Expected <= %d parameters" (verilog-point-text) max-param))
7850    (nreverse olist)))
7851
7852(defun verilog-read-decls ()
7853  "Compute signal declaration information for the current module at point.
7854Return an array of [outputs inouts inputs wire reg assign const]."
7855  (let ((end-mod-point (or (verilog-get-end-of-defun t) (point-max)))
7856	(functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t)
7857	in-modport ptype ign-prop
7858	sigs-in sigs-out sigs-inout sigs-var sigs-assign sigs-const
7859	sigs-gparam sigs-intf
7860	vec expect-signal keywd newsig rvalue enum io signed typedefed multidim
7861	modport)
7862    (save-excursion
7863      (verilog-beg-of-defun-quick)
7864      (setq sigs-const (verilog-read-auto-constants (point) end-mod-point))
7865      (while (< (point) end-mod-point)
7866	;;(if dbg (setq dbg (concat dbg (format "Pt %s  Vec %s   C%c Kwd'%s'\n" (point) vec (following-char) keywd))))
7867	(cond
7868	 ((looking-at "//")
7869	  (if (looking-at "[^\n]*\\(auto\\|synopsys\\)\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
7870	      (setq enum (match-string 2)))
7871	  (search-forward "\n"))
7872	 ((looking-at "/\\*")
7873	  (forward-char 2)
7874	  (if (looking-at "[^\n]*\\(auto\\|synopsys\\)\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
7875	      (setq enum (match-string 2)))
7876	  (or (search-forward "*/")
7877	      (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
7878	 ((looking-at "(\\*")
7879	  ;; To advance past either "(*)" or "(* ... *)" don't forward past first *
7880	  (forward-char 1)
7881	  (or (search-forward "*)")
7882	      (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
7883	 ((eq ?\" (following-char))
7884	  (or (re-search-forward "[^\\]\"" nil t)	;; don't forward-char first, since we look for a non backslash first
7885	      (error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
7886	 ((eq ?\; (following-char))
7887	  (setq vec nil  io nil  expect-signal nil  newsig nil  paren 0  rvalue nil
7888		v2kargs-ok nil  in-modport nil  ign-prop nil)
7889	  (forward-char 1))
7890	 ((eq ?= (following-char))
7891	  (setq rvalue t  newsig nil)
7892	  (forward-char 1))
7893	 ((and (eq ?, (following-char))
7894	       (eq paren sig-paren))
7895	  (setq rvalue nil)
7896	  (forward-char 1))
7897	 ;; ,'s can occur inside {} & funcs
7898	 ((looking-at "[{(]")
7899	  (setq paren (1+ paren))
7900	  (forward-char 1))
7901	 ((looking-at "[})]")
7902	  (setq paren (1- paren))
7903	  (forward-char 1)
7904	  (when (< paren sig-paren)
7905	    (setq expect-signal nil)))   ; ) that ends variables inside v2k arg list
7906	 ((looking-at "\\s-*\\(\\[[^]]+\\]\\)")
7907	  (goto-char (match-end 0))
7908	  (cond (newsig	; Memory, not just width.  Patch last signal added's memory (nth 3)
7909		 (setcar (cdr (cdr (cdr newsig)))
7910			 (if (verilog-sig-memory newsig)
7911			     (concat (verilog-sig-memory newsig) (match-string 1))
7912			   (match-string 1))))
7913		(vec ;; Multidimensional
7914		 (setq multidim (cons vec multidim))
7915		 (setq vec (verilog-string-replace-matches
7916			    "\\s-+" "" nil nil (match-string 1))))
7917		(t ;; Bit width
7918		 (setq vec (verilog-string-replace-matches
7919			    "\\s-+" "" nil nil (match-string 1))))))
7920	 ;; Normal or escaped identifier -- note we remember the \ if escaped
7921	 ((looking-at "\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
7922	  (goto-char (match-end 0))
7923	  (setq keywd (match-string 1))
7924	  (when (string-match "^\\\\" (match-string 1))
7925	    (setq keywd (concat keywd " ")))  ;; Escaped ID needs space at end
7926	  ;; Add any :: package names to same identifier
7927	  (while (looking-at "\\s-*::\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
7928	    (goto-char (match-end 0))
7929	    (setq keywd (concat keywd "::" (match-string 1)))
7930	    (when (string-match "^\\\\" (match-string 1))
7931	      (setq keywd (concat keywd " "))))  ;; Escaped ID needs space at end
7932	  (cond ((equal keywd "input")
7933		 (setq vec nil        enum nil      rvalue nil  newsig nil  signed nil
7934		       typedefed nil  multidim nil  ptype nil   modport nil
7935		       expect-signal 'sigs-in       io t        sig-paren paren))
7936		((equal keywd "output")
7937		 (setq vec nil        enum nil      rvalue nil  newsig nil  signed nil
7938		       typedefed nil  multidim nil  ptype nil   modport nil
7939		       expect-signal 'sigs-out      io t        sig-paren paren))
7940		((equal keywd "inout")
7941		 (setq vec nil        enum nil      rvalue nil  newsig nil  signed nil
7942		       typedefed nil  multidim nil  ptype nil   modport nil
7943		       expect-signal 'sigs-inout    io t        sig-paren paren))
7944		((equal keywd "parameter")
7945		 (setq vec nil        enum nil      rvalue nil  signed nil
7946		       typedefed nil  multidim nil  ptype nil   modport nil
7947		       expect-signal 'sigs-gparam   io t        sig-paren paren))
7948		((member keywd '("wire" "reg"  ; Fast
7949				 ;; net_type
7950				 "tri" "tri0" "tri1" "triand" "trior" "trireg"
7951				 "uwire" "wand" "wor"
7952				 ;; integer_atom_type
7953				 "byte" "shortint" "int" "longint" "integer" "time"
7954				 "supply0" "supply1"
7955				 ;; integer_vector_type - "reg" above
7956				 "bit" "logic"
7957				 ;; non_integer_type
7958				 "shortreal" "real" "realtime"
7959				 ;; data_type
7960				 "string" "event" "chandle"))
7961		 (cond (io
7962			(setq typedefed
7963			      (if typedefed (concat typedefed " " keywd) keywd)))
7964		       (t (setq vec nil  enum nil  rvalue nil  signed nil
7965				typedefed nil  multidim nil  sig-paren paren
7966				expect-signal 'sigs-var  modport nil))))
7967		((equal keywd "assign")
7968		 (setq vec nil        enum nil        rvalue nil  signed nil
7969		       typedefed nil  multidim nil    ptype nil   modport nil
7970		       expect-signal 'sigs-assign     sig-paren paren))
7971		((member keywd '("localparam" "genvar"))
7972		 (unless io
7973		   (setq vec nil        enum nil      rvalue nil  signed nil
7974			 typedefed nil  multidim nil  ptype nil   modport nil
7975			 expect-signal 'sigs-const    sig-paren paren)))
7976		((member keywd '("signed" "unsigned"))
7977		 (setq signed keywd))
7978		((member keywd '("assert" "assume" "cover" "expect" "restrict"))
7979		 (setq ign-prop t))
7980		((member keywd '("class" "clocking" "covergroup" "function"
7981				 "property" "randsequence" "sequence" "task"))
7982		 (unless ign-prop
7983		   (setq functask (1+ functask))))
7984		((member keywd '("endclass" "endclocking" "endgroup" "endfunction"
7985				 "endproperty" "endsequence" "endtask"))
7986		 (setq functask (1- functask)))
7987		((equal keywd "modport")
7988		 (setq in-modport t))
7989		((equal keywd "type")
7990		 (setq ptype t))
7991		;; Ifdef?  Ignore name of define
7992		((member keywd '("`ifdef" "`ifndef" "`elsif"))
7993		 (setq rvalue t))
7994		;; Type?
7995		((unless ptype
7996		   (verilog-typedef-name-p keywd))
7997		 (setq typedefed keywd))
7998		;; Interface with optional modport in v2k arglist?
7999		;; Skip over parsing modport, and take the interface name as the type
8000		((and v2kargs-ok
8001		      (eq paren 1)
8002		      (not rvalue)
8003		      (looking-at "\\s-*\\(\\.\\(\\s-*[a-zA-Z`_$][a-zA-Z0-9`_$]*\\)\\|\\)\\s-*[a-zA-Z`_$][a-zA-Z0-9`_$]*"))
8004		 (when (match-end 2) (goto-char (match-end 2)))
8005		 (setq vec nil          enum nil       rvalue nil  signed nil
8006		       typedefed keywd  multidim nil   ptype nil   modport (match-string 2)
8007		       newsig nil    sig-paren paren
8008		       expect-signal 'sigs-intf  io t  ))
8009		;; Ignore dotted LHS assignments: "assign foo.bar = z;"
8010		((looking-at "\\s-*\\.")
8011		 (goto-char (match-end 0))
8012		 (when (not rvalue)
8013		   (setq expect-signal nil)))
8014		;; New signal, maybe?
8015		((and expect-signal
8016		      (not rvalue)
8017		      (eq functask 0)
8018		      (not in-modport)
8019		      (not (member keywd verilog-keywords)))
8020		 ;; Add new signal to expect-signal's variable
8021		 (setq newsig (verilog-sig-new keywd vec nil nil enum signed typedefed multidim modport))
8022		 (set expect-signal (cons newsig
8023					  (symbol-value expect-signal))))))
8024	 (t
8025	  (forward-char 1)))
8026	(skip-syntax-forward " "))
8027      ;; Return arguments
8028      (verilog-decls-new (nreverse sigs-out)
8029			 (nreverse sigs-inout)
8030			 (nreverse sigs-in)
8031			 (nreverse sigs-var)
8032			 nil
8033			 (nreverse sigs-assign)
8034			 (nreverse sigs-const)
8035			 (nreverse sigs-gparam)
8036			 (nreverse sigs-intf)))))
8037
8038(defvar verilog-read-sub-decls-in-interfaced nil
8039  "For `verilog-read-sub-decls', process next signal as under interfaced block.")
8040
8041(defvar verilog-read-sub-decls-gate-ios nil
8042  "For `verilog-read-sub-decls', gate IO pins remaining, nil if non-primitive.")
8043
8044(eval-when-compile
8045  ;; Prevent compile warnings; these are let's, not globals
8046  ;; Do not remove the eval-when-compile
8047  ;; - we want an error when we are debugging this code if they are refed.
8048  (defvar sigs-in)
8049  (defvar sigs-inout)
8050  (defvar sigs-out)
8051  (defvar sigs-intf)
8052  (defvar sigs-intfd))
8053
8054(defun verilog-read-sub-decls-sig (submoddecls comment port sig vec multidim)
8055  "For `verilog-read-sub-decls-line', add a signal."
8056  ;; sig eq t to indicate .name syntax
8057  ;;(message "vrsds: %s(%S)" port sig)
8058  (let ((dotname (eq sig t))
8059	portdata)
8060    (when sig
8061      (setq port (verilog-symbol-detick-denumber port))
8062      (setq sig  (if dotname port (verilog-symbol-detick-denumber sig)))
8063      (if vec (setq vec  (verilog-symbol-detick-denumber vec)))
8064      (if multidim (setq multidim  (mapcar `verilog-symbol-detick-denumber multidim)))
8065      (unless (or (not sig)
8066		  (equal sig ""))  ;; Ignore .foo(1'b1) assignments
8067	(cond ((or (setq portdata (assoc port (verilog-decls-get-inouts submoddecls)))
8068		   (equal "inout" verilog-read-sub-decls-gate-ios))
8069	       (setq sigs-inout
8070		     (cons (verilog-sig-new
8071			    sig
8072			    (if dotname (verilog-sig-bits portdata) vec)
8073			    (concat "To/From " comment)
8074			    (verilog-sig-memory portdata)
8075			    nil
8076			    (verilog-sig-signed portdata)
8077			    (unless (member (verilog-sig-type portdata) '("wire" "reg"))
8078			      (verilog-sig-type portdata))
8079			    multidim nil)
8080			   sigs-inout)))
8081	      ((or (setq portdata (assoc port (verilog-decls-get-outputs submoddecls)))
8082		   (equal "output" verilog-read-sub-decls-gate-ios))
8083	       (setq sigs-out
8084		     (cons (verilog-sig-new
8085			    sig
8086			    (if dotname (verilog-sig-bits portdata) vec)
8087			    (concat "From " comment)
8088			    (verilog-sig-memory portdata)
8089			    nil
8090			    (verilog-sig-signed portdata)
8091			    ;; Though ok in SV, in V2K code, propagating the
8092			    ;;  "reg" in "output reg" upwards isn't legal.
8093			    ;; Also for backwards compatibility we don't propagate
8094			    ;;  "input wire" upwards.
8095			    ;; See also `verilog-signals-edit-wire-reg'.
8096			    (unless (member (verilog-sig-type portdata) '("wire" "reg"))
8097			      (verilog-sig-type portdata))
8098			    multidim nil)
8099			   sigs-out)))
8100	      ((or (setq portdata (assoc port (verilog-decls-get-inputs submoddecls)))
8101		   (equal "input" verilog-read-sub-decls-gate-ios))
8102	       (setq sigs-in
8103		     (cons (verilog-sig-new
8104			    sig
8105			    (if dotname (verilog-sig-bits portdata) vec)
8106			    (concat "To " comment)
8107			    (verilog-sig-memory portdata)
8108			    nil
8109			    (verilog-sig-signed portdata)
8110			    (unless (member (verilog-sig-type portdata) '("wire" "reg"))
8111			      (verilog-sig-type portdata))
8112			    multidim nil)
8113			   sigs-in)))
8114	      ((setq portdata (assoc port (verilog-decls-get-interfaces submoddecls)))
8115	       (setq sigs-intf
8116		     (cons (verilog-sig-new
8117			    sig
8118			    (if dotname (verilog-sig-bits portdata) vec)
8119			    (concat "To/From " comment)
8120			    (verilog-sig-memory portdata)
8121			    nil
8122			    (verilog-sig-signed portdata)
8123			    (verilog-sig-type portdata)
8124			    multidim nil)
8125			   sigs-intf)))
8126	      ((setq portdata (and verilog-read-sub-decls-in-interfaced
8127				   (assoc port (verilog-decls-get-vars submoddecls))))
8128	       (setq sigs-intfd
8129		     (cons (verilog-sig-new
8130			    sig
8131			    (if dotname (verilog-sig-bits portdata) vec)
8132			    (concat "To/From " comment)
8133			    (verilog-sig-memory portdata)
8134			    nil
8135			    (verilog-sig-signed portdata)
8136			    (verilog-sig-type portdata)
8137			    multidim nil)
8138			   sigs-intf)))
8139	      ;; (t  -- warning pin isn't defined.)   ; Leave for lint tool
8140	      )))))
8141
8142(defun verilog-read-sub-decls-expr (submoddecls comment port expr)
8143  "For `verilog-read-sub-decls-line', parse a subexpression and add signals."
8144  ;;(message "vrsde: '%s'" expr)
8145  ;; Replace special /*[....]*/ comments inserted by verilog-auto-inst-port
8146  (setq expr (verilog-string-replace-matches "/\\*\\(\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
8147  ;; Remove front operators
8148  (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
8149  ;;
8150  (cond
8151   ;; {..., a, b} requires us to recurse on a,b
8152   ;; To support {#{},{#{a,b}} we'll just split everything on [{},]
8153   ((string-match "^\\s-*{\\(.*\\)}\\s-*$" expr)
8154    (unless verilog-auto-ignore-concat
8155      (let ((mlst (split-string (match-string 1 expr) "[{},]"))
8156	    mstr)
8157	(while (setq mstr (pop mlst))
8158	  (verilog-read-sub-decls-expr submoddecls comment port mstr)))))
8159   (t
8160    (let (sig vec multidim)
8161      ;; Remove leading reduction operators, etc
8162      (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
8163      ;;(message "vrsde-ptop: '%s'" expr)
8164      (cond ;; Find \signal. Final space is part of escaped signal name
8165       ((string-match "^\\s-*\\(\\\\[^ \t\n\f]+\\s-\\)" expr)
8166	;;(message "vrsde-s: '%s'" (match-string 1 expr))
8167	(setq sig (match-string 1 expr)
8168	      expr (substring expr (match-end 0))))
8169       ;; Find signal
8170       ((string-match "^\\s-*\\([a-zA-Z_][a-zA-Z_0-9]*\\)" expr)
8171	;;(message "vrsde-s: '%s'" (match-string 1 expr))
8172	(setq sig (verilog-string-remove-spaces (match-string 1 expr))
8173	      expr (substring expr (match-end 0)))))
8174      ;; Find [vector] or [multi][multi][multi][vector]
8175      (while (string-match "^\\s-*\\(\\[[^]]+\\]\\)" expr)
8176	;;(message "vrsde-v: '%s'" (match-string 1 expr))
8177	(when vec (setq multidim (cons vec multidim)))
8178	(setq vec (match-string 1 expr)
8179	      expr (substring expr (match-end 0))))
8180      ;; If found signal, and nothing unrecognized, add the signal
8181      ;;(message "vrsde-rem: '%s'" expr)
8182      (when (and sig (string-match "^\\s-*$" expr))
8183	(verilog-read-sub-decls-sig submoddecls comment port sig vec multidim))))))
8184
8185(defun verilog-read-sub-decls-line (submoddecls comment)
8186  "For `verilog-read-sub-decls', read lines of port defs until none match.
8187Inserts the list of signals found, using submodi to look up each port."
8188  (let (done port)
8189    (save-excursion
8190      (forward-line 1)
8191      (while (not done)
8192	;; Get port name
8193	(cond ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*(\\s-*")
8194	       (setq port (match-string 1))
8195	       (goto-char (match-end 0)))
8196	      ;; .\escaped (
8197	      ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*(\\s-*")
8198	       (setq port (concat (match-string 1) " ")) ;; escaped id's need trailing space
8199	       (goto-char (match-end 0)))
8200	      ;; .name
8201	      ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*[,)/]")
8202	       (verilog-read-sub-decls-sig
8203		submoddecls comment (match-string 1) t ; sig==t for .name
8204		nil nil) ; vec multidim
8205	       (setq port nil))
8206	      ;; .\escaped_name
8207	      ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*[,)/]")
8208	       (verilog-read-sub-decls-sig
8209		submoddecls comment (concat (match-string 1) " ") t ; sig==t for .name
8210		nil nil) ; vec multidim
8211	       (setq port nil))
8212	      ;; random
8213	      ((looking-at "\\s-*\\.[^(]*(")
8214	       (setq port nil) ;; skip this line
8215	       (goto-char (match-end 0)))
8216	      (t
8217	       (setq port nil  done t))) ;; Unknown, ignore rest of line
8218	;; Get signal name.  Point is at the first-non-space after (
8219	;; We intentionally ignore (non-escaped) signals with .s in them
8220	;; this prevents AUTOWIRE etc from noticing hierarchical sigs.
8221	(when port
8222	  (cond ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*)")
8223		 (verilog-read-sub-decls-sig
8224		  submoddecls comment port
8225		  (verilog-string-remove-spaces (match-string 1)) ; sig
8226		  nil nil)) ; vec multidim
8227		;;
8228		((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*)")
8229		 (verilog-read-sub-decls-sig
8230		  submoddecls comment port
8231		  (verilog-string-remove-spaces (match-string 1)) ; sig
8232		  (match-string 2) nil)) ; vec multidim
8233		;; Fastpath was above looking-at's.
8234		;; For something more complicated invoke a parser
8235		((looking-at "[^)]+")
8236		 (verilog-read-sub-decls-expr
8237		  submoddecls comment port
8238		  (buffer-substring
8239		   (point) (1- (progn (search-backward "(") ; start at (
8240				      (verilog-forward-sexp-ign-cmt 1)
8241				      (point)))))))) ; expr
8242	;;
8243	(forward-line 1)))))
8244
8245(defun verilog-read-sub-decls-gate (submoddecls comment submod end-inst-point)
8246  "For `verilog-read-sub-decls', read lines of UDP gate decl until none match.
8247Inserts the list of signals found."
8248  (save-excursion
8249    (let ((iolist (cdr (assoc submod verilog-gate-ios))))
8250      (while (< (point) end-inst-point)
8251	;; Get primitive's signal name, as will never have port, and no trailing )
8252	(cond ((looking-at "//")
8253	       (search-forward "\n"))
8254	      ((looking-at "/\\*")
8255	       (or (search-forward "*/")
8256		   (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
8257	      ((looking-at "(\\*")
8258	       ;; To advance past either "(*)" or "(* ... *)" don't forward past first *
8259	       (forward-char 1)
8260	       (or (search-forward "*)")
8261		   (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
8262	      ;; On pins, parse and advance to next pin
8263	      ;; Looking at pin, but *not* an // Output comment, or ) to end the inst
8264	      ((looking-at "\\s-*[a-zA-Z0-9`_$({}\\\\][^,]*")
8265	       (goto-char (match-end 0))
8266	       (setq verilog-read-sub-decls-gate-ios (or (car iolist) "input")
8267		     iolist (cdr iolist))
8268	       (verilog-read-sub-decls-expr
8269		submoddecls comment "primitive_port"
8270		(match-string 0)))
8271	      (t
8272	       (forward-char 1)
8273	       (skip-syntax-forward " ")))))))
8274
8275(defun verilog-read-sub-decls ()
8276  "Internally parse signals going to modules under this module.
8277Return an array of [ outputs inouts inputs ] signals for modules that are
8278instantiated in this module.  For example if declare A A (.B(SIG)) and SIG
8279is an output, then SIG will be included in the list.
8280
8281This only works on instantiations created with /*AUTOINST*/ converted by
8282\\[verilog-auto-inst].  Otherwise, it would have to read in the whole
8283component library to determine connectivity of the design.
8284
8285One work around for this problem is to manually create // Inputs and //
8286Outputs comments above subcell signals, for example:
8287
8288	module ModuleName (
8289	    // Outputs
8290	    .out (out),
8291	    // Inputs
8292	    .in  (in));"
8293  (save-excursion
8294    (let ((end-mod-point (verilog-get-end-of-defun t))
8295	  st-point end-inst-point
8296	  ;; below 3 modified by verilog-read-sub-decls-line
8297	  sigs-out sigs-inout sigs-in sigs-intf sigs-intfd)
8298      (verilog-beg-of-defun-quick)
8299      (while (verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-mod-point t)
8300	(save-excursion
8301	  (goto-char (match-beginning 0))
8302	  (unless (verilog-inside-comment-or-string-p)
8303	    ;; Attempt to snarf a comment
8304	    (let* ((submod (verilog-read-inst-module))
8305		   (inst (verilog-read-inst-name))
8306		   (subprim (member submod verilog-gate-keywords))
8307		   (comment (concat inst " of " submod ".v"))
8308		   submodi submoddecls)
8309    	      (cond
8310	       (subprim
8311		(setq submodi `primitive
8312		      submoddecls (verilog-decls-new nil nil nil nil nil nil nil nil nil)
8313		      comment (concat inst " of " submod))
8314		(verilog-backward-open-paren)
8315		(setq end-inst-point (save-excursion (verilog-forward-sexp-ign-cmt 1)
8316						     (point))
8317		      st-point (point))
8318		(forward-char 1)
8319		(verilog-read-sub-decls-gate submoddecls comment submod end-inst-point))
8320	       ;; Non-primitive
8321	       (t
8322		(when (setq submodi (verilog-modi-lookup submod t))
8323		  (setq submoddecls (verilog-modi-get-decls submodi)
8324			verilog-read-sub-decls-gate-ios nil)
8325		  (verilog-backward-open-paren)
8326		  (setq end-inst-point (save-excursion (verilog-forward-sexp-ign-cmt 1)
8327						       (point))
8328			st-point (point))
8329		  ;; This could have used a list created by verilog-auto-inst
8330		  ;; However I want it to be runnable even on user's manually added signals
8331		  (let ((verilog-read-sub-decls-in-interfaced t))
8332		    (while (re-search-forward "\\s *(?\\s *// Interfaced" end-inst-point t)
8333		      (verilog-read-sub-decls-line submoddecls comment))) ;; Modifies sigs-ifd
8334		  (goto-char st-point)
8335		  (while (re-search-forward "\\s *(?\\s *// Interfaces" end-inst-point t)
8336		    (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-out
8337		  (goto-char st-point)
8338		  (while (re-search-forward "\\s *(?\\s *// Outputs" end-inst-point t)
8339		    (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-out
8340		  (goto-char st-point)
8341		  (while (re-search-forward "\\s *(?\\s *// Inouts" end-inst-point t)
8342		    (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-inout
8343		  (goto-char st-point)
8344		  (while (re-search-forward "\\s *(?\\s *// Inputs" end-inst-point t)
8345		    (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-in
8346		  )))))))
8347      ;; Combine duplicate bits
8348      ;;(setq rr (vector sigs-out sigs-inout sigs-in))
8349      (verilog-subdecls-new
8350       (verilog-signals-combine-bus (nreverse sigs-out))
8351       (verilog-signals-combine-bus (nreverse sigs-inout))
8352       (verilog-signals-combine-bus (nreverse sigs-in))
8353       (verilog-signals-combine-bus (nreverse sigs-intf))
8354       (verilog-signals-combine-bus (nreverse sigs-intfd))))))
8355
8356(defun verilog-read-inst-pins ()
8357  "Return an array of [ pins ] for the current instantiation at point.
8358For example if declare A A (.B(SIG)) then B will be included in the list."
8359  (save-excursion
8360    (let ((end-mod-point (point))	;; presume at /*AUTOINST*/ point
8361	  pins pin)
8362      (verilog-backward-open-paren)
8363      (while (re-search-forward "\\.\\([^(,) \t\n\f]*\\)\\s-*" end-mod-point t)
8364	(setq pin (match-string 1))
8365	(unless (verilog-inside-comment-or-string-p)
8366	  (setq pins (cons (list pin) pins))
8367	  (when (looking-at "(")
8368	    (verilog-forward-sexp-ign-cmt 1))))
8369      (vector pins))))
8370
8371(defun verilog-read-arg-pins ()
8372  "Return an array of [ pins ] for the current argument declaration at point."
8373  (save-excursion
8374    (let ((end-mod-point (point))	;; presume at /*AUTOARG*/ point
8375	  pins pin)
8376      (verilog-backward-open-paren)
8377      (while (re-search-forward "\\([a-zA-Z0-9$_.%`]+\\)" end-mod-point t)
8378	(setq pin (match-string 1))
8379	(unless (verilog-inside-comment-or-string-p)
8380	  (setq pins (cons (list pin) pins))))
8381      (vector pins))))
8382
8383(defun verilog-read-auto-constants (beg end-mod-point)
8384  "Return a list of AUTO_CONSTANTs used in the region from BEG to END-MOD-POINT."
8385  ;; Insert new
8386  (save-excursion
8387    (let (sig-list tpl-end-pt)
8388      (goto-char beg)
8389      (while (re-search-forward "\\<AUTO_CONSTANT" end-mod-point t)
8390	(if (not (looking-at "\\s *("))
8391	    (error "%s: Missing () after AUTO_CONSTANT" (verilog-point-text)))
8392	(search-forward "(" end-mod-point)
8393	(setq tpl-end-pt (save-excursion
8394			   (backward-char 1)
8395			   (verilog-forward-sexp-cmt 1)   ;; Moves to paren that closes argdecl's
8396			   (backward-char 1)
8397			   (point)))
8398	(while (re-search-forward "\\s-*\\([\"a-zA-Z0-9$_.%`]+\\)\\s-*,*" tpl-end-pt t)
8399	  (setq sig-list (cons (list (match-string 1) nil nil) sig-list))))
8400      sig-list)))
8401
8402(defvar verilog-cache-has-lisp nil "True if any AUTO_LISP in buffer.")
8403(make-variable-buffer-local 'verilog-cache-has-lisp)
8404
8405(defun verilog-read-auto-lisp-present ()
8406  "Set `verilog-cache-has-lisp' if any AUTO_LISP in this buffer."
8407  (save-excursion
8408    (goto-char (point-min))
8409    (setq verilog-cache-has-lisp (re-search-forward "\\<AUTO_LISP(" nil t))))
8410
8411(defun verilog-read-auto-lisp (start end)
8412  "Look for and evaluate an AUTO_LISP between START and END.
8413Must call `verilog-read-auto-lisp-present' before this function."
8414  ;; This function is expensive for large buffers, so we cache if any AUTO_LISP exists
8415  (when verilog-cache-has-lisp
8416    (save-excursion
8417      (goto-char start)
8418      (while (re-search-forward "\\<AUTO_LISP(" end t)
8419	(backward-char)
8420	(let* ((beg-pt (prog1 (point)
8421			 (verilog-forward-sexp-cmt 1)))	;; Closing paren
8422	       (end-pt (point))
8423	       (verilog-in-hooks t))
8424	  (eval-region beg-pt end-pt nil))))))
8425
8426(eval-when-compile
8427  ;; Prevent compile warnings; these are let's, not globals
8428  ;; Do not remove the eval-when-compile
8429  ;; - we want an error when we are debugging this code if they are refed.
8430  (defvar sigs-in)
8431  (defvar sigs-out-d)
8432  (defvar sigs-out-i)
8433  (defvar sigs-out-unk)
8434  (defvar sigs-temp)
8435  (defvar vector-skip-list))
8436
8437(defun verilog-read-always-signals-recurse
8438  (exit-keywd rvalue temp-next)
8439  "Recursive routine for parentheses/bracket matching.
8440EXIT-KEYWD is expression to stop at, nil if top level.
8441RVALUE is true if at right hand side of equal.
8442IGNORE-NEXT is true to ignore next token, fake from inside case statement."
8443  (let* ((semi-rvalue (equal "endcase" exit-keywd)) ;; true if after a ; we are looking for rvalue
8444	 keywd last-keywd sig-tolk sig-last-tolk gotend got-sig got-list end-else-check
8445	 ignore-next)
8446    ;;(if dbg (setq dbg (concat dbg (format "Recursion %S %S %S\n" exit-keywd rvalue temp-next))))
8447    (while (not (or (eobp) gotend))
8448      (cond
8449       ((looking-at "//")
8450	(search-forward "\n"))
8451       ((looking-at "/\\*")
8452	(or (search-forward "*/")
8453	    (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
8454       ((looking-at "(\\*")
8455	;; To advance past either "(*)" or "(* ... *)" don't forward past first *
8456	(forward-char 1)
8457	(or (search-forward "*)")
8458	    (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
8459       (t (setq keywd (buffer-substring-no-properties
8460		       (point)
8461		       (save-excursion (when (eq 0 (skip-chars-forward "a-zA-Z0-9$_.%`"))
8462					 (forward-char 1))
8463				       (point)))
8464		sig-last-tolk sig-tolk
8465		sig-tolk nil)
8466	  ;;(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))))
8467	  (cond
8468	   ((equal keywd "\"")
8469	    (or (re-search-forward "[^\\]\"" nil t)
8470		(error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
8471	   ;; else at top level loop, keep parsing
8472	   ((and end-else-check (equal keywd "else"))
8473	    ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else %s\n" keywd))))
8474	    ;; no forward movement, want to see else in lower loop
8475	    (setq end-else-check nil))
8476	   ;; End at top level loop
8477	   ((and end-else-check (looking-at "[^ \t\n\f]"))
8478	    ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else-other %s\n" keywd))))
8479	    (setq gotend t))
8480	   ;; Final statement?
8481	   ((and exit-keywd (equal keywd exit-keywd))
8482	    (setq gotend t)
8483	    (forward-char (length keywd)))
8484	   ;; Standard tokens...
8485	   ((equal keywd ";")
8486	    (setq ignore-next nil  rvalue semi-rvalue)
8487	    ;; Final statement at top level loop?
8488	    (when (not exit-keywd)
8489	      ;;(if dbg (setq dbg (concat dbg (format "\ttop-end-check %s\n" keywd))))
8490	      (setq end-else-check t))
8491	    (forward-char 1))
8492	   ((equal keywd "'")
8493	    (if (looking-at "'[sS]?[hdxboHDXBO]?[ \t]*[0-9a-fA-F_xzXZ?]+")
8494		(goto-char (match-end 0))
8495	      (forward-char 1)))
8496	   ((equal keywd ":")	;; Case statement, begin/end label, x?y:z
8497	    (cond ((equal "endcase" exit-keywd)  ;; case x: y=z; statement next
8498		   (setq ignore-next nil rvalue nil))
8499		  ((equal "?" exit-keywd)  ;; x?y:z rvalue
8500		   ) ;; NOP
8501		  ((equal "]" exit-keywd)  ;; [x:y] rvalue
8502		   ) ;; NOP
8503		  (got-sig	;; label: statement
8504		   (setq ignore-next nil rvalue semi-rvalue got-sig nil))
8505		  ((not rvalue)	;; begin label
8506		   (setq ignore-next t rvalue nil)))
8507	    (forward-char 1))
8508	   ((equal keywd "=")
8509	    (when got-sig
8510	      ;;(if dbg (setq dbg (concat dbg (format "\t\tequal got-sig=%S got-list=%s\n" got-sig got-list))))
8511	      (set got-list (cons got-sig (symbol-value got-list)))
8512	      (setq got-sig nil))
8513	    (when (not rvalue)
8514	      (if (eq (char-before) ?< )
8515		  (setq sigs-out-d (append sigs-out-d sigs-out-unk)
8516			sigs-out-unk nil)
8517		(setq sigs-out-i (append sigs-out-i sigs-out-unk)
8518		      sigs-out-unk nil)))
8519	    (setq ignore-next nil rvalue t)
8520	    (forward-char 1))
8521	   ((equal keywd "?")
8522	    (forward-char 1)
8523	    (verilog-read-always-signals-recurse ":" rvalue nil))
8524	   ((equal keywd "[")
8525	    (forward-char 1)
8526	    (verilog-read-always-signals-recurse "]" t nil))
8527	   ((equal keywd "(")
8528	    (forward-char 1)
8529	    (cond (sig-last-tolk	;; Function call; zap last signal
8530		   (setq got-sig nil)))
8531	    (cond ((equal last-keywd "for")
8532		   ;; temp-next: Variables on LHS are lvalues, but generally we want
8533		   ;; to ignore them, assuming they are loop increments
8534		   (verilog-read-always-signals-recurse ";" nil t)
8535		   (verilog-read-always-signals-recurse ";" t nil)
8536		   (verilog-read-always-signals-recurse ")" nil nil))
8537		  (t (verilog-read-always-signals-recurse ")" t nil))))
8538	   ((equal keywd "begin")
8539	    (skip-syntax-forward "w_")
8540	    (verilog-read-always-signals-recurse "end" nil nil)
8541	    ;;(if dbg (setq dbg (concat dbg (format "\tgot-end %s\n" exit-keywd))))
8542	    (setq ignore-next nil  rvalue semi-rvalue)
8543	    (if (not exit-keywd) (setq end-else-check t)))
8544	   ((member keywd '("case" "casex" "casez"))
8545	    (skip-syntax-forward "w_")
8546	    (verilog-read-always-signals-recurse "endcase" t nil)
8547	    (setq ignore-next nil  rvalue semi-rvalue)
8548	    (if (not exit-keywd) (setq gotend t)))	;; top level begin/end
8549	   ((string-match "^[$`a-zA-Z_]" keywd)	;; not exactly word constituent
8550	    (cond ((member keywd '("`ifdef" "`ifndef" "`elsif"))
8551		   (setq ignore-next t))
8552		  ((or ignore-next
8553		       (member keywd verilog-keywords)
8554		       (string-match "^\\$" keywd))	;; PLI task
8555		   (setq ignore-next nil))
8556		  (t
8557		   (setq keywd (verilog-symbol-detick-denumber keywd))
8558		   (when got-sig
8559		     (set got-list (cons got-sig (symbol-value got-list)))
8560		     ;;(if dbg (setq dbg (concat dbg (format "\t\tgot-sig=%S got-list=%S\n" got-sig got-list))))
8561		     )
8562		   (setq got-list (cond (temp-next 'sigs-temp)
8563					(rvalue 'sigs-in)
8564					(t 'sigs-out-unk))
8565			 got-sig (if (or (not keywd)
8566					 (assoc keywd (symbol-value got-list)))
8567				     nil (list keywd nil nil))
8568			 temp-next nil
8569			 sig-tolk t)))
8570	    (skip-chars-forward "a-zA-Z0-9$_.%`"))
8571	   (t
8572	    (forward-char 1)))
8573	  ;; End of non-comment token
8574	  (setq last-keywd keywd)))
8575      (skip-syntax-forward " "))
8576    ;; Append the final pending signal
8577    (when got-sig
8578      ;;(if dbg (setq dbg (concat dbg (format "\t\tfinal got-sig=%S got-list=%s\n" got-sig got-list))))
8579      (set got-list (cons got-sig (symbol-value got-list)))
8580      (setq got-sig nil))
8581    ;;(if dbg (setq dbg (concat dbg (format "ENDRecursion %s\n" exit-keywd))))
8582    ))
8583
8584(defun verilog-read-always-signals ()
8585  "Parse always block at point and return list of (outputs inout inputs)."
8586  (save-excursion
8587    (let* (;;(dbg "")
8588	   sigs-out-d sigs-out-i sigs-out-unk sigs-temp sigs-in)
8589      (search-forward ")")
8590      (verilog-read-always-signals-recurse nil nil nil)
8591      (setq sigs-out-i (append sigs-out-i sigs-out-unk)
8592	    sigs-out-unk nil)
8593      ;;(if dbg (with-current-buffer (get-buffer-create "*vl-dbg*")) (delete-region (point-min) (point-max)) (insert dbg) (setq dbg ""))
8594      ;; Return what was found
8595      (verilog-alw-new sigs-out-d sigs-out-i sigs-temp sigs-in))))
8596
8597(defun verilog-read-instants ()
8598  "Parse module at point and return list of ( ( file instance ) ... )."
8599  (verilog-beg-of-defun-quick)
8600  (let* ((end-mod-point (verilog-get-end-of-defun t))
8601	 (state nil)
8602	 (instants-list nil))
8603    (save-excursion
8604      (while (< (point) end-mod-point)
8605	;; Stay at level 0, no comments
8606	(while (progn
8607		 (setq state (parse-partial-sexp (point) end-mod-point 0 t nil))
8608		 (or (> (car state) 0)	; in parens
8609		     (nth 5 state)		; comment
8610		     ))
8611	  (forward-line 1))
8612	(beginning-of-line)
8613	(if (looking-at "^\\s-*\\([a-zA-Z0-9`_$]+\\)\\s-+\\([a-zA-Z0-9`_$]+\\)\\s-*(")
8614	    ;;(if (looking-at "^\\(.+\\)$")
8615	    (let ((module (match-string 1))
8616		  (instant (match-string 2)))
8617	      (if (not (member module verilog-keywords))
8618		  (setq instants-list (cons (list module instant) instants-list)))))
8619	(forward-line 1)))
8620    instants-list))
8621
8622
8623(defun verilog-read-auto-template-middle ()
8624  "With point in middle of an AUTO_TEMPLATE, parse it.
8625Returns REGEXP and list of ( (signal_name connection_name)... )."
8626  (save-excursion
8627    ;; Find beginning
8628    (let ((tpl-regexp "\\([0-9]+\\)")
8629	  (lineno -1)  ; -1 to offset for the AUTO_TEMPLATE's newline
8630	  (templateno 0)
8631	  tpl-sig-list tpl-wild-list tpl-end-pt rep)
8632      ;; Parse "REGEXP"
8633      ;; We reserve @"..." for future lisp expressions that evaluate
8634      ;; once-per-AUTOINST
8635      (when (looking-at "\\s-*\"\\([^\"]*\\)\"")
8636	(setq tpl-regexp (match-string 1))
8637	(goto-char (match-end 0)))
8638      (search-forward "(")
8639      ;; Parse lines in the template
8640      (when (or verilog-auto-inst-template-numbers
8641		verilog-auto-template-warn-unused)
8642	(save-excursion
8643	  (let ((pre-pt (point)))
8644	    (goto-char (point-min))
8645	    (while (search-forward "AUTO_TEMPLATE" pre-pt t)
8646	      (setq templateno (1+ templateno)))
8647	    (while (< (point) pre-pt)
8648	      (forward-line 1)
8649	      (setq lineno (1+ lineno))))))
8650      (setq tpl-end-pt (save-excursion
8651			 (backward-char 1)
8652			 (verilog-forward-sexp-cmt 1)   ;; Moves to paren that closes argdecl's
8653			 (backward-char 1)
8654			 (point)))
8655      ;;
8656      (while (< (point) tpl-end-pt)
8657	(cond ((looking-at "\\s-*\\.\\([a-zA-Z0-9`_$]+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
8658	       (setq tpl-sig-list
8659		     (cons (list
8660			    (match-string-no-properties 1)
8661			    (match-string-no-properties 2)
8662			    templateno lineno)
8663			   tpl-sig-list))
8664	       (goto-char (match-end 0)))
8665	      ;; Regexp form??
8666	      ((looking-at
8667		;; Regexp bug in XEmacs disallows ][ inside [], and wants + last
8668		"\\s-*\\.\\(\\([a-zA-Z0-9`_$+@^.*?|---]+\\|[][]\\|\\\\[()|]\\)+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
8669	       (setq rep (match-string-no-properties 3))
8670	       (goto-char (match-end 0))
8671	       (setq tpl-wild-list
8672		     (cons (list
8673			    (concat "^"
8674				    (verilog-string-replace-matches "@" "\\\\([0-9]+\\\\)" nil nil
8675								    (match-string 1))
8676				    "$")
8677			    rep
8678			    templateno lineno)
8679			   tpl-wild-list)))
8680	      ((looking-at "[ \t\f]+")
8681	       (goto-char (match-end 0)))
8682	      ((looking-at "\n")
8683	       (setq lineno (1+ lineno))
8684	       (goto-char (match-end 0)))
8685	      ((looking-at "//")
8686	       (search-forward "\n")
8687	       (setq lineno (1+ lineno)))
8688	      ((looking-at "/\\*")
8689	       (forward-char 2)
8690	       (or (search-forward "*/")
8691		   (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
8692	      (t
8693	       (error "%s: AUTO_TEMPLATE parsing error: %s"
8694		      (verilog-point-text)
8695		      (progn (looking-at ".*$") (match-string 0))))))
8696      ;; Return
8697      (vector tpl-regexp
8698	      (list tpl-sig-list tpl-wild-list)))))
8699
8700(defun verilog-read-auto-template (module)
8701  "Look for an auto_template for the instantiation of the given MODULE.
8702If found returns `verilog-read-auto-template-inside' structure."
8703  (save-excursion
8704    ;; Find beginning
8705    (let ((pt (point)))
8706      ;; Note this search is expensive, as we hunt from mod-begin to point
8707      ;; for every instantiation.  Likewise in verilog-read-auto-lisp.
8708      ;; So, we look first for an exact string rather than a slow regexp.
8709      ;; Someday we may keep a cache of every template, but this would also
8710      ;; need to record the relative position of each AUTOINST, as multiple
8711      ;; templates exist for each module, and we're inserting lines.
8712      (cond ((or
8713	      ;; See also regexp in `verilog-auto-template-lint'
8714	      (verilog-re-search-backward-substr
8715	       "AUTO_TEMPLATE"
8716	       (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)
8717	      ;; Also try forward of this AUTOINST
8718	      ;; This is for historical support; this isn't speced as working
8719	      (progn
8720		(goto-char pt)
8721		(verilog-re-search-forward-substr
8722		 "AUTO_TEMPLATE"
8723		 (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)))
8724	     (goto-char (match-end 0))
8725	     (verilog-read-auto-template-middle))
8726	    ;; If no template found
8727	    (t (vector "" nil))))))
8728;;(progn (find-file "auto-template.v") (verilog-read-auto-template "ptl_entry"))
8729
8730(defvar verilog-auto-template-hits nil "Successful lookups with `verilog-read-auto-template-hit'.")
8731(make-variable-buffer-local 'verilog-auto-template-hits)
8732
8733(defun verilog-read-auto-template-hit (tpl-ass)
8734  "Record that TPL-ASS template from `verilog-read-auto-template' was used."
8735  (when (eval-when-compile (fboundp 'make-hash-table)) ;; else feature not allowed
8736    (when verilog-auto-template-warn-unused
8737      (unless verilog-auto-template-hits
8738	(setq verilog-auto-template-hits
8739	      (make-hash-table :test 'equal :rehash-size 4.0)))
8740      (puthash (vector (nth 2 tpl-ass) (nth 3 tpl-ass)) t
8741	       verilog-auto-template-hits))))
8742
8743(defun verilog-set-define (defname defvalue &optional buffer enumname)
8744  "Set the definition DEFNAME to the DEFVALUE in the given BUFFER.
8745Optionally associate it with the specified enumeration ENUMNAME."
8746  (with-current-buffer (or buffer (current-buffer))
8747    (let ((mac (intern (concat "vh-" defname))))
8748      ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
8749      ;; Need to define to a constant if no value given
8750      (set (make-local-variable mac)
8751	   (if (equal defvalue "") "1" defvalue)))
8752    (if enumname
8753	(let ((enumvar (intern (concat "venum-" enumname))))
8754	  ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
8755	  (unless (boundp enumvar) (set enumvar nil))
8756          (add-to-list (make-local-variable enumvar) defname)))))
8757
8758(defun verilog-read-defines (&optional filename recurse subcall)
8759  "Read `defines and parameters for the current file, or optional FILENAME.
8760If the filename is provided, `verilog-library-flags' will be used to
8761resolve it.  If optional RECURSE is non-nil, recurse through `includes.
8762
8763Parameters must be simple assignments to constants, or have their own
8764\"parameter\" label rather than a list of parameters.  Thus:
8765
8766    parameter X = 5, Y = 10;	// Ok
8767    parameter X = {1'b1, 2'h2};	// Ok
8768    parameter X = {1'b1, 2'h2}, Y = 10;	// Bad, make into 2 parameter lines
8769
8770Defines must be simple text substitutions, one on a line, starting
8771at the beginning of the line.  Any ifdefs or multiline comments around the
8772define are ignored.
8773
8774Defines are stored inside Emacs variables using the name vh-{definename}.
8775
8776This function is useful for setting vh-* variables.  The file variables
8777feature can be used to set defines that `verilog-mode' can see; put at the
8778*END* of your file something like:
8779
8780    // Local Variables:
8781    // vh-macro:\"macro_definition\"
8782    // End:
8783
8784If macros are defined earlier in the same file and you want their values,
8785you can read them automatically (provided `enable-local-eval' is on):
8786
8787    // Local Variables:
8788    // eval:(verilog-read-defines)
8789    // eval:(verilog-read-defines \"group_standard_includes.v\")
8790    // End:
8791
8792Note these are only read when the file is first visited, you must use
8793\\[find-alternate-file] RET  to have these take effect after editing them!
8794
8795If you want to disable the \"Process `eval' or hook local variables\"
8796warning message, you need to add to your .emacs file:
8797
8798    (setq enable-local-eval t)"
8799  (let ((origbuf (current-buffer)))
8800    (save-excursion
8801      (unless subcall (verilog-getopt-flags))
8802      (when filename
8803	(let ((fns (verilog-library-filenames filename (buffer-file-name))))
8804	  (if fns
8805	      (set-buffer (find-file-noselect (car fns)))
8806	    (error (concat (verilog-point-text)
8807			   ": Can't find verilog-read-defines file: " filename)))))
8808      (when recurse
8809	(goto-char (point-min))
8810	(while (re-search-forward "^\\s-*`include\\s-+\\([^ \t\n\f]+\\)" nil t)
8811	  (let ((inc (verilog-string-replace-matches
8812		      "\"" "" nil nil (match-string-no-properties 1))))
8813	    (unless (verilog-inside-comment-or-string-p)
8814	      (verilog-read-defines inc recurse t)))))
8815      ;; Read `defines
8816      ;; note we don't use verilog-re... it's faster this way, and that
8817      ;; function has problems when comments are at the end of the define
8818      (goto-char (point-min))
8819      (while (re-search-forward "^\\s-*`define\\s-+\\([a-zA-Z0-9_$]+\\)\\s-+\\(.*\\)$" nil t)
8820	(let ((defname (match-string-no-properties 1))
8821	      (defvalue (match-string-no-properties 2)))
8822	  (setq defvalue (verilog-string-replace-matches "\\s-*/[/*].*$" "" nil nil defvalue))
8823	  (verilog-set-define defname defvalue origbuf)))
8824      ;; Hack: Read parameters
8825      (goto-char (point-min))
8826      (while (re-search-forward
8827	      "^\\s-*\\(parameter\\|localparam\\)\\(\\s-*\\[[^]]*\\]\\)?\\s-*" nil t)
8828	(let (enumname)
8829	  ;; The primary way of getting defines is verilog-read-decls
8830	  ;; However, that isn't called yet for included files, so we'll add another scheme
8831	  (if (looking-at "[^\n]*\\(auto\\|synopsys\\)\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
8832	      (setq enumname (match-string-no-properties 2)))
8833	  (forward-comment 99999)
8834	  (while (looking-at (concat "\\s-*,?\\s-*\\(?:/[/*].*?$\\)?\\s-*\\([a-zA-Z0-9_$]+\\)"
8835				     "\\s-*=\\s-*\\([^;,]*\\),?\\s-*\\(/[/*].*?$\\)?\\s-*"))
8836	    (verilog-set-define (match-string-no-properties 1)
8837				(match-string-no-properties 2) origbuf enumname)
8838	    (goto-char (match-end 0))
8839	    (forward-comment 99999)))))))
8840
8841(defun verilog-read-includes ()
8842  "Read `includes for the current file.
8843This will find all of the `includes which are at the beginning of lines,
8844ignoring any ifdefs or multiline comments around them.
8845`verilog-read-defines' is then performed on the current and each included
8846file.
8847
8848It is often useful put at the *END* of your file something like:
8849
8850    // Local Variables:
8851    // eval:(verilog-read-defines)
8852    // eval:(verilog-read-includes)
8853    // End:
8854
8855Note includes are only read when the file is first visited, you must use
8856\\[find-alternate-file] RET  to have these take effect after editing them!
8857
8858It is good to get in the habit of including all needed files in each .v
8859file that needs it, rather than waiting for compile time.  This will aid
8860this process, Verilint, and readability.  To prevent defining the same
8861variable over and over when many modules are compiled together, put a test
8862around the inside each include file:
8863
8864foo.v (an include file):
8865	`ifdef _FOO_V	// include if not already included
8866	`else
8867	`define _FOO_V
8868	... contents of file
8869	`endif // _FOO_V"
8870;;slow:  (verilog-read-defines nil t))
8871  (save-excursion
8872    (verilog-getopt-flags)
8873    (goto-char (point-min))
8874    (while (re-search-forward "^\\s-*`include\\s-+\\([^ \t\n\f]+\\)" nil t)
8875      (let ((inc (verilog-string-replace-matches "\"" "" nil nil (match-string 1))))
8876	(verilog-read-defines inc nil t)))))
8877
8878(defun verilog-read-signals (&optional start end)
8879  "Return a simple list of all possible signals in the file.
8880Bounded by optional region from START to END.  Overly aggressive but fast.
8881Some macros and such are also found and included.  For dinotrace.el."
8882  (let (sigs-all keywd)
8883    (progn;save-excursion
8884      (goto-char (or start (point-min)))
8885      (setq end (or end (point-max)))
8886      (while (re-search-forward "[\"/a-zA-Z_.%`]" end t)
8887	(forward-char -1)
8888	(cond
8889	 ((looking-at "//")
8890	  (search-forward "\n"))
8891	 ((looking-at "/\\*")
8892	  (search-forward "*/"))
8893	 ((looking-at "(\\*")
8894	  (or (looking-at "(\\*\\s-*)")   ; It's a "always @ (*)"
8895	      (search-forward "*)")))
8896	 ((eq ?\" (following-char))
8897	  (re-search-forward "[^\\]\""))	;; don't forward-char first, since we look for a non backslash first
8898	 ((looking-at "\\s-*\\([a-zA-Z0-9$_.%`]+\\)")
8899	  (goto-char (match-end 0))
8900	  (setq keywd (match-string-no-properties 1))
8901	  (or (member keywd verilog-keywords)
8902	      (member keywd sigs-all)
8903	      (setq sigs-all (cons keywd sigs-all))))
8904	 (t (forward-char 1))))
8905      ;; Return list
8906      sigs-all)))
8907
8908;;
8909;; Argument file parsing
8910;;
8911
8912(defun verilog-getopt (arglist)
8913  "Parse -f, -v etc arguments in ARGLIST list or string."
8914  (unless (listp arglist) (setq arglist (list arglist)))
8915  (let ((space-args '())
8916	arg next-param)
8917    ;; Split on spaces, so users can pass whole command lines
8918    (while arglist
8919      (setq arg (car arglist)
8920	    arglist (cdr arglist))
8921      (while (string-match "^\\([^ \t\n\f]+\\)[ \t\n\f]*\\(.*$\\)" arg)
8922	(setq space-args (append space-args
8923				 (list (match-string-no-properties 1 arg))))
8924	(setq arg (match-string 2 arg))))
8925    ;; Parse arguments
8926    (while space-args
8927      (setq arg (car space-args)
8928	    space-args (cdr space-args))
8929      (cond
8930       ;; Need another arg
8931       ((equal arg "-f")
8932	(setq next-param arg))
8933       ((equal arg "-v")
8934	(setq next-param arg))
8935       ((equal arg "-y")
8936	(setq next-param arg))
8937       ;; +libext+(ext1)+(ext2)...
8938       ((string-match "^\\+libext\\+\\(.*\\)" arg)
8939	(setq arg (match-string 1 arg))
8940	(while (string-match "\\([^+]+\\)\\+?\\(.*\\)" arg)
8941	  (verilog-add-list-unique `verilog-library-extensions
8942				   (match-string 1 arg))
8943	  (setq arg (match-string 2 arg))))
8944       ;;
8945       ((or (string-match "^-D\\([^+=]*\\)[+=]\\(.*\\)" arg)	;; -Ddefine=val
8946	    (string-match "^-D\\([^+=]*\\)\\(\\)" arg)	;; -Ddefine
8947	    (string-match "^\\+define\\([^+=]*\\)[+=]\\(.*\\)" arg)	;; +define+val
8948	    (string-match "^\\+define\\([^+=]*\\)\\(\\)" arg))		;; +define+define
8949	(verilog-set-define (match-string 1 arg) (match-string 2 arg)))
8950       ;;
8951       ((or (string-match "^\\+incdir\\+\\(.*\\)" arg)	;; +incdir+dir
8952	    (string-match "^-I\\(.*\\)" arg))	;; -Idir
8953	(verilog-add-list-unique `verilog-library-directories
8954				 (match-string 1 (substitute-in-file-name arg))))
8955       ;; Ignore
8956       ((equal "+librescan" arg))
8957       ((string-match "^-U\\(.*\\)" arg))	;; -Udefine
8958       ;; Second parameters
8959       ((equal next-param "-f")
8960	(setq next-param nil)
8961	(verilog-getopt-file (substitute-in-file-name arg)))
8962       ((equal next-param "-v")
8963	(setq next-param nil)
8964	(verilog-add-list-unique `verilog-library-files
8965				 (substitute-in-file-name arg)))
8966       ((equal next-param "-y")
8967	(setq next-param nil)
8968	(verilog-add-list-unique `verilog-library-directories
8969				 (substitute-in-file-name arg)))
8970       ;; Filename
8971       ((string-match "^[^-+]" arg)
8972	(verilog-add-list-unique `verilog-library-files
8973				 (substitute-in-file-name arg)))
8974       ;; Default - ignore; no warning
8975       ))))
8976;;(verilog-getopt (list "+libext+.a+.b" "+incdir+foodir" "+define+a+aval" "-f" "otherf" "-v" "library" "-y" "dir"))
8977
8978(defun verilog-getopt-file (filename)
8979  "Read Verilog options from the specified FILENAME."
8980  (save-excursion
8981    (let ((fns (verilog-library-filenames filename (buffer-file-name)))
8982	  (orig-buffer (current-buffer))
8983	  line)
8984      (if fns
8985	  (set-buffer (find-file-noselect (car fns)))
8986	(error (concat (verilog-point-text)
8987		       ": Can't find verilog-getopt-file -f file: " filename)))
8988      (goto-char (point-min))
8989      (while (not (eobp))
8990	(setq line (buffer-substring (point) (point-at-eol)))
8991	(forward-line 1)
8992	(when (string-match "//" line)
8993	  (setq line (substring line 0 (match-beginning 0))))
8994	(with-current-buffer orig-buffer  ; Variables are buffer-local, so need right context.
8995	  (verilog-getopt line))))))
8996
8997(defun verilog-getopt-flags ()
8998  "Convert `verilog-library-flags' into standard library variables."
8999  ;; If the flags are local, then all the outputs should be local also
9000  (when (local-variable-p `verilog-library-flags (current-buffer))
9001    (mapc 'make-local-variable '(verilog-library-extensions
9002                                 verilog-library-directories
9003                                 verilog-library-files
9004                                 verilog-library-flags)))
9005  ;; Allow user to customize
9006  (verilog-run-hooks 'verilog-before-getopt-flags-hook)
9007  ;; Process arguments
9008  (verilog-getopt verilog-library-flags)
9009  ;; Allow user to customize
9010  (verilog-run-hooks 'verilog-getopt-flags-hook))
9011
9012(defun verilog-add-list-unique (varref object)
9013  "Append to VARREF list the given OBJECT,
9014unless it is already a member of the variable's list."
9015  (unless (member object (symbol-value varref))
9016    (set varref (append (symbol-value varref) (list object))))
9017  varref)
9018;;(progn (setq l '()) (verilog-add-list-unique `l "a") (verilog-add-list-unique `l "a") l)
9019
9020(defun verilog-current-flags ()
9021  "Convert `verilog-library-flags' and similar variables to command line.
9022Used for __FLAGS__ in `verilog-expand-command'."
9023  (let ((cmd (mapconcat `concat verilog-library-flags " ")))
9024    (when (equal cmd "")
9025      (setq cmd (concat
9026		 "+libext+" (mapconcat `concat verilog-library-extensions "+")
9027		 (mapconcat (lambda (i) (concat " -y " i " +incdir+" i))
9028			    verilog-library-directories "")
9029		 (mapconcat (lambda (i) (concat " -v " i))
9030			    verilog-library-files ""))))
9031    cmd))
9032;;(verilog-current-flags)
9033
9034
9035;;
9036;; Cached directory support
9037;;
9038
9039(defvar verilog-dir-cache-preserving nil
9040  "If set, the directory cache is enabled, and file system changes are ignored.
9041See `verilog-dir-exists-p' and `verilog-dir-files'.")
9042
9043;; If adding new cached variable, add also to verilog-preserve-dir-cache
9044(defvar verilog-dir-cache-list nil
9045  "Alist of (((Cwd Dirname) Results)...) for caching `verilog-dir-files'.")
9046(defvar verilog-dir-cache-lib-filenames nil
9047  "Cached data for `verilog-library-filenames'.")
9048
9049(defmacro verilog-preserve-dir-cache (&rest body)
9050  "Execute the BODY forms, allowing directory cache preservation within BODY.
9051This means that changes inside BODY made to the file system will not be
9052seen by the `verilog-dir-files' and related functions."
9053  `(let ((verilog-dir-cache-preserving (current-buffer))
9054	 verilog-dir-cache-list
9055	 verilog-dir-cache-lib-filenames)
9056     (progn ,@body)))
9057
9058(defun verilog-dir-files (dirname)
9059  "Return all filenames in the DIRNAME directory.
9060Relative paths depend on the `default-directory'.
9061Results are cached if inside `verilog-preserve-dir-cache'."
9062  (unless verilog-dir-cache-preserving
9063    (setq verilog-dir-cache-list nil)) ;; Cache disabled
9064  ;; We don't use expand-file-name on the dirname to make key, as it's slow
9065  (let* ((cache-key (list dirname default-directory))
9066	 (fass (assoc cache-key verilog-dir-cache-list))
9067	 exp-dirname data)
9068    (cond (fass  ;; Return data from cache hit
9069	   (nth 1 fass))
9070	  (t
9071	   (setq exp-dirname (expand-file-name dirname)
9072		 data (and (file-directory-p exp-dirname)
9073			   (directory-files exp-dirname nil nil nil)))
9074	   ;; Note we also encache nil for non-existing dirs.
9075	   (setq verilog-dir-cache-list (cons (list cache-key data)
9076					      verilog-dir-cache-list))
9077	   data))))
9078;; Miss-and-hit test:
9079;;(verilog-preserve-dir-cache (prin1 (verilog-dir-files "."))
9080;; (prin1 (verilog-dir-files ".")) nil)
9081
9082(defun verilog-dir-file-exists-p (filename)
9083  "Return true if FILENAME exists.
9084Like `file-exists-p' but results are cached if inside
9085`verilog-preserve-dir-cache'."
9086  (let* ((dirname (file-name-directory filename))
9087	 ;; Correct for file-name-nondirectory returning same if no slash.
9088	 (dirnamed (if (or (not dirname) (equal dirname filename))
9089		       default-directory dirname))
9090	 (flist (verilog-dir-files dirnamed)))
9091    (and flist
9092	 (member (file-name-nondirectory filename) flist)
9093	 t)))
9094;;(verilog-dir-file-exists-p "verilog-mode.el")
9095;;(verilog-dir-file-exists-p "../verilog-mode/verilog-mode.el")
9096
9097
9098;;
9099;; Module name lookup
9100;;
9101
9102(defun verilog-module-inside-filename-p (module filename)
9103  "Return modi if MODULE is specified inside FILENAME, else nil.
9104Allows version control to check out the file if need be."
9105  (and (or (file-exists-p filename)
9106	   (and (fboundp 'vc-backend)
9107		(vc-backend filename)))
9108       (let (modi type)
9109	 (with-current-buffer (find-file-noselect filename)
9110	   (save-excursion
9111	     (goto-char (point-min))
9112	     (while (and
9113		     ;; It may be tempting to look for verilog-defun-re,
9114		     ;; don't, it slows things down a lot!
9115		     (verilog-re-search-forward-quick "\\<\\(module\\|interface\\|program\\)\\>" nil t)
9116		     (setq type (match-string-no-properties 0))
9117		     (verilog-re-search-forward-quick "[(;]" nil t))
9118	       (if (equal module (verilog-read-module-name))
9119		   (setq modi (verilog-modi-new module filename (point) type))))
9120	     modi)))))
9121
9122(defun verilog-is-number (symbol)
9123  "Return true if SYMBOL is number-like."
9124  (or (string-match "^[0-9 \t:]+$" symbol)
9125      (string-match "^[---]*[0-9]+$" symbol)
9126      (string-match "^[0-9 \t]+'s?[hdxbo][0-9a-fA-F_xz? \t]*$" symbol)))
9127
9128(defun verilog-symbol-detick (symbol wing-it)
9129  "Return an expanded SYMBOL name without any defines.
9130If the variable vh-{symbol} is defined, return that value.
9131If undefined, and WING-IT, return just SYMBOL without the tick, else nil."
9132  (while (and symbol (string-match "^`" symbol))
9133    (setq symbol (substring symbol 1))
9134    (setq symbol
9135	  (if (boundp (intern (concat "vh-" symbol)))
9136	      ;; Emacs has a bug where boundp on a buffer-local
9137	      ;; variable in only one buffer returns t in another.
9138	      ;; This can confuse, so check for nil.
9139	      (let ((val (eval (intern (concat "vh-" symbol)))))
9140		(if (eq val nil)
9141		    (if wing-it symbol nil)
9142		  val))
9143	    (if wing-it symbol nil))))
9144  symbol)
9145;;(verilog-symbol-detick "`mod" nil)
9146
9147(defun verilog-symbol-detick-denumber (symbol)
9148  "Return SYMBOL with defines converted and any numbers dropped to nil."
9149  (when (string-match "^`" symbol)
9150    ;; This only will work if the define is a simple signal, not
9151    ;; something like a[b].  Sorry, it should be substituted into the parser
9152    (setq symbol
9153	  (verilog-string-replace-matches
9154	   "\[[^0-9: \t]+\]" "" nil nil
9155	   (or (verilog-symbol-detick symbol nil)
9156	       (if verilog-auto-sense-defines-constant
9157		   "0"
9158		 symbol)))))
9159  (if (verilog-is-number symbol)
9160      nil
9161    symbol))
9162
9163(defun verilog-symbol-detick-text (text)
9164  "Return TEXT without any known defines.
9165If the variable vh-{symbol} is defined, substitute that value."
9166  (let ((ok t) symbol val)
9167    (while (and ok (string-match "`\\([a-zA-Z0-9_]+\\)" text))
9168      (setq symbol (match-string 1 text))
9169      ;;(message symbol)
9170      (cond ((and
9171	      (boundp (intern (concat "vh-" symbol)))
9172	      ;; Emacs has a bug where boundp on a buffer-local
9173	      ;; variable in only one buffer returns t in another.
9174	      ;; This can confuse, so check for nil.
9175	      (setq val (eval (intern (concat "vh-" symbol)))))
9176	     (setq text (replace-match val nil nil text)))
9177	    (t (setq ok nil)))))
9178  text)
9179;;(progn (setq vh-mod "`foo" vh-foo "bar") (verilog-symbol-detick-text "bar `mod `undefed"))
9180
9181(defun verilog-expand-dirnames (&optional dirnames)
9182  "Return a list of existing directories given a list of wildcarded DIRNAMES.
9183Or, just the existing dirnames themselves if there are no wildcards."
9184  ;; Note this function is performance critical.
9185  ;; Do not call anything that requires disk access that cannot be cached.
9186  (interactive)
9187  (unless dirnames (error "`verilog-library-directories' should include at least '.'"))
9188  (setq dirnames (reverse dirnames))	; not nreverse
9189  (let ((dirlist nil)
9190	pattern dirfile dirfiles dirname root filename rest basefile)
9191    (while dirnames
9192      (setq dirname (substitute-in-file-name (car dirnames))
9193	    dirnames (cdr dirnames))
9194      (cond ((string-match (concat "^\\(\\|[/\\]*[^*?]*[/\\]\\)"  ;; root
9195				   "\\([^/\\]*[*?][^/\\]*\\)"	  ;; filename with *?
9196				   "\\(.*\\)")			  ;; rest
9197			   dirname)
9198	     (setq root (match-string 1 dirname)
9199		   filename (match-string 2 dirname)
9200		   rest (match-string 3 dirname)
9201		   pattern filename)
9202	     ;; now replace those * and ? with .+ and .
9203	     ;; use ^ and /> to get only whole file names
9204	     (setq pattern (verilog-string-replace-matches "[*]" ".+" nil nil pattern)
9205		   pattern (verilog-string-replace-matches "[?]" "." nil nil pattern)
9206		   pattern (concat "^" pattern "$")
9207		   dirfiles (verilog-dir-files root))
9208	     (while dirfiles
9209	       (setq basefile (car dirfiles)
9210		     dirfile (expand-file-name (concat root basefile rest))
9211		     dirfiles (cdr dirfiles))
9212	       (if (and (string-match pattern basefile)
9213			;; Don't allow abc/*/rtl to match abc/rtl via ..
9214			(not (equal basefile "."))
9215			(not (equal basefile ".."))
9216			(file-directory-p dirfile))
9217		   (setq dirlist (cons dirfile dirlist)))))
9218	    ;; Defaults
9219	    (t
9220	     (if (file-directory-p dirname)
9221		 (setq dirlist (cons dirname dirlist))))))
9222    dirlist))
9223;;(verilog-expand-dirnames (list "." ".." "nonexist" "../*" "/home/wsnyder/*/v"))
9224
9225(defun verilog-library-filenames (filename &optional current check-ext)
9226  "Return a search path to find the given FILENAME or module name.
9227Uses the optional CURRENT filename or variable `buffer-file-name', plus
9228`verilog-library-directories' and `verilog-library-extensions'
9229variables to build the path.  With optional CHECK-EXT also check
9230`verilog-library-extensions'."
9231  (unless current (setq current (buffer-file-name)))
9232  (unless verilog-dir-cache-preserving
9233    (setq verilog-dir-cache-lib-filenames nil))
9234  (let* ((cache-key (list filename current check-ext))
9235	 (fass (assoc cache-key verilog-dir-cache-lib-filenames))
9236	 chkdirs chkdir chkexts fn outlist)
9237    (cond (fass  ;; Return data from cache hit
9238	   (nth 1 fass))
9239	  (t
9240	   ;; Note this expand can't be easily cached, as we need to
9241	   ;; pick up buffer-local variables for newly read sub-module files
9242	   (setq chkdirs (verilog-expand-dirnames verilog-library-directories))
9243	   (while chkdirs
9244	     (setq chkdir (expand-file-name (car chkdirs)
9245					    (file-name-directory current))
9246		   chkexts (if check-ext verilog-library-extensions `("")))
9247	     (while chkexts
9248	       (setq fn (expand-file-name (concat filename (car chkexts))
9249					  chkdir))
9250	       ;;(message "Check for %s" fn)
9251	       (if (verilog-dir-file-exists-p fn)
9252		   (setq outlist (cons (expand-file-name
9253					fn (file-name-directory current))
9254				       outlist)))
9255		 (setq chkexts (cdr chkexts)))
9256	     (setq chkdirs (cdr chkdirs)))
9257	   (setq outlist (nreverse outlist))
9258	   (setq verilog-dir-cache-lib-filenames
9259		 (cons (list cache-key outlist)
9260		       verilog-dir-cache-lib-filenames))
9261	   outlist))))
9262
9263(defun verilog-module-filenames (module current)
9264  "Return a search path to find the given MODULE name.
9265Uses the CURRENT filename, `verilog-library-extensions',
9266`verilog-library-directories' and `verilog-library-files'
9267variables to build the path."
9268  ;; Return search locations for it
9269  (append (list current)		; first, current buffer
9270	  (verilog-library-filenames module current t)
9271	  verilog-library-files))	; finally, any libraries
9272
9273;;
9274;; Module Information
9275;;
9276;; Many of these functions work on "modi" a module information structure
9277;; A modi is:  [module-name-string file-name begin-point]
9278
9279(defvar verilog-cache-enabled t
9280  "Non-nil enables caching of signals, etc.  Set to nil for debugging to make things SLOW!")
9281
9282(defvar verilog-modi-cache-list nil
9283  "Cache of ((Module Function) Buf-Tick Buf-Modtime Func-Returns)...
9284For speeding up verilog-modi-get-* commands.
9285Buffer-local.")
9286(make-variable-buffer-local 'verilog-modi-cache-list)
9287
9288(defvar verilog-modi-cache-preserve-tick nil
9289  "Modification tick after which the cache is still considered valid.
9290Use `verilog-preserve-modi-cache' to set it.")
9291(defvar verilog-modi-cache-preserve-buffer nil
9292  "Modification tick after which the cache is still considered valid.
9293Use `verilog-preserve-modi-cache' to set it.")
9294(defvar verilog-modi-cache-current-enable nil
9295  "Non-nil means allow caching `verilog-modi-current', set by let().")
9296(defvar verilog-modi-cache-current nil
9297  "Currently active `verilog-modi-current', if any, set by let().")
9298(defvar verilog-modi-cache-current-max nil
9299  "Current endmodule point for `verilog-modi-cache-current', if any.")
9300
9301(defun verilog-modi-current ()
9302  "Return the modi structure for the module currently at point, possibly cached."
9303  (cond ((and verilog-modi-cache-current
9304	      (>= (point) (verilog-modi-get-point verilog-modi-cache-current))
9305	      (<= (point) verilog-modi-cache-current-max))
9306	 ;; Slow assertion, for debugging the cache:
9307	 ;;(or (equal verilog-modi-cache-current (verilog-modi-current-get)) (debug))
9308	 verilog-modi-cache-current)
9309	(verilog-modi-cache-current-enable
9310	 (setq verilog-modi-cache-current (verilog-modi-current-get)
9311	       verilog-modi-cache-current-max
9312	       ;; The cache expires when we pass "endmodule" as then the
9313	       ;; current modi may change to the next module
9314	       ;; This relies on the AUTOs generally inserting, not deleting text
9315	       (save-excursion
9316		 (verilog-re-search-forward-quick verilog-end-defun-re nil nil)))
9317	 verilog-modi-cache-current)
9318	(t
9319	 (verilog-modi-current-get))))
9320
9321(defun verilog-modi-current-get ()
9322  "Return the modi structure for the module currently at point."
9323  (let* (name type pt)
9324    ;; read current module's name
9325    (save-excursion
9326      (verilog-re-search-backward-quick verilog-defun-re nil nil)
9327      (setq type (match-string-no-properties 0))
9328      (verilog-re-search-forward-quick "(" nil nil)
9329      (setq name (verilog-read-module-name))
9330      (setq pt (point)))
9331    ;; return modi - note this vector built two places
9332    (verilog-modi-new name (or (buffer-file-name) (current-buffer)) pt type)))
9333
9334(defvar verilog-modi-lookup-cache nil "Hash of (modulename modi).")
9335(make-variable-buffer-local 'verilog-modi-lookup-cache)
9336(defvar verilog-modi-lookup-last-current nil "Cache of `current-buffer' at last lookup.")
9337(defvar verilog-modi-lookup-last-tick nil "Cache of `buffer-chars-modified-tick' at last lookup.")
9338
9339(defun verilog-modi-lookup (module allow-cache &optional ignore-error)
9340  "Find the file and point at which MODULE is defined.
9341If ALLOW-CACHE is set, check and remember cache of previous lookups.
9342Return modi if successful, else print message unless IGNORE-ERROR is true."
9343  (let* ((current (or (buffer-file-name) (current-buffer)))
9344	 modi)
9345    ;; Check cache
9346    ;;(message "verilog-modi-lookup: %s" module)
9347    (cond ((and verilog-modi-lookup-cache
9348		verilog-cache-enabled
9349		allow-cache
9350		(setq modi (gethash module verilog-modi-lookup-cache))
9351		(equal verilog-modi-lookup-last-current current)
9352		;; Iff hit is in current buffer, then tick must match
9353		(or (equal verilog-modi-lookup-last-tick (buffer-chars-modified-tick))
9354		    (not (equal current (verilog-modi-file-or-buffer modi)))))
9355	   ;;(message "verilog-modi-lookup: HIT %S" modi)
9356	   modi)
9357	  ;; Miss
9358	  (t (let* ((realmod (verilog-symbol-detick module t))
9359		    (orig-filenames (verilog-module-filenames realmod current))
9360		    (filenames orig-filenames)
9361		    mif)
9362	       (while (and filenames (not mif))
9363		 (if (not (setq mif (verilog-module-inside-filename-p realmod (car filenames))))
9364		     (setq filenames (cdr filenames))))
9365	       ;; mif has correct form to become later elements of modi
9366	       (cond (mif (setq modi mif))
9367		     (t (setq modi nil)
9368			(or ignore-error
9369			    (error (concat (verilog-point-text)
9370					   ": Can't locate " module " module definition"
9371					   (if (not (equal module realmod))
9372					       (concat " (Expanded macro to " realmod ")")
9373					     "")
9374					   "\n    Check the verilog-library-directories variable."
9375					   "\n    I looked in (if not listed, doesn't exist):\n\t"
9376					   (mapconcat 'concat orig-filenames "\n\t"))))))
9377	       (when (eval-when-compile (fboundp 'make-hash-table))
9378		 (unless verilog-modi-lookup-cache
9379		   (setq verilog-modi-lookup-cache
9380			 (make-hash-table :test 'equal :rehash-size 4.0)))
9381		 (puthash module modi verilog-modi-lookup-cache))
9382	       (setq verilog-modi-lookup-last-current current
9383		     verilog-modi-lookup-last-tick (buffer-chars-modified-tick)))))
9384    modi))
9385
9386(defun verilog-modi-filename (modi)
9387  "Filename of MODI, or name of buffer if it's never been saved."
9388  (if (bufferp (verilog-modi-file-or-buffer modi))
9389      (or (buffer-file-name (verilog-modi-file-or-buffer modi))
9390	  (buffer-name (verilog-modi-file-or-buffer modi)))
9391    (verilog-modi-file-or-buffer modi)))
9392
9393(defun verilog-modi-goto (modi)
9394  "Move point/buffer to specified MODI."
9395  (or modi (error "Passed unfound modi to goto, check earlier"))
9396  (set-buffer (if (bufferp (verilog-modi-file-or-buffer modi))
9397		  (verilog-modi-file-or-buffer modi)
9398		(find-file-noselect (verilog-modi-file-or-buffer modi))))
9399  (or (equal major-mode `verilog-mode)	;; Put into Verilog mode to get syntax
9400      (verilog-mode))
9401  (goto-char (verilog-modi-get-point modi)))
9402
9403(defun verilog-goto-defun-file (module)
9404  "Move point to the file at which a given MODULE is defined."
9405  (interactive "sGoto File for Module: ")
9406  (let* ((modi (verilog-modi-lookup module nil)))
9407    (when modi
9408      (verilog-modi-goto modi)
9409      (switch-to-buffer (current-buffer)))))
9410
9411(defun verilog-modi-cache-results (modi function)
9412  "Run on MODI the given FUNCTION.  Locate the module in a file.
9413Cache the output of function so next call may have faster access."
9414  (let (fass)
9415    (save-excursion  ;; Cache is buffer-local so can't avoid this.
9416      (verilog-modi-goto modi)
9417      (if (and (setq fass (assoc (list modi function)
9418				 verilog-modi-cache-list))
9419	       ;; Destroy caching when incorrect; Modified or file changed
9420	       (not (and verilog-cache-enabled
9421			 (or (equal (buffer-chars-modified-tick) (nth 1 fass))
9422			     (and verilog-modi-cache-preserve-tick
9423				  (<= verilog-modi-cache-preserve-tick  (nth 1 fass))
9424				  (equal  verilog-modi-cache-preserve-buffer (current-buffer))))
9425			 (equal (visited-file-modtime) (nth 2 fass)))))
9426	  (setq verilog-modi-cache-list nil
9427		fass nil))
9428      (cond (fass
9429	     ;; Return data from cache hit
9430	     (nth 3 fass))
9431	    (t
9432	     ;; Read from file
9433	     ;; Clear then restore any highlighting to make emacs19 happy
9434	     (let (func-returns)
9435	       (verilog-save-font-mods
9436		(setq func-returns (funcall function)))
9437	       ;; Cache for next time
9438	       (setq verilog-modi-cache-list
9439		     (cons (list (list modi function)
9440				 (buffer-chars-modified-tick)
9441				 (visited-file-modtime)
9442				 func-returns)
9443			   verilog-modi-cache-list))
9444	       func-returns))))))
9445
9446(defun verilog-modi-cache-add (modi function element sig-list)
9447  "Add function return results to the module cache.
9448Update MODI's cache for given FUNCTION so that the return ELEMENT of that
9449function now contains the additional SIG-LIST parameters."
9450  (let (fass)
9451    (save-excursion
9452      (verilog-modi-goto modi)
9453      (if (setq fass (assoc (list modi function)
9454			    verilog-modi-cache-list))
9455	  (let ((func-returns (nth 3 fass)))
9456	    (aset func-returns element
9457		  (append sig-list (aref func-returns element))))))))
9458
9459(defmacro verilog-preserve-modi-cache (&rest body)
9460  "Execute the BODY forms, allowing cache preservation within BODY.
9461This means that changes to the buffer will not result in the cache being
9462flushed.  If the changes affect the modsig state, they must call the
9463modsig-cache-add-* function, else the results of later calls may be
9464incorrect.  Without this, changes are assumed to be adding/removing signals
9465and invalidating the cache."
9466  `(let ((verilog-modi-cache-preserve-tick (buffer-chars-modified-tick))
9467	 (verilog-modi-cache-preserve-buffer (current-buffer)))
9468     (progn ,@body)))
9469
9470
9471(defun verilog-signals-matching-enum (in-list enum)
9472  "Return all signals in IN-LIST matching the given ENUM."
9473  (let (out-list)
9474    (while in-list
9475      (if (equal (verilog-sig-enum (car in-list)) enum)
9476	  (setq out-list (cons (car in-list) out-list)))
9477      (setq in-list (cdr in-list)))
9478    ;; New scheme
9479    (let* ((enumvar (intern (concat "venum-" enum)))
9480	   (enumlist (and (boundp enumvar) (eval enumvar))))
9481      (while enumlist
9482	(add-to-list 'out-list (list (car enumlist)))
9483	(setq enumlist (cdr enumlist))))
9484    (nreverse out-list)))
9485
9486(defun verilog-signals-matching-regexp (in-list regexp)
9487  "Return all signals in IN-LIST matching the given REGEXP, if non-nil."
9488  (if (or (not regexp) (equal regexp ""))
9489      in-list
9490    (let (out-list)
9491      (while in-list
9492	(if (string-match regexp (verilog-sig-name (car in-list)))
9493	    (setq out-list (cons (car in-list) out-list)))
9494	(setq in-list (cdr in-list)))
9495      (nreverse out-list))))
9496
9497(defun verilog-signals-not-matching-regexp (in-list regexp)
9498  "Return all signals in IN-LIST not matching the given REGEXP, if non-nil."
9499  (if (or (not regexp) (equal regexp ""))
9500      in-list
9501    (let (out-list)
9502      (while in-list
9503	(if (not (string-match regexp (verilog-sig-name (car in-list))))
9504	    (setq out-list (cons (car in-list) out-list)))
9505	(setq in-list (cdr in-list)))
9506      (nreverse out-list))))
9507
9508(defun verilog-signals-matching-dir-re (in-list decl-type regexp)
9509  "Return all signals in IN-LIST matching the given DECL-TYPE and REGEXP,
9510if non-nil."
9511  (if (or (not regexp) (equal regexp ""))
9512      in-list
9513    (let (out-list to-match)
9514      (while in-list
9515	;; Note verilog-insert-one-definition matches on this order
9516	(setq to-match (concat
9517			decl-type
9518			" " (verilog-sig-signed (car in-list))
9519			" " (verilog-sig-multidim (car in-list))
9520			(verilog-sig-bits (car in-list))))
9521	(if (string-match regexp to-match)
9522	    (setq out-list (cons (car in-list) out-list)))
9523	(setq in-list (cdr in-list)))
9524      (nreverse out-list))))
9525
9526(defun verilog-signals-edit-wire-reg (in-list)
9527  "Return all signals in IN-LIST with wire/reg data types made blank."
9528  (mapcar (lambda (sig)
9529	    (when (member (verilog-sig-type sig) '("wire" "reg"))
9530	      (verilog-sig-type-set sig nil))
9531	    sig) in-list))
9532
9533;; Combined
9534(defun verilog-decls-get-signals (decls)
9535  "Return all declared signals in DECLS, excluding 'assign' statements."
9536  (append
9537   (verilog-decls-get-outputs decls)
9538   (verilog-decls-get-inouts decls)
9539   (verilog-decls-get-inputs decls)
9540   (verilog-decls-get-vars decls)
9541   (verilog-decls-get-consts decls)
9542   (verilog-decls-get-gparams decls)))
9543
9544(defun verilog-decls-get-ports (decls)
9545  (append
9546   (verilog-decls-get-outputs decls)
9547   (verilog-decls-get-inouts decls)
9548   (verilog-decls-get-inputs decls)))
9549
9550(defsubst verilog-modi-cache-add-outputs (modi sig-list)
9551  (verilog-modi-cache-add modi 'verilog-read-decls 0 sig-list))
9552(defsubst verilog-modi-cache-add-inouts (modi sig-list)
9553  (verilog-modi-cache-add modi 'verilog-read-decls 1 sig-list))
9554(defsubst verilog-modi-cache-add-inputs (modi sig-list)
9555  (verilog-modi-cache-add modi 'verilog-read-decls 2 sig-list))
9556(defsubst verilog-modi-cache-add-vars (modi sig-list)
9557  (verilog-modi-cache-add modi 'verilog-read-decls 3 sig-list))
9558
9559
9560;;
9561;; Auto creation utilities
9562;;
9563
9564(defun verilog-auto-re-search-do (search-for func)
9565  "Search for the given auto text regexp SEARCH-FOR, and perform FUNC where it occurs."
9566  (goto-char (point-min))
9567  (while (verilog-re-search-forward-quick search-for nil t)
9568    (funcall func)))
9569
9570(defun verilog-insert-one-definition (sig type indent-pt)
9571  "Print out a definition for SIG of the given TYPE,
9572with appropriate INDENT-PT indentation."
9573  (indent-to indent-pt)
9574  ;; Note verilog-signals-matching-dir-re matches on this order
9575  (insert type)
9576  (when (verilog-sig-modport sig)
9577    (insert "." (verilog-sig-modport sig)))
9578  (when (verilog-sig-signed sig)
9579    (insert " " (verilog-sig-signed sig)))
9580  (when (verilog-sig-multidim sig)
9581    (insert " " (verilog-sig-multidim-string sig)))
9582  (when (verilog-sig-bits sig)
9583    (insert " " (verilog-sig-bits sig)))
9584  (indent-to (max 24 (+ indent-pt 16)))
9585  (unless (= (char-syntax (preceding-char)) ?\  )
9586    (insert " "))  ; Need space between "]name" if indent-to did nothing
9587  (insert (verilog-sig-name sig))
9588  (when (verilog-sig-memory sig)
9589    (insert " " (verilog-sig-memory sig))))
9590
9591(defun verilog-insert-definition (modi sigs direction indent-pt v2k &optional dont-sort)
9592  "Print out a definition for MODI's list of SIGS of the given DIRECTION,
9593with appropriate INDENT-PT indentation.  If V2K, use Verilog 2001 I/O
9594format.  Sort unless DONT-SORT.  DIRECTION is normally wire/reg/output.
9595When MODI is non-null, also add to modi-cache, for tracking."
9596  (when modi
9597    (cond ((equal direction "wire")
9598	   (verilog-modi-cache-add-vars modi sigs))
9599	  ((equal direction "reg")
9600	   (verilog-modi-cache-add-vars modi sigs))
9601	  ((equal direction "output")
9602	   (verilog-modi-cache-add-outputs modi sigs)
9603	   (when verilog-auto-declare-nettype
9604	     (verilog-modi-cache-add-vars modi sigs)))
9605	  ((equal direction "input")
9606	   (verilog-modi-cache-add-inputs modi sigs)
9607	   (when verilog-auto-declare-nettype
9608	     (verilog-modi-cache-add-vars modi sigs)))
9609	  ((equal direction "inout")
9610	   (verilog-modi-cache-add-inouts modi sigs)
9611	   (when verilog-auto-declare-nettype
9612	     (verilog-modi-cache-add-vars modi sigs)))
9613	  ((equal direction "interface"))
9614	  (t
9615	   (error "Unsupported verilog-insert-definition direction: %s" direction))))
9616  (or dont-sort
9617      (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
9618  (while sigs
9619    (let ((sig (car sigs)))
9620      (verilog-insert-one-definition
9621       sig
9622       ;; Want "type x" or "output type x", not "wire type x"
9623       (cond ((or (verilog-sig-type sig)
9624		  verilog-auto-wire-type)
9625	      (concat
9626	       (when (member direction '("input" "output" "inout"))
9627		 (concat direction " "))
9628	       (or (verilog-sig-type sig)
9629		  verilog-auto-wire-type)))
9630	     ((and verilog-auto-declare-nettype
9631		   (member direction '("input" "output" "inout")))
9632	      (concat direction " " verilog-auto-declare-nettype))
9633	     (t
9634	      direction))
9635       indent-pt)
9636      (insert (if v2k "," ";"))
9637      (if (or (not (verilog-sig-comment sig))
9638	      (equal "" (verilog-sig-comment sig)))
9639	  (insert "\n")
9640	(indent-to (max 48 (+ indent-pt 40)))
9641	(verilog-insert "// " (verilog-sig-comment sig) "\n"))
9642      (setq sigs (cdr sigs)))))
9643
9644(eval-when-compile
9645  (if (not (boundp 'indent-pt))
9646      (defvar indent-pt nil "Local used by insert-indent")))
9647
9648(defun verilog-insert-indent (&rest stuff)
9649  "Indent to position stored in local `indent-pt' variable, then insert STUFF.
9650Presumes that any newlines end a list element."
9651  (let ((need-indent t))
9652    (while stuff
9653      (if need-indent (indent-to indent-pt))
9654      (setq need-indent nil)
9655      (verilog-insert (car stuff))
9656      (setq need-indent (string-match "\n$" (car stuff))
9657	    stuff (cdr stuff)))))
9658;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n"))
9659
9660(defun verilog-forward-or-insert-line ()
9661  "Move forward a line, unless at EOB, then insert a newline."
9662  (if (eobp) (insert "\n")
9663    (forward-line)))
9664
9665(defun verilog-repair-open-comma ()
9666  "Insert comma if previous argument is other than an open parenthesis or endif."
9667  ;; We can't just search backward for ) as it might be inside another expression.
9668  ;; Also want "`ifdef X   input foo   `endif" to just leave things to the human to deal with
9669  (save-excursion
9670    (verilog-backward-syntactic-ws-quick)
9671    (when (and (not (save-excursion ;; Not beginning (, or existing ,
9672		      (backward-char 1)
9673		      (looking-at "[(,]")))
9674	       (not (save-excursion ;; Not `endif, or user define
9675		      (backward-char 1)
9676		      (skip-chars-backward "[a-zA-Z0-9_`]")
9677		      (looking-at "`"))))
9678      (insert ","))))
9679
9680(defun verilog-repair-close-comma ()
9681  "If point is at a comma followed by a close parenthesis, fix it.
9682This repairs those mis-inserted by an AUTOARG."
9683  ;; It would be much nicer if Verilog allowed extra commas like Perl does!
9684  (save-excursion
9685    (verilog-forward-close-paren)
9686    (backward-char 1)
9687    (verilog-backward-syntactic-ws-quick)
9688    (backward-char 1)
9689    (when (looking-at ",")
9690      (delete-char 1))))
9691
9692(defun verilog-get-list (start end)
9693  "Return the elements of a comma separated list between START and END."
9694  (interactive)
9695  (let ((my-list (list))
9696	my-string)
9697    (save-excursion
9698      (while (< (point) end)
9699	(when (re-search-forward "\\([^,{]+\\)" end t)
9700	  (setq my-string (verilog-string-remove-spaces (match-string 1)))
9701	  (setq my-list (nconc my-list (list my-string) ))
9702	  (goto-char (match-end 0))))
9703      my-list)))
9704
9705(defun verilog-make-width-expression (range-exp)
9706  "Return an expression calculating the length of a range [x:y] in RANGE-EXP."
9707  ;; strip off the []
9708  (cond ((not range-exp)
9709	 "1")
9710	(t
9711	 (if (string-match "^\\[\\(.*\\)\\]$" range-exp)
9712	     (setq range-exp (match-string 1 range-exp)))
9713	 (cond ((not range-exp)
9714		"1")
9715	       ;; [#:#] We can compute a numeric result
9716	       ((string-match "^\\s *\\([0-9]+\\)\\s *:\\s *\\([0-9]+\\)\\s *$"
9717			      range-exp)
9718		(int-to-string
9719		 (1+ (abs (- (string-to-number (match-string 1 range-exp))
9720			     (string-to-number (match-string 2 range-exp)))))))
9721	       ;; [PARAM-1:0] can just return PARAM
9722	       ((string-match "^\\s *\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s *-\\s *1\\s *:\\s *0\\s *$" range-exp)
9723		(match-string 1 range-exp))
9724	       ;; [arbitrary] need math
9725	       ((string-match "^\\(.*\\)\\s *:\\s *\\(.*\\)\\s *$" range-exp)
9726		(concat "(1+(" (match-string 1 range-exp) ")"
9727			(if (equal "0" (match-string 2 range-exp))
9728			    ""  ;; Don't bother with -(0)
9729			  (concat "-(" (match-string 2 range-exp) ")"))
9730			")"))
9731	       (t nil)))))
9732;;(verilog-make-width-expression "`A:`B")
9733
9734(defun verilog-simplify-range-expression (expr)
9735  "Return a simplified range expression with constants eliminated from EXPR."
9736  ;; Note this is always called with brackets; ie [z] or [z:z]
9737  (if (not (string-match "[---+*()]" expr))
9738      expr ;; short-circuit
9739    (let ((out expr)
9740	  (last-pass ""))
9741      (while (not (equal last-pass out))
9742	(setq last-pass out)
9743	;; Prefix regexp needs beginning of match, or some symbol of
9744	;; lesser or equal precedence.  We assume the [:]'s exist in expr.
9745	;; Ditto the end.
9746	(while (string-match
9747		(concat "\\([[({:*+-]\\)"  ; - must be last
9748			"(\\<\\([0-9A-Za-z_]+\\))"
9749			"\\([])}:*+-]\\)")
9750		out)
9751	  (setq out (replace-match "\\1\\2\\3" nil nil out)))
9752	;; For precedence do * before +/-
9753	(while (string-match
9754		(concat "\\([[({:*+-]\\)"
9755			"\\([0-9]+\\)\\s *\\([*]\\)\\s *\\([0-9]+\\)"
9756			"\\([])}:*+-]\\)")
9757		out)
9758	  (setq out (replace-match
9759		     (concat (match-string 1 out)
9760			     (int-to-string (* (string-to-number (match-string 2 out))
9761					       (string-to-number (match-string 4 out))))
9762			     (match-string 5 out))
9763		     nil nil out)))
9764	(while (string-match
9765		(concat "\\([[({:+-]\\)" ; No * here as higher prec
9766			"\\([0-9]+\\)\\s *\\([---+]\\)\\s *\\([0-9]+\\)"
9767			"\\([])}:+-]\\)")
9768		out)
9769	  (let ((pre (match-string 1 out))
9770		(lhs (string-to-number (match-string 2 out)))
9771		(rhs (string-to-number (match-string 4 out)))
9772		(post (match-string 5 out))
9773		val)
9774	    (when (equal pre "-")
9775	      (setq lhs (- lhs)))
9776	    (setq val (if (equal (match-string 3 out) "-")
9777			  (- lhs rhs)
9778			(+ lhs rhs))
9779		  out (replace-match
9780		       (concat (if (and (equal pre "-")
9781					(< val 0))
9782				   "" ;; Not "--20" but just "-20"
9783				 pre)
9784			       (int-to-string val)
9785			       post)
9786		       nil nil out)) )))
9787      out)))
9788;;(verilog-simplify-range-expression "[1:3]") ;; 1
9789;;(verilog-simplify-range-expression "[(1):3]") ;; 1
9790;;(verilog-simplify-range-expression "[(((16)+1)+1+(1+1))]")  ;;20
9791;;(verilog-simplify-range-expression "[(2*3+6*7)]") ;; 48
9792;;(verilog-simplify-range-expression "[(FOO*4-1*2)]") ;; FOO*4-2
9793;;(verilog-simplify-range-expression "[(FOO*4+1-1)]") ;; FOO*4+0
9794;;(verilog-simplify-range-expression "[(func(BAR))]") ;; func(BAR)
9795;;(verilog-simplify-range-expression "[FOO-1+1-1+1]") ;; FOO-0
9796
9797(defun verilog-typedef-name-p (variable-name)
9798  "Return true if the VARIABLE-NAME is a type definition."
9799  (when verilog-typedef-regexp
9800    (string-match verilog-typedef-regexp variable-name)))
9801
9802;;
9803;; Auto deletion
9804;;
9805
9806(defun verilog-delete-autos-lined ()
9807  "Delete autos that occupy multiple lines, between begin and end comments."
9808  ;; The newline must not have a comment property, so we must
9809  ;; delete the end auto's newline, not the first newline
9810  (forward-line 1)
9811  (let ((pt (point)))
9812    (when (and
9813	   (looking-at "\\s-*// Beginning")
9814	   (search-forward "// End of automatic" nil t))
9815      ;; End exists
9816      (end-of-line)
9817      (forward-line 1)
9818      (delete-region pt (point)))))
9819
9820(defun verilog-delete-empty-auto-pair ()
9821  "Delete begin/end auto pair at point, if empty."
9822  (forward-line 0)
9823  (when (looking-at (concat "\\s-*// Beginning of automatic.*\n"
9824			    "\\s-*// End of automatics\n"))
9825    (delete-region (point) (save-excursion (forward-line 2) (point)))))
9826
9827(defun verilog-forward-close-paren ()
9828  "Find the close parenthesis that match the current point.
9829Ignore other close parenthesis with matching open parens."
9830  (let ((parens 1))
9831    (while (> parens 0)
9832      (unless (verilog-re-search-forward-quick "[()]" nil t)
9833	(error "%s: Mismatching ()" (verilog-point-text)))
9834      (cond ((= (preceding-char) ?\( )
9835	     (setq parens (1+ parens)))
9836	    ((= (preceding-char) ?\) )
9837	     (setq parens (1- parens)))))))
9838
9839(defun verilog-backward-open-paren ()
9840  "Find the open parenthesis that match the current point.
9841Ignore other open parenthesis with matching close parens."
9842  (let ((parens 1))
9843    (while (> parens 0)
9844      (unless (verilog-re-search-backward-quick "[()]" nil t)
9845	(error "%s: Mismatching ()" (verilog-point-text)))
9846      (cond ((= (following-char) ?\) )
9847	     (setq parens (1+ parens)))
9848	    ((= (following-char) ?\( )
9849	     (setq parens (1- parens)))))))
9850
9851(defun verilog-backward-open-bracket ()
9852  "Find the open bracket that match the current point.
9853Ignore other open bracket with matching close bracket."
9854  (let ((parens 1))
9855    (while (> parens 0)
9856      (unless (verilog-re-search-backward-quick "[][]" nil t)
9857	(error "%s: Mismatching []" (verilog-point-text)))
9858      (cond ((= (following-char) ?\] )
9859	     (setq parens (1+ parens)))
9860	    ((= (following-char) ?\[ )
9861	     (setq parens (1- parens)))))))
9862
9863(defun verilog-delete-to-paren ()
9864  "Delete the automatic inst/sense/arg created by autos.
9865Deletion stops at the matching end parenthesis, outside comments."
9866  (delete-region (point)
9867		 (save-excursion
9868		   (verilog-backward-open-paren)
9869		   (verilog-forward-sexp-ign-cmt 1)   ;; Moves to paren that closes argdecl's
9870		   (backward-char 1)
9871		   (point))))
9872
9873(defun verilog-auto-star-safe ()
9874  "Return if a .* AUTOINST is safe to delete or expand.
9875It was created by the AUTOS themselves, or by the user."
9876  (and verilog-auto-star-expand
9877       (looking-at
9878	(concat "[ \t\n\f,]*\\([)]\\|// " verilog-inst-comment-re "\\)"))))
9879
9880(defun verilog-delete-auto-star-all ()
9881  "Delete a .* AUTOINST, if it is safe."
9882  (when (verilog-auto-star-safe)
9883    (verilog-delete-to-paren)))
9884
9885(defun verilog-delete-auto-star-implicit ()
9886  "Delete all .* implicit connections created by `verilog-auto-star'.
9887This function will be called automatically at save unless
9888`verilog-auto-star-save' is set, any non-templated expanded pins will be
9889removed."
9890  (interactive)
9891  (let (paren-pt indent have-close-paren)
9892    (save-excursion
9893      (goto-char (point-min))
9894      ;; We need to match these even outside of comments.
9895      ;; For reasonable performance, we don't check if inside comments, sorry.
9896      (while (re-search-forward "// Implicit \\.\\*" nil t)
9897	(setq paren-pt (point))
9898	(beginning-of-line)
9899	(setq have-close-paren
9900	      (save-excursion
9901		(when (search-forward ");" paren-pt t)
9902		  (setq indent (current-indentation))
9903		  t)))
9904	(delete-region (point) (+ 1 paren-pt))  ; Nuke line incl CR
9905	(when have-close-paren
9906	  ;; Delete extra commentary
9907	  (save-excursion
9908	    (while (progn
9909		     (forward-line -1)
9910		     (looking-at (concat "\\s *//\\s *" verilog-inst-comment-re "\n")))
9911	      (delete-region (match-beginning 0) (match-end 0))))
9912	  ;; If it is simple, we can put the ); on the same line as the last text
9913	  (let ((rtn-pt (point)))
9914	    (save-excursion
9915	      (while (progn (backward-char 1)
9916			    (looking-at "[ \t\n\f]")))
9917	      (when (looking-at ",")
9918		(delete-region (+ 1 (point)) rtn-pt))))
9919	  (when (bolp)
9920	    (indent-to indent))
9921	  (insert ");\n")
9922	  ;; Still need to kill final comma - always is one as we put one after the .*
9923	  (re-search-backward ",")
9924	  (delete-char 1))))))
9925
9926(defun verilog-delete-auto ()
9927  "Delete the automatic outputs, regs, and wires created by \\[verilog-auto].
9928Use \\[verilog-auto] to re-insert the updated AUTOs.
9929
9930The hooks `verilog-before-delete-auto-hook' and `verilog-delete-auto-hook' are
9931called before and after this function, respectively."
9932  (interactive)
9933  (save-excursion
9934    (if (buffer-file-name)
9935	(find-file-noselect (buffer-file-name)))	;; To check we have latest version
9936    (verilog-save-no-change-functions
9937     (verilog-save-scan-cache
9938      ;; Allow user to customize
9939      (verilog-run-hooks 'verilog-before-delete-auto-hook)
9940
9941      ;; Remove those that have multi-line insertions, possibly with parameters
9942      ;; We allow anything beginning with AUTO, so that users can add their own
9943      ;; patterns
9944      (verilog-auto-re-search-do
9945       (concat "/\\*AUTO[A-Za-z0-9_]+"
9946	       ;; Optional parens or quoted parameter or .* for (((...)))
9947	       "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
9948	       "\\*/")
9949       'verilog-delete-autos-lined)
9950      ;; Remove those that are in parenthesis
9951      (verilog-auto-re-search-do
9952       (concat "/\\*"
9953	       (eval-when-compile
9954		 (verilog-regexp-words
9955		  `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
9956		    "AUTOSENSE")))
9957	       "\\*/")
9958       'verilog-delete-to-paren)
9959      ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
9960      (verilog-auto-re-search-do "\\.\\*"
9961				 'verilog-delete-auto-star-all)
9962      ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
9963      (goto-char (point-min))
9964      (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)?$" nil t)
9965	(replace-match ""))
9966
9967      ;; Final customize
9968      (verilog-run-hooks 'verilog-delete-auto-hook)))))
9969
9970;;
9971;; Auto inject
9972;;
9973
9974(defun verilog-inject-auto ()
9975  "Examine legacy non-AUTO code and insert AUTOs in appropriate places.
9976
9977Any always @ blocks with sensitivity lists that match computed lists will
9978be replaced with /*AS*/ comments.
9979
9980Any cells will get /*AUTOINST*/ added to the end of the pin list.
9981Pins with have identical names will be deleted.
9982
9983Argument lists will not be deleted, /*AUTOARG*/ will only be inserted to
9984support adding new ports.  You may wish to delete older ports yourself.
9985
9986For example:
9987
9988	module ExampInject (i, o);
9989	  input i;
9990	  input j;
9991	  output o;
9992	  always @ (i or j)
9993	     o = i | j;
9994	  InstModule instName
9995            (.foobar(baz),
9996	     j(j));
9997	endmodule
9998
9999Typing \\[verilog-inject-auto] will make this into:
10000
10001	module ExampInject (i, o/*AUTOARG*/
10002	  // Inputs
10003	  j);
10004	  input i;
10005	  output o;
10006	  always @ (/*AS*/i or j)
10007	     o = i | j;
10008	  InstModule instName
10009            (.foobar(baz),
10010	     /*AUTOINST*/
10011	     // Outputs
10012	     j(j));
10013	endmodule"
10014  (interactive)
10015  (verilog-auto t))
10016
10017(defun verilog-inject-arg ()
10018  "Inject AUTOARG into new code.  See `verilog-inject-auto'."
10019  ;; Presume one module per file.
10020  (save-excursion
10021    (goto-char (point-min))
10022    (while (verilog-re-search-forward-quick "\\<module\\>" nil t)
10023      (let ((endmodp (save-excursion
10024		       (verilog-re-search-forward-quick "\\<endmodule\\>" nil t)
10025		       (point))))
10026	;; See if there's already a comment .. inside a comment so not verilog-re-search
10027	(when (not (re-search-forward "/\\*AUTOARG\\*/" endmodp t))
10028	  (verilog-re-search-forward-quick ";" nil t)
10029	  (backward-char 1)
10030	  (verilog-backward-syntactic-ws-quick)
10031	  (backward-char 1) ; Moves to paren that closes argdecl's
10032	  (when (looking-at ")")
10033	    (verilog-insert "/*AUTOARG*/")))))))
10034
10035(defun verilog-inject-sense ()
10036  "Inject AUTOSENSE into new code.  See `verilog-inject-auto'."
10037  (save-excursion
10038    (goto-char (point-min))
10039    (while (verilog-re-search-forward-quick "\\<always\\s *@\\s *(" nil t)
10040      (let* ((start-pt (point))
10041	     (modi (verilog-modi-current))
10042	     (moddecls (verilog-modi-get-decls modi))
10043	     pre-sigs
10044	     got-sigs)
10045	(backward-char 1)
10046	(verilog-forward-sexp-ign-cmt 1)
10047	(backward-char 1) ;; End )
10048	(when (not (verilog-re-search-backward-quick "/\\*\\(AUTOSENSE\\|AS\\)\\*/" start-pt t))
10049	  (setq pre-sigs (verilog-signals-from-signame
10050			  (verilog-read-signals start-pt (point)))
10051		got-sigs (verilog-auto-sense-sigs moddecls nil))
10052	  (when (not (or (verilog-signals-not-in pre-sigs got-sigs)  ; Both are equal?
10053			 (verilog-signals-not-in got-sigs pre-sigs)))
10054	    (delete-region start-pt (point))
10055	    (verilog-insert "/*AS*/")))))))
10056
10057(defun verilog-inject-inst ()
10058  "Inject AUTOINST into new code.  See `verilog-inject-auto'."
10059  (save-excursion
10060    (goto-char (point-min))
10061    ;; It's hard to distinguish modules; we'll instead search for pins.
10062    (while (verilog-re-search-forward-quick "\\.\\s *[a-zA-Z0-9`_\$]+\\s *(\\s *[a-zA-Z0-9`_\$]+\\s *)" nil t)
10063      (verilog-backward-open-paren) ;; Inst start
10064      (cond
10065       ((= (preceding-char) ?\#)  ;; #(...) parameter section, not pin.  Skip.
10066	(forward-char 1)
10067	(verilog-forward-close-paren)) ;; Parameters done
10068       (t
10069	(forward-char 1)
10070	(let ((indent-pt (+ (current-column)))
10071	      (end-pt (save-excursion (verilog-forward-close-paren) (point))))
10072	  (cond ((verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-pt t)
10073		 (goto-char end-pt)) ;; Already there, continue search with next instance
10074		(t
10075		 ;; Delete identical interconnect
10076		 (let ((case-fold-search nil))  ;; So we don't convert upper-to-lower, etc
10077		   (while (verilog-re-search-forward-quick "\\.\\s *\\([a-zA-Z0-9`_\$]+\\)*\\s *(\\s *\\1\\s *)\\s *" end-pt t)
10078		     (delete-region (match-beginning 0) (match-end 0))
10079		     (setq end-pt (- end-pt (- (match-end 0) (match-beginning 0)))) ;; Keep it correct
10080		     (while (or (looking-at "[ \t\n\f,]+")
10081				(looking-at "//[^\n]*"))
10082		       (delete-region (match-beginning 0) (match-end 0))
10083		       (setq end-pt (- end-pt (- (match-end 0) (match-beginning 0)))))))
10084		 (verilog-forward-close-paren)
10085		 (backward-char 1)
10086		 ;; Not verilog-re-search, as we don't want to strip comments
10087		 (while (re-search-backward "[ \t\n\f]+" (- (point) 1) t)
10088		   (delete-region (match-beginning 0) (match-end 0)))
10089		 (verilog-insert "\n")
10090		 (verilog-insert-indent "/*AUTOINST*/")))))))))
10091
10092;;
10093;; Auto diff
10094;;
10095
10096(defun verilog-diff-buffers-p (b1 b2 &optional whitespace)
10097  "Return nil if buffers B1 and B2 have same contents.
10098Else, return point in B1 that first mismatches.
10099If optional WHITESPACE true, ignore whitespace."
10100  (save-excursion
10101    (let* ((case-fold-search nil)  ;; compare-buffer-substrings cares
10102	   (p1 (with-current-buffer b1 (goto-char (point-min))))
10103	   (p2 (with-current-buffer b2 (goto-char (point-min))))
10104	   (maxp1 (with-current-buffer b1 (point-max)))
10105	   (maxp2 (with-current-buffer b2 (point-max)))
10106	   (op1 -1) (op2 -1)
10107	   progress size)
10108      (while (not (and (eq p1 op1) (eq p2 op2)))
10109	;; If both windows have whitespace optionally skip over it.
10110	(when whitespace
10111	  ;; skip-syntax-* doesn't count \n
10112	  (with-current-buffer b1
10113	    (goto-char p1)
10114	    (skip-chars-forward " \t\n\r\f\v")
10115	    (setq p1 (point)))
10116	  (with-current-buffer b2
10117	    (goto-char p2)
10118	    (skip-chars-forward " \t\n\r\f\v")
10119	    (setq p2 (point))))
10120	(setq size (min (- maxp1 p1) (- maxp2 p2)))
10121	(setq progress (compare-buffer-substrings b2 p2 (+ size p2)
10122						  b1 p1 (+ size p1)))
10123	(setq progress (if (zerop progress) size (1- (abs progress))))
10124	(setq op1 p1  op2 p2
10125	      p1 (+ p1 progress)
10126	      p2 (+ p2 progress)))
10127      ;; Return value
10128      (if (and (eq p1 maxp1) (eq p2 maxp2))
10129	  nil p1))))
10130
10131(defun verilog-diff-file-with-buffer (f1 b2 &optional whitespace show)
10132  "View the differences between file F1 and buffer B2.
10133This requires the external program `diff-command' to be in your `exec-path',
10134and uses `diff-switches' in which you may want to have \"-u\" flag.
10135Ignores WHITESPACE if t, and writes output to stdout if SHOW."
10136  ;; Similar to `diff-buffer-with-file' but works on XEmacs, and doesn't
10137  ;; call `diff' as `diff' has different calling semantics on different
10138  ;; versions of Emacs.
10139  (if (not (file-exists-p f1))
10140      (message "Buffer %s has no associated file on disc" (buffer-name b2))
10141    (with-temp-buffer "*Verilog-Diff*"
10142      (let ((outbuf (current-buffer))
10143	    (f2 (make-temp-file "vm-diff-auto-")))
10144	(unwind-protect
10145	    (progn
10146	      (with-current-buffer b2
10147		(save-restriction
10148		  (widen)
10149		  (write-region (point-min) (point-max) f2 nil 'nomessage)))
10150	      (call-process diff-command nil outbuf t
10151			    diff-switches ;; User may want -u in diff-switches
10152			    (if whitespace "-b" "")
10153			    f1 f2)
10154	      ;; Print out results.  Alternatively we could have call-processed
10155	      ;; ourself, but this way we can reuse diff switches
10156	      (when show
10157		(with-current-buffer outbuf (message "%s" (buffer-string))))))
10158	(sit-for 0)
10159	(when (file-exists-p f2)
10160	  (delete-file f2))))))
10161
10162(defun verilog-diff-report (b1 b2 diffpt)
10163  "Report differences detected with `verilog-diff-auto'.
10164Differences are between buffers B1 and B2, starting at point
10165DIFFPT.  This function is called via `verilog-diff-function'."
10166  (let ((name1 (with-current-buffer b1 (buffer-file-name))))
10167    (verilog-warn "%s:%d: Difference in AUTO expansion found"
10168		  name1 (with-current-buffer b1
10169			  (1+ (count-lines (point-min) (point)))))
10170    (cond (noninteractive
10171	   (verilog-diff-file-with-buffer name1 b2 t t))
10172	  (t
10173	   (ediff-buffers b1 b2)))))
10174
10175(defun verilog-diff-auto ()
10176  "Expand AUTOs in a temporary buffer and indicate any change.
10177Whitespace differences are ignored to determine identicalness, but
10178once a difference is detected, whitespace differences may be shown.
10179
10180To call this from the command line, see \\[verilog-batch-diff-auto].
10181
10182The action on differences is selected with
10183`verilog-diff-function'.  The default is `verilog-diff-report'
10184which will report an error and run `ediff' in interactive mode,
10185or `diff' in batch mode."
10186  (interactive)
10187  (let ((b1 (current-buffer)) b2 diffpt
10188	(name1 (buffer-file-name))
10189	(newname "*Verilog-Diff*"))
10190    (save-excursion
10191      (when (get-buffer newname)
10192	(kill-buffer newname))
10193      (setq b2 (let (buffer-file-name)  ;; Else clone is upset
10194		 (clone-buffer newname)))
10195      (with-current-buffer b2
10196	;; auto requires the filename, but can't have same filename in two
10197	;; buffers; so override both b1 and b2's names
10198	(let ((buffer-file-name name1))
10199	  (unwind-protect
10200	      (progn
10201		(with-current-buffer b1 (setq buffer-file-name nil))
10202		(verilog-auto)
10203		(when (not verilog-auto-star-save)
10204		  (verilog-delete-auto-star-implicit)))
10205	    ;; Restore name if unwind
10206	    (with-current-buffer b1 (setq buffer-file-name name1)))))
10207      ;;
10208      (setq diffpt (verilog-diff-buffers-p b1 b2 t))
10209      (cond ((not diffpt)
10210	     (unless noninteractive (message "AUTO expansion identical"))
10211	     (kill-buffer newname)) ;; Nice to cleanup after oneself
10212	    (t
10213	     (funcall verilog-diff-function b1 b2 diffpt)))
10214      ;; Return result of compare
10215      diffpt)))
10216
10217
10218;;
10219;; Auto save
10220;;
10221
10222(defun verilog-auto-save-check ()
10223  "On saving see if we need auto update."
10224  (cond ((not verilog-auto-save-policy)) ; disabled
10225	((not (save-excursion
10226		(save-match-data
10227		  (let ((case-fold-search nil))
10228		    (goto-char (point-min))
10229		    (re-search-forward "AUTO" nil t))))))
10230	((eq verilog-auto-save-policy 'force)
10231	 (verilog-auto))
10232	((not (buffer-modified-p)))
10233	((eq verilog-auto-update-tick (buffer-chars-modified-tick))) ; up-to-date
10234	((eq verilog-auto-save-policy 'detect)
10235	 (verilog-auto))
10236	(t
10237	 (when (yes-or-no-p "AUTO statements not recomputed, do it now? ")
10238	   (verilog-auto))
10239	 ;; Don't ask again if didn't update
10240	 (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))))
10241  (when (not verilog-auto-star-save)
10242    (verilog-delete-auto-star-implicit))
10243  nil)	;; Always return nil -- we don't write the file ourselves
10244
10245(defun verilog-auto-read-locals ()
10246  "Return file local variable segment at bottom of file."
10247  (save-excursion
10248    (goto-char (point-max))
10249    (if (re-search-backward "Local Variables:" nil t)
10250	(buffer-substring-no-properties (point) (point-max))
10251      "")))
10252
10253(defun verilog-auto-reeval-locals (&optional force)
10254  "Read file local variable segment at bottom of file if it has changed.
10255If FORCE, always reread it."
10256  (let ((curlocal (verilog-auto-read-locals)))
10257    (when (or force (not (equal verilog-auto-last-file-locals curlocal)))
10258      (set (make-local-variable 'verilog-auto-last-file-locals) curlocal)
10259      ;; Note this may cause this function to be recursively invoked,
10260      ;; because hack-local-variables may call (verilog-mode)
10261      ;; The above when statement will prevent it from recursing forever.
10262      (hack-local-variables)
10263      t)))
10264
10265;;
10266;; Auto creation
10267;;
10268
10269(defun verilog-auto-arg-ports (sigs message indent-pt)
10270  "Print a list of ports for an AUTOINST.
10271Takes SIGS list, adds MESSAGE to front and inserts each at INDENT-PT."
10272  (when sigs
10273    (when verilog-auto-arg-sort
10274      (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
10275    (insert "\n")
10276    (indent-to indent-pt)
10277    (insert message)
10278    (insert "\n")
10279    (let ((space ""))
10280      (indent-to indent-pt)
10281      (while sigs
10282	(cond ((> (+ 2 (current-column) (length (verilog-sig-name (car sigs)))) fill-column)
10283	       (insert "\n")
10284	       (indent-to indent-pt))
10285	      (t (insert space)))
10286	(insert (verilog-sig-name (car sigs)) ",")
10287	(setq sigs (cdr sigs)
10288	      space " ")))))
10289
10290(defun verilog-auto-arg ()
10291  "Expand AUTOARG statements.
10292Replace the argument declarations at the beginning of the
10293module with ones automatically derived from input and output
10294statements.  This can be dangerous if the module is instantiated
10295using position-based connections, so use only name-based when
10296instantiating the resulting module.  Long lines are split based
10297on the `fill-column', see \\[set-fill-column].
10298
10299Limitations:
10300  Concatenation and outputting partial buses is not supported.
10301
10302  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
10303
10304For example:
10305
10306	module ExampArg (/*AUTOARG*/);
10307	  input i;
10308	  output o;
10309	endmodule
10310
10311Typing \\[verilog-auto] will make this into:
10312
10313	module ExampArg (/*AUTOARG*/
10314	  // Outputs
10315	  o,
10316	  // Inputs
10317	  i
10318	);
10319	  input i;
10320	  output o;
10321	endmodule
10322
10323The argument declarations may be printed in declaration order to best suit
10324order based instantiations, or alphabetically, based on the
10325`verilog-auto-arg-sort' variable.
10326
10327Any ports declared between the ( and /*AUTOARG*/ are presumed to be
10328predeclared and are not redeclared by AUTOARG.  AUTOARG will make a
10329conservative guess on adding a comma for the first signal, if you have
10330any ifdefs or complicated expressions before the AUTOARG you will need
10331to choose the comma yourself.
10332
10333Avoid declaring ports manually, as it makes code harder to maintain."
10334  (save-excursion
10335    (let* ((modi (verilog-modi-current))
10336	   (moddecls (verilog-modi-get-decls modi))
10337	   (skip-pins (aref (verilog-read-arg-pins) 0)))
10338      (verilog-repair-open-comma)
10339      (verilog-auto-arg-ports (verilog-signals-not-in
10340			       (verilog-decls-get-outputs moddecls)
10341			       skip-pins)
10342			      "// Outputs"
10343			      verilog-indent-level-declaration)
10344      (verilog-auto-arg-ports (verilog-signals-not-in
10345			       (verilog-decls-get-inouts moddecls)
10346			       skip-pins)
10347			      "// Inouts"
10348			      verilog-indent-level-declaration)
10349      (verilog-auto-arg-ports (verilog-signals-not-in
10350			       (verilog-decls-get-inputs moddecls)
10351			       skip-pins)
10352			      "// Inputs"
10353			      verilog-indent-level-declaration)
10354      (verilog-repair-close-comma)
10355      (unless (eq (char-before) ?/ )
10356	(insert "\n"))
10357      (indent-to verilog-indent-level-declaration))))
10358
10359(defun verilog-auto-inst-port-map (port-st)
10360  nil)
10361
10362(defvar vl-cell-type nil "See `verilog-auto-inst'.") ; Prevent compile warning
10363(defvar vl-cell-name nil "See `verilog-auto-inst'.") ; Prevent compile warning
10364(defvar vl-modport   nil "See `verilog-auto-inst'.") ; Prevent compile warning
10365(defvar vl-name  nil "See `verilog-auto-inst'.") ; Prevent compile warning
10366(defvar vl-width nil "See `verilog-auto-inst'.") ; Prevent compile warning
10367(defvar vl-dir   nil "See `verilog-auto-inst'.") ; Prevent compile warning
10368(defvar vl-bits  nil "See `verilog-auto-inst'.") ; Prevent compile warning
10369(defvar vl-mbits nil "See `verilog-auto-inst'.") ; Prevent compile warning
10370
10371(defun verilog-auto-inst-port (port-st indent-pt tpl-list tpl-num for-star par-values)
10372  "Print out an instantiation connection for this PORT-ST.
10373Insert to INDENT-PT, use template TPL-LIST.
10374@ are instantiation numbers, replaced with TPL-NUM.
10375@\"(expression @)\" are evaluated, with @ as a variable.
10376If FOR-STAR add comment it is a .* expansion.
10377If PAR-VALUES replace final strings with these parameter values."
10378  (let* ((port (verilog-sig-name port-st))
10379	 (tpl-ass (or (assoc port (car tpl-list))
10380		      (verilog-auto-inst-port-map port-st)))
10381	 ;; vl-* are documented for user use
10382	 (vl-name (verilog-sig-name port-st))
10383	 (vl-width (verilog-sig-width port-st))
10384	 (vl-modport (verilog-sig-modport port-st))
10385	 (vl-mbits (if (verilog-sig-multidim port-st)
10386                       (verilog-sig-multidim-string port-st) ""))
10387	 (vl-bits (if (or verilog-auto-inst-vector
10388			  (not (assoc port vector-skip-list))
10389			  (not (equal (verilog-sig-bits port-st)
10390				      (verilog-sig-bits (assoc port vector-skip-list)))))
10391		      (or (verilog-sig-bits port-st) "")
10392		    ""))
10393	 (case-fold-search nil)
10394	 (check-values par-values)
10395	 tpl-net)
10396    ;; Replace parameters in bit-width
10397    (when (and check-values
10398	       (not (equal vl-bits "")))
10399      (while check-values
10400	(setq vl-bits (verilog-string-replace-matches
10401		       (concat "\\<" (nth 0 (car check-values)) "\\>")
10402		       (concat "(" (nth 1 (car check-values)) ")")
10403		       t t vl-bits)
10404	      vl-mbits (verilog-string-replace-matches
10405			(concat "\\<" (nth 0 (car check-values)) "\\>")
10406			(concat "(" (nth 1 (car check-values)) ")")
10407			t t vl-mbits)
10408	      check-values (cdr check-values)))
10409      (setq vl-bits (verilog-simplify-range-expression vl-bits)
10410	    vl-mbits (verilog-simplify-range-expression vl-mbits)
10411	    vl-width (verilog-make-width-expression vl-bits))) ; Not in the loop for speed
10412    ;; Default net value if not found
10413    (setq tpl-net (concat port
10414			  (if vl-modport (concat "." vl-modport) "")
10415			  (if (verilog-sig-multidim port-st)
10416			      (concat "/*" vl-mbits vl-bits "*/")
10417			    (concat vl-bits))))
10418    ;; Find template
10419    (cond (tpl-ass	    ; Template of exact port name
10420	   (setq tpl-net (nth 1 tpl-ass)))
10421	  ((nth 1 tpl-list) ; Wildcards in template, search them
10422	   (let ((wildcards (nth 1 tpl-list)))
10423	     (while wildcards
10424	       (when (string-match (nth 0 (car wildcards)) port)
10425		 (setq tpl-ass (car wildcards)  ; so allow @ parsing
10426		       tpl-net (replace-match (nth 1 (car wildcards))
10427					      t nil port)))
10428	       (setq wildcards (cdr wildcards))))))
10429    ;; Parse Templated variable
10430    (when tpl-ass
10431      ;; Evaluate @"(lispcode)"
10432      (when (string-match "@\".*[^\\]\"" tpl-net)
10433	(while (string-match "@\"\\(\\([^\\\"]*\\(\\\\.\\)*\\)*\\)\"" tpl-net)
10434	  (setq tpl-net
10435		(concat
10436		 (substring tpl-net 0 (match-beginning 0))
10437		 (save-match-data
10438		   (let* ((expr (match-string 1 tpl-net))
10439			  (value
10440			   (progn
10441			     (setq expr (verilog-string-replace-matches "\\\\\"" "\"" nil nil expr))
10442			     (setq expr (verilog-string-replace-matches "@" tpl-num nil nil expr))
10443			     (prin1 (eval (car (read-from-string expr)))
10444				    (lambda (ch) ())))))
10445		     (if (numberp value) (setq value (number-to-string value)))
10446		     value))
10447		 (substring tpl-net (match-end 0))))))
10448      ;; Replace @ and [] magic variables in final output
10449      (setq tpl-net (verilog-string-replace-matches "@" tpl-num nil nil tpl-net))
10450      (setq tpl-net (verilog-string-replace-matches "\\[\\]" vl-bits nil nil tpl-net)))
10451    ;; Insert it
10452    (indent-to indent-pt)
10453    (insert "." port)
10454    (unless (and verilog-auto-inst-dot-name
10455		 (equal port tpl-net))
10456      (indent-to verilog-auto-inst-column)
10457      (insert "(" tpl-net ")"))
10458    (insert ",")
10459    (cond (tpl-ass
10460	   (verilog-read-auto-template-hit tpl-ass)
10461	   (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
10462			 verilog-auto-inst-column))
10463	   ;; verilog-insert requires the complete comment in one call - including the newline
10464	   (cond ((equal verilog-auto-inst-template-numbers `lhs)
10465		  (verilog-insert " // Templated"
10466				  " LHS: " (nth 0 tpl-ass)
10467				  "\n"))
10468		 (verilog-auto-inst-template-numbers
10469		  (verilog-insert " // Templated"
10470				  " T" (int-to-string (nth 2 tpl-ass))
10471				  " L" (int-to-string (nth 3 tpl-ass))
10472				  "\n"))
10473		 (t
10474		  (verilog-insert " // Templated\n"))))
10475	  (for-star
10476	   (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
10477			 verilog-auto-inst-column))
10478	   (verilog-insert " // Implicit .\*\n")) ;For some reason the . or * must be escaped...
10479	  (t
10480	   (insert "\n")))))
10481;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
10482;;(x "incom[@\"(+ (* 8 @) 7)\":@\"(* 8 @)\"]")
10483;;(x ".out (outgo[@\"(concat (+ (* 8 @) 7) \\\":\\\" ( * 8 @))\"]));")
10484
10485(defun verilog-auto-inst-port-list (sig-list indent-pt tpl-list tpl-num for-star par-values)
10486  "For `verilog-auto-inst' print a list of ports using `verilog-auto-inst-port'."
10487  (when verilog-auto-inst-sort
10488    (setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare)))
10489  (mapc (lambda (port)
10490	  (verilog-auto-inst-port port indent-pt
10491				  tpl-list tpl-num for-star par-values))
10492	sig-list))
10493
10494(defun verilog-auto-inst-first ()
10495  "Insert , etc before first ever port in this instant, as part of \\[verilog-auto-inst]."
10496  ;; Do we need a trailing comma?
10497  ;; There maybe an ifdef or something similar before us.  What a mess.  Thus
10498  ;; to avoid trouble we only insert on preceding ) or *.
10499  ;; Insert first port on new line
10500  (insert "\n")  ;; Must insert before search, so point will move forward if insert comma
10501  (save-excursion
10502    (verilog-re-search-backward-quick "[^ \t\n\f]" nil nil)
10503    (when (looking-at ")\\|\\*")  ;; Generally don't insert, unless we are fairly sure
10504      (forward-char 1)
10505      (insert ","))))
10506
10507(defun verilog-auto-star ()
10508  "Expand SystemVerilog .* pins, as part of \\[verilog-auto].
10509
10510If `verilog-auto-star-expand' is set, .* pins are treated if they were
10511AUTOINST statements, otherwise they are ignored.  For safety, Verilog mode
10512will also ignore any .* that are not last in your pin list (this prevents
10513it from deleting pins following the .* when it expands the AUTOINST.)
10514
10515On writing your file, unless `verilog-auto-star-save' is set, any
10516non-templated expanded pins will be removed.  You may do this at any time
10517with \\[verilog-delete-auto-star-implicit].
10518
10519If you are converting a module to use .* for the first time, you may wish
10520to use \\[verilog-inject-auto] and then replace the created AUTOINST with .*.
10521
10522See `verilog-auto-inst' for examples, templates, and more information."
10523  (when (verilog-auto-star-safe)
10524    (verilog-auto-inst)))
10525
10526(defun verilog-auto-inst ()
10527  "Expand AUTOINST statements, as part of \\[verilog-auto].
10528Replace the pin connections to an instantiation or interface
10529declaration with ones automatically derived from the module or
10530interface header of the instantiated item.
10531
10532If `verilog-auto-star-expand' is set, also expand SystemVerilog .* ports,
10533and delete them before saving unless `verilog-auto-star-save' is set.
10534See `verilog-auto-star' for more information.
10535
10536The pins are printed in declaration order or alphabetically,
10537based on the `verilog-auto-inst-sort' variable.
10538
10539Limitations:
10540  Module names must be resolvable to filenames by adding a
10541  `verilog-library-extensions', and being found in the same directory, or
10542  by changing the variable `verilog-library-flags' or
10543  `verilog-library-directories'.  Macros `modname are translated through the
10544  vh-{name} Emacs variable, if that is not found, it just ignores the `.
10545
10546  In templates you must have one signal per line, ending in a ), or ));,
10547  and have proper () nesting, including a final ); to end the template.
10548
10549  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
10550
10551  SystemVerilog multidimensional input/output has only experimental support.
10552
10553  SystemVerilog .name syntax is used if `verilog-auto-inst-dot-name' is set.
10554
10555  Parameters referenced by the instantiation will remain symbolic, unless
10556  `verilog-auto-inst-param-value' is set.
10557
10558  Gate primitives (and/or) may have AUTOINST for the purpose of
10559  AUTOWIRE declarations, etc.  Gates are the only case when
10560  position based connections are passed.
10561
10562For example, first take the submodule InstModule.v:
10563
10564	module InstModule (o,i);
10565	   output [31:0] o;
10566	   input i;
10567	   wire [31:0] o = {32{i}};
10568	endmodule
10569
10570This is then used in an upper level module:
10571
10572	module ExampInst (o,i);
10573	   output o;
10574	   input i;
10575	   InstModule instName
10576	     (/*AUTOINST*/);
10577	endmodule
10578
10579Typing \\[verilog-auto] will make this into:
10580
10581	module ExampInst (o,i);
10582	   output o;
10583	   input i;
10584	   InstModule instName
10585	     (/*AUTOINST*/
10586	      // Outputs
10587	      .ov	(ov[31:0]),
10588	      // Inputs
10589	      .i	(i));
10590	endmodule
10591
10592Where the list of inputs and outputs came from the inst module.
10593
10594Exceptions:
10595
10596  Unless you are instantiating a module multiple times, or the module is
10597  something trivial like an adder, DO NOT CHANGE SIGNAL NAMES ACROSS HIERARCHY.
10598  It just makes for unmaintainable code.  To sanitize signal names, try
10599  vrename from URL `http://www.veripool.org'.
10600
10601  When you need to violate this suggestion there are two ways to list
10602  exceptions, placing them before the AUTOINST, or using templates.
10603
10604  Any ports defined before the /*AUTOINST*/ are not included in the list of
10605  automatics.  This is similar to making a template as described below, but
10606  is restricted to simple connections just like you normally make.  Also note
10607  that any signals before the AUTOINST will only be picked up by AUTOWIRE if
10608  you have the appropriate // Input or // Output comment, and exactly the
10609  same line formatting as AUTOINST itself uses.
10610
10611	InstModule instName
10612          (// Inputs
10613	   .i		(my_i_dont_mess_with_it),
10614	   /*AUTOINST*/
10615	   // Outputs
10616	   .ov		(ov[31:0]));
10617
10618
10619Templates:
10620
10621  For multiple instantiations based upon a single template, create a
10622  commented out template:
10623
10624	/* InstModule AUTO_TEMPLATE (
10625		.sig3	(sigz[]),
10626		);
10627	*/
10628
10629  Templates go ABOVE the instantiation(s).  When an instantiation is
10630  expanded `verilog-mode' simply searches up for the closest template.
10631  Thus you can have multiple templates for the same module, just alternate
10632  between the template for an instantiation and the instantiation itself.
10633  (For backward compatibility if no template is found above, it
10634  will also look below, but do not use this behavior in new designs.)
10635
10636  The module name must be the same as the name of the module in the
10637  instantiation name, and the code \"AUTO_TEMPLATE\" must be in these exact
10638  words and capitalized.  Only signals that must be different for each
10639  instantiation need to be listed.
10640
10641  Inside a template, a [] in a connection name (with nothing else inside
10642  the brackets) will be replaced by the same bus subscript as it is being
10643  connected to, or the [] will be removed if it is a single bit signal.
10644  Generally it is a good idea to do this for all connections in a template,
10645  as then they will work for any width signal, and with AUTOWIRE.  See
10646  PTL_BUS becoming PTL_BUSNEW below.
10647
10648  If you have a complicated template, set `verilog-auto-inst-template-numbers'
10649  to see which regexps are matching.  Don't leave that mode set after
10650  debugging is completed though, it will result in lots of extra differences
10651  and merge conflicts.
10652
10653  Setting `verilog-auto-template-warn-unused' will report errors
10654  if any template lines are unused.
10655
10656  For example:
10657
10658	/* InstModule AUTO_TEMPLATE (
10659		.ptl_bus	(ptl_busnew[]),
10660		);
10661	*/
10662	InstModule ms2m (/*AUTOINST*/);
10663
10664  Typing \\[verilog-auto] will make this into:
10665
10666	InstModule ms2m (/*AUTOINST*/
10667	    // Outputs
10668	    .NotInTemplate	(NotInTemplate),
10669	    .ptl_bus		(ptl_busnew[3:0]),  // Templated
10670	    ....
10671
10672
10673Multiple Module Templates:
10674
10675  The same template lines can be applied to multiple modules with
10676  the syntax as follows:
10677
10678	/* InstModuleA AUTO_TEMPLATE
10679	   InstModuleB AUTO_TEMPLATE
10680	   InstModuleC AUTO_TEMPLATE
10681	   InstModuleD AUTO_TEMPLATE (
10682		.ptl_bus	(ptl_busnew[]),
10683		);
10684	*/
10685
10686  Note there is only one AUTO_TEMPLATE opening parenthesis.
10687
10688@ Templates:
10689
10690  It is common to instantiate a cell multiple times, so templates make it
10691  trivial to substitute part of the cell name into the connection name.
10692
10693	/* InstName AUTO_TEMPLATE <optional \"REGEXP\"> (
10694		.sig1	(sigx[@]),
10695		.sig2	(sigy[@\"(% (+ 1 @) 4)\"]),
10696		);
10697	*/
10698
10699  If no regular expression is provided immediately after the AUTO_TEMPLATE
10700  keyword, then the @ character in any connection names will be replaced
10701  with the instantiation number; the first digits found in the cell's
10702  instantiation name.
10703
10704  If a regular expression is provided, the @ character will be replaced
10705  with the first \(\) grouping that matches against the cell name.  Using a
10706  regexp of \"\\([0-9]+\\)\" provides identical values for @ as when no
10707  regexp is provided.  If you use multiple layers of parenthesis,
10708  \"test\\([^0-9]+\\)_\\([0-9]+\\)\" would replace @ with non-number
10709  characters after test and before _, whereas
10710  \"\\(test\\([a-z]+\\)_\\([0-9]+\\)\\)\" would replace @ with the entire
10711  match.
10712
10713  For example:
10714
10715	/* InstModule AUTO_TEMPLATE (
10716		.ptl_mapvalidx		(ptl_mapvalid[@]),
10717		.ptl_mapvalidp1x	(ptl_mapvalid[@\"(% (+ 1 @) 4)\"]),
10718		);
10719	*/
10720	InstModule ms2m (/*AUTOINST*/);
10721
10722  Typing \\[verilog-auto] will make this into:
10723
10724	InstModule ms2m (/*AUTOINST*/
10725	    // Outputs
10726	    .ptl_mapvalidx		(ptl_mapvalid[2]),
10727	    .ptl_mapvalidp1x		(ptl_mapvalid[3]));
10728
10729  Note the @ character was replaced with the 2 from \"ms2m\".
10730
10731  Alternatively, using a regular expression for @:
10732
10733	/* InstModule AUTO_TEMPLATE \"_\\([a-z]+\\)\" (
10734		.ptl_mapvalidx		(@_ptl_mapvalid),
10735		.ptl_mapvalidp1x	(ptl_mapvalid_@),
10736		);
10737	*/
10738	InstModule ms2_FOO (/*AUTOINST*/);
10739	InstModule ms2_BAR (/*AUTOINST*/);
10740
10741  Typing \\[verilog-auto] will make this into:
10742
10743	InstModule ms2_FOO (/*AUTOINST*/
10744	    // Outputs
10745	    .ptl_mapvalidx		(FOO_ptl_mapvalid),
10746	    .ptl_mapvalidp1x		(ptl_mapvalid_FOO));
10747	InstModule ms2_BAR (/*AUTOINST*/
10748	    // Outputs
10749	    .ptl_mapvalidx		(BAR_ptl_mapvalid),
10750	    .ptl_mapvalidp1x		(ptl_mapvalid_BAR));
10751
10752
10753Regexp Templates:
10754
10755  A template entry of the form
10756
10757	    .pci_req\\([0-9]+\\)_l	(pci_req_jtag_[\\1]),
10758
10759  will apply an Emacs style regular expression search for any port beginning
10760  in pci_req followed by numbers and ending in _l and connecting that to
10761  the pci_req_jtag_[] net, with the bus subscript coming from what matches
10762  inside the first set of \\( \\).  Thus pci_req2_l becomes pci_req_jtag_[2].
10763
10764  Since \\([0-9]+\\) is so common and ugly to read, a @ in the port name
10765  does the same thing.  (Note a @ in the connection/replacement text is
10766  completely different -- still use \\1 there!)  Thus this is the same as
10767  the above template:
10768
10769	    .pci_req@_l		(pci_req_jtag_[\\1]),
10770
10771  Here's another example to remove the _l, useful when naming conventions
10772  specify _ alone to mean active low.  Note the use of [] to keep the bus
10773  subscript:
10774
10775	    .\\(.*\\)_l		(\\1_[]),
10776
10777Lisp Templates:
10778
10779  First any regular expression template is expanded.
10780
10781  If the syntax @\"( ... )\" is found in a connection, the expression in
10782  quotes will be evaluated as a Lisp expression, with @ replaced by the
10783  instantiation number.  The MAPVALIDP1X example above would put @+1 modulo
10784  4 into the brackets.  Quote all double-quotes inside the expression with
10785  a leading backslash (\\\"...\\\"); or if the Lisp template is also a
10786  regexp template backslash the backslash quote (\\\\\"...\\\\\").
10787
10788  There are special variables defined that are useful in these
10789  Lisp functions:
10790
10791	vl-name        Name portion of the input/output port.
10792	vl-bits        Bus bits portion of the input/output port ('[2:0]').
10793	vl-mbits       Multidimensional array bits for port ('[2:0][3:0]').
10794	vl-width       Width of the input/output port ('3' for [2:0]).
10795                       May be a (...) expression if bits isn't a constant.
10796	vl-dir         Direction of the pin input/output/inout/interface.
10797	vl-modport     The modport, if an interface with a modport.
10798	vl-cell-type   Module name/type of the cell ('InstModule').
10799	vl-cell-name   Instance name of the cell ('instName').
10800
10801  Normal Lisp variables may be used in expressions.  See
10802  `verilog-read-defines' which can set vh-{definename} variables for use
10803  here.  Also, any comments of the form:
10804
10805	/*AUTO_LISP(setq foo 1)*/
10806
10807  will evaluate any Lisp expression inside the parenthesis between the
10808  beginning of the buffer and the point of the AUTOINST.  This allows
10809  functions to be defined or variables to be changed between instantiations.
10810  (See also `verilog-auto-insert-lisp' if you want the output from your
10811  lisp function to be inserted.)
10812
10813  Note that when using lisp expressions errors may occur when @ is not a
10814  number; you may need to use the standard Emacs Lisp functions
10815  `number-to-string' and `string-to-number'.
10816
10817  After the evaluation is completed, @ substitution and [] substitution
10818  occur.
10819
10820For more information see the \\[verilog-faq] and forums at URL
10821`http://www.veripool.org'."
10822  (save-excursion
10823    ;; Find beginning
10824    (let* ((pt (point))
10825	   (for-star (save-excursion (backward-char 2) (looking-at "\\.\\*")))
10826	   (indent-pt (save-excursion (verilog-backward-open-paren)
10827				      (1+ (current-column))))
10828	   (verilog-auto-inst-column (max verilog-auto-inst-column
10829					  (+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
10830	   (modi (verilog-modi-current))
10831	   (moddecls (verilog-modi-get-decls modi))
10832	   (vector-skip-list (unless verilog-auto-inst-vector
10833			       (verilog-decls-get-signals moddecls)))
10834	   submod submodi submoddecls
10835	   inst skip-pins tpl-list tpl-num did-first par-values)
10836
10837      ;; Find module name that is instantiated
10838      (setq submod  (verilog-read-inst-module)
10839	    inst (verilog-read-inst-name)
10840	    vl-cell-type submod
10841	    vl-cell-name inst
10842	    skip-pins (aref (verilog-read-inst-pins) 0))
10843
10844      ;; Parse any AUTO_LISP() before here
10845      (verilog-read-auto-lisp (point-min) pt)
10846
10847      ;; Read parameters (after AUTO_LISP)
10848      (setq par-values (and verilog-auto-inst-param-value
10849			    (verilog-read-inst-param-value)))
10850
10851      ;; Lookup position, etc of submodule
10852      ;; Note this may raise an error
10853      (when (and (not (member submod verilog-gate-keywords))
10854		 (setq submodi (verilog-modi-lookup submod t)))
10855	(setq submoddecls (verilog-modi-get-decls submodi))
10856	;; If there's a number in the instantiation, it may be an argument to the
10857	;; automatic variable instantiation program.
10858	(let* ((tpl-info (verilog-read-auto-template submod))
10859	       (tpl-regexp (aref tpl-info 0)))
10860	  (setq tpl-num (if (string-match tpl-regexp inst)
10861			    (match-string 1 inst)
10862			  "")
10863		tpl-list (aref tpl-info 1)))
10864	;; Find submodule's signals and dump
10865	(let ((sig-list (and (equal (verilog-modi-get-type submodi) "interface")
10866			     (verilog-signals-not-in
10867			      (verilog-decls-get-vars submoddecls)
10868			      skip-pins)))
10869	      (vl-dir "interfaced"))
10870	  (when (and sig-list
10871		     verilog-auto-inst-interfaced-ports)
10872	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
10873            ;; Note these are searched for in verilog-read-sub-decls.
10874	    (verilog-insert-indent "// Interfaced\n")
10875	    (verilog-auto-inst-port-list sig-list indent-pt
10876					 tpl-list tpl-num for-star par-values)))
10877	(let ((sig-list (verilog-signals-not-in
10878			 (verilog-decls-get-interfaces submoddecls)
10879			 skip-pins))
10880	      (vl-dir "interface"))
10881	  (when sig-list
10882	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
10883            ;; Note these are searched for in verilog-read-sub-decls.
10884	    (verilog-insert-indent "// Interfaces\n")
10885	    (verilog-auto-inst-port-list sig-list indent-pt
10886					 tpl-list tpl-num for-star par-values)))
10887	(let ((sig-list (verilog-signals-not-in
10888			 (verilog-decls-get-outputs submoddecls)
10889			 skip-pins))
10890	      (vl-dir "output"))
10891	  (when sig-list
10892	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
10893	    (verilog-insert-indent "// Outputs\n")
10894	    (verilog-auto-inst-port-list sig-list indent-pt
10895					 tpl-list tpl-num for-star par-values)))
10896	(let ((sig-list (verilog-signals-not-in
10897			 (verilog-decls-get-inouts submoddecls)
10898			 skip-pins))
10899	      (vl-dir "inout"))
10900	  (when sig-list
10901	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
10902	    (verilog-insert-indent "// Inouts\n")
10903	    (verilog-auto-inst-port-list sig-list indent-pt
10904					 tpl-list tpl-num for-star par-values)))
10905	(let ((sig-list (verilog-signals-not-in
10906			 (verilog-decls-get-inputs submoddecls)
10907			 skip-pins))
10908	      (vl-dir "input"))
10909	  (when sig-list
10910	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
10911	    (verilog-insert-indent "// Inputs\n")
10912	    (verilog-auto-inst-port-list sig-list indent-pt
10913					 tpl-list tpl-num for-star par-values)))
10914	;; Kill extra semi
10915	(save-excursion
10916	  (cond (did-first
10917		 (re-search-backward "," pt t)
10918		 (delete-char 1)
10919		 (insert ");")
10920		 (search-forward "\n")	;; Added by inst-port
10921		 (delete-char -1)
10922		 (if (search-forward ")" nil t) ;; From user, moved up a line
10923		     (delete-char -1))
10924		 (if (search-forward ";" nil t) ;; Don't error if user had syntax error and forgot it
10925		     (delete-char -1)))))))))
10926
10927(defun verilog-auto-inst-param ()
10928  "Expand AUTOINSTPARAM statements, as part of \\[verilog-auto].
10929Replace the parameter connections to an instantiation with ones
10930automatically derived from the module header of the instantiated netlist.
10931
10932See \\[verilog-auto-inst] for limitations, and templates to customize the
10933output.
10934
10935For example, first take the submodule InstModule.v:
10936
10937	module InstModule (o,i);
10938	   parameter PAR;
10939	endmodule
10940
10941This is then used in an upper level module:
10942
10943	module ExampInst (o,i);
10944	   parameter PAR;
10945	   InstModule #(/*AUTOINSTPARAM*/)
10946		instName (/*AUTOINST*/);
10947	endmodule
10948
10949Typing \\[verilog-auto] will make this into:
10950
10951	module ExampInst (o,i);
10952	   output o;
10953	   input i;
10954	   InstModule #(/*AUTOINSTPARAM*/
10955		        // Parameters
10956		        .PAR	(PAR));
10957		instName (/*AUTOINST*/);
10958	endmodule
10959
10960Where the list of parameter connections come from the inst module.
10961
10962Templates:
10963
10964  You can customize the parameter connections using AUTO_TEMPLATEs,
10965  just as you would with \\[verilog-auto-inst]."
10966  (save-excursion
10967    ;; Find beginning
10968    (let* ((pt (point))
10969	   (indent-pt (save-excursion (verilog-backward-open-paren)
10970				      (1+ (current-column))))
10971	   (verilog-auto-inst-column (max verilog-auto-inst-column
10972					  (+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
10973	   (modi (verilog-modi-current))
10974	   (moddecls (verilog-modi-get-decls modi))
10975	   (vector-skip-list (unless verilog-auto-inst-vector
10976			       (verilog-decls-get-signals moddecls)))
10977	   submod submodi submoddecls
10978	   inst skip-pins tpl-list tpl-num did-first)
10979      ;; Find module name that is instantiated
10980      (setq submod (save-excursion
10981		     ;; Get to the point where AUTOINST normally is to read the module
10982		     (verilog-re-search-forward-quick "[(;]" nil nil)
10983		     (verilog-read-inst-module))
10984	    inst   (save-excursion
10985		     ;; Get to the point where AUTOINST normally is to read the module
10986		     (verilog-re-search-forward-quick "[(;]" nil nil)
10987		     (verilog-read-inst-name))
10988	    vl-cell-type submod
10989	    vl-cell-name inst
10990	    skip-pins (aref (verilog-read-inst-pins) 0))
10991
10992      ;; Parse any AUTO_LISP() before here
10993      (verilog-read-auto-lisp (point-min) pt)
10994
10995      ;; Lookup position, etc of submodule
10996      ;; Note this may raise an error
10997      (when (setq submodi (verilog-modi-lookup submod t))
10998	(setq submoddecls (verilog-modi-get-decls submodi))
10999	;; If there's a number in the instantiation, it may be an argument to the
11000	;; automatic variable instantiation program.
11001	(let* ((tpl-info (verilog-read-auto-template submod))
11002	       (tpl-regexp (aref tpl-info 0)))
11003	  (setq tpl-num (if (string-match tpl-regexp inst)
11004			    (match-string 1 inst)
11005			  "")
11006		tpl-list (aref tpl-info 1)))
11007	;; Find submodule's signals and dump
11008	(let ((sig-list (verilog-signals-not-in
11009			 (verilog-decls-get-gparams submoddecls)
11010			 skip-pins))
11011	      (vl-dir "parameter"))
11012	  (when sig-list
11013	    (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
11014            ;; Note these are searched for in verilog-read-sub-decls.
11015	    (verilog-insert-indent "// Parameters\n")
11016	    (verilog-auto-inst-port-list sig-list indent-pt
11017					 tpl-list tpl-num nil nil)))
11018	;; Kill extra semi
11019	(save-excursion
11020	  (cond (did-first
11021		 (re-search-backward "," pt t)
11022		 (delete-char 1)
11023		 (insert ")")
11024		 (search-forward "\n")	;; Added by inst-port
11025		 (delete-char -1)
11026		 (if (search-forward ")" nil t) ;; From user, moved up a line
11027		     (delete-char -1)))))))))
11028
11029(defun verilog-auto-reg ()
11030  "Expand AUTOREG statements, as part of \\[verilog-auto].
11031Make reg statements for any output that isn't already declared,
11032and isn't a wire output from a block.  `verilog-auto-wire-type'
11033may be used to change the datatype of the declarations.
11034
11035Limitations:
11036  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11037
11038  This does NOT work on memories, declare those yourself.
11039
11040An example:
11041
11042	module ExampReg (o,i);
11043	   output o;
11044	   input i;
11045	   /*AUTOREG*/
11046	   always o = i;
11047	endmodule
11048
11049Typing \\[verilog-auto] will make this into:
11050
11051	module ExampReg (o,i);
11052	   output o;
11053	   input i;
11054	   /*AUTOREG*/
11055	   // Beginning of automatic regs (for this module's undeclared outputs)
11056	   reg		o;
11057	   // End of automatics
11058	   always o = i;
11059	endmodule"
11060  (save-excursion
11061    ;; Point must be at insertion point.
11062    (let* ((indent-pt (current-indentation))
11063	   (modi (verilog-modi-current))
11064	   (moddecls (verilog-modi-get-decls modi))
11065	   (modsubdecls (verilog-modi-get-sub-decls modi))
11066	   (sig-list (verilog-signals-not-in
11067		      (verilog-decls-get-outputs moddecls)
11068		      (append (verilog-signals-with ;; ignore typed signals
11069			       'verilog-sig-type
11070			       (verilog-decls-get-outputs moddecls))
11071			      (verilog-decls-get-vars moddecls)
11072			      (verilog-decls-get-assigns moddecls)
11073			      (verilog-decls-get-consts moddecls)
11074			      (verilog-decls-get-gparams moddecls)
11075			      (verilog-subdecls-get-interfaced modsubdecls)
11076			      (verilog-subdecls-get-outputs modsubdecls)
11077			      (verilog-subdecls-get-inouts modsubdecls)))))
11078      (when sig-list
11079	(verilog-forward-or-insert-line)
11080	(verilog-insert-indent "// Beginning of automatic regs (for this module's undeclared outputs)\n")
11081	(verilog-insert-definition modi sig-list "reg" indent-pt nil)
11082	(verilog-insert-indent "// End of automatics\n")))))
11083
11084(defun verilog-auto-reg-input ()
11085  "Expand AUTOREGINPUT statements, as part of \\[verilog-auto].
11086Make reg statements instantiation inputs that aren't already declared.
11087This is useful for making a top level shell for testing the module that is
11088to be instantiated.
11089
11090Limitations:
11091  This ONLY detects inputs of AUTOINSTants (see `verilog-read-sub-decls').
11092
11093  This does NOT work on memories, declare those yourself.
11094
11095An example (see `verilog-auto-inst' for what else is going on here):
11096
11097	module ExampRegInput (o,i);
11098	   output o;
11099	   input i;
11100	   /*AUTOREGINPUT*/
11101           InstModule instName
11102             (/*AUTOINST*/);
11103	endmodule
11104
11105Typing \\[verilog-auto] will make this into:
11106
11107	module ExampRegInput (o,i);
11108	   output o;
11109	   input i;
11110	   /*AUTOREGINPUT*/
11111	   // Beginning of automatic reg inputs (for undeclared ...
11112	   reg [31:0]		iv;	// From inst of inst.v
11113	   // End of automatics
11114	   InstModule instName
11115             (/*AUTOINST*/
11116	      // Outputs
11117	      .o		(o[31:0]),
11118	      // Inputs
11119	      .iv		(iv));
11120	endmodule"
11121  (save-excursion
11122    ;; Point must be at insertion point.
11123    (let* ((indent-pt (current-indentation))
11124	   (modi (verilog-modi-current))
11125	   (moddecls (verilog-modi-get-decls modi))
11126	   (modsubdecls (verilog-modi-get-sub-decls modi))
11127	   (sig-list (verilog-signals-combine-bus
11128		      (verilog-signals-not-in
11129		       (append (verilog-subdecls-get-inputs modsubdecls)
11130			       (verilog-subdecls-get-inouts modsubdecls))
11131		       (append (verilog-decls-get-signals moddecls)
11132			       (verilog-decls-get-assigns moddecls))))))
11133      (when sig-list
11134	(verilog-forward-or-insert-line)
11135	(verilog-insert-indent "// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)\n")
11136	(verilog-insert-definition modi sig-list "reg" indent-pt nil)
11137	(verilog-insert-indent "// End of automatics\n")))))
11138
11139(defun verilog-auto-logic-setup ()
11140  "Prepare variables due to AUTOLOGIC."
11141  (unless verilog-auto-wire-type
11142    (set (make-local-variable 'verilog-auto-wire-type)
11143	 "logic")))
11144
11145(defun verilog-auto-logic ()
11146  "Expand AUTOLOGIC statements, as part of \\[verilog-auto].
11147Make wire statements using the SystemVerilog logic keyword.
11148This is currently equivalent to:
11149
11150    /*AUTOWIRE*/
11151
11152with the below at the bottom of the file
11153
11154    // Local Variables:
11155    // verilog-auto-logic-type:\"logic\"
11156    // End:
11157
11158In the future AUTOLOGIC may declare additional identifiers,
11159while AUTOWIRE will not."
11160  (save-excursion
11161    (verilog-auto-logic-setup)
11162    (verilog-auto-wire)))
11163
11164(defun verilog-auto-wire ()
11165  "Expand AUTOWIRE statements, as part of \\[verilog-auto].
11166Make wire statements for instantiations outputs that aren't
11167already declared.  `verilog-auto-wire-type' may be used to change
11168the datatype of the declarations.
11169
11170Limitations:
11171  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls'),
11172  and all buses must have widths, such as those from AUTOINST, or using []
11173  in AUTO_TEMPLATEs.
11174
11175  This does NOT work on memories or SystemVerilog .name connections,
11176  declare those yourself.
11177
11178  Verilog mode will add \"Couldn't Merge\" comments to signals it cannot
11179  determine how to bus together.  This occurs when you have ports with
11180  non-numeric or non-sequential bus subscripts.  If Verilog mode
11181  mis-guessed, you'll have to declare them yourself.
11182
11183An example (see `verilog-auto-inst' for what else is going on here):
11184
11185	module ExampWire (o,i);
11186	   output o;
11187	   input i;
11188	   /*AUTOWIRE*/
11189           InstModule instName
11190	     (/*AUTOINST*/);
11191	endmodule
11192
11193Typing \\[verilog-auto] will make this into:
11194
11195	module ExampWire (o,i);
11196	   output o;
11197	   input i;
11198	   /*AUTOWIRE*/
11199	   // Beginning of automatic wires
11200	   wire [31:0]		ov;	// From inst of inst.v
11201	   // End of automatics
11202	   InstModule instName
11203	     (/*AUTOINST*/
11204	      // Outputs
11205	      .ov	(ov[31:0]),
11206	      // Inputs
11207	      .i	(i));
11208	   wire o = | ov;
11209	endmodule"
11210  (save-excursion
11211    ;; Point must be at insertion point.
11212    (let* ((indent-pt (current-indentation))
11213	   (modi (verilog-modi-current))
11214	   (moddecls (verilog-modi-get-decls modi))
11215	   (modsubdecls (verilog-modi-get-sub-decls modi))
11216	   (sig-list (verilog-signals-combine-bus
11217		      (verilog-signals-not-in
11218		       (append (verilog-subdecls-get-outputs modsubdecls)
11219			       (verilog-subdecls-get-inouts modsubdecls))
11220		       (verilog-decls-get-signals moddecls)))))
11221      (when sig-list
11222	(verilog-forward-or-insert-line)
11223	(verilog-insert-indent "// Beginning of automatic wires (for undeclared instantiated-module outputs)\n")
11224	(verilog-insert-definition modi sig-list "wire" indent-pt nil)
11225	(verilog-insert-indent "// End of automatics\n")
11226	;; We used to optionally call verilog-pretty-declarations and
11227	;; verilog-pretty-expr here, but it's too slow on huge modules,
11228	;; plus makes everyone's module change. Finally those call
11229	;; syntax-ppss which is broken when change hooks are disabled.
11230	))))
11231
11232(defun verilog-auto-output (&optional with-params)
11233  "Expand AUTOOUTPUT statements, as part of \\[verilog-auto].
11234Make output statements for any output signal from an /*AUTOINST*/ that
11235isn't an input to another AUTOINST.  This is useful for modules which
11236only instantiate other modules.
11237
11238Limitations:
11239  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11240
11241  If placed inside the parenthesis of a module declaration, it creates
11242  Verilog 2001 style, else uses Verilog 1995 style.
11243
11244  If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
11245  instantiation, all bets are off.  (For example due to an AUTO_TEMPLATE).
11246
11247  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
11248
11249  Signals matching `verilog-auto-output-ignore-regexp' are not included.
11250
11251An example (see `verilog-auto-inst' for what else is going on here):
11252
11253	module ExampOutput (ov,i);
11254	   input i;
11255	   /*AUTOOUTPUT*/
11256	   InstModule instName
11257	     (/*AUTOINST*/);
11258	endmodule
11259
11260Typing \\[verilog-auto] will make this into:
11261
11262	module ExampOutput (ov,i);
11263	   input i;
11264	   /*AUTOOUTPUT*/
11265	   // Beginning of automatic outputs (from unused autoinst outputs)
11266	   output [31:0]	ov;	// From inst of inst.v
11267	   // End of automatics
11268	   InstModule instName
11269	     (/*AUTOINST*/
11270	      // Outputs
11271	      .ov	(ov[31:0]),
11272	      // Inputs
11273	      .i	(i));
11274	endmodule
11275
11276You may also provide an optional regular expression, in which case only
11277signals matching the regular expression will be included.  For example the
11278same expansion will result from only extracting outputs starting with ov:
11279
11280	   /*AUTOOUTPUT(\"^ov\")*/"
11281  (save-excursion
11282    ;; Point must be at insertion point.
11283    (let* ((indent-pt (current-indentation))
11284	   (regexp (and with-params
11285			(nth 0 (verilog-read-auto-params 1))))
11286	   (v2k  (verilog-in-paren-quick))
11287	   (modi (verilog-modi-current))
11288	   (moddecls (verilog-modi-get-decls modi))
11289	   (modsubdecls (verilog-modi-get-sub-decls modi))
11290	   (sig-list (verilog-signals-not-in
11291		      (verilog-subdecls-get-outputs modsubdecls)
11292		      (append (verilog-decls-get-outputs moddecls)
11293			      (verilog-decls-get-inouts moddecls)
11294			      (verilog-subdecls-get-inputs modsubdecls)
11295			      (verilog-subdecls-get-inouts modsubdecls)))))
11296      (when regexp
11297	(setq sig-list (verilog-signals-matching-regexp
11298			sig-list regexp)))
11299      (setq sig-list (verilog-signals-not-matching-regexp
11300		      sig-list verilog-auto-output-ignore-regexp))
11301      (verilog-forward-or-insert-line)
11302      (when v2k (verilog-repair-open-comma))
11303      (when sig-list
11304	(verilog-insert-indent "// Beginning of automatic outputs (from unused autoinst outputs)\n")
11305	(verilog-insert-definition modi sig-list "output" indent-pt v2k)
11306	(verilog-insert-indent "// End of automatics\n"))
11307      (when v2k (verilog-repair-close-comma)))))
11308
11309(defun verilog-auto-output-every ()
11310  "Expand AUTOOUTPUTEVERY statements, as part of \\[verilog-auto].
11311Make output statements for any signals that aren't primary inputs or
11312outputs already.  This makes every signal in the design an output.  This is
11313useful to get Synopsys to preserve every signal in the design, since it
11314won't optimize away the outputs.
11315
11316An example:
11317
11318	module ExampOutputEvery (o,i,tempa,tempb);
11319	   output o;
11320	   input i;
11321	   /*AUTOOUTPUTEVERY*/
11322	   wire tempa = i;
11323	   wire tempb = tempa;
11324	   wire o = tempb;
11325	endmodule
11326
11327Typing \\[verilog-auto] will make this into:
11328
11329	module ExampOutputEvery (o,i,tempa,tempb);
11330	   output o;
11331	   input i;
11332	   /*AUTOOUTPUTEVERY*/
11333	   // Beginning of automatic outputs (every signal)
11334	   output	tempb;
11335	   output	tempa;
11336	   // End of automatics
11337	   wire tempa = i;
11338	   wire tempb = tempa;
11339	   wire o = tempb;
11340	endmodule"
11341  (save-excursion
11342    ;;Point must be at insertion point
11343    (let* ((indent-pt (current-indentation))
11344	   (v2k  (verilog-in-paren-quick))
11345	   (modi (verilog-modi-current))
11346	   (moddecls (verilog-modi-get-decls modi))
11347	   (sig-list (verilog-signals-combine-bus
11348		      (verilog-signals-not-in
11349		       (verilog-decls-get-signals moddecls)
11350		       (verilog-decls-get-ports moddecls)))))
11351      (verilog-forward-or-insert-line)
11352      (when v2k (verilog-repair-open-comma))
11353      (when sig-list
11354	(verilog-insert-indent "// Beginning of automatic outputs (every signal)\n")
11355	(verilog-insert-definition modi sig-list "output" indent-pt v2k)
11356	(verilog-insert-indent "// End of automatics\n"))
11357      (when v2k (verilog-repair-close-comma)))))
11358
11359(defun verilog-auto-input (&optional with-params)
11360  "Expand AUTOINPUT statements, as part of \\[verilog-auto].
11361Make input statements for any input signal into an /*AUTOINST*/ that
11362isn't declared elsewhere inside the module.  This is useful for modules which
11363only instantiate other modules.
11364
11365Limitations:
11366  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11367
11368  If placed inside the parenthesis of a module declaration, it creates
11369  Verilog 2001 style, else uses Verilog 1995 style.
11370
11371  If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
11372  instantiation, all bets are off.  (For example due to an AUTO_TEMPLATE).
11373
11374  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
11375
11376  Signals matching `verilog-auto-input-ignore-regexp' are not included.
11377
11378An example (see `verilog-auto-inst' for what else is going on here):
11379
11380	module ExampInput (ov,i);
11381	   output [31:0] ov;
11382	   /*AUTOINPUT*/
11383	   InstModule instName
11384	     (/*AUTOINST*/);
11385	endmodule
11386
11387Typing \\[verilog-auto] will make this into:
11388
11389	module ExampInput (ov,i);
11390	   output [31:0] ov;
11391	   /*AUTOINPUT*/
11392	   // Beginning of automatic inputs (from unused autoinst inputs)
11393	   input	i;	// From inst of inst.v
11394	   // End of automatics
11395	   InstModule instName
11396	     (/*AUTOINST*/
11397	      // Outputs
11398	      .ov	(ov[31:0]),
11399	      // Inputs
11400	      .i	(i));
11401	endmodule
11402
11403You may also provide an optional regular expression, in which case only
11404signals matching the regular expression will be included.  For example the
11405same expansion will result from only extracting inputs starting with i:
11406
11407	   /*AUTOINPUT(\"^i\")*/"
11408  (save-excursion
11409    (let* ((indent-pt (current-indentation))
11410	   (regexp (and with-params
11411			(nth 0 (verilog-read-auto-params 1))))
11412	   (v2k  (verilog-in-paren-quick))
11413	   (modi (verilog-modi-current))
11414	   (moddecls (verilog-modi-get-decls modi))
11415	   (modsubdecls (verilog-modi-get-sub-decls modi))
11416	   (sig-list (verilog-signals-not-in
11417		      (verilog-subdecls-get-inputs modsubdecls)
11418		      (append (verilog-decls-get-inputs moddecls)
11419			      (verilog-decls-get-inouts moddecls)
11420			      (verilog-decls-get-vars moddecls)
11421			      (verilog-decls-get-consts moddecls)
11422			      (verilog-decls-get-gparams moddecls)
11423			      (verilog-subdecls-get-interfaced modsubdecls)
11424			      (verilog-subdecls-get-outputs modsubdecls)
11425			      (verilog-subdecls-get-inouts modsubdecls)))))
11426      (when regexp
11427	(setq sig-list (verilog-signals-matching-regexp
11428			sig-list regexp)))
11429      (setq sig-list (verilog-signals-not-matching-regexp
11430		      sig-list verilog-auto-input-ignore-regexp))
11431      (verilog-forward-or-insert-line)
11432      (when v2k (verilog-repair-open-comma))
11433      (when sig-list
11434	(verilog-insert-indent "// Beginning of automatic inputs (from unused autoinst inputs)\n")
11435	(verilog-insert-definition modi sig-list "input" indent-pt v2k)
11436	(verilog-insert-indent "// End of automatics\n"))
11437      (when v2k (verilog-repair-close-comma)))))
11438
11439(defun verilog-auto-inout (&optional with-params)
11440  "Expand AUTOINOUT statements, as part of \\[verilog-auto].
11441Make inout statements for any inout signal in an /*AUTOINST*/ that
11442isn't declared elsewhere inside the module.
11443
11444Limitations:
11445  This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11446
11447  If placed inside the parenthesis of a module declaration, it creates
11448  Verilog 2001 style, else uses Verilog 1995 style.
11449
11450  If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
11451  instantiation, all bets are off.  (For example due to an AUTO_TEMPLATE).
11452
11453  Typedefs must match `verilog-typedef-regexp', which is disabled by default.
11454
11455  Signals matching `verilog-auto-inout-ignore-regexp' are not included.
11456
11457An example (see `verilog-auto-inst' for what else is going on here):
11458
11459	module ExampInout (ov,i);
11460	   input i;
11461	   /*AUTOINOUT*/
11462	   InstModule instName
11463	     (/*AUTOINST*/);
11464	endmodule
11465
11466Typing \\[verilog-auto] will make this into:
11467
11468	module ExampInout (ov,i);
11469	   input i;
11470	   /*AUTOINOUT*/
11471	   // Beginning of automatic inouts (from unused autoinst inouts)
11472	   inout [31:0]	ov;	// From inst of inst.v
11473	   // End of automatics
11474	   InstModule instName
11475	     (/*AUTOINST*/
11476	      // Inouts
11477	      .ov	(ov[31:0]),
11478	      // Inputs
11479	      .i	(i));
11480	endmodule
11481
11482You may also provide an optional regular expression, in which case only
11483signals matching the regular expression will be included.  For example the
11484same expansion will result from only extracting inouts starting with i:
11485
11486	   /*AUTOINOUT(\"^i\")*/"
11487  (save-excursion
11488    ;; Point must be at insertion point.
11489    (let* ((indent-pt (current-indentation))
11490	   (regexp (and with-params
11491			(nth 0 (verilog-read-auto-params 1))))
11492	   (v2k  (verilog-in-paren-quick))
11493	   (modi (verilog-modi-current))
11494	   (moddecls (verilog-modi-get-decls modi))
11495	   (modsubdecls (verilog-modi-get-sub-decls modi))
11496	   (sig-list (verilog-signals-not-in
11497		      (verilog-subdecls-get-inouts modsubdecls)
11498		      (append (verilog-decls-get-outputs moddecls)
11499			      (verilog-decls-get-inouts moddecls)
11500			      (verilog-decls-get-inputs moddecls)
11501			      (verilog-subdecls-get-inputs modsubdecls)
11502			      (verilog-subdecls-get-outputs modsubdecls)))))
11503      (when regexp
11504	(setq sig-list (verilog-signals-matching-regexp
11505			sig-list regexp)))
11506      (setq sig-list (verilog-signals-not-matching-regexp
11507		      sig-list verilog-auto-inout-ignore-regexp))
11508      (verilog-forward-or-insert-line)
11509      (when v2k (verilog-repair-open-comma))
11510      (when sig-list
11511	(verilog-insert-indent "// Beginning of automatic inouts (from unused autoinst inouts)\n")
11512	(verilog-insert-definition modi sig-list "inout" indent-pt v2k)
11513	(verilog-insert-indent "// End of automatics\n"))
11514      (when v2k (verilog-repair-close-comma)))))
11515
11516(defun verilog-auto-inout-module (&optional complement all-in)
11517  "Expand AUTOINOUTMODULE statements, as part of \\[verilog-auto].
11518Take input/output/inout statements from the specified module and insert
11519into the current module.  This is useful for making null templates and
11520shell modules which need to have identical I/O with another module.
11521Any I/O which are already defined in this module will not be redefined.
11522For the complement of this function, see `verilog-auto-inout-comp',
11523and to make monitors with all inputs, see `verilog-auto-inout-in'.
11524
11525Limitations:
11526  If placed inside the parenthesis of a module declaration, it creates
11527  Verilog 2001 style, else uses Verilog 1995 style.
11528
11529  Concatenation and outputting partial buses is not supported.
11530
11531  Module names must be resolvable to filenames.  See `verilog-auto-inst'.
11532
11533  Signals are not inserted in the same order as in the original module,
11534  though they will appear to be in the same order to an AUTOINST
11535  instantiating either module.
11536
11537  Signals declared as \"output reg\" or \"output wire\" etc will
11538  lose the wire/reg declaration so that shell modules may
11539  generate those outputs differently.  However, \"output logic\"
11540  is propagated.
11541
11542An example:
11543
11544	module ExampShell (/*AUTOARG*/);
11545	   /*AUTOINOUTMODULE(\"ExampMain\")*/
11546	endmodule
11547
11548	module ExampMain (i,o,io);
11549          input i;
11550          output o;
11551          inout io;
11552        endmodule
11553
11554Typing \\[verilog-auto] will make this into:
11555
11556	module ExampShell (/*AUTOARG*/i,o,io);
11557	   /*AUTOINOUTMODULE(\"ExampMain\")*/
11558           // Beginning of automatic in/out/inouts (from specific module)
11559           output o;
11560           inout io;
11561           input i;
11562	   // End of automatics
11563	endmodule
11564
11565You may also provide an optional regular expression, in which case only
11566signals matching the regular expression will be included.  For example the
11567same expansion will result from only extracting signals starting with i:
11568
11569	   /*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/
11570
11571You may also provide an optional second regular expression, in
11572which case only signals which have that pin direction and data
11573type will be included.  This matches against everything before
11574the signal name in the declaration, for example against
11575\"input\" (single bit), \"output logic\" (direction and type) or
11576\"output [1:0]\" (direction and implicit type).  You also
11577probably want to skip spaces in your regexp.
11578
11579For example, the below will result in matching the output \"o\"
11580against the previous example's module:
11581
11582	   /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/"
11583  (save-excursion
11584    (let* ((params (verilog-read-auto-params 1 3))
11585	   (submod (nth 0 params))
11586	   (regexp (nth 1 params))
11587	   (direction-re (nth 2 params))
11588	   submodi)
11589      ;; Lookup position, etc of co-module
11590      ;; Note this may raise an error
11591      (when (setq submodi (verilog-modi-lookup submod t))
11592	(let* ((indent-pt (current-indentation))
11593	       (v2k  (verilog-in-paren-quick))
11594	       (modi (verilog-modi-current))
11595	       (moddecls (verilog-modi-get-decls modi))
11596	       (submoddecls (verilog-modi-get-decls submodi))
11597	       (sig-list-i  (verilog-signals-not-in
11598			     (cond (all-in
11599				    (append
11600				     (verilog-decls-get-inputs submoddecls)
11601				     (verilog-decls-get-inouts submoddecls)
11602				     (verilog-decls-get-outputs submoddecls)))
11603				   (complement
11604				    (verilog-decls-get-outputs submoddecls))
11605				   (t (verilog-decls-get-inputs submoddecls)))
11606			     (append (verilog-decls-get-inputs moddecls))))
11607	       (sig-list-o  (verilog-signals-not-in
11608			     (cond (all-in nil)
11609				   (complement
11610				    (verilog-decls-get-inputs submoddecls))
11611				   (t (verilog-decls-get-outputs submoddecls)))
11612			     (append (verilog-decls-get-outputs moddecls))))
11613	       (sig-list-io (verilog-signals-not-in
11614			     (cond (all-in nil)
11615				   (t (verilog-decls-get-inouts submoddecls)))
11616			     (append (verilog-decls-get-inouts moddecls))))
11617	       (sig-list-if (verilog-signals-not-in
11618			     (verilog-decls-get-interfaces submoddecls)
11619			     (append (verilog-decls-get-interfaces moddecls)))))
11620	  (forward-line 1)
11621	  (setq sig-list-i  (verilog-signals-edit-wire-reg
11622			     (verilog-signals-matching-dir-re
11623			      (verilog-signals-matching-regexp sig-list-i regexp)
11624			      "input" direction-re))
11625		sig-list-o  (verilog-signals-edit-wire-reg
11626			     (verilog-signals-matching-dir-re
11627			      (verilog-signals-matching-regexp sig-list-o regexp)
11628			      "output" direction-re))
11629		sig-list-io (verilog-signals-edit-wire-reg
11630			     (verilog-signals-matching-dir-re
11631			      (verilog-signals-matching-regexp sig-list-io regexp)
11632			      "inout" direction-re))
11633		sig-list-if (verilog-signals-matching-dir-re
11634			     (verilog-signals-matching-regexp sig-list-if regexp)
11635			     "interface" direction-re))
11636	  (when v2k (verilog-repair-open-comma))
11637	  (when (or sig-list-i sig-list-o sig-list-io)
11638	    (verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n")
11639	    ;; Don't sort them so an upper AUTOINST will match the main module
11640	    (verilog-insert-definition modi sig-list-o  "output" indent-pt v2k t)
11641	    (verilog-insert-definition modi sig-list-io "inout" indent-pt v2k t)
11642	    (verilog-insert-definition modi sig-list-i  "input" indent-pt v2k t)
11643	    (verilog-insert-definition modi sig-list-if "interface" indent-pt v2k t)
11644	    (verilog-insert-indent "// End of automatics\n"))
11645	  (when v2k (verilog-repair-close-comma)))))))
11646
11647(defun verilog-auto-inout-comp ()
11648  "Expand AUTOINOUTCOMP statements, as part of \\[verilog-auto].
11649Take input/output/inout statements from the specified module and
11650insert the inverse into the current module (inputs become outputs
11651and vice-versa.)  This is useful for making test and stimulus
11652modules which need to have complementing I/O with another module.
11653Any I/O which are already defined in this module will not be
11654redefined.  For the complement of this function, see
11655`verilog-auto-inout-module'.
11656
11657Limitations:
11658  If placed inside the parenthesis of a module declaration, it creates
11659  Verilog 2001 style, else uses Verilog 1995 style.
11660
11661  Concatenation and outputting partial buses is not supported.
11662
11663  Module names must be resolvable to filenames.  See `verilog-auto-inst'.
11664
11665  Signals are not inserted in the same order as in the original module,
11666  though they will appear to be in the same order to an AUTOINST
11667  instantiating either module.
11668
11669An example:
11670
11671	module ExampShell (/*AUTOARG*/);
11672	   /*AUTOINOUTCOMP(\"ExampMain\")*/
11673	endmodule
11674
11675	module ExampMain (i,o,io);
11676          input i;
11677          output o;
11678          inout io;
11679        endmodule
11680
11681Typing \\[verilog-auto] will make this into:
11682
11683	module ExampShell (/*AUTOARG*/i,o,io);
11684	   /*AUTOINOUTCOMP(\"ExampMain\")*/
11685           // Beginning of automatic in/out/inouts (from specific module)
11686           output i;
11687           inout io;
11688           input o;
11689	   // End of automatics
11690	endmodule
11691
11692You may also provide an optional regular expression, in which case only
11693signals matching the regular expression will be included.  For example the
11694same expansion will result from only extracting signals starting with i:
11695
11696	   /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
11697  (verilog-auto-inout-module t nil))
11698
11699(defun verilog-auto-inout-in ()
11700  "Expand AUTOINOUTIN statements, as part of \\[verilog-auto].
11701Take input/output/inout statements from the specified module and
11702insert them as all inputs into the current module.  This is
11703useful for making monitor modules which need to see all signals
11704as inputs based on another module.  Any I/O which are already
11705defined in this module will not be redefined.  See also
11706`verilog-auto-inout-module'.
11707
11708Limitations:
11709  If placed inside the parenthesis of a module declaration, it creates
11710  Verilog 2001 style, else uses Verilog 1995 style.
11711
11712  Concatenation and outputting partial buses is not supported.
11713
11714  Module names must be resolvable to filenames.  See `verilog-auto-inst'.
11715
11716  Signals are not inserted in the same order as in the original module,
11717  though they will appear to be in the same order to an AUTOINST
11718  instantiating either module.
11719
11720An example:
11721
11722	module ExampShell (/*AUTOARG*/);
11723	   /*AUTOINOUTIN(\"ExampMain\")*/
11724	endmodule
11725
11726	module ExampMain (i,o,io);
11727          input i;
11728          output o;
11729          inout io;
11730        endmodule
11731
11732Typing \\[verilog-auto] will make this into:
11733
11734	module ExampShell (/*AUTOARG*/i,o,io);
11735	   /*AUTOINOUTIN(\"ExampMain\")*/
11736           // Beginning of automatic in/out/inouts (from specific module)
11737           input i;
11738           input io;
11739           input o;
11740	   // End of automatics
11741	endmodule
11742
11743You may also provide an optional regular expression, in which case only
11744signals matching the regular expression will be included.  For example the
11745same expansion will result from only extracting signals starting with i:
11746
11747	   /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
11748  (verilog-auto-inout-module nil t))
11749
11750(defun verilog-auto-insert-lisp ()
11751  "Expand AUTOINSERTLISP statements, as part of \\[verilog-auto].
11752The Lisp code provided is called, and the Lisp code calls
11753`insert` to insert text into the current file beginning on the
11754line after the AUTOINSERTLISP.
11755
11756See also AUTO_LISP, which takes a Lisp expression and evaluates
11757it during `verilog-auto-inst' but does not insert any text.
11758
11759An example:
11760
11761	module ExampInsertLisp;
11762	   /*AUTOINSERTLISP(my-verilog-insert-hello \"world\")*/
11763	endmodule
11764
11765	// For this example we declare the function in the
11766	// module's file itself.  Often you'd define it instead
11767	// in a site-start.el or .emacs file.
11768	/*
11769	 Local Variables:
11770	 eval:
11771	   (defun my-verilog-insert-hello (who)
11772	     (insert (concat \"initial $write(\\\"hello \" who \"\\\");\\n\")))
11773	 End:
11774	*/
11775
11776Typing \\[verilog-auto] will call my-verilog-insert-hello and
11777expand the above into:
11778
11779	// Beginning of automatic insert lisp
11780	initial $write(\"hello world\");
11781	// End of automatics
11782
11783You can also call an external program and insert the returned
11784text:
11785
11786	/*AUTOINSERTLISP(insert (shell-command-to-string \"echo //hello\"))*/
11787	// Beginning of automatic insert lisp
11788	//hello
11789	// End of automatics"
11790  (save-excursion
11791    ;; Point is at end of /*AUTO...*/
11792    (let* ((indent-pt (current-indentation))
11793	   (cmd-end-pt (save-excursion (search-backward ")")
11794				       (forward-char)
11795				       (point)))	;; Closing paren
11796	   (cmd-beg-pt (save-excursion (goto-char cmd-end-pt)
11797				       (backward-sexp 1)  ;; Inside comment
11798				       (point))) ;; Beginning paren
11799	   (cmd (buffer-substring-no-properties cmd-beg-pt cmd-end-pt)))
11800      (verilog-forward-or-insert-line)
11801      ;; Some commands don't move point (like insert-file) so we always
11802      ;; add the begin/end comments, then delete it if not needed
11803      (verilog-insert-indent "// Beginning of automatic insert lisp\n")
11804      (verilog-insert-indent "// End of automatics\n")
11805      (forward-line -1)
11806      (eval (read cmd))
11807      (forward-line -1)
11808      (setq verilog-scan-cache-tick nil) ;; Clear cache; inserted unknown text
11809      (verilog-delete-empty-auto-pair))))
11810
11811(defun verilog-auto-sense-sigs (moddecls presense-sigs)
11812  "Return list of signals for current AUTOSENSE block."
11813  (let* ((sigss (verilog-read-always-signals))
11814	 (sig-list (verilog-signals-not-params
11815		    (verilog-signals-not-in (verilog-alw-get-inputs sigss)
11816					    (append (and (not verilog-auto-sense-include-inputs)
11817							 (verilog-alw-get-outputs-delayed sigss))
11818						    (and (not verilog-auto-sense-include-inputs)
11819							 (verilog-alw-get-outputs-immediate sigss))
11820						    (verilog-alw-get-temps sigss)
11821						    (verilog-decls-get-consts moddecls)
11822						    (verilog-decls-get-gparams moddecls)
11823						    presense-sigs)))))
11824    sig-list))
11825
11826(defun verilog-auto-sense ()
11827  "Expand AUTOSENSE statements, as part of \\[verilog-auto].
11828Replace the always (/*AUTOSENSE*/) sensitivity list (/*AS*/ for short)
11829with one automatically derived from all inputs declared in the always
11830statement.  Signals that are generated within the same always block are NOT
11831placed into the sensitivity list (see `verilog-auto-sense-include-inputs').
11832Long lines are split based on the `fill-column', see \\[set-fill-column].
11833
11834Limitations:
11835  Verilog does not allow memories (multidimensional arrays) in sensitivity
11836  lists.  AUTOSENSE will thus exclude them, and add a /*memory or*/ comment.
11837
11838Constant signals:
11839  AUTOSENSE cannot always determine if a `define is a constant or a signal
11840  (it could be in an include file for example).  If a `define or other signal
11841  is put into the AUTOSENSE list and is not desired, use the AUTO_CONSTANT
11842  declaration anywhere in the module (parenthesis are required):
11843
11844	/* AUTO_CONSTANT ( `this_is_really_constant_dont_autosense_it ) */
11845
11846  Better yet, use a parameter, which will be understood to be constant
11847  automatically.
11848
11849OOps!
11850  If AUTOSENSE makes a mistake, please report it.  (First try putting
11851  a begin/end after your always!) As a workaround, if a signal that
11852  shouldn't be in the sensitivity list was, use the AUTO_CONSTANT above.
11853  If a signal should be in the sensitivity list wasn't, placing it before
11854  the /*AUTOSENSE*/ comment will prevent it from being deleted when the
11855  autos are updated (or added if it occurs there already).
11856
11857An example:
11858
11859	   always @ (/*AS*/) begin
11860	      /* AUTO_CONSTANT (`constant) */
11861	      outin = ina | inb | `constant;
11862	      out = outin;
11863	   end
11864
11865Typing \\[verilog-auto] will make this into:
11866
11867	   always @ (/*AS*/ina or inb) begin
11868	      /* AUTO_CONSTANT (`constant) */
11869	      outin = ina | inb | `constant;
11870	      out = outin;
11871	   end
11872
11873Note in Verilog 2001, you can often get the same result from the new @*
11874operator.  (This was added to the language in part due to AUTOSENSE!)
11875
11876	   always @* begin
11877	      outin = ina | inb | `constant;
11878	      out = outin;
11879	   end"
11880  (save-excursion
11881    ;; Find beginning
11882    (let* ((start-pt (save-excursion
11883		       (verilog-re-search-backward-quick "(" nil t)
11884		       (point)))
11885	   (indent-pt (save-excursion
11886			(or (and (goto-char start-pt) (1+ (current-column)))
11887			    (current-indentation))))
11888	   (modi (verilog-modi-current))
11889	   (moddecls (verilog-modi-get-decls modi))
11890	   (sig-memories (verilog-signals-memory
11891			  (verilog-decls-get-vars moddecls)))
11892	   sig-list not-first presense-sigs)
11893      ;; Read signals in always, eliminate outputs from sense list
11894      (setq presense-sigs (verilog-signals-from-signame
11895			   (save-excursion
11896			     (verilog-read-signals start-pt (point)))))
11897      (setq sig-list (verilog-auto-sense-sigs moddecls presense-sigs))
11898      (when sig-memories
11899	(let ((tlen (length sig-list)))
11900	  (setq sig-list (verilog-signals-not-in sig-list sig-memories))
11901	  (if (not (eq tlen (length sig-list))) (verilog-insert " /*memory or*/ "))))
11902      (if (and presense-sigs  ;; Add a "or" if not "(.... or /*AUTOSENSE*/"
11903	       (save-excursion (goto-char (point))
11904			       (verilog-re-search-backward-quick "[a-zA-Z0-9$_.%`]+" start-pt t)
11905			       (verilog-re-search-backward-quick "\\s-" start-pt t)
11906			       (while (looking-at "\\s-`endif")
11907				 (verilog-re-search-backward-quick "[a-zA-Z0-9$_.%`]+" start-pt t)
11908				 (verilog-re-search-backward-quick "\\s-" start-pt t))
11909			       (not (looking-at "\\s-or\\b"))))
11910	  (setq not-first t))
11911      (setq sig-list (sort sig-list `verilog-signals-sort-compare))
11912      (while sig-list
11913	(cond ((> (+ 4 (current-column) (length (verilog-sig-name (car sig-list)))) fill-column) ;+4 for width of or
11914	       (insert "\n")
11915	       (indent-to indent-pt)
11916	       (if not-first (insert "or ")))
11917	      (not-first (insert " or ")))
11918	(insert (verilog-sig-name (car sig-list)))
11919	(setq sig-list (cdr sig-list)
11920	      not-first t)))))
11921
11922(defun verilog-auto-reset ()
11923  "Expand AUTORESET statements, as part of \\[verilog-auto].
11924Replace the /*AUTORESET*/ comment with code to initialize all
11925registers set elsewhere in the always block.
11926
11927Limitations:
11928  AUTORESET will not clear memories.
11929
11930  AUTORESET uses <= if the signal has a <= assignment in the block,
11931  else it uses =.
11932
11933  If <= is used, all = assigned variables are ignored if
11934  `verilog-auto-reset-blocking-in-non' is nil; they are presumed
11935  to be temporaries.
11936
11937/*AUTORESET*/ presumes that any signals mentioned between the previous
11938begin/case/if statement and the AUTORESET comment are being reset manually
11939and should not be automatically reset.  This includes omitting any signals
11940used on the right hand side of assignments.
11941
11942By default, AUTORESET will include the width of the signal in the
11943autos, SystemVerilog designs may want to change this.  To control
11944this behavior, see `verilog-auto-reset-widths'.
11945
11946AUTORESET ties signals to deasserted, which is presumed to be zero.
11947Signals that match `verilog-active-low-regexp' will be deasserted by tying
11948them to a one.
11949
11950An example:
11951
11952    always @(posedge clk or negedge reset_l) begin
11953        if (!reset_l) begin
11954            c <= 1;
11955            /*AUTORESET*/
11956        end
11957        else begin
11958            a <= in_a;
11959            b <= in_b;
11960            c <= in_c;
11961        end
11962    end
11963
11964Typing \\[verilog-auto] will make this into:
11965
11966    always @(posedge core_clk or negedge reset_l) begin
11967        if (!reset_l) begin
11968            c <= 1;
11969            /*AUTORESET*/
11970            // Beginning of autoreset for uninitialized flops
11971            a <= 0;
11972            b = 0;   // if `verilog-auto-reset-blocking-in-non' true
11973            // End of automatics
11974        end
11975        else begin
11976            a <= in_a;
11977            b  = in_b;
11978            c <= in_c;
11979        end
11980    end"
11981
11982  (interactive)
11983  (save-excursion
11984    ;; Find beginning
11985    (let* ((indent-pt (current-indentation))
11986	   (modi (verilog-modi-current))
11987	   (moddecls (verilog-modi-get-decls modi))
11988	   (all-list (verilog-decls-get-signals moddecls))
11989	   sigss sig-list dly-list prereset-sigs)
11990      ;; Read signals in always, eliminate outputs from reset list
11991      (setq prereset-sigs (verilog-signals-from-signame
11992			   (save-excursion
11993			     (verilog-read-signals
11994			      (save-excursion
11995				(verilog-re-search-backward-quick "\\(@\\|\\<begin\\>\\|\\<if\\>\\|\\<case\\>\\)" nil t)
11996				(point))
11997			      (point)))))
11998      (save-excursion
11999	(verilog-re-search-backward-quick "@" nil t)
12000        (setq sigss (verilog-read-always-signals)))
12001      (setq dly-list (verilog-alw-get-outputs-delayed sigss))
12002      (setq sig-list (verilog-signals-not-in (append
12003					      (verilog-alw-get-outputs-delayed sigss)
12004					      (when (or (not (verilog-alw-get-uses-delayed sigss))
12005							verilog-auto-reset-blocking-in-non)
12006						(verilog-alw-get-outputs-immediate sigss)))
12007					     (append
12008					      (verilog-alw-get-temps sigss)
12009					      prereset-sigs)))
12010      (setq sig-list (sort sig-list `verilog-signals-sort-compare))
12011      (when sig-list
12012	(insert "\n");
12013	(verilog-insert-indent "// Beginning of autoreset for uninitialized flops\n");
12014	(while sig-list
12015	  (let ((sig (or (assoc (verilog-sig-name (car sig-list)) all-list) ;; As sig-list has no widths
12016			 (car sig-list))))
12017	    (indent-to indent-pt)
12018	    (insert (verilog-sig-name sig)
12019		    (if (assoc (verilog-sig-name sig) dly-list)
12020			(concat " <= " verilog-assignment-delay)
12021		      " = ")
12022		    (verilog-sig-tieoff sig)
12023		    ";\n")
12024	    (setq sig-list (cdr sig-list))))
12025	(verilog-insert-indent "// End of automatics")))))
12026
12027(defun verilog-auto-tieoff ()
12028  "Expand AUTOTIEOFF statements, as part of \\[verilog-auto].
12029Replace the /*AUTOTIEOFF*/ comment with code to wire-tie all unused output
12030signals to deasserted.
12031
12032/*AUTOTIEOFF*/ is used to make stub modules; modules that have the same
12033input/output list as another module, but no internals.  Specifically, it
12034finds all outputs in the module, and if that input is not otherwise declared
12035as a register or wire, creates a tieoff.
12036
12037AUTORESET ties signals to deasserted, which is presumed to be zero.
12038Signals that match `verilog-active-low-regexp' will be deasserted by tying
12039them to a one.
12040
12041You can add signals you do not want included in AUTOTIEOFF with
12042`verilog-auto-tieoff-ignore-regexp'.
12043
12044`verilog-auto-wire-type' may be used to change the datatype of
12045the declarations.
12046
12047`verilog-auto-reset-widths' may be used to change how the tieoff
12048value's width is generated.
12049
12050An example of making a stub for another module:
12051
12052    module ExampStub (/*AUTOINST*/);
12053	/*AUTOINOUTMODULE(\"Foo\")*/
12054        /*AUTOTIEOFF*/
12055        // verilator lint_off UNUSED
12056        wire _unused_ok = &{1'b0,
12057                            /*AUTOUNUSED*/
12058                            1'b0};
12059        // verilator lint_on  UNUSED
12060    endmodule
12061
12062Typing \\[verilog-auto] will make this into:
12063
12064    module ExampStub (/*AUTOINST*/...);
12065	/*AUTOINOUTMODULE(\"Foo\")*/
12066        // Beginning of autotieoff
12067        output [2:0] foo;
12068        // End of automatics
12069
12070        /*AUTOTIEOFF*/
12071        // Beginning of autotieoff
12072        wire [2:0] foo = 3'b0;
12073        // End of automatics
12074        ...
12075    endmodule"
12076  (interactive)
12077  (save-excursion
12078    ;; Find beginning
12079    (let* ((indent-pt (current-indentation))
12080	   (modi (verilog-modi-current))
12081	   (moddecls (verilog-modi-get-decls modi))
12082	   (modsubdecls (verilog-modi-get-sub-decls modi))
12083	   (sig-list (verilog-signals-not-in
12084		      (verilog-decls-get-outputs moddecls)
12085		      (append (verilog-decls-get-vars moddecls)
12086			      (verilog-decls-get-assigns moddecls)
12087			      (verilog-decls-get-consts moddecls)
12088			      (verilog-decls-get-gparams moddecls)
12089			      (verilog-subdecls-get-interfaced modsubdecls)
12090			      (verilog-subdecls-get-outputs modsubdecls)
12091			      (verilog-subdecls-get-inouts modsubdecls)))))
12092      (setq sig-list (verilog-signals-not-matching-regexp
12093		      sig-list verilog-auto-tieoff-ignore-regexp))
12094      (when sig-list
12095	(verilog-forward-or-insert-line)
12096	(verilog-insert-indent "// Beginning of automatic tieoffs (for this module's unterminated outputs)\n")
12097	(setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare))
12098	(verilog-modi-cache-add-vars modi sig-list)  ; Before we trash list
12099	(while sig-list
12100	  (let ((sig (car sig-list)))
12101	    (cond ((equal verilog-auto-tieoff-declaration "assign")
12102		   (indent-to indent-pt)
12103		   (insert "assign " (verilog-sig-name sig)))
12104		  (t
12105		   (verilog-insert-one-definition sig verilog-auto-tieoff-declaration indent-pt)))
12106	    (indent-to (max 48 (+ indent-pt 40)))
12107	    (insert "= " (verilog-sig-tieoff sig)
12108		    ";\n")
12109	    (setq sig-list (cdr sig-list))))
12110	(verilog-insert-indent "// End of automatics\n")))))
12111
12112(defun verilog-auto-undef ()
12113  "Expand AUTOUNDEF statements, as part of \\[verilog-auto].
12114Take any `defines since the last AUTOUNDEF in the current file
12115and create `undefs for them.  This is used to insure that
12116file-local defines do not polute the global `define name space.
12117
12118Limitations:
12119  AUTOUNDEF presumes any identifier following `define is the
12120  name of a define.  Any `ifdefs are ignored.
12121
12122  AUTOUNDEF suppresses creating an `undef for any define that was
12123  `undefed before the AUTOUNDEF.  This may be used to work around
12124  the ignoring of `ifdefs as shown below.
12125
12126An example:
12127
12128	`define XX_FOO
12129	`define M_BAR(x)
12130	`define M_BAZ
12131	...
12132	`ifdef NEVER
12133	  `undef M_BAZ	// Emacs will see this and not `undef M_BAZ
12134	`endif
12135	...
12136	/*AUTOUNDEF*/
12137
12138Typing \\[verilog-auto] will make this into:
12139
12140	...
12141	/*AUTOUNDEF*/
12142	// Beginning of automatic undefs
12143	`undef XX_FOO
12144	`undef M_BAR
12145	// End of automatics
12146
12147You may also provide an optional regular expression, in which case only
12148defines the regular expression will be undefed."
12149  (save-excursion
12150    (let* ((params (verilog-read-auto-params 0 1))
12151	   (regexp (nth 0 params))
12152	   (indent-pt (current-indentation))
12153	   (end-pt (point))
12154	   defs def)
12155      (save-excursion
12156	;; Scan from beginnng of file, or last AUTOUNDEF
12157	(or (verilog-re-search-backward-quick "/\\*AUTOUNDEF\\>" end-pt t)
12158	    (goto-char (point-min)))
12159	(while (verilog-re-search-forward-quick
12160		"`\\(define\\|undef\\)\\s-*\\([a-zA-Z_][a-zA-Z_0-9]*\\)" end-pt t)
12161	  (cond ((equal (match-string-no-properties 1) "define")
12162		 (setq def (match-string-no-properties 2))
12163		 (when (and (or (not regexp)
12164				(string-match regexp def))
12165			    (not (member def defs))) ;; delete-dups not in 21.1
12166		   (setq defs (cons def defs))))
12167		(t
12168		 (setq defs (delete (match-string-no-properties 2) defs))))))
12169      ;; Insert
12170      (setq defs (sort defs 'string<))
12171      (when defs
12172	(verilog-forward-or-insert-line)
12173	(verilog-insert-indent "// Beginning of automatic undefs\n")
12174	(while defs
12175	  (verilog-insert-indent "`undef " (car defs) "\n")
12176	  (setq defs (cdr defs)))
12177	(verilog-insert-indent "// End of automatics\n")))))
12178
12179(defun verilog-auto-unused ()
12180  "Expand AUTOUNUSED statements, as part of \\[verilog-auto].
12181Replace the /*AUTOUNUSED*/ comment with a comma separated list of all unused
12182input and inout signals.
12183
12184/*AUTOUNUSED*/ is used to make stub modules; modules that have the same
12185input/output list as another module, but no internals.  Specifically, it
12186finds all inputs and inouts in the module, and if that input is not otherwise
12187used, adds it to a comma separated list.
12188
12189The comma separated list is intended to be used to create a _unused_ok
12190signal.  Using the exact name \"_unused_ok\" for name of the temporary
12191signal is recommended as it will insure maximum forward compatibility, it
12192also makes lint warnings easy to understand; ignore any unused warnings
12193with \"unused\" in the signal name.
12194
12195To reduce simulation time, the _unused_ok signal should be forced to a
12196constant to prevent wiggling.  The easiest thing to do is use a
12197reduction-and with 1'b0 as shown.
12198
12199This way all unused signals are in one place, making it convenient to add
12200your tool's specific pragmas around the assignment to disable any unused
12201warnings.
12202
12203You can add signals you do not want included in AUTOUNUSED with
12204`verilog-auto-unused-ignore-regexp'.
12205
12206An example of making a stub for another module:
12207
12208    module ExampStub (/*AUTOINST*/);
12209	/*AUTOINOUTMODULE(\"Examp\")*/
12210        /*AUTOTIEOFF*/
12211        // verilator lint_off UNUSED
12212        wire _unused_ok = &{1'b0,
12213                            /*AUTOUNUSED*/
12214                            1'b0};
12215        // verilator lint_on  UNUSED
12216    endmodule
12217
12218Typing \\[verilog-auto] will make this into:
12219
12220        ...
12221        // verilator lint_off UNUSED
12222        wire _unused_ok = &{1'b0,
12223                            /*AUTOUNUSED*/
12224			    // Beginning of automatics
12225			    unused_input_a,
12226			    unused_input_b,
12227			    unused_input_c,
12228			    // End of automatics
12229                            1'b0};
12230        // verilator lint_on  UNUSED
12231    endmodule"
12232  (interactive)
12233  (save-excursion
12234    ;; Find beginning
12235    (let* ((indent-pt (progn (search-backward "/*") (current-column)))
12236	   (modi (verilog-modi-current))
12237	   (moddecls (verilog-modi-get-decls modi))
12238	   (modsubdecls (verilog-modi-get-sub-decls modi))
12239	   (sig-list (verilog-signals-not-in
12240		      (append (verilog-decls-get-inputs moddecls)
12241			      (verilog-decls-get-inouts moddecls))
12242		      (append (verilog-subdecls-get-inputs modsubdecls)
12243			      (verilog-subdecls-get-inouts modsubdecls)))))
12244      (setq sig-list (verilog-signals-not-matching-regexp
12245		      sig-list verilog-auto-unused-ignore-regexp))
12246      (when sig-list
12247	(verilog-forward-or-insert-line)
12248	(verilog-insert-indent "// Beginning of automatic unused inputs\n")
12249	(setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare))
12250	(while sig-list
12251	  (let ((sig (car sig-list)))
12252	    (indent-to indent-pt)
12253	    (insert (verilog-sig-name sig) ",\n")
12254	    (setq sig-list (cdr sig-list))))
12255	(verilog-insert-indent "// End of automatics\n")))))
12256
12257(defun verilog-enum-ascii (signm elim-regexp)
12258  "Convert an enum name SIGNM to an ascii string for insertion.
12259Remove user provided prefix ELIM-REGEXP."
12260  (or elim-regexp (setq elim-regexp "_ DONT MATCH IT_"))
12261  (let ((case-fold-search t))
12262    ;; All upper becomes all lower for readability
12263    (downcase (verilog-string-replace-matches elim-regexp "" nil nil signm))))
12264
12265(defun verilog-auto-ascii-enum ()
12266  "Expand AUTOASCIIENUM statements, as part of \\[verilog-auto].
12267Create a register to contain the ASCII decode of an enumerated signal type.
12268This will allow trace viewers to show the ASCII name of states.
12269
12270First, parameters are built into an enumeration using the synopsys enum
12271comment.  The comment must be between the keyword and the symbol.
12272\(Annoying, but that's what Synopsys's dc_shell FSM reader requires.)
12273
12274Next, registers which that enum applies to are also tagged with the same
12275enum.
12276
12277Finally, an AUTOASCIIENUM command is used.
12278
12279  The first parameter is the name of the signal to be decoded.
12280
12281  The second parameter is the name to store the ASCII code into.  For the
12282  signal foo, I suggest the name _foo__ascii, where the leading _ indicates
12283  a signal that is just for simulation, and the magic characters _ascii
12284  tell viewers like Dinotrace to display in ASCII format.
12285
12286  The third optional parameter is a string which will be removed
12287  from the state names.  It defaults to \"\" which removes nothing.
12288
12289  The fourth optional parameter is \"onehot\" to force one-hot
12290  decoding.  If unspecified, if and only if the first parameter
12291  width is 2^(number of states in enum) and does NOT match the
12292  width of the enum, the signal is assumed to be a one-hot
12293  decode.  Otherwise, it's a normal encoded state vector.
12294
12295  `verilog-auto-wire-type' may be used to change the datatype of
12296  the declarations.
12297
12298  \"auto enum\" may be used in place of \"synopsys enum\".
12299
12300An example:
12301
12302	//== State enumeration
12303	parameter [2:0] // synopsys enum state_info
12304			   SM_IDLE =  3'b000,
12305			   SM_SEND =  3'b001,
12306			   SM_WAIT1 = 3'b010;
12307	//== State variables
12308	reg [2:0]  /* synopsys enum state_info */
12309		   state_r;  /* synopsys state_vector state_r */
12310	reg [2:0]  /* synopsys enum state_info */
12311		   state_e1;
12312
12313	/*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
12314
12315Typing \\[verilog-auto] will make this into:
12316
12317	... same front matter ...
12318
12319	/*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
12320	// Beginning of automatic ASCII enum decoding
12321	reg [39:0]		state_ascii_r;		// Decode of state_r
12322	always @(state_r) begin
12323	   case ({state_r})
12324		SM_IDLE:  state_ascii_r = \"idle \";
12325		SM_SEND:  state_ascii_r = \"send \";
12326		SM_WAIT1: state_ascii_r = \"wait1\";
12327		default:  state_ascii_r = \"%Erro\";
12328	   endcase
12329	end
12330	// End of automatics"
12331  (save-excursion
12332    (let* ((params (verilog-read-auto-params 2 4))
12333	   (undecode-name (nth 0 params))
12334	   (ascii-name (nth 1 params))
12335	   (elim-regexp (and (nth 2 params)
12336			     (not (equal (nth 2 params) ""))
12337			     (nth 2 params)))
12338	   (one-hot-flag (nth 3 params))
12339	   ;;
12340	   (indent-pt (current-indentation))
12341	   (modi (verilog-modi-current))
12342	   (moddecls (verilog-modi-get-decls modi))
12343	   ;;
12344	   (sig-list-consts (append (verilog-decls-get-consts moddecls)
12345				    (verilog-decls-get-gparams moddecls)))
12346	   (sig-list-all  (append (verilog-decls-get-vars moddecls)
12347				  (verilog-decls-get-outputs moddecls)
12348				  (verilog-decls-get-inouts moddecls)
12349				  (verilog-decls-get-inputs moddecls)))
12350	   ;;
12351	   (undecode-sig (or (assoc undecode-name sig-list-all)
12352			     (error "%s: Signal %s not found in design" (verilog-point-text) undecode-name)))
12353	   (undecode-enum (or (verilog-sig-enum undecode-sig)
12354			      (error "%s: Signal %s does not have an enum tag" (verilog-point-text) undecode-name)))
12355	   ;;
12356	   (enum-sigs (verilog-signals-not-in
12357		       (or (verilog-signals-matching-enum sig-list-consts undecode-enum)
12358			   (error "%s: No state definitions for %s" (verilog-point-text) undecode-enum))
12359		       nil))
12360	   ;;
12361	   (one-hot (or
12362		     (string-match "onehot" (or one-hot-flag ""))
12363		     (and ;; width(enum) != width(sig)
12364		      (or (not (verilog-sig-bits (car enum-sigs)))
12365			  (not (equal (verilog-sig-width (car enum-sigs))
12366				      (verilog-sig-width undecode-sig))))
12367		      ;; count(enums) == width(sig)
12368		      (equal (number-to-string (length enum-sigs))
12369			     (verilog-sig-width undecode-sig)))))
12370  	   (enum-chars 0)
12371	   (ascii-chars 0))
12372      ;;
12373      ;; Find number of ascii chars needed
12374      (let ((tmp-sigs enum-sigs))
12375	(while tmp-sigs
12376	  (setq enum-chars (max enum-chars (length (verilog-sig-name (car tmp-sigs))))
12377		ascii-chars (max ascii-chars (length (verilog-enum-ascii
12378						      (verilog-sig-name (car tmp-sigs))
12379						      elim-regexp)))
12380		tmp-sigs (cdr tmp-sigs))))
12381      ;;
12382      (verilog-forward-or-insert-line)
12383      (verilog-insert-indent "// Beginning of automatic ASCII enum decoding\n")
12384      (let ((decode-sig-list (list (list ascii-name (format "[%d:0]" (- (* ascii-chars 8) 1))
12385					 (concat "Decode of " undecode-name) nil nil))))
12386	(verilog-insert-definition modi decode-sig-list "reg" indent-pt nil))
12387      ;;
12388      (verilog-insert-indent "always @(" undecode-name ") begin\n")
12389      (setq indent-pt (+ indent-pt verilog-indent-level))
12390      (verilog-insert-indent "case ({" undecode-name "})\n")
12391      (setq indent-pt (+ indent-pt verilog-case-indent))
12392      ;;
12393      (let ((tmp-sigs enum-sigs)
12394	    (chrfmt (format "%%-%ds %s = \"%%-%ds\";\n"
12395			    (+ (if one-hot 9 1) (max 8 enum-chars))
12396			    ascii-name ascii-chars))
12397	    (errname (substring "%Error" 0 (min 6 ascii-chars))))
12398	(while tmp-sigs
12399	  (verilog-insert-indent
12400	   (concat
12401	    (format chrfmt
12402		    (concat (if one-hot "(")
12403			    ;; Use enum-sigs length as that's numeric
12404			    ;; verilog-sig-width undecode-sig might not be.
12405			    (if one-hot (number-to-string (length enum-sigs)))
12406			    ;; We use a shift instead of var[index]
12407			    ;; so that a non-one hot value will show as error.
12408			    (if one-hot "'b1<<")
12409			    (verilog-sig-name (car tmp-sigs))
12410			    (if one-hot ")") ":")
12411		    (verilog-enum-ascii (verilog-sig-name (car tmp-sigs))
12412					elim-regexp))))
12413	  (setq tmp-sigs (cdr tmp-sigs)))
12414	(verilog-insert-indent (format chrfmt "default:" errname)))
12415      ;;
12416      (setq indent-pt (- indent-pt verilog-case-indent))
12417      (verilog-insert-indent "endcase\n")
12418      (setq indent-pt (- indent-pt verilog-indent-level))
12419      (verilog-insert-indent "end\n"
12420			     "// End of automatics\n"))))
12421
12422(defun verilog-auto-templated-rel ()
12423  "Replace Templated relative line numbers with absolute line numbers.
12424Internal use only.  This hacks around the line numbers in AUTOINST Templates
12425being different from the final output's line numbering."
12426  (let ((templateno 0) (template-line (list 0)) (buf-line 1))
12427    ;; Find line number each template is on
12428    ;; Count lines as we go, as otherwise it's O(n^2) to use count-lines
12429    (goto-char (point-min))
12430    (while (not (eobp))
12431      (when (looking-at ".*AUTO_TEMPLATE")
12432	(setq templateno (1+ templateno))
12433	(setq template-line (cons buf-line template-line)))
12434      (setq buf-line (1+ buf-line))
12435      (forward-line 1))
12436    (setq template-line (nreverse template-line))
12437    ;; Replace T# L# with absolute line number
12438    (goto-char (point-min))
12439    (while (re-search-forward " Templated T\\([0-9]+\\) L\\([0-9]+\\)" nil t)
12440      (replace-match
12441       (concat " Templated "
12442	       (int-to-string (+ (nth (string-to-number (match-string 1))
12443				      template-line)
12444				 (string-to-number (match-string 2)))))
12445       t t))))
12446
12447(defun verilog-auto-template-lint ()
12448  "Check AUTO_TEMPLATEs for unused lines.
12449Enable with `verilog-auto-template-warn-unused'."
12450  (let ((name1 (or (buffer-file-name) (buffer-name))))
12451    (save-excursion
12452      (goto-char (point-min))
12453      (while (re-search-forward
12454	      "^\\s-*/?\\*?\\s-*[a-zA-Z0-9`_$]+\\s-+AUTO_TEMPLATE" nil t)
12455	(let* ((tpl-info (verilog-read-auto-template-middle))
12456	       (tpl-list (aref tpl-info 1))
12457	       (tlines (append (nth 0 tpl-list) (nth 1 tpl-list)))
12458	       tpl-ass)
12459	  (while tlines
12460	    (setq tpl-ass (car tlines)
12461		  tlines (cdr tlines))
12462	    ;;;
12463	    (unless (or (not (eval-when-compile (fboundp 'make-hash-table))) ;; Not supported, no warning
12464			(not verilog-auto-template-hits)
12465			(gethash (vector (nth 2 tpl-ass) (nth 3 tpl-ass))
12466				 verilog-auto-template-hits))
12467	      (verilog-warn-error "%s:%d: AUTO_TEMPLATE line unused: \".%s (%s)\""
12468				  name1
12469				  (+ (elt tpl-ass 3)  ;; Template line number
12470				     (count-lines (point-min) (point)))
12471				  (elt tpl-ass 0) (elt tpl-ass 1))
12472	      )))))))
12473
12474
12475;;
12476;; Auto top level
12477;;
12478
12479(defun verilog-auto (&optional inject)  ; Use verilog-inject-auto instead of passing an arg
12480  "Expand AUTO statements.
12481Look for any /*AUTO...*/ commands in the code, as used in
12482instantiations or argument headers.  Update the list of signals
12483following the /*AUTO...*/ command.
12484
12485Use \\[verilog-delete-auto] to remove the AUTOs.
12486
12487Use \\[verilog-diff-auto] to see differences in AUTO expansion.
12488
12489Use \\[verilog-inject-auto] to insert AUTOs for the first time.
12490
12491Use \\[verilog-faq] for a pointer to frequently asked questions.
12492
12493The hooks `verilog-before-auto-hook' and `verilog-auto-hook' are
12494called before and after this function, respectively.
12495
12496For example:
12497	module ModuleName (/*AUTOARG*/);
12498	/*AUTOINPUT*/
12499	/*AUTOOUTPUT*/
12500	/*AUTOWIRE*/
12501	/*AUTOREG*/
12502	InstMod instName #(/*AUTOINSTPARAM*/) (/*AUTOINST*/);
12503
12504You can also update the AUTOs from the shell using:
12505	emacs --batch  <filenames.v>  -f verilog-batch-auto
12506Or fix indentation with:
12507	emacs --batch  <filenames.v>  -f verilog-batch-indent
12508Likewise, you can delete or inject AUTOs with:
12509	emacs --batch  <filenames.v>  -f verilog-batch-delete-auto
12510	emacs --batch  <filenames.v>  -f verilog-batch-inject-auto
12511Or check if AUTOs have the same expansion
12512	emacs --batch  <filenames.v>  -f verilog-batch-diff-auto
12513
12514Using \\[describe-function], see also:
12515    `verilog-auto-arg'          for AUTOARG module instantiations
12516    `verilog-auto-ascii-enum'   for AUTOASCIIENUM enumeration decoding
12517    `verilog-auto-inout-comp'   for AUTOINOUTCOMP copy complemented i/o
12518    `verilog-auto-inout-in'     for AUTOINOUTIN inputs for all i/o
12519    `verilog-auto-inout-module' for AUTOINOUTMODULE copying i/o from elsewhere
12520    `verilog-auto-inout'        for AUTOINOUT making hierarchy inouts
12521    `verilog-auto-input'        for AUTOINPUT making hierarchy inputs
12522    `verilog-auto-insert-lisp'  for AUTOINSERTLISP insert code from lisp function
12523    `verilog-auto-inst'         for AUTOINST instantiation pins
12524    `verilog-auto-star'         for AUTOINST .* SystemVerilog pins
12525    `verilog-auto-inst-param'   for AUTOINSTPARAM instantiation params
12526    `verilog-auto-logic'        for AUTOLOGIC declaring logic signals
12527    `verilog-auto-output'       for AUTOOUTPUT making hierarchy outputs
12528    `verilog-auto-output-every' for AUTOOUTPUTEVERY making all outputs
12529    `verilog-auto-reg'          for AUTOREG registers
12530    `verilog-auto-reg-input'    for AUTOREGINPUT instantiation registers
12531    `verilog-auto-reset'        for AUTORESET flop resets
12532    `verilog-auto-sense'        for AUTOSENSE always sensitivity lists
12533    `verilog-auto-tieoff'       for AUTOTIEOFF output tieoffs
12534    `verilog-auto-undef'        for AUTOUNDEF `undef of local `defines
12535    `verilog-auto-unused'       for AUTOUNUSED unused inputs/inouts
12536    `verilog-auto-wire'         for AUTOWIRE instantiation wires
12537
12538    `verilog-read-defines'      for reading `define values
12539    `verilog-read-includes'     for reading `includes
12540
12541If you have bugs with these autos, please file an issue at
12542URL `http://www.veripool.org/verilog-mode' or contact the AUTOAUTHOR
12543Wilson Snyder (wsnyder@wsnyder.org)."
12544  (interactive)
12545  (unless noninteractive (message "Updating AUTOs..."))
12546  (if (fboundp 'dinotrace-unannotate-all)
12547      (dinotrace-unannotate-all))
12548  (verilog-save-font-mods
12549   (let ((oldbuf (if (not (buffer-modified-p))
12550		     (buffer-string)))
12551	 ;; Cache directories; we don't write new files, so can't change
12552	 (verilog-dir-cache-preserving t)
12553	 ;; Cache current module
12554	 (verilog-modi-cache-current-enable t)
12555	 (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
12556	 verilog-modi-cache-current)
12557     (unwind-protect
12558	 ;; Disable change hooks for speed
12559	 ;; This let can't be part of above let; must restore
12560	 ;; after-change-functions before font-lock resumes
12561	 (verilog-save-no-change-functions
12562	  (verilog-save-scan-cache
12563	   (save-excursion
12564	     ;; Wipe cache; otherwise if we AUTOed a block above this one,
12565	     ;; we'll misremember we have generated IOs, confusing AUTOOUTPUT
12566	     (setq verilog-modi-cache-list nil)
12567	     ;; Local state
12568	     (setq verilog-auto-template-hits nil)
12569	     ;; If we're not in verilog-mode, change syntax table so parsing works right
12570	     (unless (eq major-mode `verilog-mode) (verilog-mode))
12571	     ;; Allow user to customize
12572	     (verilog-run-hooks 'verilog-before-auto-hook)
12573	     ;; Try to save the user from needing to revert-file to reread file local-variables
12574	     (verilog-auto-reeval-locals)
12575	     (verilog-read-auto-lisp-present)
12576	     (verilog-read-auto-lisp (point-min) (point-max))
12577	     (verilog-getopt-flags)
12578	     ;; From here on out, we can cache anything we read from disk
12579	     (verilog-preserve-dir-cache
12580	      ;; These two may seem obvious to do always, but on large includes it can be way too slow
12581	      (when verilog-auto-read-includes
12582		(verilog-read-includes)
12583		(verilog-read-defines nil nil t))
12584	      ;; Setup variables due to SystemVerilog expansion
12585	      (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic-setup)
12586	      ;; This particular ordering is important
12587	      ;; INST: Lower modules correct, no internal dependencies, FIRST
12588	      (verilog-preserve-modi-cache
12589	       ;; Clear existing autos else we'll be screwed by existing ones
12590	       (verilog-delete-auto)
12591	       ;; Injection if appropriate
12592	       (when inject
12593		 (verilog-inject-inst)
12594		 (verilog-inject-sense)
12595		 (verilog-inject-arg))
12596	       ;;
12597	       ;; Do user inserts first, so their code can insert AUTOs
12598	       ;; We may provide an AUTOINSERTLISPLAST if another cleanup pass is needed
12599	       (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
12600					  'verilog-auto-insert-lisp)
12601	       ;; Expand instances before need the signals the instances input/output
12602	       (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
12603	       (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
12604	       (verilog-auto-re-search-do "\\.\\*" 'verilog-auto-star)
12605	       ;; Doesn't matter when done, but combine it with a common changer
12606	       (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
12607	       (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
12608	       ;; Must be done before autoin/out as creates a reg
12609	       (verilog-auto-re-search-do "/\\*AUTOASCIIENUM([^)]*)\\*/" 'verilog-auto-ascii-enum)
12610	       ;;
12611	       ;; first in/outs from other files
12612	       (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE([^)]*)\\*/" 'verilog-auto-inout-module)
12613	       (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP([^)]*)\\*/" 'verilog-auto-inout-comp)
12614	       (verilog-auto-re-search-do "/\\*AUTOINOUTIN([^)]*)\\*/" 'verilog-auto-inout-in)
12615	       ;; next in/outs which need previous sucked inputs first
12616	       (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((\"[^\"]*\")\\)\\*/"
12617					  (lambda () (verilog-auto-output t)))
12618	       (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\*/" 'verilog-auto-output)
12619	       (verilog-auto-re-search-do "/\\*AUTOINPUT\\((\"[^\"]*\")\\)\\*/"
12620					  (lambda () (verilog-auto-input t)))
12621	       (verilog-auto-re-search-do "/\\*AUTOINPUT\\*/"  'verilog-auto-input)
12622	       (verilog-auto-re-search-do "/\\*AUTOINOUT\\((\"[^\"]*\")\\)\\*/"
12623					  (lambda () (verilog-auto-inout t)))
12624	       (verilog-auto-re-search-do "/\\*AUTOINOUT\\*/" 'verilog-auto-inout)
12625	       ;; Then tie off those in/outs
12626	       (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
12627	       ;; These can be anywhere after AUTOINSERTLISP
12628	       (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((\"[^\"]*\")\\)?\\*/" 'verilog-auto-undef)
12629	       ;; Wires/regs must be after inputs/outputs
12630	       (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic)
12631	       (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
12632	       (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
12633	       (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
12634	       ;; outputevery needs AUTOOUTPUTs done first
12635	       (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\*/" 'verilog-auto-output-every)
12636	       ;; After we've created all new variables
12637	       (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
12638	       ;; Must be after all inputs outputs are generated
12639	       (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
12640	       ;; Fix line numbers (comments only)
12641	       (when verilog-auto-inst-template-numbers
12642		 (verilog-auto-templated-rel))
12643	       (when verilog-auto-template-warn-unused
12644		 (verilog-auto-template-lint))))
12645	     ;;
12646	     (verilog-run-hooks 'verilog-auto-hook)
12647	     ;;
12648	     (when verilog-auto-delete-trailing-whitespace
12649	       (verilog-delete-trailing-whitespace))
12650	     ;;
12651	     (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))
12652	     ;;
12653	     ;; If end result is same as when started, clear modified flag
12654	     (cond ((and oldbuf (equal oldbuf (buffer-string)))
12655		    (set-buffer-modified-p nil)
12656		    (unless noninteractive (message "Updating AUTOs...done (no changes)")))
12657		   (t (unless noninteractive (message "Updating AUTOs...done"))))
12658	     ;; End of after-change protection
12659	     )))
12660       ;; Unwind forms
12661       ;; Currently handled in verilog-save-font-mods
12662       ))))
12663
12664
12665;;
12666;; Skeleton based code insertion
12667;;
12668(defvar verilog-template-map
12669  (let ((map (make-sparse-keymap)))
12670    (define-key map "a" 'verilog-sk-always)
12671    (define-key map "b" 'verilog-sk-begin)
12672    (define-key map "c" 'verilog-sk-case)
12673    (define-key map "f" 'verilog-sk-for)
12674    (define-key map "g" 'verilog-sk-generate)
12675    (define-key map "h" 'verilog-sk-header)
12676    (define-key map "i" 'verilog-sk-initial)
12677    (define-key map "j" 'verilog-sk-fork)
12678    (define-key map "m" 'verilog-sk-module)
12679    (define-key map "o" 'verilog-sk-ovm-class)
12680    (define-key map "p" 'verilog-sk-primitive)
12681    (define-key map "r" 'verilog-sk-repeat)
12682    (define-key map "s" 'verilog-sk-specify)
12683    (define-key map "t" 'verilog-sk-task)
12684    (define-key map "u" 'verilog-sk-uvm-class)
12685    (define-key map "w" 'verilog-sk-while)
12686    (define-key map "x" 'verilog-sk-casex)
12687    (define-key map "z" 'verilog-sk-casez)
12688    (define-key map "?" 'verilog-sk-if)
12689    (define-key map ":" 'verilog-sk-else-if)
12690    (define-key map "/" 'verilog-sk-comment)
12691    (define-key map "A" 'verilog-sk-assign)
12692    (define-key map "F" 'verilog-sk-function)
12693    (define-key map "I" 'verilog-sk-input)
12694    (define-key map "O" 'verilog-sk-output)
12695    (define-key map "S" 'verilog-sk-state-machine)
12696    (define-key map "=" 'verilog-sk-inout)
12697    (define-key map "W" 'verilog-sk-wire)
12698    (define-key map "R" 'verilog-sk-reg)
12699    (define-key map "D" 'verilog-sk-define-signal)
12700    map)
12701  "Keymap used in Verilog mode for smart template operations.")
12702
12703
12704;;
12705;; Place the templates into Verilog Mode.  They may be inserted under any key.
12706;; C-c C-t will be the default.  If you use templates a lot, you
12707;; may want to consider moving the binding to another key in your .emacs
12708;; file.
12709;;
12710;; Note \C-c and letter are reserved for users
12711(define-key verilog-mode-map "\C-c\C-t" verilog-template-map)
12712
12713;;; ---- statement skeletons ------------------------------------------
12714
12715(define-skeleton verilog-sk-prompt-condition
12716  "Prompt for the loop condition."
12717  "[condition]: " str )
12718
12719(define-skeleton verilog-sk-prompt-init
12720  "Prompt for the loop init statement."
12721  "[initial statement]: " str )
12722
12723(define-skeleton verilog-sk-prompt-inc
12724  "Prompt for the loop increment statement."
12725  "[increment statement]: " str )
12726
12727(define-skeleton verilog-sk-prompt-name
12728  "Prompt for the name of something."
12729  "[name]: " str)
12730
12731(define-skeleton verilog-sk-prompt-clock
12732  "Prompt for the name of something."
12733  "name and edge of clock(s): " str)
12734
12735(defvar verilog-sk-reset nil)
12736(defun verilog-sk-prompt-reset ()
12737  "Prompt for the name of a state machine reset."
12738  (setq verilog-sk-reset (read-string "name of reset: " "rst")))
12739
12740
12741(define-skeleton verilog-sk-prompt-state-selector
12742  "Prompt for the name of a state machine selector."
12743  "name of selector (eg {a,b,c,d}): " str )
12744
12745(define-skeleton verilog-sk-prompt-output
12746  "Prompt for the name of something."
12747  "output: " str)
12748
12749(define-skeleton verilog-sk-prompt-msb
12750  "Prompt for most significant bit specification."
12751  "msb:" str & ?: & '(verilog-sk-prompt-lsb) | -1 )
12752
12753(define-skeleton verilog-sk-prompt-lsb
12754  "Prompt for least significant bit specification."
12755  "lsb:" str )
12756
12757(defvar verilog-sk-p nil)
12758(define-skeleton verilog-sk-prompt-width
12759  "Prompt for a width specification."
12760  ()
12761  (progn
12762    (setq verilog-sk-p (point))
12763    (verilog-sk-prompt-msb)
12764    (if (> (point) verilog-sk-p) "] " " ")))
12765
12766(defun verilog-sk-header ()
12767  "Insert a descriptive header at the top of the file.
12768See also `verilog-header' for an alternative format."
12769  (interactive "*")
12770  (save-excursion
12771    (goto-char (point-min))
12772    (verilog-sk-header-tmpl)))
12773
12774(define-skeleton verilog-sk-header-tmpl
12775  "Insert a comment block containing the module title, author, etc."
12776  "[Description]: "
12777  "//                              -*- Mode: Verilog -*-"
12778  "\n// Filename        : " (buffer-name)
12779  "\n// Description     : " str
12780  "\n// Author          : " (user-full-name)
12781  "\n// Created On      : " (current-time-string)
12782  "\n// Last Modified By: " (user-full-name)
12783  "\n// Last Modified On: " (current-time-string)
12784  "\n// Update Count    : 0"
12785  "\n// Status          : Unknown, Use with caution!"
12786  "\n")
12787
12788(define-skeleton verilog-sk-module
12789  "Insert a module definition."
12790  ()
12791  > "module " '(verilog-sk-prompt-name) " (/*AUTOARG*/ ) ;" \n
12792  > _ \n
12793  > (- verilog-indent-level-behavioral) "endmodule" (progn (electric-verilog-terminate-line) nil))
12794
12795;;; ------------------------------------------------------------------------
12796;;; Define a default OVM class, with macros and new()
12797;;; ------------------------------------------------------------------------
12798
12799(define-skeleton verilog-sk-ovm-class
12800  "Insert a class definition"
12801  ()
12802  > "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
12803  > _ \n
12804  > "`ovm_object_utils_begin(" name ")" \n
12805  > (- verilog-indent-level) " `ovm_object_utils_end" \n
12806  > _ \n
12807  > "function new(name=\"" name "\");" \n
12808  > "super.new(name);" \n
12809  > (- verilog-indent-level) "endfunction" \n
12810  > _ \n
12811  > "endclass" (progn (electric-verilog-terminate-line) nil))
12812
12813(define-skeleton verilog-sk-uvm-class
12814  "Insert a class definition"
12815  ()
12816  > "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
12817  > _ \n
12818  > "`uvm_object_utils_begin(" name ")" \n
12819  > (- verilog-indent-level) " `uvm_object_utils_end" \n
12820  > _ \n
12821  > "function new(name=\"" name "\");" \n
12822  > "super.new(name);" \n
12823  > (- verilog-indent-level) "endfunction" \n
12824  > _ \n
12825  > "endclass" (progn (electric-verilog-terminate-line) nil))
12826
12827(define-skeleton verilog-sk-primitive
12828  "Insert a task definition."
12829  ()
12830  > "primitive " '(verilog-sk-prompt-name) " ( " '(verilog-sk-prompt-output) ("input:" ", " str ) " );"\n
12831  > _ \n
12832  > (- verilog-indent-level-behavioral) "endprimitive" (progn (electric-verilog-terminate-line) nil))
12833
12834(define-skeleton verilog-sk-task
12835  "Insert a task definition."
12836  ()
12837  > "task " '(verilog-sk-prompt-name) & ?; \n
12838  > _ \n
12839  > "begin" \n
12840  > \n
12841  > (- verilog-indent-level-behavioral) "end" \n
12842  > (- verilog-indent-level-behavioral) "endtask" (progn (electric-verilog-terminate-line) nil))
12843
12844(define-skeleton verilog-sk-function
12845  "Insert a function definition."
12846  ()
12847  > "function [" '(verilog-sk-prompt-width) | -1 '(verilog-sk-prompt-name) ?; \n
12848  > _ \n
12849  > "begin" \n
12850  > \n
12851  > (- verilog-indent-level-behavioral) "end" \n
12852  > (- verilog-indent-level-behavioral) "endfunction" (progn (electric-verilog-terminate-line) nil))
12853
12854(define-skeleton verilog-sk-always
12855  "Insert always block.  Uses the minibuffer to prompt
12856for sensitivity list."
12857  ()
12858  > "always @ ( /*AUTOSENSE*/ ) begin\n"
12859  > _ \n
12860  > (- verilog-indent-level-behavioral) "end" \n >
12861  )
12862
12863(define-skeleton verilog-sk-initial
12864  "Insert an initial block."
12865  ()
12866  > "initial begin\n"
12867  > _ \n
12868  > (- verilog-indent-level-behavioral) "end" \n > )
12869
12870(define-skeleton verilog-sk-specify
12871  "Insert specify block.  "
12872  ()
12873  > "specify\n"
12874  > _ \n
12875  > (- verilog-indent-level-behavioral) "endspecify" \n > )
12876
12877(define-skeleton verilog-sk-generate
12878  "Insert generate block.  "
12879  ()
12880  > "generate\n"
12881  > _ \n
12882  > (- verilog-indent-level-behavioral) "endgenerate" \n > )
12883
12884(define-skeleton verilog-sk-begin
12885  "Insert begin end block.  Uses the minibuffer to prompt for name."
12886  ()
12887  > "begin" '(verilog-sk-prompt-name) \n
12888  > _ \n
12889  > (- verilog-indent-level-behavioral) "end"
12890)
12891
12892(define-skeleton verilog-sk-fork
12893  "Insert a fork join block."
12894  ()
12895  > "fork\n"
12896  > "begin" \n
12897  > _ \n
12898  > (- verilog-indent-level-behavioral) "end" \n
12899  > "begin" \n
12900  > \n
12901  > (- verilog-indent-level-behavioral) "end" \n
12902  > (- verilog-indent-level-behavioral) "join" \n
12903  > )
12904
12905
12906(define-skeleton verilog-sk-case
12907  "Build skeleton case statement, prompting for the selector expression,
12908and the case items."
12909  "[selector expression]: "
12910  > "case (" str ") " \n
12911  > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n > )
12912  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
12913
12914(define-skeleton verilog-sk-casex
12915  "Build skeleton casex statement, prompting for the selector expression,
12916and the case items."
12917  "[selector expression]: "
12918  > "casex (" str ") " \n
12919  > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n > )
12920  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
12921
12922(define-skeleton verilog-sk-casez
12923  "Build skeleton casez statement, prompting for the selector expression,
12924and the case items."
12925  "[selector expression]: "
12926  > "casez (" str ") " \n
12927  > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n > )
12928  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
12929
12930(define-skeleton verilog-sk-if
12931  "Insert a skeleton if statement."
12932  > "if (" '(verilog-sk-prompt-condition) & ")" " begin" \n
12933  > _ \n
12934  > (- verilog-indent-level-behavioral) "end " \n )
12935
12936(define-skeleton verilog-sk-else-if
12937  "Insert a skeleton else if statement."
12938  > (verilog-indent-line) "else if ("
12939  (progn (setq verilog-sk-p (point)) nil) '(verilog-sk-prompt-condition) (if (> (point) verilog-sk-p) ") " -1 ) & " begin" \n
12940  > _ \n
12941  > "end" (progn (electric-verilog-terminate-line) nil))
12942
12943(define-skeleton verilog-sk-datadef
12944  "Common routine to get data definition."
12945  ()
12946  '(verilog-sk-prompt-width) | -1 ("name (RET to end):" str ", ") -2 ";" \n)
12947
12948(define-skeleton verilog-sk-input
12949  "Insert an input definition."
12950  ()
12951  > "input  [" '(verilog-sk-datadef))
12952
12953(define-skeleton verilog-sk-output
12954  "Insert an output definition."
12955  ()
12956  > "output [" '(verilog-sk-datadef))
12957
12958(define-skeleton verilog-sk-inout
12959  "Insert an inout definition."
12960  ()
12961  > "inout  [" '(verilog-sk-datadef))
12962
12963(defvar verilog-sk-signal nil)
12964(define-skeleton verilog-sk-def-reg
12965  "Insert a reg definition."
12966  ()
12967  > "reg    [" '(verilog-sk-prompt-width) | -1 verilog-sk-signal ";" \n (verilog-pretty-declarations-auto) )
12968
12969(defun verilog-sk-define-signal ()
12970  "Insert a definition of signal under point at top of module."
12971  (interactive "*")
12972  (let* ((sig-re "[a-zA-Z0-9_]*")
12973	 (v1 (buffer-substring
12974	       (save-excursion
12975		 (skip-chars-backward sig-re)
12976		 (point))
12977	       (save-excursion
12978		 (skip-chars-forward sig-re)
12979		 (point)))))
12980    (if (not (member v1 verilog-keywords))
12981	(save-excursion
12982	  (setq verilog-sk-signal v1)
12983	  (verilog-beg-of-defun)
12984	  (verilog-end-of-statement)
12985	  (verilog-forward-syntactic-ws)
12986	  (verilog-sk-def-reg)
12987	  (message "signal at point is %s" v1))
12988      (message "object at point (%s) is a keyword" v1))))
12989
12990(define-skeleton verilog-sk-wire
12991  "Insert a wire definition."
12992  ()
12993  > "wire   [" '(verilog-sk-datadef))
12994
12995(define-skeleton verilog-sk-reg
12996  "Insert a reg definition."
12997  ()
12998  > "reg   [" '(verilog-sk-datadef))
12999
13000(define-skeleton verilog-sk-assign
13001  "Insert a skeleton assign statement."
13002  ()
13003  > "assign " '(verilog-sk-prompt-name) " = " _ ";" \n)
13004
13005(define-skeleton verilog-sk-while
13006  "Insert a skeleton while loop statement."
13007  ()
13008  > "while ("  '(verilog-sk-prompt-condition)  ") begin" \n
13009  > _ \n
13010  > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
13011
13012(define-skeleton verilog-sk-repeat
13013  "Insert a skeleton repeat loop statement."
13014  ()
13015  > "repeat ("  '(verilog-sk-prompt-condition)  ") begin" \n
13016  > _ \n
13017  > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
13018
13019(define-skeleton verilog-sk-for
13020  "Insert a skeleton while loop statement."
13021  ()
13022  > "for ("
13023  '(verilog-sk-prompt-init) "; "
13024  '(verilog-sk-prompt-condition) "; "
13025  '(verilog-sk-prompt-inc)
13026  ") begin" \n
13027  > _ \n
13028  > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
13029
13030(define-skeleton verilog-sk-comment
13031  "Inserts three comment lines, making a display comment."
13032  ()
13033  > "/*\n"
13034  > "* " _ \n
13035  > "*/")
13036
13037(define-skeleton verilog-sk-state-machine
13038  "Insert a state machine definition."
13039  "Name of state variable: "
13040  '(setq input "state")
13041  > "// State registers for " str | -23 \n
13042  '(setq verilog-sk-state str)
13043  > "reg [" '(verilog-sk-prompt-width) | -1 verilog-sk-state ", next_" verilog-sk-state ?; \n
13044  '(setq input nil)
13045  > \n
13046  > "// State FF for " verilog-sk-state \n
13047  > "always @ ( " (read-string "clock:" "posedge clk") " or " (verilog-sk-prompt-reset) " ) begin" \n
13048  > "if ( " verilog-sk-reset " ) " verilog-sk-state " = 0; else" \n
13049  > verilog-sk-state " = next_" verilog-sk-state ?; \n
13050  > (- verilog-indent-level-behavioral) "end" (progn (electric-verilog-terminate-line) nil)
13051  > \n
13052  > "// Next State Logic for " verilog-sk-state \n
13053  > "always @ ( /*AUTOSENSE*/ ) begin\n"
13054  > "case (" '(verilog-sk-prompt-state-selector) ") " \n
13055  > ("case selector: " str ": begin" \n > "next_" verilog-sk-state " = " _ ";" \n > (- verilog-indent-level-behavioral) "end" \n )
13056  resume: >  (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil)
13057  > (- verilog-indent-level-behavioral) "end" (progn (electric-verilog-terminate-line) nil))
13058
13059
13060;;
13061;; Include file loading with mouse/return event
13062;;
13063;; idea & first impl.: M. Rouat (eldo-mode.el)
13064;; second (emacs/xemacs) impl.: G. Van der Plas (spice-mode.el)
13065
13066(if (featurep 'xemacs)
13067    (require 'overlay))
13068
13069(defconst verilog-include-file-regexp
13070  "^`include\\s-+\"\\([^\n\"]*\\)\""
13071  "Regexp that matches the include file.")
13072
13073(defvar verilog-mode-mouse-map
13074  (let ((map (make-sparse-keymap))) ; as described in info pages, make a map
13075    (set-keymap-parent map verilog-mode-map)
13076    ;; mouse button bindings
13077    (define-key map "\r"            'verilog-load-file-at-point)
13078    (if (featurep 'xemacs)
13079	(define-key map 'button2    'verilog-load-file-at-mouse);ffap-at-mouse ?
13080      (define-key map [mouse-2]     'verilog-load-file-at-mouse))
13081    (if (featurep 'xemacs)
13082	(define-key map 'Sh-button2 'mouse-yank) ; you wanna paste don't you ?
13083      (define-key map [S-mouse-2]   'mouse-yank-at-click))
13084    map)
13085  "Map containing mouse bindings for `verilog-mode'.")
13086
13087
13088(defun verilog-highlight-region (beg end old-len)
13089  "Colorize included files and modules in the (changed?) region.
13090Clicking on the middle-mouse button loads them in a buffer (as in dired)."
13091  (when (or verilog-highlight-includes
13092	    verilog-highlight-modules)
13093    (save-excursion
13094      (save-match-data  ;; A query-replace may call this function - do not disturb
13095	(verilog-save-buffer-state
13096	 (verilog-save-scan-cache
13097	  (let (end-point)
13098	    (goto-char end)
13099	    (setq end-point (point-at-eol))
13100	    (goto-char beg)
13101	    (beginning-of-line)  ; scan entire line
13102	    ;; delete overlays existing on this line
13103	    (let ((overlays (overlays-in (point) end-point)))
13104	      (while overlays
13105		(if (and
13106		     (overlay-get (car overlays) 'detachable)
13107		     (or (overlay-get (car overlays) 'verilog-include-file)
13108			 (overlay-get (car overlays) 'verilog-inst-module)))
13109		    (delete-overlay (car overlays)))
13110		(setq overlays (cdr overlays))))
13111	    ;;
13112	    ;; make new include overlays
13113	    (when verilog-highlight-includes
13114	      (while (search-forward-regexp verilog-include-file-regexp end-point t)
13115		(goto-char (match-beginning 1))
13116		(let ((ov (make-overlay (match-beginning 1) (match-end 1))))
13117		  (overlay-put ov 'start-closed 't)
13118		  (overlay-put ov 'end-closed 't)
13119		  (overlay-put ov 'evaporate 't)
13120		  (overlay-put ov 'verilog-include-file 't)
13121		  (overlay-put ov 'mouse-face 'highlight)
13122		  (overlay-put ov 'local-map verilog-mode-mouse-map))))
13123	    ;;
13124	    ;; make new module overlays
13125	    (goto-char beg)
13126	    ;; This scanner is syntax-fragile, so don't get bent
13127	    (when verilog-highlight-modules
13128	      (condition-case nil
13129		  (while (verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-point t)
13130		    (save-excursion
13131		      (goto-char (match-beginning 0))
13132		      (unless (verilog-inside-comment-or-string-p)
13133			(verilog-read-inst-module-matcher)   ;; sets match 0
13134			(let* ((ov (make-overlay (match-beginning 0) (match-end 0))))
13135			  (overlay-put ov 'start-closed 't)
13136			  (overlay-put ov 'end-closed 't)
13137			  (overlay-put ov 'evaporate 't)
13138			  (overlay-put ov 'verilog-inst-module 't)
13139			  (overlay-put ov 'mouse-face 'highlight)
13140			  (overlay-put ov 'local-map verilog-mode-mouse-map)))))
13141		(error nil)))
13142	    ;;
13143	    ;; Future highlights:
13144	    ;;  variables - make an Occur buffer of where referenced
13145	    ;;  pins - make an Occur buffer of the sig in the declaration module
13146	    )))))))
13147
13148(defun verilog-highlight-buffer ()
13149  "Colorize included files and modules across the whole buffer."
13150  ;; Invoked via verilog-mode calling font-lock then `font-lock-mode-hook'
13151  (interactive)
13152  ;; delete and remake overlays
13153  (verilog-highlight-region (point-min) (point-max) nil))
13154
13155;; Deprecated, but was interactive, so we'll keep it around
13156(defalias 'verilog-colorize-include-files-buffer 'verilog-highlight-buffer)
13157
13158;; ffap-at-mouse isn't useful for Verilog mode. It uses library paths.
13159;; so define this function to do more or less the same as ffap-at-mouse
13160;; but first resolve filename...
13161(defun verilog-load-file-at-mouse (event)
13162  "Load file under button 2 click's EVENT.
13163Files are checked based on `verilog-library-flags'."
13164  (interactive "@e")
13165  (save-excursion ;; implement a Verilog specific ffap-at-mouse
13166    (mouse-set-point event)
13167    (verilog-load-file-at-point t)))
13168
13169;; ffap isn't usable for Verilog mode. It uses library paths.
13170;; so define this function to do more or less the same as ffap
13171;; but first resolve filename...
13172(defun verilog-load-file-at-point (&optional warn)
13173  "Load file under point.
13174If WARN, throw warning if not found.
13175Files are checked based on `verilog-library-flags'."
13176  (interactive)
13177  (save-excursion ;; implement a Verilog specific ffap
13178    (let ((overlays (overlays-in (point) (point)))
13179	  hit)
13180      (while (and overlays (not hit))
13181	(when (overlay-get (car overlays) 'verilog-inst-module)
13182	  (verilog-goto-defun-file (buffer-substring
13183				    (overlay-start (car overlays))
13184				    (overlay-end (car overlays))))
13185	  (setq hit t))
13186	(setq overlays (cdr overlays)))
13187      ;; Include?
13188      (beginning-of-line)
13189      (when (and (not hit)
13190		 (looking-at verilog-include-file-regexp))
13191	(if (and (car (verilog-library-filenames
13192		       (match-string 1) (buffer-file-name)))
13193		 (file-readable-p (car (verilog-library-filenames
13194					(match-string 1) (buffer-file-name)))))
13195	    (find-file (car (verilog-library-filenames
13196			     (match-string 1) (buffer-file-name))))
13197	  (when warn
13198	    (message
13199	     "File '%s' isn't readable, use shift-mouse2 to paste in this field"
13200	     (match-string 1))))))))
13201
13202;;
13203;; Bug reporting
13204;;
13205
13206(defun verilog-faq ()
13207  "Tell the user their current version, and where to get the FAQ etc."
13208  (interactive)
13209  (with-output-to-temp-buffer "*verilog-mode help*"
13210    (princ (format "You are using verilog-mode %s\n" verilog-mode-version))
13211    (princ "\n")
13212    (princ "For new releases, see http://www.verilog.com\n")
13213    (princ "\n")
13214    (princ "For frequently asked questions, see http://www.veripool.org/verilog-mode-faq.html\n")
13215    (princ "\n")
13216    (princ "To submit a bug, use M-x verilog-submit-bug-report\n")
13217    (princ "\n")))
13218
13219(autoload 'reporter-submit-bug-report "reporter")
13220(defvar reporter-prompt-for-summary-p)
13221
13222(defun verilog-submit-bug-report ()
13223  "Submit via mail a bug report on verilog-mode.el."
13224  (interactive)
13225  (let ((reporter-prompt-for-summary-p t))
13226    (reporter-submit-bug-report
13227     "mac@verilog.com, wsnyder@wsnyder.org"
13228     (concat "verilog-mode v" verilog-mode-version)
13229     '(
13230       verilog-active-low-regexp
13231       verilog-after-save-font-hook
13232       verilog-align-ifelse
13233       verilog-assignment-delay
13234       verilog-auto-arg-sort
13235       verilog-auto-declare-nettype
13236       verilog-auto-delete-trailing-whitespace
13237       verilog-auto-endcomments
13238       verilog-auto-hook
13239       verilog-auto-ignore-concat
13240       verilog-auto-indent-on-newline
13241       verilog-auto-inout-ignore-regexp
13242       verilog-auto-input-ignore-regexp
13243       verilog-auto-inst-column
13244       verilog-auto-inst-dot-name
13245       verilog-auto-inst-interfaced-ports
13246       verilog-auto-inst-param-value
13247       verilog-auto-inst-sort
13248       verilog-auto-inst-template-numbers
13249       verilog-auto-inst-vector
13250       verilog-auto-lineup
13251       verilog-auto-newline
13252       verilog-auto-output-ignore-regexp
13253       verilog-auto-read-includes
13254       verilog-auto-reset-blocking-in-non
13255       verilog-auto-reset-widths
13256       verilog-auto-save-policy
13257       verilog-auto-sense-defines-constant
13258       verilog-auto-sense-include-inputs
13259       verilog-auto-star-expand
13260       verilog-auto-star-save
13261       verilog-auto-template-warn-unused
13262       verilog-auto-tieoff-declaration
13263       verilog-auto-tieoff-ignore-regexp
13264       verilog-auto-unused-ignore-regexp
13265       verilog-auto-wire-type
13266       verilog-before-auto-hook
13267       verilog-before-delete-auto-hook
13268       verilog-before-getopt-flags-hook
13269       verilog-before-save-font-hook
13270       verilog-cache-enabled
13271       verilog-case-indent
13272       verilog-cexp-indent
13273       verilog-compiler
13274       verilog-coverage
13275       verilog-delete-auto-hook
13276       verilog-getopt-flags-hook
13277       verilog-highlight-grouping-keywords
13278       verilog-highlight-includes
13279       verilog-highlight-modules
13280       verilog-highlight-p1800-keywords
13281       verilog-highlight-translate-off
13282       verilog-indent-begin-after-if
13283       verilog-indent-declaration-macros
13284       verilog-indent-level
13285       verilog-indent-level-behavioral
13286       verilog-indent-level-declaration
13287       verilog-indent-level-directive
13288       verilog-indent-level-module
13289       verilog-indent-lists
13290       verilog-library-directories
13291       verilog-library-extensions
13292       verilog-library-files
13293       verilog-library-flags
13294       verilog-linter
13295       verilog-minimum-comment-distance
13296       verilog-mode-hook
13297       verilog-mode-release-date
13298       verilog-mode-release-emacs
13299       verilog-mode-version
13300       verilog-preprocessor
13301       verilog-simulator
13302       verilog-tab-always-indent
13303       verilog-tab-to-comment
13304       verilog-typedef-regexp
13305       verilog-warn-fatal
13306       )
13307     nil nil
13308     (concat "Hi Mac,
13309
13310I want to report a bug.
13311
13312Before I go further, I want to say that Verilog mode has changed my life.
13313I save so much time, my files are colored nicely, my co workers respect
13314my coding ability... until now.  I'd really appreciate anything you
13315could do to help me out with this minor deficiency in the product.
13316
13317I've taken a look at the Verilog-Mode FAQ at
13318http://www.veripool.org/verilog-mode-faq.html.
13319
13320And, I've considered filing the bug on the issue tracker at
13321http://www.veripool.org/verilog-mode-bugs
13322since I realize that public bugs are easier for you to track,
13323and for others to search, but would prefer to email.
13324
13325So, to reproduce the bug, start a fresh Emacs via " invocation-name "
13326-no-init-file -no-site-file'.  In a new buffer, in Verilog mode, type
13327the code included below.
13328
13329Given those lines, I expected [[Fill in here]] to happen;
13330but instead, [[Fill in here]] happens!.
13331
13332== The code: =="))))
13333
13334(provide 'verilog-mode)
13335
13336;; Local Variables:
13337;; checkdoc-permit-comma-termination-flag:t
13338;; checkdoc-force-docstrings-flag:nil
13339;; End:
13340
13341;;; verilog-mode.el ends here
13342