library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.fixed_pkg.all;
use work.DigEng.all;
use work.array_type.ALL;

entity Neuron_with_Encoder_toplevel is
    Generic (Dendrite_NO : NATURAL := 4;  -- Number of input of the neuron
        decode_period : NATURAL := 256;
    
        weight_size_max : NATURAL := 1;   -- DO NOT CHANGE the weight size.   
        weight_size_min : integer := -12;  --They are not really selectable in the current design due to the limitatin of RNG.
        
        -- property of soma
        Resting_potential : NATURAL := 50;
        Refract_potential_start : NATURAL := 49;
        Refract_potential_end : NATURAL := 50;
        thredhold_potential : SFIXED := to_SFIXED(51.3, 7, -12);
        Leaky_rate : SFIXED := to_SFIXED(0.000244140625, 3, -12);
        Recharge_rate : SFIXED := to_SFIXED(0.000244140625, 3, -12);
        
        -- STDP related generics
        Pre_spike_time_window : NATURAL := 10; 
        Post_spike_time_window : NATURAL := 10;
        Positive_amp : SFIXED := to_SFIXED(0.000244140625, 1, -12);
        Negative_amp : SFIXED := to_SFIXED(0.000244140625, 1, -12));
    Port ( clk : in STD_LOGIC;
           rst : in STD_LOGIC;
           en : in STD_LOGIC;
           input : in array_2d_STD(0 to (Dendrite_NO - 1))(7 downto 0);
           output : out STD_LOGIC_VECTOR (log2(decode_period)-1 downto 0);
           weight_rst : in STD_LOGIC;
           Custom_weight_en : in STD_LOGIC;
           custom_weight : in array_2d_SFIXED(0 to dendrite_NO - 1)(weight_size_max downto weight_size_min));
end Neuron_with_Encoder_toplevel;

architecture Behavioral of Neuron_with_Encoder_toplevel is

signal Encoder_vector_out : STD_LOGIC_VECTOR(0 to dendrite_NO - 1);
signal neuron_out : STD_LOGIC;

begin

encoders : entity work.Encoder_vector
    Generic map (Encoder_NO => 4)
    Port map (clk => clk,
              rst => rst,
              en => en,
              Sig => input,
              Encoded_sig => Encoder_vector_out);
                
Neuron : entity work.Neuron_top_level
    Generic map (Dendrite_NO => Dendrite_NO,              
             weight_size_max => weight_size_max,          
             weight_size_min => weight_size_min,          
             Resting_potential => Resting_potential,        
             Refract_potential_start => Refract_potential_start,  
             Refract_potential_end => Refract_potential_end,    
             thredhold_potential => thredhold_potential,      
             Leaky_rate => Leaky_rate,
             Recharge_rate => Recharge_rate,   
             Pre_spike_time_window => Pre_spike_time_window,    
             Post_spike_time_window => Post_spike_time_window,   
             Positive_amp => Positive_amp,    
             Negative_amp => Negative_amp) 
     Port map (clk => clk,
        rst => rst,
        en => en,
        Spike_in => Encoder_vector_out,
        Spike_out => neuron_out,
        weight_rst => weight_rst,
        custom_weight_en => custom_weight_en,
        Custom_weight => custom_weight);
        
Decoder : entity work.Decoder_top_level
    Generic map (decode_period => decode_period)
    Port map (clk => clk,
              rst => rst,
              en  => en,
              spike => neuron_out,
              sig_decoded => output);
              
end Behavioral;
