2 from cocotb
.clock
import Clock
3 from cocotb
.triggers
import Timer
4 from cocotb
.utils
import get_sim_steps
5 from cocotb
.binary
import BinaryValue
7 from c4m
.cocotb
.jtag
.c4m_jtag
import JTAG_Master
8 from c4m
.cocotb
.jtag
.c4m_jtag_svfcocotb
import SVF_Executor
10 from itertools
import chain
13 from cocotb
.clock
import Clock
14 from cocotb
.triggers
import Timer
15 from cocotb
.utils
import get_sim_steps
16 from cocotb
.binary
import BinaryValue
18 from c4m
.nmigen
.jtag
.tap
import IOType
19 from c4m
.cocotb
.jtag
.c4m_jtag
import JTAG_Master
20 from c4m
.cocotb
.jtag
.c4m_jtag_svfcocotb
import SVF_Executor
22 from itertools
import chain
24 from c4m
.nmigen
.jtag
.tap
import IOType
31 def __init__(self
, dut
):
33 ti
= dut
.instance_corona
.core
.subckt_22_jtag
36 self
.sys_clk
= dut
.sys_clk
37 self
.sys_rst
= dut
.sys_rst
38 self
.jtag_tck
= dut
.jtag_tck
39 self
.jtag_tms
= dut
.jtag_tms
40 self
.jtag_tdi
= dut
.jtag_tdi
41 self
.jtag_tdo
= dut
.jtag_tdo
44 self
.iovdd
= dut
.iovdd
45 self
.iovss
= dut
.iovss
47 def info(self
, *args
, **kwargs
):
48 return self
.dut
._log
.info(*args
, **kwargs
)
51 def setup_sim(dut
, *, info
, clk_period
, run
):
52 """Initialize CPU and setup clock"""
54 wrap
= DUTWrapper(dut
)
57 clk_steps
= get_sim_steps(clk_period
, "ns")
58 cocotb
.fork(Clock(wrap
.sys_clk
, clk_steps
).start())
66 # adder test (ignore this)
71 yield Timer(int(10.5*clk_steps
))
73 yield Timer(int(5*clk_steps
))
77 def setup_jtag(dut
, *, tck_period
):
78 # Make this a generator
81 clk_steps
= get_sim_steps(tck_period
, "ns")
82 return JTAG_Master(dut
.jtag_tck
, dut
.jtag_tms
,
83 dut
.jtag_tdi
, dut
.jtag_tdo
,
88 # demo / debug how to get boundary scan names. run "python3 test.py"
89 if __name__
== '__main__':
90 pinouts
= get_jtag_boundary()
92 # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)
101 def __init__(self
, pin
):
110 if self
.type_
== IOType
.In
:
111 core_i
= getattr(wrap
.ti
, f
"{self.name}_core_i").value
112 pad_i
= getattr(wrap
.ti
, f
"{self.name}_pad_i").value
113 wrap
.info(f
"{self.name}: core.i={core_i}, pad.i={pad_i}")
114 elif self
.type_
== IOType
.Out
:
115 core_o
= getattr(wrap
.ti
, f
"{self.name}_core_o").value
116 pad_o
= getattr(wrap
.ti
, f
"{self.name}_pad_o").value
117 wrap
.info(f
"{self.name}: core.o={core_o}, pad.o={pad_o}")
118 elif self
.type_
== IOType
.TriOut
:
119 core_o
= getattr(wrap
.ti
, f
"{self.name}_core_o").value
120 core_oe
= getattr(wrap
.ti
, f
"{self.name}_core_oe").value
121 pad_o
= getattr(wrap
.ti
, f
"{self.name}_pad_o").value
122 pad_oe
= getattr(wrap
.ti
, f
"{self.name}_pad_oe").value
123 wrap
.info(f
"{self.name}: core.(o={core_o}, oe={core_oe}), " \
124 "pad.(o={pad_o}, oe={pad_oe})")
125 elif self
.type_
== IOType
.InTriOut
:
126 core_i
= getattr(wrap
.ti
, f
"{self.name}_core_i").value
127 core_o
= getattr(wrap
.ti
, f
"{self.name}_core_o").value
128 core_oe
= getattr(wrap
.ti
, f
"{self.name}_core_oe").value
129 pad_i
= getattr(wrap
.ti
, f
"{self.name}_pad_i").value
130 pad_o
= getattr(wrap
.ti
, f
"{self.name}_pad_o").value
131 pad_oe
= getattr(wrap
.ti
, f
"{self.name}_pad_oe").value
132 wrap
.info(f
"{self.name}: core.(i={core_i}, o={core_o}, " \
133 "oe={core_oe}), pad.(i={core_i}, o={pad_o}, " \
136 raise ValueError(f
"Unsupported pin type {self.type_}")
138 def data(self
, *, i
=None, o
=None, oe
=None):
139 if self
.type_
== IOType
.In
:
142 elif self
.type_
== IOType
.Out
:
145 elif self
.type_
== IOType
.TriOut
:
146 assert (o
is not None) and (oe
is not None)
148 elif self
.type_
== IOType
.InTriOut
:
149 assert (i
is not None) and(o
is not None) and (oe
is not None)
152 raise ValueError(f
"Unsupported pin type {self.type_}")
154 def check(self
, *, wrap
, i
=None, o
=None, oe
=None):
155 if self
.type_
in (IOType
.In
, IOType
.InTriOut
):
156 sig
= f
"{self.name}_core_i"
157 val
= getattr(wrap
.ti
, sig
).value
159 raise ValueError(f
"'{sig}' should be {i}, not {val}")
160 if self
.type_
in (IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
):
161 sig
= f
"{self.name}_pad_o"
162 val
= getattr(wrap
.ti
, sig
).value
164 raise ValueError(f
"'{sig}' should be {o}, not {val}")
165 if self
.type_
in (IOType
.TriOut
, IOType
.InTriOut
):
166 sig
= f
"{self.name}_pad_oe"
167 val
= getattr(wrap
.ti
, sig
).value
169 raise ValueError(f
"'{sig}' should be {oe}, not {val}")
172 def log_pins(wrap
, pins
):
177 def get_jtag_boundary():
178 """gets the list of information for jtag boundary scan
181 for pname
in ["a_0", "a_1", "a_2", "a_3",
182 "b_0", "b_1", "b_2", "b_3",
183 "f_0", "f_1", "f_2", "f_3"]:
184 if pname
.startswith('f'):
188 pin
= (None, None, ptype
, pname
)
189 pins
.append(JTAGPin(pin
))
197 def boundary_scan(wrap
, *, jtag
):
198 pins
= get_jtag_boundary()
203 wrap
.info("Before scan")
206 yield jtag
.load_ir([0, 0, 0, 0])
207 pinsdata
= tuple(pin
.data(i
=i
%2, o
=((i
%3)%2), oe
=((i
%5)%2))
208 for i
, pin
in enumerate(pins
))
209 yield jtag
.shift_data(chain(*pinsdata
))
212 wrap
.info("After scan")
214 for i
, pin
in enumerate(pins
):
215 pin
.check(wrap
=wrap
, i
=i
%2, o
=((i
%3)%2), oe
=((i
%5)%2))
220 wrap
.info("After reset")
225 def boundary_scan_reset(dut
):
226 clk_period
= 100 # 10MHz
227 tck_period
= 300 # 3MHz
229 info
= "Running boundary scan test; cpu in reset..."
230 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
232 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
234 yield from boundary_scan(wrap
, jtag
=jtag
)
236 wrap
.info("IDCODE test completed")