I have received an updated verilog-mode.el from the maintainer. I
made a couple of very simple changes - because it explicitly looked
for xemacs version number 20. I think my changes are probably OK.
Here it is:
;;; verilog-mode.el --- major mode for editing verilog source in Emacs
;;
;; $Id: verilog-mode.el,v 1.1 1998/10/07 17:48:13 nbecker Exp nbecker $
;; Copyright (C) 1996 Free Software Foundation, Inc.
;; Author: Michael McNamara (mac(a)surefirev.com)
;; President, SureFire Verification, Inc.
;; (company was previously known as Silicon Sorcery)
;; AUTO features, signal, modsig; by: Wilson Snyder (wsnyder(a)world.std.com)
;; Keywords: languages
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;; Commentary:
;;; This mode borrows heavily from the Pascal-mode and the cc-mode of emacs
;;; USAGE
;;; =====
;;; A major mode for editing Verilog HDL source code. When you have
;;; entered Verilog mode, you may get more info by pressing C-h m. You
;;; may also get online help describing various functions by: C-h f
;;; <Name of function you want described>
;;; You can get step by step help in installing this file by going to
;;; <
http://www.surefirev.com/emacs_install.html>
;;; The short list of installation instructions are: To set up
;;; automatic verilog mode, put this file in your load path, and put
;;; the following in code (please un comment it first!) in your
;;; .emacs, or in your site's site-load.el
; (autoload 'verilog-mode "verilog-mode" "Verilog mode" t )
; (setq auto-mode-alist (cons '("\\.v\\'" . verilog-mode)
auto-mode-alist))
; (setq auto-mode-alist (cons '("\\.dv\\'" . verilog-mode)
auto-mode-alist))
;;; If you want to customize Verilog mode to fit your needs better,
;;; you may add these lines (the values of the variables presented
;;; here are the defaults). Note also that if you use an emacs that
;;; supports custom, it's probably better to use the custom menu to
;;; edit these.
;;;
;;; Be sure to examine at the help for verilog-auto, and the other
;;; verilog-auto-* functions for some major coding time savers.
;;;
; ;; User customization for Verilog mode
; (setq verilog-indent-level 3
; verilog-indent-level-module 3
; verilog-indent-level-declaration 3
; verilog-indent-level-behavioral 3
; verilog-case-indent 2
; verilog-auto-newline t
; verilog-auto-indent-on-newline t
; verilog-tab-always-indent t
; verilog-auto-endcomments t
; verilog-minimum-comment-distance 40
; verilog-indent-begin-after-if t
; verilog-auto-lineup '(all))
;;; KNOWN BUGS / BUG REPORTS
;;; =======================
;;; This is beta code, and likely has bugs. Please report any and all
;;; bugs to me at verilog-mode-bugs(a)surefirev.com. Use
;;; verilog-submit-bug-report to submit a report.
;;
;;; Code:
(provide 'verilog-mode)
;; This variable will always hold the version number of the mode
(defconst verilog-mode-version "$$Revision: 1.1 $$"
"Version of this verilog mode.")
;;
;; A hack so we can support either custom, or the old defvar
;;
;; Insure we have certain packages, and deal with it if we don't
(if (fboundp 'eval-when-compile)
(eval-when-compile
(condition-case nil
(require 'imenu)
(error nil))
(condition-case nil
(require 'reporter)
(error nil))
(condition-case nil
(require 'easymenu)
(error nil))
(condition-case nil
(if (fboundp 'when)
nil ;; fab
(defmacro when (var &rest body)
(` (cond ( (, var) (,@ body))))))
(error nil))
(condition-case nil
(if (fboundp 'unless)
nil ;; fab
(defmacro unless (var &rest body)
(` (if (, var) nil (,@ body)))))
(error nil))
(condition-case nil
(if (fboundp 'store-match-data)
nil ;; fab
(defmacro store-match-data (&rest args) nil))
(error nil))
(condition-case nil
(if (boundp 'current-menubar)
nil ;; great
(defmacro set-buffer-menubar (&rest args) nil)
(defmacro add-submenu (&rest args) nil))
(error nil))
(condition-case nil
(if (fboundp 'zmacs-activate-region)
nil ;; great
(defmacro zmacs-activate-region (&rest args) nil))
(error nil))
;; Requires to define variables that would be "free" warnings
(condition-case nil
(require 'font-lock)
(error nil))
(condition-case nil
(require 'compile)
(error nil))
(condition-case nil
(require 'custom)
(error nil))
(condition-case nil
(require 'dinotrace)
(error nil))
(condition-case nil
(if (fboundp 'dinotrace-unannotate-all)
nil ;; great
(defun dinotrace-unannotate-all (&rest args) nil))
(error nil))
(condition-case nil
(if (fboundp 'customize-apropos)
nil ;; great
(defun customize-apropos (&rest args) nil))
(error nil))
(if (and (featurep 'custom) (fboundp 'custom-declare-variable))
nil ;; We've got what we needed
;; We have the old custom-library, hack around it!
(defmacro defgroup (&rest args) nil)
(defmacro customize (&rest args)
(message "Sorry, Customize is not available with this version of emacs"))
(defmacro defcustom (var value doc &rest args)
(` (defvar (, var) (, value) (, doc))))
)
(if (and (featurep 'custom) (fboundp 'customize-group))
nil ;; We've got what we needed
;; We have an intermediate custom-library, hack around it!
(defmacro customize-group (var &rest args)
(`(customize (, var) )))
)
))
(defun verilog-customize ()
"Link to customize screen for Verilog"
(interactive)
(customize-group 'verilog-mode)
)
(defun verilog-font-customize ()
"Link to customize fonts used for Verilog"
(interactive)
(customize-apropos "font-lock-*" 'faces)
)
(defgroup verilog-mode nil
"Facilitates easy editing of Verilog source text"
:group 'languages)
(defcustom verilog-compiler "vcs "
"*Program and arguments to use to compile/run/lint verilog source."
:type 'string
:group 'verilog-mode
)
(defcustom verilog-indent-level 3
"*Indentation of Verilog statements with respect to containing block."
:group 'verilog-mode
:type 'integer
)
(defcustom verilog-indent-level-module 3
"* Indentation of Module level Verilog statements. (eg always, initial)
Set to 0 to get initial and always statements lined up
on the left side of your screen."
:group 'verilog-mode
:type 'integer
)
(defcustom verilog-indent-level-declaration 3
"*Indentation of declarations with respect to containing block.
Set to 0 to get them list right under containing block."
:group 'verilog-mode
:type 'integer
)
(defcustom verilog-indent-level-behavioral 3
"*Absolute indentation of first begin in a task or function block
Set to 0 to get such code to start at the left side of the screen."
:group 'verilog-mode
:type 'integer
)
(defcustom verilog-cexp-indent 2
"*Indentation of Verilog statements split across lines."
:group 'verilog-mode
:type 'integer
)
(defcustom verilog-case-indent 2
"*Indentation for case statements."
:group 'verilog-mode
:type 'integer
)
(defcustom verilog-auto-newline t
"*Non-nil means automatically newline after semicolons"
:group 'verilog-mode
:type 'boolean
)
(defcustom verilog-auto-indent-on-newline t
"*Non-nil means automatically indent line after newline"
:group 'verilog-mode
:type 'boolean
)
(defcustom verilog-tab-always-indent t
"*Non-nil means TAB in Verilog mode should always re-indent the
current line, regardless of where in the line point is when the TAB
command is used."
:group 'verilog-mode
:type 'boolean
)
(defcustom verilog-tab-to-comment nil
"*Non-nil means TAB in Verilog mode should move to the right hand
column in preparation for a comment."
:group 'verilog-mode
:type 'boolean
)
(defcustom verilog-indent-begin-after-if t
"*If true, indent begin statements following if, else, while, for
and repeat. otherwise, line them up."
:group 'verilog-mode
:type 'boolean )
(defcustom verilog-align-ifelse nil
"*If true, align `else' under matching `if'. Otherwise
else is lined up with first character on line holding matching if "
:group 'verilog-mode
:type 'boolean )
(defcustom verilog-auto-endcomments t
"*Non-nil means a comment /* ... */ is set after the ends which ends
cases and functions. The name of the function or case will be set
between the braces."
:group 'verilog-mode
:type 'boolean )
(defcustom verilog-minimum-comment-distance 10
"*Minimum distance (in lines) between begin and end required before
a comment will be inserted. Setting this variable to zero results in
every end acquiring a comment; the default avoids too many redundant
comments in tight quarters"
:group 'verilog-mode
:type 'integer
)
(setq verilog-error-regexp
'(
("^\\(Error\\|Warning\\):.*\\s \\([^ \t]+\\)\\s *\\([0-9]+\\):" 2 3)
; vcs
("^\\(Error\\|Warning\\):.*\n\\([^ \t]+\\)\\s *\\([0-9]+\\):" 2 3) ;
vcs, with a newline
("^\\(Error\\|Warning\\):[^(]*(\\([^ \t]+\\)\\s line \\([0-9]+\\))" 2 3)
; vcs, with a newline
("^Warning:.*(port.*(\\([^ \t]+\\) line \\([0-9]+\\))" 1 2) ; vcs,
with a newline
("^syntax error:.*\n\\([^ \t]+\\)\\s *\\([0-9]+\\):" 1 2) ; vcs, with
a newline
("^([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+\\([0-9]+\\):.*$" 1 2) ;
vxl
("^([WE][0-9A-Z]+)[ \t]+\\([^ \t\n,]+\\)[, \t]+line[ \t]+\\([0-9]+\\):.*$" 1
2) ; vxl
)
; "*List of regexps for verilog compilers, like verilint. See
compilation-error-regexp-alist for the formatting."
)
(defcustom verilog-library-directories '(".")
"*List of directories when looking for files for /*AUTOINST*/
auto-instantiation. The directory may be relative to the current
file, or absolute. Having at least the current directory is a good
idea.
You might want these defined in each file; put at the *END* of your file
something like:
// Local Variables:
// verilog-library-directories:(\".\" \"subdir\"
\"subdir2\")
// End:
Note these are only read when the file is first visited, you must use
\\[find-alternate-file] RET to have these take effect after editing them!
"
:group 'verilog-mode
:type '(repeat directory)
)
(defcustom verilog-auto-sense-include-inputs nil
"*If true, AUTOSENSE should include in the sensitivity list
input signals that are also output signals in the same block."
:type 'boolean
:group 'verilog-mode)
(defcustom verilog-mode-hook nil
"*Hook (List of functions) run after verilog mode is loaded."
:type 'hook
:group 'verilog-mode)
(defcustom verilog-before-auto-hook nil
"*Hook run before verilog-mode updates AUTOs."
:type 'hook
:group 'verilog-mode)
(defcustom verilog-auto-hook nil
"*Hook run after verilog-mode updates AUTOs."
:type 'hook
:group 'verilog-mode)
(defvar verilog-auto-lineup '(all)
"*List of contexts where auto lineup of :'s or ='s should be done.
Elements can be of type: 'declaration' or 'case', which will do auto
lineup in declarations or case-statements respectively. The word 'all'
will do all lineups. '(case declaration) for instance will do lineup
in case-statements and parameter list, while '(all) will do all
lineups."
)
(defvar verilog-mode-abbrev-table nil
"Abbrev table in use in Verilog-mode buffers.")
(defvar verilog-font-lock-keywords-after-1930
'(
("^\\s-*function\\>\\s-+\\(\\(\\[[^]]*\\]\\|real\\|realtime\\|integer\\|time\\)\\s-+\\)?\\(\\sw+\\)"
3 'font-lock-function-name-face nil t)
("^\\s-*\\(task\\|module\\|macromodule\\|primitive\\)\\>\\s-*\\(\\sw+\\)"
2 'font-lock-function-name-face nil t)
("\\(\\\\\\S-*\\s-\\)\\|\\(`\\s-*[A-Za-z][A-Za-z0-9_]*\\)" 0
'font-lock-function-name-face)
("\\(@\\)\\|\\(#\\s-*\\(\\(\[0-9_\]+\\('[hdxbo][0-9_xz]*\\)?\\)\\|\\((\[^)\]*)\\|\\sw+\\)\\)\\)"
0 'font-lock-type-face)
; "integer" "event" "input" "inout"
"parameter" "defparam" "output" "supply0"
"supply1" "supply" "tri0" "tri1"
"trireg"
; "triand" trior" "wire" "wor" "wand"
"time" "real" "realtime" "reg" "signed"
"vectored"
("\\<\\(defparam\\|event\\|in\\(out\\|put\\|teger\\)\\|output\\|parameter\\|re\\(al\\(\\|time\\)\\|g\\)\\|s\\(igned\\|upply\\(\\|[01]\\)\\)\\|t\\(ime\\|ri\\([01]\\|and\\|or\\|reg\\)\\)\\|vectored\\|w\\(and\\|ire\\|or\\)\\)\\>"
0 'font-lock-type-face)
; "assign" "force" "always" "initial"
"begin" "end" "case" "casex" "casez"
"default" "endcase"
; "if" "wait" "else" "fork" "join"
"for" "while" "repeat" "forever"
"posedge" "negedge"
; "primitive" "endprimitive" "specify"
"endspecify" "table" "endtable"
; "function" "endfunction" "task" "endtask"
"module" "macromodule""endmodule"
("\\<\\(\\$[a-zA-Z][a-zA-Z0-9_\\$]*\\|\\(a\\(lways\\|ssign\\)\\|begin\\|case\\(\\|[xz]\\)\\|\\(de\\(fault\\|assign\\)\\)\\|e\\(lse\\|nd\\(\\|case\\|function\\|module\\|primitive\\|specify\\|ta\\(ble\\|sk\\)\\)\\)\\|f\\(or\\(\\|ce\\|ever\\|k\\)\\|unction\\)\\|i\\(f\\|nitial\\)\\|join\\|m\\(acromodule\\|odule\\)\\|negedge\\|p\\(osedge\\|rimitive\\)\\|re\\(peat\\|lease\\)\\|specify\\|ta\\(ble\\|sk\\)\\|w\\(ait\\|hile\\)\\)\\)\\>"
0 'font-lock-keyword-face)
)
)
(defvar verilog-font-lock-keywords-before-1930
'(
("^\\s-*function\\>\\s-+\\(\\(\\[[^]]*\\]\\|real\\|realtime\\|integer\\|time\\)\\s-+\\)?\\(\\sw+\\)"
3 font-lock-function-name-face)
("^\\s-*\\(task\\|module\\|macromodule\\|primitive\\)\\>\\s-*\\(\\sw+\\)"
2 font-lock-function-name-face nil t)
("\\(\\\\\\S-*\\s-\\)\\|\\(`\\s-*[A-Za-z][A-Za-z0-9_]*\\)" 0
font-lock-function-name-face)
("\\(@\\)\\|\\(#\\s-*\\(\\(\[0-9_\]+\\('[hdxbo][0-9_xz]*\\)?\\)\\|\\((\[^)\]*)\\|\\sw+\\)\\)\\)"
0 font-lock-type-face)
; "integer" "event" "input" "inout"
"parameter" "defparam" "output" "supply0"
"supply1" "supply" "tri0" "tri1"
"trireg"
; "triand" trior" "wire" "wor" "wand"
"time" "real" "realtime" "reg" "signed"
"vectored"
("\\<\\(defparam\\|event\\|in\\(out\\|put\\|teger\\)\\|output\\|parameter\\|re\\(al\\(\\|time\\)\\|g\\)\\|s\\(igned\\|upply\\(\\|[01]\\)\\)\\|t\\(ime\\|ri\\([01]\\|and\\|or\\|reg\\)\\)\\|vectored\\|w\\(and\\|ire\\|or\\)\\)\\>"
0 font-lock-type-face)
; "assign" "force" "always" "initial"
"begin" "end" "case" "casex" "casez"
"default" "endcase"
; "if" "wait" "else" "fork" "join"
"for" "while" "repeat" "forever"
"posedge" "negedge"
; "primitive" "endprimitive" "specify"
"endspecify" "table" "endtable"
; "function" "endfunction" "task" "endtask"
"module" "macromodule""endmodule"
("\\<\\(\\$[a-zA-Z][a-zA-Z0-9_\\$]*\\|\\(a\\(lways\\|ssign\\)\\|begin\\|case\\(\\|[xz]\\)\\|\\(de\\(fault\\|assign\\)\\)\\|e\\(lse\\|nd\\(\\|case\\|function\\|module\\|primitive\\|specify\\|ta\\(ble\\|sk\\)\\)\\)\\|f\\(or\\(\\|ce\\|ever\\|k\\)\\|unction\\)\\|i\\(f\\|nitial\\)\\|join\\|m\\(acromodule\\|odule\\)\\|negedge\\|p\\(osedge\\|rimitive\\)\\|re\\(peat\\|lease\\)\\|specify\\|ta\\(ble\\|sk\\)\\|w\\(ait\\|hile\\)\\)\\)\\>"
0 font-lock-keyword-face)
)
)
(defvar verilog-imenu-generic-expression
'((nil
"^\\s-*\\(\\(m\\(odule\\|acromodule\\)\\)\\|primitive\\)\\s-+\\([a-zA-Z0-9_.:]+\\)"
3)
("*Vars*"
"^\\s-*\\(reg\\|wire\\)\\)\\s-+\\(\\|\\[[^\\]+]\\s-+\\)\\([-A-Za-z0-9+]+\\)"
3))
"Imenu expression for Verilog-mode. See `imenu-generic-expression'.")
(defvar verilog-mode-abbrev-table nil
"Abbrev table in use in Verilog-mode buffers.")
;;;
;;; provide a verilog-header function.
;;; Customization variables:
;;;
(defvar verilog-date-scientific-format nil
"*If non-nil, dates are written in scientific format (e.g. 1997/09/17),
in european format otherwise (e.g. 17.09.1997). The braindead american
format (e.g. 09/17/1997) is not supported.")
(defvar verilog-company nil "Default name of Company for verilog
header. If set will become buffer local. ")
(defvar verilog-project nil "Default name of Project for verilog
header. If set will become buffer local.")
(define-abbrev-table 'verilog-mode-abbrev-table ())
(defvar verilog-mode-map ()
"Keymap used in Verilog mode.")
(if verilog-mode-map
()
(setq verilog-mode-map (make-sparse-keymap))
(define-key verilog-mode-map ";" 'electric-verilog-semi)
(define-key verilog-mode-map [(control 59)] 'electric-verilog-semi-with-comment)
(define-key verilog-mode-map ":" 'electric-verilog-colon)
(define-key verilog-mode-map "=" 'electric-verilog-equal)
(define-key verilog-mode-map "\`" 'electric-verilog-tick)
(define-key verilog-mode-map "\t" 'electric-verilog-tab)
(define-key verilog-mode-map "\r" 'electric-verilog-terminate-line)
(define-key verilog-mode-map "\177" 'backward-delete-char-untabify)
(define-key verilog-mode-map "\M-\C-b" 'electric-verilog-backward-sexp)
(define-key verilog-mode-map "\M-\C-f" 'electric-verilog-forward-sexp)
(define-key verilog-mode-map "\M-\r" (function (lambda ()
(interactive) (electric-verilog-terminate-line 1))))
(define-key verilog-mode-map "\M-\t" 'verilog-complete-word)
(define-key verilog-mode-map "\M-?" 'verilog-show-completions)
(define-key verilog-mode-map "\M-\C-h" 'verilog-mark-defun)
(define-key verilog-mode-map "\C-c`" 'verilog-verilint-off)
(define-key verilog-mode-map "\C-c\C-r" 'verilog-label-be)
(define-key verilog-mode-map "\C-c\C-i" 'verilog-pretty-declarations)
(define-key verilog-mode-map "\C-c\C-b" 'verilog-submit-bug-report)
(define-key verilog-mode-map "\M-*" 'verilog-star-comment)
(define-key verilog-mode-map "\C-c\C-c" 'verilog-comment-region)
(define-key verilog-mode-map "\C-c\C-u" 'verilog-uncomment-region)
(define-key verilog-mode-map "\M-\C-a" 'verilog-beg-of-defun)
(define-key verilog-mode-map "\M-\C-e" 'verilog-end-of-defun)
(define-key verilog-mode-map "\C-c\C-d" 'verilog-goto-defun)
(define-key verilog-mode-map "\C-c\C-k" 'verilog-delete-auto)
(define-key verilog-mode-map "\C-c\C-a" 'verilog-auto)
(define-key verilog-mode-map "\C-c\C-s" 'verilog-auto-save-compile)
(define-key verilog-mode-map "\C-c\C-e" 'verilog-expand-vector)
(define-key verilog-mode-map "\C-c\C-h" 'verilog-header)
)
;; menus
(defvar verilog-xemacs-menu
'("Verilog"
["Line up declarations around point" verilog-pretty-declarations t]
["Redo/insert comments on every end" verilog-label-be t]
"----"
["Beginning of function" verilog-beg-of-defun t]
["End of function" verilog-end-of-defun t]
["Mark function" verilog-mark-defun t]
["Goto function" verilog-goto-defun t]
"----"
["Move to beginning of block" electric-verilog-backward-sexp t]
["Move to end of block" electric-verilog-forward-sexp t]
"----"
["Comment Region" verilog-comment-region t]
["UnComment Region" verilog-uncomment-region t]
["Multi-line comment insert" verilog-star-comment t]
["Verilint error to comment" verilog-verilint-off t]
["Expand [x:y] vector line" verilog-expand-vector t]
"----"
["Insert begin-end block" verilog-insert-block t]
["Complete word" verilog-complete-word t]
"----"
["Recompute AUTOs" verilog-auto t]
["Kill AUTOs" verilog-delete-auto t]
["AUTO, Save, Compile" verilog-auto-save-compile t]
["Compile" verilog-compile t]
["Next Compile Error" next-error t]
"----"
("Help..."
["AUTO General" (describe-function 'verilog-auto) t]
["AUTO `define Reading" (describe-function 'verilog-read-defines) t]
["AUTO Library Path" (describe-variable 'verilog-library-directories)
t]
["AUTOARG" (describe-function 'verilog-auto-arg) t]
["AUTOINST" (describe-function 'verilog-auto-inst) t]
["AUTOINOUTMODULE" (describe-function 'verilog-auto-inout-module) t]
["AUTOINPUT" (describe-function 'verilog-auto-input) t]
["AUTOOUTPUT" (describe-function 'verilog-auto-output) t]
["AUTOOUTPUTEVERY" (describe-function 'verilog-auto-output-every) t]
["AUTOWIRE" (describe-function 'verilog-auto-wire) t]
["AUTOREG" (describe-function 'verilog-auto-reg) t]
["AUTOSENSE" (describe-function 'verilog-auto-sense) t]
)
["Submit bug report" verilog-submit-bug-report t]
["Customize Verilog Mode..." verilog-customize t]
["Customize Verilog Fonts & Colors" verilog-font-customize t]
)
"Emacs menu for VERILOG mode."
)
(or (string-match "XEmacs" emacs-version)
(easy-menu-define verilog-menu verilog-mode-map "Menu for Verilog mode"
verilog-xemacs-menu))
(defvar verilog-mode-abbrev-table nil
"Abbrev table in use in Verilog-mode buffers.")
(define-abbrev-table 'verilog-mode-abbrev-table ())
;; compilation program
(defun verilog-compile ()
"function to compile verilog"
(or (file-exists-p "makefile") (file-exists-p "Makefile")
(progn (make-local-variable 'compile-command)
(setq compile-command
(concat verilog-compiler
(or buffer-file-name ""))))))
(add-hook 'verilog-mode-hook 'verilog-compile)
(defvar verilog-error-regexp-add-didit nil)
(setq verilog-error-regexp-add-didit nil) ;; So reloading file does it again
(defun verilog-error-regexp-add ()
"Called by compilation-mode-hook to add the Verilint, VCS, etc messages to the
compilation-error-regexp-alist. This allows \\[next-error] to find the errors."
(cond (verilog-error-regexp-add-didit)
(t (setq verilog-error-regexp-add-didit t)
;; Probably buffer local at this point; maybe also in let; change all three
(set (make-local-variable 'compilation-error-regexp-alist)
(append compilation-error-regexp-alist verilog-error-regexp))
(setq compilation-error-regexp-alist
(append compilation-error-regexp-alist verilog-error-regexp))
(setq-default compilation-error-regexp-alist
(append (default-value 'compilation-error-regexp-alist) verilog-error-regexp)))))
(add-hook 'compilation-mode-hook 'verilog-error-regexp-add)
;;;
;;; Regular expressions used to calculate indent, etc.
;;;
(defconst verilog-symbol-re "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>")
(defconst verilog-case-re "\\(\\<case[xz]?\\>\\)")
;; Want to match
;; aa :
;; aa,bb :
;; a[34:32] :
;; a,
;; b :
(defconst
verilog-no-indent-begin-re
"\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\)\\>")
(defconst verilog-ends-re
(concat
"\\(\\<else\\>\\)\\|"
"\\(\\<if\\>\\)\\|"
"\\(\\<end\\>\\)\\|"
"\\(\\<join\\>\\)\\|"
"\\(\\<endcase\\>\\)\\|"
"\\(\\<endtable\\>\\)\\|"
"\\(\\<endspecify\\>\\)\\|"
"\\(\\<endfunction\\>\\)\\|"
"\\(\\<endtask\\>\\)"))
(defconst verilog-enders-re
(concat "\\(\\<endcase\\>\\)\\|"
"\\(\\<end\\>\\)\\|"
"\\(\\<end\\(\\(function\\)\\|\\(task\\)\\|"
"\\(module\\)\\|\\(primitive\\)\\)\\>\\)"))
(defconst verilog-endcomment-reason-re
(concat
"\\(\\<fork\\>\\)\\|"
"\\(\\<begin\\>\\)\\|"
"\\(\\<if\\>\\)\\|"
"\\(\\<else\\>\\)\\|"
"\\(\\<end\\>.*\\<else\\>\\)\\|"
"\\(\\<task\\>\\)\\|"
"\\(\\<function\\>\\)\\|"
"\\(\\<initial\\>\\)\\|"
"\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
"\\(\\<while\\>\\)\\|"
"\\(\\<for\\(ever\\)?\\>\\)\\|"
"\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|"
"#"))
(defconst verilog-named-block-re "begin[ \t]*:")
(defconst verilog-beg-block-re
;; "begin" "case" "casex" "fork"
"casez" "table" "specify" "function"
"task"
"\\(\\<\\(begin\\>\\|case\\(\\>\\|x\\>\\|z\\>\\)\\|f\\(ork\\>\\|unction\\>\\)\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\)")
(defconst verilog-beg-block-re-1
"\\<\\(begin\\)\\|\\(case[xz]?\\)\\|\\(fork\\)\\|\\(table\\)\\|\\(specify\\)\\|\\(function\\)\\|\\(task\\)\\>")
(defconst verilog-end-block-re
;; "end" "join" "endcase" "endtable"
"endspecify" "endtask" "endfunction"
"\\<\\(end\\(\\>\\|case\\>\\|function\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\|join\\>\\)")
(defconst verilog-end-block-re-1
"\\(\\<end\\>\\)\\|\\(\\<endcase\\>\\)\\|\\(\\<join\\>\\)\\|\\(\\<endtable\\>\\)\\|\\(\\<endspecify\\>\\)\\|\\(\\<endfunction\\>\\)\\|\\(\\<endtask\\>\\)")
(defconst verilog-declaration-re
;; "input" "inout" "output" "integer"
"parameter" "defparam" "event"
;; "real" "reg" "realtime" "time"
"tri" "tri0" "tri1" "trireg" "triand"
;; "trior" "supply0" "supply1" "wire"
"wor" "wand"
"\\(\\<\\(assign\\>\\|defparam\\>\\|event\\>\\|in\\(out\\>\\|put\\>\\|teger\\>\\)\\|output\\>\\|parameter\\>\\|re\\(al\\(\\>\\|time\\>\\)\\|g\\>\\)\\|supply\\(0\\>\\|1\\>\\)\\|t\\(ime\\>\\|ri\\(0\\>\\|1\\>\\|\\>\\|and\\>\\|or\\>\\|reg\\>\\)\\)\\|w\\(and\\>\\|ire\\>\\|or\\>\\)\\)\\)")
(defconst verilog-range-re "\\[[^]]*\\]")
(defconst verilog-macroexp-re "`\\sw+")
(defconst verilog-delay-re
"#\\s-*\\(\\([0-9_]+\\('[hdxbo][0-9_xz]+\\)?\\)\\|\\(([^)]*)\\)\\|\\(\\sw+\\)\\)")
(defconst verilog-declaration-re-2
(concat "\\s-*" verilog-declaration-re
"\\s-*\\(\\(" verilog-range-re "\\)\\|\\(" verilog-delay-re
"\\)\\|\\(" verilog-macroexp-re "\\)\\)?"))
(defconst verilog-declaration-re-1 (concat "^" verilog-declaration-re-2))
(defconst verilog-defun-re
;;"module" "macromodule" "primitive"
"\\(\\<\\(m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\)\\)")
(defconst verilog-end-defun-re
;; "endmodule" "endprimitive"
"\\(\\<end\\(module\\>\\|primitive\\>\\)\\)")
(defconst verilog-zero-indent-re
(concat verilog-defun-re "\\|" verilog-end-defun-re))
(defconst verilog-directive-re
;; "`else" "`ifdef" "`endif" "`define"
"`undef" "`include" "`timescale" "`protect"
"`endprotect
"`\\(define\\>\\|e\\(lse\\>\\|nd\\(if\\|protect\\)\\>\\)\\|i\\(fdef\\>\\|nclude\\>\\)\\|protect\\|undef\\>\\|time_?scale\\)")
(defconst verilog-directive-re-1
;; "`else" "`ifdef" "`endif" "`define"
"`undef" "`include"
(concat "[ \t]*" verilog-directive-re))
(defconst verilog-autoindent-lines-re
;; "macromodule" "module" "primitive" "end"
"endcase" "endfunction"
;; "endtask" "endmodule" "endprimitive"
"endspecify" "endtable" "join"
;; "begin" "else" "`else" "`ifdef"
"`endif" "`define" "`undef" "`include"
(concat "\\("
verilog-directive-re
"\\|\\(\\<begin\\>\\|e\\(lse\\>\\|nd\\(\\>\\|case\\>\\|function\\>\\|module\\>\\|primitive\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\)\\|join\\>\\|m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\)\\)"
)
)
(defconst verilog-behavioral-block-beg-re
"\\(\\<initial\\>\\|\\<always\\>\\|\\<function\\>\\|\\<task\\>\\)")
(defconst verilog-indent-reg
(concat
"\\(\\<begin\\>\\|\\<case[xz]?\\>\\|\\<specify\\>\\|\\<fork\\>\\|\\<table\\>\\)\\|"
"\\(\\<end\\>\\|\\<join\\>\\|\\<endcase\\>\\|\\<endtable\\>\\|\\<endspecify\\>\\)\\|"
"\\(\\<module\\>\\|\\<macromodule\\>\\|\\<primitive\\>\\|\\<initial\\>\\|\\<always\\>\\)\\|"
"\\(\\<endmodule\\>\\|\\<endprimitive\\>\\)\\|"
"\\(\\<endtask\\>\\|\\<endfunction\\>\\)\\|"
"\\(\\<function\\>\\|\\<task\\>\\)"
;; "\\|\\(\\<if\\>\\|\\<else\\>\\)"
))
(defconst verilog-indent-re
"\\(\\<\\(always\\>\\|begin\\>\\|case\\(\\>\\|x\\>\\|z\\>\\)\\|end\\(\\>\\|case\\>\\|function\\>\\|module\\>\\|primitive\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\|f\\(ork\\>\\|unction\\>\\)\\|initial\\>\\|join\\>\\|m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\|specify\\>\\|ta\\(ble\\>\\|sk\\>\\)\\)\\)")
(defconst verilog-defun-level-re
;; "module" "macromodule" "primitive" "initial"
"always" "endtask" "endfunction"
"\\(\\<\\(always\\>\\|end\\(function\\>\\|task\\>\\)\\|initial\\>\\|m\\(acromodule\\>\\|odule\\>\\)\\|primitive\\>\\)\\)")
(defconst verilog-cpp-level-re
;;"endmodule" "endprimitive"
"\\(\\<end\\(module\\>\\|primitive\\>\\)\\)")
(defconst verilog-behavioral-level-re
;; "function" "task"
"\\(\\<\\(function\\>\\|task\\>\\)\\)")
(defconst verilog-complete-reg
;; "always" "initial" "repeat" "case"
"casex" "casez" "while" "if" "for"
"forever" "else"
"\\<\\(always\\|case\\(\\|[xz]\\)\\|begin\\|else\\|for\\(\\|ever\\)\\|i\\(f\\|nitial\\)\\|repeat\\|while\\)\\>")
(defconst verilog-end-statement-re
(concat "\\(" verilog-beg-block-re "\\)\\|\\("
verilog-end-block-re "\\)"))
(defconst verilog-endcase-re
(concat verilog-case-re "\\|"
"\\(endcase\\)\\|"
verilog-defun-re
))
;;; Strings used to mark beginning and end of excluded text
(defconst verilog-exclude-str-start "/* -----\\/----- EXCLUDED -----\\/-----")
(defconst verilog-exclude-str-end " -----/\\----- EXCLUDED -----/\\----- */")
(defconst verilog-keywords
'("`define" "`else" "`endif" "`ifdef"
"`include" "`timescale" "`undef"
"always" "and" "assign" "begin" "buf"
"bufif0" "bufif1" "case" "casex"
"casez" "cmos" "default" "defparam"
"else" "end" "endcase" "endfunction"
"endmodule" "endprimitive" "endspecify"
"endtable" "endtask" "event" "for"
"force" "forever" "fork" "function"
"if" "initial" "inout" "input"
"integer" "join" "macromodule" "makefile"
"module" "nand" "negedge" "nmos"
"nor" "not" "notif0" "notif1" "or"
"output" "parameter" "pmos" "posedge"
"primitive" "pulldown" "pullup" "rcmos"
"real" "realtime" "reg" "repeat"
"rnmos" "rpmos" "rtran" "rtranif0"
"rtranif1" "signed" "specify" "supply"
"supply0" "supply1" "table" "task"
"time" "tran" "tranif0" "tranif1" "tri"
"tri0" "tri1" "triand" "trior"
"trireg" "vectored" "wait" "wand"
"while"
"wire" "wor" "xnor" "xor" )
"List of Verilog keywords.")
(defconst verilog-keywords-regexp
(concat "\\<\\(" (mapconcat 'format verilog-keywords "\\|")
"\\)\\>")
"Regexp that matches Verilog keywords.")
(defconst verilog-emacs-features
(let ((major (and (boundp 'emacs-major-version)
emacs-major-version))
(minor (and (boundp 'emacs-minor-version)
emacs-minor-version))
flavor comments)
;; figure out version numbers if not already discovered
(and (or (not major) (not minor))
(string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
(setq major (string-to-int (substring emacs-version
(match-beginning 1)
(match-end 1)))
minor (string-to-int (substring emacs-version
(match-beginning 2)
(match-end 2)))))
(if (not (and major minor))
(error "Cannot figure out the major and minor version numbers."))
;; calculate the major version
(cond
((= major 4) (setq major 'v18)) ;Epoch 4
((= major 18) (setq major 'v18)) ;Emacs 18
((= major 19) (setq major 'v19 ;Emacs 19
flavor (if (or (string-match "Lucid" emacs-version)
(string-match "XEmacs" emacs-version))
'XEmacs 'FSF)))
((or (= major 21)(= major 20)) (setq major 'v20
flavor (if (or (string-match "Lucid" emacs-version)
(string-match "XEmacs" emacs-version))
'XEmacs 'FSF)))
;; I don't know
(t (error "Cannot recognize major version number: %s" major)))
;; XEmacs 19 uses 8-bit modify-syntax-entry flags, as do all
;; patched Emacs 19, Emacs 18, Epoch 4's. Only Emacs 19 uses a
;; 1-bit flag. Let's be as smart as we can about figuring this
;; out.
(if (or (eq major 'v21)(eq major 'v20) (eq major 'v19))
(let ((table (copy-syntax-table)))
(modify-syntax-entry ?a ". 12345678" table)
(cond
;; XEmacs pre 20 and Emacs pre 19.30 use vectors for syntax tables.
((vectorp table)
(if (= (logand (lsh (aref table ?a) -16) 255) 255)
(setq comments '8-bit)
(setq comments '1-bit)))
;; XEmacs 20 is known to be 8-bit
((eq flavor 'XEmacs) (setq comments '8-bit))
;; Emacs 19.30 and beyond are known to be 1-bit
((eq flavor 'FSF) (setq comments '1-bit))
;; Don't know what this is
(t (error "Couldn't figure out syntax table format."))
))
;; Emacs 18 has no support for dual comments
(setq comments 'no-dual-comments))
;; lets do some minimal sanity checking.
(if (or
;; Lemacs before 19.6 had bugs
(and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
;; Emacs 19 before 19.21 has known bugs
(and (eq major 'v19) (eq flavor 'FSF) (< minor 21))
)
(with-output-to-temp-buffer "*verilog-mode warnings*"
(print (format
"The version of Emacs that you are running, %s,
has known bugs in its syntax parsing routines which will affect the
performance of verilog-mode. You should strongly consider upgrading to the
latest available version. verilog-mode may continue to work, after a
fashion, but strange indentation errors could be encountered."
emacs-version))))
;; Emacs 18, with no patch is not too good
(if (and (eq major 'v18) (eq comments 'no-dual-comments))
(with-output-to-temp-buffer "*verilog-mode warnings*"
(print (format
"The version of Emacs 18 you are running, %s,
has known deficiencies in its ability to handle the dual verilog
(and C++) comments, (e.g. the // and /* */ comments). This will
not be much of a problem for you if you only use the /* */ comments,
but you really should strongly consider upgrading to one of the latest
Emacs 19's. In Emacs 18, you may also experience performance degradations.
Emacs 19 has some new built-in routines which will speed things up for you.
Because of these inherent problems, verilog-mode is not supported
on emacs-18."
emacs-version))))
;; Emacs 18 with the syntax patches are no longer supported
(if (and (eq major 'v18) (not (eq comments 'no-dual-comments)))
(with-output-to-temp-buffer "*verilog-mode warnings*"
(print (format
"You are running a syntax patched Emacs 18 variant. While this should
work for you, you may want to consider upgrading to Emacs 19.
The syntax patches are no longer supported either for verilog-mode."))))
(list major comments))
"A list of features extant in the Emacs you are using.
There are many flavors of Emacs out there, each with different
features supporting those needed by verilog-mode. Heres the current
supported list, along with the values for this variable:
Vanilla Emacs 18/Epoch 4: (v18 no-dual-comments)
Emacs 18/Epoch 4 (patch2): (v18 8-bit)
XEmacs (formerly Lucid) 19: (v19 8-bit)
XEmacs 20: (v20 8-bit)
Emacs 19,20: (v19 1-bit).")
(defconst verilog-comment-start-regexp "//\\|/\\*"
"Dual comment value for `comment-start-regexp'.")
(defun verilog-populate-syntax-table (table)
;; Populate the syntax TABLE
(modify-syntax-entry ?\\ "\\" table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?- "." table)
(modify-syntax-entry ?= "." table)
(modify-syntax-entry ?% "." table)
(modify-syntax-entry ?< "." table)
(modify-syntax-entry ?> "." table)
(modify-syntax-entry ?& "." table)
(modify-syntax-entry ?| "." table)
(modify-syntax-entry ?` "w" table)
(modify-syntax-entry ?_ "w" table)
(modify-syntax-entry ?\' "." table)
)
(defun verilog-setup-dual-comments (table)
;; Set up TABLE to handle block and line style comments
(cond
((memq '8-bit verilog-emacs-features)
;; XEmacs (formerly Lucid) has the best implementation
(modify-syntax-entry ?/ ". 1456" table)
(modify-syntax-entry ?* ". 23" table)
(modify-syntax-entry ?\n "> b" table)
)
((memq '1-bit verilog-emacs-features)
;; Emacs 19 does things differently, but we can work with it
(modify-syntax-entry ?/ ". 124b" table)
(modify-syntax-entry ?* ". 23" table)
(modify-syntax-entry ?\n "> b" table)
)
))
(defvar verilog-mode-syntax-table nil
"Syntax table used in verilog-mode buffers.")
(defvar verilog-font-lock-keywords nil
"keyword highlighting used in verilog-mode buffers.")
(defvar verilog-font-lock-keywords-1 nil
"keyword highlighting used in verilog-mode buffers.")
(defvar verilog-font-lock-keywords-2 nil
"keyword highlighting used in verilog-mode buffers.")
(defvar verilog-font-lock-keywords-3 nil
"keyword highlighting used in verilog-mode buffers.")
(defvar verilog-font-lock-keywords-4 nil
"keyword highlighting used in verilog-mode buffers.")
(if verilog-font-lock-keywords
()
(cond
;; We can assume 8-bit syntax table emacsen aupport new syntax
((memq '8-bit verilog-emacs-features)
(setq verilog-font-lock-keywords verilog-font-lock-keywords-after-1930
verilog-font-lock-keywords-1 verilog-font-lock-keywords-after-1930
verilog-font-lock-keywords-2 verilog-font-lock-keywords-after-1930
verilog-font-lock-keywords-3 verilog-font-lock-keywords-after-1930
verilog-font-lock-keywords-4 verilog-font-lock-keywords-after-1930)
)
(t
(setq verilog-font-lock-keywords verilog-font-lock-keywords-before-1930
verilog-font-lock-keywords-1 verilog-font-lock-keywords-before-1930
verilog-font-lock-keywords-2 verilog-font-lock-keywords-before-1930
verilog-font-lock-keywords-3 verilog-font-lock-keywords-before-1930
verilog-font-lock-keywords-4 verilog-font-lock-keywords-before-1930)
)
)
)
;;;
;;; Macros
;;;
(defsubst verilog-string-replace-matches (from-string to-string fixedcase literal string)
"Replace occurances of from-string with to-string in the string.
The case (verilog-string-replace-matches \"o\" \"oo\" nil nil
\"foobar\")
will break, as the o's continuously replace. xa -> x works ok though."
;; Hopefully soon to a emacs built-in
(let ((start 0))
(while (string-match from-string string start)
(setq string (replace-match to-string fixedcase literal string)
start (min (length string) (match-end 0))))
string))
(defsubst verilog-string-remove-spaces (string)
"Remove spaces surrounding the string"
(save-match-data
(setq string (verilog-string-replace-matches "^\\s-+" "" nil nil
string))
(setq string (verilog-string-replace-matches "\\s-+$" "" nil nil
string))
string))
(defsubst verilog-re-search-forward (REGEXP BOUND NOERROR)
"Like re-search-forward, but skips over matches in comments or strings"
(store-match-data '(nil nil))
(while (and
(re-search-forward REGEXP BOUND NOERROR)
(and (verilog-skip-forward-comment-or-string)
(progn
(store-match-data '(nil nil))
(if BOUND
(< (point) BOUND)
t)
)
)
)
)
(match-end 0))
(defsubst verilog-re-search-backward (REGEXP BOUND NOERROR)
"Like re-search-backward, but skips over matches in comments or strings"
(store-match-data '(nil nil))
(while (and
(re-search-backward REGEXP BOUND NOERROR)
(and (verilog-skip-backward-comment-or-string)
(progn
(store-match-data '(nil nil))
(if BOUND
(> (point) BOUND)
t)
)
)
)
)
(match-end 0))
(defsubst verilog-re-search-forward-quick (regexp bound noerror)
"Like verilog-re-search-forward, but trashes match data and
is faster for regexps that don't match much.
This may at some point use text properties to ignore comments,
so there may be a large up front penalty for the first search."
(let (pt)
(while (and (not pt)
(re-search-forward regexp bound noerror))
(if (not (verilog-inside-comment-p))
(setq pt (match-end 0))))
pt))
(defsubst verilog-re-search-backward-quick (regexp bound noerror)
"Like verilog-re-search-forward, but trashes match data and
is faster for regexps that don't match much.
This may at some point use text properties to ignore comments,
so there may be a large up front penalty for the first search."
(let (pt)
(while (and (not pt)
(re-search-backward regexp bound noerror))
(if (not (verilog-inside-comment-p))
(setq pt (match-end 0))))
pt))
(defsubst verilog-get-beg-of-line (&optional arg)
(save-excursion
(beginning-of-line arg)
(point)))
(defsubst verilog-get-end-of-line (&optional arg)
(save-excursion
(end-of-line arg)
(point)))
(defun verilog-inside-comment-p ()
"Check if point inside a nested comment."
(save-excursion
(let ((st-point (point)) hitbeg)
(or (search-backward "//" (verilog-get-beg-of-line) t)
(if (progn
;; This is for tricky case //*, we keep searching if /* is proceeded by // on same line
(while (and (setq hitbeg (search-backward "/*" nil t))
(progn (forward-char 1) (search-backward "//" (verilog-get-beg-of-line)
t))))
hitbeg)
(not (search-forward "*/" st-point t)))))))
(defun verilog-declaration-end ()
(search-forward ";"))
(defun electric-verilog-backward-sexp ()
"Move backward over a sexp"
(interactive)
;; before that see if we are in a comment
(verilog-backward-sexp)
)
(defun electric-verilog-forward-sexp ()
"Move backward over a sexp"
(interactive)
;; before that see if we are in a comment
(verilog-forward-sexp)
)
(defun verilog-backward-sexp ()
(let ((reg)
(elsec 1)