---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:23:18 03/21/2026 -- Design Name: -- Module Name: Neuron - 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; entity Neuron is Generic (ADDRESS_WIDTH : integer := 11; --Weight Memory Size DATA_WIDTH : integer := 16; --Float16 Format PAGE_WIDTH : integer := 4; --max. 16 Layers INPUT_WIDTH : integer := 7; --max 128 Input Signals INPUTS : integer := 10; --Number of used inputs MULT_LATENCY : integer := 6; --make shure: Latency < inputs! ADD_LATENCY : integer := 6); Port ( --Control Signals clk : in std_logic; reset : in std_logic; execute : in std_logic; ready : out std_logic; error : out std_logic; Layer_page : in std_logic_vector(PAGE_WIDTH-1 downto 0); Layer_Input_Number : in std_logic_vector(INPUT_WIDTH-1 downto 0); --Weight Memory Signals (to read and write directly to Weight Memory) Mem_enable : in std_logic; Mem_write : in std_logic; Mem_Adr : in std_logic_vector (ADDRESS_WIDTH-1 downto 0); Mem_Data_In : in std_logic_vector (DATA_WIDTH-1 downto 0); Mem_Data_Out : out std_logic_vector (DATA_WIDTH-1 downto 0); --Input Data Signal Input : in std_logic_vector (DATA_WIDTH-1 downto 0); --Output Data Signal Output : out std_logic_vector (DATA_WIDTH-1 downto 0) ); end Neuron; architecture Behavioral of Neuron is type count_state_t is (idle, counting); signal Count_state : count_state_t; type mult_state_t is (idle, multiply); signal Mult_state : mult_state_t; type add_state_t is (idle, waiting, buffering, adding, finishing); signal Add_state : add_state_t; signal Add_Select_a : std_logic_vector(1 downto 0); signal Add_Select_b : std_logic_vector(1 downto 0); signal int_ready : std_logic; signal counter : integer range 0 to INPUTS+MULT_LATENCY+ADD_LATENCY; signal int_Output : std_logic_vector(DATA_WIDTH-1 downto 0); type array_t is array (0 to ADD_LATENCY-1) of std_logic_vector(DATA_WIDTH-1 downto 0); signal input_buffer : array_t := (others => (others => '0')); component Weight_Memory port( clk : in std_logic; Port_A_Adr : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); Port_B_enable : in std_logic; Port_B_write : in std_logic; Port_B_Adr : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); Port_B_Data_In : in std_logic_vector(DATA_WIDTH-1 downto 0); Port_A_Data_Out : out std_logic_vector(DATA_WIDTH-1 downto 0); Port_B_Data_Out : out std_logic_vector(DATA_WIDTH-1 downto 0) ); end component; signal Weight : std_logic_vector(DATA_WIDTH-1 downto 0); signal Weight_Adr : std_logic_vector(ADDRESS_WIDTH-1 downto 0); component Float_Multiply port ( a : in std_logic_vector(DATA_WIDTH-1 downto 0); b : in std_logic_vector(DATA_WIDTH-1 downto 0); clk : in std_logic; result : out std_logic_vector(DATA_WIDTH-1 downto 0); underflow : out std_logic; overflow : out std_logic; invalid_op : out std_logic; rdy : out std_logic ); end component; signal Mult_a : std_logic_vector(DATA_WIDTH-1 downto 0); signal Mult_b : std_logic_vector(DATA_WIDTH-1 downto 0); signal Mult_result : std_logic_vector(DATA_WIDTH-1 downto 0); signal Mult_underflow : std_logic; signal Mult_overflow : std_logic; signal Mult_invalid_op : std_logic; signal Mult_rdy : std_logic; component Float_Addition port ( a : in std_logic_vector(DATA_WIDTH-1 downto 0); b : in std_logic_vector(DATA_WIDTH-1 downto 0); clk : in std_logic; result : out std_logic_vector(DATA_WIDTH-1 downto 0); underflow : out std_logic; overflow : out std_logic; invalid_op : out std_logic; rdy : out std_logic ); end component; signal Add_a : std_logic_vector(DATA_WIDTH-1 downto 0); signal Add_b : std_logic_vector(DATA_WIDTH-1 downto 0); signal Add_result : std_logic_vector(DATA_WIDTH-1 downto 0); signal Add_underflow : std_logic; signal Add_overflow : std_logic; signal Add_invalid_op : std_logic; signal Add_rdy : std_logic; begin My_Weight_Memory: Weight_Memory PORT MAP( clk => clk, Port_A_Adr => Weight_Adr, Port_A_Data_Out => Weight, Port_B_enable => Mem_enable, Port_B_write => Mem_write, Port_B_Adr => Mem_Adr, Port_B_Data_In => Mem_Data_In, Port_B_Data_Out => Mem_Data_Out ); My_Float_Multiply : Float_Multiply PORT MAP ( a => Mult_a, b => Mult_b, clk => clk, result => Mult_result, underflow => Mult_underflow, overflow => Mult_overflow, invalid_op => Mult_invalid_op, rdy => Mult_rdy ); My_Float_Addition : Float_Addition PORT MAP ( a => Add_a, b => Add_b, clk => clk, result => Add_result, underflow => Add_underflow, overflow => Add_overflow, invalid_op => Add_invalid_op, rdy => Add_rdy ); count: process begin wait until rising_edge(clk); if(reset = '1') then int_ready <= '1'; counter <= 0; Count_state <= idle; else case Count_state is when idle => if(execute = '1') then int_ready <= '0'; Count_state <= counting; else int_ready <= '1'; counter <= 0; end if; when counting => counter <= counter + 1; if(counter = INPUTS+MULT_LATENCY+ADD_LATENCY-1) then Count_state <= idle; end if; when others => Count_state <= idle; counter <= 0; end case; end if; end process; mult:process begin wait until rising_edge(clk); if(reset = '1') then Mult_a <= (others => '0'); Mult_b <= (others => '0'); Mult_state <= idle; else case Mult_state is when idle => if(execute = '1') then Mult_state <= multiply; else Mult_a <= (others => '0'); Mult_b <= (others => '0'); end if; when multiply => if(counter = INPUTS) then Mult_state <= idle; Mult_a <= (others => '0'); Mult_b <= (others => '0'); else Mult_a <= Input; Mult_b <= Weight; end if; when others => Mult_state <= idle; end case; end if; end process; add:process begin wait until rising_edge(clk); if(reset = '1') then int_Output <= (others => '0'); Add_Select_a <= "00"; Add_Select_b <= "00"; Add_state <= idle; else case Add_state is when idle => if(execute = '1') then Add_Select_a <= "00"; Add_Select_b <= "00"; Add_state <= waiting; end if; when waiting => if(counter > MULT_LATENCY-1) then Add_Select_a <= "01"; Add_Select_b <= "00"; Add_state <= buffering; else Add_Select_a <= "00"; Add_Select_b <= "00"; end if; when buffering => if(counter > MULT_LATENCY+ADD_LATENCY) then Add_Select_a <= "00"; Add_Select_b <= "01"; Add_state <= adding; else input_buffer(counter-MULT_LATENCY-1) <= Mult_result; Add_Select_a <= "01"; Add_Select_b <= "01"; end if; when adding => if(counter > INPUTS+ADD_LATENCY+1) then Add_state <= finishing; else Add_Select_a <= "01"; Add_Select_b <= "01"; end if; when finishing => int_Output <= Add_result; Add_state <= idle; when others => Add_state <= idle; end case; end if; end process; with Add_Select_a select Add_a <= (others => '0') when "00", Mult_result when "01", (others => '0') when others; with Add_Select_b select Add_b <= (others => '0') when "00", Add_result when "01", (others => '0') when others; Output <= int_Output; Weight_Adr <= Layer_page & Layer_Input_Number; ready <= int_ready and not(execute); error <= Mult_underflow or Mult_overflow or Mult_invalid_op or Add_underflow or Add_overflow or Add_invalid_op;-- or Sqrt_invalid_op; end Behavioral;