FPGARelated.com
Forums

Perl Preprocessor for HDL

Started by Kevin Neilson April 19, 2005
Because of the deficiencies in Verilog or the tools, I often have to 
write Perl to generate Verilog.  Examples of these deficiencies include:

- Port list is not parameterizable without use of `defines
- Many synthesizers don't understand preprocessing constant functions
- Generate function in Verilog has limitations

Rather than write Perl to generate Verilog modules, which is a 
cumbersome flow, it would be nice to have a Perl preprocessor.  What I 
am thinking of is something that would look through your HDL, find 
formatted comments, parse parameters and `ifdefs, and then execute Perl 
and insert the results there.  It would see something like this:
.
.
.
parameter NUM_UNITS=2;
`define PARAM2 2
// Perl Start
// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) {
//   print("adder adder$j (.I(i[$j],.O(o[$j]);\n");
// }
// Perl End
.
.

Then it would execute the Perl in the comments and append the output to 
the commented section, like this:
.
.
.
parameter NUM_UNITS=2;
`define PARAM2 2
// Perl Start
// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) {
//   print("adder adder$j (.I(i[$j],.O(o[$j]);\n");
// }
// Perl End
// Generated Perl Code Start
adder adder0 (.I(i[0],.O(o[0]);
adder adder1 (.I(i[1],.O(o[1]);
adder adder2 (.I(i[2],.O(o[2]);
adder adder3 (.I(i[3],.O(o[3]);.
// Generated Perl Code End
.
.

Of course this is a simple example that can be accomlished with a 
'generate', but you get my point.  Note that the Verilog parameters have 
been parsed and can be used as Perl variables.  With this preprocessor 
you could also do a lot of floating-point preprocessing that uses 
functions like "sine" that don't exist in Verilog.  Does anything like 
this exist?  Or do I have to write my own?
-Kevin
Kevin,
It'd be less than an hour to write a Perl pre-processor to run the inline
stuff. You know about Perl's 'eval' function I assume? Read the file in,
write it back out, execute the stuff between the //Perl Start End thingies.
Cheers, Syms.

"Kevin Neilson" <kevin_neilson@removethiscomcast.net> wrote in message
news:d43ttt$a13@xco-news.xilinx.com...
> Because of the deficiencies in Verilog or the tools, I often have to > write Perl to generate Verilog. Examples of these deficiencies include: > > - Port list is not parameterizable without use of `defines > - Many synthesizers don't understand preprocessing constant functions > - Generate function in Verilog has limitations > > Rather than write Perl to generate Verilog modules, which is a > cumbersome flow, it would be nice to have a Perl preprocessor. What I > am thinking of is something that would look through your HDL, find > formatted comments, parse parameters and `ifdefs, and then execute Perl > and insert the results there. It would see something like this: > . > . > . > parameter NUM_UNITS=2; > `define PARAM2 2 > // Perl Start > // for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { > // print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); > // } > // Perl End > . > . > > Then it would execute the Perl in the comments and append the output to > the commented section, like this: > . > . > . > parameter NUM_UNITS=2; > `define PARAM2 2 > // Perl Start > // for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { > // print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); > // } > // Perl End > // Generated Perl Code Start > adder adder0 (.I(i[0],.O(o[0]); > adder adder1 (.I(i[1],.O(o[1]); > adder adder2 (.I(i[2],.O(o[2]); > adder adder3 (.I(i[3],.O(o[3]);. > // Generated Perl Code End > . > . > > Of course this is a simple example that can be accomlished with a > 'generate', but you get my point. Note that the Verilog parameters have > been parsed and can be used as Perl variables. With this preprocessor > you could also do a lot of floating-point preprocessing that uses > functions like "sine" that don't exist in Verilog. Does anything like > this exist? Or do I have to write my own? > -Kevin
Kevin Neilson wrote:
> Because of the deficiencies in Verilog or the tools, I often have to > write Perl to generate Verilog. Examples of these deficiencies
include:
> > - Port list is not parameterizable without use of `defines
Parameters work quite well for this, now that Verilog-2001 allows you to set up Verilog module port definitions much like VHDL's entities: parameters can be defined before the port list, and those parameters can be used in the port declarations. -a
Andy Peters wrote:
> Kevin Neilson wrote: > >>Because of the deficiencies in Verilog or the tools, I often have to >>write Perl to generate Verilog. Examples of these deficiencies > > include: > >>- Port list is not parameterizable without use of `defines > > > Parameters work quite well for this, now that Verilog-2001 allows you > to set up Verilog module port definitions much like VHDL's entities: > parameters can be defined before the port list, and those parameters > can be used in the port declarations. > > -a >
You can use parameters to define the width of the port, but you can't actually change the number of ports. For example, say I want a 4-port memory interface, I would want part of the port list to read: module memory( input [7:0] din0, input [7:0] din1, input [7:0] din2, input [7:0] din3, ... Whereas for an 8-port interface, I want four more of these ports. Parameters can't be used to increase the number of ports. What I can do is concatenate all the ports into a single port with parameterizable width, but that's not a very friendly interface. -Kevin
That part isn't too bad, but I think the difficult part is to be able to 
use the Verilog parameters in the Perl code.  For that to work, I have 
to be able to parse through all the files to find the values of all the 
parameters in that scope.
-Kevin
Symon wrote:
> Kevin, > It'd be less than an hour to write a Perl pre-processor to run the inline > stuff. You know about Perl's 'eval' function I assume? Read the file in, > write it back out, execute the stuff between the //Perl Start End thingies. > Cheers, Syms. > > "Kevin Neilson" <kevin_neilson@removethiscomcast.net> wrote in message > news:d43ttt$a13@xco-news.xilinx.com... > >>Because of the deficiencies in Verilog or the tools, I often have to >>write Perl to generate Verilog. Examples of these deficiencies include: >> >>- Port list is not parameterizable without use of `defines >>- Many synthesizers don't understand preprocessing constant functions >>- Generate function in Verilog has limitations >> >>Rather than write Perl to generate Verilog modules, which is a >>cumbersome flow, it would be nice to have a Perl preprocessor. What I >>am thinking of is something that would look through your HDL, find >>formatted comments, parse parameters and `ifdefs, and then execute Perl >>and insert the results there. It would see something like this: >>. >>. >>. >>parameter NUM_UNITS=2; >>`define PARAM2 2 >>// Perl Start >>// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { >>// print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); >>// } >>// Perl End >>. >>. >> >>Then it would execute the Perl in the comments and append the output to >>the commented section, like this: >>. >>. >>. >>parameter NUM_UNITS=2; >>`define PARAM2 2 >>// Perl Start >>// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { >>// print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); >>// } >>// Perl End >>// Generated Perl Code Start >>adder adder0 (.I(i[0],.O(o[0]); >>adder adder1 (.I(i[1],.O(o[1]); >>adder adder2 (.I(i[2],.O(o[2]); >>adder adder3 (.I(i[3],.O(o[3]);. >>// Generated Perl Code End >>. >>. >> >>Of course this is a simple example that can be accomlished with a >>'generate', but you get my point. Note that the Verilog parameters have >>been parsed and can be used as Perl variables. With this preprocessor >>you could also do a lot of floating-point preprocessing that uses >>functions like "sine" that don't exist in Verilog. Does anything like >>this exist? Or do I have to write my own? >>-Kevin > > >
In article <d43ttt$a13@xco-news.xilinx.com>,
Kevin Neilson  <kevin_neilson@removethiscomcast.net> wrote:
>Because of the deficiencies in Verilog or the tools, I often have to >write Perl to generate Verilog. Examples of these deficiencies include: > >- Port list is not parameterizable without use of `defines >- Many synthesizers don't understand preprocessing constant functions >- Generate function in Verilog has limitations > >Rather than write Perl to generate Verilog modules, which is a >cumbersome flow, it would be nice to have a Perl preprocessor. What I >am thinking of is something that would look through your HDL, find >formatted comments, parse parameters and `ifdefs, and then execute Perl >and insert the results there. It would see something like this: >. >. >. >parameter NUM_UNITS=2; >`define PARAM2 2 >// Perl Start >// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { >// print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); >// } >// Perl End >. >. > >Then it would execute the Perl in the comments and append the output to >the commented section, like this: >. >. >. >parameter NUM_UNITS=2; >`define PARAM2 2 >// Perl Start >// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { >// print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); >// } >// Perl End >// Generated Perl Code Start >adder adder0 (.I(i[0],.O(o[0]); >adder adder1 (.I(i[1],.O(o[1]); >adder adder2 (.I(i[2],.O(o[2]); >adder adder3 (.I(i[3],.O(o[3]);. >// Generated Perl Code End >. >. > >Of course this is a simple example that can be accomlished with a >'generate', but you get my point. Note that the Verilog parameters have >been parsed and can be used as Perl variables. With this preprocessor >you could also do a lot of floating-point preprocessing that uses >functions like "sine" that don't exist in Verilog. Does anything like >this exist? Or do I have to write my own? >-Kevin
I do this sort of thing with VHDL using Ruby (http://www.ruby-lang.org - Perl's prettier younger sister, or Perl meets SmallTalk) and Ruby's built-in ERB module which lets you embed Ruby code into a string, so you can do things like this (I was just doing this today, in fact): package mvg_avg_pkg is constant integer_part : natural := <%= @bits %>; constant frac_part : natural := <%= @bin_pt %>; constant multiplier : unsigned := <%= @bits %>-1 downto 0) := "<%= @multiplier.to_binary %>"; end package; The code between '<%=' and '%>' is valid Ruby code and gets evaluated as such and the resulting values are filled in. You can also have loops, etc. Phil
On Tue, 19 Apr 2005 17:20:21 -0600, Kevin Neilson
<kevin_neilson@removethiscomcast.net> wrote:

>That part isn't too bad, but I think the difficult part is to be able to >use the Verilog parameters in the Perl code. For that to work, I have >to be able to parse through all the files to find the values of all the >parameters in that scope. >-Kevin
I run hot and cold on the idea of using pre-processors, so I won't offer an opinion for fear of contradicting myself. But if you're looking for a perl Verilog parser, take a look at: http://www.burbleland.com/v2html/rvp.html I don't know if it'll do what you need, but perhaps it will give you some ideas. Good luck, Bob Perlman Cambrian Design Works
>Symon wrote: >> Kevin, >> It'd be less than an hour to write a Perl pre-processor to run the inline >> stuff. You know about Perl's 'eval' function I assume? Read the file in, >> write it back out, execute the stuff between the //Perl Start End thingies. >> Cheers, Syms. >> >> "Kevin Neilson" <kevin_neilson@removethiscomcast.net> wrote in message >> news:d43ttt$a13@xco-news.xilinx.com... >> >>>Because of the deficiencies in Verilog or the tools, I often have to >>>write Perl to generate Verilog. Examples of these deficiencies include: >>> >>>- Port list is not parameterizable without use of `defines >>>- Many synthesizers don't understand preprocessing constant functions >>>- Generate function in Verilog has limitations >>> >>>Rather than write Perl to generate Verilog modules, which is a >>>cumbersome flow, it would be nice to have a Perl preprocessor. What I >>>am thinking of is something that would look through your HDL, find >>>formatted comments, parse parameters and `ifdefs, and then execute Perl >>>and insert the results there. It would see something like this: >>>. >>>. >>>. >>>parameter NUM_UNITS=2; >>>`define PARAM2 2 >>>// Perl Start >>>// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { >>>// print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); >>>// } >>>// Perl End >>>. >>>. >>> >>>Then it would execute the Perl in the comments and append the output to >>>the commented section, like this: >>>. >>>. >>>. >>>parameter NUM_UNITS=2; >>>`define PARAM2 2 >>>// Perl Start >>>// for ($j=0;$j<$NUM_UNITS*PARAM2;j++) { >>>// print("adder adder$j (.I(i[$j],.O(o[$j]);\n"); >>>// } >>>// Perl End >>>// Generated Perl Code Start >>>adder adder0 (.I(i[0],.O(o[0]); >>>adder adder1 (.I(i[1],.O(o[1]); >>>adder adder2 (.I(i[2],.O(o[2]); >>>adder adder3 (.I(i[3],.O(o[3]);. >>>// Generated Perl Code End >>>. >>>. >>> >>>Of course this is a simple example that can be accomlished with a >>>'generate', but you get my point. Note that the Verilog parameters have >>>been parsed and can be used as Perl variables. With this preprocessor >>>you could also do a lot of floating-point preprocessing that uses >>>functions like "sine" that don't exist in Verilog. Does anything like >>>this exist? Or do I have to write my own? >>>-Kevin >> >> >>
Greetings,
	Not exactly an answer to your question, but the 'pyparsing' module 
for the Python language would make an excelent starting point, and the 
author offers a Verilog mode (see http://pyparsing.sourceforge.net)

I don't know if you've come across Python but I've found it makes writing 
VHDL parsers / generators trivial.  It's somewhat more pleasent on the eyes 
than Perl as well (we get enough eye strain from the HDLs... :-)

Cheers,
        Chris

 Kevin Neilson (kevin_neilson@removethiscomcast.net) wrote:
: Because of the deficiencies in Verilog or the tools, I often have to 
: write Perl to generate Verilog.  Examples of these deficiencies include:

: - Port list is not parameterizable without use of `defines
: - Many synthesizers don't understand preprocessing constant functions
: - Generate function in Verilog has limitations

: Rather than write Perl to generate Verilog modules, which is a 
: cumbersome flow, it would be nice to have a Perl preprocessor.  What I 
: am thinking of is something that would look through your HDL, find 
: formatted comments, parse parameters and `ifdefs, and then execute Perl 
: and insert the results there.  It would see something like this:
: .
: .
: .
: parameter NUM_UNITS=2;
: `define PARAM2 2
: // Perl Start
: // for ($j=0;$j<$NUM_UNITS*PARAM2;j++) {
: //   print("adder adder$j (.I(i[$j],.O(o[$j]);\n");
: // }
: // Perl End
: .
: .

: Then it would execute the Perl in the comments and append the output to 
: the commented section, like this:
: .
: .
: .
: parameter NUM_UNITS=2;
: `define PARAM2 2
: // Perl Start
: // for ($j=0;$j<$NUM_UNITS*PARAM2;j++) {
: //   print("adder adder$j (.I(i[$j],.O(o[$j]);\n");
: // }
: // Perl End
: // Generated Perl Code Start
: adder adder0 (.I(i[0],.O(o[0]);
: adder adder1 (.I(i[1],.O(o[1]);
: adder adder2 (.I(i[2],.O(o[2]);
: adder adder3 (.I(i[3],.O(o[3]);.
: // Generated Perl Code End
: .
: .

: Of course this is a simple example that can be accomlished with a 
: 'generate', but you get my point.  Note that the Verilog parameters have 
: been parsed and can be used as Perl variables.  With this preprocessor 
: you could also do a lot of floating-point preprocessing that uses 
: functions like "sine" that don't exist in Verilog.  Does anything like 
: this exist?  Or do I have to write my own?
: -Kevin