;;; vlog-mode.el --- Verilog editing commands for Emacs ; ; $Source: /home/mmabry/lisp/vlog-mode.el,v $ ; $Id: vlog-mode.el,v 1.15 1998/12/08 14:07:00 mmabry Exp mmabry $ ; ; $Log: vlog-mode.el,v $ ; Revision 1.15 1998/12/08 14:07:00 mmabry ; New indent function that works like indenting in cc-mode. Bug fixes ; in some of the module instantiation functions. Abbrev mode fixes. ; Auto-fill-mode is not turned on by vlog-mode. ; ; Revision 1.14 1998/05/15 14:29:36 mmabry ; emacs 20 font-lock fixes and a couple of minor bug fixes ; ; Revision 1.13 1998/04/17 20:55:13 mmabry ; bug fixes, clean-up, set C-c C-f to vlog-find-file ; ; Revision 1.12 1998/03/10 19:12:46 mmabry ; free variable in byte-compile ; ; Revision 1.11 1998/03/10 19:10:06 mmabry ; Bug fixes in port and instance insertion. ; Added vars to reduce instance name length. ; Added vlog-indent-line-better-2 but did not enable it since it's not ; very useful. Limited functionality. ; ; Revision 1.10 1998/02/04 16:10:55 mmabry ; heavily cleaned comments. Added stutter-period. Changed tabbing ; somewhat. ; ; Revision 1.9 1997/12/11 19:46:59 mmabry ; fixed the prefix arg for module instantiation ; ; Revision 1.8 1997/12/11 15:05:12 mmabry ; why did I comment out the loading of verilog-font-lock.el? ; ; Revision 1.7 1997/12/10 19:37:39 mmabry ; changed tabbing functionality to align line when within code. ; Some templates had a trailing space after word 'begin', which I ; removed ; ; Revision 1.6 1997/10/27 14:28:48 mmabry ; found tab bug in vlog-insert-port-connections ; ; Revision 1.5 1997/10/16 17:04:46 mmabry ; added loading of verilog-font-lock mode and bumped revision to 1.4 due ; to all the changes made. ; ; Revision 1.4 1997/10/16 16:22:04 mmabry ; cleaned up for byte compiling ; ; Revision 1.3 1997/10/15 18:56:55 mmabry ; auto-fill-mode and abbrev-mode added as defaults ; ; Revision 1.2 1997/10/14 18:43:16 mmabry ; incorporated lots of defaults into vlog-mode so that the average user ; does not require any vlog-mode-hooks just to get functionality. ; ; Revision 1.1 1997/10/03 21:04:33 mmabry ; Initial revision ; ; ;;----------------------------------------------------------------- ;; ;; Copyright (C) 1998 by Mark Mabry ;; Author: ;; Version 1.5 (Also under variable `vlog-mode-version') ;; Keywords: Verilog hdl programming ;; GNU Emacs 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, 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 GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ;;;;; Commentary: ;; Major mode for editing the Verilog hardware description language. ;; Called vlog-mode to easily allow user to try other verilog-mode modes. ;; Versions upto 1.3 are from Phil Welling ;; Based on shell-script.el and statement.el created by ;; Daniel Pfeiffer . ;; Features were added to statement.el for more flexibility in ;; making skeletons. ;; Also uses abbrev-hooked mode ideas from Todd Carpenter's vhdl-mode ;; as implemented by Richard Eversole ;; in his Verilog HDL mode. ;; Version 1.2 Improvements: ;; + vlog-insert-port-connections now correctly fills the port connection ;; region and indents multi-line ports to column of first port ;; + Modified vlog-for-var-begin and vlog-for-i-begin skeletons so that ;; they now have defaults. ;; + Changed specparam and parameter abbrevs so that additional `m' and `r', ;; respectively, is needed. ;; + Added Verilog syntax documentation to skeletons so that ;; M-x describe-function RET vlog- RET will be more useful. ;; Version 1.2a Improvements ;; + Made small fixes to work with Version 19. ;; Version 1.3 Improvements ;; + Added "forj" abbrev for `vlog-for-j-begin' since the letter "j" only ;; appears as the loop variable (whereas "i" is in begIn) to allow ;; for entire line substitution ;; + New indent mechanism `vlog-indent-line-better' ;; If text precedes cursor on that line, insert TAB; ;; Else if looking at SPC or TAB, move cursor to current indentation; ;; Else indent as far as preceding line, then by `mode-indent-level' ;; + Old indent mechanism `vlog-indent-line' is bound to ;; C-c C-i (same as C-c TAB) ;; Its operation is ;; Indent as far as preceding line, then by `mode-level-indent' ;; + "assign" abbrev for `vlog-assign' changed to "assignn" ;; Version 1.4 Improvements ;; + Fixed some vlog-in-comments bugs ;; + Added "_" as word syntax in syntax table ;; + cleaned up byte compilation ;; + New indent mechanism `vlog-indent-line-better' ;; If text precedes cursor on that line, align line with previous line ;; Else if looking at SPC or TAB, move cursor to current indentation; ;; Else indent as far as preceding line, then by `mode-indent-level'. ;; Use M-i, `tab-to-tab-stop' to insert at tab within a line. ;; + Changed `vlog-insert-port-connections' functionality so that put one ;; port per line. It works well if the input/output declarations are ;; one per line also, but often works with multiple declarations per ;; line. ;; + Created `vlog-stutter-comma' which inserts ` <= ' when two commas are ;; typed. Idea came from Todd Carpenter's vhdl mode. ;; + Created `vlog-stutter-period' which inserts a blocking assignment ` = ' ;; when 2 periods are typed. ;; + Created `vlog-update-module-ports' which updates the module port list ;; from the i/o declarations. Uses a new function, ;; `vlog-delete-module-ports'. ;; + Created `vlog-insert-module-instance' which will instantiate a module at ;; point. It asks for the file name of the module to instantiate. If ;; there are multiple modules per file, the first one is always chosen. ;; With an arg, it will put down all the wire declarations needed by ;; this block. ;; + Added two new templates: `vlog-std-reg' and `vlog-enable-reg' which ;; are templates for a behavioral flip-flop and enabled flop. ;; ;; Version 1.5 Improvements ;; + Created a new tabbing function `vlog-indent-line-better-2', which should ;; always format the line correctly. This is a major change in tabbing ;; functionality. The function parses the Verilog code and determines the ;; correct indentation based on the preceding lines of code. Solid basic ;; functionality is there. Needs more testing from others. ;; + Updated the font-lock keywords for changes in Emacs version 20. ;; + Added a new font-lock match of "FIXME" and words inside `' to be fontified ;; with warning face. ;; + Bug fixes in `abbrev-mode-hook' and `vlog-insert-module-instance'. ;; Enjoy! ;;;;; Support: ;; I am basically issuing this as is. ;; I am slowing adding more high-level functionality to it, and solidifying ;; newer functions. ;; Please send me any errors/improvements since I would like ;; to correct/add them if feasible. ;;;;; Installation: ;; Three files are needed: ;; 1. vlog-mode.el ;; 2. statement.el File with statement-skeleton functions ;; 3. paired-insert.el File for bracket matching (not as important) ;; 4. verilog-font-lock.el Font Lock mode ;; Place them in one of the directories of your load-path if you can. ;; If you don't know your load path, type the following in emacs: ;; M-x describe-variable RET load-path RET ;; If these are unwriteable by you, create a directory for them (ie ~/.lisp) ;; and add the following to your ~/.emacs file: ;; (setq load-path (cons "/home/user/.lisp" load-path)) ;; ;; I would recommend byte compiling those 3 files so that they will be ;; faster. Try ;; M-x byte-compile-file RET vlog-mode.el RET ;; etc. in emacs. ;; Ignore warnings about auto-fill-hook or auto-fill-function. They are ;; version specific. ;; Also, add the following to your ~/.emacs file: ;; ;; ;; Vlog-mode customization ;; (autoload 'vlog-mode "vlog-mode" "Verilog Editing Mode" t) ;; (autoload 'define-statement-skeleton "statement" "\ ;; Command for defining a statement-skeleton." nil 'macro) ;; (autoload 'insert-statement-skeleton "statement" "\ ;; Command for inserting a statement-skeleton." nil nil) ;; (autoload 'self-insert-maybe-paired "paired-insert" nil t nil) ;; (autoload 'mirror-mode "paired-insert" nil t nil) ;; ;; (setq auto-mode-alist (cons '("\\.v$" . vlog-mode) auto-mode-alist)) ;; ;; (add-hook 'vlog-mode-hook ;; '(lambda () ;; (progn ;; (auto-fill-mode 1) ; Enable auto-fill-mode ;; (abbrev-mode 1) ; Enable abbrev-mode ;; ;; ;; That's it. ;; ;; Customization examples. Add these to vlog-mode-hook ;; ;; ;; Set number of spaces for indent ;; (setq mode-indent-level 3) ;; ;; ; Enable matched parens ;; (setq self-insert-normally nil) ;; ;; ;; Uncomment following line for previous indent behavior ;; ;(setq indent-line-function 'vlog-indent-line) ;; ;; ;; ;;;; Examples of adjusting configuration ;; ;; Example of new skeleton ;; (vlog-defun vlog-try-this "a new skeleton" ;; (nil "what to try: " "This is new: " str)) ;; ;; Example of redefining a skeleton ;; (put 'vlog-for nil '("upper limit: " ;; "better for \(i=0;i<" str ";i=i+1\)" \n)) ;;;;; Usage: ;; The vlog-mode-hook shown above is the default I normally used. ;; Abbrev mode enabled will probably be the fastest way to insert code. ;; As expected, you are free to change any of the key bindings and ;; abbrevs that you like. ;; ;; For most, you type the Verilog construct and it will expand. ;; For net data types, reg data types, and primitive gates, type the ;; last char twice (ie 'andd' expands to 'and '). ;; This choice allows the user to insert a simple 'and' faster. ;; ;; To list the abbrevs, ;; M-x list-abbrevs RET ;; One way of having different abbrev bindings would be to start a ;; session in vlog-mode, ;; M-x write-abbrev-file RET ~/.abbrev_defs RET ;; Then, edit ~/.abbrev_defs to suit your needs. ;; This program will only create a vlog-mode-abbrev-table if not ;; already specified. ;;; Code: ;; page 1: variables and settings ;; page 2: mode-command and utility functions ;; page 3: statement syntax-commands for various shells ;; page 4: various other commands ;;;###autoload ;(setq auto-mode-alist ;;; - that have a suffix .v ; (cons '("\\.v$" . vlog-mode) ; auto-mode-alist)) (defvar vlog-mode-version "1.5" "Version number for vlog-mode") ;; Font Lock variables (load "verilog-font-lock") ;; Syntax table (defvar vlog-mode-syntax-table (let ((table (copy-syntax-table (standard-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) ; set Underscore to word class (modify-syntax-entry ?_ "w" table) (modify-syntax-entry ?\' "." table) ;;;; For Emacs 19 ;; For dual comments (block and line style) (modify-syntax-entry ?/ ". 124b" table) (modify-syntax-entry ?* ". 23" table) (modify-syntax-entry ?\n "> b" table) ;; Give CR the same syntax as newline, for selective-display (modify-syntax-entry ?\^m "> b" table) ;;;; For XEmacs ;(modify-syntax-entry ?/ ". 1456" table) ;(modify-syntax-entry ?* ". 23" table) ;(modify-syntax-entry ?\n "> b" table) ;; Give CR the same syntax as newline, for selective-display ;(modify-syntax-entry ?\^m "> b" table) table) "Syntax table in use in vlog-mode.") (defvar vlog-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-ca" 'vlog-assign) (define-key map "\C-cb" 'vlog-begin-end-groupname) (define-key map "\C-cc" 'comment-region) (define-key map "\C-ce" 'vlog-enable-reg) (define-key map "\C-cf" 'vlog-function) (define-key map "\C-cg" 'vlog-declare-reg) (define-key map "\C-ci" 'vlog-if-else-begin) (define-key map "\C-cj" 'vlog-fork-join-groupname) (define-key map "\C-cm" 'vlog-insert-module-instance) (define-key map "\C-cq" 'vlog-query-for-variable) (define-key map "\C-cr" 'vlog-std-reg) (define-key map "\C-ct" 'vlog-table) (define-key map "\C-cw" 'vlog-declare-wire) (define-key map "\C-c[" 'beginning-of-vlog-module) (define-key map "\C-c]" 'end-of-vlog-module) (define-key map "\C-c\C-a" 'vlog-always-begin) (define-key map "\C-c\C-b" 'vlog-begin-end) ; (define-key map "\C-c\C-c" 'vlog-case-choice) (define-key map "\C-c\C-c" 'vlog-case-statements) (define-key map "\C-c\ec" 'vlog-compiler-celldefine) (define-key map "\C-c\C-d" 'vlog-defparam) (define-key map "\C-c\ed" 'vlog-compiler-define) ; (define-key map "\C-c\C-f" 'vlog-for-var-begin) (define-key map "\C-c\C-f" 'vlog-find-file) (define-key map "\C-c\C-j" 'vlog-fork-join) ; (define-key map "\C-c\C-i" 'vlog-indent-line) (define-key map "\C-c\ei" 'vlog-compiler-ifdef-else) (define-key map "\C-c\C-m" 'vlog-module) (define-key map "\C-c\em" 'vlog-insert-port-connections) (define-key map "\C-c\C-n" 'vlog-net-data-types-choice) (define-key map "\C-c\C-r" 'vlog-reg-data-types-choice) (define-key map "\C-c\C-p" 'vlog-primitive-gates-choice) (define-key map "\C-c\p" 'vlog-pin-to-pin-path-delays) (define-key map "\C-c\C-o" 'vlog-operators) (define-key map "\C-c\C-s" 'vlog-specify) (define-key map "\C-c\C-t" 'vlog-task) (define-key map "\C-c\C-u" 'vlog-user-defined-primitive) (define-key map "\C-c\ep" 'vlog-builtin-print-choice) (define-key map "\C-c\e\C-p" 'vlog-builtin-fprint-choice) (define-key map "(" 'self-insert-maybe-paired) (define-key map "{" 'self-insert-maybe-paired) (define-key map "[" 'self-insert-maybe-paired) (define-key map "'" 'self-insert-maybe-paired) (define-key map "`" 'self-insert-maybe-paired) (define-key map "\"" 'self-insert-maybe-paired) ; (define-key map "." 'vlog-stutter-period) (define-key map "," 'vlog-stutter-comma) (define-key map "\C-m" 'vlog-newline-and-indent) (define-key map "\C-j" 'newline) map) "Keymap used in vlog-mode.") (defvar vlog-shell nil "The shell being programmed. nil because only used for vlog.") ;; this gets assigned to mode-indent-level ;(defvar vlog-indent-level 2 ; "The default value for indenting in vlog-mode. ;This is the width of tab stops after the indentation of the preceeding line.") (defvar mode-indent-level 2 "The default value for indenting in vlog-mode. This is the width of tab stops after the indentation of the preceeding line.") (defvar vlog-remember-variable-min 2 "*Don't remember variables less than this length for completing reads.") (defvar vlog-fill-port-list nil "*Specifies whether to fill the module port list.") (defvar end-comment-column 76 "*Specifies the fill column for comments in vlog-mode.") (defvar vlog-module-multiline-to-first-port nil "*Whether to have multiple lines in a module port list.") ; This goes into your .abbrev_defs file, but if it isn't there, this takes ; care of adding it automatically. (defvar vlog-mode-abbrev-table nil "Abbreviation table used in Vlog HDL mode buffers.") ;process-environment and reserved words (defvar vlog-variables '(("always") ("endtask") ("or") ("supply0") ("and") ("event") ("output") ("supply1") ("assign") ("for") ("parameter") ("table") ("attribute") ("force") ("pmos") ("task") ("begin") ("forever") ("posedge") ("time") ("buf") ("fork") ("primitive") ("tran") ("bufif0") ("function") ("pull0") ("tranif0") ("bufif1") ("highz0") ("pull1") ("tranif1") ("case") ("highz1") ("pulldown") ("tri") ("casex") ("if") ("pullup") ("tri0") ("casez") ("initial") ("rcmos") ("tri1") ("cmos") ("inout") ("reg") ("triand") ("deassign") ("input") ("release") ("trior") ("default") ("integer") ("repeat") ("trireg") ("defparam") ("join") ("rnmos") ("use") ("disable") ("large") ("rpmos") ("vectored") ("edge") ("macromodule") ("rtran") ("wait") ("else") ("medium") ("rtranif0") ("wand") ("end") ("module") ("rtranif1") ("weak0") ("endattribute") ("nand") ("scalared") ("weak1") ("endcase") ("negedge") ("small") ("while") ("endfunction") ("nmos") ("specify") ("wired") ("endmodule") ("nor") ("specparam") ("wor") ("endprimitive") ("not") ("strength") ("xnor") ("endspecify") ("notif0") ("strong0") ("xor") ("endtable") ("notif1") ("strong1") ) "Alist of all variables and reserved words used for completing read.") ;; mode-command and utility functions (require 'dabbrev) ;(load "paired-insert.el") (autoload 'define-statement-skeleton "statement" "Command for defining a statement-skeleton." nil 'macro) (autoload 'insert-statement-skeleton "statement" "Command for inserting a statement-skeleton." nil nil) (autoload 'self-insert-maybe-paired "paired-insert") ;;;###autoload (defun vlog-mode () "Major mode for editing Verilog files. Behavior is to use statement skeletons for the various Verilog constructs. These statements may be invoked either through an extensive abbrev-mode table or through the C-c prefix. The syntax of statements can be modified by putting a property on the command or new ones defined with vlog-defun. For example (put 'vlog-until nil '(() \"until \" _ \\n > \"do\" \\n \"done\")) or (put 'vlog-if nil '(\"What? \" \"If ya got ( \" str \" ) ya betta { }\")) where `vlog-until' or `vlog-if' have been or will be defined by `vlog-defun'. The following commands are available: \\[vlog-always] Insert an always block statement \\[vlog-always-begin] Insert an always block statement with a begin-end statement \\[vlog-assign] Insert an explicit assign statement \\[vlog-begin-end] Insert a begin-end statement \\[vlog-begin-end-groupname] Insert begin-end statement with group_name \\[vlog-case-choice] Insert a case statement \\[vlog-case-statements] Insert a case statement prompting for the individual statements \\[vlog-compiler-celldefine] Insert a `celldefine and `endcelldefine compiler directives statement \\[vlog-compiler-define] Insert a `define compiler directive statement \\[vlog-defparam] Insert a defparam statement \\[vlog-find-file] Opens the filename specified by the word that point is on. Must be in current dir. \\[vlog-for] Insert a for statement \\[vlog-for-var-begin] Insert a for statement with index var choice \\[vlog-fork-join] Insert a fork-join statement \\[vlog-fork-join-groupname] Insert fork-join statement with group_name \\[vlog-function] Insert a function statement \\[vlog-if-else] Insert an if statement with multiple else statements \\[vlog-if-else-begin] Insert an if statement with multiple else statements and begin-end pairs \\[vlog-compiler-ifdef-else] Insert an `ifdef compiler directive statement with an `else statement \\[vlog-module] Insert a 'module ' statement \\[vlog-insert-port-connections] Insert port connections for module \\[vlog-update-module-ports] Updates all ports in a module declaration from i/o declares \\[vlog-module-instance] Insert a module instance (old and very manual) \\[vlog-insert-module-instance] Insert a module instance as taken from the file containing the definition of the module. \\[vlog-update-module-instance] Deletes and re-instantiates the instance that the point is on. \\[vlog-integer] Insert an integer with size, base, and value \\[vlog-net-data-types-choice] Insert net data types with drive_strength, size, and delay \\[vlog-reg-data-types-choice] Insert register data types with size and array_size \\[vlog-primitive-gates-choice] Insert a primitive (gate) instance with drive_strength, delay, name, and array range \\[vlog-specify] Insert a specify block statement \\[vlog-task] Insert a task statement \\[vlog-table] Insert a table statement \\[vlog-user-defined-primitive] Insert a User Defined Primitive (UDP) \\[vlog-pin-to-pin-path-delays] Insert pin-to-pin path delays \\[vlog-operators] Insert an operator statement \\[backward-delete-char] Delete backward one character \\[backward-delete-char-untabify] Delete backward one position, even if it was a tab. \\[help-for-help] Help key binding \\[vlog-newline-and-indent] Delete unquoted space and indent new line same as this one. \\[vlog-inline-comment] Add an inline comment with // \\[vlog-query-for-variable] Query for a variable or reserved word with completions offered \\[vlog-insert-port-connections] Insert output, inout, and input sigs in module ports." (interactive) (kill-all-local-variables) (set-syntax-table vlog-mode-syntax-table) (use-local-map vlog-mode-map) (make-local-variable 'indent-line-function) (make-local-variable 'comment-start) (make-local-variable 'comment-start-skip) (make-local-variable 'comment-end) (make-local-variable 'comment-multi-line) (make-local-variable 'comment-column) (make-local-variable 'end-comment-column) (make-local-variable 'font-lock-defaults) (make-local-variable 'require-final-newline) (make-local-variable 'vlog-shell) (make-local-variable 'self-insert-paired-alist) (make-local-variable 'self-insert-no-pairing) (make-local-variable 'vlog-variables) (make-local-variable 'dabbrev-case-fold-search) (make-local-variable 'dabbrev-case-replace) (make-local-variable 'font-lock-keywords) ; (make-local-variable 'mode-indent-level) ;; If non-nil, make vlog-insert-port-connections indent to 1st port (make-local-variable 'vlog-module-multiline-to-first-port) (make-local-variable 'font-lock-defaults) ; (make-local-variable 'vlog-module-port-per-line) (setq major-mode 'vlog-mode mode-name "Vlog" local-abbrev-table vlog-mode-abbrev-table abbrev-mode 1 indent-line-function 'vlog-indent-line-better-2 comment-start "// " comment-end "" comment-start-skip "/\\*+ *\\|// *" comment-multi-line nil comment-column 40 end-comment-column 76 fill-column 76 dabbrev-case-fold-search t dabbrev-case-replace nil ;; C shells do ; require-final-newline t self-insert-paired-alist '((?` ?`)) self-insert-no-pairing 'vlog-quoted-p vlog-module-multiline-to-first-port nil) (setq font-lock-defaults '(verilog-font-lock-keywords nil t)) (run-hooks 'vlog-mode-hook)) (put 'vlog-defun 'lisp-indent-hook 'defun) (defmacro vlog-defun (command documentation &rest definitions) "Define COMMAND with [DOCSTRING] to insert statements as in DEFINITION ... Prior definitions (e.g. from ~/.emacs) are maintained. Each definition is built up as (SHELL PROMPT ELEMENT ...). Alternately a synonym definition can be (SHELL . PREVIOUSLY-DEFINED-SHELL). For the meaning of (PROMPT ELEMENT ...) see insert-statement-skeleton. Each DEFINITION is actually stored as (put COMMAND SHELL (PROMPT ELEMENT ...)), which you can also do yourself." (or (stringp documentation) (setq definitions (cons documentation definitions) documentation "")) ;; The compiled version doesn't. (require 'backquote) (`(progn (let ((definitions '(, definitions))) (while definitions (or (get '(, command) (car (car definitions))) (put '(, command) (car (car definitions)) (if (symbolp (cdr (car definitions))) (get '(, command) (cdr (car definitions))) (cdr (car definitions))))) (setq definitions (cdr definitions)))) (defun (, command) (arg) (, documentation) (interactive "*P") (insert-statement-skeleton (or (get '(, command) vlog-shell) (error "%s statement syntax not defined for shell %s." '(, command) vlog-shell))))))) ;; Old indent-line-better ;(defun vlog-indent-line-better () ; "If text precedes point on that line, insert TAB; ; Else if looking at SPC or TAB, move cursor to current indentation; ; Else indent as far as preceding line, then by steps of `mode-indent-level'" ; (interactive) ; (let ((previous (save-excursion ; (previous-line 1) ; (current-indentation))) ;get indentation col of prev line ; (origpos (point)) ; (origmarker (point-marker)) ; (current (save-excursion ; (back-to-indentation) ; (current-column)))) ;get indentation col of this line ; (beginning-of-line) ; (if (re-search-forward "[^ \t]" origpos 'f) ;goto to origpos if fail ; ;cursor is within the line of code ; ; This inserted 'mode-indent-level' spaces within line of code ;; (progn ;; (goto-char origpos) ;; ;(insert "\t") ;; mhm - use spaces instead of tab ;; (insert-char ?\ mode-indent-level) ;; ) ; ;; This code lines up this line with previous line ; (progn ; (back-to-indentation) ; (delete-region (point) ;to possibly replace spaces with tabs ; (progn (beginning-of-line) ; (point))) ; (indent-to previous) ; (goto-char origmarker) ; ) ; (if (looking-at "[ \t]") ;origpos is within initial indentation ; (back-to-indentation) ; (progn ;cursor is at start of line of code ; (delete-region (point) ;to possibly replace spaces with tabs ; (progn (beginning-of-line) ; (point))) ; (indent-to (if (< current previous) ; previous ; (+ current mode-indent-level)))) ; )))) (defvar vlog-begend-regexp "\\(\\\\|\\\\)") (defvar vlog-begendcase-regexp "\\(\\\\|\\\\)") (defvar vlog-begenddef-regexp "\\(\`ifdef\\>\\|\`endif\\>\\)") (defvar vlog-begendmod-regexp "\\(\\\\|\\\\)") (defun vlog-indent-line-better-2 () "If text precedes point on that line, insert TAB; Else if looking at SPC or TAB, move cursor to current indentation; Else indent as far as preceding line, then by steps of `mode-indent-level' -mhm " (interactive) ;(debug 'debug) (let ((origmarker (point-marker)) (origpos (point)) (endline nil) (markerhack nil) ; get indentation col of prev line ; (previous (vlog-get-previous-indent)) previous (eol (save-excursion (end-of-line) (point))) (bol (save-excursion (beginning-of-line) (point)))) (beginning-of-line) ; Is this line an `end' line? (cond ((looking-at "\\s *\\(\\\\|\`else\\>\\|\`endif\\>\\)") ;; this line has end on it ; (message "ms is %s" (match-string 2)) (setq endline 't) (cond ;; endcase ((string= (match-string 2) "case") (setq previous (save-excursion (vlog-find-matching-begin vlog-begendcase-regexp "endcase")))) ;; `endif/`else ((or (string= (match-string 1) "`endif") (string= (match-string 1) "`else")) (setq previous (save-excursion (vlog-find-matching-begin vlog-begenddef-regexp "endif")))) ((string= (match-string 2) "module") (setq previous (save-excursion (vlog-find-matching-begin vlog-begendmod-regexp "endmodule")))) ;; end (t (setq previous (save-excursion (vlog-find-matching-begin vlog-begend-regexp "end"))))) (back-to-indentation) (delete-region (point) bol) (indent-to previous) ; (if (not (< previous mode-indent-level)) ; (indent-to (- previous mode-indent-level)) ;) (goto-char origmarker)) ; no "end" on this line ; this line ends in a comma ; ((and (looking-at "[^*,\\s *$") ; ; if previous line ends in a comma, line them up ; (save-excursion ; (forward-line -1) ; (looking-at "\\s +\\..*,\\s *$"))) ; (setq previous (save-excursion ; (forward-line -1) ; (back-to-indentation) ; (current-column))) ; (message "dot comma line") ; (back-to-indentation) ; (delete-region (point) bol) ; (indent-to previous) ; (goto-char origmarker) ; ) ; else, this is not an `end' line (t (let ((parselim (save-excursion (beginning-of-line) (point))) ;; `ToDo' Optimization? => set cl-paren-lim = parselim. (cl-paren-lim (save-excursion (beginning-of-line) (point)))) (setq previous (save-excursion (vlog-prev-line-indent-walk parselim cl-paren-lim))) ; (message "previous is %s" previous) (back-to-indentation) ;; indent for line continuation ; (if (vlog-line-continuation endline) ; (setq previous (+ previous mode-indent-level))) (cond ;; blank line ((and (looking-at "$") (eq bol origpos)) ; (message "Blank line") (setq markerhack 'blank-line) ) ;; for maintaining cursor position ((and (not (> origpos (point))) (not (eq bol (save-excursion (goto-char origmarker) (point))))) ; (message "reseting origmarker") (setq origmarker (save-excursion (forward-char 1) (point-marker))) (setq markerhack 'indent-rgn) ) ) ;; Do new indentation (delete-region (point) bol) (indent-to previous) ;; Correct cursor position (goto-char origmarker) (cond ((eq markerhack 'indent-rgn) (forward-char -1)) ((eq markerhack 'blank-line) (end-of-line)) ) ;; don't leave cursor on bol (if (eq (current-column) 0) (back-to-indentation)) ) ) ) ) ) ; (defvar vlog-initial-indent 2) (defvar vlog-statement-begin-regexp "\\(\\\\|\\\\|\\\\|\\\\|\\\\)" ) ;(setq vlog-statement-begin-regexp ; "\\(\\\\|\\\\|\\\\|\\\\|\\\\)" ) (defvar vlog-case-item-begin-regexp "\\w+:\\s +") ;(setq vlog-case-item-begin-regexp "\\w+:\\s +") (defun vlog-begin-end-search-backward () "" (if (re-search-backward "^.*\\(\\\\|\\\\|\\\\)" (point-min) 't) (progn (goto-char (match-beginning 1)) (if (vlog-in-comment) (vlog-begin-end-search-backward) (progn (beginning-of-line) ; (message "Found a true begin/end") 't ) ) ;else return 0 because there wasn't one to be found ) ) ) (defun vlog-line-continuation (endline) "When to add another indent due to line continuation" ; (message "Inside line continuation check") (save-excursion (if (or (eq endline t) (looking-at "[^\n]*\\.*$")) nil (forward-line -1) (if (or (looking-at "[ \t]*$") (looking-at "[^\n]*\\(;\\|\\\\).*$") (looking-at "\\s *\\(`?end\\(if\\)?\\|case\\).*$")) nil t)))) (defun vlog-find-matching-begin (begend-regexp end-str &optional move) "" ;(debug 'debug) (let ((ms nil)) (defun inner-find-matching-begin (begend-regexp end-str ) "" (while (or (string= ms end-str) (string= ms nil)) (re-search-backward begend-regexp (point-min) 't) (setq ms (match-string 0)) (while (vlog-in-comment) (re-search-backward begend-regexp (point-min) 't) (setq ms (match-string 0)) ) (if (string= ms end-str) (progn ; (inner-find-matching-begin begend-regexp end-str) (inner-find-matching-begin begend-regexp end-str)) ; (message "inner begin is %s" (point)) ) ) (setq ms nil) ) ; (message "bg is %s" begend-regexp) ; (message "es is %s" end-str) (inner-find-matching-begin begend-regexp end-str) ) (if (eq move t) ;don't move to point just return col (progn ;(message "point is %s" (point)) ; (message "On line: %s" (count-lines (point-min) (point))) ) (back-to-indentation) ; (message "Matching Begin is at %s" (point)) (current-column)) ) (defun vlog-backward-parens-get-col (bol) "" (skip-chars-backward " \t" bol) (if (memq (char-before) '(?\) ?\] ?\})) (backward-list)) (back-to-indentation) (current-column)) ;(defun vlog-backward-parens (bol) ; "" ; (skip-chars-backward " \t" bol) ; (if (memq (char-before) '(?\) ?\] ?\})) ; (backward-list)) ; (back-to-indentation) ; (current-column)) (defun vlog-prev-line-indent-walk (parselim cl-paren-lim) "Walk up the code testing for a line to derive the indent level from. Return the indent level." (let (bol ms (continued-line nil) (begin-on-curline nil) (pstate nil) (no-cont-line nil) (indent-lvl 0)) (defun vlog-unmatched-open-paren-line (parselim) "" (save-excursion ; (message "point is %d" (point)) ; (message "parselim is %d" parselim) (setq pstate (parse-partial-sexp (point) parselim)) ; (message "paren depth is %s" (nth 0 pstate)) ; (message "position is %s" (nth 1 pstate)) (nth 1 pstate) ) ) (defun vlog-unmatched-close-paren-line (cl-paren-lim) "" (save-excursion (setq pstate (parse-partial-sexp (point) cl-paren-lim)) ; (message "position is %s" (nth 2 pstate)) ; (message "min paren depth is %s" (nth 6 pstate)) (if (< (nth 6 pstate) 0) t nil ) ) ) (defun indent-anchor (first-line) "Returns indent level based current line, if there are code anchor points on the line. If not, return nil." (beginning-of-line) (setq bol (point)) ; (message "Walking on line %d i-a" (1+ (count-lines (point-min) (point)))) (cond ;; check for begin/end/case ((looking-at "[^\n]*\\(\\\\|\\\\|\\\\)") ; (message "line has begin/end/case match") (setq ms (match-string 1)) (goto-char (match-beginning 1)) (if (not (vlog-in-comment)) (progn ; (message "Found a true begin/end") (if (string= ms "begin") (progn ; (message "mil is %d" mode-indent-level) ; (setq indent-lvl (vlog-backward-parens-get-col bol)) (setq indent-lvl (+ (vlog-backward-parens-get-col bol) mode-indent-level))) (back-to-indentation) ; (message "case or end match") ; (message "match string is %s" ms) (setq indent-lvl (+ (current-column) (if (or (string= ms "case") (string= ms "casex") (string= ms "casez")) mode-indent-level 0)))) ) ; (vlog-prev-line-indent-walk parselim) ; else go up 1 line and look again nil ) ) ;; check for ifdef/else/endif ((looking-at "[^\n]*\\(\`ifdef\\>\\|\`else\\>\\|\`endif\\>\\)") ; (message "line has ifdef/else/endif match") (setq ms (match-string 1)) (goto-char (match-beginning 1)) (if (not (vlog-in-comment)) ; (progn ; (message "Found a true ifdef/endif") ; (setq indent-lvl (current-column)) (setq indent-lvl (+ (current-column) (if (or (string= ms "\`ifdef") (string= ms "\`else")) mode-indent-level 0))) ; ) ; (vlog-prev-line-indent-walk parselim) ; else go up 1 line and look again nil ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; check for if/else without a begin ;;; Work in Progress ;; ;; ((looking-at "\w*\\(else\\>\\||if\\>\\) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; check for (, {, [ on current line ;; first check for a closing paren w/o a preceeding open paren ((and (goto-char bol) (vlog-unmatched-open-paren-line parselim)) ; (message "checking for unmatched open paren") (goto-char (nth 1 pstate)) (setq continued-line nil) (setq indent-lvl (1+ (current-column))) ) ;; check to see if we are inside parens. if so move to begin of parens. ((and (goto-char bol) (vlog-unmatched-close-paren-line cl-paren-lim)) ; (message "we are inside some parens. Getting out.") ; (vlog-find-matching-begin "\(\\|\)" "\)" t) (if (eq first-line t) (progn (if (re-search-forward "[^\n]*;" (save-excursion (end-of-line) (point)) t) (if (or (vlog-in-comment) (vlog-in-quote)) nil (setq no-cont-line t)) (setq no-cont-line t)) (beginning-of-line))) (up-list -1) nil ) ;; check for reg/wire/input/output/inout declare ;; (this is a shortcut to looking for module definition ((looking-at "\\s *\\(reg\\|wire\\|\\(in\\|out\\)put\\|inout\\)\\>") ; (message "line initial reg/wire/io declare match") (goto-char (match-beginning 1)) (if (not (vlog-in-comment)) (setq indent-lvl (current-column)) ; (vlog-prev-line-indent-walk parselim) ; else go up 1 line and look again nil )) ;; check for module definition ((looking-at "\\s *\\(module\\)") ; (message "line has module match") (goto-char (match-beginning 1)) (if (not (vlog-in-comment)) (progn ; (message "Found a true module") (setq indent-lvl (+ (current-column) mode-indent-level))) ; (vlog-prev-line-indent-walk parselim) ; else go up 1 line and look again nil )) ;; default case - we didn't find anything on this line. Go up ;; one and try again (t (goto-char bol) ; (message "nothing found on this line") ; (vlog-prev-line-indent-walk parselim) ;; if we are at beginning of buffer set indent-lvl = 0 (if (eq (point) (point-min)) (progn (setq continued-line nil) ;turn off so indent-lvl will = 0 0) nil ) ) ) ) ; (message "point is %s" (point)) ;; test for begin on current line. No line continue here. (setq begin-on-curline (looking-at "[^\n]*\\.*$")) ; (message "First line check starting") (forward-line -1) ; goto previous line (if (setq indent-lvl (indent-anchor t)) indent-lvl ;; set line cont flag (if (and (not begin-on-curline) (not no-cont-line) (not (looking-at "[ \t]*$")) (not (looking-at "[ \t]*`"))) (progn (if (re-search-forward "[^\n]*;" (save-excursion (end-of-line) (point)) t) ; (message "On line %d" (1+ (count-lines (point-min) (point)))) ; (if (looking-at "[^\n]*;") (if (or (vlog-in-comment) (vlog-in-quote)) (progn ; (message "semi was inside comment") (setq continued-line nil)) ) ;; no ";" on line (end-of-line) (if (vlog-in-comment) (progn ; (message "testing cont line in comment") (setq continued-line nil)) ; comments aren't continues ; (message "failed cont line in comment test") (setq continued-line t)))) ) (beginning-of-line) (forward-line -1) ; (message "cont line is %s" continued-line) ;; walk up file for indent level (while (not (setq indent-lvl (indent-anchor nil))) (forward-line -1)) (setq indent-lvl (+ indent-lvl (if continued-line mode-indent-level 0))) ) )) ;(defun vlog-indent-line () ; "Indent as far as preceding line, then by steps of `mode-indent-level'." ; (interactive) ; (let ((previous (save-excursion ; (previous-line 1) ; (current-indentation))) ; (current (progn ; (back-to-indentation) ; (current-column)))) ; (delete-region (point) ; (progn (beginning-of-line) ; (point))) ; to possibly replace spaces with tabs ; (indent-to (if (< current previous) ; previous ; (+ current mode-indent-level))) ; ) ; ) (defun vlog-remember-variable (var) "Make VARIABLE available for future completing reads in this buffer." ;; Used with vlog-query-for-variable (or (< (length var) vlog-remember-variable-min) (assoc var vlog-variables) (setq vlog-variables (cons (list var) vlog-variables))) var) (defun vlog-quoted-p () "Is point preceded by an odd number of backslashes?" (eq 1 (% (- (point) (save-excursion (skip-chars-backward "\\\\") (point))) 2))) ;; various other commands (defun vlog-query-for-variable (arg) "Query for a variable-name or reserved words with completions offered." (interactive "*p") (let (completion-ignore-case (minibuffer-local-completion-map (or (get 'vlog-query-for-variable 'keymap) (put 'vlog-query-for-variable 'keymap (copy-keymap minibuffer-local-completion-map)))) (buffer (current-buffer))) (insert (prog1 (vlog-remember-variable (completing-read "Variable: " vlog-variables (function (lambda (element) (or (not (cdr element)) (memq vlog-shell (cdr element))))))) (if (eq t arg) (forward-char 1)))) (if (eq t arg) (forward-char 1)))) (defun vlog-newline-and-indent (&optional arg) "Strip unquoted whitespace, insert a newline and indent it like current line. Unquoted whitespace is stripped from the current line's end, unless a prefix ARG is given." (interactive "*P") (let ((previous (current-indentation)) str (end-of-line (point))) (if arg () (skip-chars-backward " \t") (and (< (point) end-of-line) ; (vlog-quoted-p) (forward-char 1)) ; (setq str (read-string (format "%s%c%d" "ready2" ? (point)))) (delete-region (point) end-of-line) ) (newline) (indent-for-tab-command) ; (skip-chars-forward " \t") ; (message "%d" previous) ; (indent-to previous) )) ;;======================================================================== ;; statement syntax-commands ;;======================================================================== ;; You are welcome to add the syntax or even completely new statements as ;; appropriate for your favorite style. (vlog-defun vlog-always "Insert an always block statement." (nil "Condition: " "always @ (" str ")" \n > _ )) (vlog-defun vlog-always-begin "Insert an always block statement with a begin-end statement." (nil "Condition: " "always @ (" str ") begin" \n > _ \n < "end//always ")) (vlog-defun vlog-assign "Insert an explicit assign statement." (nil nil "assign " ("[delay rise \(min\)]: " % "#\(" str ("[delay rise \(typ\)]: " % ":" str ("[delay rise \(max\)]: " % ":" str)) ("[delay fall\(min\)]: " % "," str ("[delay fall \(typ\)]: " % ":" str ("[delay fall \(max\)]: " % ":" str)) ("[delay turn-off\(min\)]: " % "," str ("[delay turn-off \(typ\)]: " % ":" str ("[delay turn-off \(max\)]: " % ":" str)))) "\) ") ("net_name: " % str) " = " ("assignment: " % str) ";")) (vlog-defun vlog-begin-end "Insert a begin-end statement." (nil nil "begin" \n > _ \n < "end")) (vlog-defun vlog-begin-end-groupname "Insert a begin-end statement with optional groupname." (nil nil "begin" ("[group_name]: " % ": " str) \n > _ \n < "end")) (vlog-defun vlog-case-choice "Insert a case statement prompting for case matches with choice of case type." (nil nil "case" ("type of case \(null, x, or z\): " % str) " \(" ("net or register: " % str) "\)" \n > ("[case match]: " % str ": " _ ";" \n ("[case match]: " str ": ;" \n)) ("[default]: " % "default: ;" \n) < "endcase" )) (vlog-defun vlog-case "Insert a case statement prompting for case matches." (nil nil " \(" ("net or register: " % str) "\)" \n > ("[case match]: " % str ": " _ ";" \n ("[case match]: " str ": ;" \n)) ("[default]: " % "default: ;" \n) < "endcase" )) (vlog-defun vlog-case-statements "Insert a case statement prompting for case matches and for the individual statements." (nil nil "case" ("type of case \(null, x, or z\): " % str) " \(" ("net or register: " % str) "\)" \n > ("[case match]: " str ": " ("[statement]: " % str) ";" \n) "default: " _ ";" \n < "endcase")) (vlog-defun vlog-compiler-celldefine "Insert a `celldefine and `endcelldefine compiler directives statement." (nil nil "`celldefine" \n _ \n "`endcelldefine")) (vlog-defun vlog-compiler-define "Insert a `define compiler directive statement." (nil "mnemonic [with optional (args)]: " "`define " str ("text_string [include optional (args)]: " % " " str) \n )) (vlog-defun vlog-defparam "Insert a defparam for parameter redefinition." (nil nil ("defparam instance_name: " "defparam " str "." ("parameter_name: " % str) " = " ("value: " % str) ";"))) (vlog-defun vlog-for "Insert a for statement." (nil "Initial assignment: " "for \(" str "; " ("expression: " % str) "; " ("step assignment: " % str) "\)" \n > _ )) (vlog-defun vlog-for-i-begin "Insert a for statement using i with begin-end pair." (nil "upper limit[32]: " "for \(i=0; i<" str | "32" "; i=i+1\) begin" \n > _ \n < "end")) (vlog-defun vlog-for-j-begin "Insert a for statement using j with begin-end pair." (nil "upper limit[32]: " "for \(j=0; j<" str | "32" "; j=j+1\) begin" \n > _ \n < "end")) (vlog-defun vlog-std-reg "Make a specific register always statement" (nil "Reg name: " "always @ (posedge clk or negedge reset_l) begin" \n > "if (!reset_l) begin" \n > str " <= 0;" \n < "end" \n "else begin" \n > str " <= ;" \n < "end" \n < "end//always ")) (vlog-defun vlog-enable-reg "Make a specific enabled register always statement" (nil "Reg name: " "always @ (posedge clk or negedge reset_l) begin" \n > "if (!reset_l) begin" \n > str " <= 0;" \n < "end" \n "else begin" \n > "if () begin" \n > str " <= ;" \n < "end" \n < "end" \n < "end//always ")) (vlog-defun vlog-for-var-begin "Insert a for statement using index var (prompted for) with begin-end pair. Prefix ARG can change the upper limit from the default." (nil "index variable: " "for \(" str | "i" "=0; " str | "i" "<" arg | "32" "; " str | "i" "=" str | "i" "+1\) begin" \n > _ \n < "end")) (vlog-defun vlog-for-begin "Insert a for statement with begin-end pair." (nil "Initial assignment: " "for \(" str "; " ("expression: " % str) "; " ("step assignment: " % str) "\) begin" \n > _ \n < "end")) (vlog-defun vlog-fork-join "Insert a fork-join statement." (nil nil "fork" \n > _ \n < "join")) (vlog-defun vlog-fork-join-groupname "Insert a fork-join statement with optional group_name." (nil nil "fork " ("[group_name]: " % ": " str) \n > _ \n < "join")) (vlog-defun vlog-function "Insert a function statement. Functions must have at least one input, and may have any number of outputs or inouts \(output and inouts new in OVI 2.0\). They may not contain timing controls. Functions return the value assigned to the name of the function." (nil nil "function " ("[return size msb]: " % "[" str ("return size lsb: " % ":" str) "] ") ("function_name: " % str) ";" \n > ("output signals with same port size: " "output " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) ("inout signals with same port size: " "inout " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) ("input signals with same port size: " "input " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) \n _ \n \n < "endfunction" \n)) (vlog-defun vlog-if-else "Insert an if statement with multiple else statements." (nil "expression: " "if \(" str "\)" \n > _ ("[else if expression]: " \n < "else if \(" str "\)" \n > ) ("[else]: " % \n < "else" \n > ))) (vlog-defun vlog-if-else-begin "Insert an if statement with multiple else statements inserting a begin-end pair for each one." (nil "expression: " "if \(" str "\) begin" \n > _ \n < "end" ("[else if expression]: " \n "else if \(" str "\) begin" \n > \n < "end") ("[else]: " % \n "else begin" \n > \n < "end"))) (vlog-defun vlog-compiler-ifdef-else "Insert an `ifdef compiler directive statement with an `else statement." (nil nil "`ifdef " ("define_mnemonic: " % str \n) > _ \n ("[`else]: " % < "`else" \n > \n) < "`endif")) (vlog-defun vlog-module "Insert a 'module ' statement." (nil "module_name: " "module " str " ();" \n > ("output signals with same port size: " "output " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) ("inout signals with same port size: " "inout " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) ("input signals with same port size: " "input " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) \n _ \n \n < "endmodule //of " str \n)) (vlog-defun vlog-module-instance "Insert a module instance." (nil "module name for this instance: " str " " ("[parameter assignments]: " % "#\(" str "\) ") ;; Instance name required so if no name, no ports are asked for. ("instance name: " % str ("port connections: " % " \(" str "\)") ("instance name: " ", " str ("port connections: " % " \(" str "\)"))) ";")) (vlog-defun vlog-integer "Insert an integer with size, base, and value. Ex: 8'hA7" (nil "Integer size: " str ("base (b, o, d, h): " % "'" str ("value: " % str)))) (vlog-defun vlog-net-data-types-choice "Insert choice of net data type with drive_strength, size, and delay. Form: net_type \(drive_strength\) [size] #delay net_name\(s\) [= continuous assign]; net_types: wire, wor, wand, tri, trior, triand, tri1, tri0, supply0, supply1, and trireg" (nil nil ("Net type: " str " " ("[drive_strength1]: " % "\(" str ("drive_strength0: " % "," str ) "\) ") ("[size msb]: " % "[" str ("size lsb: " % ":" str) "] ") ("[delay rise \(min\)]: " % "#\(" str ("[delay rise \(typ\)]: " % ":" str ("[delay rise \(max\)]: " % ":" str)) ("[delay fall\(min\)]: " % "," str ("[delay fall \(typ\)]: " % ":" str ("[delay fall \(max\)]: " % ":" str)) ("[delay turn-off\(min\)]: " % "," str ("[delay turn-off \(typ\)]: " % ":" str ("[delay turn-off \(max\)]: " % ":" str)))) "\) ") ("net_names: " % str ) ("[continuous assignment]: " % " = " str) ";"))) (vlog-defun vlog-net-data-types "Insert net data types with drive_strength, size, and delay. Form: net_type \(drive_strength\) [size] #delay net_name\(s\) [= continuous assign]; net_types: wire, wor, wand, tri, trior, triand, tri1, tri0, supply0, supply1, and trireg" (nil nil ("[drive_strength1]: " % "\(" str ("drive_strength0: " % "," str ) "\) ") ("[size msb]: " % "[" str ("size lsb: " % ":" str) "] ") ("[delay rise \(min\)]: " % "#\(" str ("[delay rise \(typ\)]: " % ":" str ("[delay rise \(max\)]: " % ":" str)) ("[delay fall\(min\)]: " % "," str ("[delay fall \(typ\)]: " % ":" str ("[delay fall \(max\)]: " % ":" str)) ("[delay turn-off\(min\)]: " % "," str ("[delay turn-off \(typ\)]: " % ":" str ("[delay turn-off \(max\)]: " % ":" str)))) "\) ") ("net_names: " % str ) ("[continuous assignment]: " % " = " str) ";")) (vlog-defun vlog-reg-data-types-choice "Insert choice of register data type with size and array_size. Form: register_type [size] name [array_size]; register_types: reg, integer, time, and real" (nil nil ("Register type: " str " " ("[size msb]: " % "[" str ("size lsb: " % ":" str) "] ") ("register names: " % str ) ("[first address of array size]: " % " [" str ("last address of array size: " % ":" str) "]") ";"))) (vlog-defun vlog-reg-data-types "Insert register data types with size and array_size. Form: register_type [size] name [array_size]; register_types: reg, integer, time, and real" (nil nil ("[size msb]: " % "[" str ("size lsb: " % ":" str) "] ") ("register names: " % str ) ("[first address of array size]: " % " [" str ("last address of array size: " % ":" str) "]") ";")) (vlog-defun vlog-parameter "Insert a parameter data type." (nil nil ("parameter constant_name: " "parameter " str " = " ("value: " % str) ";" \n))) (vlog-defun vlog-primitive-gates-choice "Insert a primitive (gate) instance with drive_strength, delay, name, and array range with choice of primitive. Form: prim_type (drive_strength) #delay [instance_name] [instance_array_range \(OVI 2.0\)] \(terminals\); prim_types: and, nand, or, nor, xor, xnor \(<1 output>, <1 or more inputs>\) buf, not \(<1 or more outputs>, <1 input>\) bufif[01], notif[01], [pn]mos, r[pn]mos \(<1 output>, <1 input>, <1 control>\) cmos, rcmos \(<1 output>,<1 input>,,

\) tran, rtran \(<2 bidir inouts>\) tranif[01], rtranif[01] \(<2 bidir inouts>, <1 control>\) pullup, pulldown \(<1 output>\)" (nil "Primitive type: " str " " ("[drive_strength1]: " % "\(" str ("drive_strength0: " % "," str ) "\) ") ("[delay rise \(min\)]: " % "#\(" str ("[delay rise \(typ\)]: " % ":" str ("[delay rise \(max\)]: " % ":" str)) ("[delay fall\(min\)]: " % "," str ("[delay fall \(typ\)]: " % ":" str ("[delay fall \(max\)]: " % ":" str)) ("[delay turn-off\(min\)]: " % "," str ("[delay turn-off \(typ\)]: " % ":" str ("[delay turn-off \(max\)]: " % ":" str)))) "\) ") ("[instance name]: " % str ("[array range msb \(OVI 2.0\)]: " % "[" str ("array range lsb: " % ":" str) "]") " " ) "\(" ("terminals: " % str) "\)" ("[instance name]: " ", " str ("[array range msb \(OVI 2.0\)]: " % "[" str ("array range lsb: " % ":" str) "]") " \(" ("terminals: " % str) "\)" ) ";" \n )) (vlog-defun vlog-primitive-gates "Insert a primitive (gate) instance with drive_strength, delay, name, and array range. Form: prim_type (drive_strength) #delay [instance_name] [instance_array_range \(OVI 2.0\)] \(terminals\); prim_types: and, nand, or, nor, xor, xnor \(<1 output>, <1 or more inputs>\) buf, not \(<1 or more outputs>, <1 input>\) bufif[01], notif[01], [pn]mos, r[pn]mos \(<1 output>, <1 input>, <1 control>\) cmos, rcmos \(<1 output>,<1 input>,,

\) tran, rtran \(<2 bidir inouts>\) tranif[01], rtranif[01] \(<2 bidir inouts>, <1 control>\) pullup, pulldown \(<1 output>\)" (nil nil ("[drive_strength1]: " % "\(" str ("drive_strength0: " % "," str ) "\) ") ("[delay rise \(min\)]: " % "#\(" str ("[delay rise \(typ\)]: " % ":" str ("[delay rise \(max\)]: " % ":" str)) ("[delay fall\(min\)]: " % "," str ("[delay fall \(typ\)]: " % ":" str ("[delay fall \(max\)]: " % ":" str)) ("[delay turn-off\(min\)]: " % "," str ("[delay turn-off \(typ\)]: " % ":" str ("[delay turn-off \(max\)]: " % ":" str)))) "\) ") ("[instance name]: " % str ("[array range msb \(OVI 2.0\)]: " % "[" str ("array range lsb: " % ":" str) "]") " " ) "\(" ("terminals: " % str) "\)" ("[instance name]: " ", " str ("[array range msb \(OVI 2.0\)]: " % "[" str ("array range lsb: " % ":" str) "]") " \(" ("terminals: " % str) "\)" ) ";" \n )) (vlog-defun vlog-specify "Insert a specify block statement." (nil nil "specify" \n > ("specparam constant_name: " "specparam " str " = " ("value: " % str) ";" \n) _ \n < "endspecify")) (vlog-defun vlog-specparam "Insert a specparam data type." (nil nil ("specparam constant_name: " "specparam " str " = " ("value: " % str) ";" \n))) (vlog-defun vlog-task "Insert a task statement. Tasks are subroutines, and may have any number of inputs, outputs, or inouts, and may contain timing controls." (nil "task_name: " "task " str ";" \n > ("output signals with same port size: " "output " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) ("inout signals with same port size: " "inout " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) ("input signals with same port size: " "input " ("[msb]: " % "[" str ("lsb: " % ":" str ) "] ") str ";" \n) \n _ \n \n < "endtask //of " str \n)) (vlog-defun vlog-table "Insert a table statement for UDPs. Entry forms: input_logic_values : output_logic_values; input_logic_values : state : output_logic_values; Table symbols: 0,1 logic 0,1 x,X unknown ? don't care if 0, 1, or X b,B don't care if 0 or 1 \(vw\) transition from logic v to logic w r,R rising transition: same as \(01\) f,F falling transition: same as \(10\) p,P positive transition: same as \(01\), \(0X\), or \(X1\) n,N negative transition: same as \(10\), \(1X\), or \(X0\) * any possible transition: same as \(??\) - no change on output of sequential device" (nil nil "table" \n > _ \n < "endtable")) (vlog-defun vlog-user-defined-primitive "Insert a User Defined Primitive \(UDP\)." (nil "primitive_name: " "primitive " str " ();" \n > ("output terminal: " % "output " str ";" \n ) ("input terminals: " "input " str ";" \n) ("[reg output]: " % "reg " str ";" \n) "table" \n > _ \n < "endtable" \n < "endprimitive //of " str \n)) (vlog-defun vlog-pin-to-pin-path-delays "Insert a pin-to-pin path delay for within a specify block. Forms: \(input [polarity]*> output\) = \(delay\) \(input [polarity]=> output\) = \(delay\) if \(cond\) \(input [polarity][=*]> output\) = \(delay\) \(edge input [=*]> \(output [polarity]: source\)\) = \(delay\) Different delays can be specified for 1,2,3,6, or 12 transitions." (nil nil ("[if (condition using input ports)] condition: " "if \(" str "\) " ("input_port\(s\) with [polarity(+/-)]: " % "\(" str " ") ("=> or *>: " % str " ") ("output_port\(s\) or \(output [polarity]: source\): " % str "\) = ") ("delay rise \(min\): " % "\(" str ("[delay rise \(typ\)]: " % ":" str ("[delay rise \(max\)]: " % ":" str)) ("delay fall\(min\): " % "," str ("[delay fall \(typ\)]: " % ":" str ("[delay fall \(max\)]: " % ":" str)) ("[delay turn-off\(min\)]: " % "," str ("[delay turn-off \(typ\)]: " % ":" str ("[delay turn-off \(max\)]: " % ":" str)) ("[delay for other transitions]: " % ", " str))) "\)") ";" \n))) (vlog-defun vlog-expression-question "Prompt for expression for repeat and while statements." (nil "expression: " "\(" str | "1" "\) ")) (vlog-defun vlog-operators "Insert an 'operator' statement. Form: [operand] operator operand Arithmetic operators: + - * / % - Negate \(in 2's complement\) -n Bitwise operators: ~ invert each bit ~n & AND each bit | OR each bit ^ XOR each bit ~^ ^~ XNOR each bit Unary Reduction Operators: &, ~& AND, NAND all bits together &n |, ~| OR, NOR all bits together |n ^, ~^ ^~ XOR, XNOR all bits together ^n Logical Operators: ! Is not true? !n &&, || Both, either true? ==, != Equal, not equal for 0 or 1 ===,!== Equal, not identical for 0, 1, X, and Z Relational Operators: < > <= >= Logical Shift Operators: << >> Shift left, right n times m >> n Other Operators: ?: