Simplify signal generation for TAP wishbone interfaces.
[c4m-jtag.git] / c4m / nmigen / jtag / tap.py
index 3698c1f20f355dd5b0592788e379b170fac7bf59..a723ab2a222efc591fc5d0a300067c367c5f32b1 100755 (executable)
@@ -7,7 +7,7 @@ from nmigen.lib.io import *
 from nmigen.hdl.rec import Direction
 from nmigen.tracer import get_var_name
 
-from c4m_repo.nmigen.lib import Wishbone
+from nmigen_soc.wishbone import Interface as WishboneInterface
 
 from .bus import Interface
 
@@ -269,19 +269,24 @@ class TAP(Elaboratable):
             m.d.comb += self.bus.tdo.eq(sigs.tdo_jtag)
 
 
-    def add_wishbone(self, *, ircodes, address_width, data_width, sel_width=None, domain="sync"):
+    def add_wishbone(self, *, ircodes, address_width, data_width, granularity=None, domain="sync"):
         """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")
@@ -289,7 +294,8 @@ class TAP(Elaboratable):
         sr_addr = self.add_shiftreg(ircodes[0], address_width, domain=domain)
         sr_data = self.add_shiftreg(ircodes[1:], data_width, domain=domain)
 
-        wb = Wishbone(data_width=data_width, address_width=address_width, sel_width=sel_width, master=True)
+        wb = WishboneInterface(data_width=data_width, addr_width=address_width,
+                               granularity=granularity, features={"stall", "lock", "err", "rty"})
 
         self._wbs.append((sr_addr, sr_data, wb, domain))
 
@@ -303,54 +309,34 @@ class TAP(Elaboratable):
 
             with m.FSM(domain=domain) as fsm:
                 with m.State("IDLE"):
-                    m.d.comb += [
-                        wb.cyc.eq(0),
-                        wb.stb.eq(0),
-                        wb.we.eq(0),
-                    ]
                     with m.If(sr_addr.oe): # WBADDR code
-                        m.d[domain] += wb.addr.eq(sr_addr.o)
+                        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.addr.eq(wb.addr + 1)
+                        m.d[domain] += wb.adr.eq(wb.adr + 1)
                         m.next = "READ"
-
-                    with m.If(sr_data.oe[1]): # WBWRITE code
+                    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"):
-                    m.d.comb += [
-                        wb.cyc.eq(1),
-                        wb.stb.eq(1),
-                        wb.we.eq(0),
-                    ]
                     with m.If(~wb.stall):
                         m.next = "READACK"
                 with m.State("READACK"):
-                    m.d.comb += [
-                        wb.cyc.eq(1),
-                        wb.stb.eq(0),
-                        wb.we.eq(0),
-                    ]
                     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"):
-                    m.d.comb += [
-                        wb.cyc.eq(1),
-                        wb.stb.eq(1),
-                        wb.we.eq(1),
-                    ]
                     with m.If(~wb.stall):
                         m.next = "WRITEREADACK"
                 with m.State("WRITEREADACK"):
-                    m.d.comb += [
-                        wb.cyc.eq(1),
-                        wb.stb.eq(0),
-                        wb.we.eq(0),
-                    ]
                     with m.If(wb.ack):
-                        m.d[domain] += wb.addr.eq(wb.addr + 1)
+                        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")),
+                ]