]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/verilog-mode.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / progmodes / verilog-mode.el
index 7bd43a39325bac8d7ac9dca683ada81f50273013..6b6cc643ffc95dd8107a3315bdf8a77564269e60 100644 (file)
 ;;
 
 ;; This variable will always hold the version number of the mode
-(defconst verilog-mode-version "2015-09-18-314cf1d-vpo-GNU"
+(defconst verilog-mode-version "2015-11-21-8112ca0-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.")
@@ -230,10 +230,9 @@ STRING should be given if the last search was by `string-match' on STRING."
         `(customize ,var))
       )
 
-    (unless (boundp 'inhibit-point-motion-hooks)
-      (defvar inhibit-point-motion-hooks nil))
-    (unless (boundp 'deactivate-mark)
-      (defvar deactivate-mark nil))
+    (defvar inhibit-modification-hooks)
+    (defvar inhibit-point-motion-hooks)
+    (defvar deactivate-mark)
     )
   ;;
   ;; OK, do this stuff if we are NOT XEmacs:
@@ -326,6 +325,14 @@ wherever possible, since it is slow."
                 (looking-at (concat "\\(?:"  regexp "\\)\\'")))))
         (not (null pos)))))))
 
+(eval-and-compile
+  (cond
+   ((fboundp 'restore-buffer-modified-p)
+    ;; Faster, as does not update mode line when nothing changes
+    (defalias 'verilog-restore-buffer-modified-p 'restore-buffer-modified-p))
+   (t
+    (defalias 'verilog-restore-buffer-modified-p 'set-buffer-modified-p))))
+
 (eval-and-compile
   ;; Both xemacs and emacs
   (condition-case nil
@@ -827,6 +834,10 @@ Function takes three arguments, the original buffer, the
 difference buffer, and the point in original buffer with the
 first difference.")
 
+(defvar verilog-diff-ignore-regexp nil
+  "Non-nil specifies regexp which `verilog-diff-auto' will ignore.
+This is typically nil.")
+
 ;;; Compile support:
 ;;
 
@@ -2937,8 +2948,6 @@ find the errors."
     (modify-syntax-entry ?> "." table)
     (modify-syntax-entry ?& "." table)
     (modify-syntax-entry ?| "." table)
-    ;; FIXME: This goes against Emacs conventions.  Use "_" syntax instead and
-    ;; then use regexps with things like "\\_<...\\_>".
     (modify-syntax-entry ?` "w" table)  ; ` is part of definition symbols in Verilog
     (modify-syntax-entry ?_ "w" table)
     (modify-syntax-entry ?\' "." table)
@@ -3225,56 +3234,63 @@ A change is considered significant if it affects the buffer text
 in any way that isn't completely restored again.  Any
 user-visible changes to the buffer must not be within a
 `verilog-save-buffer-state'."
-  ;; From c-save-buffer-state
-  `(let* ((modified (buffer-modified-p))
-         (buffer-undo-list t)
-         (inhibit-read-only t)
-         (inhibit-point-motion-hooks t)
-         (verilog-no-change-functions t)
-         before-change-functions
-         after-change-functions
-         deactivate-mark
-         buffer-file-name ; Prevent primitives checking
-         buffer-file-truename) ; for file modification
-     (unwind-protect
-        (progn ,@body)
-       (and (not modified)
-           (buffer-modified-p)
-           (set-buffer-modified-p nil)))))
+  `(let ((inhibit-point-motion-hooks t)
+         (verilog-no-change-functions t))
+     ,(if (fboundp 'with-silent-modifications)
+          `(with-silent-modifications ,@body)
+        ;; Backward compatible version of with-silent-modifications
+        `(let* ((modified (buffer-modified-p))
+                (buffer-undo-list t)
+                (inhibit-read-only t)
+                (inhibit-modification-hooks t)
+                ;; XEmacs ignores inhibit-modification-hooks.
+                before-change-functions after-change-functions
+                deactivate-mark
+                buffer-file-name        ; Prevent primitives checking
+                buffer-file-truename)  ; for file modification
+           (unwind-protect
+               (progn ,@body)
+             (and (not modified)
+                  (buffer-modified-p)
+                  (verilog-restore-buffer-modified-p nil)))))))
 
-(defmacro verilog-save-no-change-functions (&rest body)
-  "Execute BODY forms, disabling all change hooks in BODY.
-For insignificant changes, see instead `verilog-save-buffer-state'."
-  `(let* ((inhibit-point-motion-hooks t)
-         (verilog-no-change-functions t)
-         before-change-functions
-         after-change-functions)
-     (progn ,@body)))
 
 (defvar verilog-save-font-mod-hooked nil
-  "Local variable when inside a `verilog-save-font-mods' block.")
+  "Local variable when inside a `verilog-save-font-no-change-functions' block.")
 (make-variable-buffer-local 'verilog-save-font-mod-hooked)
 
-(defmacro verilog-save-font-mods (&rest body)
 "Execute BODY forms, disabling text modifications to allow performing BODY.
+(defmacro verilog-save-font-no-change-functions (&rest body)
"Execute BODY forms, disabling all change hooks in BODY.
 Includes temporary disabling of `font-lock' to restore the buffer
 to full text form for parsing.  Additional actions may be specified with
-`verilog-before-save-font-hook' and `verilog-after-save-font-hook'."
-  ;; Before version 20, match-string with font-lock returns a
-  ;; vector that is not equal to the string.  IE if on "input"
-  ;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
-  `(let* ((hooked (unless verilog-save-font-mod-hooked
-                   (verilog-run-hooks 'verilog-before-save-font-hook)
-                   t))
-         (verilog-save-font-mod-hooked t)
-         (fontlocked (when (and (boundp 'font-lock-mode) font-lock-mode)
-                       (font-lock-mode 0)
-                       t)))
-     (unwind-protect
-         (progn ,@body)
-       ;; Unwind forms
-       (when fontlocked (font-lock-mode t))
-       (when hooked (verilog-run-hooks 'verilog-after-save-font-hook)))))
+`verilog-before-save-font-hook' and `verilog-after-save-font-hook'.
+For insignificant changes, see instead `verilog-save-buffer-state'."
+ `(if verilog-save-font-mod-hooked ; Short-circuit a recursive call
+      (progn ,@body)
+    ;; Before version 20, match-string with font-lock returns a
+    ;; vector that is not equal to the string.  IE if on "input"
+    ;; nil==(equal "input" (progn (looking-at "input") (match-string 0)))
+    ;; Therefore we must remove and restore font-lock mode
+    (verilog-run-hooks 'verilog-before-save-font-hook)
+    (let* ((verilog-save-font-mod-hooked (- (point-max) (point-min)))
+           ;; Significant speed savings with no font-lock properties
+           (fontlocked (when (and (boundp 'font-lock-mode) font-lock-mode)
+                         (font-lock-mode 0)
+                         t)))
+      (run-hook-with-args 'before-change-functions (point-min) (point-max))
+      (unwind-protect
+          ;; Must inhibit and restore hooks before restoring font-lock
+          (let* ((inhibit-point-motion-hooks t)
+                 (inhibit-modification-hooks t)
+                 (verilog-no-change-functions t)
+                 ;; XEmacs and pre-Emacs 21 ignore inhibit-modification-hooks.
+                 before-change-functions after-change-functions)
+            (progn ,@body))
+        ;; Unwind forms
+        (run-hook-with-args 'after-change-functions (point-min) (point-max)
+                            verilog-save-font-mod-hooked) ; old length
+        (when fontlocked (font-lock-mode t))
+        (verilog-run-hooks 'verilog-after-save-font-hook)))))
 
 ;;
 ;; Comment detection and caching
@@ -8074,7 +8090,7 @@ Duplicate signals are also removed.  For example A[2] and A[1] become A[2:1]."
             (when (and sv-busstring
                        (not (equal sv-busstring (verilog-sig-bits sig))))
                (when nil  ; Debugging
-                (message (concat "Warning, can't merge into single bus %s%s"
+                (message (concat "Warning, can't merge into single bus `%s%s'"
                                  ", the AUTOs may be wrong")
                          sv-name bus))
               (setq buswarn ", Couldn't Merge"))
@@ -8377,18 +8393,18 @@ Return an array of [outputs inouts inputs wire reg assign const]."
                 (setcar (cdr (cdr (cdr newsig)))
                         (if (verilog-sig-memory newsig)
                             (concat (verilog-sig-memory newsig) (match-string 1))
-                          (match-string 1))))
+                          (match-string-no-properties 1))))
                 (vec  ; Multidimensional
                 (setq multidim (cons vec multidim))
                 (setq vec (verilog-string-replace-matches
-                           "\\s-+" "" nil nil (match-string 1))))
+                           "\\s-+" "" nil nil (match-string-no-properties 1))))
                 (t  ; Bit width
                 (setq vec (verilog-string-replace-matches
-                           "\\s-+" "" nil nil (match-string 1))))))
+                           "\\s-+" "" nil nil (match-string-no-properties 1))))))
         ;; Normal or escaped identifier -- note we remember the \ if escaped
         ((looking-at "\\s-*\\([a-zA-Z0-9`_$]+\\|\\\\[^ \t\n\f]+\\)")
          (goto-char (match-end 0))
-         (setq keywd (match-string 1))
+         (setq keywd (match-string-no-properties 1))
          (when (string-match "^\\\\" (match-string 1))
             (setq keywd (concat keywd " ")))  ; Escaped ID needs space at end
          ;; Add any :: package names to same identifier
@@ -8573,11 +8589,12 @@ Return an array of [outputs inouts inputs wire reg assign const]."
   (defvar sigs-out-unk)
   (defvar sigs-temp)
   ;; These are known to be from other packages and may not be defined
-  (defvar diff-command nil)
+  (defvar diff-command)
   ;; There are known to be from newer versions of Emacs
-  (defvar create-lockfiles))
+  (defvar create-lockfiles)
+  (defvar which-func-modes))
 
-(defun verilog-read-sub-decls-sig (submoddecls comment port sig vec multidim)
+(defun verilog-read-sub-decls-sig (submoddecls comment port sig vec multidim mem)
   "For `verilog-read-sub-decls-line', add a signal."
   ;; sig eq t to indicate .name syntax
   ;;(message "vrsds: %s(%S)" port sig)
@@ -8588,6 +8605,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
       (setq sig  (if dotname port (verilog-symbol-detick-denumber sig)))
       (if vec (setq vec  (verilog-symbol-detick-denumber vec)))
       (if multidim (setq multidim  (mapcar `verilog-symbol-detick-denumber multidim)))
+      (if mem (setq mem (verilog-symbol-detick-denumber mem)))
       (unless (or (not sig)
                   (equal sig ""))  ; Ignore .foo(1'b1) assignments
        (cond ((or (setq portdata (assoc port (verilog-decls-get-inouts submoddecls)))
@@ -8597,7 +8615,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
                            sig
                            (if dotname (verilog-sig-bits portdata) vec)
                            (concat "To/From " comment)
-                           (verilog-sig-memory portdata)
+                            mem
                            nil
                            (verilog-sig-signed portdata)
                            (unless (member (verilog-sig-type portdata) '("wire" "reg"))
@@ -8611,7 +8629,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
                            sig
                            (if dotname (verilog-sig-bits portdata) vec)
                            (concat "From " comment)
-                           (verilog-sig-memory portdata)
+                           mem
                            nil
                            (verilog-sig-signed portdata)
                            ;; Though ok in SV, in V2K code, propagating the
@@ -8630,7 +8648,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
                            sig
                            (if dotname (verilog-sig-bits portdata) vec)
                            (concat "To " comment)
-                           (verilog-sig-memory portdata)
+                           mem
                            nil
                            (verilog-sig-signed portdata)
                            (unless (member (verilog-sig-type portdata) '("wire" "reg"))
@@ -8643,7 +8661,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
                            sig
                            (if dotname (verilog-sig-bits portdata) vec)
                            (concat "To/From " comment)
-                           (verilog-sig-memory portdata)
+                           mem
                            nil
                            (verilog-sig-signed portdata)
                            (verilog-sig-type portdata)
@@ -8656,7 +8674,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
                            sig
                            (if dotname (verilog-sig-bits portdata) vec)
                            (concat "To/From " comment)
-                           (verilog-sig-memory portdata)
+                           mem
                            nil
                            (verilog-sig-signed portdata)
                            (verilog-sig-type portdata)
@@ -8669,7 +8687,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
   "For `verilog-read-sub-decls-line', parse a subexpression and add signals."
   ;;(message "vrsde: `%s'" expr)
   ;; Replace special /*[....]*/ comments inserted by verilog-auto-inst-port
-  (setq expr (verilog-string-replace-matches "/\\*\\(\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
+  (setq expr (verilog-string-replace-matches "/\\*\\(\\.?\\[[^*]+\\]\\)\\*/" "\\1" nil nil expr))
   ;; Remove front operators
   (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
   ;;
@@ -8683,7 +8701,7 @@ Return an array of [outputs inouts inputs wire reg assign const]."
        (while (setq mstr (pop mlst))
          (verilog-read-sub-decls-expr submoddecls comment port mstr)))))
    (t
-    (let (sig vec multidim)
+    (let (sig vec multidim mem)
       ;; Remove leading reduction operators, etc
       (setq expr (verilog-string-replace-matches "^\\s-*[---+~!|&]+\\s-*" "" nil nil expr))
       ;;(message "vrsde-ptop: `%s'" expr)
@@ -8703,10 +8721,15 @@ Return an array of [outputs inouts inputs wire reg assign const]."
        (when vec (setq multidim (cons vec multidim)))
        (setq vec (match-string 1 expr)
              expr (substring expr (match-end 0))))
+      ;; Find .[unpacked_memory] or .[unpacked][unpacked]...
+      (while (string-match "^\\s-*\\.\\(\\[[^]]+\\]\\)" expr)
+       ;;(message "vrsde-m: `%s'" (match-string 1 expr))
+       (setq mem (match-string 1 expr)
+             expr (substring expr (match-end 0))))
       ;; If found signal, and nothing unrecognized, add the signal
       ;;(message "vrsde-rem: `%s'" expr)
       (when (and sig (string-match "^\\s-*$" expr))
-       (verilog-read-sub-decls-sig submoddecls comment port sig vec multidim))))))
+       (verilog-read-sub-decls-sig submoddecls comment port sig vec multidim mem))))))
 
 (defun verilog-read-sub-decls-line (submoddecls comment)
   "For `verilog-read-sub-decls', read lines of port defs until none match.
@@ -8717,23 +8740,23 @@ Inserts the list of signals found, using submodi to look up each port."
       (while (not done)
        ;; Get port name
        (cond ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*(\\s-*")
-              (setq port (match-string 1))
+              (setq port (match-string-no-properties 1))
               (goto-char (match-end 0)))
              ;; .\escaped (
              ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*(\\s-*")
-               (setq port (concat (match-string 1) " "))  ; escaped id's need trailing space
+               (setq port (concat (match-string-no-properties 1) " "))  ; escaped id's need trailing space
               (goto-char (match-end 0)))
              ;; .name
              ((looking-at "\\s-*\\.\\s-*\\([a-zA-Z0-9`_$]*\\)\\s-*[,)/]")
               (verilog-read-sub-decls-sig
-               submoddecls comment (match-string 1) t ; sig==t for .name
-               nil nil) ; vec multidim
+               submoddecls comment (match-string-no-properties 1) t ; sig==t for .name
+               nil nil nil) ; vec multidim mem
               (setq port nil))
              ;; .\escaped_name
              ((looking-at "\\s-*\\.\\s-*\\(\\\\[^ \t\n\f]*\\)\\s-*[,)/]")
               (verilog-read-sub-decls-sig
-               submoddecls comment (concat (match-string 1) " ") t ; sig==t for .name
-               nil nil) ; vec multidim
+               submoddecls comment (concat (match-string-no-properties 1) " ") t ; sig==t for .name
+               nil nil nil) ; vec multidim mem
               (setq port nil))
              ;; random
              ((looking-at "\\s-*\\.[^(]*(")
@@ -8748,20 +8771,20 @@ Inserts the list of signals found, using submodi to look up each port."
          (cond ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*)")
                 (verilog-read-sub-decls-sig
                  submoddecls comment port
-                 (verilog-string-remove-spaces (match-string 1)) ; sig
-                 nil nil)) ; vec multidim
+                 (verilog-string-remove-spaces (match-string-no-properties 1)) ; sig
+                 nil nil nil)) ; vec multidim mem
                ;;
                ((looking-at "\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\s-*\\(\\[[^]]+\\]\\)\\s-*)")
                 (verilog-read-sub-decls-sig
                  submoddecls comment port
-                 (verilog-string-remove-spaces (match-string 1)) ; sig
-                 (match-string 2) nil)) ; vec multidim
+                 (verilog-string-remove-spaces (match-string-no-properties 1)) ; sig
+                 (match-string-no-properties 2) nil nil)) ; vec multidim mem
                ;; Fastpath was above looking-at's.
                ;; For something more complicated invoke a parser
                ((looking-at "[^)]+")
                 (verilog-read-sub-decls-expr
                  submoddecls comment port
-                 (buffer-substring
+                 (buffer-substring-no-properties
                   (point) (1- (progn (search-backward "(") ; start at (
                                      (verilog-forward-sexp-ign-cmt 1)
                                      (point)))))))) ; expr
