FPGARelated.com
Forums

Voila: Nedit macro to produce verilog module instantiations

Started by Timothy Miller November 4, 2003
I am a user of Nedit (nedit.org) and I do a lot of Verilog coding. 
When coding verilog modules, you have a module definition which takes
one form, and you have a module instantiation which takes another
form.  Even with columnar copy/paste/search/replace, it can be a
tedious process to convert one to the other.  Thus, I humbly offer a
Nedit macro I wrote that converts a module definition (header) to an
instantiation.  Make a copy of the module definition header, paste it
where you want it, put the cursor anywhere within the copy, and then
run the macro.


Thus, if you have this:

module lut(
   clock,
   pixel_in,
   pixel_out
);

Running the macro will produce this:

module lut(
   .clock          (clock),
   .pixel_in       (pixel_in),
   .pixel_out      (pixel_out)
);

You have to remove 'module' and add an instance name manually.

Please excuse if the characters don't line up in the email, but in the
editor, the port wires all line up.  The macro will attempt to leave
comments alone (commas in the comments cause a bug right now), and if
more than one port name is on the same line, then it will separate
them automatically into separate lines.

Thus, this:

module lut(
   clock, pixel_in, pixel_out
);

Will also be converted automatically into this:

module lut(
   .clock          (clock),
   .pixel_in       (pixel_in),
   .pixel_out      (pixel_out)
);


The only restriction I want to put on the macro is that I am not
legally liable for any damage caused by it.  I only hope others will
find it useful. Please use it.  If there are problems, I will help
people with it who want to use it.  This macro has saved me incredible
amounts of time, and I know others will be pleased to have it.

Another thing I should note is that this assumes emulated tabs and
relies on $em_tab_dist.


I'm not sure what is the best form for providing the macro.  Below is
a copy out of my .nedit file, but if you would like me to provide it
in a different form, please ask!

   Verilog Module Instance@Verilog:Alt+1::: {\n\
       # Rewind to (\n\
       \n\
       start = search("(", $cursor, "backward")\n\
       if (get_character(start) != "(") {\n\
           beep()\n\
           return 0\n\
       }\n\
       \n\
       start++\n\
       \n\
       # Scan for max comma column so that port variables are aligned
in a pretty column.\n\
       # This detects when multiple port names are on the same line
and estimates the width\n\
       # column alignment of port subsequent to the first on a
line.\n\
       # NOTE: Will screw up if there are commas in comments.  Will
fix later.\n\
       max_col = 0\n\
       last_comma = start\n\
       same_line = 1\n\
       pos = start\n\
       set_cursor_pos(start)\n\
       while (pos < $text_length) {\n\
           c = get_character(pos)\n\
           if (c == ")") {\n\
               # quit at end of instance\n\
               break\n\
           } else if (c == "\\n") {\n\
               # end of line means accurate column number\n\
               last_comma = pos\n\
               same_line = 0\n\
           } else if (c == ",") {\n\
               dist = pos - last_comma\n\
               if (same_line) {\n\
                   # if this is on the same line as the last port, add
tab spacing into distance\n\
                   dist += $em_tab_dist\n\
               }\n\
               if (dist > max_col) {\n\
                   max_col = dist\n\
               }\n\
       \n\
               last_comma = pos\n\
               same_line = 1\n\
           }\n\
       \n\
           pos++\n\
       }\n\
       \n\
       \n\
       # Insert a tab's worth of spacing between port name and
variable.\n\
       # Then pad out to an integral tab stop.\n\
       max_col += $em_tab_dist\n\
       i = max_col % $em_tab_dist\n\
       if (i) max_col += $em_tab_dist-i\n\
       \n\
       # How to break between multiple ports on same line\n\
       indent = "\\n"\n\
       for (i=0; i<$em_tab_dist; i++) indent = indent " "\n\
       \n\
       pos = start\n\
       set_cursor_pos(pos)\n\
       start = -1\n\
       end = -1\n\
       last_line = $line\n\
       \n\
       comment = 0\n\
       star = 0\n\
       \n\
       while (pos < $text_length) {\n\
           c = get_character(pos)\n\
       \n\
           if (comment == 1) {\n\
               star = 0\n\
               if (c == "/") {\n\
                   comment = 3\n\
               } else if (c == "*") {\n\
                   comment = 2\n\
               } else {\n\
                   comment = 0\n\
               }\n\
           } else if (comment == 2) {\n\
               if (star && c == "/") comment = 0\n\
               star = (c == "*")\n\
           } else if (comment == 3) {\n\
               if (c == "\\n" || c == "\\r") {\n\
                   comment = 0\n\
               }\n\
           } else if (c == "/") {\n\
               comment = 1\n\
           } else if (c == " " || c == "\\n" || c == "\\t" || c ==
"\\r") {\n\
           end = pos\n\
           } else if (c == "," || c == ")") {\n\
               if (start >= 0) {\n\
                   # When port name is found, insert dot and
(portname).\n\
                   # also, insert line break when applicable\n\
       \n\
               if (end <= start) end = pos\n\
                   string = "(" get_range(start, end) ")"\n\
                   set_cursor_pos(start)\n\
               if ($line == last_line) insert_string(indent)\n\
               insert_string(".")\n\
                   set_cursor_pos($cursor + end - start)\n\
                   i = $column\n\
                   while (i < max_col) {\n\
                       string = " " string\n\
                       i++\n\
                   }\n\
               insert_string(string)\n\
               pos = $cursor\n\
               start = -1\n\
                   end = -1\n\
       \n\
                   last_line = $line\n\
               }\n\
       \n\
               if (c == ")") break\n\
           } else {\n\
           if (start < 0) start = pos\n\
           }\n\
       \n\
           pos++\n\
       }\n\
   }\n
