;;; verilog-mode.el --- major mode for editing verilog source in Emacs
-;; Copyright (C) 1996-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2015 Free Software Foundation, Inc.
;; Author: Michael McNamara <mac@verilog.com>
;; Wilson Snyder <wsnyder@wsnyder.org>
;;; Code:
;; This variable will always hold the version number of the mode
-(defconst verilog-mode-version "2013-11-05-78e66ba-vpo"
+(defconst verilog-mode-version "2015-05-14-6232468-vpo-GNU"
"Version of this Verilog mode.")
(defconst verilog-mode-release-emacs t
"If non-nil, this version of Verilog mode was released with Emacs itself.")
;; Emacs.
(defalias 'verilog-regexp-opt 'regexp-opt)))
+;; emacs >=22 has looking-back, but older emacs and xemacs don't.
+;; This function is lifted directly from emacs's subr.el
+;; so that it can be used by xemacs.
+;; The idea for this was borrowed from org-mode via this link:
+;; https://lists.gnu.org/archive/html/emacs-orgmode/2009-12/msg00032.html
+(eval-and-compile
+ (cond
+ ((fboundp 'looking-back)
+ (defalias 'verilog-looking-back 'looking-back))
+ (t
+ (defun verilog-looking-back (regexp limit &optional greedy)
+ "Return non-nil if text before point matches regular expression REGEXP.
+Like `looking-at' except matches before point, and is slower.
+LIMIT if non-nil speeds up the search by specifying a minimum
+starting position, to avoid checking matches that would start
+before LIMIT.
+
+If GREEDY is non-nil, extend the match backwards as far as
+possible, stopping when a single additional previous character
+cannot be part of a match for REGEXP. When the match is
+extended, its starting position is allowed to occur before
+LIMIT.
+
+As a general recommendation, try to avoid using `looking-back'
+wherever possible, since it is slow."
+ (let ((start (point))
+ (pos
+ (save-excursion
+ (and (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)
+ (point)))))
+ (if (and greedy pos)
+ (save-restriction
+ (narrow-to-region (point-min) start)
+ (while (and (> pos (point-min))
+ (save-excursion
+ (goto-char pos)
+ (backward-char 1)
+ (looking-at (concat "\\(?:" regexp "\\)\\'"))))
+ (setq pos (1- pos)))
+ (save-excursion
+ (goto-char pos)
+ (looking-at (concat "\\(?:" regexp "\\)\\'")))))
+ (not (null pos)))))))
+
(eval-and-compile
;; Both xemacs and emacs
(condition-case nil
(defcustom verilog-highlight-grouping-keywords nil
"Non-nil means highlight grouping keywords more dramatically.
-If false, these words are in the `font-lock-type-face'; if True then they are in
-`verilog-font-lock-ams-face'. Some find that special highlighting on these
-grouping constructs allow the structure of the code to be understood at a glance."
+If false, these words are in the `font-lock-type-face'; if True
+then they are in `verilog-font-lock-grouping-keywords-face'.
+Some find that special highlighting on these grouping constructs
+allow the structure of the code to be understood at a glance."
:group 'verilog-mode-indent
:type 'boolean)
(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp)
:type 'string)
(put 'verilog-assignment-delay 'safe-local-variable 'stringp)
+(defcustom verilog-auto-arg-format 'packed
+ "Formatting to use for AUTOARG signal names.
+If 'packed', then as many inputs and outputs that fit within
+`fill-column' will be put onto one line.
+
+If 'single', then a single input or output will be put onto each
+line."
+ :version "25.1"
+ :type '(radio (const :tag "Line up Assignments and Declarations" packed)
+ (const :tag "Line up Assignment statements" single))
+ :group 'verilog-mode-auto)
+(put 'verilog-auto-arg-format 'safe-local-variable
+ '(lambda (x) (memq x '(packed single))))
+
(defcustom verilog-auto-arg-sort nil
"Non-nil means AUTOARG signal names will be sorted, not in declaration order.
Declaration order is advantageous with order based instantiations
:help "Help on AUTOINPUT - adding inputs from cells"]
["AUTOINSERTLISP" (describe-function 'verilog-auto-insert-lisp)
:help "Help on AUTOINSERTLISP - insert text from a lisp function"]
+ ["AUTOINSERTLAST" (describe-function 'verilog-auto-insert-last)
+ :help "Help on AUTOINSERTLISPLAST - insert text from a lisp function"]
["AUTOINST" (describe-function 'verilog-auto-inst)
:help "Help on AUTOINST - adding pins for cells"]
["AUTOINST (.*)" (describe-function 'verilog-auto-star)
string))
(defsubst verilog-re-search-forward (REGEXP BOUND NOERROR)
- ; checkdoc-params: (REGEXP BOUND NOERROR)
+ ;; checkdoc-params: (REGEXP BOUND NOERROR)
"Like `re-search-forward', but skips over match in comments or strings."
(let ((mdata '(nil nil))) ;; So match-end will return nil if no matches found
(while (and
(match-end 0)))
(defsubst verilog-re-search-backward (REGEXP BOUND NOERROR)
- ; checkdoc-params: (REGEXP BOUND NOERROR)
+ ;; checkdoc-params: (REGEXP BOUND NOERROR)
"Like `re-search-backward', but skips over match in comments or strings."
(let ((mdata '(nil nil))) ;; So match-end will return nil if no matches found
(while (and
pt))
(defsubst verilog-re-search-backward-quick (regexp bound noerror)
- ; checkdoc-params: (REGEXP BOUND NOERROR)
+ ;; checkdoc-params: (REGEXP BOUND NOERROR)
"Like `verilog-re-search-backward', including use of REGEXP BOUND and NOERROR,
but trashes match data and is faster for REGEXP that doesn't match often.
This uses `verilog-scan' and text properties to ignore comments,
(unless (bolp) (insert "\n"))))
(defvar compile-command)
+(defvar create-lockfiles) ;; Emacs 24
;; compilation program
(defun verilog-set-compile-command ()
(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs))
(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs))
-(defconst verilog-directive-re
+(defconst verilog-compiler-directives
(eval-when-compile
- (verilog-regexp-words
- '(
- "`case" "`default" "`define" "`else" "`elsif" "`endfor" "`endif"
- "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
- "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
- "`time_scale" "`undef" "`while" ))))
+ '( ;; compiler directives, from IEEE 1800-2012 section 22.1
+ "`__FILE__" "`__LINE" "`begin_keywords" "`celldefine" "`default_nettype"
+ "`define" "`else" "`elsif" "`end_keywords" "`endcelldefine" "`endif"
+ "`ifdef" "`ifndef" "`include" "`line" "`nounconnected_drive" "`pragma"
+ "`resetall" "`timescale" "`unconnected_drive" "`undef" "`undefineall"
+ ;; compiler directives not covered by IEEE 1800
+ "`case" "`default" "`endfor" "`endprotect" "`endswitch" "`endwhile" "`for"
+ "`format" "`if" "`let" "`protect" "`switch" "`timescale" "`time_scale"
+ "`while"
+ ))
+ "List of Verilog compiler directives.")
+
+(defconst verilog-directive-re
+ (verilog-regexp-words verilog-compiler-directives))
(defconst verilog-directive-re-1
(concat "[ \t]*" verilog-directive-re))
;; "\\(assert\\|assume\\|cover\\)\\s-+property\\>"
(defconst verilog-no-indent-begin-re
- "\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\|always_comb\\|always_ff\\|always_latch\\)\\>")
+ (eval-when-compile
+ (verilog-regexp-words
+ '("always" "always_comb" "always_ff" "always_latch" "initial" "final" ;; procedural blocks
+ "if" "else" ;; conditional statements
+ "while" "for" "foreach" "repeat" "do" "forever" )))) ;; loop statements
(defconst verilog-ends-re
;; Parenthesis indicate type of keyword found
"endinterface"
"endpackage"
"endsequence"
+ "endproperty"
"endspecify"
"endtable"
"endtask"
"\\(program\\)\\|" ; 13
"\\(sequence\\)\\|" ; 14
"\\(clocking\\)\\|" ; 15
+ "\\(property\\)\\|" ; 16
"\\)\\>\\)"))
(defconst verilog-end-block-re
(eval-when-compile
"\\(\\<begin\\>\\)\\|" ; 1
"\\(\\<else\\>\\)\\|" ; 2
"\\(\\<end\\>\\s-+\\<else\\>\\)\\|" ; 3
- "\\(\\<always_comb\\>\\(\[ \t\]*@\\)?\\)\\|" ; 4
- "\\(\\<always_ff\\>\\(\[ \t\]*@\\)?\\)\\|" ; 5
- "\\(\\<always_latch\\>\\(\[ \t\]*@\\)?\\)\\|" ; 6
+ "\\(\\<always\\(?:_ff\\)?\\>\\(?:\[ \t\]*@\\)\\)\\|" ; 4 (matches always or always_ff w/ @...)
+ "\\(\\<always\\(?:_comb\\|_latch\\)?\\>\\)\\|" ; 5 (matches always, always_comb, always_latch w/o @...)
"\\(\\<fork\\>\\)\\|" ; 7
- "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
"\\(\\<if\\>\\)\\|"
verilog-property-re "\\|"
"\\(\\(" verilog-label-re "\\)?\\<assert\\>\\)\\|"
"\\(\\<package\\>\\)\\|"
"\\(\\<final\\>\\)\\|"
"\\(@\\)\\|"
- "\\(\\<while\\>\\)\\|"
+ "\\(\\<while\\>\\)\\|\\(\\<do\\>\\)\\|"
"\\(\\<for\\(ever\\|each\\)?\\>\\)\\|"
"\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|"
"#"))
"join" "join_any" "join_none"
"end"
"endcase"
- "endconfig"
+ "endchecker"
"endclass"
"endclocking"
+ "endconfig"
"endfunction"
"endgenerate"
+ "endgroup"
"endmodule"
"endprimitive"
"endinterface"
"endpackage"
+ "endprogram"
+ "endproperty"
+ "endsequence"
"endspecify"
"endtable"
"endtask" )
(defconst verilog-declaration-re
(concat "\\(" verilog-declaration-prefix-re "\\s-*\\)?" verilog-declaration-core-re))
(defconst verilog-range-re "\\(\\[[^]]*\\]\\s-*\\)+")
-(defconst verilog-optional-signed-re "\\s-*\\(signed\\)?")
+(defconst verilog-optional-signed-re "\\s-*\\(\\(un\\)?signed\\)?")
(defconst verilog-optional-signed-range-re
(concat
- "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?"))
+ "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<\\(un\\)?signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?"))
(defconst verilog-macroexp-re "`\\sw+")
(defconst verilog-delay-re "#\\s-*\\(\\([0-9_]+\\('s?[hdxbo][0-9a-fA-F_xz]+\\)?\\)\\|\\(([^()]*)\\)\\|\\(\\sw+\\)\\)")
(defconst verilog-disable-fork-re "\\(disable\\|wait\\)\\s-+fork\\>")
(defconst verilog-extended-case-re "\\(\\(unique0?\\s-+\\|priority\\s-+\\)?case[xz]?\\)")
(defconst verilog-extended-complete-re
- (concat "\\(\\(\\<extern\\s-+\\|\\<\\(\\<pure\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)\\)"
+ (concat "\\(\\(\\<extern\\s-+\\|\\<\\(\\<\\(pure\\|context\\)\\>\\s-+\\)?virtual\\s-+\\|\\<protected\\s-+\\)*\\(\\<function\\>\\|\\<task\\>\\)\\)"
"\\|\\(\\(\\<typedef\\>\\s-+\\)*\\(\\<struct\\>\\|\\<union\\>\\|\\<class\\>\\)\\)"
- "\\|\\(\\(\\<import\\>\\s-+\\)?\\(\"DPI-C\"\\s-+\\)?\\(\\<pure\\>\\s-+\\)?\\(function\\>\\|task\\>\\)\\)"
+ "\\|\\(\\(\\<import\\>\\s-+\\)?\\(\"DPI-C\"\\s-+\\)?\\(\\<\\(pure\\|context\\)\\>\\s-+\\)?\\([A-Za-z_][A-Za-z0-9_]*\\s-+=\\s-+\\)?\\(function\\>\\|task\\>\\)\\)"
"\\|" verilog-extended-case-re ))
(defconst verilog-basic-complete-re
(eval-when-compile
"String used to mark end of excluded text.")
(defconst verilog-preprocessor-re
(eval-when-compile
- (verilog-regexp-words
- `(
- "`define" "`include" "`ifdef" "`ifndef" "`if" "`endif" "`else"
- ))))
+ (concat
+ ;; single words
+ "\\(?:"
+ (verilog-regexp-words
+ `("`__FILE__"
+ "`__LINE__"
+ "`celldefine"
+ "`else"
+ "`end_keywords"
+ "`endcelldefine"
+ "`endif"
+ "`nounconnected_drive"
+ "`resetall"
+ "`unconnected_drive"
+ "`undefineall"))
+ "\\)\\|\\(?:"
+ ;; two words: i.e. `ifdef DEFINE
+ "\\<\\(`elsif\\|`ifn?def\\|`undef\\|`default_nettype\\|`begin_keywords\\)\\>\\s-"
+ "\\)\\|\\(?:"
+ ;; `line number "filename" level
+ "\\<\\(`line\\)\\>\\s-+[0-9]+\\s-+\"[^\"]+\"\\s-+[012]"
+ "\\)\\|\\(?:"
+ ;;`include "file" or `include <file>
+ "\\<\\(`include\\)\\>\\s-+\\(?:\"[^\"]+\"\\|<[^>]+>\\)"
+ "\\)\\|\\(?:"
+ ;; `pragma <stuff> (no mention in IEEE 1800-2012 that pragma can span multiple lines
+ "\\<\\(`pragma\\)\\>\\s-+.+$"
+ "\\)\\|\\(?:"
+ ;; `timescale time_unit / time_precision
+ "\\<\\(`timescale\\)\\>\\s-+10\\{0,2\\}\\s-*[munpf]?s\\s-*\\/\\s-*10\\{0,2\\}\\s-*[munpf]?s"
+ "\\)\\|\\(?:"
+ ;; `define and `if can span multiple lines if line ends in '\'. NOTE: `if is not IEEE 1800-2012
+ ;; from http://www.emacswiki.org/emacs/MultilineRegexp
+ (concat "\\<\\(`define\\|`if\\)\\>" ;; directive
+ "\\s-+" ;; separator
+ "\\(?:.*?\\(?:\n.*\\)*?\\)" ;; definition: to end of line, then maybe more lines (excludes any trailing \n)
+ "\\(?:\n\\s-*\n\\|\\'\\)") ;; blank line or EOF
+ "\\)\\|\\(?:"
+ ;; `<macro>() : i.e. `uvm_info(a,b,c) or any other pre-defined macro
+ ;; Since parameters inside the macro can have parentheses, and
+ ;; the macro can span multiple lines, just look for the opening
+ ;; parentheses and then continue to the end of the first
+ ;; non-escaped EOL
+ (concat "\\<`\\w+\\>\\s-*("
+ "\\(?:.*?\\(?:\n.*\\)*?\\)" ;; definition: to end of line, then maybe more lines (excludes any trailing \n)
+ "\\(?:\n\\s-*\n\\|\\'\\)") ;; blank line or EOF
+ "\\)"
+ )))
(defconst verilog-keywords
- '( "`case" "`default" "`define" "`else" "`endfor" "`endif"
- "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef"
- "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
- "`time_scale" "`undef" "`while"
-
+ (append verilog-compiler-directives
+ '(
"after" "alias" "always" "always_comb" "always_ff" "always_latch" "and"
"assert" "assign" "assume" "automatic" "before" "begin" "bind"
"bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte"
"sync_reject_on" "unique0" "until" "until_with" "untyped" "weak"
;; 1800-2012
"implements" "interconnect" "nettype" "soft"
- )
- "List of Verilog keywords.")
+ ))
+ "List of Verilog keywords.")
(defconst verilog-comment-start-regexp "//\\|/\\*"
"Dual comment value for `comment-start-regexp'.")
(defface verilog-font-lock-grouping-keywords-face
'((((class color)
(background light))
- (:foreground "red4" :bold t ))
+ (:foreground "Purple" :bold t ))
(((class color)
(background dark))
- (:foreground "red4" :bold t ))
+ (:foreground "orange1" :bold t ))
(t (:italic t)))
"Font lock mode face used to highlight verilog grouping keywords."
:group 'font-lock-highlighting-faces)
'(
"and" "bit" "buf" "bufif0" "bufif1" "cmos" "defparam"
"event" "genvar" "inout" "input" "integer" "localparam"
- "logic" "mailbox" "nand" "nmos" "not" "notif0" "notif1" "or"
+ "logic" "mailbox" "nand" "nmos" "nor" "not" "notif0" "notif1" "or"
"output" "parameter" "pmos" "pull0" "pull1" "pulldown" "pullup"
"rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran"
"rtranif0" "rtranif1" "semaphore" "signed" "struct" "supply"
;; Fontify all types
(if verilog-highlight-grouping-keywords
(cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
- 'verilog-font-lock-ams-face)
+ 'verilog-font-lock-grouping-keywords-face)
(cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
'font-lock-type-face))
(cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>")
(setq verilog-scan-cache-tick nil))
(defun verilog-scan-cache-ok-p ()
- "Return t iff the scan cache is up to date."
+ "Return t if the scan cache is up to date."
(or (and verilog-scan-cache-preserving
(eq verilog-scan-cache-preserving (current-buffer))
verilog-scan-cache-tick)
(verilog-re-search-backward reg nil 'move))
(cond
((match-end 1) ; matched verilog-end-block-re
- ; try to leap back to matching outward block by striding across
- ; indent level changing tokens then immediately
- ; previous line governs indentation.
+ ;; try to leap back to matching outward block by striding across
+ ;; indent level changing tokens then immediately
+ ;; previous line governs indentation.
(verilog-leap-to-head))
((match-end 2) ; else, we're in deep
(setq elsec (1+ elsec)))
(mark-defun)))
(defun verilog-comment-region (start end)
- ; checkdoc-params: (start end)
+ ;; checkdoc-params: (start end)
"Put the region into a Verilog comment.
The comments that are in this area are \"deformed\":
`*)' becomes `!(*' and `}' becomes `!{'.
(while (and
(> (marker-position e) (point))
(verilog-re-search-forward
- (concat
- "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\|\\(interface\\)\\|\\(package\\)\\|\\(case\\)\\)?\\>"
- "\\|\\(`endif\\)\\|\\(`else\\)")
+ verilog-auto-end-comment-lines-re
nil 'move))
(goto-char (match-beginning 0))
(let ((indent-str (verilog-indent-line)))
;; or the token before us unambiguously ends a statement,
;; then move back a token and test again.
(not (or
- ;; stop if beginning of buffer
- (bolp)
- ;; stop if we find a ;
+ ;; stop if beginning of buffer
+ (bobp)
+ ;; stop if looking at a pre-processor directive
+ (looking-at "`\\w+")
+ ;; stop if we find a ;
(= (preceding-char) ?\;)
- ;; stop if we see a named coverpoint
+ ;; stop if we see a named coverpoint
(looking-at "\\w+\\W*:\\W*\\(coverpoint\\|cross\\|constraint\\)")
- ;; keep going if we are in the middle of a word
+ ;; keep going if we are in the middle of a word
(not (or (looking-at "\\<") (forward-word -1)))
- ;; stop if we see an assertion (perhaps labeled)
+ ;; stop if we see an assertion (perhaps labeled)
(and
- (looking-at "\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)")
+ (looking-at "\\(\\w+\\W*:\\W*\\)?\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)")
(progn
- (setq h (point))
- (save-excursion
- (verilog-backward-token)
- (if (looking-at verilog-label-re)
- (setq h (point))))
- (goto-char h)))
- ;; stop if we see an extended complete reg, perhaps a complete one
+ (setq h (point))
+ (save-excursion
+ (verilog-backward-token)
+ (if (and (looking-at verilog-label-re)
+ (not (looking-at verilog-end-block-re)))
+ (setq h (point))))
+ (goto-char h)))
+ ;; stop if we see an extended complete reg, perhaps a complete one
(and
- (looking-at verilog-complete-reg)
- (let* ((p (point)))
- (while (and (looking-at verilog-extended-complete-re)
- (progn (setq p (point))
- (verilog-backward-token)
- (/= p (point)))))
- (goto-char p)))
- ;; stop if we see a complete reg (previous found extended ones)
+ (looking-at verilog-complete-reg)
+ (let* ((p (point)))
+ (while (and (looking-at verilog-extended-complete-re)
+ (progn (setq p (point))
+ (verilog-backward-token)
+ (/= p (point)))))
+ (goto-char p)))
+ ;; stop if we see a complete reg (previous found extended ones)
(looking-at verilog-basic-complete-re)
- ;; stop if previous token is an ender
+ ;; stop if previous token is an ender
(save-excursion
- (verilog-backward-token)
- (or
- (looking-at verilog-end-block-re)
- (looking-at verilog-preprocessor-re))))) ;; end of test
- (verilog-backward-syntactic-ws)
- (verilog-backward-token))
+ (verilog-backward-token)
+ (looking-at verilog-end-block-re))))
+ (verilog-backward-syntactic-ws)
+ (verilog-backward-token))
;; Now point is where the previous line ended.
- (verilog-forward-syntactic-ws)))
+ (verilog-forward-syntactic-ws)
+ ;; Skip forward over any preprocessor directives, as they have wacky indentation
+ (if (looking-at verilog-preprocessor-re)
+ (progn (goto-char (match-end 0))
+ (verilog-forward-syntactic-ws)))))
(defun verilog-beg-of-statement-1 ()
"Move backward to beginning of statement."
(verilog-backward-syntactic-ws)
(if (or (bolp)
(= (preceding-char) ?\;)
- (save-excursion
+ (progn
(verilog-backward-token)
(looking-at verilog-ends-re)))
(progn
(goto-char pt)
- (throw 'done t))
- (verilog-backward-token))))
+ (throw 'done t)))))
(verilog-forward-syntactic-ws)))
;
; (while (and
((equal (char-after) ?\})
(forward-char))
- ;; Skip to end of statement
+ ;; Skip to end of statement
((condition-case nil
(setq pos
(catch 'found
(setq nest (1+ nest)))
((match-end 2)
(if (= nest 1)
- (throw 'found 1))
+ (throw 'found 1))
(setq nest (1- nest)))
(t
(throw 'found (= nest 0)))))))
"\\(`ifdef\\>\\)\\|"
"\\(`ifndef\\>\\)\\|"
"\\(`elsif\\>\\)"))
+
(defun verilog-set-auto-endcomments (indent-str kill-existing-comment)
"Add ending comment with given INDENT-STR.
With KILL-EXISTING-COMMENT, remove what was there before.
(setq str (concat " // else: !assert " str ))
(throw 'skip 1)))))))))
- (; always_comb, always_ff, always_latch
- (or (match-end 4) (match-end 5) (match-end 6))
+ (; always, always_comb, always_latch w/o @...
+ (match-end 5)
(goto-char (match-end 0))
(setq there (point))
(setq err nil)
(throw 'skip 1))))
))))
(end-of-line)
+ (if kill-existing-comment
+ (verilog-kill-existing-comment))
+ (delete-horizontal-space)
(insert (concat " // " string ))))
(;- this is end{function,generate,task,module,primitive,table,generate}
(cond
((match-end 5) ;; of verilog-end-block-ordered-re
(setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
- (setq name-re "\\w+\\s-*("))
+ (setq name-re "\\w+\\(?:\n\\|\\s-\\)*[(;]"))
((match-end 6) ;; of verilog-end-block-ordered-re
(setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
- (setq name-re "\\w+\\s-*("))
+ (setq name-re "\\w+\\(?:\n\\|\\s-\\)*[(;]"))
((match-end 7) ;; of verilog-end-block-ordered-re
(setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>"))
((match-end 8) ;; of verilog-end-block-ordered-re
(setq reg "\\(\\<\\(rand\\)?sequence\\>\\)\\|\\(\\<\\(endsequence\\|primitive\\|interface\\|\\(macro\\)?module\\)\\>\\)"))
((match-end 15) ;; of verilog-end-block-ordered-re
(setq reg "\\(\\<clocking\\>\\)\\|\\<endclocking\\>"))
+ ((match-end 16) ;; of verilog-end-block-ordered-re
+ (setq reg "\\(\\<property\\>\\)\\|\\<endproperty\\>"))
(t (error "Problem in verilog-set-auto-endcomments")))
(let (b e)
(list
(let ((default (verilog-expand-command verilog-preprocessor)))
(set (make-local-variable `verilog-preprocessor)
- (read-from-minibuffer "Run Preprocessor (like this): "
- default nil nil
- 'verilog-preprocess-history default)))))
+ (read-from-minibuffer "Run Preprocessor (like this): "
+ default nil nil
+ 'verilog-preprocess-history default)))))
(unless command (setq command (verilog-expand-command verilog-preprocessor)))
(let* ((fontlocked (and (boundp 'font-lock-mode) font-lock-mode))
- (dir (file-name-directory (or filename buffer-file-name)))
- (cmd (concat "cd " dir "; " command)))
+ (dir (file-name-directory (or filename buffer-file-name)))
+ (cmd (concat "cd " dir "; " command)))
(with-output-to-temp-buffer "*Verilog-Preprocessed*"
(with-current-buffer (get-buffer "*Verilog-Preprocessed*")
(insert (concat "// " cmd "\n"))
(verilog-mode)
;; Without this force, it takes a few idle seconds
;; to get the color, which is very jarring
- (when fontlocked (font-lock-fontify-buffer))))))
+ (unless (fboundp 'font-lock-ensure)
+ ;; We should use font-lock-ensure in preference to
+ ;; font-lock-fontify-buffer, but IIUC the problem this is supposed to
+ ;; solve only appears in Emacsen older than font-lock-ensure anyway.
+ ;; So avoid bytecomp's interactive-only by going through intern.
+ (when fontlocked (funcall (intern "font-lock-fontify-buffer"))))))))
\f
;;
;; Make sure any sub-files we read get proper mode
(setq-default major-mode 'verilog-mode)
;; Ditto files already read in
- (mapc (lambda (buf)
- (when (buffer-file-name buf)
- (with-current-buffer buf
- (verilog-mode))))
- (buffer-list))
- ;; Process the files
- (mapcar (lambda (buf)
+ ;; Remember buffer list, so don't later pickup any verilog-getopt files
+ (let ((orig-buffer-list (buffer-list)))
+ (mapc (lambda (buf)
(when (buffer-file-name buf)
- (save-excursion
- (if (not (file-exists-p (buffer-file-name buf)))
- (error
- (concat "File not found: " (buffer-file-name buf))))
- (message (concat "Processing " (buffer-file-name buf)))
- (set-buffer buf)
- (funcall funref)
- (unless no-save (save-buffer)))))
- (buffer-list))))
+ (with-current-buffer buf
+ (verilog-mode)
+ (verilog-auto-reeval-locals)
+ (verilog-getopt-flags))))
+ orig-buffer-list)
+ ;; Process the files
+ (mapcar (lambda (buf)
+ (when (buffer-file-name buf)
+ (save-excursion
+ (if (not (file-exists-p (buffer-file-name buf)))
+ (error
+ (concat "File not found: " (buffer-file-name buf))))
+ (message (concat "Processing " (buffer-file-name buf)))
+ (set-buffer buf)
+ (funcall funref)
+ (when (and (not no-save)
+ (buffer-modified-p)) ;; Avoid "no changes to be saved"
+ (save-buffer)))))
+ orig-buffer-list))))
(defun verilog-batch-auto ()
"For use with --batch, perform automatic expansions as a stand-alone tool.
(if (save-excursion (beginning-of-line)
(and (looking-at verilog-directive-re-1)
(not (or (looking-at "[ \t]*`[ou]vm_")
- (looking-at "[ \t]*`vmm_")))))
+ (looking-at "[ \t]*`vmm_")))))
(throw 'nesting 'directive))
;; indent structs as if there were module level
(setq structres (verilog-in-struct-nested-p))
((equal (char-after) ?\{)
;; block type returned based on outer constraint { or inner
(if (verilog-at-constraint-p)
- (cond (inconstraint (throw 'nesting 'constraint))
- (t (throw 'nesting 'statement)))))
+ (cond (inconstraint
+ (beginning-of-line nil)
+ (skip-chars-forward " \t")
+ (throw 'nesting 'constraint))
+ (t
+ (throw 'nesting 'statement)))))
((equal (char-after) ?\})
(let (par-pos
(there (verilog-at-close-constraint-p)))
; endfunction
(verilog-beg-of-statement)
(if (looking-at verilog-beg-block-re-ordered)
- (throw 'nesting 'block)
- (throw 'nesting 'defun)))
+ (throw 'nesting 'block)
+ (throw 'nesting 'defun)))
- ;;
+ ;;
((looking-at "\\<property\\>")
; *sigh*
; {assert|assume|cover} property (); are complete
(setq sreg reg)
(setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|_none\\)?\\>\\)" ))
)))
- ;no nesting
+ ;; no nesting
(if (and
(verilog-re-search-backward reg nil 'move)
(match-end 1)) ; task -> could be virtual and/or protected
(;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete
t
(forward-word -1)
- (while (= (preceding-char) ?\_)
+ (while (or (= (preceding-char) ?\_)
+ (= (preceding-char) ?\@)
+ (= (preceding-char) ?\.))
(forward-word -1))
(cond
((looking-at "\\<else\\>")
(save-match-data
(save-excursion
(verilog-re-search-backward "\\((\\*\\)\\|\\(\\*)\\)" nil 'move)
- (numberp (match-beginning 1)))))
+ (cond
+ ((match-end 1)
+ (progn (goto-char (match-end 1))
+ (not (looking-at "\\s-*)")))
+ nil)
+ ((match-end 2)
+ (progn (goto-char (match-beginning 2))
+ (not (looking-at "(\\s-*")))
+ nil)
+ (t nil)))))
(defun verilog-in-parameter-p ()
"Return true if point is in a parameter assignment #( p1=1, p2=5)."
(defun verilog-at-constraint-p ()
"If at the { of a constraint or coverpoint definition, return true, moving point to constraint."
(if (save-excursion
+ (let ((p (point)))
(and
(equal (char-after) ?\{)
(forward-list)
(progn (backward-char 1)
(verilog-backward-ws&directives)
+ (and
(or (equal (char-before) ?\{) ;; empty case
(equal (char-before) ?\;)
- (equal (char-before) ?\})))))
+ (equal (char-before) ?\}))
+ ;; skip what looks like bus repetition operator {#{
+ (not (string-match "^{\\s-*[0-9]+\\s-*{" (buffer-substring p (point)))))))))
(progn
(let ( (pt (point)) (pass 0))
(verilog-backward-ws&directives)
))
;; if first word token not keyword, it maybe the instance name
;; check next word token
- (if (looking-at "\\<\\w+\\>\\|\\s-*(\\s-*\\w+")
+ (if (looking-at "\\<\\w+\\>\\|\\s-*(\\s-*\\S-+")
(progn (verilog-beg-of-statement)
(if (looking-at (concat "\\<\\(constraint\\|"
"\\(?:\\w+\\s-*:\\s-*\\)?\\(coverpoint\\|cross\\)"
(goto-char (- (point) 2))
t) ;; Let nth 4 state handle the rest
((and (not (bobp))
- (= (char-before) ?\))
- (= (char-before (1- (point))) ?\*))
+ (verilog-looking-back "\\*)" nil)
+ (not (verilog-looking-back "(\\s-*\\*)" nil)))
(goto-char (- (point) 2))
(if (search-backward "(*" nil t)
(progn
(progn
(goto-char h)
nil))))
- ((looking-at "(\\*")
+ ((and (looking-at "(\\*") ;; attribute start, but not an event (*) or (* )
+ (not (looking-at "(\\*\\s-*)")))
(progn
(setq h (point))
(goto-char (match-end 0))
(cond
((or
(= (preceding-char) ?\,)
- (= (preceding-char) ?\])
(save-excursion
(verilog-beg-of-statement-1)
(looking-at verilog-declaration-re)))
(looking-at verilog-declaration-re))
(verilog-indent-declaration ind))
+ (;-- form feeds - ignored as bug in indent-line-to in < 24.5
+ (looking-at "\f"))
+
(;-- Everything else
t
(let ((val (eval (cdr (assoc type verilog-indent-alist)))))
endpos (set-marker (make-marker) end)
base-ind (progn
(goto-char start)
- (forward-char 1)
- (skip-chars-forward " \t")
- (current-column))
- )
+ (forward-char 1)
+ (skip-chars-forward " \t")
+ (current-column)))
;; in a declaration block (not in argument list)
(setq
start (progn
(nreverse out-list)))))
;;(verilog-signals-not-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" "")))
+(defun verilog-signals-not-in-struct (in-list not-list)
+ "Return list of signals in IN-LIST that aren't also in NOT-LIST.
+Also remove any duplicates in IN-LIST.
+Any structure in not-list will remove all members in in-list.
+Signals must be in standard (base vector) form."
+ (cond ((eval-when-compile (fboundp 'make-hash-table))
+ (let ((ht (make-hash-table :test 'equal :rehash-size 4.0))
+ out-list addit nm)
+ (while not-list
+ (puthash (car (car not-list)) t ht)
+ (setq not-list (cdr not-list)))
+ (while in-list
+ (setq nm (verilog-sig-name (car in-list)))
+ (when (not (gethash nm ht))
+ (setq addit t)
+ (while (string-match "^\\([^\\].*\\)\\.[^.]+$" nm)
+ (setq nm (match-string 1 nm))
+ (setq addit (and addit
+ (not (gethash nm ht)))))
+ (when addit
+ (setq out-list (cons (car in-list) out-list))
+ (puthash (verilog-sig-name (car in-list)) t ht)))
+ (setq in-list (cdr in-list)))
+ (nreverse out-list)))
+ ;; Slower Fallback if no hash tables (pre Emacs 21.1/XEmacs 21.4)
+ (t
+ (let (out-list addit nm)
+ (while in-list
+ (setq nm (verilog-sig-name (car in-list)))
+ (when (and (not (assoc nm not-list))
+ (not (assoc nm out-list)))
+ (setq addit t)
+ (while (string-match "^\\([^\\].*\\)\\.[^.]+$" nm)
+ (setq nm (match-string 1 nm))
+ (setq addit (and addit
+ (not (assoc nm not-list)))))
+ (when addit
+ (setq out-list (cons (car in-list) out-list))))
+ (setq in-list (cdr in-list)))
+ (nreverse out-list)))))
+;;(verilog-signals-not-in-struct '(("A" "") ("B" "") ("DEL.SUB.A" "[2:3]")) '(("DEL.SUB" "") ("EXT" "")))
+
(defun verilog-signals-memory (in-list)
"Return list of signals in IN-LIST that are memorized (multidimensional)."
(let (out-list)
Return an array of [outputs inouts inputs wire reg assign const]."
(let ((end-mod-point (or (verilog-get-end-of-defun) (point-max)))
(functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t)
- in-modport in-clocking ptype ign-prop
+ in-modport in-clocking in-ign-to-semi ptype ign-prop
sigs-in sigs-out sigs-inout sigs-var sigs-assign sigs-const
sigs-gparam sigs-intf sigs-modports
vec expect-signal keywd newsig rvalue enum io signed typedefed multidim
(or (re-search-forward "[^\\]\"" nil t) ;; don't forward-char first, since we look for a non backslash first
(error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
((eq ?\; (following-char))
- (when (and in-modport (not (eq in-modport t))) ;; end of a modport declaration
- (verilog-modport-decls-set
- in-modport
- (verilog-decls-new sigs-out sigs-inout sigs-in
- nil nil nil nil nil nil))
- ;; Pop from varstack to restore state to pre-clocking
- (setq tmp (car varstack)
- varstack (cdr varstack)
- sigs-out (aref tmp 0)
- sigs-inout (aref tmp 1)
- sigs-in (aref tmp 2)))
- (setq vec nil io nil expect-signal nil newsig nil paren 0 rvalue nil
- v2kargs-ok nil in-modport nil ign-prop nil)
+ (cond (in-ign-to-semi ;; Such as inside a "import ...;" in a module header
+ (setq in-ign-to-semi nil))
+ ((and in-modport (not (eq in-modport t))) ;; end of a modport declaration
+ (verilog-modport-decls-set
+ in-modport
+ (verilog-decls-new sigs-out sigs-inout sigs-in
+ nil nil nil nil nil nil))
+ ;; Pop from varstack to restore state to pre-clocking
+ (setq tmp (car varstack)
+ varstack (cdr varstack)
+ sigs-out (aref tmp 0)
+ sigs-inout (aref tmp 1)
+ sigs-in (aref tmp 2))
+ (setq vec nil io nil expect-signal nil newsig nil paren 0 rvalue nil
+ v2kargs-ok nil in-modport nil ign-prop nil))
+ (t
+ (setq vec nil io nil expect-signal nil newsig nil paren 0 rvalue nil
+ v2kargs-ok nil in-modport nil ign-prop nil)))
(forward-char 1))
((eq ?= (following-char))
(setq rvalue t newsig nil)
typedefed nil multidim nil ptype nil modport nil
expect-signal 'sigs-assign sig-paren paren))
((member keywd '("localparam" "genvar"))
- (unless io
- (setq vec nil enum nil rvalue nil signed nil
- typedefed nil multidim nil ptype nil modport nil
- expect-signal 'sigs-const sig-paren paren)))
+ (setq vec nil enum nil rvalue nil signed nil
+ typedefed nil multidim nil ptype nil modport nil
+ expect-signal 'sigs-const sig-paren paren))
((member keywd '("signed" "unsigned"))
(setq signed keywd))
((member keywd '("assert" "assume" "cover" "expect" "restrict"))
(setq in-modport t))
((equal keywd "clocking")
(setq in-clocking t))
+ ((equal keywd "import")
+ (if v2kargs-ok ;; import in module header, not a modport import
+ (setq in-ign-to-semi t rvalue t)))
((equal keywd "type")
(setq ptype t))
+ ((equal keywd "var"))
;; Ifdef? Ignore name of define
((member keywd '("`ifdef" "`ifndef" "`elsif"))
(setq rvalue t))
(setq typedefed
(if typedefed (concat typedefed " " keywd) keywd)))
(t (setq vec nil enum nil rvalue nil signed nil
- typedefed nil multidim nil sig-paren paren
+ typedefed keywd ; Have a type
+ multidim nil sig-paren paren
expect-signal 'sigs-var modport nil))))
;; Interface with optional modport in v2k arglist?
;; Skip over parsing modport, and take the interface name as the type
(eq functask 0)
(not (member keywd verilog-keywords)))
;; Add new signal to expect-signal's variable
+ ;;(if dbg (setq dbg (concat dbg (format "Pt %s New sig %s'\n" (point) keywd))))
(setq newsig (verilog-sig-new keywd vec nil nil enum signed typedefed multidim modport))
(set expect-signal (cons newsig
(symbol-value expect-signal))))))
(defvar sigs-temp)
;; These are known to be from other packages and may not be defined
(defvar diff-command nil)
- (defvar vector-skip-list)
;; There are known to be from newer versions of Emacs
(defvar create-lockfiles))
(save-excursion
(let* (;;(dbg "")
sigs-out-d sigs-out-i sigs-out-unk sigs-temp sigs-in)
- (search-forward ")")
(verilog-read-always-signals-recurse nil nil nil)
(setq sigs-out-i (append sigs-out-i sigs-out-unk)
sigs-out-unk nil)
`define _FOO_V
... contents of file
`endif // _FOO_V"
-;;slow: (verilog-read-defines nil t))
+ ;;slow: (verilog-read-defines nil t)
(save-excursion
(verilog-getopt-flags)
(goto-char (point-min))
(setq outlist (cons (expand-file-name
fn (file-name-directory current))
outlist)))
- (setq chkexts (cdr chkexts)))
+ (setq chkexts (cdr chkexts)))
(setq chkdirs (cdr chkdirs)))
(setq outlist (nreverse outlist))
(setq verilog-dir-cache-lib-filenames
allow-cache
(setq modi (gethash module verilog-modi-lookup-cache))
(equal verilog-modi-lookup-last-current current)
- ;; Iff hit is in current buffer, then tick must match
+ ;; If hit is in current buffer, then tick must match
(or (equal verilog-modi-lookup-last-tick (buffer-chars-modified-tick))
(not (equal current (verilog-modi-file-or-buffer modi)))))
;;(message "verilog-modi-lookup: HIT %S" modi)
(defun verilog-diff-auto ()
"Expand AUTOs in a temporary buffer and indicate any change.
-Whitespace differences are ignored to determine identicalness, but
-once a difference is detected, whitespace differences may be shown.
+Whitespace is ignored when detecting differences, but once a
+difference is detected, whitespace differences may be shown.
To call this from the command line, see \\[verilog-batch-diff-auto].
;;
(defun verilog-auto-arg-ports (sigs message indent-pt)
- "Print a list of ports for an AUTOINST.
+ "Print a list of ports for AUTOARG.
Takes SIGS list, adds MESSAGE to front and inserts each at INDENT-PT."
(when sigs
(when verilog-auto-arg-sort
(let ((space ""))
(indent-to indent-pt)
(while sigs
- (cond ((> (+ 2 (current-column) (length (verilog-sig-name (car sigs)))) fill-column)
+ (cond ((equal verilog-auto-arg-format 'single)
+ (insert space)
+ (indent-to indent-pt)
+ (setq space "\n"))
+ ;; verilog-auto-arg-format 'packed
+ ((> (+ 2 (current-column) (length (verilog-sig-name (car sigs)))) fill-column)
(insert "\n")
- (indent-to indent-pt))
- (t (insert space)))
+ (indent-to indent-pt)
+ (setq space " "))
+ (t
+ (insert space)
+ (setq space " ")))
(insert (verilog-sig-name (car sigs)) ",")
- (setq sigs (cdr sigs)
- space " ")))))
+ (setq sigs (cdr sigs))))))
(defun verilog-auto-arg ()
"Expand AUTOARG statements.
output o;
endmodule
-The argument declarations may be printed in declaration order to best suit
-order based instantiations, or alphabetically, based on the
-`verilog-auto-arg-sort' variable.
+The argument declarations may be printed in declaration order to
+best suit order based instantiations, or alphabetically, based on
+the `verilog-auto-arg-sort' variable.
+
+Formatting is controlled with `verilog-auto-arg-format' variable.
Any ports declared between the ( and /*AUTOARG*/ are presumed to be
predeclared and are not redeclared by AUTOARG. AUTOARG will make a
(defvar vl-bits nil "See `verilog-auto-inst'.") ; Prevent compile warning
(defvar vl-mbits nil "See `verilog-auto-inst'.") ; Prevent compile warning
-(defun verilog-auto-inst-port (port-st indent-pt tpl-list tpl-num for-star par-values)
+(defun verilog-auto-inst-port (port-st indent-pt moddecls tpl-list tpl-num for-star par-values)
"Print out an instantiation connection for this PORT-ST.
Insert to INDENT-PT, use template TPL-LIST.
@ are instantiation numbers, replaced with TPL-NUM.
(vl-mbits (if (verilog-sig-multidim port-st)
(verilog-sig-multidim-string port-st) ""))
(vl-bits (if (or verilog-auto-inst-vector
- (not (assoc port vector-skip-list))
+ (not (assoc port (verilog-decls-get-signals moddecls)))
(not (equal (verilog-sig-bits port-st)
- (verilog-sig-bits (assoc port vector-skip-list)))))
+ (verilog-sig-bits
+ (assoc port (verilog-decls-get-signals moddecls))))))
(or (verilog-sig-bits port-st) "")
""))
(case-fold-search nil)
(concat "/*" vl-mbits vl-bits "*/")
(concat vl-bits))
tpl-net (concat port
- (if vl-modport (concat "." vl-modport) "")
+ (if (and vl-modport
+ ;; .modport cannot be added if attachment is
+ ;; already declared as modport, VCS croaks
+ (let ((sig (assoc port (verilog-decls-get-interfaces moddecls))))
+ (not (and sig (verilog-sig-modport sig)))))
+ (concat "." vl-modport) "")
dflt-bits))
;; Find template
(cond (tpl-ass ; Template of exact port name
;;(x "incom[@\"(+ (* 8 @) 7)\":@\"(* 8 @)\"]")
;;(x ".out (outgo[@\"(concat (+ (* 8 @) 7) \\\":\\\" ( * 8 @))\"]));")
-(defun verilog-auto-inst-port-list (sig-list indent-pt tpl-list tpl-num for-star par-values)
+(defun verilog-auto-inst-port-list (sig-list indent-pt moddecls tpl-list tpl-num for-star par-values)
"For `verilog-auto-inst' print a list of ports using `verilog-auto-inst-port'."
(when verilog-auto-inst-sort
(setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare)))
(mapc (lambda (port)
- (verilog-auto-inst-port port indent-pt
+ (verilog-auto-inst-port port indent-pt moddecls
tpl-list tpl-num for-star par-values))
sig-list))
(+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
(modi (verilog-modi-current))
(moddecls (verilog-modi-get-decls modi))
- (vector-skip-list (unless verilog-auto-inst-vector
- (verilog-decls-get-signals moddecls)))
submod submodi submoddecls
inst skip-pins tpl-list tpl-num did-first par-values)
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
;; Note these are searched for in verilog-read-sub-decls.
(verilog-insert-indent "// Interfaced\n")
- (verilog-auto-inst-port-list sig-list indent-pt
+ (verilog-auto-inst-port-list sig-list indent-pt moddecls
tpl-list tpl-num for-star par-values)))
(let ((sig-list (verilog-signals-not-in
(verilog-decls-get-interfaces submoddecls)
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
;; Note these are searched for in verilog-read-sub-decls.
(verilog-insert-indent "// Interfaces\n")
- (verilog-auto-inst-port-list sig-list indent-pt
+ (verilog-auto-inst-port-list sig-list indent-pt moddecls
tpl-list tpl-num for-star par-values)))
(let ((sig-list (verilog-signals-not-in
(verilog-decls-get-outputs submoddecls)
(when sig-list
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
(verilog-insert-indent "// Outputs\n")
- (verilog-auto-inst-port-list sig-list indent-pt
+ (verilog-auto-inst-port-list sig-list indent-pt moddecls
tpl-list tpl-num for-star par-values)))
(let ((sig-list (verilog-signals-not-in
(verilog-decls-get-inouts submoddecls)
(when sig-list
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
(verilog-insert-indent "// Inouts\n")
- (verilog-auto-inst-port-list sig-list indent-pt
+ (verilog-auto-inst-port-list sig-list indent-pt moddecls
tpl-list tpl-num for-star par-values)))
(let ((sig-list (verilog-signals-not-in
(verilog-decls-get-inputs submoddecls)
(when sig-list
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
(verilog-insert-indent "// Inputs\n")
- (verilog-auto-inst-port-list sig-list indent-pt
+ (verilog-auto-inst-port-list sig-list indent-pt moddecls
tpl-list tpl-num for-star par-values)))
;; Kill extra semi
(save-excursion
(+ 16 (* 8 (/ (+ indent-pt 7) 8)))))
(modi (verilog-modi-current))
(moddecls (verilog-modi-get-decls modi))
- (vector-skip-list (unless verilog-auto-inst-vector
- (verilog-decls-get-signals moddecls)))
submod submodi submoddecls
inst skip-pins tpl-list tpl-num did-first)
;; Find module name that is instantiated
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
;; Note these are searched for in verilog-read-sub-decls.
(verilog-insert-indent "// Parameters\n")
- (verilog-auto-inst-port-list sig-list indent-pt
+ (verilog-auto-inst-port-list sig-list indent-pt moddecls
tpl-list tpl-num nil nil)))
;; Kill extra semi
(save-excursion
Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+ Types are added to declarations if an AUTOLOGIC or
+ `verilog-auto-wire-type' is set to logic.
+
Signals matching `verilog-auto-output-ignore-regexp' are not included.
An example (see `verilog-auto-inst' for what else is going on here):
wire tempa = i;
wire tempb = tempa;
wire o = tempb;
- endmodule"
+ endmodule
+
+You may also provide an optional regular expression, in which case only
+signals matching the regular expression will be included. For example the
+same expansion will result from only extracting outputs starting with ov:
+
+ /*AUTOOUTPUTEVERY(\"^ov\")*/"
(save-excursion
;;Point must be at insertion point
(let* ((indent-pt (current-indentation))
+ (params (verilog-read-auto-params 0 1))
+ (regexp (nth 0 params))
(v2k (verilog-in-paren-quick))
(modi (verilog-modi-current))
(moddecls (verilog-modi-get-decls modi))
(verilog-signals-not-in
(verilog-decls-get-signals moddecls)
(verilog-decls-get-ports moddecls)))))
+ (when regexp
+ (setq sig-list (verilog-signals-matching-regexp
+ sig-list regexp)))
+ (setq sig-list (verilog-signals-not-matching-regexp
+ sig-list verilog-auto-output-ignore-regexp))
(verilog-forward-or-insert-line)
(when v2k (verilog-repair-open-comma))
(when sig-list
Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+ Types are added to declarations if an AUTOLOGIC or
+ `verilog-auto-wire-type' is set to logic.
+
Signals matching `verilog-auto-input-ignore-regexp' are not included.
An example (see `verilog-auto-inst' for what else is going on here):
Typedefs must match `verilog-typedef-regexp', which is disabled by default.
+ Types are added to declarations if an AUTOLOGIC or
+ `verilog-auto-wire-type' is set to logic.
+
Signals matching `verilog-auto-inout-ignore-regexp' are not included.
An example (see `verilog-auto-inst' for what else is going on here):
/*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/
-You may also provide an optional second regular expression, in
-which case only signals which have that pin direction and data
-type will be included. This matches against everything before
-the signal name in the declaration, for example against
-\"input\" (single bit), \"output logic\" (direction and type) or
+You may also provide an optional third argument regular
+expression, in which case only signals which have that pin
+direction and data type matching that regular expression will be
+included. This matches against everything before the signal name
+in the declaration, for example against \"input\" (single
+bit), \"output logic\" (direction and type) or
\"output [1:0]\" (direction and implicit type). You also
probably want to skip spaces in your regexp.
For example, the below will result in matching the output \"o\"
against the previous example's module:
- /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/"
+ /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/
+
+You may also provide an optional fourth argument regular
+expression, which if not \"\" only signals which do NOT match
+that expression are included."
+ ;; Beware spacing of quotes in above as can mess up Emacs indenter
(save-excursion
- (let* ((params (verilog-read-auto-params 1 3))
+ (let* ((params (verilog-read-auto-params 1 4))
(submod (nth 0 params))
(regexp (nth 1 params))
(direction-re (nth 2 params))
+ (not-re (nth 3 params))
submodi)
;; Lookup position, etc of co-module
;; Note this may raise an error
(append (verilog-decls-get-interfaces moddecls)))))
(forward-line 1)
(setq sig-list-i (verilog-signals-edit-wire-reg
- (verilog-signals-matching-dir-re
- (verilog-signals-matching-regexp sig-list-i regexp)
- "input" direction-re))
+ (verilog-signals-not-matching-regexp
+ (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-i regexp)
+ "input" direction-re) not-re))
sig-list-o (verilog-signals-edit-wire-reg
- (verilog-signals-matching-dir-re
- (verilog-signals-matching-regexp sig-list-o regexp)
- "output" direction-re))
+ (verilog-signals-not-matching-regexp
+ (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-o regexp)
+ "output" direction-re) not-re))
sig-list-io (verilog-signals-edit-wire-reg
+ (verilog-signals-not-matching-regexp
+ (verilog-signals-matching-dir-re
+ (verilog-signals-matching-regexp sig-list-io regexp)
+ "inout" direction-re) not-re))
+ sig-list-if (verilog-signals-not-matching-regexp
(verilog-signals-matching-dir-re
- (verilog-signals-matching-regexp sig-list-io regexp)
- "inout" direction-re))
- sig-list-if (verilog-signals-matching-dir-re
- (verilog-signals-matching-regexp sig-list-if regexp)
- "interface" direction-re))
+ (verilog-signals-matching-regexp sig-list-if regexp)
+ "interface" direction-re) not-re))
(when v2k (verilog-repair-open-comma))
- (when (or sig-list-i sig-list-o sig-list-io)
+ (when (or sig-list-i sig-list-o sig-list-io sig-list-if)
(verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n")
;; Don't sort them so an upper AUTOINST will match the main module
(verilog-insert-definition modi sig-list-o "output" indent-pt v2k t)
signals matching the regular expression will be included. For example the
same expansion will result from only extracting signals starting with i:
- /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
+ /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/
+
+You may also provide an optional third argument regular
+expression, in which case only signals which have that pin
+direction and data type matching that regular expression will be
+included. This matches against everything before the signal name
+in the declaration, for example against \"input\" (single
+bit), \"output logic\" (direction and type)
+or \"output [1:0]\" (direction and implicit type). You also
+probably want to skip spaces in your regexp.
+
+For example, the below will result in matching the output \"o\"
+against the previous example's module:
+
+ /*AUTOINOUTCOMP(\"ExampMain\",\"\",\"^output.*\")*/
+
+You may also provide an optional fourth argument regular
+expression, which if not \"\" only signals which do NOT match
+that expression are included."
+ ;; Beware spacing of quotes in above as can mess up Emacs indenter
(verilog-auto-inout-module t nil))
(defun verilog-auto-inout-in ()
signals matching the regular expression will be included. For example the
same expansion will result from only extracting signals starting with i:
- /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/"
+ /*AUTOINOUTIN(\"ExampMain\",\"^i\")*/"
(verilog-auto-inout-module nil t))
(defun verilog-auto-inout-param ()
(defun verilog-auto-insert-lisp ()
"Expand AUTOINSERTLISP statements, as part of \\[verilog-auto].
-The Lisp code provided is called, and the Lisp code calls
-`insert` to insert text into the current file beginning on the
-line after the AUTOINSERTLISP.
+The Lisp code provided is called before other AUTOS are expanded,
+and the Lisp code generally will call `insert` to insert text
+into the current file beginning on the line after the
+AUTOINSERTLISP.
+
+See also AUTOINSERTLAST and `verilog-auto-insert-last' which
+executes after (as opposed to before) other AUTOs.
See also AUTO_LISP, which takes a Lisp expression and evaluates
it during `verilog-auto-inst' but does not insert any text.
(setq verilog-scan-cache-tick nil) ;; Clear cache; inserted unknown text
(verilog-delete-empty-auto-pair))))
+(defun verilog-auto-insert-last ()
+ "Expand AUTOINSERTLAST statements, as part of \\[verilog-auto].
+The Lisp code provided is called after all other AUTOS have been
+expanded, and the Lisp code generally will call `insert` to
+insert text into the current file beginning on the line after the
+AUTOINSERTLAST.
+
+Other than when called (after AUTOs are expanded), the functionality
+is otherwise identical to AUTOINSERTLISP and `verilog-auto-insert-lisp' which
+executes before (as opposed to after) other AUTOs.
+
+See `verilog-auto-insert-lisp' for examples."
+ (verilog-auto-insert-lisp))
+
(defun verilog-auto-sense-sigs (moddecls presense-sigs)
"Return list of signals for current AUTOSENSE block."
- (let* ((sigss (verilog-read-always-signals))
+ (let* ((sigss (save-excursion
+ (search-forward ")")
+ (verilog-read-always-signals)))
(sig-list (verilog-signals-not-params
(verilog-signals-not-in (verilog-alw-get-inputs sigss)
(append (and (not verilog-auto-sense-include-inputs)
(save-excursion
(verilog-read-signals
(save-excursion
- (verilog-re-search-backward-quick "\\(@\\|\\<begin\\>\\|\\<if\\>\\|\\<case\\>\\)" nil t)
+ (verilog-re-search-backward-quick
+ "\\(@\\|\\<\\(begin\\|if\\|case\\|always\\(_latch\\|_ff\\|_comb\\)?\\)\\>\\)" nil t)
(point))
(point)))))
(save-excursion
- (verilog-re-search-backward-quick "@" nil t)
+ (verilog-re-search-backward-quick "\\(@\\|\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\)\\>\\)" nil t)
(setq sigss (verilog-read-always-signals)))
(setq dly-list (verilog-alw-get-outputs-delayed sigss))
- (setq sig-list (verilog-signals-not-in (append
- (verilog-alw-get-outputs-delayed sigss)
- (when (or (not (verilog-alw-get-uses-delayed sigss))
- verilog-auto-reset-blocking-in-non)
- (verilog-alw-get-outputs-immediate sigss)))
- (append
- (verilog-alw-get-temps sigss)
- prereset-sigs)))
+ (setq sig-list (verilog-signals-not-in-struct
+ (append
+ (verilog-alw-get-outputs-delayed sigss)
+ (when (or (not (verilog-alw-get-uses-delayed sigss))
+ verilog-auto-reset-blocking-in-non)
+ (verilog-alw-get-outputs-immediate sigss)))
+ (append
+ (verilog-alw-get-temps sigss)
+ prereset-sigs)))
(setq sig-list (sort sig-list `verilog-signals-sort-compare))
(when sig-list
(insert "\n");
`verilog-auto-inout-param' for AUTOINOUTPARAM copying params from elsewhere
`verilog-auto-input' for AUTOINPUT making hierarchy inputs
`verilog-auto-insert-lisp' for AUTOINSERTLISP insert code from lisp function
+ `verilog-auto-insert-last' for AUTOINSERTLAST insert code from lisp function
`verilog-auto-inst' for AUTOINST instantiation pins
`verilog-auto-star' for AUTOINST .* SystemVerilog pins
`verilog-auto-inst-param' for AUTOINSTPARAM instantiation params
(verilog-inject-arg))
;;
;; Do user inserts first, so their code can insert AUTOs
- ;; We may provide an AUTOINSERTLISPLAST if another cleanup pass is needed
(verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
'verilog-auto-insert-lisp)
;; Expand instances before need the signals the instances input/output
(verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
(verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
;; outputevery needs AUTOOUTPUTs done first
- (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\*/" 'verilog-auto-output-every)
+ (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\((.*?)\\)?\\*/" 'verilog-auto-output-every)
;; After we've created all new variables
(verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
;; Must be after all inputs outputs are generated
(verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
+ ;; User inserts
+ (verilog-auto-re-search-do "/\\*AUTOINSERTLAST(.*?)\\*/" 'verilog-auto-insert-last)
;; Fix line numbers (comments only)
(when verilog-auto-inst-template-numbers
(verilog-auto-templated-rel))
> "`ovm_object_utils_begin(" name ")" \n
> (- verilog-indent-level) " `ovm_object_utils_end" \n
> _ \n
- > "function new(name=\"" name "\");" \n
+ > "function new(string name=\"" name "\");" \n
> "super.new(name);" \n
> (- verilog-indent-level) "endfunction" \n
> _ \n
> "`uvm_object_utils_begin(" name ")" \n
> (- verilog-indent-level) "`uvm_object_utils_end" \n
> _ \n
- > "function new(name=\"" name "\");" \n
+ > "function new(string name=\"" name "\");" \n
> "super.new(name);" \n
> (- verilog-indent-level) "endfunction" \n
> _ \n
> "`uvm_component_utils_begin(" name ")" \n
> (- verilog-indent-level) "`uvm_component_utils_end" \n
> _ \n
- > "function new(name=\"\", uvm_component parent);" \n
+ > "function new(string name=\"\", uvm_component parent);" \n
> "super.new(name, parent);" \n
> (- verilog-indent-level) "endfunction" \n
> _ \n
()
> "begin" '(verilog-sk-prompt-name) \n
> _ \n
- > (- verilog-indent-level-behavioral) "end"
-)
+ > (- verilog-indent-level-behavioral) "end" )
(define-skeleton verilog-sk-fork
"Insert a fork join block."