⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jtag.vhd

📁 JTAG CPLD实现源代码
💻 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -