Multipliers, dividers, adders etc....

A

asparnique

Guest
Hi,

Generally as nwbie with verilog, after sifting through a few relevant sites
I couldn't help noticing requests/aid/help on various implementations of
multipliers, dividers, look-ahead-carry adders .. and generally such things
that are widely used & necessary. However verilog does provide *, /, +, -
etc. as operators that will presumably be synthesizable into real hardware.
I presume different synthesis tools have different ways of generating and or
optimizing the hardware representing these common operations, so why should
there be a need to specifically use customized verilog code to implement
multipliers, dividers etc. ?? Is this an issue of IP ownership ? i.e. who
may/may not end up being the real owner of the generated hardware ?? Or do
people just prefer customising such operations for their specific
applications ? Can't see the real point of "re-inventing the wheel" if it's
there ...

M
 
On Wed, 30 Dec 2009 19:33:34 +0100, "asparnique" wrote:

Generally as nwbie with verilog, after sifting through a few relevant sites
I couldn't help noticing requests/aid/help on various implementations of
multipliers, dividers, look-ahead-carry adders .. and generally such things
that are widely used & necessary. However verilog does provide *, /, +, -
etc. as operators that will presumably be synthesizable into real hardware.
I presume different synthesis tools have different ways of generating and or
optimizing the hardware representing these common operations, so why should
there be a need to specifically use customized verilog code to implement
multipliers, dividers etc. ??
If you read answers to such posts here on comp.lang.verilog you will
generally see exactly the answer you would expect: At first, leave it
to the synthesis tool. It will usually do a good job. Only in very
extreme cases, where you have some wild or special requirement, it is
possible that the synthesis tool will miss an opportunity and you may
need to re-invent some wheels on its behalf. Even if synthesis
results are sub-optimal, if they are "good enough" (i.e. they meet
your area and timing requirements) then there is no need to improve
them manually.

The big exceptions to this are floating-point arithmetic, and
dividers. Bear in mind that synthesis must implement the operators
as logic that works in a single clock cycle. Both for FP and for /
there is no sensible combinatorial implementation; any realistic
hardware would perform the operation over multiple cycles, and
you must describe that operation explicitly to synthesis.

As has been pointed out on many occasions, synth tools are often
quite smart about pipelining operations when they get the chance.
For example:

reg [N-1:0] MultInA, MultInB;
reg [2*N-1:0] Quotient;

always @(posedge clock) begin
MultInA <= A;
MultInB <= B; // Register the multiplier's inputs
Quotient <= MultInA * MultInB; // Register its output
end

A synthesis tool can see that the result appears on Quotient
two clock cycles after it is presented on inputs A,B. It may
then choose to push the MultIn registers into the multiplier,
making it pipelined. The value on the primary output Quotient
remains correct after this is done; the values in MultIn...
are, however, very different from what you would see in simulation.
This is OK provided you don't use those input registers anywhere
else in the design.

This technique of "pushing logic through registers" is a neat
way of allowing synth tools the freedom to create pipelined
hardware.

Is this an issue of IP ownership ? i.e. who
may/may not end up being the real owner of the generated hardware ??
Not as far as I'm aware.

Or do people just prefer customising such operations for their
specific applications ? Can't see the real point of "re-inventing
the wheel" if it's there ...
Masochism is out there....
--
Jonathan Bromley
 
Hi,

Thanks for confirming what I was thinking. Generally I notice such verilog
code for *, /, + etc. is used a point of explaining the use of the language
and implementation with simulation in mind, and generally in text books. I
came across this in quite a few text books on verilog, and having a
background in C/C++ this was never an issue for obvious reasons. However it
is clearly possible to use either the synthesised *, / or +, - for the
specific device Altera, Xilinx etc. or code your own verilog as you wish.
The later is generally not what I was after, as I wish to spend my energy &
time on the implementation of the actual application and the algorithms etc,
and leave the rest to the simulation and synthesisers to implement etc.
With regards to floating point, well if one can get away with integers, that
is perfectly fine with me. However division is also an operator in the same
context as *, so would it be so much different for the synthesisers to
produce an optimised (for speed or gate count) divide operation ?? Just
wondering ...

Regards, M

