Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 30.10.2018 09:14:15
-- Design Name:
-- Module Name: hist_system_top - 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;

-- 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 hist_system_top is
   
    generic (
              adc_bit_num : natural := 14; --input data from ad converter is 14 bit
              bit_num : natural := 10; -- number of bits for our data (scaled from 14 bit to 10 bit)
              bin_num : natural := 1024; -- number of bins in histogram. IMPORTANT: this number has to be equal to 2**bit_num.
              buffer_size: natural := 24; --size of each BRAM_buffer in bits ; 24 bit = MAX, je izhodni signal HISTOGRAM, ki  gre v procesor 24-bitni
              num_of_units: natural := 1; -- number of BRAM_buffer and PE_unit units. IMPORTANT: MAX NUMBER OF UNITS IS 33, otherwise overflow (i think, check this out) !!!!  
              comm_bit_num: natural := 32; -- uporabljeno za komunikacijo s procesorjem
              mode: string := "MODE_3"; -- modes of operation: MODE_1 = navaden algoritm, MODE_2 = odklop bufferja in 1 enota, MODE_3 = novo od 30.11.2018 naprej
              byte: natural := 8
            );                          

    port (  
            clk: in std_logic; --iz ADC
            data_in: in unsigned ( (adc_bit_num - 1) downto 0 ); --iz ADC
            INT_res: out std_logic; --signal za reset integratorja, pride iz ADC_unit, to peles na vezje
           
            PM_trigger_in: in unsigned ( (adc_bit_num - 1) downto 0);
            --vhodni/izhodni signali za komunikacijo s procesorjem
            rstn: in std_logic; --reset signal. Ko je '0' resetira prejete podatke
            HW_addr: in std_logic_vector ( (comm_bit_num - 1) downto 0 );
            data_from_UC: in std_logic_vector ( (comm_bit_num - 1) downto 0 );
            wr_en: in std_logic; --procesor pove komponenti, da bo pisal vanjo
            rd_en: in std_logic; -- procesor pove komponenti, da bo bral iz nje <-- Q: ali je lahko tole moj UC_wr_en???
            data_for_UC: out std_logic_vector ( (comm_bit_num - 1) downto 0 );
            error: out std_logic;
            ack: out std_logic
            -----------------------------------------------------------------------
            --START: in std_logic; --TODO: premakni v komunikacijsko enoto
            --UC_wr_en: in std_logic; -- procesor pove hist_system_top, da lahko poslje nov podatek procesorjuTODO: za testiranje ta tukaj, drugace v komunikacijski enoti = ren
            --data_out: out integer;       --TODO: spravi ga v komunikacijsko enoto
            --RESET: in std_logic;
            --ADC_threshold: in unsigned ( (11 - 1) downto 0 );
            --ADC_capt_num_of_samples: in unsigned ( (byte - 1) downto 0 )
           
            );
           
           


end hist_system_top;

architecture Behavioral of hist_system_top is

