00001 --**************************************************************
00002 --* *
00003 --* The source code for the ATLAS BCM "AAA" FPGA is made *
00004 --* available via the GNU General Public License (GPL) *
00005 --* unless otherwise stated below. *
00006 --* *
00007 --* In case of problems/questions/bug reports etc. please *
00008 --* contact michael.niegl@cern.ch *
00009 --* *
00010 --**************************************************************
00011
00012 --**************************************************************
00013 --* *
00014 --* $Source: /local/reps/bcmfpga/bcm_aaa/bcm_aaa/rod/bcm_rod_formatter.vhd,v $
00015 --* $Revision: 1.21.2.6 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:48 $ *
00019
00020
00021 --* *
00022 --**************************************************************
00023
00024 library ieee;
00025
00026 use ieee.std_logic_1164.all;
00027
00028 use ieee.std_logic_arith.all;
00029
00030 use ieee.std_logic_unsigned.all;
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 entity bcm_rod_formatter is
00041 generic (
00042 -- some data constants:
00043 INPUT_DATA_WIDTH : positive := 32;
00044 MAX_FRAGMENT_SIZE : (11 downto 0) := X"17f";
00045 -- some constants for the header:
00046 SLINK_BEGIN_OF_FRAGMENT : (31 downto 0) := X"b0f00000";
00047 SLINK_END_OF_FRAGMENT : (31 downto 0) := X"e0f00000";
00048 ROD_HEADER : (31 downto 0) := X"ee1234ee";
00049 ROD_HEADER_WORDS : (31 downto 0) := X"00000009";
00050 ROD_STATUS_BLOCK_WORD1 : (31 downto 0) := X"12345678";
00051 ROD_STATUS_BLOCK_WORD2 : (31 downto 0) := X"87654321";
00052 ROD_STATUS_BLOCK_WORDS : (31 downto 0) := X"00000002";
00053 ROD_STATUS_BLOCK_BEFORE_DATA : (31 downto 0) := X"00000000";
00054 ROD_STATUS_BLOCK_AFTER_DATA : (31 downto 0) := X"00000001";
00055 ROD_EMPTY : (31 downto 0) := X"00000000"
00056 );
00057 port (
00058 -- clock and synchronus reset
00059 CLK : in ;
00060 SCLR : in ;
00061 -- input data
00062 rod_data_vld : in ;
00063 rod_data_available : in := '0';
00064 rod_fragment_end : in := '0';
00065 rod_input_data : in (INPUT_DATA_WIDTH-1 downto 0);
00066 rod_data_next : out := '0';
00067 rod_format_version : in (31 downto 0) := X"03010001";
00068 rod_source_ID : in (31 downto 0) := X"00810000";
00069 rod_run_number : in (31 downto 0) := X"7fffffff";
00070 rod_CTP_trigger_type : in (31 downto 0) := X"00000011";
00071 rod_detector_event_type : in (31 downto 0) := X"000000dd";
00072 -- SLINK interface:
00073 hola_LFF : in ;
00074 hola_LDOWN : in ;
00075 hola_LRL : in (3 downto 0);
00076 hola_CLK : out ;
00077 hola_UD : out (31 downto 0);
00078 hola_URESET : out ;
00079 hola_UTEST : out ;
00080 hola_UCTRL : out ;
00081 hola_UWEN : out ;
00082 hola_UDW : out (1 downto 0) := "00"
00083 );
00084 end bcm_rod_formatter;
00085
00086
00087 architecture bcm_rod_formatter_arc of bcm_rod_formatter is
00088
00089
00090 component bcm_rod_slink
00091 port (
00092 CLK : in ;
00093 SCLR : in ;
00094 formatter_control_word_flag : in ;
00095 formatter_data_in : in (31 downto 0);
00096 formatter_data_valid : in ;
00097 formatter_reset_link : in ;
00098 formatter_ignore_slink_status : in ;
00099 formatter_stop_transfer : out ;
00100 -- SLINK interface
00101 slink_full_flag : in ;
00102 slink_down : in ;
00103 slink_link_return_lines : in (3 downto 0);
00104 slink_clock : out ;
00105 slink_data_out : out (31 downto 0);
00106 slink_reset : out ;
00107 slink_test : out ;
00108 slink_control_word_flag : out ;
00109 slink_write_enable : out ;
00110 slink_data_width : out (1 downto 0) := "00"
00111 );
00112 end component;
00113
00114
00115 type bcm_rod_formatter_fsm_state_typedef is (
00116 formatter_idle,
00117 formatter_begin_of_fragment,
00118 formatter_header,
00119 formatter_header_size,
00120 formatter_format_version,
00121 formatter_source_ID,
00122 formatter_run_number,
00123 formatter_Level1_ID,
00124 formatter_BC_ID,
00125 formatter_trigger_type,
00126 formatter_detector_event_type,
00127 formatter_data,
00128 formatter_last_data,
00129 formatter_status_word_1,
00130 formatter_status_word_2,
00131 formatter_status_block_words,
00132 formatter_data_block_words,
00133 formatter_status_block_position,
00134 formatter_end_of_fragment
00135 );
00136
00137 signal fsm_state : bcm_rod_formatter_fsm_state_typedef;
00138 signal formatter_data_valid : ;
00139 signal formatter_data_in : (31 downto 0) := (others => '0');
00140 signal lvlid_i : (31 downto 0) := (others => '0');
00141 signal formatter_control_word_flag : ;
00142 signal formatter_stop_transfer : ;
00143 signal intern_slink_data_out : ;
00144 signal reset_n : ;
00145 signal data_counter : (11 downto 0) := (others => '0');
00146 signal buffer_data : (223 downto 0) := (others => '0');
00147 signal buffer_counter : (7 downto 0) := (others => '0');
00148 signal buffer_eof : (6 downto 0) := (others => '0');
00149 signal last_data_next : ;
00150 signal buffer_data_next : ;
00151 signal last_data_available : ;
00152 signal last_data_available_i : ;
00153 signal LinkBusy : ;
00154 signal FSMBusy : ;
00155
00156 begin
00157
00158 reset_n <= not SCLR;
00159 formatter_stop_transfer <= LinkBusy;
00160
00161
00162 output_interface : bcm_rod_slink
00163 port map (
00164 CLK => CLK,
00165 SCLR => SCLR,
00166 -- ROD formatter interface
00167 formatter_control_word_flag => formatter_control_word_flag, --ControlWord,
00168 formatter_data_in => formatter_data_in, --OutputBus,
00169 formatter_data_valid => formatter_data_valid, --LinkWrite,
00170 formatter_reset_link => reset_n,
00171 formatter_ignore_slink_status => '0', --FIXME: ignoreSlinkStatus,
00172 formatter_stop_transfer => LinkBusy,
00173 -- SLINK interface
00174 slink_full_flag => hola_LFF,
00175 slink_down => hola_LDOWN,
00176 slink_link_return_lines => hola_LRL,
00177 slink_clock => hola_CLK,
00178 slink_data_out => hola_UD,
00179 slink_reset => hola_URESET ,
00180 slink_test => hola_UTEST,
00181 slink_control_word_flag => hola_UCTRL,
00182 slink_write_enable => hola_UWEN,
00183 slink_data_width => hola_UDW
00184 );
00185
00186
00187
00188
00189
00190
00191 RAM_reader : process (CLK, SCLR)
00192 begin
00193 if SCLR = '1' then
00194 rod_data_next <= '0';
00195 buffer_data_next <= '0';
00196 last_data_available <= '0';
00197 last_data_available_i <= '0';
00198 last_data_next <= '0';
00199 buffer_counter <= (others => '0');
00200 buffer_eof <= (others => '0');
00201 buffer_data <= (others => '0');
00202 elsif (CLK'event and CLK = '1') then
00203 if rod_data_available = '1' then
00204 rod_data_next <= '1';
00205 buffer_data_next <= '1';
00206 else
00207 rod_data_next <= '0';
00208 buffer_data_next <= '0';
00209 end if;
00210 -- shift data out
00211 if (formatter_stop_transfer = '0') and (fsm_state = formatter_detector_event_type or
00212 fsm_state = formatter_data or
00213 fsm_state = formatter_source_ID) then
00214 if fsm_state = formatter_source_ID then
00215 rod_data_next <= '0';
00216 end if;
00217 if (rod_data_vld and (last_data_available or last_data_available_i)) = '1' then -- fill and shift out
00218 case buffer_counter is
00219 when "00000001" =>
00220 buffer_data <= X"000000000000000000000000000000000000000000000000" & rod_input_data;
00221 buffer_eof <= "000000" & rod_fragment_end;
00222 when "00000010" =>
00223 buffer_data <= X"0000000000000000000000000000000000000000" & rod_input_data & buffer_data(63 downto 32);
00224 buffer_eof <= "00000" & rod_fragment_end & buffer_eof(1);
00225 when "00000011" =>
00226 buffer_data <= X"00000000000000000000000000000000" & rod_input_data & buffer_data(95 downto 32);
00227 buffer_eof <= "0000" & rod_fragment_end & buffer_eof(2 downto 1);
00228 when "00000100" =>
00229 buffer_data <= X"000000000000000000000000" & rod_input_data & buffer_data(127 downto 32);
00230 buffer_eof <= "000" & rod_fragment_end & buffer_eof(3 downto 1);
00231 when "00000101" =>
00232 buffer_data <= X"0000000000000000" & rod_input_data & buffer_data(159 downto 32);
00233 buffer_eof <= "00" & rod_fragment_end & buffer_eof(4 downto 1);
00234 when "00000110" =>
00235 buffer_data <= X"00000000" & rod_input_data & buffer_data(191 downto 32);
00236 buffer_eof <= '0' & rod_fragment_end & buffer_eof(5 downto 1);
00237 when "00000111" =>
00238 buffer_data <= rod_input_data & buffer_data(223 downto 32);
00239 buffer_eof <= rod_fragment_end & buffer_eof(6 downto 1);
00240 when others =>
00241 buffer_data <= rod_input_data & buffer_data(223 downto 32);
00242 buffer_eof <= rod_fragment_end & buffer_eof(6 downto 1);
00243 end case;
00244 buffer_counter <= buffer_counter;
00245 elsif buffer_counter /= "00000000" then -- just shift out
00246 buffer_data <= rod_input_data & buffer_data(223 downto 32);
00247 buffer_eof <= rod_fragment_end & buffer_eof(6 downto 1);
00248 buffer_counter <= buffer_counter - "01";
00249 end if;
00250 else -- nothing to shift
00251 if (rod_data_vld and (last_data_available or last_data_available_i)) = '1' then -- fill
00252 case buffer_counter is
00253 when "00000000" =>
00254 buffer_data <= X"000000000000000000000000000000000000000000000000" & rod_input_data;
00255 buffer_eof <= "000000" & rod_fragment_end;
00256 when "00000001" =>
00257 buffer_data <= X"0000000000000000000000000000000000000000" & rod_input_data & buffer_data(31 downto 0);
00258 buffer_eof <= "00000" & rod_fragment_end & buffer_eof(0);
00259 when "00000010" =>
00260 buffer_data <= X"00000000000000000000000000000000" & rod_input_data & buffer_data(63 downto 0);
00261 buffer_eof <= "0000" & rod_fragment_end & buffer_eof(1 downto 0);
00262 when "00000011" =>
00263 buffer_data <= X"000000000000000000000000" & rod_input_data & buffer_data(95 downto 0);
00264 buffer_eof <= "000" & rod_fragment_end & buffer_eof(2 downto 0);
00265 when "00000100" =>
00266 buffer_data <= X"0000000000000000" & rod_input_data & buffer_data(127 downto 0);
00267 buffer_eof <= "00" & rod_fragment_end & buffer_eof(3 downto 0);
00268 when "00000101" =>
00269 buffer_data <= X"00000000" & rod_input_data & buffer_data(159 downto 0);
00270 buffer_eof <= '0' & rod_fragment_end & buffer_eof(4 downto 0);
00271 rod_data_next <= '0';
00272 when "00000110" =>
00273 buffer_data <= rod_input_data & buffer_data(191 downto 0);
00274 buffer_eof <= rod_fragment_end & buffer_eof(5 downto 0);
00275 rod_data_next <= '0';
00276 when "00000111" =>
00277 buffer_data <= buffer_data;
00278 buffer_eof <= buffer_eof;
00279 rod_data_next <= '0';
00280 when others =>
00281 buffer_data <= rod_input_data & buffer_data(223 downto 32);
00282 buffer_eof <= rod_fragment_end & buffer_eof(6 downto 1);
00283 end case;
00284 buffer_counter <= buffer_counter + "01";
00285 elsif buffer_counter /= "00000000" then
00286 rod_data_next <= '0';
00287 end if;
00288 end if;
00289 last_data_next <= buffer_data_next;
00290 last_data_available <= rod_data_available;
00291 last_data_available_i <= last_data_available;
00292 end if;
00293 end process;
00294
00295
00296
00297 formatter_fsm : process (CLK, SCLR)
00298 begin
00299 if (SCLR = '1') then
00300 fsm_state <= formatter_idle;
00301 formatter_data_valid <= '0';
00302 formatter_control_word_flag <= '1';
00303 formatter_data_in <= ROD_EMPTY;
00304 data_counter <= X"000";
00305 lvlid_i <= (others => '0');
00306 elsif (CLK'event and CLK = '1') then
00307 if (formatter_stop_transfer = '1') then
00308 fsm_state <= fsm_state;
00309 formatter_data_valid <= formatter_data_valid;
00310 formatter_control_word_flag <= formatter_control_word_flag;
00311 formatter_data_in <= formatter_data_in;
00312 data_counter <= data_counter;
00313 else
00314 if ((fsm_state = formatter_end_of_fragment or fsm_state = formatter_idle) and (buffer_counter = "000")) then
00315 formatter_data_valid <= '0';
00316 else
00317 formatter_data_valid <= '1';
00318 end if;
00319 if ((fsm_state = formatter_status_block_position) or
00320 (fsm_state = formatter_end_of_fragment and (not (buffer_counter = "000"))) or
00321 (fsm_state = formatter_idle and (not (buffer_counter = "000")))) then
00322 formatter_control_word_flag <= '0';
00323 else
00324 formatter_control_word_flag <= '1';
00325 end if;
00326 data_counter <= data_counter;
00327 case fsm_state is
00328 when formatter_idle =>
00329 if (not (buffer_counter = "0000")) then
00330 fsm_state <= formatter_begin_of_fragment;
00331 formatter_data_in <= SLINK_BEGIN_OF_FRAGMENT;
00332 else
00333 fsm_state <= formatter_idle;
00334 formatter_data_in <= ROD_EMPTY;
00335 end if;
00336 when formatter_begin_of_fragment =>
00337 fsm_state <= formatter_header;
00338 formatter_data_in <= ROD_HEADER;
00339 when formatter_header =>
00340 fsm_state <= formatter_header_size;
00341 formatter_data_in <= ROD_HEADER_WORDS;
00342 when formatter_header_size =>
00343 fsm_state <= formatter_format_version;
00344 formatter_data_in <= rod_format_version;
00345 when formatter_format_version =>
00346 fsm_state <= formatter_source_ID;
00347 formatter_data_in <= rod_source_ID;
00348 when formatter_source_ID =>
00349 fsm_state <= formatter_run_number;
00350 formatter_data_in <= rod_run_number;
00351 lvlid_i <= buffer_data(31 downto 0);
00352 when formatter_run_number =>
00353 fsm_state <= formatter_Level1_ID;
00354 formatter_data_in <= lvlid_i;
00355 when formatter_Level1_ID =>
00356 fsm_state <= formatter_BC_ID;
00357 formatter_data_in <= x"00000" & buffer_data(31 downto 20);
00358 when formatter_BC_ID =>
00359 fsm_state <= formatter_trigger_type;
00360 formatter_data_in <= rod_CTP_trigger_type;
00361 when formatter_trigger_type =>
00362 fsm_state <= formatter_detector_event_type;
00363 formatter_data_in <= rod_detector_event_type;
00364 when formatter_detector_event_type =>
00365 fsm_state <= formatter_data;
00366 formatter_data_in <= buffer_data(31 downto 0);
00367 data_counter <= (data_counter + "01");
00368 when formatter_data =>
00369 data_counter <= (data_counter + "01");
00370 formatter_data_in <= buffer_data(31 downto 0);
00371 if (data_counter = MAX_FRAGMENT_SIZE or buffer_eof(0) = '1') then
00372 fsm_state <= formatter_last_data;
00373 else
00374 fsm_state <= formatter_data;
00375 end if;
00376 when formatter_last_data =>
00377 fsm_state <= formatter_status_word_1;
00378 formatter_data_in <= ROD_STATUS_BLOCK_WORD1;
00379 when formatter_status_word_1 =>
00380 fsm_state <= formatter_status_word_2;
00381 formatter_data_in <= ROD_STATUS_BLOCK_WORD2;
00382 when formatter_status_word_2 =>
00383 fsm_state <= formatter_status_block_words;
00384 formatter_data_in <= ROD_STATUS_BLOCK_WORDS;
00385 when formatter_status_block_words =>
00386 fsm_state <= formatter_data_block_words;
00387 formatter_data_in <= X"00000" & data_counter;
00388 when formatter_data_block_words =>
00389 fsm_state <= formatter_status_block_position;
00390 formatter_data_in <= ROD_STATUS_BLOCK_AFTER_DATA;
00391 data_counter <= X"000";
00392 when formatter_status_block_position =>
00393 fsm_state <= formatter_end_of_fragment;
00394 formatter_data_in <= SLINK_END_OF_FRAGMENT;
00395 when formatter_end_of_fragment =>
00396 if buffer_counter /= 0 then
00397 fsm_state <= formatter_begin_of_fragment;
00398 formatter_data_in <= SLINK_BEGIN_OF_FRAGMENT;
00399 else
00400 fsm_state <= formatter_idle;
00401 formatter_data_in <= ROD_EMPTY;
00402 end if;
00403 when others => null;
00404 end case;
00405 end if;
00406 end if;
00407 end process;
00408
00409 end bcm_rod_formatter_arc;
00410
00411