Can anyone point me at a decent binary divide function. It doesn't have
to deal with remainders, although that might be a plus later on down the
line. I assume I could subtract B from A a bunch of times, but that seems
awfully inefficient.
Thanks,
MikeC
--
Michael D. Callaghan Hudson, New Hampshire mi...@mv.mv.com
------------------------------------------------------------------
To see a complete list of Computer Hardware and Software currently
available, simply issue the command: "finger -l mi...@mv.mv.com".
> I'm synthesizing a VHDL design right now using Synario. It's choking
> on my C := A/B function. A & B are std_logic_vector (15 downto 0). They
> are converted to signed integers, and then divided. It won't synthesize.
>
> Can anyone point me at a decent binary divide function. It doesn't have
> to deal with remainders, although that might be a plus later on down the
> line. I assume I could subtract B from A a bunch of times, but that seems
> awfully inefficient.
Just taking a guess here, but if C is an integer type you need to use
something like
C := A mod B
so that you don't end up with a fractional part.
--
damir smitlener |
da...@mindspring.com |
smi...@optica.mirc.gatech.edu |
Mike> I'm synthesizing a VHDL design right now using Synario. It's
Mike> choking on my C := A/B function. A & B are std_logic_vector
Mike> (15 downto 0). They are converted to signed integers, and
Mike> then divided. It won't synthesize.
You didn't mention which synthesis program you're using, but the Viewlogic
VHDL Synthesis manual (for example) states that:
a) multiplication, division, MOD, and REM of constants is allowed (duh)
b) multiplication, division, MID, and REM is supported if the second
operand is a constant and a power of 2
c) multiplication, division, MOD, and REM is not supported if both
operands are variables or signals.
Bummer,
Kelly
--
Kelly Hall <ha...@lal.cs.byu.edu>
http://lal.cs.byu.edu/people/hall.html
: Mike> I'm synthesizing a VHDL design right now using Synario. It's
: Mike> choking on my C := A/B function. A & B are std_logic_vector
: Mike> (15 downto 0). They are converted to signed integers, and
: Mike> then divided. It won't synthesize.
: You didn't mention which synthesis program you're using, but the Viewlogic
: VHDL Synthesis manual (for example) states that:
: a) multiplication, division, MOD, and REM of constants is allowed (duh)
: b) multiplication, division, MID, and REM is supported if the second
: operand is a constant and a power of 2
: c) multiplication, division, MOD, and REM is not supported if both
: operands are variables or signals.
I'm sure someone will find an exception to this, but here goes anyway...
You won't find a combinatorial divider in any synthesis tool. Like the
multiplier, the divider is a big circuit, but the divider is much
slower, proportional to n^2 with 2 n-bit inputs. Probably someone has
used a combinatorial divider somewhere, but it is hard to think of a
situation where its price/performance is acceptable.
If you need the answer in a single clock cycle, you could look up the
reciprocal, and use a combinatorial multiplier. If this is for an ASIC,
hope your vendor supports embedded ROM's; you probably don't want to
synthesize the table with your 16-bit input. This approach pre-supposes
your synthesis vendor supports C<=A*B; Synopsys does.
A variation of the above is to look up an approximate reciprocal, and
refine it using some Newton-whoever numerical method technique. If
you're like me, you don't remember anything from "Applied Numerical
Methods"... This method will burn a few clock cycles.
If you have lots of clock cycles, binary long division can be
implemented quite cheaply. There are a number of ways to speed this up,
at some gate expense. An nice feature is you get the remainder for
free.
If this division is part of a larger calculation, be sure to do it last.
Integer division has a way of leaving quotients with hardly any
significant digits.
Hope this helps.
--
Kevin D. Libby kli...@ede.sanders.lockheed.com
Sanders: NCA1-4266, 95 Canal St, Nashua, NH 03061-0868
"I'm synthesizing a VHDL design right now using Synario. It's choking
"on my C := A/B function. A & B are std_logic_vector (15 downto 0). They
"are converted to signed integers, and then divided. It won't synthesize.
"
"Can anyone point me at a decent binary divide function. It doesn't have
"to deal with remainders, although that might be a plus later on down the
"line. I assume I could subtract B from A a bunch of times, but that seems
"awfully inefficient. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"
That's the right idea, but normalise B by shifting to the left (by
m bits) until the MSB is "1". Then, if B>A, shift right by n bits
until A>B. Put a "1" in bit m-n of the result. Then subtract B from A.
Now do the whole thing again on the remainder. i.e. binary long
division!
Many refinements are possible, for example, if you shift A and keep
B still, you can use the other end of the same register to hold the
result.
Or something.
-- David Pashley <
------------------------ < < < ---------- Email: da...@fpga.demon.co.uk
| Direct Insight Ltd < < < < > Tel: +44 1280 700262 |
| *The EDA Source* < < < Fax: +44 1280 705196 |
--------------------------- < ------------------------------------------
>I'm synthesizing a VHDL design right now using Synario. It's choking
>on my C := A/B function. A & B are std_logic_vector (15 downto 0). They
>are converted to signed integers, and then divided. It won't synthesize.
>Can anyone point me at a decent binary divide function. It doesn't have
>to deal with remainders, although that might be a plus later on down the
>line. I assume I could subtract B from A a bunch of times, but that seems
>awfully inefficient.
The following VHDL compiles in Synario, however "/" specifies a lot of logic
so you might consider if a combinational divide is really the implementation
you want.
library ieee,dataio;
use ieee.std_logic_1164.all;
use dataio.std_logic_ops.all;
entity div is
port(a,b: in std_logic_vector(15 downto 0);
c : out std_logic_vector(15 downto 0));
end;
architecture dataflow of div is
begin
c <= to_vector(15, to_integer(a) / to_integer(b));
end dataflow;