@@ -9894,7 +9917,7 @@ Return modi if successful, else print message unless IGNORE-ERROR is true."
               (or mif ignore-error
                   (error
                    (concat
-                    "%s: Can't locate %s module definition%s"
+                    "%s: Can't locate `%s' module definition%s"
                     "\n    Check the verilog-library-directories variable."
                     "\n    I looked in (if not listed, doesn't exist):\n\t%s")
                    (verilog-point-text) module
@@ -9959,9 +9982,9 @@ Cache the output of function so next call may have faster access."
            (t
             ;; Read from file
             ;; Clear then restore any highlighting to make emacs19 happy
-            (let (func-returns)
-              (verilog-save-font-mods
-               (setq func-returns (funcall function)))
+             (let ((func-returns
+                    (verilog-save-font-no-change-functions
+                     (funcall function))))
               ;; Cache for next time
               (setq verilog-modi-cache-list
                     (cons (list (list modi function)
@@ -10003,7 +10026,7 @@ Report errors unless optional IGNORE-ERROR."
   (let* ((realname (verilog-symbol-detick name t))
         (modport (assoc name (verilog-decls-get-modports (verilog-modi-get-decls modi)))))
     (or modport ignore-error
-       (error "%s: Can't locate %s modport definition%s"
+       (error "%s: Can't locate `%s' modport definition%s"
                (verilog-point-text) name
                (if (not (equal name realname))
                    (concat " (Expanded macro to " realname ")")
@@ -10193,7 +10216,7 @@ When MODI is non-null, also add to modi-cache, for tracking."
          ((equal direction "parameter")
           (verilog-modi-cache-add-gparams modi sigs))
          (t
-          (error "Unsupported verilog-insert-definition direction: %s" direction))))
+          (error "Unsupported verilog-insert-definition direction: `%s'" direction))))
   (or dont-sort
       (setq sigs (sort (copy-alist sigs) `verilog-signals-sort-compare)))
   (while sigs
@@ -10224,7 +10247,7 @@ When MODI is non-null, also add to modi-cache, for tracking."
 
 (eval-when-compile
   (if (not (boundp 'indent-pt))
-      (defvar indent-pt nil "Local used by insert-indent")))
+      (defvar indent-pt nil "Local used by `verilog-insert-indent'.")))
 
 (defun verilog-insert-indent (&rest stuff)
   "Indent to position stored in local `indent-pt' variable, then insert STUFF.
@@ -10510,6 +10533,41 @@ removed."
          (re-search-backward ",")
          (delete-char 1))))))
 
+(defun verilog-delete-auto-buffer ()
+  "Perform `verilog-delete-auto' on the current buffer.
+Intended for internal use inside a `verilog-save-font-no-change-functions' block."
+  ;; Allow user to customize
+  (verilog-run-hooks 'verilog-before-delete-auto-hook)
+
+  ;; Remove those that have multi-line insertions, possibly with parameters
+  ;; We allow anything beginning with AUTO, so that users can add their own
+  ;; patterns
+  (verilog-auto-re-search-do
+   (concat "/\\*AUTO[A-Za-z0-9_]+"
+           ;; Optional parens or quoted parameter or .* for (((...)))
+           "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
+           "\\*/")
+   'verilog-delete-autos-lined)
+  ;; Remove those that are in parenthesis
+  (verilog-auto-re-search-do
+   (concat "/\\*"
+           (eval-when-compile
+             (verilog-regexp-words
+              `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
+                "AUTOSENSE")))
+           "\\*/")
+   'verilog-delete-to-paren)
+  ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
+  (verilog-auto-re-search-do "\\.\\*"
+                             'verilog-delete-auto-star-all)
+  ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
+  (goto-char (point-min))
+  (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)?$" nil t)
+    (replace-match ""))
+
+  ;; Final customize
+  (verilog-run-hooks 'verilog-delete-auto-hook))
+
 (defun verilog-delete-auto ()
   "Delete the automatic outputs, regs, and wires created by \\[verilog-auto].
 Use \\[verilog-auto] to re-insert the updated AUTOs.
@@ -10520,39 +10578,10 @@ called before and after this function, respectively."
   (save-excursion
     (if (buffer-file-name)
         (find-file-noselect (buffer-file-name)))  ; To check we have latest version
-    (verilog-save-no-change-functions
+    (verilog-save-font-no-change-functions
      (verilog-save-scan-cache
-      ;; Allow user to customize
-      (verilog-run-hooks 'verilog-before-delete-auto-hook)
-
-      ;; Remove those that have multi-line insertions, possibly with parameters
-      ;; We allow anything beginning with AUTO, so that users can add their own
-      ;; patterns
-      (verilog-auto-re-search-do
-       (concat "/\\*AUTO[A-Za-z0-9_]+"
-              ;; Optional parens or quoted parameter or .* for (((...)))
-              "\\(\\|([^)]*)\\|(\"[^\"]*\")\\).*?"
-              "\\*/")
-       'verilog-delete-autos-lined)
-      ;; Remove those that are in parenthesis
-      (verilog-auto-re-search-do
-       (concat "/\\*"
-              (eval-when-compile
-                (verilog-regexp-words
-                 `("AS" "AUTOARG" "AUTOCONCATWIDTH" "AUTOINST" "AUTOINSTPARAM"
-                   "AUTOSENSE")))
-              "\\*/")
-       'verilog-delete-to-paren)
-      ;; Do .* instantiations, but avoid removing any user pins by looking for our magic comments
-      (verilog-auto-re-search-do "\\.\\*"
-                                'verilog-delete-auto-star-all)
-      ;; Remove template comments ... anywhere in case was pasted after AUTOINST removed
-      (goto-char (point-min))
-      (while (re-search-forward "\\s-*// \\(Templated\\|Implicit \\.\\*\\)\\([ \tLT0-9]*\\| LHS: .*\\)?$" nil t)
-       (replace-match ""))
+      (verilog-delete-auto-buffer)))))
 
-      ;; Final customize
-      (verilog-run-hooks 'verilog-delete-auto-hook)))))
 \f
 ;;; Auto inject:
 ;;
@@ -10679,10 +10708,11 @@ Typing \\[verilog-inject-auto] will make this into:
 ;; Auto diff:
 ;;
 
-(defun verilog-diff-buffers-p (b1 b2 &optional whitespace)
+(defun verilog-diff-buffers-p (b1 b2 &optional whitespace regexp)
   "Return nil if buffers B1 and B2 have same contents.
 Else, return point in B1 that first mismatches.
-If optional WHITESPACE true, ignore whitespace."
+If optional WHITESPACE true, ignore whitespace.
+If optional REGEXP, ignore differences matching it."
   (save-excursion
     (let* ((case-fold-search nil)  ; compare-buffer-substrings cares
           (p1 (with-current-buffer b1 (goto-char (point-min))))
@@ -10703,6 +10733,15 @@ If optional WHITESPACE true, ignore whitespace."
            (goto-char p2)
            (skip-chars-forward " \t\n\r\f\v")
            (setq p2 (point))))
+       (when regexp
+         (with-current-buffer b1
+           (goto-char p1)
+           (when (looking-at regexp)
+              (setq p1 (match-end 0))))
+         (with-current-buffer b2
+           (goto-char p2)
+           (when (looking-at regexp)
+              (setq p2 (match-end 0)))))
        (setq size (min (- maxp1 p1) (- maxp2 p2)))
        (setq progress (compare-buffer-substrings b2 p2 (+ size p2)
                                                  b1 p1 (+ size p1)))
@@ -10723,7 +10762,7 @@ Ignores WHITESPACE if t, and writes output to stdout if SHOW."
   ;; call `diff' as `diff' has different calling semantics on different
   ;; versions of Emacs.
   (if (not (file-exists-p f1))
-      (message "Buffer %s has no associated file on disc" (buffer-name b2))
+      (message "Buffer `%s' has no associated file on disk" (buffer-name b2))
     (with-temp-buffer "*Verilog-Diff*"
                       (let ((outbuf (current-buffer))
                             (f2 (make-temp-file "vm-diff-auto-")))
@@ -10791,7 +10830,7 @@ or `diff' in batch mode."
            ;; Restore name if unwind
            (with-current-buffer b1 (setq buffer-file-name name1)))))
       ;;
-      (setq diffpt (verilog-diff-buffers-p b1 b2 t))
+      (setq diffpt (verilog-diff-buffers-p b1 b2 t verilog-diff-ignore-regexp))
       (cond ((not diffpt)
             (unless noninteractive (message "AUTO expansion identical"))
              (kill-buffer newname))  ; Nice to cleanup after oneself
@@ -11054,6 +11093,7 @@ If PAR-VALUES replace final strings with these parameter values."
         (vl-name (verilog-sig-name port-st))
         (vl-width (verilog-sig-width port-st))
         (vl-modport (verilog-sig-modport port-st))
+        (vl-memory (verilog-sig-memory port-st))
         (vl-mbits (if (verilog-sig-multidim port-st)
                        (verilog-sig-multidim-string port-st) ""))
         (vl-bits (if (or verilog-auto-inst-vector
@@ -11078,15 +11118,25 @@ If PAR-VALUES replace final strings with these parameter values."
                        (concat "\\<" (nth 0 (car check-values)) "\\>")
                        (concat "(" (nth 1 (car check-values)) ")")
                        t t vl-mbits)
+             vl-memory (when vl-memory
+                          (verilog-string-replace-matches
+                           (concat "\\<" (nth 0 (car check-values)) "\\>")
+                           (concat "(" (nth 1 (car check-values)) ")")
+                           t t vl-memory))
              check-values (cdr check-values)))
       (setq vl-bits (verilog-simplify-range-expression vl-bits)
            vl-mbits (verilog-simplify-range-expression vl-mbits)
+           vl-memory (when vl-memory (verilog-simplify-range-expression vl-memory))
            vl-width (verilog-make-width-expression vl-bits))) ; Not in the loop for speed
     ;; Default net value if not found
-    (setq dflt-bits (if (and (verilog-sig-bits port-st)
-                            (or (verilog-sig-multidim port-st)
-                                (verilog-sig-memory port-st)))
-                       (concat "/*" vl-mbits vl-bits "*/")
+    (setq dflt-bits (if (or (and (verilog-sig-bits port-st)
+                                 (verilog-sig-multidim port-st))
+                            (verilog-sig-memory port-st))
+                       (concat "/*" vl-mbits vl-bits
+                                ;; .[ used to separate packed from unpacked
+                                (if vl-memory "." "")
+                                (if vl-memory vl-memory "")
+                                "*/")
                      (concat vl-bits))
          tpl-net (concat port
                          (if (and vl-modport
@@ -11157,7 +11207,7 @@ If PAR-VALUES replace final strings with these parameter values."
          (for-star
           (indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
                         verilog-auto-inst-column))
-          (verilog-insert " // Implicit .\*\n")) ;For some reason the . or * must be escaped...
+          (verilog-insert " // Implicit .*\n"))
          (t
           (insert "\n")))))
 ;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
@@ -13316,13 +13366,16 @@ Typing \\[verilog-auto] will make this into:
           (sig-list-all  (verilog-decls-get-iovars moddecls))
           ;;
           (undecode-sig (or (assoc undecode-name sig-list-all)
-                            (error "%s: Signal %s not found in design" (verilog-point-text) undecode-name)))
+                            (error "%s: Signal `%s' not found in design"
+                                    (verilog-point-text) undecode-name)))
           (undecode-enum (or (verilog-sig-enum undecode-sig)
-                             (error "%s: Signal %s does not have an enum tag" (verilog-point-text) undecode-name)))
+                             (error "%s: Signal `%s' does not have an enum tag"
+                                     (verilog-point-text) undecode-name)))
           ;;
           (enum-sigs (verilog-signals-not-in
                       (or (verilog-signals-matching-enum sig-list-consts undecode-enum)
-                          (error "%s: No state definitions for %s" (verilog-point-text) undecode-enum))
+                          (error "%s: No state definitions for `%s'"
+                                  (verilog-point-text) undecode-enum))
                       nil))
           ;;
           (one-hot (or
@@ -13518,120 +13571,115 @@ Wilson Snyder (wsnyder@wsnyder.org)."
   (unless noninteractive (message "Updating AUTOs..."))
   (if (fboundp 'dinotrace-unannotate-all)
       (dinotrace-unannotate-all))
-  (verilog-save-font-mods
+  ;; Disable change hooks for speed
+  ;; This let can't be part of above let; must restore
+  ;; after-change-functions before font-lock resumes
+  (verilog-save-font-no-change-functions
    (let ((oldbuf (if (not (buffer-modified-p))
-                    (buffer-string)))
-        (case-fold-search verilog-case-fold)
-        ;; Cache directories; we don't write new files, so can't change
-        (verilog-dir-cache-preserving t)
-        ;; Cache current module
-        (verilog-modi-cache-current-enable t)
-        (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
-        verilog-modi-cache-current)
-     (unwind-protect
-        ;; Disable change hooks for speed
-        ;; This let can't be part of above let; must restore
-        ;; after-change-functions before font-lock resumes
-        (verilog-save-no-change-functions
-         (verilog-save-scan-cache
-          (save-excursion
-            ;; Wipe cache; otherwise if we AUTOed a block above this one,
-            ;; we'll misremember we have generated IOs, confusing AUTOOUTPUT
-            (setq verilog-modi-cache-list nil)
-            ;; Local state
-            (verilog-read-auto-template-init)
-            ;; If we're not in verilog-mode, change syntax table so parsing works right
-            (unless (eq major-mode `verilog-mode) (verilog-mode))
-            ;; Allow user to customize
-            (verilog-run-hooks 'verilog-before-auto-hook)
-            ;; Try to save the user from needing to revert-file to reread file local-variables
-            (verilog-auto-reeval-locals)
-            (verilog-read-auto-lisp-present)
-            (verilog-read-auto-lisp (point-min) (point-max))
-            (verilog-getopt-flags)
-            ;; From here on out, we can cache anything we read from disk
-            (verilog-preserve-dir-cache
-             ;; These two may seem obvious to do always, but on large includes it can be way too slow
-             (when verilog-auto-read-includes
-               (verilog-read-includes)
-               (verilog-read-defines nil nil t))
-             ;; Setup variables due to SystemVerilog expansion
-             (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic-setup)
-             ;; This particular ordering is important
-             ;; INST: Lower modules correct, no internal dependencies, FIRST
-             (verilog-preserve-modi-cache
-              ;; Clear existing autos else we'll be screwed by existing ones
-              (verilog-delete-auto)
-              ;; Injection if appropriate
-              (when inject
-                (verilog-inject-inst)
-                (verilog-inject-sense)
-                (verilog-inject-arg))
-              ;;
-              ;; Do user inserts first, so their code can insert AUTOs
-              (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
-                                         'verilog-auto-insert-lisp)
-              ;; Expand instances before need the signals the instances input/output
-              (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
-              (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
-              (verilog-auto-re-search-do "\\.\\*" 'verilog-auto-star)
-              ;; Doesn't matter when done, but combine it with a common changer
-              (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
-              (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
-              ;; Must be done before autoin/out as creates a reg
-              (verilog-auto-re-search-do "/\\*AUTOASCIIENUM(.*?)\\*/" 'verilog-auto-ascii-enum)
-              ;;
-              ;; first in/outs from other files
-              (verilog-auto-re-search-do "/\\*AUTOINOUTMODPORT(.*?)\\*/" 'verilog-auto-inout-modport)
-              (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE(.*?)\\*/" 'verilog-auto-inout-module)
-              (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP(.*?)\\*/" 'verilog-auto-inout-comp)
-              (verilog-auto-re-search-do "/\\*AUTOINOUTIN(.*?)\\*/" 'verilog-auto-inout-in)
-              (verilog-auto-re-search-do "/\\*AUTOINOUTPARAM(.*?)\\*/" 'verilog-auto-inout-param)
-              ;; next in/outs which need previous sucked inputs first
-              (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((.*?)\\)?\\*/" 'verilog-auto-output)
-              (verilog-auto-re-search-do "/\\*AUTOINPUT\\((.*?)\\)?\\*/" 'verilog-auto-input)
-              (verilog-auto-re-search-do "/\\*AUTOINOUT\\((.*?)\\)?\\*/" 'verilog-auto-inout)
-              ;; Then tie off those in/outs
-              (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
-              ;; These can be anywhere after AUTOINSERTLISP
-              (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((.*?)\\)?\\*/" 'verilog-auto-undef)
-              ;; Wires/regs must be after inputs/outputs
-              (verilog-auto-re-search-do "/\\*AUTOASSIGNMODPORT(.*?)\\*/" 'verilog-auto-assign-modport)
-              (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic)
-              (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
-              (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
-              (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
-              ;; outputevery needs AUTOOUTPUTs done first
-              (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\((.*?)\\)?\\*/" 'verilog-auto-output-every)
-              ;; After we've created all new variables
-              (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
-              ;; Must be after all inputs outputs are generated
-              (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
-              ;; 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))
-              (when verilog-auto-template-warn-unused
-                (verilog-auto-template-lint))))
-            ;;
-            (verilog-run-hooks 'verilog-auto-hook)
-            ;;
-            (when verilog-auto-delete-trailing-whitespace
-              (verilog-delete-trailing-whitespace))
-            ;;
-            (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))
-            ;;
-            ;; If end result is same as when started, clear modified flag
-            (cond ((and oldbuf (equal oldbuf (buffer-string)))
-                   (set-buffer-modified-p nil)
-                   (unless noninteractive (message "Updating AUTOs...done (no changes)")))
-                  (t (unless noninteractive (message "Updating AUTOs...done"))))
-            ;; End of after-change protection
-            )))
-       ;; Unwind forms
-       ;; Currently handled in verilog-save-font-mods
-       ))))
+                     (buffer-string)))
+         (case-fold-search verilog-case-fold)
+         ;; Cache directories; we don't write new files, so can't change
+         (verilog-dir-cache-preserving t)
+         ;; Cache current module
+         (verilog-modi-cache-current-enable t)
+         (verilog-modi-cache-current-max (point-min)) ; IE it's invalid
+         verilog-modi-cache-current)
+     (verilog-save-scan-cache
+      (save-excursion
+        ;; Wipe cache; otherwise if we AUTOed a block above this one,
+        ;; we'll misremember we have generated IOs, confusing AUTOOUTPUT
+        (setq verilog-modi-cache-list nil)
+        ;; Local state
+        (verilog-read-auto-template-init)
+        ;; If we're not in verilog-mode, change syntax table so parsing works right
+        (unless (eq major-mode `verilog-mode) (verilog-mode))
+        ;; Allow user to customize
+        (verilog-run-hooks 'verilog-before-auto-hook)
+        ;; Try to save the user from needing to revert-file to reread file local-variables
+        (verilog-auto-reeval-locals)
+        (verilog-read-auto-lisp-present)
+        (verilog-read-auto-lisp (point-min) (point-max))
+        (verilog-getopt-flags)
+        ;; From here on out, we can cache anything we read from disk
+        (verilog-preserve-dir-cache
+         ;; These two may seem obvious to do always, but on large includes it can be way too slow
+         (when verilog-auto-read-includes
+           (verilog-read-includes)
+           (verilog-read-defines nil nil t))
+         ;; Setup variables due to SystemVerilog expansion
+         (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic-setup)
+         ;; This particular ordering is important
+         ;; INST: Lower modules correct, no internal dependencies, FIRST
+         (verilog-preserve-modi-cache
+          ;; Clear existing autos else we'll be screwed by existing ones
+          (verilog-delete-auto-buffer)
+          ;; Injection if appropriate
+          (when inject
+            (verilog-inject-inst)
+            (verilog-inject-sense)
+            (verilog-inject-arg))
+          ;;
+          ;; Do user inserts first, so their code can insert AUTOs
+          (verilog-auto-re-search-do "/\\*AUTOINSERTLISP(.*?)\\*/"
+                                     'verilog-auto-insert-lisp)
+          ;; Expand instances before need the signals the instances input/output
+          (verilog-auto-re-search-do "/\\*AUTOINSTPARAM\\*/" 'verilog-auto-inst-param)
+          (verilog-auto-re-search-do "/\\*AUTOINST\\*/" 'verilog-auto-inst)
+          (verilog-auto-re-search-do "\\.\\*" 'verilog-auto-star)
+          ;; Doesn't matter when done, but combine it with a common changer
+          (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense)
+          (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset)
+          ;; Must be done before autoin/out as creates a reg
+          (verilog-auto-re-search-do "/\\*AUTOASCIIENUM(.*?)\\*/" 'verilog-auto-ascii-enum)
+          ;;
+          ;; first in/outs from other files
+          (verilog-auto-re-search-do "/\\*AUTOINOUTMODPORT(.*?)\\*/" 'verilog-auto-inout-modport)
+          (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE(.*?)\\*/" 'verilog-auto-inout-module)
+          (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP(.*?)\\*/" 'verilog-auto-inout-comp)
+          (verilog-auto-re-search-do "/\\*AUTOINOUTIN(.*?)\\*/" 'verilog-auto-inout-in)
+          (verilog-auto-re-search-do "/\\*AUTOINOUTPARAM(.*?)\\*/" 'verilog-auto-inout-param)
+          ;; next in/outs which need previous sucked inputs first
+          (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((.*?)\\)?\\*/" 'verilog-auto-output)
+          (verilog-auto-re-search-do "/\\*AUTOINPUT\\((.*?)\\)?\\*/" 'verilog-auto-input)
+          (verilog-auto-re-search-do "/\\*AUTOINOUT\\((.*?)\\)?\\*/" 'verilog-auto-inout)
+          ;; Then tie off those in/outs
+          (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff)
+          ;; These can be anywhere after AUTOINSERTLISP
+          (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((.*?)\\)?\\*/" 'verilog-auto-undef)
+          ;; Wires/regs must be after inputs/outputs
+          (verilog-auto-re-search-do "/\\*AUTOASSIGNMODPORT(.*?)\\*/" 'verilog-auto-assign-modport)
+          (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic)
+          (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire)
+          (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg)
+          (verilog-auto-re-search-do "/\\*AUTOREGINPUT\\*/" 'verilog-auto-reg-input)
+          ;; outputevery needs AUTOOUTPUTs done first
+          (verilog-auto-re-search-do "/\\*AUTOOUTPUTEVERY\\((.*?)\\)?\\*/" 'verilog-auto-output-every)
+          ;; After we've created all new variables
+          (verilog-auto-re-search-do "/\\*AUTOUNUSED\\*/" 'verilog-auto-unused)
+          ;; Must be after all inputs outputs are generated
+          (verilog-auto-re-search-do "/\\*AUTOARG\\*/" 'verilog-auto-arg)
+          ;; 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))
+          (when verilog-auto-template-warn-unused
+            (verilog-auto-template-lint))))
+        ;;
+        (verilog-run-hooks 'verilog-auto-hook)
+        ;;
+        (when verilog-auto-delete-trailing-whitespace
+          (verilog-delete-trailing-whitespace))
+        ;;
+        (set (make-local-variable 'verilog-auto-update-tick) (buffer-chars-modified-tick))
+        ;;
+        ;; If end result is same as when started, clear modified flag
+        (cond ((and oldbuf (equal oldbuf (buffer-string)))
+               (verilog-restore-buffer-modified-p nil)
+               (unless noninteractive (message "Updating AUTOs...done (no changes)")))
+              (t (unless noninteractive (message "Updating AUTOs...done"))))
+        ;; End of save-cache
+        )))))
 \f
 ;;; Skeletons:
 ;;