?? tap.vhd
字號:
--
-- Copyright (C) 2003 by J. Kearney, Bolton, Massachusetts
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details.
--
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
library unisim;
use unisim.vcomponents.all;
entity TAP is
port
(reset : in std_logic;
clk96 : in std_logic;
clk64 : in std_logic;
clk_select : in unsigned(3 downto 0);
busy : out std_logic;
tristate : in boolean;
TCK_term : in std_logic_vector(1 downto 0);
TDO_term : in std_logic;
run_start : in std_logic;
run_ack : buffer std_logic;
run_freerun : in std_logic;
run_bits : in unsigned(11 downto 0);
run_TMS : in unsigned(11 downto 0);
run_TDI : in boolean;
run_TDO : in boolean;
run_pingTMS : in boolean;
wr_clk : out std_logic;
wr_addr : buffer unsigned(11 downto 0);
wr_store : out std_logic;
wr_data : out std_logic;
rd_clk : out std_logic;
rd_addr : buffer unsigned(11 downto 0);
rd_data : in std_logic;
TCK : out std_logic_vector(1 downto 0);
TCK_fb : in std_logic;
TDI : out std_logic_vector(1 downto 0);
TMS : out std_logic;
TDO : in std_logic);
end TAP;
architecture RTL of TAP is
component ClkMux is
Port ( RESET : in std_logic;
A : in std_logic;
B : in std_logic;
sel : in std_logic;
O : out std_logic);
end component;
component Sync is
Port ( RESET : in std_logic;
REQ : in std_logic;
ACK : in std_logic;
STATUS : buffer std_logic);
end component;
signal clk_base : std_logic;
signal clk_divider: unsigned(7 downto 0);
signal jtag_clk : std_logic;
type States is
(Idle, Handshake, Starting, Run, Stopping, Freerun);
signal state : States;
signal max : unsigned(run_bits'range);
signal tms_i : unsigned(run_TMS'length downto 0);
signal tdo_1, tdo_2, tdo_3 : std_logic;
signal running, tck_i, ack : std_logic;
signal clocking, writing, reading, pingTMS : boolean;
begin
--========================================================================
-- Synthesize the JTAG clock
-- first, select 96 or 64 MHz base
mux: ClkMux port map (RESET => reset, A => clk96, B => clk64, sel => clk_select(0), O => clk_base);
-- then divide it by 2, 4, .. 256
process (reset, clk_base)
begin
if reset = '1' then
clk_divider <= (others => '0');
elsif rising_edge(clk_base) then
clk_divider <= clk_divider + 1;
end if;
end process;
-- and select a tap from that
jtag_clk <= clk_divider(to_integer(clk_select(3 downto 1)));
--========================================================================
-- The actual TAP controller
busy <= '1' when state /= Idle else '0';
wr_clk <= TCK_fb;
wr_store <= '1' when clocking and writing else '0';
wr_data <= TDO;
rd_clk <= jtag_clk when reading else '0';
tdo_3 <= tdo_2 when clocking else '0';
TDI(1) <= 'Z' when tristate or (TDO_term = '0') else '0';
TDI(0) <= 'Z' when tristate else tdo_3;
tck_i <= '1' when (jtag_clk = '0') and clocking else '0';
TCK(0) <= 'Z' when tristate or (TCK_term(0) = '0') else tck_i;
TCK(1) <= 'Z' when tristate or (TCK_term(1) = '0') else tck_i;
TMS <= 'Z' when tristate else tms_i(0); -- tms comes from shift register
-- tdo is pipelined 2 cycles
process (reset, jtag_clk)
begin
if reset = '1' then
tdo_1 <= '0';
tdo_2 <= '0';
elsif rising_edge(jtag_clk) then -- falling edge of tck
tdo_2 <= tdo_1;
tdo_1 <= rd_data; -- latch tdo data
end if;
end process;
-- maintain read and write address:
-- init when not being used
-- increment on falling edge of clk to set up for rising edge read or write
process (running, jtag_clk)
begin
if running = '0' then
rd_addr <= to_unsigned(0, rd_addr'length);
rd_addr <= rd_addr + 1;
end if;
end process;
process (running, jtag_clk)
begin
if running = '0' then
wr_addr <= unsigned(to_signed(-2, wr_addr'length));
elsif rising_edge(jtag_clk) then
wr_addr <= wr_addr + 1;
end if;
end process;
shaker: Sync port map
(RESET => reset,
REQ => run_start,
ACK => not ack,
STATUS => run_ack);
process (reset, jtag_clk, run_start)
begin
if reset = '1' then
state <= Idle;
tms_i(0) <= '0';
writing <= false;
reading <= false;
clocking <= false;
running <= '0';
ack <= '0';
elsif rising_edge(jtag_clk) then
case state is
when Idle => -- wait for start signal
if run_start = '1' then
max <= run_bits; -- latch vector size
tms_i <= run_TMS & "0";-- latch tms data
writing <= run_tdi;
reading <= run_tdo;
pingTMS <= run_pingTMS;
state <= Handshake;
ack <= '1';
elsif run_freerun = '1' then
writing <= false;
reading <= false;
clocking <= true;
state <= Freerun;
ack <= '1';
end if;
when Freerun =>
ack <= '0';
if run_freerun = '0' then
state <= Idle;
clocking <= false;
end if;
when Handshake =>
ack <= '0';
running <= '1';
state <= Starting;
when Starting =>
state <= Run;
when Run =>
if max = 0 then -- done?
state <= Stopping;
clocking <= false;
tms_i(0) <= '0';
elsif pingTMS and (max = 1) then
tms_i(0) <= '1';
clocking <= true;
max <= max - 1;
else
clocking <= true;
max <= max - 1;
for idx in tms_i'right to tms_i'left-1 loop
tms_i(idx) <= tms_i(idx + 1);
end loop;
end if;
when Stopping =>
running <= '0';
state <= Idle;
end case;
end if;
end process;
end RTL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -