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_slink.vhd,v $*
00015 --* $Revision: 1.12.2.5 $ *
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 library unisim;
00034
00035 use unisim.vcomponents.all;
00036
00037
00038
00039
00040
00041 entity bcm_rod_slink is
00042 generic (
00043 DATA_WIDTH : (1 downto 0) := "00";
00044 TEST : := '1'
00045 );
00046 port (
00047 CLK : in ;
00048 SCLR : in ;
00049 -- ROD formatter interface
00050 formatter_control_word_flag : in ;
00051 formatter_data_in : in (31 downto 0);
00052 formatter_data_valid : in ;
00053 formatter_reset_link : in ;
00054 formatter_ignore_slink_status : in ;
00055 formatter_stop_transfer : out ;
00056 -- SLINK interface
00057 slink_full_flag : in ;
00058 slink_down : in ;
00059 slink_link_return_lines : in (3 downto 0);
00060 slink_clock : out ;
00061 slink_data_out : out (31 downto 0);
00062 slink_reset : out ;
00063 slink_test : out ;
00064 slink_control_word_flag : out ;
00065 slink_write_enable : out ;
00066 slink_data_width : out (1 downto 0) := "00"
00067 );
00068 end bcm_rod_slink;
00069
00070
00071 architecture bcm_rod_slink_arc of bcm_rod_slink is
00072
00073
00074 type bcm_slink_fsm_state_typedef is (
00075 link_idle,
00076 link_down,
00077 link_write,
00078 link_notransfer,
00079 link_full,
00080 link_wait1,
00081 link_wait2,
00082 link_wait3
00083 );
00084
00085 signal fsm_state : bcm_slink_fsm_state_typedef; -- SLINK FSM states
00086 signal enable : ;
00087 signal fsm_stop : ;
00088 signal intern_slink_full_flag : ;
00089 signal intern_slink_down : ;
00090 signal intern_enable : ;
00091 signal intern_data_pending : ;
00092
00093 begin
00094
00095 slink_data_width <= DATA_WIDTH;
00096 slink_test <= TEST;
00097 slink_clock <= CLK;
00098 slink_reset <= not (SCLR);
00099 enable <= (formatter_ignore_slink_status or (intern_slink_full_flag and intern_slink_down)) and not fsm_stop;
00100 formatter_stop_transfer <= not formatter_ignore_slink_status and (not (intern_slink_full_flag and intern_slink_down) or fsm_stop);
00101
00102
00103 slink_full_FDRSE : FDRSE
00104 generic map (
00105 INIT => '0' ) -- Initial value of register ('0' or '1')
00106 port map (
00107 Q => intern_slink_full_flag, -- Data output
00108 C => CLK , -- Clock input
00109 CE => '1' , -- Clock enable input
00110 D => slink_full_flag, -- Data input
00111 R => '0' , -- Synchronous reset input
00112 S => '0' -- Synchronous set input
00113 );
00114
00115
00116 slink_down_FDRSE : FDRSE
00117 generic map (
00118 INIT => '0' ) -- Initial value of register ('0' or '1')
00119 port map (
00120 Q => intern_slink_down, -- Data output
00121 C => CLK , -- Clock input
00122 CE => '1' , -- Clock enable input
00123 D => slink_down, -- Data input
00124 R => '0' , -- Synchronous reset input
00125 S => '0' -- Synchronous set input
00126 );
00127
00128
00129 enable_FDRSE : FDRSE
00130 generic map (
00131 INIT => '0' ) -- Initial value of register ('0' or '1')
00132 port map (
00133 Q => intern_enable, -- Data output
00134 C => CLK , -- Clock input
00135 CE => '1' , -- Clock enable input
00136 D => enable , -- Data input
00137 R => SCLR, -- Synchronous reset input
00138 S => '0' -- Synchronous set input
00139 );
00140
00141
00142 control_word_FDRSE : FDRSE
00143 generic map (
00144 INIT => '0' ) -- Initial value of register ('0' or '1')
00145 port map (
00146 Q => slink_control_word_flag, -- Data output
00147 C => CLK , -- Clock input
00148 CE => intern_enable, -- Clock enable input
00149 R => '0' , -- synchronous clear input
00150 D => formatter_control_word_flag, -- Data input
00151 S => SCLR -- synchronous set input
00152 );
00153
00154
00155 data_vld : FDRSE
00156 generic map (
00157 INIT => '0' ) -- Initial value of register ('0' or '1')
00158 port map (
00159 Q => intern_data_pending, -- Data output
00160 C => CLK , -- Clock input
00161 CE => intern_enable, -- Clock enable input
00162 D => formatter_data_valid, -- Data input
00163 R => SCLR, -- Synchronous reset input
00164 S => '0' -- Synchronous set input
00165 );
00166
00167 DFF_arr : for I in 31 downto 0 generate
00168
00169
00170 data_register : FDRSE
00171 generic map (
00172 INIT => '0' ) -- Initial value of register ('0' or '1')
00173 port map (
00174 Q => slink_data_out(I), -- Data output
00175 C => CLK , -- Clock input
00176 CE => intern_enable, -- Clock enable input
00177 D => formatter_data_in(I), -- Data input
00178 R => SCLR , -- Synchronous reset input
00179 S => '0' -- Synchronous set input
00180 );
00181
00182 end generate DFF_arr;
00183
00184
00185 slink_fsm : process (CLK, SCLR)
00186 begin
00187 if (SCLR = '1') then
00188 fsm_state <= link_idle;
00189 fsm_stop <= '1';
00190 slink_write_enable <= '1';
00191 elsif (CLK'event and CLK = '1') then
00192 if (intern_slink_down = '0' and formatter_ignore_slink_status = '0') then
00193 fsm_state <= link_down;
00194 fsm_stop <= '1';
00195 slink_write_enable <= '1';
00196 else
00197 case fsm_state is
00198 when link_idle =>
00199 fsm_stop <= '0';
00200 if (formatter_data_valid = '1') then
00201 fsm_state <= link_write;
00202 slink_write_enable <= '0';
00203 else
00204 fsm_state <= link_notransfer;
00205 end if;
00206 when link_write =>
00207 if ((intern_slink_full_flag = '1' or formatter_ignore_slink_status = '1') and formatter_data_valid = '0') then
00208 fsm_state <= link_notransfer;
00209 slink_write_enable <= '1';
00210 elsif (intern_slink_full_flag = '0' and formatter_ignore_slink_status = '0') then
00211 fsm_state <= link_full;
00212 slink_write_enable <= '1';
00213 else
00214 fsm_state <= link_write;
00215 end if;
00216 when link_notransfer =>
00217 if ((intern_slink_full_flag = '1' or formatter_ignore_slink_status = '1') and formatter_data_valid = '1') then
00218 fsm_state <= link_write;
00219 slink_write_enable <= '0';
00220 elsif (intern_slink_full_flag = '0' and formatter_ignore_slink_status = '0') then
00221 fsm_state <= link_full;
00222 else
00223 fsm_state <= link_notransfer;
00224 end if;
00225 when link_full =>
00226 if (formatter_ignore_slink_status = '1') then
00227 -- After a reset the ignore SlinkStatus might be set to '0'.
00228 -- if there is active ('0') lff line the STM ends up in the
00229 -- LinkFull_state. In order to ignore the lff there must be
00230 -- a way to escape the state if the ignoreSlinkStatus line
00231 -- is set to '1' later. Therfore this condition here.
00232 fsm_state <= link_idle;
00233 elsif (intern_slink_full_flag = '1' and intern_data_pending = '1') then
00234 fsm_state <= link_write;
00235 slink_write_enable <= '0';
00236 elsif (intern_slink_full_flag = '1' and intern_data_pending = '0') then
00237 fsm_state <= link_notransfer;
00238 else
00239 fsm_state <= link_full;
00240 end if;
00241 when link_down =>
00242 fsm_state <= link_wait1;
00243 when link_wait1 =>
00244 fsm_state <= link_wait2;
00245 when link_wait2 =>
00246 fsm_state <= link_wait3;
00247 when link_wait3 =>
00248 fsm_state <= link_idle;
00249 fsm_stop <= '0';
00250 end case;
00251 end if;
00252 end if;
00253 end process slink_fsm;
00254
00255 end bcm_rod_slink_arc;
00256
00257
00258