Index: /firmware/FAD/FACT_FAD_20MHz_VAR_PS/FACT_FAD_lib/hdl/memory_manager_2.vhd
===================================================================
--- /firmware/FAD/FACT_FAD_20MHz_VAR_PS/FACT_FAD_lib/hdl/memory_manager_2.vhd	(revision 10889)
+++ /firmware/FAD/FACT_FAD_20MHz_VAR_PS/FACT_FAD_lib/hdl/memory_manager_2.vhd	(revision 10889)
@@ -0,0 +1,400 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use ieee.STD_LOGIC_UNSIGNED.all;
+
+library FACT_FAD_lib;
+use FACT_FAD_lib.fad_definitions.all;
+
+-- library UNISIM;
+-- use UNISIM.VComponents.all;
+-- USE IEEE.NUMERIC_STD.all;
+
+-- RAM_ADDR_WIDTH_64B is used for 
+-- output ram_start_addr
+
+-- RAM_ADDR_WIDTH_16B is used for
+-- output wiz_ram_start_addr 
+
+
+ENTITY memory_manager_2 IS
+generic(
+	RAM_ADDR_WIDTH_64B : integer := 12;
+	RAM_ADDR_WIDTH_16B : integer := 14 
+);
+PORT( 
+	state          : OUT    std_logic_vector (3 DOWNTO 0);  -- state is encoded here ... useful for debugging.
+
+	clk : IN std_logic;
+	
+	-- CONFIG handshake:
+	config_start : IN std_logic;
+	config_ready : OUT std_logic := '1';
+		-- output of CONFIG states
+	roi_array : IN roi_array_type;
+	roi_max : OUT roi_max_type := (others => conv_std_logic_vector (0, 11));
+	package_length : OUT std_logic_vector (15 downto 0) := (others => '0');
+	
+	wiz_number_of_channels : OUT std_logic_vector (3 downto 0) := (others => '0');
+	
+	-- interface to DG:
+	dg_start_config : OUT std_logic := '0';
+	dg_config_done : IN std_logic;
+	ram_write_ready : IN std_logic;
+	ram_write_ea : OUT std_logic := '0';
+	ram_start_addr : OUT std_logic_vector (RAM_ADDR_WIDTH_64B-1 DOWNTO 0) := (others => '0');
+	
+	-- interface to W5300:
+	wiz_read_done : IN std_logic;
+	wiz_write_ea : OUT std_logic := '0';
+	wiz_write_length : OUT std_logic_vector (16 downto 0) := (others => '0');
+	wiz_ram_start_addr : OUT std_logic_vector (RAM_ADDR_WIDTH_16B-1 downto 0) := (others => '0');
+	wiz_write_header : OUT std_logic := '0';
+	wiz_write_end : OUT std_logic := '0';
+	
+	
+	data_ram_empty : out std_logic			-- stupid signal, I need to get rid of it. DN 23.05.2011
+);
+
+-- Declarations
+
+END memory_manager_2 ;
+
+--
+ARCHITECTURE beha OF memory_manager_2 IS
+
+type state_mm_type is (	MM_CONFIG, MAX_ROI, MAX_ROI1, MAX_ROI2, FIFO_CALC, RAM_CALC, RAM_CALC1, RAM_CALC2, 
+						CONFIG_DG, WAIT_FOR_CONFIG_DG,
+						MM_MAIN,
+						WRITE_FIN, READ_FIN, UPDATE_OUTPUT, UPDATE_OUTPUT_2);
+signal state_mm : state_mm_type := MM_CONFIG;
+
+--type roi_array_type is array (0 to 35) of integer range 0 to 1024;
+type roi_max_array_type is array (0 to 8) of integer range 0 to 1024;
+type channel_size_type is array (0 to 8) of integer range 0 to W5300_TX_FIFO_SIZE;
+type fifo_write_length_type is array (0 to 8) of integer range 0 to W5300_TX_FIFO_SIZE;
+type fifo_channels_array_type is array (0 to 8) of integer range 0 to 9;
+type fifo_package_size_ram_type is array (0 to 8) of integer range 0 to RAM_SIZE_16B;
+
+signal roi_max_array : roi_max_array_type := (others => 0);
+
+-- size of channel groups (16 bit)
+signal channel_size : channel_size_type := (others => 0);
+-- write length of packages (16 bit)
+signal fifo_write_length : fifo_write_length_type := (others => 0);
+-- number of channels per package
+signal fifo_channels_array : fifo_channels_array_type := (others => 0);
+-- size of packages in ram (16 bit)
+signal fifo_package_size_ram : fifo_package_size_ram_type := (others => 0);
+--
+signal event_size_ram : integer range 0 to RAM_SIZE_16B := 0;
+signal event_size_ram_64b : integer range 0 to RAM_SIZE_64B := 0;
+signal event_size : integer range 0 to RAM_SIZE_16B := 0;
+
+signal drs_id : integer range 0 to 4 := 0;
+signal channel_id : integer range 0 to 9 := 0;
+signal channel_index : integer range 0 to 9 := 0;
+signal package_index : integer range 0 to 9 := 0;
+signal number_of_packages : integer range 0 to 9 := 0;
+signal max_events_ram : integer range 0 to 2048;
+signal events_in_ram : integer range 0 to 2048;
+signal event_start_addr : integer range 0 to (RAM_SIZE_64B - 1);
+signal write_start_addr : integer range 0 to (RAM_SIZE_16B - 1);
+
+
+signal roi_index : integer range 0 to 45 := 0;
+signal temp_roi : integer range 0 to 1024 := 0;
+
+-- SYNCH IN INPUT SIGNALS -----------------------------------------
+
+	signal config_start_sr		: std_logic_vector(1 downto 0) := "00";
+	signal ram_write_ready_sr	: std_logic_vector(1 downto 0) := "00";
+	signal wiz_read_ready_sr 			: std_logic_vector(1 downto 0) := "00";
+	signal dg_config_done_sr : std_logic_vector(1 downto 0) := "00";
+		-- no shift register, but local copy.
+	signal roi_array_local : roi_array_type;
+	
+	
+	signal state_sig : std_logic_vector( 3 downto 0 ) := "0000";
+
+BEGIN
+	state <= state_sig;
+
+	data_ram_empty <= '1' when events_in_ram = 0 else '0'; 
+  
+	mm : process (clk)
+	begin
+		if rising_edge (clk) then
+		-- here: the synchin in of asynchronous input signals takes place. 
+		config_start_sr		<= config_start_sr(0) & config_start;
+		ram_write_ready_sr	<= ram_write_ready_sr(0) & ram_write_ready;
+		wiz_read_ready_sr 			<= wiz_read_ready_sr(0) & wiz_read_done;
+		dg_config_done_sr <= dg_config_done_sr(0) & dg_config_done;
+		roi_array_local 	<= roi_array;
+		
+		case state_mm is
+		
+		
+		
+    
+        when MM_CONFIG =>
+			state_sig <= X"1";
+
+			
+            config_ready <= '0';
+            roi_max_array <= (others => 0);
+            channel_size <= (others => 0);
+            fifo_write_length <= (others => 0);
+            fifo_channels_array <= (others => 0);
+            event_size <= 0;
+            ram_write_ea <= '0';
+			wiz_write_ea <= '0';
+            state_mm <= MAX_ROI;
+          
+        
+        -- calculate max ROIs and channel sizes
+        when MAX_ROI =>
+			state_sig <= X"2";
+          roi_index <= (drs_id * 9) + channel_id;
+          state_mm <= MAX_ROI1;
+        when MAX_ROI1 =>
+			state_sig <= X"3";
+          temp_roi <= roi_array_local (roi_index);
+          state_mm <= MAX_ROI2;
+        when MAX_ROI2 =>
+			state_sig <= X"4";
+          if (channel_id < 9) then
+            if ( temp_roi > roi_max_array (channel_id)) then
+              roi_max_array (channel_id) <= temp_roi;
+            end if;
+            channel_size (channel_id) <= channel_size (channel_id) + temp_roi + CHANNEL_HEADER_SIZE;
+            drs_id <= drs_id + 1;
+            state_mm <= MAX_ROI;
+            if (drs_id = 3) then
+              drs_id <= 0;
+              channel_id <= channel_id + 1;
+            end if;
+          else
+            drs_id <= 0;
+            channel_id <= 0;
+            channel_size (0) <= channel_size (0) + PACKAGE_HEADER_LENGTH;
+            channel_size (8) <= channel_size (8) + PACKAGE_END_LENGTH;
+            state_mm <= FIFO_CALC;
+          end if;
+        
+        -- calculate number of channels that fit in FIFO
+        when FIFO_CALC =>
+			state_sig <= X"5";
+          if (channel_id < 9) then
+            if ((fifo_write_length (package_index) + channel_size (channel_id)) <= W5300_TX_FIFO_SIZE) then
+              fifo_write_length (package_index) <= fifo_write_length (package_index) + channel_size (channel_id);
+              fifo_channels_array (package_index) <= fifo_channels_array (package_index) + 1;
+              channel_id <= channel_id + 1;
+              event_size <= event_size + channel_size (channel_id);
+            else
+              package_index <= package_index + 1;
+            end if;
+          else
+            number_of_packages <= package_index + 1;
+            package_index <= 0;
+            channel_index <= 0;
+            channel_id <= 0;
+            fifo_package_size_ram <= (others => 0);
+            fifo_package_size_ram (0) <= PACKAGE_HEADER_LENGTH + PACKAGE_HEADER_ZEROS; 
+            event_size_ram <= 0;
+            event_size_ram_64b <= 0;
+            max_events_ram <= 0;           
+            state_mm <= RAM_CALC;
+          end if;
+          
+        when RAM_CALC =>
+			state_sig <= X"6";
+          if (package_index < number_of_packages) then
+            if (channel_index < fifo_channels_array (package_index)) then
+              fifo_package_size_ram (package_index) <= 
+			  fifo_package_size_ram (package_index) + ((roi_max_array (channel_id) + CHANNEL_HEADER_SIZE) * NUMBER_OF_DRS);
+              channel_index <= channel_index + 1;
+              channel_id <= channel_id + 1;
+            else
+              package_index <= package_index + 1;
+              event_size_ram <= event_size_ram + fifo_package_size_ram (package_index);
+              channel_index <= 0;
+            end if;
+          else
+            fifo_package_size_ram (package_index - 1) <= fifo_package_size_ram (package_index - 1) + PACKAGE_END_LENGTH + PACKAGE_END_ZEROS;
+            event_size_ram <= event_size_ram + PACKAGE_END_LENGTH + PACKAGE_END_ZEROS;
+            state_mm <= RAM_CALC1;
+          end if;
+        when RAM_CALC1 =>
+			state_sig <= X"7";
+          max_events_ram <= max_events_ram + 1;
+          if ((max_events_ram * event_size_ram) <= RAM_SIZE_16B) then
+            state_mm <= RAM_CALC1;
+          else
+            max_events_ram <= max_events_ram - 1;
+            state_mm <= RAM_CALC2;
+          end if;
+        when RAM_CALC2 =>
+			state_sig <= X"8";
+          event_size_ram_64b <= (event_size_ram / 4);
+          events_in_ram <= 0;
+          event_start_addr <= 0;
+          write_start_addr <= 0;
+          package_index <= 0;
+          channel_id <= 0;
+          ram_start_addr <= (others => '0');
+          
+          package_length <= conv_std_logic_vector (event_size, 16);
+          for i in 0 to 8 loop
+            roi_max(i) <= conv_std_logic_vector(roi_max_array(i), 11);
+          end loop;
+          state_mm <= CONFIG_DG;
+		  
+		 when CONFIG_DG =>
+			state_sig <= X"9";
+			dg_start_config <= '1';
+			state_mm <= CONFIG_DG;
+			if (dg_config_done_sr(1) = '0') then
+				dg_start_config <= '0';
+				state_mm <= WAIT_FOR_CONFIG_DG;
+			end if;
+		 
+		 when WAIT_FOR_CONFIG_DG =>
+			state_sig <= X"E";
+			state_mm <= WAIT_FOR_CONFIG_DG;
+			if (dg_config_done_sr(1) = '1') then
+				state_mm <= UPDATE_OUTPUT;
+			end if;
+		  
+		  
+		when MM_MAIN =>
+			state_sig <= X"A";
+			state_mm <= MM_MAIN;
+			
+			config_ready <= '1';
+		
+			if (config_start_sr(1) = '1') then
+				state_mm <= MM_CONFIG;
+				
+			elsif (ram_write_ready_sr(1) = '1') then
+				-- this is part of the DG - MM handshake. 
+				-- pulling write_ea low shows that MM understood DG is ready
+				ram_write_ea <= '0';
+
+				events_in_ram <= events_in_ram + 1;
+				if ((event_start_addr + event_size_ram_64b) < (RAM_SIZE_64B - event_size_ram_64b)) then
+				  event_start_addr <= event_start_addr + event_size_ram_64b;
+				else
+				  event_start_addr <= 0;
+				end if;
+				state_mm <= WRITE_FIN;
+				
+			elsif (wiz_read_ready_sr(1) = '1') then
+				wiz_write_ea <= '0';
+				
+				if (package_index = (number_of_packages - 1)) then
+				
+					-- next address 
+					if ((write_start_addr + fifo_package_size_ram (package_index)) < (RAM_SIZE_16B - event_size_ram)) then
+						write_start_addr <= write_start_addr + fifo_package_size_ram (package_index);
+					else
+						write_start_addr <= 0;
+					end if;
+				else
+					write_start_addr <= write_start_addr + fifo_package_size_ram (package_index);
+				end if;
+				
+				-- increase pack_index
+				-- the package_index goes from 0..NumOfPack-1
+				
+				if ( package_index < (number_of_packages - 1)) then
+					package_index <= package_index + 1;
+				else
+					package_index <= 0;
+					events_in_ram <= events_in_ram - 1;
+				end if;
+				
+				
+				
+				
+				state_mm <= READ_FIN;
+			
+			end if;
+		  
+		------------------------- WRITING to MEM was finished ------------------------------------
+		------------------------------------------------------------------------------------------		  
+		when WRITE_FIN =>
+			state_sig <= X"B";
+			ram_start_addr <= conv_std_logic_vector(event_start_addr, RAM_ADDR_WIDTH_64B);
+			-- 2nd part of hand shake is, that DG pulls low ram_write_ready
+			if (ram_write_ready_sr(1) = '0') then
+				state_mm <= UPDATE_OUTPUT;
+			end if;
+			
+
+		------------------------- READING from MEM was finished ----------------------------------
+		------------------------------------------------------------------------------------------
+			
+		when READ_FIN =>
+			state_sig <= X"C";
+			if (wiz_read_ready_sr(1) = '0') then 
+				
+			
+				state_mm <= UPDATE_OUTPUT;
+			end if;
+			
+						
+			
+		 
+		when UPDATE_OUTPUT =>
+				
+			   
+				wiz_ram_start_addr <= conv_std_logic_vector(write_start_addr, RAM_ADDR_WIDTH_16B);
+				wiz_write_length <= conv_std_logic_vector(fifo_write_length (package_index), 17);
+				wiz_number_of_channels <= conv_std_logic_vector(fifo_channels_array (package_index), 4);
+				
+				if (package_index = 0) then
+					-- first package -> write header
+					wiz_write_header <= '1';
+				else
+					wiz_write_header <= '0';
+				end if;
+				if (package_index = (number_of_packages - 1)) then
+					-- last package -> write end-flag
+					wiz_write_end <= '1';
+				else
+					wiz_write_end <= '0';
+				end if;
+			
+			state_mm <= UPDATE_OUTPUT_2;
+		
+		
+		when UPDATE_OUTPUT_2 =>
+			state_sig <= X"D";
+			state_mm <= MM_MAIN;
+			
+			if (events_in_ram > 0) then
+				wiz_write_ea <= '1';
+			else 
+				wiz_write_ea <= '0';
+			end if;  
+			
+			if (events_in_ram < max_events_ram) then
+				ram_write_ea <= '1';              
+			else 
+				ram_write_ea <= '0';
+			end if;
+			
+			
+		when others =>
+			state_sig <= X"F";
+			state_mm <= MM_CONFIG;
+       
+      end case; -- state_mm
+    end if;
+  end process mm; 
+  
+   
+  
+END ARCHITECTURE beha;
+
