Don't use tri-state logic for TDO; introduce TDO_EN signal to indicate when TDO is...
[c4m-jtag.git] / rtl / vhdl / c4m_jtag_iocell.vhdl
1 -- An JTAG boundary scan for bidirectional I/O
2
3 library ieee;
4 use ieee.std_logic_1164.ALL;
5
6 use work.c4m_jtag.ALL;
7
8 entity c4m_jtag_iocell is
9 generic (
10 IR_WIDTH: integer := 2
11 );
12 port (
13 -- core connections
14 CORE_IN: out std_logic;
15 CORE_OUT: in std_logic;
16 CORE_EN: in std_logic;
17
18 -- pad connections
19 PAD_IN: in std_logic;
20 PAD_OUT: out std_logic;
21 PAD_EN: out std_logic;
22
23 -- BD shift register
24 BDSR_IN: in std_logic;
25 BDSR_OUT: out std_logic;
26
27 -- Mode of I/O cell
28 IOMODE: in SRIOMODE_TYPE;
29 SAMPLEMODE: in SRSAMPLEMODE_TYPE;
30 TCK: in std_logic
31 );
32 end c4m_jtag_iocell;
33
34 architecture rtl of c4m_jtag_iocell is
35 signal SR_IOIN: std_logic;
36 signal SR_IOOUT: std_logic;
37 signal SR_IOEN: std_logic;
38
39 signal CORE_IN_BD: std_logic;
40 signal PAD_OUT_BD: std_logic;
41 signal PAD_EN_BD: std_logic;
42 begin
43 with IOMODE select
44 CORE_IN <=
45 PAD_IN when SR_Through | SR_Z,
46 PAD_IN when SR_2Pad,
47 CORE_IN_BD when SR_2Core,
48 'X' when others;
49
50 with IOMODE select
51 PAD_OUT <=
52 CORE_OUT when SR_Through,
53 PAD_OUT_BD when SR_2Pad,
54 '0' when SR_2Core | SR_Z,
55 'X' when others;
56
57 with IOMODE select
58 PAD_EN <=
59 CORE_EN when SR_Through,
60 PAD_EN_BD when SR_2Pad,
61 '0' when SR_2Core | SR_Z,
62 'X' when others;
63
64 process (TCK)
65 begin
66 -- Sampling of inputs and shifting of boundary scan SR needs to be done on
67 -- rising edge of TCK
68 if rising_edge(TCK) then
69 case SAMPLEMODE is
70 when SR_Sample =>
71 SR_IOIN <= PAD_IN;
72 SR_IOOUT <= CORE_OUT;
73 SR_IOEN <= CORE_EN;
74
75 when SR_Shift =>
76 SR_IOIN <= BDSR_IN;
77 SR_IOOUT <= SR_IOIN;
78 SR_IOEN <= SR_IOOUT;
79
80 when others =>
81 null;
82 end case;
83 end if;
84
85 -- Update of output from boundary scan SR needs to be done on falling edge
86 -- of TCK
87 if falling_edge(TCK) then
88 case SAMPLEMODE is
89 when SR_Update =>
90 CORE_IN_BD <= SR_IOIN;
91 PAD_OUT_BD <= SR_IOOUT;
92 PAD_EN_BD <= SR_IOEN;
93
94 when others =>
95 null;
96 end case;
97 end if;
98 end process;
99
100 BDSR_OUT <= SR_IOEN;
101 end rtl;