@@ -72,6 +72,15 @@ backend."
7272
7373
7474; ;;; Utils
75+ ; ;;;; hierarchy.el
76+ (defvar verilog-ext-hierarchy-current-flat-hierarchy nil
77+ " Current flat hierarchy.
78+
79+ Used by `verilog-ext-hierarchy-extract--internal' and its subroutines.
80+
81+ Needed since `verilog-ext-hierarchy-extract--childrenfn' can only have one
82+ argument (item)." )
83+
7584(defun verilog-ext-hierarchy--get-node-leaf (node )
7685 " Return leaf name of hierarchical reference NODE.
7786E.g: return \" leaf\" for \" top.block.subblock.leaf\" ."
@@ -84,6 +93,50 @@ E.g: return \"top.block.subblock\" for \"top.block.subblock.leaf\"."
8493 (unless (string= prefix " " )
8594 prefix)))
8695
96+ (defun verilog-ext-hierarchy-extract--childrenfn (item )
97+ " Childrenfn for `hierarchy' .
98+ Arg ITEM are hierarchy nodes."
99+ (let* ((prefix (verilog-ext-hierarchy--get-node-prefix item))
100+ (leaf (verilog-ext-hierarchy--get-node-leaf item))
101+ (children (cdr (assoc (car (split-string leaf " :" )) verilog-ext-hierarchy-current-flat-hierarchy))))
102+ (mapcar (lambda (child ) (concat (when prefix (concat prefix " ." )) leaf " ." child)) children)))
103+
104+ (defun verilog-ext-hierarchy-extract--construct-node (node hierarchy )
105+ " Recursively build HIERARCHY for NODE using childrenfn."
106+ (let ((children (mapcar (lambda (child )
107+ (concat node " ." child))
108+ (cdr (assoc (verilog-ext-hierarchy--get-node-leaf node) verilog-ext-hierarchy-current-flat-hierarchy)))))
109+ (when children
110+ (hierarchy-add-tree hierarchy node nil #'verilog-ext-hierarchy-extract--childrenfn )
111+ (dolist (child children)
112+ (verilog-ext-hierarchy-extract--construct-node child hierarchy)))
113+ hierarchy))
114+
115+ (defun verilog-ext-hierarchy-extract--internal (module )
116+ " Construct hierarchy struct for MODULE.
117+
118+ Modules and instances will be analyzed from the value of
119+ `verilog-ext-hierarchy-current-flat-hierarchy' .
120+ This alist must be populated before calling the function!
121+
122+ `verilog-ext-hierarchy-current-flat-hierarchy' is an alist of the form:
123+ ((moduleA instanceA1:NAME_A1 instanceA2:NAME_A2 ...)
124+ (moduleB instanceB1:NAME_B1 instanceB2:NAME_B2 ...)
125+ ..)
126+
127+ Return populated `hierarchy' struct."
128+ ; ; Some checks
129+ (unless verilog-ext-hierarchy-current-flat-hierarchy
130+ (user-error " Empty hierarchy database, maybe run first `verilog-ext-workspace-hierarchy-parse' ?" ))
131+ (unless (assoc module verilog-ext-hierarchy-current-flat-hierarchy)
132+ (user-error " Could not find %s in the flat-hierarchy" module))
133+ (if (not (cdr (assoc module verilog-ext-hierarchy-current-flat-hierarchy)))
134+ (user-error " Current module has no instances" )
135+ ; ; Construct node
136+ (verilog-ext-hierarchy-extract--construct-node module (hierarchy-new))))
137+
138+
139+ ; ;;;; Frontend format conversion
87140(defun verilog-ext-hierarchy--convert-struct-to-string (hierarchy-struct )
88141 " Convert HIERARCHY-STRUCT to a string.
89142Used to convert hierarchy formats for displaying on different frontends."
@@ -162,6 +215,7 @@ Alist will be of the form (module instance1:NAME1 instance2:NAME2 ...)."
162215 ; ; Return value
163216 hierarchy-alist))
164217
218+
165219; ;;; Backends/extraction
166220; ;;;; Vhier
167221(defconst verilog-ext-hierarchy-vhier-buffer-name " *Verilog-Perl*"
@@ -173,10 +227,9 @@ Alist will be of the form (module instance1:NAME1 instance2:NAME2 ...)."
173227 " --no-missing"
174228 " --missing-modules" ))
175229
176- (defun verilog-ext-hierarchy-extract- vhier (module )
230+ (defun verilog-ext-hierarchy-vhier-extract (module )
177231 " Extract hierarchy of MODULE using Verilog-Perl vhier as a backend.
178232Return hierarchy as an indented string."
179- (interactive )
180233 (unless (executable-find " vhier" )
181234 (error " Executable vhier not found " ))
182235 (let* ((library-args (verilog-expand-command " __FLAGS__" ))
@@ -199,74 +252,73 @@ Return hierarchy as an indented string."
199252 (verilog-ext-replace-regexp-whole-buffer (concat " \\ (?1:" verilog-identifier-sym-re " \\ ) \\ (?2:" verilog-identifier-sym-re " \\ )" ) " \\ 2:\\ 1" )
200253 (buffer-substring-no-properties (point-min ) (point-max )))))
201254
202- ; ;;;; Builtin
203- (defvar verilog-ext-hierarchy-builtin-current-flat-hierarchy nil
204- " Current flat hierarchy.
205- Used by `verilog-ext-hierarchy-extract-builtin' and its subroutines. Needed
206- since `verilog-ext-hierarchy-extract-builtin--childrenfn' can only have one
207- argument (item)." )
208255
256+ ; ;;;; Tree-sitter
257+ (defun verilog-ext-hierarchy-tree-sitter-parse-file (file )
258+ " Return alist with modules and instances from FILE.
259+
260+ Each alist element car is a found module in the file.
261+ These elements cdr are the list of that module's instances.
262+
263+ Instances have module:INST format to make them unique for `hierarchy'
264+ displaying. Modules have no instance name since they are parsed on its
265+ declaration."
266+ (let (modules inst-nodes inst-type inst-name instances module-instances-alist)
267+ (with-temp-buffer
268+ (insert-file-contents file)
269+ (verilog-ts-mode)
270+ (setq modules (verilog-ts-module-declarations))
271+ (dolist (module modules)
272+ (goto-char (cadr module))
273+ (setq inst-nodes (cdr (treesit-induce-sparse-tree (verilog-ts--node-at-bol) " module_instantiation" )))
274+ (dolist (inst-node inst-nodes)
275+ (setq inst-type (treesit-node-text (treesit-search-subtree (car inst-node) " simple_identifier" ) :no-props ))
276+ (setq inst-name (treesit-node-text (treesit-search-subtree (car inst-node) " name_of_instance" ) :no-props ))
277+ (push (concat inst-type " :" inst-name) instances))
278+ (push (cons (car module) (nreverse instances)) module-instances-alist))
279+ module-instances-alist)))
280+
281+ (defun verilog-ext-hierarchy-tree-sitter-extract (module )
282+ " Extract hierarchy of MODULE using tree-sitter as a backend.
283+
284+ Populate `verilog-ext-hierarchy-current-flat-hierarchy' with alist of modules
285+ and instances."
286+ (unless (eq verilog-ext-hierarchy-backend 'tree-sitter )
287+ (error " Wrong backend! " ))
288+ (verilog-ext-hierarchy-extract--internal module))
289+
290+
291+ ; ;;;; Builtin
209292(defun verilog-ext-hierarchy-builtin-parse-file (file )
210- " Return list with modules and instances from FILE.
293+ " Return alist with modules and instances from FILE.
211294
212- The returned list car is the first found module in the file.
213- The returned list cdr is the list of that module's instances.
295+ Each alist element car is a found module in the file.
296+ These elements cdr are the list of that module's instances.
214297
215298Instances have module:INST format to make them unique for `hierarchy'
216299displaying. Modules have no instance name since they are parsed on its
217300declaration."
218- (let (modules instances)
301+ (let (modules instances module-instances-alist )
219302 (with-temp-buffer
220303 (insert-file-contents file)
221304 (verilog-mode )
222305 (setq modules (verilog-ext-scan-buffer-modules))
223- (when modules
306+ (dolist (module modules)
307+ (setq instances nil )
224308 (while (verilog-ext-find-module-instance-fwd)
225309 (push (concat (match-string-no-properties 1 ) " :" (match-string-no-properties 2 )) instances))
226- (cons (car modules) (reverse instances))))))
227-
228- (defun verilog-ext-hierarchy-extract-builtin--childrenfn (item )
229- " Childrenfn for `hierarchy' .
230- Arg ITEM are hierarchy nodes."
231- (let* ((prefix (verilog-ext-hierarchy--get-node-prefix item))
232- (leaf (verilog-ext-hierarchy--get-node-leaf item))
233- (children (cdr (assoc (car (split-string leaf " :" )) verilog-ext-hierarchy-builtin-current-flat-hierarchy))))
234- (mapcar (lambda (child ) (concat (when prefix (concat prefix " ." )) leaf " ." child)) children)))
310+ (push (cons module (reverse instances)) module-instances-alist))
311+ module-instances-alist)))
235312
236- (defun verilog-ext-hierarchy-extract-builtin--construct-node (node hierarchy )
237- " Recursively build HIERARCHY for NODE using childrenfn."
238- (let ((children (mapcar (lambda (child )
239- (concat node " ." child))
240- (cdr (assoc (verilog-ext-hierarchy--get-node-leaf node) verilog-ext-hierarchy-builtin-current-flat-hierarchy)))))
241- (when children
242- (hierarchy-add-tree hierarchy node nil #'verilog-ext-hierarchy-extract-builtin--childrenfn )
243- (dolist (child children)
244- (verilog-ext-hierarchy-extract-builtin--construct-node child hierarchy)))
245- hierarchy))
313+ (defun verilog-ext-hierarchy-builtin-extract (module )
314+ " Extract hierarchy of MODULE using builtin Elisp backend.
246315
247- (defun verilog-ext-hierarchy-extract-builtin (module &optional flat-hierarchy )
248- " Construct hierarchy for MODULE using builtin backend.
316+ Populate `verilog-ext-hierarchy-current-flat-hierarchy' with alist of modules
317+ and instances."
318+ (unless (eq verilog-ext-hierarchy-backend 'builtin )
319+ (error " Wrong backend! " ))
320+ (verilog-ext-hierarchy-extract--internal module))
249321
250- Modules and instances will be analyzed from FLAT-HIERARCHY input if provided.
251- Otherwise, extract from `verilog-ext-hierarchy-builtin-current-flat-hierarchy' :
252- - This is a list of the form (module instance1:NAME1 instance2:NAME2 ...)
253-
254- This optional arg is intended to be used for conversion between vhier/builtin.
255-
256- Return populated `hierarchy' struct."
257- (let ((hierarchy-struct (hierarchy-new))
258- (hierarchy-alist (or flat-hierarchy
259- verilog-ext-hierarchy-builtin-current-flat-hierarchy)))
260- (unless hierarchy-alist
261- (user-error " Empty hierarchy database, maybe run first `verilog-ext-workspace-hierarchy-builtin-parse' ?" ))
262- (unless (assoc module hierarchy-alist)
263- (user-error " Could not find %s in the flat-hierarchy" module))
264- (if (not (cdr (assoc module hierarchy-alist)))
265- (user-error " Current module has no instances" )
266- ; ; DANGER: Don't forget to update `verilog-ext-hierarchy-builtin-current-flat-hierarchy'
267- ; ; before populating the`hierarchy-struct' if using flat-hierarchy as an input!
268- (setq verilog-ext-hierarchy-builtin-current-flat-hierarchy hierarchy-alist)
269- (verilog-ext-hierarchy-extract-builtin--construct-node module hierarchy-struct))))
270322
271323; ;;; Frontends/navigation
272324; ;;;; hierarchy.el
@@ -462,10 +514,13 @@ If these have been set before, keep their values."
462514 " Construct hierarchy for MODULE depending on selected backend."
463515 (cond (; ; Verilog-Perl vhier
464516 (eq verilog-ext-hierarchy-backend 'vhier )
465- (verilog-ext-hierarchy-extract-vhier module)) ; Returns indented string
466- ; ; Built-in
467- ((eq verilog-ext-hierarchy-backend 'builtin )
468- (verilog-ext-hierarchy-extract-builtin module)) ; Returns populated hierarchy struct
517+ (verilog-ext-hierarchy-vhier-extract module)) ; Returns indented string
518+ (; ; Tree-sitter
519+ (eq verilog-ext-hierarchy-backend 'tree-sitter )
520+ (verilog-ext-hierarchy-tree-sitter-extract module)) ; Returns populated hierarchy struct
521+ (; ; Built-in
522+ (eq verilog-ext-hierarchy-backend 'builtin )
523+ (verilog-ext-hierarchy-builtin-extract module)) ; Returns populated hierarchy struct
469524 ; ; Fallback
470525 (t (error " Must set a proper extraction backend in `verilog-ext-hierarchy-backend' " ))))
471526
@@ -488,7 +543,8 @@ convert between an indented string and a populated hierarchy struct."
488543 (when (stringp hierarchy)
489544 (let ((top-module (string-trim-left (car (split-string (car (split-string hierarchy " \n " )) " :" )))) ; First line of the string, as parsed by vhier
490545 (hierarchy-alist (verilog-ext-hierarchy--convert-string-to-alist hierarchy)))
491- (setq display-hierarchy (verilog-ext-hierarchy-extract-builtin top-module hierarchy-alist))))
546+ (setq verilog-ext-hierarchy-current-flat-hierarchy hierarchy-alist)
547+ (setq display-hierarchy (verilog-ext-hierarchy-extract--internal top-module))))
492548 (verilog-ext-hierarchy-display-twidget display-hierarchy))
493549 ; ; Fallback
494550 (t (error " Must set a proper display frontend in `verilog-ext-hierarchy-frontend' " )))))
0 commit comments