----------------COMPONENTS---------------------------

    component ADC_unit
       
        generic ( adc_bit_num : natural := 14; --input data from ad converter is 14 bit
              bit_num : natural := 10; -- number of bits for our data (scaled from 14 bit to 10 bit)
              num_of_units: natural := 2; -- number of BRAM_buffer and PE_unit units
              buffer_size: natural := 5; --size of each BRAM_buffer in bits
              mode: string := "MODE_3"; -- modes of operation: MODE_1 = navaden algoritm, MODE_2 = odklop bufferja in 1 enota, MODE_3 = novo od 30.11.2018 naprej
              byte: natural := 8
                                                                         
             );
             
        port ( clk_in: in std_logic;
           START: in std_logic; -- start the system
           data_in : in unsigned ( (adc_bit_num - 1) downto 0 ); --data from ADC
           ADC_unit_feedback: in std_logic;
           AD_wr_en: out unsigned ( (num_of_units - 1) downto 0 );-- goes to BRAM_buffer, to AD_wr_en signal
           AD_addr: out unsigned ( (buffer_size - 1) downto 0 );  -- goes to BRAM_buffer, address signal
           data_out: out unsigned ( (bit_num - 1) downto 0 ); -- goes to data_in of BRAM_buffer
           --MODE_3--
           threshold: in unsigned ( (11 - 1) downto 0 );
           capt_num_of_samples: in unsigned ( (byte - 1) downto 0);
           INT_res: out std_logic; --reset signal za integrator
           
           SW_trigger_value: in unsigned(4 downto 0);
           PM_trigger_in: in unsigned ( (adc_bit_num - 1) downto 0)
          );
    end component;
   
   
    component BRAM_buffer is
       
        generic (
                  bit_num : natural := 10; --number of data bits
                  buffer_size : natural := 26); -- buffer size in bits, 5 bit gets 32 different values
       
        port (
               clk: in std_logic;
               AD_wr_en: in std_logic; --from AD unit, enable writing into bram
               AD_addr: in unsigned ( (buffer_size - 1) downto 0); --from AD unit, address for writing
               PE_addr: in unsigned ( (buffer_size - 1) downto 0 ); -- from PE_unit, address for reading
               PE_wr_en: in std_logic; -- from PE_unit, enable writing into PE unit
               data_in : in unsigned ( (bit_num - 1) downto 0 ); --data from ADC
               data_out : out unsigned ( (bit_num - 1) downto 0 ); -- data for PE_unit
               BUFF_data_ready: out std_logic --signal, ki PE_enoti pove, da so podatki pripravljeni (prviè)--preveri ali je to potrebno, ker bodo itak samo nièle letele iz PE enote predn se kaj vpiše, nièle lahko na raèunalniku preè vržem
              );
           
    end component;
   
   
     component PE_unit
        generic (
                  bit_num : natural := 10;
                  bin_num : natural := 1024;
                  buffer_size : natural := 5;
                  byte: natural := 8;
                  mode: string := "MODE_3" );
        port (
                clk: in std_logic;
                UC_wr_en: in std_logic; --microprocessor tells PE_unit that it read current data and is ready for the next one -- ustavljanje, pošiljaj histogram takrat, ko je procesor ready, ne vsak clk cikel
                PE_START: in std_logic; --flag that tells PE_unit that BRAM_buffer is full
                data_in : in unsigned ( (bit_num - 1) downto 0 ); --data for PE unit from BRAM_buffer
                BUFF_addr: out unsigned ( (buffer_size - 1) downto 0 ); -- address for BRAM_buffer, goes to PE_addr
                PE_wr_rd_en: out std_logic; -- signal to tell BRAM_buffer to start sending when '1' and to tell PE_unit to start sending when '0'
                data_out: out unsigned ( buffer_size downto 0 ); -- output data
                UC_rd_en_final: out std_logic; --tells microprocessor that data is ready to be sent from PE_unit to microprocessor
                ---MODE_3 additional ports---
                write_A_M3: in std_logic; --gre na write_A, ko smo v postopku branja,  
                PE_RESET: in std_logic;
                ADC_unit_RESET: out std_logic;
                UC_rd_en_current: out std_logic  
             );
    end component;


