veripool / verilog-mode

Verilog-Mode for Emacs with Indentation, Hightlighting and AUTOs. Master repository for pushing to GNU, verilog.com and veripool.org.
http://veripool.org/verilog-mode
GNU General Public License v3.0
247 stars 90 forks source link

AUTO_LISP to increment signal occurrence to create array #1694

Closed amolsynapse2 closed 3 years ago

amolsynapse2 commented 3 years ago

I have several small design, which has few common signals. Below code is referring as "sig" & "sig2". These signals are part of multiple designs like design1, design2 & so on. While instantiating i want to convert signal RHS as a array based on Occurrence using Some LISP function. The output signals are given as input to another design (final_sig), which takes MAX_WIDTH for each signal. MAX_WIDTH is parameter of final_sig design. We can still use same LISP identify parameter value. Best of my knowledge i tried using global variable + some functions but i'm not able to achieve it. Following is snippet for Verilog Code. I have added comment with expected behavior using "EXP".

In Short i'm trying to create the Array for the signal as per signal_name in design & used in another module as a input as well as parameter width. Because this lisp needs to back-reference for occurrence. It's not self contained using simple LISP. Need higher knowledge of lisp.

This is small code that i have tried // Initialize start count. using -1 as first call will return 0.

/AUTO_LISP(defvar sig_name -1)/ // Init Start value for sig /AUTO_LISP(defvar sig2_name -1)/ // Init Start Value for sig2

// function for increment, which take name of signal to increment
/AUTO_LISP(defun testfunc (sig_name) (setq sig_name (+ sig_name 1 )) ) /

module top (/AUTOARG/ // Outputs );

wire sig; // --> EXP to be sig [3:0] wire sig2; // --> Exp tp be sig2[4:0]

design1 u_x ( // Outputs .sig (sig), // Exp sig[0] first occurrence for signal sig .sig2 (sig2)); // Exp sig2[0] first occurrence for signal sig2 design2 u_y ( // Outputs .sig2 (sig2)); // Exp sig2[1] 2nd occurrence of signal sig2 design3 u_z ( // Outputs .sig (sig)); // Exp sig[1] 2nd occurrence

design1 u_a ( // Outputs .sig (sig), // Exp sig[2], 3rd .sig2 (sig2)); // Exp sig2[2], 3rd design2 u_b ( // Outputs .sig2 (sig2)); // Exp sig2[3], 4th design1 u_c ( // Outputs .sig (sig), // Exp sig[3], 4th .sig2 (sig2)); // Exp sig2[4], 5th

final_sig #(.WIDTH_1 (SUM_OF_ALL_SIG_OCCURRENCE), .WIDTH_2 (SUM_OF_ALL_SIG2_OCCURRENCE) ) u_dd ( .in_1 (sig [SUM_OF_ALL_SIG_OCCURRENCE-1:0]), .in_2 (sig2 [SUM_OF_ALL_SIG2_OCCURRENCE-1:0]) ); endmodule

wsnyder commented 3 years ago

Sorry, I'm having trouble understanding what you want. Can you please attach an example that I can AUTO myself that shows what you get now, and what you'd like it to make (made by hand). Thanks

amolsynapse2 commented 3 years ago

test.v.txt

Thanks for your time. I've attached verilog code. which has 2 top level module

  1. top:- in which i'm doing AUTO's
  2. top_exp:- which has manual edits for expected behavior.

Once Again thanks.

wsnyder commented 3 years ago

You were very close, basically it was always setting "sig-name" as the name of the variable, you instead want that to be a different symbol based on the signal name, so just

/*
design1 AUTO_TEMPLATE
design2 AUTO_TEMPLATE
design3 AUTO_TEMPLATE (
  .\(.*\) (\1[@"(setq \1 (1+ \1))"]),
);
*/

and later

/*
final_sig AUTO_TEMPLATE (
  .WIDTH_1    (@"sig"-1),
  .WIDTH_2    (@"sig2"-1),
  .in_1       (sig[]),
  .in_2       (sig2[]),
);
*/
amolsynapse2 commented 3 years ago

test_V2.txt Thanks Wsnyder. The First part worked perfectly, but not 2nd part. While doing final_sig, its taking initial value instead of "sig" value from buffer. Attached modified code for reference.

One more interesting observation that i like to share. When running in batch mode, i get the output that is shown in test_V2.txt. When i ran the same in emacs GUI mode, for every C-c C-a, values are incremented again from its last value instead of initial value i.e -1, which is expected as values are still in emacs-buffer. I'm not worried because using batch mode only.

FYI:- My Verilog-Mode.el version is 2019-10-16-38c3cc8-vpo

wsnyder commented 3 years ago

The AUTOs don't evaluate in top-down order, rather e.g. AUTOINSTPARAM must be done before any AUTOINST, so the params are getting the earlier value of sig/sig2. Fortunately what I think you want doesn't even need autos.

final_sig #(// Parameters
            .WIDTH_1                    ($bits(sig)),
            .WIDTH_2                    ($bits(sig2)))
   u_dd(
        // Inputs
        .in_1                           (sig),
        .in_2                           (sig2));

The values in non-batch keep incrementing because a defvar only sets the value when a variable is first created, you'd need a verilog-auto-hook defined to reset them. But as you're only using batch mode sounds you are ok.