Sized genvar

A

Allan Herriman

Guest
Hi,

I'm trying to do something like this:

wire [3:0] foo;

generate
genvar i;
for (i=0; i<16; i=i+1) begin : label
bar u1 (
.baz({foo,i}) // here
)
end
endgenerate

and at 'here' I would like to use the value of the genvar i, but with
a defined width (4 in this case) instead of 32 bits, such that the
concatenation {foo,i} is 8 bits wide.

Does anyone know how I can do this? I tried a bunch of things, but
none of them worked, either because they are illegal in Verilog, or
because the tools didn't support them.

BTW, changing the module 'bar' isn't an option.

Oh, any solution must work in the current version of XST.

Thanks,
Allan
 
I've had success with another synthesizer using something like:

.baz( {foo, 4'hf & i} ) // attempting to force the size
or
.baz( foo<<4 | i ) // giving up on size and getting foo where I want

"Allan Herriman" <allan.herriman.hates.spam@ctam.com.au.invalid> wrote in
message news:icj130dieteeam7e2l35u05cn1rmjt530l@4ax.com...
Hi,

I'm trying to do something like this:

wire [3:0] foo;

generate
genvar i;
for (i=0; i<16; i=i+1) begin : label
bar u1 (
.baz({foo,i}) // here
)
end
endgenerate

and at 'here' I would like to use the value of the genvar i, but with
a defined width (4 in this case) instead of 32 bits, such that the
concatenation {foo,i} is 8 bits wide.

Does anyone know how I can do this? I tried a bunch of things, but
none of them worked, either because they are illegal in Verilog, or
because the tools didn't support them.

BTW, changing the module 'bar' isn't an option.

Oh, any solution must work in the current version of XST.

Thanks,
Allan
 
"Allan Herriman" <allan.herriman.hates.spam@ctam.com.au.invalid>
wrote in message news:icj130dieteeam7e2l35u05cn1rmjt530l@4ax.com...

I'm trying to do something like this:

wire [3:0] foo;

generate
genvar i;
for (i=0; i<16; i=i+1) begin : label
bar u1 (
.baz({foo,i}) // here
)
end
endgenerate

and at 'here' I would like to use the value of the genvar i, but with
a defined width (4 in this case) instead of 32 bits, such that the
concatenation {foo,i} is 8 bits wide.

Does anyone know how I can do this? I tried a bunch of things, but
none of them worked, either because they are illegal in Verilog, or
because the tools didn't support them.
Spookily, I was frustrated today by almost exactly this - the
fact that you can't declare a localparam within a generate.

How about you declare a net and assign to it?

genvar i;
for (i=...) begin : label
wire [3:0] id = i; // continuous assignment
// throws away unwanted MSBs
bar u1 (
.baz( {foo, id} );
);
end
endgenerate
--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.


I can't comment on whether this is OK in XST, sorry.
 
On Mon, 16 Feb 2004 16:37:36 -0000, "Jonathan Bromley"
<jonathan.bromley@doulos.com> wrote:

"Allan Herriman" <allan.herriman.hates.spam@ctam.com.au.invalid
wrote in message news:icj130dieteeam7e2l35u05cn1rmjt530l@4ax.com...

I'm trying to do something like this:

wire [3:0] foo;

generate
genvar i;
for (i=0; i<16; i=i+1) begin : label
bar u1 (
.baz({foo,i}) // here
)
end
endgenerate

and at 'here' I would like to use the value of the genvar i, but with
a defined width (4 in this case) instead of 32 bits, such that the
concatenation {foo,i} is 8 bits wide.

Does anyone know how I can do this? I tried a bunch of things, but
none of them worked, either because they are illegal in Verilog, or
because the tools didn't support them.

Spookily, I was frustrated today by almost exactly this - the
fact that you can't declare a localparam within a generate.

How about you declare a net and assign to it?

genvar i;
for (i=...) begin : label
wire [3:0] id = i; // continuous assignment
// throws away unwanted MSBs
bar u1 (
.baz( {foo, id} );
);
end
endgenerate
Thanks Jonathan,

The 'wire' approach works. I had also tried using a localparam to do
something similar, but I was quite surprised to find that a localparam
can't be declared here, whereas a wire can.

But my final solution was:

..baz( {foo, id[3:0]} ), which the tools seem to like.

Regards,
Allan.
 
Allan Herriman <allan.herriman.hates.spam@ctam.com.au.invalid> wrote in message news:<icj130dieteeam7e2l35u05cn1rmjt530l@4ax.com>...
and at 'here' I would like to use the value of the genvar i, but with
a defined width (4 in this case) instead of 32 bits, such that the
concatenation {foo,i} is 8 bits wide.

Does anyone know how I can do this? I tried a bunch of things, but
none of them worked, either because they are illegal in Verilog, or
because the tools didn't support them.
The LRM says that the value of a genvar can be referenced in any
context where the value of a parameter could be referenced (I know,
because I proposed that text). That means that it should be legal
to take a part select of it. As with an integer or a parameter that
has no explicit range declaration, a genvar should have an implicit
range of [WIDTH-1:0], where WIDTH is the width of a genvar in the
particular implementation. So you should be able to get what you
want with {foo, i[3:0]}.

But that is a lot of "shoulds". Your tools may not support this.
Some implementers may not have interpreted the LRM this way, or
may have chosen not to implement it fully. It works fine in
NC-Verilog.
 
"John_H" <johnhandwork@mail.com> wrote in message news:<Zb6Yb.3$JR.7005@news-west.eli.net>...
I've had success with another synthesizer using something like:

.baz( {foo, 4'hf & i} ) // attempting to force the size
Only if your synthesizer is based on an incorrect interpretation of
the Verilog language. The expression (4'hf & i) will be as wide as
the wider operand, which is i. You can mask the excess bits of i to
zeroes, but that doesn't reduce the size.

.baz( foo<<4 | i ) // giving up on size and getting foo where I want
This should work, assuming the usual convention of truncating an overly
wide port expression to match the port width.
 
"Jonathan Bromley" <jonathan.bromley@doulos.com> wrote in message news:<c0qrn7$a0o$1$8300dec7@news.demon.co.uk>...
Spookily, I was frustrated today by almost exactly this - the
fact that you can't declare a localparam within a generate.
I am working on getting that changed. There is no reason they
shouldn't be allowed. And they are potentially useful to hold
the value of an expression involving a genvar, though I hadn't
thought of this particular situation.

How about you declare a net and assign to it?
That sounds like it might work, though it is annoying to have
to do something like that just to extract bits from a constant.
 
On 16 Feb 2004 19:19:02 -0800, sharp@cadence.com (Steven Sharp) wrote:
[snip]

Thanks Steve.

Any idea why the LRM doesn't allow localparams to be defined inside a
for - generate?

From a user's point of view, it makes sense to be able to define a
localparam wherever a wire or reg can be declared.

Thanks,
Allan.
 
Allan Herriman <allan.herriman.hates.spam@ctam.com.au.invalid> wrote in message news:<5o5330hvsfhosuqhu11nvskpom3he1uemt@4ax.com>...
From a user's point of view, it makes sense to be able to define a
localparam wherever a wire or reg can be declared.
Now that I think about it, localparam is the Verilog equivalent of a
C++ const, and yes, I agree that we should be declare them like wires
and regs.

--a
 
Allan Herriman <allan.herriman.hates.spam@ctam.com.au.invalid> wrote in message news:<5o5330hvsfhosuqhu11nvskpom3he1uemt@4ax.com>...
Any idea why the LRM doesn't allow localparams to be defined inside a
for - generate?
I don't know. I think this had already been specified before I started
participating in the standardization. I can only speculate how this
came about. There doesn't appear to be any technical reason for such
a restriction, so the possibility may just have been overlooked.

The issue came up recently as part of proposed changes to clarify the
specification of generates and interpret them in a way that is practical
to implement.

The meaning and behavior of a genvar reference within a generate-for is
not well specified. The original specification seemed to be based on
the idea that the references get replaced textually with numeric
constants in some kind of textual expansion of the loop, as if it could
be done by a macro preprocessor. In fact, it can't be done by a
macro preprocessor. Generates can depend on parameter values, which
can't be determined until well after the input text has been processed
into internal representations.

The alternate idea that the references to the genvar are to a single
object that somehow simultaneously has a different constant value in
different instances of the loop is bizarre. It doesn't match anything
else in the language (or any other that I am familiar with). An
identifier that has different values in different instances of the loop
implies multiple local versions of an object with that name. That is
exactly how VHDL deals with this situation in its generate-for construct.

So the proposal would specify that a generate-for contains an implicit
localparam with the same name as the genvar, and set to the value of the
genvar for that instance of the loop. A reference to the genvar name
inside the loop is actually a reference to this localparam, which holds
the desired different constant value in each instance. This still works
exactly the way you intuitively want it to work, but also precisely
defines what those genvar references mean. You can do anything with
them that you could do with a localparam, because they really are
references to a localparam. For example, since it is legal to use a
part select of a localparam, it is legal to say i[3:0] inside the loop.
You couldn't do this if i were textually replaced with a numeric
constant. Or you could pass i to VPI, and VPI can access it like a
normal localparam.

After you specify that a generate-for creates an implicit localparam
inside the loop, it becomes obvious that users should be able to
declare their own localparams inside the loop.
 

Welcome to EDABoard.com

Sponsor

Back
Top