------------------SIGNALS--------------------------
   
    --ADC_unit signals
     signal PE_wr_rd_en_all_units: unsigned ( (num_of_units - 1) downto 0 ) := (others => '0'); -- combines all PE_wr_rd signals together
     signal zeros: unsigned ( (num_of_units - 1) downto 0 ) := (others => '0');
     signal ones:  unsigned ( (num_of_units - 1) downto 0 ) := (others => '1');
     signal PE_wr_rd_en_sig: std_logic;-- := '0';
     signal ADC_unit_feedback_sig: std_logic := '0';
     signal ADC_threshold_sig: unsigned ( 10 downto 0) := (others => '0');
     signal ADC_capt_num_of_samples_sig: unsigned ( (byte - 1) downto 0 ) := (others => '0');
     signal ADC_unit_RESET_sig: std_logic := '0';
     
     signal SW_trigger_value_sig : unsigned (4 downto 0) :=  (others => '0');
     
 
     signal AD_wr_en_sig: unsigned ( (num_of_units - 1) downto 0 ) := (others => '0') ;
     signal AD_addr_sig: unsigned ( (buffer_size - 1) downto 0 ) := (others => '0');
     signal ADC_data_sig: unsigned ( (bit_num - 1) downto 0 ) := (others => '0');
     
     --BRAM_buffer_signals
     type buff_data_connection is array ( 0 to (num_of_units -1) ) of unsigned ( (bit_num - 1) downto 0 );
     signal BUFF_data_out : buff_data_connection := (others => (others => '0'));
     
     signal BUFF_en: unsigned ( (num_of_units - 1) downto 0 );
     signal BUFF_data_in: unsigned ( (bit_num - 1) downto 0 );
     
     signal BUFF_data_ready_sig: std_logic := '0';
     signal PE_BUFF_addr_sig_1 : unsigned ( (buffer_size - 1) downto 0):= (others => '0');
     signal PE_BUFF_addr_sig_2 : unsigned ( (buffer_size - 1) downto 0);
     
     
     --PE_unit signals
     type PE_data_connection is array ( 0 to (num_of_units - 1) ) of unsigned (buffer_size downto 0);
     signal PE_data_out : PE_data_connection := (others => (others => '0'));
     
     signal PE_en_1: std_logic;
     signal PE_en_2: std_logic;
     signal PE_en_3: std_logic;
     signal PE_data_in_1: buff_data_connection;
     signal PE_data_in_2: buff_data_connection;
     
     signal UC_rd_en_all_units : unsigned ( (num_of_units - 1) downto 0 ) := (others => '0'); -- vsi morjo bit 1, da je UC_rd_en = 1
     signal UC_rd_en_final_sig: std_logic; --procesor gleda ta signal, ko je 1, prenese 1023 podatkov in to je histogram
     signal UC_rd_en_current_sig: std_logic;
     signal UC_wr_en_sig : std_logic := '0'; -- komponenta gleda ta signal (kontrolira ga procesor), ko je falling edge, pošlje nov podatek procesorju
     
     
     --Other signals
     shared variable PE_data_sum: unsigned (23 downto 0) := (others => '0'); --glej zapiske za razporeditev podatkov na izhodno vodilo (15.11.2018)
     signal HISTOGRAM: unsigned (23 downto 0) := (others => '0'); --izhodni podatki
     
     
     --UC communication signals
     constant HIST_SYS_ADDR: std_logic_vector (19 downto 0) := X"00000"; --naslov mojega hardwarea je 0
     signal data_for_UC_sig : std_logic_vector ( (comm_bit_num - 1) downto 0 ) := (others => '0');
     signal START_sig: std_logic := '0';
     signal RESET_sig: std_logic := '0';
   
     
     
     
     signal data_in_mappped_sig:  unsigned ( (bit_num - 1) downto 0);
     
     
begin


--------COMBINATIONAL PART----------------
   
    --M5--
    PE_wr_rd_en_sig <= '0' when PE_wr_rd_en_all_units = zeros else
                       '1' when PE_wr_rd_en_all_units = ones;

    --M6--
    UC_rd_en_final_sig <= '0' when UC_rd_en_all_units = zeros else
                          '1' when UC_rd_en_all_units = ones;


    --M7--
    PE_en_3 <= PE_en_2   when (MODE = "MODE_1" or MODE = "MODE_2") else
               START_sig when MODE = "MODE_3";
   
   
--   ------SIGNALI, KI SO DRUGACE PRIKLOPLJENI NA PROCESOR------------
--   data_out <= to_integer(HISTOGRAM);
   
--   UC_wr_en_sig <= UC_wr_en; --TODO: spremenjeno 16.11. -- to ni vec tako, sedaj je signal povezan na komunikacijsko enoto
   
--   START_sig <= START; -- TODO: to za zdej, potem bo start povezan preko komunikacijske enote --POVEZANO
   

