Using a `define multiple times on single line gives weird re

A

ajcrm125

Guest
If I ty something like this:

`define SIZE 5

wire msbs_are_zero;
wire [0:`SIZE-1] data;

// should result to:
//assign msbs_are_zero = (data[0:3] == 4'b0000);
assign msbs_are_zero = (data[0:`SIZE-2] == `SIZE-1'b0000);


I get an error like "redundant digits in numeric numeral" (MTI) or
"too many digits in binary" (Debussy) which leads me to believe the
2nd evaluation of `SIZE is not 5.

I know I can get around this by coding it differently but I coded it
specifically for testing a theory when the RTL failed formal
equivalence.

Any ideas what the compilers are doing here? Maybe there's something
in the standard I'm missing?
 
On Dec 10, 3:08 pm, ajcrm125 <ajcrm...@gmail.com> wrote:
If I ty something like this:

`define SIZE 5

wire msbs_are_zero;
wire [0:`SIZE-1] data;

// should result to:
//assign msbs_are_zero = (data[0:3] == 4'b0000);
assign msbs_are_zero = (data[0:`SIZE-2] == `SIZE-1'b0000);

I get an error like "redundant digits in numeric numeral" (MTI) or
"too many digits in binary" (Debussy) which leads me to believe the
2nd evaluation of `SIZE is not 5.

I know I can get around this by coding it differently but I coded it
specifically for testing a theory when the RTL failed formal
equivalence.

Any ideas what the compilers are doing here? Maybe there's something
in the standard I'm missing?
If instead you use a parameter, does it still fail? E.g.
parameter SIZE = 5; then get rid of the backtick?
- Mark
 
ajcrm125 wrote:
If I ty something like this:

`define SIZE 5

wire msbs_are_zero;
wire [0:`SIZE-1] data;

// should result to:
//assign msbs_are_zero = (data[0:3] == 4'b0000);
assign msbs_are_zero = (data[0:`SIZE-2] == `SIZE-1'b0000);


I get an error like "redundant digits in numeric numeral" (MTI) or
"too many digits in binary" (Debussy) which leads me to believe the
2nd evaluation of `SIZE is not 5.

I know I can get around this by coding it differently but I coded it
specifically for testing a theory when the RTL failed formal
equivalence.

Any ideas what the compilers are doing here? Maybe there's something
in the standard I'm missing?
After substitution, `SIZE-1'b0000 becomes

5-1'b0000

which is equal to 5, not zero. So then msbs_are_zero gets asserted when
data[0:3] is 5.

The easiest solution here is to just leave the zero unsized. That is,
just write:

assign msbs_are_zero = (data[0:`SIZE-2] == 0);

This will work just fine. The unsized zero will become a 32- or 64-bit
zero and only the bottom four bits will be used for the comparison.
This is Verilog, so you don't have to worry about making sure all the
sizes of the arguments match, like you would with VHDL.

If you really want to have the zero sized properly, you must use the
Verilog replicator construct:


assign msbs_are_zero = (data[0:`SIZE-2] == {(`SIZE-1){1'b0}});

Some other suggestions: use parameters instead of `defines. Also,
convention states buses should be written msb first, as in
wire [3:0] data;

-Kevin
 
On Dec 10, 3:47 pm, Kevin Neilson
<kevin_neil...@removethiscomcast.net> wrote:
ajcrm125 wrote:
If I ty something like this:

`define SIZE 5

wire msbs_are_zero;
wire [0:`SIZE-1] data;

// should result to:
//assign msbs_are_zero = (data[0:3] == 4'b0000);
assign msbs_are_zero = (data[0:`SIZE-2] == `SIZE-1'b0000);

I get an error like "redundant digits in numeric numeral" (MTI) or
"too many digits in binary" (Debussy) which leads me to believe the
2nd evaluation of `SIZE is not 5.

I know I can get around this by coding it differently but I coded it
specifically for testing a theory when the RTL failed formal
equivalence.

Any ideas what the compilers are doing here? Maybe there's something
in the standard I'm missing?

After substitution, `SIZE-1'b0000 becomes

5-1'b0000

which is equal to 5, not zero. So then msbs_are_zero gets asserted when
data[0:3] is 5.

The easiest solution here is to just leave the zero unsized. That is,
just write:

assign msbs_are_zero = (data[0:`SIZE-2] == 0);

This will work just fine. The unsized zero will become a 32- or 64-bit
zero and only the bottom four bits will be used for the comparison.
This is Verilog, so you don't have to worry about making sure all the
sizes of the arguments match, like you would with VHDL.

If you really want to have the zero sized properly, you must use the
Verilog replicator construct:

