сумма 1 в векторе
http://electronix.ru/forum/index.php?s=&am...st&p=814251 (verilog) ( объяснение
Viko http://electronix.ru/forum/index.php?s=&am...st&p=814665 )
полный аналог на Vhdl
CODE
---- Объяснение:
---- Нулевая ступень - суммируем группы по 4 бита, каждому такому сумматору должно потребоваться 3 LUT и никаких переносов.
---- Дальше суммируем обычным деревом сумматоров. Но - старшие биты в каждом из сумматоров обладают свойством, назовем, "исключительности".
---- То есть, если этот бит в 1, то все остальные младшие биты в 0 (максимальные числа в ступенях s0, s1, s2, s3 будут 4, 8, 16 и 32).
---- Поэтому для вычисления старшего бита не нужны переносы из младших. Вот на этих переносах задержки и экономятся.
---- Дальше - нужно применить схемы параллельных переносов, когда для их формирования используются только входные сигналы.
---- Только нужно еще определить, в каком случае параллельные переносы будут эффективнее последовательных.
---- Надеюсь, если правильно все написать, то быстродействие будет не меньше, чем при игнорировании carry.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE ieee.numeric_std.ALL;
entity sum1_std_logic_vector is
Port ( clk : in std_logic;
rst : in std_logic;
d : in std_logic_vector(63 downto 0);
sum : out std_logic_vector(6 downto 0));
end sum1_std_logic_vector;
architecture behavioral of sum1_std_logic_vector is
type ARRAY_TYPE_s0 is array (0 to 15) of std_logic_vector(2 downto 0);
type ARRAY_TYPE_s1 is array (0 to 7) of std_logic_vector(3 downto 0);
type ARRAY_TYPE_s2 is array (0 to 3) of std_logic_vector(4 downto 0);
type ARRAY_TYPE_s3 is array (0 to 1) of std_logic_vector(5 downto 0);
signal s0 : ARRAY_TYPE_s0;
signal s1 : ARRAY_TYPE_s1;
signal s2 : ARRAY_TYPE_s2;
signal s3 : ARRAY_TYPE_s3;
signal dc : std_logic_vector(63 downto 0);
signal sumc : std_logic_vector(6 downto 0);
begin
process (clk, rst)
begin
if (clk'event and clk = '1') then
dc <= d;
sum <= sumc;
end if;
end process;
process (dc, d, s0, s1, s2, s3)
begin
for i in 0 to 15 loop
s0(i) <= conv_std_logic_vector( conv_integer(dc(4*i)) + conv_integer(dc(4*i + 1)) + conv_integer(dc(4*i + 2)) + conv_integer(dc(4*i + 3)), 3);
for j in 0 to 7 loop
s1(j)(2 downto 0) <= conv_std_logic_vector( conv_integer(s0(2*j)) + conv_integer(s0(2*j +1)), 3);
s1(j)(3) <= s0(2*j)(2) and s0(2*j +1)(2);
end loop;
for k in 0 to 3 loop
s2(k)(3 downto 0) <= s1(2*k) + s1(2*k +1);
s2(k)(4) <= s1(2*k)(3) and s1(2*k +1)(3);
end loop;
for m in 0 to 1 loop
s3(m)(4 downto 0) <= conv_std_logic_vector( conv_integer(s2(2*m)) + conv_integer(s2(2*m +1)), 5);
s3(m)(5) <= s2(2*m)(4) and s2(2*m +1)(4);
end loop;
sumc(5 downto 0) <= conv_std_logic_vector (conv_integer(s3(0)) + conv_integer(s3(1)), 6);
sumc(6) <= s3(0)(5) and s3(1)(5);
end loop;
end process;
end behavioral;
простенький тестбенч
CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE ieee.numeric_std.ALL;
ENTITY sum1_std_logic_vector_vhd_tst IS
END sum1_std_logic_vector_vhd_tst;
ARCHITECTURE sum1_std_logic_vector_arch OF sum1_std_logic_vector_vhd_tst IS
-- constants
-- signals
SIGNAL clk : STD_LOGIC;
SIGNAL d : STD_LOGIC_VECTOR(63 DOWNTO 0):= (63 => '1', 62 => '1', 61 => '1', 60 => '1', others => '0');
SIGNAL rst : STD_LOGIC;
SIGNAL sum : STD_LOGIC_VECTOR(6 DOWNTO 0);
COMPONENT sum1_std_logic_vector
PORT (
clk : IN STD_LOGIC;
d : IN STD_LOGIC_VECTOR(63 DOWNTO 0);
rst : IN STD_LOGIC;
sum : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
);
END COMPONENT;
BEGIN
i1 : sum1_std_logic_vector
PORT MAP (
-- list connections between master ports and signals
clk => clk,
d => d,
rst => rst,
sum => sum
);
clk_process :process
begin
clk <= '1';
wait for 5 ns;
clk <= '0';
wait for 5 ns;
end process;
rst_process :process
begin
rst <= '0';
wait for 10 ns;
rst <= '1';
wait;
end process;
process (clk, rst)
begin
if (clk'event and clk = '1') then
--d <= "0000000000000000111111111111111111111111000000000000111111111111";
d <= d + "0000000000000000000000000000000000000000000000000000000000000001";
end if;
end process;
END sum1_std_logic_vector_arch;