ANSI/v2001 port list with parameter from `included file?

D

David Rogoff

Guest
I'm not sure how to do this. I have a module with a port whose width
is set by a parameter. In v95, you'd do this:

// ---------------------
// file a
module a (zz);

`include "myparameters.v"

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

Now, I know you can use parameters in ports like this:

// ---------------------
// file a
module a #(parameter MYWIDTH=5) (zz);

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

But this parameter is defined in the module port list. Is this legal?

// ---------------------
// file a
module a #(
`include "myparameters.v"
) (zz);

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

It's easy if I used a macro instead of a parmaeter since those can be
defined outside a module. How about defining the parameters in a
dummy module and used a hierarchical reference? Would this be
synthesizable? Packages? Other ideas?

Thanks,

David
 
On Apr 13, 10:30 pm, David Rogoff <da...@therogoffs.com> wrote:
I'm not sure how to do this.  I have a module with a port whose width
is set by a parameter. In v95, you'd do this:

// ---------------------
// file a
module a (zz);

`include "myparameters.v"

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

Now, I know you can use parameters in ports like this:

// ---------------------
// file a
module a  #(parameter MYWIDTH=5) (zz);

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

But this parameter is defined in the module port list.  Is this legal?

// ---------------------
// file a
module a  #(
`include "myparameters.v"
    ) (zz);

input [MYWIDTH-1:0] zz;
endmodule
I don't think so. It's a currently active feature request for
the next round of IEEE-1800 standardization.

It's easy if I used a macro instead of a parmaeter since those can be
defined outside a module.
But, of course, they can't be different per-instance.

How about defining the parameters in a
dummy module and used a hierarchical reference?  Would this be
synthesizable?
Very unlikely; synthesis almost never tolerates hierarchical
references. In any case you've got to be quite careful about
cross-module references to parameters - it's embarrassingly
easy to get cyclical dependencies.

 Packages? Other ideas?
Packages sounds good. SystemVerilog-2009 allows you to
import a package in the module header, which is very close
to what you were asking for - but nicer. Badger your tool
vendor(s) to support that feature.

Without module-header package imports it's a lot nastier;
either you must import the package into $unit scope (ugh)
by placing the import outside the module altogether, or else
you must explicitly use the package scope resolution operator
for each parameter - which rather defeats your intent.

Not a very satisfying answer, I'm afraid.
--
Jonathan Bromley
 
Jonathan Bromley wrote:
On Apr 13, 10:30 pm, David Rogoff<da...@therogoffs.com> wrote:
I'm not sure how to do this. I have a module with a port whose width
is set by a parameter. In v95, you'd do this:

// ---------------------
// file a
module a (zz);

`include "myparameters.v"

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

Now, I know you can use parameters in ports like this:

// ---------------------
// file a
module a #(parameter MYWIDTH=5) (zz);

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

But this parameter is defined in the module port list. Is this legal?

