;;; 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 "2014-05-31-3cd8144-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)
If 'single', then a single input or output will be put onto each
line."
- :version "24.5"
+ :version "25.1"
:type '(radio (const :tag "Line up Assignments and Declarations" packed)
(const :tag "Line up Assignment statements" single))
:group 'verilog-mode-auto)
: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)
(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.")
(defconst verilog-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)
;; 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 "\\)\\>")
(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
(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)
;; 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.
- (when fontlocked (font-lock-fontify-buffer)))))))
+ ;; So avoid bytecomp's interactive-only by going through intern.
+ (when fontlocked (funcall (intern "font-lock-fontify-buffer"))))))))
\f
;;
((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)))
(;-- 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)))))
(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)
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 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
(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)
(indent-to indent-pt)
(while sigs
(cond ((equal verilog-auto-arg-format 'single)
+ (insert space)
(indent-to indent-pt)
(setq space "\n"))
;; verilog-auto-arg-format 'packed
(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 sig-list-if)
(verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n")
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