Skip to content

Commit

Permalink
WIP: Almost added compilation stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
gmlarumbe committed May 30, 2023
1 parent 5ebe339 commit 7cd7f60
Showing 1 changed file with 138 additions and 61 deletions.
199 changes: 138 additions & 61 deletions verilog-ext-compile.el
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,37 @@

;;; Commentary:

;; Compilation related SystemVerilog utils
;; Compilation related SystemVerilog functions.
;;
;; This file provides functions to perform compilations with syntax highlighting
;; and jump to error based on `compilation-mode'.
;;
;; Some usage examples:
;; - (verilog-ext-compile-verilator (concat "verilator --lint-only " buffer-file-name))
;; - (verilog-ext-compile-iverilog (concat "iverilog " buffer-file-name))
;; - (verilog-ext-compile-verible (concat "verible-verilog-lint " buffer-file-name))
;; - (verilog-ext-compile-slang (concat "slang --color-diagnostics=false " buffer-file-name))
;; - (verilog-ext-compile-svlint (concat "svlint -1 " buffer-file-name))
;; - (verilog-ext-compile-surelog (concat "surelog -parseonly " buffer-file-name))

;;; Code:

(require 'verilog-mode)

(defconst verilog-ext-compile-filename-re "[a-zA-Z0-9-_\\.\\/]+")

(defconst verilog-ext-compile-msg-code-face 'verilog-ext-compile-msg-code-face)
(defface verilog-ext-compile-msg-code-face
'((t (:foreground "gray55")))
"Face for compilation message codes."
:group 'fpga)

(defconst verilog-ext-compile-bin-face 'verilog-ext-compile-bin-face)
(defface verilog-ext-compile-bin-face
'((t (:foreground "goldenrod")))
"Face for compilation binaries."
:group 'fpga)

(defmacro verilog-ext-compile-define-mode (name &rest args)
"Macro to define a compilation derived mode for a Verilog error regexp.
Expand Down Expand Up @@ -67,62 +92,142 @@ ARGS is a property list."


;;;; Compilation-re
;; TODO: Update according to the ones at flycheck
;; TODO: Add notes?
(defvar verilog-ext-compile-verilator-re
'((verilator-error "%?\\(Error\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4 nil 2 nil (1 compilation-error-face) (2 compilation-line-face))
(verilator-warning "%?\\(Warning\\)\\(-[^:]+\\|\\):[\n ]*\\([^ \t:]+\\):\\([0-9]+\\):" 3 4 nil 1 nil (1 compilation-warning-face) (2 compilation-line-face)))
(defconst verilog-ext-compile-verilator-re
`((verilator-error ,(concat "^%\\(?1:Error: Internal Error\\): \\(?2:" verilog-ext-compile-filename-re "\\):\\(?3:[0-9]+\\):\\(?4:[0-9]+\\)") 2 3 4 2 nil (1 compilation-error-face))
(verilator-error2 ,(concat "^%\\(?1:Error\\): \\(?2:" verilog-ext-compile-filename-re "\\):\\(?3:[0-9]+\\):\\(?4:[0-9]+\\): ") 2 3 4 2 nil (1 compilation-error-face))
(verilator-error3 ,(concat "^%\\(?1:Error\\)-\\(?2:[^:]+\\): \\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\): ") 3 4 5 2 nil (1 compilation-error-face) (2 verilog-ext-compile-msg-code-face))
(verilator-error4 "^%\\(?1:Error\\): " nil nil nil 2 nil (1 compilation-error-face))
(verilator-warning ,(concat "^%\\(?1:Warning\\)-\\(?2:[^:]+\\): \\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\): ") 3 4 5 1 nil (1 compilation-error-face) (2 verilog-ext-compile-msg-code-face)))
"Verilator regexps.")

