2 from nmigen
.hdl
.rec
import Direction
5 class DMIInterface(Record
):
6 def __init__(self
, name
=None, addr_wid
=4, data_wid
=64):
8 ('addr_i', addr_wid
, Direction
.FANIN
), # DMI register address
9 ('din', data_wid
, Direction
.FANIN
), # DMI data write in (we=1)
10 ('dout', data_wid
, Direction
.FANOUT
), # DMI data read out (we=0)
11 ('req_i', 1, Direction
.FANIN
), # DMI request valid (stb)
12 ('we_i', 1, Direction
.FANIN
), # DMI write-enable
13 ('ack_o', 1, Direction
.FANOUT
), # DMI ack request
15 super().__init
__(name
=name
, layout
=layout
)
18 class Interface(Record
):
23 with_reset : bool, default=False
24 wether to include trst field; if this field is not present a JTAG master
25 should not rely on this pin for resetting a TAP.
27 def __init__(self
, *, with_reset
=False, name
=None, src_loc_at
=0):
29 ("tck", 1, Direction
.NONE
),
30 ("tms", 1, Direction
.NONE
),
31 ("tdo", 1, Direction
.FANOUT
),
32 ("tdi", 1, Direction
.FANIN
),
36 ("trst", 1, Direction
.FANOUT
)
38 super().__init
__(layout
, name
=name
, src_loc_at
=src_loc_at
+1)
41 class Chain(Elaboratable
):
42 """A chain of JTAG interfaces.
46 buses : iterable of :class:`Interface`, default=[]
47 Initial value of the buses in the chain.
48 with_reset : bool, default=False
49 Wether the generated bus has a reset pin. If value is True all buses in
50 the chain also have to have a reset signal
54 bus : :class:`Interface`
56 def __init__(self
, *, with_reset
=False, buses
=[], name
=None, src_loc_at
=0):
58 if not isinstance(bus
, Interface
):
59 raise ValueError("Object in buses that is not a JTAG Interface")
60 if with_reset
and not hasattr(bus
, "trst"):
61 raise ValueError("JTAG bus in buses without a reset signal")
64 "with_reset": with_reset
,
65 "src_loc_at": src_loc_at
+ 1,
68 kwargs
["name"] = name
+ "_bus"
69 self
.bus
= Interface(**kwargs
)
74 """Add a bus to the chain"""
76 if not isinstance(bus
, Interface
):
77 raise ValueError("bus in not a JTAG Interface")
78 if hasattr(self
.bus
, "trst") and not hasattr(bus
, "trst"):
79 raise ValueError("bus needs to have a reset signal")
80 self
._buses
.append(bus
)
82 def elaborate(self
, platform
):
83 with_reset
= hasattr(self
.bus
, "trst")
87 # Connect first and last
89 self
._buses
[0].tdi
.eq(self
.bus
.tdo
),
90 self
.bus
.tdi
.eq(self
._buses
[-1].tdo
),
92 for i
in range(len(self
._buses
)):
93 if i
< len(self
._buses
) - 1:
94 m
.d
.comb
+= self
._buses
[i
+1].tdi
.eq(self
._buses
[i
].tdo
)
96 m
.d
.comb
+= self
._buses
[i
].trst
.eq(self
.bus
.trst
)