// ---------------------
// file a
module a #(
`include "myparameters.v"
) (zz);

input [MYWIDTH-1:0] zz;
endmodule

I don't think so. It's a currently active feature request for
the next round of IEEE-1800 standardization.

It's easy if I used a macro instead of a parmaeter since those can be
defined outside a module.

But, of course, they can't be different per-instance.

How about defining the parameters in a
dummy module and used a hierarchical reference? Would this be
synthesizable?

Very unlikely; synthesis almost never tolerates hierarchical
references. In any case you've got to be quite careful about
cross-module references to parameters - it's embarrassingly
easy to get cyclical dependencies.

Packages? Other ideas?

Packages sounds good. SystemVerilog-2009 allows you to
import a package in the module header, which is very close
to what you were asking for - but nicer. Badger your tool
vendor(s) to support that feature.

Without module-header package imports it's a lot nastier;
either you must import the package into $unit scope (ugh)
by placing the import outside the module altogether, or else
you must explicitly use the package scope resolution operator
for each parameter - which rather defeats your intent.

Not a very satisfying answer, I'm afraid.
--
Jonathan Bromley

It's been a year since I asked this, but I was reading the 1800-2009 LRM
and had a related question about parameters and localparams. I wanted
to do something like this:

module mymod
#(
parameter INPUT_WIDTH = 5,
localparam INPUT_MSB = (INPUT_WIDTH-1) // real case a little
more complicated, but similar idea
)
(
input [INPUT_MSB:0] d_in,
output dont_care
);

This gives an error from the compiler. If I change the localparam to a
parameter, it works ok, but it's a little ugly since someone could
override INPUT_MSB, especially if they're not using the SV named
parameters in the instantiation of the module.

Anyone (Hi Jonathan!) know if this is being worked on for updates to
1800-xxx? Also, how can one see the discussions of the spec? Joining
the IEEE?

Thanks,

David
 
On May 16, 9:03 pm, David Rogoff <da...@therogoffs.com> wrote:
Jonathan Bromley wrote:
On Apr 13, 10:30 pm, David Rogoff<da...@therogoffs.com>  wrote:

Now, I know you can use parameters in ports like this:

// ---------------------
// file a
module a  #(parameter MYWIDTH=5) (zz);

input [MYWIDTH-1:0] zz;
endmodule
// ----------------

But this parameter is defined in the module port list.  Is this legal?

// ---------------------
// file a
module a  #(
`include "myparameters.v"
     ) (zz);

input [MYWIDTH-1:0] zz;
endmodule

I don't think so.  It's a currently active feature request for
the next round of IEEE-1800 standardization.
Regarding this original question: there shouldn't be any problem with
this. A `include just pulls in the text. As long as the result is
legal syntax, it should work. It is the same as if you pulled those
parameter definitions into the file with an editor, except you used
`include to tell the compiler to do it for you before compiling it.

If you have multiple parameters, you can't just use the same
myparameters.v file that you used inside a module, because the syntax
is slightly different. In the module port list they are separated by
commas instead of semicolons. But if you adjust your syntax, this
should work.


How about defining the parameters in a
dummy module and used a hierarchical reference?  Would this be
synthesizable?
If you are planning to use the parameter in a context that requires a
"constant expression", such as a vector range, then this not only
isn't synthesizable, it isn't legal. Hierarchical references aren't
allowed in constant expressions, largely to avoid creating
circularities. There are some holes in the rules about this, due to
legacy issues with Verilog-XL. There has been discussion in committee
about relaxing these rules in some way. But currently I would
continue to say that this is illegal.


It's been a year since I asked this, but I was reading the 1800-2009 LRM
and had a related question about parameters and localparams.  I wanted
to do something like this:

module mymod
   #(
     parameter INPUT_WIDTH = 5,
     localparam INPUT_MSB = (INPUT_WIDTH-1)    // real case a little
more complicated, but similar idea
    )
    (
     input [INPUT_MSB:0]  d_in,
     output dont_care
    );

This gives an error from the compiler.  If I change the localparam to a
parameter, it works ok, but it's a little ugly since someone could
override INPUT_MSB, especially if they're not using the SV named
parameters in the instantiation of the module.

Anyone (Hi Jonathan!) know if this is being worked on for updates to
1800-xxx?   Also, how can one see the discussions of the spec?  Joining
the IEEE?
The 2009 LRM allows this. Look at the BNF. But the 2005 LRM did not,
so some tools may not support it yet.
 
In article <b0061c9e-cc98-43e4-baa2-253a0cb4e8c1@j13g2000pro.googlegroups.com>,
Steven Sharp <sesharpma@gmail.com> wrote:
On May 16, 9:03 pm, David Rogoff <da...@therogoffs.com> wrote:
module mymod
   #(
     parameter INPUT_WIDTH = 5,
     localparam INPUT_MSB = (INPUT_WIDTH-1)    // real case a little
more complicated, but similar idea
    )
    (
     input [INPUT_MSB:0]  d_in,
     output dont_care
    );

This gives an error from the compiler.  If I change the localparam to a
parameter, it works ok, but it's a little ugly since someone could
override INPUT_MSB, especially if they're not using the SV named
parameters in the instantiation of the module.