(defvar verilog-ext-compile-iverilog-re
(defconst verilog-ext-compile-iverilog-re
'((iverilog-unsupported "\\(?1:.*\\):\\(?2:[0-9]+\\):.*sorry:" 1 2 nil 0 nil (1 compilation-info-face) (2 compilation-line-face))
(iverilog-warning "\\(?1:.*\\):\\(?2:[0-9]+\\):.*warning:" 1 2 nil 1 nil (1 compilation-warning-face) (2 compilation-line-face))
(iverilog-warning2 "^\\(?1:warning\\):" 1 nil nil 1 nil )
(iverilog-error "\\(?1:.*\\):\\(?2:[0-9]+\\):.*error:" 1 2 nil 2 nil (1 compilation-error-face) (2 compilation-line-face))
(iverilog-error2 "\\(?1:.*\\):\\(?2:[0-9]+\\):.*syntax error" 1 2 nil 2 nil (1 compilation-error-face) (2 compilation-line-face))
(vvp-warning "^\\(?1:WARNING\\): \\(?2:.*\\):\\(?3:[0-9]+\\):" 2 3 nil 1 nil (1 compilation-warning-face) (2 compilation-warning-face) (3 compilation-line-face))
(vvp-error "^\\(?1:ERROR\\): \\(?2:.*\\):\\(?3:[0-9]+\\):" 2 3 nil 2 nil (1 compilation-warning-face) (2 compilation-warning-face) (3 compilation-line-face))
(vvp-info "^\\(?1:LXT2 info\\):" 1 nil nil 0 nil))
"Icarus Verilog regexps.")

;; TODO: Add slang/svlint and others...
(defconst verilog-ext-compile-verible-re
`(;; Verible regexps are common for error/warning/infos. It is important to declare errors before warnings below
(verible-error ,(concat "^\\(?1:" verilog-ext-compile-filename-re "\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\)-*[0-9]*:\\s-*" "syntax error at ") 1 2 3 2 nil)
(verible-error2 ,(concat "^\\(?1:" verilog-ext-compile-filename-re "\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\)-*[0-9]*:\\s-*" "preprocessing error at ") 1 2 3 2 nil)
(verible-warning ,(concat "^\\(?1:" verilog-ext-compile-filename-re "\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\)-*[0-9]*:\\s-*") 1 2 3 1 nil))
"Verible regexps.")

(defconst verilog-ext-compile-slang-re
`((slang-error ,(concat "\\(?1:" verilog-ext-compile-filename-re "\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): error: ") 1 2 3 2 nil)
(slang-warning ,(concat "\\(?1:" verilog-ext-compile-filename-re "\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): warning: ") 1 2 3 1 nil)
(slang-info ,(concat "\\(?1:" verilog-ext-compile-filename-re "\\):\\(?2:[0-9]+\\):\\(?3:[0-9]+\\): note: ") 1 2 3 0 nil))
"Slang regexps.")

(defconst verilog-ext-compile-svlint-re
`((svlint-error ,(concat "^\\(?1:Fail\\)\\s-*\\(?2:" verilog-ext-compile-filename-re "\\):\\(?3:[0-9]+\\):\\(?4:[0-9]+\\)\\s-*.*hint: ") 2 3 4 2 nil (1 compilation-error-face))
(svlint-error2 ,(concat "^\\(?1:Error\\)\\s-*\\(?2:" verilog-ext-compile-filename-re "\\):\\(?3:[0-9]+\\):\\(?4:[0-9]+\\)\\s-*.*hint: ") 2 3 4 2 nil (1 compilation-error-face)))
"Svlint regexps.")

(defconst verilog-ext-compile-surelog-re
`((surelog-fatal ,(concat "^\\[\\(?1:FAT:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+\\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\):\\s-+") 3 4 5 2 nil (1 compilation-error-face) (2 verilog-ext-compile-msg-code-face))
(surelog-error ,(concat "^\\[\\(?1:ERR:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+\\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\):\\s-+") 3 4 5 2 nil (1 compilation-error-face) (2 verilog-ext-compile-msg-code-face))
(surelog-syntax ,(concat "^\\[\\(?1:SNT:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+\\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\):\\s-+") 3 4 5 2 nil (1 compilation-error-face) (2 verilog-ext-compile-msg-code-face))
(surelog-warning ,(concat "^\\[\\(?1:WRN:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+\\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\):\\s-+") 3 4 5 1 nil (1 compilation-warning-face) (2 verilog-ext-compile-msg-code-face))
(surelog-note ,(concat "^\\[\\(?1:NTE:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+\\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\):\\s-+") 3 4 5 0 nil (1 compilation-info-face) (2 verilog-ext-compile-msg-code-face))
(surelog-info ,(concat "^\\[\\(?1:INF:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+\\(?3:" verilog-ext-compile-filename-re "\\):\\(?4:[0-9]+\\):\\(?5:[0-9]+\\):\\s-+") 3 4 5 0 nil (1 compilation-info-face) (2 verilog-ext-compile-msg-code-face))
(surelog-info2 ,(concat "^\\[\\(?1:INF:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+") nil nil nil 0 nil (1 compilation-info-face) (2 verilog-ext-compile-msg-code-face)))
"Surelog regexps.")

