-- RESET and IRQ for the TRAP chips not ready!!! -- Offset -- 0 rw SCSN switch select -- 0 only the local scsn slave -- 1 the local and the other fpga slave -- 2 the local, the other fpga slave and the 4 traps for ni test -- 3 the local and the DUT -- 4 the local, the DUT and the 4 traps for ni test -- 5 the local and the WT -- 6 the local and the 4 traps for ni test -- 7 the local, the other fpga and the WT -- In cases without DUT in the chain, bit3 of the switch determins the static value to SCSN1 input of DUT -- switch bit 4 is wafer tester DUT input invert -- switch bit 5 is wafer tester DUT output invert -- switch bit 6 is DUT inputs crossing -- switch bit 7 is DUT outputs crossing -- 0x10 rw oase_mode(8) & ni_sel_s(7..4) & ni_sel_p(3..0) -- for ni_sel_s and ni_sel_p see the TRAP3 documentation -- oase mode not implemented yet -- 0x20 r hardware version(4 bits) & serial nummer(4 bits) -- 0x20 w ni reset_n -- reset for the 4 TRAP chips for NI test -- 0x21 w ni irq_n -- IRQ for the 4 TRAP chips for NI test -- 0x30 w dut reset_n -- reset for the DUT chip -- 0x31 w dut irq_n -- IRQ for the DUT chip -- 0x40 r SEBD_IN(8..6) & SEBD_OE(5..3) & SEBD_OUT(2..0) -- 0x40 w SEBD_OE(5..3) & SEBD_OUT(2..0) -- 0x50 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; -- 0x80 r next address NI input port -- 0x81 r parity counters -- 0x80 w clear NI input port LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity general_config is generic( SERNR : Integer := 0; HDVER : Integer := 0); port ( clk : in std_logic; reset_n : in std_logic; reset_pup_n : in std_logic; -- enable ce : in std_logic; -- internal bus bus_addr : in std_logic_vector( 7 downto 0); bus_we : in std_logic; -- write enable bus_din : in std_logic_vector(31 downto 0); bus_dout : out std_logic_vector(31 downto 0); -- config registers -- scsn switch sw_sel : out std_logic_vector( 7 downto 0); -- addr 0 -- NI receiver ni_sel_s : out std_logic_vector( 3 downto 0); -- addr 0x10 ni_sel_p : out std_logic_vector( 3 downto 0); ni_or_mask : out std_logic_vector( 9 downto 0); ni_and_mask : out std_logic_vector( 9 downto 0); ni_xor_mask : out std_logic_vector( 9 downto 0); ni_oase_mode : out std_logic; ni_jtag_mode : out std_logic; ni_ctrl_jtag : out std_logic; -- irq/rst of the 4 ni ni_irq_n : out std_logic; -- addr 0x20/21 ni_rst_n : out std_logic; -- irq/rst of DUT dut_irq_n : inout std_logic; -- addr 0x30/31 dut_rst_n : inout std_logic; -- single ended bidir pins of DUT sebd_out : out std_logic_vector( 2 downto 0); -- addr 0x40/1 sebd_oe : out std_logic_vector( 2 downto 0); -- readonly tst_pad : in std_logic_vector( 3 downto 0); -- addr 0x90 sebd_in : in std_logic_vector( 2 downto 0); -- addr 0x42 ni_naddr : in std_logic_vector(23 downto 0); -- next address, to the IO 0x18 ni_pcnt : in std_logic_vector(23 downto 0); -- parity counters ni_direct : in std_logic_vector(16 downto 0); -- addr 0xA0 ni_clear : out std_logic ); end general_config; architecture a of general_config is component irq_rst is port ( clk : in std_logic; reset_n : in std_logic; irq_start : in std_logic; rst_start : in std_logic; irq_n : out std_logic; rst_n : out std_logic); end component; signal sw_sel_i : std_logic_vector(sw_sel'range); -- addr 0 -- NI receiver signal ni_sel_s_i : std_logic_vector( 3 downto 0); -- addr 0x10 signal ni_sel_p_i : std_logic_vector( 3 downto 0); signal ni_oase_mode_i : std_logic; signal ni_jtag_mode_i : std_logic; signal ni_ctrl_jtag_i : std_logic; signal ni_or_mask_i : std_logic_vector( 9 downto 0); signal ni_and_mask_i : std_logic_vector( 9 downto 0); signal ni_xor_mask_i : std_logic_vector( 9 downto 0); -- single ended bidir pins of DUT signal sebd_out_i : std_logic_vector( 2 downto 0); -- addr 0x40/1 signal sebd_oe_i : std_logic_vector( 3 downto 0); signal flag_ni_irq : std_logic; signal flag_ni_rst : std_logic; signal flag_dut_irq : std_logic; signal flag_dut_rst : std_logic; signal dut_rst_r : std_logic; signal dut_irq_r : std_logic; signal dut_irq_n_i : std_logic; signal dut_rst_n_i : std_logic; signal se0_cnt : std_logic_vector(7 downto 0); signal se1_cnt : std_logic_vector(7 downto 0); signal se2_cnt : std_logic_vector(7 downto 0); signal se_pre_cnt : std_logic_vector(3 downto 0); signal se_cnt_full : std_logic_vector(7 downto 0); signal ser_nr : std_logic_vector(3 downto 0); signal hd_ver : std_logic_vector(3 downto 0); begin se_cnt_full <= (others => '1'); ser_nr <= conv_std_logic_vector(SERNR, ser_nr'length); hd_ver <= conv_std_logic_vector(HDVER, hd_ver'length); process(clk, reset_n) begin if reset_n='0' then flag_ni_irq <= '1'; flag_ni_rst <= '1'; flag_dut_irq <= '1'; flag_dut_rst <= '1'; sebd_out_i <= (others => '0'); sebd_oe_i <= (others => '0'); ni_or_mask_i <= (others => '0'); ni_and_mask_i <= (others => '1'); ni_xor_mask_i <= (others => '0'); ni_sel_s_i <= "1000"; ni_sel_p_i <= "1001"; ni_oase_mode_i <= '0'; ni_jtag_mode_i <= '0'; ni_ctrl_jtag_i <= '0'; -- sw_sel_i <= (others => '0'); ni_clear <= '1'; elsif clk'event and clk='1' then flag_ni_irq <= '0'; flag_ni_rst <= '0'; flag_dut_irq <= '0'; flag_dut_rst <= '0'; ni_clear <= '0'; if bus_we='1' and ce='1' then case bus_addr(7 downto 4) is -- when "0000" => sw_sel_i <= bus_din(sw_sel_i'range); when "0001" => ni_sel_s_i <= bus_din(3 downto 0); ni_sel_p_i <= bus_din(7 downto 4); ni_oase_mode_i <= bus_din(8); ni_jtag_mode_i <= bus_din(10); ni_ctrl_jtag_i <= bus_din(9); when "0010" => if bus_addr(0)='1' then flag_ni_irq <= '1'; end if; if bus_addr(0)='0' then flag_ni_rst <= '1'; end if; when "0011" => if bus_addr(0)='1' then flag_dut_irq <= '1'; end if; if bus_addr(0)='0' then flag_dut_rst <= '1'; end if; when "0100" => sebd_out_i <= bus_din(2 downto 0); sebd_oe_i <= bus_din(7 downto 4); when "0101" => ni_or_mask_i <= bus_din( 9 downto 0); ni_and_mask_i <= bus_din(19 downto 10); ni_xor_mask_i <= bus_din(29 downto 20); when "1000" => ni_clear <= '1'; when others => NULL; end case; end if; end if; end process; process(clk, reset_pup_n) begin if reset_pup_n='0' then sw_sel_i <= (others => '0'); elsif clk'event and clk='1' then if bus_we='1' and ce='1' then case bus_addr(7 downto 4) is when "0000" => sw_sel_i <= bus_din(sw_sel_i'range); when others => NULL; end case; end if; end if; end process; process(clk, reset_n) begin if clk'event and clk='1' then if flag_dut_rst='1' then se0_cnt <= (others => '0'); se1_cnt <= (others => '0'); se2_cnt <= (others => '0'); se_pre_cnt <= (others => '0'); else se_pre_cnt <= se_pre_cnt + 1; if se_pre_cnt = "1111" then if sebd_in(0)='0' and se0_cnt /= se_cnt_full then se0_cnt <= se0_cnt + 1; end if; if sebd_in(1)='0' and se1_cnt /= se_cnt_full then se1_cnt <= se1_cnt + 1; end if; if sebd_in(2)='0' and se2_cnt /= se_cnt_full then se2_cnt <= se2_cnt + 1; end if; end if; end if; end if; end process; sw_sel <= sw_sel_i; ni_sel_s <= ni_sel_s_i; ni_sel_p <= ni_sel_p_i; ni_or_mask <= ni_or_mask_i; ni_and_mask <= ni_and_mask_i; ni_xor_mask <= ni_xor_mask_i; ni_oase_mode <= ni_oase_mode_i; ni_jtag_mode <= ni_jtag_mode_i; ni_ctrl_jtag <= ni_ctrl_jtag_i; sebd_out <= sebd_out_i; sebd_oe <= sebd_oe_i(sebd_oe'range); process(sw_sel_i, ni_sel_s_i, ni_sel_p_i, ni_oase_mode_i, ni_jtag_mode_i, ni_ctrl_jtag_i, tst_pad, ni_direct, sebd_out_i, sebd_oe_i, sebd_in, ni_naddr, bus_addr, se0_cnt, se1_cnt, se2_cnt, ni_pcnt, dut_rst_r, dut_irq_r, ni_or_mask_i, ni_and_mask_i, ni_xor_mask_i, ser_nr, hd_ver) begin bus_dout <= (others => '0'); case bus_addr(7 downto 4) is when "0000" => bus_dout(sw_sel_i'range) <= sw_sel_i; when "0001" => bus_dout(10 downto 0) <= ni_jtag_mode_i & ni_ctrl_jtag_i & ni_oase_mode_i & ni_sel_p_i & ni_sel_s_i; when "0010" => bus_dout(ser_nr'length+hd_ver'length-1 downto 0) <= hd_ver & ser_nr; when "0011" => bus_dout(23 downto 0) <= se2_cnt & se1_cnt & se0_cnt; bus_dout(31) <= dut_rst_r; bus_dout(30) <= dut_irq_r; when "0100" => bus_dout(10 downto 0) <= sebd_in & sebd_oe_i & '0' & sebd_out_i; bus_dout(31) <= '1'; when "0101" => bus_dout( 9 downto 0) <= ni_or_mask_i; bus_dout(19 downto 10) <= ni_and_mask_i; bus_dout(29 downto 20) <= ni_xor_mask_i; when "1000" => if bus_addr(0)='0' then bus_dout(ni_naddr'range) <= ni_naddr; else bus_dout(ni_naddr'range) <= ni_pcnt; end if; when "1001" => bus_dout(tst_pad'range) <= tst_pad; when "1010" => bus_dout(ni_direct'range) <= ni_direct; when others => NULL; end case; end process; dut_ir: irq_rst port map( clk => clk, reset_n => reset_n, irq_start => flag_dut_irq, rst_start => flag_dut_rst, irq_n => dut_irq_n_i, rst_n => dut_rst_n_i); dut_irq_n <= dut_irq_n_i when (sebd_oe_i(3)='1' or dut_irq_n_i='0') else 'Z'; dut_rst_n <= dut_rst_n_i when (sebd_oe_i(3)='1' or dut_rst_n_i='0') else 'Z'; dut_rst_r <= dut_rst_n; dut_irq_r <= dut_irq_n; ni_ir: irq_rst port map( clk => clk, reset_n => reset_n, irq_start => flag_ni_irq, rst_start => flag_ni_rst, irq_n => ni_irq_n, rst_n => ni_rst_n); end;