URL
https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk
Subversion Repositories pcie_ds_dma
[/] [pcie_ds_dma/] [trunk/] [core/] [adm/] [main/] [trd_pio_std_v4.vhd] - Rev 17
Go to most recent revision | Compare with Previous | Blame | View Log
--------------------------------------------------------------------------------------------------- -- -- Title : trd_pio_std_v4 -- Design : adp101v7_v20_admddc4x16_s -- Author : ILYA Ivanov -- Company : Instrumental System -- --------------------------------------------------------------------------------------------------- -- -- Description : Модуль управления портом PIOX -- --------------------------------------------------------------------------------------------------- -- -- Version : 1.3 --------------------------------------------------------------------------------------------------- -- -- Version 1.3 18.12.2009 -- Исправлено формирование сигнала PIO_RD во время сброса -- --------------------------------------------------------------------------------------------------- -- -- Version 1.2 21.02.2006 -- Добавлено использование сигналов TTL в режиме LVDS -- --------------------------------------------------------------------------------------------------- -- -- Version 1.1 12.12.2005 -- Убраны буфера с 3 состоянием -- --------------------------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.adm2_pkg.all; package trd_pio_std_v4_pkg is constant ID_PIO_STD : std_logic_vector( 15 downto 0 ):=x"0003"; -- идентификатор тетрады constant ID_MODE_PIO_STD : std_logic_vector( 15 downto 0 ):=x"0004"; -- модификатор тетрады constant VER_PIO_STD : std_logic_vector( 15 downto 0 ):=x"0103"; -- версия тетрады constant RES_PIO_STD : std_logic_vector( 15 downto 0 ):=x"0000"; -- ресурсы тетрады constant FIFO_PIO_STD : std_logic_vector( 15 downto 0 ):=x"0000"; -- размер FIFO constant FTYPE_PIO_STD : std_logic_vector( 15 downto 0 ):=x"0000"; -- ширина FIFO component trd_pio_std_v4 is generic ( -- 1 - бит MODE1[ENABLE] не используется -- 2 - бит MODE1[ENABLE] используется use_enable : integer:=1 ); port( -- GLOBAL reset : in std_logic; clk : in std_logic; -- Управление тетрадой data_in : in std_logic_vector( 15 downto 0 ); -- шина данных DATA cmd_data_in : in std_logic_vector( 15 downto 0 ); -- шина данных CMD_DATA cmd : in bl_cmd; -- сигналы управления data_out : out std_logic_vector( 15 downto 0 ); -- выход данных с третьим состоянием (через buft) data_out2 : out std_logic_vector( 15 downto 0 ); -- выход данных напрямую cmd_data_out: out std_logic_vector( 15 downto 0 ); -- выходы регистров с третьим состоянием (через buft) cmd_data_out2 : out std_logic_vector( 15 downto 0 ); -- выходы регистров напрямую bx_irq : out std_logic; -- 1 - прерывание от тетрады --- сигналы управления PIOX ------------ pio_enable : out std_logic; -- '0' - разрешение выхода pio_wr, pio_rd pen0 : out std_logic; pen1_in : in std_logic:='0'; pen1 : out std_logic; pen1_oe : out std_logic; pio_oe0 : out std_logic; -- '0' - разрешение выхода pio(7..0) pio_oe1 : out std_logic; -- '0' - разрешение выхода pio(15..8) pio_in : in std_logic_vector( 15 downto 0 ); -- вход данных pio_out : out std_logic_vector( 15 downto 0 ); -- выход данных -- только для режима TTL pio_wr : out std_logic; -- строб записи pio_rd : out std_logic; -- строб чтения ack_wr : in std_logic; -- подтверждение записи ack_rd : in std_logic; -- подтверждение чтения lvds : out std_logic -- 0-режим LVDS разрешает выход pio(15,13,11,9) ---------------------------------------- ); end component; end trd_pio_std_v4_pkg; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.adm2_pkg.all; entity trd_pio_std_v4 is generic ( -- 1 - бит MODE1[ENABLE] не используется -- 2 - бит MODE1[ENABLE] используется use_enable : integer:=1 ); port( -- GLOBAL reset : in std_logic; clk : in std_logic; -- Управление тетрадой data_in : in std_logic_vector( 15 downto 0 ); -- шина данных DATA cmd_data_in : in std_logic_vector( 15 downto 0 ); -- шина данных CMD_DATA cmd : in bl_cmd; -- сигналы управления data_out : out std_logic_vector( 15 downto 0 ); -- выход данных с третьим состоянием (через buft) data_out2 : out std_logic_vector( 15 downto 0 ); -- выход данных напрямую cmd_data_out: out std_logic_vector( 15 downto 0 ); -- выходы регистров с третьим состоянием (через buft) cmd_data_out2 : out std_logic_vector( 15 downto 0 ); -- выходы регистров напрямую bx_irq : out std_logic; -- 1 - прерывание от тетрады --- сигналы управления PIOX ------------ pio_enable : out std_logic; -- '0' - разрешение выхода pio_wr, pio_rd pen0 : out std_logic; pen1_in : in std_logic:='0'; pen1 : out std_logic; pen1_oe : out std_logic; pio_oe0 : out std_logic; -- '0' - разрешение выхода pio(7..0) pio_oe1 : out std_logic; -- '0' - разрешение выхода pio(15..8) pio_in : in std_logic_vector( 15 downto 0 ); -- вход данных pio_out : out std_logic_vector( 15 downto 0 ); -- выход данных -- только для режима TTL pio_wr : out std_logic; -- строб записи pio_rd : out std_logic; -- строб чтения ack_wr : in std_logic; -- подтверждение записи ack_rd : in std_logic; -- подтверждение чтения lvds : out std_logic -- 0-режим LVDS разрешает выход pio(15,13,11,9) ---------------------------------------- ); end trd_pio_std_v4; architecture trd_pio_std_v4 of trd_pio_std_v4 is signal c_status : std_logic_vector( 15 downto 0 ); signal c_pio : std_logic_vector( 15 downto 0 ); -- защёлкнутые данные с разъёма signal c_flag, c_irq : std_logic_vector( 12 downto 9 ); signal c_mask, c_inv : std_logic_vector( 12 downto 9 ); signal c_mode0 : std_logic_vector( 15 downto 0 ); signal c_mode1 : std_logic_vector( 15 downto 0 ); signal c_mode2 : std_logic_vector( 15 downto 0 ); signal cnt_wr : std_logic_vector( 7 downto 0 ); -- счётчик строба записи signal cnt_rd : std_logic_vector( 7 downto 0 ):=(others=>'0'); -- счётчик строба чтения signal cnt_wr_z : std_logic; -- 1 - cnt_wr="0000" signal cnt_rd_z : std_logic; -- 1 - cnt_rd="0000" signal fack_wr : std_logic; -- 1 - фронт ack_wr signal fack_rd : std_logic; -- 1 - фронт ack_rd signal fack_wr_clr : std_logic; -- 1 - сброс fack_wr signal fack_rd_clr : std_logic; -- 1 - сброс fack_rd signal pio_read : std_logic; -- строб записи в c_pio signal start_rd : std_logic; -- 1 - запуск счётчика cnt_rd signal c_rst : std_logic; -- 0 - сброс тетрады signal cmd_rdy : std_logic; -- 1 - готовность тетрады к выполнению команды -- signal s_pio_in : std_logic_vector(15 downto 0); signal s_pio_out : std_logic_vector(15 downto 0); signal lvds_pio_in : std_logic_vector(15 downto 0); signal lvds_pio_out : std_logic_vector(15 downto 0); signal s_pio_wr : std_logic; -- строб записи signal s_pio_rd : std_logic; -- строб чтения signal s_ack_wr : std_logic; -- подтверждение записи signal s_ack_rd : std_logic; -- подтверждение чтения signal ack_wr_lvds : std_logic; signal ack_rd_lvds : std_logic; signal pcout : std_logic; signal pio_en : std_logic; signal s_pio_wr_lvds : std_logic; begin xstatus: ctrl_buft16 port map( t => cmd.status_cs, i => c_status, o => cmd_data_out ); cmd_data_out2<=c_status; xdata: ctrl_buft16 port map( t => cmd.data_cs, i => c_pio, o => data_out ); data_out2<=c_pio; data_out2 <= c_pio; cmd_data_out2 <= c_status; data_out2<=c_pio; pr_mode0: process( reset, clk ) begin if( reset='0' ) then c_mode0<=(others=>'0'); elsif( rising_edge( clk ) ) then if( cmd.cmd_data_we='1' ) then if( cmd.adr(9)='0' and cmd.adr(8)='0' ) then case cmd.adr( 3 downto 0 ) is when "0000" => c_mode0<=cmd_data_in; when others=>null; end case; end if; end if; end if; end process; c_rst <= reset and ( not c_mode0(0) ); pr_reg: process( c_rst, clk ) begin if( c_rst='0' ) then c_mode1 <=(others=>'0'); c_mode2 <=(others=>'0'); c_mask <=(others=>'0'); c_inv <=(others=>'0'); elsif( rising_edge( clk ) ) then if( cmd.cmd_data_we='1' ) then if( cmd.adr(9)='0' and cmd.adr(8)='0' ) then case cmd.adr( 3 downto 0 ) is when "0001" => c_mask( 12 downto 9 )<=cmd_data_in( 12 downto 9 ); when "0010" => c_inv( 12 downto 9 )<=cmd_data_in( 12 downto 9 ); when "1001" => c_mode1<=cmd_data_in; when "1010" => c_mode2<=cmd_data_in; when others=>null; end case; end if; end if; end if; end process; c_status(1)<='0'; c_status(2)<='0'; c_status(3)<='0'; c_status(4)<='0'; c_status(5)<='0'; c_status(6)<='0'; c_status(7)<='0'; c_status(8)<='0'; c_status(13)<='0'; c_status(14)<='0'; c_status(15)<='0'; c_status(11)<=fack_wr; c_status(12)<=fack_rd; pr_status: process( clk ) begin if( rising_edge( clk ) ) then c_status(0)<=cmd_rdy; c_status(9)<=s_ack_wr; c_status(10)<=s_ack_rd; end if; end process; c_flag<=c_status( 12 downto 9 ) xor c_inv; c_irq<= c_flag and c_mask; pr_irq: process( c_irq, clk ) variable v: std_logic; begin v:='0'; for i in 9 to 12 loop v:=v or c_irq( i ); end loop; if( rising_edge( clk ) ) then bx_irq<=v and c_mode0(2); end if; end process; pr_s_pio_wr: process( c_rst, clk ) begin if( c_rst='0' ) then cnt_wr<=(others=>'0'); elsif( rising_edge( clk ) ) then if( cmd.data_we='1' ) then cnt_wr<=c_mode2( 7 downto 0 ); elsif( cnt_wr_z='0' ) then cnt_wr<=cnt_wr-1; end if; end if; end process; cnt_wr_z<='1' when cnt_wr=x"00" else '0'; s_pio_wr<=cnt_wr_z or not c_rst; --pr_s_pio_rd: process( c_rst, clk ) begin -- if( c_rst='0' ) then -- cnt_rd<=(others=>'0'); -- elsif( rising_edge( clk ) ) then -- if( start_rd='1' ) then -- cnt_rd<=c_mode2( 15 downto 8 ); -- elsif( cnt_rd_z='0' ) then -- cnt_rd<=cnt_rd-1; -- end if; -- end if; --end process; pr_s_pio_rd: process( start_rd, c_rst, clk ) begin if( c_rst='0' ) then cnt_rd<=(others=>'0'); elsif( start_rd='1' ) then cnt_rd<=c_mode2( 15 downto 8 ); elsif( rising_edge( clk ) ) then if( cnt_rd_z='0' ) then cnt_rd<=cnt_rd-1; end if; end if; end process; cnt_rd_z<='1' when cnt_rd=x"00" else '0'; s_pio_rd<=cnt_rd_z or not c_rst; pr_fack_wr: process( c_rst, s_ack_wr, fack_wr_clr ) begin if( c_rst='0' or fack_wr_clr='1' ) then fack_wr<='0'; elsif( rising_edge( s_ack_wr ) ) then fack_wr<='1'; end if; end process; pr_fack_rd: process( c_rst, s_ack_rd, fack_rd_clr ) begin if( c_rst='0' or fack_rd_clr='1' ) then fack_rd<='0'; elsif( rising_edge( s_ack_rd ) ) then fack_rd<='1'; end if; end process; -------------------------------------------------------------------- pr_start_rd: process( c_rst, clk ) begin if( c_rst='0' ) then start_rd<='0'; elsif( rising_edge( clk ) ) then if( c_mode1(2)='0' ) then -- внутренняя синхронизация if( cmd.cmd_data_we='1' and cmd.adr(9)='1' and cmd.adr(8)='0' and cmd.adr(0)='1' ) then start_rd<='1'; else start_rd<='0'; end if; else -- внешняя синхронизация start_rd<=not cmd.data_cs; end if; end if; end process; pr_fack_clr: process( c_rst, clk ) variable v0, v1: std_logic; begin if( c_rst='0' ) then fack_wr_clr<='0'; fack_rd_clr<='0'; elsif( rising_edge( clk ) ) then v0:='0'; v1:='0'; if( c_mode1(2)='0' ) then if( cmd.cmd_data_we='1' ) then if( cmd.adr(9)='1' and cmd.adr(8)='0' and cmd.adr(0)='0' ) then v1:=cmd_data_in( 12 ); end if; end if; else v1:=not cmd.data_cs; end if; if( cmd.cmd_data_we='1' ) then if( cmd.adr(9)='1' and cmd.adr(8)='0' and cmd.adr(0)='0' ) then v0:=cmd_data_in( 11 ); end if; end if; fack_wr_clr<=v0; fack_rd_clr<=v1; end if; end process; cmd_rdy <= cnt_wr_z and (cnt_rd_z or c_mode1(3)) ; pr_pio_out: process( c_rst, clk ) begin if( c_rst='0' ) then s_pio_out<=(others=>'0'); elsif( rising_edge( clk ) ) then if( cmd.data_we='1' ) then s_pio_out<=data_in; end if; end if; end process; pr_c_pio: process( c_rst, pio_read ) begin if( c_rst='0' ) then c_pio<=(others=>'0'); elsif( rising_edge( pio_read ) ) then c_pio<=s_pio_in; end if; end process; process(c_mode1(3 downto 2),cnt_rd_z,s_ack_rd,clk ) begin case c_mode1(3 downto 2) is when "00" => pio_read <= cnt_rd_z; when "01" => pio_read <= s_ack_rd; when "10" => pio_read <= clk; when others => null; end case; end process; pio_out <=lvds_pio_out when c_mode1(10)='1' else s_pio_out; s_pio_in <=lvds_pio_in when c_mode1(10)='1' else pio_in; gen_pio: for ii in 0 to 7 generate lvds_pio_out(ii*2)<= s_pio_out(ii); lvds_pio_in(ii) <= pio_in(2*ii); end generate; lvds_pio_out(9)<='1'; --pen0 lvds_pio_out(11)<='0'; --pen1 lvds_pio_out(13)<=c_mode1(0); lvds_pio_out(15)<=c_mode1(1); pio_enable<=pio_en; -- not c_mode1(11); gen_en1: if use_enable=2 generate pio_en <= not c_mode1(11); end generate; gen_en2: if use_enable=1 generate pio_en <= '0'; end generate; pio_wr <= s_pio_wr when c_mode1(10)='0' else s_pio_wr_lvds; pio_rd <= s_pio_rd; s_ack_wr <= ack_wr when c_mode1(10)='0' else ack_wr_lvds ; s_ack_rd <= ack_rd when c_mode1(10)='0' else ack_rd_lvds ; process(c_mode1(13), pen1_in) begin if c_mode1(13) ='0' then ack_wr_lvds<=pen1_in; ack_rd_lvds<=ack_rd; else ack_rd_lvds<=pen1_in; ack_wr_lvds<=ack_rd; end if; end process; s_pio_wr_lvds <= s_pio_wr when c_mode1(12)='0' else s_pio_rd; pcout<=s_pio_rd when c_mode1(12)='0' else s_pio_wr; pen0 <= pcout when c_mode1(10)='1' else not c_mode1(0); pen1 <= not c_mode1(1); pio_oe0 <= not c_mode1(0) or pio_en; pio_oe1 <= not c_mode1(1) or pio_en; lvds <= not c_mode1(1) or pio_en when c_mode1(10) ='0' else pio_en; pen1_oe<=c_mode1(10) or pio_en; end trd_pio_std_v4;
Go to most recent revision | Compare with Previous | Blame | View Log