2 from nmigen
.hdl
.rec
import Direction
4 class Interface(Record
):
9 with_reset : bool, default=False
10 wether to include trst field; if this field is not present a JTAG master
11 should not rely on this pin for resetting a TAP.
13 def __init__(self
, *, with_reset
=False, name
=None, src_loc_at
=0):
15 ("tck", 1, Direction
.NONE
),
16 ("tms", 1, Direction
.NONE
),
17 ("tdo", 1, Direction
.FANOUT
),
18 ("tdi", 1, Direction
.FANIN
),
22 ("trst", 1, Direction
.FANOUT
)
24 super().__init
__(layout
, name
=name
, src_loc_at
=src_loc_at
+1)
27 class Chain(Elaboratable
):
28 """A chain of JTAG interfaces.
32 buses : iterable of :class:`Interface`, default=[]
33 Initial value of the buses in the chain.
34 with_reset : bool, default=False
35 Wether the generated bus has a reset pin. If value is True all buses in
36 the chain also have to have a reset signal
40 bus : :class:`Interface`
42 def __init__(self
, *, with_reset
=False, buses
=[], name
=None, src_loc_at
=0):
44 if not isinstance(bus
, Interface
):
45 raise ValueError("Object in buses that is not a JTAG Interface")
46 if with_reset
and not hasattr(bus
, "trst"):
47 raise ValueError("JTAG bus in buses without a reset signal")
50 "with_reset": with_reset
,
51 "src_loc_at": src_loc_at
+ 1,
54 kwargs
["name"] = name
+ "_bus"
55 self
.bus
= Interface(**kwargs
)
60 """Add a bus to the chain"""
62 if not isinstance(bus
, Interface
):
63 raise ValueError("bus in not a JTAG Interface")
64 if hasattr(self
.bus
, "trst") and not hasattr(bus
, "trst"):
65 raise ValueError("bus needs to have a reset signal")
66 self
._buses
.append(bus
)
68 def elaborate(self
, platform
):
69 with_reset
= hasattr(self
.bus
, "trst")
73 # Connect first and last
75 self
._buses
[0].tdi
.eq(self
.bus
.tdo
),
76 self
.bus
.tdi
.eq(self
._buses
[-1].tdo
),
78 for i
in range(len(self
._buses
)):
79 if i
< len(self
._buses
) - 1:
80 m
.d
.comb
+= self
._buses
[i
+1].tdi
.eq(self
._buses
[i
].tdo
)
82 m
.d
.comb
+= self
._buses
[i
].trst
.eq(self
.bus
.trst
)