| 1 | library ieee;
|
|---|
| 2 | use ieee.std_logic_1164.all;
|
|---|
| 3 | use IEEE.STD_LOGIC_ARITH.all;
|
|---|
| 4 | use ieee.STD_LOGIC_UNSIGNED.all;
|
|---|
| 5 |
|
|---|
| 6 | library FACT_FAD_lib;
|
|---|
| 7 | use FACT_FAD_lib.fad_definitions.all;
|
|---|
| 8 |
|
|---|
| 9 | -- library UNISIM;
|
|---|
| 10 | -- use UNISIM.VComponents.all;
|
|---|
| 11 | -- USE IEEE.NUMERIC_STD.all;
|
|---|
| 12 |
|
|---|
| 13 | -- RAM_ADDR_WIDTH_64B is used for
|
|---|
| 14 | -- output ram_start_addr
|
|---|
| 15 |
|
|---|
| 16 | -- RAM_ADDR_WIDTH_16B is used for
|
|---|
| 17 | -- output wiz_ram_start_addr
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 | ENTITY memory_manager_2 IS
|
|---|
| 21 | generic(
|
|---|
| 22 | RAM_ADDR_WIDTH_64B : integer := 12;
|
|---|
| 23 | RAM_ADDR_WIDTH_16B : integer := 14
|
|---|
| 24 | );
|
|---|
| 25 | PORT(
|
|---|
| 26 | state : OUT std_logic_vector (3 DOWNTO 0); -- state is encoded here ... useful for debugging.
|
|---|
| 27 |
|
|---|
| 28 | clk : IN std_logic;
|
|---|
| 29 |
|
|---|
| 30 | -- CONFIG handshake:
|
|---|
| 31 | config_start : IN std_logic;
|
|---|
| 32 | config_ready : OUT std_logic := '1';
|
|---|
| 33 | -- output of CONFIG states
|
|---|
| 34 | roi_array : IN roi_array_type;
|
|---|
| 35 | roi_max : OUT roi_max_type := (others => conv_std_logic_vector (0, 11));
|
|---|
| 36 | package_length : OUT std_logic_vector (15 downto 0) := (others => '0');
|
|---|
| 37 |
|
|---|
| 38 | wiz_number_of_channels : OUT std_logic_vector (3 downto 0) := (others => '0');
|
|---|
| 39 |
|
|---|
| 40 | -- interface to DG:
|
|---|
| 41 | dg_start_config : OUT std_logic := '0';
|
|---|
| 42 | dg_config_done : IN std_logic;
|
|---|
| 43 | ram_write_ready : IN std_logic;
|
|---|
| 44 | ram_write_ea : OUT std_logic := '0';
|
|---|
| 45 | ram_start_addr : OUT std_logic_vector (RAM_ADDR_WIDTH_64B-1 DOWNTO 0) := (others => '0');
|
|---|
| 46 |
|
|---|
| 47 | -- interface to W5300:
|
|---|
| 48 | wiz_read_done : IN std_logic;
|
|---|
| 49 | wiz_write_ea : OUT std_logic := '0';
|
|---|
| 50 | wiz_write_length : OUT std_logic_vector (16 downto 0) := (others => '0');
|
|---|
| 51 | wiz_ram_start_addr : OUT std_logic_vector (RAM_ADDR_WIDTH_16B-1 downto 0) := (others => '0');
|
|---|
| 52 | wiz_write_header : OUT std_logic := '0';
|
|---|
| 53 | wiz_write_end : OUT std_logic := '0';
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 | data_ram_empty : out std_logic -- stupid signal, I need to get rid of it. DN 23.05.2011
|
|---|
| 57 | );
|
|---|
| 58 |
|
|---|
| 59 | -- Declarations
|
|---|
| 60 |
|
|---|
| 61 | END memory_manager_2 ;
|
|---|
| 62 |
|
|---|
| 63 | --
|
|---|
| 64 | ARCHITECTURE beha OF memory_manager_2 IS
|
|---|
| 65 |
|
|---|
| 66 | type state_mm_type is ( MM_CONFIG, MAX_ROI, MAX_ROI1, MAX_ROI2, FIFO_CALC, RAM_CALC, RAM_CALC1, RAM_CALC2,
|
|---|
| 67 | CONFIG_DG, WAIT_FOR_CONFIG_DG,
|
|---|
| 68 | MM_MAIN,
|
|---|
| 69 | WRITE_FIN, READ_FIN, UPDATE_OUTPUT, UPDATE_OUTPUT_2);
|
|---|
| 70 | signal state_mm : state_mm_type := MM_CONFIG;
|
|---|
| 71 |
|
|---|
| 72 | --type roi_array_type is array (0 to 35) of integer range 0 to 1024;
|
|---|
| 73 | type roi_max_array_type is array (0 to 8) of integer range 0 to 1024;
|
|---|
| 74 | type channel_size_type is array (0 to 8) of integer range 0 to W5300_TX_FIFO_SIZE;
|
|---|
| 75 | type fifo_write_length_type is array (0 to 8) of integer range 0 to W5300_TX_FIFO_SIZE;
|
|---|
| 76 | type fifo_channels_array_type is array (0 to 8) of integer range 0 to 9;
|
|---|
| 77 | type fifo_package_size_ram_type is array (0 to 8) of integer range 0 to RAM_SIZE_16B;
|
|---|
| 78 |
|
|---|
| 79 | signal roi_max_array : roi_max_array_type := (others => 0);
|
|---|
| 80 |
|
|---|
| 81 | -- size of channel groups (16 bit)
|
|---|
| 82 | signal channel_size : channel_size_type := (others => 0);
|
|---|
| 83 | -- write length of packages (16 bit)
|
|---|
| 84 | signal fifo_write_length : fifo_write_length_type := (others => 0);
|
|---|
| 85 | -- number of channels per package
|
|---|
| 86 | signal fifo_channels_array : fifo_channels_array_type := (others => 0);
|
|---|
| 87 | -- size of packages in ram (16 bit)
|
|---|
| 88 | signal fifo_package_size_ram : fifo_package_size_ram_type := (others => 0);
|
|---|
| 89 | --
|
|---|
| 90 | signal event_size_ram : integer range 0 to RAM_SIZE_16B := 0;
|
|---|
| 91 | signal event_size_ram_64b : integer range 0 to RAM_SIZE_64B := 0;
|
|---|
| 92 | signal event_size : integer range 0 to RAM_SIZE_16B := 0;
|
|---|
| 93 |
|
|---|
| 94 | signal drs_id : integer range 0 to 4 := 0;
|
|---|
| 95 | signal channel_id : integer range 0 to 9 := 0;
|
|---|
| 96 | signal channel_index : integer range 0 to 9 := 0;
|
|---|
| 97 | signal package_index : integer range 0 to 9 := 0;
|
|---|
| 98 | signal number_of_packages : integer range 0 to 9 := 0;
|
|---|
| 99 | signal max_events_ram : integer range 0 to 2048;
|
|---|
| 100 | signal events_in_ram : integer range 0 to 2048;
|
|---|
| 101 | signal event_start_addr : integer range 0 to (RAM_SIZE_64B - 1);
|
|---|
| 102 | signal write_start_addr : integer range 0 to (RAM_SIZE_16B - 1);
|
|---|
| 103 |
|
|---|
| 104 |
|
|---|
| 105 | signal roi_index : integer range 0 to 45 := 0;
|
|---|
| 106 | signal temp_roi : integer range 0 to 1024 := 0;
|
|---|
| 107 |
|
|---|
| 108 | -- SYNCH IN INPUT SIGNALS -----------------------------------------
|
|---|
| 109 |
|
|---|
| 110 | signal config_start_sr : std_logic_vector(1 downto 0) := "00";
|
|---|
| 111 | signal ram_write_ready_sr : std_logic_vector(1 downto 0) := "00";
|
|---|
| 112 | signal wiz_read_ready_sr : std_logic_vector(1 downto 0) := "00";
|
|---|
| 113 | signal dg_config_done_sr : std_logic_vector(1 downto 0) := "00";
|
|---|
| 114 | -- no shift register, but local copy.
|
|---|
| 115 | signal roi_array_local : roi_array_type;
|
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| 118 | signal state_sig : std_logic_vector( 3 downto 0 ) := "0000";
|
|---|
| 119 |
|
|---|
| 120 | BEGIN
|
|---|
| 121 | state <= state_sig;
|
|---|
| 122 |
|
|---|
| 123 | data_ram_empty <= '1' when events_in_ram = 0 else '0';
|
|---|
| 124 |
|
|---|
| 125 | mm : process (clk)
|
|---|
| 126 | begin
|
|---|
| 127 | if rising_edge (clk) then
|
|---|
| 128 | -- here: the synchin in of asynchronous input signals takes place.
|
|---|
| 129 | config_start_sr <= config_start_sr(0) & config_start;
|
|---|
| 130 | ram_write_ready_sr <= ram_write_ready_sr(0) & ram_write_ready;
|
|---|
| 131 | wiz_read_ready_sr <= wiz_read_ready_sr(0) & wiz_read_done;
|
|---|
| 132 | dg_config_done_sr <= dg_config_done_sr(0) & dg_config_done;
|
|---|
| 133 | roi_array_local <= roi_array;
|
|---|
| 134 |
|
|---|
| 135 | case state_mm is
|
|---|
| 136 |
|
|---|
| 137 |
|
|---|
| 138 |
|
|---|
| 139 |
|
|---|
| 140 | when MM_CONFIG =>
|
|---|
| 141 | state_sig <= X"1";
|
|---|
| 142 |
|
|---|
| 143 |
|
|---|
| 144 | config_ready <= '0';
|
|---|
| 145 | roi_max_array <= (others => 0);
|
|---|
| 146 | channel_size <= (others => 0);
|
|---|
| 147 | fifo_write_length <= (others => 0);
|
|---|
| 148 | fifo_channels_array <= (others => 0);
|
|---|
| 149 | event_size <= 0;
|
|---|
| 150 | ram_write_ea <= '0';
|
|---|
| 151 | wiz_write_ea <= '0';
|
|---|
| 152 | state_mm <= MAX_ROI;
|
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 | -- calculate max ROIs and channel sizes
|
|---|
| 156 | when MAX_ROI =>
|
|---|
| 157 | state_sig <= X"2";
|
|---|
| 158 | roi_index <= (drs_id * 9) + channel_id;
|
|---|
| 159 | state_mm <= MAX_ROI1;
|
|---|
| 160 | when MAX_ROI1 =>
|
|---|
| 161 | state_sig <= X"3";
|
|---|
| 162 | temp_roi <= roi_array_local (roi_index);
|
|---|
| 163 | state_mm <= MAX_ROI2;
|
|---|
| 164 | when MAX_ROI2 =>
|
|---|
| 165 | state_sig <= X"4";
|
|---|
| 166 | if (channel_id < 9) then
|
|---|
| 167 | if ( temp_roi > roi_max_array (channel_id)) then
|
|---|
| 168 | roi_max_array (channel_id) <= temp_roi;
|
|---|
| 169 | end if;
|
|---|
| 170 | channel_size (channel_id) <= channel_size (channel_id) + temp_roi + CHANNEL_HEADER_SIZE;
|
|---|
| 171 | drs_id <= drs_id + 1;
|
|---|
| 172 | state_mm <= MAX_ROI;
|
|---|
| 173 | if (drs_id = 3) then
|
|---|
| 174 | drs_id <= 0;
|
|---|
| 175 | channel_id <= channel_id + 1;
|
|---|
| 176 | end if;
|
|---|
| 177 | else
|
|---|
| 178 | drs_id <= 0;
|
|---|
| 179 | channel_id <= 0;
|
|---|
| 180 | channel_size (0) <= channel_size (0) + PACKAGE_HEADER_LENGTH;
|
|---|
| 181 | channel_size (8) <= channel_size (8) + PACKAGE_END_LENGTH;
|
|---|
| 182 | state_mm <= FIFO_CALC;
|
|---|
| 183 | end if;
|
|---|
| 184 |
|
|---|
| 185 | -- calculate number of channels that fit in FIFO
|
|---|
| 186 | when FIFO_CALC =>
|
|---|
| 187 | state_sig <= X"5";
|
|---|
| 188 | if (channel_id < 9) then
|
|---|
| 189 | if ((fifo_write_length (package_index) + channel_size (channel_id)) <= W5300_TX_FIFO_SIZE) then
|
|---|
| 190 | fifo_write_length (package_index) <= fifo_write_length (package_index) + channel_size (channel_id);
|
|---|
| 191 | fifo_channels_array (package_index) <= fifo_channels_array (package_index) + 1;
|
|---|
| 192 | channel_id <= channel_id + 1;
|
|---|
| 193 | event_size <= event_size + channel_size (channel_id);
|
|---|
| 194 | else
|
|---|
| 195 | package_index <= package_index + 1;
|
|---|
| 196 | end if;
|
|---|
| 197 | else
|
|---|
| 198 | number_of_packages <= package_index + 1;
|
|---|
| 199 | package_index <= 0;
|
|---|
| 200 | channel_index <= 0;
|
|---|
| 201 | channel_id <= 0;
|
|---|
| 202 | fifo_package_size_ram <= (others => 0);
|
|---|
| 203 | fifo_package_size_ram (0) <= PACKAGE_HEADER_LENGTH + PACKAGE_HEADER_ZEROS;
|
|---|
| 204 | event_size_ram <= 0;
|
|---|
| 205 | event_size_ram_64b <= 0;
|
|---|
| 206 | max_events_ram <= 0;
|
|---|
| 207 | state_mm <= RAM_CALC;
|
|---|
| 208 | end if;
|
|---|
| 209 |
|
|---|
| 210 | when RAM_CALC =>
|
|---|
| 211 | state_sig <= X"6";
|
|---|
| 212 | if (package_index < number_of_packages) then
|
|---|
| 213 | if (channel_index < fifo_channels_array (package_index)) then
|
|---|
| 214 | fifo_package_size_ram (package_index) <=
|
|---|
| 215 | fifo_package_size_ram (package_index) + ((roi_max_array (channel_id) + CHANNEL_HEADER_SIZE) * NUMBER_OF_DRS);
|
|---|
| 216 | channel_index <= channel_index + 1;
|
|---|
| 217 | channel_id <= channel_id + 1;
|
|---|
| 218 | else
|
|---|
| 219 | package_index <= package_index + 1;
|
|---|
| 220 | event_size_ram <= event_size_ram + fifo_package_size_ram (package_index);
|
|---|
| 221 | channel_index <= 0;
|
|---|
| 222 | end if;
|
|---|
| 223 | else
|
|---|
| 224 | fifo_package_size_ram (package_index - 1) <= fifo_package_size_ram (package_index - 1) + PACKAGE_END_LENGTH + PACKAGE_END_ZEROS;
|
|---|
| 225 | event_size_ram <= event_size_ram + PACKAGE_END_LENGTH + PACKAGE_END_ZEROS;
|
|---|
| 226 | state_mm <= RAM_CALC1;
|
|---|
| 227 | end if;
|
|---|
| 228 | when RAM_CALC1 =>
|
|---|
| 229 | state_sig <= X"7";
|
|---|
| 230 | max_events_ram <= max_events_ram + 1;
|
|---|
| 231 | if ((max_events_ram * event_size_ram) <= RAM_SIZE_16B) then
|
|---|
| 232 | state_mm <= RAM_CALC1;
|
|---|
| 233 | else
|
|---|
| 234 | max_events_ram <= max_events_ram - 1;
|
|---|
| 235 | state_mm <= RAM_CALC2;
|
|---|
| 236 | end if;
|
|---|
| 237 | when RAM_CALC2 =>
|
|---|
| 238 | state_sig <= X"8";
|
|---|
| 239 | event_size_ram_64b <= (event_size_ram / 4);
|
|---|
| 240 | events_in_ram <= 0;
|
|---|
| 241 | event_start_addr <= 0;
|
|---|
| 242 | write_start_addr <= 0;
|
|---|
| 243 | package_index <= 0;
|
|---|
| 244 | channel_id <= 0;
|
|---|
| 245 | ram_start_addr <= (others => '0');
|
|---|
| 246 |
|
|---|
| 247 | package_length <= conv_std_logic_vector (event_size, 16);
|
|---|
| 248 | for i in 0 to 8 loop
|
|---|
| 249 | roi_max(i) <= conv_std_logic_vector(roi_max_array(i), 11);
|
|---|
| 250 | end loop;
|
|---|
| 251 | state_mm <= CONFIG_DG;
|
|---|
| 252 |
|
|---|
| 253 | when CONFIG_DG =>
|
|---|
| 254 | state_sig <= X"9";
|
|---|
| 255 | dg_start_config <= '1';
|
|---|
| 256 | state_mm <= CONFIG_DG;
|
|---|
| 257 | if (dg_config_done_sr(1) = '0') then
|
|---|
| 258 | dg_start_config <= '0';
|
|---|
| 259 | state_mm <= WAIT_FOR_CONFIG_DG;
|
|---|
| 260 | end if;
|
|---|
| 261 |
|
|---|
| 262 | when WAIT_FOR_CONFIG_DG =>
|
|---|
| 263 | state_sig <= X"E";
|
|---|
| 264 | state_mm <= WAIT_FOR_CONFIG_DG;
|
|---|
| 265 | if (dg_config_done_sr(1) = '1') then
|
|---|
| 266 | state_mm <= UPDATE_OUTPUT;
|
|---|
| 267 | end if;
|
|---|
| 268 |
|
|---|
| 269 |
|
|---|
| 270 | when MM_MAIN =>
|
|---|
| 271 | state_sig <= X"A";
|
|---|
| 272 | state_mm <= MM_MAIN;
|
|---|
| 273 |
|
|---|
| 274 | config_ready <= '1';
|
|---|
| 275 |
|
|---|
| 276 | if (config_start_sr(1) = '1') then
|
|---|
| 277 | state_mm <= MM_CONFIG;
|
|---|
| 278 |
|
|---|
| 279 | elsif (ram_write_ready_sr(1) = '1') then
|
|---|
| 280 | -- this is part of the DG - MM handshake.
|
|---|
| 281 | -- pulling write_ea low shows that MM understood DG is ready
|
|---|
| 282 | ram_write_ea <= '0';
|
|---|
| 283 |
|
|---|
| 284 | events_in_ram <= events_in_ram + 1;
|
|---|
| 285 | if ((event_start_addr + event_size_ram_64b) < (RAM_SIZE_64B - event_size_ram_64b)) then
|
|---|
| 286 | event_start_addr <= event_start_addr + event_size_ram_64b;
|
|---|
| 287 | else
|
|---|
| 288 | event_start_addr <= 0;
|
|---|
| 289 | end if;
|
|---|
| 290 | state_mm <= WRITE_FIN;
|
|---|
| 291 |
|
|---|
| 292 | elsif (wiz_read_ready_sr(1) = '1') then
|
|---|
| 293 | wiz_write_ea <= '0';
|
|---|
| 294 |
|
|---|
| 295 | if (package_index = (number_of_packages - 1)) then
|
|---|
| 296 |
|
|---|
| 297 | -- next address
|
|---|
| 298 | if ((write_start_addr + fifo_package_size_ram (package_index)) < (RAM_SIZE_16B - event_size_ram)) then
|
|---|
| 299 | write_start_addr <= write_start_addr + fifo_package_size_ram (package_index);
|
|---|
| 300 | else
|
|---|
| 301 | write_start_addr <= 0;
|
|---|
| 302 | end if;
|
|---|
| 303 | else
|
|---|
| 304 | write_start_addr <= write_start_addr + fifo_package_size_ram (package_index);
|
|---|
| 305 | end if;
|
|---|
| 306 |
|
|---|
| 307 | -- increase pack_index
|
|---|
| 308 | -- the package_index goes from 0..NumOfPack-1
|
|---|
| 309 |
|
|---|
| 310 | if ( package_index < (number_of_packages - 1)) then
|
|---|
| 311 | package_index <= package_index + 1;
|
|---|
| 312 | else
|
|---|
| 313 | package_index <= 0;
|
|---|
| 314 | events_in_ram <= events_in_ram - 1;
|
|---|
| 315 | end if;
|
|---|
| 316 |
|
|---|
| 317 |
|
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 | state_mm <= READ_FIN;
|
|---|
| 321 |
|
|---|
| 322 | end if;
|
|---|
| 323 |
|
|---|
| 324 | ------------------------- WRITING to MEM was finished ------------------------------------
|
|---|
| 325 | ------------------------------------------------------------------------------------------
|
|---|
| 326 | when WRITE_FIN =>
|
|---|
| 327 | state_sig <= X"B";
|
|---|
| 328 | ram_start_addr <= conv_std_logic_vector(event_start_addr, RAM_ADDR_WIDTH_64B);
|
|---|
| 329 | -- 2nd part of hand shake is, that DG pulls low ram_write_ready
|
|---|
| 330 | if (ram_write_ready_sr(1) = '0') then
|
|---|
| 331 | state_mm <= UPDATE_OUTPUT;
|
|---|
| 332 | end if;
|
|---|
| 333 |
|
|---|
| 334 |
|
|---|
| 335 | ------------------------- READING from MEM was finished ----------------------------------
|
|---|
| 336 | ------------------------------------------------------------------------------------------
|
|---|
| 337 |
|
|---|
| 338 | when READ_FIN =>
|
|---|
| 339 | state_sig <= X"C";
|
|---|
| 340 | if (wiz_read_ready_sr(1) = '0') then
|
|---|
| 341 |
|
|---|
| 342 |
|
|---|
| 343 | state_mm <= UPDATE_OUTPUT;
|
|---|
| 344 | end if;
|
|---|
| 345 |
|
|---|
| 346 |
|
|---|
| 347 |
|
|---|
| 348 |
|
|---|
| 349 | when UPDATE_OUTPUT =>
|
|---|
| 350 |
|
|---|
| 351 |
|
|---|
| 352 | wiz_ram_start_addr <= conv_std_logic_vector(write_start_addr, RAM_ADDR_WIDTH_16B);
|
|---|
| 353 | wiz_write_length <= conv_std_logic_vector(fifo_write_length (package_index), 17);
|
|---|
| 354 | wiz_number_of_channels <= conv_std_logic_vector(fifo_channels_array (package_index), 4);
|
|---|
| 355 |
|
|---|
| 356 | if (package_index = 0) then
|
|---|
| 357 | -- first package -> write header
|
|---|
| 358 | wiz_write_header <= '1';
|
|---|
| 359 | else
|
|---|
| 360 | wiz_write_header <= '0';
|
|---|
| 361 | end if;
|
|---|
| 362 |
|
|---|
| 363 | if (package_index = (number_of_packages - 1)) then
|
|---|
| 364 | -- last package -> write end-flag
|
|---|
| 365 | wiz_write_end <= '1';
|
|---|
| 366 | else
|
|---|
| 367 | wiz_write_end <= '0';
|
|---|
| 368 | end if;
|
|---|
| 369 |
|
|---|
| 370 | state_mm <= UPDATE_OUTPUT_2;
|
|---|
| 371 |
|
|---|
| 372 |
|
|---|
| 373 | when UPDATE_OUTPUT_2 =>
|
|---|
| 374 | state_sig <= X"D";
|
|---|
| 375 | state_mm <= MM_MAIN;
|
|---|
| 376 |
|
|---|
| 377 | if (events_in_ram > 0) then
|
|---|
| 378 | wiz_write_ea <= '1';
|
|---|
| 379 | else
|
|---|
| 380 | wiz_write_ea <= '0';
|
|---|
| 381 | end if;
|
|---|
| 382 |
|
|---|
| 383 | if (events_in_ram < max_events_ram) then
|
|---|
| 384 | ram_write_ea <= '1';
|
|---|
| 385 | else
|
|---|
| 386 | ram_write_ea <= '0';
|
|---|
| 387 | end if;
|
|---|
| 388 |
|
|---|
| 389 |
|
|---|
| 390 | when others =>
|
|---|
| 391 | state_sig <= X"F";
|
|---|
| 392 | state_mm <= MM_CONFIG;
|
|---|
| 393 |
|
|---|
| 394 | end case; -- state_mm
|
|---|
| 395 | end if;
|
|---|
| 396 | end process mm;
|
|---|
| 397 |
|
|---|
| 398 |
|
|---|
| 399 |
|
|---|
| 400 | END ARCHITECTURE beha;
|
|---|
| 401 |
|
|---|