(defvar verilog-ext-compile-verilator-buf "*verilator*")
(defvar verilog-ext-compile-iverilog-buf "*iverilog*")
(defvar verilog-ext-compile-verible-buf "*verible*")
(defvar verilog-ext-compile-slang-buf "*slang*")
(defvar verilog-ext-compile-svlint-buf "*svlint*")
(defvar verilog-ext-compile-surelog-buf "*surelog*")

;;;; Compilation-modes and functions
;;;###autoload (autoload 'verilog-ext-compile-verilator-mode "verilog-ext-compile.el")
(verilog-ext-compile-define-mode verilog-ext-compile-verilator-mode
:desc "Verilator"
:docstring "Verilator Compilation mode."
:compile-re verilog-ext-verilator-compile-re
:buf-name verilog-ext-verilator-buf)
:compile-re verilog-ext-compile-verilator-re
:buf-name verilog-ext-compile-verilator-buf)

;;;###autoload (autoload 'verilog-ext-compile-verilator "verilog-ext-compile.el")
(verilog-ext-compile-define-fn verilog-ext-compile-verilator
:docstring "Compile Verilator COMMAND with error regexp highlighting."
:buf verilog-ext-verilator-buf
:buf verilog-ext-compile-verilator-buf
:comp-mode verilog-ext-compile-verilator-mode)


