http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> I have a signal (integer). How can I describe synthesizable code

> for dividing that signal by 48 ? Result (ls_rowaddr) should

> be whole-number that is integer.
This is an interesting problem. You could use my general entity

for dividing two arbitrary numbers:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;

entity binary_division is

generic(

bits: positive :=

;

port(

dividend: in unsigned(bits-1 downto 0);

divisor: in unsigned(bits-1 downto 0);

quotient: out unsigned(bits-1 downto 0);

remainder: out unsigned(bits-1 downto 0);

division_by_zero_error: out boolean);

end entity binary_division;

architecture rtl of binary_division is

begin

divide: process(dividend, divisor)

variable temp_dividend: unsigned(bits-1 downto 0);

variable temp_divisor: unsigned(bits-1 downto 0);

variable temp_quotient: unsigned(bits-1 downto 0);

variable align_count: natural range 0 to bits;

begin

-- init

temp_dividend := dividend;

temp_divisor := divisor;

temp_quotient := (others => '0');

if temp_divisor = 0 then

division_by_zero_error <= true;

quotient <= (others => '0');

remainder <= (others => '0');

else

division_by_zero_error <= false;

if temp_divisor > temp_dividend then

quotient <= (others => '0');

remainder <= dividend;

else

-- left align

align_count := 0;

for i in 1 to bits-1 loop

exit when temp_divisor(bits-1) = '1';

temp_divisor := shift_left(temp_divisor, 1);

align_count := align_count + 1;

end loop;

-- divide

for i in 0 to bits-1 loop

if temp_divisor > temp_dividend then

temp_quotient := temp_quotient(bits-2 downto 0) & '0';

else

temp_quotient := temp_quotient(bits-2 downto 0) & '1';

temp_dividend := temp_dividend - temp_divisor;

end if;

temp_divisor := shift_right(temp_divisor, 1);

exit when align_count = 0;

align_count := align_count - 1;

end loop;

quotient <= temp_quotient;

remainder <= temp_dividend;

end if;

end if;

end process;

end architecture rtl;

But this uses a lot of LUTs, 5% of a Cyclone I (about 300 logic elements)

for 8 bit and the worst case timing between input and output is 66.6 ns

(if you tweek a bit the project settings, it can be reduced to 53 ns).

For 16 bit you can use it for benchmarking synthesizer tools, but I

would not recommend it in real designs, because it uses 21% (about 1,300

logic elements) and worst timing is 122 ns. For 32 bit the Quartus II

says "Current module quartus_fit ended unexpectedly", maybe because

it needs more logic elements than available.

There are faster algorithms (

http://en.wikipedia.org/wiki/Division_(digital) ),

but if you don't need high parallel speed and if you have a clock, you

can serialize the algorithm, which shouldn't need very many logic elements.

The testbench:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;

entity binary_division_test is

end entity binary_division_test;

architecture rtl of binary_division_test is

constant bits: positive := 8;

signal dividend: unsigned(bits-1 downto 0);

signal divisor: unsigned(bits-1 downto 0);

signal quotient: unsigned(bits-1 downto 0);

signal remainder: unsigned(bits-1 downto 0);

signal division_by_zero_error: boolean;

begin

binary_division_inst: entity binary_division

generic map(

bits => bits)

port map(

dividend => dividend,

divisor => divisor,

quotient => quotient,

remainder => remainder,

division_by_zero_error => division_by_zero_error);

test_divide: process

variable count: positive;

begin

dividend <= to_unsigned(0, bits);

divisor <= to_unsigned(0, bits);

wait for 1 ps;

count := 1;

for i in 1 to bits loop

count := 2*count;

end loop;

count := count - 1;

for i in 0 to count loop

for j in 0 to count loop

dividend <= to_unsigned(i, bits);

divisor <= to_unsigned(j, bits);

wait for 1 ps;

if j = 0 then

assert quotient = 0 report "quotient error" severity failure;

assert remainder = 0 report "remainder error" severity failure;

assert division_by_zero_error report "division_by_zero_error error" severity failure;

else

assert quotient = i / j report "quotient error" severity failure;

assert remainder = i - i / j * j report "remainder error" severity failure;

assert not division_by_zero_error report "division_by_zero_error error" severity failure;

end if;

end loop;

end loop;

wait for 1 ps;

assert false report "No failure, simulation was successful." severity failure;

end process;

end architecture rtl;

--

Frank Buss,

(E-Mail Removed)
http://www.frank-buss.de,

http://www.it4-systems.de