Created
April 29, 2024 11:31
-
-
Save purpl3F0x/34676024f27b3f48af0aec49d3d4e177 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; | |
use ieee.std_logic_1164.all; | |
use ieee.numeric_std.all; | |
entity mac is | |
generic ( | |
SIZEIN : natural := 8; -- width of the inputs | |
SIZEOUT : natural := 19 -- width of the output | |
); | |
port ( | |
clk : in std_logic; | |
init : in std_logic; | |
a : in std_logic_vector (SIZEIN-1 downto 0); | |
b : in std_logic_vector (SIZEIN-1 downto 0); | |
accum_out : out std_logic_vector (SIZEOUT-1 downto 0)); | |
end entity; | |
architecture rtl of mac is | |
-- Declare registers for intermediate values | |
signal a_reg, b_reg : unsigned (SIZEIN-1 downto 0) := (others => '0'); | |
signal init_reg : std_logic; | |
signal mult_reg : unsigned (2*SIZEIN-1 downto 0) := (others => '0'); | |
signal adder_out, old_result : unsigned (SIZEOUT-1 downto 0) := (others => '0'); | |
begin | |
process (adder_out, init_reg) | |
begin | |
if init_reg = '1' then | |
old_result <= (others => '0'); | |
else | |
-- 'init' is now active (=low) and opens the accumulation loop. | |
-- The accumulator takes the next multiplier output in | |
-- the same cycle. | |
old_result <= adder_out; | |
end if; | |
end process; | |
process (clk) | |
begin | |
if rising_edge(clk) then | |
a_reg <= unsigned(a); | |
b_reg <= unsigned(b); | |
mult_reg <= a_reg * b_reg; | |
init_reg <= init; | |
-- Store accumulation result into a register | |
adder_out <= old_result + mult_reg; | |
end if; | |
end process; | |
-- Output accumulation result | |
accum_out <= std_logic_vector(adder_out); | |
end rtl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library IEEE; | |
use IEEE.STD_LOGIC_1164.ALL; | |
use IEEE.NUMERIC_STD.ALL; | |
entity mac_tb is | |
end mac_tb; | |
architecture Behavioral of mac_tb is | |
signal a, b : std_logic_vector(7 downto 0); | |
signal acc_out : std_logic_vector(18 downto 0); | |
signal clk : std_logic := '0'; | |
signal init : std_logic := '0'; | |
begin | |
uut: entity work.mac | |
Port map ( | |
clk => clk, | |
a => a, | |
b => b, | |
init => init, | |
accum_out => acc_out | |
); | |
clk_proc: process is | |
begin | |
clk <= not clk; | |
wait for 5 ns; | |
end process; | |
stimulus: process is | |
begin | |
for i in 0 to 15 loop | |
a <= std_logic_vector(to_unsigned(i, a'length)); | |
for j in 0 to 15 loop | |
b <= std_logic_vector(to_unsigned(j, b'length)); | |
wait for 10 ns; | |
end loop; | |
end loop; | |
wait for 20 ns; | |
assert (unsigned(acc_out) = 14400) severity FAILURE; | |
Init <= '0'; | |
a <= (others => '0'); | |
b <= (others => '0'); | |
wait for 10 ns; | |
Init <= '1'; | |
wait for 10 ns; | |
Init <= '0'; | |
assert (unsigned(acc_out) = 0) severity FAILURE; | |
a <= (others => '1'); | |
b <= (others => '1'); | |
wait for 10 * 8 ns; | |
assert (unsigned(acc_out) = 520200) severity FAILURE; | |
Init <= '1'; | |
wait for 10 ns; | |
assert (unsigned(acc_out) = 65025) severity FAILURE; | |
std.env.finish; | |
end process; | |
end Behavioral; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment