[email protected] 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 := 8);
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,
[email protected]
http://www.frank-buss.de, http://www.it4-systems.de