What happened to the bit-width of sum of multiplication?

M

Mr. Ken

Guest
// -----------------------
input [7:0] a, b;
output [16:0] c; // 0~131072

reg [16:0] c;

always @(clock)
c = (a * a) + (b * b); // 255*255*2 = 130050
//------------------------


When I run syntax checking, it returns a warning of unequal bitwidth in
assignment.

How can I fix this warning?
 
In Verilog, the width of the result of a binary operation is the
maximum width of the operands. In your case, each operand is 8 bits so
the result of the multiplication will be 8 bits. When you add the two
8-bit numbers, the result will also be 8 bits. To get the 16-bit
result, you need to make things 16 bits wide so use something like...

c = (a * (a + 16'h0)) + (b * (b + 16'h0));

David Walker

On Dec 18, 7:35 am, "Mr. Ken" <Mr....@novice.com> wrote:
// -----------------------
input [7:0] a, b;
output [16:0] c; // 0~131072

reg [16:0] c;

always @(clock)
c = (a * a) + (b * b); // 255*255*2 = 130050
//------------------------

When I run syntax checking, it returns a warning of unequal bitwidth in
assignment.

How can I fix this warning?
 
dbwalker0min@gmail.com wrote:
In Verilog, the width of the result of a binary operation is the
maximum width of the operands.
Actually, it is the width of the "context", or expression in which it
appears (for operands which are "context determined", which depends on
the operator). Operands of multiplication and addition are context
determined. And in the case of an assignment, the left-hand-side is
considered to be part of the context for the expression on the
right-hand-side.

In your case, each operand is 8 bits so
the result of the multiplication will be 8 bits. When you add the two
8-bit numbers, the result will also be 8 bits.
But the LHS is 17 bits, so the result of the multiplications will be 17
bits, as will the result of the addition.

To get the 16-bit
result, you need to make things 16 bits wide so use something like...

c = (a * (a + 16'h0)) + (b * (b + 16'h0));
This is unnecessary. The rules in Verilog were designed to make this
unnecessary. There are a few situations where something like this is
needed, but this is not one of them.

On Dec 18, 7:35 am, "Mr. Ken" <Mr....@novice.com> wrote:

When I run syntax checking, it returns a warning of unequal bitwidth in
assignment.

How can I fix this warning?
I don't know. Your tool may not be implementing the Verilog expression
width rules correctly. Or we may not be understanding the meaning of
the warning.
 
I confused self-determined expressions with context-determine
expressions. Thanks.

David Walker

sharp@cadence.com wrote:
dbwalker0min@gmail.com wrote:
In Verilog, the width of the result of a binary operation is the
maximum width of the operands.

Actually, it is the width of the "context", or expression in which it
appears (for operands which are "context determined", which depends on
the operator). Operands of multiplication and addition are context
determined. And in the case of an assignment, the left-hand-side is
considered to be part of the context for the expression on the
right-hand-side.

In your case, each operand is 8 bits so
the result of the multiplication will be 8 bits. When you add the two
8-bit numbers, the result will also be 8 bits.

But the LHS is 17 bits, so the result of the multiplications will be 17
bits, as will the result of the addition.

To get the 16-bit
result, you need to make things 16 bits wide so use something like...

c = (a * (a + 16'h0)) + (b * (b + 16'h0));

This is unnecessary. The rules in Verilog were designed to make this
unnecessary. There are a few situations where something like this is
needed, but this is not one of them.

On Dec 18, 7:35 am, "Mr. Ken" <Mr....@novice.com> wrote:

When I run syntax checking, it returns a warning of unequal bitwidth in
assignment.

How can I fix this warning?

I don't know. Your tool may not be implementing the Verilog expression
width rules correctly. Or we may not be understanding the meaning of
the warning.
 
Hi experts....

Multiplication....of 8 bit width register with 8 bit register will it
not give....16bit result.....for...eg....if we multiply
.....250*249=62,250 [ 111 10011 0010 1010] ( 15bits width...)...Please
clarify my Doubt..
 
