From: Luke Kenneth Casson Leighton Date: Fri, 9 Oct 2020 13:16:20 +0000 (+0100) Subject: use libresoc version of c4m-jtag repo X-Git-Tag: 24jan2021_ls180~169 X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=commitdiff_plain;h=a7056a9213412d9da7074155781791c0c8146f5b use libresoc version of c4m-jtag repo --- diff --git a/src/soc/debug/dmi2jtag.py b/src/soc/debug/dmi2jtag.py index 048c9bf7..7f464d93 100644 --- a/src/soc/debug/dmi2jtag.py +++ b/src/soc/debug/dmi2jtag.py @@ -6,7 +6,6 @@ based on Staf Verhaegen (Chips4Makers) wishbone TAP from nmigen import (Module, Signal, Elaboratable, Const) from nmigen.cli import rtlil from c4m.nmigen.jtag.tap import TAP, IOType -from soc.debug.dmi import DMIInterface, DBGCore from nmigen_soc.wishbone.sram import SRAM from nmigen import Memory, Signal, Module @@ -35,201 +34,6 @@ from nmigen_soc.wishbone import Interface as WishboneInterface class DMITAP(TAP): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._dmis = [] - - def elaborate(self, platform): - m = super().elaborate(platform) - self._elaborate_dmis(m) - return m - - # XXX have to over-ride add_wishbone here due to unneeded features - # being added - def add_wishbone(self, *, ircodes, address_width, data_width, - granularity=None, domain="sync", - name=None, src_loc_at=0): - """Add a wishbone interface - - In order to allow high JTAG clock speed, data will be cached. This - means that if data is output the value of the next address will - be read automatically. - - Parameters: - ----------- - ircodes: sequence of three integer for the JTAG IR codes; - they represent resp. WBADDR, WBREAD and WBREADWRITE. First code - has a shift register of length 'address_width', the two other codes - share a shift register of length data_width. - address_width: width of the address - data_width: width of the data - - Returns: - wb: nmigen_soc.wishbone.bus.Interface - The Wishbone interface, is pipelined and has stall field. - """ - if len(ircodes) != 3: - raise ValueError("3 IR Codes have to be provided") - - if name is None: - name = "wb" + str(len(self._wbs)) - sr_addr = self.add_shiftreg( - ircode=ircodes[0], length=address_width, domain=domain, - name=name+"_addrsr" - ) - sr_data = self.add_shiftreg( - ircode=ircodes[1:], length=data_width, domain=domain, - name=name+"_datasr" - ) - - wb = WishboneInterface(data_width=data_width, addr_width=address_width, - granularity=granularity, - #features={"stall", "lock", "err", "rty"}, - features={"err"}, - name=name, src_loc_at=src_loc_at+1) - - self._wbs.append((sr_addr, sr_data, wb, domain)) - - return wb - - - def add_dmi(self, *, ircodes, address_width=8, data_width=64, - domain="sync", name=None): - """Add a DMI interface - - * writing to DMIADDR will automatically trigger a DMI READ. - the DMI address does not alter (so writes can be done at that addr) - * reading from DMIREAD triggers a DMI READ at the current DMI addr - the address is automatically incremented by 1 after. - * writing to DMIWRITE triggers a DMI WRITE at the current DMI addr - the address is automatically incremented by 1 after. - - Parameters: - ----------- - ircodes: sequence of three integer for the JTAG IR codes; - they represent resp. DMIADDR, DMIREAD and DMIWRITE. - First code has a shift register of length 'address_width', - the two other codes share a shift register of length - data_width. - - address_width: width of the address - data_width: width of the data - - Returns: - dmi: soc.debug.dmi.DMIInterface - The DMI interface - """ - if len(ircodes) != 3: - raise ValueError("3 IR Codes have to be provided") - - if name is None: - name = "dmi" + str(len(self._dmis)) - - # add 2 shift registers: one for addr, one for data. - sr_addr = self.add_shiftreg(ircode=ircodes[0], length=address_width, - domain=domain, name=name+"_addrsr") - sr_data = self.add_shiftreg(ircode=ircodes[1:], length=data_width, - domain=domain, name=name+"_datasr") - - dmi = DMIInterface(name=name) - self._dmis.append((sr_addr, sr_data, dmi, domain)) - - return dmi - - def _elaborate_dmis(self, m): - for sr_addr, sr_data, dmi, domain in self._dmis: - cd = m.d[domain] - m.d.comb += sr_addr.i.eq(dmi.addr_i) - - with m.FSM(domain=domain) as ds: - - # detect mode based on whether jtag addr or data read/written - with m.State("IDLE"): - with m.If(sr_addr.oe): # DMIADDR code - cd += dmi.addr_i.eq(sr_addr.o) - m.next = "READ" - with m.Elif(sr_data.oe[0]): # DMIREAD code - # If data is - cd += dmi.addr_i.eq(dmi.addr_i + 1) - m.next = "READ" - with m.Elif(sr_data.oe[1]): # DMIWRITE code - cd += dmi.din.eq(sr_data.o) - m.next = "WRRD" - - # req_i raises for 1 clock - with m.State("READ"): - m.next = "READACK" - - # wait for read ack - with m.State("READACK"): - with m.If(dmi.ack_o): - # Store read data in sr_data.i hold till next read - cd += sr_data.i.eq(dmi.dout) - m.next = "IDLE" - - # req_i raises for 1 clock - with m.State("WRRD"): - m.next = "WRRDACK" - - # wait for write ack - with m.State("WRRDACK"): - with m.If(dmi.ack_o): - cd += dmi.addr_i.eq(dmi.addr_i + 1) - m.next = "READ" # for readwrite - - # set DMI req and write-enable based on ongoing FSM states - m.d.comb += [ - dmi.req_i.eq(ds.ongoing("READ") | ds.ongoing("WRRD")), - dmi.we_i.eq(ds.ongoing("WRRD")), - ] - - def _elaborate_wishbones(self, m): - for sr_addr, sr_data, wb, domain in self._wbs: - m.d.comb += sr_addr.i.eq(wb.adr) - - if hasattr(wb, "sel"): - # Always selected - m.d.comb += [s.eq(1) for s in wb.sel] - - with m.FSM(domain=domain) as fsm: - with m.State("IDLE"): - with m.If(sr_addr.oe): # WBADDR code - m.d[domain] += wb.adr.eq(sr_addr.o) - m.next = "READ" - with m.Elif(sr_data.oe[0]): # WBREAD code - # If data is - m.d[domain] += wb.adr.eq(wb.adr + 1) - m.next = "READ" - with m.Elif(sr_data.oe[1]): # WBWRITE code - m.d[domain] += wb.dat_w.eq(sr_data.o) - m.next = "WRITEREAD" - with m.State("READ"): - if not hasattr(wb, "stall"): - m.next = "READACK" - else: - with m.If(~wb.stall): - m.next = "READACK" - with m.State("READACK"): - with m.If(wb.ack): - # Store read data in sr_data.i and keep it there til next read - m.d[domain] += sr_data.i.eq(wb.dat_r) - m.next = "IDLE" - with m.State("WRITEREAD"): - if not hasattr(wb, "stall"): - m.next = "WRITEREADACK" - else: - with m.If(~wb.stall): - m.next = "WRITEREADACK" - with m.State("WRITEREADACK"): - with m.If(wb.ack): - m.d[domain] += wb.adr.eq(wb.adr + 1) - m.next = "READ" - - m.d.comb += [ - wb.cyc.eq(~fsm.ongoing("IDLE")), - wb.stb.eq(fsm.ongoing("READ") | fsm.ongoing("WRITEREAD")), - wb.we.eq(fsm.ongoing("WRITEREAD")), - ] def external_ports(self): return [self.bus.tdo, self.bus.tdi, self.bus.tms, self.bus.tck] @@ -242,7 +46,7 @@ if __name__ == '__main__': dut.sr = dut.add_shiftreg(ircode=4, length=3) # test loopback register # create and connect wishbone SRAM (a quick way to do WB test) - dut.wb = dut.add_wishbone(ircodes=[5, 6, 7], + dut.wb = dut.add_wishbone(ircodes=[5, 6, 7], features={'err'}, address_width=16, data_width=16) # create DMI2JTAG (goes through to dmi_sim()) diff --git a/src/soc/debug/jtag.py b/src/soc/debug/jtag.py index 03f69768..74d50136 100644 --- a/src/soc/debug/jtag.py +++ b/src/soc/debug/jtag.py @@ -80,7 +80,7 @@ class JTAG(DMITAP, Pins): self.sr = self.add_shiftreg(ircode=4, length=3) # create and connect wishbone - self.wb = self.add_wishbone(ircodes=[5, 6, 7], + self.wb = self.add_wishbone(ircodes=[5, 6, 7], features={'err'}, address_width=29, data_width=wb_data_wid, name="jtag_wb") diff --git a/src/soc/debug/test/test_jtag_tap.py b/src/soc/debug/test/test_jtag_tap.py index 8c88271b..6cc7e14c 100644 --- a/src/soc/debug/test/test_jtag_tap.py +++ b/src/soc/debug/test/test_jtag_tap.py @@ -155,6 +155,7 @@ if __name__ == '__main__': # create and connect wishbone SRAM (a quick way to do WB test) dut.wb = dut.add_wishbone(ircodes=[WB_ADDR, WB_READ, WB_WRRD], + features={'err'}, address_width=16, data_width=16) memory = Memory(width=16, depth=16) sram = SRAM(memory=memory, bus=dut.wb)