Jag håller på att lär mig om generics (alltså att man kan generiskt skapa en modul genom att specificera dess storlek), och det fungerar hittills bra, men jag har en idé nu som jag är osäker på hur jag ska göra.
Det jag funderar på är automatisk generering av signaler.
Exempel:
Låt oss säga att jag har en generisk input av N bitar, det jag då vill är generiskt skapa antalet signaler som behövs för att addera par av bitar.
Dvs jag vill ha signaler, s1, s2, ..., sN/2 så s1 = input(0) + input(1), ... sN/2 = input(N-1) + input(N).
Går det att skapa signaler generiskt på detta vis eller har jag fel tänk här?
Det jag vill göra är bestämma antalet grejer att göra i parallel i stegen av en pipeline baserat på inputs storlek.
Edit: La in lite exempel kod.
Jag beräknar Hamming Distance och jag vill att alla mina beräkningar ska skala med N.
Så antalet steg i adder tree'et ska öka och att count_ones ska alltid arbeta i 8-bit chunks.
Kod: Markera allt
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use work.misc_functions.all;
entity hamming_distance is
generic (
N : positive := 64 -- N must be a multiple of 32.
);
port (
clk : in std_logic;
rst : in std_logic;
inputA : in std_logic_vector ((N - 1) downto 0);
inputB : in std_logic_vector ((N - 1) downto 0);
output : out unsigned ((integer(ceil(log2(real(N)))) - 1) downto 0)
);
end hamming_distance;
architecture Behavioral of hamming_distance is
signal after_XOR : std_logic_vector ((N - 1) downto 0);
signal after_c1 : integer;
signal after_c2 : integer;
signal after_c3 : integer;
signal after_c4 : integer;
signal after_c5 : integer;
signal after_c6 : integer;
signal after_c7 : integer;
signal after_c8 : integer;
signal after_add1 : integer;
signal after_add2 : integer;
signal after_add3 : integer;
signal after_add4 : integer;
signal after_add5 : integer;
signal after_add6 : integer;
signal output_stage : unsigned ((integer(ceil(log2(real(N)))) - 1) downto 0);
begin
-- Calculate the Hamming distance between inputA and inputB.
-- Pipeline: 5-stages.
process (clk, rst) begin
if rising_edge(clk) then
if rst = '1' then
after_XOR <= (others => '0');
output_stage <= (others => '0');
after_c1 <= 0;
after_c2 <= 0;
after_c3 <= 0;
after_c4 <= 0;
after_c5 <= 0;
after_c6 <= 0;
after_c7 <= 0;
after_c8 <= 0;
after_add1 <= 0;
after_add2 <= 0;
after_add3 <= 0;
after_add4 <= 0;
after_add5 <= 0;
after_add6 <= 0;
else
-- Stage 1: XOR
after_XOR <= inputA xor inputB;
-- Stage 2: count ones in 8-bit chunks
after_c1 <= count_ones(after_XOR(63 downto 56));
after_c2 <= count_ones(after_XOR(55 downto 48));
after_c3 <= count_ones(after_XOR(47 downto 40));
after_c4 <= count_ones(after_XOR(39 downto 32));
after_c5 <= count_ones(after_XOR(31 downto 24));
after_c6 <= count_ones(after_XOR(23 downto 16));
after_c7 <= count_ones(after_XOR(15 downto 8));
after_c8 <= count_ones(after_XOR(7 downto 0));
-- Stage 3: first level of adder tree
after_add1 <= after_c1 + after_c2;
after_add2 <= after_c3 + after_c4;
after_add3 <= after_c5 + after_c6;
after_add4 <= after_c7 + after_c8;
-- Stage 4: second level of adder tree
after_add5 <= after_add1 + after_add2;
after_add6 <= after_add3 + after_add4;
-- Stage 5: third level of adder tree
output_stage <= to_unsigned(after_add5 + after_add6, output_stage'length);
end if;
end if;
end process;
output <= output_stage;
end Behavioral;