Voila: Nedit macro to produce verilog module instantiations

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= 0) {\n\ # When port name is found, insert dot and (portname).\n\ # also, insert line break when applicable\n\ \n\ if (end

Reply to
Timothy Miller
Loading thread data ...

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örg

--
Niki -- The NEdit WiKi:
http://www.nr.no/~joachim/Niki/
Reply to
Joerg Fischer

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

Reply to
vijay

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.

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.

Oh, I have done that. The first thing I did was email snipped-for-privacy@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!

Reply to
Timothy Miller

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

Reply to
Bob Perlman

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

Reply to
Joerg Fischer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.