AMBPEX5_v20_SX50T_CORE
adm/main/trd_pio_std_v4.vhd
00001 ---------------------------------------------------------------------------------------------------
00002 --
00003 -- Title       : trd_pio_std_v4
00004 -- Design      : adp101v7_v20_admddc4x16_s
00005 -- Author      : ILYA Ivanov
00006 -- Company     : Instrumental System
00007 --
00008 ---------------------------------------------------------------------------------------------------
00009 --
00010 -- Description : Модуль управления портом PIOX
00011 --
00012 ---------------------------------------------------------------------------------------------------
00013 --
00014 -- Version     : 1.3
00015 ---------------------------------------------------------------------------------------------------
00016 --                                      
00017 -- Version 1.3  18.12.2009
00018 --                      Исправлено формирование сигнала PIO_RD во время сброса
00019 --
00020 ---------------------------------------------------------------------------------------------------
00021 --                                      
00022 -- Version 1.2  21.02.2006               
00023 --                      Добавлено использование сигналов TTL в режиме LVDS
00024 --
00025 ---------------------------------------------------------------------------------------------------
00026 --                                      
00027 -- Version 1.1  12.12.2005
00028 --                              Убраны буфера с 3 состоянием
00029 --
00030 ---------------------------------------------------------------------------------------------------
00031 
00032 
00033  
00034 library ieee;                                                              
00035 use ieee.std_logic_1164.all;
00036 
00037 use work.adm2_pkg.all;
00038 
00039 package trd_pio_std_v4_pkg is
00040         
00041 constant  ID_PIO_STD            : std_logic_vector( 15 downto 0 ):=x"0003"; -- идентификатор тетрады
00042 constant  ID_MODE_PIO_STD       : std_logic_vector( 15 downto 0 ):=x"0004"; -- модификатор тетрады
00043 constant  VER_PIO_STD           : std_logic_vector( 15 downto 0 ):=x"0103";     -- версия тетрады
00044 constant  RES_PIO_STD           : std_logic_vector( 15 downto 0 ):=x"0000";     -- ресурсы тетрады
00045 constant  FIFO_PIO_STD          : std_logic_vector( 15 downto 0 ):=x"0000"; -- размер FIFO
00046 constant  FTYPE_PIO_STD         : std_logic_vector( 15 downto 0 ):=x"0000"; -- ширина FIFO
00047 
00048 component trd_pio_std_v4 is
00049         generic (                                        
00050           -- 1 - бит MODE1[ENABLE] не используется
00051           -- 2 - бит MODE1[ENABLE] используется
00052           use_enable : integer:=1 
00053         );
00054         port(           
00055         
00056                 -- GLOBAL
00057                 reset           : in std_logic;
00058                 clk                     : in std_logic;
00059                 
00060                 -- Управление тетрадой
00061                 data_in         : in std_logic_vector( 15 downto 0 ); -- шина данных DATA
00062                 cmd_data_in     : in std_logic_vector( 15 downto 0 ); -- шина данных CMD_DATA
00063                 cmd                     : in bl_cmd;                                              -- сигналы управления
00064                 
00065                 data_out        : out std_logic_vector( 15 downto 0 ); -- выход данных с третьим состоянием (через buft)      
00066                 data_out2   : out std_logic_vector( 15 downto 0 ); -- выход данных напрямую 
00067                 cmd_data_out: out std_logic_vector( 15 downto 0 ); -- выходы регистров с третьим состоянием (через buft)
00068                 cmd_data_out2 : out std_logic_vector( 15 downto 0 ); -- выходы регистров напрямую
00069                 
00070                 bx_irq          : out std_logic;  -- 1 - прерывание от тетрады
00071 
00072                 --- сигналы управления PIOX ------------
00073             pio_enable  : out std_logic; -- '0' - разрешение выхода pio_wr, pio_rd
00074                 
00075                 pen0            : out std_logic;
00076                 
00077                 pen1_in         : in  std_logic:='0';                   
00078                 pen1            : out std_logic;                
00079                 pen1_oe         : out std_logic;        
00080                 
00081                 pio_oe0         : out std_logic; --     '0'     - разрешение выхода pio(7..0) 
00082                 pio_oe1         : out std_logic; --     '0'     - разрешение выхода pio(15..8)
00083                 
00084                 pio_in          : in  std_logic_vector( 15 downto 0 ); -- вход данных
00085                 pio_out         : out std_logic_vector( 15 downto 0 ); -- выход данных
00086                 
00087                 -- только для режима TTL
00088                 pio_wr          : out std_logic; -- строб записи
00089                 pio_rd          : out std_logic; -- строб чтения
00090                 ack_wr          : in  std_logic; -- подтверждение записи
00091                 ack_rd          : in  std_logic;  -- подтверждение чтения    
00092                 
00093                 lvds            : out std_logic  -- 0-режим LVDS разрешает выход pio(15,13,11,9)
00094                 
00095         ----------------------------------------
00096                 
00097             );
00098 end component;
00099                 
00100 end trd_pio_std_v4_pkg;
00101 
00102                           
00103 library ieee;
00104 use ieee.std_logic_1164.all;    
00105 use ieee.std_logic_arith.all;
00106 use ieee.std_logic_unsigned.all;
00107 
00108 
00109 use work.adm2_pkg.all;
00110 
00111 entity trd_pio_std_v4 is 
00112         generic (                                        
00113           -- 1 - бит MODE1[ENABLE] не используется
00114           -- 2 - бит MODE1[ENABLE] используется
00115           use_enable : integer:=1 
00116         );
00117         port(           
00118         
00119                 -- GLOBAL
00120                 reset           : in std_logic;
00121                 clk                     : in std_logic;
00122                 
00123                 -- Управление тетрадой
00124                 data_in         : in std_logic_vector( 15 downto 0 ); -- шина данных DATA
00125                 cmd_data_in     : in std_logic_vector( 15 downto 0 ); -- шина данных CMD_DATA
00126                 cmd                     : in bl_cmd;                                              -- сигналы управления
00127                 
00128                 data_out        : out std_logic_vector( 15 downto 0 ); -- выход данных с третьим состоянием (через buft)      
00129                 data_out2   : out std_logic_vector( 15 downto 0 ); -- выход данных напрямую 
00130                 cmd_data_out: out std_logic_vector( 15 downto 0 ); -- выходы регистров с третьим состоянием (через buft)
00131                 cmd_data_out2 : out std_logic_vector( 15 downto 0 ); -- выходы регистров напрямую
00132                 
00133                 bx_irq          : out std_logic;  -- 1 - прерывание от тетрады
00134 
00135                 --- сигналы управления PIOX ------------
00136             pio_enable  : out std_logic; -- '0' - разрешение выхода pio_wr, pio_rd
00137                 
00138                 pen0            : out std_logic;
00139                 
00140                 pen1_in         : in  std_logic:='0';                   
00141                 pen1            : out std_logic;                
00142                 pen1_oe         : out std_logic;        
00143                 
00144                 pio_oe0         : out std_logic; --     '0'     - разрешение выхода pio(7..0) 
00145                 pio_oe1         : out std_logic; --     '0'     - разрешение выхода pio(15..8)
00146                 
00147                 pio_in          : in  std_logic_vector( 15 downto 0 ); -- вход данных
00148                 pio_out         : out std_logic_vector( 15 downto 0 ); -- выход данных
00149                 
00150                 -- только для режима TTL
00151                 pio_wr          : out std_logic; -- строб записи
00152                 pio_rd          : out std_logic; -- строб чтения
00153                 ack_wr          : in  std_logic; -- подтверждение записи
00154                 ack_rd          : in  std_logic;  -- подтверждение чтения    
00155                 
00156                 lvds            : out std_logic  -- 0-режим LVDS разрешает выход pio(15,13,11,9)
00157                 
00158         ----------------------------------------
00159                 
00160             );
00161 end trd_pio_std_v4;
00162                                                                                                                  
00163 
00164 architecture trd_pio_std_v4 of trd_pio_std_v4 is 
00165 
00166 
00167 
00168 signal  c_status                : std_logic_vector( 15 downto 0 );
00169 signal  c_pio                   : std_logic_vector( 15 downto 0 ); -- защёлкнутые данные с разъёма
00170 signal  c_flag, c_irq   : std_logic_vector( 12 downto 9 );
00171 signal  c_mask, c_inv   : std_logic_vector( 12 downto 9 );
00172 signal  c_mode0                 : std_logic_vector( 15 downto 0 );
00173 signal  c_mode1                 : std_logic_vector( 15 downto 0 );
00174 signal  c_mode2                 : std_logic_vector( 15 downto 0 );
00175 signal  cnt_wr                  : std_logic_vector( 7 downto 0 );  -- счётчик строба записи
00176 signal  cnt_rd                  : std_logic_vector( 7 downto 0 ):=(others=>'0');  -- счётчик строба чтения
00177 signal  cnt_wr_z                : std_logic; -- 1 - cnt_wr="0000"
00178 signal  cnt_rd_z                : std_logic; -- 1 - cnt_rd="0000"
00179 signal  fack_wr                 : std_logic; -- 1 - фронт ack_wr
00180 signal  fack_rd                 : std_logic; -- 1 - фронт ack_rd
00181 signal  fack_wr_clr     : std_logic; -- 1 - сброс fack_wr
00182 signal  fack_rd_clr     : std_logic; -- 1 - сброс fack_rd
00183 signal  pio_read                : std_logic; -- строб записи в c_pio
00184 signal  start_rd                : std_logic; -- 1 - запуск счётчика cnt_rd
00185 signal  c_rst                   : std_logic; -- 0 - сброс тетрады
00186 signal  cmd_rdy                 : std_logic; -- 1 - готовность тетрады к выполнению команды  
00187 --
00188 signal  s_pio_in                : std_logic_vector(15 downto 0);
00189 signal  s_pio_out               : std_logic_vector(15 downto 0);   
00190 signal  lvds_pio_in     : std_logic_vector(15 downto 0);
00191 signal  lvds_pio_out    : std_logic_vector(15 downto 0);  
00192 signal  s_pio_wr                : std_logic; -- строб записи
00193 signal  s_pio_rd                : std_logic; -- строб чтения
00194 signal  s_ack_wr                : std_logic; -- подтверждение записи
00195 signal  s_ack_rd                : std_logic;  -- подтверждение чтения 
00196 signal  ack_wr_lvds     : std_logic;
00197 signal  ack_rd_lvds             : std_logic; 
00198 signal  pcout           : std_logic;   
00199 signal  pio_en          : std_logic;                             
00200 signal  s_pio_wr_lvds   : std_logic;
00201 
00202 
00203 begin              
00204         
00205         
00206 xstatus: ctrl_buft16 port map( 
00207         t => cmd.status_cs,
00208         i =>  c_status,
00209         o => cmd_data_out );
00210 cmd_data_out2<=c_status;        
00211         
00212 xdata: ctrl_buft16 port map(
00213         t => cmd.data_cs,
00214         i => c_pio,
00215         o => data_out ); 
00216 data_out2<=c_pio;  
00217         
00218         
00219 data_out2       <= c_pio; 
00220 cmd_data_out2 <= c_status;
00221 
00222 data_out2<=c_pio;  
00223 
00224         
00225         
00226 pr_mode0: process( reset, clk ) begin
00227         if( reset='0' ) then
00228                 c_mode0<=(others=>'0');
00229         elsif( rising_edge( clk ) ) then
00230                 if( cmd.cmd_data_we='1' ) then
00231                         if( cmd.adr(9)='0' and cmd.adr(8)='0' ) then
00232                           case cmd.adr( 3 downto 0 ) is
00233                                   when "0000" => c_mode0<=cmd_data_in;
00234                                   when others=>null;
00235                           end case;
00236                         end if;
00237                 end if;
00238         end if;
00239 end process;                      
00240 
00241 c_rst <= reset and ( not c_mode0(0) );
00242 
00243 
00244 pr_reg: process( c_rst, clk ) 
00245 begin
00246         if( c_rst='0' ) then
00247                 c_mode1 <=(others=>'0');
00248                 c_mode2 <=(others=>'0');         
00249                 c_mask  <=(others=>'0');                         
00250                 c_inv   <=(others=>'0');                
00251         elsif( rising_edge( clk ) ) then
00252                 if( cmd.cmd_data_we='1' ) then
00253                         if( cmd.adr(9)='0' and cmd.adr(8)='0' ) then
00254                           case cmd.adr( 3 downto 0 ) is
00255                                   when "0001" => c_mask( 12 downto 9 )<=cmd_data_in( 12 downto 9 );
00256                                   when "0010" => c_inv( 12 downto 9 )<=cmd_data_in( 12 downto 9 );
00257                                   when "1001" => c_mode1<=cmd_data_in;
00258                                   when "1010" => c_mode2<=cmd_data_in;
00259                                   when others=>null;
00260                           end case;
00261                         end if;
00262                 end if;
00263         end if;
00264 end process;
00265 
00266 c_status(1)<='0';
00267 c_status(2)<='0';
00268 c_status(3)<='0';
00269 c_status(4)<='0';
00270 c_status(5)<='0';
00271 c_status(6)<='0';  
00272 c_status(7)<='0';
00273 c_status(8)<='0';
00274 c_status(13)<='0';
00275 c_status(14)<='0';
00276 c_status(15)<='0';
00277 
00278 c_status(11)<=fack_wr;
00279 c_status(12)<=fack_rd;
00280 
00281 pr_status: process( clk ) begin
00282         if( rising_edge( clk ) ) then
00283                 c_status(0)<=cmd_rdy;
00284                 c_status(9)<=s_ack_wr;
00285                 c_status(10)<=s_ack_rd;
00286         end if;
00287 end process; 
00288 
00289 
00290 c_flag<=c_status( 12 downto 9 ) xor c_inv;
00291 c_irq<= c_flag and c_mask;
00292 
00293 pr_irq: process( c_irq, clk ) 
00294  variable v: std_logic;
00295 begin   
00296         v:='0';
00297         for i in 9 to 12 loop
00298                 v:=v or c_irq( i );
00299         end loop;
00300         if( rising_edge( clk ) ) then
00301                 bx_irq<=v and c_mode0(2);
00302         end if;
00303 end process;
00304 
00305 
00306 pr_s_pio_wr: process( c_rst, clk ) begin
00307         if( c_rst='0' ) then
00308                 cnt_wr<=(others=>'0');
00309         elsif( rising_edge( clk ) ) then
00310                 if( cmd.data_we='1' ) then
00311                         cnt_wr<=c_mode2( 7 downto 0 );
00312                 elsif( cnt_wr_z='0' ) then
00313                         cnt_wr<=cnt_wr-1;
00314                 end if;
00315         end if;
00316 end process;
00317 
00318 cnt_wr_z<='1' when cnt_wr=x"00" else '0';
00319         
00320 s_pio_wr<=cnt_wr_z or not c_rst;
00321         
00322 --pr_s_pio_rd: process( c_rst, clk ) begin
00323 --      if( c_rst='0' ) then
00324 --              cnt_rd<=(others=>'0');
00325 --      elsif( rising_edge( clk ) ) then
00326 --              if( start_rd='1' ) then
00327 --                      cnt_rd<=c_mode2( 15 downto 8 );
00328 --              elsif( cnt_rd_z='0' ) then
00329 --                      cnt_rd<=cnt_rd-1;
00330 --              end if;
00331 --      end if;
00332 --end process;
00333 
00334 pr_s_pio_rd: process( start_rd, c_rst, clk )
00335 begin                            
00336         if( c_rst='0' ) then
00337                 cnt_rd<=(others=>'0');
00338         elsif( start_rd='1' ) then
00339                 cnt_rd<=c_mode2( 15 downto 8 );
00340         elsif( rising_edge( clk ) ) then
00341                 if( cnt_rd_z='0' ) then
00342                         cnt_rd<=cnt_rd-1;
00343                 end if;
00344         end if;
00345 end process;
00346 
00347 cnt_rd_z<='1' when cnt_rd=x"00" else '0';
00348         
00349 s_pio_rd<=cnt_rd_z or not c_rst;
00350 
00351 pr_fack_wr: process( c_rst, s_ack_wr, fack_wr_clr ) begin
00352         if( c_rst='0' or fack_wr_clr='1' ) then
00353                 fack_wr<='0';
00354         elsif( rising_edge( s_ack_wr ) ) then
00355                 fack_wr<='1';
00356         end if;
00357 end process;
00358 
00359 pr_fack_rd: process( c_rst, s_ack_rd, fack_rd_clr ) begin
00360         if( c_rst='0' or fack_rd_clr='1' ) then
00361                 fack_rd<='0';
00362         elsif( rising_edge( s_ack_rd ) ) then
00363                 fack_rd<='1';
00364         end if;
00365 end process;
00366 
00367 --------------------------------------------------------------------
00368 
00369 pr_start_rd: process( c_rst, clk ) begin
00370         if( c_rst='0' ) then
00371                 start_rd<='0';
00372         elsif( rising_edge( clk ) ) then
00373                 if( c_mode1(2)='0' ) then  -- внутренняя синхронизация
00374                         if( cmd.cmd_data_we='1' and cmd.adr(9)='1' and cmd.adr(8)='0' 
00375                                 and cmd.adr(0)='1' )  then
00376                                 start_rd<='1';
00377                         else
00378                                 start_rd<='0';
00379                         end if;
00380                 else                       -- внешняя синхронизация
00381                         start_rd<=not cmd.data_cs;
00382                 end if;
00383         end if;
00384 end process;
00385 
00386 pr_fack_clr: process( c_rst, clk ) 
00387  variable v0, v1: std_logic;
00388 begin
00389         if( c_rst='0' ) then
00390                 fack_wr_clr<='0';
00391                 fack_rd_clr<='0';
00392         elsif( rising_edge( clk ) ) then
00393                 v0:='0'; v1:='0';
00394                 
00395                 if( c_mode1(2)='0' ) then
00396                  if( cmd.cmd_data_we='1' ) then
00397                         if( cmd.adr(9)='1' and cmd.adr(8)='0' and cmd.adr(0)='0' ) then
00398                                 v1:=cmd_data_in( 12 );
00399                         end if;
00400                  end if;
00401                 else
00402                         v1:=not cmd.data_cs;
00403                 end if;
00404                 
00405                 if( cmd.cmd_data_we='1' ) then
00406                         if( cmd.adr(9)='1' and cmd.adr(8)='0' and cmd.adr(0)='0' ) then
00407                                 v0:=cmd_data_in( 11 );
00408                         end if;
00409                 end if;
00410                 
00411                 fack_wr_clr<=v0;
00412                 fack_rd_clr<=v1;
00413                 
00414         end if;
00415 end process;
00416 
00417 cmd_rdy <= cnt_wr_z and (cnt_rd_z or c_mode1(3)) ;   
00418 
00419 pr_pio_out: process( c_rst, clk ) begin
00420         if( c_rst='0' ) then
00421                 s_pio_out<=(others=>'0');
00422         elsif( rising_edge( clk ) ) then
00423                 if( cmd.data_we='1' ) then
00424                         s_pio_out<=data_in;       
00425                 end if;
00426         end if;
00427 end process;
00428 
00429 pr_c_pio: process( c_rst, pio_read ) begin
00430         if( c_rst='0' ) then
00431                 c_pio<=(others=>'0');
00432         elsif( rising_edge( pio_read ) ) then
00433                 c_pio<=s_pio_in;
00434         end if;
00435 end process;
00436         
00437 process(c_mode1(3 downto 2),cnt_rd_z,s_ack_rd,clk )
00438 begin
00439         case c_mode1(3 downto 2) is 
00440                 when "00" => pio_read <= cnt_rd_z;
00441                 when "01" => pio_read <= s_ack_rd;
00442                 when "10" => pio_read <= clk;
00443                 when others => null;
00444         end case;
00445 end process;    
00446         
00447 pio_out  <=lvds_pio_out when c_mode1(10)='1' else s_pio_out; 
00448 
00449 s_pio_in <=lvds_pio_in  when c_mode1(10)='1' else pio_in;  
00450         
00451 gen_pio: for ii in 0 to 7 generate
00452         lvds_pio_out(ii*2)<= s_pio_out(ii); 
00453         lvds_pio_in(ii) <= pio_in(2*ii);
00454 end generate; 
00455 
00456 lvds_pio_out(9)<='1';   --pen0
00457 lvds_pio_out(11)<='0';  --pen1
00458 lvds_pio_out(13)<=c_mode1(0);
00459 lvds_pio_out(15)<=c_mode1(1);
00460 
00461 
00462 
00463 
00464 pio_enable<=pio_en; -- not c_mode1(11); 
00465 
00466 gen_en1: if use_enable=2 generate pio_en <= not c_mode1(11); end generate;
00467 gen_en2: if use_enable=1 generate pio_en <= '0';                         end generate;
00468         
00469 pio_wr    <= s_pio_wr when c_mode1(10)='0' else s_pio_wr_lvds;
00470 pio_rd    <= s_pio_rd;
00471 s_ack_wr  <= ack_wr when c_mode1(10)='0' else ack_wr_lvds  ;
00472 s_ack_rd  <= ack_rd when c_mode1(10)='0' else ack_rd_lvds  ;  
00473         
00474 process(c_mode1(13), pen1_in)
00475 begin
00476         if c_mode1(13) ='0' then
00477                 ack_wr_lvds<=pen1_in; ack_rd_lvds<=ack_rd;
00478         else
00479                 ack_rd_lvds<=pen1_in; ack_wr_lvds<=ack_rd;
00480         end if;
00481 end process;                                                                     
00482 
00483 s_pio_wr_lvds <= s_pio_wr when c_mode1(12)='0' else s_pio_rd;
00484 
00485 pcout<=s_pio_rd when c_mode1(12)='0' else s_pio_wr;
00486 
00487 pen0 <= pcout when c_mode1(10)='1' else not c_mode1(0);
00488 pen1 <= not c_mode1(1); 
00489 
00490 pio_oe0 <= not c_mode1(0) or  pio_en; 
00491 pio_oe1 <= not c_mode1(1) or  pio_en; 
00492 lvds    <= not c_mode1(1) or  pio_en when  c_mode1(10) ='0' else pio_en; 
00493 
00494 pen1_oe<=c_mode1(10) or pio_en;
00495 
00496 end trd_pio_std_v4;
00497