from soc.debug.dmi import DMIInterface, DBGCore
from soc.debug.test.dmi_sim import dmi_sim
from soc.debug.test.jtagremote import JTAGServer, JTAGClient
+from nmigen.build.res import ResourceError
# Was thinking of using these functions, but skipped for simplicity for now
# XXX nope. the output from JSON file.
gpios.append("%d*" % i)
return {'uart': ['tx+', 'rx-'],
'gpio': gpios,
+ #'jtag': ['tms-', 'tdi-', 'tdo+', 'tck+'],
'i2c': ['sda*', 'scl+']}
"""
return resources
+def JTAGResource(*args):
+ io = []
+ io.append(Subsignal("tms", Pins("tms", dir="i", assert_width=1)))
+ io.append(Subsignal("tdi", Pins("tdi", dir="i", assert_width=1)))
+ io.append(Subsignal("tck", Pins("tck", dir="i", assert_width=1)))
+ io.append(Subsignal("tdo", Pins("tdo", dir="o", assert_width=1)))
+ return Resource.family(*args, default_name="jtag", ios=io)
+
def UARTResource(*args, rx, tx):
io = []
io.append(Subsignal("rx", Pins(rx, dir="i", assert_width=1)))
class Blinker(Elaboratable):
def __init__(self, pinset):
self.jtag = JTAG({}, "sync")
+ memory = Memory(width=32, depth=16)
+ self.sram = SRAM(memory=memory, bus=self.jtag.wb)
def elaborate(self, platform):
m = Module()
m.submodules.jtag = self.jtag
+ m.submodules.sram = self.sram
+
count = Signal(5)
m.d.sync += count.eq(5)
print ("resources", platform.resources.items())
intermediary = Signal()
m.d.comb += uart.tx.eq(intermediary)
m.d.comb += intermediary.eq(uart.rx)
+
+ # wire up JTAG otherwise we are in trouble (no clock)
+ jtag = platform.request('jtag')
+ m.d.comb += self.jtag.bus.tdi.eq(jtag.tdi)
+ m.d.comb += self.jtag.bus.tck.eq(jtag.tck)
+ m.d.comb += self.jtag.bus.tms.eq(jtag.tms)
+ m.d.comb += jtag.tdo.eq(self.jtag.bus.tdo)
+
return m
connectors = []
resources = OrderedDict()
required_tools = []
- command_templates = ['/bin/true']
+ command_templates = ['/bin/true'] # no command needed: stops barfing
file_templates = {
**TemplatedPlatform.build_script_templates,
"{{name}}.il": r"""
self.pad_mgr = ResourceManager([], [])
self.jtag = jtag
super().__init__()
+
# create set of pin resources based on the pinset, this is for the core
self.add_resources(resources)
# record resource lookup between core IO names and pads
self.padlookup = {}
+ # add JTAG without scan
+ self.add_resources([JTAGResource('jtag', 0)], no_boundary_scan=True)
+
def request(self, name, number=0, *, dir=None, xdr=None):
"""request a Resource (e.g. name="uart", number=0) which will
return a data structure containing Records of all the pins.
pad_start_ports = len(self.pad_mgr._ports)
try:
pvalue = self.pad_mgr.request(name, number, dir=dir, xdr=xdr)
- except AssertionError:
+ except ResourceError:
return value
pad_end_ports = len(self.pad_mgr._ports)
print("No JTAG chain in-between")
m.d.comb += pin.i.eq(self._invert_if(invert, port))
return m
+ if pin.name not in self.padlookup:
+ print("No pin named %s, not connecting to JTAG BS" % pin.name)
+ m.d.comb += pin.i.eq(self._invert_if(invert, port))
+ return m
(padres, padpin, padport, padattrs) = self.padlookup[pin.name]
io = self.jtag.ios[pin.name]
print (" pad", padres, padpin, padport, attrs)
print("No JTAG chain in-between")
m.d.comb += port.eq(self._invert_if(invert, pin.o))
return m
+ if pin.name not in self.padlookup:
+ print("No pin named %s, not connecting to JTAG BS" % pin.name)
+ m.d.comb += port.eq(self._invert_if(invert, pin.o))
+ return m
(padres, padpin, padport, padattrs) = self.padlookup[pin.name]
io = self.jtag.ios[pin.name]
print (" pad", padres, padpin, padport, padattrs)
def get_input_output(self, pin, port, attrs, invert):
self._check_feature("single-ended input/output", pin, attrs,
valid_xdrs=(0,), valid_attrs=None)
-
+
print (" get_input_output", pin, "port", port, port.layout)
- m = Module()
+ m = Module()
if pin.name in ['clk_0', 'rst_0']: # sigh
print("No JTAG chain in-between")
m.submodules += Instance("$tribuf",
port_i = port.io[0]
port_o = port.io[1]
port_oe = port.io[2]
-
+
padport_i = padport.io[0]
padport_o = padport.io[1]
padport_oe = padport.io[2]
m.d.comb += pin.i.eq(port_i)
m.d.comb += port_o.eq(pin.o)
m.d.comb += port_oe.eq(pin.oe)
- # Connect SoC port to JTAG io.core side
+ # Connect SoC port to JTAG io.core side
m.d.comb += port_i.eq(io.core.i)
m.d.comb += io.core.o.eq(port_o)
m.d.comb += io.core.oe.eq(port_oe)
self.fragment = fragment
return super().toolchain_prepare(fragment, name, **kwargs)
-
"""
and to create a Platform instance with that list, and build
something random
"""
pinset = dummy_pinset()
top = Blinker(pinset)
-print(pinset)
-resources = create_resources(pinset)
-p = ASICPlatform (resources, top.jtag)
-p.build(top)
-# this is what needs to gets treated as "top", after "main module" top
-# is augmented with IO pads with JTAG tacked on. the expectation that
-# the get_input() etc functions will be called magically by some other
-# function is unrealistic.
-top_fragment = p.fragment
+
# XXX these modules are all being added *AFTER* the build process links
# everything together. the expectation that this would work is... unrealistic.
cdut._ir_width = top.jtag._ir_width
cdut.scan_len = top.jtag.scan_len
-memory = Memory(width=64, depth=16)
-sram = SRAM(memory=memory, bus=top.jtag.wb)
-
-#m = Module()
-#m.submodules.ast = dut
-#m.submodules.sram = sram
+print(pinset)
+resources = create_resources(pinset)
+p = ASICPlatform (resources, top.jtag)
+p.build(top)
+# this is what needs to gets treated as "top", after "main module" top
+# is augmented with IO pads with JTAG tacked on. the expectation that
+# the get_input() etc functions will be called magically by some other
+# function is unrealistic.
+top_fragment = p.fragment
# XXX simulating top (the module that does not itself contain IO pads
# because that's covered by build) cannot possibly be expected to work
# particularly when modules have been added *after* the platform build()
# function has been called.
-sim = Simulator(top)
+sim = Simulator(top_fragment)
sim.add_clock(1e-6, domain="sync") # standard clock
sim.add_sync_process(wrap(jtag_srv(top))) #? jtag server