Voila: Nedit macro to produce verilog module instantiations

T

Timothy Miller

Guest
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ö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!
 
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))
}

for (i = 0; i < port[]; i++) {
newtext = newtext blank "." port jf_indent(extent -
length(port))\
blank "(" port "),\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örg
 
Really appreciate your contribution.
the function is extrmely useful.
I have loaded it from the menu file -> load macro file,
but can not find it under macro list,
do i need to register it with nedit,
and how to invoke it?

thanks
 
Really appreciate your contribution.
the function is extrmely useful.
I have loaded it from the menu file -> load macro file,
but can not find it under macro list,
do i need to register it with nedit,
and how to invoke it?

thanks
 

Welcome to EDABoard.com

Sponsor

Back
Top