Hallo zusammen, ich brauche eure Hilfe, bin ein VHDL-Anfaenger :) Hab ne Aufgabe bekommen einen FIR mit variabler Anzahl von Koeffizienten in VHDL zu realiseiren. Irgendwie scheint mein Code nicht richtig zu sein, oder mein Testbench ist einfach falsch geschrieben... FIR:
1 | library ieee; |
2 | |
3 | use ieee.std_logic_1164.all; |
4 | use ieee.std_logic_arith.all; |
5 | use ieee.std_logic_signed.all; |
6 | --use ieee.std_logic_unsigned.all;
|
7 | |
8 | package FILTER_PACK is |
9 | constant K: integer := 6; -- Anzahl Filterkoeffizienten |
10 | constant EIN_SIZE: integer := 9; -- Bitbreite Eingang |
11 | constant AUS_SIZE: integer := 11; -- Biltbreite Ausgang |
12 | constant MULT_SIZE: integer := 18; -- Multiplizierer Bitbreite 2*EIN_SIZE |
13 | constant ADD_SIZE: integer := 19; -- Addierer Bitbreite MULT_SIZE + ld(K)-1 |
14 | constant PIPE: integer := 5; -- Anzahl von Stufen im Multiplizierer-Pipeline |
15 | constant FACTOR: integer := 8; -- Ergebnis geteilt durch 2^FACTOR |
16 | end FILTER_PACK; |
17 | |
18 | library ieee; |
19 | |
20 | use ieee.std_logic_1164.all; |
21 | use ieee.std_logic_arith.all; |
22 | use ieee.std_logic_signed.all; |
23 | --use ieee.std_logic_unsigned.all;
|
24 | |
25 | library work; |
26 | use work.FILTER_PACK.all; |
27 | |
28 | entity FILTER is |
29 | port (clk: in std_logic; |
30 | load_x: in std_logic; |
31 | data_in: in std_logic_vector(EIN_SIZE - 1 downto 0); |
32 | koeff_in: in std_logic_vector(EIN_SIZE - 1 downto 0); |
33 | data_out: out std_logic_vector(AUS_SIZE - 1 downto 0)); |
34 | end FILTER; |
35 | |
36 | architecture arch of filter is |
37 | subtype EIN_BIT is std_logic_vector(EIN_SIZE - 1 downto 0); |
38 | subtype MULT_BIT is std_logic_vector(MULT_SIZE - 1 downto 0); |
39 | subtype ADD_BIT is std_logic_vector(ADD_SIZE - 1 downto 0); |
40 | type ARRAY_EIN_BIT is array (0 to K - 1) of EIN_BIT; |
41 | type ARRAY_MULT_BIT is array (0 to K - 1) of MULT_BIT; |
42 | type ARRAY_ADD_BIT is array (0 to K - 1) of ADD_BIT; |
43 | |
44 | signal ein: EIN_BIT; |
45 | signal aus: ADD_BIT; |
46 | signal koeff: ARRAY_EIN_BIT; -- Koeffizient array |
47 | signal prod: ARRAY_MULT_BIT; -- Produkt array |
48 | signal sum: ARRAY_ADD_BIT; -- Addierer array |
49 | |
50 | component pipelined_multiplier is |
51 | generic ( |
52 | size: integer; |
53 | level: integer); |
54 | |
55 | port ( |
56 | a : in std_logic_vector (size-1 downto 0) ; |
57 | b : in std_logic_vector (size-1 downto 0) ; |
58 | clk : in std_logic; |
59 | res : out std_logic_vector (2*size-1 downto 0)); |
60 | |
61 | end component pipelined_multiplier ; |
62 | |
63 | |
64 | begin
|
65 | |
66 | LOAD: process -- Data oder Koeffizienten werden geladen |
67 | |
68 | begin
|
69 | wait until clk = '1'; |
70 | if (load_x = '1') then |
71 | koeff(K - 1) <= koeff_in; -- Koeffizient in den Register speichern |
72 | for i in K-2 downto 0 loop |
73 | koeff(i) <= koeff(i + 1); |
74 | end loop; |
75 | else
|
76 | ein <= data_in; -- sonst Data laden |
77 | end if; |
78 | end process LOAD; |
79 | |
80 | SUMM: process (clk) -- in diesem Pozess wird die Summe gebildet |
81 | begin
|
82 | if clk'event and (clk = '1') then |
83 | for i in 0 to k - 2 loop |
84 | sum(i) <= (prod(i)(MULT_SIZE - 1) & prod(i)) + sum(i + 1); |
85 | --sum(i) <= "0" & prod(i) + sum(i + 1);
|
86 | end loop; |
87 | sum(k - 1) <= prod(k - 1)(MULT_SIZE - 1) & prod(k - 1); |
88 | --sum(k - 1) <= "0" & prod(k - 1);
|
89 | end if; |
90 | aus <= sum(0); |
91 | end process SUMM; |
92 | |
93 | MUL_GEN: for i in 0 to k - 1 generate |
94 | mul: pipelined_multiplier |
95 | generic map (size => EIN_SIZE, |
96 | level => PIPE) |
97 | port map (a => ein, |
98 | b => koeff(i), |
99 | clk => clk, |
100 | res => prod(i)); |
101 | end generate; |
102 | |
103 | data_out <= aus(ADD_SIZE - 1 downto FACTOR); |
104 | |
105 | end arch; |
Pipelined-miltiplizierer:
1 | library ieee ; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.std_logic_arith.all; |
4 | use ieee.std_logic_signed.all; |
5 | |
6 | entity pipelined_multiplier is |
7 | generic ( |
8 | size: integer; |
9 | level: integer); |
10 | |
11 | port ( |
12 | a : in std_logic_vector (size-1 downto 0) ; |
13 | b : in std_logic_vector (size-1 downto 0) ; |
14 | clk : in std_logic; |
15 | res : out std_logic_vector (2*size-1 downto 0)); |
16 | end pipelined_multiplier ; |
17 | |
18 | architecture arch of pipelined_multiplier is |
19 | type levels_of_registers is array(level-1 downto 0) of signed(2*size-1 downto 0); |
20 | signal a_int : signed (size-1 downto 0); |
21 | signal b_int : signed (size-1 downto 0); |
22 | signal res_int: levels_of_registers; |
23 | |
24 | begin
|
25 | res <= std_logic_vector(res_int (level-1)); |
26 | |
27 | process(clk) |
28 | begin
|
29 | if clk'event and clk = '1' then |
30 | -- multiplier operand inputs are registered
|
31 | a_int <= signed (a); |
32 | b_int <= signed (b); |
33 | -- 'level' levels of registers to be inferred at the
|
34 | -- output of the multiplier
|
35 | res_int(0) <= a_int*b_int; |
36 | for i in 1 to level-1 loop |
37 | res_int (i) <= res_int (i-1); |
38 | end loop; |
39 | end if; |
40 | end process; |
41 | end arch; |
Und Testbench:
1 | LIBRARY ieee; |
2 | USE ieee.std_logic_1164.ALL; |
3 | USE ieee.std_logic_signed.all; |
4 | USE ieee.numeric_std.ALL; |
5 | |
6 | ENTITY filter_tb IS |
7 | END filter_tb; |
8 | |
9 | ARCHITECTURE testbench OF filter_tb IS |
10 | |
11 | -- Component Declaration for the Unit Under Test (UUT)
|
12 | |
13 | COMPONENT filter |
14 | PORT( |
15 | clk : IN std_logic; |
16 | load_x : IN std_logic; |
17 | data_in : IN std_logic_vector(8 downto 0); |
18 | koeff_in : IN std_logic_vector(8 downto 0); |
19 | data_out : OUT std_logic_vector(10 downto 0) |
20 | );
|
21 | END COMPONENT; |
22 | |
23 | |
24 | --Inputs
|
25 | signal clk : std_logic := '0'; |
26 | signal load_x : std_logic := '0'; |
27 | signal data_in : std_logic_vector(8 downto 0) := (others => '0'); |
28 | signal koeff_in : std_logic_vector(8 downto 0) := (others => '0'); |
29 | |
30 | --Outputs
|
31 | signal data_out : std_logic_vector(10 downto 0); |
32 | |
33 | -- Clock period definitions
|
34 | constant clk_period : time := 50 ns; -- 20 MHz |
35 | |
36 | BEGIN
|
37 | |
38 | -- Instantiate the Unit Under Test (UUT)
|
39 | uut: filter PORT MAP ( |
40 | clk => clk, |
41 | load_x => load_x, |
42 | data_in => data_in, |
43 | koeff_in => koeff_in, |
44 | data_out => data_out |
45 | );
|
46 | |
47 | -- Clock process definitions
|
48 | clk_process: process |
49 | begin
|
50 | clk <= '0'; |
51 | wait for clk_period/2; |
52 | clk <= '1'; |
53 | wait for clk_period/2; |
54 | end process; |
55 | |
56 | |
57 | -- Stimulus process
|
58 | stim_proc: process |
59 | begin
|
60 | load_x <= '0'; |
61 | data_in <= "000000000"; |
62 | koeff_in <= "001111100"; -- Koeff 1 - 124 |
63 | wait for clk_period; |
64 | koeff_in <= "000110010"; -- Koeff 2 - 50 |
65 | --koeff_in <= "000000000";
|
66 | wait for clk_period; |
67 | koeff_in <= "001000011"; -- Koeff 3 - 67 |
68 | --koeff_in <= "000000000";
|
69 | wait for clk_period; |
70 | koeff_in <= "001010011"; -- Koeff 4 - 83 |
71 | --koeff_in <= "000000000";
|
72 | wait for clk_period; |
73 | koeff_in <= "011010110"; -- Koeff 5 - 214 |
74 | --koeff_in <= "000000000";
|
75 | wait for clk_period; |
76 | koeff_in <= "010110000"; -- Koeff 6 - 176 |
77 | --koeff_in <= "000000000";
|
78 | wait for clk_period; |
79 | koeff_in <= "000000000"; |
80 | wait for 2*clk_period; |
81 | load_x <= '1'; |
82 | wait for clk_period; |
83 | data_in <= "001100100"; |
84 | --wait for 2*clk_period;
|
85 | --data_in <= "000000000";
|
86 | |
87 | -- hold reset state for 100ms.
|
88 | --wait for 100ms;
|
89 | |
90 | -- wait for clk_period*10;
|
91 | |
92 | -- insert stimulus here
|
93 | |
94 | wait; |
95 | end process; |
96 | |
97 | END; |
Es laesst sich alles komplilieren, entsteht auch Hardware... Ich kriege aber kein richtiges Ergebnisbei der Simulation.