Verlog 2001 signed numbers

K

Kevin Neilson

Guest
In Verilog-2001, there is signed number support. However, I'm not sure what
any of it actually does. You can declare registers as signed, but I don't
know how they are treated differently. You can assign a number a signed
value, like 16'shFF, but I don't know how that is different that assigning
16'hFF. I don't think it's possible, even with the new features, to assign
negative numbers to a register, like A <= -16'shAB.

There are also the $signed and $unsigned functions, but I can't see that
they work. I have a signed number that I want to output to a DAC, so I
used the $unsigned function, but Synplify seemed to ignore it even though
the feature is supported. (I implemented the feature by hand by inverting
the sign bit to make an unsigned number.)

The only new feature I can see that does anything is the arithmetic right
shift, or >>>. This is a syntactically nice way of shifting a number and
sign-extending it. But other than that, what do all the other features do?

-Kevin
 
"Kevin Neilson" <kevin_neilson@removethistextcomcast.net> wrote in message news:<x7Q2b.268731$Ho3.35401@sccrnsc03>...
In Verilog-2001, there is signed number support. However, I'm not sure what
any of it actually does. You can declare registers as signed, but I don't
know how they are treated differently. You can assign a number a signed
value, like 16'shFF, but I don't know how that is different that assigning
16'hFF.
Signed numbers aren't about different bits in the variables, they are
about how those bits are treated. Some operations in the language are
really two different operations: one that gets used on signed values,
and a different one that gets used on unsigned ones.

For example, consider division. If you take a 4-bit value with all
1 bits and divide it by the number 3, you will get different results
depending on whether you do unsigned or signed division. If you treat
these as unsigned values, you are dividing 15 by 3, and the result
should be 5. If you treat them as signed values, you are dividing
-1 by 3, which is 0 with a discarded remainder of -1.

Most operations in the language are actually the same for signed and
unsigned operands. That is why we use twos-complement representation,
because it means we can use the same hardware for signed and unsigned
operations.

Division is different, as noted above. The >>> operator you mentioned
is different also. It is an arithmetic shift in signed expressions, but
a logical shift in unsigned ones. The most important operation is
probably the automatic width-extension of operands to the width of the
expression. This is done with sign-extension in signed expressions
and zero-extension in unsigned ones.

For example, suppose you are building a multiplier that multiplies two
16-bit quantities together to produce a full 32-bit result. What really
happens in Verilog is that both factors are extended to 32 bits, and
then multiplied together. If the factors are sign-extended, then this
is effectively a signed multiply. If they are zero-extended, then it
is effectively an unsigned multiply.

The signedness of the operands (such as regs and constants), is used
to determine whether the expression is signed or unsigned. Generally,
if all of the operands are signed, then the expression is signed and
the operations are done signed. If any of them are unsigned, then
the expression is unsigned, and all operations are done unsigned.

I don't think it's possible, even with the new features, to assign
negative numbers to a register, like A <= -16'shAB.
Sure it is. But the value -16'shAB has the same bit pattern as the
value 16'hFF55 in twos-complement notation. There is no difference
in those two values stored in a 16-bit register. However, if A were
a 20-bit register, there is a difference in the values that would end
up being assigned. The signed value -16'shAB would get sign-extended
to 20 bits, so A would end up with the bit pattern 20'hFFF55. But if
you assigned A the unsigned value 16'hFF55, it would get zero-extended
to 20 bits, so A would end up with the bit pattern 20'h0FF55 instead.

There are also the $signed and $unsigned functions, but I can't see that
they work.
They aren't supposed to change the bits of the value. They change whether
the value is to be treated as signed or unsigned by the expression. They
are of limited use for that though. Unless you make sure that all of the
values in an expression are signed, the expression ends up unsigned anyway.
 

Welcome to EDABoard.com

Sponsor

Back
Top