On 20 Dec 2006 20:53:06 -0800, vlnaran@gmail.com wrote:

Multiplication....of 8 bit width register with 8 bit register will it
not give....16bit result.....for...eg....if we multiply
....250*249=62,250 [ 111 10011 0010 1010] ( 15bits width...).
If you multiply an 8-bit *number* by another 8-bit *number*,
you need 16 bits to hold the largest possible result.

However, that's not the way the Verilog language thinks about it.

Here's a sensible design fragment...

reg [15:0] product; // 16-bit reg to hold result
reg [7:0] v1, v2; // two 8-bit values to multiply together
//
product = v1 * v2;

In this case, Verilog looks at all three operands (product, v1, v2)
and finds which of them has the largest number of bits. Clearly
in this case that's "product", which is 16 bits wide. Verilog then
widens all the operands to that width. Consequently, the
calculation that Verilog *really* performs is...

product = {8'b0, v1} * {8'b0, v2};

multiplying two 16-bit values together and copying the result
into a 16-bit register. In this situation there will be no loss
of data even if v1 and v2 both hold the largest possible value.

But now consider this...

reg [9:0] badProduct;
//
badProduct = v1 * v2;

In this case, the widest operand is only 10 bits wide. So we
extend v1 and v2 to 10 bits, and do this calculation:

badProduct = {2'b0, v1} * {2'b0, v2};

Now, of course, if the result is larger than 1023 we will lose
some most-significant digits; the result has overflowed, and
Verilog's standard copying rules say that the most-significant
bits that don't fit into badProduct are simply thrown away.

This is just the way Verilog is defined to work. It is very,
very helpful in some situations; it is awkward and error-prone
in other situations. Provided you know what is happening,
all should be well. Steven Sharp (who replied earlier in this
thread) has written many excellent and authoritative posts
on this tricky issue over the past few years, and I'm happy
to acknowledge my debt to him for clarifying some of the
most difficult areas.
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
"Jonathan Bromley" <jonathan.bromley@MYCOMPANY.com> wrote in message
news:416lo2d2h6d5nk8isa5b709m2775pf9nqj@4ax.com...
On 20 Dec 2006 20:53:06 -0800, vlnaran@gmail.com wrote:

Multiplication....of 8 bit width register with 8 bit register will it
not give....16bit result.....for...eg....if we multiply
....250*249=62,250 [ 111 10011 0010 1010] ( 15bits width...).

If you multiply an 8-bit *number* by another 8-bit *number*,
you need 16 bits to hold the largest possible result.

However, that's not the way the Verilog language thinks about it.

Here's a sensible design fragment...

reg [15:0] product; // 16-bit reg to hold result
reg [7:0] v1, v2; // two 8-bit values to multiply together
//
product = v1 * v2;

In this case, Verilog looks at all three operands (product, v1, v2)
and finds which of them has the largest number of bits. Clearly
in this case that's "product", which is 16 bits wide. Verilog then
widens all the operands to that width. Consequently, the
calculation that Verilog *really* performs is...

product = {8'b0, v1} * {8'b0, v2};

multiplying two 16-bit values together and copying the result
into a 16-bit register. In this situation there will be no loss
of data even if v1 and v2 both hold the largest possible value.
Regarding synthesis, design compiler and Xilinx only implement unsigned
multiplier
with two 8-bit operands, is it true?
 
"Mr. Ken" <Mr.Ken@novice.com> wrote in message news:em67uf$ajv$1@reader01.singnet.com.sg...
// -----------------------
input [7:0] a, b;
output [16:0] c; // 0~131072

reg [16:0] c;

always @(clock)
c = (a * a) + (b * b); // 255*255*2 = 130050
//------------------------


When I run syntax checking, it returns a warning of unequal bitwidth in assignment.


How can I fix this warning?
As others have pointed out, there is no problem with your expression, and I am sure both simulation and synthesis results will
match.
So you would simply ignore this warning (the tool that produced it drew an incorrect conclusion)
Which tool did you use that produces this warning ?

 

Welcome to EDABoard.com

Sponsor

Back
Top