---------------------------------------------------------------------------------- -- Company: Lawrence Berkeley National Laboratory -- Engineer: Jean-Marie Bussat -- -- Create Date: 16:31:34 08/10/2006 -- Design Name: Optical interface CPLD -- Module Name: NI_Interface - Behavioral -- Project Name: SAO - Multiple Waveform Digitizer System -- Target Devices: XC95288TQ144-7 -- Tool versions: Webpack 8.2i -- Description: Interface with the National Instruments DIO board -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Simulation OK: 08/23/06 (test bench: simNI_Interface.vhd) -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity NI_Interface is Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; ACK1 : in STD_LOGIC; ACK2 : in STD_LOGIC; REQ1 : out STD_LOGIC; REQ2 : out STD_LOGIC; data_in : in STD_LOGIC_VECTOR(15 downto 0); wen : in STD_LOGIC; wdone : out STD_LOGIC; command_out: out STD_LOGIC_VECTOR(15 downto 0); cav : out STD_LOGIC; -- Command AVailable PORT1 : in STD_LOGIC_VECTOR(15 downto 0); PORT2 : out STD_LOGIC_VECTOR(15 downto 0) ); end NI_Interface; architecture Behavioral of NI_Interface is -- signals for port 2 signal ack2_sync : std_logic; signal req2_cnt : std_logic_vector(1 downto 0); signal req2_cnt_ld : std_logic; type PORT2_STATE is ( idle,request,req_low,req_high,done ); signal p2state : PORT2_STATE; -- signals for port 1 signal ack1_sync : std_logic_vector(16 downto 0); -- (2 downto 0) signal cmd_en : std_logic; signal PORT1sig, PORT1sig2 : STD_LOGIC_VECTOR(15 downto 0); --dd begin -- Make sure the inputs are synchronous or at least -- stable when they are used later SYNC_IN : process(rst,clk,ACK1,ACK2) begin if rst='1' then ack1_sync<=(others => '0'); ack2_sync<='0'; else if clk'event and clk='0' then ack1_sync(16 downto 1)<=ack1_sync(15 downto 0); --ack1_sync(2 downto 1)<=ack1_sync(1 downto 0); ack1_sync(0)<=ACK1; ack2_sync<=ACK2; end if; end if; end process SYNC_IN; -- ____________________ -- / /, -- / PORT 2 MANAGEMENT // --/___________________// -- -------------------/ -- PORT 2 is output only (status/FIFO data to DIO board) -- ===================================================== PORT2_INTERFACE : process(rst,clk,ack2_sync) begin if rst='1' then p2state<=idle; REQ2<='0'; req2_cnt_ld<='1'; wdone<='0'; else if clk'event and clk='1' then case p2state is when idle => REQ2<='0'; req2_cnt_ld<='1'; wdone<='0'; if wen='1' then p2state<=request; end if; when request => REQ2<='1'; req2_cnt_ld<='1'; wdone<='0'; if ack2_sync='1' then p2state<=req_low; end if; when req_low => REQ2<='0'; req2_cnt_ld<='0'; wdone<='0'; if req2_cnt="00" then p2state<=req_high; end if; when req_high => REQ2<='1'; req2_cnt_ld<='0'; wdone<='0'; if ack2_sync='0' then--if req2_cnt="00" then -- what is this doing? p2state<=done; end if; when done => REQ2<='0'; req2_cnt_ld<='1'; wdone<='1'; --if ack2_sync='0' then p2state<=idle; --end if; when others => REQ2<='0'; req2_cnt_ld<='1'; wdone<='0'; p2state<=idle; end case; end if; end if; end process PORT2_INTERFACE; PORT2<=data_in; REQ2_TIMER : process(rst,clk,req2_cnt_ld) begin if rst='1' then req2_cnt<="00"; else if clk'event and clk='1' then if req2_cnt_ld='1' then req2_cnt<="10"; else req2_cnt<=req2_cnt-"01"; end if; end if; end if; end process REQ2_TIMER; -- ____________________ -- / /, -- / PORT 1 MANAGEMENT // --/___________________// -- -------------------/ -- PORT 1 is input only (DIO commands to DAQ system) -- ================================================= -- <- 225 ns -> -- ___________ -- ACK _____| |_______ -- ____________ -- REQ _______| |____ -- -- Here, REQ is a delayed version of ACK and we assume -- that the DIO board respects its own timing requirements: -- Since the ACK pulse should last 225ns, the REQ pulse -- will also last 225ns and meet the 75ns minimum requirement. PORT1_INTERFACE : process(rst,clk,ack1_sync) begin if rst='1' then REQ1<='0'; cmd_en<='0'; cav<='0'; else if clk'event and clk='0' then REQ1<=ack1_sync(16); -- handshake with DIO REQ1<=ack1_sync(2); cmd_en<=ack1_sync(10) and not ack1_sync(11); -- store data present on PORT1 cmd_en<=ack1_sync(0) and not ack1_sync(1); cav<=ack1_sync(16) and not ack1_sync(15); -- raise data available flag cav<=ack1_sync(2) and not ack1_sync(1); end if; end if; end process PORT1_INTERFACE; -- Register that stores commands received from the DIO board COMMAND_REGISTER : process(rst,clk,cmd_en,PORT1) begin if rst='1' then command_out<=(others=>'0'); else if clk'event and clk='1' then -- PORT1sig <= PORT1;--DD -- PORT1sig2 <= PORT1sig;--DD -- if cmd_en='1' then --For some reason, when this signal is not commented the data is latched wrongly DD -- command_out<=PORT1sig;--DD command_out<=PORT1; -- end if; end if; end if; end process COMMAND_REGISTER; end Behavioral;