----------------------------------------------------------------------------------
-- 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 vpie, nièle lahko na raèunalniku preè vrem
);
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, poiljaj 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, polje 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 setevanjem
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 setevanjem
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;