--   RESET_sig <= RESET;
--   ADC_threshold_sig <= ADC_threshold;
--   ADC_capt_num_of_samples_sig <= ADC_capt_num_of_samples;
-----------------------------------------------------------------------------
   
   
   --Multiplekserji / Demultiplekserji za eliminacijo bufferjev
   --D1--
   PE_en_1 <= AD_wr_en_sig(0) when (MODE = "MODE_2" or MODE = "MODE_3") else --ko je samo 1 enota, je itak AD_wr_en samo std_logic, ima samo 0-ti element
               '0';
   
   BUFF_en <= AD_wr_en_sig when MODE = "MODE_1"  else
              (others => '0');
   
   --D2--
   PE_data_in_1(0) <= ADC_data_sig when (MODE = "MODE_2" or MODE = "MODE_3") else
                   (others => '0');
   
   BUFF_data_in <= ADC_data_sig when MODE = "MODE_1" else
                   (others => '0');
   
   --M1--
   PE_en_2 <= PE_en_1 when (MODE = "MODE_2" or MODE = "MODE_3") else
              BUFF_data_ready_sig;  
   
   --M2--
   PE_data_in_2 <= PE_data_in_1 when (MODE = "MODE_2" or MODE = "MODE_3") else
                   BUFF_data_out;
   
   --M3--
   PE_BUFF_addr_sig_2 <= (others => '0') when (MODE = "MODE_2" or MODE = "MODE_3") else
                         PE_BUFF_addr_sig_1;
                         
   --M4--
   ADC_unit_feedback_sig <= UC_rd_en_final_sig when  ( MODE = "MODE_2" or (MODE = "MODE_3" and ADC_unit_RESET_sig = '0') ) else
                            '1' when (MODE = "MODE_3" and ADC_unit_RESET_sig = '1') else
                            PE_wr_rd_en_sig;-- za MODE_1
           
   

------------------------CONNECT COMPONENTS---------------------

    ADC_unit_connect: ADC_unit generic map ( adc_bit_num  => adc_bit_num,
                                             bit_num      => bit_num,
                                             num_of_units => num_of_units,
                                             buffer_size  => buffer_size,
                                             byte        => byte,
                                             mode        => mode)

                               port map (clk_in              => clk,
                                         START               => START_sig,
                                         data_in             => data_in,
                                         ADC_unit_feedback   => ADC_unit_feedback_sig,
                                         AD_wr_en            => AD_wr_en_sig,
                                         AD_addr             => AD_addr_sig,
                                         data_out            => ADC_data_sig,
                                         threshold           => ADC_threshold_sig,
                                         capt_num_of_samples => ADC_capt_num_of_samples_sig,
                                         INT_res             => INT_res,
                                         
                                         SW_trigger_value    => SW_trigger_value_sig,
                                         PM_trigger_in       => PM_trigger_in
                                         );
         
                                         

    BUFF_ON_OFF: if (num_of_units /= 1) generate -- if generate vklaplja in izklaplja BRAM_buffer glede na stevilo enot (num_of_units)
   
        BRAM_buffer_connect: for i in 0 to (num_of_units - 2) generate
         
                 BUFF: BRAM_buffer generic map ( bit_num     => bit_num,
                                                 buffer_size => buffer_size )
                             
                                   port map ( clk             => clk,
                                              AD_wr_en        => BUFF_en(i),
                                              AD_addr         => AD_addr_sig,
                                              PE_addr         => PE_BUFF_addr_sig_2,
                                              PE_wr_en        => PE_wr_rd_en_sig,
                                              data_in         => BUFF_data_in,
                                              data_out        => buff_data_out(i),
                                              BUFF_data_ready => open );
         end generate;
         
         BRAM_buffer_connect_BUFF_last: BRAM_buffer generic map ( bit_num     => bit_num,
                                                                  buffer_size => buffer_size )
                                             
                                                    port map ( clk => clk,
                                                               AD_wr_en        => BUFF_en(num_of_units - 1),
                                                               AD_addr         => AD_addr_sig,
                                                               PE_addr         => PE_BUFF_addr_sig_2,
                                                               PE_wr_en        => PE_wr_rd_en_sig,
                                                               data_in         => BUFF_data_in,
                                                               data_out        => buff_data_out(num_of_units - 1),
                                                               BUFF_data_ready => BUFF_data_ready_sig ); --zadnji sprozi branje v PE_enoto
                           
    end generate;
                               
                               
     PE_unit_connect: for i in 0 to (num_of_units - 1) generate
             
             PE: PE_unit generic map ( bit_num     => bit_num,
                                       bin_num     => bin_num,
                                       buffer_size => buffer_size,
                                       byte        => byte,
                                       mode        => mode )
                                       
                         port map ( clk              => clk,
                                    PE_START         => PE_en_3,
                                    data_in          => PE_data_in_2(i),
                                    BUFF_addr        => PE_BUFF_addr_sig_1,
                                    PE_wr_rd_en      => PE_wr_rd_en_all_units(i),
                                    data_out         => PE_data_out(i),
                                    UC_rd_en_final   => UC_rd_en_all_units(i), --komponenta pove procesorju, da je data ready za posiljanje v procesor
                                    UC_rd_en_current => UC_rd_en_current_sig,
                                    UC_wr_en         => UC_wr_en_sig,  -- procesor pove komponenti, da lahko poslje nov podatek
                                    write_A_M3       => PE_en_1,
                                    ADC_unit_RESET   => ADC_unit_RESET_sig,
                                    PE_RESET         => RESET_sig
                                    );
     
     end generate;
           

