Verilog2001 $signed question

D

Davy

Guest
Hi all,

How can I multiply a signed operand with a unsigned operand?

Code:
input [7:0] a;
input signed [7:0] b;
output signed [15:0] z;


Code:
assign z = $signed({1'b0,a}) * b;


or

Code:
assign z = $signed(a) * b;


And why?

Thanks!
Davy
 
On 11 Jun 2006 19:05:00 -0700, "Davy" <zhushenli@gmail.com> wrote:

Hi all,

How can I multiply a signed operand with a unsigned operand?

Code:
input [7:0] a;
input signed [7:0] b;
output signed [15:0] z;


Code:
assign z = $signed({1'b0,a}) * b;


or

Code:
assign z = $signed(a) * b;


And why?
The former because the spec says that result of a signed op unsigned
expression is unsigned so you need to make "a" also a signed variable.
 
Davy wrote:
How can I multiply a signed operand with a unsigned operand?

Code:
input [7:0] a;
input signed [7:0] b;
output signed [15:0] z;


Code:
assign z = $signed({1'b0,a}) * b;
This will give you the effect of multiplying a*b with a treated as its
unsigned value, and b treated as its signed value.

Code:
assign z = $signed(a) * b;
This will give you the effect of multiplying a*b with both treated as
signed values.

Signed and unsigned multiplication are only different if you consider
"widening" multiplies, where the result is wider than the input
operands. There is no actual difference between signed and unsigned
multiplication if the multiplication is "non-widening", i.e. if the
result is the same width as the two input operands. All multiplication
in Verilog is actually "non-widening", since the operands are extended
to the width of the result before multiplying. It is this extension of
the operands that gives the same effect as a "widening" multiply. And
what determines whether the effect of that "widening" multiply acts
like a signed or unsigned multiply is whether the operands are
sign-extended or zero-extended.

If you sign-extend both operands, then it will act like a signed
widening multiply. That is what happens in your second code example.
In your first example, it still does a sign-extension. However, you
have explicitly zero-extended a by one bit first, so the sign bit is
zero. Then the sign-extension of the concatenation becomes a
zero-extension of a. Since you zero-extended a and sign-extended b,
you get the effect of a mixed unsigned/signed multiply.

If you left the $signed off of a, then the Verilog rules for mixed
signed/unsigned operands would kick in, and both a and be would be
treated as unsigned and zero-extended. This would give you the effect
of an unsigned multiply.

The cases you have given are simple enough that you don't really need
to understand the details of the Verilog operations. It is enough to
know that in the second case, you have asked it to treat a as signed
for the multiply. In the first case, you have told it to treat a as
signed, but only after adding a zero sign bit to make it positive.
 
Hi sharp,

Thanks!

So if the
input [7:0] a = 8'b1xxx_xxxx;
$signed(a) is a negative number, while $signed({1'b0,a}) is a positive
number, is it right?

Best regards,
Davy

sharp@cadence.com wrote:
Davy wrote:
How can I multiply a signed operand with a unsigned operand?

Code:
input [7:0] a;
input signed [7:0] b;
output signed [15:0] z;


Code:
assign z = $signed({1'b0,a}) * b;

This will give you the effect of multiplying a*b with a treated as its
unsigned value, and b treated as its signed value.

Code:
assign z = $signed(a) * b;

This will give you the effect of multiplying a*b with both treated as
signed values.

And why?

Signed and unsigned multiplication are only different if you consider
"widening" multiplies, where the result is wider than the input
operands. There is no actual difference between signed and unsigned
multiplication if the multiplication is "non-widening", i.e. if the
result is the same width as the two input operands. All multiplication
in Verilog is actually "non-widening", since the operands are extended
to the width of the result before multiplying. It is this extension of
the operands that gives the same effect as a "widening" multiply. And
what determines whether the effect of that "widening" multiply acts
like a signed or unsigned multiply is whether the operands are
sign-extended or zero-extended.

If you sign-extend both operands, then it will act like a signed
widening multiply. That is what happens in your second code example.
In your first example, it still does a sign-extension. However, you
have explicitly zero-extended a by one bit first, so the sign bit is
zero. Then the sign-extension of the concatenation becomes a
zero-extension of a. Since you zero-extended a and sign-extended b,
you get the effect of a mixed unsigned/signed multiply.

If you left the $signed off of a, then the Verilog rules for mixed
signed/unsigned operands would kick in, and both a and be would be
treated as unsigned and zero-extended. This would give you the effect
of an unsigned multiply.

The cases you have given are simple enough that you don't really need
to understand the details of the Verilog operations. It is enough to
know that in the second case, you have asked it to treat a as signed
for the multiply. In the first case, you have told it to treat a as
signed, but only after adding a zero sign bit to make it positive.
 

Welcome to EDABoard.com

Sponsor

Back
Top