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/div/lvl1_buf.vhd,v $*
00015 --* $Revision: 1.31.2.3 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:45 $ *
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 use ieee.numeric_std.all;
00033
00034 library unisim;
00035
00036 use unisim.vcomponents.all;
00037
00038
00039
00040
00041
00042
00043
00044 entity lvl1_buf is
00045 port (RESET : in ;
00046 CLKWR : in ;
00047 CLKRD : in ;
00048 DATA_OUT : out (191 downto 0) := (others => '0');
00049 DATA_IN : in (175 downto 0);
00050 WR_BID : in (11 downto 0) := "000000000000";
00051 RD_BID : in (11 downto 0) := "000000000000";
00052 VLD : out ;
00053 EN_B : in ;
00054 NUM : in (6 downto 0) := "0000001";
00055 FINISH : in ;
00056 all_READ : out ;
00057 PAUSE : in ;
00058 READ_ERROR : out ;
00059 WE : in
00060 );
00061 end lvl1_buf;
00062
00063
00064
00065
00066
00067
00068
00069 architecture lvl1_buf_arc of lvl1_buf is
00070 ---------------------------- signals -------------------------------
00071 signal data_i : (191 downto 0) := (others => '0');
00072 signal data_out_i : (191 downto 0) := (others => '0');
00073 signal cnt_a : (11 downto 0) := (others => '0');
00074 signal cnt_b : (11 downto 0) := (others => '0');
00075 signal bid_lastin : (11 downto 0) := (others => '0');
00076 signal bid_lastram : (11 downto 0) := (others => '0');
00077 signal num_i : (6 downto 0) := "0000001";
00078 signal rden : := '0';
00079 signal check : := '0';
00080 signal rden_ram : := '0';
00081 signal more : := '0';
00082 signal more2 : := '0';
00083 signal allr : := '0';
00084 signal nblock : := '1';
00085 signal vld_i : := '0';
00086
00087 ---------------------------- components -------------------------------
00088
00089 component lvl1_circ_buffer
00090 port (
00091 addra : in (11 downto 0);
00092 addrb : in (11 downto 0);
00093 clka : in ;
00094 clkb : in ;
00095 dina : in (191 downto 0);
00096 doutb : out (191 downto 0);
00097 ena : in ;
00098 enb : in ;
00099 wea : in );
00100 end component;
00101
00102 ---------------------------- main code -------------------------------
00103 begin
00104
00105 READ_ERROR <= '0';
00106 all_READ <= allr;
00107 VLD <= vld_i;
00108
00109
00110 buf_i : lvl1_circ_buffer
00111 port map
00112 (
00113 addra => cnt_a,
00114 addrb => cnt_b,
00115 clka => CLKWR,
00116 clkb => CLKRD,
00117 dina => data_i,
00118 doutb => data_out_i,
00119 ena => '1' ,
00120 enb => rden,
00121 wea => WE
00122 );
00123
00124
00125 addr_gen_a : process(CLKWR)
00126 begin
00127 if CLKWR'event and CLKWR = '1' then
00128 if RESET = '1' then
00129 cnt_a <= (others => '0');
00130 data_i <= (others => '0');
00131 bid_lastram <= (others => '0');
00132 bid_lastin <= (others => '0');
00133 else
00134 if WE = '1' then
00135 cnt_a <= WR_BID; --* store last wr BID
00136 data_i <= WR_BID & DATA_IN & "0000";
00137 bid_lastin <= WR_BID;
00138 if WR_BID = 0 then
00139 bid_lastram <= bid_lastin;
00140 else
00141 bid_lastram <= bid_lastram;
00142 end if;
00143 end if;
00144 end if;
00145 end if;
00146 end process addr_gen_a;
00147
00148
00149 rd_ram : process(CLKRD)
00150 begin
00151 if CLKRD'event and CLKRD = '1' then
00152 if RESET = '1' then
00153 cnt_b <= (others => '0');
00154 rden_ram <= '0';
00155 more <= '0';
00156 else
00157 if PAUSE = '0' then
00158
00159 if EN_B = '1' then
00160 cnt_b <= RD_BID;
00161 rden_ram <= '1';
00162 num_i <= NUM;
00163
00164 if NUM > 1 then
00165 more <= '1';
00166 else
00167 more <= '0';
00168 end if;
00169
00170 elsif (more2 and nblock and (not rden_ram)) = '1' then
00171 rden_ram <= '1';
00172 num_i <= num_i - 1;
00173 cnt_b <= cnt_b + 1;
00174 if cnt_b = bid_lastram and bid_lastram > 0 then
00175 cnt_b <= (others => '0');
00176 end if;
00177
00178 else
00179 cnt_b <= cnt_b;
00180 rden_ram <= '0';
00181 more <= '0';
00182 end if;
00183
00184 else
00185 cnt_b <= cnt_b;
00186 rden_ram <= '0';
00187 end if;
00188 end if;
00189 end if;
00190 end process;
00191
00192 check <= rden when rising_edge(CLKRD);
00193 rden <= rden_ram and nblock;
00194
00195
00196 fwd_data : process (CLKRD)
00197 begin -- process fwd_data
00198 if CLKRD'event and CLKRD = '1' then -- rising clock edge
00199 if RESET = '1' then
00200 allr <= '0';
00201 vld_i <= '0';
00202 DATA_OUT <= (others => '0');
00203 else
00204 if PAUSE = '0' then
00205
00206 if check = '1' then
00207 DATA_OUT <= data_out_i;
00208 vld_i <= '1';
00209 if more2 = '0' then
00210 allr <= '1';
00211 else
00212 allr <= '0';
00213 end if;
00214
00215 else
00216 allr <= '0';
00217 vld_i <= '0';
00218 DATA_OUT <= (others => '0');
00219 end if;
00220
00221 else
00222 allr <= '0';
00223 vld_i <= '0';
00224 DATA_OUT <= (others => '0');
00225 end if;
00226
00227 end if;
00228 end if;
00229 end process fwd_data;
00230
00231
00232 latch_more2 : process (CLKRD, RESET)
00233 begin -- process latch_more
00234 if RESET = '1' then -- asynchronous reset (active high)
00235 more2 <= '0';
00236 elsif CLKRD'event and CLKRD = '1' then -- rising clock edge
00237 if (num_i-1) = 0 or FINISH = '1' then
00238 more2 <= '0';
00239 elsif more = '1' then
00240 more2 <= '1';
00241 end if;
00242 end if;
00243 end process latch_more2;
00244
00245
00246 latch_block : process (CLKRD, RESET)
00247 begin -- process latch_more
00248 if RESET = '1' then -- asynchronous reset (active high)
00249 nblock <= '1';
00250 elsif CLKRD'event and CLKRD = '1' then -- rising clock edge
00251 if vld_i = '1' then
00252 nblock <= '1';
00253 elsif rden = '1' then
00254 nblock <= '0';
00255 end if;
00256 end if;
00257 end process latch_block;
00258
00259 end lvl1_buf_arc;