diff --git a/OperativeUnit.vhd b/OperativeUnit.vhd new file mode 100644 index 0000000000000000000000000000000000000000..21d1a2dc74f8151b07efcfeef5739cc1ae7d8be6 --- /dev/null +++ b/OperativeUnit.vhd @@ -0,0 +1,121 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 03/27/2025 06:13:36 PM +-- Design Name: +-- Module Name: OperativeUnit - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity OperativeUnit is + port ( + I_clock : in std_logic; + I_reset : in std_logic; + I_inputSample : in std_logic_vector(7 downto 0); + I_loadShift : in std_logic; + I_initAddress : in std_logic; + I_incrAddress : in std_logic; + I_initSum : in std_logic; + I_loadSum : in std_logic; + I_loadY : in std_logic; + O_processingDone : out std_logic; + O_Y : out std_logic_vector(7 downto 0) + ); + +end OperativeUnit; + +architecture Behavioral of OperativeUnit is + +type registerFile is array(0 to 128) of signed(10 downto 0); + signal SR_coefRegister : registerFile; + + signal SR_shiftRegister : registerFile; + signal SC_multOperand1 : signed(10 downto 0); + signal SC_multOperand2 : signed(10 downto 0); + signal SC_MultResult : signed(21 downto 0); + signal SC_addResult : signed(25 downto 0); + signal SR_sum : signed(25 downto 0); + signal SR_Y : signed(7 downto 0); + signal SR_readAddress : integer range 0 to 128; + +begin + + shift : process (I_clock) is + begin + if I_reset = '1' then + SR_shiftRegister <= (others => (others => '0')); + elsif rising_edge(I_clock) then + if I_loadShift = '1' then + SR_shiftRegister <= (others => signed(I_inputSample)); + end if; + end if; + end process shift; + + incr_address : process (I_clock) is + begin + if I_reset = '1' then + SR_readAddress <= 0; + elsif rising_edge(I_clock) then + if I_incrAddress = '1' then + SR_readAddress <= SR_readAddress + 1; + end if; + end if; + end process incr_address; + + O_processingDone <= '1' when SR_readAddress = 128 else '0'; + + SC_multOperand1 <= SR_shiftRegister(SR_readAddress); + SC_multOperand2 <= SR_coefRegister(SR_readAddress); + SC_MultResult <= SC_multOperand1 * SC_multOperand2; + SC_addResult <= resize(SC_MultResult, SC_addResult'length) + SR_sum; + + sum_acc : process (I_clock) is + begin + if I_reset = '1' then + SR_sum <= (others => '0'); + elsif rising_edge(I_clock) then + if I_initSum = '1' then + SR_sum <= (others => '0'); + elsif I_loadSum = '1' then + SR_sum <= SC_addResult; + end if; + end if; + end process sum_acc; + + store_result : process (I_clock) is + begin + if rising_edge(I_clock) then + if I_loadY = '1' then + SR_Y <= SR_sum(15 downto 8); + end if; + end if; + end process store_result; + + O_Y <= std_logic_vector(SR_Y); + +end Behavioral;