;; TODO: Define macro that sets the proper variables
;; (defmacro verilog-ext-compile-setup (mode)
;; "Setup compilation functions."
;; (declare (indent 1) (debug 1))
;; `(let ((modes (mapcar #'car verilog-ext-compile-modes-alist)))
;; ;; (dolist (mode modes)
;; (define-compilation-mode (intern (concat "compilation-" (symbol-name ,mode) "-mode")) (capitalize ,mode)
;; (concat "Compilation Mode with " (capitalize ,mode) " regexps.")
;; (setq-local compilation-skip-threshold 2) ; Default to check errors
;; (setq-local compilation-error-regexp-alist (mapcar 'car verilog-ext-compile-re-synplify))
;; (setq-local compilation-error-regexp-alist-alist verilog-ext-compile-re-synplify))))

;;;; Compilation-derived modes
;; TODO: Still need to do something more generic
;; TODO: Add the appended regexps
(define-compilation-mode compilation-xcelium-mode "Xcelium"
"Xcelium compilation mode."
(setq-local compilation-skip-threshold 2) ; Default to check errors
(setq-local compilation-error-regexp-alist (mapcar 'car verilog-ext-compile-xrun-re))
(setq-local compilation-error-regexp-alist-alist verilog-ext-compile-xrun-re))

;;;###autoload (autoload 'verilog-ext-compile-iverilog-mode "verilog-ext-compile.el")
(verilog-ext-compile-define-mode verilog-ext-compile-iverilog-mode
:desc "Iverilog"
:docstring "Iverilog Compilation mode."
:compile-re verilog-ext-compile-iverilog-re
:buf-name verilog-ext-compile-iverilog-buf)

;;;###autoload (autoload 'verilog-ext-compile-iverilog "verilog-ext-compile.el")
(verilog-ext-compile-define-fn verilog-ext-compile-iverilog
:docstring "Compile Iverilog COMMAND with error regexp highlighting."
:buf verilog-ext-compile-iverilog-buf
:comp-mode verilog-ext-compile-iverilog-mode)

;;;###autoload (autoload 'verilog-ext-compile-verible-mode "verilog-ext-compile.el")
(verilog-ext-compile-define-mode verilog-ext-compile-verible-mode
:desc "Verible"
:docstring "Verible Compilation mode."
:compile-re verilog-ext-compile-verible-re
:buf-name verilog-ext-compile-verible-buf)

;;;###autoload (autoload 'verilog-ext-compile-verible "verilog-ext-compile.el")
(verilog-ext-compile-define-fn verilog-ext-compile-verible
:docstring "Compile Verible COMMAND with error regexp highlighting."
:buf verilog-ext-compile-verible-buf
:comp-mode verilog-ext-compile-verible-mode)

;;;###autoload (autoload 'verilog-ext-compile-slang-mode "verilog-ext-compile.el")
(verilog-ext-compile-define-mode verilog-ext-compile-slang-mode
:desc "Slang"
:docstring "Slang Compilation mode."
:compile-re verilog-ext-compile-slang-re
:buf-name verilog-ext-compile-slang-buf)

;;;###autoload (autoload 'verilog-ext-compile-slang "verilog-ext-compile.el")
(verilog-ext-compile-define-fn verilog-ext-compile-slang
:docstring "Compile Slang COMMAND with error regexp highlighting."
:buf verilog-ext-compile-slang-buf
:comp-mode verilog-ext-compile-slang-mode)

;;;###autoload (autoload 'verilog-ext-compile-svlint-mode "verilog-ext-compile.el")
(verilog-ext-compile-define-mode verilog-ext-compile-svlint-mode
:desc "Svlint"
:docstring "Svlint Compilation mode."
:compile-re verilog-ext-compile-svlint-re
:buf-name verilog-ext-compile-svlint-buf)

;;;###autoload (autoload 'verilog-ext-compile-svlint "verilog-ext-compile.el")
(verilog-ext-compile-define-fn verilog-ext-compile-svlint
:docstring "Compile Svlint COMMAND with error regexp highlighting."
:buf verilog-ext-compile-svlint-buf
:comp-mode verilog-ext-compile-svlint-mode)

;;;###autoload (autoload 'verilog-ext-compile-surelog-mode "verilog-ext-compile.el")
(verilog-ext-compile-define-mode verilog-ext-compile-surelog-mode
:desc "Surelog"
:docstring "Surelog Compilation mode."
:compile-re verilog-ext-compile-surelog-re
:buf-name verilog-ext-compile-surelog-buf)

;;;###autoload (autoload 'verilog-ext-compile-surelog "verilog-ext-compile.el")
(verilog-ext-compile-define-fn verilog-ext-compile-surelog
:docstring "Compile Surelog COMMAND with error regexp highlighting."
:buf verilog-ext-compile-surelog-buf
:comp-mode verilog-ext-compile-surelog-mode)


;;;; Other compilation commands
;;;###autoload
(defun verilog-ext-preprocess ()
"Preprocess current file.
Choose among different available programs and update `verilog-preprocessor'
Expand All @@ -148,34 +253,6 @@ variable."
(pop-to-buffer "*Verilog-Preprocessed*")))


;;;; Verilator
;; INFO: Verilator does not support SystemVerilog verification constructs.
;; Therefore, any source with constructs such as a clocking blocks or classes must be
;; deleted from `verilator.files' (copied previously from gtags.file for example)
;; If that is not possible because it is used as a source (e.g. a SystemVerilog interface
;; with a clocking block), then tweak/comment temporarily files by hand.
;;
;; INFO: This is useful while developing small IPs
(defvar larumbe/verilator-project-list nil)

(defun larumbe/verilator-lint-command ()
"Return current verilator int command based on selected project from `larumbe/verilator-project-list'."
(let* ((project (completing-read "Select project: " (mapcar #'car larumbe/verilator-project-list)))
(lint-files (nth 0 (cdr (assoc project larumbe/verilator-project-list))))
(lint-top (nth 1 (cdr (assoc project larumbe/verilator-project-list)))))
(concat "verilator --lint-only +1800-2012ext+sv "
"-f " lint-files " "
"--top-module " lint-top)))

;;;###autoload
(defun larumbe/verilator-lint ()
"Files created with ggtags and renamed (useful for small projects).
It's faster than Vivado elaboration since it does not elaborate design"
(interactive)
(larumbe/compile (larumbe/verilator-lint-command) nil "verilator"))




(provide 'verilog-ext-compile)

Expand Down

0 comments on commit 7cd7f60

Please sign in to comment.