assign msbs_are_zero = (data[0:`SIZE-2] == {(`SIZE-1){1'b0}});

Some other suggestions: use parameters instead of `defines. Also,
convention states buses should be written msb first, as in
wire [3:0] data;

-Kevin
That is true... inless you work for IBM. :) Our entire PowerPC and
CoreConnect architecture is big endian. (I.E. MSB is 0)
I can't stand it... but I don't get to make da'rules. :-D
 
ajcrm125 wrote:

(snip)

== {(`SIZE-1){1'b0}});

Some other suggestions: use parameters instead of `defines. Also,
convention states buses should be written msb first, as in
wire [3:0] data;

That is true... inless you work for IBM. :) Our entire PowerPC and
CoreConnect architecture is big endian. (I.E. MSB is 0)
I can't stand it... but I don't get to make da'rules. :-D
S/360 (and successors) are also big endian with the MSB bit 0.

It is especially interesting to see how they went to 64 bit
z/Architecture by renumbering the bits. The 32 bit registers
are the low half of 64 bit registers, with bits numbered 32:63.

I did once have to write a bit reverser in verilog, and found
you can't do it by reversing the start and end. You have to
write out all the bits.

-- glen
 
glen herrmannsfeldt wrote:
ajcrm125 wrote:

(snip)

assign msbs_are_zero = (data[0:`SIZE-2] == {(`SIZE-1){1'b0}});

Some other suggestions: use parameters instead of `defines. Also,
convention states buses should be written msb first, as in
wire [3:0] data;

That is true... inless you work for IBM. :) Our entire PowerPC and
CoreConnect architecture is big endian. (I.E. MSB is 0)
I can't stand it... but I don't get to make da'rules. :-D

S/360 (and successors) are also big endian with the MSB bit 0.

It is especially interesting to see how they went to 64 bit
z/Architecture by renumbering the bits. The 32 bit registers
are the low half of 64 bit registers, with bits numbered 32:63.

I did once have to write a bit reverser in verilog, and found
you can't do it by reversing the start and end. You have to
write out all the bits.

-- glen

That's true. I've seen it written as a function, though, which makes it
a bit less ugly. I.e., bus_b = bitreverse(bus_a, 32 /* # of bits in bus*/);

I remember working on some board and we'd switched from a little-endian
controller to big-endian PowerPC Motorola controller. On the first pass
of the PCB we had a bunch of reversed buses. Thanks, IBM! It's
probably an IBM legacy issue based on how Herman Hollerith's designed
his tabulating machine.
-Kevin
 
On Dec 10, 3:08 pm, ajcrm125 <ajcrm...@gmail.com> wrote:
If I ty something like this:

`define SIZE 5

wire msbs_are_zero;
wire [0:`SIZE-1] data;

// should result to:
//assign msbs_are_zero = (data[0:3] == 4'b0000);
assign msbs_are_zero = (data[0:`SIZE-2] == `SIZE-1'b0000);

I get an error like "redundant digits in numeric numeral" (MTI) or
"too many digits in binary" (Debussy) which leads me to believe the
2nd evaluation of `SIZE is not 5.
It is 5 all right. The issue is that the substitution comes out to

5-1'b0000

which is treated as

5-(1'b0000)

and the tools are complaining about you specifying 4 bits of 0 in a 1-
bit-wide literal.

You cannot even explicitly specify (`SIZE-1)'b0000. The width field
of a literal must be decimal digits, not an expression. A literal is
a simple numeric constant, not a complex operator for building
constants out of expressions. If you want to build a constant from
expressions using an operator, you can use a multiple-concatenation:
{(`SIZE-1){1'b0}}. Or you can just use a simple 0 and rely on the
implicit width conversion rules instead of trying to specify it
precisely.
 
Kevin Neilson wrote:

(snip on bit numbering)

I remember working on some board and we'd switched from a little-endian
controller to big-endian PowerPC Motorola controller. On the first pass
of the PCB we had a bunch of reversed buses. Thanks, IBM! It's
probably an IBM legacy issue based on how Herman Hollerith's designed
his tabulating machine.
Numbering the MSB zero is consistent with big endian byte ordering.

Even though there aren't any instructions with bit addressing, it is
still nice to see the documentation consistent. I believe that STRETCH
did have some bit addressing, though.

-- glen
 
On Dec 10, 12:47 pm, Kevin Neilson
<kevin_neil...@removethiscomcast.net> wrote:
ajcrm125 wrote:
If I ty something like this:

`define SIZE 5

wire msbs_are_zero;
wire [0:`SIZE-1] data;

// should result to:
//assign msbs_are_zero = (data[0:3] == 4'b0000);
assign msbs_are_zero = (data[0:`SIZE-2] == `SIZE-1'b0000);

I get an error like "redundant digits in numeric numeral" (MTI) or
"too many digits in binary" (Debussy) which leads me to believe the
2nd evaluation of `SIZE is not 5.

I know I can get around this by coding it differently but I coded it
specifically for testing a theory when the RTL failed formal
equivalence.

Any ideas what the compilers are doing here? Maybe there's something
in the standard I'm missing?

After substitution, `SIZE-1'b0000 becomes

5-1'b0000

which is equal to 5, not zero. So then msbs_are_zero gets asserted when
data[0:3] is 5.

The easiest solution here is to just leave the zero unsized. That is,
just write:

assign msbs_are_zero = (data[0:`SIZE-2] == 0);

This will work just fine. The unsized zero will become a 32- or 64-bit
zero and only the bottom four bits will be used for the comparison.
This is Verilog, so you don't have to worry about making sure all the
sizes of the arguments match, like you would with VHDL.

If you really want to have the zero sized properly, you must use the
Verilog replicator construct:

assign msbs_are_zero = (data[0:`SIZE-2] == {(`SIZE-1){1'b0}});

Some other suggestions: use parameters instead of `defines. Also,
convention states buses should be written msb first, as in
wire [3:0] data;

-Kevin
As Kevin pointed out:
After substitution, `SIZE-1'b0000 becomes

5-1'b0000

Looking at this, you have 5 - 1'b0000

1'b0000 has too many digits - this is the source of the warning.

As he also pointed out, the RHS turns into a value of 5 which is not
the value you want.

John Providenza
 

Welcome to EDABoard.com

Sponsor

Back
Top