* s/gnu-linux.h: Fix mark_memory typo (Bug#10286).
[bpt/emacs.git] / lisp / progmodes / verilog-mode.el
CommitLineData
6341f357 1;; verilog-mode.el --- major mode for editing verilog source in Emacs
6341f357 2
73b0cd50 3;; Copyright (C) 1996-2011 Free Software Foundation, Inc.
6341f357 4
a03c2342
WS
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
6341f357 10;;
6341f357
DN
11;; Keywords: languages
12
241760a3
SM
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
60618039
DN
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
637b4d38
GM
24;; This file is part of GNU Emacs.
25
b1fc2b50 26;; GNU Emacs is free software: you can redistribute it and/or modify
6341f357 27;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
28;; the Free Software Foundation, either version 3 of the License, or
29;; (at your option) any later version.
6341f357 30
637b4d38 31;; GNU Emacs is distributed in the hope that it will be useful,
6341f357
DN
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
b1fc2b50 37;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
6341f357
DN
38
39;;; Commentary:
40
60618039 41;; This mode borrows heavily from the Pascal-mode and the cc-mode of Emacs
6341f357
DN
42
43;; USAGE
44;; =====
45
60618039 46;; A major mode for editing Verilog HDL source code. When you have
6341f357
DN
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
60618039 55;; under continuous development. Hence this is beta code, and likely
a3a8b002
DN
56;; has bugs. Please report any issues to the issue tracker at
57;; http://www.veripool.org/verilog-mode
6341f357
DN
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
60618039 67;; your Emacs environment. Sometimes this is difficult for local
6341f357
DN
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
37ea4b9b 76;; automatic Verilog mode, put this file in your load path, and put
6341f357
DN
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 )
fd9ea9d3 81; (add-to-list 'auto-mode-alist '("\\.[ds]?vh?\\'" . verilog-mode))
6341f357 82
a03c2342
WS
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;;
6341f357 86;; If you want to customize Verilog mode to fit your needs better,
a03c2342 87;; you may add the below lines (the values of the variables presented
60618039 88;; here are the defaults). Note also that if you use an Emacs that
6341f357 89;; supports custom, it's probably better to use the custom menu to
9489a450 90;; edit these. If working as a member of a large team these settings
a03c2342
WS
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.
6341f357 94;;
a03c2342
WS
95; ;; Enable syntax highlighting of **all** languages
96; (global-font-lock-mode t)
97;
6341f357
DN
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
a3a8b002 111; verilog-auto-lineup 'declarations
6341f357
DN
112; verilog-highlight-p1800-keywords nil
113; verilog-linter "my_lint_shell_command"
114; )
115
116;; \f
117
118;;; History:
37ea4b9b 119;;
7cb1c4d7 120;; See commit history at http://www.veripool.org/verilog-mode.html
60618039
DN
121;; (This section is required to appease checkdoc.)
122
6341f357
DN
123;;; Code:
124
6341f357 125;; This variable will always hold the version number of the mode
9489a450 126(defconst verilog-mode-version "725"
1418c701 127 "Version of this Verilog mode.")
9489a450 128(defconst verilog-mode-release-date "2011-11-27-GNU"
1418c701 129 "Release date of this Verilog mode.")
60618039 130(defconst verilog-mode-release-emacs t
1418c701 131 "If non-nil, this version of Verilog mode was released with Emacs itself.")
6341f357
DN
132
133(defun verilog-version ()
134 "Inform caller of the version of this file."
135 (interactive)
7ea26faf 136 (message "Using verilog-mode version %s" verilog-mode-version))
6341f357
DN
137
138;; Insure we have certain packages, and deal with it if we don't
60618039 139;; Be sure to note which Emacs flavor and version added each feature.
6edb5716 140(eval-when-compile
7cb1c4d7 141 ;; Provide stuff if we are XEmacs
7ea26faf
DN
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))
7ea26faf
DN
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))
9489a450
MM
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))
7ea26faf
DN
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.
6341f357
DN
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."
7ea26faf
DN
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)
60618039
DN
209 (current-buffer)))))
210 )
7ea26faf
DN
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
37ea4b9b 218 "Sorry, Customize is not available with this version of Emacs"))
7ea26faf
DN
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 )
6341f357 227
7ea26faf
DN
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))
a03c2342
WS
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 ;;
7cb1c4d7
DN
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 )
6341f357 247
6341f357
DN
248;; Provide a regular expression optimization routine, using regexp-opt
249;; if provided by the user's elisp libraries
250(eval-and-compile
60618039
DN
251 ;; The below were disabled when GNU Emacs 22 was released;
252 ;; perhaps some still need to be there to support Emacs 21.
7ea26faf
DN
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
6341f357 261 ;with just a two input regexp
7ea26faf
DN
262 (defun verilog-regexp-opt (a b)
263 "Deal with differing number of required arguments for `regexp-opt'.
6341f357 264 Call 'regexp-opt' on A and B."
60618039 265 (regexp-opt a b 't))
7ea26faf
DN
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)))
6341f357 286
a03c2342
WS
287(eval-and-compile
288 ;; Both xemacs and emacs
9489a450
MM
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))
a03c2342
WS
295 (condition-case nil
296 (unless (fboundp 'buffer-chars-modified-tick) ;; Emacs 22 added
297 (defmacro buffer-chars-modified-tick () (buffer-modified-tick)))
9489a450
MM
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"))
a03c2342
WS
303 (error nil)))
304
38f584e9
DN
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) "\\>")))
a03c2342
WS
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) "\\>"))
6341f357 313
495ab0d5 314(defun verilog-easy-menu-filter (menu)
a3a8b002 315 "Filter `easy-menu-define' MENU to support new features."
495ab0d5
DN
316 (cond ((not (featurep 'xemacs))
317 menu) ;; GNU Emacs - passthru
0d26e0b6 318 ;; XEmacs doesn't support :help. Strip it.
495ab0d5
DN
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
9489a450
MM
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
6341f357 344(defun verilog-customize ()
495ab0d5 345 "Customize variables and other settings used by Verilog-Mode."
6341f357
DN
346 (interactive)
347 (customize-group 'verilog-mode))
348
349(defun verilog-font-customize ()
495ab0d5 350 "Customize fonts used by Verilog-Mode."
6341f357 351 (interactive)
7ea26faf
DN
352 (if (fboundp 'customize-apropos)
353 (customize-apropos "font-lock-*" 'faces)))
6341f357 354
eaf7efe9
DN
355(defun verilog-booleanp (value)
356 "Return t if VALUE is boolean.
a3a8b002
DN
357This implements GNU Emacs 22.1's `booleanp' function in earlier Emacs.
358This function may be removed when Emacs 21 is no longer supported."
eaf7efe9
DN
359 (or (equal value t) (equal value nil)))
360
a3a8b002
DN
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
9489a450
MM
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)))))
d63b01e1 394
6341f357 395(defgroup verilog-mode nil
37ea4b9b 396 "Facilitates easy editing of Verilog source text."
8e788369 397 :version "22.2"
6341f357
DN
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
37ea4b9b 406 "Customize indentation and highlighting of Verilog source text."
6341f357
DN
407 :group 'verilog-mode)
408
409(defgroup verilog-mode-actions nil
37ea4b9b 410 "Customize actions on Verilog source text."
6341f357
DN
411 :group 'verilog-mode)
412
413(defgroup verilog-mode-auto nil
37ea4b9b 414 "Customize AUTO actions when expanding Verilog source text."
6341f357
DN
415 :group 'verilog-mode)
416
a03c2342
WS
417(defvar verilog-debug nil
418 "If set, enable debug messages for `verilog-mode' internals.")
419
6341f357
DN
420(defcustom verilog-linter
421 "echo 'No verilog-linter set, see \"M-x describe-variable verilog-linter\"'"
37ea4b9b 422 "*Unix program and arguments to call to run a lint checker on Verilog source.
6341f357
DN
423Depending on the `verilog-set-compile-command', this may be invoked when
424you type \\[compile]. When the compile completes, \\[next-error] will take
425you to the next lint error."
426 :type 'string
427 :group 'verilog-mode-actions)
60618039 428;; We don't mark it safe, as it's used as a shell command
6341f357
DN
429
430(defcustom verilog-coverage
431 "echo 'No verilog-coverage set, see \"M-x describe-variable verilog-coverage\"'"
37ea4b9b 432 "*Program and arguments to use to annotate for coverage Verilog source.
6341f357
DN
433Depending on the `verilog-set-compile-command', this may be invoked when
434you type \\[compile]. When the compile completes, \\[next-error] will take
435you to the next lint error."
436 :type 'string
437 :group 'verilog-mode-actions)
60618039 438;; We don't mark it safe, as it's used as a shell command
6341f357
DN
439
440(defcustom verilog-simulator
441 "echo 'No verilog-simulator set, see \"M-x describe-variable verilog-simulator\"'"
37ea4b9b 442 "*Program and arguments to use to interpret Verilog source.
6341f357
DN
443Depending on the `verilog-set-compile-command', this may be invoked when
444you type \\[compile]. When the compile completes, \\[next-error] will take
445you to the next lint error."
446 :type 'string
447 :group 'verilog-mode-actions)
60618039 448;; We don't mark it safe, as it's used as a shell command
6341f357
DN
449
450(defcustom verilog-compiler
451 "echo 'No verilog-compiler set, see \"M-x describe-variable verilog-compiler\"'"
37ea4b9b 452 "*Program and arguments to use to compile Verilog source.
6341f357
DN
453Depending on the `verilog-set-compile-command', this may be invoked when
454you type \\[compile]. When the compile completes, \\[next-error] will take
455you to the next lint error."
456 :type 'string
457 :group 'verilog-mode-actions)
60618039 458;; We don't mark it safe, as it's used as a shell command
6341f357 459
a03c2342
WS
460(defcustom verilog-preprocessor
461 ;; Very few tools give preprocessed output, so we'll default to Verilog-Perl
462 "vppreproc __FLAGS__ __FILE__"
463 "*Program and arguments to use to preprocess Verilog source.
464This is invoked with `verilog-preprocess', and depending on the
465`verilog-set-compile-command', may also be invoked when you type
466\\[compile]. When the compile completes, \\[next-error] will
467take you to the next lint error."
468 :type 'string
469 :group 'verilog-mode-actions)
470;; We don't mark it safe, as it's used as a shell command
471
472(defvar verilog-preprocess-history nil
473 "History for `verilog-preprocess'.")
474
6341f357
DN
475(defvar verilog-tool 'verilog-linter
476 "Which tool to use for building compiler-command.
a03c2342
WS
477Either nil, `verilog-linter, `verilog-compiler,
478`verilog-coverage, `verilog-preprocessor, or `verilog-simulator.
479Alternatively use the \"Choose Compilation Action\" menu. See
480`verilog-set-compile-command' for more information.")
6341f357
DN
481
482(defcustom verilog-highlight-translate-off nil
483 "*Non-nil means background-highlight code excluded from translation.
484That is, all code between \"// synopsys translate_off\" and
485\"// synopsys translate_on\" is highlighted using a different background color
486\(face `verilog-font-lock-translate-off-face').
487
488Note: This will slow down on-the-fly fontification (and thus editing).
489
490Note: Activate the new setting in a Verilog buffer by re-fontifying it (menu
491entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
492 :type 'boolean
493 :group 'verilog-mode-indent)
60618039 494;; Note we don't use :safe, as that would break on Emacsen before 22.0.
eaf7efe9 495(put 'verilog-highlight-translate-off 'safe-local-variable 'verilog-booleanp)
6341f357 496
a3a8b002
DN
497(defcustom verilog-auto-lineup 'declarations
498 "*Type of statements to lineup across multiple lines.
499If 'all' is selected, then all line ups described below are done.
500
501If 'declaration', then just declarations are lined up with any
502preceding declarations, taking into account widths and the like,
503so or example the code:
504 reg [31:0] a;
505 reg b;
506would become
507 reg [31:0] a;
508 reg b;
509
510If 'assignment', then assignments are lined up with any preceding
511assignments, so for example the code
512 a_long_variable <= b + c;
513 d = e + f;
514would become
515 a_long_variable <= b + c;
516 d = e + f;
517
518In order to speed up editing, large blocks of statements are lined up
519only when a \\[verilog-pretty-expr] is typed; and large blocks of declarations
520are lineup only when \\[verilog-pretty-declarations] is typed."
521
522 :type '(radio (const :tag "Line up Assignments and Declarations" all)
523 (const :tag "Line up Assignment statements" assignments )
86a4c7ac 524 (const :tag "Line up Declarations" declarations)
a3a8b002
DN
525 (function :tag "Other"))
526 :group 'verilog-mode-indent )
527
6341f357
DN
528(defcustom verilog-indent-level 3
529 "*Indentation of Verilog statements with respect to containing block."
530 :group 'verilog-mode-indent
531 :type 'integer)
60618039 532(put 'verilog-indent-level 'safe-local-variable 'integerp)
6341f357
DN
533
534(defcustom verilog-indent-level-module 3
37ea4b9b 535 "*Indentation of Module level Verilog statements (eg always, initial).
6341f357
DN
536Set to 0 to get initial and always statements lined up on the left side of
537your screen."
538 :group 'verilog-mode-indent
539 :type 'integer)
60618039 540(put 'verilog-indent-level-module 'safe-local-variable 'integerp)
6341f357
DN
541
542(defcustom verilog-indent-level-declaration 3
543 "*Indentation of declarations with respect to containing block.
544Set to 0 to get them list right under containing block."
545 :group 'verilog-mode-indent
546 :type 'integer)
60618039 547(put 'verilog-indent-level-declaration 'safe-local-variable 'integerp)
6341f357
DN
548
549(defcustom verilog-indent-declaration-macros nil
550 "*How to treat macro expansions in a declaration.
551If nil, indent as:
552 input [31:0] a;
553 input `CP;
554 output c;
555If non nil, treat as:
556 input [31:0] a;
557 input `CP ;
558 output c;"
559 :group 'verilog-mode-indent
560 :type 'boolean)
eaf7efe9 561(put 'verilog-indent-declaration-macros 'safe-local-variable 'verilog-booleanp)
6341f357
DN
562
563(defcustom verilog-indent-lists t
564 "*How to treat indenting items in a list.
565If t (the default), indent as:
566 always @( posedge a or
567 reset ) begin
568
569If nil, treat as:
570 always @( posedge a or
571 reset ) begin"
572 :group 'verilog-mode-indent
573 :type 'boolean)
eaf7efe9 574(put 'verilog-indent-lists 'safe-local-variable 'verilog-booleanp)
6341f357
DN
575
576(defcustom verilog-indent-level-behavioral 3
577 "*Absolute indentation of first begin in a task or function block.
578Set to 0 to get such code to start at the left side of the screen."
579 :group 'verilog-mode-indent
580 :type 'integer)
60618039 581(put 'verilog-indent-level-behavioral 'safe-local-variable 'integerp)
6341f357
DN
582
583(defcustom verilog-indent-level-directive 1
584 "*Indentation to add to each level of `ifdef declarations.
585Set to 0 to have all directives start at the left side of the screen."
586 :group 'verilog-mode-indent
587 :type 'integer)
60618039 588(put 'verilog-indent-level-directive 'safe-local-variable 'integerp)
6341f357
DN
589
590(defcustom verilog-cexp-indent 2
591 "*Indentation of Verilog statements split across lines."
592 :group 'verilog-mode-indent
593 :type 'integer)
60618039 594(put 'verilog-cexp-indent 'safe-local-variable 'integerp)
6341f357
DN
595
596(defcustom verilog-case-indent 2
597 "*Indentation for case statements."
598 :group 'verilog-mode-indent
599 :type 'integer)
60618039 600(put 'verilog-case-indent 'safe-local-variable 'integerp)
6341f357
DN
601
602(defcustom verilog-auto-newline t
603 "*True means automatically newline after semicolons."
604 :group 'verilog-mode-indent
605 :type 'boolean)
eaf7efe9 606(put 'verilog-auto-newline 'safe-local-variable 'verilog-booleanp)
6341f357
DN
607
608(defcustom verilog-auto-indent-on-newline t
609 "*True means automatically indent line after newline."
610 :group 'verilog-mode-indent
611 :type 'boolean)
eaf7efe9 612(put 'verilog-auto-indent-on-newline 'safe-local-variable 'verilog-booleanp)
6341f357
DN
613
614(defcustom verilog-tab-always-indent t
615 "*True means TAB should always re-indent the current line.
37ea4b9b 616A nil value means TAB will only reindent when at the beginning of the line."
6341f357
DN
617 :group 'verilog-mode-indent
618 :type 'boolean)
eaf7efe9 619(put 'verilog-tab-always-indent 'safe-local-variable 'verilog-booleanp)
6341f357
DN
620
621(defcustom verilog-tab-to-comment nil
622 "*True means TAB moves to the right hand column in preparation for a comment."
623 :group 'verilog-mode-actions
624 :type 'boolean)
eaf7efe9 625(put 'verilog-tab-to-comment 'safe-local-variable 'verilog-booleanp)
6341f357
DN
626
627(defcustom verilog-indent-begin-after-if t
628 "*If true, indent begin statements following if, else, while, for and repeat.
629Otherwise, line them up."
630 :group 'verilog-mode-indent
60618039 631 :type 'boolean)
eaf7efe9 632(put 'verilog-indent-begin-after-if 'safe-local-variable 'verilog-booleanp)
6341f357
DN
633
634
635(defcustom verilog-align-ifelse nil
636 "*If true, align `else' under matching `if'.
637Otherwise else is lined up with first character on line holding matching if."
638 :group 'verilog-mode-indent
60618039 639 :type 'boolean)
eaf7efe9 640(put 'verilog-align-ifelse 'safe-local-variable 'verilog-booleanp)
6341f357
DN
641
642(defcustom verilog-minimum-comment-distance 10
643 "*Minimum distance (in lines) between begin and end required before a comment.
644Setting this variable to zero results in every end acquiring a comment; the
37ea4b9b 645default avoids too many redundant comments in tight quarters."
6341f357
DN
646 :group 'verilog-mode-indent
647 :type 'integer)
60618039 648(put 'verilog-minimum-comment-distance 'safe-local-variable 'integerp)
6341f357 649
6341f357 650(defcustom verilog-highlight-p1800-keywords nil
60618039
DN
651 "*True means highlight words newly reserved by IEEE-1800.
652These will appear in `verilog-font-lock-p1800-face' in order to gently
653suggest changing where these words are used as variables to something else.
37ea4b9b 654A nil value means highlight these words as appropriate for the SystemVerilog
60618039 655IEEE-1800 standard. Note that changing this will require restarting Emacs
37ea4b9b 656to see the effect as font color choices are cached by Emacs."
6341f357
DN
657 :group 'verilog-mode-indent
658 :type 'boolean)
eaf7efe9 659(put 'verilog-highlight-p1800-keywords 'safe-local-variable 'verilog-booleanp)
6341f357 660
a1ebd734
DN
661(defcustom verilog-highlight-grouping-keywords nil
662 "*True means highlight grouping keywords 'begin' and 'end' more dramatically.
a3a8b002
DN
663If false, these words are in the `font-lock-type-face'; if True then they are in
664`verilog-font-lock-ams-face'. Some find that special highlighting on these
a1ebd734
DN
665grouping constructs allow the structure of the code to be understood at a glance."
666 :group 'verilog-mode-indent
667 :type 'boolean)
b1d0fc86 668(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp)
a1ebd734 669
a03c2342
WS
670(defcustom verilog-highlight-modules nil
671 "*True means highlight module statements for `verilog-load-file-at-point'.
672When true, mousing over module names will allow jumping to the
673module definition. If false, this is not supported. Setting
674this is experimental, and may lead to bad performance."
675 :group 'verilog-mode-indent
676 :type 'boolean)
677(put 'verilog-highlight-modules 'safe-local-variable 'verilog-booleanp)
678
679(defcustom verilog-highlight-includes t
680 "*True means highlight module statements for `verilog-load-file-at-point'.
681When true, mousing over include file names will allow jumping to the
682file referenced. If false, this is not supported."
683 :group 'verilog-mode-indent
684 :type 'boolean)
685(put 'verilog-highlight-includes 'safe-local-variable 'verilog-booleanp)
686
9489a450
MM
687(defcustom verilog-auto-declare-nettype nil
688 "*Non-nil specifies the data type to use with `verilog-auto-input' etc.
689Set this to \"wire\" if the Verilog code uses \"`default_nettype
690none\". Note using `default_nettype none isn't recommended practice; this
691mode is experimental."
692 :group 'verilog-mode-actions
693 :type 'boolean)
694(put 'verilog-auto-declare-nettype 'safe-local-variable `stringp)
695
696(defcustom verilog-auto-wire-type nil
697 "*Non-nil specifies the data type to use with `verilog-auto-wire' etc.
698Set this to \"logic\" for SystemVerilog code, or use `verilog-auto-logic'."
699 :group 'verilog-mode-actions
700 :type 'boolean)
701(put 'verilog-auto-wire-type 'safe-local-variable `stringp)
702
6341f357
DN
703(defcustom verilog-auto-endcomments t
704 "*True means insert a comment /* ... */ after 'end's.
705The name of the function or case will be set between the braces."
706 :group 'verilog-mode-actions
60618039 707 :type 'boolean)
eaf7efe9 708(put 'verilog-auto-endcomments 'safe-local-variable 'verilog-booleanp)
6341f357 709
9489a450
MM
710(defcustom verilog-auto-delete-trailing-whitespace nil
711 "*True means to `delete-trailing-whitespace' in `verilog-auto'."
712 :group 'verilog-mode-actions
713 :type 'boolean)
714(put 'verilog-auto-delete-trailing-whitespace 'safe-local-variable 'verilog-booleanp)
715
14862301
SM
716(defcustom verilog-auto-ignore-concat nil
717 "*True means ignore signals in {...} concatenations for AUTOWIRE etc.
718This will exclude signals referenced as pin connections in {...}
719from AUTOWIRE, AUTOOUTPUT and friends. This flag should be set
720for backward compatibility only and not set in new designs; it
721may be removed in future versions."
722 :group 'verilog-mode-actions
723 :type 'boolean)
724(put 'verilog-auto-ignore-concat 'safe-local-variable 'verilog-booleanp)
725
6341f357
DN
726(defcustom verilog-auto-read-includes nil
727 "*True means to automatically read includes before AUTOs.
728This will do a `verilog-read-defines' and `verilog-read-includes' before
729each AUTO expansion. This makes it easier to embed defines and includes,
730but can result in very slow reading times if there are many or large
731include files."
732 :group 'verilog-mode-actions
60618039 733 :type 'boolean)
eaf7efe9 734(put 'verilog-auto-read-includes 'safe-local-variable 'verilog-booleanp)
6341f357
DN
735
736(defcustom verilog-auto-save-policy nil
737 "*Non-nil indicates action to take when saving a Verilog buffer with AUTOs.
738A value of `force' will always do a \\[verilog-auto] automatically if
739needed on every save. A value of `detect' will do \\[verilog-auto]
740automatically when it thinks necessary. A value of `ask' will query the
741user when it thinks updating is needed.
742
743You should not rely on the 'ask or 'detect policies, they are safeguards
744only. They do not detect when AUTOINSTs need to be updated because a
745sub-module's port list has changed."
746 :group 'verilog-mode-actions
747 :type '(choice (const nil) (const ask) (const detect) (const force)))
748
749(defcustom verilog-auto-star-expand t
750 "*Non-nil indicates to expand a SystemVerilog .* instance ports.
751They will be expanded in the same way as if there was a AUTOINST in the
752instantiation. See also `verilog-auto-star' and `verilog-auto-star-save'."
753 :group 'verilog-mode-actions
754 :type 'boolean)
eaf7efe9 755(put 'verilog-auto-star-expand 'safe-local-variable 'verilog-booleanp)
6341f357
DN
756
757(defcustom verilog-auto-star-save nil
758 "*Non-nil indicates to save to disk SystemVerilog .* instance expansions.
37ea4b9b
JB
759A nil value indicates direct connections will be removed before saving.
760Only meaningful to those created due to `verilog-auto-star-expand' being set.
6341f357
DN
761
762Instead of setting this, you may want to use /*AUTOINST*/, which will
763always be saved."
764 :group 'verilog-mode-actions
765 :type 'boolean)
eaf7efe9 766(put 'verilog-auto-star-save 'safe-local-variable 'verilog-booleanp)
6341f357
DN
767
768(defvar verilog-auto-update-tick nil
769 "Modification tick at which autos were last performed.")
770
771(defvar verilog-auto-last-file-locals nil
772 "Text from file-local-variables during last evaluation.")
773
9489a450
MM
774(defvar verilog-diff-function 'verilog-diff-report
775 "*Function to run when `verilog-diff-auto' detects differences.
776Function takes three arguments, the original buffer, the
777difference buffer, and the point in original buffer with the
778first difference.")
779
a3a8b002
DN
780;;; Compile support
781(require 'compile)
d88782c3 782(defvar verilog-error-regexp-added nil)
a03c2342 783
d88782c3
DN
784(defvar verilog-error-regexp-emacs-alist
785 '(
786 (verilog-xl-1
787 "\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 3)
788 (verilog-xl-2
789 "([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 1 3)
790 (verilog-IES
a03c2342 791 ".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)" 2 3)
d88782c3
DN
792 (verilog-surefire-1
793 "[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 2)
794 (verilog-surefire-2
795 "\\(WARNING\\|ERROR\\|INFO\\)[^:]*: \\([^,]+\\),\\s-+\\(line \\)?\\([0-9]+\\):" 2 4 )
796 (verilog-verbose
797 "\
798\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
799:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 2 5)
800 (verilog-xsim
801 "\\(Error\\|Warning\\).*in file (\\([^ \t]+\\) at line *\\([0-9]+\\))" 2 3)
802 (verilog-vcs-1
803 "\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 3)
804 (verilog-vcs-2
805 "Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 2)
806 (verilog-vcs-3
807 "\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 3)
808 (verilog-vcs-4
809 "syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 2)
810 (verilog-verilator
811 "%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4)
812 (verilog-leda
a03c2342 813 "^In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\(Warning\\|Error\\|Failure\\)[^\n]*" 1 2)
d88782c3 814 )
a03c2342
WS
815 "List of regexps for Verilog compilers.
816See `compilation-error-regexp-alist' for the formatting. For Emacs 22+.")
817
818(defvar verilog-error-regexp-xemacs-alist
819 ;; Emacs form is '((v-tool "re" 1 2) ...)
820 ;; XEmacs form is '(verilog ("re" 1 2) ...)
0d26e0b6 821 ;; So we can just map from Emacs to XEmacs
a03c2342
WS
822 (cons 'verilog (mapcar 'cdr verilog-error-regexp-emacs-alist))
823 "List of regexps for Verilog compilers.
824See `compilation-error-regexp-alist-alist' for the formatting. For XEmacs.")
6341f357
DN
825
826(defvar verilog-error-font-lock-keywords
827 '(
a03c2342
WS
828 ;; verilog-xl-1
829 ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
830 ("\\(Error\\|Warning\\)!.*\n?.*\"\\([^\"]+\\)\", \\([0-9]+\\)" 2 bold t)
831 ;; verilog-xl-2
832 ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 1 bold t)
833 ("([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\(line[ \t]+\\)?\\([0-9]+\\):.*$" 3 bold t)
834 ;; verilog-IES (nc-verilog)
835 (".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)|" 2 bold t)
836 (".*\\*[WE],[0-9A-Z]+\\(\[[0-9A-Z_,]+\]\\)? (\\([^ \t,]+\\),\\([0-9]+\\)|" 3 bold t)
837 ;; verilog-surefire-1
6341f357
DN
838 ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 1 bold t)
839 ("[^\n]*\\[\\([^:]+\\):\\([0-9]+\\)\\]" 2 bold t)
a03c2342 840 ;; verilog-surefire-2
6341f357
DN
841 ("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 2 bold t)
842 ("\\(WARNING\\|ERROR\\|INFO\\): \\([^,]+\\), line \\([0-9]+\\):" 3 bold t)
a03c2342 843 ;; verilog-verbose
6341f357
DN
844 ("\
845\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
846:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 bold t)
847 ("\
848\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
849:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 bold t)
a03c2342 850 ;; verilog-vcs-1
6341f357
DN
851 ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 2 bold t)
852 ("\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\) line *\\([0-9]+\\))" 3 bold t)
a03c2342 853 ;; verilog-vcs-2
6341f357
DN
854 ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
855 ("Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 bold t)
a03c2342 856 ;; verilog-vcs-3
6341f357
DN
857 ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
858 ("\\(Error\\|Warning\\):[\n.]*\\([^ \t]+\\) *\\([0-9]+\\):" 3 bold t)
a03c2342 859 ;; verilog-vcs-4
6341f357
DN
860 ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 1 bold t)
861 ("syntax error:.*\n\\([^ \t]+\\) *\\([0-9]+\\):" 2 bold t)
a03c2342
WS
862 ;; verilog-verilator
863 (".*%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 bold t)
864 (".*%?\\(Error\\|Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 4 bold t)
865 ;; verilog-leda
866 ("^In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\(Warning\\|Error\\|Failure\\)[^\n]*" 1 bold t)
867 ("^In file \\([^ \t]+\\)[ \t]+line[ \t]+\\([0-9]+\\):\n[^\n]*\n[^\n]*\n\\(Warning\\|Error\\|Failure\\)[^\n]*" 2 bold t)
6341f357 868 )
a03c2342
WS
869 "*Keywords to also highlight in Verilog *compilation* buffers.
870Only used in XEmacs; GNU Emacs uses `verilog-error-regexp-emacs-alist'.")
6341f357
DN
871
872(defcustom verilog-library-flags '("")
873 "*List of standard Verilog arguments to use for /*AUTOINST*/.
874These arguments are used to find files for `verilog-auto', and match
875the flags accepted by a standard Verilog-XL simulator.
876
877 -f filename Reads more `verilog-library-flags' from the filename.
878 +incdir+dir Adds the directory to `verilog-library-directories'.
879 -Idir Adds the directory to `verilog-library-directories'.
880 -y dir Adds the directory to `verilog-library-directories'.
881 +libext+.v Adds the extensions to `verilog-library-extensions'.
882 -v filename Adds the filename to `verilog-library-files'.
883
884 filename Adds the filename to `verilog-library-files'.
885 This is not recommended, -v is a better choice.
886
887You might want these defined in each file; put at the *END* of your file
888something like:
889
890 // Local Variables:
891 // verilog-library-flags:(\"-y dir -y otherdir\")
892 // End:
893
894Verilog-mode attempts to detect changes to this local variable, but they
37ea4b9b 895are only insured to be correct when the file is first visited. Thus if you
6341f357
DN
896have problems, use \\[find-alternate-file] RET to have these take effect.
897
898See also the variables mentioned above."
899 :group 'verilog-mode-auto
900 :type '(repeat string))
60618039 901(put 'verilog-library-flags 'safe-local-variable 'listp)
6341f357
DN
902
903(defcustom verilog-library-directories '(".")
904 "*List of directories when looking for files for /*AUTOINST*/.
905The directory may be relative to the current file, or absolute.
906Environment variables are also expanded in the directory names.
907Having at least the current directory is a good idea.
908
909You might want these defined in each file; put at the *END* of your file
910something like:
911
912 // Local Variables:
913 // verilog-library-directories:(\".\" \"subdir\" \"subdir2\")
914 // End:
915
916Verilog-mode attempts to detect changes to this local variable, but they
37ea4b9b 917are only insured to be correct when the file is first visited. Thus if you
6341f357
DN
918have problems, use \\[find-alternate-file] RET to have these take effect.
919
920See also `verilog-library-flags', `verilog-library-files'
921and `verilog-library-extensions'."
922 :group 'verilog-mode-auto
923 :type '(repeat file))
60618039 924(put 'verilog-library-directories 'safe-local-variable 'listp)
6341f357
DN
925
926(defcustom verilog-library-files '()
60618039
DN
927 "*List of files to search for modules.
928AUTOINST will use this when it needs to resolve a module name.
6341f357
DN
929This is a complete path, usually to a technology file with many standard
930cells defined in it.
931
932You might want these defined in each file; put at the *END* of your file
933something like:
934
935 // Local Variables:
936 // verilog-library-files:(\"/some/path/technology.v\" \"/some/path/tech2.v\")
937 // End:
938
939Verilog-mode attempts to detect changes to this local variable, but they
37ea4b9b 940are only insured to be correct when the file is first visited. Thus if you
6341f357
DN
941have problems, use \\[find-alternate-file] RET to have these take effect.
942
943See also `verilog-library-flags', `verilog-library-directories'."
944 :group 'verilog-mode-auto
945 :type '(repeat directory))
60618039 946(put 'verilog-library-files 'safe-local-variable 'listp)
6341f357 947
7cb1c4d7 948(defcustom verilog-library-extensions '(".v" ".sv")
6341f357
DN
949 "*List of extensions to use when looking for files for /*AUTOINST*/.
950See also `verilog-library-flags', `verilog-library-directories'."
951 :type '(repeat string)
952 :group 'verilog-mode-auto)
60618039 953(put 'verilog-library-extensions 'safe-local-variable 'listp)
6341f357
DN
954
955(defcustom verilog-active-low-regexp nil
956 "*If set, treat signals matching this regexp as active low.
957This is used for AUTORESET and AUTOTIEOFF. For proper behavior,
958you will probably also need `verilog-auto-reset-widths' set."
959 :group 'verilog-mode-auto
960 :type 'string)
60618039 961(put 'verilog-active-low-regexp 'safe-local-variable 'stringp)
6341f357
DN
962
963(defcustom verilog-auto-sense-include-inputs nil
964 "*If true, AUTOSENSE should include all inputs.
965If nil, only inputs that are NOT output signals in the same block are
966included."
60618039
DN
967 :group 'verilog-mode-auto
968 :type 'boolean)
eaf7efe9 969(put 'verilog-auto-sense-include-inputs 'safe-local-variable 'verilog-booleanp)
6341f357
DN
970
971(defcustom verilog-auto-sense-defines-constant nil
972 "*If true, AUTOSENSE should assume all defines represent constants.
973When true, the defines will not be included in sensitivity lists. To
974maintain compatibility with other sites, this should be set at the bottom
37ea4b9b 975of each Verilog file that requires it, rather than being set globally."
60618039
DN
976 :group 'verilog-mode-auto
977 :type 'boolean)
eaf7efe9 978(put 'verilog-auto-sense-defines-constant 'safe-local-variable 'verilog-booleanp)
6341f357 979
9489a450
MM
980(defcustom verilog-auto-reset-blocking-in-non t
981 "*If true, AUTORESET will reset those signals which were
982assigned with blocking assignments (=) even in a block with
983non-blocking assignments (<=).
984
985If nil, all blocking assigned signals are ignored when any
986non-blocking assignment is in the AUTORESET block. This allows
987blocking assignments to be used for temporary values and not have
988those temporaries reset. See example in `verilog-auto-reset'."
989 :type 'boolean
990 :group 'verilog-mode-auto)
991(put 'verilog-auto-reset-blocking-in-non 'safe-local-variable 'verilog-booleanp)
992
6341f357
DN
993(defcustom verilog-auto-reset-widths t
994 "*If true, AUTORESET should determine the width of signals.
995This is then used to set the width of the zero (32'h0 for example). This
996is required by some lint tools that aren't smart enough to ignore widths of
997the constant zero. This may result in ugly code when parameters determine
37ea4b9b 998the MSB or LSB of a signal inside an AUTORESET."
6341f357
DN
999 :type 'boolean
1000 :group 'verilog-mode-auto)
eaf7efe9 1001(put 'verilog-auto-reset-widths 'safe-local-variable 'verilog-booleanp)
6341f357
DN
1002
1003(defcustom verilog-assignment-delay ""
1004 "*Text used for delays in delayed assignments. Add a trailing space if set."
60618039
DN
1005 :group 'verilog-mode-auto
1006 :type 'string)
1007(put 'verilog-assignment-delay 'safe-local-variable 'stringp)
6341f357 1008
a3a8b002 1009(defcustom verilog-auto-arg-sort nil
4c36be58 1010 "*If set, AUTOARG signal names will be sorted, not in declaration order.
14862301
SM
1011Declaration order is advantageous with order based instantiations
1012and is the default for backward compatibility. Sorted order
1013reduces changes when declarations are moved around in a file, and
9489a450
MM
1014it's bad practice to rely on order based instantiations anyhow.
1015
1016See also `verilog-auto-inst-sort'."
a3a8b002
DN
1017 :group 'verilog-mode-auto
1018 :type 'boolean)
1019(put 'verilog-auto-arg-sort 'safe-local-variable 'verilog-booleanp)
1020
a03c2342
WS
1021(defcustom verilog-auto-inst-dot-name nil
1022 "*If true, when creating ports with AUTOINST, use .name syntax.
1023This will use \".port\" instead of \".port(port)\" when possible.
1024This is only legal in SystemVerilog files, and will confuse older
1025simulators. Setting `verilog-auto-inst-vector' to nil may also
1026be desirable to increase how often .name will be used."
1027 :group 'verilog-mode-auto
1028 :type 'boolean)
1029(put 'verilog-auto-inst-dot-name 'safe-local-variable 'verilog-booleanp)
1030
4c5e69c6
DN
1031(defcustom verilog-auto-inst-param-value nil
1032 "*If set, AUTOINST will replace parameters with the parameter value.
1033If nil, leave parameters as symbolic names.
1034
1035Parameters must be in Verilog 2001 format #(...), and if a parameter is not
1036listed as such there (as when the default value is acceptable), it will not
1037be replaced, and will remain symbolic.
1038
1039For example, imagine a submodule uses parameters to declare the size of its
1040inputs. This is then used by a upper module:
1041
a03c2342 1042 module InstModule (o,i);
4c5e69c6
DN
1043 parameter WIDTH;
1044 input [WIDTH-1:0] i;
1045 endmodule
1046
1047 module ExampInst;
1048 InstModule
1049 #(PARAM(10))
1050 instName
1051 (/*AUTOINST*/
1052 .i (i[PARAM-1:0]));
1053
1054Note even though PARAM=10, the AUTOINST has left the parameter as a
1055symbolic name. If `verilog-auto-inst-param-value' is set, this will
1056instead expand to:
1057
1058 module ExampInst;
1059 InstModule
1060 #(PARAM(10))
1061 instName
1062 (/*AUTOINST*/
1063 .i (i[9:0]));"
1064 :group 'verilog-mode-auto
1065 :type 'boolean)
7cb1c4d7 1066(put 'verilog-auto-inst-param-value 'safe-local-variable 'verilog-booleanp)
4c5e69c6 1067
9489a450
MM
1068(defcustom verilog-auto-inst-sort nil
1069 "*If set, AUTOINST signal names will be sorted, not in declaration order.
1070Also affects AUTOINSTPARAM. Declaration order is the default for
1071backward compatibility, and as some teams prefer signals that are
1072declared together to remain together. Sorted order reduces
1073changes when declarations are moved around in a file.
1074
1075See also `verilog-auto-arg-sort'."
1076 :group 'verilog-mode-auto
1077 :type 'boolean)
1078(put 'verilog-auto-inst-sort 'safe-local-variable 'verilog-booleanp)
1079
6341f357
DN
1080(defcustom verilog-auto-inst-vector t
1081 "*If true, when creating default ports with AUTOINST, use bus subscripts.
1082If nil, skip the subscript when it matches the entire bus as declared in
1083the module (AUTOWIRE signals always are subscripted, you must manually
37ea4b9b
JB
1084declare the wire to have the subscripts removed.) Setting this to nil may
1085speed up some simulators, but is less general and harder to read, so avoid."
6341f357 1086 :group 'verilog-mode-auto
60618039 1087 :type 'boolean)
eaf7efe9 1088(put 'verilog-auto-inst-vector 'safe-local-variable 'verilog-booleanp)
6341f357
DN
1089
1090(defcustom verilog-auto-inst-template-numbers nil
1091 "*If true, when creating templated ports with AUTOINST, add a comment.
9489a450
MM
1092
1093If t, the comment will add the line number of the template that
1094was used for that port declaration. This setting is suggested
1095only for debugging use, as regular use may cause a large numbers
1096of merge conflicts.
1097
1098If 'lhs', the comment will show the left hand side of the
1099AUTO_TEMPLATE rule that is matched. This is less precise than
1100numbering (t) when multiple rules have the same pin name, but
1101won't merge conflict."
6341f357 1102 :group 'verilog-mode-auto
9489a450
MM
1103 :type '(choice (const nil) (const t) (const lhs)))
1104(put 'verilog-auto-inst-template-numbers 'safe-local-variable
1105 '(lambda (x) (memq x '(nil t lhs))))
6341f357 1106
4c5e69c6
DN
1107(defcustom verilog-auto-inst-column 40
1108 "*Indent-to column number for net name part of AUTOINST created pin."
1109 :group 'verilog-mode-indent
1110 :type 'integer)
1111(put 'verilog-auto-inst-column 'safe-local-variable 'integerp)
6341f357
DN
1112
1113(defcustom verilog-auto-input-ignore-regexp nil
1114 "*If set, when creating AUTOINPUT list, ignore signals matching this regexp.
1115See the \\[verilog-faq] for examples on using this."
1116 :group 'verilog-mode-auto
60618039
DN
1117 :type 'string)
1118(put 'verilog-auto-input-ignore-regexp 'safe-local-variable 'stringp)
6341f357
DN
1119
1120(defcustom verilog-auto-inout-ignore-regexp nil
1121 "*If set, when creating AUTOINOUT list, ignore signals matching this regexp.
1122See the \\[verilog-faq] for examples on using this."
1123 :group 'verilog-mode-auto
60618039
DN
1124 :type 'string)
1125(put 'verilog-auto-inout-ignore-regexp 'safe-local-variable 'stringp)
6341f357
DN
1126
1127(defcustom verilog-auto-output-ignore-regexp nil
1128 "*If set, when creating AUTOOUTPUT list, ignore signals matching this regexp.
1129See the \\[verilog-faq] for examples on using this."
1130 :group 'verilog-mode-auto
60618039
DN
1131 :type 'string)
1132(put 'verilog-auto-output-ignore-regexp 'safe-local-variable 'stringp)
6341f357 1133
9489a450
MM
1134(defcustom verilog-auto-tieoff-declaration "wire"
1135 "*Data type used for the declaration for AUTOTIEOFF. If \"wire\" then
1136create a wire, if \"assign\" create an assignment, else the data type for
1137variable creation."
1138 :group 'verilog-mode-auto
1139 :type 'string)
1140(put 'verilog-auto-tieoff-declaration 'safe-local-variable 'stringp)
1141
a03c2342
WS
1142(defcustom verilog-auto-tieoff-ignore-regexp nil
1143 "*If set, when creating AUTOTIEOFF list, ignore signals matching this regexp.
1144See the \\[verilog-faq] for examples on using this."
1145 :group 'verilog-mode-auto
1146 :type 'string)
1147(put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable 'stringp)
1148
6341f357
DN
1149(defcustom verilog-auto-unused-ignore-regexp nil
1150 "*If set, when creating AUTOUNUSED list, ignore signals matching this regexp.
1151See the \\[verilog-faq] for examples on using this."
1152 :group 'verilog-mode-auto
60618039
DN
1153 :type 'string)
1154(put 'verilog-auto-unused-ignore-regexp 'safe-local-variable 'stringp)
6341f357
DN
1155
1156(defcustom verilog-typedef-regexp nil
1157 "*If non-nil, regular expression that matches Verilog-2001 typedef names.
1158For example, \"_t$\" matches typedefs named with _t, as in the C language."
1159 :group 'verilog-mode-auto
60618039
DN
1160 :type 'string)
1161(put 'verilog-typedef-regexp 'safe-local-variable 'stringp)
6341f357
DN
1162
1163(defcustom verilog-mode-hook 'verilog-set-compile-command
37ea4b9b 1164 "*Hook run after Verilog mode is loaded."
6341f357
DN
1165 :type 'hook
1166 :group 'verilog-mode)
1167
1168(defcustom verilog-auto-hook nil
1169 "*Hook run after `verilog-mode' updates AUTOs."
60618039
DN
1170 :group 'verilog-mode-auto
1171 :type 'hook)
6341f357
DN
1172
1173(defcustom verilog-before-auto-hook nil
1174 "*Hook run before `verilog-mode' updates AUTOs."
60618039
DN
1175 :group 'verilog-mode-auto
1176 :type 'hook)
6341f357
DN
1177
1178(defcustom verilog-delete-auto-hook nil
1179 "*Hook run after `verilog-mode' deletes AUTOs."
60618039
DN
1180 :group 'verilog-mode-auto
1181 :type 'hook)
6341f357
DN
1182
1183(defcustom verilog-before-delete-auto-hook nil
1184 "*Hook run before `verilog-mode' deletes AUTOs."
60618039
DN
1185 :group 'verilog-mode-auto
1186 :type 'hook)
6341f357
DN
1187
1188(defcustom verilog-getopt-flags-hook nil
1189 "*Hook run after `verilog-getopt-flags' determines the Verilog option lists."
60618039
DN
1190 :group 'verilog-mode-auto
1191 :type 'hook)
6341f357
DN
1192
1193(defcustom verilog-before-getopt-flags-hook nil
1194 "*Hook run before `verilog-getopt-flags' determines the Verilog option lists."
60618039
DN
1195 :group 'verilog-mode-auto
1196 :type 'hook)
6341f357
DN
1197
1198(defvar verilog-imenu-generic-expression
1199 '((nil "^\\s-*\\(\\(m\\(odule\\|acromodule\\)\\)\\|primitive\\)\\s-+\\([a-zA-Z0-9_.:]+\\)" 4)
1200 ("*Vars*" "^\\s-*\\(reg\\|wire\\)\\s-+\\(\\|\\[[^]]+\\]\\s-+\\)\\([A-Za-z0-9_]+\\)" 3))
37ea4b9b 1201 "Imenu expression for Verilog mode. See `imenu-generic-expression'.")
6341f357
DN
1202
1203;;
1204;; provide a verilog-header function.
1205;; Customization variables:
1206;;
1207(defvar verilog-date-scientific-format nil
1208 "*If non-nil, dates are written in scientific format (e.g. 1997/09/17).
1209If nil, in European format (e.g. 17.09.1997). The brain-dead American
1210format (e.g. 09/17/1997) is not supported.")
1211
1212(defvar verilog-company nil
37ea4b9b 1213 "*Default name of Company for Verilog header.
6341f357 1214If set will become buffer local.")
7ea26faf
DN
1215(make-variable-buffer-local 'verilog-company)
1216
6341f357 1217(defvar verilog-project nil
37ea4b9b 1218 "*Default name of Project for Verilog header.
6341f357 1219If set will become buffer local.")
7ea26faf
DN
1220(make-variable-buffer-local 'verilog-project)
1221
7d49d8e1 1222(defvar verilog-mode-map
6edb5716
DN
1223 (let ((map (make-sparse-keymap)))
1224 (define-key map ";" 'electric-verilog-semi)
1225 (define-key map [(control 59)] 'electric-verilog-semi-with-comment)
1226 (define-key map ":" 'electric-verilog-colon)
1227 ;;(define-key map "=" 'electric-verilog-equal)
1228 (define-key map "\`" 'electric-verilog-tick)
1229 (define-key map "\t" 'electric-verilog-tab)
1230 (define-key map "\r" 'electric-verilog-terminate-line)
1231 ;; backspace/delete key bindings
1232 (define-key map [backspace] 'backward-delete-char-untabify)
1233 (unless (boundp 'delete-key-deletes-forward) ; XEmacs variable
1234 (define-key map [delete] 'delete-char)
1235 (define-key map [(meta delete)] 'kill-word))
1236 (define-key map "\M-\C-b" 'electric-verilog-backward-sexp)
1237 (define-key map "\M-\C-f" 'electric-verilog-forward-sexp)
1238 (define-key map "\M-\r" `electric-verilog-terminate-and-indent)
1239 (define-key map "\M-\t" 'verilog-complete-word)
1240 (define-key map "\M-?" 'verilog-show-completions)
9489a450 1241 ;; Note \C-c and letter are reserved for users
6edb5716
DN
1242 (define-key map "\C-c\`" 'verilog-lint-off)
1243 (define-key map "\C-c\*" 'verilog-delete-auto-star-implicit)
9489a450 1244 (define-key map "\C-c\?" 'verilog-diff-auto)
6edb5716
DN
1245 (define-key map "\C-c\C-r" 'verilog-label-be)
1246 (define-key map "\C-c\C-i" 'verilog-pretty-declarations)
1247 (define-key map "\C-c=" 'verilog-pretty-expr)
1248 (define-key map "\C-c\C-b" 'verilog-submit-bug-report)
1249 (define-key map "\M-*" 'verilog-star-comment)
1250 (define-key map "\C-c\C-c" 'verilog-comment-region)
1251 (define-key map "\C-c\C-u" 'verilog-uncomment-region)
e1776067
DN
1252 (when (featurep 'xemacs)
1253 (define-key map [(meta control h)] 'verilog-mark-defun)
1254 (define-key map "\M-\C-a" 'verilog-beg-of-defun)
1255 (define-key map "\M-\C-e" 'verilog-end-of-defun))
6edb5716
DN
1256 (define-key map "\C-c\C-d" 'verilog-goto-defun)
1257 (define-key map "\C-c\C-k" 'verilog-delete-auto)
1258 (define-key map "\C-c\C-a" 'verilog-auto)
1259 (define-key map "\C-c\C-s" 'verilog-auto-save-compile)
a03c2342 1260 (define-key map "\C-c\C-p" 'verilog-preprocess)
6edb5716
DN
1261 (define-key map "\C-c\C-z" 'verilog-inject-auto)
1262 (define-key map "\C-c\C-e" 'verilog-expand-vector)
30d48f20
DN
1263 (define-key map "\C-c\C-h" 'verilog-header)
1264 map)
6341f357 1265 "Keymap used in Verilog mode.")
6341f357
DN
1266
1267;; menus
7d55bf04
DN
1268(easy-menu-define
1269 verilog-menu verilog-mode-map "Menu for Verilog mode"
495ab0d5
DN
1270 (verilog-easy-menu-filter
1271 '("Verilog"
1272 ("Choose Compilation Action"
1273 ["None"
1274 (progn
1275 (setq verilog-tool nil)
1276 (verilog-set-compile-command))
1277 :style radio
1278 :selected (equal verilog-tool nil)
1279 :help "When invoking compilation, use compile-command"]
1280 ["Lint"
1281 (progn
1282 (setq verilog-tool 'verilog-linter)
1283 (verilog-set-compile-command))
1284 :style radio
1285 :selected (equal verilog-tool `verilog-linter)
1286 :help "When invoking compilation, use lint checker"]
1287 ["Coverage"
1288 (progn
1289 (setq verilog-tool 'verilog-coverage)
1290 (verilog-set-compile-command))
1291 :style radio
1292 :selected (equal verilog-tool `verilog-coverage)
1293 :help "When invoking compilation, annotate for coverage"]
1294 ["Simulator"
1295 (progn
1296 (setq verilog-tool 'verilog-simulator)
1297 (verilog-set-compile-command))
1298 :style radio
1299 :selected (equal verilog-tool `verilog-simulator)
1300 :help "When invoking compilation, interpret Verilog source"]
1301 ["Compiler"
1302 (progn
1303 (setq verilog-tool 'verilog-compiler)
1304 (verilog-set-compile-command))
1305 :style radio
1306 :selected (equal verilog-tool `verilog-compiler)
1307 :help "When invoking compilation, compile Verilog source"]
a03c2342
WS
1308 ["Preprocessor"
1309 (progn
1310 (setq verilog-tool 'verilog-preprocessor)
1311 (verilog-set-compile-command))
1312 :style radio
1313 :selected (equal verilog-tool `verilog-preprocessor)
1314 :help "When invoking compilation, preprocess Verilog source, see also `verilog-preprocess'"]
495ab0d5
DN
1315 )
1316 ("Move"
1317 ["Beginning of function" verilog-beg-of-defun
1318 :keys "C-M-a"
1319 :help "Move backward to the beginning of the current function or procedure"]
1320 ["End of function" verilog-end-of-defun
1321 :keys "C-M-e"
1322 :help "Move forward to the end of the current function or procedure"]
1323 ["Mark function" verilog-mark-defun
1324 :keys "C-M-h"
1325 :help "Mark the current Verilog function or procedure"]
1326 ["Goto function/module" verilog-goto-defun
1327 :help "Move to specified Verilog module/task/function"]
1328 ["Move to beginning of block" electric-verilog-backward-sexp
1329 :help "Move backward over one balanced expression"]
1330 ["Move to end of block" electric-verilog-forward-sexp
1331 :help "Move forward over one balanced expression"]
1332 )
1333 ("Comments"
1334 ["Comment Region" verilog-comment-region
1335 :help "Put marked area into a comment"]
1336 ["UnComment Region" verilog-uncomment-region
1337 :help "Uncomment an area commented with Comment Region"]
1338 ["Multi-line comment insert" verilog-star-comment
1339 :help "Insert Verilog /* */ comment at point"]
1340 ["Lint error to comment" verilog-lint-off
1341 :help "Convert a Verilog linter warning line into a disable statement"]
1342 )
1343 "----"
1344 ["Compile" compile
1345 :help "Perform compilation-action (above) on the current buffer"]
1346 ["AUTO, Save, Compile" verilog-auto-save-compile
1347 :help "Recompute AUTOs, save buffer, and compile"]
1348 ["Next Compile Error" next-error
1349 :help "Visit next compilation error message and corresponding source code"]
1350 ["Ignore Lint Warning at point" verilog-lint-off
1351 :help "Convert a Verilog linter warning line into a disable statement"]
1352 "----"
1353 ["Line up declarations around point" verilog-pretty-declarations
1354 :help "Line up declarations around point"]
1355 ["Line up equations around point" verilog-pretty-expr
1356 :help "Line up expressions around point"]
1357 ["Redo/insert comments on every end" verilog-label-be
1358 :help "Label matching begin ... end statements"]
1359 ["Expand [x:y] vector line" verilog-expand-vector
1360 :help "Take a signal vector on the current line and expand it to multiple lines"]
1361 ["Insert begin-end block" verilog-insert-block
1362 :help "Insert begin ... end"]
1363 ["Complete word" verilog-complete-word
1364 :help "Complete word at point"]
1365 "----"
1366 ["Recompute AUTOs" verilog-auto
1367 :help "Expand AUTO meta-comment statements"]
1368 ["Kill AUTOs" verilog-delete-auto
1369 :help "Remove AUTO expansions"]
9489a450
MM
1370 ["Diff AUTOs" verilog-diff-auto
1371 :help "Show differences in AUTO expansions"]
495ab0d5
DN
1372 ["Inject AUTOs" verilog-inject-auto
1373 :help "Inject AUTOs into legacy non-AUTO buffer"]
1374 ("AUTO Help..."
1375 ["AUTO General" (describe-function 'verilog-auto)
1376 :help "Help introduction on AUTOs"]
1377 ["AUTO Library Flags" (describe-variable 'verilog-library-flags)
1378 :help "Help on verilog-library-flags"]
1379 ["AUTO Library Path" (describe-variable 'verilog-library-directories)
1380 :help "Help on verilog-library-directories"]
1381 ["AUTO Library Files" (describe-variable 'verilog-library-files)
1382 :help "Help on verilog-library-files"]
1383 ["AUTO Library Extensions" (describe-variable 'verilog-library-extensions)
1384 :help "Help on verilog-library-extensions"]
1385 ["AUTO `define Reading" (describe-function 'verilog-read-defines)
1386 :help "Help on reading `defines"]
1387 ["AUTO `include Reading" (describe-function 'verilog-read-includes)
1388 :help "Help on parsing `includes"]
1389 ["AUTOARG" (describe-function 'verilog-auto-arg)
1390 :help "Help on AUTOARG - declaring module port list"]
1391 ["AUTOASCIIENUM" (describe-function 'verilog-auto-ascii-enum)
1392 :help "Help on AUTOASCIIENUM - creating ASCII for enumerations"]
86a4c7ac 1393 ["AUTOINOUTCOMP" (describe-function 'verilog-auto-inout-comp)
7cb1c4d7 1394 :help "Help on AUTOINOUTCOMP - copying complemented i/o from another file"]
9489a450
MM
1395 ["AUTOINOUTIN" (describe-function 'verilog-auto-inout-in)
1396 :help "Help on AUTOINOUTCOMP - copying i/o from another file as all inputs"]
495ab0d5
DN
1397 ["AUTOINOUTMODULE" (describe-function 'verilog-auto-inout-module)
1398 :help "Help on AUTOINOUTMODULE - copying i/o from another file"]
a3a8b002
DN
1399 ["AUTOINSERTLISP" (describe-function 'verilog-auto-insert-lisp)
1400 :help "Help on AUTOINSERTLISP - insert text from a lisp function"]
495ab0d5
DN
1401 ["AUTOINOUT" (describe-function 'verilog-auto-inout)
1402 :help "Help on AUTOINOUT - adding inouts from cells"]
1403 ["AUTOINPUT" (describe-function 'verilog-auto-input)
1404 :help "Help on AUTOINPUT - adding inputs from cells"]
1405 ["AUTOINST" (describe-function 'verilog-auto-inst)
1406 :help "Help on AUTOINST - adding pins for cells"]
1407 ["AUTOINST (.*)" (describe-function 'verilog-auto-star)
1408 :help "Help on expanding Verilog-2001 .* pins"]
1409 ["AUTOINSTPARAM" (describe-function 'verilog-auto-inst-param)
1410 :help "Help on AUTOINSTPARAM - adding parameter pins to cells"]
9489a450
MM
1411 ["AUTOLOGIC" (describe-function 'verilog-auto-logic)
1412 :help "Help on AUTOLOGIC - declaring logic signals"]
495ab0d5
DN
1413 ["AUTOOUTPUT" (describe-function 'verilog-auto-output)
1414 :help "Help on AUTOOUTPUT - adding outputs from cells"]
1415 ["AUTOOUTPUTEVERY" (describe-function 'verilog-auto-output-every)
1416 :help "Help on AUTOOUTPUTEVERY - adding outputs of all signals"]
1417 ["AUTOREG" (describe-function 'verilog-auto-reg)
1418 :help "Help on AUTOREG - declaring registers for non-wires"]
1419 ["AUTOREGINPUT" (describe-function 'verilog-auto-reg-input)
1420 :help "Help on AUTOREGINPUT - declaring inputs for non-wires"]
1421 ["AUTORESET" (describe-function 'verilog-auto-reset)
1422 :help "Help on AUTORESET - resetting always blocks"]
1423 ["AUTOSENSE" (describe-function 'verilog-auto-sense)
1424 :help "Help on AUTOSENSE - sensitivity lists for always blocks"]
1425 ["AUTOTIEOFF" (describe-function 'verilog-auto-tieoff)
1426 :help "Help on AUTOTIEOFF - tieing off unused outputs"]
1427 ["AUTOUNUSED" (describe-function 'verilog-auto-unused)
1428 :help "Help on AUTOUNUSED - terminating unused inputs"]
1429 ["AUTOWIRE" (describe-function 'verilog-auto-wire)
1430 :help "Help on AUTOWIRE - declaring wires for cells"]
1431 )
1432 "----"
1433 ["Submit bug report" verilog-submit-bug-report
1434 :help "Submit via mail a bug report on verilog-mode.el"]
1435 ["Version and FAQ" verilog-faq
1436 :help "Show the current version, and where to get the FAQ etc"]
1437 ["Customize Verilog Mode..." verilog-customize
1438 :help "Customize variables and other settings used by Verilog-Mode"]
1439 ["Customize Verilog Fonts & Colors" verilog-font-customize
1440 :help "Customize fonts used by Verilog-Mode."])))
7d55bf04
DN
1441
1442(easy-menu-define
1443 verilog-stmt-menu verilog-mode-map "Menu for statement templates in Verilog."
495ab0d5
DN
1444 (verilog-easy-menu-filter
1445 '("Statements"
1446 ["Header" verilog-sk-header
1447 :help "Insert a header block at the top of file"]
1448 ["Comment" verilog-sk-comment
1449 :help "Insert a comment block"]
1450 "----"
1451 ["Module" verilog-sk-module
1452 :help "Insert a module .. (/*AUTOARG*/);.. endmodule block"]
9489a450
MM
1453 ["OVM Class" verilog-sk-ovm-class
1454 :help "Insert an OVM class block"]
1455 ["UVM Class" verilog-sk-uvm-class
1456 :help "Insert an UVM class block"]
495ab0d5
DN
1457 ["Primitive" verilog-sk-primitive
1458 :help "Insert a primitive .. (.. );.. endprimitive block"]
1459 "----"
1460 ["Input" verilog-sk-input
1461 :help "Insert an input declaration"]
1462 ["Output" verilog-sk-output
1463 :help "Insert an output declaration"]
1464 ["Inout" verilog-sk-inout
1465 :help "Insert an inout declaration"]
1466 ["Wire" verilog-sk-wire
1467 :help "Insert a wire declaration"]
1468 ["Reg" verilog-sk-reg
1469 :help "Insert a register declaration"]
1470 ["Define thing under point as a register" verilog-sk-define-signal
1471 :help "Define signal under point as a register at the top of the module"]
1472 "----"
1473 ["Initial" verilog-sk-initial
1474 :help "Insert an initial begin .. end block"]
1475 ["Always" verilog-sk-always
1476 :help "Insert an always @(AS) begin .. end block"]
1477 ["Function" verilog-sk-function
1478 :help "Insert a function .. begin .. end endfunction block"]
1479 ["Task" verilog-sk-task
1480 :help "Insert a task .. begin .. end endtask block"]
1481 ["Specify" verilog-sk-specify
1482 :help "Insert a specify .. endspecify block"]
1483 ["Generate" verilog-sk-generate
1484 :help "Insert a generate .. endgenerate block"]
1485 "----"
1486 ["Begin" verilog-sk-begin
1487 :help "Insert a begin .. end block"]
1488 ["If" verilog-sk-if
1489 :help "Insert an if (..) begin .. end block"]
1490 ["(if) else" verilog-sk-else-if
1491 :help "Insert an else if (..) begin .. end block"]
1492 ["For" verilog-sk-for
1493 :help "Insert a for (...) begin .. end block"]
1494 ["While" verilog-sk-while
1495 :help "Insert a while (...) begin .. end block"]
1496 ["Fork" verilog-sk-fork
1497 :help "Insert a fork begin .. end .. join block"]
1498 ["Repeat" verilog-sk-repeat
1499 :help "Insert a repeat (..) begin .. end block"]
1500 ["Case" verilog-sk-case
1501 :help "Insert a case block, prompting for details"]
1502 ["Casex" verilog-sk-casex
1503 :help "Insert a casex (...) item: begin.. end endcase block"]
1504 ["Casez" verilog-sk-casez
1505 :help "Insert a casez (...) item: begin.. end endcase block"])))
6341f357
DN
1506
1507(defvar verilog-mode-abbrev-table nil
1508 "Abbrev table in use in Verilog-mode buffers.")
1509
1510(define-abbrev-table 'verilog-mode-abbrev-table ())
9489a450
MM
1511(verilog-define-abbrev verilog-mode-abbrev-table "class" "" 'verilog-sk-ovm-class)
1512(verilog-define-abbrev verilog-mode-abbrev-table "always" "" 'verilog-sk-always)
1513(verilog-define-abbrev verilog-mode-abbrev-table "begin" nil `verilog-sk-begin)
1514(verilog-define-abbrev verilog-mode-abbrev-table "case" "" `verilog-sk-case)
1515(verilog-define-abbrev verilog-mode-abbrev-table "for" "" `verilog-sk-for)
1516(verilog-define-abbrev verilog-mode-abbrev-table "generate" "" `verilog-sk-generate)
1517(verilog-define-abbrev verilog-mode-abbrev-table "initial" "" `verilog-sk-initial)
1518(verilog-define-abbrev verilog-mode-abbrev-table "fork" "" `verilog-sk-fork)
1519(verilog-define-abbrev verilog-mode-abbrev-table "module" "" `verilog-sk-module)
1520(verilog-define-abbrev verilog-mode-abbrev-table "primitive" "" `verilog-sk-primitive)
1521(verilog-define-abbrev verilog-mode-abbrev-table "repeat" "" `verilog-sk-repeat)
1522(verilog-define-abbrev verilog-mode-abbrev-table "specify" "" `verilog-sk-specify)
1523(verilog-define-abbrev verilog-mode-abbrev-table "task" "" `verilog-sk-task)
1524(verilog-define-abbrev verilog-mode-abbrev-table "while" "" `verilog-sk-while)
1525(verilog-define-abbrev verilog-mode-abbrev-table "casex" "" `verilog-sk-casex)
1526(verilog-define-abbrev verilog-mode-abbrev-table "casez" "" `verilog-sk-casez)
1527(verilog-define-abbrev verilog-mode-abbrev-table "if" "" `verilog-sk-if)
1528(verilog-define-abbrev verilog-mode-abbrev-table "else if" "" `verilog-sk-else-if)
1529(verilog-define-abbrev verilog-mode-abbrev-table "assign" "" `verilog-sk-assign)
1530(verilog-define-abbrev verilog-mode-abbrev-table "function" "" `verilog-sk-function)
1531(verilog-define-abbrev verilog-mode-abbrev-table "input" "" `verilog-sk-input)
1532(verilog-define-abbrev verilog-mode-abbrev-table "output" "" `verilog-sk-output)
1533(verilog-define-abbrev verilog-mode-abbrev-table "inout" "" `verilog-sk-inout)
1534(verilog-define-abbrev verilog-mode-abbrev-table "wire" "" `verilog-sk-wire)
1535(verilog-define-abbrev verilog-mode-abbrev-table "reg" "" `verilog-sk-reg)
6341f357 1536
b68a96b9
DN
1537;;
1538;; Macros
1539;;
1540
a03c2342 1541(defsubst verilog-within-string ()
3ba6b2ee 1542 (nth 3 (parse-partial-sexp (point-at-bol) (point))))
a03c2342 1543
b68a96b9
DN
1544(defsubst verilog-string-replace-matches (from-string to-string fixedcase literal string)
1545 "Replace occurrences of FROM-STRING with TO-STRING.
1546FIXEDCASE and LITERAL as in `replace-match`. STRING is what to replace.
1547The case (verilog-string-replace-matches \"o\" \"oo\" nil nil \"foobar\")
1548will break, as the o's continuously replace. xa -> x works ok though."
1549 ;; Hopefully soon to a emacs built-in
9489a450
MM
1550 ;; Also note \ in the replacement prevent multiple replacements; IE
1551 ;; (verilog-string-replace-matches "@" "\\\\([0-9]+\\\\)" nil nil "wire@_@")
1552 ;; Gives "wire\([0-9]+\)_@" not "wire\([0-9]+\)_\([0-9]+\)"
b68a96b9
DN
1553 (let ((start 0))
1554 (while (string-match from-string string start)
1555 (setq string (replace-match to-string fixedcase literal string)
4c5e69c6 1556 start (min (length string) (+ (match-beginning 0) (length to-string)))))
b68a96b9
DN
1557 string))
1558
1559(defsubst verilog-string-remove-spaces (string)
1560 "Remove spaces surrounding STRING."
1561 (save-match-data
1562 (setq string (verilog-string-replace-matches "^\\s-+" "" nil nil string))
1563 (setq string (verilog-string-replace-matches "\\s-+$" "" nil nil string))
1564 string))
1565
1566(defsubst verilog-re-search-forward (REGEXP BOUND NOERROR)
1567 ; checkdoc-params: (REGEXP BOUND NOERROR)
1568 "Like `re-search-forward', but skips over match in comments or strings."
7cb1c4d7
DN
1569 (let ((mdata '(nil nil))) ;; So match-end will return nil if no matches found
1570 (while (and
1571 (re-search-forward REGEXP BOUND NOERROR)
1572 (setq mdata (match-data))
1573 (and (verilog-skip-forward-comment-or-string)
1574 (progn
1575 (setq mdata '(nil nil))
1576 (if BOUND
1577 (< (point) BOUND)
1578 t)))))
1579 (store-match-data mdata)
1580 (match-end 0)))
b68a96b9
DN
1581
1582(defsubst verilog-re-search-backward (REGEXP BOUND NOERROR)
1583 ; checkdoc-params: (REGEXP BOUND NOERROR)
1584 "Like `re-search-backward', but skips over match in comments or strings."
7cb1c4d7
DN
1585 (let ((mdata '(nil nil))) ;; So match-end will return nil if no matches found
1586 (while (and
1587 (re-search-backward REGEXP BOUND NOERROR)
1588 (setq mdata (match-data))
1589 (and (verilog-skip-backward-comment-or-string)
1590 (progn
1591 (setq mdata '(nil nil))
1592 (if BOUND
1593 (> (point) BOUND)
1594 t)))))
1595 (store-match-data mdata)
1596 (match-end 0)))
b68a96b9
DN
1597
1598(defsubst verilog-re-search-forward-quick (regexp bound noerror)
1599 "Like `verilog-re-search-forward', including use of REGEXP BOUND and NOERROR,
1600but trashes match data and is faster for REGEXP that doesn't match often.
9489a450 1601This uses `verilog-scan' and text properties to ignore comments,
b68a96b9
DN
1602so there may be a large up front penalty for the first search."
1603 (let (pt)
1604 (while (and (not pt)
1605 (re-search-forward regexp bound noerror))
9489a450
MM
1606 (if (verilog-inside-comment-or-string-p)
1607 (re-search-forward "[/\"\n]" nil t) ;; Only way a comment or quote can end
1608 (setq pt (match-end 0))))
b68a96b9
DN
1609 pt))
1610
1611(defsubst verilog-re-search-backward-quick (regexp bound noerror)
1612 ; checkdoc-params: (REGEXP BOUND NOERROR)
1613 "Like `verilog-re-search-backward', including use of REGEXP BOUND and NOERROR,
1614but trashes match data and is faster for REGEXP that doesn't match often.
9489a450 1615This uses `verilog-scan' and text properties to ignore comments,
b68a96b9
DN
1616so there may be a large up front penalty for the first search."
1617 (let (pt)
1618 (while (and (not pt)
1619 (re-search-backward regexp bound noerror))
9489a450
MM
1620 (if (verilog-inside-comment-or-string-p)
1621 (re-search-backward "[/\"]" nil t) ;; Only way a comment or quote can begin
1622 (setq pt (match-beginning 0))))
b68a96b9
DN
1623 pt))
1624
a03c2342
WS
1625(defsubst verilog-re-search-forward-substr (substr regexp bound noerror)
1626 "Like `re-search-forward', but first search for SUBSTR constant.
1627Then searched for the normal REGEXP (which contains SUBSTR), with given
1628BOUND and NOERROR. The REGEXP must fit within a single line.
1629This speeds up complicated regexp matches."
1630 ;; Problem with overlap: search-forward BAR then FOOBARBAZ won't match.
1631 ;; thus require matches to be on one line, and use beginning-of-line.
1632 (let (done)
1633 (while (and (not done)
1634 (search-forward substr bound noerror))
1635 (save-excursion
1636 (beginning-of-line)
3ba6b2ee 1637 (setq done (re-search-forward regexp (point-at-eol) noerror)))
a03c2342
WS
1638 (unless (and (<= (match-beginning 0) (point))
1639 (>= (match-end 0) (point)))
1640 (setq done nil)))
1641 (when done (goto-char done))
1642 done))
1643;;(verilog-re-search-forward-substr "-end" "get-end-of" nil t) ;;-end (test bait)
1644
1645(defsubst verilog-re-search-backward-substr (substr regexp bound noerror)
1646 "Like `re-search-backward', but first search for SUBSTR constant.
1647Then searched for the normal REGEXP (which contains SUBSTR), with given
1648BOUND and NOERROR. The REGEXP must fit within a single line.
1649This speeds up complicated regexp matches."
1650 ;; Problem with overlap: search-backward BAR then FOOBARBAZ won't match.
1651 ;; thus require matches to be on one line, and use beginning-of-line.
1652 (let (done)
1653 (while (and (not done)
1654 (search-backward substr bound noerror))
1655 (save-excursion
1656 (end-of-line)
3ba6b2ee 1657 (setq done (re-search-backward regexp (point-at-bol) noerror)))
a03c2342
WS
1658 (unless (and (<= (match-beginning 0) (point))
1659 (>= (match-end 0) (point)))
1660 (setq done nil)))
1661 (when done (goto-char done))
1662 done))
1663;;(verilog-re-search-backward-substr "-end" "get-end-of" nil t) ;;-end (test bait)
b68a96b9 1664
9489a450
MM
1665(defun verilog-delete-trailing-whitespace ()
1666 "Delete trailing spaces or tabs, but not newlines nor linefeeds."
1667 ;; Similar to `delete-trailing-whitespace' but that's not present in XEmacs
1668 (save-excursion
1669 (goto-char (point-min))
1670 (while (re-search-forward "[ \t]+$" nil t) ;; Not syntatic WS as no formfeed
1671 (replace-match "" nil nil))))
1672
60618039
DN
1673(defvar compile-command)
1674
6341f357
DN
1675;; compilation program
1676(defun verilog-set-compile-command ()
37ea4b9b 1677 "Function to compute shell command to compile Verilog.
6341f357
DN
1678
1679This reads `verilog-tool' and sets `compile-command'. This specifies the
1680program that executes when you type \\[compile] or
1681\\[verilog-auto-save-compile].
1682
a03c2342
WS
1683By default `verilog-tool' uses a Makefile if one exists in the
1684current directory. If not, it is set to the `verilog-linter',
1685`verilog-compiler', `verilog-coverage', `verilog-preprocessor',
1686or `verilog-simulator' variables, as selected with the Verilog ->
1687\"Choose Compilation Action\" menu.
6341f357
DN
1688
1689You should set `verilog-tool' or the other variables to the path and
1690arguments for your Verilog simulator. For example:
1691 \"vcs -p123 -O\"
1692or a string like:
1693 \"(cd /tmp; surecov %s)\".
1694
1695In the former case, the path to the current buffer is concat'ed to the
1696value of `verilog-tool'; in the later, the path to the current buffer is
1697substituted for the %s.
1698
a03c2342
WS
1699Where __FLAGS__ appears in the string `verilog-current-flags'
1700will be substituted.
1701
1702Where __FILE__ appears in the string, the variable
1703`buffer-file-name' of the current buffer, without the directory
1704portion, will be substituted."
6341f357
DN
1705 (interactive)
1706 (cond
1707 ((or (file-exists-p "makefile") ;If there is a makefile, use it
1708 (file-exists-p "Makefile"))
175069ef 1709 (set (make-local-variable 'compile-command) "make "))
6341f357 1710 (t
175069ef 1711 (set (make-local-variable 'compile-command)
9489a450
MM
1712 (if verilog-tool
1713 (if (string-match "%s" (eval verilog-tool))
1714 (format (eval verilog-tool) (or buffer-file-name ""))
1715 (concat (eval verilog-tool) " " (or buffer-file-name "")))
1716 ""))))
6341f357
DN
1717 (verilog-modify-compile-command))
1718
a03c2342
WS
1719(defun verilog-expand-command (command)
1720 "Replace meta-information in COMMAND and return it.
1721Where __FLAGS__ appears in the string `verilog-current-flags'
1722will be substituted. Where __FILE__ appears in the string, the
1723current buffer's file-name, without the directory portion, will
1724be substituted."
1725 (setq command (verilog-string-replace-matches
1726 ;; Note \\b only works if under verilog syntax table
1727 "\\b__FLAGS__\\b" (verilog-current-flags)
1728 t t command))
1729 (setq command (verilog-string-replace-matches
1730 "\\b__FILE__\\b" (file-name-nondirectory
1731 (or (buffer-file-name) ""))
1732 t t command))
1733 command)
1734
6341f357 1735(defun verilog-modify-compile-command ()
a03c2342 1736 "Update `compile-command' using `verilog-expand-command'."
6341f357
DN
1737 (when (and
1738 (stringp compile-command)
a03c2342 1739 (string-match "\\b\\(__FLAGS__\\|__FILE__\\)\\b" compile-command))
175069ef 1740 (set (make-local-variable 'compile-command)
9489a450 1741 (verilog-expand-command compile-command))))
6341f357 1742
d9e8a018
GM
1743(if (featurep 'xemacs)
1744 ;; Following code only gets called from compilation-mode-hook on XEmacs to add error handling.
1745 (defun verilog-error-regexp-add-xemacs ()
1746 "Teach XEmacs about verilog errors.
7ea26faf
DN
1747Called by `compilation-mode-hook'. This allows \\[next-error] to
1748find the errors."
d9e8a018
GM
1749 (interactive)
1750 (if (boundp 'compilation-error-regexp-systems-alist)
1751 (if (and
1752 (not (equal compilation-error-regexp-systems-list 'all))
1753 (not (member compilation-error-regexp-systems-list 'verilog)))
1754 (push 'verilog compilation-error-regexp-systems-list)))
1755 (if (boundp 'compilation-error-regexp-alist-alist)
1756 (if (not (assoc 'verilog compilation-error-regexp-alist-alist))
1757 (setcdr compilation-error-regexp-alist-alist
1758 (cons verilog-error-regexp-xemacs-alist
1759 (cdr compilation-error-regexp-alist-alist)))))
1760 (if (boundp 'compilation-font-lock-keywords)
1761 (progn
9489a450
MM
1762 (set (make-local-variable 'compilation-font-lock-keywords)
1763 verilog-error-font-lock-keywords)
d9e8a018
GM
1764 (font-lock-set-defaults)))
1765 ;; Need to re-run compilation-error-regexp builder
1766 (if (fboundp 'compilation-build-compilation-error-regexp-alist)
1767 (compilation-build-compilation-error-regexp-alist))
1768 ))
d88782c3
DN
1769
1770;; Following code only gets called from compilation-mode-hook on Emacs to add error handling.
a3a8b002
DN
1771(defun verilog-error-regexp-add-emacs ()
1772 "Tell Emacs compile that we are Verilog.
1773Called by `compilation-mode-hook'. This allows \\[next-error] to
1774find the errors."
1775 (interactive)
d88782c3
DN
1776 (if (boundp 'compilation-error-regexp-alist-alist)
1777 (progn
1778 (if (not (assoc 'verilog-xl-1 compilation-error-regexp-alist-alist))
1779 (mapcar
1780 (lambda (item)
1781 (push (car item) compilation-error-regexp-alist)
1782 (push item compilation-error-regexp-alist-alist)
1783 )
1784 verilog-error-regexp-emacs-alist)))))
1785
1786(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs))
1787(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs))
6341f357
DN
1788
1789(defconst verilog-directive-re
a03c2342
WS
1790 (eval-when-compile
1791 (verilog-regexp-words
1792 '(
1793 "`case" "`default" "`define" "`else" "`elsif" "`endfor" "`endif"
1794 "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
1795 "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
1796 "`time_scale" "`undef" "`while" ))))
6341f357 1797
a3a8b002
DN
1798(defconst verilog-directive-re-1
1799 (concat "[ \t]*" verilog-directive-re))
1800
6341f357
DN
1801(defconst verilog-directive-begin
1802 "\\<`\\(for\\|i\\(f\\|fdef\\|fndef\\)\\|switch\\|while\\)\\>")
1803
1804(defconst verilog-directive-middle
a03c2342 1805 "\\<`\\(else\\|elsif\\|default\\|case\\)\\>")
6341f357
DN
1806
1807(defconst verilog-directive-end
1808 "`\\(endfor\\|endif\\|endswitch\\|endwhile\\)\\>")
1809
a3a8b002
DN
1810(defconst verilog-ovm-begin-re
1811 (eval-when-compile
1812 (verilog-regexp-opt
1813 '(
1814 "`ovm_component_utils_begin"
14862301 1815 "`ovm_component_param_utils_begin"
a3a8b002
DN
1816 "`ovm_field_utils_begin"
1817 "`ovm_object_utils_begin"
14862301 1818 "`ovm_object_param_utils_begin"
a3a8b002
DN
1819 "`ovm_sequence_utils_begin"
1820 "`ovm_sequencer_utils_begin"
1821 ) nil )))
1822
1823(defconst verilog-ovm-end-re
1824 (eval-when-compile
1825 (verilog-regexp-opt
1826 '(
1827 "`ovm_component_utils_end"
1828 "`ovm_field_utils_end"
1829 "`ovm_object_utils_end"
1830 "`ovm_sequence_utils_end"
1831 "`ovm_sequencer_utils_end"
1832 ) nil )))
1833
9489a450
MM
1834(defconst verilog-uvm-begin-re
1835 (eval-when-compile
1836 (verilog-regexp-opt
1837 '(
1838 "`uvm_component_utils_begin"
1839 "`uvm_component_param_utils_begin"
1840 "`uvm_field_utils_begin"
1841 "`uvm_object_utils_begin"
1842 "`uvm_object_param_utils_begin"
1843 "`uvm_sequence_utils_begin"
1844 "`uvm_sequencer_utils_begin"
1845 ) nil )))
1846
1847(defconst verilog-uvm-end-re
1848 (eval-when-compile
1849 (verilog-regexp-opt
1850 '(
1851 "`uvm_component_utils_end"
1852 "`uvm_field_utils_end"
1853 "`uvm_object_utils_end"
1854 "`uvm_sequence_utils_end"
1855 "`uvm_sequencer_utils_end"
1856 ) nil )))
1857
86a4c7ac
DN
1858(defconst verilog-vmm-begin-re
1859 (eval-when-compile
1860 (verilog-regexp-opt
1861 '(
1862 "`vmm_data_member_begin"
1863 "`vmm_env_member_begin"
1864 "`vmm_scenario_member_begin"
1865 "`vmm_subenv_member_begin"
1866 "`vmm_xactor_member_begin"
1867 ) nil ) ) )
1868
1869(defconst verilog-vmm-end-re
1870 (eval-when-compile
1871 (verilog-regexp-opt
1872 '(
1873 "`vmm_data_member_end"
1874 "`vmm_env_member_end"
1875 "`vmm_scenario_member_end"
1876 "`vmm_subenv_member_end"
1877 "`vmm_xactor_member_end"
1878 ) nil ) ) )
1879
1880(defconst verilog-vmm-statement-re
1881 (eval-when-compile
1882 (verilog-regexp-opt
1883 '(
1884;; "`vmm_xactor_member_enum_array"
1885 "`vmm_\\(data\\|env\\|scenario\\|subenv\\|xactor\\)_member_\\(scalar\\|string\\|enum\\|vmm_data\\|channel\\|xactor\\|subenv\\|user_defined\\)\\(_array\\)?"
1886;; "`vmm_xactor_member_scalar_array"
1887;; "`vmm_xactor_member_scalar"
1888 ) nil )))
1889
a3a8b002
DN
1890(defconst verilog-ovm-statement-re
1891 (eval-when-compile
1892 (verilog-regexp-opt
1893 '(
1894 ;; Statements
1895 "`DUT_ERROR"
1896 "`MESSAGE"
1897 "`dut_error"
1898 "`message"
1899 "`ovm_analysis_imp_decl"
1900 "`ovm_blocking_get_imp_decl"
1901 "`ovm_blocking_get_peek_imp_decl"
1902 "`ovm_blocking_master_imp_decl"
1903 "`ovm_blocking_peek_imp_decl"
1904 "`ovm_blocking_put_imp_decl"
1905 "`ovm_blocking_slave_imp_decl"
1906 "`ovm_blocking_transport_imp_decl"
1907 "`ovm_component_registry"
1908 "`ovm_component_registry_param"
1909 "`ovm_component_utils"
1910 "`ovm_create"
1911 "`ovm_create_seq"
1912 "`ovm_declare_sequence_lib"
1913 "`ovm_do"
1914 "`ovm_do_seq"
1915 "`ovm_do_seq_with"
1916 "`ovm_do_with"
1917 "`ovm_error"
1918 "`ovm_fatal"
1919 "`ovm_field_aa_int_byte"
1920 "`ovm_field_aa_int_byte_unsigned"
1921 "`ovm_field_aa_int_int"
1922 "`ovm_field_aa_int_int_unsigned"
1923 "`ovm_field_aa_int_integer"
1924 "`ovm_field_aa_int_integer_unsigned"
1925 "`ovm_field_aa_int_key"
1926 "`ovm_field_aa_int_longint"
1927 "`ovm_field_aa_int_longint_unsigned"
1928 "`ovm_field_aa_int_shortint"
1929 "`ovm_field_aa_int_shortint_unsigned"
1930 "`ovm_field_aa_int_string"
1931 "`ovm_field_aa_object_int"
1932 "`ovm_field_aa_object_string"
1933 "`ovm_field_aa_string_int"
1934 "`ovm_field_aa_string_string"
1935 "`ovm_field_array_int"
1936 "`ovm_field_array_object"
1937 "`ovm_field_array_string"
1938 "`ovm_field_enum"
1939 "`ovm_field_event"
1940 "`ovm_field_int"
1941 "`ovm_field_object"
1942 "`ovm_field_queue_int"
1943 "`ovm_field_queue_object"
1944 "`ovm_field_queue_string"
1945 "`ovm_field_sarray_int"
1946 "`ovm_field_string"
1947 "`ovm_field_utils"
1948 "`ovm_file"
1949 "`ovm_get_imp_decl"
1950 "`ovm_get_peek_imp_decl"
1951 "`ovm_info"
1952 "`ovm_info1"
1953 "`ovm_info2"
1954 "`ovm_info3"
1955 "`ovm_info4"
1956 "`ovm_line"
1957 "`ovm_master_imp_decl"
1958 "`ovm_msg_detail"
1959 "`ovm_non_blocking_transport_imp_decl"
1960 "`ovm_nonblocking_get_imp_decl"
1961 "`ovm_nonblocking_get_peek_imp_decl"
1962 "`ovm_nonblocking_master_imp_decl"
1963 "`ovm_nonblocking_peek_imp_decl"
1964 "`ovm_nonblocking_put_imp_decl"
1965 "`ovm_nonblocking_slave_imp_decl"
1966 "`ovm_object_registry"
1967 "`ovm_object_registry_param"
1968 "`ovm_object_utils"
1969 "`ovm_peek_imp_decl"
1970 "`ovm_phase_func_decl"
1971 "`ovm_phase_task_decl"
1972 "`ovm_print_aa_int_object"
1973 "`ovm_print_aa_string_int"
1974 "`ovm_print_aa_string_object"
1975 "`ovm_print_aa_string_string"
1976 "`ovm_print_array_int"
1977 "`ovm_print_array_object"
1978 "`ovm_print_array_string"
1979 "`ovm_print_object_queue"
1980 "`ovm_print_queue_int"
1981 "`ovm_print_string_queue"
1982 "`ovm_put_imp_decl"
1983 "`ovm_rand_send"
1984 "`ovm_rand_send_with"
1985 "`ovm_send"
1986 "`ovm_sequence_utils"
1987 "`ovm_slave_imp_decl"
1988 "`ovm_transport_imp_decl"
1989 "`ovm_update_sequence_lib"
1990 "`ovm_update_sequence_lib_and_item"
1991 "`ovm_warning"
1992 "`static_dut_error"
1993 "`static_message") nil )))
1994
9489a450
MM
1995(defconst verilog-uvm-statement-re
1996 (eval-when-compile
1997 (verilog-regexp-opt
1998 '(
1999 ;; Statements
2000 "`uvm_analysis_imp_decl"
2001 "`uvm_blocking_get_imp_decl"
2002 "`uvm_blocking_get_peek_imp_decl"
2003 "`uvm_blocking_master_imp_decl"
2004 "`uvm_blocking_peek_imp_decl"
2005 "`uvm_blocking_put_imp_decl"
2006 "`uvm_blocking_slave_imp_decl"
2007 "`uvm_blocking_transport_imp_decl"
2008 "`uvm_component_param_utils"
2009 "`uvm_component_registry"
2010 "`uvm_component_registry_param"
2011 "`uvm_component_utils"
2012 "`uvm_create"
2013 "`uvm_create_on"
2014 "`uvm_create_seq" ;; Undocumented in 1.1
2015 "`uvm_declare_p_sequencer"
2016 "`uvm_declare_sequence_lib" ;; Deprecated in 1.1
2017 "`uvm_do"
2018 "`uvm_do_callbacks"
2019 "`uvm_do_callbacks_exit_on"
2020 "`uvm_do_obj_callbacks"
2021 "`uvm_do_obj_callbacks_exit_on"
2022 "`uvm_do_on"
2023 "`uvm_do_on_pri"
2024 "`uvm_do_on_pri_with"
2025 "`uvm_do_on_with"
2026 "`uvm_do_pri"
2027 "`uvm_do_pri_with"
2028 "`uvm_do_seq" ;; Undocumented in 1.1
2029 "`uvm_do_seq_with" ;; Undocumented in 1.1
2030 "`uvm_do_with"
2031 "`uvm_error"
2032 "`uvm_error_context"
2033 "`uvm_fatal"
2034 "`uvm_fatal_context"
2035 "`uvm_field_aa_int_byte"
2036 "`uvm_field_aa_int_byte_unsigned"
2037 "`uvm_field_aa_int_enum"
2038 "`uvm_field_aa_int_int"
2039 "`uvm_field_aa_int_int_unsigned"
2040 "`uvm_field_aa_int_integer"
2041 "`uvm_field_aa_int_integer_unsigned"
2042 "`uvm_field_aa_int_key"
2043 "`uvm_field_aa_int_longint"
2044 "`uvm_field_aa_int_longint_unsigned"
2045 "`uvm_field_aa_int_shortint"
2046 "`uvm_field_aa_int_shortint_unsigned"
2047 "`uvm_field_aa_int_string"
2048 "`uvm_field_aa_object_int"
2049 "`uvm_field_aa_object_string"
2050 "`uvm_field_aa_string_int"
2051 "`uvm_field_aa_string_string"
2052 "`uvm_field_array_enum"
2053 "`uvm_field_array_int"
2054 "`uvm_field_array_object"
2055 "`uvm_field_array_string"
2056 "`uvm_field_enum"
2057 "`uvm_field_event"
2058 "`uvm_field_int"
2059 "`uvm_field_object"
2060 "`uvm_field_queue_enum"
2061 "`uvm_field_queue_int"
2062 "`uvm_field_queue_object"
2063 "`uvm_field_queue_string"
2064 "`uvm_field_real"
2065 "`uvm_field_sarray_enum"
2066 "`uvm_field_sarray_int"
2067 "`uvm_field_sarray_object"
2068 "`uvm_field_sarray_string"
2069 "`uvm_field_string"
2070 "`uvm_field_utils"
2071 "`uvm_file" ;; Undocumented in 1.1, use `__FILE__
2072 "`uvm_get_imp_decl"
2073 "`uvm_get_peek_imp_decl"
2074 "`uvm_info"
2075 "`uvm_info_context"
2076 "`uvm_line" ;; Undocumented in 1.1, use `__LINE__
2077 "`uvm_master_imp_decl"
2078 "`uvm_non_blocking_transport_imp_decl" ;; Deprecated in 1.1
2079 "`uvm_nonblocking_get_imp_decl"
2080 "`uvm_nonblocking_get_peek_imp_decl"
2081 "`uvm_nonblocking_master_imp_decl"
2082 "`uvm_nonblocking_peek_imp_decl"
2083 "`uvm_nonblocking_put_imp_decl"
2084 "`uvm_nonblocking_slave_imp_decl"
2085 "`uvm_nonblocking_transport_imp_decl"
2086 "`uvm_object_param_utils"
2087 "`uvm_object_registry"
2088 "`uvm_object_registry_param" ;; Undocumented in 1.1
2089 "`uvm_object_utils"
2090 "`uvm_pack_array"
2091 "`uvm_pack_arrayN"
2092 "`uvm_pack_enum"
2093 "`uvm_pack_enumN"
2094 "`uvm_pack_int"
2095 "`uvm_pack_intN"
2096 "`uvm_pack_queue"
2097 "`uvm_pack_queueN"
2098 "`uvm_pack_real"
2099 "`uvm_pack_sarray"
2100 "`uvm_pack_sarrayN"
2101 "`uvm_pack_string"
2102 "`uvm_peek_imp_decl"
2103 "`uvm_put_imp_decl"
2104 "`uvm_rand_send"
2105 "`uvm_rand_send_pri"
2106 "`uvm_rand_send_pri_with"
2107 "`uvm_rand_send_with"
2108 "`uvm_record_attribute"
2109 "`uvm_record_field"
2110 "`uvm_register_cb"
2111 "`uvm_send"
2112 "`uvm_send_pri"
2113 "`uvm_sequence_utils" ;; Deprecated in 1.1
2114 "`uvm_set_super_type"
2115 "`uvm_slave_imp_decl"
2116 "`uvm_transport_imp_decl"
2117 "`uvm_unpack_array"
2118 "`uvm_unpack_arrayN"
2119 "`uvm_unpack_enum"
2120 "`uvm_unpack_enumN"
2121 "`uvm_unpack_int"
2122 "`uvm_unpack_intN"
2123 "`uvm_unpack_queue"
2124 "`uvm_unpack_queueN"
2125 "`uvm_unpack_real"
2126 "`uvm_unpack_sarray"
2127 "`uvm_unpack_sarrayN"
2128 "`uvm_unpack_string"
2129 "`uvm_update_sequence_lib" ;; Deprecated in 1.1
2130 "`uvm_update_sequence_lib_and_item" ;; Deprecated in 1.1
2131 "`uvm_warning"
2132 "`uvm_warning_context") nil )))
2133
6341f357
DN
2134
2135;;
2136;; Regular expressions used to calculate indent, etc.
2137;;
2138(defconst verilog-symbol-re "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>")
6341f357
DN
2139;; Want to match
2140;; aa :
2141;; aa,bb :
2142;; a[34:32] :
2143;; a,
2144;; b :
9489a450
MM
2145(defconst verilog-assignment-operator-re
2146 (eval-when-compile
2147 (verilog-regexp-opt
2148 `(
2149 ;; blocking assignment_operator
2150 "=" "+=" "-=" "*=" "/=" "%=" "&=" "|=" "^=" "<<=" ">>=" "<<<=" ">>>="
2151 ;; non blocking assignment operator
2152 "<="
2153 ;; comparison
2154 "==" "!=" "===" "!===" "<=" ">=" "==\?" "!=\?"
2155 ;; event_trigger
2156 "->" "->>"
2157 ;; property_expr
2158 "|->" "|=>"
2159 ;; Is this a legal verilog operator?
2160 ":="
2161 ) 't
2162 )))
2163(defconst verilog-assignment-operation-re
2164 (concat
2165; "\\(^\\s-*[A-Za-z0-9_]+\\(\\[\\([A-Za-z0-9_]+\\)\\]\\)*\\s-*\\)"
2166; "\\(^\\s-*[^=<>+-*/%&|^:\\s-]+[^=<>+-*/%&|^\n]*?\\)"
2167 "\\(^.*?\\)" "\\B" verilog-assignment-operator-re "\\B" ))
6341f357 2168
14862301 2169(defconst verilog-label-re (concat verilog-symbol-re "\\s-*:\\s-*"))
a03c2342
WS
2170(defconst verilog-property-re
2171 (concat "\\(" verilog-label-re "\\)?"
2172 "\\(\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(assert\\)"))
2173 ;; "\\(assert\\|assume\\|cover\\)\\s-+property\\>"
2174
6341f357
DN
2175(defconst verilog-no-indent-begin-re
2176 "\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\|always_comb\\|always_ff\\|always_latch\\)\\>")
2177
2178(defconst verilog-ends-re
2179 ;; Parenthesis indicate type of keyword found
2180 (concat
2181 "\\(\\<else\\>\\)\\|" ; 1
2182 "\\(\\<if\\>\\)\\|" ; 2
86a4c7ac
DN
2183 "\\(\\<assert\\>\\)\\|" ; 3
2184 "\\(\\<end\\>\\)\\|" ; 3.1
6341f357
DN
2185 "\\(\\<endcase\\>\\)\\|" ; 4
2186 "\\(\\<endfunction\\>\\)\\|" ; 5
2187 "\\(\\<endtask\\>\\)\\|" ; 6
2188 "\\(\\<endspecify\\>\\)\\|" ; 7
2189 "\\(\\<endtable\\>\\)\\|" ; 8
2190 "\\(\\<endgenerate\\>\\)\\|" ; 9
2191 "\\(\\<join\\(_any\\|_none\\)?\\>\\)\\|" ; 10
2192 "\\(\\<endclass\\>\\)\\|" ; 11
a3a8b002 2193 "\\(\\<endgroup\\>\\)\\|" ; 12
86a4c7ac
DN
2194 ;; VMM
2195 "\\(\\<`vmm_data_member_end\\>\\)\\|"
2196 "\\(\\<`vmm_env_member_end\\>\\)\\|"
2197 "\\(\\<`vmm_scenario_member_end\\>\\)\\|"
2198 "\\(\\<`vmm_subenv_member_end\\>\\)\\|"
2199 "\\(\\<`vmm_xactor_member_end\\>\\)\\|"
a3a8b002
DN
2200 ;; OVM
2201 "\\(\\<`ovm_component_utils_end\\>\\)\\|"
2202 "\\(\\<`ovm_field_utils_end\\>\\)\\|"
2203 "\\(\\<`ovm_object_utils_end\\>\\)\\|"
2204 "\\(\\<`ovm_sequence_utils_end\\>\\)\\|"
2205 "\\(\\<`ovm_sequencer_utils_end\\>\\)"
9489a450
MM
2206 ;; UVM
2207 "\\(\\<`uvm_component_utils_end\\>\\)\\|"
2208 "\\(\\<`uvm_field_utils_end\\>\\)\\|"
2209 "\\(\\<`uvm_object_utils_end\\>\\)\\|"
2210 "\\(\\<`uvm_sequence_utils_end\\>\\)\\|"
2211 "\\(\\<`uvm_sequencer_utils_end\\>\\)"
6341f357
DN
2212 ))
2213
2214(defconst verilog-auto-end-comment-lines-re
da6062e6 2215 ;; Matches to names in this list cause auto-end-commenting
6341f357
DN
2216 (concat "\\("
2217 verilog-directive-re "\\)\\|\\("
2218 (eval-when-compile
2219 (verilog-regexp-words
2220 `( "begin"
2221 "else"
2222 "end"
2223 "endcase"
2224 "endclass"
2225 "endclocking"
2226 "endgroup"
2227 "endfunction"
2228 "endmodule"
2229 "endprogram"
2230 "endprimitive"
2231 "endinterface"
2232 "endpackage"
2233 "endsequence"
2234 "endspecify"
2235 "endtable"
2236 "endtask"
2237 "join"
2238 "join_any"
2239 "join_none"
2240 "module"
2241 "macromodule"
2242 "primitive"
2243 "interface"
2244 "package")))
2245 "\\)"))
2246
2247;;; NOTE: verilog-leap-to-head expects that verilog-end-block-re and
2248;;; verilog-end-block-ordered-re matches exactly the same strings.
2249(defconst verilog-end-block-ordered-re
2250 ;; Parenthesis indicate type of keyword found
2251 (concat "\\(\\<endcase\\>\\)\\|" ; 1
2252 "\\(\\<end\\>\\)\\|" ; 2
2253 "\\(\\<end" ; 3, but not used
2254 "\\(" ; 4, but not used
2255 "\\(function\\)\\|" ; 5
2256 "\\(task\\)\\|" ; 6
2257 "\\(module\\)\\|" ; 7
2258 "\\(primitive\\)\\|" ; 8
2259 "\\(interface\\)\\|" ; 9
2260 "\\(package\\)\\|" ; 10
2261 "\\(class\\)\\|" ; 11
2262 "\\(group\\)\\|" ; 12
2263 "\\(program\\)\\|" ; 13
2264 "\\(sequence\\)\\|" ; 14
2265 "\\(clocking\\)\\|" ; 15
2266 "\\)\\>\\)"))
2267(defconst verilog-end-block-re
2268 (eval-when-compile
2269 (verilog-regexp-words
2270
2271 `("end" ;; closes begin
2272 "endcase" ;; closes any of case, casex casez or randcase
2273 "join" "join_any" "join_none" ;; closes fork
2274 "endclass"
2275 "endtable"
2276 "endspecify"
2277 "endfunction"
2278 "endgenerate"
2279 "endtask"
2280 "endgroup"
2281 "endproperty"
2282 "endinterface"
2283 "endpackage"
2284 "endprogram"
2285 "endsequence"
2286 "endclocking"
a3a8b002
DN
2287 ;; OVM
2288 "`ovm_component_utils_end"
2289 "`ovm_field_utils_end"
2290 "`ovm_object_utils_end"
2291 "`ovm_sequence_utils_end"
2292 "`ovm_sequencer_utils_end"
9489a450
MM
2293 ;; UVM
2294 "`uvm_component_utils_end"
2295 "`uvm_field_utils_end"
2296 "`uvm_object_utils_end"
2297 "`uvm_sequence_utils_end"
2298 "`uvm_sequencer_utils_end"
86a4c7ac
DN
2299 ;; VMM
2300 "`vmm_data_member_end"
2301 "`vmm_env_member_end"
2302 "`vmm_scenario_member_end"
2303 "`vmm_subenv_member_end"
2304 "`vmm_xactor_member_end"
60618039 2305 ))))
6341f357
DN
2306
2307
2308(defconst verilog-endcomment-reason-re
2309 ;; Parenthesis indicate type of keyword found
2310 (concat
a3a8b002
DN
2311 "\\(\\<begin\\>\\)\\|" ; 1
2312 "\\(\\<else\\>\\)\\|" ; 2
2313 "\\(\\<end\\>\\s-+\\<else\\>\\)\\|" ; 3
2314 "\\(\\<always_comb\\>\\(\[ \t\]*@\\)?\\)\\|" ; 4
2315 "\\(\\<always_ff\\>\\(\[ \t\]*@\\)?\\)\\|" ; 5
2316 "\\(\\<always_latch\\>\\(\[ \t\]*@\\)?\\)\\|" ; 6
2317 "\\(\\<fork\\>\\)\\|" ; 7
14862301 2318 "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
6341f357 2319 "\\(\\<if\\>\\)\\|"
a03c2342
WS
2320 verilog-property-re "\\|"
2321 "\\(\\(" verilog-label-re "\\)?\\<assert\\>\\)\\|"
6341f357 2322 "\\(\\<clocking\\>\\)\\|"
14862301
SM
2323 "\\(\\<task\\>\\)\\|"
2324 "\\(\\<function\\>\\)\\|"
6341f357
DN
2325 "\\(\\<initial\\>\\)\\|"
2326 "\\(\\<interface\\>\\)\\|"
2327 "\\(\\<package\\>\\)\\|"
2328 "\\(\\<final\\>\\)\\|"
6341f357
DN
2329 "\\(@\\)\\|"
2330 "\\(\\<while\\>\\)\\|"
2331 "\\(\\<for\\(ever\\|each\\)?\\>\\)\\|"
2332 "\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|"
2333 "#"))
2334
2335(defconst verilog-named-block-re "begin[ \t]*:")
2336
2337;; These words begin a block which can occur inside a module which should be indented,
2338;; and closed with the respective word from the end-block list
2339
2340(defconst verilog-beg-block-re
2341 (eval-when-compile
2342 (verilog-regexp-words
2343 `("begin"
2344 "case" "casex" "casez" "randcase"
2345 "clocking"
2346 "generate"
2347 "fork"
2348 "function"
2349 "property"
2350 "specify"
2351 "table"
2352 "task"
9489a450 2353 ;; OVM
a3a8b002 2354 "`ovm_component_utils_begin"
14862301 2355 "`ovm_component_param_utils_begin"
a3a8b002
DN
2356 "`ovm_field_utils_begin"
2357 "`ovm_object_utils_begin"
14862301 2358 "`ovm_object_param_utils_begin"
a3a8b002
DN
2359 "`ovm_sequence_utils_begin"
2360 "`ovm_sequencer_utils_begin"
9489a450
MM
2361 ;; UVM
2362 "`uvm_component_utils_begin"
2363 "`uvm_component_param_utils_begin"
2364 "`uvm_field_utils_begin"
2365 "`uvm_object_utils_begin"
2366 "`uvm_object_param_utils_begin"
2367 "`uvm_sequence_utils_begin"
2368 "`uvm_sequencer_utils_begin"
86a4c7ac
DN
2369 ;; VMM
2370 "`vmm_data_member_begin"
2371 "`vmm_env_member_begin"
2372 "`vmm_scenario_member_begin"
2373 "`vmm_subenv_member_begin"
2374 "`vmm_xactor_member_begin"
6341f357
DN
2375 ))))
2376;; These are the same words, in a specific order in the regular
2377;; expression so that matching will work nicely for
2378;; verilog-forward-sexp and verilog-calc-indent
6341f357 2379(defconst verilog-beg-block-re-ordered
4c5e69c6
DN
2380 ( concat "\\(\\<begin\\>\\)" ;1
2381 "\\|\\(\\<randcase\\>\\|\\(\\<unique\\s-+\\|priority\\s-+\\)?case[xz]?\\>\\)" ; 2,3
9489a450 2382 "\\|\\(\\(\\<disable\\>\\s-+\\|\\<wait\\>\\s-+\\)?fork\\>\\)" ;4,5
4c5e69c6
DN
2383 "\\|\\(\\<class\\>\\)" ;6
2384 "\\|\\(\\<table\\>\\)" ;7
2385 "\\|\\(\\<specify\\>\\)" ;8
2386 "\\|\\(\\<function\\>\\)" ;9
a3a8b002
DN
2387 "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<function\\>\\)" ;10
2388 "\\|\\(\\<task\\>\\)" ;14
2389 "\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)*\\<task\\>\\)" ;15
2390 "\\|\\(\\<generate\\>\\)" ;18
2391 "\\|\\(\\<covergroup\\>\\)" ;16 20
2392 "\\|\\(\\(\\(\\<cover\\>\\s-+\\)\\|\\(\\<assert\\>\\s-+\\)\\)*\\<property\\>\\)" ;17 21
2393 "\\|\\(\\<\\(rand\\)?sequence\\>\\)" ;21 25
2394 "\\|\\(\\<clocking\\>\\)" ;22 27
9489a450 2395 "\\|\\(\\<`[ou]vm_[a-z_]+_begin\\>\\)" ;28
86a4c7ac 2396 "\\|\\(\\<`vmm_[a-z_]+_member_begin\\>\\)"
a3a8b002
DN
2397 ;;
2398
4c5e69c6 2399 ))
6341f357
DN
2400
2401(defconst verilog-end-block-ordered-rry
2402 [ "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)"
2403 "\\(\\<randcase\\>\\|\\<case[xz]?\\>\\)\\|\\(\\<endcase\\>\\)"
2404 "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)"
2405 "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)"
2406 "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)"
2407 "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)"
2408 "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)"
2409 "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)"
2410 "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)"
2411 "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)"
2412 "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)"
2413 "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)"
2414 "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)"
2415 ] )
2416
2417(defconst verilog-nameable-item-re
2418 (eval-when-compile
2419 (verilog-regexp-words
2420 `("begin"
2421 "fork"
2422 "join" "join_any" "join_none"
2423 "end"
2424 "endcase"
2425 "endconfig"
2426 "endclass"
2427 "endclocking"
2428 "endfunction"
2429 "endgenerate"
2430 "endmodule"
86a4c7ac 2431 "endprimitive"
6341f357
DN
2432 "endinterface"
2433 "endpackage"
2434 "endspecify"
2435 "endtable"
2436 "endtask" )
2437 )))
2438
2439(defconst verilog-declaration-opener
2440 (eval-when-compile
2441 (verilog-regexp-words
2442 `("module" "begin" "task" "function"))))
2443
2444(defconst verilog-declaration-prefix-re
2445 (eval-when-compile
2446 (verilog-regexp-words
2447 `(
2448 ;; port direction
6edb5716 2449 "inout" "input" "output" "ref"
6341f357
DN
2450 ;; changeableness
2451 "const" "static" "protected" "local"
2452 ;; parameters
6edb5716 2453 "localparam" "parameter" "var"
6341f357
DN
2454 ;; type creation
2455 "typedef"
2456 ))))
2457(defconst verilog-declaration-core-re
2458 (eval-when-compile
2459 (verilog-regexp-words
2460 `(
7e2a6000 2461 ;; port direction (by themselves)
871c637e 2462 "inout" "input" "output"
6341f357
DN
2463 ;; integer_atom_type
2464 "byte" "shortint" "int" "longint" "integer" "time"
2465 ;; integer_vector_type
2466 "bit" "logic" "reg"
2467 ;; non_integer_type
2468 "shortreal" "real" "realtime"
2469 ;; net_type
2470 "supply0" "supply1" "tri" "triand" "trior" "trireg" "tri0" "tri1" "uwire" "wire" "wand" "wor"
2471 ;; misc
2472 "string" "event" "chandle" "virtual" "enum" "genvar"
2473 "struct" "union"
2474 ;; builtin classes
6edb5716 2475 "mailbox" "semaphore"
6341f357 2476 ))))
6edb5716 2477(defconst verilog-declaration-re
6341f357
DN
2478 (concat "\\(" verilog-declaration-prefix-re "\\s-*\\)?" verilog-declaration-core-re))
2479(defconst verilog-range-re "\\(\\[[^]]*\\]\\s-*\\)+")
2480(defconst verilog-optional-signed-re "\\s-*\\(signed\\)?")
2481(defconst verilog-optional-signed-range-re
2482 (concat
2483 "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?"))
2484(defconst verilog-macroexp-re "`\\sw+")
2485
2486(defconst verilog-delay-re "#\\s-*\\(\\([0-9_]+\\('s?[hdxbo][0-9a-fA-F_xz]+\\)?\\)\\|\\(([^()]*)\\)\\|\\(\\sw+\\)\\)")
2487(defconst verilog-declaration-re-2-no-macro
2488 (concat "\\s-*" verilog-declaration-re
2489 "\\s-*\\(\\(" verilog-optional-signed-range-re "\\)\\|\\(" verilog-delay-re "\\)"
2490 "\\)?"))
2491(defconst verilog-declaration-re-2-macro
2492 (concat "\\s-*" verilog-declaration-re
2493 "\\s-*\\(\\(" verilog-optional-signed-range-re "\\)\\|\\(" verilog-delay-re "\\)"
2494 "\\|\\(" verilog-macroexp-re "\\)"
2495 "\\)?"))
2496(defconst verilog-declaration-re-1-macro
2497 (concat "^" verilog-declaration-re-2-macro))
2498
2499(defconst verilog-declaration-re-1-no-macro (concat "^" verilog-declaration-re-2-no-macro))
2500
2501(defconst verilog-defun-re
2502 (eval-when-compile (verilog-regexp-words `("macromodule" "module" "class" "program" "interface" "package" "primitive" "config"))))
2503(defconst verilog-end-defun-re
2504 (eval-when-compile (verilog-regexp-words `("endmodule" "endclass" "endprogram" "endinterface" "endpackage" "endprimitive" "endconfig"))))
2505(defconst verilog-zero-indent-re
2506 (concat verilog-defun-re "\\|" verilog-end-defun-re))
9489a450
MM
2507(defconst verilog-inst-comment-re
2508 (eval-when-compile (verilog-regexp-words `("Outputs" "Inouts" "Inputs" "Interfaces" "Interfaced"))))
6341f357
DN
2509
2510(defconst verilog-behavioral-block-beg-re
2a9eb3f5
DN
2511 (eval-when-compile (verilog-regexp-words `("initial" "final" "always" "always_comb" "always_latch" "always_ff"
2512 "function" "task"))))
a3a8b002 2513(defconst verilog-coverpoint-re "\\w+\\s*:\\s*\\(coverpoint\\|cross\\constraint\\)" )
6341f357
DN
2514(defconst verilog-indent-re
2515 (eval-when-compile
2516 (verilog-regexp-words
2517 `(
2518 "{"
2519 "always" "always_latch" "always_ff" "always_comb"
2520 "begin" "end"
2521; "unique" "priority"
2522 "case" "casex" "casez" "randcase" "endcase"
2523 "class" "endclass"
2524 "clocking" "endclocking"
2525 "config" "endconfig"
2526 "covergroup" "endgroup"
2527 "fork" "join" "join_any" "join_none"
2528 "function" "endfunction"
2529 "final"
2530 "generate" "endgenerate"
2531 "initial"
2532 "interface" "endinterface"
2533 "module" "macromodule" "endmodule"
2534 "package" "endpackage"
4c36be58 2535 "primitive" "endprimitive"
6341f357
DN
2536 "program" "endprogram"
2537 "property" "endproperty"
2538 "sequence" "randsequence" "endsequence"
2539 "specify" "endspecify"
2540 "table" "endtable"
2541 "task" "endtask"
4c5e69c6 2542 "virtual"
6341f357
DN
2543 "`case"
2544 "`default"
2545 "`define" "`undef"
a03c2342 2546 "`if" "`ifdef" "`ifndef" "`else" "`elsif" "`endif"
6341f357
DN
2547 "`while" "`endwhile"
2548 "`for" "`endfor"
2549 "`format"
2550 "`include"
2551 "`let"
2552 "`protect" "`endprotect"
2553 "`switch" "`endswitch"
2554 "`timescale"
2555 "`time_scale"
a3a8b002
DN
2556 ;; OVM Begin tokens
2557 "`ovm_component_utils_begin"
14862301 2558 "`ovm_component_param_utils_begin"
a3a8b002
DN
2559 "`ovm_field_utils_begin"
2560 "`ovm_object_utils_begin"
14862301 2561 "`ovm_object_param_utils_begin"
a3a8b002
DN
2562 "`ovm_sequence_utils_begin"
2563 "`ovm_sequencer_utils_begin"
2564 ;; OVM End tokens
2565 "`ovm_component_utils_end"
2566 "`ovm_field_utils_end"
2567 "`ovm_object_utils_end"
2568 "`ovm_sequence_utils_end"
2569 "`ovm_sequencer_utils_end"
9489a450
MM
2570 ;; UVM Begin tokens
2571 "`uvm_component_utils_begin"
2572 "`uvm_component_param_utils_begin"
2573 "`uvm_field_utils_begin"
2574 "`uvm_object_utils_begin"
2575 "`uvm_object_param_utils_begin"
2576 "`uvm_sequence_utils_begin"
2577 "`uvm_sequencer_utils_begin"
2578 ;; UVM End tokens
2579 "`uvm_component_utils_end" ;; Typo in spec, it's not uvm_component_end
2580 "`uvm_field_utils_end"
2581 "`uvm_object_utils_end"
2582 "`uvm_sequence_utils_end"
2583 "`uvm_sequencer_utils_end"
86a4c7ac
DN
2584 ;; VMM Begin tokens
2585 "`vmm_data_member_begin"
2586 "`vmm_env_member_begin"
2587 "`vmm_scenario_member_begin"
2588 "`vmm_subenv_member_begin"
2589 "`vmm_xactor_member_begin"
2590 ;; VMM End tokens
2591 "`vmm_data_member_end"
2592 "`vmm_env_member_end"
2593 "`vmm_scenario_member_end"
2594 "`vmm_subenv_member_end"
2595 "`vmm_xactor_member_end"
6341f357
DN
2596 ))))
2597
a3a8b002
DN
2598(defconst verilog-defun-level-not-generate-re
2599 (eval-when-compile
2600 (verilog-regexp-words
2601 `( "module" "macromodule" "primitive" "class" "program"
2602 "interface" "package" "config"))))
2603
6341f357
DN
2604(defconst verilog-defun-level-re
2605 (eval-when-compile
2606 (verilog-regexp-words
a3a8b002
DN
2607 (append
2608 `( "module" "macromodule" "primitive" "class" "program"
2609 "interface" "package" "config")
2610 `( "initial" "final" "always" "always_comb" "always_ff"
2611 "always_latch" "endtask" "endfunction" )))))
6341f357 2612
a3a8b002 2613(defconst verilog-defun-level-generate-only-re
6341f357
DN
2614 (eval-when-compile
2615 (verilog-regexp-words
a3a8b002
DN
2616 `( "initial" "final" "always" "always_comb" "always_ff"
2617 "always_latch" "endtask" "endfunction" ))))
6341f357
DN
2618
2619(defconst verilog-cpp-level-re
2620 (eval-when-compile
2621 (verilog-regexp-words
2622 `(
2623 "endmodule" "endprimitive" "endinterface" "endpackage" "endprogram" "endclass"
2624 ))))
9489a450 2625(defconst verilog-disable-fork-re "\\(disable\\|wait\\)\\s-+fork\\>")
6341f357
DN
2626(defconst verilog-extended-case-re "\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?")
2627(defconst verilog-extended-complete-re
a03c2342 2628 (concat "\\(\\<extern\\s-+\\|\\<\\(\\<pure\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)"
6341f357 2629 "\\|\\(\\<typedef\\>\\s-+\\)*\\(\\<struct\\>\\|\\<union\\>\\|\\<class\\>\\)"
a3a8b002 2630 "\\|\\(\\<import\\>\\s-+\\)?\"DPI-C\"\\s-+\\(function\\>\\|task\\>\\)"
6341f357
DN
2631 "\\|" verilog-extended-case-re ))
2632(defconst verilog-basic-complete-re
2633 (eval-when-compile
2634 (verilog-regexp-words
2635 `(
2636 "always" "assign" "always_latch" "always_ff" "always_comb" "constraint"
2637 "import" "initial" "final" "module" "macromodule" "repeat" "randcase" "while"
14862301 2638 "if" "for" "forever" "foreach" "else" "parameter" "do" "localparam" "assert"
6341f357
DN
2639 ))))
2640(defconst verilog-complete-reg
2641 (concat
2642 verilog-extended-complete-re
2643 "\\|"
2644 verilog-basic-complete-re))
2645
2646(defconst verilog-end-statement-re
2647 (concat "\\(" verilog-beg-block-re "\\)\\|\\("
2648 verilog-end-block-re "\\)"))
2649
2650(defconst verilog-endcase-re
a3a8b002 2651 (concat verilog-extended-case-re "\\|"
6341f357
DN
2652 "\\(endcase\\)\\|"
2653 verilog-defun-re
2654 ))
2655
2656(defconst verilog-exclude-str-start "/* -----\\/----- EXCLUDED -----\\/-----"
2657 "String used to mark beginning of excluded text.")
2658(defconst verilog-exclude-str-end " -----/\\----- EXCLUDED -----/\\----- */"
2659 "String used to mark end of excluded text.")
2660(defconst verilog-preprocessor-re
2661 (eval-when-compile
2662 (verilog-regexp-words
2663 `(
2664 "`define" "`include" "`ifdef" "`ifndef" "`if" "`endif" "`else"
2665 ))))
2666
2667(defconst verilog-keywords
2668 '( "`case" "`default" "`define" "`else" "`endfor" "`endif"
2669 "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
2670 "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
2671 "`time_scale" "`undef" "`while"
2672
2673 "after" "alias" "always" "always_comb" "always_ff" "always_latch" "and"
2674 "assert" "assign" "assume" "automatic" "before" "begin" "bind"
2675 "bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte"
2676 "case" "casex" "casez" "cell" "chandle" "class" "clocking" "cmos"
2677 "config" "const" "constraint" "context" "continue" "cover"
2678 "covergroup" "coverpoint" "cross" "deassign" "default" "defparam"
2679 "design" "disable" "dist" "do" "edge" "else" "end" "endcase"
2680 "endclass" "endclocking" "endconfig" "endfunction" "endgenerate"
2681 "endgroup" "endinterface" "endmodule" "endpackage" "endprimitive"
2682 "endprogram" "endproperty" "endspecify" "endsequence" "endtable"
2683 "endtask" "enum" "event" "expect" "export" "extends" "extern"
2684 "final" "first_match" "for" "force" "foreach" "forever" "fork"
2685 "forkjoin" "function" "generate" "genvar" "highz0" "highz1" "if"
2686 "iff" "ifnone" "ignore_bins" "illegal_bins" "import" "incdir"
2687 "include" "initial" "inout" "input" "inside" "instance" "int"
2688 "integer" "interface" "intersect" "join" "join_any" "join_none"
2689 "large" "liblist" "library" "local" "localparam" "logic"
2690 "longint" "macromodule" "mailbox" "matches" "medium" "modport" "module"
2691 "nand" "negedge" "new" "nmos" "nor" "noshowcancelled" "not"
2692 "notif0" "notif1" "null" "or" "output" "package" "packed"
2693 "parameter" "pmos" "posedge" "primitive" "priority" "program"
2694 "property" "protected" "pull0" "pull1" "pulldown" "pullup"
2695 "pulsestyle_onevent" "pulsestyle_ondetect" "pure" "rand" "randc"
2696 "randcase" "randsequence" "rcmos" "real" "realtime" "ref" "reg"
2697 "release" "repeat" "return" "rnmos" "rpmos" "rtran" "rtranif0"
2698 "rtranif1" "scalared" "semaphore" "sequence" "shortint" "shortreal"
2699 "showcancelled" "signed" "small" "solve" "specify" "specparam"
2700 "static" "string" "strong0" "strong1" "struct" "super" "supply0"
2701 "supply1" "table" "tagged" "task" "this" "throughout" "time"
2702 "timeprecision" "timeunit" "tran" "tranif0" "tranif1" "tri"
2703 "tri0" "tri1" "triand" "trior" "trireg" "type" "typedef" "union"
2704 "unique" "unsigned" "use" "uwire" "var" "vectored" "virtual" "void"
2705 "wait" "wait_order" "wand" "weak0" "weak1" "while" "wildcard"
2706 "wire" "with" "within" "wor" "xnor" "xor"
fd9ea9d3
WS
2707 ;; 1800-2009
2708 "accept_on" "checker" "endchecker" "eventually" "global" "implies"
2709 "let" "nexttime" "reject_on" "restrict" "s_always" "s_eventually"
2710 "s_nexttime" "s_until" "s_until_with" "strong" "sync_accept_on"
2711 "sync_reject_on" "unique0" "until" "until_with" "untyped" "weak"
6341f357
DN
2712 )
2713 "List of Verilog keywords.")
2714
6341f357
DN
2715(defconst verilog-comment-start-regexp "//\\|/\\*"
2716 "Dual comment value for `comment-start-regexp'.")
2717
e1776067
DN
2718(defvar verilog-mode-syntax-table
2719 (let ((table (make-syntax-table)))
2720 ;; Populate the syntax TABLE.
2721 (modify-syntax-entry ?\\ "\\" table)
2722 (modify-syntax-entry ?+ "." table)
2723 (modify-syntax-entry ?- "." table)
2724 (modify-syntax-entry ?= "." table)
2725 (modify-syntax-entry ?% "." table)
2726 (modify-syntax-entry ?< "." table)
2727 (modify-syntax-entry ?> "." table)
2728 (modify-syntax-entry ?& "." table)
2729 (modify-syntax-entry ?| "." table)
2730 (modify-syntax-entry ?` "w" table)
2731 (modify-syntax-entry ?_ "w" table)
2732 (modify-syntax-entry ?\' "." table)
2733
2734 ;; Set up TABLE to handle block and line style comments.
2735 (if (featurep 'xemacs)
2736 (progn
2737 ;; XEmacs (formerly Lucid) has the best implementation
2738 (modify-syntax-entry ?/ ". 1456" table)
2739 (modify-syntax-entry ?* ". 23" table)
2740 (modify-syntax-entry ?\n "> b" table))
d63b01e1 2741 ;; Emacs does things differently, but we can work with it
e1776067
DN
2742 (modify-syntax-entry ?/ ". 124b" table)
2743 (modify-syntax-entry ?* ". 23" table)
2744 (modify-syntax-entry ?\n "> b" table))
2745 table)
37ea4b9b 2746 "Syntax table used in Verilog mode buffers.")
6341f357 2747
7ea26faf 2748(defvar verilog-font-lock-keywords nil
6341f357
DN
2749 "Default highlighting for Verilog mode.")
2750
7ea26faf 2751(defvar verilog-font-lock-keywords-1 nil
6341f357
DN
2752 "Subdued level highlighting for Verilog mode.")
2753
7ea26faf 2754(defvar verilog-font-lock-keywords-2 nil
6341f357
DN
2755 "Medium level highlighting for Verilog mode.
2756See also `verilog-font-lock-extra-types'.")
2757
7ea26faf 2758(defvar verilog-font-lock-keywords-3 nil
6341f357
DN
2759 "Gaudy level highlighting for Verilog mode.
2760See also `verilog-font-lock-extra-types'.")
2761(defvar verilog-font-lock-translate-off-face
2762 'verilog-font-lock-translate-off-face
2763 "Font to use for translated off regions.")
2764(defface verilog-font-lock-translate-off-face
2765 '((((class color)
2766 (background light))
2767 (:background "gray90" :italic t ))
2768 (((class color)
2769 (background dark))
2770 (:background "gray10" :italic t ))
2771 (((class grayscale) (background light))
2772 (:foreground "DimGray" :italic t))
2773 (((class grayscale) (background dark))
2774 (:foreground "LightGray" :italic t))
2775 (t (:italis t)))
2776 "Font lock mode face used to background highlight translate-off regions."
2777 :group 'font-lock-highlighting-faces)
2778
2779(defvar verilog-font-lock-p1800-face
2780 'verilog-font-lock-p1800-face
2781 "Font to use for p1800 keywords.")
2782(defface verilog-font-lock-p1800-face
2783 '((((class color)
2784 (background light))
2785 (:foreground "DarkOrange3" :bold t ))
2786 (((class color)
2787 (background dark))
2788 (:foreground "orange1" :bold t ))
2789 (t (:italic t)))
2790 "Font lock mode face used to highlight P1800 keywords."
2791 :group 'font-lock-highlighting-faces)
2792
2793(defvar verilog-font-lock-ams-face
2794 'verilog-font-lock-ams-face
2795 "Font to use for Analog/Mixed Signal keywords.")
2796(defface verilog-font-lock-ams-face
2797 '((((class color)
2798 (background light))
2799 (:foreground "Purple" :bold t ))
2800 (((class color)
2801 (background dark))
2802 (:foreground "orange1" :bold t ))
2803 (t (:italic t)))
2804 "Font lock mode face used to highlight AMS keywords."
2805 :group 'font-lock-highlighting-faces)
2806
2a9eb3f5
DN
2807(defvar verilog-font-grouping-keywords-face
2808 'verilog-font-lock-grouping-keywords-face
2809 "Font to use for Verilog Grouping Keywords (such as begin..end).")
2810(defface verilog-font-lock-grouping-keywords-face
2811 '((((class color)
2812 (background light))
2813 (:foreground "red4" :bold t ))
2814 (((class color)
2815 (background dark))
2816 (:foreground "red4" :bold t ))
2817 (t (:italic t)))
2818 "Font lock mode face used to highlight verilog grouping keywords."
2819 :group 'font-lock-highlighting-faces)
2820
6341f357
DN
2821(let* ((verilog-type-font-keywords
2822 (eval-when-compile
2823 (verilog-regexp-opt
2824 '(
2825 "and" "bit" "buf" "bufif0" "bufif1" "cmos" "defparam"
2826 "event" "genvar" "inout" "input" "integer" "localparam"
2827 "logic" "mailbox" "nand" "nmos" "not" "notif0" "notif1" "or"
fd9ea9d3 2828 "output" "parameter" "pmos" "pull0" "pull1" "pulldown" "pullup"
6341f357
DN
2829 "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran"
2830 "rtranif0" "rtranif1" "semaphore" "signed" "struct" "supply"
2831 "supply0" "supply1" "time" "tran" "tranif0" "tranif1"
2832 "tri" "tri0" "tri1" "triand" "trior" "trireg" "typedef"
2833 "uwire" "vectored" "wand" "wire" "wor" "xnor" "xor"
2834 ) nil )))
2835
2836 (verilog-pragma-keywords
2837 (eval-when-compile
2838 (verilog-regexp-opt
9c059794 2839 '("surefire" "synopsys" "rtl_synthesis" "verilint" "leda" "0in") nil
6341f357
DN
2840 )))
2841
fd9ea9d3 2842 (verilog-1800-2005-keywords
6341f357
DN
2843 (eval-when-compile
2844 (verilog-regexp-opt
2845 '("alias" "assert" "assume" "automatic" "before" "bind"
2846 "bins" "binsof" "break" "byte" "cell" "chandle" "class"
2847 "clocking" "config" "const" "constraint" "context" "continue"
2848 "cover" "covergroup" "coverpoint" "cross" "deassign" "design"
2849 "dist" "do" "edge" "endclass" "endclocking" "endconfig"
2850 "endgroup" "endprogram" "endproperty" "endsequence" "enum"
2851 "expect" "export" "extends" "extern" "first_match" "foreach"
2852 "forkjoin" "genvar" "highz0" "highz1" "ifnone" "ignore_bins"
2853 "illegal_bins" "import" "incdir" "include" "inside" "instance"
2854 "int" "intersect" "large" "liblist" "library" "local" "longint"
2855 "matches" "medium" "modport" "new" "noshowcancelled" "null"
2856 "packed" "program" "property" "protected" "pull0" "pull1"
2857 "pulsestyle_onevent" "pulsestyle_ondetect" "pure" "rand" "randc"
2858 "randcase" "randsequence" "ref" "release" "return" "scalared"
2859 "sequence" "shortint" "shortreal" "showcancelled" "small" "solve"
2860 "specparam" "static" "string" "strong0" "strong1" "struct"
2861 "super" "tagged" "this" "throughout" "timeprecision" "timeunit"
2862 "type" "union" "unsigned" "use" "var" "virtual" "void"
2863 "wait_order" "weak0" "weak1" "wildcard" "with" "within"
2864 ) nil )))
2865
fd9ea9d3
WS
2866 (verilog-1800-2009-keywords
2867 (eval-when-compile
2868 (verilog-regexp-opt
2869 '("accept_on" "checker" "endchecker" "eventually" "global"
2870 "implies" "let" "nexttime" "reject_on" "restrict" "s_always"
2871 "s_eventually" "s_nexttime" "s_until" "s_until_with" "strong"
2872 "sync_accept_on" "sync_reject_on" "unique0" "until"
2873 "until_with" "untyped" "weak" ) nil )))
2874
6341f357
DN
2875 (verilog-ams-keywords
2876 (eval-when-compile
2877 (verilog-regexp-opt
2878 '("above" "abs" "absdelay" "acos" "acosh" "ac_stim"
2879 "aliasparam" "analog" "analysis" "asin" "asinh" "atan" "atan2" "atanh"
2880 "branch" "ceil" "connectmodule" "connectrules" "cos" "cosh" "ddt"
2881 "ddx" "discipline" "driver_update" "enddiscipline" "endconnectrules"
2882 "endnature" "endparamset" "exclude" "exp" "final_step" "flicker_noise"
2883 "floor" "flow" "from" "ground" "hypot" "idt" "idtmod" "inf"
2884 "initial_step" "laplace_nd" "laplace_np" "laplace_zd" "laplace_zp"
2885 "last_crossing" "limexp" "ln" "log" "max" "min" "nature"
2886 "net_resolution" "noise_table" "paramset" "potential" "pow" "sin"
2887 "sinh" "slew" "sqrt" "tan" "tanh" "timer" "transition" "white_noise"
2888 "wreal" "zi_nd" "zi_np" "zi_zd" ) nil )))
2889
2890 (verilog-font-keywords
2891 (eval-when-compile
2892 (verilog-regexp-opt
2893 '(
2a9eb3f5
DN
2894 "assign" "case" "casex" "casez" "randcase" "deassign"
2895 "default" "disable" "else" "endcase" "endfunction"
6341f357
DN
2896 "endgenerate" "endinterface" "endmodule" "endprimitive"
2897 "endspecify" "endtable" "endtask" "final" "for" "force" "return" "break"
2898 "continue" "forever" "fork" "function" "generate" "if" "iff" "initial"
2899 "interface" "join" "join_any" "join_none" "macromodule" "module" "negedge"
2900 "package" "endpackage" "always" "always_comb" "always_ff"
2901 "always_latch" "posedge" "primitive" "priority" "release"
2902 "repeat" "specify" "table" "task" "unique" "wait" "while"
2903 "class" "program" "endclass" "endprogram"
2a9eb3f5
DN
2904 ) nil )))
2905
2906 (verilog-font-grouping-keywords
2907 (eval-when-compile
2908 (verilog-regexp-opt
2909 '( "begin" "end" ) nil ))))
6341f357
DN
2910
2911 (setq verilog-font-lock-keywords
2912 (list
2913 ;; Fontify all builtin keywords
2914 (concat "\\<\\(" verilog-font-keywords "\\|"
2915 ;; And user/system tasks and functions
a1ebd734
DN
2916 "\\$[a-zA-Z][a-zA-Z0-9_\\$]*"
2917 "\\)\\>")
b1d0fc86
DN
2918 ;; Fontify all types
2919 (if verilog-highlight-grouping-keywords
2920 (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
2921 'verilog-font-lock-ams-face)
2922 (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
2923 'font-lock-type-face))
2924 (cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>")
a1ebd734 2925 'font-lock-type-face)
fd9ea9d3 2926 ;; Fontify IEEE-1800-2005 keywords appropriately
6341f357 2927 (if verilog-highlight-p1800-keywords
fd9ea9d3 2928 (cons (concat "\\<\\(" verilog-1800-2005-keywords "\\)\\>")
6341f357 2929 'verilog-font-lock-p1800-face)
fd9ea9d3
WS
2930 (cons (concat "\\<\\(" verilog-1800-2005-keywords "\\)\\>")
2931 'font-lock-type-face))
2932 ;; Fontify IEEE-1800-2009 keywords appropriately
2933 (if verilog-highlight-p1800-keywords
2934 (cons (concat "\\<\\(" verilog-1800-2009-keywords "\\)\\>")
2935 'verilog-font-lock-p1800-face)
2936 (cons (concat "\\<\\(" verilog-1800-2009-keywords "\\)\\>")
6341f357
DN
2937 'font-lock-type-face))
2938 ;; Fontify Verilog-AMS keywords
2939 (cons (concat "\\<\\(" verilog-ams-keywords "\\)\\>")
60618039 2940 'verilog-font-lock-ams-face)))
6341f357
DN
2941
2942 (setq verilog-font-lock-keywords-1
2943 (append verilog-font-lock-keywords
2944 (list
2945 ;; Fontify module definitions
2946 (list
2947 "\\<\\(\\(macro\\)?module\\|primitive\\|class\\|program\\|interface\\|package\\|task\\)\\>\\s-*\\(\\sw+\\)"
2948 '(1 font-lock-keyword-face)
2949 '(3 font-lock-function-name-face 'prepend))
2950 ;; Fontify function definitions
2951 (list
2952 (concat "\\<function\\>\\s-+\\(integer\\|real\\(time\\)?\\|time\\)\\s-+\\(\\sw+\\)" )
2953 '(1 font-lock-keyword-face)
ecb0ab90 2954 '(3 font-lock-constant-face prepend))
6341f357
DN
2955 '("\\<function\\>\\s-+\\(\\[[^]]+\\]\\)\\s-+\\(\\sw+\\)"
2956 (1 font-lock-keyword-face)
ecb0ab90 2957 (2 font-lock-constant-face append))
6341f357 2958 '("\\<function\\>\\s-+\\(\\sw+\\)"
ecb0ab90 2959 1 'font-lock-constant-face append))))
6341f357
DN
2960
2961 (setq verilog-font-lock-keywords-2
2962 (append verilog-font-lock-keywords-1
2963 (list
2964 ;; Fontify pragmas
2965 (concat "\\(//\\s-*" verilog-pragma-keywords "\\s-.*\\)")
2966 ;; Fontify escaped names
2967 '("\\(\\\\\\S-*\\s-\\)" 0 font-lock-function-name-face)
2968 ;; Fontify macro definitions/ uses
2969 '("`\\s-*[A-Za-z][A-Za-z0-9_]*" 0 (if (boundp 'font-lock-preprocessor-face)
2970 'font-lock-preprocessor-face
2971 'font-lock-type-face))
2972 ;; Fontify delays/numbers
2973 '("\\(@\\)\\|\\(#\\s-*\\(\\(\[0-9_.\]+\\('s?[hdxbo][0-9a-fA-F_xz]*\\)?\\)\\|\\(([^()]+)\\|\\sw+\\)\\)\\)"
2974 0 font-lock-type-face append)
2975 ;; Fontify instantiation names
a03c2342 2976 '("\\([A-Za-z][A-Za-z0-9_]*\\)\\s-*(" 1 font-lock-function-name-face)
6341f357
DN
2977 )))
2978
2979 (setq verilog-font-lock-keywords-3
2980 (append verilog-font-lock-keywords-2
2981 (when verilog-highlight-translate-off
2982 (list
2983 ;; Fontify things in translate off regions
7ea26faf
DN
2984 '(verilog-match-translate-off
2985 (0 'verilog-font-lock-translate-off-face prepend))
2986 )))))
6341f357 2987
a03c2342
WS
2988;;
2989;; Buffer state preservation
2990
2991(defmacro verilog-save-buffer-state (&rest body)
2992 "Execute BODY forms, saving state around insignificant change.
2993Changes in text properties like `face' or `syntax-table' are
2994considered insignificant. This macro allows text properties to
2995be changed, even in a read-only buffer.
2996
2997A change is considered significant if it affects the buffer text
2998in any way that isn't completely restored again. Any
2999user-visible changes to the buffer must not be within a
3000`verilog-save-buffer-state'."
3001 ;; From c-save-buffer-state
3002 `(let* ((modified (buffer-modified-p))
3003 (buffer-undo-list t)
3004 (inhibit-read-only t)
3005 (inhibit-point-motion-hooks t)
9489a450 3006 (verilog-no-change-functions t)
a03c2342
WS
3007 before-change-functions
3008 after-change-functions
3009 deactivate-mark
3010 buffer-file-name ; Prevent primitives checking
3011 buffer-file-truename) ; for file modification
3012 (unwind-protect
3013 (progn ,@body)
3014 (and (not modified)
3015 (buffer-modified-p)
3016 (set-buffer-modified-p nil)))))
3017
3018(defmacro verilog-save-no-change-functions (&rest body)
3019 "Execute BODY forms, disabling all change hooks in BODY.
53964682 3020For insignificant changes, see instead `verilog-save-buffer-state'."
a03c2342 3021 `(let* ((inhibit-point-motion-hooks t)
9489a450 3022 (verilog-no-change-functions t)
a03c2342
WS
3023 before-change-functions
3024 after-change-functions)
3025 (progn ,@body)))
6341f357 3026
a03c2342
WS
3027;;
3028;; Comment detection and caching
3029
3030(defvar verilog-scan-cache-preserving nil
3031 "If set, the specified buffer's comment properties are static.
9489a450 3032Buffer changes will be ignored. See `verilog-inside-comment-or-string-p'
a03c2342
WS
3033and `verilog-scan'.")
3034
3035(defvar verilog-scan-cache-tick nil
3036 "Modification tick at which `verilog-scan' was last completed.")
3037(make-variable-buffer-local 'verilog-scan-cache-tick)
3038
9489a450
MM
3039(defun verilog-scan-cache-flush ()
3040 "Flush the `verilog-scan' cache."
3041 (setq verilog-scan-cache-tick nil))
3042
a03c2342
WS
3043(defun verilog-scan-cache-ok-p ()
3044 "Return t iff the scan cache is up to date."
3045 (or (and verilog-scan-cache-preserving
3046 (eq verilog-scan-cache-preserving (current-buffer))
3047 verilog-scan-cache-tick)
3048 (equal verilog-scan-cache-tick (buffer-chars-modified-tick))))
3049
3050(defmacro verilog-save-scan-cache (&rest body)
3051 "Execute the BODY forms, allowing scan cache preservation within BODY.
3052This requires that insertions must use `verilog-insert'."
3053 ;; If the buffer is out of date, trash it, as we'll not check later the tick
3054 ;; Note this must work properly if there's multiple layers of calls
3055 ;; to verilog-save-scan-cache even with differing ticks.
3056 `(progn
3057 (unless (verilog-scan-cache-ok-p) ;; Must be before let
3058 (setq verilog-scan-cache-tick nil))
3059 (let* ((verilog-scan-cache-preserving (current-buffer)))
3060 (progn ,@body))))
3061
3062(defun verilog-scan-region (beg end)
9489a450
MM
3063 "Parse between BEG and END for `verilog-inside-comment-or-string-p'.
3064This creates v-cmts properties where comments are in force."
a03c2342
WS
3065 ;; Why properties and not overlays? Overlays have much slower non O(1)
3066 ;; lookup times.
3067 ;; This function is warm - called on every verilog-insert
6341f357 3068 (save-excursion
a03c2342
WS
3069 (save-match-data
3070 (verilog-save-buffer-state
3071 (let (pt)
3072 (goto-char beg)
3073 (while (< (point) end)
3074 (cond ((looking-at "//")
3075 (setq pt (point))
3076 (or (search-forward "\n" end t)
3077 (goto-char end))
3078 ;; "1+": The leading // or /* itself isn't considered as
3079 ;; being "inside" the comment, so that a (search-backward)
3080 ;; that lands at the start of the // won't mis-indicate
9489a450
MM
3081 ;; it's inside a comment. Also otherwise it would be
3082 ;; hard to find a commented out /*AS*/ vs one that isn't
3083 (put-text-property (1+ pt) (point) 'v-cmts t))
a03c2342
WS
3084 ((looking-at "/\\*")
3085 (setq pt (point))
3086 (or (search-forward "*/" end t)
3087 ;; No error - let later code indicate it so we can
3088 ;; use inside functions on-the-fly
3089 ;;(error "%s: Unmatched /* */, at char %d"
3090 ;; (verilog-point-text) (point))
3091 (goto-char end))
9489a450
MM
3092 (put-text-property (1+ pt) (point) 'v-cmts t))
3093 ((looking-at "\"")
3094 (setq pt (point))
3095 (or (re-search-forward "[^\\]\"" end t) ;; don't forward-char first, since we look for a non backslash first
3096 ;; No error - let later code indicate it so we can
3097 (goto-char end))
3098 (put-text-property (1+ pt) (point) 'v-cmts t))
a03c2342
WS
3099 (t
3100 (forward-char 1)
9489a450
MM
3101 (if (re-search-forward "[/\"]" end t)
3102 (backward-char 1)
a03c2342
WS
3103 (goto-char end))))))))))
3104
3105(defun verilog-scan ()
3106 "Parse the buffer, marking all comments with properties.
3107Also assumes any text inserted since `verilog-scan-cache-tick'
3108either is ok to parse as a non-comment, or `verilog-insert' was used."
9489a450 3109 ;; See also `verilog-scan-debug' and `verilog-scan-and-debug'
a03c2342
WS
3110 (unless (verilog-scan-cache-ok-p)
3111 (save-excursion
3112 (verilog-save-buffer-state
3113 (when verilog-debug
3114 (message "Scanning %s cache=%s cachetick=%S tick=%S" (current-buffer)
3115 verilog-scan-cache-preserving verilog-scan-cache-tick
3116 (buffer-chars-modified-tick)))
9489a450 3117 (remove-text-properties (point-min) (point-max) '(v-cmts nil))
a03c2342
WS
3118 (verilog-scan-region (point-min) (point-max))
3119 (setq verilog-scan-cache-tick (buffer-chars-modified-tick))
8350f087 3120 (when verilog-debug (message "Scanning... done"))))))
6341f357 3121
9489a450
MM
3122(defun verilog-scan-debug ()
3123 "For debugging, show with display face results of `verilog-scan'."
3124 (font-lock-mode 0)
3125 ;;(if dbg (setq dbg (concat dbg (format "verilog-scan-debug\n"))))
3126 (save-excursion
3127 (goto-char (point-min))
3128 (remove-text-properties (point-min) (point-max) '(face nil))
3129 (while (not (eobp))
3130 (cond ((get-text-property (point) 'v-cmts)
3131 (put-text-property (point) (1+ (point)) `face 'underline)
3132 ;;(if dbg (setq dbg (concat dbg (format " v-cmts at %S\n" (point)))))
3133 (forward-char 1))
3134 (t
3135 (goto-char (or (next-property-change (point)) (point-max))))))))
3136
3137(defun verilog-scan-and-debug ()
3138 "For debugging, run `verilog-scan' and `verilog-scan-debug'."
3139 (let (verilog-scan-cache-preserving
3140 verilog-scan-cache-tick)
3141 (goto-char (point-min))
3142 (verilog-scan)
3143 (verilog-scan-debug)))
3144
3145(defun verilog-inside-comment-or-string-p (&optional pos)
3146 "Check if optional point POS is inside a comment.
a03c2342
WS
3147This may require a slow pre-parse of the buffer with `verilog-scan'
3148to establish comment properties on all text."
3149 ;; This function is very hot
3150 (verilog-scan)
9489a450
MM
3151 (if pos
3152 (and (>= pos (point-min))
3153 (get-text-property pos 'v-cmts))
3154 (get-text-property (point) 'v-cmts)))
a03c2342
WS
3155
3156(defun verilog-insert (&rest stuff)
9489a450 3157 "Insert STUFF arguments, tracking for `verilog-inside-comment-or-string-p'.
a03c2342
WS
3158Any insert that includes a comment must have the entire commente
3159inserted using a single call to `verilog-insert'."
3160 (let ((pt (point)))
3161 (while stuff
3162 (insert (car stuff))
3163 (setq stuff (cdr stuff)))
3164 (verilog-scan-region pt (point))))
3165
3166;; More searching
6341f357
DN
3167
3168(defun verilog-declaration-end ()
3169 (search-forward ";"))
3170
3171(defun verilog-point-text (&optional pointnum)
3172 "Return text describing where POINTNUM or current point is (for errors).
3173Use filename, if current buffer being edited shorten to just buffer name."
3174 (concat (or (and (equal (window-buffer (selected-window)) (current-buffer))
3175 (buffer-name))
3176 buffer-file-name
3177 (buffer-name))
9489a450 3178 ":" (int-to-string (1+ (count-lines (point-min) (or pointnum (point)))))))
6341f357
DN
3179
3180(defun electric-verilog-backward-sexp ()
495ab0d5 3181 "Move backward over one balanced expression."
6341f357
DN
3182 (interactive)
3183 ;; before that see if we are in a comment
60618039
DN
3184 (verilog-backward-sexp))
3185
6341f357 3186(defun electric-verilog-forward-sexp ()
495ab0d5 3187 "Move forward over one balanced expression."
6341f357
DN
3188 (interactive)
3189 ;; before that see if we are in a comment
60618039
DN
3190 (verilog-forward-sexp))
3191
6341f357
DN
3192;;;used by hs-minor-mode
3193(defun verilog-forward-sexp-function (arg)
3194 (if (< arg 0)
3195 (verilog-backward-sexp)
3196 (verilog-forward-sexp)))
3197
3198
3199(defun verilog-backward-sexp ()
3200 (let ((reg)
3201 (elsec 1)
3202 (found nil)
60618039 3203 (st (point)))
6341f357
DN
3204 (if (not (looking-at "\\<"))
3205 (forward-word -1))
3206 (cond
60618039 3207 ((verilog-skip-backward-comment-or-string))
6341f357
DN
3208 ((looking-at "\\<else\\>")
3209 (setq reg (concat
3210 verilog-end-block-re
3211 "\\|\\(\\<else\\>\\)"
60618039 3212 "\\|\\(\\<if\\>\\)"))
6341f357
DN
3213 (while (and (not found)
3214 (verilog-re-search-backward reg nil 'move))
3215 (cond
3216 ((match-end 1) ; matched verilog-end-block-re
3217 ; try to leap back to matching outward block by striding across
3218 ; indent level changing tokens then immediately
3219 ; previous line governs indentation.
3220 (verilog-leap-to-head))
3221 ((match-end 2) ; else, we're in deep
3222 (setq elsec (1+ elsec)))
3223 ((match-end 3) ; found it
3224 (setq elsec (1- elsec))
3225 (if (= 0 elsec)
3226 ;; Now previous line describes syntax
60618039 3227 (setq found 't))))))
6341f357
DN
3228 ((looking-at verilog-end-block-re)
3229 (verilog-leap-to-head))
3230 ((looking-at "\\(endmodule\\>\\)\\|\\(\\<endprimitive\\>\\)\\|\\(\\<endclass\\>\\)\\|\\(\\<endprogram\\>\\)\\|\\(\\<endinterface\\>\\)\\|\\(\\<endpackage\\>\\)")
3231 (cond
3232 ((match-end 1)
3233 (verilog-re-search-backward "\\<\\(macro\\)?module\\>" nil 'move))
3234 ((match-end 2)
3235 (verilog-re-search-backward "\\<primitive\\>" nil 'move))
3236 ((match-end 3)
3237 (verilog-re-search-backward "\\<class\\>" nil 'move))
3238 ((match-end 4)
3239 (verilog-re-search-backward "\\<program\\>" nil 'move))
3240 ((match-end 5)
3241 (verilog-re-search-backward "\\<interface\\>" nil 'move))
3242 ((match-end 6)
3243 (verilog-re-search-backward "\\<package\\>" nil 'move))
3244 (t
3245 (goto-char st)
3246 (backward-sexp 1))))
3247 (t
3248 (goto-char st)
60618039 3249 (backward-sexp)))))
6341f357
DN
3250
3251(defun verilog-forward-sexp ()
3252 (let ((reg)
3253 (md 2)
4c5e69c6
DN
3254 (st (point))
3255 (nest 'yes))
6341f357
DN
3256 (if (not (looking-at "\\<"))
3257 (forward-word -1))
3258 (cond
3259 ((verilog-skip-forward-comment-or-string)
60618039 3260 (verilog-forward-syntactic-ws))
4c5e69c6 3261 ((looking-at verilog-beg-block-re-ordered)
6341f357 3262 (cond
4c5e69c6
DN
3263 ((match-end 1);
3264 ;; Search forward for matching end
6341f357 3265 (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
4c5e69c6
DN
3266 ((match-end 2)
3267 ;; Search forward for matching endcase
2a9eb3f5
DN
3268 (setq reg "\\(\\<randcase\\>\\|\\(\\<unique\\>\\s-+\\|\\<priority\\>\\s-+\\)?\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
3269 (setq md 3) ;; ender is third item in regexp
3270 )
4c5e69c6 3271 ((match-end 4)
9489a450 3272 ;; might be "disable fork" or "wait fork"
fd9ea9d3
WS
3273 (let
3274 (here)
9489a450
MM
3275 (if (or
3276 (looking-at verilog-disable-fork-re)
3277 (and (looking-at "fork")
3278 (progn
3279 (setq here (point)) ;; sometimes a fork is just a fork
3280 (forward-word -1)
3281 (looking-at verilog-disable-fork-re))))
3282 (progn ;; it is a disable fork; ignore it
fd9ea9d3 3283 (goto-char (match-end 0))
9489a450 3284 (forward-word 1)
fd9ea9d3 3285 (setq reg nil))
9489a450
MM
3286 (progn ;; it is a nice simple fork
3287 (goto-char here) ;; return from looking for "disable fork"
3288 ;; Search forward for matching join
3289 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))))
4c5e69c6
DN
3290 ((match-end 6)
3291 ;; Search forward for matching endclass
6341f357 3292 (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
a3a8b002 3293
4c5e69c6
DN
3294 ((match-end 7)
3295 ;; Search forward for matching endtable
3296 (setq reg "\\<endtable\\>" )
3297 (setq nest 'no))
3298 ((match-end 8)
3299 ;; Search forward for matching endspecify
3300 (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
3301 ((match-end 9)
3302 ;; Search forward for matching endfunction
3303 (setq reg "\\<endfunction\\>" )
3304 (setq nest 'no))
3305 ((match-end 10)
a3a8b002
DN
3306 ;; Search forward for matching endfunction
3307 (setq reg "\\<endfunction\\>" )
3308 (setq nest 'no))
3309 ((match-end 14)
4c5e69c6
DN
3310 ;; Search forward for matching endtask
3311 (setq reg "\\<endtask\\>" )
3312 (setq nest 'no))
a3a8b002 3313 ((match-end 15)
4c5e69c6
DN
3314 ;; Search forward for matching endtask
3315 (setq reg "\\<endtask\\>" )
3316 (setq nest 'no))
a3a8b002 3317 ((match-end 19)
4c5e69c6
DN
3318 ;; Search forward for matching endgenerate
3319 (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
a3a8b002 3320 ((match-end 20)
4c5e69c6
DN
3321 ;; Search forward for matching endgroup
3322 (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
a3a8b002 3323 ((match-end 21)
4c5e69c6
DN
3324 ;; Search forward for matching endproperty
3325 (setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
a3a8b002 3326 ((match-end 25)
4c5e69c6
DN
3327 ;; Search forward for matching endsequence
3328 (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" )
3329 (setq md 3)) ; 3 to get to endsequence in the reg above
a3a8b002 3330 ((match-end 27)
4c5e69c6
DN
3331 ;; Search forward for matching endclocking
3332 (setq reg "\\(\\<clocking\\>\\)\\|\\(\\<endclocking\\>\\)" )))
2a9eb3f5
DN
3333 (if (and reg
3334 (forward-word 1))
6341f357 3335 (catch 'skip
a3a8b002 3336 (if (eq nest 'yes)
82883f0a
GM
3337 (let ((depth 1)
3338 here)
4c5e69c6
DN
3339 (while (verilog-re-search-forward reg nil 'move)
3340 (cond
fd9ea9d3 3341 ((match-end md) ; a closer in regular expression, so we are climbing out
4c5e69c6
DN
3342 (setq depth (1- depth))
3343 (if (= 0 depth) ; we are out!
3344 (throw 'skip 1)))
fd9ea9d3
WS
3345 ((match-end 1) ; an opener in the r-e, so we are in deeper now
3346 (setq here (point)) ; remember where we started
3347 (goto-char (match-beginning 1))
3348 (cond
fd9ea9d3
WS
3349 ((if (or
3350 (looking-at verilog-disable-fork-re)
3351 (and (looking-at "fork")
82883f0a 3352 (progn
fd9ea9d3
WS
3353 (forward-word -1)
3354 (looking-at verilog-disable-fork-re))))
3355 (progn ;; it is a disable fork; another false alarm
3356 (goto-char (match-end 0)))
3357 (progn ;; it is a simple fork (or has nothing to do with fork)
3358 (goto-char here)
3359 (setq depth (1+ depth))))))))))
4c5e69c6
DN
3360 (if (verilog-re-search-forward reg nil 'move)
3361 (throw 'skip 1))))))
a3a8b002 3362
6341f357
DN
3363 ((looking-at (concat
3364 "\\(\\<\\(macro\\)?module\\>\\)\\|"
3365 "\\(\\<primitive\\>\\)\\|"
3366 "\\(\\<class\\>\\)\\|"
3367 "\\(\\<program\\>\\)\\|"
3368 "\\(\\<interface\\>\\)\\|"
3369 "\\(\\<package\\>\\)"))
3370 (cond
3371 ((match-end 1)
3372 (verilog-re-search-forward "\\<endmodule\\>" nil 'move))
3373 ((match-end 2)
3374 (verilog-re-search-forward "\\<endprimitive\\>" nil 'move))
3375 ((match-end 3)
3376 (verilog-re-search-forward "\\<endclass\\>" nil 'move))
3377 ((match-end 4)
3378 (verilog-re-search-forward "\\<endprogram\\>" nil 'move))
3379 ((match-end 5)
3380 (verilog-re-search-forward "\\<endinterface\\>" nil 'move))
3381 ((match-end 6)
3382 (verilog-re-search-forward "\\<endpackage\\>" nil 'move))
3383 (t
3384 (goto-char st)
3385 (if (= (following-char) ?\) )
3386 (forward-char 1)
3387 (forward-sexp 1)))))
3388 (t
3389 (goto-char st)
3390 (if (= (following-char) ?\) )
3391 (forward-char 1)
60618039 3392 (forward-sexp 1))))))
6341f357
DN
3393
3394(defun verilog-declaration-beg ()
3395 (verilog-re-search-backward verilog-declaration-re (bobp) t))
3396
6341f357
DN
3397;;
3398;;
3399;; Mode
3400;;
3401(defvar verilog-which-tool 1)
6edb5716 3402;;;###autoload
175069ef 3403(define-derived-mode verilog-mode prog-mode "Verilog"
6341f357
DN
3404 "Major mode for editing Verilog code.
3405\\<verilog-mode-map>
3406See \\[describe-function] verilog-auto (\\[verilog-auto]) for details on how
3407AUTOs can improve coding efficiency.
3408
3409Use \\[verilog-faq] for a pointer to frequently asked questions.
3410
3411NEWLINE, TAB indents for Verilog code.
3412Delete converts tabs to spaces as it moves back.
3413
3414Supports highlighting.
3415
3416Turning on Verilog mode calls the value of the variable `verilog-mode-hook'
3417with no args, if that value is non-nil.
3418
3419Variables controlling indentation/edit style:
3420
3421 variable `verilog-indent-level' (default 3)
3422 Indentation of Verilog statements with respect to containing block.
3423 `verilog-indent-level-module' (default 3)
3424 Absolute indentation of Module level Verilog statements.
3425 Set to 0 to get initial and always statements lined up
3426 on the left side of your screen.
3427 `verilog-indent-level-declaration' (default 3)
3428 Indentation of declarations with respect to containing block.
3429 Set to 0 to get them list right under containing block.
3430 `verilog-indent-level-behavioral' (default 3)
3431 Indentation of first begin in a task or function block
37ea4b9b
JB
3432 Set to 0 to get such code to lined up underneath the task or
3433 function keyword.
6341f357 3434 `verilog-indent-level-directive' (default 1)
37ea4b9b 3435 Indentation of `ifdef/`endif blocks.
6341f357
DN
3436 `verilog-cexp-indent' (default 1)
3437 Indentation of Verilog statements broken across lines i.e.:
3438 if (a)
3439 begin
3440 `verilog-case-indent' (default 2)
3441 Indentation for case statements.
3442 `verilog-auto-newline' (default nil)
3443 Non-nil means automatically newline after semicolons and the punctuation
3444 mark after an end.
3445 `verilog-auto-indent-on-newline' (default t)
37ea4b9b 3446 Non-nil means automatically indent line after newline.
6341f357
DN
3447 `verilog-tab-always-indent' (default t)
3448 Non-nil means TAB in Verilog mode should always reindent the current line,
3449 regardless of where in the line point is when the TAB command is used.
3450 `verilog-indent-begin-after-if' (default t)
3451 Non-nil means to indent begin statements following a preceding
37ea4b9b 3452 if, else, while, for and repeat statements, if any. Otherwise,
6341f357
DN
3453 the begin is lined up with the preceding token. If t, you get:
3454 if (a)
3455 begin // amount of indent based on `verilog-cexp-indent'
3456 otherwise you get:
3457 if (a)
3458 begin
3459 `verilog-auto-endcomments' (default t)
3460 Non-nil means a comment /* ... */ is set after the ends which ends
3461 cases, tasks, functions and modules.
3462 The type and name of the object will be set between the braces.
3463 `verilog-minimum-comment-distance' (default 10)
3464 Minimum distance (in lines) between begin and end required before a comment
3465 will be inserted. Setting this variable to zero results in every
3466 end acquiring a comment; the default avoids too many redundant
3467 comments in tight quarters.
a3a8b002 3468 `verilog-auto-lineup' (default 'declarations)
6341f357
DN
3469 List of contexts where auto lineup of code should be done.
3470
3471Variables controlling other actions:
3472
3473 `verilog-linter' (default surelint)
3474 Unix program to call to run the lint checker. This is the default
3475 command for \\[compile-command] and \\[verilog-auto-save-compile].
3476
3477See \\[customize] for the complete list of variables.
3478
3479AUTO expansion functions are, in part:
3480
3481 \\[verilog-auto] Expand AUTO statements.
3482 \\[verilog-delete-auto] Remove the AUTOs.
3483 \\[verilog-inject-auto] Insert AUTOs for the first time.
3484
3485Some other functions are:
3486
3487 \\[verilog-complete-word] Complete word with appropriate possibilities.
3488 \\[verilog-mark-defun] Mark function.
3489 \\[verilog-beg-of-defun] Move to beginning of current function.
3490 \\[verilog-end-of-defun] Move to end of current function.
3491 \\[verilog-label-be] Label matching begin ... end, fork ... join, etc statements.
3492
3493 \\[verilog-comment-region] Put marked area in a comment.
3494 \\[verilog-uncomment-region] Uncomment an area commented with \\[verilog-comment-region].
495ab0d5 3495 \\[verilog-insert-block] Insert begin ... end.
6341f357
DN
3496 \\[verilog-star-comment] Insert /* ... */.
3497
495ab0d5 3498 \\[verilog-sk-always] Insert an always @(AS) begin .. end block.
6341f357
DN
3499 \\[verilog-sk-begin] Insert a begin .. end block.
3500 \\[verilog-sk-case] Insert a case block, prompting for details.
3501 \\[verilog-sk-for] Insert a for (...) begin .. end block, prompting for details.
3502 \\[verilog-sk-generate] Insert a generate .. endgenerate block.
495ab0d5 3503 \\[verilog-sk-header] Insert a header block at the top of file.
6341f357
DN
3504 \\[verilog-sk-initial] Insert an initial begin .. end block.
3505 \\[verilog-sk-fork] Insert a fork begin .. end .. join block.
3506 \\[verilog-sk-module] Insert a module .. (/*AUTOARG*/);.. endmodule block.
9489a450
MM
3507 \\[verilog-sk-ovm-class] Insert an OVM Class block.
3508 \\[verilog-sk-uvm-class] Insert an UVM Class block.
6341f357
DN
3509 \\[verilog-sk-primitive] Insert a primitive .. (.. );.. endprimitive block.
3510 \\[verilog-sk-repeat] Insert a repeat (..) begin .. end block.
3511 \\[verilog-sk-specify] Insert a specify .. endspecify block.
3512 \\[verilog-sk-task] Insert a task .. begin .. end endtask block.
3513 \\[verilog-sk-while] Insert a while (...) begin .. end block, prompting for details.
3514 \\[verilog-sk-casex] Insert a casex (...) item: begin.. end endcase block, prompting for details.
3515 \\[verilog-sk-casez] Insert a casez (...) item: begin.. end endcase block, prompting for details.
3516 \\[verilog-sk-if] Insert an if (..) begin .. end block.
3517 \\[verilog-sk-else-if] Insert an else if (..) begin .. end block.
3518 \\[verilog-sk-comment] Insert a comment block.
3519 \\[verilog-sk-assign] Insert an assign .. = ..; statement.
3520 \\[verilog-sk-function] Insert a function .. begin .. end endfunction block.
3521 \\[verilog-sk-input] Insert an input declaration, prompting for details.
3522 \\[verilog-sk-output] Insert an output declaration, prompting for details.
3523 \\[verilog-sk-state-machine] Insert a state machine definition, prompting for details.
3524 \\[verilog-sk-inout] Insert an inout declaration, prompting for details.
3525 \\[verilog-sk-wire] Insert a wire declaration, prompting for details.
3526 \\[verilog-sk-reg] Insert a register declaration, prompting for details.
3527 \\[verilog-sk-define-signal] Define signal under point as a register at the top of the module.
3528
3529All key bindings can be seen in a Verilog-buffer with \\[describe-bindings].
3530Key bindings specific to `verilog-mode-map' are:
3531
3532\\{verilog-mode-map}"
175069ef 3533 :abbrev-table verilog-mode-abbrev-table
60618039 3534 (set (make-local-variable 'beginning-of-defun-function)
6edb5716 3535 'verilog-beg-of-defun)
60618039 3536 (set (make-local-variable 'end-of-defun-function)
6edb5716 3537 'verilog-end-of-defun)
6341f357 3538 (set-syntax-table verilog-mode-syntax-table)
175069ef
SM
3539 (set (make-local-variable 'indent-line-function)
3540 #'verilog-indent-line-relative)
6341f357 3541 (setq comment-indent-function 'verilog-comment-indent)
175069ef 3542 (set (make-local-variable 'parse-sexp-ignore-comments) nil)
175069ef
SM
3543 (set (make-local-variable 'comment-start) "// ")
3544 (set (make-local-variable 'comment-end) "")
3545 (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|// *")
3546 (set (make-local-variable 'comment-multi-line) nil)
6341f357
DN
3547 ;; Set up for compilation
3548 (setq verilog-which-tool 1)
3549 (setq verilog-tool 'verilog-linter)
3550 (verilog-set-compile-command)
3551 (when (boundp 'hack-local-variables-hook) ;; Also modify any file-local-variables
3552 (add-hook 'hack-local-variables-hook 'verilog-modify-compile-command t))
3553
3554 ;; Setting up menus
6edb5716 3555 (when (featurep 'xemacs)
7d55bf04
DN
3556 (easy-menu-add verilog-stmt-menu)
3557 (easy-menu-add verilog-menu)
3558 (setq mode-popup-menu (cons "Verilog Mode" verilog-stmt-menu)))
60618039 3559
d63b01e1 3560 ;; Stuff for GNU Emacs
7ea26faf 3561 (set (make-local-variable 'font-lock-defaults)
7664ec44 3562 `((verilog-font-lock-keywords verilog-font-lock-keywords-1
7ea26faf
DN
3563 verilog-font-lock-keywords-2
3564 verilog-font-lock-keywords-3)
7664ec44 3565 nil nil nil
a3a8b002
DN
3566 ,(if (functionp 'syntax-ppss)
3567 ;; verilog-beg-of-defun uses syntax-ppss, and syntax-ppss uses
3568 ;; font-lock-beginning-of-syntax-function, so
3569 ;; font-lock-beginning-of-syntax-function, can't use
7664ec44 3570 ;; verilog-beg-of-defun.
a3a8b002
DN
3571 nil
3572 'verilog-beg-of-defun)))
6341f357 3573 ;;------------------------------------------------------------
a03c2342 3574 ;; now hook in 'verilog-highlight-include-files (eldo-mode.el&spice-mode.el)
6341f357 3575 ;; all buffer local:
a03c2342
WS
3576 (unless noninteractive ;; Else can't see the result, and change hooks are slow
3577 (when (featurep 'xemacs)
3578 (make-local-hook 'font-lock-mode-hook)
3579 (make-local-hook 'font-lock-after-fontify-buffer-hook); doesn't exist in Emacs
3580 (make-local-hook 'after-change-functions))
3581 (add-hook 'font-lock-mode-hook 'verilog-highlight-buffer t t)
3582 (add-hook 'font-lock-after-fontify-buffer-hook 'verilog-highlight-buffer t t) ; not in Emacs
3583 (add-hook 'after-change-functions 'verilog-highlight-region t t))
6341f357 3584
37ea4b9b 3585 ;; Tell imenu how to handle Verilog.
175069ef
SM
3586 (set (make-local-variable 'imenu-generic-expression)
3587 verilog-imenu-generic-expression)
9c059794 3588 ;; Tell which-func-modes that imenu knows about verilog
7d0da90e 3589 (when (boundp 'which-func-modes)
9c059794 3590 (add-to-list 'which-func-modes 'verilog-mode))
6341f357 3591 ;; hideshow support
9c059794
DN
3592 (when (boundp 'hs-special-modes-alist)
3593 (unless (assq 'verilog-mode hs-special-modes-alist)
3594 (setq hs-special-modes-alist
3595 (cons '(verilog-mode-mode "\\<begin\\>" "\\<end\\>" nil
3596 verilog-forward-sexp-function)
3597 hs-special-modes-alist))))
6341f357
DN
3598
3599 ;; Stuff for autos
9489a450
MM
3600 (add-hook 'write-contents-hooks 'verilog-auto-save-check nil 'local)
3601 ;; verilog-mode-hook call added by define-derived-mode
3602 )
6341f357
DN
3603\f
3604
3605;;
3606;; Electric functions
3607;;
3608(defun electric-verilog-terminate-line (&optional arg)
3609 "Terminate line and indent next line.
3610With optional ARG, remove existing end of line comments."
3611 (interactive)
3612 ;; before that see if we are in a comment
d63b01e1 3613 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
3614 (cond
3615 ((nth 7 state) ; Inside // comment
3616 (if (eolp)
3617 (progn
3618 (delete-horizontal-space)
3619 (newline))
3620 (progn
3621 (newline)
7ea26faf 3622 (insert "// ")
6341f357
DN
3623 (beginning-of-line)))
3624 (verilog-indent-line))
3625 ((nth 4 state) ; Inside any comment (hence /**/)
3626 (newline)
3627 (verilog-more-comment))
3628 ((eolp)
3629 ;; First, check if current line should be indented
3630 (if (save-excursion
3631 (delete-horizontal-space)
3632 (beginning-of-line)
3633 (skip-chars-forward " \t")
3634 (if (looking-at verilog-auto-end-comment-lines-re)
3635 (let ((indent-str (verilog-indent-line)))
3636 ;; Maybe we should set some endcomments
3637 (if verilog-auto-endcomments
3638 (verilog-set-auto-endcomments indent-str arg))
3639 (end-of-line)
3640 (delete-horizontal-space)
3641 (if arg
3642 ()
3643 (newline))
3644 nil)
3645 (progn
3646 (end-of-line)
3647 (delete-horizontal-space)
60618039 3648 't)))
6341f357
DN
3649 ;; see if we should line up assignments
3650 (progn
a3a8b002
DN
3651 (if (or (eq 'all verilog-auto-lineup)
3652 (eq 'assignments verilog-auto-lineup))
3653 (verilog-pretty-expr t "\\(<\\|:\\)?=" ))
60618039
DN
3654 (newline))
3655 (forward-line 1))
6341f357
DN
3656 ;; Indent next line
3657 (if verilog-auto-indent-on-newline
60618039 3658 (verilog-indent-line)))
6341f357 3659 (t
60618039 3660 (newline)))))
6341f357
DN
3661
3662(defun electric-verilog-terminate-and-indent ()
3663 "Insert a newline and indent for the next statement."
3664 (interactive)
3665 (electric-verilog-terminate-line 1))
3666
3667(defun electric-verilog-semi ()
3668 "Insert `;' character and reindent the line."
3669 (interactive)
a3a8b002 3670 (verilog-insert-last-command-event)
6341f357
DN
3671
3672 (if (or (verilog-in-comment-or-string-p)
3673 (verilog-in-escaped-name-p))
3674 ()
3675 (save-excursion
3676 (beginning-of-line)
3677 (verilog-forward-ws&directives)
60618039 3678 (verilog-indent-line))
6341f357
DN
3679 (if (and verilog-auto-newline
3680 (not (verilog-parenthesis-depth)))
3681 (electric-verilog-terminate-line))))
3682
3683(defun electric-verilog-semi-with-comment ()
3684 "Insert `;' character, reindent the line and indent for comment."
3685 (interactive)
3686 (insert "\;")
3687 (save-excursion
3688 (beginning-of-line)
3689 (verilog-indent-line))
3690 (indent-for-comment))
3691
3692(defun electric-verilog-colon ()
3693 "Insert `:' and do all indentations except line indent on this line."
3694 (interactive)
a3a8b002 3695 (verilog-insert-last-command-event)
6341f357
DN
3696 ;; Do nothing if within string.
3697 (if (or
3698 (verilog-within-string)
3699 (not (verilog-in-case-region-p)))
3700 ()
3701 (save-excursion
3702 (let ((p (point))
3703 (lim (progn (verilog-beg-of-statement) (point))))
3704 (goto-char p)
3705 (verilog-backward-case-item lim)
3706 (verilog-indent-line)))
3707;; (let ((verilog-tab-always-indent nil))
3708;; (verilog-indent-line))
3709 ))
3710
3711;;(defun electric-verilog-equal ()
3712;; "Insert `=', and do indentation if within block."
3713;; (interactive)
a3a8b002 3714;; (verilog-insert-last-command-event)
6341f357
DN
3715;; Could auto line up expressions, but not yet
3716;; (if (eq (car (verilog-calculate-indent)) 'block)
3717;; (let ((verilog-tab-always-indent nil))
3718;; (verilog-indent-command)))
3719;; )
3720
3721(defun electric-verilog-tick ()
3722 "Insert back-tick, and indent to column 0 if this is a CPP directive."
3723 (interactive)
a3a8b002 3724 (verilog-insert-last-command-event)
6341f357 3725 (save-excursion
a3a8b002
DN
3726 (if (verilog-in-directive-p)
3727 (verilog-indent-line))))
6341f357
DN
3728
3729(defun electric-verilog-tab ()
3730 "Function called when TAB is pressed in Verilog mode."
3731 (interactive)
3732 ;; If verilog-tab-always-indent, indent the beginning of the line.
7cb1c4d7
DN
3733 (cond
3734 ;; The region is active, indent it.
3735 ((and (region-active-p)
3736 (not (eq (region-beginning) (region-end))))
3737 (indent-region (region-beginning) (region-end) nil))
3738 ((or verilog-tab-always-indent
3739 (save-excursion
3740 (skip-chars-backward " \t")
3741 (bolp)))
3742 (let* ((oldpnt (point))
3743 (boi-point
3744 (save-excursion
3745 (beginning-of-line)
3746 (skip-chars-forward " \t")
3747 (verilog-indent-line)
3748 (back-to-indentation)
3749 (point))))
3750 (if (< (point) boi-point)
3751 (back-to-indentation)
3752 (cond ((not verilog-tab-to-comment))
3753 ((not (eolp))
3754 (end-of-line))
3755 (t
3756 (indent-for-comment)
3757 (when (and (eolp) (= oldpnt (point)))
6341f357 3758 ; kill existing comment
7cb1c4d7
DN
3759 (beginning-of-line)
3760 (re-search-forward comment-start-skip oldpnt 'move)
3761 (goto-char (match-beginning 0))
3762 (skip-chars-backward " \t")
3763 (kill-region (point) oldpnt)))))))
3764 (t (progn (insert "\t")))))
a3a8b002 3765
6341f357
DN
3766\f
3767
3768;;
3769;; Interactive functions
3770;;
3771
3772(defun verilog-indent-buffer ()
3773 "Indent-region the entire buffer as Verilog code.
3774To call this from the command line, see \\[verilog-batch-indent]."
3775 (interactive)
3776 (verilog-mode)
3777 (indent-region (point-min) (point-max) nil))
3778
3779(defun verilog-insert-block ()
3780 "Insert Verilog begin ... end; block in the code with right indentation."
3781 (interactive)
3782 (verilog-indent-line)
3783 (insert "begin")
3784 (electric-verilog-terminate-line)
3785 (save-excursion
3786 (electric-verilog-terminate-line)
3787 (insert "end")
3788 (beginning-of-line)
3789 (verilog-indent-line)))
3790
3791(defun verilog-star-comment ()
3792 "Insert Verilog star comment at point."
3793 (interactive)
3794 (verilog-indent-line)
3795 (insert "/*")
3796 (save-excursion
3797 (newline)
3798 (insert " */"))
3799 (newline)
3800 (insert " * "))
3801
7ea26faf 3802(defun verilog-insert-1 (fmt max)
60618039 3803 "Use format string FMT to insert integers 0 to MAX - 1.
7ea26faf
DN
3804Inserts one integer per line, at the current column. Stops early
3805if it reaches the end of the buffer."
3806 (let ((col (current-column))
3807 (n 0))
3808 (save-excursion
3809 (while (< n max)
3810 (insert (format fmt n))
3811 (forward-line 1)
3812 ;; Note that this function does not bother to check for lines
3813 ;; shorter than col.
3814 (if (eobp)
3815 (setq n max)
3816 (setq n (1+ n))
3817 (move-to-column col))))))
3818
3819(defun verilog-insert-indices (max)
3820 "Insert a set of indices into a rectangle.
3821The upper left corner is defined by point. Indices begin with 0
3822and extend to the MAX - 1. If no prefix arg is given, the user
3823is prompted for a value. The indices are surrounded by square
3824brackets \[]. For example, the following code with the point
3825located after the first 'a' gives:
6341f357
DN
3826
3827 a = b a[ 0] = b
3828 a = b a[ 1] = b
3829 a = b a[ 2] = b
3830 a = b a[ 3] = b
3831 a = b ==> insert-indices ==> a[ 4] = b
3832 a = b a[ 5] = b
3833 a = b a[ 6] = b
3834 a = b a[ 7] = b
3835 a = b a[ 8] = b"
3836
60618039 3837 (interactive "NMAX: ")
7ea26faf 3838 (verilog-insert-1 "[%3d]" max))
6341f357 3839
7ea26faf 3840(defun verilog-generate-numbers (max)
6341f357
DN
3841 "Insert a set of generated numbers into a rectangle.
3842The upper left corner is defined by point. The numbers are padded to three
3843digits, starting with 000 and extending to (MAX - 1). If no prefix argument
7ea26faf 3844is supplied, then the user is prompted for the MAX number. Consider the
6341f357
DN
3845following code fragment:
3846
7ea26faf
DN
3847 buf buf buf buf000
3848 buf buf buf buf001
3849 buf buf buf buf002
3850 buf buf buf buf003
3851 buf buf ==> generate-numbers ==> buf buf004
3852 buf buf buf buf005
3853 buf buf buf buf006
3854 buf buf buf buf007
3855 buf buf buf buf008"
3856
60618039 3857 (interactive "NMAX: ")
7ea26faf 3858 (verilog-insert-1 "%3.3d" max))
6341f357
DN
3859
3860(defun verilog-mark-defun ()
37ea4b9b 3861 "Mark the current Verilog function (or procedure).
6341f357
DN
3862This puts the mark at the end, and point at the beginning."
3863 (interactive)
7d55bf04
DN
3864 (if (featurep 'xemacs)
3865 (progn
3866 (push-mark (point))
3867 (verilog-end-of-defun)
3868 (push-mark (point))
3869 (verilog-beg-of-defun)
3870 (if (fboundp 'zmacs-activate-region)
3871 (zmacs-activate-region)))
3872 (mark-defun)))
6341f357
DN
3873
3874(defun verilog-comment-region (start end)
3875 ; checkdoc-params: (start end)
3876 "Put the region into a Verilog comment.
3877The comments that are in this area are \"deformed\":
3878`*)' becomes `!(*' and `}' becomes `!{'.
3879These deformed comments are returned to normal if you use
3880\\[verilog-uncomment-region] to undo the commenting.
3881
3882The commented area starts with `verilog-exclude-str-start', and ends with
3883`verilog-exclude-str-end'. But if you change these variables,
3884\\[verilog-uncomment-region] won't recognize the comments."
3885 (interactive "r")
3886 (save-excursion
3887 ;; Insert start and endcomments
3888 (goto-char end)
3889 (if (and (save-excursion (skip-chars-forward " \t") (eolp))
3890 (not (save-excursion (skip-chars-backward " \t") (bolp))))
3891 (forward-line 1)
3892 (beginning-of-line))
3893 (insert verilog-exclude-str-end)
3894 (setq end (point))
3895 (newline)
3896 (goto-char start)
3897 (beginning-of-line)
3898 (insert verilog-exclude-str-start)
3899 (newline)
3900 ;; Replace end-comments within commented area
3901 (goto-char end)
3902 (save-excursion
3903 (while (re-search-backward "\\*/" start t)
3904 (replace-match "*-/" t t)))
3905 (save-excursion
3906 (let ((s+1 (1+ start)))
3907 (while (re-search-backward "/\\*" s+1 t)
60618039 3908 (replace-match "/-*" t t))))))
6341f357
DN
3909
3910(defun verilog-uncomment-region ()
3911 "Uncomment a commented area; change deformed comments back to normal.
3912This command does nothing if the pointer is not in a commented
3913area. See also `verilog-comment-region'."
3914 (interactive)
3915 (save-excursion
3916 (let ((start (point))
3917 (end (point)))
3918 ;; Find the boundaries of the comment
3919 (save-excursion
3920 (setq start (progn (search-backward verilog-exclude-str-start nil t)
3921 (point)))
3922 (setq end (progn (search-forward verilog-exclude-str-end nil t)
3923 (point))))
3924 ;; Check if we're really inside a comment
3925 (if (or (equal start (point)) (<= end (point)))
3926 (message "Not standing within commented area.")
3927 (progn
3928 ;; Remove endcomment
3929 (goto-char end)
3930 (beginning-of-line)
3931 (let ((pos (point)))
3932 (end-of-line)
3933 (delete-region pos (1+ (point))))
3934 ;; Change comments back to normal
3935 (save-excursion
3936 (while (re-search-backward "\\*-/" start t)
3937 (replace-match "*/" t t)))
3938 (save-excursion
3939 (while (re-search-backward "/-\\*" start t)
3940 (replace-match "/*" t t)))
3941 ;; Remove start comment
3942 (goto-char start)
3943 (beginning-of-line)
3944 (let ((pos (point)))
3945 (end-of-line)
3946 (delete-region pos (1+ (point)))))))))
3947
3948(defun verilog-beg-of-defun ()
3949 "Move backward to the beginning of the current function or procedure."
3950 (interactive)
3951 (verilog-re-search-backward verilog-defun-re nil 'move))
3952
9489a450
MM
3953(defun verilog-beg-of-defun-quick ()
3954 "Move backward to the beginning of the current function or procedure.
3955Uses `verilog-scan' cache."
3956 (interactive)
3957 (verilog-re-search-backward-quick verilog-defun-re nil 'move))
3958
6341f357
DN
3959(defun verilog-end-of-defun ()
3960 "Move forward to the end of the current function or procedure."
3961 (interactive)
3962 (verilog-re-search-forward verilog-end-defun-re nil 'move))
3963
3964(defun verilog-get-beg-of-defun (&optional warn)
3965 (save-excursion
3966 (cond ((verilog-re-search-forward-quick verilog-defun-re nil t)
3967 (point))
3968 (t
3969 (error "%s: Can't find module beginning" (verilog-point-text))
3970 (point-max)))))
3971(defun verilog-get-end-of-defun (&optional warn)
3972 (save-excursion
3973 (cond ((verilog-re-search-forward-quick verilog-end-defun-re nil t)
3974 (point))
3975 (t
3976 (error "%s: Can't find endmodule" (verilog-point-text))
3977 (point-max)))))
3978
3979(defun verilog-label-be (&optional arg)
3980 "Label matching begin ... end, fork ... join and case ... endcase statements.
3981With ARG, first kill any existing labels."
3982 (interactive)
3983 (let ((cnt 0)
3984 (oldpos (point))
3985 (b (progn
3986 (verilog-beg-of-defun)
3987 (point-marker)))
3988 (e (progn
3989 (verilog-end-of-defun)
60618039 3990 (point-marker))))
6341f357
DN
3991 (goto-char (marker-position b))
3992 (if (> (- e b) 200)
3993 (message "Relabeling module..."))
3994 (while (and
3995 (> (marker-position e) (point))
3996 (verilog-re-search-forward
3997 (concat
3998 "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\|\\(interface\\)\\|\\(package\\)\\|\\(case\\)\\)?\\>"
3999 "\\|\\(`endif\\)\\|\\(`else\\)")
4000 nil 'move))
4001 (goto-char (match-beginning 0))
4002 (let ((indent-str (verilog-indent-line)))
4003 (verilog-set-auto-endcomments indent-str 't)
4004 (end-of-line)
60618039 4005 (delete-horizontal-space))
6341f357
DN
4006 (setq cnt (1+ cnt))
4007 (if (= 9 (% cnt 10))
60618039 4008 (message "%d..." cnt)))
6341f357
DN
4009 (goto-char oldpos)
4010 (if (or
4011 (> (- e b) 200)
4012 (> cnt 20))
60618039 4013 (message "%d lines auto commented" cnt))))
6341f357
DN
4014
4015(defun verilog-beg-of-statement ()
4016 "Move backward to beginning of statement."
4017 (interactive)
4018 ;; Move back token by token until we see the end
4c36be58 4019 ;; of some earlier line.
a03c2342
WS
4020 (let (h)
4021 (while
4022 ;; If the current point does not begin a new
4023 ;; statement, as in the character ahead of us is a ';', or SOF
4024 ;; or the string after us unambiguously starts a statement,
4025 ;; or the token before us unambiguously ends a statement,
4026 ;; then move back a token and test again.
4027 (not (or
4028 ;; stop if beginning of buffer
4029 (bolp)
4030 ;; stop if we find a ;
4031 (= (preceding-char) ?\;)
4032 ;; stop if we see a named coverpoint
4033 (looking-at "\\w+\\W*:\\W*\\(coverpoint\\|cross\\|constraint\\)")
4034 ;; keep going if we are in the middle of a word
4035 (not (or (looking-at "\\<") (forward-word -1)))
53964682 4036 ;; stop if we see an assertion (perhaps labeled)
a03c2342
WS
4037 (and
4038 (looking-at "\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)")
4039 (progn
4040 (setq h (point))
4041 (save-excursion
4042 (verilog-backward-token)
4043 (if (looking-at verilog-label-re)
4044 (setq h (point))))
4045 (goto-char h)))
4046 ;; stop if we see a complete reg, perhaps an extended one
4047 (and
4048 (looking-at verilog-complete-reg)
4049 (let* ((p (point)))
4050 (while (and (looking-at verilog-extended-complete-re)
4051 (progn (setq p (point))
4052 (verilog-backward-token)
4053 (/= p (point)))))
4054 (goto-char p)))
4055 ;; stop if we see a complete reg (previous found extended ones)
4056 (looking-at verilog-basic-complete-re)
4057 ;; stop if previous token is an ender
4058 (save-excursion
4059 (verilog-backward-token)
4060 (or
4061 (looking-at verilog-end-block-re)
4062 (looking-at verilog-preprocessor-re))))) ;; end of test
6341f357
DN
4063 (verilog-backward-syntactic-ws)
4064 (verilog-backward-token))
a03c2342
WS
4065 ;; Now point is where the previous line ended.
4066 (verilog-forward-syntactic-ws)))
6341f357
DN
4067
4068(defun verilog-beg-of-statement-1 ()
4069 "Move backward to beginning of statement."
4070 (interactive)
a3a8b002
DN
4071 (if (verilog-in-comment-p)
4072 (verilog-backward-syntactic-ws))
6341f357 4073 (let ((pt (point)))
a3a8b002
DN
4074 (catch 'done
4075 (while (not (looking-at verilog-complete-reg))
4076 (setq pt (point))
4077 (verilog-backward-syntactic-ws)
4078 (if (or (bolp)
a03c2342
WS
4079 (= (preceding-char) ?\;)
4080 (save-excursion
4081 (verilog-backward-token)
4082 (looking-at verilog-ends-re)))
a3a8b002
DN
4083 (progn
4084 (goto-char pt)
4085 (throw 'done t))
4086 (verilog-backward-token))))
4087 (verilog-forward-syntactic-ws)))
4088;
4089; (while (and
4090; (not (looking-at verilog-complete-reg))
4091; (not (bolp))
4092; (not (= (preceding-char) ?\;)))
4093; (verilog-backward-token)
4094; (verilog-backward-syntactic-ws)
4095; (setq pt (point)))
4096; (goto-char pt)
4097; ;(verilog-forward-syntactic-ws)
6341f357
DN
4098
4099(defun verilog-end-of-statement ()
4100 "Move forward to end of current statement."
4101 (interactive)
4102 (let ((nest 0) pos)
a3a8b002
DN
4103 (cond
4104 ((verilog-in-directive-p)
4105 (forward-line 1)
4106 (backward-char 1))
4107
4108 ((looking-at verilog-beg-block-re)
4109 (verilog-forward-sexp))
4110
4111 ((equal (char-after) ?\})
4112 (forward-char))
4113
4114 ;; Skip to end of statement
4115 ((condition-case nil
4116 (setq pos
4117 (catch 'found
4118 (while t
4119 (forward-sexp 1)
4120 (verilog-skip-forward-comment-or-string)
4121 (if (eolp)
4122 (forward-line 1))
4123 (cond ((looking-at "[ \t]*;")
4124 (skip-chars-forward "^;")
4125 (forward-char 1)
4126 (throw 'found (point)))
4127 ((save-excursion
4128 (forward-sexp -1)
4129 (looking-at verilog-beg-block-re))
4130 (goto-char (match-beginning 0))
4131 (throw 'found nil))
4132 ((looking-at "[ \t]*)")
4133 (throw 'found (point)))
4134 ((eobp)
4135 (throw 'found (point)))
4136 )))
4137
4138 )
4139 (error nil))
4140 (if (not pos)
4141 ;; Skip a whole block
4142 (catch 'found
4143 (while t
4144 (verilog-re-search-forward verilog-end-statement-re nil 'move)
4145 (setq nest (if (match-end 1)
4146 (1+ nest)
4147 (1- nest)))
4148 (cond ((eobp)
4149 (throw 'found (point)))
4150 ((= 0 nest)
4151 (throw 'found (verilog-end-of-statement))))))
4152 pos)))))
6341f357
DN
4153
4154(defun verilog-in-case-region-p ()
37ea4b9b
JB
4155 "Return true if in a case region.
4156More specifically, point @ in the line foo : @ begin"
6341f357
DN
4157 (interactive)
4158 (save-excursion
4159 (if (and
4160 (progn (verilog-forward-syntactic-ws)
4161 (looking-at "\\<begin\\>"))
4162 (progn (verilog-backward-syntactic-ws)
4163 (= (preceding-char) ?\:)))
4164 (catch 'found
4165 (let ((nest 1))
4166 (while t
4167 (verilog-re-search-backward
4168 (concat "\\(\\<module\\>\\)\\|\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|"
4169 "\\(\\<endcase\\>\\)\\>")
4170 nil 'move)
4171 (cond
4172 ((match-end 3)
4173 (setq nest (1+ nest)))
4174 ((match-end 2)
4175 (if (= nest 1)
4176 (throw 'found 1))
4177 (setq nest (1- nest)))
4178 (t
60618039 4179 (throw 'found (= nest 0)))))))
6341f357 4180 nil)))
9489a450 4181
a03c2342 4182(defun verilog-backward-up-list (arg)
9489a450
MM
4183 "Like `backward-up-list', but deal with comments."
4184 (let ((parse-sexp-ignore-comments t))
4185 (backward-up-list arg)))
4186
4187(defun verilog-forward-sexp-cmt (arg)
4188 "Call `forward-sexp', inside comments."
4189 (let ((parse-sexp-ignore-comments nil))
4190 (forward-sexp arg)))
4191
4192(defun verilog-forward-sexp-ign-cmt (arg)
4193 "Call `forward-sexp', ignoring comments."
4194 (let ((parse-sexp-ignore-comments t))
4195 (forward-sexp arg)))
a03c2342 4196
6341f357 4197(defun verilog-in-struct-region-p ()
37ea4b9b
JB
4198 "Return true if in a struct region.
4199More specifically, in a list after a struct|union keyword."
6341f357
DN
4200 (interactive)
4201 (save-excursion
d63b01e1 4202 (let* ((state (verilog-syntax-ppss))
6341f357
DN
4203 (depth (nth 0 state)))
4204 (if depth
a03c2342 4205 (progn (verilog-backward-up-list depth)
6341f357 4206 (verilog-beg-of-statement)
60618039 4207 (looking-at "\\<typedef\\>?\\s-*\\<struct\\|union\\>"))))))
6341f357
DN
4208
4209(defun verilog-in-generate-region-p ()
37ea4b9b
JB
4210 "Return true if in a generate region.
4211More specifically, after a generate and before an endgenerate."
6341f357 4212 (interactive)
a3a8b002 4213 (let ((nest 1))
6341f357 4214 (save-excursion
a3a8b002
DN
4215 (catch 'done
4216 (while (and
4217 (/= nest 0)
4218 (verilog-re-search-backward
4219 "\\<\\(module\\)\\|\\(generate\\)\\|\\(endgenerate\\)\\>" nil 'move)
4220 (cond
4221 ((match-end 1) ; module - we have crawled out
4222 (throw 'done 1))
4223 ((match-end 2) ; generate
4224 (setq nest (1- nest)))
4225 ((match-end 3) ; endgenerate
4226 (setq nest (1+ nest))))))))
6341f357
DN
4227 (= nest 0) )) ; return nest
4228
4229(defun verilog-in-fork-region-p ()
4230 "Return true if between a fork and join."
4231 (interactive)
4232 (let ((lim (save-excursion (verilog-beg-of-defun) (point)))
60618039 4233 (nest 1))
6341f357
DN
4234 (save-excursion
4235 (while (and
4236 (/= nest 0)
4237 (verilog-re-search-backward "\\<\\(fork\\)\\|\\(join\\(_any\\|_none\\)?\\)\\>" lim 'move)
4238 (cond
4239 ((match-end 1) ; fork
4240 (setq nest (1- nest)))
4241 ((match-end 2) ; join
60618039 4242 (setq nest (1+ nest)))))))
6341f357
DN
4243 (= nest 0) )) ; return nest
4244
4245(defun verilog-backward-case-item (lim)
4246 "Skip backward to nearest enclosing case item.
4247Limit search to point LIM."
4248 (interactive)
4249 (let ((str 'nil)
4250 (lim1
4251 (progn
4252 (save-excursion
4253 (verilog-re-search-backward verilog-endcomment-reason-re
4254 lim 'move)
4255 (point)))))
4256 ;; Try to find the real :
4257 (if (save-excursion (search-backward ":" lim1 t))
4258 (let ((colon 0)
4259 b e )
4260 (while
4261 (and
4262 (< colon 1)
4263 (verilog-re-search-backward "\\(\\[\\)\\|\\(\\]\\)\\|\\(:\\)"
4264 lim1 'move))
4265 (cond
4266 ((match-end 1) ;; [
4267 (setq colon (1+ colon))
4268 (if (>= colon 0)
4269 (error "%s: unbalanced [" (verilog-point-text))))
4270 ((match-end 2) ;; ]
4271 (setq colon (1- colon)))
4272
4273 ((match-end 3) ;; :
60618039 4274 (setq colon (1+ colon)))))
6341f357
DN
4275 ;; Skip back to beginning of case item
4276 (skip-chars-backward "\t ")
4277 (verilog-skip-backward-comment-or-string)
4278 (setq e (point))
4279 (setq b
4280 (progn
4281 (if
4282 (verilog-re-search-backward
4283 "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
4284 (progn
4285 (cond
4286 ((match-end 1)
4287 (goto-char (match-end 1))
4288 (verilog-forward-ws&directives)
4289 (if (looking-at "(")
4290 (progn
4291 (forward-sexp)
4292 (verilog-forward-ws&directives)))
4293 (point))
4294 (t
4295 (goto-char (match-end 0))
4296 (verilog-forward-ws&directives)
60618039
DN
4297 (point))))
4298 (error "Malformed case item"))))
6341f357
DN
4299 (setq str (buffer-substring b e))
4300 (if
4301 (setq e
4302 (string-match
4303 "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
4304 (setq str (concat (substring str 0 e) "...")))
4305 str)
4306 'nil)))
4307\f
4308
4309;;
4310;; Other functions
4311;;
4312
6ca0ff73 4313(defun verilog-kill-existing-comment ()
6341f357
DN
4314 "Kill auto comment on this line."
4315 (save-excursion
4316 (let* (
4317 (e (progn
4318 (end-of-line)
4319 (point)))
4320 (b (progn
4321 (beginning-of-line)
4322 (search-forward "//" e t))))
4323 (if b
4324 (delete-region (- b 2) e)))))
4325
4326(defconst verilog-directive-nest-re
4327 (concat "\\(`else\\>\\)\\|"
4328 "\\(`endif\\>\\)\\|"
4329 "\\(`if\\>\\)\\|"
4330 "\\(`ifdef\\>\\)\\|"
a03c2342
WS
4331 "\\(`ifndef\\>\\)\\|"
4332 "\\(`elsif\\>\\)"))
6341f357
DN
4333(defun verilog-set-auto-endcomments (indent-str kill-existing-comment)
4334 "Add ending comment with given INDENT-STR.
4335With KILL-EXISTING-COMMENT, remove what was there before.
4336Insert `// case: 7 ' or `// NAME ' on this line if appropriate.
4337Insert `// case expr ' if this line ends a case block.
4338Insert `// ifdef FOO ' if this line ends code conditional on FOO.
37ea4b9b
JB
4339Insert `// NAME ' if this line ends a function, task, module,
4340primitive or interface named NAME."
6341f357
DN
4341 (save-excursion
4342 (cond
4343 (; Comment close preprocessor directives
4344 (and
4345 (looking-at "\\(`endif\\)\\|\\(`else\\)")
4346 (or kill-existing-comment
4347 (not (save-excursion
4348 (end-of-line)
3ba6b2ee 4349 (search-backward "//" (point-at-bol) t)))))
6341f357
DN
4350 (let ((nest 1) b e
4351 m
60618039 4352 (else (if (match-end 2) "!" " ")))
6341f357
DN
4353 (end-of-line)
4354 (if kill-existing-comment
6ca0ff73 4355 (verilog-kill-existing-comment))
6341f357
DN
4356 (delete-horizontal-space)
4357 (save-excursion
4358 (backward-sexp 1)
4359 (while (and (/= nest 0)
4360 (verilog-re-search-backward verilog-directive-nest-re nil 'move))
4361 (cond
4362 ((match-end 1) ; `else
4363 (if (= nest 1)
4364 (setq else "!")))
4365 ((match-end 2) ; `endif
4366 (setq nest (1+ nest)))
4367 ((match-end 3) ; `if
4368 (setq nest (1- nest)))
4369 ((match-end 4) ; `ifdef
4370 (setq nest (1- nest)))
4371 ((match-end 5) ; `ifndef
a03c2342
WS
4372 (setq nest (1- nest)))
4373 ((match-end 6) ; `elsif
4374 (if (= nest 1)
4375 (progn
4376 (setq else "!")
4377 (setq nest 0))))))
6341f357
DN
4378 (if (match-end 0)
4379 (setq
4380 m (buffer-substring
4381 (match-beginning 0)
4382 (match-end 0))
4383 b (progn
4384 (skip-chars-forward "^ \t")
4385 (verilog-forward-syntactic-ws)
4386 (point))
4387 e (progn
4388 (skip-chars-forward "a-zA-Z0-9_")
60618039 4389 (point)))))
6341f357
DN
4390 (if b
4391 (if (> (count-lines (point) b) verilog-minimum-comment-distance)
4392 (insert (concat " // " else m " " (buffer-substring b e))))
4393 (progn
a03c2342 4394 (insert " // unmatched `else, `elsif or `endif")
60618039 4395 (ding 't)))))
6341f357
DN
4396
4397 (; Comment close case/class/function/task/module and named block
4398 (and (looking-at "\\<end")
4399 (or kill-existing-comment
4400 (not (save-excursion
4401 (end-of-line)
3ba6b2ee 4402 (search-backward "//" (point-at-bol) t)))))
6341f357
DN
4403 (let ((type (car indent-str)))
4404 (unless (eq type 'declaration)
4405 (unless (looking-at (concat "\\(" verilog-end-block-ordered-re "\\)[ \t]*:")) ;; ignore named ends
4406 (if (looking-at verilog-end-block-ordered-re)
4407 (cond
4408 (;- This is a case block; search back for the start of this case
4409 (match-end 1) ;; of verilog-end-block-ordered-re
4410
4411 (let ((err 't)
4412 (str "UNMATCHED!!"))
4413 (save-excursion
4414 (verilog-leap-to-head)
4415 (cond
4416 ((looking-at "\\<randcase\\>")
4417 (setq str "randcase")
7ea26faf 4418 (setq err nil))
a3a8b002
DN
4419 ((looking-at "\\(\\(unique\\s-+\\|priority\\s-+\\)?case[xz]?\\)")
4420 (goto-char (match-end 0))
4421 (setq str (concat (match-string 0) " " (verilog-get-expr)))
4422 (setq err nil))
4423 ))
6341f357
DN
4424 (end-of-line)
4425 (if kill-existing-comment
6ca0ff73 4426 (verilog-kill-existing-comment))
6341f357
DN
4427 (delete-horizontal-space)
4428 (insert (concat " // " str ))
7ea26faf 4429 (if err (ding 't))))
6341f357
DN
4430
4431 (;- This is a begin..end block
4432 (match-end 2) ;; of verilog-end-block-ordered-re
4433 (let ((str " // UNMATCHED !!")
4434 (err 't)
4435 (here (point))
4436 there
60618039 4437 cntx)
6341f357
DN
4438 (save-excursion
4439 (verilog-leap-to-head)
4440 (setq there (point))
4441 (if (not (match-end 0))
4442 (progn
4443 (goto-char here)
4444 (end-of-line)
4445 (if kill-existing-comment
6ca0ff73 4446 (verilog-kill-existing-comment))
6341f357
DN
4447 (delete-horizontal-space)
4448 (insert str)
60618039 4449 (ding 't))
6341f357
DN
4450 (let ((lim
4451 (save-excursion (verilog-beg-of-defun) (point)))
60618039 4452 (here (point)))
6341f357
DN
4453 (cond
4454 (;-- handle named block differently
4455 (looking-at verilog-named-block-re)
4456 (search-forward ":")
4457 (setq there (point))
4458 (setq str (verilog-get-expr))
4459 (setq err nil)
4460 (setq str (concat " // block: " str )))
4461
4462 ((verilog-in-case-region-p) ;-- handle case item differently
4463 (goto-char here)
4464 (setq str (verilog-backward-case-item lim))
4465 (setq there (point))
4466 (setq err nil)
4467 (setq str (concat " // case: " str )))
4468
4469 (;- try to find "reason" for this begin
4470 (cond
4471 (;
4472 (eq here (progn
a03c2342
WS
4473 ;; (verilog-backward-token)
4474 (verilog-beg-of-statement)
6341f357
DN
4475 (point)))
4476 (setq err nil)
4477 (setq str ""))
4478 ((looking-at verilog-endcomment-reason-re)
4479 (setq there (match-end 0))
a3a8b002 4480 (setq cntx (concat (match-string 0) " "))
6341f357
DN
4481 (cond
4482 (;- begin
a3a8b002 4483 (match-end 1)
6341f357
DN
4484 (setq err nil)
4485 (save-excursion
4486 (if (and (verilog-continued-line)
4487 (looking-at "\\<repeat\\>\\|\\<wait\\>\\|\\<always\\>"))
4488 (progn
4489 (goto-char (match-end 0))
4490 (setq there (point))
4491 (setq str
a3a8b002 4492 (concat " // " (match-string 0) " " (verilog-get-expr))))
6341f357
DN
4493 (setq str ""))))
4494
4495 (;- else
a3a8b002 4496 (match-end 2)
6341f357 4497 (let ((nest 0)
a03c2342 4498 ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)\\|\\(assert\\)"))
6341f357
DN
4499 (catch 'skip
4500 (while (verilog-re-search-backward reg nil 'move)
4501 (cond
4502 ((match-end 1) ; begin
4503 (setq nest (1- nest)))
4504 ((match-end 2) ; end
4505 (setq nest (1+ nest)))
4506 ((match-end 3)
4507 (if (= 0 nest)
4508 (progn
4509 (goto-char (match-end 0))
4510 (setq there (point))
4511 (setq err nil)
4512 (setq str (verilog-get-expr))
4513 (setq str (concat " // else: !if" str ))
a03c2342
WS
4514 (throw 'skip 1))))
4515 ((match-end 4)
4516 (if (= 0 nest)
4517 (progn
4518 (goto-char (match-end 0))
4519 (setq there (point))
4520 (setq err nil)
4521 (setq str (verilog-get-expr))
4522 (setq str (concat " // else: !assert " str ))
60618039 4523 (throw 'skip 1)))))))))
6341f357 4524 (;- end else
a3a8b002 4525 (match-end 3)
6341f357
DN
4526 (goto-char there)
4527 (let ((nest 0)
a03c2342 4528 (reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)\\|\\(assert\\)"))
6341f357
DN
4529 (catch 'skip
4530 (while (verilog-re-search-backward reg nil 'move)
4531 (cond
4532 ((match-end 1) ; begin
4533 (setq nest (1- nest)))
4534 ((match-end 2) ; end
4535 (setq nest (1+ nest)))
4536 ((match-end 3)
4537 (if (= 0 nest)
4538 (progn
4539 (goto-char (match-end 0))
4540 (setq there (point))
4541 (setq err nil)
4542 (setq str (verilog-get-expr))
4543 (setq str (concat " // else: !if" str ))
a03c2342
WS
4544 (throw 'skip 1))))
4545 ((match-end 4)
4546 (if (= 0 nest)
4547 (progn
4548 (goto-char (match-end 0))
4549 (setq there (point))
4550 (setq err nil)
4551 (setq str (verilog-get-expr))
4552 (setq str (concat " // else: !assert " str ))
60618039 4553 (throw 'skip 1)))))))))
a03c2342 4554
a3a8b002
DN
4555 (; always_comb, always_ff, always_latch
4556 (or (match-end 4) (match-end 5) (match-end 6))
4557 (goto-char (match-end 0))
4558 (setq there (point))
4559 (setq err nil)
4560 (setq str (concat " // " cntx )))
6341f357
DN
4561
4562 (;- task/function/initial et cetera
4563 t
4564 (match-end 0)
4565 (goto-char (match-end 0))
4566 (setq there (point))
4567 (setq err nil)
a3a8b002 4568 (setq str (concat " // " cntx (verilog-get-expr))))
6341f357
DN
4569
4570 (;-- otherwise...
60618039 4571 (setq str " // auto-endcomment confused "))))
6341f357
DN
4572
4573 ((and
4574 (verilog-in-case-region-p) ;-- handle case item differently
4575 (progn
4576 (setq there (point))
4577 (goto-char here)
4578 (setq str (verilog-backward-case-item lim))))
4579 (setq err nil)
4580 (setq str (concat " // case: " str )))
4581
4582 ((verilog-in-fork-region-p)
4583 (setq err nil)
4584 (setq str " // fork branch" ))
4585
4586 ((looking-at "\\<end\\>")
4587 ;; HERE
4588 (forward-word 1)
4589 (verilog-forward-syntactic-ws)
4590 (setq err nil)
4591 (setq str (verilog-get-expr))
4592 (setq str (concat " // " cntx str )))
4593
4594 ))))
4595 (goto-char here)
4596 (end-of-line)
4597 (if kill-existing-comment
6ca0ff73 4598 (verilog-kill-existing-comment))
6341f357
DN
4599 (delete-horizontal-space)
4600 (if (or err
4601 (> (count-lines here there) verilog-minimum-comment-distance))
4602 (insert str))
4603 (if err (ding 't))
4604 ))))
4605 (;- this is endclass, which can be nested
4606 (match-end 11) ;; of verilog-end-block-ordered-re
4607 ;;(goto-char there)
4608 (let ((nest 0)
60618039
DN
4609 (reg "\\<\\(class\\)\\|\\(endclass\\)\\|\\(package\\|primitive\\|\\(macro\\)?module\\)\\>")
4610 string)
6341f357
DN
4611 (save-excursion
4612 (catch 'skip
4613 (while (verilog-re-search-backward reg nil 'move)
4614 (cond
4615 ((match-end 3) ; endclass
4616 (ding 't)
4617 (setq string "unmatched endclass")
4618 (throw 'skip 1))
4619
4620 ((match-end 2) ; endclass
4621 (setq nest (1+ nest)))
4622
4623 ((match-end 1) ; class
4624 (setq nest (1- nest))
4625 (if (< nest 0)
4626 (progn
4627 (goto-char (match-end 0))
4628 (let (b e)
4629 (setq b (progn
4630 (skip-chars-forward "^ \t")
4631 (verilog-forward-ws&directives)
4632 (point))
4633 e (progn
4634 (skip-chars-forward "a-zA-Z0-9_")
4635 (point)))
4636 (setq string (buffer-substring b e)))
4637 (throw 'skip 1))))
4638 ))))
4639 (end-of-line)
60618039 4640 (insert (concat " // " string ))))
6341f357
DN
4641
4642 (;- this is end{function,generate,task,module,primitive,table,generate}
4643 ;- which can not be nested.
4644 t
9c059794 4645 (let (string reg (name-re nil))
6341f357
DN
4646 (end-of-line)
4647 (if kill-existing-comment
4648 (save-match-data
6ca0ff73 4649 (verilog-kill-existing-comment)))
6341f357
DN
4650 (delete-horizontal-space)
4651 (backward-sexp)
4652 (cond
4653 ((match-end 5) ;; of verilog-end-block-ordered-re
4654 (setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
9c059794
DN
4655 (setq name-re "\\w+\\s-*(")
4656 )
6341f357
DN
4657 ((match-end 6) ;; of verilog-end-block-ordered-re
4658 (setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)"))
4659 ((match-end 7) ;; of verilog-end-block-ordered-re
4660 (setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>"))
4661 ((match-end 8) ;; of verilog-end-block-ordered-re
4662 (setq reg "\\(\\<primitive\\>\\)\\|\\(\\<\\(endprimitive\\|package\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4663 ((match-end 9) ;; of verilog-end-block-ordered-re
4664 (setq reg "\\(\\<interface\\>\\)\\|\\(\\<\\(endinterface\\|package\\|primitive\\|\\(macro\\)?module\\)\\>\\)"))
4665 ((match-end 10) ;; of verilog-end-block-ordered-re
4666 (setq reg "\\(\\<package\\>\\)\\|\\(\\<\\(endpackage\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4667 ((match-end 11) ;; of verilog-end-block-ordered-re
4668 (setq reg "\\(\\<class\\>\\)\\|\\(\\<\\(endclass\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4669 ((match-end 12) ;; of verilog-end-block-ordered-re
4670 (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<\\(endcovergroup\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4671 ((match-end 13) ;; of verilog-end-block-ordered-re
4672 (setq reg "\\(\\<program\\>\\)\\|\\(\\<\\(endprogram\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4673 ((match-end 14) ;; of verilog-end-block-ordered-re
4674 (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<\\(endsequence\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
4675 ((match-end 15) ;; of verilog-end-block-ordered-re
4676 (setq reg "\\(\\<clocking\\>\\)\\|\\<endclocking\\>"))
4677
60618039 4678 (t (error "Problem in verilog-set-auto-endcomments")))
6341f357
DN
4679 (let (b e)
4680 (save-excursion
4681 (verilog-re-search-backward reg nil 'move)
4682 (cond
4683 ((match-end 1)
4684 (setq b (progn
4685 (skip-chars-forward "^ \t")
4686 (verilog-forward-ws&directives)
a03c2342
WS
4687 (if (looking-at "static\\|automatic")
4688 (progn
4689 (goto-char (match-end 0))
4690 (verilog-forward-ws&directives)))
9c059794 4691 (if (and name-re (verilog-re-search-forward name-re nil 'move))
6341f357 4692 (progn
9c059794 4693 (goto-char (match-beginning 0))
60618039 4694 (verilog-forward-ws&directives)))
6341f357
DN
4695 (point))
4696 e (progn
4697 (skip-chars-forward "a-zA-Z0-9_")
4698 (point)))
4699 (setq string (buffer-substring b e)))
4700 (t
4701 (ding 't)
4702 (setq string "unmatched end(function|task|module|primitive|interface|package|class|clocking)")))))
4703 (end-of-line)
4704 (insert (concat " // " string )))
4705 ))))))))))
4706
4707(defun verilog-get-expr()
37ea4b9b 4708 "Grab expression at point, e.g, case ( a | b & (c ^d))."
6341f357
DN
4709 (let* ((b (progn
4710 (verilog-forward-syntactic-ws)
4711 (skip-chars-forward " \t")
4712 (point)))
4713 (e (let ((par 1))
4714 (cond
4715 ((looking-at "@")
4716 (forward-char 1)
4717 (verilog-forward-syntactic-ws)
4718 (if (looking-at "(")
4719 (progn
4720 (forward-char 1)
4721 (while (and (/= par 0)
4722 (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
4723 (cond
4724 ((match-end 1)
4725 (setq par (1+ par)))
4726 ((match-end 2)
4727 (setq par (1- par)))))))
4728 (point))
4729 ((looking-at "(")
4730 (forward-char 1)
4731 (while (and (/= par 0)
4732 (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
4733 (cond
4734 ((match-end 1)
4735 (setq par (1+ par)))
4736 ((match-end 2)
4737 (setq par (1- par)))))
4738 (point))
4739 ((looking-at "\\[")
4740 (forward-char 1)
4741 (while (and (/= par 0)
4742 (verilog-re-search-forward "\\(\\[\\)\\|\\(\\]\\)" nil 'move))
4743 (cond
4744 ((match-end 1)
4745 (setq par (1+ par)))
4746 ((match-end 2)
4747 (setq par (1- par)))))
4748 (verilog-forward-syntactic-ws)
4749 (skip-chars-forward "^ \t\n\f")
4750 (point))
4751 ((looking-at "/[/\\*]")
4752 b)
4753 ('t
4754 (skip-chars-forward "^: \t\n\f")
60618039 4755 (point)))))
6341f357
DN
4756 (str (buffer-substring b e)))
4757 (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
4758 (setq str (concat (substring str 0 e) "...")))
4759 str))
4760
4761(defun verilog-expand-vector ()
4762 "Take a signal vector on the current line and expand it to multiple lines.
4763Useful for creating tri's and other expanded fields."
4764 (interactive)
4765 (verilog-expand-vector-internal "[" "]"))
4766
4767(defun verilog-expand-vector-internal (bra ket)
4768 "Given BRA, the start brace and KET, the end brace, expand one line into many lines."
4769 (save-excursion
4770 (forward-line 0)
4771 (let ((signal-string (buffer-substring (point)
4772 (progn
4773 (end-of-line) (point)))))
7ea26faf
DN
4774 (if (string-match
4775 (concat "\\(.*\\)"
4776 (regexp-quote bra)
4777 "\\([0-9]*\\)\\(:[0-9]*\\|\\)\\(::[0-9---]*\\|\\)"
60618039
DN
4778 (regexp-quote ket)
4779 "\\(.*\\)$") signal-string)
6341f357 4780 (let* ((sig-head (match-string 1 signal-string))
7ea26faf 4781 (vec-start (string-to-number (match-string 2 signal-string)))
6341f357
DN
4782 (vec-end (if (= (match-beginning 3) (match-end 3))
4783 vec-start
7ea26faf
DN
4784 (string-to-number
4785 (substring signal-string (1+ (match-beginning 3))
4786 (match-end 3)))))
4787 (vec-range
4788 (if (= (match-beginning 4) (match-end 4))
4789 1
4790 (string-to-number
4791 (substring signal-string (+ 2 (match-beginning 4))
4792 (match-end 4)))))
6341f357
DN
4793 (sig-tail (match-string 5 signal-string))
4794 vec)
4795 ;; Decode vectors
4796 (setq vec nil)
4797 (if (< vec-range 0)
4798 (let ((tmp vec-start))
4799 (setq vec-start vec-end
4800 vec-end tmp
4801 vec-range (- vec-range))))
4802 (if (< vec-end vec-start)
4803 (while (<= vec-end vec-start)
4804 (setq vec (append vec (list vec-start)))
4805 (setq vec-start (- vec-start vec-range)))
4806 (while (<= vec-start vec-end)
4807 (setq vec (append vec (list vec-start)))
4808 (setq vec-start (+ vec-start vec-range))))
4809 ;;
4810 ;; Delete current line
4811 (delete-region (point) (progn (forward-line 0) (point)))
4812 ;;
4813 ;; Expand vector
4814 (while vec
7ea26faf
DN
4815 (insert (concat sig-head bra
4816 (int-to-string (car vec)) ket sig-tail "\n"))
6341f357
DN
4817 (setq vec (cdr vec)))
4818 (delete-char -1)
4819 ;;
4820 )))))
4821
4822(defun verilog-strip-comments ()
37ea4b9b 4823 "Strip all comments from the Verilog code."
6341f357
DN
4824 (interactive)
4825 (goto-char (point-min))
4826 (while (re-search-forward "//" nil t)
4827 (if (verilog-within-string)
4828 (re-search-forward "\"" nil t)
4829 (if (verilog-in-star-comment-p)
4830 (re-search-forward "\*/" nil t)
4831 (let ((bpt (- (point) 2)))
4832 (end-of-line)
4833 (delete-region bpt (point))))))
4834 ;;
4835 (goto-char (point-min))
4836 (while (re-search-forward "/\\*" nil t)
4837 (if (verilog-within-string)
4838 (re-search-forward "\"" nil t)
4839 (let ((bpt (- (point) 2)))
4840 (re-search-forward "\\*/")
4841 (delete-region bpt (point))))))
4842
4843(defun verilog-one-line ()
37ea4b9b 4844 "Convert structural Verilog instances to occupy one line."
6341f357
DN
4845 (interactive)
4846 (goto-char (point-min))
4847 (while (re-search-forward "\\([^;]\\)[ \t]*\n[ \t]*" nil t)
4848 (replace-match "\\1 " nil nil)))
4849
4850(defun verilog-linter-name ()
4851 "Return name of linter, either surelint or verilint."
4852 (let ((compile-word1 (verilog-string-replace-matches "\\s .*$" "" nil nil
4853 compile-command))
4854 (lint-word1 (verilog-string-replace-matches "\\s .*$" "" nil nil
4855 verilog-linter)))
4856 (cond ((equal compile-word1 "surelint") `surelint)
4857 ((equal compile-word1 "verilint") `verilint)
4858 ((equal lint-word1 "surelint") `surelint)
4859 ((equal lint-word1 "verilint") `verilint)
4860 (t `surelint)))) ;; back compatibility
4861
4862(defun verilog-lint-off ()
4863 "Convert a Verilog linter warning line into a disable statement.
4864For example:
4865 pci_bfm_null.v, line 46: Unused input: pci_rst_
4866becomes a comment for the appropriate tool.
4867
4868The first word of the `compile-command' or `verilog-linter'
37ea4b9b 4869variables is used to determine which product is being used.
6341f357
DN
4870
4871See \\[verilog-surelint-off] and \\[verilog-verilint-off]."
4872 (interactive)
4873 (let ((linter (verilog-linter-name)))
4874 (cond ((equal linter `surelint)
4875 (verilog-surelint-off))
4876 ((equal linter `verilint)
4877 (verilog-verilint-off))
4878 (t (error "Linter name not set")))))
4879
7ea26faf 4880(defvar compilation-last-buffer)
a3a8b002 4881(defvar next-error-last-buffer)
7ea26faf 4882
6341f357
DN
4883(defun verilog-surelint-off ()
4884 "Convert a SureLint warning line into a disable statement.
4885Run from Verilog source window; assumes there is a *compile* buffer
4886with point set appropriately.
4887
4888For example:
4889 WARNING [STD-UDDONX]: xx.v, line 8: output out is never assigned.
4890becomes:
4891 // surefire lint_line_off UDDONX"
4892 (interactive)
7ea26faf
DN
4893 (let ((buff (if (boundp 'next-error-last-buffer)
4894 next-error-last-buffer
4895 compilation-last-buffer)))
4896 (when (buffer-live-p buff)
7ea26faf
DN
4897 (save-excursion
4898 (switch-to-buffer buff)
4899 (beginning-of-line)
4900 (when
4901 (looking-at "\\(INFO\\|WARNING\\|ERROR\\) \\[[^-]+-\\([^]]+\\)\\]: \\([^,]+\\), line \\([0-9]+\\): \\(.*\\)$")
4902 (let* ((code (match-string 2))
4903 (file (match-string 3))
4904 (line (match-string 4))
4905 (buffer (get-file-buffer file))
4906 dir filename)
4907 (unless buffer
4908 (progn
4909 (setq buffer
4910 (and (file-exists-p file)
4911 (find-file-noselect file)))
4912 (or buffer
4913 (let* ((pop-up-windows t))
4914 (let ((name (expand-file-name
4915 (read-file-name
4916 (format "Find this error in: (default %s) "
4917 file)
4918 dir file t))))
4919 (if (file-directory-p name)
4920 (setq name (expand-file-name filename name)))
4921 (setq buffer
4922 (and (file-exists-p name)
4923 (find-file-noselect name))))))))
4924 (switch-to-buffer buffer)
5f68c1b7
GM
4925 (goto-char (point-min))
4926 (forward-line (- (string-to-number line)))
7ea26faf
DN
4927 (end-of-line)
4928 (catch 'already
4929 (cond
4930 ((verilog-in-slash-comment-p)
4931 (re-search-backward "//")
4932 (cond
4933 ((looking-at "// surefire lint_off_line ")
4934 (goto-char (match-end 0))
3ba6b2ee 4935 (let ((lim (point-at-eol)))
7ea26faf
DN
4936 (if (re-search-forward code lim 'move)
4937 (throw 'already t)
4938 (insert (concat " " code)))))
4939 (t
4940 )))
4941 ((verilog-in-star-comment-p)
4942 (re-search-backward "/\*")
60618039 4943 (insert (format " // surefire lint_off_line %6s" code )))
7ea26faf
DN
4944 (t
4945 (insert (format " // surefire lint_off_line %6s" code ))
4946 )))))))))
6341f357
DN
4947
4948(defun verilog-verilint-off ()
4949 "Convert a Verilint warning line into a disable statement.
4950
4951For example:
4952 (W240) pci_bfm_null.v, line 46: Unused input: pci_rst_
4953becomes:
4954 //Verilint 240 off // WARNING: Unused input"
4955 (interactive)
4956 (save-excursion
4957 (beginning-of-line)
4958 (when (looking-at "\\(.*\\)([WE]\\([0-9A-Z]+\\)).*,\\s +line\\s +[0-9]+:\\s +\\([^:\n]+\\):?.*$")
4959 (replace-match (format
4960 ;; %3s makes numbers 1-999 line up nicely
4961 "\\1//Verilint %3s off // WARNING: \\3"
4962 (match-string 2)))
4963 (beginning-of-line)
4964 (verilog-indent-line))))
4965
4966(defun verilog-auto-save-compile ()
4967 "Update automatics with \\[verilog-auto], save the buffer, and compile."
4968 (interactive)
4969 (verilog-auto) ; Always do it for safety
4970 (save-buffer)
4971 (compile compile-command))
4972
a03c2342
WS
4973(defun verilog-preprocess (&optional command filename)
4974 "Preprocess the buffer, similar to `compile', but leave output in Verilog-Mode.
4975Takes optional COMMAND or defaults to `verilog-preprocessor', and
4976FILENAME or defaults to `buffer-file-name`."
4977 (interactive
4978 (list
4979 (let ((default (verilog-expand-command verilog-preprocessor)))
4980 (set (make-local-variable `verilog-preprocessor)
4981 (read-from-minibuffer "Run Preprocessor (like this): "
4982 default nil nil
4983 'verilog-preprocess-history default)))))
4984 (unless command (setq command (verilog-expand-command verilog-preprocessor)))
8468f78b
WS
4985 (let* ((fontlocked (and (boundp 'font-lock-mode) font-lock-mode))
4986 (dir (file-name-directory (or filename buffer-file-name)))
a03c2342
WS
4987 (file (file-name-nondirectory (or filename buffer-file-name)))
4988 (cmd (concat "cd " dir "; " command " " file)))
4989 (with-output-to-temp-buffer "*Verilog-Preprocessed*"
8468f78b 4990 (with-current-buffer (get-buffer "*Verilog-Preprocessed*")
a03c2342
WS
4991 (insert (concat "// " cmd "\n"))
4992 (shell-command cmd "*Verilog-Preprocessed*")
4993 (verilog-mode)
8468f78b
WS
4994 ;; Without this force, it takes a few idle seconds
4995 ;; to get the color, which is very jarring
4996 (when fontlocked (font-lock-fontify-buffer))))))
6341f357
DN
4997\f
4998
4999;;
5000;; Batch
5001;;
5002
5003(defmacro verilog-batch-error-wrapper (&rest body)
5004 "Execute BODY and add error prefix to any errors found.
5005This lets programs calling batch mode to easily extract error messages."
6edb5716
DN
5006 `(condition-case err
5007 (progn ,@body)
5008 (error
5009 (error "%%Error: %s%s" (error-message-string err)
d63b01e1 5010 (if (featurep 'xemacs) "\n" ""))))) ;; XEmacs forgets to add a newline
6341f357 5011
9489a450
MM
5012(defun verilog-batch-execute-func (funref &optional no-save)
5013 "Internal processing of a batch command, running FUNREF on all command arguments.
5014Save the result unless optional NO-SAVE is t."
6341f357 5015 (verilog-batch-error-wrapper
14862301
SM
5016 ;; Setting global variables like that is *VERY NASTY* !!! --Stef
5017 ;; However, this function is called only when Emacs is being used as
5018 ;; a standalone language instead of as an editor, so we'll live.
5019 ;;
6341f357
DN
5020 ;; General globals needed
5021 (setq make-backup-files nil)
5022 (setq-default make-backup-files nil)
5023 (setq enable-local-variables t)
5024 (setq enable-local-eval t)
5025 ;; Make sure any sub-files we read get proper mode
14acf2f5 5026 (setq-default major-mode 'verilog-mode)
6341f357 5027 ;; Ditto files already read in
7ea26faf 5028 (mapc (lambda (buf)
60618039 5029 (when (buffer-file-name buf)
14acf2f5 5030 (with-current-buffer buf
60618039
DN
5031 (verilog-mode))))
5032 (buffer-list))
6341f357 5033 ;; Process the files
4f91a816 5034 (mapcar (lambda (buf)
9489a450
MM
5035 (when (buffer-file-name buf)
5036 (save-excursion
5037 (if (not (file-exists-p (buffer-file-name buf)))
5038 (error
5039 (concat "File not found: " (buffer-file-name buf))))
5040 (message (concat "Processing " (buffer-file-name buf)))
5041 (set-buffer buf)
5042 (funcall funref)
5043 (unless no-save (save-buffer)))))
6341f357
DN
5044 (buffer-list))))
5045
5046(defun verilog-batch-auto ()
5047 "For use with --batch, perform automatic expansions as a stand-alone tool.
37ea4b9b 5048This sets up the appropriate Verilog mode environment, updates automatics
6341f357
DN
5049with \\[verilog-auto] on all command-line files, and saves the buffers.
5050For proper results, multiple filenames need to be passed on the command
5051line in bottom-up order."
5052 (unless noninteractive
5053 (error "Use verilog-batch-auto only with --batch")) ;; Otherwise we'd mess up buffer modes
5054 (verilog-batch-execute-func `verilog-auto))
5055
5056(defun verilog-batch-delete-auto ()
5057 "For use with --batch, perform automatic deletion as a stand-alone tool.
37ea4b9b 5058This sets up the appropriate Verilog mode environment, deletes automatics
6341f357
DN
5059with \\[verilog-delete-auto] on all command-line files, and saves the buffers."
5060 (unless noninteractive
5061 (error "Use verilog-batch-delete-auto only with --batch")) ;; Otherwise we'd mess up buffer modes
5062 (verilog-batch-execute-func `verilog-delete-auto))
5063
9489a450
MM
5064(defun verilog-batch-diff-auto ()
5065 "For use with --batch, perform automatic differences as a stand-alone tool.
5066This sets up the appropriate Verilog mode environment, expand automatics
5067with \\[verilog-diff-auto] on all command-line files, and reports an error
5068if any differences are observed. This is appropriate for adding to regressions
5069to insure automatics are always properly maintained."
5070 (unless noninteractive
5071 (error "Use verilog-batch-diff-auto only with --batch")) ;; Otherwise we'd mess up buffer modes
5072 (verilog-batch-execute-func `verilog-diff-auto t))
5073
6341f357
DN
5074(defun verilog-batch-inject-auto ()
5075 "For use with --batch, perform automatic injection as a stand-alone tool.
37ea4b9b 5076This sets up the appropriate Verilog mode environment, injects new automatics
6341f357
DN
5077with \\[verilog-inject-auto] on all command-line files, and saves the buffers.
5078For proper results, multiple filenames need to be passed on the command
5079line in bottom-up order."
5080 (unless noninteractive
5081 (error "Use verilog-batch-inject-auto only with --batch")) ;; Otherwise we'd mess up buffer modes
5082 (verilog-batch-execute-func `verilog-inject-auto))
5083
5084(defun verilog-batch-indent ()
9489a450 5085 "For use with --batch, reindent an a entire file as a stand-alone tool.
37ea4b9b 5086This sets up the appropriate Verilog mode environment, calls
6341f357
DN
5087\\[verilog-indent-buffer] on all command-line files, and saves the buffers."
5088 (unless noninteractive
5089 (error "Use verilog-batch-indent only with --batch")) ;; Otherwise we'd mess up buffer modes
5090 (verilog-batch-execute-func `verilog-indent-buffer))
5091\f
5092
5093;;
5094;; Indentation
5095;;
5096(defconst verilog-indent-alist
5097 '((block . (+ ind verilog-indent-level))
5098 (case . (+ ind verilog-case-indent))
5099 (cparenexp . (+ ind verilog-indent-level))
5100 (cexp . (+ ind verilog-cexp-indent))
5101 (defun . verilog-indent-level-module)
5102 (declaration . verilog-indent-level-declaration)
5103 (directive . (verilog-calculate-indent-directive))
5104 (tf . verilog-indent-level)
5105 (behavioral . (+ verilog-indent-level-behavioral verilog-indent-level-module))
5106 (statement . ind)
5107 (cpp . 0)
5108 (comment . (verilog-comment-indent))
5109 (unknown . 3)
5110 (string . 0)))
5111
5112(defun verilog-continued-line-1 (lim)
5113 "Return true if this is a continued line.
5114Set point to where line starts. Limit search to point LIM."
5115 (let ((continued 't))
5116 (if (eq 0 (forward-line -1))
5117 (progn
5118 (end-of-line)
5119 (verilog-backward-ws&directives lim)
5120 (if (bobp)
5121 (setq continued nil)
5122 (setq continued (verilog-backward-token))))
5123 (setq continued nil))
5124 continued))
5125
5126(defun verilog-calculate-indent ()
5127 "Calculate the indent of the current Verilog line.
5128Examine previous lines. Once a line is found that is definitive as to the
37ea4b9b
JB
5129type of the current line, return that lines' indent level and its type.
5130Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
6341f357
DN
5131 (save-excursion
5132 (let* ((starting_position (point))
5133 (par 0)
5134 (begin (looking-at "[ \t]*begin\\>"))
5135 (lim (save-excursion (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)" nil t)))
5136 (type (catch 'nesting
5137 ;; Keep working backwards until we can figure out
5138 ;; what type of statement this is.
5139 ;; Basically we need to figure out
5140 ;; 1) if this is a continuation of the previous line;
5141 ;; 2) are we in a block scope (begin..end)
5142
5143 ;; if we are in a comment, done.
5144 (if (verilog-in-star-comment-p)
5145 (throw 'nesting 'comment))
5146
5147 ;; if we have a directive, done.
a3a8b002
DN
5148 (if (save-excursion (beginning-of-line)
5149 (and (looking-at verilog-directive-re-1)
9489a450 5150 (not (or (looking-at "[ \t]*`[ou]vm_")
86a4c7ac 5151 (looking-at "[ \t]*`vmm_")))))
6341f357 5152 (throw 'nesting 'directive))
a3a8b002
DN
5153 ;; indent structs as if there were module level
5154 (if (verilog-in-struct-p)
5155 (throw 'nesting 'block))
6341f357 5156
9489a450
MM
5157 ;; if we are in a parenthesized list, and the user likes to indent these, return.
5158 ;; unless we are in the newfangled coverpoint or constraint blocks
5159 (if (and
a3a8b002
DN
5160 verilog-indent-lists
5161 (verilog-in-paren)
5162 (not (verilog-in-coverage-p))
5163 )
9489a450 5164 (progn (setq par 1)
a3a8b002 5165 (throw 'nesting 'block)))
6341f357 5166
9489a450
MM
5167 ;; See if we are continuing a previous line
5168 (while t
5169 ;; trap out if we crawl off the top of the buffer
5170 (if (bobp) (throw 'nesting 'cpp))
5171
5172 (if (verilog-continued-line-1 lim)
5173 (let ((sp (point)))
5174 (if (and
5175 (not (looking-at verilog-complete-reg))
5176 (verilog-continued-line-1 lim))
5177 (progn (goto-char sp)
5178 (throw 'nesting 'cexp))
5179
5180 (goto-char sp))
5181
5182 (if (and begin
5183 (not verilog-indent-begin-after-if)
5184 (looking-at verilog-no-indent-begin-re))
5185 (progn
5186 (beginning-of-line)
5187 (skip-chars-forward " \t")
5188 (throw 'nesting 'statement))
5189 (progn
5190 (throw 'nesting 'cexp))))
5191 ;; not a continued line
5192 (goto-char starting_position))
5193
5194 (if (looking-at "\\<else\\>")
5195 ;; search back for governing if, striding across begin..end pairs
5196 ;; appropriately
5197 (let ((elsec 1))
5198 (while (verilog-re-search-backward verilog-ends-re nil 'move)
5199 (cond
5200 ((match-end 1) ; else, we're in deep
5201 (setq elsec (1+ elsec)))
5202 ((match-end 2) ; if
5203 (setq elsec (1- elsec))
5204 (if (= 0 elsec)
5205 (if verilog-align-ifelse
5206 (throw 'nesting 'statement)
5207 (progn ;; back up to first word on this line
5208 (beginning-of-line)
5209 (verilog-forward-syntactic-ws)
5210 (throw 'nesting 'statement)))))
5211 ((match-end 3) ; assert block
5212 (setq elsec (1- elsec))
5213 (verilog-beg-of-statement) ;; doesn't get to beginning
5214 (if (looking-at verilog-property-re)
5215 (throw 'nesting 'statement) ; We don't need an endproperty for these
5216 (throw 'nesting 'block) ;We still need a endproperty
5217 ))
5218 (t ; endblock
5219 ; try to leap back to matching outward block by striding across
5220 ; indent level changing tokens then immediately
5221 ; previous line governs indentation.
5222 (let (( reg) (nest 1))
5223 ;; verilog-ends => else|if|end|join(_any|_none|)|endcase|endclass|endtable|endspecify|endfunction|endtask|endgenerate|endgroup
5224 (cond
5225 ((match-end 4) ; end
5226 ;; Search back for matching begin
5227 (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
5228 ((match-end 5) ; endcase
5229 ;; Search back for matching case
5230 (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
5231 ((match-end 6) ; endfunction
5232 ;; Search back for matching function
5233 (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
5234 ((match-end 7) ; endtask
5235 ;; Search back for matching task
5236 (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
5237 ((match-end 8) ; endspecify
5238 ;; Search back for matching specify
5239 (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
5240 ((match-end 9) ; endtable
5241 ;; Search back for matching table
5242 (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
5243 ((match-end 10) ; endgenerate
5244 ;; Search back for matching generate
5245 (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
5246 ((match-end 11) ; joins
5247 ;; Search back for matching fork
5248 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|none\\)?\\>\\)" ))
5249 ((match-end 12) ; class
5250 ;; Search back for matching class
5251 (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
5252 ((match-end 13) ; covergroup
5253 ;; Search back for matching covergroup
5254 (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" )))
5255 (catch 'skip
5256 (while (verilog-re-search-backward reg nil 'move)
6341f357 5257 (cond
9489a450
MM
5258 ((match-end 1) ; begin
5259 (setq nest (1- nest))
5260 (if (= 0 nest)
5261 (throw 'skip 1)))
5262 ((match-end 2) ; end
5263 (setq nest (1+ nest)))))
5264 )))))))
5265 (throw 'nesting (verilog-calc-1)))
5266 );; catch nesting
6341f357
DN
5267 );; type
5268 )
5269 ;; Return type of block and indent level.
5270 (if (not type)
5271 (setq type 'cpp))
5272 (if (> par 0) ; Unclosed Parenthesis
5273 (list 'cparenexp par)
5274 (cond
5275 ((eq type 'case)
5276 (list type (verilog-case-indent-level)))
5277 ((eq type 'statement)
5278 (list type (current-column)))
5279 ((eq type 'defun)
5280 (list type 0))
5281 (t
60618039
DN
5282 (list type (verilog-current-indent-level))))))))
5283
6341f357
DN
5284(defun verilog-wai ()
5285 "Show matching nesting block for debugging."
5286 (interactive)
5287 (save-excursion
4c5e69c6
DN
5288 (let* ((type (verilog-calc-1))
5289 depth)
5290 ;; Return type of block and indent level.
5291 (if (not type)
5292 (setq type 'cpp))
5293 (if (and
5294 verilog-indent-lists
a3a8b002
DN
5295 (not(or (verilog-in-coverage-p)
5296 (verilog-in-struct-p)))
4c5e69c6
DN
5297 (verilog-in-paren))
5298 (setq depth 1)
5299 (cond
5300 ((eq type 'case)
5301 (setq depth (verilog-case-indent-level)))
5302 ((eq type 'statement)
5303 (setq depth (current-column)))
5304 ((eq type 'defun)
5305 (setq depth 0))
5306 (t
5307 (setq depth (verilog-current-indent-level)))))
5308 (message "You are at nesting %s depth %d" type depth))))
6341f357
DN
5309
5310(defun verilog-calc-1 ()
5311 (catch 'nesting
a3a8b002
DN
5312 (let ((re (concat "\\({\\|}\\|" verilog-indent-re "\\)")))
5313 (while (verilog-re-search-backward re nil 'move)
5314 (catch 'continue
5315 (cond
5316 ((equal (char-after) ?\{)
5317 (if (verilog-at-constraint-p)
5318 (throw 'nesting 'block)))
6341f357 5319
a3a8b002
DN
5320 ((equal (char-after) ?\})
5321 (let ((there (verilog-at-close-constraint-p)))
86a4c7ac 5322 (if there ;; we are at the } that closes a constraint. Find the { that opens it
a3a8b002
DN
5323 (progn
5324 (forward-char 1)
5325 (backward-list 1)
5326 (verilog-beg-of-statement)))))
6341f357 5327
a3a8b002
DN
5328 ((looking-at verilog-beg-block-re-ordered)
5329 (cond
5330 ((match-end 2) ; *sigh* could be "unique case" or "priority casex"
5331 (let ((here (point)))
5332 (verilog-beg-of-statement)
5333 (if (looking-at verilog-extended-case-re)
5334 (throw 'nesting 'case)
5335 (goto-char here)))
5336 (throw 'nesting 'case))
5337
5338 ((match-end 4) ; *sigh* could be "disable fork"
5339 (let ((here (point)))
5340 (verilog-beg-of-statement)
9489a450 5341 (if (looking-at verilog-disable-fork-re)
fd9ea9d3 5342 t ; this is a normal statement
a3a8b002
DN
5343 (progn ; or is fork, starts a new block
5344 (goto-char here)
5345 (throw 'nesting 'block)))))
5346
a03c2342
WS
5347 ((match-end 27) ; *sigh* might be a clocking declaration
5348 (let ((here (point)))
5349 (if (verilog-in-paren)
5350 t ; this is a normal statement
5351 (progn ; or is fork, starts a new block
5352 (goto-char here)
5353 (throw 'nesting 'block)))))
a3a8b002
DN
5354
5355 ;; need to consider typedef struct here...
5356 ((looking-at "\\<class\\|struct\\|function\\|task\\>")
6341f357
DN
5357 ; *sigh* These words have an optional prefix:
5358 ; extern {virtual|protected}? function a();
6341f357
DN
5359 ; typedef class foo;
5360 ; and we don't want to confuse this with
5361 ; function a();
5362 ; property
5363 ; ...
5364 ; endfunction
a3a8b002
DN
5365 (verilog-beg-of-statement)
5366 (if (looking-at verilog-beg-block-re-ordered)
5367 (throw 'nesting 'block)
5368 (throw 'nesting 'defun)))
7cb1c4d7 5369
a3a8b002
DN
5370 ((looking-at "\\<property\\>")
5371 ; *sigh*
7cb1c4d7 5372 ; {assert|assume|cover} property (); are complete
14862301 5373 ; and could also be labeled: - foo: assert property
7cb1c4d7
DN
5374 ; but
5375 ; property ID () ... needs end_property
a3a8b002 5376 (verilog-beg-of-statement)
a03c2342 5377 (if (looking-at verilog-property-re)
14862301 5378 (throw 'continue 'statement) ; We don't need an endproperty for these
a3a8b002
DN
5379 (throw 'nesting 'block) ;We still need a endproperty
5380 ))
6341f357 5381
a3a8b002 5382 (t (throw 'nesting 'block))))
6341f357 5383
a3a8b002
DN
5384 ((looking-at verilog-end-block-re)
5385 (verilog-leap-to-head)
5386 (if (verilog-in-case-region-p)
5387 (progn
5388 (verilog-leap-to-case-head)
5389 (if (looking-at verilog-extended-case-re)
5390 (throw 'nesting 'case)))))
6341f357 5391
a3a8b002
DN
5392 ((looking-at verilog-defun-level-re)
5393 (if (looking-at verilog-defun-level-generate-only-re)
5394 (if (verilog-in-generate-region-p)
14862301 5395 (throw 'continue 'foo) ; always block in a generate - keep looking
a3a8b002
DN
5396 (throw 'nesting 'defun))
5397 (throw 'nesting 'defun)))
5398
5399 ((looking-at verilog-cpp-level-re)
5400 (throw 'nesting 'cpp))
5401
5402 ((bobp)
5403 (throw 'nesting 'cpp)))))
5404
5405 (throw 'nesting 'cpp))))
6341f357
DN
5406
5407(defun verilog-calculate-indent-directive ()
5408 "Return indentation level for directive.
5409For speed, the searcher looks at the last directive, not the indent
5410of the appropriate enclosing block."
5411 (let ((base -1) ;; Indent of the line that determines our indentation
60618039 5412 (ind 0)) ;; Relative offset caused by other directives (like `endif on same line as `else)
6341f357
DN
5413 ;; Start at current location, scan back for another directive
5414
5415 (save-excursion
5416 (beginning-of-line)
5417 (while (and (< base 0)
5418 (verilog-re-search-backward verilog-directive-re nil t))
5419 (cond ((save-excursion (skip-chars-backward " \t") (bolp))
60618039 5420 (setq base (current-indentation))))
6341f357
DN
5421 (cond ((and (looking-at verilog-directive-end) (< base 0)) ;; Only matters when not at BOL
5422 (setq ind (- ind verilog-indent-level-directive)))
5423 ((and (looking-at verilog-directive-middle) (>= base 0)) ;; Only matters when at BOL
5424 (setq ind (+ ind verilog-indent-level-directive)))
5425 ((looking-at verilog-directive-begin)
5426 (setq ind (+ ind verilog-indent-level-directive)))))
5427 ;; Adjust indent to starting indent of critical line
5428 (setq ind (max 0 (+ ind base))))
5429
5430 (save-excursion
5431 (beginning-of-line)
5432 (skip-chars-forward " \t")
5433 (cond ((or (looking-at verilog-directive-middle)
5434 (looking-at verilog-directive-end))
5435 (setq ind (max 0 (- ind verilog-indent-level-directive))))))
5436 ind))
5437
5438(defun verilog-leap-to-case-head ()
5439 (let ((nest 1))
5440 (while (/= 0 nest)
a3a8b002
DN
5441 (verilog-re-search-backward
5442 (concat
5443 "\\(\\<randcase\\>\\|\\(\\<unique\\s-+\\|priority\\s-+\\)?\\<case[xz]?\\>\\)"
5444 "\\|\\(\\<endcase\\>\\)" )
5445 nil 'move)
6341f357
DN
5446 (cond
5447 ((match-end 1)
a3a8b002
DN
5448 (let ((here (point)))
5449 (verilog-beg-of-statement)
5450 (unless (looking-at verilog-extended-case-re)
5451 (goto-char here)))
6341f357 5452 (setq nest (1- nest)))
a3a8b002 5453 ((match-end 3)
6341f357
DN
5454 (setq nest (1+ nest)))
5455 ((bobp)
5456 (ding 't)
5457 (setq nest 0))))))
5458
5459(defun verilog-leap-to-head ()
37ea4b9b
JB
5460 "Move point to the head of this block.
5461Jump from end to matching begin, from endcase to matching case, and so on."
6341f357
DN
5462 (let ((reg nil)
5463 snest
4c5e69c6 5464 (nesting 'yes)
6341f357
DN
5465 (nest 1))
5466 (cond
5467 ((looking-at "\\<end\\>")
5468 ;; 1: Search back for matching begin
5469 (setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|"
5470 "\\(\\<endcase\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" )))
4c5e69c6 5471 ((looking-at "\\<endtask\\>")
a3a8b002 5472 ;; 2: Search back for matching task
4c5e69c6
DN
5473 (setq reg "\\(\\<task\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<task\\>\\)")
5474 (setq nesting 'no))
6341f357 5475 ((looking-at "\\<endcase\\>")
a3a8b002
DN
5476 (catch 'nesting
5477 (verilog-leap-to-case-head) )
5478 (setq reg nil) ; to force skip
5479 )
5480
6341f357 5481 ((looking-at "\\<join\\(_any\\|_none\\)?\\>")
a3a8b002 5482 ;; 4: Search back for matching fork
6341f357
DN
5483 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
5484 ((looking-at "\\<endclass\\>")
a3a8b002 5485 ;; 5: Search back for matching class
6341f357
DN
5486 (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
5487 ((looking-at "\\<endtable\\>")
a3a8b002 5488 ;; 6: Search back for matching table
6341f357
DN
5489 (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
5490 ((looking-at "\\<endspecify\\>")
a3a8b002 5491 ;; 7: Search back for matching specify
6341f357
DN
5492 (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
5493 ((looking-at "\\<endfunction\\>")
a3a8b002
DN
5494 ;; 8: Search back for matching function
5495 (setq reg "\\(\\<function\\>\\)\\|\\(\\(\\(\\<virtual\\>\\s-+\\)\\|\\(\\<protected\\>\\s-+\\)\\)+\\<function\\>\\)")
5496 (setq nesting 'no))
5497 ;;(setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
6341f357
DN
5498 ((looking-at "\\<endgenerate\\>")
5499 ;; 8: Search back for matching generate
5500 (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
6341f357
DN
5501 ((looking-at "\\<endgroup\\>")
5502 ;; 10: Search back for matching covergroup
5503 (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" ))
5504 ((looking-at "\\<endproperty\\>")
5505 ;; 11: Search back for matching property
5506 (setq reg "\\(\\<property\\>\\)\\|\\(\\<endproperty\\>\\)" ))
9489a450
MM
5507 ((looking-at verilog-uvm-end-re)
5508 ;; 12: Search back for matching sequence
5509 (setq reg (concat "\\(" verilog-uvm-begin-re "\\|" verilog-uvm-end-re "\\)")))
a3a8b002
DN
5510 ((looking-at verilog-ovm-end-re)
5511 ;; 12: Search back for matching sequence
5512 (setq reg (concat "\\(" verilog-ovm-begin-re "\\|" verilog-ovm-end-re "\\)")))
86a4c7ac
DN
5513 ((looking-at verilog-vmm-end-re)
5514 ;; 12: Search back for matching sequence
5515 (setq reg (concat "\\(" verilog-vmm-begin-re "\\|" verilog-vmm-end-re "\\)")))
6341f357
DN
5516 ((looking-at "\\<endinterface\\>")
5517 ;; 12: Search back for matching interface
5518 (setq reg "\\(\\<interface\\>\\)\\|\\(\\<endinterface\\>\\)" ))
5519 ((looking-at "\\<endsequence\\>")
5520 ;; 12: Search back for matching sequence
5521 (setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<endsequence\\>\\)" ))
5522 ((looking-at "\\<endclocking\\>")
5523 ;; 12: Search back for matching clocking
60618039 5524 (setq reg "\\(\\<clocking\\)\\|\\(\\<endclocking\\>\\)" )))
6341f357
DN
5525 (if reg
5526 (catch 'skip
4c5e69c6
DN
5527 (if (eq nesting 'yes)
5528 (let (sreg)
5529 (while (verilog-re-search-backward reg nil 'move)
5530 (cond
5531 ((match-end 1) ; begin
0e5c8aed
DN
5532 (if (looking-at "fork")
5533 (let ((here (point)))
5534 (verilog-beg-of-statement)
5535 (unless (looking-at verilog-disable-fork-re)
5536 (goto-char here)
5537 (setq nest (1- nest))))
5538 (setq nest (1- nest)))
4c5e69c6
DN
5539 (if (= 0 nest)
5540 ;; Now previous line describes syntax
5541 (throw 'skip 1))
5542 (if (and snest
5543 (= snest nest))
5544 (setq reg sreg)))
5545 ((match-end 2) ; end
5546 (setq nest (1+ nest)))
5547 ((match-end 3)
5548 ;; endcase, jump to case
5549 (setq snest nest)
5550 (setq nest (1+ nest))
5551 (setq sreg reg)
5552 (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
5553 ((match-end 4)
5554 ;; join, jump to fork
5555 (setq snest nest)
5556 (setq nest (1+ nest))
5557 (setq sreg reg)
5558 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
5559 )))
5560 ;no nesting
5561 (if (and
a3a8b002 5562 (verilog-re-search-backward reg nil 'move)
4c5e69c6
DN
5563 (match-end 1)) ; task -> could be virtual and/or protected
5564 (progn
5565 (verilog-beg-of-statement)
5566 (throw 'skip 1))
5567 (throw 'skip 1)))))))
6341f357
DN
5568
5569(defun verilog-continued-line ()
5570 "Return true if this is a continued line.
37ea4b9b 5571Set point to where line starts."
6341f357
DN
5572 (let ((continued 't))
5573 (if (eq 0 (forward-line -1))
5574 (progn
5575 (end-of-line)
5576 (verilog-backward-ws&directives)
5577 (if (bobp)
5578 (setq continued nil)
5579 (while (and continued
5580 (save-excursion
5581 (skip-chars-backward " \t")
5582 (not (bolp))))
60618039 5583 (setq continued (verilog-backward-token)))))
6341f357
DN
5584 (setq continued nil))
5585 continued))
5586
5587(defun verilog-backward-token ()
0b381c7e 5588 "Step backward token, returning true if this is a continued line."
6341f357
DN
5589 (interactive)
5590 (verilog-backward-syntactic-ws)
5591 (cond
5592 ((bolp)
5593 nil)
5594 (;-- Anything ending in a ; is complete
5595 (= (preceding-char) ?\;)
5596 nil)
5597 (; If a "}" is prefixed by a ";", then this is a complete statement
5598 ; i.e.: constraint foo { a = b; }
5599 (= (preceding-char) ?\})
5600 (progn
5601 (backward-char)
a3a8b002 5602 (not(verilog-at-close-constraint-p))))
6341f357
DN
5603 (;-- constraint foo { a = b }
5604 ; is a complete statement. *sigh*
5605 (= (preceding-char) ?\{)
5606 (progn
5607 (backward-char)
60618039 5608 (not (verilog-at-constraint-p))))
a3a8b002
DN
5609 (;" string "
5610 (= (preceding-char) ?\")
5611 (backward-char)
5612 (verilog-skip-backward-comment-or-string)
5613 nil)
5614
5615 (; [3:4]
5616 (= (preceding-char) ?\])
5617 (backward-char)
5618 (verilog-backward-open-bracket)
5619 t)
5620
6341f357
DN
5621 (;-- Could be 'case (foo)' or 'always @(bar)' which is complete
5622 ; also could be simply '@(foo)'
5623 ; or foo u1 #(a=8)
5624 ; (b, ... which ISN'T complete
5625 ;;;; Do we need this???
5626 (= (preceding-char) ?\))
5627 (progn
5628 (backward-char)
a03c2342 5629 (verilog-backward-up-list 1)
6341f357
DN
5630 (verilog-backward-syntactic-ws)
5631 (let ((back (point)))
5632 (forward-word -1)
5633 (cond
a3a8b002 5634 ;;XX
6341f357
DN
5635 ((looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|case\\(\\|[xz]\\)\\|for\\(\\|each\\|ever\\)\\|i\\(f\\|nitial\\)\\|repeat\\|while\\)\\>")
5636 (not (looking-at "\\<randcase\\>\\|\\<case[xz]?\\>[^:]")))
9489a450
MM
5637 ((looking-at verilog-uvm-statement-re)
5638 nil)
5639 ((looking-at verilog-uvm-begin-re)
5640 t)
5641 ((looking-at verilog-uvm-end-re)
5642 t)
a3a8b002
DN
5643 ((looking-at verilog-ovm-statement-re)
5644 nil)
5645 ((looking-at verilog-ovm-begin-re)
5646 t)
5647 ((looking-at verilog-ovm-end-re)
5648 t)
86a4c7ac
DN
5649 ;; JBA find VMM macros
5650 ((looking-at verilog-vmm-statement-re)
5651 nil )
5652 ((looking-at verilog-vmm-begin-re)
5653 t)
5654 ((looking-at verilog-vmm-end-re)
5655 nil)
5656 ;; JBA trying to catch macro lines with no ; at end
5657 ((looking-at "\\<`")
5658 nil)
6341f357
DN
5659 (t
5660 (goto-char back)
5661 (cond
5662 ((= (preceding-char) ?\@)
5663 (backward-char)
5664 (save-excursion
5665 (verilog-backward-token)
5666 (not (looking-at "\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\|initial\\|while\\)\\>"))))
5667 ((= (preceding-char) ?\#)
60618039
DN
5668 (backward-char))
5669 (t t)))))))
6341f357
DN
5670
5671 (;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete
5672 t
5673 (forward-word -1)
0e5c8aed
DN
5674 (while (= (preceding-char) ?\_)
5675 (forward-word -1))
6341f357
DN
5676 (cond
5677 ((looking-at "\\<else\\>")
5678 t)
2a9eb3f5
DN
5679 ((looking-at verilog-behavioral-block-beg-re)
5680 t)
6341f357
DN
5681 ((looking-at verilog-indent-re)
5682 nil)
5683 (t
5684 (let
5685 ((back (point)))
5686 (verilog-backward-syntactic-ws)
5687 (cond
5688 ((= (preceding-char) ?\:)
5689 (backward-char)
5690 (verilog-backward-syntactic-ws)
5691 (backward-sexp)
5692 (if (looking-at verilog-nameable-item-re )
5693 nil
60618039 5694 t))
6341f357
DN
5695 ((= (preceding-char) ?\#)
5696 (backward-char)
5697 t)
5698 ((= (preceding-char) ?\`)
5699 (backward-char)
5700 t)
5701
5702 (t
5703 (goto-char back)
60618039 5704 t))))))))
6341f357 5705
fd9ea9d3 5706(defun verilog-backward-syntactic-ws ()
9489a450 5707 "Move backwards putting point after first non-whitespace non-comment."
fd9ea9d3
WS
5708 (verilog-skip-backward-comments)
5709 (forward-comment (- (buffer-size))))
6341f357 5710
9489a450
MM
5711(defun verilog-backward-syntactic-ws-quick ()
5712 "As with `verilog-backward-syntactic-ws' but uses `verilog-scan' cache."
5713 (while (cond ((bobp)
5714 nil) ; Done
5715 ((> (skip-syntax-backward " ") 0)
5716 t)
5717 ((eq (preceding-char) ?\n) ;; \n's terminate // so aren't space syntax
5718 (forward-char -1)
5719 t)
5720 ((or (verilog-inside-comment-or-string-p (1- (point)))
5721 (verilog-inside-comment-or-string-p (point)))
5722 (re-search-backward "[/\"]" nil t) ;; Only way a comment or quote can begin
5723 t))))
5724
fd9ea9d3
WS
5725(defun verilog-forward-syntactic-ws ()
5726 (verilog-skip-forward-comment-p)
5727 (forward-comment (buffer-size)))
6341f357
DN
5728
5729(defun verilog-backward-ws&directives (&optional bound)
5730 "Backward skip over syntactic whitespace and compiler directives for Emacs 19.
5731Optional BOUND limits search."
5732 (save-restriction
5733 (let* ((bound (or bound (point-min)))
5734 (here bound)
5735 (p nil) )
5736 (if (< bound (point))
5737 (progn
d63b01e1 5738 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5739 (cond
5740 ((nth 7 state) ;; in // comment
5741 (verilog-re-search-backward "//" nil 'move)
5742 (skip-chars-backward "/"))
5743 ((nth 4 state) ;; in /* */ comment
5744 (verilog-re-search-backward "/\*" nil 'move))))
5745 (narrow-to-region bound (point))
5746 (while (/= here (point))
5747 (setq here (point))
5748 (verilog-skip-backward-comments)
5749 (setq p
5750 (save-excursion
5751 (beginning-of-line)
5752 (cond
a3a8b002
DN
5753 ((and verilog-highlight-translate-off
5754 (verilog-within-translate-off))
6341f357
DN
5755 (verilog-back-to-start-translate-off (point-min)))
5756 ((looking-at verilog-directive-re-1)
5757 (point))
5758 (t
5759 nil))))
60618039 5760 (if p (goto-char p))))))))
6341f357
DN
5761
5762(defun verilog-forward-ws&directives (&optional bound)
5763 "Forward skip over syntactic whitespace and compiler directives for Emacs 19.
5764Optional BOUND limits search."
5765 (save-restriction
5766 (let* ((bound (or bound (point-max)))
5767 (here bound)
60618039 5768 jump)
6341f357
DN
5769 (if (> bound (point))
5770 (progn
d63b01e1 5771 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5772 (cond
5773 ((nth 7 state) ;; in // comment
a03c2342
WS
5774 (end-of-line)
5775 (forward-char 1)
5776 (skip-chars-forward " \t\n\f")
5777 )
6341f357 5778 ((nth 4 state) ;; in /* */ comment
a03c2342 5779 (verilog-re-search-forward "\*\/\\s-*" nil 'move))))
6341f357
DN
5780 (narrow-to-region (point) bound)
5781 (while (/= here (point))
5782 (setq here (point)
5783 jump nil)
5784 (forward-comment (buffer-size))
a03c2342
WS
5785 (and (looking-at "\\s-*(\\*.*\\*)\\s-*") ;; Attribute
5786 (goto-char (match-end 0)))
6341f357
DN
5787 (save-excursion
5788 (beginning-of-line)
5789 (if (looking-at verilog-directive-re-1)
5790 (setq jump t)))
5791 (if jump
60618039 5792 (beginning-of-line 2))))))))
6341f357
DN
5793
5794(defun verilog-in-comment-p ()
5795 "Return true if in a star or // comment."
d63b01e1 5796 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5797 (or (nth 4 state) (nth 7 state))))
5798
5799(defun verilog-in-star-comment-p ()
5800 "Return true if in a star comment."
d63b01e1 5801 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5802 (and
5803 (nth 4 state) ; t if in a comment of style a // or b /**/
5804 (not
5805 (nth 7 state) ; t if in a comment of style b /**/
5806 ))))
5807
5808(defun verilog-in-slash-comment-p ()
5809 "Return true if in a slash comment."
d63b01e1 5810 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5811 (nth 7 state)))
5812
5813(defun verilog-in-comment-or-string-p ()
5814 "Return true if in a string or comment."
d63b01e1 5815 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5816 (or (nth 3 state) (nth 4 state) (nth 7 state)))) ; Inside string or comment)
5817
a03c2342
WS
5818(defun verilog-in-attribute-p ()
5819 "Return true if point is in an attribute (* [] attribute *)."
9489a450
MM
5820 (save-match-data
5821 (save-excursion
5822 (verilog-re-search-backward "\\((\\*\\)\\|\\(\\*)\\)" nil 'move)
5823 (numberp (match-beginning 1)))))
5824
5825(defun verilog-in-parameter-p ()
5826 "Return true if point is in a parameter assignment #( p1=1, p2=5)."
5827 (save-match-data
5828 (save-excursion
5829 (verilog-re-search-backward "\\(#(\\)\\|\\()\\)" nil 'move)
5830 (numberp (match-beginning 1)))))
a03c2342 5831
6341f357
DN
5832(defun verilog-in-escaped-name-p ()
5833 "Return true if in an escaped name."
5834 (save-excursion
5835 (backward-char)
5836 (skip-chars-backward "^ \t\n\f")
5837 (if (equal (char-after (point) ) ?\\ )
5838 t
5839 nil)))
a3a8b002 5840(defun verilog-in-directive-p ()
a03c2342 5841 "Return true if in a directive."
a3a8b002
DN
5842 (save-excursion
5843 (beginning-of-line)
5844 (looking-at verilog-directive-re-1)))
6341f357 5845
9489a450
MM
5846(defun verilog-in-parenthesis-p ()
5847 "Return true if in a ( ) expression (but not { } or [ ])."
5848 (save-match-data
5849 (save-excursion
5850 (verilog-re-search-backward "\\((\\)\\|\\()\\)" nil 'move)
5851 (numberp (match-beginning 1)))))
5852
6341f357 5853(defun verilog-in-paren ()
9489a450
MM
5854 "Return true if in a parenthetical expression.
5855May cache result using `verilog-syntax-ppss'."
d63b01e1 5856 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5857 (> (nth 0 state) 0 )))
5858
9489a450
MM
5859(defun verilog-in-paren-quick ()
5860 "Return true if in a parenthetical expression.
5861Always starts from point-min, to allow inserts with hooks disabled."
5862 ;; The -quick refers to its use alongside the other -quick functions,
5863 ;; not that it's likely to be faster than verilog-in-paren.
5864 (let ((state (save-excursion (parse-partial-sexp (point-min) (point)))))
5865 (> (nth 0 state) 0 )))
5866
a3a8b002
DN
5867(defun verilog-in-struct-p ()
5868 "Return true if in a struct declaration."
5869 (interactive)
5870 (save-excursion
5871 (if (verilog-in-paren)
5872 (progn
a03c2342 5873 (verilog-backward-up-list 1)
a3a8b002
DN
5874 (verilog-at-struct-p)
5875 )
5876 nil)))
5877
5878(defun verilog-in-coverage-p ()
6341f357
DN
5879 "Return true if in a constraint or coverpoint expression."
5880 (interactive)
5881 (save-excursion
5882 (if (verilog-in-paren)
5883 (progn
a03c2342 5884 (verilog-backward-up-list 1)
6341f357
DN
5885 (verilog-at-constraint-p)
5886 )
5887 nil)))
5888(defun verilog-at-close-constraint-p ()
5889 "If at the } that closes a constraint or covergroup, return true."
5890 (if (and
5891 (equal (char-after) ?\})
5892 (verilog-in-paren))
5893
5894 (save-excursion
5895 (verilog-backward-ws&directives)
5896 (if (equal (char-before) ?\;)
5897 (point)
5898 nil))))
5899
5900(defun verilog-at-constraint-p ()
5901 "If at the { of a constraint or coverpoint definition, return true, moving point to constraint."
5902 (if (save-excursion
5903 (and
5904 (equal (char-after) ?\{)
5905 (forward-list)
5906 (progn (backward-char 1)
5907 (verilog-backward-ws&directives)
60618039 5908 (equal (char-before) ?\;))))
6341f357
DN
5909 ;; maybe
5910 (verilog-re-search-backward "\\<constraint\\|coverpoint\\|cross\\>" nil 'move)
5911 ;; not
60618039 5912 nil))
6341f357 5913
a3a8b002
DN
5914(defun verilog-at-struct-p ()
5915 "If at the { of a struct, return true, moving point to struct."
5916 (save-excursion
5917 (if (and (equal (char-after) ?\{)
5918 (verilog-backward-token))
0e5c8aed 5919 (looking-at "\\<struct\\|union\\|packed\\|\\(un\\)?signed\\>")
a3a8b002
DN
5920 nil)))
5921
6341f357
DN
5922(defun verilog-parenthesis-depth ()
5923 "Return non zero if in parenthetical-expression."
d63b01e1 5924 (save-excursion (nth 1 (verilog-syntax-ppss))))
6341f357
DN
5925
5926
5927(defun verilog-skip-forward-comment-or-string ()
5928 "Return true if in a string or comment."
d63b01e1 5929 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5930 (cond
5931 ((nth 3 state) ;Inside string
495ab0d5 5932 (search-forward "\"")
6341f357
DN
5933 t)
5934 ((nth 7 state) ;Inside // comment
5935 (forward-line 1)
5936 t)
5937 ((nth 4 state) ;Inside any comment (hence /**/)
5938 (search-forward "*/"))
5939 (t
5940 nil))))
5941
5942(defun verilog-skip-backward-comment-or-string ()
5943 "Return true if in a string or comment."
d63b01e1 5944 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5945 (cond
5946 ((nth 3 state) ;Inside string
5947 (search-backward "\"")
5948 t)
5949 ((nth 7 state) ;Inside // comment
5950 (search-backward "//")
5951 (skip-chars-backward "/")
5952 t)
5953 ((nth 4 state) ;Inside /* */ comment
5954 (search-backward "/*")
5955 t)
5956 (t
5957 nil))))
5958
5959(defun verilog-skip-backward-comments ()
5960 "Return true if a comment was skipped."
5961 (let ((more t))
5962 (while more
5963 (setq more
d63b01e1 5964 (let ((state (save-excursion (verilog-syntax-ppss))))
6341f357
DN
5965 (cond
5966 ((nth 7 state) ;Inside // comment
5967 (search-backward "//")
5968 (skip-chars-backward "/")
5969 (skip-chars-backward " \t\n\f")
5970 t)
5971 ((nth 4 state) ;Inside /* */ comment
5972 (search-backward "/*")
5973 (skip-chars-backward " \t\n\f")
5974 t)
5975 ((and (not (bobp))
5976 (= (char-before) ?\/)
60618039 5977 (= (char-before (1- (point))) ?\*))
6341f357 5978 (goto-char (- (point) 2))
a03c2342
WS
5979 t) ;; Let nth 4 state handle the rest
5980 ((and (not (bobp))
5981 (= (char-before) ?\))
5982 (= (char-before (1- (point))) ?\*))
5983 (goto-char (- (point) 2))
5984 (if (search-backward "(*" nil t)
5985 (progn
5986 (skip-chars-backward " \t\n\f")
5987 t)
5988 (progn
5989 (goto-char (+ (point) 2))
5990 nil)))
6341f357 5991 (t
a03c2342 5992 (/= (skip-chars-backward " \t\n\f") 0))))))))
6341f357
DN
5993
5994(defun verilog-skip-forward-comment-p ()
5995 "If in comment, move to end and return true."
a03c2342
WS
5996 (let* (h
5997 (state (save-excursion (verilog-syntax-ppss)))
5998 (skip (cond
5999 ((nth 3 state) ;Inside string
6000 t)
6001 ((nth 7 state) ;Inside // comment
6002 (end-of-line)
6003 (forward-char 1)
6004 t)
6005 ((nth 4 state) ;Inside /* comment
6006 (search-forward "*/")
6007 t)
6008 ((verilog-in-attribute-p) ;Inside (* attribute
6009 (search-forward "*)" nil t)
6010 t)
6011 (t nil))))
6012 (skip-chars-forward " \t\n\f")
6013 (while
6014 (cond
6015 ((looking-at "\\/\\*")
6016 (progn
6017 (setq h (point))
6018 (goto-char (match-end 0))
6019 (if (search-forward "*/" nil t)
6020 (progn
6021 (skip-chars-forward " \t\n\f")
6022 (setq skip 't))
6023 (progn
6024 (goto-char h)
6025 nil))))
6026 ((looking-at "(\\*")
6027 (progn
6028 (setq h (point))
6029 (goto-char (match-end 0))
6030 (if (search-forward "*)" nil t)
6031 (progn
6032 (skip-chars-forward " \t\n\f")
6033 (setq skip 't))
6034 (progn
6035 (goto-char h)
6036 nil))))
6037 (t nil)))
6038 skip))
6341f357
DN
6039
6040(defun verilog-indent-line-relative ()
6041 "Cheap version of indent line.
6042Only look at a few lines to determine indent level."
6043 (interactive)
6044 (let ((indent-str)
6045 (sp (point)))
6046 (if (looking-at "^[ \t]*$")
6047 (cond ;- A blank line; No need to be too smart.
6048 ((bobp)
6049 (setq indent-str (list 'cpp 0)))
6050 ((verilog-continued-line)
6051 (let ((sp1 (point)))
6052 (if (verilog-continued-line)
7ea26faf
DN
6053 (progn
6054 (goto-char sp)
60618039
DN
6055 (setq indent-str
6056 (list 'statement (verilog-current-indent-level))))
6341f357
DN
6057 (goto-char sp1)
6058 (setq indent-str (list 'block (verilog-current-indent-level)))))
6059 (goto-char sp))
6060 ((goto-char sp)
6061 (setq indent-str (verilog-calculate-indent))))
6062 (progn (skip-chars-forward " \t")
6063 (setq indent-str (verilog-calculate-indent))))
6064 (verilog-do-indent indent-str)))
6065
6066(defun verilog-indent-line ()
6067 "Indent for special part of code."
6068 (verilog-do-indent (verilog-calculate-indent)))
6069
6070(defun verilog-do-indent (indent-str)
6071 (let ((type (car indent-str))
6072 (ind (car (cdr indent-str))))
6073 (cond
6074 (; handle continued exp
6075 (eq type 'cexp)
6076 (let ((here (point)))
6077 (verilog-backward-syntactic-ws)
6078 (cond
6079 ((or
6080 (= (preceding-char) ?\,)
6081 (= (preceding-char) ?\])
6082 (save-excursion
6083 (verilog-beg-of-statement-1)
6084 (looking-at verilog-declaration-re)))
6085 (let* ( fst
6086 (val
6087 (save-excursion
6088 (backward-char 1)
6089 (verilog-beg-of-statement-1)
6090 (setq fst (point))
6091 (if (looking-at verilog-declaration-re)
6092 (progn ;; we have multiple words
6093 (goto-char (match-end 0))
6094 (skip-chars-forward " \t")
6095 (cond
6096 ((and verilog-indent-declaration-macros
6097 (= (following-char) ?\`))
6098 (progn
6099 (forward-char 1)
6100 (forward-word 1)
6101 (skip-chars-forward " \t")))
6102 ((= (following-char) ?\[)
6103 (progn
6104 (forward-char 1)
a03c2342 6105 (verilog-backward-up-list -1)
60618039 6106 (skip-chars-forward " \t"))))
6341f357
DN
6107 (current-column))
6108 (progn
6109 (goto-char fst)
60618039 6110 (+ (current-column) verilog-cexp-indent))))))
6341f357 6111 (goto-char here)
9489a450
MM
6112 (indent-line-to val)
6113 (if (and (not verilog-indent-lists)
6114 (verilog-in-paren))
6115 (verilog-pretty-declarations))
6116 ))
6341f357
DN
6117 ((= (preceding-char) ?\) )
6118 (goto-char here)
6119 (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
6120 (indent-line-to val)))
6121 (t
6122 (goto-char here)
6123 (let ((val))
6124 (verilog-beg-of-statement-1)
6125 (if (and (< (point) here)
6126 (verilog-re-search-forward "=[ \\t]*" here 'move))
6127 (setq val (current-column))
6128 (setq val (eval (cdr (assoc type verilog-indent-alist)))))
6129 (goto-char here)
60618039 6130 (indent-line-to val))))))
6341f357
DN
6131
6132 (; handle inside parenthetical expressions
6133 (eq type 'cparenexp)
a03c2342
WS
6134 (let* ( here
6135 (val (save-excursion
6136 (verilog-backward-up-list 1)
6137 (forward-char 1)
6138 (if verilog-indent-lists
6139 (skip-chars-forward " \t")
6140 (verilog-forward-syntactic-ws))
6141 (setq here (point))
6142 (current-column)))
6143
6144 (decl (save-excursion
6145 (goto-char here)
6146 (verilog-forward-syntactic-ws)
6147 (setq here (point))
6148 (looking-at verilog-declaration-re))))
6149 (indent-line-to val)
6150 (if decl
6151 (verilog-pretty-declarations))))
a3a8b002 6152
6341f357
DN
6153 (;-- Handle the ends
6154 (or
6155 (looking-at verilog-end-block-re )
6156 (verilog-at-close-constraint-p))
6157 (let ((val (if (eq type 'statement)
6158 (- ind verilog-indent-level)
6159 ind)))
6160 (indent-line-to val)))
6161
6162 (;-- Case -- maybe line 'em up
6163 (and (eq type 'case) (not (looking-at "^[ \t]*$")))
6164 (progn
6165 (cond
6166 ((looking-at "\\<endcase\\>")
6167 (indent-line-to ind))
6168 (t
6169 (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
6170 (indent-line-to val))))))
6171
6172 (;-- defun
6173 (and (eq type 'defun)
6174 (looking-at verilog-zero-indent-re))
6175 (indent-line-to 0))
6176
6177 (;-- declaration
6178 (and (or
6179 (eq type 'defun)
6180 (eq type 'block))
6181 (looking-at verilog-declaration-re))
6182 (verilog-indent-declaration ind))
6183
6184 (;-- Everything else
6185 t
6186 (let ((val (eval (cdr (assoc type verilog-indent-alist)))))
60618039
DN
6187 (indent-line-to val))))
6188
6341f357
DN
6189 (if (looking-at "[ \t]+$")
6190 (skip-chars-forward " \t"))
6191 indent-str ; Return indent data
6192 ))
6193
6194(defun verilog-current-indent-level ()
37ea4b9b 6195 "Return the indent-level of the current statement."
6341f357
DN
6196 (save-excursion
6197 (let (par-pos)
6198 (beginning-of-line)
6199 (setq par-pos (verilog-parenthesis-depth))
6200 (while par-pos
6201 (goto-char par-pos)
6202 (beginning-of-line)
6203 (setq par-pos (verilog-parenthesis-depth)))
6204 (skip-chars-forward " \t")
6205 (current-column))))
6206
6207(defun verilog-case-indent-level ()
37ea4b9b 6208 "Return the indent-level of the current statement.
6341f357
DN
6209Do not count named blocks or case-statements."
6210 (save-excursion
6211 (skip-chars-forward " \t")
6212 (cond
6213 ((looking-at verilog-named-block-re)
6214 (current-column))
a3a8b002 6215 ((and (not (looking-at verilog-extended-case-re))
6341f357
DN
6216 (looking-at "^[^:;]+[ \t]*:"))
6217 (verilog-re-search-forward ":" nil t)
6218 (skip-chars-forward " \t")
6219 (current-column))
6220 (t
6221 (current-column)))))
6222
6223(defun verilog-indent-comment ()
6224 "Indent current line as comment."
6225 (let* ((stcol
6226 (cond
6227 ((verilog-in-star-comment-p)
6228 (save-excursion
6229 (re-search-backward "/\\*" nil t)
6230 (1+(current-column))))
6231 (comment-column
6232 comment-column )
6233 (t
6234 (save-excursion
6235 (re-search-backward "//" nil t)
60618039 6236 (current-column))))))
6341f357
DN
6237 (indent-line-to stcol)
6238 stcol))
6239
6240(defun verilog-more-comment ()
6241 "Make more comment lines like the previous."
6242 (let* ((star 0)
6243 (stcol
6244 (cond
6245 ((verilog-in-star-comment-p)
6246 (save-excursion
6247 (setq star 1)
6248 (re-search-backward "/\\*" nil t)
6249 (1+(current-column))))
6250 (comment-column
6251 comment-column )
6252 (t
6253 (save-excursion
6254 (re-search-backward "//" nil t)
60618039 6255 (current-column))))))
6341f357
DN
6256 (progn
6257 (indent-to stcol)
6258 (if (and star
6259 (save-excursion
6260 (forward-line -1)
6261 (skip-chars-forward " \t")
6262 (looking-at "\*")))
6263 (insert "* ")))))
6264
6265(defun verilog-comment-indent (&optional arg)
6266 "Return the column number the line should be indented to.
6267ARG is ignored, for `comment-indent-function' compatibility."
6268 (cond
6269 ((verilog-in-star-comment-p)
6270 (save-excursion
6271 (re-search-backward "/\\*" nil t)
6272 (1+(current-column))))
6273 ( comment-column
6274 comment-column )
6275 (t
6276 (save-excursion
6277 (re-search-backward "//" nil t)
6278 (current-column)))))
6279
6280;;
6281
7e2a6000 6282(defun verilog-pretty-declarations (&optional quiet)
a3a8b002
DN
6283 "Line up declarations around point.
6284Be verbose about progress unless optional QUIET set."
6341f357 6285 (interactive)
fd9ea9d3
WS
6286 (let* ((m1 (make-marker))
6287 (e (point))
6288 el
6289 r
6290 (here (point))
6291 ind
6292 start
6293 startpos
6294 end
6295 endpos
6296 base-ind
6297 )
6298 (save-excursion
6299 (if (progn
6300; (verilog-beg-of-statement-1)
6301 (beginning-of-line)
a03c2342 6302 (verilog-forward-syntactic-ws)
fd9ea9d3 6303 (and (not (verilog-in-directive-p)) ;; could have `define input foo
a3a8b002 6304 (looking-at verilog-declaration-re)))
fd9ea9d3 6305 (progn
a03c2342
WS
6306 (if (verilog-parenthesis-depth)
6307 ;; in an argument list or parameter block
6308 (setq el (verilog-backward-up-list -1)
fd9ea9d3
WS
6309 start (progn
6310 (goto-char e)
a03c2342 6311 (verilog-backward-up-list 1)
fd9ea9d3
WS
6312 (forward-line) ;; ignore ( input foo,
6313 (verilog-re-search-forward verilog-declaration-re el 'move)
6314 (goto-char (match-beginning 0))
6315 (skip-chars-backward " \t")
6316 (point))
6317 startpos (set-marker (make-marker) start)
6318 end (progn
6319 (goto-char start)
a03c2342 6320 (verilog-backward-up-list -1)
fd9ea9d3
WS
6321 (forward-char -1)
6322 (verilog-backward-syntactic-ws)
6323 (point))
6324 endpos (set-marker (make-marker) end)
6325 base-ind (progn
6326 (goto-char start)
a03c2342
WS
6327 (forward-char 1)
6328 (skip-chars-forward " \t")
6329 (current-column))
fd9ea9d3
WS
6330 )
6331 ;; in a declaration block (not in argument list)
a03c2342 6332 (setq
fd9ea9d3
WS
6333 start (progn
6334 (verilog-beg-of-statement-1)
6335 (while (and (looking-at verilog-declaration-re)
6336 (not (bobp)))
6337 (skip-chars-backward " \t")
6338 (setq e (point))
6339 (beginning-of-line)
6340 (verilog-backward-syntactic-ws)
6341 (backward-char)
6342 (verilog-beg-of-statement-1))
6343 e)
6344 startpos (set-marker (make-marker) start)
6345 end (progn
6346 (goto-char here)
6347 (verilog-end-of-statement)
6348 (setq e (point)) ;Might be on last line
6349 (verilog-forward-syntactic-ws)
6350 (while (looking-at verilog-declaration-re)
fd9ea9d3
WS
6351 (verilog-end-of-statement)
6352 (setq e (point))
6353 (verilog-forward-syntactic-ws))
6354 e)
6355 endpos (set-marker (make-marker) end)
6356 base-ind (progn
6357 (goto-char start)
6358 (verilog-do-indent (verilog-calculate-indent))
6359 (verilog-forward-ws&directives)
6360 (current-column))))
6361 ;; OK, start and end are set
6362 (goto-char (marker-position startpos))
6363 (if (and (not quiet)
6364 (> (- end start) 100))
6365 (message "Lining up declarations..(please stand by)"))
6366 ;; Get the beginning of line indent first
6367 (while (progn (setq e (marker-position endpos))
6368 (< (point) e))
6369 (cond
a03c2342 6370 ((save-excursion (skip-chars-backward " \t")
fd9ea9d3
WS
6371 (bolp))
6372 (verilog-forward-ws&directives)
6373 (indent-line-to base-ind)
6374 (verilog-forward-ws&directives)
6375 (if (< (point) e)
6376 (verilog-re-search-forward "[ \t\n\f]" e 'move)))
6377 (t
6378 (just-one-space)
6379 (verilog-re-search-forward "[ \t\n\f]" e 'move)))
6380 ;;(forward-line)
6381 )
6382 ;; Now find biggest prefix
6383 (setq ind (verilog-get-lineup-indent (marker-position startpos) endpos))
6384 ;; Now indent each line.
6385 (goto-char (marker-position startpos))
6386 (while (progn (setq e (marker-position endpos))
6387 (setq r (- e (point)))
6388 (> r 0))
6389 (setq e (point))
6390 (unless quiet (message "%d" r))
a03c2342 6391 ;;(verilog-do-indent (verilog-calculate-indent)))
fd9ea9d3
WS
6392 (verilog-forward-ws&directives)
6393 (cond
6394 ((or (and verilog-indent-declaration-macros
6395 (looking-at verilog-declaration-re-2-macro))
6396 (looking-at verilog-declaration-re-2-no-macro))
6397 (let ((p (match-end 0)))
6398 (set-marker m1 p)
6399 (if (verilog-re-search-forward "[[#`]" p 'move)
6400 (progn
6401 (forward-char -1)
6402 (just-one-space)
6403 (goto-char (marker-position m1))
6404 (just-one-space)
6405 (indent-to ind))
6406 (progn
6407 (just-one-space)
6408 (indent-to ind)))))
6409 ((verilog-continued-line-1 (marker-position startpos))
6410 (goto-char e)
6411 (indent-line-to ind))
6412 ((verilog-in-struct-p)
6413 ;; could have a declaration of a user defined item
6414 (goto-char e)
6415 (verilog-end-of-statement))
6416 (t ; Must be comment or white space
6417 (goto-char e)
6418 (verilog-forward-ws&directives)
6419 (forward-line -1)))
6420 (forward-line 1))
6421 (unless quiet (message "")))))))
6341f357 6422
7e2a6000 6423(defun verilog-pretty-expr (&optional quiet myre)
9489a450
MM
6424 "Line up expressions around point, optionally QUIET with regexp MYRE ignored."
6425 (interactive)
6426 (if (not (verilog-in-comment-or-string-p))
6427 (save-excursion
6428 (let ((rexp (concat "^\\s-*" verilog-complete-reg)))
6429 (beginning-of-line)
6430 (if (and (not (looking-at rexp ))
6431 (looking-at verilog-assignment-operation-re)
6432 (save-excursion
6433 (goto-char (match-end 2))
6434 (and (not (verilog-in-attribute-p))
6435 (not (verilog-in-parameter-p))
6436 (not (verilog-in-comment-or-string-p)))))
6437 (let* ((here (point))
6438 (e) (r)
6439 (start
6440 (progn
6441 (beginning-of-line)
6442 (setq e (point))
6443 (verilog-backward-syntactic-ws)
6444 (beginning-of-line)
6445 (while (and (not (looking-at rexp ))
6446 (looking-at verilog-assignment-operation-re)
6447 (not (bobp))
6448 )
6449 (setq e (point))
6450 (verilog-backward-syntactic-ws)
6451 (beginning-of-line)
6452 ) ;Ack, need to grok `define
6453 e))
6454 (end
6455 (progn
6456 (goto-char here)
6457 (end-of-line)
6458 (setq e (point)) ;Might be on last line
6459 (verilog-forward-syntactic-ws)
6460 (beginning-of-line)
6461 (while (and
6462 (not (looking-at rexp ))
6463 (looking-at verilog-assignment-operation-re)
6464 (progn
6465 (end-of-line)
6466 (not (eq e (point)))))
6467 (setq e (point))
6468 (verilog-forward-syntactic-ws)
6469 (beginning-of-line)
6470 )
6471 e))
6472 (endpos (set-marker (make-marker) end))
6473 (ind)
6474 )
6475 (goto-char start)
6476 (verilog-do-indent (verilog-calculate-indent))
6477 (if (and (not quiet)
6478 (> (- end start) 100))
6479 (message "Lining up expressions..(please stand by)"))
6480
6481 ;; Set indent to minimum throughout region
6482 (while (< (point) (marker-position endpos))
6483 (beginning-of-line)
6484 (verilog-just-one-space verilog-assignment-operation-re)
6485 (beginning-of-line)
6486 (verilog-do-indent (verilog-calculate-indent))
6487 (end-of-line)
6488 (verilog-forward-syntactic-ws)
6489 )
6490
6491 ;; Now find biggest prefix
6492 (setq ind (verilog-get-lineup-indent-2 verilog-assignment-operation-re start endpos))
6493
6494 ;; Now indent each line.
6495 (goto-char start)
6496 (while (progn (setq e (marker-position endpos))
6497 (setq r (- e (point)))
6498 (> r 0))
6499 (setq e (point))
6500 (if (not quiet) (message "%d" r))
6501 (cond
6502 ((looking-at verilog-assignment-operation-re)
6503 (goto-char (match-beginning 2))
6504 (if (not (or (verilog-in-parenthesis-p) ;; leave attributes and comparisons alone
6505 (verilog-in-coverage-p)))
6506 (if (eq (char-after) ?=)
6507 (indent-to (1+ ind)) ; line up the = of the <= with surrounding =
6508 (indent-to ind)
6509 ))
6510 )
6511 ((verilog-continued-line-1 start)
6512 (goto-char e)
6513 (indent-line-to ind))
6514 (t ; Must be comment or white space
6515 (goto-char e)
6516 (verilog-forward-ws&directives)
6517 (forward-line -1))
6518 )
6519 (forward-line 1))
6520 (unless quiet (message ""))
6521 ))))))
6341f357
DN
6522
6523(defun verilog-just-one-space (myre)
6524 "Remove extra spaces around regular expression MYRE."
6525 (interactive)
6526 (if (and (not(looking-at verilog-complete-reg))
6527 (looking-at myre))
6528 (let ((p1 (match-end 1))
6529 (p2 (match-end 2)))
6530 (progn
6531 (goto-char p2)
9489a450 6532 (just-one-space)
6341f357 6533 (goto-char p1)
9489a450 6534 (just-one-space)))))
6341f357
DN
6535
6536(defun verilog-indent-declaration (baseind)
6537 "Indent current lines as declaration.
6538Line up the variable names based on previous declaration's indentation.
6539BASEIND is the base indent to offset everything."
6540 (interactive)
6541 (let ((pos (point-marker))
6542 (lim (save-excursion
6543 ;; (verilog-re-search-backward verilog-declaration-opener nil 'move)
6544 (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<module\\>\\)\\|\\(\\<task\\>\\)" nil 'move)
6545 (point)))
6546 (ind)
6547 (val)
60618039 6548 (m1 (make-marker)))
7ea26faf
DN
6549 (setq val
6550 (+ baseind (eval (cdr (assoc 'declaration verilog-indent-alist)))))
6341f357
DN
6551 (indent-line-to val)
6552
6553 ;; Use previous declaration (in this module) as template.
a3a8b002
DN
6554 (if (or (eq 'all verilog-auto-lineup)
6555 (eq 'declarations verilog-auto-lineup))
6edb5716 6556 (if (verilog-re-search-backward
6341f357
DN
6557 (or (and verilog-indent-declaration-macros
6558 verilog-declaration-re-1-macro)
6559 verilog-declaration-re-1-no-macro) lim t)
6560 (progn
6561 (goto-char (match-end 0))
6562 (skip-chars-forward " \t")
6563 (setq ind (current-column))
6564 (goto-char pos)
7ea26faf
DN
6565 (setq val
6566 (+ baseind
6567 (eval (cdr (assoc 'declaration verilog-indent-alist)))))
6341f357
DN
6568 (indent-line-to val)
6569 (if (and verilog-indent-declaration-macros
6570 (looking-at verilog-declaration-re-2-macro))
6571 (let ((p (match-end 0)))
6572 (set-marker m1 p)
6573 (if (verilog-re-search-forward "[[#`]" p 'move)
6574 (progn
6575 (forward-char -1)
6576 (just-one-space)
6577 (goto-char (marker-position m1))
6578 (just-one-space)
60618039 6579 (indent-to ind))
6341f357
DN
6580 (if (/= (current-column) ind)
6581 (progn
6582 (just-one-space)
60618039 6583 (indent-to ind)))))
6341f357
DN
6584 (if (looking-at verilog-declaration-re-2-no-macro)
6585 (let ((p (match-end 0)))
6586 (set-marker m1 p)
6587 (if (verilog-re-search-forward "[[`#]" p 'move)
6588 (progn
6589 (forward-char -1)
6590 (just-one-space)
6591 (goto-char (marker-position m1))
6592 (just-one-space)
6593 (indent-to ind))
6594 (if (/= (current-column) ind)
6595 (progn
6596 (just-one-space)
7ea26faf
DN
6597 (indent-to ind))))))))))
6598 (goto-char pos)))
6341f357
DN
6599
6600(defun verilog-get-lineup-indent (b edpos)
6601 "Return the indent level that will line up several lines within the region.
6602Region is defined by B and EDPOS."
6603 (save-excursion
6604 (let ((ind 0) e)
6605 (goto-char b)
6606 ;; Get rightmost position
6607 (while (progn (setq e (marker-position edpos))
6608 (< (point) e))
6edb5716 6609 (if (verilog-re-search-forward
6341f357
DN
6610 (or (and verilog-indent-declaration-macros
6611 verilog-declaration-re-1-macro)
6612 verilog-declaration-re-1-no-macro) e 'move)
6613 (progn
6614 (goto-char (match-end 0))
6615 (verilog-backward-syntactic-ws)
6616 (if (> (current-column) ind)
6617 (setq ind (current-column)))
6618 (goto-char (match-end 0)))))
6619 (if (> ind 0)
6620 (1+ ind)
6621 ;; No lineup-string found
6622 (goto-char b)
6623 (end-of-line)
fd9ea9d3
WS
6624 (verilog-backward-syntactic-ws)
6625 ;;(skip-chars-backward " \t")
6341f357
DN
6626 (1+ (current-column))))))
6627
6628(defun verilog-get-lineup-indent-2 (myre b edpos)
6629 "Return the indent level that will line up several lines within the region."
6630 (save-excursion
6631 (let ((ind 0) e)
6632 (goto-char b)
6633 ;; Get rightmost position
6634 (while (progn (setq e (marker-position edpos))
6635 (< (point) e))
7e2a6000 6636 (if (and (verilog-re-search-forward myre e 'move)
9489a450 6637 (not (verilog-in-attribute-p))) ;; skip attribute exprs
6341f357 6638 (progn
7e2a6000 6639 (goto-char (match-beginning 2))
6341f357
DN
6640 (verilog-backward-syntactic-ws)
6641 (if (> (current-column) ind)
6642 (setq ind (current-column)))
7e2a6000
DN
6643 (goto-char (match-end 0)))
6644 ))
6341f357
DN
6645 (if (> ind 0)
6646 (1+ ind)
6647 ;; No lineup-string found
6648 (goto-char b)
6649 (end-of-line)
6650 (skip-chars-backward " \t")
6651 (1+ (current-column))))))
6652
6653(defun verilog-comment-depth (type val)
6654 "A useful mode debugging aide. TYPE and VAL are comments for insertion."
6655 (save-excursion
6656 (let
6657 ((b (prog2
6658 (beginning-of-line)
6659 (point-marker)
6660 (end-of-line)))
6661 (e (point-marker)))
6662 (if (re-search-backward " /\\* \[#-\]# \[a-zA-Z\]+ \[0-9\]+ ## \\*/" b t)
6663 (progn
6664 (replace-match " /* -# ## */")
6665 (end-of-line))
6666 (progn
6667 (end-of-line)
6668 (insert " /* ## ## */"))))
6669 (backward-char 6)
6670 (insert
6671 (format "%s %d" type val))))
6672
6673;; \f
6674;;
6675;; Completion
6676;;
6677(defvar verilog-str nil)
6678(defvar verilog-all nil)
6679(defvar verilog-pred nil)
6680(defvar verilog-buffer-to-use nil)
6681(defvar verilog-flag nil)
6682(defvar verilog-toggle-completions nil
6683 "*True means \\<verilog-mode-map>\\[verilog-complete-word] should try all possible completions one by one.
6684Repeated use of \\[verilog-complete-word] will show you all of them.
6685Normally, when there is more than one possible completion,
6686it displays a list of all possible completions.")
6687
6688
6689(defvar verilog-type-keywords
6690 '(
6691 "and" "buf" "bufif0" "bufif1" "cmos" "defparam" "inout" "input"
6692 "integer" "localparam" "logic" "mailbox" "nand" "nmos" "nor" "not" "notif0"
fd9ea9d3 6693 "notif1" "or" "output" "parameter" "pmos" "pull0" "pull1" "pulldown" "pullup"
6341f357
DN
6694 "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran" "rtranif0"
6695 "rtranif1" "semaphore" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1"
6696 "triand" "trior" "trireg" "wand" "wire" "wor" "xnor" "xor"
6697 )
6698 "*Keywords for types used when completing a word in a declaration or parmlist.
0e5c8aed 6699\(integer, real, reg...)")
6341f357
DN
6700
6701(defvar verilog-cpp-keywords
6702 '("module" "macromodule" "primitive" "timescale" "define" "ifdef" "ifndef" "else"
6703 "endif")
6704 "*Keywords to complete when at first word of a line in declarative scope.
0e5c8aed 6705\(initial, always, begin, assign...)
6341f357 6706The procedures and variables defined within the Verilog program
37ea4b9b 6707will be completed at runtime and should not be added to this list.")
6341f357
DN
6708
6709(defvar verilog-defun-keywords
6710 (append
6711 '(
6712 "always" "always_comb" "always_ff" "always_latch" "assign"
6713 "begin" "end" "generate" "endgenerate" "module" "endmodule"
6714 "specify" "endspecify" "function" "endfunction" "initial" "final"
6715 "task" "endtask" "primitive" "endprimitive"
6716 )
6717 verilog-type-keywords)
6718 "*Keywords to complete when at first word of a line in declarative scope.
0e5c8aed 6719\(initial, always, begin, assign...)
6341f357 6720The procedures and variables defined within the Verilog program
37ea4b9b 6721will be completed at runtime and should not be added to this list.")
6341f357
DN
6722
6723(defvar verilog-block-keywords
6724 '(
6725 "begin" "break" "case" "continue" "else" "end" "endfunction"
6726 "endgenerate" "endinterface" "endpackage" "endspecify" "endtask"
6727 "for" "fork" "if" "join" "join_any" "join_none" "repeat" "return"
6728 "while")
6729 "*Keywords to complete when at first word of a line in behavioral scope.
0e5c8aed 6730\(begin, if, then, else, for, fork...)
6341f357 6731The procedures and variables defined within the Verilog program
37ea4b9b 6732will be completed at runtime and should not be added to this list.")
6341f357
DN
6733
6734(defvar verilog-tf-keywords
6735 '("begin" "break" "fork" "join" "join_any" "join_none" "case" "end" "endtask" "endfunction" "if" "else" "for" "while" "repeat")
6736 "*Keywords to complete when at first word of a line in a task or function.
0e5c8aed 6737\(begin, if, then, else, for, fork.)
6341f357 6738The procedures and variables defined within the Verilog program
37ea4b9b 6739will be completed at runtime and should not be added to this list.")
6341f357
DN
6740
6741(defvar verilog-case-keywords
6742 '("begin" "fork" "join" "join_any" "join_none" "case" "end" "endcase" "if" "else" "for" "repeat")
6743 "*Keywords to complete when at first word of a line in case scope.
0e5c8aed 6744\(begin, if, then, else, for, fork...)
6341f357 6745The procedures and variables defined within the Verilog program
37ea4b9b 6746will be completed at runtime and should not be added to this list.")
6341f357
DN
6747
6748(defvar verilog-separator-keywords
6749 '("else" "then" "begin")
6750 "*Keywords to complete when NOT standing at the first word of a statement.
0e5c8aed 6751\(else, then, begin...)
37ea4b9b
JB
6752Variables and function names defined within the Verilog program
6753will be completed at runtime and should not be added to this list.")
6341f357 6754
a03c2342
WS
6755(defvar verilog-gate-ios
6756 ;; All these have an implied {"input"...} at the end
6757 '(("and" "output")
6758 ("buf" "output")
6759 ("bufif0" "output")
6760 ("bufif1" "output")
6761 ("cmos" "output")
6762 ("nand" "output")
6763 ("nmos" "output")
6764 ("nor" "output")
6765 ("not" "output")
6766 ("notif0" "output")
6767 ("notif1" "output")
6768 ("or" "output")
6769 ("pmos" "output")
6770 ("pulldown" "output")
6771 ("pullup" "output")
6772 ("rcmos" "output")
6773 ("rnmos" "output")
6774 ("rpmos" "output")
6775 ("rtran" "inout" "inout")
6776 ("rtranif0" "inout" "inout")
6777 ("rtranif1" "inout" "inout")
6778 ("tran" "inout" "inout")
6779 ("tranif0" "inout" "inout")
6780 ("tranif1" "inout" "inout")
6781 ("xnor" "output")
6782 ("xor" "output"))
6783 "*Map of direction for each positional argument to each gate primitive.")
6784
6785(defvar verilog-gate-keywords (mapcar `car verilog-gate-ios)
6786 "*Keywords for gate primitives.")
6787
6341f357
DN
6788(defun verilog-string-diff (str1 str2)
6789 "Return index of first letter where STR1 and STR2 differs."
6790 (catch 'done
6791 (let ((diff 0))
6792 (while t
6793 (if (or (> (1+ diff) (length str1))
6794 (> (1+ diff) (length str2)))
6795 (throw 'done diff))
6796 (or (equal (aref str1 diff) (aref str2 diff))
6797 (throw 'done diff))
6798 (setq diff (1+ diff))))))
6799
6800;; Calculate all possible completions for functions if argument is `function',
6801;; completions for procedures if argument is `procedure' or both functions and
6802;; procedures otherwise.
6803
6804(defun verilog-func-completion (type)
6805 "Build regular expression for module/task/function names.
6806TYPE is 'module, 'tf for task or function, or t if unknown."
6807 (if (string= verilog-str "")
6808 (setq verilog-str "[a-zA-Z_]"))
6809 (let ((verilog-str (concat (cond
6810 ((eq type 'module) "\\<\\(module\\)\\s +")
6811 ((eq type 'tf) "\\<\\(task\\|function\\)\\s +")
6812 (t "\\<\\(task\\|function\\|module\\)\\s +"))
6813 "\\<\\(" verilog-str "[a-zA-Z0-9_.]*\\)\\>"))
6814 match)
6815
6816 (if (not (looking-at verilog-defun-re))
6817 (verilog-re-search-backward verilog-defun-re nil t))
6818 (forward-char 1)
6819
6820 ;; Search through all reachable functions
6821 (goto-char (point-min))
6822 (while (verilog-re-search-forward verilog-str (point-max) t)
6823 (progn (setq match (buffer-substring (match-beginning 2)
6824 (match-end 2)))
6825 (if (or (null verilog-pred)
6826 (funcall verilog-pred match))
6827 (setq verilog-all (cons match verilog-all)))))
6828 (if (match-beginning 0)
6829 (goto-char (match-beginning 0)))))
6830
6831(defun verilog-get-completion-decl (end)
6832 "Macro for searching through current declaration (var, type or const)
6833for matches of `str' and adding the occurrence tp `all' through point END."
6834 (let ((re (or (and verilog-indent-declaration-macros
6835 verilog-declaration-re-2-macro)
6836 verilog-declaration-re-2-no-macro))
6837 decl-end match)
6838 ;; Traverse lines
6839 (while (and (< (point) end)
6840 (verilog-re-search-forward re end t))
6841 ;; Traverse current line
6842 (setq decl-end (save-excursion (verilog-declaration-end)))
6843 (while (and (verilog-re-search-forward verilog-symbol-re decl-end t)
6844 (not (match-end 1)))
6845 (setq match (buffer-substring (match-beginning 0) (match-end 0)))
6846 (if (string-match (concat "\\<" verilog-str) match)
6847 (if (or (null verilog-pred)
6848 (funcall verilog-pred match))
6849 (setq verilog-all (cons match verilog-all)))))
60618039
DN
6850 (forward-line 1)))
6851 verilog-all)
6341f357
DN
6852
6853(defun verilog-type-completion ()
6854 "Calculate all possible completions for types."
6855 (let ((start (point))
6856 goon)
6857 ;; Search for all reachable type declarations
6858 (while (or (verilog-beg-of-defun)
6859 (setq goon (not goon)))
6860 (save-excursion
6861 (if (and (< start (prog1 (save-excursion (verilog-end-of-defun)
6862 (point))
6863 (forward-char 1)))
6864 (verilog-re-search-forward
6865 "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>"
6866 start t)
6867 (not (match-end 1)))
6868 ;; Check current type declaration
6869 (verilog-get-completion-decl start))))))
6870
6871(defun verilog-var-completion ()
6872 "Calculate all possible completions for variables (or constants)."
6873 (let ((start (point)))
6874 ;; Search for all reachable var declarations
6875 (verilog-beg-of-defun)
6876 (save-excursion
6877 ;; Check var declarations
6878 (verilog-get-completion-decl start))))
6879
6880(defun verilog-keyword-completion (keyword-list)
6881 "Give list of all possible completions of keywords in KEYWORD-LIST."
4f91a816 6882 (mapcar (lambda (s)
9489a450
MM
6883 (if (string-match (concat "\\<" verilog-str) s)
6884 (if (or (null verilog-pred)
6885 (funcall verilog-pred s))
6886 (setq verilog-all (cons s verilog-all)))))
6341f357
DN
6887 keyword-list))
6888
6889
6890(defun verilog-completion (verilog-str verilog-pred verilog-flag)
6891 "Function passed to `completing-read', `try-completion' or `all-completions'.
6892Called to get completion on VERILOG-STR. If VERILOG-PRED is non-nil, it
6893must be a function to be called for every match to check if this should
37ea4b9b
JB
6894really be a match. If VERILOG-FLAG is t, the function returns a list of
6895all possible completions. If VERILOG-FLAG is nil it returns a string,
6896the longest possible completion, or t if VERILOG-STR is an exact match.
6897If VERILOG-FLAG is 'lambda, the function returns t if VERILOG-STR is an
6898exact match, nil otherwise."
6341f357
DN
6899 (save-excursion
6900 (let ((verilog-all nil))
6901 ;; Set buffer to use for searching labels. This should be set
6902 ;; within functions which use verilog-completions
6903 (set-buffer verilog-buffer-to-use)
6904
6905 ;; Determine what should be completed
6906 (let ((state (car (verilog-calculate-indent))))
6907 (cond ((eq state 'defun)
6908 (save-excursion (verilog-var-completion))
6909 (verilog-func-completion 'module)
6910 (verilog-keyword-completion verilog-defun-keywords))
6911
6912 ((eq state 'behavioral)
6913 (save-excursion (verilog-var-completion))
6914 (verilog-func-completion 'module)
6915 (verilog-keyword-completion verilog-defun-keywords))
6916
6917 ((eq state 'block)
6918 (save-excursion (verilog-var-completion))
6919 (verilog-func-completion 'tf)
6920 (verilog-keyword-completion verilog-block-keywords))
6921
6922 ((eq state 'case)
6923 (save-excursion (verilog-var-completion))
6924 (verilog-func-completion 'tf)
6925 (verilog-keyword-completion verilog-case-keywords))
6926
6927 ((eq state 'tf)
6928 (save-excursion (verilog-var-completion))
6929 (verilog-func-completion 'tf)
6930 (verilog-keyword-completion verilog-tf-keywords))
6931
6932 ((eq state 'cpp)
6933 (save-excursion (verilog-var-completion))
6934 (verilog-keyword-completion verilog-cpp-keywords))
6935
6936 ((eq state 'cparenexp)
6937 (save-excursion (verilog-var-completion)))
6938
6939 (t;--Anywhere else
6940 (save-excursion (verilog-var-completion))
6941 (verilog-func-completion 'both)
6942 (verilog-keyword-completion verilog-separator-keywords))))
6943
6944 ;; Now we have built a list of all matches. Give response to caller
6945 (verilog-completion-response))))
6946
6947(defun verilog-completion-response ()
6948 (cond ((or (equal verilog-flag 'lambda) (null verilog-flag))
6949 ;; This was not called by all-completions
6950 (if (null verilog-all)
6951 ;; Return nil if there was no matching label
6952 nil
6953 ;; Get longest string common in the labels
6954 (let* ((elm (cdr verilog-all))
6955 (match (car verilog-all))
6956 (min (length match))
6957 tmp)
6958 (if (string= match verilog-str)
6959 ;; Return t if first match was an exact match
6960 (setq match t)
6961 (while (not (null elm))
6962 ;; Find longest common string
6963 (if (< (setq tmp (verilog-string-diff match (car elm))) min)
6964 (progn
6965 (setq min tmp)
6966 (setq match (substring match 0 min))))
6967 ;; Terminate with match=t if this is an exact match
6968 (if (string= (car elm) verilog-str)
6969 (progn
6970 (setq match t)
6971 (setq elm nil))
6972 (setq elm (cdr elm)))))
6973 ;; If this is a test just for exact match, return nil ot t
6974 (if (and (equal verilog-flag 'lambda) (not (equal match 't)))
6975 nil
6976 match))))
6977 ;; If flag is t, this was called by all-completions. Return
6978 ;; list of all possible completions
6979 (verilog-flag
6980 verilog-all)))
6981
6982(defvar verilog-last-word-numb 0)
6983(defvar verilog-last-word-shown nil)
6984(defvar verilog-last-completions nil)
6985
6986(defun verilog-complete-word ()
6987 "Complete word at current point.
6988\(See also `verilog-toggle-completions', `verilog-type-keywords',
6989and `verilog-separator-keywords'.)"
6990 (interactive)
6991 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
6992 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
6993 (verilog-str (buffer-substring b e))
6994 ;; The following variable is used in verilog-completion
6995 (verilog-buffer-to-use (current-buffer))
6996 (allcomp (if (and verilog-toggle-completions
6997 (string= verilog-last-word-shown verilog-str))
6998 verilog-last-completions
6999 (all-completions verilog-str 'verilog-completion)))
7000 (match (if verilog-toggle-completions
7001 "" (try-completion
4f91a816 7002 verilog-str (mapcar (lambda (elm)
6341f357
DN
7003 (cons elm 0)) allcomp)))))
7004 ;; Delete old string
7005 (delete-region b e)
7006
7007 ;; Toggle-completions inserts whole labels
7008 (if verilog-toggle-completions
7009 (progn
7010 ;; Update entry number in list
7011 (setq verilog-last-completions allcomp
7012 verilog-last-word-numb
7013 (if (>= verilog-last-word-numb (1- (length allcomp)))
7014 0
7015 (1+ verilog-last-word-numb)))
7016 (setq verilog-last-word-shown (elt allcomp verilog-last-word-numb))
7017 ;; Display next match or same string if no match was found
7018 (if (not (null allcomp))
7019 (insert "" verilog-last-word-shown)
7020 (insert "" verilog-str)
7021 (message "(No match)")))
7022 ;; The other form of completion does not necessarily do that.
7023
7024 ;; Insert match if found, or the original string if no match
7025 (if (or (null match) (equal match 't))
7026 (progn (insert "" verilog-str)
7027 (message "(No match)"))
7028 (insert "" match))
7029 ;; Give message about current status of completion
7030 (cond ((equal match 't)
7031 (if (not (null (cdr allcomp)))
7032 (message "(Complete but not unique)")
7033 (message "(Sole completion)")))
7034 ;; Display buffer if the current completion didn't help
7035 ;; on completing the label.
7036 ((and (not (null (cdr allcomp))) (= (length verilog-str)
7037 (length match)))
7038 (with-output-to-temp-buffer "*Completions*"
7039 (display-completion-list allcomp))
7040 ;; Wait for a key press. Then delete *Completion* window
7041 (momentary-string-display "" (point))
7042 (delete-window (get-buffer-window (get-buffer "*Completions*")))
7043 )))))
7044
7045(defun verilog-show-completions ()
7046 "Show all possible completions at current point."
7047 (interactive)
7048 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
7049 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
7050 (verilog-str (buffer-substring b e))
7051 ;; The following variable is used in verilog-completion
7052 (verilog-buffer-to-use (current-buffer))
7053 (allcomp (if (and verilog-toggle-completions
7054 (string= verilog-last-word-shown verilog-str))
7055 verilog-last-completions
7056 (all-completions verilog-str 'verilog-completion))))
7057 ;; Show possible completions in a temporary buffer.
7058 (with-output-to-temp-buffer "*Completions*"
7059 (display-completion-list allcomp))
7060 ;; Wait for a key press. Then delete *Completion* window
7061 (momentary-string-display "" (point))
7062 (delete-window (get-buffer-window (get-buffer "*Completions*")))))
7063
7064
7065(defun verilog-get-default-symbol ()
7066 "Return symbol around current point as a string."
7067 (save-excursion
7068 (buffer-substring (progn
7069 (skip-chars-backward " \t")
7070 (skip-chars-backward "a-zA-Z0-9_")
7071 (point))
7072 (progn
7073 (skip-chars-forward "a-zA-Z0-9_")
7074 (point)))))
7075
7076(defun verilog-build-defun-re (str &optional arg)
7077 "Return function/task/module starting with STR as regular expression.
7078With optional second ARG non-nil, STR is the complete name of the instruction."
7079 (if arg
7080 (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "\\)\\>")
7081 (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "[a-zA-Z0-9_]*\\)\\>")))
7082
7083(defun verilog-comp-defun (verilog-str verilog-pred verilog-flag)
7084 "Function passed to `completing-read', `try-completion' or `all-completions'.
7085Returns a completion on any function name based on VERILOG-STR prefix. If
7086VERILOG-PRED is non-nil, it must be a function to be called for every match
7087to check if this should really be a match. If VERILOG-FLAG is t, the
7088function returns a list of all possible completions. If it is nil it
7089returns a string, the longest possible completion, or t if VERILOG-STR is
7090an exact match. If VERILOG-FLAG is 'lambda, the function returns t if
7091VERILOG-STR is an exact match, nil otherwise."
7092 (save-excursion
7093 (let ((verilog-all nil)
7094 match)
7095
7096 ;; Set buffer to use for searching labels. This should be set
7097 ;; within functions which use verilog-completions
7098 (set-buffer verilog-buffer-to-use)
7099
7100 (let ((verilog-str verilog-str))
7101 ;; Build regular expression for functions
7102 (if (string= verilog-str "")
7103 (setq verilog-str (verilog-build-defun-re "[a-zA-Z_]"))
7104 (setq verilog-str (verilog-build-defun-re verilog-str)))
7105 (goto-char (point-min))
7106
7107 ;; Build a list of all possible completions
7108 (while (verilog-re-search-forward verilog-str nil t)
7109 (setq match (buffer-substring (match-beginning 2) (match-end 2)))
7110 (if (or (null verilog-pred)
7111 (funcall verilog-pred match))
7112 (setq verilog-all (cons match verilog-all)))))
7113
7114 ;; Now we have built a list of all matches. Give response to caller
7115 (verilog-completion-response))))
7116
7117(defun verilog-goto-defun ()
a03c2342 7118 "Move to specified Verilog module/interface/task/function.
6341f357
DN
7119The default is a name found in the buffer around point.
7120If search fails, other files are checked based on
7121`verilog-library-flags'."
7122 (interactive)
7123 (let* ((default (verilog-get-default-symbol))
7124 ;; The following variable is used in verilog-comp-function
7125 (verilog-buffer-to-use (current-buffer))
7126 (label (if (not (string= default ""))
7127 ;; Do completion with default
a3a8b002
DN
7128 (completing-read (concat "Goto-Label: (default "
7129 default ") ")
6341f357
DN
7130 'verilog-comp-defun nil nil "")
7131 ;; There is no default value. Complete without it
a3a8b002 7132 (completing-read "Goto-Label: "
6341f357
DN
7133 'verilog-comp-defun nil nil "")))
7134 pt)
a3a8b002
DN
7135 ;; Make sure library paths are correct, in case need to resolve module
7136 (verilog-auto-reeval-locals)
7137 (verilog-getopt-flags)
6341f357
DN
7138 ;; If there was no response on prompt, use default value
7139 (if (string= label "")
7140 (setq label default))
7141 ;; Goto right place in buffer if label is not an empty string
7142 (or (string= label "")
7143 (progn
7144 (save-excursion
7145 (goto-char (point-min))
7ea26faf
DN
7146 (setq pt
7147 (re-search-forward (verilog-build-defun-re label t) nil t)))
6341f357
DN
7148 (when pt
7149 (goto-char pt)
7150 (beginning-of-line))
7151 pt)
60618039 7152 (verilog-goto-defun-file label))))
6341f357
DN
7153
7154;; Eliminate compile warning
7d55bf04 7155(defvar occur-pos-list)
6341f357
DN
7156
7157(defun verilog-showscopes ()
7158 "List all scopes in this module."
7159 (interactive)
7160 (let ((buffer (current-buffer))
7161 (linenum 1)
7162 (nlines 0)
7163 (first 1)
7164 (prevpos (point-min))
7165 (final-context-start (make-marker))
60618039 7166 (regexp "\\(module\\s-+\\w+\\s-*(\\)\\|\\(\\w+\\s-+\\w+\\s-*(\\)"))
6341f357
DN
7167 (with-output-to-temp-buffer "*Occur*"
7168 (save-excursion
7169 (message (format "Searching for %s ..." regexp))
7170 ;; Find next match, but give up if prev match was at end of buffer.
7171 (while (and (not (= prevpos (point-max)))
7172 (verilog-re-search-forward regexp nil t))
7173 (goto-char (match-beginning 0))
7174 (beginning-of-line)
7175 (save-match-data
7176 (setq linenum (+ linenum (count-lines prevpos (point)))))
7177 (setq prevpos (point))
7178 (goto-char (match-end 0))
7179 (let* ((start (save-excursion
7180 (goto-char (match-beginning 0))
7181 (forward-line (if (< nlines 0) nlines (- nlines)))
7182 (point)))
7183 (end (save-excursion
7184 (goto-char (match-end 0))
7185 (if (> nlines 0)
7186 (forward-line (1+ nlines))
7187 (forward-line 1))
7188 (point)))
7189 (tag (format "%3d" linenum))
7190 (empty (make-string (length tag) ?\ ))
7191 tem)
7192 (save-excursion
7193 (setq tem (make-marker))
7194 (set-marker tem (point))
7195 (set-buffer standard-output)
7196 (setq occur-pos-list (cons tem occur-pos-list))
7197 (or first (zerop nlines)
7198 (insert "--------\n"))
7199 (setq first nil)
7200 (insert-buffer-substring buffer start end)
7201 (backward-char (- end start))
7202 (setq tem (if (< nlines 0) (- nlines) nlines))
7203 (while (> tem 0)
7204 (insert empty ?:)
7205 (forward-line 1)
7206 (setq tem (1- tem)))
7207 (let ((this-linenum linenum))
7208 (set-marker final-context-start
7209 (+ (point) (- (match-end 0) (match-beginning 0))))
7210 (while (< (point) final-context-start)
7211 (if (null tag)
7212 (setq tag (format "%3d" this-linenum)))
7213 (insert tag ?:)))))))
7214 (set-buffer-modified-p nil))))
7215
7216
7217;; Highlight helper functions
7218(defconst verilog-directive-regexp "\\(translate\\|coverage\\|lint\\)_")
7219(defun verilog-within-translate-off ()
7220 "Return point if within translate-off region, else nil."
7221 (and (save-excursion
7222 (re-search-backward
7223 (concat "//\\s-*.*\\s-*" verilog-directive-regexp "\\(on\\|off\\)\\>")
7224 nil t))
7225 (equal "off" (match-string 2))
7226 (point)))
7227
7228(defun verilog-start-translate-off (limit)
7229 "Return point before translate-off directive if before LIMIT, else nil."
7230 (when (re-search-forward
7231 (concat "//\\s-*.*\\s-*" verilog-directive-regexp "off\\>")
7232 limit t)
7233 (match-beginning 0)))
7234
7235(defun verilog-back-to-start-translate-off (limit)
7236 "Return point before translate-off directive if before LIMIT, else nil."
7237 (when (re-search-backward
7238 (concat "//\\s-*.*\\s-*" verilog-directive-regexp "off\\>")
7239 limit t)
7240 (match-beginning 0)))
7241
7242(defun verilog-end-translate-off (limit)
7243 "Return point after translate-on directive if before LIMIT, else nil."
7244
7245 (re-search-forward (concat
7246 "//\\s-*.*\\s-*" verilog-directive-regexp "on\\>") limit t))
7247
7248(defun verilog-match-translate-off (limit)
7249 "Match a translate-off block, setting `match-data' and returning t, else nil.
7250Bound search by LIMIT."
7251 (when (< (point) limit)
7252 (let ((start (or (verilog-within-translate-off)
7253 (verilog-start-translate-off limit)))
7254 (case-fold-search t))
7255 (when start
7256 (let ((end (or (verilog-end-translate-off limit) limit)))
7257 (set-match-data (list start end))
7258 (goto-char end))))))
7259
7260(defun verilog-font-lock-match-item (limit)
7261 "Match, and move over, any declaration item after point.
7262Bound search by LIMIT. Adapted from
7263`font-lock-match-c-style-declaration-item-and-skip-to-next'."
7264 (condition-case nil
7265 (save-restriction
7266 (narrow-to-region (point-min) limit)
7267 ;; match item
7268 (when (looking-at "\\s-*\\([a-zA-Z]\\w*\\)")
7269 (save-match-data
7270 (goto-char (match-end 1))
7271 ;; move to next item
7272 (if (looking-at "\\(\\s-*,\\)")
7273 (goto-char (match-end 1))
7274 (end-of-line) t))))
7275 (error nil)))
7276
7277
7278;; Added by Subbu Meiyappan for Header
7279
7280(defun verilog-header ()
a3a8b002
DN
7281 "Insert a standard Verilog file header.
7282See also `verilog-sk-header' for an alternative format."
6341f357
DN
7283 (interactive)
7284 (let ((start (point)))
7285 (insert "\
7286//-----------------------------------------------------------------------------
7287// Title : <title>
7288// Project : <project>
7289//-----------------------------------------------------------------------------
7290// File : <filename>
7291// Author : <author>
7292// Created : <credate>
7293// Last modified : <moddate>
7294//-----------------------------------------------------------------------------
7295// Description :
7296// <description>
7297//-----------------------------------------------------------------------------
7298// Copyright (c) <copydate> by <company> This model is the confidential and
7299// proprietary property of <company> and the possession or use of this
7300// file requires a written license from <company>.
7301//------------------------------------------------------------------------------
7302// Modification history :
7303// <modhist>
7304//-----------------------------------------------------------------------------
7305
7306")
7307 (goto-char start)
7308 (search-forward "<filename>")
7309 (replace-match (buffer-name) t t)
7310 (search-forward "<author>") (replace-match "" t t)
7311 (insert (user-full-name))
7312 (insert " <" (user-login-name) "@" (system-name) ">")
7313 (search-forward "<credate>") (replace-match "" t t)
6ca0ff73 7314 (verilog-insert-date)
6341f357 7315 (search-forward "<moddate>") (replace-match "" t t)
6ca0ff73 7316 (verilog-insert-date)
6341f357 7317 (search-forward "<copydate>") (replace-match "" t t)
6ca0ff73 7318 (verilog-insert-year)
6341f357 7319 (search-forward "<modhist>") (replace-match "" t t)
6ca0ff73 7320 (verilog-insert-date)
6341f357
DN
7321 (insert " : created")
7322 (goto-char start)
7323 (let (string)
7324 (setq string (read-string "title: "))
7325 (search-forward "<title>")
7326 (replace-match string t t)
7327 (setq string (read-string "project: " verilog-project))
6341f357
DN
7328 (setq verilog-project string)
7329 (search-forward "<project>")
7330 (replace-match string t t)
7331 (setq string (read-string "Company: " verilog-company))
6341f357
DN
7332 (setq verilog-company string)
7333 (search-forward "<company>")
7334 (replace-match string t t)
7335 (search-forward "<company>")
7336 (replace-match string t t)
7337 (search-forward "<company>")
7338 (replace-match string t t)
7339 (search-backward "<description>")
60618039 7340 (replace-match "" t t))))
6341f357 7341
6ca0ff73 7342;; verilog-header Uses the verilog-insert-date function
6341f357 7343
6ca0ff73 7344(defun verilog-insert-date ()
6341f357
DN
7345 "Insert date from the system."
7346 (interactive)
a3a8b002
DN
7347 (if verilog-date-scientific-format
7348 (insert (format-time-string "%Y/%m/%d"))
7349 (insert (format-time-string "%d.%m.%Y"))))
6341f357 7350
6ca0ff73 7351(defun verilog-insert-year ()
6341f357
DN
7352 "Insert year from the system."
7353 (interactive)
a3a8b002 7354 (insert (format-time-string "%Y")))
6341f357
DN
7355
7356\f
7357;;
7358;; Signal list parsing
7359;;
7360
7361;; Elements of a signal list
a03c2342
WS
7362(defsubst verilog-sig-new (name bits comment mem enum signed type multidim modport)
7363 (list name bits comment mem enum signed type multidim modport))
6341f357
DN
7364(defsubst verilog-sig-name (sig)
7365 (car sig))
7366(defsubst verilog-sig-bits (sig)
7367 (nth 1 sig))
7368(defsubst verilog-sig-comment (sig)
7369 (nth 2 sig))
7370(defsubst verilog-sig-memory (sig)
7371 (nth 3 sig))
7372(defsubst verilog-sig-enum (sig)
7373 (nth 4 sig))
7374(defsubst verilog-sig-signed (sig)
7375 (nth 5 sig))
7376(defsubst verilog-sig-type (sig)
7377 (nth 6 sig))
7378(defsubst verilog-sig-multidim (sig)
7379 (nth 7 sig))
7380(defsubst verilog-sig-multidim-string (sig)
7381 (if (verilog-sig-multidim sig)
7382 (let ((str "") (args (verilog-sig-multidim sig)))
7383 (while args
7384 (setq str (concat str (car args)))
7385 (setq args (cdr args)))
7386 str)))
a3a8b002
DN
7387(defsubst verilog-sig-modport (sig)
7388 (nth 8 sig))
6341f357
DN
7389(defsubst verilog-sig-width (sig)
7390 (verilog-make-width-expression (verilog-sig-bits sig)))
7391
9489a450
MM
7392(defsubst verilog-alw-new (outputs-del outputs-imm temps inputs)
7393 (list outputs-del outputs-imm temps inputs))
7394(defsubst verilog-alw-get-outputs-delayed (sigs)
6341f357 7395 (nth 0 sigs))
9489a450 7396(defsubst verilog-alw-get-outputs-immediate (sigs)
a03c2342 7397 (nth 1 sigs))
9489a450 7398(defsubst verilog-alw-get-temps (sigs)
a03c2342 7399 (nth 2 sigs))
9489a450 7400(defsubst verilog-alw-get-inputs (sigs)
6341f357 7401 (nth 3 sigs))
9489a450
MM
7402(defsubst verilog-alw-get-uses-delayed (sigs)
7403 (nth 0 sigs))
6341f357 7404
a03c2342
WS
7405(defsubst verilog-modi-new (name fob pt type)
7406 (vector name fob pt type))
7407(defsubst verilog-modi-name (modi)
7408 (aref modi 0))
7409(defsubst verilog-modi-file-or-buffer (modi)
7410 (aref modi 1))
7411(defsubst verilog-modi-get-point (modi)
7412 (aref modi 2))
7413(defsubst verilog-modi-get-type (modi) ;; "module" or "interface"
7414 (aref modi 3))
7415(defsubst verilog-modi-get-decls (modi)
7416 (verilog-modi-cache-results modi 'verilog-read-decls))
7417(defsubst verilog-modi-get-sub-decls (modi)
7418 (verilog-modi-cache-results modi 'verilog-read-sub-decls))
7419
7420;; Signal reading for given module
7421;; Note these all take modi's - as returned from verilog-modi-current
9489a450
MM
7422(defsubst verilog-decls-new (out inout in vars unuseds assigns consts gparams interfaces)
7423 (vector out inout in vars unuseds assigns consts gparams interfaces))
a03c2342
WS
7424(defsubst verilog-decls-get-outputs (decls)
7425 (aref decls 0))
7426(defsubst verilog-decls-get-inouts (decls)
7427 (aref decls 1))
7428(defsubst verilog-decls-get-inputs (decls)
7429 (aref decls 2))
9489a450 7430(defsubst verilog-decls-get-vars (decls)
a03c2342 7431 (aref decls 3))
9489a450
MM
7432;;(defsubst verilog-decls-get-unused (decls)
7433;; (aref decls 4))
a03c2342
WS
7434(defsubst verilog-decls-get-assigns (decls)
7435 (aref decls 5))
7436(defsubst verilog-decls-get-consts (decls)
7437 (aref decls 6))
7438(defsubst verilog-decls-get-gparams (decls)
7439 (aref decls 7))
7440(defsubst verilog-decls-get-interfaces (decls)
7441 (aref decls 8))
7442
7443(defsubst verilog-subdecls-new (out inout in intf intfd)
7444 (vector out inout in intf intfd))
7445(defsubst verilog-subdecls-get-outputs (subdecls)
7446 (aref subdecls 0))
7447(defsubst verilog-subdecls-get-inouts (subdecls)
7448 (aref subdecls 1))
7449(defsubst verilog-subdecls-get-inputs (subdecls)
7450 (aref subdecls 2))
7451(defsubst verilog-subdecls-get-interfaces (subdecls)
7452 (aref subdecls 3))
7453(defsubst verilog-subdecls-get-interfaced (subdecls)
7454 (aref subdecls 4))
7455
6341f357 7456(defun verilog-signals-not-in (in-list not-list)
37ea4b9b
JB
7457 "Return list of signals in IN-LIST that aren't also in NOT-LIST.
7458Also remove any duplicates in IN-LIST.
6341f357 7459Signals must be in standard (base vector) form."
a03c2342
WS
7460 ;; This function is hot, so implemented as O(1)
7461 (cond ((eval-when-compile (fboundp 'make-hash-table))
7462 (let ((ht (make-hash-table :test 'equal :rehash-size 4.0))
7463 out-list)
7464 (while not-list
7465 (puthash (car (car not-list)) t ht)
7466 (setq not-list (cdr not-list)))
7467 (while in-list
7468 (when (not (gethash (car (car in-list)) ht))
7469 (setq out-list (cons (car in-list) out-list))
7470 (puthash (car (car in-list)) t ht))
7471 (setq in-list (cdr in-list)))
7472 (nreverse out-list)))
7473 ;; Slower Fallback if no hash tables (pre Emacs 21.1/XEmacs 21.4)
7474 (t
7475 (let (out-list)
7476 (while in-list
7477 (if (not (or (assoc (car (car in-list)) not-list)
7478 (assoc (car (car in-list)) out-list)))
7479 (setq out-list (cons (car in-list) out-list)))
7480 (setq in-list (cdr in-list)))
7481 (nreverse out-list)))))
6341f357
DN
7482;;(verilog-signals-not-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" "")))
7483
6341f357 7484(defun verilog-signals-memory (in-list)
53964682 7485 "Return list of signals in IN-LIST that are memorized (multidimensional)."
6341f357
DN
7486 (let (out-list)
7487 (while in-list
7488 (if (nth 3 (car in-list))
7489 (setq out-list (cons (car in-list) out-list)))
7490 (setq in-list (cdr in-list)))
7491 out-list))
7492;;(verilog-signals-memory '(("A" nil nil "[3:0]")) '(("B" nil nil nil)))
7493
7494(defun verilog-signals-sort-compare (a b)
7495 "Compare signal A and B for sorting."
7496 (string< (car a) (car b)))
7497
7498(defun verilog-signals-not-params (in-list)
7499 "Return list of signals in IN-LIST that aren't parameters or numeric constants."
7500 (let (out-list)
7501 (while in-list
7502 (unless (boundp (intern (concat "vh-" (car (car in-list)))))
7503 (setq out-list (cons (car in-list) out-list)))
7504 (setq in-list (cdr in-list)))
7505 (nreverse out-list)))
7506
7507(defun verilog-signals-combine-bus (in-list)
7508 "Return a list of signals in IN-LIST, with busses combined.
7509Duplicate signals are also removed. For example A[2] and A[1] become A[2:1]."
7510 (let (combo buswarn
7511 out-list
7512 sig highbit lowbit ; Temp information about current signal
7513 sv-name sv-highbit sv-lowbit ; Details about signal we are forming
7514 sv-comment sv-memory sv-enum sv-signed sv-type sv-multidim sv-busstring
a3a8b002 7515 sv-modport
6341f357
DN
7516 bus)
7517 ;; Shove signals so duplicated signals will be adjacent
7518 (setq in-list (sort in-list `verilog-signals-sort-compare))
7519 (while in-list
7520 (setq sig (car in-list))
7521 ;; No current signal; form from existing details
7522 (unless sv-name
7523 (setq sv-name (verilog-sig-name sig)
7524 sv-highbit nil
7525 sv-busstring nil
7526 sv-comment (verilog-sig-comment sig)
7527 sv-memory (verilog-sig-memory sig)
7528 sv-enum (verilog-sig-enum sig)
7529 sv-signed (verilog-sig-signed sig)
7530 sv-type (verilog-sig-type sig)
7531 sv-multidim (verilog-sig-multidim sig)
a3a8b002 7532 sv-modport (verilog-sig-modport sig)
6341f357 7533 combo ""
60618039 7534 buswarn ""))
6341f357
DN
7535 ;; Extract bus details
7536 (setq bus (verilog-sig-bits sig))
9489a450 7537 (setq bus (and bus (verilog-simplify-range-expression bus)))
6341f357
DN
7538 (cond ((and bus
7539 (or (and (string-match "\\[\\([0-9]+\\):\\([0-9]+\\)\\]" bus)
7ea26faf
DN
7540 (setq highbit (string-to-number (match-string 1 bus))
7541 lowbit (string-to-number
7542 (match-string 2 bus))))
6341f357 7543 (and (string-match "\\[\\([0-9]+\\)\\]" bus)
7ea26faf 7544 (setq highbit (string-to-number (match-string 1 bus))
6341f357
DN
7545 lowbit highbit))))
7546 ;; Combine bits in bus
7547 (if sv-highbit
7548 (setq sv-highbit (max highbit sv-highbit)
7549 sv-lowbit (min lowbit sv-lowbit))
7550 (setq sv-highbit highbit
7551 sv-lowbit lowbit)))
7552 (bus
7553 ;; String, probably something like `preproc:0
7554 (setq sv-busstring bus)))
7555 ;; Peek ahead to next signal
7556 (setq in-list (cdr in-list))
7557 (setq sig (car in-list))
7558 (cond ((and sig (equal sv-name (verilog-sig-name sig)))
7559 ;; Combine with this signal
7ea26faf
DN
7560 (when (and sv-busstring
7561 (not (equal sv-busstring (verilog-sig-bits sig))))
6341f357
DN
7562 (when nil ;; Debugging
7563 (message (concat "Warning, can't merge into single bus "
7564 sv-name bus
7565 ", the AUTOs may be wrong")))
7566 (setq buswarn ", Couldn't Merge"))
7567 (if (verilog-sig-comment sig) (setq combo ", ..."))
7568 (setq sv-memory (or sv-memory (verilog-sig-memory sig))
7569 sv-enum (or sv-enum (verilog-sig-enum sig))
7570 sv-signed (or sv-signed (verilog-sig-signed sig))
7571 sv-type (or sv-type (verilog-sig-type sig))
a3a8b002
DN
7572 sv-multidim (or sv-multidim (verilog-sig-multidim sig))
7573 sv-modport (or sv-modport (verilog-sig-modport sig))))
6341f357
DN
7574 ;; Doesn't match next signal, add to queue, zero in prep for next
7575 ;; Note sig may also be nil for the last signal in the list
7576 (t
7577 (setq out-list
a03c2342
WS
7578 (cons (verilog-sig-new
7579 sv-name
7ea26faf
DN
7580 (or sv-busstring
7581 (if sv-highbit
7582 (concat "[" (int-to-string sv-highbit) ":"
7583 (int-to-string sv-lowbit) "]")))
60618039 7584 (concat sv-comment combo buswarn)
a3a8b002 7585 sv-memory sv-enum sv-signed sv-type sv-multidim sv-modport)
a03c2342 7586 out-list)
60618039 7587 sv-name nil))))
6341f357
DN
7588 ;;
7589 out-list))
7590
7591(defun verilog-sig-tieoff (sig &optional no-width)
60618039 7592 "Return tieoff expression for given SIG, with appropriate width.
6341f357
DN
7593Ignore width if optional NO-WIDTH is set."
7594 (let* ((width (if no-width nil (verilog-sig-width sig))))
7595 (concat
7596 (if (and verilog-active-low-regexp
7597 (string-match verilog-active-low-regexp (verilog-sig-name sig)))
7598 "~" "")
7599 (cond ((not width)
7600 "0")
7601 ((string-match "^[0-9]+$" width)
7602 (concat width (if (verilog-sig-signed sig) "'sh0" "'h0")))
7603 (t
7604 (concat "{" width "{1'b0}}"))))))
7605
7606;;
7607;; Port/Wire/Etc Reading
7608;;
7609
7610(defun verilog-read-inst-backward-name ()
7611 "Internal. Move point back to beginning of inst-name."
7612 (verilog-backward-open-paren)
7613 (let (done)
7614 (while (not done)
7615 (verilog-re-search-backward-quick "\\()\\|\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil) ; ] isn't word boundary
7616 (cond ((looking-at ")")
7617 (verilog-backward-open-paren))
7618 (t (setq done t)))))
7619 (while (looking-at "\\]")
7620 (verilog-backward-open-bracket)
7621 (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|\\]\\)" nil nil))
7622 (skip-chars-backward "a-zA-Z0-9`_$"))
7623
a03c2342
WS
7624(defun verilog-read-inst-module-matcher ()
7625 "Set match data 0 with module_name when point is inside instantiation."
7626 (verilog-read-inst-backward-name)
7627 ;; Skip over instantiation name
7628 (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|)\\)" nil nil) ; ) isn't word boundary
7629 ;; Check for parameterized instantiations
7630 (when (looking-at ")")
7631 (verilog-backward-open-paren)
7632 (verilog-re-search-backward-quick "\\b[a-zA-Z0-9`_\$]" nil nil))
7633 (skip-chars-backward "a-zA-Z0-9'_$")
7634 (looking-at "[a-zA-Z0-9`_\$]+")
7635 ;; Important: don't use match string, this must work with Emacs 19 font-lock on
7636 (buffer-substring-no-properties (match-beginning 0) (match-end 0))
7637 ;; Caller assumes match-beginning/match-end is still set
7638 )
7639
6341f357
DN
7640(defun verilog-read-inst-module ()
7641 "Return module_name when point is inside instantiation."
7642 (save-excursion
a03c2342 7643 (verilog-read-inst-module-matcher)))
6341f357
DN
7644
7645(defun verilog-read-inst-name ()
7646 "Return instance_name when point is inside instantiation."
7647 (save-excursion
7648 (verilog-read-inst-backward-name)
7649 (looking-at "[a-zA-Z0-9`_\$]+")
d63b01e1 7650 ;; Important: don't use match string, this must work with Emacs 19 font-lock on
6341f357
DN
7651 (buffer-substring-no-properties (match-beginning 0) (match-end 0))))
7652
7653(defun verilog-read-module-name ()
7654 "Return module name when after its ( or ;."
7655 (save-excursion
7656 (re-search-backward "[(;]")
9489a450
MM
7657 ;; Due to "module x import y (" we must search for declaration begin
7658 (verilog-re-search-backward-quick verilog-defun-re nil nil)
7659 (goto-char (match-end 0))
7660 (verilog-re-search-forward-quick "\\b[a-zA-Z0-9`_\$]+" nil nil)
d63b01e1 7661 ;; Important: don't use match string, this must work with Emacs 19 font-lock on
a3a8b002
DN
7662 (verilog-symbol-detick
7663 (buffer-substring-no-properties (match-beginning 0) (match-end 0)) t)))
6341f357 7664
4c5e69c6
DN
7665(defun verilog-read-inst-param-value ()
7666 "Return list of parameters and values when point is inside instantiation."
7667 (save-excursion
7668 (verilog-read-inst-backward-name)
7669 ;; Skip over instantiation name
7670 (verilog-re-search-backward-quick "\\(\\b[a-zA-Z0-9`_\$]\\|)\\)" nil nil) ; ) isn't word boundary
7671 ;; If there are parameterized instantiations
7672 (when (looking-at ")")
7673 (let ((end-pt (point))
7674 params
7675 param-name paren-beg-pt param-value)
7676 (verilog-backward-open-paren)
7677 (while (verilog-re-search-forward-quick "\\." end-pt t)
7678 (verilog-re-search-forward-quick "\\([a-zA-Z0-9`_\$]\\)" nil nil)
7679 (skip-chars-backward "a-zA-Z0-9'_$")
7680 (looking-at "[a-zA-Z0-9`_\$]+")
7681 (setq param-name (buffer-substring-no-properties
7682 (match-beginning 0) (match-end 0)))
7683 (verilog-re-search-forward-quick "(" nil nil)
7684 (setq paren-beg-pt (point))
7685 (verilog-forward-close-paren)
7686 (setq param-value (verilog-string-remove-spaces
7687 (buffer-substring-no-properties
7688 paren-beg-pt (1- (point)))))
7689 (setq params (cons (list param-name param-value) params)))
7690 params))))
7691
6341f357
DN
7692(defun verilog-read-auto-params (num-param &optional max-param)
7693 "Return parameter list inside auto.
7694Optional NUM-PARAM and MAX-PARAM check for a specific number of parameters."
7695 (let ((olist))
7696 (save-excursion
7697 ;; /*AUTOPUNT("parameter", "parameter")*/
7698 (search-backward "(")
7699 (while (looking-at "(?\\s *\"\\([^\"]*\\)\"\\s *,?")
7700 (setq olist (cons (match-string 1) olist))
7701 (goto-char (match-end 0))))
7702 (or (eq nil num-param)
7703 (<= num-param (length olist))
7704 (error "%s: Expected %d parameters" (verilog-point-text) num-param))
7705 (if (eq max-param nil) (setq max-param num-param))
7706 (or (eq nil max-param)
7707 (>= max-param (length olist))
7708 (error "%s: Expected <= %d parameters" (verilog-point-text) max-param))
7709 (nreverse olist)))
7710
7711(defun verilog-read-decls ()
7712 "Compute signal declaration information for the current module at point.
7713Return a array of [outputs inouts inputs wire reg assign const]."
7714 (let ((end-mod-point (or (verilog-get-end-of-defun t) (point-max)))
a3a8b002 7715 (functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t)
9489a450
MM
7716 in-modport ign-prop
7717 sigs-in sigs-out sigs-inout sigs-var sigs-assign sigs-const
a3a8b002
DN
7718 sigs-gparam sigs-intf
7719 vec expect-signal keywd newsig rvalue enum io signed typedefed multidim
7720 modport)
6341f357 7721 (save-excursion
9489a450 7722 (verilog-beg-of-defun-quick)
6341f357
DN
7723 (setq sigs-const (verilog-read-auto-constants (point) end-mod-point))
7724 (while (< (point) end-mod-point)
a03c2342 7725 ;;(if dbg (setq dbg (concat dbg (format "Pt %s Vec %s C%c Kwd'%s'\n" (point) vec (following-char) keywd))))
6341f357
DN
7726 (cond
7727 ((looking-at "//")
7728 (if (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
7729 (setq enum (match-string 1)))
7730 (search-forward "\n"))
7731 ((looking-at "/\\*")
7732 (forward-char 2)
a03c2342 7733 (if (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
6341f357
DN
7734 (setq enum (match-string 1)))
7735 (or (search-forward "*/")
7736 (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
7737 ((looking-at "(\\*")
9489a450
MM
7738 ;; To advance past either "(*)" or "(* ... *)" don't forward past first *
7739 (forward-char 1)
7740 (or (search-forward "*)")
6341f357
DN
7741 (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
7742 ((eq ?\" (following-char))
7743 (or (re-search-forward "[^\\]\"" nil t) ;; don't forward-char first, since we look for a non backslash first
7744 (error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
7745 ((eq ?\; (following-char))
a3a8b002 7746 (setq vec nil io nil expect-signal nil newsig nil paren 0 rvalue nil
9489a450 7747 v2kargs-ok nil in-modport nil ign-prop nil)
6341f357
DN
7748 (forward-char 1))
7749 ((eq ?= (following-char))
7750 (setq rvalue t newsig nil)
7751 (forward-char 1))
14862301
SM
7752 ((and (eq ?, (following-char))
7753 (eq paren sig-paren))
7754 (setq rvalue nil)
7755 (forward-char 1))
7756 ;; ,'s can occur inside {} & funcs
7757 ((looking-at "[{(]")
7758 (setq paren (1+ paren))
7759 (forward-char 1))
7760 ((looking-at "[})]")
7761 (setq paren (1- paren))
7762 (forward-char 1)
7763 (when (< paren sig-paren)
7764 (setq expect-signal nil))) ; ) that ends variables inside v2k arg list
6341f357
DN
7765 ((looking-at "\\s-*\\(\\[[^]]+\\]\\)")
7766 (goto-char (match-end 0))
7767 (cond (newsig ; Memory, not just width. Patch last signal added's memory (nth 3)
8468f78b
WS
7768 (setcar (cdr (cdr (cdr newsig)))
7769 (if (verilog-sig-memory newsig)
7770 (concat (verilog-sig-memory newsig) (match-string 1))
7771 (match-string 1))))
6341f357
DN
7772 (vec ;; Multidimensional
7773 (setq multidim (cons vec multidim))
7774 (setq vec (verilog-string-replace-matches
7775 "\\s-+" "" nil nil (match-string 1))))
7776 (t ;; Bit width
7777 (setq vec (verilog-string-replace-matches
7778 "\\s-+" "" nil nil (match-string 1))))))
7779 ;; Normal or escaped identifier -- note we remember the \ if escaped
7780 ((looking-at "\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
7781 (goto-char (match-end 0))
7782 (setq keywd (match-string 1))
86a4c7ac 7783 (when (string-match "^\\\\" (match-string 1))
6341f357 7784 (setq keywd (concat keywd " "))) ;; Escaped ID needs space at end
86a4c7ac
DN
7785 ;; Add any :: package names to same identifier
7786 (while (looking-at "\\s-*::\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
7787 (goto-char (match-end 0))
7788 (setq keywd (concat keywd "::" (match-string 1)))
7789 (when (string-match "^\\\\" (match-string 1))
7790 (setq keywd (concat keywd " ")))) ;; Escaped ID needs space at end
6341f357
DN
7791 (cond ((equal keywd "input")
7792 (setq vec nil enum nil rvalue nil newsig nil signed nil typedefed nil multidim nil sig-paren paren
a3a8b002 7793 expect-signal 'sigs-in io t modport nil))
6341f357
DN
7794 ((equal keywd "output")
7795 (setq vec nil enum nil rvalue nil newsig nil signed nil typedefed nil multidim nil sig-paren paren
a3a8b002 7796 expect-signal 'sigs-out io t modport nil))
6341f357
DN
7797 ((equal keywd "inout")
7798 (setq vec nil enum nil rvalue nil newsig nil signed nil typedefed nil multidim nil sig-paren paren
a3a8b002
DN
7799 expect-signal 'sigs-inout io t modport nil))
7800 ((equal keywd "parameter")
7801 (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
7802 expect-signal 'sigs-gparam io t modport nil))
9489a450
MM
7803 ((member keywd '("wire"
7804 "tri" "tri0" "tri1" "triand" "trior" "wand" "wor"
7805 "reg" "trireg"
a3a8b002 7806 "byte" "shortint" "int" "longint" "integer" "time"
a03c2342
WS
7807 "bit" "logic"
7808 "shortreal" "real" "realtime"
7809 "string" "event" "chandle"))
6341f357 7810 (unless io (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
9489a450 7811 expect-signal 'sigs-var modport nil)))
6341f357
DN
7812 ((equal keywd "assign")
7813 (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
a3a8b002
DN
7814 expect-signal 'sigs-assign modport nil))
7815 ((member keywd '("supply0" "supply1" "supply"
7816 "localparam" "genvar"))
6341f357 7817 (unless io (setq vec nil enum nil rvalue nil signed nil typedefed nil multidim nil sig-paren paren
a3a8b002 7818 expect-signal 'sigs-const modport nil)))
9489a450
MM
7819 ((member keywd '("signed" "unsigned"))
7820 (setq signed keywd))
7821 ((member keywd '("assert" "assume" "cover" "expect" "restrict"))
7822 (setq ign-prop t))
a3a8b002
DN
7823 ((member keywd '("class" "clocking" "covergroup" "function"
7824 "property" "randsequence" "sequence" "task"))
9489a450
MM
7825 (unless ign-prop
7826 (setq functask (1+ functask))))
a3a8b002
DN
7827 ((member keywd '("endclass" "endclocking" "endgroup" "endfunction"
7828 "endproperty" "endsequence" "endtask"))
6341f357 7829 (setq functask (1- functask)))
a03c2342
WS
7830 ((equal keywd "modport")
7831 (setq in-modport t))
a3a8b002 7832 ;; Ifdef? Ignore name of define
a03c2342 7833 ((member keywd '("`ifdef" "`ifndef" "`elsif"))
6341f357 7834 (setq rvalue t))
a3a8b002 7835 ;; Type?
6341f357
DN
7836 ((verilog-typedef-name-p keywd)
7837 (setq typedefed keywd))
a3a8b002
DN
7838 ;; Interface with optional modport in v2k arglist?
7839 ;; Skip over parsing modport, and take the interface name as the type
7840 ((and v2kargs-ok
7841 (eq paren 1)
a03c2342
WS
7842 (not rvalue)
7843 (looking-at "\\s-*\\(\\.\\(\\s-*[a-zA-Z`_$][a-zA-Z0-9`_$]*\\)\\|\\)\\s-*[a-zA-Z`_$][a-zA-Z0-9`_$]*"))
a3a8b002
DN
7844 (when (match-end 2) (goto-char (match-end 2)))
7845 (setq vec nil enum nil rvalue nil newsig nil signed nil typedefed keywd multidim nil sig-paren paren
7846 expect-signal 'sigs-intf io t modport (match-string 2)))
a03c2342
WS
7847 ;; Ignore dotted LHS assignments: "assign foo.bar = z;"
7848 ((looking-at "\\s-*\\.")
7849 (goto-char (match-end 0))
7850 (when (not rvalue)
7851 (setq expect-signal nil)))
a3a8b002 7852 ;; New signal, maybe?
6341f357 7853 ((and expect-signal
6341f357 7854 (not rvalue)
a03c2342
WS
7855 (eq functask 0)
7856 (not in-modport)
6341f357
DN
7857 (not (member keywd verilog-keywords)))
7858 ;; Add new signal to expect-signal's variable
a03c2342 7859 (setq newsig (verilog-sig-new keywd vec nil nil enum signed typedefed multidim modport))
6341f357
DN
7860 (set expect-signal (cons newsig
7861 (symbol-value expect-signal))))))
7862 (t
7863 (forward-char 1)))
7864 (skip-syntax-forward " "))
7865 ;; Return arguments
a03c2342
WS
7866 (verilog-decls-new (nreverse sigs-out)
7867 (nreverse sigs-inout)
7868 (nreverse sigs-in)
9489a450
MM
7869 (nreverse sigs-var)
7870 nil
a03c2342
WS
7871 (nreverse sigs-assign)
7872 (nreverse sigs-const)
7873 (nreverse sigs-gparam)
7874 (nreverse sigs-intf)))))
7875
7876(defvar verilog-read-sub-decls-in-interfaced nil
7877 "For `verilog-read-sub-decls', process next signal as under interfaced block.")
7878
7879(defvar verilog-read-sub-decls-gate-ios nil
7880 "For `verilog-read-sub-decls', gate IO pins remaining, nil if non-primitive.")
6341f357 7881
60618039
DN
7882(eval-when-compile
7883 ;; Prevent compile warnings; these are let's, not globals
7884 ;; Do not remove the eval-when-compile
7885 ;; - we want a error when we are debugging this code if they are refed.
7886 (defvar sigs-in)
7887 (defvar sigs-inout)
a3a8b002 7888 (defvar sigs-out)
a03c2342
WS
7889 (defvar sigs-intf)
7890 (defvar sigs-intfd))
5509c6ad
DN
7891
7892(defun verilog-read-sub-decls-sig (submoddecls comment port sig vec multidim)
37ea4b9b 7893 "For `verilog-read-sub-decls-line', add a signal."
a03c2342
WS
7894 ;; sig eq t to indicate .name syntax
7895 ;;(message "vrsds: %s(%S)" port sig)
7896 (let ((dotname (eq sig t))
7897 portdata)
6341f357
DN
7898 (when sig
7899 (setq port (verilog-symbol-detick-denumber port))
a03c2342 7900 (setq sig (if dotname port (verilog-symbol-detick-denumber sig)))
6341f357
DN
7901 (if vec (setq vec (verilog-symbol-detick-denumber vec)))
7902 (if multidim (setq multidim (mapcar `verilog-symbol-detick-denumber multidim)))
7903 (unless (or (not sig)
7904 (equal sig "")) ;; Ignore .foo(1'b1) assignments
a03c2342
WS
7905 (cond ((or (setq portdata (assoc port (verilog-decls-get-inouts submoddecls)))
7906 (equal "inout" verilog-read-sub-decls-gate-ios))
7907 (setq sigs-inout
7908 (cons (verilog-sig-new
7909 sig
7910 (if dotname (verilog-sig-bits portdata) vec)
8468f78b
WS
7911 (concat "To/From " comment)
7912 (verilog-sig-memory portdata)
7913 nil
a03c2342
WS
7914 (verilog-sig-signed portdata)
7915 (verilog-sig-type portdata)
7916 multidim nil)
7917 sigs-inout)))
7918 ((or (setq portdata (assoc port (verilog-decls-get-outputs submoddecls)))
7919 (equal "output" verilog-read-sub-decls-gate-ios))
7920 (setq sigs-out
7921 (cons (verilog-sig-new
7922 sig
7923 (if dotname (verilog-sig-bits portdata) vec)
8468f78b
WS
7924 (concat "From " comment)
7925 (verilog-sig-memory portdata)
7926 nil
a03c2342
WS
7927 (verilog-sig-signed portdata)
7928 (verilog-sig-type portdata)
7929 multidim nil)
7930 sigs-out)))
7931 ((or (setq portdata (assoc port (verilog-decls-get-inputs submoddecls)))
7932 (equal "input" verilog-read-sub-decls-gate-ios))
7933 (setq sigs-in
7934 (cons (verilog-sig-new
7935 sig
7936 (if dotname (verilog-sig-bits portdata) vec)
8468f78b
WS
7937 (concat "To " comment)
7938 (verilog-sig-memory portdata)
7939 nil
a03c2342
WS
7940 (verilog-sig-signed portdata)
7941 (verilog-sig-type portdata)
7942 multidim nil)
7943 sigs-in)))
a3a8b002 7944 ((setq portdata (assoc port (verilog-decls-get-interfaces submoddecls)))
a03c2342
WS
7945 (setq sigs-intf
7946 (cons (verilog-sig-new
7947 sig
7948 (if dotname (verilog-sig-bits portdata) vec)
8468f78b
WS
7949 (concat "To/From " comment)
7950 (verilog-sig-memory portdata)
7951 nil
a03c2342
WS
7952 (verilog-sig-signed portdata)
7953 (verilog-sig-type portdata)
7954 multidim nil)
7955 sigs-intf)))
7956 ((setq portdata (and verilog-read-sub-decls-in-interfaced
9489a450 7957 (assoc port (verilog-decls-get-vars submoddecls))))
a03c2342
WS
7958 (setq sigs-intfd
7959 (cons (verilog-sig-new
7960 sig
7961 (if dotname (verilog-sig-bits portdata) vec)
8468f78b
WS
7962 (concat "To/From " comment)
7963 (verilog-sig-memory portdata)
7964 nil
a03c2342
WS
7965 (verilog-sig-signed portdata)
7966 (verilog-sig-type portdata)
7967 multidim nil)
7968 sigs-intf)))
6341f357
DN
7969 ;; (t -- warning pin isn't defined.) ; Leave for lint tool
7970 )))))
7971
a3a8b002
DN
7972(defun verilog-read-sub-decls-expr (submoddecls comment port expr)
7973 "For `verilog-read-sub-decls-line', parse a subexpression and add signals."
7974 ;;(message "vrsde: '%s'" expr)
7975 ;; Replace special /*[....]*/ comments inserted by verilog-auto-inst-port
7976 (setq expr (verilog-string-replace-matches "/\\*\\(\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
7977 ;; Remove front operators
7978 (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
7979 ;;
7980 (cond
7981 ;; {..., a, b} requires us to recurse on a,b
a03c2342
WS
7982 ;; To support {#{},{#{a,b}} we'll just split everything on [{},]
7983 ((string-match "^\\s-*{\\(.*\\)}\\s-*$" expr)
14862301 7984 (unless verilog-auto-ignore-concat
a03c2342 7985 (let ((mlst (split-string (match-string 1 expr) "[{},]"))
14862301
SM
7986 mstr)
7987 (while (setq mstr (pop mlst))
7988 (verilog-read-sub-decls-expr submoddecls comment port mstr)))))
a3a8b002
DN
7989 (t
7990 (let (sig vec multidim)
a03c2342
WS
7991 ;; Remove leading reduction operators, etc
7992 (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
7993 ;;(message "vrsde-ptop: '%s'" expr)
a3a8b002
DN
7994 (cond ;; Find \signal. Final space is part of escaped signal name
7995 ((string-match "^\\s-*\\(\\\\[^ \t\n\f]+\\s-\\)" expr)
7996 ;;(message "vrsde-s: '%s'" (match-string 1 expr))
7997 (setq sig (match-string 1 expr)
7998 expr (substring expr (match-end 0))))
7999 ;; Find signal
a03c2342 8000 ((string-match "^\\s-*\\([a-zA-Z_][a-zA-Z_0-9]*\\)" expr)
a3a8b002
DN
8001 ;;(message "vrsde-s: '%s'" (match-string 1 expr))
8002 (setq sig (verilog-string-remove-spaces (match-string 1 expr))
8003 expr (substring expr (match-end 0)))))
8004 ;; Find [vector] or [multi][multi][multi][vector]
8005 (while (string-match "^\\s-*\\(\\[[^]]+\\]\\)" expr)
8006 ;;(message "vrsde-v: '%s'" (match-string 1 expr))
8007 (when vec (setq multidim (cons vec multidim)))
8008 (setq vec (match-string 1 expr)
8009 expr (substring expr (match-end 0))))
8010 ;; If found signal, and nothing unrecognized, add the signal
8011 ;;(message "vrsde-rem: '%s'" expr)
8012 (when (and sig (string-match "^\\s-*$" expr))
8013 (verilog-read-sub-decls-sig submoddecls comment port sig vec multidim))))))
8014
5509c6ad 8015(defun verilog-read-sub-decls-line (submoddecls comment)
a03c2342
WS
8016 "For `verilog-read-sub-decls', read lines of port defs until none match.
8017Inserts the list of signals found, using submodi to look up each port."
a3a8b002 8018 (let (done port)
6341f357
DN
8019 (save-excursion
8020 (forward-line 1)
8021 (while (not done)
8022 ;; Get port name
8023 (cond ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*(\\s-*")
8024 (setq port (match-string 1))
8025 (goto-char (match-end 0)))
a03c2342 8026 ;; .\escaped (
6341f357
DN
8027 ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*(\\s-*")
8028 (setq port (concat (match-string 1) " ")) ;; escaped id's need trailing space
8029 (goto-char (match-end 0)))
a03c2342
WS
8030 ;; .name
8031 ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*[,)/]")
8032 (verilog-read-sub-decls-sig
8033 submoddecls comment (match-string 1) t ; sig==t for .name
8034 nil nil) ; vec multidim
8035 (setq port nil))
8036 ;; .\escaped_name
8037 ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*[,)/]")
8038 (verilog-read-sub-decls-sig
8039 submoddecls comment (concat (match-string 1) " ") t ; sig==t for .name
8040 nil nil) ; vec multidim
8041 (setq port nil))
8042 ;; random
6341f357
DN
8043 ((looking-at "\\s-*\\.[^(]*(")
8044 (setq port nil) ;; skip this line
8045 (goto-char (match-end 0)))
8046 (t
8047 (setq port nil done t))) ;; Unknown, ignore rest of line
a3a8b002
DN
8048 ;; Get signal name. Point is at the first-non-space after (
8049 ;; We intentionally ignore (non-escaped) signals with .s in them
8050 ;; this prevents AUTOWIRE etc from noticing hierarchical sigs.
6341f357 8051 (when port
a03c2342 8052 (cond ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*)")
a3a8b002
DN
8053 (verilog-read-sub-decls-sig
8054 submoddecls comment port
8055 (verilog-string-remove-spaces (match-string 1)) ; sig
8056 nil nil)) ; vec multidim
8057 ;;
a03c2342 8058 ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*)")
a3a8b002
DN
8059 (verilog-read-sub-decls-sig
8060 submoddecls comment port
8061 (verilog-string-remove-spaces (match-string 1)) ; sig
8062 (match-string 2) nil)) ; vec multidim
8063 ;; Fastpath was above looking-at's.
8064 ;; For something more complicated invoke a parser
8065 ((looking-at "[^)]+")
8066 (verilog-read-sub-decls-expr
8067 submoddecls comment port
8068 (buffer-substring
fd9ea9d3 8069 (point) (1- (progn (search-backward "(") ; start at (
9489a450
MM
8070 (verilog-forward-sexp-ign-cmt 1)
8071 (point)))))))) ; expr
6341f357
DN
8072 ;;
8073 (forward-line 1)))))
8074
a03c2342
WS
8075(defun verilog-read-sub-decls-gate (submoddecls comment submod end-inst-point)
8076 "For `verilog-read-sub-decls', read lines of UDP gate decl until none match.
8077Inserts the list of signals found."
8078 (save-excursion
8079 (let ((iolist (cdr (assoc submod verilog-gate-ios))))
8080 (while (< (point) end-inst-point)
8081 ;; Get primitive's signal name, as will never have port, and no trailing )
8082 (cond ((looking-at "//")
8083 (search-forward "\n"))
8084 ((looking-at "/\\*")
8085 (or (search-forward "*/")
8086 (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
8087 ((looking-at "(\\*")
9489a450
MM
8088 ;; To advance past either "(*)" or "(* ... *)" don't forward past first *
8089 (forward-char 1)
8090 (or (search-forward "*)")
a03c2342
WS
8091 (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
8092 ;; On pins, parse and advance to next pin
8093 ;; Looking at pin, but *not* an // Output comment, or ) to end the inst
8094 ((looking-at "\\s-*[a-zA-Z0-9`_$({}\\\\][^,]*")
8095 (goto-char (match-end 0))
8096 (setq verilog-read-sub-decls-gate-ios (or (car iolist) "input")
8097 iolist (cdr iolist))
8098 (verilog-read-sub-decls-expr
8099 submoddecls comment "primitive_port"
8100 (match-string 0)))
8101 (t
8102 (forward-char 1)
8103 (skip-syntax-forward " ")))))))
8104
6341f357
DN
8105(defun verilog-read-sub-decls ()
8106 "Internally parse signals going to modules under this module.
8107Return a array of [ outputs inouts inputs ] signals for modules that are
8108instantiated in this module. For example if declare A A (.B(SIG)) and SIG
8109is a output, then SIG will be included in the list.
8110
8111This only works on instantiations created with /*AUTOINST*/ converted by
8112\\[verilog-auto-inst]. Otherwise, it would have to read in the whole
8113component library to determine connectivity of the design.
8114
8115One work around for this problem is to manually create // Inputs and //
8116Outputs comments above subcell signals, for example:
8117
1dd4b004 8118 module ModuleName (
6341f357
DN
8119 // Outputs
8120 .out (out),
8121 // Inputs
8122 .in (in));"
8123 (save-excursion
8124 (let ((end-mod-point (verilog-get-end-of-defun t))
8125 st-point end-inst-point
8126 ;; below 3 modified by verilog-read-sub-decls-line
a03c2342 8127 sigs-out sigs-inout sigs-in sigs-intf sigs-intfd)
9489a450
MM
8128 (verilog-beg-of-defun-quick)
8129 (while (verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-mod-point t)
6341f357
DN
8130 (save-excursion
8131 (goto-char (match-beginning 0))
9489a450 8132 (unless (verilog-inside-comment-or-string-p)
6341f357
DN
8133 ;; Attempt to snarf a comment
8134 (let* ((submod (verilog-read-inst-module))
8135 (inst (verilog-read-inst-name))
a03c2342 8136 (subprim (member submod verilog-gate-keywords))
5509c6ad
DN
8137 (comment (concat inst " of " submod ".v"))
8138 submodi submoddecls)
a03c2342
WS
8139 (cond
8140 (subprim
8141 (setq submodi `primitive
8142 submoddecls (verilog-decls-new nil nil nil nil nil nil nil nil nil)
8143 comment (concat inst " of " submod))
6341f357 8144 (verilog-backward-open-paren)
9489a450
MM
8145 (setq end-inst-point (save-excursion (verilog-forward-sexp-ign-cmt 1)
8146 (point))
6341f357 8147 st-point (point))
a03c2342
WS
8148 (forward-char 1)
8149 (verilog-read-sub-decls-gate submoddecls comment submod end-inst-point))
8150 ;; Non-primitive
8151 (t
8152 (when (setq submodi (verilog-modi-lookup submod t))
8153 (setq submoddecls (verilog-modi-get-decls submodi)
8154 verilog-read-sub-decls-gate-ios nil)
8155 (verilog-backward-open-paren)
9489a450
MM
8156 (setq end-inst-point (save-excursion (verilog-forward-sexp-ign-cmt 1)
8157 (point))
a03c2342
WS
8158 st-point (point))
8159 ;; This could have used a list created by verilog-auto-inst
8160 ;; However I want it to be runnable even on user's manually added signals
8161 (let ((verilog-read-sub-decls-in-interfaced t))
8162 (while (re-search-forward "\\s *(?\\s *// Interfaced" end-inst-point t)
8163 (verilog-read-sub-decls-line submoddecls comment))) ;; Modifies sigs-ifd
8164 (goto-char st-point)
8165 (while (re-search-forward "\\s *(?\\s *// Interfaces" end-inst-point t)
8166 (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-out
8167 (goto-char st-point)
8168 (while (re-search-forward "\\s *(?\\s *// Outputs" end-inst-point t)
8169 (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-out
8170 (goto-char st-point)
8171 (while (re-search-forward "\\s *(?\\s *// Inouts" end-inst-point t)
8172 (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-inout
8173 (goto-char st-point)
8174 (while (re-search-forward "\\s *(?\\s *// Inputs" end-inst-point t)
8175 (verilog-read-sub-decls-line submoddecls comment)) ;; Modifies sigs-in
8176 )))))))
6341f357
DN
8177 ;; Combine duplicate bits
8178 ;;(setq rr (vector sigs-out sigs-inout sigs-in))
a03c2342
WS
8179 (verilog-subdecls-new
8180 (verilog-signals-combine-bus (nreverse sigs-out))
8181 (verilog-signals-combine-bus (nreverse sigs-inout))
8182 (verilog-signals-combine-bus (nreverse sigs-in))
8183 (verilog-signals-combine-bus (nreverse sigs-intf))
8184 (verilog-signals-combine-bus (nreverse sigs-intfd))))))
6341f357
DN
8185
8186(defun verilog-read-inst-pins ()
37ea4b9b 8187 "Return an array of [ pins ] for the current instantiation at point.
6341f357
DN
8188For example if declare A A (.B(SIG)) then B will be included in the list."
8189 (save-excursion
8190 (let ((end-mod-point (point)) ;; presume at /*AUTOINST*/ point
8191 pins pin)
8192 (verilog-backward-open-paren)
8193 (while (re-search-forward "\\.\\([^(,) \t\n\f]*\\)\\s-*" end-mod-point t)
8194 (setq pin (match-string 1))
9489a450 8195 (unless (verilog-inside-comment-or-string-p)
6341f357
DN
8196 (setq pins (cons (list pin) pins))
8197 (when (looking-at "(")
9489a450 8198 (verilog-forward-sexp-ign-cmt 1))))
6341f357
DN
8199 (vector pins))))
8200
8201(defun verilog-read-arg-pins ()
37ea4b9b 8202 "Return an array of [ pins ] for the current argument declaration at point."
6341f357
DN
8203 (save-excursion
8204 (let ((end-mod-point (point)) ;; presume at /*AUTOARG*/ point
8205 pins pin)
8206 (verilog-backward-open-paren)
8207 (while (re-search-forward "\\([a-zA-Z0-9$_.%`]+\\)" end-mod-point t)
8208 (setq pin (match-string 1))
9489a450 8209 (unless (verilog-inside-comment-or-string-p)
6341f357
DN
8210 (setq pins (cons (list pin) pins))))
8211 (vector pins))))
8212
8213(defun verilog-read-auto-constants (beg end-mod-point)
8214 "Return a list of AUTO_CONSTANTs used in the region from BEG to END-MOD-POINT."
8215 ;; Insert new
8216 (save-excursion
8217 (let (sig-list tpl-end-pt)
8218 (goto-char beg)
8219 (while (re-search-forward "\\<AUTO_CONSTANT" end-mod-point t)
8220 (if (not (looking-at "\\s *("))
8221 (error "%s: Missing () after AUTO_CONSTANT" (verilog-point-text)))
8222 (search-forward "(" end-mod-point)
8223 (setq tpl-end-pt (save-excursion
8224 (backward-char 1)
9489a450 8225 (verilog-forward-sexp-cmt 1) ;; Moves to paren that closes argdecl's
6341f357
DN
8226 (backward-char 1)
8227 (point)))
8228 (while (re-search-forward "\\s-*\\([\"a-zA-Z0-9$_.%`]+\\)\\s-*,*" tpl-end-pt t)
8229 (setq sig-list (cons (list (match-string 1) nil nil) sig-list))))
8230 sig-list)))
8231
a03c2342
WS
8232(defvar verilog-cache-has-lisp nil "True if any AUTO_LISP in buffer.")
8233(make-variable-buffer-local 'verilog-cache-has-lisp)
8234
8235(defun verilog-read-auto-lisp-present ()
8236 "Set `verilog-cache-has-lisp' if any AUTO_LISP in this buffer."
6341f357 8237 (save-excursion
9489a450 8238 (goto-char (point-min))
a03c2342
WS
8239 (setq verilog-cache-has-lisp (re-search-forward "\\<AUTO_LISP(" nil t))))
8240
8241(defun verilog-read-auto-lisp (start end)
8242 "Look for and evaluate a AUTO_LISP between START and END.
8243Must call `verilog-read-auto-lisp-present' before this function."
8244 ;; This function is expensive for large buffers, so we cache if any AUTO_LISP exists
8245 (when verilog-cache-has-lisp
8246 (save-excursion
8247 (goto-char start)
8248 (while (re-search-forward "\\<AUTO_LISP(" end t)
8249 (backward-char)
8250 (let* ((beg-pt (prog1 (point)
9489a450 8251 (verilog-forward-sexp-cmt 1))) ;; Closing paren
a03c2342
WS
8252 (end-pt (point)))
8253 (eval-region beg-pt end-pt nil))))))
6341f357 8254
60618039
DN
8255(eval-when-compile
8256 ;; Prevent compile warnings; these are let's, not globals
8257 ;; Do not remove the eval-when-compile
8258 ;; - we want a error when we are debugging this code if they are refed.
8259 (defvar sigs-in)
9489a450
MM
8260 (defvar sigs-out-d)
8261 (defvar sigs-out-i)
8262 (defvar sigs-out-unk)
a03c2342 8263 (defvar sigs-temp)
60618039 8264 (defvar vector-skip-list))
6341f357
DN
8265
8266(defun verilog-read-always-signals-recurse
a03c2342 8267 (exit-keywd rvalue temp-next)
6341f357
DN
8268 "Recursive routine for parentheses/bracket matching.
8269EXIT-KEYWD is expression to stop at, nil if top level.
8270RVALUE is true if at right hand side of equal.
8271IGNORE-NEXT is true to ignore next token, fake from inside case statement."
8272 (let* ((semi-rvalue (equal "endcase" exit-keywd)) ;; true if after a ; we are looking for rvalue
a03c2342
WS
8273 keywd last-keywd sig-tolk sig-last-tolk gotend got-sig got-list end-else-check
8274 ignore-next)
8275 ;;(if dbg (setq dbg (concat dbg (format "Recursion %S %S %S\n" exit-keywd rvalue temp-next))))
6341f357
DN
8276 (while (not (or (eobp) gotend))
8277 (cond
8278 ((looking-at "//")
8279 (search-forward "\n"))
8280 ((looking-at "/\\*")
8281 (or (search-forward "*/")
8282 (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
8283 ((looking-at "(\\*")
9489a450
MM
8284 ;; To advance past either "(*)" or "(* ... *)" don't forward past first *
8285 (forward-char 1)
8286 (or (search-forward "*)")
6341f357
DN
8287 (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
8288 (t (setq keywd (buffer-substring-no-properties
8289 (point)
8290 (save-excursion (when (eq 0 (skip-chars-forward "a-zA-Z0-9$_.%`"))
8291 (forward-char 1))
8292 (point)))
8293 sig-last-tolk sig-tolk
8294 sig-tolk nil)
14862301 8295 ;;(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))))
6341f357
DN
8296 (cond
8297 ((equal keywd "\"")
8298 (or (re-search-forward "[^\\]\"" nil t)
8299 (error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
8300 ;; else at top level loop, keep parsing
8301 ((and end-else-check (equal keywd "else"))
8302 ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else %s\n" keywd))))
8303 ;; no forward movement, want to see else in lower loop
8304 (setq end-else-check nil))
8305 ;; End at top level loop
8306 ((and end-else-check (looking-at "[^ \t\n\f]"))
8307 ;;(if dbg (setq dbg (concat dbg (format "\tif-check-else-other %s\n" keywd))))
8308 (setq gotend t))
8309 ;; Final statement?
8310 ((and exit-keywd (equal keywd exit-keywd))
8311 (setq gotend t)
8312 (forward-char (length keywd)))
8313 ;; Standard tokens...
8314 ((equal keywd ";")
8315 (setq ignore-next nil rvalue semi-rvalue)
8316 ;; Final statement at top level loop?
8317 (when (not exit-keywd)
8318 ;;(if dbg (setq dbg (concat dbg (format "\ttop-end-check %s\n" keywd))))
8319 (setq end-else-check t))
8320 (forward-char 1))
8321 ((equal keywd "'")
14862301 8322 (if (looking-at "'[sS]?[hdxboHDXBO]?[ \t]*[0-9a-fA-F_xzXZ?]+")
6341f357
DN
8323 (goto-char (match-end 0))
8324 (forward-char 1)))
8325 ((equal keywd ":") ;; Case statement, begin/end label, x?y:z
8326 (cond ((equal "endcase" exit-keywd) ;; case x: y=z; statement next
8327 (setq ignore-next nil rvalue nil))
8328 ((equal "?" exit-keywd) ;; x?y:z rvalue
8329 ) ;; NOP
a3a8b002
DN
8330 ((equal "]" exit-keywd) ;; [x:y] rvalue
8331 ) ;; NOP
6341f357
DN
8332 (got-sig ;; label: statement
8333 (setq ignore-next nil rvalue semi-rvalue got-sig nil))
8334 ((not rvalue) ;; begin label
8335 (setq ignore-next t rvalue nil)))
8336 (forward-char 1))
8337 ((equal keywd "=")
9489a450
MM
8338 (when got-sig
8339 ;;(if dbg (setq dbg (concat dbg (format "\t\tequal got-sig=%S got-list=%s\n" got-sig got-list))))
8340 (set got-list (cons got-sig (symbol-value got-list)))
8341 (setq got-sig nil))
8342 (when (not rvalue)
8343 (if (eq (char-before) ?< )
8344 (setq sigs-out-d (append sigs-out-d sigs-out-unk)
8345 sigs-out-unk nil)
8346 (setq sigs-out-i (append sigs-out-i sigs-out-unk)
8347 sigs-out-unk nil)))
6341f357
DN
8348 (setq ignore-next nil rvalue t)
8349 (forward-char 1))
8350 ((equal keywd "?")
8351 (forward-char 1)
8352 (verilog-read-always-signals-recurse ":" rvalue nil))
8353 ((equal keywd "[")
8354 (forward-char 1)
8355 (verilog-read-always-signals-recurse "]" t nil))
8356 ((equal keywd "(")
8357 (forward-char 1)
8358 (cond (sig-last-tolk ;; Function call; zap last signal
8359 (setq got-sig nil)))
8360 (cond ((equal last-keywd "for")
a03c2342
WS
8361 ;; temp-next: Variables on LHS are lvalues, but generally we want
8362 ;; to ignore them, assuming they are loop increments
8363 (verilog-read-always-signals-recurse ";" nil t)
6341f357
DN
8364 (verilog-read-always-signals-recurse ";" t nil)
8365 (verilog-read-always-signals-recurse ")" nil nil))
8366 (t (verilog-read-always-signals-recurse ")" t nil))))
8367 ((equal keywd "begin")
8368 (skip-syntax-forward "w_")
8369 (verilog-read-always-signals-recurse "end" nil nil)
8370 ;;(if dbg (setq dbg (concat dbg (format "\tgot-end %s\n" exit-keywd))))
8371 (setq ignore-next nil rvalue semi-rvalue)
8372 (if (not exit-keywd) (setq end-else-check t)))
a03c2342 8373 ((member keywd '("case" "casex" "casez"))
6341f357
DN
8374 (skip-syntax-forward "w_")
8375 (verilog-read-always-signals-recurse "endcase" t nil)
8376 (setq ignore-next nil rvalue semi-rvalue)
8377 (if (not exit-keywd) (setq gotend t))) ;; top level begin/end
8378 ((string-match "^[$`a-zA-Z_]" keywd) ;; not exactly word constituent
a03c2342 8379 (cond ((member keywd '("`ifdef" "`ifndef" "`elsif"))
6341f357
DN
8380 (setq ignore-next t))
8381 ((or ignore-next
8382 (member keywd verilog-keywords)
8383 (string-match "^\\$" keywd)) ;; PLI task
8384 (setq ignore-next nil))
8385 (t
8386 (setq keywd (verilog-symbol-detick-denumber keywd))
8387 (when got-sig
a03c2342
WS
8388 (set got-list (cons got-sig (symbol-value got-list)))
8389 ;;(if dbg (setq dbg (concat dbg (format "\t\tgot-sig=%S got-list=%S\n" got-sig got-list))))
6341f357 8390 )
a03c2342
WS
8391 (setq got-list (cond (temp-next 'sigs-temp)
8392 (rvalue 'sigs-in)
9489a450 8393 (t 'sigs-out-unk))
6341f357 8394 got-sig (if (or (not keywd)
a03c2342 8395 (assoc keywd (symbol-value got-list)))
6341f357 8396 nil (list keywd nil nil))
a03c2342 8397 temp-next nil
6341f357
DN
8398 sig-tolk t)))
8399 (skip-chars-forward "a-zA-Z0-9$_.%`"))
8400 (t
8401 (forward-char 1)))
8402 ;; End of non-comment token
60618039 8403 (setq last-keywd keywd)))
6341f357
DN
8404 (skip-syntax-forward " "))
8405 ;; Append the final pending signal
8406 (when got-sig
a03c2342
WS
8407 ;;(if dbg (setq dbg (concat dbg (format "\t\tfinal got-sig=%S got-list=%s\n" got-sig got-list))))
8408 (set got-list (cons got-sig (symbol-value got-list)))
6341f357
DN
8409 (setq got-sig nil))
8410 ;;(if dbg (setq dbg (concat dbg (format "ENDRecursion %s\n" exit-keywd))))
8411 ))
8412
8413(defun verilog-read-always-signals ()
8414 "Parse always block at point and return list of (outputs inout inputs)."
6341f357
DN
8415 (save-excursion
8416 (let* (;;(dbg "")
9489a450 8417 sigs-out-d sigs-out-i sigs-out-unk sigs-temp sigs-in)
6341f357
DN
8418 (search-forward ")")
8419 (verilog-read-always-signals-recurse nil nil nil)
9489a450
MM
8420 (setq sigs-out-i (append sigs-out-i sigs-out-unk)
8421 sigs-out-unk nil)
14862301 8422 ;;(if dbg (with-current-buffer (get-buffer-create "*vl-dbg*")) (delete-region (point-min) (point-max)) (insert dbg) (setq dbg ""))
6341f357 8423 ;; Return what was found
9489a450 8424 (verilog-alw-new sigs-out-d sigs-out-i sigs-temp sigs-in))))
6341f357
DN
8425
8426(defun verilog-read-instants ()
8427 "Parse module at point and return list of ( ( file instance ) ... )."
9489a450 8428 (verilog-beg-of-defun-quick)
6341f357
DN
8429 (let* ((end-mod-point (verilog-get-end-of-defun t))
8430 (state nil)
8431 (instants-list nil))
8432 (save-excursion
8433 (while (< (point) end-mod-point)
8434 ;; Stay at level 0, no comments
8435 (while (progn
8436 (setq state (parse-partial-sexp (point) end-mod-point 0 t nil))
8437 (or (> (car state) 0) ; in parens
8438 (nth 5 state) ; comment
8439 ))
8440 (forward-line 1))
8441 (beginning-of-line)
8442 (if (looking-at "^\\s-*\\([a-zA-Z0-9`_$]+\\)\\s-+\\([a-zA-Z0-9`_$]+\\)\\s-*(")
8443 ;;(if (looking-at "^\\(.+\\)$")
8444 (let ((module (match-string 1))
8445 (instant (match-string 2)))
8446 (if (not (member module verilog-keywords))
8447 (setq instants-list (cons (list module instant) instants-list)))))
60618039 8448 (forward-line 1)))
6341f357
DN
8449 instants-list))
8450
8451
8452(defun verilog-read-auto-template (module)
8453 "Look for a auto_template for the instantiation of the given MODULE.
8454If found returns the signal name connections. Return REGEXP and
37ea4b9b 8455list of ( (signal_name connection_name)... )."
6341f357
DN
8456 (save-excursion
8457 ;; Find beginning
8458 (let ((tpl-regexp "\\([0-9]+\\)")
9489a450 8459 (lineno -1) ; -1 to offset for the AUTO_TEMPLATE's newline
6341f357 8460 (templateno 0)
a03c2342 8461 (pt (point))
6341f357 8462 tpl-sig-list tpl-wild-list tpl-end-pt rep)
a03c2342
WS
8463 ;; Note this search is expensive, as we hunt from mod-begin to point
8464 ;; for every instantiation. Likewise in verilog-read-auto-lisp.
8465 ;; So, we look first for an exact string rather than a slow regexp.
8466 ;; Someday we may keep a cache of every template, but this would also
8467 ;; need to record the relative position of each AUTOINST, as multiple
8468 ;; templates exist for each module, and we're inserting lines.
6341f357 8469 (cond ((or
a03c2342
WS
8470 (verilog-re-search-backward-substr
8471 "AUTO_TEMPLATE"
8472 (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)
8473 ;; Also try forward of this AUTOINST
8474 ;; This is for historical support; this isn't speced as working
8475 (progn
8476 (goto-char pt)
8477 (verilog-re-search-forward-substr
8478 "AUTO_TEMPLATE"
8479 (concat "^\\s-*/?\\*?\\s-*" module "\\s-+AUTO_TEMPLATE") nil t)))
6341f357
DN
8480 (goto-char (match-end 0))
8481 ;; Parse "REGEXP"
a03c2342
WS
8482 ;; We reserve @"..." for future lisp expressions that evaluate
8483 ;; once-per-AUTOINST
14862301 8484 (when (looking-at "\\s-*\"\\([^\"]*\\)\"")
6341f357
DN
8485 (setq tpl-regexp (match-string 1))
8486 (goto-char (match-end 0)))
8487 (search-forward "(")
8488 ;; Parse lines in the template
8489 (when verilog-auto-inst-template-numbers
8490 (save-excursion
9489a450
MM
8491 (let ((pre-pt (point)))
8492 (goto-char (point-min))
8493 (while (search-forward "AUTO_TEMPLATE" pre-pt t)
8494 (setq templateno (1+ templateno)))
8495 (while (< (point) pre-pt)
8496 (forward-line 1)
8497 (setq lineno (1+ lineno))))))
6341f357
DN
8498 (setq tpl-end-pt (save-excursion
8499 (backward-char 1)
9489a450 8500 (verilog-forward-sexp-cmt 1) ;; Moves to paren that closes argdecl's
6341f357
DN
8501 (backward-char 1)
8502 (point)))
8503 ;;
8504 (while (< (point) tpl-end-pt)
8505 (cond ((looking-at "\\s-*\\.\\([a-zA-Z0-9`_$]+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
9489a450
MM
8506 (setq tpl-sig-list
8507 (cons (list
8508 (match-string-no-properties 1)
8509 (match-string-no-properties 2)
8510 templateno lineno)
8511 tpl-sig-list))
6341f357
DN
8512 (goto-char (match-end 0)))
8513 ;; Regexp form??
8514 ((looking-at
d63b01e1 8515 ;; Regexp bug in XEmacs disallows ][ inside [], and wants + last
6341f357
DN
8516 "\\s-*\\.\\(\\([a-zA-Z0-9`_$+@^.*?|---]+\\|[][]\\|\\\\[()|]\\)+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
8517 (setq rep (match-string-no-properties 3))
8518 (goto-char (match-end 0))
8519 (setq tpl-wild-list
8520 (cons (list
8521 (concat "^"
8522 (verilog-string-replace-matches "@" "\\\\([0-9]+\\\\)" nil nil
8523 (match-string 1))
8524 "$")
8525 rep
8526 templateno lineno)
8527 tpl-wild-list)))
8528 ((looking-at "[ \t\f]+")
8529 (goto-char (match-end 0)))
8530 ((looking-at "\n")
8531 (setq lineno (1+ lineno))
8532 (goto-char (match-end 0)))
8533 ((looking-at "//")
9489a450
MM
8534 (search-forward "\n")
8535 (setq lineno (1+ lineno)))
6341f357
DN
8536 ((looking-at "/\\*")
8537 (forward-char 2)
8538 (or (search-forward "*/")
8539 (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
8540 (t
8541 (error "%s: AUTO_TEMPLATE parsing error: %s"
8542 (verilog-point-text)
60618039 8543 (progn (looking-at ".*$") (match-string 0))))))
6341f357
DN
8544 ;; Return
8545 (vector tpl-regexp
8546 (list tpl-sig-list tpl-wild-list)))
8547 ;; If no template found
8548 (t (vector tpl-regexp nil))))))
8549;;(progn (find-file "auto-template.v") (verilog-read-auto-template "ptl_entry"))
8550
8551(defun verilog-set-define (defname defvalue &optional buffer enumname)
8552 "Set the definition DEFNAME to the DEFVALUE in the given BUFFER.
8553Optionally associate it with the specified enumeration ENUMNAME."
9a529312 8554 (with-current-buffer (or buffer (current-buffer))
6341f357
DN
8555 (let ((mac (intern (concat "vh-" defname))))
8556 ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
8557 ;; Need to define to a constant if no value given
14862301 8558 (set (make-local-variable mac)
6341f357
DN
8559 (if (equal defvalue "") "1" defvalue)))
8560 (if enumname
8561 (let ((enumvar (intern (concat "venum-" enumname))))
8562 ;;(message "Define %s=%s" defname defvalue) (sleep-for 1)
a3a8b002 8563 (unless (boundp enumvar) (set enumvar nil))
175069ef 8564 (add-to-list (make-local-variable enumvar) defname)))))
6341f357
DN
8565
8566(defun verilog-read-defines (&optional filename recurse subcall)
8567 "Read `defines and parameters for the current file, or optional FILENAME.
8568If the filename is provided, `verilog-library-flags' will be used to
8569resolve it. If optional RECURSE is non-nil, recurse through `includes.
8570
8571Parameters must be simple assignments to constants, or have their own
8572\"parameter\" label rather than a list of parameters. Thus:
8573
8574 parameter X = 5, Y = 10; // Ok
8575 parameter X = {1'b1, 2'h2}; // Ok
8576 parameter X = {1'b1, 2'h2}, Y = 10; // Bad, make into 2 parameter lines
8577
8578Defines must be simple text substitutions, one on a line, starting
8579at the beginning of the line. Any ifdefs or multiline comments around the
8580define are ignored.
8581
8582Defines are stored inside Emacs variables using the name vh-{definename}.
8583
8584This function is useful for setting vh-* variables. The file variables
8585feature can be used to set defines that `verilog-mode' can see; put at the
8586*END* of your file something like:
8587
8588 // Local Variables:
8589 // vh-macro:\"macro_definition\"
8590 // End:
8591
8592If macros are defined earlier in the same file and you want their values,
8593you can read them automatically (provided `enable-local-eval' is on):
8594
8595 // Local Variables:
8596 // eval:(verilog-read-defines)
8597 // eval:(verilog-read-defines \"group_standard_includes.v\")
8598 // End:
8599
8600Note these are only read when the file is first visited, you must use
8601\\[find-alternate-file] RET to have these take effect after editing them!
8602
8603If you want to disable the \"Process `eval' or hook local variables\"
8604warning message, you need to add to your .emacs file:
8605
8606 (setq enable-local-eval t)"
8607 (let ((origbuf (current-buffer)))
8608 (save-excursion
8609 (unless subcall (verilog-getopt-flags))
8610 (when filename
8611 (let ((fns (verilog-library-filenames filename (buffer-file-name))))
8612 (if fns
8613 (set-buffer (find-file-noselect (car fns)))
8614 (error (concat (verilog-point-text)
8615 ": Can't find verilog-read-defines file: " filename)))))
8616 (when recurse
8617 (goto-char (point-min))
8618 (while (re-search-forward "^\\s-*`include\\s-+\\([^ \t\n\f]+\\)" nil t)
a03c2342
WS
8619 (let ((inc (verilog-string-replace-matches
8620 "\"" "" nil nil (match-string-no-properties 1))))
9489a450 8621 (unless (verilog-inside-comment-or-string-p)
6341f357
DN
8622 (verilog-read-defines inc recurse t)))))
8623 ;; Read `defines
8624 ;; note we don't use verilog-re... it's faster this way, and that
8625 ;; function has problems when comments are at the end of the define
8626 (goto-char (point-min))
8627 (while (re-search-forward "^\\s-*`define\\s-+\\([a-zA-Z0-9_$]+\\)\\s-+\\(.*\\)$" nil t)
8628 (let ((defname (match-string-no-properties 1))
8629 (defvalue (match-string-no-properties 2)))
8630 (setq defvalue (verilog-string-replace-matches "\\s-*/[/*].*$" "" nil nil defvalue))
8631 (verilog-set-define defname defvalue origbuf)))
8632 ;; Hack: Read parameters
8633 (goto-char (point-min))
8634 (while (re-search-forward
9489a450 8635 "^\\s-*\\(parameter\\|localparam\\)\\(\\s-*\\[[^]]*\\]\\)?\\s-*" nil t)
a3a8b002 8636 (let (enumname)
6341f357
DN
8637 ;; The primary way of getting defines is verilog-read-decls
8638 ;; However, that isn't called yet for included files, so we'll add another scheme
8639 (if (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
8640 (setq enumname (match-string-no-properties 1)))
6341f357 8641 (forward-comment 999)
9489a450
MM
8642 (while (looking-at (concat "\\s-*,?\\s-*\\(?:/[/*].*?$\\)?\\s-*\\([a-zA-Z0-9_$]+\\)"
8643 "\\s-*=\\s-*\\([^;,]*\\),?\\s-*\\(/[/*].*?$\\)?\\s-*"))
a03c2342
WS
8644 (verilog-set-define (match-string-no-properties 1)
8645 (match-string-no-properties 2) origbuf enumname)
6341f357 8646 (goto-char (match-end 0))
60618039 8647 (forward-comment 999)))))))
6341f357
DN
8648
8649(defun verilog-read-includes ()
8650 "Read `includes for the current file.
8651This will find all of the `includes which are at the beginning of lines,
8652ignoring any ifdefs or multiline comments around them.
8653`verilog-read-defines' is then performed on the current and each included
8654file.
8655
8656It is often useful put at the *END* of your file something like:
8657
8658 // Local Variables:
8659 // eval:(verilog-read-defines)
8660 // eval:(verilog-read-includes)
8661 // End:
8662
8663Note includes are only read when the file is first visited, you must use
8664\\[find-alternate-file] RET to have these take effect after editing them!
8665
8666It is good to get in the habit of including all needed files in each .v
8667file that needs it, rather than waiting for compile time. This will aid
8668this process, Verilint, and readability. To prevent defining the same
8669variable over and over when many modules are compiled together, put a test
8670around the inside each include file:
8671
8672foo.v (a include):
8673 `ifdef _FOO_V // include if not already included
8674 `else
8675 `define _FOO_V
8676 ... contents of file
8677 `endif // _FOO_V"
8678;;slow: (verilog-read-defines nil t))
8679 (save-excursion
8680 (verilog-getopt-flags)
8681 (goto-char (point-min))
8682 (while (re-search-forward "^\\s-*`include\\s-+\\([^ \t\n\f]+\\)" nil t)
8683 (let ((inc (verilog-string-replace-matches "\"" "" nil nil (match-string 1))))
8684 (verilog-read-defines inc nil t)))))
8685
8686(defun verilog-read-signals (&optional start end)
8687 "Return a simple list of all possible signals in the file.
8688Bounded by optional region from START to END. Overly aggressive but fast.
37ea4b9b 8689Some macros and such are also found and included. For dinotrace.el."
6341f357
DN
8690 (let (sigs-all keywd)
8691 (progn;save-excursion
8692 (goto-char (or start (point-min)))
8693 (setq end (or end (point-max)))
8694 (while (re-search-forward "[\"/a-zA-Z_.%`]" end t)
8695 (forward-char -1)
8696 (cond
8697 ((looking-at "//")
8698 (search-forward "\n"))
8699 ((looking-at "/\\*")
8700 (search-forward "*/"))
8701 ((looking-at "(\\*")
8702 (or (looking-at "(\\*\\s-*)") ; It's a "always @ (*)"
8703 (search-forward "*)")))
8704 ((eq ?\" (following-char))
8705 (re-search-forward "[^\\]\"")) ;; don't forward-char first, since we look for a non backslash first
8706 ((looking-at "\\s-*\\([a-zA-Z0-9$_.%`]+\\)")
8707 (goto-char (match-end 0))
8708 (setq keywd (match-string-no-properties 1))
8709 (or (member keywd verilog-keywords)
8710 (member keywd sigs-all)
8711 (setq sigs-all (cons keywd sigs-all))))
60618039 8712 (t (forward-char 1))))
6341f357
DN
8713 ;; Return list
8714 sigs-all)))
8715
8716;;
8717;; Argument file parsing
8718;;
8719
8720(defun verilog-getopt (arglist)
8721 "Parse -f, -v etc arguments in ARGLIST list or string."
8722 (unless (listp arglist) (setq arglist (list arglist)))
8723 (let ((space-args '())
8724 arg next-param)
8725 ;; Split on spaces, so users can pass whole command lines
8726 (while arglist
8727 (setq arg (car arglist)
8728 arglist (cdr arglist))
8729 (while (string-match "^\\([^ \t\n\f]+\\)[ \t\n\f]*\\(.*$\\)" arg)
8730 (setq space-args (append space-args
8731 (list (match-string-no-properties 1 arg))))
8732 (setq arg (match-string 2 arg))))
8733 ;; Parse arguments
8734 (while space-args
8735 (setq arg (car space-args)
8736 space-args (cdr space-args))
8737 (cond
8738 ;; Need another arg
8739 ((equal arg "-f")
8740 (setq next-param arg))
8741 ((equal arg "-v")
8742 (setq next-param arg))
8743 ((equal arg "-y")
8744 (setq next-param arg))
8745 ;; +libext+(ext1)+(ext2)...
8746 ((string-match "^\\+libext\\+\\(.*\\)" arg)
8747 (setq arg (match-string 1 arg))
8748 (while (string-match "\\([^+]+\\)\\+?\\(.*\\)" arg)
8749 (verilog-add-list-unique `verilog-library-extensions
8750 (match-string 1 arg))
8751 (setq arg (match-string 2 arg))))
8752 ;;
8753 ((or (string-match "^-D\\([^+=]*\\)[+=]\\(.*\\)" arg) ;; -Ddefine=val
8754 (string-match "^-D\\([^+=]*\\)\\(\\)" arg) ;; -Ddefine
8755 (string-match "^\\+define\\([^+=]*\\)[+=]\\(.*\\)" arg) ;; +define+val
8756 (string-match "^\\+define\\([^+=]*\\)\\(\\)" arg)) ;; +define+define
8757 (verilog-set-define (match-string 1 arg) (match-string 2 arg)))
8758 ;;
8759 ((or (string-match "^\\+incdir\\+\\(.*\\)" arg) ;; +incdir+dir
8760 (string-match "^-I\\(.*\\)" arg)) ;; -Idir
8761 (verilog-add-list-unique `verilog-library-directories
a3a8b002 8762 (match-string 1 (substitute-in-file-name arg))))
6341f357
DN
8763 ;; Ignore
8764 ((equal "+librescan" arg))
8765 ((string-match "^-U\\(.*\\)" arg)) ;; -Udefine
8766 ;; Second parameters
8767 ((equal next-param "-f")
8768 (setq next-param nil)
a3a8b002 8769 (verilog-getopt-file (substitute-in-file-name arg)))
6341f357
DN
8770 ((equal next-param "-v")
8771 (setq next-param nil)
a3a8b002
DN
8772 (verilog-add-list-unique `verilog-library-files
8773 (substitute-in-file-name arg)))
6341f357
DN
8774 ((equal next-param "-y")
8775 (setq next-param nil)
a3a8b002
DN
8776 (verilog-add-list-unique `verilog-library-directories
8777 (substitute-in-file-name arg)))
6341f357
DN
8778 ;; Filename
8779 ((string-match "^[^-+]" arg)
a3a8b002
DN
8780 (verilog-add-list-unique `verilog-library-files
8781 (substitute-in-file-name arg)))
6341f357 8782 ;; Default - ignore; no warning
60618039 8783 ))))
6341f357
DN
8784;;(verilog-getopt (list "+libext+.a+.b" "+incdir+foodir" "+define+a+aval" "-f" "otherf" "-v" "library" "-y" "dir"))
8785
8786(defun verilog-getopt-file (filename)
37ea4b9b 8787 "Read Verilog options from the specified FILENAME."
6341f357
DN
8788 (save-excursion
8789 (let ((fns (verilog-library-filenames filename (buffer-file-name)))
8790 (orig-buffer (current-buffer))
8791 line)
8792 (if fns
8793 (set-buffer (find-file-noselect (car fns)))
8794 (error (concat (verilog-point-text)
5509c6ad 8795 ": Can't find verilog-getopt-file -f file: " filename)))
6341f357
DN
8796 (goto-char (point-min))
8797 (while (not (eobp))
3ba6b2ee 8798 (setq line (buffer-substring (point) (point-at-eol)))
6341f357
DN
8799 (forward-line 1)
8800 (when (string-match "//" line)
8801 (setq line (substring line 0 (match-beginning 0))))
14862301 8802 (with-current-buffer orig-buffer ; Variables are buffer-local, so need right context.
6341f357
DN
8803 (verilog-getopt line))))))
8804
8805(defun verilog-getopt-flags ()
8806 "Convert `verilog-library-flags' into standard library variables."
8807 ;; If the flags are local, then all the outputs should be local also
8808 (when (local-variable-p `verilog-library-flags (current-buffer))
7ea26faf
DN
8809 (mapc 'make-local-variable '(verilog-library-extensions
8810 verilog-library-directories
8811 verilog-library-files
8812 verilog-library-flags)))
6341f357 8813 ;; Allow user to customize
9489a450 8814 (verilog-run-hooks 'verilog-before-getopt-flags-hook)
6341f357
DN
8815 ;; Process arguments
8816 (verilog-getopt verilog-library-flags)
8817 ;; Allow user to customize
9489a450 8818 (verilog-run-hooks 'verilog-getopt-flags-hook))
6341f357
DN
8819
8820(defun verilog-add-list-unique (varref object)
8821 "Append to VARREF list the given OBJECT,
37ea4b9b 8822unless it is already a member of the variable's list."
6341f357
DN
8823 (unless (member object (symbol-value varref))
8824 (set varref (append (symbol-value varref) (list object))))
8825 varref)
8826;;(progn (setq l '()) (verilog-add-list-unique `l "a") (verilog-add-list-unique `l "a") l)
8827
a03c2342
WS
8828(defun verilog-current-flags ()
8829 "Convert `verilog-library-flags' and similar variables to command line.
8830Used for __FLAGS__ in `verilog-expand-command'."
8831 (let ((cmd (mapconcat `concat verilog-library-flags " ")))
8832 (when (equal cmd "")
8833 (setq cmd (concat
8834 "+libext+" (mapconcat `concat verilog-library-extensions "+")
8835 (mapconcat (lambda (i) (concat " -y " i " +incdir+" i))
8836 verilog-library-directories "")
8837 (mapconcat (lambda (i) (concat " -v " i))
8838 verilog-library-files ""))))
8839 cmd))
8840;;(verilog-current-flags)
8841
6341f357 8842\f
5509c6ad
DN
8843;;
8844;; Cached directory support
8845;;
8846
8847(defvar verilog-dir-cache-preserving nil
8848 "If set, the directory cache is enabled, and file system changes are ignored.
8849See `verilog-dir-exists-p' and `verilog-dir-files'.")
8850
8851;; If adding new cached variable, add also to verilog-preserve-dir-cache
8852(defvar verilog-dir-cache-list nil
8853 "Alist of (((Cwd Dirname) Results)...) for caching `verilog-dir-files'.")
8854(defvar verilog-dir-cache-lib-filenames nil
8855 "Cached data for `verilog-library-filenames'.")
8856
8857(defmacro verilog-preserve-dir-cache (&rest body)
8858 "Execute the BODY forms, allowing directory cache preservation within BODY.
8859This means that changes inside BODY made to the file system will not be
8860seen by the `verilog-dir-files' and related functions."
a03c2342 8861 `(let ((verilog-dir-cache-preserving (current-buffer))
5509c6ad
DN
8862 verilog-dir-cache-list
8863 verilog-dir-cache-lib-filenames)
8864 (progn ,@body)))
8865
8866(defun verilog-dir-files (dirname)
8867 "Return all filenames in the DIRNAME directory.
8868Relative paths depend on the `default-directory'.
8869Results are cached if inside `verilog-preserve-dir-cache'."
8870 (unless verilog-dir-cache-preserving
8871 (setq verilog-dir-cache-list nil)) ;; Cache disabled
8872 ;; We don't use expand-file-name on the dirname to make key, as it's slow
8873 (let* ((cache-key (list dirname default-directory))
8874 (fass (assoc cache-key verilog-dir-cache-list))
8875 exp-dirname data)
8876 (cond (fass ;; Return data from cache hit
8877 (nth 1 fass))
8878 (t
8879 (setq exp-dirname (expand-file-name dirname)
8880 data (and (file-directory-p exp-dirname)
8881 (directory-files exp-dirname nil nil nil)))
8882 ;; Note we also encache nil for non-existing dirs.
8883 (setq verilog-dir-cache-list (cons (list cache-key data)
8884 verilog-dir-cache-list))
8885 data))))
8886;; Miss-and-hit test:
8887;;(verilog-preserve-dir-cache (prin1 (verilog-dir-files "."))
8888;; (prin1 (verilog-dir-files ".")) nil)
8889
8890(defun verilog-dir-file-exists-p (filename)
8891 "Return true if FILENAME exists.
8892Like `file-exists-p' but results are cached if inside
8893`verilog-preserve-dir-cache'."
8894 (let* ((dirname (file-name-directory filename))
8895 ;; Correct for file-name-nondirectory returning same if no slash.
8896 (dirnamed (if (or (not dirname) (equal dirname filename))
8897 default-directory dirname))
8898 (flist (verilog-dir-files dirnamed)))
8899 (and flist
8900 (member (file-name-nondirectory filename) flist)
8901 t)))
8902;;(verilog-dir-file-exists-p "verilog-mode.el")
8903;;(verilog-dir-file-exists-p "../verilog-mode/verilog-mode.el")
8904
8905\f
6341f357
DN
8906;;
8907;; Module name lookup
8908;;
8909
8910(defun verilog-module-inside-filename-p (module filename)
a03c2342 8911 "Return modi if MODULE is specified inside FILENAME, else nil.
6341f357
DN
8912Allows version control to check out the file if need be."
8913 (and (or (file-exists-p filename)
7ea26faf
DN
8914 (and (fboundp 'vc-backend)
8915 (vc-backend filename)))
a03c2342 8916 (let (modi type)
9a529312 8917 (with-current-buffer (find-file-noselect filename)
14862301
SM
8918 (save-excursion
8919 (goto-char (point-min))
8920 (while (and
8921 ;; It may be tempting to look for verilog-defun-re,
8922 ;; don't, it slows things down a lot!
9489a450 8923 (verilog-re-search-forward-quick "\\<\\(module\\|interface\\|program\\)\\>" nil t)
a03c2342 8924 (setq type (match-string-no-properties 0))
14862301
SM
8925 (verilog-re-search-forward-quick "[(;]" nil t))
8926 (if (equal module (verilog-read-module-name))
a03c2342
WS
8927 (setq modi (verilog-modi-new module filename (point) type))))
8928 modi)))))
6341f357
DN
8929
8930(defun verilog-is-number (symbol)
8931 "Return true if SYMBOL is number-like."
8932 (or (string-match "^[0-9 \t:]+$" symbol)
8933 (string-match "^[---]*[0-9]+$" symbol)
60618039 8934 (string-match "^[0-9 \t]+'s?[hdxbo][0-9a-fA-F_xz? \t]*$" symbol)))
6341f357
DN
8935
8936(defun verilog-symbol-detick (symbol wing-it)
37ea4b9b 8937 "Return an expanded SYMBOL name without any defines.
6341f357
DN
8938If the variable vh-{symbol} is defined, return that value.
8939If undefined, and WING-IT, return just SYMBOL without the tick, else nil."
8940 (while (and symbol (string-match "^`" symbol))
8941 (setq symbol (substring symbol 1))
8942 (setq symbol
8943 (if (boundp (intern (concat "vh-" symbol)))
8944 ;; Emacs has a bug where boundp on a buffer-local
8945 ;; variable in only one buffer returns t in another.
8946 ;; This can confuse, so check for nil.
8947 (let ((val (eval (intern (concat "vh-" symbol)))))
8948 (if (eq val nil)
8949 (if wing-it symbol nil)
8950 val))
8951 (if wing-it symbol nil))))
8952 symbol)
8953;;(verilog-symbol-detick "`mod" nil)
8954
8955(defun verilog-symbol-detick-denumber (symbol)
8956 "Return SYMBOL with defines converted and any numbers dropped to nil."
8957 (when (string-match "^`" symbol)
8958 ;; This only will work if the define is a simple signal, not
8959 ;; something like a[b]. Sorry, it should be substituted into the parser
8960 (setq symbol
8961 (verilog-string-replace-matches
8962 "\[[^0-9: \t]+\]" "" nil nil
8963 (or (verilog-symbol-detick symbol nil)
8964 (if verilog-auto-sense-defines-constant
8965 "0"
8966 symbol)))))
8967 (if (verilog-is-number symbol)
8968 nil
8969 symbol))
8970
8971(defun verilog-symbol-detick-text (text)
37ea4b9b 8972 "Return TEXT without any known defines.
6341f357
DN
8973If the variable vh-{symbol} is defined, substitute that value."
8974 (let ((ok t) symbol val)
8975 (while (and ok (string-match "`\\([a-zA-Z0-9_]+\\)" text))
8976 (setq symbol (match-string 1 text))
a3a8b002 8977 ;;(message symbol)
6341f357
DN
8978 (cond ((and
8979 (boundp (intern (concat "vh-" symbol)))
8980 ;; Emacs has a bug where boundp on a buffer-local
8981 ;; variable in only one buffer returns t in another.
8982 ;; This can confuse, so check for nil.
8983 (setq val (eval (intern (concat "vh-" symbol)))))
8984 (setq text (replace-match val nil nil text)))
8985 (t (setq ok nil)))))
8986 text)
8987;;(progn (setq vh-mod "`foo" vh-foo "bar") (verilog-symbol-detick-text "bar `mod `undefed"))
8988
8989(defun verilog-expand-dirnames (&optional dirnames)
8990 "Return a list of existing directories given a list of wildcarded DIRNAMES.
8991Or, just the existing dirnames themselves if there are no wildcards."
5509c6ad
DN
8992 ;; Note this function is performance critical.
8993 ;; Do not call anything that requires disk access that cannot be cached.
6341f357
DN
8994 (interactive)
8995 (unless dirnames (error "`verilog-library-directories' should include at least '.'"))
8996 (setq dirnames (reverse dirnames)) ; not nreverse
8997 (let ((dirlist nil)
5509c6ad 8998 pattern dirfile dirfiles dirname root filename rest basefile)
6341f357
DN
8999 (while dirnames
9000 (setq dirname (substitute-in-file-name (car dirnames))
9001 dirnames (cdr dirnames))
9002 (cond ((string-match (concat "^\\(\\|[/\\]*[^*?]*[/\\]\\)" ;; root
9003 "\\([^/\\]*[*?][^/\\]*\\)" ;; filename with *?
9004 "\\(.*\\)") ;; rest
9005 dirname)
9006 (setq root (match-string 1 dirname)
9007 filename (match-string 2 dirname)
9008 rest (match-string 3 dirname)
9009 pattern filename)
9010 ;; now replace those * and ? with .+ and .
9011 ;; use ^ and /> to get only whole file names
6341f357
DN
9012 (setq pattern (verilog-string-replace-matches "[*]" ".+" nil nil pattern)
9013 pattern (verilog-string-replace-matches "[?]" "." nil nil pattern)
5509c6ad
DN
9014 pattern (concat "^" pattern "$")
9015 dirfiles (verilog-dir-files root))
6341f357 9016 (while dirfiles
5509c6ad
DN
9017 (setq basefile (car dirfiles)
9018 dirfile (expand-file-name (concat root basefile rest))
6341f357 9019 dirfiles (cdr dirfiles))
5509c6ad
DN
9020 (if (and (string-match pattern basefile)
9021 ;; Don't allow abc/*/rtl to match abc/rtl via ..
9022 (not (equal basefile "."))
9023 (not (equal basefile ".."))
9024 (file-directory-p dirfile))
60618039 9025 (setq dirlist (cons dirfile dirlist)))))
6341f357
DN
9026 ;; Defaults
9027 (t
9028 (if (file-directory-p dirname)
60618039 9029 (setq dirlist (cons dirname dirlist))))))
6341f357
DN
9030 dirlist))
9031;;(verilog-expand-dirnames (list "." ".." "nonexist" "../*" "/home/wsnyder/*/v"))
9032
0e5c8aed 9033(defun verilog-library-filenames (filename &optional current check-ext)
5509c6ad 9034 "Return a search path to find the given FILENAME or module name.
0e5c8aed
DN
9035Uses the optional CURRENT filename or buffer-file-name, plus
9036`verilog-library-directories' and `verilog-library-extensions'
9037variables to build the path. With optional CHECK-EXT also check
9038`verilog-library-extensions'."
9039 (unless current (setq current (buffer-file-name)))
5509c6ad
DN
9040 (unless verilog-dir-cache-preserving
9041 (setq verilog-dir-cache-lib-filenames nil))
9042 (let* ((cache-key (list filename current check-ext))
9043 (fass (assoc cache-key verilog-dir-cache-lib-filenames))
9044 chkdirs chkdir chkexts fn outlist)
9045 (cond (fass ;; Return data from cache hit
9046 (nth 1 fass))
9047 (t
9048 ;; Note this expand can't be easily cached, as we need to
9049 ;; pick up buffer-local variables for newly read sub-module files
9050 (setq chkdirs (verilog-expand-dirnames verilog-library-directories))
9051 (while chkdirs
9052 (setq chkdir (expand-file-name (car chkdirs)
9053 (file-name-directory current))
9054 chkexts (if check-ext verilog-library-extensions `("")))
9055 (while chkexts
9056 (setq fn (expand-file-name (concat filename (car chkexts))
9057 chkdir))
9058 ;;(message "Check for %s" fn)
9059 (if (verilog-dir-file-exists-p fn)
9060 (setq outlist (cons (expand-file-name
9061 fn (file-name-directory current))
9062 outlist)))
9063 (setq chkexts (cdr chkexts)))
9064 (setq chkdirs (cdr chkdirs)))
9065 (setq outlist (nreverse outlist))
9066 (setq verilog-dir-cache-lib-filenames
9067 (cons (list cache-key outlist)
9068 verilog-dir-cache-lib-filenames))
9069 outlist))))
6341f357
DN
9070
9071(defun verilog-module-filenames (module current)
9072 "Return a search path to find the given MODULE name.
9073Uses the CURRENT filename, `verilog-library-extensions',
9074`verilog-library-directories' and `verilog-library-files'
9075variables to build the path."
9076 ;; Return search locations for it
9077 (append (list current) ; first, current buffer
9078 (verilog-library-filenames module current t)
9079 verilog-library-files)) ; finally, any libraries
9080
9081;;
9082;; Module Information
9083;;
9084;; Many of these functions work on "modi" a module information structure
9085;; A modi is: [module-name-string file-name begin-point]
9086
9087(defvar verilog-cache-enabled t
9088 "If true, enable caching of signals, etc. Set to nil for debugging to make things SLOW!")
9089
9090(defvar verilog-modi-cache-list nil
9091 "Cache of ((Module Function) Buf-Tick Buf-Modtime Func-Returns)...
9092For speeding up verilog-modi-get-* commands.
9093Buffer-local.")
7ea26faf
DN
9094(make-variable-buffer-local 'verilog-modi-cache-list)
9095
6341f357
DN
9096(defvar verilog-modi-cache-preserve-tick nil
9097 "Modification tick after which the cache is still considered valid.
5509c6ad 9098Use `verilog-preserve-modi-cache' to set it.")
6341f357
DN
9099(defvar verilog-modi-cache-preserve-buffer nil
9100 "Modification tick after which the cache is still considered valid.
5509c6ad 9101Use `verilog-preserve-modi-cache' to set it.")
a03c2342
WS
9102(defvar verilog-modi-cache-current-enable nil
9103 "If true, allow caching `verilog-modi-current', set by let().")
9104(defvar verilog-modi-cache-current nil
9105 "Currently active `verilog-modi-current', if any, set by let().")
9106(defvar verilog-modi-cache-current-max nil
9107 "Current endmodule point for `verilog-modi-cache-current', if any.")
6341f357
DN
9108
9109(defun verilog-modi-current ()
a03c2342
WS
9110 "Return the modi structure for the module currently at point, possibly cached."
9111 (cond ((and verilog-modi-cache-current
9112 (>= (point) (verilog-modi-get-point verilog-modi-cache-current))
9113 (<= (point) verilog-modi-cache-current-max))
9114 ;; Slow assertion, for debugging the cache:
9115 ;;(or (equal verilog-modi-cache-current (verilog-modi-current-get)) (debug))
9116 verilog-modi-cache-current)
9117 (verilog-modi-cache-current-enable
9118 (setq verilog-modi-cache-current (verilog-modi-current-get)
9119 verilog-modi-cache-current-max
9120 ;; The cache expires when we pass "endmodule" as then the
9121 ;; current modi may change to the next module
9122 ;; This relies on the AUTOs generally inserting, not deleting text
9123 (save-excursion
9124 (verilog-re-search-forward-quick verilog-end-defun-re nil nil)))
9125 verilog-modi-cache-current)
9126 (t
9127 (verilog-modi-current-get))))
9128
9129(defun verilog-modi-current-get ()
6341f357 9130 "Return the modi structure for the module currently at point."
a03c2342 9131 (let* (name type pt)
6341f357
DN
9132 ;; read current module's name
9133 (save-excursion
9134 (verilog-re-search-backward-quick verilog-defun-re nil nil)
a03c2342 9135 (setq type (match-string-no-properties 0))
6341f357
DN
9136 (verilog-re-search-forward-quick "(" nil nil)
9137 (setq name (verilog-read-module-name))
9138 (setq pt (point)))
a03c2342
WS
9139 ;; return modi - note this vector built two places
9140 (verilog-modi-new name (or (buffer-file-name) (current-buffer)) pt type)))
6341f357 9141
a03c2342
WS
9142(defvar verilog-modi-lookup-cache nil "Hash of (modulename modi).")
9143(make-variable-buffer-local 'verilog-modi-lookup-cache)
9144(defvar verilog-modi-lookup-last-current nil "Cache of `current-buffer' at last lookup.")
9145(defvar verilog-modi-lookup-last-tick nil "Cache of `buffer-chars-modified-tick' at last lookup.")
6341f357
DN
9146
9147(defun verilog-modi-lookup (module allow-cache &optional ignore-error)
9148 "Find the file and point at which MODULE is defined.
9149If ALLOW-CACHE is set, check and remember cache of previous lookups.
9150Return modi if successful, else print message unless IGNORE-ERROR is true."
a03c2342
WS
9151 (let* ((current (or (buffer-file-name) (current-buffer)))
9152 modi)
9153 ;; Check cache
9154 ;;(message "verilog-modi-lookup: %s" module)
9155 (cond ((and verilog-modi-lookup-cache
6341f357
DN
9156 verilog-cache-enabled
9157 allow-cache
a03c2342 9158 (setq modi (gethash module verilog-modi-lookup-cache))
6341f357 9159 (equal verilog-modi-lookup-last-current current)
a03c2342
WS
9160 ;; Iff hit is in current buffer, then tick must match
9161 (or (equal verilog-modi-lookup-last-tick (buffer-chars-modified-tick))
9162 (not (equal current (verilog-modi-file-or-buffer modi)))))
9163 ;;(message "verilog-modi-lookup: HIT %S" modi)
9164 modi)
9165 ;; Miss
6341f357
DN
9166 (t (let* ((realmod (verilog-symbol-detick module t))
9167 (orig-filenames (verilog-module-filenames realmod current))
9168 (filenames orig-filenames)
a03c2342
WS
9169 mif)
9170 (while (and filenames (not mif))
9171 (if (not (setq mif (verilog-module-inside-filename-p realmod (car filenames))))
6341f357 9172 (setq filenames (cdr filenames))))
a03c2342
WS
9173 ;; mif has correct form to become later elements of modi
9174 (cond (mif (setq modi mif))
9175 (t (setq modi nil)
6341f357
DN
9176 (or ignore-error
9177 (error (concat (verilog-point-text)
9178 ": Can't locate " module " module definition"
9179 (if (not (equal module realmod))
9180 (concat " (Expanded macro to " realmod ")")
9181 "")
9182 "\n Check the verilog-library-directories variable."
9183 "\n I looked in (if not listed, doesn't exist):\n\t"
60618039 9184 (mapconcat 'concat orig-filenames "\n\t"))))))
a03c2342
WS
9185 (when (eval-when-compile (fboundp 'make-hash-table))
9186 (unless verilog-modi-lookup-cache
9187 (setq verilog-modi-lookup-cache
9188 (make-hash-table :test 'equal :rehash-size 4.0)))
9189 (puthash module modi verilog-modi-lookup-cache))
9190 (setq verilog-modi-lookup-last-current current
9191 verilog-modi-lookup-last-tick (buffer-chars-modified-tick)))))
9192 modi))
6341f357
DN
9193
9194(defun verilog-modi-filename (modi)
37ea4b9b 9195 "Filename of MODI, or name of buffer if it's never been saved."
6341f357
DN
9196 (if (bufferp (verilog-modi-file-or-buffer modi))
9197 (or (buffer-file-name (verilog-modi-file-or-buffer modi))
9198 (buffer-name (verilog-modi-file-or-buffer modi)))
9199 (verilog-modi-file-or-buffer modi)))
9200
9201(defun verilog-modi-goto (modi)
9202 "Move point/buffer to specified MODI."
9203 (or modi (error "Passed unfound modi to goto, check earlier"))
9204 (set-buffer (if (bufferp (verilog-modi-file-or-buffer modi))
9205 (verilog-modi-file-or-buffer modi)
9206 (find-file-noselect (verilog-modi-file-or-buffer modi))))
37ea4b9b 9207 (or (equal major-mode `verilog-mode) ;; Put into Verilog mode to get syntax
6341f357 9208 (verilog-mode))
a03c2342 9209 (goto-char (verilog-modi-get-point modi)))
6341f357
DN
9210
9211(defun verilog-goto-defun-file (module)
9212 "Move point to the file at which a given MODULE is defined."
9213 (interactive "sGoto File for Module: ")
9214 (let* ((modi (verilog-modi-lookup module nil)))
9215 (when modi
9216 (verilog-modi-goto modi)
9217 (switch-to-buffer (current-buffer)))))
9218
9219(defun verilog-modi-cache-results (modi function)
9220 "Run on MODI the given FUNCTION. Locate the module in a file.
9221Cache the output of function so next call may have faster access."
5509c6ad
DN
9222 (let (fass)
9223 (save-excursion ;; Cache is buffer-local so can't avoid this.
6341f357 9224 (verilog-modi-goto modi)
5509c6ad 9225 (if (and (setq fass (assoc (list modi function)
6341f357
DN
9226 verilog-modi-cache-list))
9227 ;; Destroy caching when incorrect; Modified or file changed
9228 (not (and verilog-cache-enabled
a03c2342 9229 (or (equal (buffer-chars-modified-tick) (nth 1 fass))
6341f357
DN
9230 (and verilog-modi-cache-preserve-tick
9231 (<= verilog-modi-cache-preserve-tick (nth 1 fass))
9232 (equal verilog-modi-cache-preserve-buffer (current-buffer))))
9233 (equal (visited-file-modtime) (nth 2 fass)))))
9234 (setq verilog-modi-cache-list nil
9235 fass nil))
9236 (cond (fass
5509c6ad
DN
9237 ;; Return data from cache hit
9238 (nth 3 fass))
6341f357
DN
9239 (t
9240 ;; Read from file
86a4c7ac 9241 ;; Clear then restore any highlighting to make emacs19 happy
6341f357
DN
9242 (let ((fontlocked (when (and (boundp 'font-lock-mode)
9243 font-lock-mode)
7cb1c4d7 9244 (font-lock-mode 0)
5509c6ad
DN
9245 t))
9246 func-returns)
6341f357 9247 (setq func-returns (funcall function))
5509c6ad 9248 (when fontlocked (font-lock-mode t))
9c059794
DN
9249 ;; Cache for next time
9250 (setq verilog-modi-cache-list
5509c6ad 9251 (cons (list (list modi function)
a03c2342 9252 (buffer-chars-modified-tick)
9c059794
DN
9253 (visited-file-modtime)
9254 func-returns)
5509c6ad
DN
9255 verilog-modi-cache-list))
9256 func-returns))))))
6341f357
DN
9257
9258(defun verilog-modi-cache-add (modi function element sig-list)
9259 "Add function return results to the module cache.
9260Update MODI's cache for given FUNCTION so that the return ELEMENT of that
9261function now contains the additional SIG-LIST parameters."
9262 (let (fass)
9263 (save-excursion
9264 (verilog-modi-goto modi)
5509c6ad 9265 (if (setq fass (assoc (list modi function)
6341f357
DN
9266 verilog-modi-cache-list))
9267 (let ((func-returns (nth 3 fass)))
9268 (aset func-returns element
9269 (append sig-list (aref func-returns element))))))))
9270
5509c6ad 9271(defmacro verilog-preserve-modi-cache (&rest body)
6341f357
DN
9272 "Execute the BODY forms, allowing cache preservation within BODY.
9273This means that changes to the buffer will not result in the cache being
9274flushed. If the changes affect the modsig state, they must call the
9275modsig-cache-add-* function, else the results of later calls may be
9276incorrect. Without this, changes are assumed to be adding/removing signals
9277and invalidating the cache."
a03c2342 9278 `(let ((verilog-modi-cache-preserve-tick (buffer-chars-modified-tick))
6341f357
DN
9279 (verilog-modi-cache-preserve-buffer (current-buffer)))
9280 (progn ,@body)))
9281
6341f357
DN
9282
9283(defun verilog-signals-matching-enum (in-list enum)
9284 "Return all signals in IN-LIST matching the given ENUM."
9285 (let (out-list)
9286 (while in-list
9287 (if (equal (verilog-sig-enum (car in-list)) enum)
9288 (setq out-list (cons (car in-list) out-list)))
9289 (setq in-list (cdr in-list)))
9290 ;; New scheme
9291 (let* ((enumvar (intern (concat "venum-" enum)))
9292 (enumlist (and (boundp enumvar) (eval enumvar))))
9293 (while enumlist
9294 (add-to-list 'out-list (list (car enumlist)))
9295 (setq enumlist (cdr enumlist))))
9296 (nreverse out-list)))
9297
e2076c2c
DN
9298(defun verilog-signals-matching-regexp (in-list regexp)
9299 "Return all signals in IN-LIST matching the given REGEXP, if non-nil."
a3a8b002 9300 (if (or (not regexp) (equal regexp ""))
e2076c2c
DN
9301 in-list
9302 (let (out-list)
9303 (while in-list
9304 (if (string-match regexp (verilog-sig-name (car in-list)))
9305 (setq out-list (cons (car in-list) out-list)))
9306 (setq in-list (cdr in-list)))
9307 (nreverse out-list))))
9308
6341f357
DN
9309(defun verilog-signals-not-matching-regexp (in-list regexp)
9310 "Return all signals in IN-LIST not matching the given REGEXP, if non-nil."
a3a8b002 9311 (if (or (not regexp) (equal regexp ""))
6341f357
DN
9312 in-list
9313 (let (out-list)
9314 (while in-list
9315 (if (not (string-match regexp (verilog-sig-name (car in-list))))
9316 (setq out-list (cons (car in-list) out-list)))
9317 (setq in-list (cdr in-list)))
9318 (nreverse out-list))))
9319
a3a8b002 9320(defun verilog-signals-matching-dir-re (in-list decl-type regexp)
0e5c8aed 9321 "Return all signals in IN-LIST matching the given DECL-TYPE and REGEXP,
a3a8b002
DN
9322if non-nil."
9323 (if (or (not regexp) (equal regexp ""))
9324 in-list
9325 (let (out-list to-match)
9326 (while in-list
9327 ;; Note verilog-insert-one-definition matches on this order
9328 (setq to-match (concat
9329 decl-type
9330 " " (verilog-sig-signed (car in-list))
9331 " " (verilog-sig-multidim (car in-list))
9332 (verilog-sig-bits (car in-list))))
9333 (if (string-match regexp to-match)
9334 (setq out-list (cons (car in-list) out-list)))
9335 (setq in-list (cdr in-list)))
9336 (nreverse out-list))))
9337
6341f357 9338;; Combined
5509c6ad 9339(defun verilog-decls-get-signals (decls)
9489a450 9340 "Return all declared signals, excluding 'assign' statements."
6341f357 9341 (append
5509c6ad
DN
9342 (verilog-decls-get-outputs decls)
9343 (verilog-decls-get-inouts decls)
9344 (verilog-decls-get-inputs decls)
9489a450 9345 (verilog-decls-get-vars decls)
5509c6ad
DN
9346 (verilog-decls-get-consts decls)
9347 (verilog-decls-get-gparams decls)))
9348
9349(defun verilog-decls-get-ports (decls)
6341f357 9350 (append
5509c6ad
DN
9351 (verilog-decls-get-outputs decls)
9352 (verilog-decls-get-inouts decls)
9353 (verilog-decls-get-inputs decls)))
6341f357
DN
9354
9355(defsubst verilog-modi-cache-add-outputs (modi sig-list)
9356 (verilog-modi-cache-add modi 'verilog-read-decls 0 sig-list))
9357(defsubst verilog-modi-cache-add-inouts (modi sig-list)
9358 (verilog-modi-cache-add modi 'verilog-read-decls 1 sig-list))
9359(defsubst verilog-modi-cache-add-inputs (modi sig-list)
9360 (verilog-modi-cache-add modi 'verilog-read-decls 2 sig-list))
9489a450 9361(defsubst verilog-modi-cache-add-vars (modi sig-list)
6341f357 9362 (verilog-modi-cache-add modi 'verilog-read-decls 3 sig-list))
6341f357
DN
9363
9364(defun verilog-signals-from-signame (signame-list)
9365 "Return signals in standard form from SIGNAME-LIST, a simple list of signal names."
9366 (mapcar (function (lambda (name) (list name nil nil)))
9367 signame-list))
9368\f
9369;;
9370;; Auto creation utilities
9371;;
9372
495ab0d5
DN
9373(defun verilog-auto-re-search-do (search-for func)
9374 "Search for the given auto text regexp SEARCH-FOR, and perform FUNC where it occurs."
6341f357 9375 (goto-char (point-min))
9489a450 9376 (while (verilog-re-search-forward-quick search-for nil t)
495ab0d5 9377 (funcall func)))
6341f357 9378
6341f357 9379(defun verilog-insert-one-definition (sig type indent-pt)
60618039 9380 "Print out a definition for SIG of the given TYPE,
6341f357
DN
9381with appropriate INDENT-PT indentation."
9382 (indent-to indent-pt)
a3a8b002 9383 ;; Note verilog-signals-matching-dir-re matches on this order
6341f357 9384 (insert type)
a3a8b002
DN
9385 (when (verilog-sig-modport sig)
9386 (insert "." (verilog-sig-modport sig)))
6341f357
DN
9387 (when (verilog-sig-signed sig)
9388 (insert " " (verilog-sig-signed sig)))
9389 (when (verilog-sig-multidim sig)
9390 (insert " " (verilog-sig-multidim-string sig)))
9391 (when (verilog-sig-bits sig)
9392 (insert " " (verilog-sig-bits sig)))
9393 (indent-to (max 24 (+ indent-pt 16)))
9394 (unless (= (char-syntax (preceding-char)) ?\ )
9395 (insert " ")) ; Need space between "]name" if indent-to did nothing
8468f78b
WS
9396 (insert (verilog-sig-name sig))
9397 (when (verilog-sig-memory sig)
9398 (insert " " (verilog-sig-memory sig))))
6341f357 9399
9489a450
MM
9400(defun verilog-insert-definition (modi sigs direction indent-pt v2k &optional dont-sort)
9401 "Print out a definition for MODI's list of SIGS of the given DIRECTION,
6341f357 9402with appropriate INDENT-PT indentation. If V2K, use Verilog 2001 I/O
9489a450
MM
9403format. Sort unless DONT-SORT. DIRECTION is normally wire/reg/output.
9404When MODI is non-null, also add to modi-cache, for tracking."
9405 (when modi
9406 (cond ((equal direction "wire")
9407 (verilog-modi-cache-add-vars modi sigs))
9408 ((equal direction "reg")
9409 (verilog-modi-cache-add-vars modi sigs))
9410 ((equal direction "output")
9411 (verilog-modi-cache-add-outputs modi sigs)
9412 (when verilog-auto-declare-nettype
9413 (verilog-modi-cache-add-vars modi sigs)))
9414 ((equal direction "input")
9415 (verilog-modi-cache-add-inputs modi sigs)
9416 (when verilog-auto-declare-nettype
9417 (verilog-modi-cache-add-vars modi sigs)))
9418 ((equal direction "inout")
9419 (verilog-modi-cache-add-inouts modi sigs)
9420 (when verilog-auto-declare-nettype
9421 (verilog-modi-cache-add-vars modi sigs)))
9422 ((equal direction "interface"))
9423 (t
9424 (error "Unsupported verilog-insert-definition direction: %s" direction))))
6341f357
DN
9425 (or dont-sort
9426 (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
9427 (while sigs
9428 (let ((sig (car sigs)))
9429 (verilog-insert-one-definition
9430 sig
9431 ;; Want "type x" or "output type x", not "wire type x"
9489a450
MM
9432 (cond ((or (verilog-sig-type sig)
9433 verilog-auto-wire-type)
6341f357 9434 (concat
9489a450
MM
9435 (when (member direction '("input" "output" "inout"))
9436 (concat direction " "))
9437 (or (verilog-sig-type sig)
9438 verilog-auto-wire-type)))
9439 ((and verilog-auto-declare-nettype
9440 (member direction '("input" "output" "inout")))
9441 (concat direction " " verilog-auto-declare-nettype))
9442 (t
9443 direction))
6341f357
DN
9444 indent-pt)
9445 (insert (if v2k "," ";"))
9446 (if (or (not (verilog-sig-comment sig))
9447 (equal "" (verilog-sig-comment sig)))
9448 (insert "\n")
9449 (indent-to (max 48 (+ indent-pt 40)))
a03c2342 9450 (verilog-insert "// " (verilog-sig-comment sig) "\n"))
6341f357
DN
9451 (setq sigs (cdr sigs)))))
9452
9453(eval-when-compile
9454 (if (not (boundp 'indent-pt))
9455 (defvar indent-pt nil "Local used by insert-indent")))
9456
9457(defun verilog-insert-indent (&rest stuff)
9458 "Indent to position stored in local `indent-pt' variable, then insert STUFF.
9459Presumes that any newlines end a list element."
9460 (let ((need-indent t))
9461 (while stuff
9462 (if need-indent (indent-to indent-pt))
9463 (setq need-indent nil)
a03c2342 9464 (verilog-insert (car stuff))
6341f357
DN
9465 (setq need-indent (string-match "\n$" (car stuff))
9466 stuff (cdr stuff)))))
9467;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n"))
9468
9469(defun verilog-repair-open-comma ()
a3a8b002
DN
9470 "Insert comma if previous argument is other than a open parenthesis or endif."
9471 ;; We can't just search backward for ) as it might be inside another expression.
9472 ;; Also want "`ifdef X input foo `endif" to just leave things to the human to deal with
6341f357 9473 (save-excursion
9489a450 9474 (verilog-backward-syntactic-ws-quick)
a3a8b002
DN
9475 (when (and (not (save-excursion ;; Not beginning (, or existing ,
9476 (backward-char 1)
9477 (looking-at "[(,]")))
9478 (not (save-excursion ;; Not `endif, or user define
9479 (backward-char 1)
9480 (skip-chars-backward "[a-zA-Z0-9_`]")
9481 (looking-at "`"))))
9482 (insert ","))))
6341f357
DN
9483
9484(defun verilog-repair-close-comma ()
9485 "If point is at a comma followed by a close parenthesis, fix it.
9486This repairs those mis-inserted by a AUTOARG."
9487 ;; It would be much nicer if Verilog allowed extra commas like Perl does!
9488 (save-excursion
9489 (verilog-forward-close-paren)
9490 (backward-char 1)
9489a450 9491 (verilog-backward-syntactic-ws-quick)
6341f357
DN
9492 (backward-char 1)
9493 (when (looking-at ",")
9494 (delete-char 1))))
9495
9496(defun verilog-get-list (start end)
9497 "Return the elements of a comma separated list between START and END."
9498 (interactive)
9499 (let ((my-list (list))
9500 my-string)
9501 (save-excursion
9502 (while (< (point) end)
9503 (when (re-search-forward "\\([^,{]+\\)" end t)
9504 (setq my-string (verilog-string-remove-spaces (match-string 1)))
9505 (setq my-list (nconc my-list (list my-string) ))
9506 (goto-char (match-end 0))))
9507 my-list)))
9508
9509(defun verilog-make-width-expression (range-exp)
9510 "Return an expression calculating the length of a range [x:y] in RANGE-EXP."
9511 ;; strip off the []
9512 (cond ((not range-exp)
9513 "1")
9514 (t
9515 (if (string-match "^\\[\\(.*\\)\\]$" range-exp)
9516 (setq range-exp (match-string 1 range-exp)))
9517 (cond ((not range-exp)
9518 "1")
a3a8b002 9519 ;; [#:#] We can compute a numeric result
7ea26faf
DN
9520 ((string-match "^\\s *\\([0-9]+\\)\\s *:\\s *\\([0-9]+\\)\\s *$"
9521 range-exp)
9522 (int-to-string
9523 (1+ (abs (- (string-to-number (match-string 1 range-exp))
9524 (string-to-number (match-string 2 range-exp)))))))
a3a8b002
DN
9525 ;; [PARAM-1:0] can just return PARAM
9526 ((string-match "^\\s *\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s *-\\s *1\\s *:\\s *0\\s *$" range-exp)
9527 (match-string 1 range-exp))
9528 ;; [arbitrary] need math
6341f357 9529 ((string-match "^\\(.*\\)\\s *:\\s *\\(.*\\)\\s *$" range-exp)
7ea26faf 9530 (concat "(1+(" (match-string 1 range-exp) ")"
60618039
DN
9531 (if (equal "0" (match-string 2 range-exp))
9532 "" ;; Don't bother with -(0)
6341f357
DN
9533 (concat "-(" (match-string 2 range-exp) ")"))
9534 ")"))
9535 (t nil)))))
9536;;(verilog-make-width-expression "`A:`B")
9537
9489a450
MM
9538(defun verilog-simplify-range-expression (expr)
9539 "Return a simplified range expression with constants eliminated from EXPR."
9540 ;; Note this is always called with brackets; ie [z] or [z:z]
9541 (if (not (string-match "[---+*()]" expr))
9542 expr ;; short-circuit
9543 (let ((out expr)
9544 (last-pass ""))
9545 (while (not (equal last-pass out))
9546 (setq last-pass out)
9547 ;; Prefix regexp needs beginning of match, or some symbol of
9548 ;; lesser or equal precedence. We assume the [:]'s exist in expr.
9549 ;; Ditto the end.
9550 (while (string-match
9551 (concat "\\([[({:*+-]\\)" ; - must be last
9552 "(\\<\\([0-9A-Za-z_]+\\))"
9553 "\\([])}:*+-]\\)")
9554 out)
9555 (setq out (replace-match "\\1\\2\\3" nil nil out)))
9556 ;; For precedence do * before +/-
9557 (while (string-match
9558 (concat "\\([[({:*+-]\\)"
9559 "\\([0-9]+\\)\\s *\\([*]\\)\\s *\\([0-9]+\\)"
9560 "\\([])}:*+-]\\)")
9561 out)
9562 (setq out (replace-match
9563 (concat (match-string 1 out)
9564 (int-to-string (* (string-to-number (match-string 2 out))
9565 (string-to-number (match-string 4 out))))
9566 (match-string 5 out))
9567 nil nil out)))
9568 (while (string-match
9569 (concat "\\([[({:+-]\\)" ; No * here as higher prec
9570 "\\([0-9]+\\)\\s *\\([---+]\\)\\s *\\([0-9]+\\)"
9571 "\\([])}:+-]\\)")
9572 out)
9573 (let ((pre (match-string 1 out))
9574 (lhs (string-to-number (match-string 2 out)))
9575 (rhs (string-to-number (match-string 4 out)))
9576 (post (match-string 5 out))
9577 val)
9578 (when (equal pre "-")
9579 (setq lhs (- lhs)))
9580 (setq val (if (equal (match-string 3 out) "-")
9581 (- lhs rhs)
9582 (+ lhs rhs))
9583 out (replace-match
9584 (concat (if (and (equal pre "-")
9585 (< val 0))
9586 "" ;; Not "--20" but just "-20"
9587 pre)
9588 (int-to-string val)
9589 post)
9590 nil nil out)) )))
9591 out)))
9592;;(verilog-simplify-range-expression "[1:3]") ;; 1
9593;;(verilog-simplify-range-expression "[(1):3]") ;; 1
9594;;(verilog-simplify-range-expression "[(((16)+1)+1+(1+1))]") ;;20
9595;;(verilog-simplify-range-expression "[(2*3+6*7)]") ;; 48
9596;;(verilog-simplify-range-expression "[(FOO*4-1*2)]") ;; FOO*4-2
9597;;(verilog-simplify-range-expression "[(FOO*4+1-1)]") ;; FOO*4+0
9598;;(verilog-simplify-range-expression "[(func(BAR))]") ;; func(BAR)
9599;;(verilog-simplify-range-expression "[FOO-1+1-1+1]") ;; FOO-0
4c5e69c6 9600
6341f357
DN
9601(defun verilog-typedef-name-p (variable-name)
9602 "Return true if the VARIABLE-NAME is a type definition."
9603 (when verilog-typedef-regexp
9604 (string-match verilog-typedef-regexp variable-name)))
9605\f
9606;;
9607;; Auto deletion
9608;;
9609
9610(defun verilog-delete-autos-lined ()
9611 "Delete autos that occupy multiple lines, between begin and end comments."
9489a450
MM
9612 ;; The newline must not have a comment property, so we must
9613 ;; delete the end auto's newline, not the first newline
9614 (forward-line 1)
6341f357 9615 (let ((pt (point)))
6341f357
DN
9616 (when (and
9617 (looking-at "\\s-*// Beginning")
9618 (search-forward "// End of automatic" nil t))
9619 ;; End exists
9620 (end-of-line)
9489a450
MM
9621 (forward-line 1)
9622 (delete-region pt (point)))))
6341f357 9623
0e5c8aed
DN
9624(defun verilog-delete-empty-auto-pair ()
9625 "Delete begin/end auto pair at point, if empty."
9626 (forward-line 0)
9627 (when (looking-at (concat "\\s-*// Beginning of automatic.*\n"
9628 "\\s-*// End of automatics\n"))
9629 (delete-region (point) (save-excursion (forward-line 2) (point)))))
9630
6341f357 9631(defun verilog-forward-close-paren ()
37ea4b9b
JB
9632 "Find the close parenthesis that match the current point.
9633Ignore other close parenthesis with matching open parens."
6341f357
DN
9634 (let ((parens 1))
9635 (while (> parens 0)
9636 (unless (verilog-re-search-forward-quick "[()]" nil t)
9637 (error "%s: Mismatching ()" (verilog-point-text)))
9638 (cond ((= (preceding-char) ?\( )
9639 (setq parens (1+ parens)))
9640 ((= (preceding-char) ?\) )
9641 (setq parens (1- parens)))))))
9642
9643(defun verilog-backward-open-paren ()
37ea4b9b
JB
9644 "Find the open parenthesis that match the current point.
9645Ignore other open parenthesis with matching close parens."
6341f357
DN
9646 (let ((parens 1))
9647 (while (> parens 0)
9648 (unless (verilog-re-search-backward-quick "[()]" nil t)
9649 (error "%s: Mismatching ()" (verilog-point-text)))
9650 (cond ((= (following-char) ?\) )
9651 (setq parens (1+ parens)))
9652 ((= (following-char) ?\( )
9653 (setq parens (1- parens)))))))
9654
9655(defun verilog-backward-open-bracket ()
37ea4b9b
JB
9656 "Find the open bracket that match the current point.
9657Ignore other open bracket with matching close bracket."
6341f357
DN
9658 (let ((parens 1))
9659 (while (> parens 0)
9660 (unless (verilog-re-search-backward-quick "[][]" nil t)
9661 (error "%s: Mismatching []" (verilog-point-text)))
9662 (cond ((= (following-char) ?\] )
9663 (setq parens (1+ parens)))
9664 ((= (following-char) ?\[ )
9665 (setq parens (1- parens)))))))
9666
9667(defun verilog-delete-to-paren ()
9668 "Delete the automatic inst/sense/arg created by autos.
9489a450 9669Deletion stops at the matching end parenthesis, outside comments."
6341f357
DN
9670 (delete-region (point)
9671 (save-excursion
9672 (verilog-backward-open-paren)
9489a450 9673 (verilog-forward-sexp-ign-cmt 1) ;; Moves to paren that closes argdecl's
6341f357
DN
9674 (backward-char 1)
9675 (point))))
9676
9677(defun verilog-auto-star-safe ()
9678 "Return if a .* AUTOINST is safe to delete or expand.
9679It was created by the AUTOS themselves, or by the user."
9680 (and verilog-auto-star-expand
9489a450
MM
9681 (looking-at
9682 (concat "[ \t\n\f,]*\\([)]\\|// " verilog-inst-comment-re "\\)"))))
6341f357
DN
9683
9684(defun verilog-delete-auto-star-all ()
9685 "Delete a .* AUTOINST, if it is safe."
9686 (when (verilog-auto-star-safe)
9687 (verilog-delete-to-paren)))
9688
9689(defun verilog-delete-auto-star-implicit ()
9690 "Delete all .* implicit connections created by `verilog-auto-star'.
9691This function will be called automatically at save unless
9692`verilog-auto-star-save' is set, any non-templated expanded pins will be
9693removed."
9694 (interactive)
9695 (let (paren-pt indent have-close-paren)
9696 (save-excursion
9697 (goto-char (point-min))
9698 ;; We need to match these even outside of comments.
9699 ;; For reasonable performance, we don't check if inside comments, sorry.
9700 (while (re-search-forward "// Implicit \\.\\*" nil t)
9701 (setq paren-pt (point))
9702 (beginning-of-line)
9703 (setq have-close-paren
9704 (save-excursion
9705 (when (search-forward ");" paren-pt t)
9706 (setq indent (current-indentation))
9707 t)))
9708 (delete-region (point) (+ 1 paren-pt)) ; Nuke line incl CR
9709 (when have-close-paren
9710 ;; Delete extra commentary
9711 (save-excursion
9712 (while (progn
9713 (forward-line -1)
9489a450 9714 (looking-at (concat "\\s *//\\s *" verilog-inst-comment-re "\n")))
6341f357
DN
9715 (delete-region (match-beginning 0) (match-end 0))))
9716 ;; If it is simple, we can put the ); on the same line as the last text
9717 (let ((rtn-pt (point)))
9718 (save-excursion
9719 (while (progn (backward-char 1)
9720 (looking-at "[ \t\n\f]")))
9721 (when (looking-at ",")
9722 (delete-region (+ 1 (point)) rtn-pt))))
9723 (when (bolp)
9724 (indent-to indent))
9725 (insert ");\n")
9726 ;; Still need to kill final comma - always is one as we put one after the .*
9727 (re-search-backward ",")
9728 (delete-char 1))))))
9729
9730(defun verilog-delete-auto ()
9731 "Delete the automatic outputs, regs, and wires created by \\[verilog-auto].
9732Use \\[verilog-auto] to re-insert the updated AUTOs.
9733
9734The hooks `verilog-before-delete-auto-hook' and `verilog-delete-auto-hook' are
9735called before and after this function, respectively."
9736 (interactive)
9737 (save-excursion
9738 (if (buffer-file-name)
9739 (find-file-noselect (buffer-file-name))) ;; To check we have latest version
a03c2342
WS
9740 (verilog-save-no-change-functions
9741 (verilog-save-scan-cache
9742 ;; Allow user to customize
9489a450 9743 (verilog-run-hooks 'verilog-before-delete-auto-hook)
a03c2342
WS
9744
9745 ;; Remove those that have multi-line insertions, possibly with parameters
9489a450
MM
9746 ;; We allow anything beginning with AUTO, so that users can add their own
9747 ;; patterns
a03c2342 9748 (verilog-auto-re-search-do
9489a450 9749 (concat "/\\*AUTO[A-Za-z0-9_]+"
a03c2342
WS
9750 ;; Optional parens or quoted parameter or .* for (((...)))
9751 "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
9752 "\\*/")
9753 'verilog-delete-autos-lined)
9754 ;; Remove those that are in parenthesis
9755 (verilog-auto-re-search-do
9756 (concat "/\\*"
9757 (eval-when-compile
9758 (verilog-regexp-words
9759 `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
9760 "AUTOSENSE")))
9761 "\\*/")
9762 'verilog-delete-to-paren)
9763 ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
9764 (verilog-auto-re-search-do "\\.\\*"
9765 'verilog-delete-auto-star-all)
9766 ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
9767 (goto-char (point-min))
9489a450 9768 (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)?$" nil t)
a03c2342 9769 (replace-match ""))
6341f357 9770
a03c2342 9771 ;; Final customize
9489a450 9772 (verilog-run-hooks 'verilog-delete-auto-hook)))))
6341f357
DN
9773\f
9774;;
9775;; Auto inject
9776;;
9777
9778(defun verilog-inject-auto ()
9779 "Examine legacy non-AUTO code and insert AUTOs in appropriate places.
9780
9781Any always @ blocks with sensitivity lists that match computed lists will
9782be replaced with /*AS*/ comments.
9783
37ea4b9b
JB
9784Any cells will get /*AUTOINST*/ added to the end of the pin list.
9785Pins with have identical names will be deleted.
6341f357
DN
9786
9787Argument lists will not be deleted, /*AUTOARG*/ will only be inserted to
9788support adding new ports. You may wish to delete older ports yourself.
9789
9790For example:
9791
1dd4b004 9792 module ExampInject (i, o);
6341f357
DN
9793 input i;
9794 input j;
9795 output o;
9796 always @ (i or j)
9797 o = i | j;
1dd4b004
DN
9798 InstModule instName
9799 (.foobar(baz),
9800 j(j));
6341f357
DN
9801 endmodule
9802
9803Typing \\[verilog-inject-auto] will make this into:
9804
1dd4b004 9805 module ExampInject (i, o/*AUTOARG*/
6341f357
DN
9806 // Inputs
9807 j);
9808 input i;
9809 output o;
9810 always @ (/*AS*/i or j)
9811 o = i | j;
1dd4b004
DN
9812 InstModule instName
9813 (.foobar(baz),
9814 /*AUTOINST*/
9815 // Outputs
9816 j(j));
6341f357
DN
9817 endmodule"
9818 (interactive)
9819 (verilog-auto t))
9820
9821(defun verilog-inject-arg ()
9822 "Inject AUTOARG into new code. See `verilog-inject-auto'."
9823 ;; Presume one module per file.
9824 (save-excursion
9825 (goto-char (point-min))
9826 (while (verilog-re-search-forward-quick "\\<module\\>" nil t)
9827 (let ((endmodp (save-excursion
9828 (verilog-re-search-forward-quick "\\<endmodule\\>" nil t)
9829 (point))))
9830 ;; See if there's already a comment .. inside a comment so not verilog-re-search
9831 (when (not (re-search-forward "/\\*AUTOARG\\*/" endmodp t))
9832 (verilog-re-search-forward-quick ";" nil t)
9833 (backward-char 1)
9489a450 9834 (verilog-backward-syntactic-ws-quick)
6341f357
DN
9835 (backward-char 1) ; Moves to paren that closes argdecl's
9836 (when (looking-at ")")
a03c2342 9837 (verilog-insert "/*AUTOARG*/")))))))
6341f357
DN
9838
9839(defun verilog-inject-sense ()
9840 "Inject AUTOSENSE into new code. See `verilog-inject-auto'."
9841 (save-excursion
9842 (goto-char (point-min))
9843 (while (verilog-re-search-forward-quick "\\<always\\s *@\\s *(" nil t)
5509c6ad 9844 (let* ((start-pt (point))
9c059794 9845 (modi (verilog-modi-current))
5509c6ad 9846 (moddecls (verilog-modi-get-decls modi))
9c059794
DN
9847 pre-sigs
9848 got-sigs)
6341f357 9849 (backward-char 1)
9489a450 9850 (verilog-forward-sexp-ign-cmt 1)
6341f357 9851 (backward-char 1) ;; End )
9489a450 9852 (when (not (verilog-re-search-backward-quick "/\\*\\(AUTOSENSE\\|AS\\)\\*/" start-pt t))
6341f357
DN
9853 (setq pre-sigs (verilog-signals-from-signame
9854 (verilog-read-signals start-pt (point)))
5509c6ad 9855 got-sigs (verilog-auto-sense-sigs moddecls nil))
6341f357
DN
9856 (when (not (or (verilog-signals-not-in pre-sigs got-sigs) ; Both are equal?
9857 (verilog-signals-not-in got-sigs pre-sigs)))
9858 (delete-region start-pt (point))
a03c2342 9859 (verilog-insert "/*AS*/")))))))
6341f357
DN
9860
9861(defun verilog-inject-inst ()
9862 "Inject AUTOINST into new code. See `verilog-inject-auto'."
9863 (save-excursion
9864 (goto-char (point-min))
9865 ;; It's hard to distinguish modules; we'll instead search for pins.
9866 (while (verilog-re-search-forward-quick "\\.\\s *[a-zA-Z0-9`_\$]+\\s *(\\s *[a-zA-Z0-9`_\$]+\\s *)" nil t)
9867 (verilog-backward-open-paren) ;; Inst start
9868 (cond
9869 ((= (preceding-char) ?\#) ;; #(...) parameter section, not pin. Skip.
9870 (forward-char 1)
9871 (verilog-forward-close-paren)) ;; Parameters done
9872 (t
9873 (forward-char 1)
9874 (let ((indent-pt (+ (current-column)))
9875 (end-pt (save-excursion (verilog-forward-close-paren) (point))))
9489a450 9876 (cond ((verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-pt t)
6341f357
DN
9877 (goto-char end-pt)) ;; Already there, continue search with next instance
9878 (t
9879 ;; Delete identical interconnect
9880 (let ((case-fold-search nil)) ;; So we don't convert upper-to-lower, etc
9489a450 9881 (while (verilog-re-search-forward-quick "\\.\\s *\\([a-zA-Z0-9`_\$]+\\)*\\s *(\\s *\\1\\s *)\\s *" end-pt t)
6341f357
DN
9882 (delete-region (match-beginning 0) (match-end 0))
9883 (setq end-pt (- end-pt (- (match-end 0) (match-beginning 0)))) ;; Keep it correct
9884 (while (or (looking-at "[ \t\n\f,]+")
9885 (looking-at "//[^\n]*"))
9886 (delete-region (match-beginning 0) (match-end 0))
9887 (setq end-pt (- end-pt (- (match-end 0) (match-beginning 0)))))))
9888 (verilog-forward-close-paren)
9889 (backward-char 1)
9890 ;; Not verilog-re-search, as we don't want to strip comments
9891 (while (re-search-backward "[ \t\n\f]+" (- (point) 1) t)
9892 (delete-region (match-beginning 0) (match-end 0)))
a03c2342
WS
9893 (verilog-insert "\n")
9894 (verilog-insert-indent "/*AUTOINST*/")))))))))
6341f357 9895\f
9489a450
MM
9896;;
9897;; Auto diff
9898;;
9899
9900(defun verilog-diff-buffers-p (b1 b2 &optional whitespace)
9901 "Return nil if buffers B1 and B2 have same contents.
9902Else, return point in B1 that first mismatches.
9903If optional WHITESPACE true, ignore whitespace."
9904 (save-excursion
9905 (let* ((case-fold-search nil) ;; compare-buffer-substrings cares
9906 (p1 (with-current-buffer b1 (goto-char (point-min))))
9907 (p2 (with-current-buffer b2 (goto-char (point-min))))
9908 (maxp1 (with-current-buffer b1 (point-max)))
9909 (maxp2 (with-current-buffer b2 (point-max)))
9910 (op1 -1) (op2 -1)
9911 progress size)
9912 (while (not (and (eq p1 op1) (eq p2 op2)))
9913 ;; If both windows have whitespace optionally skip over it.
9914 (when whitespace
9915 ;; skip-syntax-* doesn't count \n
9916 (with-current-buffer b1
9917 (goto-char p1)
9918 (skip-chars-forward " \t\n\r\f\v")
9919 (setq p1 (point)))
9920 (with-current-buffer b2
9921 (goto-char p2)
9922 (skip-chars-forward " \t\n\r\f\v")
9923 (setq p2 (point))))
9924 (setq size (min (- maxp1 p1) (- maxp2 p2)))
9925 (setq progress (compare-buffer-substrings b2 p2 (+ size p2)
9926 b1 p1 (+ size p1)))
9927 (setq progress (if (zerop progress) size (1- (abs progress))))
9928 (setq op1 p1 op2 p2
9929 p1 (+ p1 progress)
9930 p2 (+ p2 progress)))
9931 ;; Return value
9932 (if (and (eq p1 maxp1) (eq p2 maxp2))
9933 nil p1))))
9934
9935(defun verilog-diff-file-with-buffer (f1 b2 &optional whitespace show)
9936 "View the differences between file F1 and buffer B2.
9937This requires the external program `diff-command' to be in your `exec-path',
9938and uses `diff-switches' in which you may want to have \"-u\" flag.
9939Ignores WHITESPACE if t, and writes output to stdout if SHOW."
9940 ;; Similar to `diff-buffer-with-file' but works on XEmacs, and doesn't
9941 ;; call `diff' as `diff' has different calling semantics on different
9942 ;; versions of Emacs.
9943 (if (not (file-exists-p f1))
9944 (message "Buffer %s has no associated file on disc" (buffer-name b2))
9945 (with-temp-buffer "*Verilog-Diff*"
9946 (let ((outbuf (current-buffer))
9947 (f2 (make-temp-file "vm-diff-auto-")))
9948 (unwind-protect
9949 (progn
9950 (with-current-buffer b2
9951 (save-restriction
9952 (widen)
9953 (write-region (point-min) (point-max) f2 nil 'nomessage)))
9954 (call-process diff-command nil outbuf t
9955 diff-switches ;; User may want -u in diff-switches
9956 (if whitespace "-b" "")
9957 f1 f2)
9958 ;; Print out results. Alternatively we could have call-processed
9959 ;; ourself, but this way we can reuse diff switches
9960 (when show
9961 (with-current-buffer outbuf (message "%s" (buffer-string))))))
9962 (sit-for 0)
9963 (when (file-exists-p f2)
9964 (delete-file f2))))))
9965
9966(defun verilog-diff-report (b1 b2 diffpt)
9967 "Report differences detected with `verilog-diff-auto'.
9968Differences are between buffers B1 and B2, starting at point
9969DIFFPT. This function is called via `verilog-diff-function'."
9970 (let ((name1 (with-current-buffer b1 (buffer-file-name))))
9971 (message "%%Warning: %s:%d: Difference in AUTO expansion found"
9972 name1 (with-current-buffer b1 (1+ (count-lines (point-min) (point)))))
9973 (cond (noninteractive
9974 (verilog-diff-file-with-buffer name1 b2 t t))
9975 (t
9976 (ediff-buffers b1 b2)))))
9977
9978(defun verilog-diff-auto ()
9979 "Expand AUTOs in a temporary buffer and indicate any changes.
9980Whitespace differences are ignored to determine identicalness, but
9981once a difference is detected, whitespace differences may be shown.
9982
9983To call this from the command line, see \\[verilog-batch-diff-auto].
9984
9985The action on differences is selected with
9986`verilog-diff-function'. The default is `verilog-diff-report'
9987which will report an error and run `ediff' in interactive mode,
9988or `diff' in batch mode."
9989 (interactive)
9990 (let ((b1 (current-buffer)) b2 diffpt
9991 (name1 (buffer-file-name))
9992 (newname "*Verilog-Diff*"))
9993 (save-excursion
9994 (when (get-buffer newname)
9995 (kill-buffer newname))
9996 (setq b2 (let (buffer-file-name) ;; Else clone is upset
9997 (clone-buffer newname)))
9998 (with-current-buffer b2
9999 ;; auto requires the filename, but can't have same filename in two
10000 ;; buffers; so override both b1 and b2's names
10001 (let ((buffer-file-name name1))
10002 (unwind-protect
10003 (progn
10004 (with-current-buffer b1 (setq buffer-file-name nil))
10005 (verilog-auto)
10006 (when (not verilog-auto-star-save)
10007 (verilog-delete-auto-star-implicit)))
10008 ;; Restore name if unwind
10009 (with-current-buffer b1 (setq buffer-file-name name1)))))
10010 ;;
10011 (setq diffpt (verilog-diff-buffers-p b1 b2 t))
10012 (cond ((not diffpt)
10013 (unless noninteractive (message "AUTO expansion identical"))
10014 (kill-buffer newname)) ;; Nice to cleanup after oneself
10015 (t
10016 (funcall verilog-diff-function b1 b2 diffpt)))
10017 ;; Return result of compare
10018 diffpt)))
10019
10020\f
6341f357
DN
10021;;
10022;; Auto save
10023;;
10024
10025(defun verilog-auto-save-check ()
10026 "On saving see if we need auto update."
10027 (cond ((not verilog-auto-save-policy)) ; disabled
10028 ((not (save-excursion
10029 (save-match-data
10030 (let ((case-fold-search nil))
10031 (goto-char (point-min))
10032 (re-search-forward "AUTO" nil t))))))
10033 ((eq verilog-auto-save-policy 'force)
10034 (verilog-auto))
10035 ((not (buffer-modified-p)))
a03c2342 10036 ((eq verilog-auto-update-tick (buffer-chars-modified-tick))) ; up-to-date
6341f357
DN
10037 ((eq verilog-auto-save-policy 'detect)
10038 (verilog-auto))
10039 (t
10040 (when (yes-or-no-p "AUTO statements not recomputed, do it now? ")
10041 (verilog-auto))
10042 ;; Don't ask again if didn't update
a03c2342 10043 (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))))
6341f357
DN
10044 (when (not verilog-auto-star-save)
10045 (verilog-delete-auto-star-implicit))
10046 nil) ;; Always return nil -- we don't write the file ourselves
10047
10048(defun verilog-auto-read-locals ()
10049 "Return file local variable segment at bottom of file."
10050 (save-excursion
10051 (goto-char (point-max))
10052 (if (re-search-backward "Local Variables:" nil t)
10053 (buffer-substring-no-properties (point) (point-max))
10054 "")))
10055
10056(defun verilog-auto-reeval-locals (&optional force)
10057 "Read file local variable segment at bottom of file if it has changed.
10058If FORCE, always reread it."
6341f357
DN
10059 (let ((curlocal (verilog-auto-read-locals)))
10060 (when (or force (not (equal verilog-auto-last-file-locals curlocal)))
175069ef 10061 (set (make-local-variable 'verilog-auto-last-file-locals) curlocal)
a3a8b002
DN
10062 ;; Note this may cause this function to be recursively invoked,
10063 ;; because hack-local-variables may call (verilog-mode)
6341f357
DN
10064 ;; The above when statement will prevent it from recursing forever.
10065 (hack-local-variables)
10066 t)))
10067\f
10068;;
10069;; Auto creation
10070;;
10071
10072(defun verilog-auto-arg-ports (sigs message indent-pt)
10073 "Print a list of ports for a AUTOINST.
10074Takes SIGS list, adds MESSAGE to front and inserts each at INDENT-PT."
10075 (when sigs
a3a8b002
DN
10076 (when verilog-auto-arg-sort
10077 (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
6341f357
DN
10078 (insert "\n")
10079 (indent-to indent-pt)
10080 (insert message)
10081 (insert "\n")
10082 (let ((space ""))
10083 (indent-to indent-pt)
10084 (while sigs
10085 (cond ((> (+ 2 (current-column) (length (verilog-sig-name (car sigs)))) fill-column)
10086 (insert "\n")
10087 (indent-to indent-pt))
10088 (t (insert space)))
10089 (insert (verilog-sig-name (car sigs)) ",")
10090 (setq sigs (cdr sigs)
10091 space " ")))))
10092
10093(defun verilog-auto-arg ()
10094 "Expand AUTOARG statements.
10095Replace the argument declarations at the beginning of the
10096module with ones automatically derived from input and output
10097statements. This can be dangerous if the module is instantiated
10098using position-based connections, so use only name-based when
10099instantiating the resulting module. Long lines are split based
10100on the `fill-column', see \\[set-fill-column].
10101
10102Limitations:
10103 Concatenation and outputting partial busses is not supported.
10104
10105 Typedefs must match `verilog-typedef-regexp', which is disabled by default.
10106
10107For example:
10108
1dd4b004 10109 module ExampArg (/*AUTOARG*/);
6341f357
DN
10110 input i;
10111 output o;
10112 endmodule
10113
10114Typing \\[verilog-auto] will make this into:
10115
1dd4b004 10116 module ExampArg (/*AUTOARG*/
6341f357
DN
10117 // Outputs
10118 o,
10119 // Inputs
10120 i
10121 );
10122 input i;
10123 output o;
10124 endmodule
10125
a3a8b002
DN
10126The argument declarations may be printed in declaration order to best suit
10127order based instantiations, or alphabetically, based on the
10128`verilog-auto-arg-sort' variable.
10129
6341f357
DN
10130Any ports declared between the ( and /*AUTOARG*/ are presumed to be
10131predeclared and are not redeclared by AUTOARG. AUTOARG will make a
37ea4b9b
JB
10132conservative guess on adding a comma for the first signal, if you have
10133any ifdefs or complicated expressions before the AUTOARG you will need
10134to choose the comma yourself.
6341f357
DN
10135
10136Avoid declaring ports manually, as it makes code harder to maintain."
10137 (save-excursion
5509c6ad
DN
10138 (let* ((modi (verilog-modi-current))
10139 (moddecls (verilog-modi-get-decls modi))
9c059794 10140 (skip-pins (aref (verilog-read-arg-pins) 0)))
6341f357
DN
10141 (verilog-repair-open-comma)
10142 (verilog-auto-arg-ports (verilog-signals-not-in
5509c6ad 10143 (verilog-decls-get-outputs moddecls)
6341f357
DN
10144 skip-pins)
10145 "// Outputs"
10146 verilog-indent-level-declaration)
10147 (verilog-auto-arg-ports (verilog-signals-not-in
5509c6ad 10148 (verilog-decls-get-inouts moddecls)
6341f357
DN
10149 skip-pins)
10150 "// Inouts"
10151 verilog-indent-level-declaration)
10152 (verilog-auto-arg-ports (verilog-signals-not-in
5509c6ad 10153 (verilog-decls-get-inputs moddecls)
6341f357
DN
10154 skip-pins)
10155 "// Inputs"
10156 verilog-indent-level-declaration)
10157 (verilog-repair-close-comma)
10158 (unless (eq (char-before) ?/ )
10159 (insert "\n"))
60618039 10160 (indent-to verilog-indent-level-declaration))))
6341f357
DN
10161
10162(defun verilog-auto-inst-port-map (port-st)
10163 nil)
10164
6341f357
DN
10165(defvar vl-cell-type nil "See `verilog-auto-inst'.") ; Prevent compile warning
10166(defvar vl-cell-name nil "See `verilog-auto-inst'.") ; Prevent compile warning
a3a8b002 10167(defvar vl-modport nil "See `verilog-auto-inst'.") ; Prevent compile warning
6341f357
DN
10168(defvar vl-name nil "See `verilog-auto-inst'.") ; Prevent compile warning
10169(defvar vl-width nil "See `verilog-auto-inst'.") ; Prevent compile warning
10170(defvar vl-dir nil "See `verilog-auto-inst'.") ; Prevent compile warning
fd9ea9d3
WS
10171(defvar vl-bits nil "See `verilog-auto-inst'.") ; Prevent compile warning
10172(defvar vl-mbits nil "See `verilog-auto-inst'.") ; Prevent compile warning
6341f357 10173
4c5e69c6 10174(defun verilog-auto-inst-port (port-st indent-pt tpl-list tpl-num for-star par-values)
6341f357
DN
10175 "Print out a instantiation connection for this PORT-ST.
10176Insert to INDENT-PT, use template TPL-LIST.
10177@ are instantiation numbers, replaced with TPL-NUM.
60618039 10178@\"(expression @)\" are evaluated, with @ as a variable.
4c5e69c6
DN
10179If FOR-STAR add comment it is a .* expansion.
10180If PAR-VALUES replace final strings with these parameter values."
6341f357
DN
10181 (let* ((port (verilog-sig-name port-st))
10182 (tpl-ass (or (assoc port (car tpl-list))
10183 (verilog-auto-inst-port-map port-st)))
10184 ;; vl-* are documented for user use
10185 (vl-name (verilog-sig-name port-st))
10186 (vl-width (verilog-sig-width port-st))
a3a8b002 10187 (vl-modport (verilog-sig-modport port-st))
a03c2342 10188 (vl-mbits (if (verilog-sig-multidim port-st)
fd9ea9d3 10189 (verilog-sig-multidim-string port-st) ""))
6341f357
DN
10190 (vl-bits (if (or verilog-auto-inst-vector
10191 (not (assoc port vector-skip-list))
10192 (not (equal (verilog-sig-bits port-st)
10193 (verilog-sig-bits (assoc port vector-skip-list)))))
10194 (or (verilog-sig-bits port-st) "")
10195 ""))
4c5e69c6 10196 (case-fold-search nil)
7cb1c4d7
DN
10197 (check-values par-values)
10198 tpl-net)
4c5e69c6
DN
10199 ;; Replace parameters in bit-width
10200 (when (and check-values
10201 (not (equal vl-bits "")))
10202 (while check-values
10203 (setq vl-bits (verilog-string-replace-matches
10204 (concat "\\<" (nth 0 (car check-values)) "\\>")
10205 (concat "(" (nth 1 (car check-values)) ")")
10206 t t vl-bits)
9489a450
MM
10207 vl-mbits (verilog-string-replace-matches
10208 (concat "\\<" (nth 0 (car check-values)) "\\>")
10209 (concat "(" (nth 1 (car check-values)) ")")
10210 t t vl-mbits)
4c5e69c6 10211 check-values (cdr check-values)))
9489a450
MM
10212 (setq vl-bits (verilog-simplify-range-expression vl-bits)
10213 vl-mbits (verilog-simplify-range-expression vl-mbits)
10214 vl-width (verilog-make-width-expression vl-bits))) ; Not in the loop for speed
7cb1c4d7 10215 ;; Default net value if not found
a3a8b002
DN
10216 (setq tpl-net (concat port
10217 (if vl-modport (concat "." vl-modport) "")
10218 (if (verilog-sig-multidim port-st)
9489a450 10219 (concat "/*" vl-mbits vl-bits "*/")
a3a8b002 10220 (concat vl-bits))))
6341f357
DN
10221 ;; Find template
10222 (cond (tpl-ass ; Template of exact port name
10223 (setq tpl-net (nth 1 tpl-ass)))
10224 ((nth 1 tpl-list) ; Wildcards in template, search them
10225 (let ((wildcards (nth 1 tpl-list)))
10226 (while wildcards
10227 (when (string-match (nth 0 (car wildcards)) port)
10228 (setq tpl-ass (car wildcards) ; so allow @ parsing
10229 tpl-net (replace-match (nth 1 (car wildcards))
10230 t nil port)))
10231 (setq wildcards (cdr wildcards))))))
10232 ;; Parse Templated variable
10233 (when tpl-ass
10234 ;; Evaluate @"(lispcode)"
10235 (when (string-match "@\".*[^\\]\"" tpl-net)
10236 (while (string-match "@\"\\(\\([^\\\"]*\\(\\\\.\\)*\\)*\\)\"" tpl-net)
10237 (setq tpl-net
10238 (concat
10239 (substring tpl-net 0 (match-beginning 0))
10240 (save-match-data
10241 (let* ((expr (match-string 1 tpl-net))
10242 (value
10243 (progn
10244 (setq expr (verilog-string-replace-matches "\\\\\"" "\"" nil nil expr))
10245 (setq expr (verilog-string-replace-matches "@" tpl-num nil nil expr))
10246 (prin1 (eval (car (read-from-string expr)))
10247 (lambda (ch) ())))))
10248 (if (numberp value) (setq value (number-to-string value)))
60618039 10249 value))
6341f357
DN
10250 (substring tpl-net (match-end 0))))))
10251 ;; Replace @ and [] magic variables in final output
10252 (setq tpl-net (verilog-string-replace-matches "@" tpl-num nil nil tpl-net))
60618039 10253 (setq tpl-net (verilog-string-replace-matches "\\[\\]" vl-bits nil nil tpl-net)))
4c5e69c6 10254 ;; Insert it
6341f357
DN
10255 (indent-to indent-pt)
10256 (insert "." port)
a03c2342
WS
10257 (unless (and verilog-auto-inst-dot-name
10258 (equal port tpl-net))
10259 (indent-to verilog-auto-inst-column)
10260 (insert "(" tpl-net ")"))
10261 (insert ",")
6341f357
DN
10262 (cond (tpl-ass
10263 (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
10264 verilog-auto-inst-column))
9489a450
MM
10265 ;; verilog-insert requires the complete comment in one call - including the newline
10266 (cond ((equal verilog-auto-inst-template-numbers `lhs)
10267 (verilog-insert " // Templated"
10268 " LHS: " (nth 0 tpl-ass)
10269 "\n"))
10270 (verilog-auto-inst-template-numbers
10271 (verilog-insert " // Templated"
10272 " T" (int-to-string (nth 2 tpl-ass))
10273 " L" (int-to-string (nth 3 tpl-ass))
10274 "\n"))
10275 (t
10276 (verilog-insert " // Templated\n"))))
6341f357
DN
10277 (for-star
10278 (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
10279 verilog-auto-inst-column))
9489a450
MM
10280 (verilog-insert " // Implicit .\*\n")) ;For some reason the . or * must be escaped...
10281 (t
10282 (insert "\n")))))
6341f357
DN
10283;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
10284;;(x "incom[@\"(+ (* 8 @) 7)\":@\"(* 8 @)\"]")
10285;;(x ".out (outgo[@\"(concat (+ (* 8 @) 7) \\\":\\\" ( * 8 @))\"]));")
10286
9489a450
MM
10287(defun verilog-auto-inst-port-list (sig-list indent-pt tpl-list tpl-num for-star par-values)
10288 "For `verilog-auto-inst' print a list of ports using `verilog-auto-inst-port'."
10289 (when verilog-auto-inst-sort
10290 (setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare)))
10291 (mapc (lambda (port)
10292 (verilog-auto-inst-port port indent-pt
10293 tpl-list tpl-num for-star par-values))
10294 sig-list))
10295
6341f357
DN
10296(defun verilog-auto-inst-first ()
10297 "Insert , etc before first ever port in this instant, as part of \\[verilog-auto-inst]."
10298 ;; Do we need a trailing comma?
10299 ;; There maybe a ifdef or something similar before us. What a mess. Thus
86a4c7ac 10300 ;; to avoid trouble we only insert on preceding ) or *.
6341f357
DN
10301 ;; Insert first port on new line
10302 (insert "\n") ;; Must insert before search, so point will move forward if insert comma
10303 (save-excursion
9489a450 10304 (verilog-re-search-backward-quick "[^ \t\n\f]" nil nil)
6341f357
DN
10305 (when (looking-at ")\\|\\*") ;; Generally don't insert, unless we are fairly sure
10306 (forward-char 1)
10307 (insert ","))))
10308
10309(defun verilog-auto-star ()
10310 "Expand SystemVerilog .* pins, as part of \\[verilog-auto].
10311
10312If `verilog-auto-star-expand' is set, .* pins are treated if they were
37ea4b9b 10313AUTOINST statements, otherwise they are ignored. For safety, Verilog mode
6341f357
DN
10314will also ignore any .* that are not last in your pin list (this prevents
10315it from deleting pins following the .* when it expands the AUTOINST.)
10316
10317On writing your file, unless `verilog-auto-star-save' is set, any
10318non-templated expanded pins will be removed. You may do this at any time
10319with \\[verilog-delete-auto-star-implicit].
10320
10321If you are converting a module to use .* for the first time, you may wish
10322to use \\[verilog-inject-auto] and then replace the created AUTOINST with .*.
10323
10324See `verilog-auto-inst' for examples, templates, and more information."
10325 (when (verilog-auto-star-safe)
10326 (verilog-auto-inst)))
10327
10328(defun verilog-auto-inst ()
10329 "Expand AUTOINST statements, as part of \\[verilog-auto].
a03c2342
WS
10330Replace the pin connections to an instantiation or interface
10331declaration with ones automatically derived from the module or
10332interface header of the instantiated item.
6341f357
DN
10333
10334If `verilog-auto-star-expand' is set, also expand SystemVerilog .* ports,
10335and delete them before saving unless `verilog-auto-star-save' is set.
10336See `verilog-auto-star' for more information.
10337
9489a450
MM
10338The pins are printed in declaration order or alphabetically,
10339based on the `verilog-auto-inst-sort' variable.
10340
6341f357
DN
10341Limitations:
10342 Module names must be resolvable to filenames by adding a
10343 `verilog-library-extensions', and being found in the same directory, or
10344 by changing the variable `verilog-library-flags' or
10345 `verilog-library-directories'. Macros `modname are translated through the
10346 vh-{name} Emacs variable, if that is not found, it just ignores the `.
10347
10348 In templates you must have one signal per line, ending in a ), or ));,
10349 and have proper () nesting, including a final ); to end the template.
10350
10351 Typedefs must match `verilog-typedef-regexp', which is disabled by default.
10352
37ea4b9b 10353 SystemVerilog multidimensional input/output has only experimental support.
6341f357 10354
a03c2342
WS
10355 SystemVerilog .name syntax is used if `verilog-auto-inst-dot-name' is set.
10356
4c5e69c6
DN
10357 Parameters referenced by the instantiation will remain symbolic, unless
10358 `verilog-auto-inst-param-value' is set.
10359
a03c2342
WS
10360 Gate primitives (and/or) may have AUTOINST for the purpose of
10361 AUTOWIRE declarations, etc. Gates are the only case when
10362 position based connections are passed.
10363
1dd4b004 10364For example, first take the submodule InstModule.v:
6341f357 10365
a03c2342 10366 module InstModule (o,i);
6341f357
DN
10367 output [31:0] o;
10368 input i;
10369 wire [31:0] o = {32{i}};
10370 endmodule
10371
10372This is then used in a upper level module:
10373
a03c2342 10374 module ExampInst (o,i);
6341f357
DN
10375 output o;
10376 input i;
1dd4b004
DN
10377 InstModule instName
10378 (/*AUTOINST*/);
6341f357
DN
10379 endmodule
10380
10381Typing \\[verilog-auto] will make this into:
10382
a03c2342 10383 module ExampInst (o,i);
6341f357
DN
10384 output o;
10385 input i;
1dd4b004
DN
10386 InstModule instName
10387 (/*AUTOINST*/
10388 // Outputs
10389 .ov (ov[31:0]),
10390 // Inputs
10391 .i (i));
6341f357
DN
10392 endmodule
10393
10394Where the list of inputs and outputs came from the inst module.
10395\f
10396Exceptions:
10397
10398 Unless you are instantiating a module multiple times, or the module is
37ea4b9b 10399 something trivial like an adder, DO NOT CHANGE SIGNAL NAMES ACROSS HIERARCHY.
6341f357 10400 It just makes for unmaintainable code. To sanitize signal names, try
855b42a2 10401 vrename from URL `http://www.veripool.org'.
6341f357
DN
10402
10403 When you need to violate this suggestion there are two ways to list
10404 exceptions, placing them before the AUTOINST, or using templates.
10405
10406 Any ports defined before the /*AUTOINST*/ are not included in the list of
10407 automatics. This is similar to making a template as described below, but
10408 is restricted to simple connections just like you normally make. Also note
10409 that any signals before the AUTOINST will only be picked up by AUTOWIRE if
10410 you have the appropriate // Input or // Output comment, and exactly the
10411 same line formatting as AUTOINST itself uses.
10412
1dd4b004
DN
10413 InstModule instName
10414 (// Inputs
10415 .i (my_i_dont_mess_with_it),
10416 /*AUTOINST*/
10417 // Outputs
10418 .ov (ov[31:0]));
6341f357
DN
10419
10420\f
10421Templates:
10422
10423 For multiple instantiations based upon a single template, create a
10424 commented out template:
10425
1dd4b004 10426 /* InstModule AUTO_TEMPLATE (
6341f357
DN
10427 .sig3 (sigz[]),
10428 );
10429 */
10430
37ea4b9b 10431 Templates go ABOVE the instantiation(s). When an instantiation is
6341f357
DN
10432 expanded `verilog-mode' simply searches up for the closest template.
10433 Thus you can have multiple templates for the same module, just alternate
37ea4b9b 10434 between the template for an instantiation and the instantiation itself.
6341f357
DN
10435
10436 The module name must be the same as the name of the module in the
10437 instantiation name, and the code \"AUTO_TEMPLATE\" must be in these exact
10438 words and capitalized. Only signals that must be different for each
10439 instantiation need to be listed.
10440
10441 Inside a template, a [] in a connection name (with nothing else inside
10442 the brackets) will be replaced by the same bus subscript as it is being
10443 connected to, or the [] will be removed if it is a single bit signal.
10444 Generally it is a good idea to do this for all connections in a template,
10445 as then they will work for any width signal, and with AUTOWIRE. See
10446 PTL_BUS becoming PTL_BUSNEW below.
10447
10448 If you have a complicated template, set `verilog-auto-inst-template-numbers'
10449 to see which regexps are matching. Don't leave that mode set after
10450 debugging is completed though, it will result in lots of extra differences
10451 and merge conflicts.
10452
10453 For example:
10454
1dd4b004 10455 /* InstModule AUTO_TEMPLATE (
6341f357
DN
10456 .ptl_bus (ptl_busnew[]),
10457 );
10458 */
1dd4b004 10459 InstModule ms2m (/*AUTOINST*/);
6341f357
DN
10460
10461 Typing \\[verilog-auto] will make this into:
10462
1dd4b004 10463 InstModule ms2m (/*AUTOINST*/
6341f357
DN
10464 // Outputs
10465 .NotInTemplate (NotInTemplate),
10466 .ptl_bus (ptl_busnew[3:0]), // Templated
10467 ....
9489a450
MM
10468
10469\f
10470Multiple Module Templates:
10471
10472 The same template lines can be applied to multiple modules with
10473 the syntax as follows:
10474
10475 /* InstModuleA AUTO_TEMPLATE
10476 InstModuleB AUTO_TEMPLATE
10477 InstModuleC AUTO_TEMPLATE
10478 InstModuleD AUTO_TEMPLATE (
10479 .ptl_bus (ptl_busnew[]),
10480 );
10481 */
10482
10483 Note there is only one AUTO_TEMPLATE opening parenthesis.
6341f357
DN
10484\f
10485@ Templates:
10486
10487 It is common to instantiate a cell multiple times, so templates make it
10488 trivial to substitute part of the cell name into the connection name.
10489
1dd4b004 10490 /* InstName AUTO_TEMPLATE <optional \"REGEXP\"> (
6341f357
DN
10491 .sig1 (sigx[@]),
10492 .sig2 (sigy[@\"(% (+ 1 @) 4)\"]),
10493 );
10494 */
10495
10496 If no regular expression is provided immediately after the AUTO_TEMPLATE
10497 keyword, then the @ character in any connection names will be replaced
10498 with the instantiation number; the first digits found in the cell's
10499 instantiation name.
10500
10501 If a regular expression is provided, the @ character will be replaced
10502 with the first \(\) grouping that matches against the cell name. Using a
10503 regexp of \"\\([0-9]+\\)\" provides identical values for @ as when no
10504 regexp is provided. If you use multiple layers of parenthesis,
10505 \"test\\([^0-9]+\\)_\\([0-9]+\\)\" would replace @ with non-number
10506 characters after test and before _, whereas
10507 \"\\(test\\([a-z]+\\)_\\([0-9]+\\)\\)\" would replace @ with the entire
10508 match.
10509
10510 For example:
10511
1dd4b004 10512 /* InstModule AUTO_TEMPLATE (
6341f357
DN
10513 .ptl_mapvalidx (ptl_mapvalid[@]),
10514 .ptl_mapvalidp1x (ptl_mapvalid[@\"(% (+ 1 @) 4)\"]),
10515 );
10516 */
1dd4b004 10517 InstModule ms2m (/*AUTOINST*/);
6341f357
DN
10518
10519 Typing \\[verilog-auto] will make this into:
10520
1dd4b004 10521 InstModule ms2m (/*AUTOINST*/
6341f357
DN
10522 // Outputs
10523 .ptl_mapvalidx (ptl_mapvalid[2]),
10524 .ptl_mapvalidp1x (ptl_mapvalid[3]));
10525
10526 Note the @ character was replaced with the 2 from \"ms2m\".
10527
10528 Alternatively, using a regular expression for @:
10529
1dd4b004 10530 /* InstModule AUTO_TEMPLATE \"_\\([a-z]+\\)\" (
6341f357
DN
10531 .ptl_mapvalidx (@_ptl_mapvalid),
10532 .ptl_mapvalidp1x (ptl_mapvalid_@),
10533 );
10534 */
1dd4b004
DN
10535 InstModule ms2_FOO (/*AUTOINST*/);
10536 InstModule ms2_BAR (/*AUTOINST*/);
6341f357
DN
10537
10538 Typing \\[verilog-auto] will make this into:
10539
1dd4b004 10540 InstModule ms2_FOO (/*AUTOINST*/
6341f357
DN
10541 // Outputs
10542 .ptl_mapvalidx (FOO_ptl_mapvalid),
10543 .ptl_mapvalidp1x (ptl_mapvalid_FOO));
1dd4b004 10544 InstModule ms2_BAR (/*AUTOINST*/
6341f357
DN
10545 // Outputs
10546 .ptl_mapvalidx (BAR_ptl_mapvalid),
10547 .ptl_mapvalidp1x (ptl_mapvalid_BAR));
10548
10549\f
10550Regexp Templates:
10551
10552 A template entry of the form
10553
10554 .pci_req\\([0-9]+\\)_l (pci_req_jtag_[\\1]),
10555
37ea4b9b 10556 will apply an Emacs style regular expression search for any port beginning
6341f357
DN
10557 in pci_req followed by numbers and ending in _l and connecting that to
10558 the pci_req_jtag_[] net, with the bus subscript coming from what matches
10559 inside the first set of \\( \\). Thus pci_req2_l becomes pci_req_jtag_[2].
10560
10561 Since \\([0-9]+\\) is so common and ugly to read, a @ in the port name
0e5c8aed 10562 does the same thing. (Note a @ in the connection/replacement text is
6341f357
DN
10563 completely different -- still use \\1 there!) Thus this is the same as
10564 the above template:
10565
10566 .pci_req@_l (pci_req_jtag_[\\1]),
10567
10568 Here's another example to remove the _l, useful when naming conventions
10569 specify _ alone to mean active low. Note the use of [] to keep the bus
10570 subscript:
10571
10572 .\\(.*\\)_l (\\1_[]),
10573\f
10574Lisp Templates:
10575
10576 First any regular expression template is expanded.
10577
10578 If the syntax @\"( ... )\" is found in a connection, the expression in
10579 quotes will be evaluated as a Lisp expression, with @ replaced by the
10580 instantiation number. The MAPVALIDP1X example above would put @+1 modulo
10581 4 into the brackets. Quote all double-quotes inside the expression with
0e5c8aed
DN
10582 a leading backslash (\\\"...\\\"); or if the Lisp template is also a
10583 regexp template backslash the backslash quote (\\\\\"...\\\\\").
10584
10585 There are special variables defined that are useful in these
10586 Lisp functions:
6341f357 10587
37ea4b9b
JB
10588 vl-name Name portion of the input/output port.
10589 vl-bits Bus bits portion of the input/output port ('[2:0]').
fd9ea9d3 10590 vl-mbits Multidimensional array bits for port ('[2:0][3:0]').
37ea4b9b 10591 vl-width Width of the input/output port ('3' for [2:0]).
6341f357 10592 May be a (...) expression if bits isn't a constant.
a3a8b002
DN
10593 vl-dir Direction of the pin input/output/inout/interface.
10594 vl-modport The modport, if an interface with a modport.
1dd4b004
DN
10595 vl-cell-type Module name/type of the cell ('InstModule').
10596 vl-cell-name Instance name of the cell ('instName').
6341f357
DN
10597
10598 Normal Lisp variables may be used in expressions. See
10599 `verilog-read-defines' which can set vh-{definename} variables for use
10600 here. Also, any comments of the form:
10601
10602 /*AUTO_LISP(setq foo 1)*/
10603
10604 will evaluate any Lisp expression inside the parenthesis between the
10605 beginning of the buffer and the point of the AUTOINST. This allows
10606 functions to be defined or variables to be changed between instantiations.
a3a8b002
DN
10607 (See also `verilog-auto-insert-lisp' if you want the output from your
10608 lisp function to be inserted.)
6341f357
DN
10609
10610 Note that when using lisp expressions errors may occur when @ is not a
37ea4b9b 10611 number; you may need to use the standard Emacs Lisp functions
6341f357
DN
10612 `number-to-string' and `string-to-number'.
10613
10614 After the evaluation is completed, @ substitution and [] substitution
0e5c8aed
DN
10615 occur.
10616
10617For more information see the \\[verilog-faq] and forums at URL
10618`http://www.veripool.org'."
6341f357
DN
10619 (save-excursion
10620 ;; Find beginning
10621 (let* ((pt (point))
10622 (for-star (save-excursion (backward-char 2) (looking-at "\\.\\*")))
10623 (indent-pt (save-excursion (verilog-backward-open-paren)
10624 (1+ (current-column))))
10625 (verilog-auto-inst-column (max verilog-auto-inst-column
10626 (+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
10627 (modi (verilog-modi-current))
5509c6ad 10628 (moddecls (verilog-modi-get-decls modi))
6341f357 10629 (vector-skip-list (unless verilog-auto-inst-vector
5509c6ad
DN
10630 (verilog-decls-get-signals moddecls)))
10631 submod submodi submoddecls
4c5e69c6
DN
10632 inst skip-pins tpl-list tpl-num did-first par-values)
10633
6341f357
DN
10634 ;; Find module name that is instantiated
10635 (setq submod (verilog-read-inst-module)
10636 inst (verilog-read-inst-name)
10637 vl-cell-type submod
10638 vl-cell-name inst
10639 skip-pins (aref (verilog-read-inst-pins) 0))
10640
10641 ;; Parse any AUTO_LISP() before here
10642 (verilog-read-auto-lisp (point-min) pt)
10643
4c5e69c6
DN
10644 ;; Read parameters (after AUTO_LISP)
10645 (setq par-values (and verilog-auto-inst-param-value
10646 (verilog-read-inst-param-value)))
10647
6341f357
DN
10648 ;; Lookup position, etc of submodule
10649 ;; Note this may raise an error
a03c2342
WS
10650 (when (and (not (member submod verilog-gate-keywords))
10651 (setq submodi (verilog-modi-lookup submod t)))
5509c6ad 10652 (setq submoddecls (verilog-modi-get-decls submodi))
6341f357
DN
10653 ;; If there's a number in the instantiation, it may be a argument to the
10654 ;; automatic variable instantiation program.
10655 (let* ((tpl-info (verilog-read-auto-template submod))
10656 (tpl-regexp (aref tpl-info 0)))
10657 (setq tpl-num (if (string-match tpl-regexp inst)
10658 (match-string 1 inst)
10659 "")
10660 tpl-list (aref tpl-info 1)))
10661 ;; Find submodule's signals and dump
a03c2342
WS
10662 (let ((sig-list (and (equal (verilog-modi-get-type submodi) "interface")
10663 (verilog-signals-not-in
9489a450 10664 (verilog-decls-get-vars submoddecls)
a03c2342
WS
10665 skip-pins)))
10666 (vl-dir "interfaced"))
10667 (when sig-list
10668 (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
10669 ;; Note these are searched for in verilog-read-sub-decls.
10670 (verilog-insert-indent "// Interfaced\n")
9489a450
MM
10671 (verilog-auto-inst-port-list sig-list indent-pt
10672 tpl-list tpl-num for-star par-values)))
a3a8b002
DN
10673 (let ((sig-list (verilog-signals-not-in
10674 (verilog-decls-get-interfaces submoddecls)
10675 skip-pins))
10676 (vl-dir "interface"))
10677 (when sig-list
10678 (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
a3a8b002 10679 ;; Note these are searched for in verilog-read-sub-decls.
a03c2342 10680 (verilog-insert-indent "// Interfaces\n")
9489a450
MM
10681 (verilog-auto-inst-port-list sig-list indent-pt
10682 tpl-list tpl-num for-star par-values)))
6341f357 10683 (let ((sig-list (verilog-signals-not-in
5509c6ad 10684 (verilog-decls-get-outputs submoddecls)
6341f357
DN
10685 skip-pins))
10686 (vl-dir "output"))
10687 (when sig-list
10688 (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
a03c2342 10689 (verilog-insert-indent "// Outputs\n")
9489a450
MM
10690 (verilog-auto-inst-port-list sig-list indent-pt
10691 tpl-list tpl-num for-star par-values)))
6341f357 10692 (let ((sig-list (verilog-signals-not-in
5509c6ad 10693 (verilog-decls-get-inouts submoddecls)
6341f357
DN
10694 skip-pins))
10695 (vl-dir "inout"))
10696 (when sig-list
10697 (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
a03c2342 10698 (verilog-insert-indent "// Inouts\n")
9489a450
MM
10699 (verilog-auto-inst-port-list sig-list indent-pt
10700 tpl-list tpl-num for-star par-values)))
6341f357 10701 (let ((sig-list (verilog-signals-not-in
5509c6ad 10702 (verilog-decls-get-inputs submoddecls)
6341f357
DN
10703 skip-pins))
10704 (vl-dir "input"))
10705 (when sig-list
10706 (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
a03c2342 10707 (verilog-insert-indent "// Inputs\n")
9489a450
MM
10708 (verilog-auto-inst-port-list sig-list indent-pt
10709 tpl-list tpl-num for-star par-values)))
6341f357
DN
10710 ;; Kill extra semi
10711 (save-excursion
10712 (cond (did-first
10713 (re-search-backward "," pt t)
10714 (delete-char 1)
10715 (insert ");")
10716 (search-forward "\n") ;; Added by inst-port
d355a0b7 10717 (delete-char -1)
6341f357 10718 (if (search-forward ")" nil t) ;; From user, moved up a line
d355a0b7 10719 (delete-char -1))
6341f357 10720 (if (search-forward ";" nil t) ;; Don't error if user had syntax error and forgot it
d355a0b7 10721 (delete-char -1)))))))))
6341f357
DN
10722
10723(defun verilog-auto-inst-param ()
10724 "Expand AUTOINSTPARAM statements, as part of \\[verilog-auto].
10725Replace the parameter connections to an instantiation with ones
10726automatically derived from the module header of the instantiated netlist.
10727
10728See \\[verilog-auto-inst] for limitations, and templates to customize the
10729output.
10730
1dd4b004 10731For example, first take the submodule InstModule.v:
6341f357 10732
a03c2342 10733 module InstModule (o,i);
6341f357
DN
10734 parameter PAR;
10735 endmodule
10736
10737This is then used in a upper level module:
10738
a03c2342 10739 module ExampInst (o,i);
6341f357 10740 parameter PAR;
1dd4b004
DN
10741 InstModule #(/*AUTOINSTPARAM*/)
10742 instName (/*AUTOINST*/);
6341f357
DN
10743 endmodule
10744
10745Typing \\[verilog-auto] will make this into:
10746
a03c2342 10747 module ExampInst (o,i);
6341f357
DN
10748 output o;
10749 input i;
1dd4b004
DN
10750 InstModule #(/*AUTOINSTPARAM*/
10751 // Parameters
10752 .PAR (PAR));
10753 instName (/*AUTOINST*/);
6341f357
DN
10754 endmodule
10755
10756Where the list of parameter connections come from the inst module.
10757\f
10758Templates:
10759
10760 You can customize the parameter connections using AUTO_TEMPLATEs,
10761 just as you would with \\[verilog-auto-inst]."
10762 (save-excursion
10763 ;; Find beginning
10764 (let* ((pt (point))
10765 (indent-pt (save-excursion (verilog-backward-open-paren)
10766 (1+ (current-column))))
10767 (verilog-auto-inst-column (max verilog-auto-inst-column
10768 (+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
10769 (modi (verilog-modi-current))
5509c6ad 10770 (moddecls (verilog-modi-get-decls modi))
6341f357 10771 (vector-skip-list (unless verilog-auto-inst-vector
5509c6ad
DN
10772 (verilog-decls-get-signals moddecls)))
10773 submod submodi submoddecls
10774 inst skip-pins tpl-list tpl-num did-first)
6341f357
DN
10775 ;; Find module name that is instantiated
10776 (setq submod (save-excursion
10777 ;; Get to the point where AUTOINST normally is to read the module
10778 (verilog-re-search-forward-quick "[(;]" nil nil)
10779 (verilog-read-inst-module))
10780 inst (save-excursion
10781 ;; Get to the point where AUTOINST normally is to read the module
10782 (verilog-re-search-forward-quick "[(;]" nil nil)
10783 (verilog-read-inst-name))
10784 vl-cell-type submod
10785 vl-cell-name inst
10786 skip-pins (aref (verilog-read-inst-pins) 0))
10787
10788 ;; Parse any AUTO_LISP() before here
10789 (verilog-read-auto-lisp (point-min) pt)
10790
10791 ;; Lookup position, etc of submodule
10792 ;; Note this may raise an error
10793 (when (setq submodi (verilog-modi-lookup submod t))
5509c6ad 10794 (setq submoddecls (verilog-modi-get-decls submodi))
6341f357
DN
10795 ;; If there's a number in the instantiation, it may be a argument to the
10796 ;; automatic variable instantiation program.
10797 (let* ((tpl-info (verilog-read-auto-template submod))
10798 (tpl-regexp (aref tpl-info 0)))
10799 (setq tpl-num (if (string-match tpl-regexp inst)
10800 (match-string 1 inst)
10801 "")
10802 tpl-list (aref tpl-info 1)))
10803 ;; Find submodule's signals and dump
10804 (let ((sig-list (verilog-signals-not-in
5509c6ad 10805 (verilog-decls-get-gparams submoddecls)
6341f357
DN
10806 skip-pins))
10807 (vl-dir "parameter"))
10808 (when sig-list
10809 (when (not did-first) (verilog-auto-inst-first) (setq did-first t))
7ea26faf 10810 ;; Note these are searched for in verilog-read-sub-decls.
a03c2342 10811 (verilog-insert-indent "// Parameters\n")
9489a450
MM
10812 (verilog-auto-inst-port-list sig-list indent-pt
10813 tpl-list tpl-num nil nil)))
6341f357
DN
10814 ;; Kill extra semi
10815 (save-excursion
10816 (cond (did-first
10817 (re-search-backward "," pt t)
10818 (delete-char 1)
10819 (insert ")")
10820 (search-forward "\n") ;; Added by inst-port
d355a0b7 10821 (delete-char -1)
6341f357 10822 (if (search-forward ")" nil t) ;; From user, moved up a line
d355a0b7 10823 (delete-char -1)))))))))
6341f357
DN
10824
10825(defun verilog-auto-reg ()
10826 "Expand AUTOREG statements, as part of \\[verilog-auto].
10827Make reg statements for any output that isn't already declared,
9489a450
MM
10828and isn't a wire output from a block. `verilog-auto-wire-type'
10829may be used to change the datatype of the declarations.
6341f357
DN
10830
10831Limitations:
10832 This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
10833
10834 This does NOT work on memories, declare those yourself.
10835
10836An example:
10837
a03c2342 10838 module ExampReg (o,i);
6341f357
DN
10839 output o;
10840 input i;
10841 /*AUTOREG*/
10842 always o = i;
10843 endmodule
10844
10845Typing \\[verilog-auto] will make this into:
10846
a03c2342 10847 module ExampReg (o,i);
6341f357
DN
10848 output o;
10849 input i;
10850 /*AUTOREG*/
10851 // Beginning of automatic regs (for this module's undeclared outputs)
1dd4b004 10852 reg o;
6341f357
DN
10853 // End of automatics
10854 always o = i;
10855 endmodule"
10856 (save-excursion
10857 ;; Point must be at insertion point.
10858 (let* ((indent-pt (current-indentation))
10859 (modi (verilog-modi-current))
5509c6ad
DN
10860 (moddecls (verilog-modi-get-decls modi))
10861 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357 10862 (sig-list (verilog-signals-not-in
5509c6ad 10863 (verilog-decls-get-outputs moddecls)
9489a450 10864 (append (verilog-decls-get-vars moddecls)
5509c6ad
DN
10865 (verilog-decls-get-assigns moddecls)
10866 (verilog-decls-get-consts moddecls)
10867 (verilog-decls-get-gparams moddecls)
a03c2342 10868 (verilog-subdecls-get-interfaced modsubdecls)
5509c6ad
DN
10869 (verilog-subdecls-get-outputs modsubdecls)
10870 (verilog-subdecls-get-inouts modsubdecls)))))
6341f357
DN
10871 (forward-line 1)
10872 (when sig-list
10873 (verilog-insert-indent "// Beginning of automatic regs (for this module's undeclared outputs)\n")
9489a450 10874 (verilog-insert-definition modi sig-list "reg" indent-pt nil)
60618039 10875 (verilog-insert-indent "// End of automatics\n")))))
6341f357
DN
10876
10877(defun verilog-auto-reg-input ()
10878 "Expand AUTOREGINPUT statements, as part of \\[verilog-auto].
10879Make reg statements instantiation inputs that aren't already declared.
10880This is useful for making a top level shell for testing the module that is
10881to be instantiated.
10882
10883Limitations:
10884 This ONLY detects inputs of AUTOINSTants (see `verilog-read-sub-decls').
10885
10886 This does NOT work on memories, declare those yourself.
10887
10888An example (see `verilog-auto-inst' for what else is going on here):
10889
a03c2342 10890 module ExampRegInput (o,i);
6341f357
DN
10891 output o;
10892 input i;
10893 /*AUTOREGINPUT*/
1dd4b004
DN
10894 InstModule instName
10895 (/*AUTOINST*/);
6341f357
DN
10896 endmodule
10897
10898Typing \\[verilog-auto] will make this into:
10899
a03c2342 10900 module ExampRegInput (o,i);
6341f357
DN
10901 output o;
10902 input i;
10903 /*AUTOREGINPUT*/
10904 // Beginning of automatic reg inputs (for undeclared ...
1dd4b004 10905 reg [31:0] iv; // From inst of inst.v
6341f357 10906 // End of automatics
1dd4b004
DN
10907 InstModule instName
10908 (/*AUTOINST*/
10909 // Outputs
10910 .o (o[31:0]),
10911 // Inputs
10912 .iv (iv));
6341f357
DN
10913 endmodule"
10914 (save-excursion
10915 ;; Point must be at insertion point.
10916 (let* ((indent-pt (current-indentation))
10917 (modi (verilog-modi-current))
5509c6ad
DN
10918 (moddecls (verilog-modi-get-decls modi))
10919 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357
DN
10920 (sig-list (verilog-signals-combine-bus
10921 (verilog-signals-not-in
5509c6ad
DN
10922 (append (verilog-subdecls-get-inputs modsubdecls)
10923 (verilog-subdecls-get-inouts modsubdecls))
9489a450
MM
10924 (append (verilog-decls-get-signals moddecls)
10925 (verilog-decls-get-assigns moddecls))))))
6341f357
DN
10926 (forward-line 1)
10927 (when sig-list
10928 (verilog-insert-indent "// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)\n")
9489a450 10929 (verilog-insert-definition modi sig-list "reg" indent-pt nil)
60618039 10930 (verilog-insert-indent "// End of automatics\n")))))
6341f357 10931
9489a450
MM
10932(defun verilog-auto-logic ()
10933 "Expand AUTOLOGIC statements, as part of \\[verilog-auto].
10934Make wire statements using the SystemVerilog logic keyword.
10935This is currently equivelent to:
10936
10937 /*AUTOWIRE*/
10938
10939with the below at the bottom of the file
10940
10941 // Local Variables:
10942 // verilog-auto-logic-type:\"logic\"
10943 // End:
10944
10945In the future AUTOLOGIC may declare additional identifiers,
10946while AUTOWIRE will not."
10947 (save-excursion
10948 (unless verilog-auto-wire-type
10949 (set (make-local-variable 'verilog-auto-wire-type)
10950 "logic"))
10951 (verilog-auto-wire)))
10952
6341f357
DN
10953(defun verilog-auto-wire ()
10954 "Expand AUTOWIRE statements, as part of \\[verilog-auto].
10955Make wire statements for instantiations outputs that aren't
9489a450
MM
10956already declared. `verilog-auto-wire-type' may be used to change
10957the datatype of the declarations.
6341f357
DN
10958
10959Limitations:
10960 This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls'),
10961 and all busses must have widths, such as those from AUTOINST, or using []
10962 in AUTO_TEMPLATEs.
10963
10964 This does NOT work on memories or SystemVerilog .name connections,
10965 declare those yourself.
10966
37ea4b9b
JB
10967 Verilog mode will add \"Couldn't Merge\" comments to signals it cannot
10968 determine how to bus together. This occurs when you have ports with
10969 non-numeric or non-sequential bus subscripts. If Verilog mode
6341f357
DN
10970 mis-guessed, you'll have to declare them yourself.
10971
10972An example (see `verilog-auto-inst' for what else is going on here):
10973
a03c2342 10974 module ExampWire (o,i);
6341f357
DN
10975 output o;
10976 input i;
10977 /*AUTOWIRE*/
1dd4b004
DN
10978 InstModule instName
10979 (/*AUTOINST*/);
6341f357
DN
10980 endmodule
10981
10982Typing \\[verilog-auto] will make this into:
10983
a03c2342 10984 module ExampWire (o,i);
6341f357
DN
10985 output o;
10986 input i;
10987 /*AUTOWIRE*/
10988 // Beginning of automatic wires
10989 wire [31:0] ov; // From inst of inst.v
10990 // End of automatics
1dd4b004
DN
10991 InstModule instName
10992 (/*AUTOINST*/
10993 // Outputs
10994 .ov (ov[31:0]),
10995 // Inputs
10996 .i (i));
6341f357
DN
10997 wire o = | ov;
10998 endmodule"
10999 (save-excursion
11000 ;; Point must be at insertion point.
11001 (let* ((indent-pt (current-indentation))
11002 (modi (verilog-modi-current))
5509c6ad
DN
11003 (moddecls (verilog-modi-get-decls modi))
11004 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357
DN
11005 (sig-list (verilog-signals-combine-bus
11006 (verilog-signals-not-in
5509c6ad
DN
11007 (append (verilog-subdecls-get-outputs modsubdecls)
11008 (verilog-subdecls-get-inouts modsubdecls))
11009 (verilog-decls-get-signals moddecls)))))
6341f357
DN
11010 (forward-line 1)
11011 (when sig-list
11012 (verilog-insert-indent "// Beginning of automatic wires (for undeclared instantiated-module outputs)\n")
9489a450 11013 (verilog-insert-definition modi sig-list "wire" indent-pt nil)
6341f357 11014 (verilog-insert-indent "// End of automatics\n")
9489a450
MM
11015 ;; We used to optionally call verilog-pretty-declarations and
11016 ;; verilog-pretty-expr here, but it's too slow on huge modules,
11017 ;; plus makes everyone's module change. Finally those call
11018 ;; syntax-ppss which is broken when change hooks are disabled.
11019 ))))
6341f357 11020
e2076c2c 11021(defun verilog-auto-output (&optional with-params)
6341f357
DN
11022 "Expand AUTOOUTPUT statements, as part of \\[verilog-auto].
11023Make output statements for any output signal from an /*AUTOINST*/ that
11024isn't a input to another AUTOINST. This is useful for modules which
11025only instantiate other modules.
11026
11027Limitations:
11028 This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11029
11030 If placed inside the parenthesis of a module declaration, it creates
11031 Verilog 2001 style, else uses Verilog 1995 style.
11032
11033 If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
11034 instantiation, all bets are off. (For example due to a AUTO_TEMPLATE).
11035
11036 Typedefs must match `verilog-typedef-regexp', which is disabled by default.
11037
11038 Signals matching `verilog-auto-output-ignore-regexp' are not included.
11039
11040An example (see `verilog-auto-inst' for what else is going on here):
11041
a03c2342 11042 module ExampOutput (ov,i);
6341f357
DN
11043 input i;
11044 /*AUTOOUTPUT*/
1dd4b004
DN
11045 InstModule instName
11046 (/*AUTOINST*/);
6341f357
DN
11047 endmodule
11048
11049Typing \\[verilog-auto] will make this into:
11050
a03c2342 11051 module ExampOutput (ov,i);
6341f357
DN
11052 input i;
11053 /*AUTOOUTPUT*/
11054 // Beginning of automatic outputs (from unused autoinst outputs)
1dd4b004 11055 output [31:0] ov; // From inst of inst.v
6341f357 11056 // End of automatics
1dd4b004
DN
11057 InstModule instName
11058 (/*AUTOINST*/
11059 // Outputs
11060 .ov (ov[31:0]),
11061 // Inputs
11062 .i (i));
e2076c2c
DN
11063 endmodule
11064
11065You may also provide an optional regular expression, in which case only
11066signals matching the regular expression will be included. For example the
11067same expansion will result from only extracting outputs starting with ov:
11068
11069 /*AUTOOUTPUT(\"^ov\")*/"
6341f357
DN
11070 (save-excursion
11071 ;; Point must be at insertion point.
11072 (let* ((indent-pt (current-indentation))
e2076c2c
DN
11073 (regexp (and with-params
11074 (nth 0 (verilog-read-auto-params 1))))
9489a450 11075 (v2k (verilog-in-paren-quick))
6341f357 11076 (modi (verilog-modi-current))
5509c6ad
DN
11077 (moddecls (verilog-modi-get-decls modi))
11078 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357 11079 (sig-list (verilog-signals-not-in
5509c6ad
DN
11080 (verilog-subdecls-get-outputs modsubdecls)
11081 (append (verilog-decls-get-outputs moddecls)
11082 (verilog-decls-get-inouts moddecls)
11083 (verilog-subdecls-get-inputs modsubdecls)
11084 (verilog-subdecls-get-inouts modsubdecls)))))
e2076c2c
DN
11085 (when regexp
11086 (setq sig-list (verilog-signals-matching-regexp
11087 sig-list regexp)))
6341f357
DN
11088 (setq sig-list (verilog-signals-not-matching-regexp
11089 sig-list verilog-auto-output-ignore-regexp))
11090 (forward-line 1)
11091 (when v2k (verilog-repair-open-comma))
11092 (when sig-list
11093 (verilog-insert-indent "// Beginning of automatic outputs (from unused autoinst outputs)\n")
9489a450 11094 (verilog-insert-definition modi sig-list "output" indent-pt v2k)
6341f357 11095 (verilog-insert-indent "// End of automatics\n"))
60618039 11096 (when v2k (verilog-repair-close-comma)))))
6341f357
DN
11097
11098(defun verilog-auto-output-every ()
11099 "Expand AUTOOUTPUTEVERY statements, as part of \\[verilog-auto].
11100Make output statements for any signals that aren't primary inputs or
11101outputs already. This makes every signal in the design a output. This is
11102useful to get Synopsys to preserve every signal in the design, since it
11103won't optimize away the outputs.
11104
11105An example:
11106
a03c2342 11107 module ExampOutputEvery (o,i,tempa,tempb);
6341f357
DN
11108 output o;
11109 input i;
11110 /*AUTOOUTPUTEVERY*/
11111 wire tempa = i;
11112 wire tempb = tempa;
11113 wire o = tempb;
11114 endmodule
11115
11116Typing \\[verilog-auto] will make this into:
11117
a03c2342 11118 module ExampOutputEvery (o,i,tempa,tempb);
6341f357
DN
11119 output o;
11120 input i;
11121 /*AUTOOUTPUTEVERY*/
11122 // Beginning of automatic outputs (every signal)
1dd4b004
DN
11123 output tempb;
11124 output tempa;
6341f357
DN
11125 // End of automatics
11126 wire tempa = i;
11127 wire tempb = tempa;
11128 wire o = tempb;
11129 endmodule"
11130 (save-excursion
11131 ;;Point must be at insertion point
11132 (let* ((indent-pt (current-indentation))
9489a450 11133 (v2k (verilog-in-paren-quick))
6341f357 11134 (modi (verilog-modi-current))
5509c6ad 11135 (moddecls (verilog-modi-get-decls modi))
6341f357
DN
11136 (sig-list (verilog-signals-combine-bus
11137 (verilog-signals-not-in
5509c6ad
DN
11138 (verilog-decls-get-signals moddecls)
11139 (verilog-decls-get-ports moddecls)))))
6341f357
DN
11140 (forward-line 1)
11141 (when v2k (verilog-repair-open-comma))
11142 (when sig-list
11143 (verilog-insert-indent "// Beginning of automatic outputs (every signal)\n")
9489a450 11144 (verilog-insert-definition modi sig-list "output" indent-pt v2k)
6341f357 11145 (verilog-insert-indent "// End of automatics\n"))
60618039 11146 (when v2k (verilog-repair-close-comma)))))
6341f357 11147
e2076c2c 11148(defun verilog-auto-input (&optional with-params)
6341f357
DN
11149 "Expand AUTOINPUT statements, as part of \\[verilog-auto].
11150Make input statements for any input signal into an /*AUTOINST*/ that
11151isn't declared elsewhere inside the module. This is useful for modules which
11152only instantiate other modules.
11153
11154Limitations:
11155 This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11156
11157 If placed inside the parenthesis of a module declaration, it creates
11158 Verilog 2001 style, else uses Verilog 1995 style.
11159
11160 If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
11161 instantiation, all bets are off. (For example due to a AUTO_TEMPLATE).
11162
11163 Typedefs must match `verilog-typedef-regexp', which is disabled by default.
11164
11165 Signals matching `verilog-auto-input-ignore-regexp' are not included.
11166
11167An example (see `verilog-auto-inst' for what else is going on here):
11168
a03c2342 11169 module ExampInput (ov,i);
6341f357
DN
11170 output [31:0] ov;
11171 /*AUTOINPUT*/
1dd4b004
DN
11172 InstModule instName
11173 (/*AUTOINST*/);
6341f357
DN
11174 endmodule
11175
11176Typing \\[verilog-auto] will make this into:
11177
a03c2342 11178 module ExampInput (ov,i);
6341f357
DN
11179 output [31:0] ov;
11180 /*AUTOINPUT*/
11181 // Beginning of automatic inputs (from unused autoinst inputs)
1dd4b004 11182 input i; // From inst of inst.v
6341f357 11183 // End of automatics
1dd4b004
DN
11184 InstModule instName
11185 (/*AUTOINST*/
11186 // Outputs
11187 .ov (ov[31:0]),
11188 // Inputs
11189 .i (i));
e2076c2c
DN
11190 endmodule
11191
11192You may also provide an optional regular expression, in which case only
11193signals matching the regular expression will be included. For example the
11194same expansion will result from only extracting inputs starting with i:
11195
11196 /*AUTOINPUT(\"^i\")*/"
6341f357
DN
11197 (save-excursion
11198 (let* ((indent-pt (current-indentation))
e2076c2c
DN
11199 (regexp (and with-params
11200 (nth 0 (verilog-read-auto-params 1))))
9489a450 11201 (v2k (verilog-in-paren-quick))
6341f357 11202 (modi (verilog-modi-current))
5509c6ad
DN
11203 (moddecls (verilog-modi-get-decls modi))
11204 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357 11205 (sig-list (verilog-signals-not-in
5509c6ad
DN
11206 (verilog-subdecls-get-inputs modsubdecls)
11207 (append (verilog-decls-get-inputs moddecls)
11208 (verilog-decls-get-inouts moddecls)
9489a450 11209 (verilog-decls-get-vars moddecls)
5509c6ad
DN
11210 (verilog-decls-get-consts moddecls)
11211 (verilog-decls-get-gparams moddecls)
a03c2342 11212 (verilog-subdecls-get-interfaced modsubdecls)
5509c6ad
DN
11213 (verilog-subdecls-get-outputs modsubdecls)
11214 (verilog-subdecls-get-inouts modsubdecls)))))
e2076c2c
DN
11215 (when regexp
11216 (setq sig-list (verilog-signals-matching-regexp
11217 sig-list regexp)))
6341f357
DN
11218 (setq sig-list (verilog-signals-not-matching-regexp
11219 sig-list verilog-auto-input-ignore-regexp))
11220 (forward-line 1)
11221 (when v2k (verilog-repair-open-comma))
11222 (when sig-list
11223 (verilog-insert-indent "// Beginning of automatic inputs (from unused autoinst inputs)\n")
9489a450 11224 (verilog-insert-definition modi sig-list "input" indent-pt v2k)
6341f357 11225 (verilog-insert-indent "// End of automatics\n"))
60618039 11226 (when v2k (verilog-repair-close-comma)))))
6341f357 11227
e2076c2c 11228(defun verilog-auto-inout (&optional with-params)
6341f357
DN
11229 "Expand AUTOINOUT statements, as part of \\[verilog-auto].
11230Make inout statements for any inout signal in an /*AUTOINST*/ that
11231isn't declared elsewhere inside the module.
11232
11233Limitations:
11234 This ONLY detects outputs of AUTOINSTants (see `verilog-read-sub-decls').
11235
11236 If placed inside the parenthesis of a module declaration, it creates
11237 Verilog 2001 style, else uses Verilog 1995 style.
11238
11239 If any concatenation, or bit-subscripts are missing in the AUTOINSTant's
11240 instantiation, all bets are off. (For example due to a AUTO_TEMPLATE).
11241
11242 Typedefs must match `verilog-typedef-regexp', which is disabled by default.
11243
11244 Signals matching `verilog-auto-inout-ignore-regexp' are not included.
11245
11246An example (see `verilog-auto-inst' for what else is going on here):
11247
a03c2342 11248 module ExampInout (ov,i);
6341f357
DN
11249 input i;
11250 /*AUTOINOUT*/
1dd4b004
DN
11251 InstModule instName
11252 (/*AUTOINST*/);
6341f357
DN
11253 endmodule
11254
11255Typing \\[verilog-auto] will make this into:
11256
a03c2342 11257 module ExampInout (ov,i);
6341f357
DN
11258 input i;
11259 /*AUTOINOUT*/
11260 // Beginning of automatic inouts (from unused autoinst inouts)
1dd4b004 11261 inout [31:0] ov; // From inst of inst.v
6341f357 11262 // End of automatics
1dd4b004
DN
11263 InstModule instName
11264 (/*AUTOINST*/
11265 // Inouts
11266 .ov (ov[31:0]),
11267 // Inputs
11268 .i (i));
e2076c2c
DN
11269 endmodule
11270
11271You may also provide an optional regular expression, in which case only
11272signals matching the regular expression will be included. For example the
11273same expansion will result from only extracting inouts starting with i:
11274
11275 /*AUTOINOUT(\"^i\")*/"
6341f357
DN
11276 (save-excursion
11277 ;; Point must be at insertion point.
11278 (let* ((indent-pt (current-indentation))
e2076c2c
DN
11279 (regexp (and with-params
11280 (nth 0 (verilog-read-auto-params 1))))
9489a450 11281 (v2k (verilog-in-paren-quick))
6341f357 11282 (modi (verilog-modi-current))
5509c6ad
DN
11283 (moddecls (verilog-modi-get-decls modi))
11284 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357 11285 (sig-list (verilog-signals-not-in
5509c6ad
DN
11286 (verilog-subdecls-get-inouts modsubdecls)
11287 (append (verilog-decls-get-outputs moddecls)
11288 (verilog-decls-get-inouts moddecls)
11289 (verilog-decls-get-inputs moddecls)
11290 (verilog-subdecls-get-inputs modsubdecls)
11291 (verilog-subdecls-get-outputs modsubdecls)))))
e2076c2c
DN
11292 (when regexp
11293 (setq sig-list (verilog-signals-matching-regexp
11294 sig-list regexp)))
6341f357
DN
11295 (setq sig-list (verilog-signals-not-matching-regexp
11296 sig-list verilog-auto-inout-ignore-regexp))
11297 (forward-line 1)
11298 (when v2k (verilog-repair-open-comma))
11299 (when sig-list
11300 (verilog-insert-indent "// Beginning of automatic inouts (from unused autoinst inouts)\n")
9489a450 11301 (verilog-insert-definition modi sig-list "inout" indent-pt v2k)
6341f357 11302 (verilog-insert-indent "// End of automatics\n"))
60618039 11303 (when v2k (verilog-repair-close-comma)))))
6341f357 11304
9489a450 11305(defun verilog-auto-inout-module (&optional complement all-in)
6341f357
DN
11306 "Expand AUTOINOUTMODULE statements, as part of \\[verilog-auto].
11307Take input/output/inout statements from the specified module and insert
11308into the current module. This is useful for making null templates and
37ea4b9b
JB
11309shell modules which need to have identical I/O with another module.
11310Any I/O which are already defined in this module will not be redefined.
9489a450
MM
11311For the complement of this function, see `verilog-auto-inout-comp',
11312and to make monitors with all inputs, see `verilog-auto-inout-in'.
6341f357
DN
11313
11314Limitations:
11315 If placed inside the parenthesis of a module declaration, it creates
11316 Verilog 2001 style, else uses Verilog 1995 style.
11317
11318 Concatenation and outputting partial busses is not supported.
11319
11320 Module names must be resolvable to filenames. See `verilog-auto-inst'.
11321
11322 Signals are not inserted in the same order as in the original module,
11323 though they will appear to be in the same order to a AUTOINST
11324 instantiating either module.
11325
11326An example:
11327
a03c2342 11328 module ExampShell (/*AUTOARG*/);
1dd4b004 11329 /*AUTOINOUTMODULE(\"ExampMain\")*/
6341f357
DN
11330 endmodule
11331
a03c2342 11332 module ExampMain (i,o,io);
6341f357
DN
11333 input i;
11334 output o;
11335 inout io;
11336 endmodule
11337
11338Typing \\[verilog-auto] will make this into:
11339
a03c2342 11340 module ExampShell (/*AUTOARG*/i,o,io);
1dd4b004 11341 /*AUTOINOUTMODULE(\"ExampMain\")*/
6341f357 11342 // Beginning of automatic in/out/inouts (from specific module)
6341f357
DN
11343 output o;
11344 inout io;
7cb1c4d7 11345 input i;
6341f357 11346 // End of automatics
1dd4b004
DN
11347 endmodule
11348
11349You may also provide an optional regular expression, in which case only
11350signals matching the regular expression will be included. For example the
11351same expansion will result from only extracting signals starting with i:
11352
a3a8b002
DN
11353 /*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/
11354
14862301 11355You may also provide an optional second regular expression, in
a3a8b002
DN
11356which case only signals which have that pin direction and data
11357type will be included. This matches against everything before
11358the signal name in the declaration, for example against
11359\"input\" (single bit), \"output logic\" (direction and type) or
11360\"output [1:0]\" (direction and implicit type). You also
11361probably want to skip spaces in your regexp.
11362
11363For example, the below will result in matching the output \"o\"
11364against the previous example's module:
11365
11366 /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/"
6341f357 11367 (save-excursion
a3a8b002 11368 (let* ((params (verilog-read-auto-params 1 3))
1dd4b004
DN
11369 (submod (nth 0 params))
11370 (regexp (nth 1 params))
a3a8b002 11371 (direction-re (nth 2 params))
1dd4b004 11372 submodi)
6341f357
DN
11373 ;; Lookup position, etc of co-module
11374 ;; Note this may raise an error
11375 (when (setq submodi (verilog-modi-lookup submod t))
11376 (let* ((indent-pt (current-indentation))
9489a450 11377 (v2k (verilog-in-paren-quick))
6341f357 11378 (modi (verilog-modi-current))
5509c6ad
DN
11379 (moddecls (verilog-modi-get-decls modi))
11380 (submoddecls (verilog-modi-get-decls submodi))
6341f357 11381 (sig-list-i (verilog-signals-not-in
9489a450
MM
11382 (cond (all-in
11383 (append
11384 (verilog-decls-get-inputs submoddecls)
11385 (verilog-decls-get-inouts submoddecls)
11386 (verilog-decls-get-outputs submoddecls)))
11387 (complement
11388 (verilog-decls-get-outputs submoddecls))
11389 (t (verilog-decls-get-inputs submoddecls)))
5509c6ad 11390 (append (verilog-decls-get-inputs moddecls))))
6341f357 11391 (sig-list-o (verilog-signals-not-in
9489a450
MM
11392 (cond (all-in nil)
11393 (complement
11394 (verilog-decls-get-inputs submoddecls))
11395 (t (verilog-decls-get-outputs submoddecls)))
5509c6ad 11396 (append (verilog-decls-get-outputs moddecls))))
6341f357 11397 (sig-list-io (verilog-signals-not-in
9489a450
MM
11398 (cond (all-in nil)
11399 (t (verilog-decls-get-inouts submoddecls)))
a3a8b002
DN
11400 (append (verilog-decls-get-inouts moddecls))))
11401 (sig-list-if (verilog-signals-not-in
11402 (verilog-decls-get-interfaces submoddecls)
11403 (append (verilog-decls-get-interfaces moddecls)))))
6341f357 11404 (forward-line 1)
a3a8b002
DN
11405 (setq sig-list-i (verilog-signals-matching-dir-re
11406 (verilog-signals-matching-regexp sig-list-i regexp)
11407 "input" direction-re)
11408 sig-list-o (verilog-signals-matching-dir-re
11409 (verilog-signals-matching-regexp sig-list-o regexp)
11410 "output" direction-re)
11411 sig-list-io (verilog-signals-matching-dir-re
11412 (verilog-signals-matching-regexp sig-list-io regexp)
11413 "inout" direction-re)
11414 sig-list-if (verilog-signals-matching-dir-re
11415 (verilog-signals-matching-regexp sig-list-if regexp)
11416 "interface" direction-re))
6341f357
DN
11417 (when v2k (verilog-repair-open-comma))
11418 (when (or sig-list-i sig-list-o sig-list-io)
11419 (verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n")
11420 ;; Don't sort them so a upper AUTOINST will match the main module
9489a450
MM
11421 (verilog-insert-definition modi sig-list-o "output" indent-pt v2k t)
11422 (verilog-insert-definition modi sig-list-io "inout" indent-pt v2k t)
11423 (verilog-insert-definition modi sig-list-i "input" indent-pt v2k t)
11424 (verilog-insert-definition modi sig-list-if "interface" indent-pt v2k t)
6341f357 11425 (verilog-insert-indent "// End of automatics\n"))
60618039 11426 (when v2k (verilog-repair-close-comma)))))))
6341f357 11427
7cb1c4d7
DN
11428(defun verilog-auto-inout-comp ()
11429 "Expand AUTOINOUTCOMP statements, as part of \\[verilog-auto].
11430Take input/output/inout statements from the specified module and
11431insert the inverse into the current module (inputs become outputs
11432and vice-versa.) This is useful for making test and stimulus
11433modules which need to have complementing I/O with another module.
11434Any I/O which are already defined in this module will not be
a03c2342
WS
11435redefined. For the complement of this function, see
11436`verilog-auto-inout-module'.
7cb1c4d7
DN
11437
11438Limitations:
11439 If placed inside the parenthesis of a module declaration, it creates
11440 Verilog 2001 style, else uses Verilog 1995 style.
11441
11442 Concatenation and outputting partial busses is not supported.
11443
11444 Module names must be resolvable to filenames. See `verilog-auto-inst'.
11445
11446 Signals are not inserted in the same order as in the original module,
11447 though they will appear to be in the same order to a AUTOINST
11448 instantiating either module.
11449
11450An example:
11451
a03c2342 11452 module ExampShell (/*AUTOARG*/);
7cb1c4d7
DN
11453 /*AUTOINOUTCOMP(\"ExampMain\")*/
11454 endmodule
11455
a03c2342 11456 module ExampMain (i,o,io);
7cb1c4d7
DN
11457 input i;
11458 output o;
11459 inout io;
11460 endmodule
11461
11462Typing \\[verilog-auto] will make this into:
11463
a03c2342 11464 module ExampShell (/*AUTOARG*/i,o,io);
7cb1c4d7
DN
11465 /*AUTOINOUTCOMP(\"ExampMain\")*/
11466 // Beginning of automatic in/out/inouts (from specific module)
11467 output i;
11468 inout io;
11469 input o;
11470 // End of automatics
11471 endmodule
11472
11473You may also provide an optional regular expression, in which case only
11474signals matching the regular expression will be included. For example the
11475same expansion will result from only extracting signals starting with i:
11476
11477 /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
9489a450
MM
11478 (verilog-auto-inout-module t nil))
11479
11480(defun verilog-auto-inout-in ()
11481 "Expand AUTOINOUTIN statements, as part of \\[verilog-auto].
11482Take input/output/inout statements from the specified module and
11483insert them as all inputs into the current module. This is
11484useful for making monitor modules which need to see all signals
11485as inputs based on another module. Any I/O which are already
11486defined in this module will not be redefined. See also
11487`verilog-auto-inout-module'.
11488
11489Limitations:
11490 If placed inside the parenthesis of a module declaration, it creates
11491 Verilog 2001 style, else uses Verilog 1995 style.
11492
11493 Concatenation and outputting partial busses is not supported.
11494
11495 Module names must be resolvable to filenames. See `verilog-auto-inst'.
11496
11497 Signals are not inserted in the same order as in the original module,
11498 though they will appear to be in the same order to a AUTOINST
11499 instantiating either module.
11500
11501An example:
11502
11503 module ExampShell (/*AUTOARG*/);
11504 /*AUTOINOUTIN(\"ExampMain\")*/
11505 endmodule
11506
11507 module ExampMain (i,o,io);
11508 input i;
11509 output o;
11510 inout io;
11511 endmodule
11512
11513Typing \\[verilog-auto] will make this into:
11514
11515 module ExampShell (/*AUTOARG*/i,o,io);
11516 /*AUTOINOUTIN(\"ExampMain\")*/
11517 // Beginning of automatic in/out/inouts (from specific module)
11518 input i;
11519 input io;
11520 input o;
11521 // End of automatics
11522 endmodule
11523
11524You may also provide an optional regular expression, in which case only
11525signals matching the regular expression will be included. For example the
11526same expansion will result from only extracting signals starting with i:
11527
11528 /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
11529 (verilog-auto-inout-module nil t))
7cb1c4d7 11530
a3a8b002
DN
11531(defun verilog-auto-insert-lisp ()
11532 "Expand AUTOINSERTLISP statements, as part of \\[verilog-auto].
11533The Lisp code provided is called, and the Lisp code calls
11534`insert` to insert text into the current file beginning on the
11535line after the AUTOINSERTLISP.
11536
11537See also AUTO_LISP, which takes a Lisp expression and evaluates
11538it during `verilog-auto-inst' but does not insert any text.
11539
11540An example:
11541
11542 module ExampInsertLisp;
11543 /*AUTOINSERTLISP(my-verilog-insert-hello \"world\")*/
11544 endmodule
11545
11546 // For this example we declare the function in the
11547 // module's file itself. Often you'd define it instead
11548 // in a site-start.el or .emacs file.
11549 /*
11550 Local Variables:
11551 eval:
11552 (defun my-verilog-insert-hello (who)
11553 (insert (concat \"initial $write(\\\"hello \" who \"\\\");\\n\")))
11554 End:
11555 */
11556
11557Typing \\[verilog-auto] will call my-verilog-insert-hello and
11558expand the above into:
11559
11560 // Beginning of automatic insert lisp
11561 initial $write(\"hello world\");
11562 // End of automatics
11563
11564You can also call an external program and insert the returned
11565text:
11566
11567 /*AUTOINSERTLISP(insert (shell-command-to-string \"echo //hello\"))*/
11568 // Beginning of automatic insert lisp
11569 //hello
11570 // End of automatics"
11571 (save-excursion
11572 ;; Point is at end of /*AUTO...*/
11573 (let* ((indent-pt (current-indentation))
11574 (cmd-end-pt (save-excursion (search-backward ")")
11575 (forward-char)
11576 (point))) ;; Closing paren
11577 (cmd-beg-pt (save-excursion (goto-char cmd-end-pt)
9489a450 11578 (backward-sexp 1) ;; Inside comment
a3a8b002
DN
11579 (point))) ;; Beginning paren
11580 (cmd (buffer-substring-no-properties cmd-beg-pt cmd-end-pt)))
11581 (forward-line 1)
0e5c8aed
DN
11582 ;; Some commands don't move point (like insert-file) so we always
11583 ;; add the begin/end comments, then delete it if not needed
11584 (verilog-insert-indent "// Beginning of automatic insert lisp\n")
11585 (verilog-insert-indent "// End of automatics\n")
11586 (forward-line -1)
11587 (eval (read cmd))
11588 (forward-line -1)
a03c2342 11589 (setq verilog-scan-cache-tick nil) ;; Clear cache; inserted unknown text
0e5c8aed 11590 (verilog-delete-empty-auto-pair))))
a3a8b002 11591
5509c6ad 11592(defun verilog-auto-sense-sigs (moddecls presense-sigs)
6341f357
DN
11593 "Return list of signals for current AUTOSENSE block."
11594 (let* ((sigss (verilog-read-always-signals))
11595 (sig-list (verilog-signals-not-params
11596 (verilog-signals-not-in (verilog-alw-get-inputs sigss)
11597 (append (and (not verilog-auto-sense-include-inputs)
9489a450
MM
11598 (verilog-alw-get-outputs-delayed sigss))
11599 (and (not verilog-auto-sense-include-inputs)
11600 (verilog-alw-get-outputs-immediate sigss))
a03c2342 11601 (verilog-alw-get-temps sigss)
5509c6ad
DN
11602 (verilog-decls-get-consts moddecls)
11603 (verilog-decls-get-gparams moddecls)
6341f357
DN
11604 presense-sigs)))))
11605 sig-list))
11606
11607(defun verilog-auto-sense ()
11608 "Expand AUTOSENSE statements, as part of \\[verilog-auto].
11609Replace the always (/*AUTOSENSE*/) sensitivity list (/*AS*/ for short)
11610with one automatically derived from all inputs declared in the always
11611statement. Signals that are generated within the same always block are NOT
11612placed into the sensitivity list (see `verilog-auto-sense-include-inputs').
11613Long lines are split based on the `fill-column', see \\[set-fill-column].
11614
11615Limitations:
11616 Verilog does not allow memories (multidimensional arrays) in sensitivity
11617 lists. AUTOSENSE will thus exclude them, and add a /*memory or*/ comment.
11618
11619Constant signals:
11620 AUTOSENSE cannot always determine if a `define is a constant or a signal
11621 (it could be in a include file for example). If a `define or other signal
11622 is put into the AUTOSENSE list and is not desired, use the AUTO_CONSTANT
11623 declaration anywhere in the module (parenthesis are required):
11624
11625 /* AUTO_CONSTANT ( `this_is_really_constant_dont_autosense_it ) */
11626
11627 Better yet, use a parameter, which will be understood to be constant
11628 automatically.
11629
11630OOps!
11631 If AUTOSENSE makes a mistake, please report it. (First try putting
11632 a begin/end after your always!) As a workaround, if a signal that
11633 shouldn't be in the sensitivity list was, use the AUTO_CONSTANT above.
11634 If a signal should be in the sensitivity list wasn't, placing it before
11635 the /*AUTOSENSE*/ comment will prevent it from being deleted when the
11636 autos are updated (or added if it occurs there already).
11637
11638An example:
11639
1dd4b004 11640 always @ (/*AS*/) begin
6341f357
DN
11641 /* AUTO_CONSTANT (`constant) */
11642 outin = ina | inb | `constant;
11643 out = outin;
11644 end
11645
11646Typing \\[verilog-auto] will make this into:
11647
1dd4b004 11648 always @ (/*AS*/ina or inb) begin
6341f357
DN
11649 /* AUTO_CONSTANT (`constant) */
11650 outin = ina | inb | `constant;
11651 out = outin;
1dd4b004
DN
11652 end
11653
11654Note in Verilog 2001, you can often get the same result from the new @*
11655operator. (This was added to the language in part due to AUTOSENSE!)
11656
11657 always @* begin
11658 outin = ina | inb | `constant;
11659 out = outin;
6341f357
DN
11660 end"
11661 (save-excursion
11662 ;; Find beginning
11663 (let* ((start-pt (save-excursion
9489a450 11664 (verilog-re-search-backward-quick "(" nil t)
6341f357
DN
11665 (point)))
11666 (indent-pt (save-excursion
11667 (or (and (goto-char start-pt) (1+ (current-column)))
11668 (current-indentation))))
11669 (modi (verilog-modi-current))
5509c6ad 11670 (moddecls (verilog-modi-get-decls modi))
6341f357 11671 (sig-memories (verilog-signals-memory
9489a450 11672 (verilog-decls-get-vars moddecls)))
6341f357
DN
11673 sig-list not-first presense-sigs)
11674 ;; Read signals in always, eliminate outputs from sense list
11675 (setq presense-sigs (verilog-signals-from-signame
11676 (save-excursion
11677 (verilog-read-signals start-pt (point)))))
5509c6ad 11678 (setq sig-list (verilog-auto-sense-sigs moddecls presense-sigs))
6341f357
DN
11679 (when sig-memories
11680 (let ((tlen (length sig-list)))
11681 (setq sig-list (verilog-signals-not-in sig-list sig-memories))
a03c2342 11682 (if (not (eq tlen (length sig-list))) (verilog-insert " /*memory or*/ "))))
6341f357
DN
11683 (if (and presense-sigs ;; Add a "or" if not "(.... or /*AUTOSENSE*/"
11684 (save-excursion (goto-char (point))
9489a450
MM
11685 (verilog-re-search-backward-quick "[a-zA-Z0-9$_.%`]+" start-pt t)
11686 (verilog-re-search-backward-quick "\\s-" start-pt t)
6341f357 11687 (while (looking-at "\\s-`endif")
9489a450
MM
11688 (verilog-re-search-backward-quick "[a-zA-Z0-9$_.%`]+" start-pt t)
11689 (verilog-re-search-backward-quick "\\s-" start-pt t))
6341f357
DN
11690 (not (looking-at "\\s-or\\b"))))
11691 (setq not-first t))
11692 (setq sig-list (sort sig-list `verilog-signals-sort-compare))
11693 (while sig-list
11694 (cond ((> (+ 4 (current-column) (length (verilog-sig-name (car sig-list)))) fill-column) ;+4 for width of or
11695 (insert "\n")
11696 (indent-to indent-pt)
11697 (if not-first (insert "or ")))
11698 (not-first (insert " or ")))
11699 (insert (verilog-sig-name (car sig-list)))
11700 (setq sig-list (cdr sig-list)
60618039 11701 not-first t)))))
6341f357
DN
11702
11703(defun verilog-auto-reset ()
11704 "Expand AUTORESET statements, as part of \\[verilog-auto].
11705Replace the /*AUTORESET*/ comment with code to initialize all
11706registers set elsewhere in the always block.
11707
11708Limitations:
11709 AUTORESET will not clear memories.
11710
9489a450 11711 AUTORESET uses <= if the signal has a <= assignment in the block,
a3a8b002 11712 else it uses =.
6341f357 11713
9489a450
MM
11714 If <= is used, all = assigned variables are ignored if
11715 `verilog-auto-reset-blocking-in-non' is nil; they are presumed
11716 to be temporaries.
11717
6341f357
DN
11718/*AUTORESET*/ presumes that any signals mentioned between the previous
11719begin/case/if statement and the AUTORESET comment are being reset manually
11720and should not be automatically reset. This includes omitting any signals
11721used on the right hand side of assignments.
11722
11723By default, AUTORESET will include the width of the signal in the autos,
11724this is a recent change. To control this behavior, see
11725`verilog-auto-reset-widths'.
11726
11727AUTORESET ties signals to deasserted, which is presumed to be zero.
11728Signals that match `verilog-active-low-regexp' will be deasserted by tieing
11729them to a one.
11730
11731An example:
11732
11733 always @(posedge clk or negedge reset_l) begin
11734 if (!reset_l) begin
11735 c <= 1;
11736 /*AUTORESET*/
11737 end
11738 else begin
11739 a <= in_a;
11740 b <= in_b;
11741 c <= in_c;
11742 end
11743 end
11744
11745Typing \\[verilog-auto] will make this into:
11746
11747 always @(posedge core_clk or negedge reset_l) begin
11748 if (!reset_l) begin
11749 c <= 1;
11750 /*AUTORESET*/
11751 // Beginning of autoreset for uninitialized flops
11752 a <= 0;
9489a450 11753 b = 0; // if `verilog-auto-reset-blocking-in-non' true
6341f357
DN
11754 // End of automatics
11755 end
11756 else begin
11757 a <= in_a;
9489a450 11758 b = in_b;
6341f357
DN
11759 c <= in_c;
11760 end
11761 end"
11762
11763 (interactive)
11764 (save-excursion
11765 ;; Find beginning
11766 (let* ((indent-pt (current-indentation))
11767 (modi (verilog-modi-current))
5509c6ad
DN
11768 (moddecls (verilog-modi-get-decls modi))
11769 (all-list (verilog-decls-get-signals moddecls))
9489a450 11770 sigss sig-list dly-list prereset-sigs)
6341f357
DN
11771 ;; Read signals in always, eliminate outputs from reset list
11772 (setq prereset-sigs (verilog-signals-from-signame
11773 (save-excursion
11774 (verilog-read-signals
11775 (save-excursion
9489a450 11776 (verilog-re-search-backward-quick "\\(@\\|\\<begin\\>\\|\\<if\\>\\|\\<case\\>\\)" nil t)
6341f357
DN
11777 (point))
11778 (point)))))
11779 (save-excursion
9489a450 11780 (verilog-re-search-backward-quick "@" nil t)
6341f357 11781 (setq sigss (verilog-read-always-signals)))
9489a450
MM
11782 (setq dly-list (verilog-alw-get-outputs-delayed sigss))
11783 (setq sig-list (verilog-signals-not-in (append
11784 (verilog-alw-get-outputs-delayed sigss)
11785 (when (or (not (verilog-alw-get-uses-delayed sigss))
11786 verilog-auto-reset-blocking-in-non)
11787 (verilog-alw-get-outputs-immediate sigss)))
a03c2342
WS
11788 (append
11789 (verilog-alw-get-temps sigss)
11790 prereset-sigs)))
6341f357
DN
11791 (setq sig-list (sort sig-list `verilog-signals-sort-compare))
11792 (when sig-list
11793 (insert "\n");
a03c2342 11794 (verilog-insert-indent "// Beginning of autoreset for uninitialized flops\n");
6341f357
DN
11795 (while sig-list
11796 (let ((sig (or (assoc (verilog-sig-name (car sig-list)) all-list) ;; As sig-list has no widths
11797 (car sig-list))))
9489a450 11798 (indent-to indent-pt)
6341f357 11799 (insert (verilog-sig-name sig)
9489a450
MM
11800 (if (assoc (verilog-sig-name sig) dly-list)
11801 (concat " <= " verilog-assignment-delay)
11802 " = ")
6341f357
DN
11803 (verilog-sig-tieoff sig (not verilog-auto-reset-widths))
11804 ";\n")
6341f357 11805 (setq sig-list (cdr sig-list))))
9489a450 11806 (verilog-insert-indent "// End of automatics")))))
6341f357
DN
11807
11808(defun verilog-auto-tieoff ()
11809 "Expand AUTOTIEOFF statements, as part of \\[verilog-auto].
11810Replace the /*AUTOTIEOFF*/ comment with code to wire-tie all unused output
11811signals to deasserted.
11812
11813/*AUTOTIEOFF*/ is used to make stub modules; modules that have the same
11814input/output list as another module, but no internals. Specifically, it
11815finds all outputs in the module, and if that input is not otherwise declared
11816as a register or wire, creates a tieoff.
11817
11818AUTORESET ties signals to deasserted, which is presumed to be zero.
11819Signals that match `verilog-active-low-regexp' will be deasserted by tieing
11820them to a one.
11821
a03c2342
WS
11822You can add signals you do not want included in AUTOTIEOFF with
11823`verilog-auto-tieoff-ignore-regexp'.
11824
9489a450
MM
11825`verilog-auto-wire-type' may be used to change the datatype of
11826the declarations.
11827
6341f357
DN
11828An example of making a stub for another module:
11829
1dd4b004 11830 module ExampStub (/*AUTOINST*/);
6341f357
DN
11831 /*AUTOINOUTMODULE(\"Foo\")*/
11832 /*AUTOTIEOFF*/
11833 // verilator lint_off UNUSED
11834 wire _unused_ok = &{1'b0,
11835 /*AUTOUNUSED*/
11836 1'b0};
11837 // verilator lint_on UNUSED
11838 endmodule
11839
11840Typing \\[verilog-auto] will make this into:
11841
1dd4b004 11842 module ExampStub (/*AUTOINST*/...);
6341f357
DN
11843 /*AUTOINOUTMODULE(\"Foo\")*/
11844 // Beginning of autotieoff
11845 output [2:0] foo;
11846 // End of automatics
11847
11848 /*AUTOTIEOFF*/
11849 // Beginning of autotieoff
11850 wire [2:0] foo = 3'b0;
11851 // End of automatics
11852 ...
11853 endmodule"
11854 (interactive)
11855 (save-excursion
11856 ;; Find beginning
11857 (let* ((indent-pt (current-indentation))
11858 (modi (verilog-modi-current))
5509c6ad
DN
11859 (moddecls (verilog-modi-get-decls modi))
11860 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357 11861 (sig-list (verilog-signals-not-in
5509c6ad 11862 (verilog-decls-get-outputs moddecls)
9489a450 11863 (append (verilog-decls-get-vars moddecls)
5509c6ad
DN
11864 (verilog-decls-get-assigns moddecls)
11865 (verilog-decls-get-consts moddecls)
11866 (verilog-decls-get-gparams moddecls)
a03c2342 11867 (verilog-subdecls-get-interfaced modsubdecls)
5509c6ad
DN
11868 (verilog-subdecls-get-outputs modsubdecls)
11869 (verilog-subdecls-get-inouts modsubdecls)))))
a03c2342
WS
11870 (setq sig-list (verilog-signals-not-matching-regexp
11871 sig-list verilog-auto-tieoff-ignore-regexp))
6341f357
DN
11872 (when sig-list
11873 (forward-line 1)
11874 (verilog-insert-indent "// Beginning of automatic tieoffs (for this module's unterminated outputs)\n")
11875 (setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare))
9489a450 11876 (verilog-modi-cache-add-vars modi sig-list) ; Before we trash list
6341f357
DN
11877 (while sig-list
11878 (let ((sig (car sig-list)))
9489a450
MM
11879 (cond ((equal verilog-auto-tieoff-declaration "assign")
11880 (indent-to indent-pt)
11881 (insert "assign " (verilog-sig-name sig)))
11882 (t
11883 (verilog-insert-one-definition sig verilog-auto-tieoff-declaration indent-pt)))
6341f357
DN
11884 (indent-to (max 48 (+ indent-pt 40)))
11885 (insert "= " (verilog-sig-tieoff sig)
11886 ";\n")
11887 (setq sig-list (cdr sig-list))))
60618039 11888 (verilog-insert-indent "// End of automatics\n")))))
6341f357
DN
11889
11890(defun verilog-auto-unused ()
11891 "Expand AUTOUNUSED statements, as part of \\[verilog-auto].
11892Replace the /*AUTOUNUSED*/ comment with a comma separated list of all unused
11893input and inout signals.
11894
11895/*AUTOUNUSED*/ is used to make stub modules; modules that have the same
11896input/output list as another module, but no internals. Specifically, it
11897finds all inputs and inouts in the module, and if that input is not otherwise
11898used, adds it to a comma separated list.
11899
11900The comma separated list is intended to be used to create a _unused_ok
11901signal. Using the exact name \"_unused_ok\" for name of the temporary
11902signal is recommended as it will insure maximum forward compatibility, it
11903also makes lint warnings easy to understand; ignore any unused warnings
11904with \"unused\" in the signal name.
11905
11906To reduce simulation time, the _unused_ok signal should be forced to a
11907constant to prevent wiggling. The easiest thing to do is use a
11908reduction-and with 1'b0 as shown.
11909
11910This way all unused signals are in one place, making it convenient to add
11911your tool's specific pragmas around the assignment to disable any unused
11912warnings.
11913
11914You can add signals you do not want included in AUTOUNUSED with
11915`verilog-auto-unused-ignore-regexp'.
11916
11917An example of making a stub for another module:
11918
1dd4b004
DN
11919 module ExampStub (/*AUTOINST*/);
11920 /*AUTOINOUTMODULE(\"Examp\")*/
6341f357
DN
11921 /*AUTOTIEOFF*/
11922 // verilator lint_off UNUSED
11923 wire _unused_ok = &{1'b0,
11924 /*AUTOUNUSED*/
11925 1'b0};
11926 // verilator lint_on UNUSED
11927 endmodule
11928
11929Typing \\[verilog-auto] will make this into:
11930
11931 ...
11932 // verilator lint_off UNUSED
11933 wire _unused_ok = &{1'b0,
11934 /*AUTOUNUSED*/
11935 // Beginning of automatics
11936 unused_input_a,
11937 unused_input_b,
11938 unused_input_c,
11939 // End of automatics
11940 1'b0};
11941 // verilator lint_on UNUSED
11942 endmodule"
11943 (interactive)
11944 (save-excursion
11945 ;; Find beginning
11946 (let* ((indent-pt (progn (search-backward "/*") (current-column)))
11947 (modi (verilog-modi-current))
5509c6ad
DN
11948 (moddecls (verilog-modi-get-decls modi))
11949 (modsubdecls (verilog-modi-get-sub-decls modi))
6341f357 11950 (sig-list (verilog-signals-not-in
5509c6ad
DN
11951 (append (verilog-decls-get-inputs moddecls)
11952 (verilog-decls-get-inouts moddecls))
11953 (append (verilog-subdecls-get-inputs modsubdecls)
11954 (verilog-subdecls-get-inouts modsubdecls)))))
6341f357
DN
11955 (setq sig-list (verilog-signals-not-matching-regexp
11956 sig-list verilog-auto-unused-ignore-regexp))
11957 (when sig-list
11958 (forward-line 1)
11959 (verilog-insert-indent "// Beginning of automatic unused inputs\n")
11960 (setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare))
11961 (while sig-list
11962 (let ((sig (car sig-list)))
11963 (indent-to indent-pt)
11964 (insert (verilog-sig-name sig) ",\n")
11965 (setq sig-list (cdr sig-list))))
60618039 11966 (verilog-insert-indent "// End of automatics\n")))))
6341f357
DN
11967
11968(defun verilog-enum-ascii (signm elim-regexp)
37ea4b9b 11969 "Convert an enum name SIGNM to an ascii string for insertion.
6341f357
DN
11970Remove user provided prefix ELIM-REGEXP."
11971 (or elim-regexp (setq elim-regexp "_ DONT MATCH IT_"))
11972 (let ((case-fold-search t))
11973 ;; All upper becomes all lower for readability
11974 (downcase (verilog-string-replace-matches elim-regexp "" nil nil signm))))
11975
11976(defun verilog-auto-ascii-enum ()
11977 "Expand AUTOASCIIENUM statements, as part of \\[verilog-auto].
11978Create a register to contain the ASCII decode of a enumerated signal type.
11979This will allow trace viewers to show the ASCII name of states.
11980
11981First, parameters are built into a enumeration using the synopsys enum
11982comment. The comment must be between the keyword and the symbol.
6edb5716 11983\(Annoying, but that's what Synopsys's dc_shell FSM reader requires.)
6341f357
DN
11984
11985Next, registers which that enum applies to are also tagged with the same
9489a450 11986enum.
6341f357
DN
11987
11988Finally, a AUTOASCIIENUM command is used.
11989
11990 The first parameter is the name of the signal to be decoded.
11991
11992 The second parameter is the name to store the ASCII code into. For the
11993 signal foo, I suggest the name _foo__ascii, where the leading _ indicates
11994 a signal that is just for simulation, and the magic characters _ascii
11995 tell viewers like Dinotrace to display in ASCII format.
11996
9489a450
MM
11997 The third optional parameter is a string which will be removed
11998 from the state names. It defaults to "" which removes nothing.
11999
12000 The fourth optional parameter is \"onehot\" to force one-hot
12001 decoding. If unspecified, if and only if the first parameter
12002 width is 2^(number of states in enum) and does NOT match the
12003 width of the enum, the signal is assumed to be a one hot
12004 decode. Otherwise, it's a normal encoded state vector.
12005
12006 `verilog-auto-wire-type' may be used to change the datatype of
12007 the declarations.
6341f357
DN
12008
12009An example:
12010
12011 //== State enumeration
12012 parameter [2:0] // synopsys enum state_info
12013 SM_IDLE = 3'b000,
12014 SM_SEND = 3'b001,
12015 SM_WAIT1 = 3'b010;
12016 //== State variables
a3a8b002
DN
12017 reg [2:0] /* synopsys enum state_info */
12018 state_r; /* synopsys state_vector state_r */
12019 reg [2:0] /* synopsys enum state_info */
12020 state_e1;
6341f357
DN
12021
12022 /*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
12023
12024Typing \\[verilog-auto] will make this into:
12025
12026 ... same front matter ...
12027
12028 /*AUTOASCIIENUM(\"state_r\", \"state_ascii_r\", \"SM_\")*/
12029 // Beginning of automatic ASCII enum decoding
12030 reg [39:0] state_ascii_r; // Decode of state_r
12031 always @(state_r) begin
12032 case ({state_r})
12033 SM_IDLE: state_ascii_r = \"idle \";
12034 SM_SEND: state_ascii_r = \"send \";
12035 SM_WAIT1: state_ascii_r = \"wait1\";
12036 default: state_ascii_r = \"%Erro\";
12037 endcase
12038 end
12039 // End of automatics"
12040 (save-excursion
9489a450 12041 (let* ((params (verilog-read-auto-params 2 4))
6341f357
DN
12042 (undecode-name (nth 0 params))
12043 (ascii-name (nth 1 params))
9489a450
MM
12044 (elim-regexp (and (nth 2 params)
12045 (not (equal (nth 2 params) ""))
12046 (nth 2 params)))
12047 (one-hot-flag (nth 3 params))
6341f357
DN
12048 ;;
12049 (indent-pt (current-indentation))
12050 (modi (verilog-modi-current))
5509c6ad 12051 (moddecls (verilog-modi-get-decls modi))
6341f357 12052 ;;
5509c6ad
DN
12053 (sig-list-consts (append (verilog-decls-get-consts moddecls)
12054 (verilog-decls-get-gparams moddecls)))
9489a450 12055 (sig-list-all (append (verilog-decls-get-vars moddecls)
5509c6ad
DN
12056 (verilog-decls-get-outputs moddecls)
12057 (verilog-decls-get-inouts moddecls)
9489a450 12058 (verilog-decls-get-inputs moddecls)))
6341f357
DN
12059 ;;
12060 (undecode-sig (or (assoc undecode-name sig-list-all)
12061 (error "%s: Signal %s not found in design" (verilog-point-text) undecode-name)))
12062 (undecode-enum (or (verilog-sig-enum undecode-sig)
12063 (error "%s: Signal %s does not have a enum tag" (verilog-point-text) undecode-name)))
12064 ;;
a3a8b002
DN
12065 (enum-sigs (verilog-signals-not-in
12066 (or (verilog-signals-matching-enum sig-list-consts undecode-enum)
12067 (error "%s: No state definitions for %s" (verilog-point-text) undecode-enum))
12068 nil))
6341f357 12069 ;;
9489a450
MM
12070 (one-hot (or
12071 (string-match "onehot" (or one-hot-flag ""))
12072 (and ;; width(enum) != width(sig)
12073 (or (not (verilog-sig-bits (car enum-sigs)))
12074 (not (equal (verilog-sig-width (car enum-sigs))
12075 (verilog-sig-width undecode-sig))))
12076 ;; count(enums) == width(sig)
12077 (equal (number-to-string (length enum-sigs))
12078 (verilog-sig-width undecode-sig)))))
a3a8b002 12079 (enum-chars 0)
6341f357
DN
12080 (ascii-chars 0))
12081 ;;
12082 ;; Find number of ascii chars needed
12083 (let ((tmp-sigs enum-sigs))
12084 (while tmp-sigs
12085 (setq enum-chars (max enum-chars (length (verilog-sig-name (car tmp-sigs))))
12086 ascii-chars (max ascii-chars (length (verilog-enum-ascii
12087 (verilog-sig-name (car tmp-sigs))
12088 elim-regexp)))
12089 tmp-sigs (cdr tmp-sigs))))
12090 ;;
12091 (forward-line 1)
12092 (verilog-insert-indent "// Beginning of automatic ASCII enum decoding\n")
12093 (let ((decode-sig-list (list (list ascii-name (format "[%d:0]" (- (* ascii-chars 8) 1))
12094 (concat "Decode of " undecode-name) nil nil))))
9489a450 12095 (verilog-insert-definition modi decode-sig-list "reg" indent-pt nil))
6341f357
DN
12096 ;;
12097 (verilog-insert-indent "always @(" undecode-name ") begin\n")
12098 (setq indent-pt (+ indent-pt verilog-indent-level))
9489a450 12099 (verilog-insert-indent "case ({" undecode-name "})\n")
6341f357
DN
12100 (setq indent-pt (+ indent-pt verilog-case-indent))
12101 ;;
12102 (let ((tmp-sigs enum-sigs)
a3a8b002
DN
12103 (chrfmt (format "%%-%ds %s = \"%%-%ds\";\n"
12104 (+ (if one-hot 9 1) (max 8 enum-chars))
6341f357
DN
12105 ascii-name ascii-chars))
12106 (errname (substring "%Error" 0 (min 6 ascii-chars))))
12107 (while tmp-sigs
12108 (verilog-insert-indent
a3a8b002
DN
12109 (concat
12110 (format chrfmt
12111 (concat (if one-hot "(")
9489a450
MM
12112 ;; Use enum-sigs length as that's numeric
12113 ;; verilog-sig-width undecode-sig might not be.
12114 (if one-hot (number-to-string (length enum-sigs)))
a3a8b002
DN
12115 ;; We use a shift instead of var[index]
12116 ;; so that a non-one hot value will show as error.
12117 (if one-hot "'b1<<")
12118 (verilog-sig-name (car tmp-sigs))
12119 (if one-hot ")") ":")
12120 (verilog-enum-ascii (verilog-sig-name (car tmp-sigs))
12121 elim-regexp))))
6341f357
DN
12122 (setq tmp-sigs (cdr tmp-sigs)))
12123 (verilog-insert-indent (format chrfmt "default:" errname)))
12124 ;;
12125 (setq indent-pt (- indent-pt verilog-case-indent))
12126 (verilog-insert-indent "endcase\n")
12127 (setq indent-pt (- indent-pt verilog-indent-level))
12128 (verilog-insert-indent "end\n"
60618039 12129 "// End of automatics\n"))))
6341f357
DN
12130
12131(defun verilog-auto-templated-rel ()
12132 "Replace Templated relative line numbers with absolute line numbers.
12133Internal use only. This hacks around the line numbers in AUTOINST Templates
12134being different from the final output's line numbering."
a03c2342 12135 (let ((templateno 0) (template-line (list 0)) (buf-line 1))
6341f357 12136 ;; Find line number each template is on
a03c2342 12137 ;; Count lines as we go, as otherwise it's O(n^2) to use count-lines
6341f357 12138 (goto-char (point-min))
a03c2342
WS
12139 (while (not (eobp))
12140 (when (looking-at ".*AUTO_TEMPLATE")
12141 (setq templateno (1+ templateno))
12142 (setq template-line (cons buf-line template-line)))
12143 (setq buf-line (1+ buf-line))
12144 (forward-line 1))
6341f357
DN
12145 (setq template-line (nreverse template-line))
12146 ;; Replace T# L# with absolute line number
12147 (goto-char (point-min))
12148 (while (re-search-forward " Templated T\\([0-9]+\\) L\\([0-9]+\\)" nil t)
7ea26faf
DN
12149 (replace-match
12150 (concat " Templated "
12151 (int-to-string (+ (nth (string-to-number (match-string 1))
12152 template-line)
12153 (string-to-number (match-string 2)))))
12154 t t))))
6341f357
DN
12155
12156\f
12157;;
12158;; Auto top level
12159;;
12160
12161(defun verilog-auto (&optional inject) ; Use verilog-inject-auto instead of passing a arg
12162 "Expand AUTO statements.
12163Look for any /*AUTO...*/ commands in the code, as used in
12164instantiations or argument headers. Update the list of signals
12165following the /*AUTO...*/ command.
12166
12167Use \\[verilog-delete-auto] to remove the AUTOs.
12168
9489a450
MM
12169Use \\[verilog-diff-auto] to see differences in AUTO expansion.
12170
6341f357
DN
12171Use \\[verilog-inject-auto] to insert AUTOs for the first time.
12172
12173Use \\[verilog-faq] for a pointer to frequently asked questions.
12174
12175The hooks `verilog-before-auto-hook' and `verilog-auto-hook' are
12176called before and after this function, respectively.
12177
12178For example:
a03c2342 12179 module ModuleName (/*AUTOARG*/);
6341f357
DN
12180 /*AUTOINPUT*/
12181 /*AUTOOUTPUT*/
12182 /*AUTOWIRE*/
12183 /*AUTOREG*/
1dd4b004 12184 InstMod instName #(/*AUTOINSTPARAM*/) (/*AUTOINST*/);
6341f357
DN
12185
12186You can also update the AUTOs from the shell using:
12187 emacs --batch <filenames.v> -f verilog-batch-auto
12188Or fix indentation with:
12189 emacs --batch <filenames.v> -f verilog-batch-indent
12190Likewise, you can delete or inject AUTOs with:
12191 emacs --batch <filenames.v> -f verilog-batch-delete-auto
12192 emacs --batch <filenames.v> -f verilog-batch-inject-auto
9489a450
MM
12193Or check if AUTOs have the same expansion
12194 emacs --batch <filenames.v> -f verilog-batch-diff-auto
6341f357
DN
12195
12196Using \\[describe-function], see also:
12197 `verilog-auto-arg' for AUTOARG module instantiations
12198 `verilog-auto-ascii-enum' for AUTOASCIIENUM enumeration decoding
9489a450
MM
12199 `verilog-auto-inout-comp' for AUTOINOUTCOMP copy complemented i/o
12200 `verilog-auto-inout-in' for AUTOINOUTIN inputs for all i/o
6341f357
DN
12201 `verilog-auto-inout-module' for AUTOINOUTMODULE copying i/o from elsewhere
12202 `verilog-auto-inout' for AUTOINOUT making hierarchy inouts
12203 `verilog-auto-input' for AUTOINPUT making hierarchy inputs
a3a8b002 12204 `verilog-auto-insert-lisp' for AUTOINSERTLISP insert code from lisp function
6341f357
DN
12205 `verilog-auto-inst' for AUTOINST instantiation pins
12206 `verilog-auto-star' for AUTOINST .* SystemVerilog pins
12207 `verilog-auto-inst-param' for AUTOINSTPARAM instantiation params
9489a450 12208 `verilog-auto-logic' for AUTOLOGIC declaring logic signals
6341f357
DN
12209 `verilog-auto-output' for AUTOOUTPUT making hierarchy outputs
12210 `verilog-auto-output-every' for AUTOOUTPUTEVERY making all outputs
12211 `verilog-auto-reg' for AUTOREG registers
12212 `verilog-auto-reg-input' for AUTOREGINPUT instantiation registers
12213 `verilog-auto-reset' for AUTORESET flop resets
12214 `verilog-auto-sense' for AUTOSENSE always sensitivity lists
12215 `verilog-auto-tieoff' for AUTOTIEOFF output tieoffs
12216 `verilog-auto-unused' for AUTOUNUSED unused inputs/inouts
12217 `verilog-auto-wire' for AUTOWIRE instantiation wires
12218
12219 `verilog-read-defines' for reading `define values
12220 `verilog-read-includes' for reading `includes
12221
a3a8b002 12222If you have bugs with these autos, please file an issue at
855b42a2 12223URL `http://www.veripool.org/verilog-mode' or contact the AUTOAUTHOR
a3a8b002 12224Wilson Snyder (wsnyder@wsnyder.org)."
6341f357
DN
12225 (interactive)
12226 (unless noninteractive (message "Updating AUTOs..."))
7ea26faf 12227 (if (fboundp 'dinotrace-unannotate-all)
6341f357
DN
12228 (dinotrace-unannotate-all))
12229 (let ((oldbuf (if (not (buffer-modified-p))
12230 (buffer-string)))
12231 ;; Before version 20, match-string with font-lock returns a
12232 ;; vector that is not equal to the string. IE if on "input"
12233 ;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
12234 (fontlocked (when (and (boundp 'font-lock-mode)
12235 font-lock-mode)
7cb1c4d7 12236 (font-lock-mode 0)
5509c6ad
DN
12237 t))
12238 ;; Cache directories; we don't write new files, so can't change
a03c2342
WS
12239 (verilog-dir-cache-preserving t)
12240 ;; Cache current module
12241 (verilog-modi-cache-current-enable t)
12242 (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
12243 verilog-modi-cache-current)
12244 (unwind-protect
12245 ;; Disable change hooks for speed
12246 ;; This let can't be part of above let; must restore
12247 ;; after-change-functions before font-lock resumes
12248 (verilog-save-no-change-functions
12249 (verilog-save-scan-cache
12250 (save-excursion
9489a450
MM
12251 ;; Wipe cache; otherwise if we AUTOed a block above this one,
12252 ;; we'll misremember we have generated IOs, confusing AUTOOUTPUT
12253 (setq verilog-modi-cache-list nil)
a03c2342
WS
12254 ;; If we're not in verilog-mode, change syntax table so parsing works right
12255 (unless (eq major-mode `verilog-mode) (verilog-mode))
12256 ;; Allow user to customize
9489a450 12257 (verilog-run-hooks 'verilog-before-auto-hook)
a03c2342
WS
12258 ;; Try to save the user from needing to revert-file to reread file local-variables
12259 (verilog-auto-reeval-locals)
12260 (verilog-read-auto-lisp-present)
12261 (verilog-read-auto-lisp (point-min) (point-max))
12262 (verilog-getopt-flags)
12263 ;; From here on out, we can cache anything we read from disk
12264 (verilog-preserve-dir-cache
12265 ;; These two may seem obvious to do always, but on large includes it can be way too slow
12266 (when verilog-auto-read-includes
12267 (verilog-read-includes)
12268 (verilog-read-defines nil nil t))
12269 ;; This particular ordering is important
12270 ;; INST: Lower modules correct, no internal dependencies, FIRST
12271 (verilog-preserve-modi-cache
12272 ;; Clear existing autos else we'll be screwed by existing ones
12273 (verilog-delete-auto)
12274 ;; Injection if appropriate
12275 (when inject
12276 (verilog-inject-inst)
12277 (verilog-inject-sense)
12278 (verilog-inject-arg))
12279 ;;
12280 ;; Do user inserts first, so their code can insert AUTOs
12281 ;; We may provide a AUTOINSERTLISPLAST if another cleanup pass is needed
12282 (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
12283 'verilog-auto-insert-lisp)
12284 ;; Expand instances before need the signals the instances input/output
12285 (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
12286 (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
12287 (verilog-auto-re-search-do "\\.\\*" 'verilog-auto-star)
12288 ;; Doesn't matter when done, but combine it with a common changer
12289 (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
12290 (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
12291 ;; Must be done before autoin/out as creates a reg
12292 (verilog-auto-re-search-do "/\\*AUTOASCIIENUM([^)]*)\\*/" 'verilog-auto-ascii-enum)
12293 ;;
12294 ;; first in/outs from other files
12295 (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE([^)]*)\\*/" 'verilog-auto-inout-module)
12296 (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP([^)]*)\\*/" 'verilog-auto-inout-comp)
9489a450 12297 (verilog-auto-re-search-do "/\\*AUTOINOUTIN([^)]*)\\*/" 'verilog-auto-inout-in)
a03c2342
WS
12298 ;; next in/outs which need previous sucked inputs first
12299 (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((\"[^\"]*\")\\)\\*/"
4f91a816 12300 (lambda () (verilog-auto-output t)))
a03c2342
WS
12301 (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\*/" 'verilog-auto-output)
12302 (verilog-auto-re-search-do "/\\*AUTOINPUT\\((\"[^\"]*\")\\)\\*/"
4f91a816 12303 (lambda () (verilog-auto-input t)))
a03c2342
WS
12304 (verilog-auto-re-search-do "/\\*AUTOINPUT\\*/" 'verilog-auto-input)
12305 (verilog-auto-re-search-do "/\\*AUTOINOUT\\((\"[^\"]*\")\\)\\*/"
4f91a816 12306 (lambda () (verilog-auto-inout t)))
a03c2342
WS
12307 (verilog-auto-re-search-do "/\\*AUTOINOUT\\*/" 'verilog-auto-inout)
12308 ;; Then tie off those in/outs
12309 (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
12310 ;; Wires/regs must be after inputs/outputs
9489a450 12311 (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic)
a03c2342
WS
12312 (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
12313 (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
12314 (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
12315 ;; outputevery needs AUTOOUTPUTs done first
12316 (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\*/" 'verilog-auto-output-every)
12317 ;; After we've created all new variables
12318 (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
12319 ;; Must be after all inputs outputs are generated
12320 (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
12321 ;; Fix line numbers (comments only)
12322 (when verilog-auto-inst-template-numbers
12323 (verilog-auto-templated-rel))))
12324 ;;
9489a450
MM
12325 (verilog-run-hooks 'verilog-auto-hook)
12326 ;;
12327 (when verilog-auto-delete-trailing-whitespace
12328 (verilog-delete-trailing-whitespace))
a03c2342
WS
12329 ;;
12330 (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))
12331 ;;
12332 ;; If end result is same as when started, clear modified flag
12333 (cond ((and oldbuf (equal oldbuf (buffer-string)))
12334 (set-buffer-modified-p nil)
12335 (unless noninteractive (message "Updating AUTOs...done (no changes)")))
12336 (t (unless noninteractive (message "Updating AUTOs...done"))))
12337 ;; End of after-change protection
12338 )))
12339 ;; Unwind forms
12340 (progn
12341 ;; Restore font-lock
12342 (when fontlocked (font-lock-mode t))))))
6341f357
DN
12343\f
12344
12345;;
12346;; Skeleton based code insertion
12347;;
60618039 12348(defvar verilog-template-map
6edb5716
DN
12349 (let ((map (make-sparse-keymap)))
12350 (define-key map "a" 'verilog-sk-always)
12351 (define-key map "b" 'verilog-sk-begin)
12352 (define-key map "c" 'verilog-sk-case)
12353 (define-key map "f" 'verilog-sk-for)
12354 (define-key map "g" 'verilog-sk-generate)
12355 (define-key map "h" 'verilog-sk-header)
12356 (define-key map "i" 'verilog-sk-initial)
12357 (define-key map "j" 'verilog-sk-fork)
12358 (define-key map "m" 'verilog-sk-module)
9489a450 12359 (define-key map "o" 'verilog-sk-ovm-class)
6edb5716
DN
12360 (define-key map "p" 'verilog-sk-primitive)
12361 (define-key map "r" 'verilog-sk-repeat)
12362 (define-key map "s" 'verilog-sk-specify)
12363 (define-key map "t" 'verilog-sk-task)
9489a450 12364 (define-key map "u" 'verilog-sk-uvm-class)
6edb5716
DN
12365 (define-key map "w" 'verilog-sk-while)
12366 (define-key map "x" 'verilog-sk-casex)
12367 (define-key map "z" 'verilog-sk-casez)
12368 (define-key map "?" 'verilog-sk-if)
12369 (define-key map ":" 'verilog-sk-else-if)
12370 (define-key map "/" 'verilog-sk-comment)
12371 (define-key map "A" 'verilog-sk-assign)
12372 (define-key map "F" 'verilog-sk-function)
12373 (define-key map "I" 'verilog-sk-input)
12374 (define-key map "O" 'verilog-sk-output)
12375 (define-key map "S" 'verilog-sk-state-machine)
12376 (define-key map "=" 'verilog-sk-inout)
12377 (define-key map "W" 'verilog-sk-wire)
12378 (define-key map "R" 'verilog-sk-reg)
30d48f20
DN
12379 (define-key map "D" 'verilog-sk-define-signal)
12380 map)
6341f357
DN
12381 "Keymap used in Verilog mode for smart template operations.")
12382
6341f357
DN
12383
12384;;
12385;; Place the templates into Verilog Mode. They may be inserted under any key.
12386;; C-c C-t will be the default. If you use templates a lot, you
12387;; may want to consider moving the binding to another key in your .emacs
12388;; file.
12389;;
9489a450 12390;; Note \C-c and letter are reserved for users
6341f357
DN
12391(define-key verilog-mode-map "\C-c\C-t" verilog-template-map)
12392
12393;;; ---- statement skeletons ------------------------------------------
12394
12395(define-skeleton verilog-sk-prompt-condition
12396 "Prompt for the loop condition."
12397 "[condition]: " str )
12398
12399(define-skeleton verilog-sk-prompt-init
12400 "Prompt for the loop init statement."
12401 "[initial statement]: " str )
12402
12403(define-skeleton verilog-sk-prompt-inc
12404 "Prompt for the loop increment statement."
12405 "[increment statement]: " str )
12406
12407(define-skeleton verilog-sk-prompt-name
12408 "Prompt for the name of something."
12409 "[name]: " str)
12410
12411(define-skeleton verilog-sk-prompt-clock
12412 "Prompt for the name of something."
12413 "name and edge of clock(s): " str)
12414
12415(defvar verilog-sk-reset nil)
12416(defun verilog-sk-prompt-reset ()
12417 "Prompt for the name of a state machine reset."
7ea26faf 12418 (setq verilog-sk-reset (read-string "name of reset: " "rst")))
6341f357
DN
12419
12420
12421(define-skeleton verilog-sk-prompt-state-selector
12422 "Prompt for the name of a state machine selector."
12423 "name of selector (eg {a,b,c,d}): " str )
12424
12425(define-skeleton verilog-sk-prompt-output
12426 "Prompt for the name of something."
12427 "output: " str)
12428
12429(define-skeleton verilog-sk-prompt-msb
9489a450 12430 "Prompt for most significant bit specification."
f07fe184 12431 "msb:" str & ?: & '(verilog-sk-prompt-lsb) | -1 )
6341f357
DN
12432
12433(define-skeleton verilog-sk-prompt-lsb
12434 "Prompt for least significant bit specification."
12435 "lsb:" str )
12436
12437(defvar verilog-sk-p nil)
12438(define-skeleton verilog-sk-prompt-width
12439 "Prompt for a width specification."
12440 ()
12441 (progn
12442 (setq verilog-sk-p (point))
12443 (verilog-sk-prompt-msb)
12444 (if (> (point) verilog-sk-p) "] " " ")))
12445
12446(defun verilog-sk-header ()
a3a8b002
DN
12447 "Insert a descriptive header at the top of the file.
12448See also `verilog-header' for an alternative format."
6341f357
DN
12449 (interactive "*")
12450 (save-excursion
12451 (goto-char (point-min))
12452 (verilog-sk-header-tmpl)))
12453
12454(define-skeleton verilog-sk-header-tmpl
12455 "Insert a comment block containing the module title, author, etc."
12456 "[Description]: "
12457 "// -*- Mode: Verilog -*-"
12458 "\n// Filename : " (buffer-name)
12459 "\n// Description : " str
12460 "\n// Author : " (user-full-name)
12461 "\n// Created On : " (current-time-string)
a3a8b002
DN
12462 "\n// Last Modified By: " (user-full-name)
12463 "\n// Last Modified On: " (current-time-string)
6341f357
DN
12464 "\n// Update Count : 0"
12465 "\n// Status : Unknown, Use with caution!"
12466 "\n")
12467
12468(define-skeleton verilog-sk-module
12469 "Insert a module definition."
12470 ()
f07fe184 12471 > "module " '(verilog-sk-prompt-name) " (/*AUTOARG*/ ) ;" \n
6341f357
DN
12472 > _ \n
12473 > (- verilog-indent-level-behavioral) "endmodule" (progn (electric-verilog-terminate-line) nil))
12474
9489a450
MM
12475;;; ------------------------------------------------------------------------
12476;;; Define a default OVM class, with macros and new()
12477;;; ------------------------------------------------------------------------
12478
12479(define-skeleton verilog-sk-ovm-class
12480 "Insert a class definition"
12481 ()
12482 > "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
12483 > _ \n
12484 > "`ovm_object_utils_begin(" name ")" \n
12485 > (- verilog-indent-level) " `ovm_object_utils_end" \n
12486 > _ \n
12487 > "function new(name=\"" name "\");" \n
12488 > "super.new(name);" \n
12489 > (- verilog-indent-level) "endfunction" \n
12490 > _ \n
12491 > "endclass" (progn (electric-verilog-terminate-line) nil))
12492
12493(define-skeleton verilog-sk-uvm-class
12494 "Insert a class definition"
12495 ()
12496 > "class " (setq name (skeleton-read "Name: ")) " extends " (skeleton-read "Extends: ") ";" \n
12497 > _ \n
12498 > "`uvm_object_utils_begin(" name ")" \n
12499 > (- verilog-indent-level) " `uvm_object_utils_end" \n
12500 > _ \n
12501 > "function new(name=\"" name "\");" \n
12502 > "super.new(name);" \n
12503 > (- verilog-indent-level) "endfunction" \n
12504 > _ \n
12505 > "endclass" (progn (electric-verilog-terminate-line) nil))
12506
6341f357
DN
12507(define-skeleton verilog-sk-primitive
12508 "Insert a task definition."
12509 ()
f07fe184 12510 > "primitive " '(verilog-sk-prompt-name) " ( " '(verilog-sk-prompt-output) ("input:" ", " str ) " );"\n
6341f357
DN
12511 > _ \n
12512 > (- verilog-indent-level-behavioral) "endprimitive" (progn (electric-verilog-terminate-line) nil))
12513
12514(define-skeleton verilog-sk-task
12515 "Insert a task definition."
12516 ()
f07fe184 12517 > "task " '(verilog-sk-prompt-name) & ?; \n
6341f357
DN
12518 > _ \n
12519 > "begin" \n
12520 > \n
12521 > (- verilog-indent-level-behavioral) "end" \n
12522 > (- verilog-indent-level-behavioral) "endtask" (progn (electric-verilog-terminate-line) nil))
12523
12524(define-skeleton verilog-sk-function
12525 "Insert a function definition."
12526 ()
f07fe184 12527 > "function [" '(verilog-sk-prompt-width) | -1 '(verilog-sk-prompt-name) ?; \n
6341f357
DN
12528 > _ \n
12529 > "begin" \n
12530 > \n
12531 > (- verilog-indent-level-behavioral) "end" \n
12532 > (- verilog-indent-level-behavioral) "endfunction" (progn (electric-verilog-terminate-line) nil))
12533
12534(define-skeleton verilog-sk-always
12535 "Insert always block. Uses the minibuffer to prompt
12536for sensitivity list."
12537 ()
12538 > "always @ ( /*AUTOSENSE*/ ) begin\n"
12539 > _ \n
12540 > (- verilog-indent-level-behavioral) "end" \n >
12541 )
12542
12543(define-skeleton verilog-sk-initial
12544 "Insert an initial block."
12545 ()
12546 > "initial begin\n"
12547 > _ \n
12548 > (- verilog-indent-level-behavioral) "end" \n > )
12549
12550(define-skeleton verilog-sk-specify
12551 "Insert specify block. "
12552 ()
12553 > "specify\n"
12554 > _ \n
12555 > (- verilog-indent-level-behavioral) "endspecify" \n > )
12556
12557(define-skeleton verilog-sk-generate
12558 "Insert generate block. "
12559 ()
12560 > "generate\n"
12561 > _ \n
12562 > (- verilog-indent-level-behavioral) "endgenerate" \n > )
12563
12564(define-skeleton verilog-sk-begin
37ea4b9b 12565 "Insert begin end block. Uses the minibuffer to prompt for name."
6341f357 12566 ()
f07fe184 12567 > "begin" '(verilog-sk-prompt-name) \n
6341f357
DN
12568 > _ \n
12569 > (- verilog-indent-level-behavioral) "end"
12570)
12571
12572(define-skeleton verilog-sk-fork
37ea4b9b 12573 "Insert a fork join block."
6341f357
DN
12574 ()
12575 > "fork\n"
12576 > "begin" \n
12577 > _ \n
12578 > (- verilog-indent-level-behavioral) "end" \n
12579 > "begin" \n
12580 > \n
12581 > (- verilog-indent-level-behavioral) "end" \n
12582 > (- verilog-indent-level-behavioral) "join" \n
12583 > )
12584
12585
12586(define-skeleton verilog-sk-case
12587 "Build skeleton case statement, prompting for the selector expression,
12588and the case items."
12589 "[selector expression]: "
12590 > "case (" str ") " \n
a3a8b002 12591 > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n > )
6341f357
DN
12592 resume: > (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
12593
12594(define-skeleton verilog-sk-casex
12595 "Build skeleton casex statement, prompting for the selector expression,
12596and the case items."
12597 "[selector expression]: "
12598 > "casex (" str ") " \n
a3a8b002 12599 > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n > )
6341f357
DN
12600 resume: > (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
12601
12602(define-skeleton verilog-sk-casez
12603 "Build skeleton casez statement, prompting for the selector expression,
12604and the case items."
12605 "[selector expression]: "
12606 > "casez (" str ") " \n
a3a8b002 12607 > ("case selector: " str ": begin" \n > _ \n > (- verilog-indent-level-behavioral) "end" \n > )
6341f357
DN
12608 resume: > (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil))
12609
12610(define-skeleton verilog-sk-if
12611 "Insert a skeleton if statement."
f07fe184 12612 > "if (" '(verilog-sk-prompt-condition) & ")" " begin" \n
6341f357
DN
12613 > _ \n
12614 > (- verilog-indent-level-behavioral) "end " \n )
12615
12616(define-skeleton verilog-sk-else-if
12617 "Insert a skeleton else if statement."
12618 > (verilog-indent-line) "else if ("
f07fe184 12619 (progn (setq verilog-sk-p (point)) nil) '(verilog-sk-prompt-condition) (if (> (point) verilog-sk-p) ") " -1 ) & " begin" \n
6341f357
DN
12620 > _ \n
12621 > "end" (progn (electric-verilog-terminate-line) nil))
12622
12623(define-skeleton verilog-sk-datadef
37ea4b9b 12624 "Common routine to get data definition."
6341f357 12625 ()
f07fe184 12626 '(verilog-sk-prompt-width) | -1 ("name (RET to end):" str ", ") -2 ";" \n)
6341f357
DN
12627
12628(define-skeleton verilog-sk-input
12629 "Insert an input definition."
12630 ()
f07fe184 12631 > "input [" '(verilog-sk-datadef))
6341f357
DN
12632
12633(define-skeleton verilog-sk-output
12634 "Insert an output definition."
12635 ()
f07fe184 12636 > "output [" '(verilog-sk-datadef))
6341f357
DN
12637
12638(define-skeleton verilog-sk-inout
12639 "Insert an inout definition."
12640 ()
f07fe184 12641 > "inout [" '(verilog-sk-datadef))
6341f357
DN
12642
12643(defvar verilog-sk-signal nil)
12644(define-skeleton verilog-sk-def-reg
12645 "Insert a reg definition."
12646 ()
f07fe184 12647 > "reg [" '(verilog-sk-prompt-width) | -1 verilog-sk-signal ";" \n (verilog-pretty-declarations) )
6341f357
DN
12648
12649(defun verilog-sk-define-signal ()
12650 "Insert a definition of signal under point at top of module."
12651 (interactive "*")
60618039 12652 (let* ((sig-re "[a-zA-Z0-9_]*")
6341f357
DN
12653 (v1 (buffer-substring
12654 (save-excursion
12655 (skip-chars-backward sig-re)
12656 (point))
12657 (save-excursion
12658 (skip-chars-forward sig-re)
60618039 12659 (point)))))
6341f357
DN
12660 (if (not (member v1 verilog-keywords))
12661 (save-excursion
12662 (setq verilog-sk-signal v1)
12663 (verilog-beg-of-defun)
12664 (verilog-end-of-statement)
12665 (verilog-forward-syntactic-ws)
12666 (verilog-sk-def-reg)
12667 (message "signal at point is %s" v1))
60618039 12668 (message "object at point (%s) is a keyword" v1))))
6341f357
DN
12669
12670(define-skeleton verilog-sk-wire
12671 "Insert a wire definition."
12672 ()
f07fe184 12673 > "wire [" '(verilog-sk-datadef))
6341f357
DN
12674
12675(define-skeleton verilog-sk-reg
12676 "Insert a reg definition."
12677 ()
f07fe184 12678 > "reg [" '(verilog-sk-datadef))
6341f357
DN
12679
12680(define-skeleton verilog-sk-assign
12681 "Insert a skeleton assign statement."
12682 ()
f07fe184 12683 > "assign " '(verilog-sk-prompt-name) " = " _ ";" \n)
6341f357
DN
12684
12685(define-skeleton verilog-sk-while
12686 "Insert a skeleton while loop statement."
12687 ()
f07fe184 12688 > "while (" '(verilog-sk-prompt-condition) ") begin" \n
6341f357
DN
12689 > _ \n
12690 > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
12691
12692(define-skeleton verilog-sk-repeat
12693 "Insert a skeleton repeat loop statement."
12694 ()
f07fe184 12695 > "repeat (" '(verilog-sk-prompt-condition) ") begin" \n
6341f357
DN
12696 > _ \n
12697 > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
12698
12699(define-skeleton verilog-sk-for
12700 "Insert a skeleton while loop statement."
12701 ()
12702 > "for ("
f07fe184
DN
12703 '(verilog-sk-prompt-init) "; "
12704 '(verilog-sk-prompt-condition) "; "
12705 '(verilog-sk-prompt-inc)
6341f357
DN
12706 ") begin" \n
12707 > _ \n
12708 > (- verilog-indent-level-behavioral) "end " (progn (electric-verilog-terminate-line) nil))
12709
12710(define-skeleton verilog-sk-comment
12711 "Inserts three comment lines, making a display comment."
12712 ()
12713 > "/*\n"
12714 > "* " _ \n
12715 > "*/")
12716
12717(define-skeleton verilog-sk-state-machine
12718 "Insert a state machine definition."
12719 "Name of state variable: "
12720 '(setq input "state")
12721 > "// State registers for " str | -23 \n
12722 '(setq verilog-sk-state str)
f07fe184 12723 > "reg [" '(verilog-sk-prompt-width) | -1 verilog-sk-state ", next_" verilog-sk-state ?; \n
6341f357
DN
12724 '(setq input nil)
12725 > \n
12726 > "// State FF for " verilog-sk-state \n
12727 > "always @ ( " (read-string "clock:" "posedge clk") " or " (verilog-sk-prompt-reset) " ) begin" \n
12728 > "if ( " verilog-sk-reset " ) " verilog-sk-state " = 0; else" \n
12729 > verilog-sk-state " = next_" verilog-sk-state ?; \n
12730 > (- verilog-indent-level-behavioral) "end" (progn (electric-verilog-terminate-line) nil)
12731 > \n
12732 > "// Next State Logic for " verilog-sk-state \n
12733 > "always @ ( /*AUTOSENSE*/ ) begin\n"
f07fe184 12734 > "case (" '(verilog-sk-prompt-state-selector) ") " \n
6341f357
DN
12735 > ("case selector: " str ": begin" \n > "next_" verilog-sk-state " = " _ ";" \n > (- verilog-indent-level-behavioral) "end" \n )
12736 resume: > (- verilog-case-indent) "endcase" (progn (electric-verilog-terminate-line) nil)
12737 > (- verilog-indent-level-behavioral) "end" (progn (electric-verilog-terminate-line) nil))
6341f357
DN
12738\f
12739
12740;;
12741;; Include file loading with mouse/return event
12742;;
12743;; idea & first impl.: M. Rouat (eldo-mode.el)
12744;; second (emacs/xemacs) impl.: G. Van der Plas (spice-mode.el)
12745
12746(if (featurep 'xemacs)
af62aa88 12747 (require 'overlay))
6341f357
DN
12748
12749(defconst verilog-include-file-regexp
12750 "^`include\\s-+\"\\([^\n\"]*\\)\""
12751 "Regexp that matches the include file.")
12752
60618039 12753(defvar verilog-mode-mouse-map
6341f357
DN
12754 (let ((map (make-sparse-keymap))) ; as described in info pages, make a map
12755 (set-keymap-parent map verilog-mode-map)
12756 ;; mouse button bindings
12757 (define-key map "\r" 'verilog-load-file-at-point)
12758 (if (featurep 'xemacs)
12759 (define-key map 'button2 'verilog-load-file-at-mouse);ffap-at-mouse ?
12760 (define-key map [mouse-2] 'verilog-load-file-at-mouse))
12761 (if (featurep 'xemacs)
12762 (define-key map 'Sh-button2 'mouse-yank) ; you wanna paste don't you ?
30d48f20
DN
12763 (define-key map [S-mouse-2] 'mouse-yank-at-click))
12764 map)
6edb5716
DN
12765 "Map containing mouse bindings for `verilog-mode'.")
12766
6341f357 12767
a03c2342
WS
12768(defun verilog-highlight-region (beg end old-len)
12769 "Colorize included files and modules in the (changed?) region.
6341f357 12770Clicking on the middle-mouse button loads them in a buffer (as in dired)."
a03c2342
WS
12771 (when (or verilog-highlight-includes
12772 verilog-highlight-modules)
12773 (save-excursion
12774 (save-match-data ;; A query-replace may call this function - do not disturb
12775 (verilog-save-buffer-state
12776 (verilog-save-scan-cache
12777 (let (end-point)
12778 (goto-char end)
3ba6b2ee 12779 (setq end-point (point-at-eol))
a03c2342
WS
12780 (goto-char beg)
12781 (beginning-of-line) ; scan entire line
12782 ;; delete overlays existing on this line
12783 (let ((overlays (overlays-in (point) end-point)))
12784 (while overlays
12785 (if (and
12786 (overlay-get (car overlays) 'detachable)
12787 (or (overlay-get (car overlays) 'verilog-include-file)
12788 (overlay-get (car overlays) 'verilog-inst-module)))
12789 (delete-overlay (car overlays)))
12790 (setq overlays (cdr overlays))))
12791 ;;
12792 ;; make new include overlays
12793 (when verilog-highlight-includes
12794 (while (search-forward-regexp verilog-include-file-regexp end-point t)
12795 (goto-char (match-beginning 1))
12796 (let ((ov (make-overlay (match-beginning 1) (match-end 1))))
12797 (overlay-put ov 'start-closed 't)
12798 (overlay-put ov 'end-closed 't)
12799 (overlay-put ov 'evaporate 't)
12800 (overlay-put ov 'verilog-include-file 't)
12801 (overlay-put ov 'mouse-face 'highlight)
12802 (overlay-put ov 'local-map verilog-mode-mouse-map))))
12803 ;;
12804 ;; make new module overlays
12805 (goto-char beg)
12806 ;; This scanner is syntax-fragile, so don't get bent
12807 (when verilog-highlight-modules
12808 (condition-case nil
9489a450 12809 (while (verilog-re-search-forward-quick "\\(/\\*AUTOINST\\*/\\|\\.\\*\\)" end-point t)
a03c2342
WS
12810 (save-excursion
12811 (goto-char (match-beginning 0))
9489a450 12812 (unless (verilog-inside-comment-or-string-p)
a03c2342
WS
12813 (verilog-read-inst-module-matcher) ;; sets match 0
12814 (let* ((ov (make-overlay (match-beginning 0) (match-end 0))))
12815 (overlay-put ov 'start-closed 't)
12816 (overlay-put ov 'end-closed 't)
12817 (overlay-put ov 'evaporate 't)
12818 (overlay-put ov 'verilog-inst-module 't)
12819 (overlay-put ov 'mouse-face 'highlight)
12820 (overlay-put ov 'local-map verilog-mode-mouse-map)))))
12821 (error nil)))
12822 ;;
12823 ;; Future highlights:
12824 ;; variables - make an Occur buffer of where referenced
12825 ;; pins - make an Occur buffer of the sig in the declaration module
12826 )))))))
12827
12828(defun verilog-highlight-buffer ()
12829 "Colorize included files and modules across the whole buffer."
12830 ;; Invoked via verilog-mode calling font-lock then `font-lock-mode-hook'
6341f357 12831 (interactive)
a03c2342
WS
12832 ;; delete and remake overlays
12833 (verilog-highlight-region (point-min) (point-max) nil))
12834
12835;; Deprecated, but was interactive, so we'll keep it around
12836(defalias 'verilog-colorize-include-files-buffer 'verilog-highlight-buffer)
6341f357 12837
37ea4b9b 12838;; ffap-at-mouse isn't useful for Verilog mode. It uses library paths.
6341f357
DN
12839;; so define this function to do more or less the same as ffap-at-mouse
12840;; but first resolve filename...
12841(defun verilog-load-file-at-mouse (event)
12842 "Load file under button 2 click's EVENT.
a03c2342 12843Files are checked based on `verilog-library-flags'."
6341f357 12844 (interactive "@e")
37ea4b9b 12845 (save-excursion ;; implement a Verilog specific ffap-at-mouse
6341f357 12846 (mouse-set-point event)
a03c2342 12847 (verilog-load-file-at-point t)))
6341f357 12848
8350f087 12849;; ffap isn't usable for Verilog mode. It uses library paths.
6341f357
DN
12850;; so define this function to do more or less the same as ffap
12851;; but first resolve filename...
a03c2342 12852(defun verilog-load-file-at-point (&optional warn)
6341f357 12853 "Load file under point.
a03c2342
WS
12854If WARN, throw warning if not found.
12855Files are checked based on `verilog-library-flags'."
6341f357 12856 (interactive)
37ea4b9b 12857 (save-excursion ;; implement a Verilog specific ffap
a03c2342
WS
12858 (let ((overlays (overlays-in (point) (point)))
12859 hit)
12860 (while (and overlays (not hit))
12861 (when (overlay-get (car overlays) 'verilog-inst-module)
12862 (verilog-goto-defun-file (buffer-substring
12863 (overlay-start (car overlays))
12864 (overlay-end (car overlays))))
12865 (setq hit t))
12866 (setq overlays (cdr overlays)))
12867 ;; Include?
12868 (beginning-of-line)
12869 (when (and (not hit)
12870 (looking-at verilog-include-file-regexp))
12871 (if (and (car (verilog-library-filenames
12872 (match-string 1) (buffer-file-name)))
12873 (file-readable-p (car (verilog-library-filenames
12874 (match-string 1) (buffer-file-name)))))
6341f357 12875 (find-file (car (verilog-library-filenames
a03c2342
WS
12876 (match-string 1) (buffer-file-name))))
12877 (when warn
12878 (message
12879 "File '%s' isn't readable, use shift-mouse2 to paste in this field"
12880 (match-string 1))))))))
6341f357
DN
12881
12882;;
12883;; Bug reporting
12884;;
12885
12886(defun verilog-faq ()
12887 "Tell the user their current version, and where to get the FAQ etc."
12888 (interactive)
12889 (with-output-to-temp-buffer "*verilog-mode help*"
12890 (princ (format "You are using verilog-mode %s\n" verilog-mode-version))
12891 (princ "\n")
12892 (princ "For new releases, see http://www.verilog.com\n")
12893 (princ "\n")
7cb1c4d7 12894 (princ "For frequently asked questions, see http://www.veripool.org/verilog-mode-faq.html\n")
6341f357
DN
12895 (princ "\n")
12896 (princ "To submit a bug, use M-x verilog-submit-bug-report\n")
12897 (princ "\n")))
12898
7ea26faf 12899(autoload 'reporter-submit-bug-report "reporter")
60618039 12900(defvar reporter-prompt-for-summary-p)
7ea26faf 12901
6341f357
DN
12902(defun verilog-submit-bug-report ()
12903 "Submit via mail a bug report on verilog-mode.el."
12904 (interactive)
12905 (let ((reporter-prompt-for-summary-p t))
12906 (reporter-submit-bug-report
86a4c7ac 12907 "mac@verilog.com, wsnyder@wsnyder.org"
6341f357
DN
12908 (concat "verilog-mode v" verilog-mode-version)
12909 '(
a03c2342 12910 verilog-active-low-regexp
6341f357 12911 verilog-align-ifelse
a03c2342
WS
12912 verilog-assignment-delay
12913 verilog-auto-arg-sort
6341f357
DN
12914 verilog-auto-endcomments
12915 verilog-auto-hook
a03c2342 12916 verilog-auto-ignore-concat
6341f357 12917 verilog-auto-indent-on-newline
a03c2342
WS
12918 verilog-auto-inout-ignore-regexp
12919 verilog-auto-input-ignore-regexp
12920 verilog-auto-inst-column
12921 verilog-auto-inst-dot-name
12922 verilog-auto-inst-param-value
6341f357 12923 verilog-auto-inst-template-numbers
a03c2342 12924 verilog-auto-inst-vector
6341f357
DN
12925 verilog-auto-lineup
12926 verilog-auto-newline
a03c2342
WS
12927 verilog-auto-output-ignore-regexp
12928 verilog-auto-read-includes
12929 verilog-auto-reset-widths
6341f357
DN
12930 verilog-auto-save-policy
12931 verilog-auto-sense-defines-constant
12932 verilog-auto-sense-include-inputs
a03c2342
WS
12933 verilog-auto-star-expand
12934 verilog-auto-star-save
12935 verilog-auto-unused-ignore-regexp
6341f357 12936 verilog-before-auto-hook
a03c2342
WS
12937 verilog-before-delete-auto-hook
12938 verilog-before-getopt-flags-hook
6341f357
DN
12939 verilog-case-indent
12940 verilog-cexp-indent
12941 verilog-compiler
12942 verilog-coverage
a03c2342
WS
12943 verilog-delete-auto-hook
12944 verilog-getopt-flags-hook
12945 verilog-highlight-grouping-keywords
12946 verilog-highlight-p1800-keywords
6341f357
DN
12947 verilog-highlight-translate-off
12948 verilog-indent-begin-after-if
12949 verilog-indent-declaration-macros
12950 verilog-indent-level
12951 verilog-indent-level-behavioral
12952 verilog-indent-level-declaration
12953 verilog-indent-level-directive
12954 verilog-indent-level-module
12955 verilog-indent-lists
6341f357
DN
12956 verilog-library-directories
12957 verilog-library-extensions
12958 verilog-library-files
a03c2342 12959 verilog-library-flags
6341f357
DN
12960 verilog-linter
12961 verilog-minimum-comment-distance
12962 verilog-mode-hook
a03c2342 12963 verilog-preprocessor
6341f357
DN
12964 verilog-simulator
12965 verilog-tab-always-indent
12966 verilog-tab-to-comment
a03c2342 12967 verilog-typedef-regexp
6341f357
DN
12968 )
12969 nil nil
12970 (concat "Hi Mac,
12971
86a4c7ac 12972I want to report a bug.
6341f357
DN
12973
12974Before I go further, I want to say that Verilog mode has changed my life.
12975I save so much time, my files are colored nicely, my co workers respect
12976my coding ability... until now. I'd really appreciate anything you
12977could do to help me out with this minor deficiency in the product.
12978
86a4c7ac 12979I've taken a look at the Verilog-Mode FAQ at
7cb1c4d7 12980http://www.veripool.org/verilog-mode-faq.html.
6341f357 12981
86a4c7ac
DN
12982And, I've considered filing the bug on the issue tracker at
12983http://www.veripool.org/verilog-mode-bugs
12984since I realize that public bugs are easier for you to track,
12985and for others to search, but would prefer to email.
12986
12987So, to reproduce the bug, start a fresh Emacs via " invocation-name "
37ea4b9b 12988-no-init-file -no-site-file'. In a new buffer, in Verilog mode, type
6341f357
DN
12989the code included below.
12990
12991Given those lines, I expected [[Fill in here]] to happen;
12992but instead, [[Fill in here]] happens!.
12993
12994== The code: =="))))
12995
6edb5716
DN
12996(provide 'verilog-mode)
12997
6341f357
DN
12998;; Local Variables:
12999;; checkdoc-permit-comma-termination-flag:t
13000;; checkdoc-force-docstrings-flag:nil
13001;; End:
13002
13003;;; verilog-mode.el ends here