Re: B19 - Signed arithmetic

From: Elliot Mednick (elliot@wellspring.com)
Date: Fri May 09 1997 - 11:58:32 PDT


Here is my opinion on Signed Arithmetic for Verilog.

STATEMENT
I agree that signed arithmetic should be part of the Verilog language. I do
not agree with the proposed implementation.

SUMMARY
There are (at least) two ways to represent signed arithmetic in a
programming language: using signed operands and using signed operators. B19
takes the signed operand approach. I strongly feel that Verilog should use
signed operators to implement signed arithmetic.

ARGUMENT
Most high-level languages, like C, implement signed arithmetic by
introducing the signed data type. This overloads the operator. For
instance, there are really two integer divide operators, one for signed and
one for unsigned (and one for real, one for double, etc.). This is fine for
a "real" programming language, where the intent is to "program" or control
something. In C, data type abstraction is a Good Thing and hiding details
is good.

Verilog, by contrast, is used to "describe" something. Verilog code is
written as a description of some hardware. The fact that it is executed is
really secondary. It is executed only to test the description. The real
value in Verilog code is that it is later parsed -- by synthesis tools or by
humans who use Verilog code as an "executable specifications". Thus, we
need to see as much as possible what is going on in the code and not hide
anything. (The exception to this is for architectural-level code which
indeed to for execution, so, in this case only, abstract data types are Good.)

So, in Verilog, the data types correlate to some aspect of hardware. Under
the right circumstances, the data type "reg" describes, indeed, a hardware
register. Hardware registers are containers, descriptions. When we
describe a register, we don't care what's in them. Thus, there is no
concept of "signed" and "unsigned". When you draw a schematic of a
register, you don't lay a "signed D flop".

What you *do* draw are signed operators. There is a difference between a
signed divide unit and an unsigned divide unit.

Lets take a general case. Say you are designing an ALU (Arithmetic Logic
Unit). The ALU contains a number of arithmetic functions like addition,
subtraction, divide, multiple -- all signed and unsigned. The ALU is fed by
a register file. If you are writing the Verilog code to describe this, do
you make the register file signed? Or unsigned? My answer in neither; you
make the operators signed and unsigned.

By adding signed registers to the language, the whole language suddenly gets
more complex. You need rules for data promotion and conversion, and all the
overloading rules. Mapping signed registers to hardware is a problem and
synthesis is a problem.

In contrast, by adding signed *operators* to the language, implementation is
simple -- almost, but not quite trivial -- and the usage is also
straightforward.

There is precedence for this method. An early hardware description language
called ISP (Instruction Set Processor) was described in Siewiorek, Bell, and
Newell's book _COMPUTER STRUCTURES; PRINCIPLES AND EXAMPLES_. (I'm in the
process of moving, so the book is temporarily packed away. I'll try to get
it out in the next couple of weeks.) In it, they used a concept of operator
modifiers. Signed/unsigned is one of the modifiers.

So, I informally propose (that is, I propose the concept but I am not
proposing the actually wording) that we reject B19 and add the following
operators to the Verilog language:

igned multiply
signed divide
signed relational operators
signed right shift (sign extend)
(Are there others?)

If two unequal-length registers are being combined using a signed operator,
then the smallest is extended, using the general rules of expression
lengths, except using sign extension. Negative numbers are defined as the
high bit of the operand being set and the rest of the bits are twos compliment.

As for syntax, I am open, but propose either of these two:

igned multiply :* `*
signed divide :/ `/
signed relational operators :> :< :>= :<= `> `< `>= `<=
signed right shift :>> `>>

I slightly prefer the back tick because it makes it look like a compiler
modifier. I can understand arguments against it, since back ticks are now
used as macros and compiler directives, but I think that the modification to
the lexical analyzer of a Verilog tool would be trivial.

I would optionally add the `signed and `unsigned compiler directives to
delimit regions which modify all operators past the directive. Thus:

`signed
snafu = foo / bar; // this is a signed divide.

This greatly reduces the problem of signed arithemtic, makes it easy to
implement, easy to use, easy to read, easy to write and easy to synthesize.
I think it also makes PLI implementation easier because it only requires a
few -- optional -- utility functions. No data types are added or changed.

Best Regards,
--Elliot

--
Elliot Mednick                                      P.O. Box 150
Wellspring Solutions, Inc.                          Sutton, MA.  01590
                                                    (508) 865-7271
<elliot@wellspring.com>                             (508) 865-1113 [fax]


This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:54:40 PDT and
sponsored by Boyd Technology, Inc.