Anyone (Hi Jonathan!) know if this is being worked on for updates to
1800-xxx?   Also, how can one see the discussions of the spec?  Joining
the IEEE?

The 2009 LRM allows this. Look at the BNF. But the 2005 LRM did not,
so some tools may not support it yet.
A trick we use to make this work (in a Verilog-2001 compatible way ) -
It's a bit kludge - but works.

module mymod
#(
parameter INPUT_WIDTH = 5
)
(
input [ INPUT_MSB_func( INPUT_WIDTH ) : 0 ] d_in
);

localparam INPUT_MSB = INPUT_WIDTH - 1;

function integer INPUT_MSB_func( foo );
INPUT_MSB_func = INPUT_MSB;
endfunction


I.e. Forward decleration of contant functions are allowed.

Note, that we've found that certain simulators do require you to pass
an argument to the function - like I did here passing
to argument foo - even though it's not used. Without
an argument - The simulator had a bug where it took
whatever value it first "saw" (I think during elaboration?) and
assumed that was the value always. (Even when the parameter
was overridden with different values). Passing an argument to
the constant function (even with it not being used) worked
around this bug.

As I said, a bit kludge, but it works.

--Mark
 
On 17 May 2011 15:27:50 GMT, gtwrek@sonic.net (Mark Curry) wrote:

A trick we use to make this work (in a Verilog-2001 compatible way ) -
[snip]
I.e. Forward decleration of contant functions are allowed.
Very interesting - filed in the "sure to come in handy
one day" part of my head.

Thanks.
--
Jonathan Bromley
 
On Monday, May 16, 2011 10:26:08 PM UTC-7, Steven Sharp wrote:
If you have multiple parameters, you can't just use the same
myparameters.v file that you used inside a module, because the syntax
is slightly different. In the module port list they are separated by
commas instead of semicolons. But if you adjust your syntax, this
should work.
Steven,

I was going to do something like this but need both version - with commas for including in the header and semicolons for including in the module body. Any good / simple way to have a single master file that generates the two different include files without a PERL script - hopefully just using Verilog? It's not a big deal since it's just change s/;/,/ other than there's no comma on the last parameter but there is a semicolon.

Thanks,

David
 
On 7/25/2011 11:12 AM, unfrostedpoptart wrote:
On Monday, May 16, 2011 10:26:08 PM UTC-7, Steven Sharp wrote:
If you have multiple parameters, you can't just use the same
myparameters.v file that you used inside a module, because the
syntax is slightly different. In the module port list they are
separated by commas instead of semicolons. But if you adjust your
syntax, this should work.

Steven,

I was going to do something like this but need both version - with
commas for including in the header and semicolons for including in
the module body. Any good / simple way to have a single master file
that generates the two different include files without a PERL script
- hopefully just using Verilog? It's not a big deal since it's just
change s/;/,/ other than there's no comma on the last parameter but
there is a semicolon.

Thanks,

David
Off the top of my head something like the following should work.

File: base_inc.v

parameter foo = 1 `MY_SEP // Define for foo.
parameter bar = 2 `MY_ENDSEP // Define for bar.

File: mod_inc.v

`define MY_SEP ;
`define MY_ENDSEP ;
`include "base_inc.v"
`undef MY_BEGIN
`undef MY_SEP

File: port_inc.v

`define MY_SEP ,
`define MY_ENDSEP
`include "base_inc.v"
`undef MY_BEGIN
`undef MY_SEP

File: top.v

module port_top
#(
`include "port_inc.v"
);
initial $display("%m has foo = %d and bar = %d", foo, bar);
endmodule

module top;
`include "mod_inc.v"
initial $display("%m has foo = %d and bar = %d", foo, bar);
endmodule

There's no checking that the MY_SEP and MY_ENDSEP defines are not
already used for something else so add code for that or just make sure
they are unique to this purpose.

Cary
 
Very clever Cary. Something in my brain makes me worry that this could blow up, but so far I can't think of why it would.

David
 

Welcome to EDABoard.com

Sponsor

Back
Top