--------------SEQUENTIAL PART --------------------------------

    HIST_RECONSTRUCTION: process (clk)
        --variable PE_data_sum: integer := 0; --TODO: stevilo bitov tega signala in izhodnega signala mora biti:
    begin                                    -- N = buffer_size + log(number_of_units) / log(2)
                                             
        if ( rising_edge(clk) ) then
           
           
            if (UC_rd_en_final_sig = '1') then
                PE_data_sum := (others => '0'); --da se ponastavi na 0 pred vsakim seštevanjem          
                for i in 0 to (num_of_units - 1) loop
                    PE_data_sum := PE_data_sum + to_integer(PE_data_out(i)); --TODO: ali rabim tukaj to_integer ?? Bo pravilno tudi èe ga ni (signala imata razlicno st. bitov)???
                end loop;

           
            elsif (UC_rd_en_current_sig = '1') then
               
                PE_data_sum := (others => '0'); --da se ponastavi na 0 pred vsakim seštevanjem          
               
                for i in 0 to (num_of_units - 1) loop
                    PE_data_sum := PE_data_sum + to_integer(PE_data_out(i)); --TODO: ali rabim tukaj to_integer ?? Bo pravilno tudi èe ga ni (signala imata razlicno st. bitov)???
                end loop;

            end if;
           
           
           
            HISTOGRAM <= PE_data_sum;
           
           
        end if;
       
    end process;
               
     
 
 -----------------------COMMUNICATION WITH MICROPROCESSOR-----------------  
 

    REC_FROM_MICROPROCESSOR: process (clk)
   
    begin
   
        if ( rising_edge(clk) ) then
             
             if (rstn = '0') then
                START_sig <= '0';
             elsif ( wr_en = '1' and HW_addr(19 downto 0) = HIST_SYS_ADDR ) then -- Q: kaksen naj bo HW address??  --mora biti 19 downto 0, tako kot na vajah
                START_sig <= data_from_UC(0);
                RESET_sig <= data_from_UC(1);
                ADC_threshold_sig <= unsigned(data_from_UC(18 downto 8));
                ADC_capt_num_of_samples_sig <= unsigned(data_from_UC(26 downto 19));
                SW_trigger_value_sig <= unsigned(data_from_UC(31 downto 27));
               
             end if;
             
         end if;
         
    end process;
   
 -----------------------  
    UC_wr_en_sig <= rd_en; -- signal za menjavo izhodnih podatkov iz komponente
    data_for_UC_sig <= std_logic_vector(HISTOGRAM) & "00000" & START_sig & UC_rd_en_current_sig & UC_rd_en_final_sig;    --Q: a bo to OK, ta pretvorba?? Se kej podatkov izgubi ali pomesa??
    error <= '0'; -- iz vaje 7                                      
   
    --data_for_UC_sig <=== zlozim vse podatke, ki jih hocem poslati procesorju v 32 bitni signal
   
    SEND_TO_MICROPROCESSOR: process (HW_addr, wr_en, rd_en, UC_rd_en_final_sig)
   
    begin
       
        if ( (wr_en or rd_en)  = '1' ) then
            ack <= '1';
        end if;
       
        if ( HW_addr(19 downto 0) = HIST_SYS_ADDR ) then
            data_for_UC <= data_for_UC_sig;
        else
            data_for_UC <= (others =>'0');
        end if;
       
    end process;
 
      --Q: kje pa tukaj pride rn_en oz UC_wr_en_sig v postev???

                                       
                                         
                                         

end Behavioral;