"Jonathan Bromley" wrote in message
news:fsjnj5l5shl0ulu28r5dmpidjmnp4luo9r@4ax.com...
On Wed, 30 Dec 2009 19:33:34 +0100, "asparnique" wrote:

Generally as nwbie with verilog, after sifting through a few relevant
sites
I couldn't help noticing requests/aid/help on various implementations of
multipliers, dividers, look-ahead-carry adders .. and generally such
things
that are widely used & necessary. However verilog does provide *, /, +, -
etc. as operators that will presumably be synthesizable into real
hardware.
I presume different synthesis tools have different ways of generating and
or
optimizing the hardware representing these common operations, so why
should
there be a need to specifically use customized verilog code to implement
multipliers, dividers etc. ??

If you read answers to such posts here on comp.lang.verilog you will
generally see exactly the answer you would expect: At first, leave it
to the synthesis tool. It will usually do a good job. Only in very
extreme cases, where you have some wild or special requirement, it is
possible that the synthesis tool will miss an opportunity and you may
need to re-invent some wheels on its behalf. Even if synthesis
results are sub-optimal, if they are "good enough" (i.e. they meet
your area and timing requirements) then there is no need to improve
them manually.

The big exceptions to this are floating-point arithmetic, and
dividers. Bear in mind that synthesis must implement the operators
as logic that works in a single clock cycle. Both for FP and for /
there is no sensible combinatorial implementation; any realistic
hardware would perform the operation over multiple cycles, and
you must describe that operation explicitly to synthesis.

As has been pointed out on many occasions, synth tools are often
quite smart about pipelining operations when they get the chance.
For example:

reg [N-1:0] MultInA, MultInB;
reg [2*N-1:0] Quotient;

always @(posedge clock) begin
MultInA <= A;
MultInB <= B; // Register the multiplier's inputs
Quotient <= MultInA * MultInB; // Register its output
end

A synthesis tool can see that the result appears on Quotient
two clock cycles after it is presented on inputs A,B. It may
then choose to push the MultIn registers into the multiplier,
making it pipelined. The value on the primary output Quotient
remains correct after this is done; the values in MultIn...
are, however, very different from what you would see in simulation.
This is OK provided you don't use those input registers anywhere
else in the design.

This technique of "pushing logic through registers" is a neat
way of allowing synth tools the freedom to create pipelined
hardware.

Is this an issue of IP ownership ? i.e. who
may/may not end up being the real owner of the generated hardware ??

Not as far as I'm aware.

Or do people just prefer customising such operations for their
specific applications ? Can't see the real point of "re-inventing
the wheel" if it's there ...

Masochism is out there....
--
Jonathan Bromley
 
On Thu, 31 Dec 2009 14:04:46 +0100, "asparnique" wrote:

is clearly possible to use either the synthesised *, / or +, - for the
specific device Altera, Xilinx etc. or code your own verilog as you wish.
The later is generally not what I was after, as I wish to spend my energy &
time on the implementation of the actual application and the algorithms etc,
and leave the rest to the simulation and synthesisers to implement etc.
Agreed 100%. Don't keep a dog and bark yourself.

With regards to floating point, well if one can get away with integers, that
is perfectly fine with me. However division is also an operator in the same
context as *, so would it be so much different for the synthesisers to
produce an optimised (for speed or gate count) divide operation ?? Just
wondering ...
Well..... Others may correct me here, but I think this is
roughly right.... It is comparatively easy to parallelize
many of the various operations required for a multiplication,
but division is inherently sequential and therefore the hardware
required to perform a combinational divide operation is likely to
have very long combinational delay paths in it. Consequently,
divide blocks are almost always designed to work over a number
of clock cycles, and therefore can't be represented by the /
operator in standard RTL synthesis. On the other hand,
fully combinational multipliers are possible and well-known
(albeit quite large and complicated), so a synthesisable *
operator makes good sense. This is, of course, especially
true in the many modern FPGAs that have dedicated fast
multiplier blocks on-chip.

It may be that there are synthesis tools that can infer
combinational hardware from the / operator, but I'm not
aware of any myself.

Of course, divide by a constant power of 2 is a simple
right shift and can be synthesised by most tools.
--
Jonathan Bromley
 

Welcome to EDABoard.com

Sponsor

Back
Top