library IEEE; use IEEE.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; -- Offset -- 0x00 rw rst_opend & rst_inv & sel_p(7..4) & sel_s(3..0) -- sel_p and sel_s have the same meaning as in TRAP NPn and NED -- configuration registers -- rst_opend - if 1 the reset output is open drain output -- rst_inv - if 1 the reset output is inverted, otherwise is active low -- 0x00 r bit 10 - reset read back. -- 0x01 rw xor_mask(29..20) & and_mask(19..10) & or_mask(9..0) for NI input data -- data_internal <= ( (ni_data xor xor_mask) and and_mask) or or_mask -- 0x02 r the number of 16-bit words, pos_edge_strobe(23..12)/neg_edge_strobe(11..0) -- add 1 and divide by 2 to get the number of 32-bit words to read. -- pos_edge and neg_edge must be equal! -- 0x03 r the number of 16-bit words with wrong parity, pos_edge_strobe(23..12)/neg_edge_strobe(11..0) -- 0x02 w clear NI input port -- 0x03 w activate the reset output -- -- 0x800..0xFFF D(4*k+3) & D(4*k+2) & D(4*k+1) & D(4*k), k=0..8191 -- Stored data from the NI output port of the DUT. The next write address -- (for 16-bit data) for each strobe edge can be read at 0x6002 (see above) -- The last 16-bit word in trap-mode (not oase mode) can not be read correctly. entity ni2io_wt is port ( reset_n : in std_logic; -- asynchronous reset clk : in std_logic; -- read clock clk120 : in std_logic; -- read clock -- lvds strobe : in std_logic; -- incoming DDR strobe signal lvds_data_in : in std_logic_vector( 9 downto 0); -- incoming DDR data sync. to strobe -- ctrl : out std_logic; -- control to the trap -- PASA serial receiver PA_SCLK : in std_logic; PA_SDAT : in std_logic; PA_SSTR : in std_logic; wrst_n : out std_logic; wrst_n_in : in std_logic; wrst_n_oe : out std_logic; -- to the internal bus CE : in std_logic; WE : in std_logic; wdata : in std_logic_vector(31 downto 0); addr : in std_logic_vector(11 downto 0); rdata : out std_logic_vector(31 downto 0) -- data output, sync. to internal clk ); end ni2io_wt; architecture a of ni2io_wt is component ni2io is port ( reset_n : in std_logic; -- asynchronous reset clk : in std_logic; -- read clock strobe : in std_logic; -- incoming DDR strobe signal oa_ctrl : in std_logic; -- oase mode control from the trap lvds_data_in : in std_logic_vector( 9 downto 0); -- incoming DDR data sync. to strobe clear : in std_logic; -- synchronous reset oase_mode : in std_logic; -- from the configuration sel_s : in std_logic_vector( 3 downto 0); sel_p : in std_logic_vector( 3 downto 0); or_mask : in std_logic_vector( 9 downto 0); and_mask : in std_logic_vector( 9 downto 0); xor_mask : in std_logic_vector( 9 downto 0); naddr : out std_logic_vector(23 downto 0); raddr : in std_logic_vector(10 downto 0); pcnt : out std_logic_vector(23 downto 0); rdata : out std_logic_vector(31 downto 0) -- data output, sync. to internal clk ); end component; component clk_counter is port ( clk : in std_logic; reset_n : in std_logic; ce : in std_logic; strb_dout : out std_logic_vector( 7 downto 0); strb_clk : in std_logic ); end component; component dig_cntrl2 IS GENERIC (Ndac : Integer := 8; Nch : Integer := 18); -- Ndac < Nch !!! PORT( CLK : IN STD_LOGIC; -- serial clock DIN : IN STD_LOGIC; -- serial data STR : IN STD_LOGIC; -- strobe, trigger the pulser DAC : OUT STD_LOGIC_VECTOR( 7 downto 0); -- to the DAC EN : OUT STD_LOGIC_VECTOR(17 downto 0) -- to the trigger of each channel ); END component; signal oase_mode : std_logic; signal clear : std_logic; signal oa_ctrl : std_logic; signal sel_s : std_logic_vector( 3 downto 0); signal sel_p : std_logic_vector( 3 downto 0); signal or_mask : std_logic_vector( 9 downto 0); signal and_mask : std_logic_vector( 9 downto 0); signal xor_mask : std_logic_vector( 9 downto 0); signal sel : std_logic_vector( 2 downto 0); signal naddr : std_logic_vector(23 downto 0); signal pcnt : std_logic_vector(23 downto 0); signal rdata_ni : std_logic_vector(31 downto 0); signal PASA_DAC : STD_LOGIC_VECTOR( 7 downto 0); signal PASA_EN : STD_LOGIC_VECTOR(17 downto 0); --signal lvds_data_in_cor : std_logic_vector( 9 downto 0); signal cnt_rst : std_logic_vector( 8 downto 0); signal rst_full : std_logic_vector(cnt_rst'range); signal rst_start : std_logic; signal PA_SCLK_i : std_logic; signal PA_SDAT_i : std_logic; signal PA_SSTR_i : std_logic; signal wrst_n_i : std_logic; signal rst_inv : std_logic; signal rst_opend : std_logic; signal rst_back : std_logic; signal strb_dout : std_logic_vector( 7 downto 0); begin -- the signals are inverted on the wafer tester adapter card! PA_SCLK_i <= not PA_SCLK; PA_SDAT_i <= not PA_SDAT; PA_SSTR_i <= not PA_SSTR; pasa_int: dig_cntrl2 PORT map( CLK => PA_SCLK_i, DIN => PA_SDAT_i, STR => PA_SSTR_i, DAC => PASA_DAC, EN => PASA_EN ); oase_mode <= '0'; oa_ctrl <= '0'; scnt: clk_counter port map( clk => clk120, reset_n => reset_n, ce => clear, strb_dout => strb_dout, strb_clk => strobe ); ni: ni2io port map( reset_n => reset_n, clk => clk, strobe => strobe, lvds_data_in => lvds_data_in, clear => clear, oase_mode => oase_mode, oa_ctrl => oa_ctrl, sel_s => sel_s, sel_p => sel_p, or_mask => or_mask, and_mask => and_mask, xor_mask => xor_mask, naddr => naddr, raddr => addr(10 downto 0), pcnt => pcnt, rdata => rdata_ni ); sel <= addr(addr'high) & addr(addr'low+1) & addr(addr'low); process(sel, rdata_ni, naddr, sel_p, sel_s, pcnt, rst_opend, rst_inv, rst_back, or_mask, and_mask, xor_mask, strb_dout) begin rdata <= (others => '0'); case sel is when "100" | "101" | "110" | "111" => rdata(rdata_ni'range) <= rdata_ni; when "000" => rdata(10 downto 0) <= rst_back & rst_opend & rst_inv & sel_p & sel_s; when "001" => --rdata(17 downto 0) <= PASA_EN; --rdata(27 downto 20) <= PASA_DAC; rdata( 9 downto 0) <= or_mask; rdata(19 downto 10) <= and_mask; rdata(29 downto 20) <= xor_mask; when "010" => rdata(naddr'range) <= naddr; rdata(31 downto 24) <= strb_dout; when "011" => rdata(pcnt'range) <= pcnt; when others => rdata <= (others => '-'); end case; end process; process(clk, reset_n) begin if reset_n='0' then sel_s <= "1000"; sel_p <= "1001"; clear <= '1'; rst_start <= '1'; rst_inv <= '1'; rst_opend <= '0'; or_mask <= (others => '0'); and_mask <= (others => '1'); xor_mask <= (others => '1'); -- in WT the data bits are inverted elsif clk'event and clk='1' then clear <= '0'; rst_start <= '0'; if we='1' and ce='1' then case addr(1 downto 0) is when "00" => sel_s <= wdata(3 downto 0); sel_p <= wdata(7 downto 4); rst_inv <= wdata(8); rst_opend <= wdata(9); when "01" => or_mask <= wdata( 9 downto 0); and_mask <= wdata(19 downto 10); xor_mask <= wdata(29 downto 20); when "10" => clear <= '1'; when "11" => rst_start <= '1'; when others => NULL; end case; end if; end if; end process; rst_full <= (others => '1'); process(clk, reset_n) begin if reset_n = '0' then cnt_rst <= (others => '0'); elsif clk'event and clk= '1' then if rst_start = '1' then cnt_rst <= (others => '0'); elsif cnt_rst /= rst_full then cnt_rst <= cnt_rst + 1; end if; end if; end process; -- the signal is inverted on the wafer tester adapter card! wrst_n_i <= (rst_inv xor cnt_rst(cnt_rst'high-1) ); -- wrst_n <= '0' when wrst_n_i='0' else '1' when rst_opend='0' else 'Z'; wrst_n <= wrst_n_i; wrst_n_oe <= not (rst_opend and wrst_n_i); rst_back <= wrst_n_in; end;