Timothy Miller wrote:
> I'm not sure what is the best form for providing the macro.
Rather not the way you do. Please write a subroutine (ie define function_name { } ) and just call it in the menu entry (function_name()). BTW, I only looked quickly on the macro and it looks rather complicated. Notice that you probably would better use arrays in combination with the split() function. (What NEdit version do you have? - latest would be 5.4) Moreover, for sharing macro functions, coming to nedit.org or Niki would be nice, too :-) Cheers, J&#4294967295;rg -- Niki -- The NEdit WiKi: http://www.nr.no/~joachim/Niki/
theosib@hotmail.com (Timothy Miller) wrote in message news:<80eae8c5.0311041140.7516de73@posting.google.com>...
> I am a user of Nedit (nedit.org) and I do a lot of Verilog coding. > When coding verilog modules, you have a module definition which takes > one form, and you have a module instantiation which takes another > form. Even with columnar copy/paste/search/replace, it can be a > tedious process to convert one to the other. Thus, I humbly offer a > Nedit macro I wrote that converts a module definition (header) to an > instantiation. Make a copy of the module definition header, paste it > where you want it, put the cursor anywhere within the copy, and then > run the macro. >
Similar function is provided by other scripts available on the web. You could try invoking these scripts from your editor. for example I use the alias \xemacs -l ~/.emacs.batch -l verilog-mode.el !* -f verilog-auto -f save-buffer --batch To take advantage of the features found in verilog-mode.el in my editor(vim) Regards Vijay
Joerg Fischer <jf505@yahoo.de> wrote in message news:<3fa823c6$0$12470$9b622d9e@news.freenet.de>...
> Timothy Miller wrote: > > I'm not sure what is the best form for providing the macro. > > Rather not the way you do. Please write a subroutine (ie > define function_name { > } > ) > and just call it in the menu entry (function_name()).
Where do I put that function? Do I put it directly into a file somewhere? Or does Nedit have a menu for that? What you say makes sense, so I think I should do it.
> > BTW, I only looked quickly on the macro and it looks rather > complicated. Notice that you probably would better use arrays in > combination with the split() function. (What NEdit version do you > have? - latest would be 5.4)
I'm not sure what you think I should use arrays for. Could you be more specific? The reason it's somewhat complicated is that I have to have two state machines capable of parsing text and dealing with a variety of different possible things that might be found. YACC uses state machines for parsing, and I have found that to be a good approach even when coding a parser by hand.
> > Moreover, for sharing macro functions, coming to nedit.org or Niki > would be nice, too :-)
Oh, I have done that. The first thing I did was email develop@nedit.org, but I have no idea if it actually got there. No responses or anything, so that's why I posted to the usenet. I'm not sure what Niki is. I could go there, or you could share it for me if you like. Thanks!
Hi - 

On 5 Nov 2003 03:32:50 -0800, ra1brzrufe001@sneakemail.com (vijay)
wrote:

>theosib@hotmail.com (Timothy Miller) wrote in message news:<80eae8c5.0311041140.7516de73@posting.google.com>... >> I am a user of Nedit (nedit.org) and I do a lot of Verilog coding. >> When coding verilog modules, you have a module definition which takes >> one form, and you have a module instantiation which takes another >> form. Even with columnar copy/paste/search/replace, it can be a >> tedious process to convert one to the other. Thus, I humbly offer a >> Nedit macro I wrote that converts a module definition (header) to an >> instantiation. Make a copy of the module definition header, paste it >> where you want it, put the cursor anywhere within the copy, and then >> run the macro. >> >Similar function is provided by other scripts available on the web. >You could try invoking these scripts from your editor. >for example I use the alias >\xemacs -l ~/.emacs.batch -l verilog-mode.el !* -f verilog-auto -f >save-buffer --batch >To take advantage of the features found in verilog-mode.el in my >editor(vim) >Regards >Vijay
I second that; I do the same thing from within my editor (Ultraedit). The point is this: you can use a good deal of the power of Verilog mode for emacs *without ever opening up Emacs*. Automatically generating argument lists, either for modules or their instantiations, is a snap. Bob Perlman Cambrian Design Works
Timothy Miller wrote:
>> BTW, I only looked quickly on the macro and it looks rather >> complicated. Notice that you probably would better use arrays in >> combination with the split() function. (What NEdit version do you >> have? - latest would be 5.4) > > I'm not sure what you think I should use arrays for. Could you be > more specific?
OK, I hacked quickly a much simpler alternative macro together that does the same as yours (it doesn't consider tabs nor comments though): define jf_test { start = search("(", $cursor, "backward") if (start != -1) { start = start + 1 } else { beep() return } end = search(")", $cursor) if (end == -1) { return } end = end - 1 text = get_range(start, end) port = split(text, "(?n\\s*,\\s*)", "regex") indent = search_string(port[0], "\\S", 0, "regex") blank = jf_indent(indent) newtext = "" extent = 0 port[0] = substring(port[0], indent, length(port[0])) for (i = 0; i < port[]; i++) { extent = max(extent, length(port[i])) } for (i = 0; i < port[]; i++) { newtext = newtext blank "." port[i] jf_indent(extent - length(port[i]))\ blank "(" port[i] "),\n" } newtext = substring(newtext, 0, length(newtext) - 2) "\n" replace_range(start + 1, end + 1, newtext) } define jf_indent { blank = "" for (i = 1; i <= $1; i++) { blank = blank " " } return(blank) } Cheers, J&#4294967295;rg