RAVEN VHDL CODE
Device: Altera EPM3064
--------------------------------------------------------------------
-- RAVEN: ARM JTAG ICE
--------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RAVEN IS
PORT(
--------------------------------------------------
-- LPT Data Port, Data Input --
LPT_Data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
-- LPT Control Port C3-C2-C0, --
LPT_Ctl : IN STD_LOGIC_VECTOR (2 DOWNTO 0);
-- LPT Control Port C1, Data Write pulse --
LPT_C1 : IN STD_LOGIC;
-- LPT State Port S6..S3, Data Output --
LPT_In : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
-- LPT Busy, High = Busy, Low = Ready --
LPT_Busy : OUT STD_LOGIC;
--------------------------------------------------
clk : IN STD_LOGIC; -- 主时钟频率为TCK时钟的两倍
-- JTAG PORT --
tTDO : IN STD_LOGIC;
nTRST : OUT STD_LOGIC;
nSRST : OUT STD_LOGIC;
tTMS : OUT STD_LOGIC;
tTDI : OUT STD_LOGIC;
tTCK : OUT STD_LOGIC);
END RAVEN;
ARCHITECTURE a OF RAVEN IS
SIGNAL d, pq : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL cmd : INTEGER RANGE 0 TO 7;
SIGNAL len : INTEGER RANGE 0 TO 7;
SIGNAL len_cnt : INTEGER RANGE 0 TO 7;
SIGNAL tck_num : INTEGER RANGE 0 TO 7;
SIGNAL tck_cnt : INTEGER RANGE 0 TO 7;
SIGNAL lpt_req : STD_LOGIC;
SIGNAL stck : STD_LOGIC;
SIGNAL stdo : STD_LOGIC;
SIGNAL start : STD_LOGIC;
SIGNAL shift_en : STD_LOGIC;
SIGNAL shift_mod : STD_LOGIC;
SIGNAL shift_end : STD_LOGIC;
SIGNAL s3, s4, s5 : STD_LOGIC;
SIGNAL TRST, SRST : STD_LOGIC;
SIGNAL shift_req : STD_LOGIC;
SIGNAL cnt_load_req : STD_LOGIC;
SIGNAL TCK_pedge : STD_LOGIC;
SIGNAL TCK_nedge : STD_LOGIC;
BEGIN
shift_req <= '1' WHEN lpt_req = '1' AND (cmd = 4 OR cmd = 6) ELSE
'0';
cnt_load_req <= '1' WHEN lpt_req = '1' AND (cmd = 4 OR cmd = 7) ELSE
'0';
len <= CONV_INTEGER(d) / 8 WHEN cmd = 7 ELSE
6;
cmd <= CONV_INTEGER(LPT_Ctl);
-- lpt_req --
PROCESS (clk)
VARIABLE x, y : STD_LOGIC;
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF (NOT x AND y) = '1' THEN
lpt_req <= '1';
d <= LPT_Data;
ELSE lpt_req <= '0';
END IF;
y := x;
x := lpt_c1;
END IF;
END PROCESS;
-- start, shift_mod, config: tck_num --
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF lpt_req = '1' AND (cmd = 4 OR cmd = 6) THEN
start <= '1';
ELSE start <= '0';
END IF;
IF lpt_req = '1' AND cmd = 6 THEN
shift_mod <= '1';
ELSIF lpt_req = '1' AND cmd = 4 THEN
shift_mod <= '0';
END IF;
IF lpt_req = '1' AND cmd = 7 THEN
tck_num <= CONV_INTEGER(d);
END IF;
END IF;
END PROCESS;
-- shift_en --
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '0' THEN
IF start = '1' THEN
shift_en <= '1';
ELSIF shift_end = '1' THEN
shift_en <= '0';
END IF;
END IF;
END PROCESS;
-- config: len --
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF cnt_load_req = '1' THEN
len_cnt <= len;
ELSIF TCK_nedge = '1' THEN
len_cnt <= len_cnt - 1;
END IF;
END IF;
END PROCESS;
-- shift_end --
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF shift_req = '1' THEN
shift_end <= '0';
ELSIF TCK_nedge = '1' AND len_cnt = 0 THEN
shift_end <= '1';
END IF;
END IF;
END PROCESS;
-- TCK --
PROCESS (clk)
VARIABLE a : STD_LOGIC;
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF shift_en = '1' THEN
IF TCK_pedge = '1' THEN
a := '1';
ELSIF TCK_nedge = '1' THEN
a := '0';
END IF;
IF tck_cnt = tck_num THEN
tck_cnt <= 0;
IF a = '1' THEN
TCK_pedge <= '0';
TCK_nedge <= '1';
ELSE
TCK_pedge <= '1';
TCK_nedge <= '0';
END IF;
ELSE
tck_cnt <= tck_cnt + 1;
TCK_pedge <= '0';
TCK_nedge <= '0';
END IF;
IF a = '1' THEN
stck <= '1';
ELSE
stck <= '0';
END IF;
ELSE
TCK_pedge <= '0';
TCK_nedge <= '0';
END IF;
END IF;
END PROCESS;
-- s4, s5 --
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF lpt_req = '1' AND cmd = 4 THEN
s4 <= tTDO;
END IF;
IF lpt_req = '1' AND (cmd = 6 OR cmd = 7) THEN
s5 <= NOT s5;
END IF;
END IF;
END PROCESS;
-- TDI/TMS shift reg --
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF shift_req = '1' THEN
pq <= d;
END IF;
IF TCK_nedge = '1' THEN
FOR i IN 0 TO 6 LOOP
pq(i) <= pq(i+1);
END LOOP;
pq(7) <= tTDO;
END IF;
END IF;
END PROCESS;
-- LPT Output ----------------------------------------------------
LPT_Busy <= shift_en OR NOT LPT_C1;
LPT_In <= pq(7 DOWNTO 4) WHEN cmd = 0 ELSE
pq(3 DOWNTO 0) WHEN cmd = 2 ELSE
"0000" WHEN cmd = 1 ELSE
"0000" WHEN cmd = 3 ELSE
shift_en & s5 & s4 & s3;
s3 <= 'X';
-- JTAG Output ---------------------------------------------------
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF cmd = 5 AND LPT_C1 = '0' AND d(7) = '1' THEN
TRST <= '1';
ELSE TRST <= '0';
END IF;
END IF;
END PROCESS;
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF cmd = 5 AND LPT_C1 = '0' AND d(0) = '1' THEN
SRST <= '1';
ELSE SRST <= '0';
END IF;
END IF;
END PROCESS;
nTRST <= '0' WHEN TRST = '1' ELSE -- nTRST可为OC输出或推拉输出
'Z';
nSRST <= '0' WHEN SRST = '1' ELSE -- nSRST应为OC输出
'Z';
tTDI <= pq(0) WHEN shift_mod = '1' ELSE
pq(7);
tTMS <= pq(0) WHEN shift_mod = '0' ELSE
'0';
tTCK <= stck;
------------------------------------------------------------------
END a;