www.pudn.com > jtag_cpld_vhdl.rar > jtag.vhd


 
-- Faster JTAG tool over EPP port 
-- Writen By tpu, 2004-06-10 
--  
-- write: 
--     address 0: last data length, 1-8 bits 
--     address 1: tdi data(data & cmd) 
--     address 2: tms data 
-- read: 
--     address x: tdo data 
-- status read: 
--     epp/spp status byte d6-d3: rsr full, rbr full, tsr empty, thr empty 
--  
-- block: 
--  --------------------------------------------------- 
--  |   _______    ___________             _______    | 
--  |   | thr |    |bit count|             | rbr |    | 
--  |   -------    -----------             -------    | 
--  |      |                                  |       | 
--  |   _______                            _______    | 
--  |MSB| tsr |LSB -> TDI/TMS     TDO-> MSB| rsr |LSB | 
--  |   -------                            -------    | 
--  --------------------------------------------------- 
--  
-- device  : EPM7128STC100-15 
-- crystal : 20 MHz 
-- tck     : 5 MHz 
--  
--  
 
LIBRARY ieee; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.STD_LOGIC_ARITH.ALL; 
USE IEEE.STD_LOGIC_UNSIGNED.ALL; 
 
ENTITY jtag IS 
PORT( 
 clk  :IN STD_LOGIC; 
 rst  :IN STD_LOGIC; 
  
 EPP_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); 
 nwrite :IN STD_LOGIC; 
 nwait :OUT STD_LOGIC; 
 ndatastb:IN STD_LOGIC; 
 naddrstb:IN STD_LOGIC; 
  
 
 in_d6 :OUT STD_LOGIC; 
 in_d5 :OUT STD_LOGIC; 
 in_d4 :OUT STD_LOGIC; 
 in_d3 :OUT STD_LOGIC; 
 
 led0 :OUT STD_LOGIC; 
 led1 :OUT STD_LOGIC; 
 led2 :OUT STD_LOGIC; 
 led3 :OUT STD_LOGIC; 
 
 tdo_i :IN STD_LOGIC; 
 tdi_o :OUT STD_LOGIC; 
 tms_o :OUT STD_LOGIC; 
 ntrst_o :OUT STD_LOGIC; 
 tck_o :OUT STD_LOGIC 
); 
END jtag; 
 
ARCHITECTURE main OF jtag IS 
 SIGNAL thcnt_w0 :STD_LOGIC; 
 SIGNAL thcnt_w1 :STD_LOGIC; 
 SIGNAL thcnt_w :STD_LOGIC; 
 SIGNAL thcnt :STD_LOGIC_VECTOR(3 DOWNTO 0); 
  
 SIGNAL thr_w0 :STD_LOGIC; 
 SIGNAL thr_w1 :STD_LOGIC; 
 SIGNAL thr_w :STD_LOGIC; 
 SIGNAL thr  :STD_LOGIC_VECTOR(7 DOWNTO 0); 
 SIGNAL thr_e :STD_LOGIC; 
 SIGNAL data_type:STD_LOGIC; 
 SIGNAL last_data:STD_LOGIC; 
 
 SIGNAL tsr_e :STD_LOGIC; 
 SIGNAL tsr_e0 :STD_LOGIC; 
 SIGNAL tsr  :STD_LOGIC_VECTOR(7 DOWNTO 0); 
 SIGNAL tms0  :STD_LOGIC; 
 SIGNAL auto_tms  :STD_LOGIC; 
 
 SIGNAL tscnt :STD_LOGIC_VECTOR(5 DOWNTO 0); 
 SIGNAL tscnt_z :STD_LOGIC; 
 SIGNAL tscnt_z0 :STD_LOGIC; 
  
 SIGNAL rbr_r0 :STD_LOGIC; 
 SIGNAL rbr_r1 :STD_LOGIC; 
 SIGNAL rbr_r :STD_LOGIC; 
 SIGNAL rbr  :STD_LOGIC_VECTOR(7 DOWNTO 0); 
 SIGNAL rbr_f0 :STD_LOGIC; 
 SIGNAL rbr_f :STD_LOGIC; 
  
 SIGNAL rsr_f :STD_LOGIC; 
 SIGNAL rsr  :STD_LOGIC_VECTOR(7 DOWNTO 0); 
 
 SIGNAL addr_w0 :STD_LOGIC; 
 SIGNAL addr_w1 :STD_LOGIC; 
 SIGNAL addr_w :STD_LOGIC; 
 SIGNAL addr_reg:STD_LOGIC_VECTOR(1 DOWNTO 0); 
  
 SIGNAL strobe :STD_LOGIC; 
 SIGNAL wait_out:STD_LOGIC; 
BEGIN 
 
 -- EPP status 
 in_d3 <= thr_e; 
 in_d4 <= tsr_e; 
 in_d5 <= rbr_f; 
 in_d6 <= rsr_f; 
 
 -- LED status; 
 led0 <= NOT rsr_f; 
 led1 <= NOT rbr_f; 
 led2 <= NOT addr_reg(0); 
 led3 <= NOT addr_reg(1); 
 
 -- nWait generation 
 PROCESS(rst, clk) 
 BEGIN 
  IF rst='0' THEN 
   strobe <= '1'; 
  ELSIF RISING_EDGE(clk) THEN 
   strobe <= ndatastb AND naddrstb; 
  END IF; 
 END PROCESS; 
 
 PROCESS(rst, clk) 
 BEGIN 
  IF rst='0' THEN 
   wait_out <= '0'; 
  ELSIF RISING_EDGE(clk) THEN 
   wait_out <= NOT strobe; 
  END IF; 
 END PROCESS; 
 nwait <= wait_out; 
 
 -- read and write signal 
 addr_w0 <= nwrite OR naddrstb; 
 thcnt_w0 <= nwrite OR ndatastb OR addr_reg(0) OR addr_reg(1); 
 thr_w0  <= nwrite OR ndatastb OR NOT(addr_reg(0) OR addr_reg(1)); 
 rbr_r0  <= ndatastb OR (NOT nwrite) OR (NOT naddrstb); 
 
 -- Delay signal 
 PROCESS(clk) 
 BEGIN 
  IF RISING_EDGE(clk) THEN 
   addr_w1 <= addr_w0; 
   addr_w  <= addr_w1; 
 
   thcnt_w1<= thcnt_w0; 
   thcnt_w <= thcnt_w1; 
 
   thr_w1  <= thr_w0; 
   thr_w   <= thr_w1; 
 
   rbr_r1  <= rbr_r0; 
   rbr_r   <= rbr_r1; 
    
   rbr_f0  <= rbr_f; 
 
   tsr_e0  <= tsr_e; 
 
   tscnt_z0<= tscnt_z; 
  END IF; 
 END PROCESS; 
 
 -- address write 
 PROCESS(rst, addr_w) 
 BEGIN 
  IF rst='0' THEN 
   addr_reg <= "10"; 
  ELSIF FALLING_EDGE(addr_w) THEN 
   addr_reg <= EPP_DATA(1 DOWNTO 0); 
  END IF; 
 END PROCESS; 
 
 -- counter write 
 PROCESS(rst, clk, thcnt_w) 
 BEGIN 
  IF rst='0' THEN 
   thcnt <= "1000"; 
   last_data <= '0'; 
  ELSIF RISING_EDGE(clk) THEN 
   IF thcnt_w='0' THEN 
    thcnt <= EPP_DATA(3 DOWNTO 0); 
    last_data <= '1'; 
   ELSIF tscnt_z='0' AND tscnt_z0='1' THEN 
    thcnt <= "1000"; 
    last_data <= '0'; 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- data write 
 PROCESS(thr_w) 
 BEGIN 
  IF FALLING_EDGE(thr_w) THEN 
   thr <= EPP_DATA; 
   data_type <= addr_reg(0); 
  END IF; 
 END PROCESS; 
 
 -- data read 
 PROCESS(rbr_r, rbr) 
 BEGIN 
  IF rbr_r='0' THEN 
   EPP_DATA <= rbr; 
  ELSE 
   EPP_DATA <= "ZZZZZZZZ"; 
  END IF; 
 END PROCESS; 
 
----------------------------------------------------------------- 
 
 -- thr_e 
 PROCESS(rst, clk, thr_w1, thr_w, tsr_e) 
 BEGIN 
  IF rst='0' THEN 
   thr_e <= '1'; 
  ELSIF RISING_EDGE(clk) THEN 
   IF thr_w1='0' AND thr_w='1' THEN 
    thr_e <= '0'; 
   ELSIF tsr_e='0' AND tsr_e0='1' THEN 
    thr_e <= '1'; 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- tsr_e 
 PROCESS(rst, clk, thr_e) 
 BEGIN 
  IF rst='0' THEN 
   tsr_e <= '1'; 
  ELSIF RISING_EDGE(clk) THEN 
--   IF tsr_e='1' AND thr_e='0' AND rsr_f='0' THEN 
   IF tsr_e='1' AND thr_e='0' THEN 
    tsr_e <= '0'; 
   ELSIF tscnt_z='1' AND tscnt_z0='0' THEN 
    tsr_e <= '1'; 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- tsr 
 PROCESS(clk, thr_e) 
 BEGIN 
  IF RISING_EDGE(clk) THEN 
--   IF tsr_e='1' AND thr_e='0' AND rsr_f='0' THEN 
   IF tsr_e='1' AND thr_e='0' THEN 
    tsr <= thr; 
   ELSIF tscnt(1)='1' AND tscnt(0)='0' THEN 
    tsr <= '0' & tsr(7 DOWNTO 1); 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- tdi 
 PROCESS(clk) 
 BEGIN 
  IF RISING_EDGE(clk) THEN 
   IF data_type='1' THEN 
    tdi_o <= tsr(0); 
   ELSE 
    tdi_o <= '0'; 
   END IF; 
  END IF; 
 END PROCESS; 
  
 -- tms 
 PROCESS(clk) 
 BEGIN 
  IF RISING_EDGE(clk) THEN 
   IF tscnt(5 DOWNTO 2)="0001" AND auto_tms='1' AND data_type='1' THEN 
    tms0 <= '1'; 
   ELSIF data_type='0' THEN 
    tms0 <= tsr(0); 
   END IF; 
  END IF; 
 END PROCESS; 
 tms_o <= tms0; 
 ntrst_o <= rst; 
  
 -- tscnt 
 PROCESS(rst, clk) 
 BEGIN 
  IF rst='0' THEN 
   tscnt_z <= '1'; 
   tscnt <= "000000"; 
  ELSIF RISING_EDGE(clk) THEN 
   IF tsr_e='0' AND tsr_e0='1' THEN 
    tscnt_z <= '0'; 
    tscnt <= thcnt & "00"; 
    auto_tms <= last_data; 
   ELSIF tscnt="000000" THEN 
    tscnt_z <= '1'; 
    auto_tms <= '0'; 
   ELSE 
    tscnt_z <= '0'; 
    tscnt <= tscnt-1; 
   END IF; 
  END IF; 
 END PROCESS; 
 tck_o <= tscnt(1); 
----------------------------------------------------- 
 
 -- rsr_f 
 PROCESS(rst, clk) 
 BEGIN 
  IF rst='0' THEN 
   rsr_f <= '0'; 
  ELSIF RISING_EDGE(clk) THEN 
   IF tscnt_z='1' AND tscnt_z0='0' THEN 
    rsr_f <= '1'; 
--   ELSIF rbr_f='1' AND rbr_f0='0' THEN 
   ELSIF (rbr_f='1' AND rbr_f0='0') OR (tsr_e='0' AND tsr_e0='1') THEN 
    rsr_f <= '0'; 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- rbr_f 
 PROCESS(rst, clk) 
 BEGIN 
  IF rst='0' THEN 
   rbr_f <= '0'; 
  ELSIF RISING_EDGE(clk) THEN 
   IF rbr_r1='1' AND rbr_r='0' THEN 
    rbr_f <= '0'; 
   ELSIF rsr_f='1' AND rbr_f='0' THEN 
    rbr_f <= '1'; 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- rsr 
 PROCESS(clk) 
 BEGIN 
  IF RISING_EDGE(clk) THEN 
   IF tscnt(1)='1' AND tscnt(0)='1' AND tscnt_z='0' THEN 
    rsr <= rsr(6 DOWNTO 0) & tdo_i; 
   END IF; 
  END IF; 
 END PROCESS; 
 
 -- rbr 
 PROCESS(clk) 
 BEGIN 
  IF RISING_EDGE(clk) THEN 
   IF rsr_f='1' AND rbr_f='0' THEN 
    rbr <= rsr; 
   END IF; 
  END IF; 
 END PROCESS; 
  
END main;