format code
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 8 Apr 2022 23:23:51 +0000 (16:23 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Fri, 8 Apr 2022 23:23:51 +0000 (16:23 -0700)
26 files changed:
src/nmutil/byterev.py
src/nmutil/clz.py
src/nmutil/concurrentunit.py
src/nmutil/dynamicpipe.py
src/nmutil/formal/proof_clz.py
src/nmutil/iocontrol.py
src/nmutil/latch.py
src/nmutil/multipipe.py
src/nmutil/nmoperator.py
src/nmutil/noconflict.py
src/nmutil/picker.py
src/nmutil/pipemodbase.py
src/nmutil/plru.py
src/nmutil/queue.py
src/nmutil/ripple.py
src/nmutil/sim_tmp_alternative.py
src/nmutil/singlepipe.py
src/nmutil/stageapi.py
src/nmutil/test/example_buf_pipe.py
src/nmutil/test/example_gtkwave.py
src/nmutil/test/test_clz.py
src/nmutil/test/test_inout_mux_pipe.py
src/nmutil/test/test_inout_unary_mux_cancel_pipe.py
src/nmutil/test/test_outmux_pipe.py
src/nmutil/test/test_reservation_stations.py
src/nmutil/util.py

index 7dad4508ac12584056d5c8837fa6d043234d21e8..84ba740a6a0b02888416b32e7ae13624609b72c1 100644 (file)
@@ -7,6 +7,8 @@
 from nmigen import Signal, Cat
 
 # TODO: turn this into a module?
+
+
 def byte_reverse(m, name, data, length):
     """byte_reverse: unlike nmigen word_select this takes a dynamic length
 
@@ -28,11 +30,10 @@ def byte_reverse(m, name, data, length):
 
     # Switch statement needed: dynamic length had better be = 1,2,4 or 8
     with m.Switch(length):
-        for j in [1,2,4,8]:
+        for j in [1, 2, 4, 8]:
             with m.Case(j):
                 rev = []
                 for i in range(j):
                     rev.append(data.word_select(j-1-i, 8))
                 comb += data_r.eq(Cat(*rev))
     return data_r
-
index 2fda8c2b578a5a335cc33bcdca5fac3083c4d483..39e832941be146533479552cd59aede32db18da1 100644 (file)
@@ -10,6 +10,7 @@ import math
 
 """
 
+
 class CLZ(Elaboratable):
     def __init__(self, width):
         self.width = width
@@ -86,4 +87,3 @@ class CLZ(Elaboratable):
         comb += self.lz.eq(pairs[0][0])
 
         return m
-
index e802ed6a93b01d68ee44eb9f76690a41edcfcf25..bbb605977c2cafe58d34b6c8eef5e2f0e3163e0f 100644 (file)
@@ -101,6 +101,7 @@ class ALUProxy:
     sandwiched in between the fan-in and fan-out.  One ALU looks like
     it is multiple concurrent ALUs
     """
+
     def __init__(self, alu, p, n):
         self.alu = alu
         self.p = p
@@ -121,14 +122,15 @@ class ReservationStations(Elaboratable):
 
         Fan-in and Fan-out are combinatorial.
     """
+
     def __init__(self, num_rows, maskwid=0, feedback_width=None):
         self.num_rows = nr = num_rows
         self.feedback_width = feedback_width
         self.inpipe = InMuxPipe(nr, self.i_specfn, maskwid)   # fan-in
-        self.outpipe = MuxOutPipe(nr, self.o_specfn, maskwid) # fan-out
+        self.outpipe = MuxOutPipe(nr, self.o_specfn, maskwid)  # fan-out
 
         self.p = self.inpipe.p  # kinda annoying,
-        self.n = self.outpipe.n # use pipe in/out as this class in/out
+        self.n = self.outpipe.n  # use pipe in/out as this class in/out
         self._ports = self.inpipe.ports() + self.outpipe.ports()
 
     def setup_pseudoalus(self):
@@ -190,6 +192,7 @@ class ReservationStations2(Elaboratable):
 
         FAILING TO SET THE MUXID IS GUARANTEED TO RESULT IN CORRUPTED DATA.
     """
+
     def __init__(self, alu, num_rows, alu_name=None):
         if alu_name is None:
             alu_name = "alu"
@@ -208,7 +211,7 @@ class ReservationStations2(Elaboratable):
             self.p.append(p)
             self.n.append(n)
 
-        self.pipe = self # for Arbiter to select the incoming prevcontrols
+        self.pipe = self  # for Arbiter to select the incoming prevcontrols
 
         # set up pseudo-alus that look like a standard pipeline
         self.pseudoalus = []
@@ -226,7 +229,7 @@ class ReservationStations2(Elaboratable):
 
     def elaborate(self, platform):
         m = Module()
-        pe = PriorityEncoder(self.num_rows) # input priority picker
+        pe = PriorityEncoder(self.num_rows)  # input priority picker
         m.submodules[self.alu_name] = self.alu
         m.submodules.selector = pe
         for i, (p, n) in enumerate(zip(self.p, self.n)):
@@ -238,9 +241,9 @@ class ReservationStations2(Elaboratable):
         self.m_id = Signal.like(pe.o)
 
         # ReservationStation status information, progressively updated in FSM
-        rsvd = Signal(self.num_rows) # indicates RS data in flight
-        sent = Signal(self.num_rows) # sent indicates data in pipeline
-        wait = Signal(self.num_rows) # the outputs are waiting for accept
+        rsvd = Signal(self.num_rows)  # indicates RS data in flight
+        sent = Signal(self.num_rows)  # sent indicates data in pipeline
+        wait = Signal(self.num_rows)  # the outputs are waiting for accept
 
         # pick first non-reserved ReservationStation with data not already
         # sent into the ALU
@@ -250,7 +253,7 @@ class ReservationStations2(Elaboratable):
 
         # mux in and mux out ids.  note that all data *must* have a muxid
         mid = self.m_id                   # input mux selector
-        o_muxid = self.alu.n.o_data.muxid # output mux selector
+        o_muxid = self.alu.n.o_data.muxid  # output mux selector
 
         # technically speaking this could be set permanently "HI".
         # when all the ReservationStations outputs are waiting,
@@ -267,68 +270,68 @@ class ReservationStations2(Elaboratable):
 
         # first, establish input: select one input to pass data to (p_mux)
         for i in range(self.num_rows):
-            i_buf, o_buf = self.alu.new_specs("buf%d" % i) # buffers
+            i_buf, o_buf = self.alu.new_specs("buf%d" % i)  # buffers
             with m.FSM():
                 # indicate ready to accept data, and accept it if incoming
                 # BUT, if there is an opportunity to send on immediately
                 # to the ALU, take it early (combinatorial)
                 with m.State("ACCEPTING%d" % i):
-                    m.d.comb += self.p[i].o_ready.eq(1) # ready indicator
+                    m.d.comb += self.p[i].o_ready.eq(1)  # ready indicator
                     with m.If(self.p[i].i_valid):  # valid data incoming
                         m.d.sync += rsvd[i].eq(1)  # now reserved
                         # a unique opportunity: the ALU happens to be free
-                        with m.If(mid == i): # picker selected us
+                        with m.If(mid == i):  # picker selected us
                             with m.If(self.alu.p.o_ready):  # ALU can accept
-                                m.d.comb += self.alu.p.i_valid.eq(1) # transfer
+                                # transfer
+                                m.d.comb += self.alu.p.i_valid.eq(1)
                                 m.d.comb += nmoperator.eq(self.alu.p.i_data,
-                                                         self.p[i].i_data)
-                                m.d.sync += sent[i].eq(1) # now reserved
-                                m.next = "WAITOUT%d" % i # move to "wait output"
+                                                          self.p[i].i_data)
+                                m.d.sync += sent[i].eq(1)  # now reserved
+                                m.next = "WAITOUT%d" % i  # move to "wait output"
                         with m.Else():
                             # nope. ALU wasn't free. try next cycle(s)
                             m.d.sync += nmoperator.eq(i_buf, self.p[i].i_data)
-                            m.next = "ACCEPTED%d" % i # move to "accepted"
+                            m.next = "ACCEPTED%d" % i  # move to "accepted"
 
                 # now try to deliver to the ALU, but only if we are "picked"
                 with m.State("ACCEPTED%d" % i):
-                    with m.If(mid == i): # picker selected us
+                    with m.If(mid == i):  # picker selected us
                         with m.If(self.alu.p.o_ready):  # ALU can accept
-                            m.d.comb += self.alu.p.i_valid.eq(1) # transfer
+                            m.d.comb += self.alu.p.i_valid.eq(1)  # transfer
                             m.d.comb += nmoperator.eq(self.alu.p.i_data, i_buf)
-                            m.d.sync += sent[i].eq(1) # now reserved
-                            m.next = "WAITOUT%d" % i # move to "wait output"
+                            m.d.sync += sent[i].eq(1)  # now reserved
+                            m.next = "WAITOUT%d" % i  # move to "wait output"
 
                 # waiting for output to appear on the ALU, take a copy
                 # BUT, again, if there is an opportunity to send on
                 # immediately, take it (combinatorial)
                 with m.State("WAITOUT%d" % i):
-                    with m.If(o_muxid == i): # when ALU output matches our RS
+                    with m.If(o_muxid == i):  # when ALU output matches our RS
                         with m.If(self.alu.n.o_valid):  # ALU can accept
                             # second unique opportunity: the RS is ready
-                            with m.If(self.n[i].i_ready): # ready to receive
-                                m.d.comb += self.n[i].o_valid.eq(1) # valid
+                            with m.If(self.n[i].i_ready):  # ready to receive
+                                m.d.comb += self.n[i].o_valid.eq(1)  # valid
                                 m.d.comb += nmoperator.eq(self.n[i].o_data,
                                                           self.alu.n.o_data)
-                                m.d.sync += wait[i].eq(0) # clear waiting
-                                m.d.sync += sent[i].eq(0) # and sending
-                                m.d.sync += rsvd[i].eq(0) # and reserved
-                                m.next = "ACCEPTING%d" % i # back to "accepting"
+                                m.d.sync += wait[i].eq(0)  # clear waiting
+                                m.d.sync += sent[i].eq(0)  # and sending
+                                m.d.sync += rsvd[i].eq(0)  # and reserved
+                                m.next = "ACCEPTING%d" % i  # back to "accepting"
                             with m.Else():
                                 # nope. RS wasn't ready. try next cycles
-                                m.d.sync += wait[i].eq(1) # now waiting
+                                m.d.sync += wait[i].eq(1)  # now waiting
                                 m.d.sync += nmoperator.eq(o_buf,
                                                           self.alu.n.o_data)
-                                m.next = "SENDON%d" % i # move to "send data on"
+                                m.next = "SENDON%d" % i  # move to "send data on"
 
                 # waiting for "valid" indicator on RS output: deliver it
                 with m.State("SENDON%d" % i):
-                    with m.If(self.n[i].i_ready): # user is ready to receive
-                        m.d.comb += self.n[i].o_valid.eq(1) # indicate valid
+                    with m.If(self.n[i].i_ready):  # user is ready to receive
+                        m.d.comb += self.n[i].o_valid.eq(1)  # indicate valid
                         m.d.comb += nmoperator.eq(self.n[i].o_data, o_buf)
-                        m.d.sync += wait[i].eq(0) # clear waiting
-                        m.d.sync += sent[i].eq(0) # and sending
-                        m.d.sync += rsvd[i].eq(0) # and reserved
-                        m.next = "ACCEPTING%d" % i # and back to "accepting"
+                        m.d.sync += wait[i].eq(0)  # clear waiting
+                        m.d.sync += sent[i].eq(0)  # and sending
+                        m.d.sync += rsvd[i].eq(0)  # and reserved
+                        m.next = "ACCEPTING%d" % i  # and back to "accepting"
 
         return m
-
index 0187cf29cc594429a587e1abc7a2a0609b721bfc..95f58e5fe3f275ebe74ea4af6565ec0db053eda0 100644 (file)
@@ -27,6 +27,7 @@ import threading
 # list post:
 # http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-July/002259.html
 
+
 class Meta(ABCMeta):
     registry = {}
     recursing = threading.local()
@@ -38,11 +39,11 @@ class Meta(ABCMeta):
         if mcls.recursing.check:
             return super().__call__(*args, **kw)
         spec = args[0]
-        base = spec.pipekls # pick up the dynamic class from PipelineSpec, HERE
+        base = spec.pipekls  # pick up the dynamic class from PipelineSpec, HERE
 
         if (cls, base) not in mcls.registry:
-            print ("__call__", args, kw, cls, base,
-                   base.__bases__, cls.__bases__)
+            print("__call__", args, kw, cls, base,
+                  base.__bases__, cls.__bases__)
             mcls.registry[cls, base] = type(
                 cls.__name__,
                 (cls, base) + cls.__bases__[1:],
@@ -74,7 +75,7 @@ class Meta(ABCMeta):
 
 class DynamicPipe(metaclass=Meta):
     def __init__(self, *args):
-        print ("DynamicPipe init", super(), args)
+        print("DynamicPipe init", super(), args)
         super().__init__(self, *args)
 
 
@@ -84,7 +85,7 @@ class DynamicPipe(metaclass=Meta):
 # could hypothetically be passed through the pspec.
 class SimpleHandshakeRedir(SimpleHandshake):
     def __init__(self, mod, *args):
-        print ("redir", mod, args)
+        print("redir", mod, args)
         stage = self
         if args and args[0].stage:
             stage = args[0].stage
@@ -97,6 +98,5 @@ class MaskCancellableRedir(MaskCancellable):
         maskwid = args[0].maskwid
         if args[0].stage:
             stage = args[0].stage
-        print ("redir mask", mod, args, maskwid)
+        print("redir mask", mod, args, maskwid)
         MaskCancellable.__init__(self, stage, maskwid)
-
index aac25d30528bbdb43a025936efc952af983bd035..2bfcfe6e53295d31e6210097e326d77043290e62 100644 (file)
@@ -23,7 +23,6 @@ class Driver(Elaboratable):
         sig_in = Signal.like(dut.sig_in)
         count = Signal.like(dut.lz)
 
-
         m.d.comb += [
             sig_in.eq(AnyConst(width)),
             dut.sig_in.eq(sig_in),
@@ -43,20 +42,23 @@ class Driver(Elaboratable):
         comb += result_sig.eq(result)
 
         comb += Assert(result_sig == count)
-        
+
         # setup the inputs and outputs of the DUT as anyconst
 
         return m
 
+
 class CLZTestCase(FHDLTestCase):
     def test_proof(self):
         module = Driver()
         self.assertFormal(module, mode="bmc", depth=4)
+
     def test_ilang(self):
         dut = Driver()
         vl = rtlil.convert(dut, ports=[])
         with open("clz.il", "w") as f:
             f.write(vl)
 
+
 if __name__ == '__main__':
     unittest.main()
index c4da57bf86c04cf2d9fd0f371aeddae251add0fd..4705b0079f2ea8fc1720b980da68b7ff4c496ef7 100644 (file)
@@ -42,9 +42,9 @@ class Object:
         self.fields = OrderedDict()
 
     def __setattr__(self, k, v):
-        print ("kv", k, v)
+        print("kv", k, v)
         if (k.startswith('_') or k in ["fields", "name", "src_loc"] or
-           k in dir(Object) or "fields" not in self.__dict__):
+                k in dir(Object) or "fields" not in self.__dict__):
             return object.__setattr__(self, k, v)
         self.fields[k] = v
 
@@ -67,16 +67,16 @@ class Object:
         res = []
         for (k, o) in self.fields.items():
             i = getattr(inp, k)
-            print ("eq", o, i)
+            print("eq", o, i)
             rres = o.eq(i)
             if isinstance(rres, Sequence):
                 res += rres
             else:
                 res.append(rres)
-        print (res)
+        print(res)
         return res
 
-    def ports(self): # being called "keys" would be much better
+    def ports(self):  # being called "keys" would be much better
         return list(self)
 
 
@@ -92,16 +92,15 @@ def add_prefix_to_record_signals(prefix, record):
 
 class RecordObject(Record):
     def __init__(self, layout=None, name=None):
-        #if name is None:
+        # if name is None:
         #    name = tracer.get_var_name(depth=2, default="$ro")
         Record.__init__(self, layout=layout or [], name=name)
 
-
     def __setattr__(self, k, v):
         #print(f"RecordObject setattr({k}, {v})")
         #print (dir(Record))
         if (k.startswith('_') or k in ["fields", "name", "src_loc"] or
-           k in dir(Record) or "fields" not in self.__dict__):
+                k in dir(Record) or "fields" not in self.__dict__):
             return object.__setattr__(self, k, v)
 
         if self.name is None:
@@ -126,7 +125,7 @@ class RecordObject(Record):
         self.layout.fields.update(newlayout)
 
     def __iter__(self):
-        for x in self.fields.values(): # remember: fields is an OrderedDict
+        for x in self.fields.values():  # remember: fields is an OrderedDict
             if hasattr(x, 'ports'):
                 yield from x.ports()
             elif isinstance(x, Record):
@@ -137,7 +136,7 @@ class RecordObject(Record):
             else:
                 yield x
 
-    def ports(self): # would be better being called "keys"
+    def ports(self):  # would be better being called "keys"
         return list(self)
 
 
@@ -151,7 +150,7 @@ class PrevControl(Elaboratable):
     """
 
     def __init__(self, i_width=1, stage_ctl=False, maskwid=0, offs=0,
-                       name=None):
+                 name=None):
         if name is None:
             name = ""
         n_piv = "p_i_valid"+name
@@ -164,7 +163,7 @@ class PrevControl(Elaboratable):
             self.stop_i = Signal(maskwid)              # prev   >>in  self
         self.i_valid = Signal(i_width, name=n_piv)     # prev   >>in  self
         self._o_ready = Signal(name=n_por)             # prev   <<out self
-        self.i_data = None # XXX MUST BE ADDED BY USER
+        self.i_data = None  # XXX MUST BE ADDED BY USER
         if stage_ctl:
             self.s_o_ready = Signal(name="p_s_o_rdy")    # prev   <<out self
         self.trigger = Signal(reset_less=True)
@@ -174,7 +173,7 @@ class PrevControl(Elaboratable):
         """ public-facing API: indicates (externally) that stage is ready
         """
         if self.stage_ctl:
-            return self.s_o_ready # set dynamically by stage
+            return self.s_o_ready  # set dynamically by stage
         return self._o_ready      # return this when not under dynamic control
 
     def _connect_in(self, prev, direct=False, fn=None,
@@ -219,8 +218,8 @@ class PrevControl(Elaboratable):
 
     def eq(self, i):
         res = [nmoperator.eq(self.i_data, i.i_data),
-                self.o_ready.eq(i.o_ready),
-                self.i_valid.eq(i.i_valid)]
+               self.o_ready.eq(i.o_ready),
+               self.i_valid.eq(i.i_valid)]
         if self.maskwid:
             res.append(self.mask_i.eq(i.mask_i))
         return res
@@ -249,6 +248,7 @@ class NextControl(Elaboratable):
         * i_ready: input from next stage indicating that it can accept data
         * o_data : an output - MUST be added by the USER of this class
     """
+
     def __init__(self, stage_ctl=False, maskwid=0, name=None):
         if name is None:
             name = ""
@@ -258,13 +258,13 @@ class NextControl(Elaboratable):
         self.stage_ctl = stage_ctl
         self.maskwid = maskwid
         if maskwid:
-            self.mask_o = Signal(maskwid) # self out>>  next
-            self.stop_o = Signal(maskwid) # self out>>  next
-        self.o_valid = Signal(name=n_nov) # self out>>  next
-        self.i_ready = Signal(name=n_nir) # self <<in   next
-        self.o_data = None # XXX MUST BE ADDED BY USER
-        #if self.stage_ctl:
-        self.d_valid = Signal(reset=1) # INTERNAL (data valid)
+            self.mask_o = Signal(maskwid)  # self out>>  next
+            self.stop_o = Signal(maskwid)  # self out>>  next
+        self.o_valid = Signal(name=n_nov)  # self out>>  next
+        self.i_ready = Signal(name=n_nir)  # self <<in   next
+        self.o_data = None  # XXX MUST BE ADDED BY USER
+        # if self.stage_ctl:
+        self.d_valid = Signal(reset=1)  # INTERNAL (data valid)
         self.trigger = Signal(reset_less=True)
 
     @property
@@ -289,8 +289,8 @@ class NextControl(Elaboratable):
                 res.append(nxt.stop_i.eq(self.stop_o))
         if do_data:
             res.append(nmoperator.eq(nxt.i_data, self.o_data))
-        print ("connect to next", self, self.maskwid, nxt.i_data,
-                                  do_data, do_stop)
+        print("connect to next", self, self.maskwid, nxt.i_data,
+              do_data, do_stop)
         return res
 
     def _connect_out(self, nxt, direct=False, fn=None,
@@ -331,4 +331,3 @@ class NextControl(Elaboratable):
 
     def ports(self):
         return list(self)
-
index e25050867aab9825f0d7541d6444cec2a310995e..769f76848f1bb36d3298cf098f7cfd115ebe8fee 100644 (file)
@@ -45,7 +45,7 @@ def latchregister(m, incoming, outgoing, settrue, name=None):
     else:
         reg = Signal.like(incoming, name=name)
     m.d.comb += outgoing.eq(Mux(settrue, incoming, reg))
-    with m.If(settrue): # pass in some kind of expression/condition here
+    with m.If(settrue):  # pass in some kind of expression/condition here
         m.d.sync += reg.eq(incoming)      # latch input into register
     return reg
 
@@ -65,7 +65,7 @@ class SRLatch(Elaboratable):
         qint = mkname("qint", name)
         qlq_n = mkname("qlq", name)
         self.s = Signal(llen, name=s_n, reset=0)
-        self.r = Signal(llen, name=r_n, reset=(1<<llen)-1) # defaults to off
+        self.r = Signal(llen, name=r_n, reset=(1 << llen)-1)  # defaults to off
         self.q = Signal(llen, name=q_n, reset_less=True)
         self.qn = Signal(llen, name=qn_n, reset_less=True)
         self.qlq = Signal(llen, name=qlq_n, reset_less=True)
@@ -82,7 +82,7 @@ class SRLatch(Elaboratable):
         else:
             m.d.comb += self.q.eq(next_o)
         m.d.comb += self.qn.eq(~self.q)
-        m.d.comb += self.qlq.eq(self.q | self.q_int) # useful output
+        m.d.comb += self.qlq.eq(self.q | self.q_int)  # useful output
 
         return m
 
@@ -113,6 +113,7 @@ def sr_sim(dut):
     yield
     yield
 
+
 def test_sr():
     dut = SRLatch(llen=4)
     vl = rtlil.convert(dut, ports=dut.ports())
@@ -128,5 +129,6 @@ def test_sr():
 
     run_simulation(dut, sr_sim(dut), vcd_name='test_srlatch_async.vcd')
 
+
 if __name__ == '__main__':
     test_sr()
index 13aaca3f21700f776715692b6246e6e040878d76..d882742d764384f64ce59f773cb10c541dede64c 100644 (file)
@@ -32,6 +32,7 @@ from nmutil.iocontrol import NextControl, PrevControl
 class MultiInControlBase(Elaboratable):
     """ Common functions for Pipeline API
     """
+
     def __init__(self, in_multi=None, p_len=1, maskwid=0, routemask=False):
         """ Multi-input Control class.  Conforms to same API as ControlBase...
             mostly.  has additional indices to the *multiple* input stages
@@ -45,16 +46,16 @@ class MultiInControlBase(Elaboratable):
         """
         self.routemask = routemask
         # set up input and output IO ACK (prev/next ready/valid)
-        print ("multi_in", self, maskwid, p_len, routemask)
+        print("multi_in", self, maskwid, p_len, routemask)
         p = []
         for i in range(p_len):
             p.append(PrevControl(in_multi, maskwid=maskwid))
         self.p = Array(p)
         if routemask:
-            nmaskwid = maskwid # straight route mask mode
+            nmaskwid = maskwid  # straight route mask mode
         else:
-            nmaskwid = maskwid * p_len # fan-in mode
-        self.n = NextControl(maskwid=nmaskwid) # masks fan in (Cat)
+            nmaskwid = maskwid * p_len  # fan-in mode
+        self.n = NextControl(maskwid=nmaskwid)  # masks fan in (Cat)
 
     def connect_to_next(self, nxt, p_idx=0):
         """ helper function to connect to the next stage data/valid/ready.
@@ -101,6 +102,7 @@ class MultiInControlBase(Elaboratable):
 class MultiOutControlBase(Elaboratable):
     """ Common functions for Pipeline API
     """
+
     def __init__(self, n_len=1, in_multi=None, maskwid=0, routemask=False):
         """ Multi-output Control class.  Conforms to same API as ControlBase...
             mostly.  has additional indices to the multiple *output* stages
@@ -115,9 +117,9 @@ class MultiOutControlBase(Elaboratable):
         """
 
         if routemask:
-            nmaskwid = maskwid # straight route mask mode
+            nmaskwid = maskwid  # straight route mask mode
         else:
-            nmaskwid = maskwid * n_len # fan-out mode
+            nmaskwid = maskwid * n_len  # fan-out mode
 
         # set up input and output IO ACK (prev/next ready/valid)
         self.p = PrevControl(in_multi, maskwid=nmaskwid)
@@ -177,17 +179,17 @@ class CombMultiOutPipeline(MultiOutControlBase):
 
     def __init__(self, stage, n_len, n_mux, maskwid=0, routemask=False):
         MultiOutControlBase.__init__(self, n_len=n_len, maskwid=maskwid,
-                                            routemask=routemask)
+                                     routemask=routemask)
         self.stage = stage
         self.maskwid = maskwid
         self.routemask = routemask
         self.n_mux = n_mux
 
         # set up the input and output data
-        self.p.i_data = _spec(stage.ispec, 'i_data') # input type
+        self.p.i_data = _spec(stage.ispec, 'i_data')  # input type
         for i in range(n_len):
             name = 'o_data_%d' % i
-            self.n[i].o_data = _spec(stage.ospec, name) # output type
+            self.n[i].o_data = _spec(stage.ospec, name)  # output type
 
     def process(self, i):
         if hasattr(self.stage, "process"):
@@ -197,18 +199,18 @@ class CombMultiOutPipeline(MultiOutControlBase):
     def elaborate(self, platform):
         m = MultiOutControlBase.elaborate(self, platform)
 
-        if hasattr(self.n_mux, "elaborate"): # TODO: identify submodule?
+        if hasattr(self.n_mux, "elaborate"):  # TODO: identify submodule?
             m.submodules.n_mux = self.n_mux
 
         # need buffer register conforming to *input* spec
-        r_data = _spec(self.stage.ispec, 'r_data') # input type
+        r_data = _spec(self.stage.ispec, 'r_data')  # input type
         if hasattr(self.stage, "setup"):
             self.stage.setup(m, r_data)
 
         # multiplexer id taken from n_mux
         muxid = self.n_mux.m_id
-        print ("self.n_mux", self.n_mux)
-        print ("self.n_mux.m_id", self.n_mux.m_id)
+        print("self.n_mux", self.n_mux)
+        print("self.n_mux.m_id", self.n_mux.m_id)
 
         self.n_mux.m_id.name = "m_id"
 
@@ -216,7 +218,7 @@ class CombMultiOutPipeline(MultiOutControlBase):
         p_i_valid = Signal(reset_less=True)
         pv = Signal(reset_less=True)
         m.d.comb += p_i_valid.eq(self.p.i_valid_test)
-        #m.d.comb += pv.eq(self.p.i_valid) #& self.n[muxid].i_ready)
+        # m.d.comb += pv.eq(self.p.i_valid) #& self.n[muxid].i_ready)
         m.d.comb += pv.eq(self.p.i_valid & self.p.o_ready)
 
         # all outputs to next stages first initialised to zero (invalid)
@@ -224,18 +226,17 @@ class CombMultiOutPipeline(MultiOutControlBase):
         for i in range(len(self.n)):
             m.d.comb += self.n[i].o_valid.eq(0)
         if self.routemask:
-            #with m.If(pv):
+            # with m.If(pv):
             m.d.comb += self.n[muxid].o_valid.eq(pv)
             m.d.comb += self.p.o_ready.eq(self.n[muxid].i_ready)
         else:
             data_valid = self.n[muxid].o_valid
             m.d.comb += self.p.o_ready.eq(self.n[muxid].i_ready)
-            m.d.comb += data_valid.eq(p_i_valid | \
-                                    (~self.n[muxid].i_ready & data_valid))
-
+            m.d.comb += data_valid.eq(p_i_valid |
+                                      (~self.n[muxid].i_ready & data_valid))
 
         # send data on
-        #with m.If(pv):
+        # with m.If(pv):
         m.d.comb += eq(r_data, self.p.i_data)
         #m.d.comb += eq(self.n[muxid].o_data, self.process(r_data))
         for i in range(len(self.n)):
@@ -243,13 +244,13 @@ class CombMultiOutPipeline(MultiOutControlBase):
                 m.d.comb += eq(self.n[i].o_data, self.process(r_data))
 
         if self.maskwid:
-            if self.routemask: # straight "routing" mode - treat like data
+            if self.routemask:  # straight "routing" mode - treat like data
                 m.d.comb += self.n[muxid].stop_o.eq(self.p.stop_i)
                 with m.If(pv):
                     m.d.comb += self.n[muxid].mask_o.eq(self.p.mask_i)
             else:
-                ml = [] # accumulate output masks
-                ms = [] # accumulate output stops
+                ml = []  # accumulate output masks
+                ms = []  # accumulate output stops
                 # fan-out mode.
                 # conditionally fan-out mask bits, always fan-out stop bits
                 for i in range(len(self.n)):
@@ -278,7 +279,7 @@ class CombMultiInPipeline(MultiInControlBase):
 
     def __init__(self, stage, p_len, p_mux, maskwid=0, routemask=False):
         MultiInControlBase.__init__(self, p_len=p_len, maskwid=maskwid,
-                                          routemask=routemask)
+                                    routemask=routemask)
         self.stage = stage
         self.maskwid = maskwid
         self.p_mux = p_mux
@@ -286,7 +287,7 @@ class CombMultiInPipeline(MultiInControlBase):
         # set up the input and output data
         for i in range(p_len):
             name = 'i_data_%d' % i
-            self.p[i].i_data = _spec(stage.ispec, name) # input type
+            self.p[i].i_data = _spec(stage.ispec, name)  # input type
         self.n.o_data = _spec(stage.ospec, 'o_data')
 
     def process(self, i):
@@ -307,15 +308,15 @@ class CombMultiInPipeline(MultiInControlBase):
         p_len = len(self.p)
         for i in range(p_len):
             name = 'r_%d' % i
-            r = _spec(self.stage.ispec, name) # input type
+            r = _spec(self.stage.ispec, name)  # input type
             r_data.append(r)
             data_valid.append(Signal(name="data_valid", reset_less=True))
             p_i_valid.append(Signal(name="p_i_valid", reset_less=True))
             n_i_readyn.append(Signal(name="n_i_readyn", reset_less=True))
             if hasattr(self.stage, "setup"):
-                print ("setup", self, self.stage, r)
+                print("setup", self, self.stage, r)
                 self.stage.setup(m, r)
-        if True: # len(r_data) > 1: # hmm always create an Array even of len 1
+        if True:  # len(r_data) > 1: # hmm always create an Array even of len 1
             p_i_valid = Array(p_i_valid)
             n_i_readyn = Array(n_i_readyn)
             data_valid = Array(data_valid)
@@ -323,7 +324,7 @@ class CombMultiInPipeline(MultiInControlBase):
         nirn = Signal(reset_less=True)
         m.d.comb += nirn.eq(~self.n.i_ready)
         mid = self.p_mux.m_id
-        print ("CombMuxIn mid", self, self.stage, self.routemask, mid, p_len)
+        print("CombMuxIn mid", self, self.stage, self.routemask, mid, p_len)
         for i in range(p_len):
             m.d.comb += data_valid[i].eq(0)
             m.d.comb += n_i_readyn[i].eq(1)
@@ -346,8 +347,8 @@ class CombMultiInPipeline(MultiInControlBase):
             av.append(data_valid[i])
         anyvalid = Cat(*av)
         m.d.comb += self.n.o_valid.eq(anyvalid.bool())
-        m.d.comb += data_valid[mid].eq(p_i_valid[mid] | \
-                                    (n_i_readyn[mid] ))
+        m.d.comb += data_valid[mid].eq(p_i_valid[mid] |
+                                       (n_i_readyn[mid]))
 
         if self.routemask:
             # XXX hack - fixes loop
@@ -368,8 +369,8 @@ class CombMultiInPipeline(MultiInControlBase):
                     with m.If(mid == i):
                         m.d.comb += eq(self.n.o_data, r_data[i])
         else:
-            ml = [] # accumulate output masks
-            ms = [] # accumulate output stops
+            ml = []  # accumulate output masks
+            ms = []  # accumulate output stops
             for i in range(p_len):
                 vr = Signal(reset_less=True)
                 p = self.p[i]
@@ -417,7 +418,7 @@ class NonCombMultiInPipeline(MultiInControlBase):
 
     def __init__(self, stage, p_len, p_mux, maskwid=0, routemask=False):
         MultiInControlBase.__init__(self, p_len=p_len, maskwid=maskwid,
-                                          routemask=routemask)
+                                    routemask=routemask)
         self.stage = stage
         self.maskwid = maskwid
         self.p_mux = p_mux
@@ -425,7 +426,7 @@ class NonCombMultiInPipeline(MultiInControlBase):
         # set up the input and output data
         for i in range(p_len):
             name = 'i_data_%d' % i
-            self.p[i].i_data = _spec(stage.ispec, name) # input type
+            self.p[i].i_data = _spec(stage.ispec, name)  # input type
         self.n.o_data = _spec(stage.ospec, 'o_data')
 
     def process(self, i):
@@ -445,12 +446,12 @@ class NonCombMultiInPipeline(MultiInControlBase):
         p_len = len(self.p)
         for i in range(p_len):
             name = 'r_%d' % i
-            r = _spec(self.stage.ispec, name) # input type
+            r = _spec(self.stage.ispec, name)  # input type
             r_data.append(r)
             r_busy.append(Signal(name="r_busy%d" % i, reset_less=True))
             p_i_valid.append(Signal(name="p_i_valid%d" % i, reset_less=True))
             if hasattr(self.stage, "setup"):
-                print ("setup", self, self.stage, r)
+                print("setup", self, self.stage, r)
                 self.stage.setup(m, r)
         if len(r_data) > 1:
             r_data = Array(r_data)
@@ -460,7 +461,7 @@ class NonCombMultiInPipeline(MultiInControlBase):
         nirn = Signal(reset_less=True)
         m.d.comb += nirn.eq(~self.n.i_ready)
         mid = self.p_mux.m_id
-        print ("CombMuxIn mid", self, self.stage, self.routemask, mid, p_len)
+        print("CombMuxIn mid", self, self.stage, self.routemask, mid, p_len)
         for i in range(p_len):
             m.d.comb += r_busy[i].eq(0)
             m.d.comb += n_i_readyn[i].eq(1)
@@ -481,8 +482,8 @@ class NonCombMultiInPipeline(MultiInControlBase):
             av.append(data_valid[i])
         anyvalid = Cat(*av)
         m.d.comb += self.n.o_valid.eq(anyvalid.bool())
-        m.d.comb += data_valid[mid].eq(p_i_valid[mid] | \
-                                    (n_i_readyn[mid] ))
+        m.d.comb += data_valid[mid].eq(p_i_valid[mid] |
+                                       (n_i_readyn[mid]))
 
         if self.routemask:
             # XXX hack - fixes loop
@@ -501,8 +502,8 @@ class NonCombMultiInPipeline(MultiInControlBase):
                     m.d.comb += eq(self.n.mask_o, self.p[i].mask_i)
                     m.d.comb += eq(r_data[i], self.p[i].i_data)
         else:
-            ml = [] # accumulate output masks
-            ms = [] # accumulate output stops
+            ml = []  # accumulate output masks
+            ms = []  # accumulate output stops
             for i in range(p_len):
                 vr = Signal(reset_less=True)
                 p = self.p[i]
@@ -532,35 +533,35 @@ class NonCombMultiInPipeline(MultiInControlBase):
 
 class CombMuxOutPipe(CombMultiOutPipeline):
     def __init__(self, stage, n_len, maskwid=0, muxidname=None,
-                                     routemask=False):
+                 routemask=False):
         muxidname = muxidname or "muxid"
         # HACK: stage is also the n-way multiplexer
         CombMultiOutPipeline.__init__(self, stage, n_len=n_len,
-                                            n_mux=stage, maskwid=maskwid,
-                                            routemask=routemask)
+                                      n_mux=stage, maskwid=maskwid,
+                                      routemask=routemask)
 
         # HACK: n-mux is also the stage... so set the muxid equal to input muxid
         muxid = getattr(self.p.i_data, muxidname)
-        print ("combmuxout", muxidname, muxid)
+        print("combmuxout", muxidname, muxid)
         stage.m_id = muxid
 
 
-
 class InputPriorityArbiter(Elaboratable):
     """ arbitration module for Input-Mux pipe, baed on PriorityEncoder
     """
+
     def __init__(self, pipe, num_rows):
         self.pipe = pipe
         self.num_rows = num_rows
         self.mmax = int(log(self.num_rows) / log(2))
-        self.m_id = Signal(self.mmax, reset_less=True) # multiplex id
+        self.m_id = Signal(self.mmax, reset_less=True)  # multiplex id
         self.active = Signal(reset_less=True)
 
     def elaborate(self, platform):
         m = Module()
 
         assert len(self.pipe.p) == self.num_rows, \
-                "must declare input to be same size"
+            "must declare input to be same size"
         pe = PriorityEncoder(self.num_rows)
         m.submodules.selector = pe
 
@@ -576,7 +577,7 @@ class InputPriorityArbiter(Elaboratable):
             else:
                 m.d.comb += p_i_valid.eq(self.pipe.p[i].i_valid_test)
             in_ready.append(p_i_valid)
-        m.d.comb += pe.i.eq(Cat(*in_ready)) # array of input "valids"
+        m.d.comb += pe.i.eq(Cat(*in_ready))  # array of input "valids"
         m.d.comb += self.active.eq(~pe.n)   # encoder active (one input valid)
         m.d.comb += self.m_id.eq(pe.o)       # output one active input
 
@@ -586,7 +587,6 @@ class InputPriorityArbiter(Elaboratable):
         return [self.m_id, self.active]
 
 
-
 class PriorityCombMuxInPipe(CombMultiInPipeline):
     """ an example of how to use the combinatorial pipeline.
     """
index a5fa03bd9a21ae51cc07bf67e05d1fa7b73456e0..e48bb7fb56222d5de82fdf79b77278aa6bb4f1ca 100644 (file)
@@ -41,6 +41,7 @@ class Visitor2:
         python object, enumerate them, find out the list of Signals that way,
         and assign them.
     """
+
     def iterator2(self, o, i):
         if isinstance(o, dict):
             yield from self.dict_iter2(o, i)
@@ -83,10 +84,10 @@ class Visitor2:
                 val = ai.fields
             else:
                 val = ai
-            if hasattr(val, field_name): # check for attribute
+            if hasattr(val, field_name):  # check for attribute
                 val = getattr(val, field_name)
             else:
-                val = val[field_name] # dictionary-style specification
+                val = val[field_name]  # dictionary-style specification
             yield from self.iterator2(ao.fields[field_name], val)
 
     def record_iter2(self, ao, ai):
@@ -95,10 +96,10 @@ class Visitor2:
                 val = ai.fields
             else:
                 val = ai
-            if hasattr(val, field_name): # check for attribute
+            if hasattr(val, field_name):  # check for attribute
                 val = getattr(val, field_name)
             else:
-                val = val[field_name] # dictionary-style specification
+                val = val[field_name]  # dictionary-style specification
             yield from self.iterator2(ao.fields[field_name], val)
 
     def arrayproxy_iter2(self, ao, ai):
@@ -120,6 +121,7 @@ class Visitor:
     """ a helper class for iterating single-argument compound data structures.
         similar to Visitor2.
     """
+
     def iterate(self, i):
         """ iterate a compound structure recursively using yield
         """
@@ -141,10 +143,10 @@ class Visitor:
                 val = ai.fields
             else:
                 val = ai
-            if hasattr(val, field_name): # check for attribute
+            if hasattr(val, field_name):  # check for attribute
                 val = getattr(val, field_name)
             else:
-                val = val[field_name] # dictionary-style specification
+                val = val[field_name]  # dictionary-style specification
             #print ("recidx", idx, field_name, field_shape, val)
             yield from self.iterate(val)
 
@@ -181,8 +183,6 @@ def cat(i):
     """ flattens a compound structure recursively using Cat
     """
     from nmigen._utils import flatten
-    #res = list(flatten(i)) # works (as of nmigen commit f22106e5) HOWEVER...
-    res = list(Visitor().iterate(i)) # needed because input may be a sequence
+    # res = list(flatten(i)) # works (as of nmigen commit f22106e5) HOWEVER...
+    res = list(Visitor().iterate(i))  # needed because input may be a sequence
     return Cat(*res)
-
-
index ad7eb09d0281c600719870a2bd49adfd0fcdd8b1..01bc52ad19ed2c92d65ef6c7e6634f4c3364f7ea 100644 (file)
@@ -1,28 +1,33 @@
-import inspect, types
+import inspect
+import types
 
 ############## preliminary: two utility functions #####################
 
+
 def skip_redundant(iterable, skipset=None):
-   "Redundant items are repeated items or items in the original skipset."
-   if skipset is None: skipset = set()
-   for item in iterable:
-       if item not in skipset:
-           skipset.add(item)
-           yield item
+    "Redundant items are repeated items or items in the original skipset."
+    if skipset is None:
+        skipset = set()
+    for item in iterable:
+        if item not in skipset:
+            skipset.add(item)
+            yield item
 
 
 def remove_redundant(metaclasses):
-   skipset = set([type])
-   for meta in metaclasses: # determines the metaclasses to be skipped
-       skipset.update(inspect.getmro(meta)[1:])
-   return tuple(skip_redundant(metaclasses, skipset))
+    skipset = set([type])
+    for meta in metaclasses:  # determines the metaclasses to be skipped
+        skipset.update(inspect.getmro(meta)[1:])
+    return tuple(skip_redundant(metaclasses, skipset))
 
 ##################################################################
 ## now the core of the module: two mutually recursive functions ##
 ##################################################################
 
+
 memoized_metaclasses_map = {}
 
+
 def get_noconflict_metaclass(bases, left_metas, right_metas):
     """Not intended to be used outside of this module, unless you know
     what you are doing."""
@@ -32,24 +37,25 @@ def get_noconflict_metaclass(bases, left_metas, right_metas):
 
     # return existing confict-solving meta, if any
     if needed_metas in memoized_metaclasses_map:
-      return memoized_metaclasses_map[needed_metas]
+        return memoized_metaclasses_map[needed_metas]
     # nope: compute, memoize and return needed conflict-solving meta
     elif not needed_metas:         # wee, a trivial case, happy us
         meta = type
-    elif len(needed_metas) == 1: # another trivial case
-       meta = needed_metas[0]
+    elif len(needed_metas) == 1:  # another trivial case
+        meta = needed_metas[0]
     # check for recursion, can happen i.e. for Zope ExtensionClasses
-    elif needed_metas == bases: 
+    elif needed_metas == bases:
         raise TypeError("Incompatible root metatypes", needed_metas)
-    else: # gotta work ...
+    else:  # gotta work ...
         metaname = '_' + ''.join([m.__name__ for m in needed_metas])
         meta = classmaker()(metaname, needed_metas, {})
     memoized_metaclasses_map[needed_metas] = meta
     return meta
 
+
 def classmaker(left_metas=(), right_metas=()):
     def make_class(name, bases, adict):
-        print ("make_class", name)
+        print("make_class", name)
         metaclass = get_noconflict_metaclass(bases, left_metas, right_metas)
         return metaclass(name, bases, adict)
     return make_class
index 0babc074a9eeb9663793bcc4fd1bfdb259d631bc..380ffb8051289a962976dc308af8b02af8e3fff0 100644 (file)
@@ -36,6 +36,7 @@ class PriorityPicker(Elaboratable):
         * reverse_i=True is for convenient reverseal of the input bits
         * reverse_o=True is for convenient reversal of the output bits
     """
+
     def __init__(self, wid, lsb_mode=False, reverse_i=False, reverse_o=False):
         self.wid = wid
         # inputs
@@ -44,14 +45,14 @@ class PriorityPicker(Elaboratable):
         self.reverse_o = reverse_o
         self.i = Signal(wid, reset_less=True)
         self.o = Signal(wid, reset_less=True)
-        self.en_o = Signal(reset_less=True) # true if any output is true
+        self.en_o = Signal(reset_less=True)  # true if any output is true
 
     def elaborate(self, platform):
         m = Module()
 
         # works by saying, "if all previous bits were zero, we get a chance"
         res = []
-        ni = Signal(self.wid, reset_less = True)
+        ni = Signal(self.wid, reset_less=True)
         i = list(self.i)
         if self.reverse_i:
             i.reverse()
@@ -60,7 +61,7 @@ class PriorityPicker(Elaboratable):
         if self.lsb_mode:
             prange.reverse()
         for n in prange:
-            t = Signal(name="t%d" % n, reset_less = True)
+            t = Signal(name="t%d" % n, reset_less=True)
             res.append(t)
             if n == 0:
                 m.d.comb += t.eq(i[n])
@@ -71,7 +72,7 @@ class PriorityPicker(Elaboratable):
         # we like Cat(*xxx).  turn lists into concatenated bits
         m.d.comb += self.o.eq(Cat(*res))
         # useful "is any output enabled" signal
-        m.d.comb += self.en_o.eq(self.o.bool()) # true if 1 input is true
+        m.d.comb += self.en_o.eq(self.o.bool())  # true if 1 input is true
 
         return m
 
@@ -95,16 +96,16 @@ class MultiPriorityPicker(Elaboratable):
 
         Also outputted (optional): an index for each picked "thing".
     """
+
     def __init__(self, wid, levels, indices=False, multiin=False):
         self.levels = levels
         self.wid = wid
         self.indices = indices
         self.multiin = multiin
 
-
         if multiin:
             # multiple inputs, multiple outputs.
-            i_l = [] # array of picker outputs
+            i_l = []  # array of picker outputs
             for j in range(self.levels):
                 i = Signal(self.wid, name="i_%d" % j, reset_less=True)
                 i_l.append(i)
@@ -114,7 +115,7 @@ class MultiPriorityPicker(Elaboratable):
             self.i = Signal(self.wid, reset_less=True)
 
         # create array of (single-bit) outputs (unary)
-        o_l = [] # array of picker outputs
+        o_l = []  # array of picker outputs
         for j in range(self.levels):
             o = Signal(self.wid, name="o_%d" % j, reset_less=True)
             o_l.append(o)
@@ -128,7 +129,7 @@ class MultiPriorityPicker(Elaboratable):
 
         # add an array of indices
         lidx = math.ceil(math.log2(self.levels))
-        idx_o = [] # store the array of indices
+        idx_o = []  # store the array of indices
         for j in range(self.levels):
             i = Signal(lidx, name="idxo_%d" % j, reset_less=True)
             idx_o.append(i)
@@ -160,10 +161,10 @@ class MultiPriorityPicker(Elaboratable):
                 p_mask = Const(0, self.wid)
             else:
                 mask = Signal(self.wid, name="m_%d" % j, reset_less=True)
-                comb += mask.eq(prev_pp.o | p_mask) # accumulate output bits
+                comb += mask.eq(prev_pp.o | p_mask)  # accumulate output bits
                 comb += pp.i.eq(i & ~mask)          # mask out input
                 p_mask = mask
-            i = pp.i # for input to next round
+            i = pp.i  # for input to next round
             prev_pp = pp
 
         # accumulate the enables
index 1706e97c076d6abecb61251d167faa26d16722af..455a2040fb869ff8fb5c97770da938d6566b9400 100644 (file)
@@ -16,8 +16,9 @@ from nmutil.singlepipe import StageChain
 class PipeModBase(Elaboratable):
     """PipeModBase: common code between nearly every pipeline module
     """
+
     def __init__(self, pspec, modname):
-        self.modname = modname # use this to give a name to this module
+        self.modname = modname  # use this to give a name to this module
         self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
@@ -39,6 +40,7 @@ class PipeModBaseChain(DynamicPipe):
     and uses pspec.pipekls to dynamically select the pipeline type
     Also conforms to the Pipeline Stage API
     """
+
     def __init__(self, pspec):
         self.pspec = pspec
         self.chain = self.get_chain()
@@ -55,10 +57,10 @@ class PipeModBaseChain(DynamicPipe):
         return self.chain[-1].ospec()
 
     def process(self, i):
-        return self.o # ... returned here (see setup comment below)
+        return self.o  # ... returned here (see setup comment below)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
-        StageChain(self.chain).setup(m, i) # input linked here, through chain
-        self.o = self.chain[-1].o # output is the last thing in the chain...
+        StageChain(self.chain).setup(m, i)  # input linked here, through chain
+        self.o = self.chain[-1].o  # output is the last thing in the chain...
index 4f07a88560c800a9f5eaf6618ed0fc029f3f6681..5dabd14e2e93bd65cf5596cd243d2bdc21f66273 100644 (file)
@@ -63,7 +63,7 @@ class PLRU(Elaboratable):
                     shift = LOG_TLB - lvl
                     new_idx = Const(~((i >> (shift-1)) & 1), 1)
                     plru_idx = idx_base + (i >> shift)
-                    #print("plru", i, lvl, hex(idx_base),
+                    # print("plru", i, lvl, hex(idx_base),
                     #      plru_idx, shift, new_idx)
                     m.d.sync += plru_tree[plru_idx].eq(new_idx)
 
@@ -91,8 +91,8 @@ class PLRU(Elaboratable):
                 new_idx = (i >> (shift-1)) & 1
                 plru_idx = idx_base + (i >> shift)
                 plru = Signal(reset_less=True,
-                              name="plru-%d-%d-%d-%d" % \
-                                    (i, lvl, plru_idx, new_idx))
+                              name="plru-%d-%d-%d-%d" %
+                              (i, lvl, plru_idx, new_idx))
                 m.d.comb += plru.eq(plru_tree[plru_idx])
                 if new_idx:
                     en.append(~plru)  # yes inverted (using bool() below)
@@ -134,8 +134,8 @@ class PLRUs(Elaboratable):
         comb += te.n.eq(~self.valid)
         comb += te.i.eq(self.index)
 
-        out = Array(Signal(self.n_bits, name="plru_out%d" % x) \
-                             for x in range(self.n_plrus))
+        out = Array(Signal(self.n_bits, name="plru_out%d" % x)
+                    for x in range(self.n_plrus))
 
         for i in range(self.n_plrus):
             # PLRU interface
@@ -160,10 +160,7 @@ if __name__ == '__main__':
     with open("test_plru.il", "w") as f:
         f.write(vl)
 
-
     dut = PLRUs(4, 2)
     vl = rtlil.convert(dut, ports=dut.ports())
     with open("test_plrus.il", "w") as f:
         f.write(vl)
-
-
index 7bd75a6c721e300e302d2c1d288b8cff5f22e1a7..f205e4710990bdd310033b5a34c459d44c3c4376 100644 (file)
@@ -74,17 +74,19 @@ class Queue(FIFOInterface, Elaboratable):
         # deq is "dequeue" (data out, aka "next stage")
         p_o_ready = self.w_rdy
         p_i_valid = self.w_en
-        enq_data = self.w_data # aka p_i_data
+        enq_data = self.w_data  # aka p_i_data
 
         n_o_valid = self.r_rdy
         n_i_ready = self.r_en
-        deq_data = self.r_data # aka n_o_data
+        deq_data = self.r_data  # aka n_o_data
 
         # intermediaries
         ptr_width = bits_for(self.depth - 1) if self.depth > 1 else 0
-        enq_ptr = Signal(ptr_width) # cyclic pointer to "insert" point (wrport)
-        deq_ptr = Signal(ptr_width) # cyclic pointer to "remove" point (rdport)
-        maybe_full = Signal() # not reset_less (set by sync)
+        # cyclic pointer to "insert" point (wrport)
+        enq_ptr = Signal(ptr_width)
+        # cyclic pointer to "remove" point (rdport)
+        deq_ptr = Signal(ptr_width)
+        maybe_full = Signal()  # not reset_less (set by sync)
 
         # temporaries
         do_enq = Signal(reset_less=True)
@@ -96,17 +98,17 @@ class Queue(FIFOInterface, Elaboratable):
         enq_max = Signal(reset_less=True)
         deq_max = Signal(reset_less=True)
 
-        m.d.comb += [ptr_match.eq(enq_ptr == deq_ptr), # read-ptr = write-ptr
+        m.d.comb += [ptr_match.eq(enq_ptr == deq_ptr),  # read-ptr = write-ptr
                      ptr_diff.eq(enq_ptr - deq_ptr),
                      enq_max.eq(enq_ptr == self.depth - 1),
                      deq_max.eq(deq_ptr == self.depth - 1),
                      empty.eq(ptr_match & ~maybe_full),
                      full.eq(ptr_match & maybe_full),
-                     do_enq.eq(p_o_ready & p_i_valid), # write conditions ok
-                     do_deq.eq(n_i_ready & n_o_valid), # read conditions ok
+                     do_enq.eq(p_o_ready & p_i_valid),  # write conditions ok
+                     do_deq.eq(n_i_ready & n_o_valid),  # read conditions ok
 
                      # set r_rdy and w_rdy (NOTE: see pipe mode below)
-                     n_o_valid.eq(~empty), # cannot read if empty!
+                     n_o_valid.eq(~empty),  # cannot read if empty!
                      p_o_ready.eq(~full),  # cannot write if full!
 
                      # set up memory and connect to input and output
@@ -114,8 +116,9 @@ class Queue(FIFOInterface, Elaboratable):
                      ram_write.data.eq(enq_data),
                      ram_write.en.eq(do_enq),
                      ram_read.addr.eq(deq_ptr),
-                     deq_data.eq(ram_read.data) # NOTE: overridden in fwft mode
-                    ]
+                     # NOTE: overridden in fwft mode
+                     deq_data.eq(ram_read.data)
+                     ]
 
         # under write conditions, SRAM write-pointer moves on next clock
         with m.If(do_enq):
index 363099532fbcdd3303f3431d05872abdf7dcca60..6b40d43a5ba8e5043c8eabbcd181d09634265a2a 100644 (file)
@@ -30,6 +30,7 @@ class Ripple(Elaboratable):
         results_in => 0 0 1 0 1 0 0 1
         output     => 1 1 1 0 0 1 1 1
     """
+
     def __init__(self, width, start_lsb=True):
         self.width = width
         self.start_lsb = start_lsb
@@ -43,13 +44,15 @@ class Ripple(Elaboratable):
         width = self.width
 
         results_in = list(self.results_in)
-        if not self.start_lsb: results_in = reversed(results_in)
+        if not self.start_lsb:
+            results_in = reversed(results_in)
         l = [results_in[0]]
 
         for i in range(width-1):
             l.append(Mux(self.gates[i], results_in[i+1], self.output[i]))
 
-        if not self.start_lsb: l = reversed(l)
+        if not self.start_lsb:
+            l = reversed(l)
         comb += self.output.eq(Cat(*l))
 
         return m
@@ -61,6 +64,7 @@ class RippleLSB(Ripple):
     based on a partition mask, the LSB is "rippled" (duplicated)
     up to the beginning of the next partition.
     """
+
     def __init__(self, width):
         Ripple.__init__(self, width, start_lsb=True)
 
@@ -71,6 +75,7 @@ class RippleMSB(Ripple):
     based on a partition mask, the MSB is "rippled" (duplicated)
     down to the beginning of the next partition.
     """
+
     def __init__(self, width):
         Ripple.__init__(self, width, start_lsb=True)
 
@@ -84,6 +89,7 @@ class MoveMSBDown(Elaboratable):
     into its own useful module), then ANDs the (new) LSB with the
     partition mask to isolate it.
     """
+
     def __init__(self, width):
         self.width = width
         self.results_in = Signal(width, reset_less=True)
@@ -97,14 +103,14 @@ class MoveMSBDown(Elaboratable):
         intermed = Signal(width, reset_less=True)
 
         # first propagate MSB down until the nearest partition gate
-        comb += intermed[-1].eq(self.results_in[-1]) # start at MSB
+        comb += intermed[-1].eq(self.results_in[-1])  # start at MSB
         for i in range(width-2, -1, -1):
             cur = Mux(self.gates[i], self.results_in[i], intermed[i+1])
             comb += intermed[i].eq(cur)
 
         # now only select those bits where the mask starts
-        out = [intermed[0]] # LSB of first part always set
-        for i in range(width-1): # length of partition gates
+        out = [intermed[0]]  # LSB of first part always set
+        for i in range(width-1):  # length of partition gates
             out.append(self.gates[i] & intermed[i+1])
         comb += self.output.eq(Cat(*out))
 
@@ -116,4 +122,3 @@ if __name__ == "__main__":
     # then check with yosys "read_ilang ripple.il; show top"
     alu = MoveMSBDown(width=4)
     main(alu, ports=[alu.results_in, alu.gates, alu.output])
-
index a90b6e78c5139153b7ab9e01ff1e56c25fcae2d4..21ecb743e8ac94f9ab531378f09f856323f58771 100644 (file)
@@ -41,7 +41,7 @@ except ImportError:
                                        Delay, Settle, Tick, Passive)
 
 nmigen_sim_environ_variable = os.environ.get("NMIGEN_SIM_MODE") \
-                              or "pysim"
+    or "pysim"
 """Detected run-time engine from environment"""
 
 
index 9d7e154ab1cbb30b2207dd58e4cf597f24be6c9f..3fae364960e19e8553bbdef34a9048653ab00b00 100644 (file)
@@ -160,11 +160,13 @@ class RecordBasedStage(Stage):
         honestly it's a lot easier just to create a direct Records-based
         class (see ExampleAddRecordStage)
     """
+
     def __init__(self, in_shape, out_shape, processfn, setupfn=None):
         self.in_shape = in_shape
         self.out_shape = out_shape
         self.__process = processfn
         self.__setup = setupfn
+
     def ispec(self): return Record(self.in_shape)
     def ospec(self): return Record(self.out_shape)
     def process(seif, i): return self.__process(i)
@@ -179,6 +181,7 @@ class PassThroughStage(StageCls):
         (many APIs would potentially use a static "wrap" method in e.g.
          StageCls to achieve a similar effect)
     """
+
     def __init__(self, iospecfn): self.iospecfn = iospecfn
     def ispec(self): return self.iospecfn()
     def ospec(self): return self.iospecfn()
@@ -194,6 +197,7 @@ class ControlBase(StageHelper, Elaboratable):
         *BYPASSES* a ControlBase instance ready/valid signalling, which
         clearly should not be done without a really, really good reason.
     """
+
     def __init__(self, stage=None, in_multi=None, stage_ctl=False, maskwid=0):
         """ Base class containing ready/valid/data to previous and next stages
 
@@ -205,7 +209,7 @@ class ControlBase(StageHelper, Elaboratable):
             * add o_data member to NextControl (n)
             Calling ControlBase._new_data is a good way to do that.
         """
-        print ("ControlBase", self, stage, in_multi, stage_ctl)
+        print("ControlBase", self, stage, in_multi, stage_ctl)
         StageHelper.__init__(self, stage)
 
         # set up input and output IO ACK (prev/next ready/valid)
@@ -284,19 +288,19 @@ class ControlBase(StageHelper, Elaboratable):
         """
         assert len(pipechain) > 0, "pipechain must be non-zero length"
         assert self.stage is None, "do not use connect with a stage"
-        eqs = [] # collated list of assignment statements
+        eqs = []  # collated list of assignment statements
 
         # connect inter-chain
         for i in range(len(pipechain)-1):
             pipe1 = pipechain[i]                # earlier
             pipe2 = pipechain[i+1]              # later (by 1)
-            eqs += pipe1.connect_to_next(pipe2) # earlier n to later p
+            eqs += pipe1.connect_to_next(pipe2)  # earlier n to later p
 
         # connect front and back of chain to ourselves
         front = pipechain[0]                # first in chain
         end = pipechain[-1]                 # last in chain
-        self.set_specs(front, end) # sets up ispec/ospec functions
-        self._new_data("chain") # NOTE: REPLACES existing data
+        self.set_specs(front, end)  # sets up ispec/ospec functions
+        self._new_data("chain")  # NOTE: REPLACES existing data
         eqs += front._connect_in(self)      # front p to our p
         eqs += end._connect_out(self)       # end n   to our n
 
@@ -308,8 +312,8 @@ class ControlBase(StageHelper, Elaboratable):
         return nmoperator.eq(self.p.i_data, i)
 
     def __iter__(self):
-        yield from self.p # yields ready/valid/data (data also gets yielded)
-        yield from self.n # ditto
+        yield from self.p  # yields ready/valid/data (data also gets yielded)
+        yield from self.n  # ditto
 
     def ports(self):
         return list(self)
@@ -383,36 +387,39 @@ class BufferedHandshake(ControlBase):
         por_pivn = Signal(reset_less=True)
         npnn = Signal(reset_less=True)
         self.m.d.comb += [p_i_valid.eq(self.p.i_valid_test),
-                     o_n_validn.eq(~self.n.o_valid),
-                     n_i_ready.eq(self.n.i_ready_test),
-                     nir_por.eq(n_i_ready & self.p._o_ready),
-                     nir_por_n.eq(n_i_ready & ~self.p._o_ready),
-                     nir_novn.eq(n_i_ready | o_n_validn),
-                     nirn_novn.eq(~n_i_ready & o_n_validn),
-                     npnn.eq(nir_por | nirn_novn),
-                     por_pivn.eq(self.p._o_ready & ~p_i_valid)
-        ]
+                          o_n_validn.eq(~self.n.o_valid),
+                          n_i_ready.eq(self.n.i_ready_test),
+                          nir_por.eq(n_i_ready & self.p._o_ready),
+                          nir_por_n.eq(n_i_ready & ~self.p._o_ready),
+                          nir_novn.eq(n_i_ready | o_n_validn),
+                          nirn_novn.eq(~n_i_ready & o_n_validn),
+                          npnn.eq(nir_por | nirn_novn),
+                          por_pivn.eq(self.p._o_ready & ~p_i_valid)
+                          ]
 
         # store result of processing in combinatorial temporary
         self.m.d.comb += nmoperator.eq(result, self.data_r)
 
         # if not in stall condition, update the temporary register
-        with self.m.If(self.p.o_ready): # not stalled
-            self.m.d.sync += nmoperator.eq(r_data, result) # update buffer
+        with self.m.If(self.p.o_ready):  # not stalled
+            self.m.d.sync += nmoperator.eq(r_data, result)  # update buffer
 
         # data pass-through conditions
         with self.m.If(npnn):
-            o_data = self._postprocess(result) # XXX TBD, does nothing right now
-            self.m.d.sync += [self.n.o_valid.eq(p_i_valid), # valid if p_valid
-                              nmoperator.eq(self.n.o_data, o_data), # update out
-                             ]
+            # XXX TBD, does nothing right now
+            o_data = self._postprocess(result)
+            self.m.d.sync += [self.n.o_valid.eq(p_i_valid),  # valid if p_valid
+                              # update out
+                              nmoperator.eq(self.n.o_data, o_data),
+                              ]
         # buffer flush conditions (NOTE: can override data passthru conditions)
-        with self.m.If(nir_por_n): # not stalled
+        with self.m.If(nir_por_n):  # not stalled
             # Flush the [already processed] buffer to the output port.
-            o_data = self._postprocess(r_data) # XXX TBD, does nothing right now
+            # XXX TBD, does nothing right now
+            o_data = self._postprocess(r_data)
             self.m.d.sync += [self.n.o_valid.eq(1),  # reg empty
-                              nmoperator.eq(self.n.o_data, o_data), # flush
-                             ]
+                              nmoperator.eq(self.n.o_data, o_data),  # flush
+                              ]
         # output ready conditions
         self.m.d.sync += self.p._o_ready.eq(nir_novn | por_pivn)
 
@@ -433,6 +440,7 @@ class MaskNoDelayCancellable(ControlBase):
                               |             |
                               +--process->--^
     """
+
     def __init__(self, stage, maskwid, in_multi=None, stage_ctl=False):
         ControlBase.__init__(self, stage, in_multi, stage_ctl, maskwid)
 
@@ -459,8 +467,9 @@ class MaskNoDelayCancellable(ControlBase):
         m.d.sync += self.n.o_valid.eq(p_i_valid)
         m.d.sync += self.n.mask_o.eq(Mux(p_i_valid, maskedout, 0))
         with m.If(p_i_valid):
-            o_data = self._postprocess(result) # XXX TBD, does nothing right now
-            m.d.sync += nmoperator.eq(self.n.o_data, o_data) # update output
+            # XXX TBD, does nothing right now
+            o_data = self._postprocess(result)
+            m.d.sync += nmoperator.eq(self.n.o_data, o_data)  # update output
 
         # output valid if
         # input always "ready"
@@ -492,8 +501,9 @@ class MaskCancellable(ControlBase):
                               |             |
                               +--process->--^
     """
+
     def __init__(self, stage, maskwid, in_multi=None, stage_ctl=False,
-                       dynamic=False):
+                 dynamic=False):
         ControlBase.__init__(self, stage, in_multi, stage_ctl, maskwid)
         self.dynamic = dynamic
         if dynamic:
@@ -525,7 +535,7 @@ class MaskCancellable(ControlBase):
             m.d.comb += [p_i_valid.eq(self.p.i_valid_test & maskedout.bool()),
                          n_i_ready.eq(self.n.i_ready_test),
                          p_i_valid_p_o_ready.eq(p_i_valid & self.p.o_ready),
-            ]
+                         ]
 
             # if idmask nonzero, mask gets passed on (and register set).
             # register is left as-is if idmask is zero, but out-mask is set to
@@ -548,7 +558,7 @@ class MaskCancellable(ControlBase):
                 m.d.sync += r_busy.eq(1)      # output valid
             # previous invalid or not ready, however next is accepting
             with m.Elif(n_i_ready):
-                m.d.sync += r_busy.eq(0) # ...so set output invalid
+                m.d.sync += r_busy.eq(0)  # ...so set output invalid
 
             # output set combinatorially from latch
             m.d.comb += nmoperator.eq(self.n.o_data, r_latch)
@@ -627,24 +637,26 @@ class SimpleHandshake(ControlBase):
         m.d.comb += [p_i_valid.eq(self.p.i_valid_test),
                      n_i_ready.eq(self.n.i_ready_test),
                      p_i_valid_p_o_ready.eq(p_i_valid & self.p.o_ready),
-        ]
+                     ]
 
         # store result of processing in combinatorial temporary
         m.d.comb += nmoperator.eq(result, self.data_r)
 
         # previous valid and ready
         with m.If(p_i_valid_p_o_ready):
-            o_data = self._postprocess(result) # XXX TBD, does nothing right now
+            # XXX TBD, does nothing right now
+            o_data = self._postprocess(result)
             m.d.sync += [r_busy.eq(1),      # output valid
-                         nmoperator.eq(self.n.o_data, o_data), # update output
-                        ]
+                         nmoperator.eq(self.n.o_data, o_data),  # update output
+                         ]
         # previous invalid or not ready, however next is accepting
         with m.Elif(n_i_ready):
-            o_data = self._postprocess(result) # XXX TBD, does nothing right now
+            # XXX TBD, does nothing right now
+            o_data = self._postprocess(result)
             m.d.sync += [nmoperator.eq(self.n.o_data, o_data)]
             # TODO: could still send data here (if there was any)
-            #m.d.sync += self.n.o_valid.eq(0) # ...so set output invalid
-            m.d.sync += r_busy.eq(0) # ...so set output invalid
+            # m.d.sync += self.n.o_valid.eq(0) # ...so set output invalid
+            m.d.sync += r_busy.eq(0)  # ...so set output invalid
 
         m.d.comb += self.n.o_valid.eq(r_busy)
         # if next is ready, so is previous
@@ -725,8 +737,8 @@ class UnbufferedPipeline(ControlBase):
     def elaborate(self, platform):
         self.m = m = ControlBase.elaborate(self, platform)
 
-        data_valid = Signal() # is data valid or not
-        r_data = _spec(self.stage.ospec, "r_tmp") # output type
+        data_valid = Signal()  # is data valid or not
+        r_data = _spec(self.stage.ospec, "r_tmp")  # output type
 
         # some temporaries
         p_i_valid = Signal(reset_less=True)
@@ -742,7 +754,7 @@ class UnbufferedPipeline(ControlBase):
 
         with m.If(pv):
             m.d.sync += nmoperator.eq(r_data, self.data_r)
-        o_data = self._postprocess(r_data) # XXX TBD, does nothing right now
+        o_data = self._postprocess(r_data)  # XXX TBD, does nothing right now
         m.d.comb += nmoperator.eq(self.n.o_data, o_data)
 
         return self.m
@@ -812,8 +824,8 @@ class UnbufferedPipeline2(ControlBase):
     def elaborate(self, platform):
         self.m = m = ControlBase.elaborate(self, platform)
 
-        buf_full = Signal() # is data valid or not
-        buf = _spec(self.stage.ospec, "r_tmp") # output type
+        buf_full = Signal()  # is data valid or not
+        buf = _spec(self.stage.ospec, "r_tmp")  # output type
 
         # some temporaries
         p_i_valid = Signal(reset_less=True)
@@ -824,7 +836,7 @@ class UnbufferedPipeline2(ControlBase):
         m.d.sync += buf_full.eq(~self.n.i_ready_test & self.n.o_valid)
 
         o_data = Mux(buf_full, buf, self.data_r)
-        o_data = self._postprocess(o_data) # XXX TBD, does nothing right now
+        o_data = self._postprocess(o_data)  # XXX TBD, does nothing right now
         m.d.comb += nmoperator.eq(self.n.o_data, o_data)
         m.d.sync += nmoperator.eq(buf, self.n.o_data)
 
@@ -867,7 +879,7 @@ class PassThroughHandshake(ControlBase):
     def elaborate(self, platform):
         self.m = m = ControlBase.elaborate(self, platform)
 
-        r_data = _spec(self.stage.ospec, "r_tmp") # output type
+        r_data = _spec(self.stage.ospec, "r_tmp")  # output type
 
         # temporaries
         p_i_valid = Signal(reset_less=True)
@@ -875,12 +887,12 @@ class PassThroughHandshake(ControlBase):
         m.d.comb += p_i_valid.eq(self.p.i_valid_test)
         m.d.comb += pvr.eq(p_i_valid & self.p.o_ready)
 
-        m.d.comb += self.p.o_ready.eq(~self.n.o_valid |  self.n.i_ready_test)
-        m.d.sync += self.n.o_valid.eq(p_i_valid       | ~self.p.o_ready)
+        m.d.comb += self.p.o_ready.eq(~self.n.o_valid | self.n.i_ready_test)
+        m.d.sync += self.n.o_valid.eq(p_i_valid | ~self.p.o_ready)
 
         odata = Mux(pvr, self.data_r, r_data)
         m.d.sync += nmoperator.eq(r_data, odata)
-        r_data = self._postprocess(r_data) # XXX TBD, does nothing right now
+        r_data = self._postprocess(r_data)  # XXX TBD, does nothing right now
         m.d.comb += nmoperator.eq(self.n.o_data, r_data)
 
         return m
@@ -891,6 +903,7 @@ class RegisterPipeline(UnbufferedPipeline):
         sync'd latch out of o_data and o_valid as an indirect byproduct
         of using PassThroughStage
     """
+
     def __init__(self, iospecfn):
         UnbufferedPipeline.__init__(self, PassThroughStage(iospecfn))
 
@@ -901,8 +914,9 @@ class FIFOControl(ControlBase):
 
         i_data -> fifo.din -> FIFO -> fifo.dout -> o_data
     """
+
     def __init__(self, depth, stage, in_multi=None, stage_ctl=False,
-                                     fwft=True, pipe=False):
+                 fwft=True, pipe=False):
         """ FIFO Control
 
             * :depth: number of entries in the FIFO
@@ -948,24 +962,25 @@ class FIFOControl(ControlBase):
             m.d.comb += nmoperator.eq(result, self.process(i_data))
             return nmoperator.cat(result)
 
-        ## prev: make the FIFO (Queue object) "look" like a PrevControl...
+        # prev: make the FIFO (Queue object) "look" like a PrevControl...
         m.submodules.fp = fp = PrevControl()
         fp.i_valid, fp._o_ready, fp.i_data = fifo.w_en, fifo.w_rdy, fifo.w_data
         m.d.comb += fp._connect_in(self.p, fn=processfn)
 
         # next: make the FIFO (Queue object) "look" like a NextControl...
         m.submodules.fn = fn = NextControl()
-        fn.o_valid, fn.i_ready, fn.o_data  = fifo.r_rdy, fifo.r_en, fifo.r_data
+        fn.o_valid, fn.i_ready, fn.o_data = fifo.r_rdy, fifo.r_en, fifo.r_data
         connections = fn._connect_out(self.n, fn=nmoperator.cat)
         valid_eq, ready_eq, o_data = connections
 
         # ok ok so we can't just do the ready/valid eqs straight:
         # first 2 from connections are the ready/valid, 3rd is data.
         if self.fwft:
-            m.d.comb += [valid_eq, ready_eq] # combinatorial on next ready/valid
+            # combinatorial on next ready/valid
+            m.d.comb += [valid_eq, ready_eq]
         else:
-            m.d.sync += [valid_eq, ready_eq] # non-fwft mode needs sync
-        o_data = self._postprocess(o_data) # XXX TBD, does nothing right now
+            m.d.sync += [valid_eq, ready_eq]  # non-fwft mode needs sync
+        o_data = self._postprocess(o_data)  # XXX TBD, does nothing right now
         m.d.comb += o_data
 
         return m
@@ -975,19 +990,23 @@ class FIFOControl(ControlBase):
 class UnbufferedPipeline(FIFOControl):
     def __init__(self, stage, in_multi=None, stage_ctl=False):
         FIFOControl.__init__(self, 1, stage, in_multi, stage_ctl,
-                                   fwft=True, pipe=False)
+                             fwft=True, pipe=False)
 
 # aka "BreakReadyStage" XXX had to set fwft=True to get it to work
+
+
 class PassThroughHandshake(FIFOControl):
     def __init__(self, stage, in_multi=None, stage_ctl=False):
         FIFOControl.__init__(self, 1, stage, in_multi, stage_ctl,
-                                   fwft=True, pipe=True)
+                             fwft=True, pipe=True)
 
 # this is *probably* BufferedHandshake, although test #997 now succeeds.
+
+
 class BufferedHandshake(FIFOControl):
     def __init__(self, stage, in_multi=None, stage_ctl=False):
         FIFOControl.__init__(self, 2, stage, in_multi, stage_ctl,
-                                   fwft=True, pipe=False)
+                             fwft=True, pipe=False)
 
 
 """
index fc5d709f43809a8d5ae34a5ebe61486264db1a62..bc79071046b5d358e4c9c005b9704be3c48f2ff8 100644 (file)
@@ -118,10 +118,10 @@ class StageCls(metaclass=ABCMeta):
     def ispec(self): pass       # REQUIRED
     @abstractmethod
     def ospec(self): pass       # REQUIRED
-    #@abstractmethod
-    #def setup(self, m, i): pass # OPTIONAL
-    #@abstractmethod
-    #def process(self, i): pass  # OPTIONAL
+    # @abstractmethod
+    # def setup(self, m, i): pass # OPTIONAL
+    # @abstractmethod
+    # def process(self, i): pass  # OPTIONAL
 
 
 class Stage(metaclass=ABCMeta):
@@ -140,12 +140,12 @@ class Stage(metaclass=ABCMeta):
     @abstractmethod
     def ospec(): pass
 
-    #@staticmethod
-    #@abstractmethod
+    # @staticmethod
+    # @abstractmethod
     #def setup(m, i): pass
 
-    #@staticmethod
-    #@abstractmethod
+    # @staticmethod
+    # @abstractmethod
     #def process(i): pass
 
 
@@ -157,6 +157,7 @@ class StageHelper(Stage):
         it differs from the stage that it wraps in that all the "optional"
         functions are provided (hence the designation "convenience wrapper")
     """
+
     def __init__(self, stage):
         self.stage = stage
         self._ispecfn = None
@@ -197,8 +198,8 @@ class StageHelper(Stage):
         if self.stage is not None and hasattr(self.stage, "setup"):
             self.stage.setup(m, i)
 
-    def _postprocess(self, i): # XXX DISABLED
-        return i # RETURNS INPUT
+    def _postprocess(self, i):  # XXX DISABLED
+        return i  # RETURNS INPUT
         if hasattr(self.stage, "postprocess"):
             return self.stage.postprocess(i)
         return i
@@ -243,6 +244,7 @@ class StageChain(StageHelper):
         side-effects (state-based / clock-based input) or conditional
         (inter-chain) dependencies, unless you really know what you are doing.
     """
+
     def __init__(self, chain, specallocate=False):
         assert len(chain) > 0, "stage chain must be non-zero length"
         self.chain = chain
@@ -262,12 +264,13 @@ class StageChain(StageHelper):
             o = _spec(ofn, cname)
             if isinstance(o, Elaboratable):
                 setattr(m.submodules, cname, o)
-            m.d.comb += nmoperator.eq(o, c.process(i)) # process input into "o"
+            # process input into "o"
+            m.d.comb += nmoperator.eq(o, c.process(i))
             if idx == len(self.chain)-1:
                 break
             ifn = self.chain[idx+1].ispec   # new input on next loop
             i = _spec(ifn, 'chainin%d' % (idx+1))
-            m.d.comb += nmoperator.eq(i, o) # assign to next input
+            m.d.comb += nmoperator.eq(i, o)  # assign to next input
         self.o = o
         return self.o                       # last loop is the output
 
@@ -280,6 +283,4 @@ class StageChain(StageHelper):
         return self.o                       # last loop is the output
 
     def process(self, i):
-        return self.o # conform to Stage API: return last-loop output
-
-
+        return self.o  # conform to Stage API: return last-loop output
index 61e9b1346e5cb1cf7402dd27b1393561cd710b0c..823a999b52052a7a11e5ddb1c845b127f1ffae22 100644 (file)
@@ -4,8 +4,8 @@
 from nmutil.nmoperator import eq
 from nmutil.iocontrol import (PrevControl, NextControl)
 from nmutil.singlepipe import (PrevControl, NextControl, ControlBase,
-                        StageCls, Stage, StageChain,
-                        BufferedHandshake, UnbufferedPipeline)
+                               StageCls, Stage, StageChain,
+                               BufferedHandshake, UnbufferedPipeline)
 
 from nmigen import Signal, Module
 from nmigen.cli import verilog, rtlil
index 21fc4911f8ca1935358885825f77926e0911905e..c01bfac366da498dadb5537221ee6a08dd81fc67 100644 (file)
@@ -28,6 +28,7 @@ class Shifter(Elaboratable):
 
         * ``n_o_valid`` and ``n_i_ready``: handshake
     """
+
     def __init__(self, width):
         self.width = width
         """data width"""
index 14e34726720bebb2864a2e8f733d273680e14432..e9b893b62df9be8cb086fa9b0496e8416d2eba8f 100644 (file)
@@ -16,7 +16,6 @@ class CLZTestCase(unittest.TestCase):
         sig_in = Signal.like(dut.sig_in)
         count = Signal.like(dut.lz)
 
-
         m.d.comb += [
             dut.sig_in.eq(sig_in),
             count.eq(dut.lz)]
index a9fd4160668f102b5e8db8ab0c52bd89e410ce15..149c6a5c05e473946df980ff404142fe56fd4d6e 100644 (file)
@@ -32,16 +32,15 @@ class PassData(Object):
         self.data = Signal(16, reset_less=True)
 
 
-
 class PassThroughStage:
     def ispec(self):
         return PassData()
+
     def ospec(self):
-        return self.ispec() # same as ospec
+        return self.ispec()  # same as ospec
 
     def process(self, i):
-        return i # pass-through
-
+        return i  # pass-through
 
 
 class PassThroughPipe(SimpleHandshake):
@@ -59,7 +58,7 @@ class InputTest:
             self.di[muxid] = {}
             self.do[muxid] = {}
             for i in range(self.tlen):
-                self.di[muxid][i] = randint(0, 255) + (muxid<<8)
+                self.di[muxid][i] = randint(0, 255) + (muxid << 8)
                 self.do[muxid][i] = self.di[muxid][i]
 
     def send(self, muxid):
@@ -76,7 +75,7 @@ class InputTest:
                 yield
                 o_p_ready = yield rs.o_ready
 
-            print ("send", muxid, i, hex(op2))
+            print("send", muxid, i, hex(op2))
 
             yield rs.i_valid.eq(0)
             # wait random period of time before queueing another value
@@ -86,22 +85,22 @@ class InputTest:
         yield rs.i_valid.eq(0)
         yield
 
-        print ("send ended", muxid)
+        print("send ended", muxid)
 
-        ## wait random period of time before queueing another value
-        #for i in range(randint(0, 3)):
+        # wait random period of time before queueing another value
+        # for i in range(randint(0, 3)):
         #    yield
 
         #send_range = randint(0, 3)
-        #if send_range == 0:
+        # if send_range == 0:
         #    send = True
-        #else:
+        # else:
         #    send = randint(0, send_range) != 0
 
     def rcv(self, muxid):
         while True:
             #stall_range = randint(0, 3)
-            #for j in range(randint(1,10)):
+            # for j in range(randint(1,10)):
             #    stall = randint(0, stall_range) != 0
             #    yield self.dut.n[0].i_ready.eq(stall)
             #    yield
@@ -117,20 +116,20 @@ class InputTest:
             out_i = yield n.o_data.idx
             out_v = yield n.o_data.data
 
-            print ("recv", out_muxid, out_i, hex(out_v))
+            print("recv", out_muxid, out_i, hex(out_v))
 
             # see if this output has occurred already, delete it if it has
             assert muxid == out_muxid, \
-                    "out_muxid %d not correct %d" % (out_muxid, muxid)
+                "out_muxid %d not correct %d" % (out_muxid, muxid)
             assert out_i in self.do[muxid], "out_i %d not in array %s" % \
-                                          (out_i, repr(self.do[muxid]))
-            assert self.do[muxid][out_i] == out_v # pass-through data
+                (out_i, repr(self.do[muxid]))
+            assert self.do[muxid][out_i] == out_v  # pass-through data
             del self.do[muxid][out_i]
 
             # check if there's any more outputs
             if len(self.do[muxid]) == 0:
                 break
-        print ("recv ended", muxid)
+        print("recv ended", muxid)
 
 
 class TestPriorityMuxPipe(PriorityCombMuxInPipe):
@@ -151,7 +150,7 @@ class OutputTest:
                 muxid = i
             else:
                 muxid = randint(0, dut.num_rows-1)
-            data = randint(0, 255) + (muxid<<8)
+            data = randint(0, 255) + (muxid << 8)
 
     def send(self):
         for i in range(self.tlen * dut.num_rows):
@@ -167,7 +166,7 @@ class OutputTest:
                 yield
                 o_p_ready = yield rs.o_ready
 
-            print ("send", muxid, i, hex(op2))
+            print("send", muxid, i, hex(op2))
 
             yield rs.i_valid.eq(0)
             # wait random period of time before queueing another value
@@ -187,13 +186,13 @@ class TestMuxOutPipe(CombMuxOutPipe):
 class TestInOutPipe(Elaboratable):
     def __init__(self, num_rows=4):
         self.num_rows = num_rows
-        self.inpipe = TestPriorityMuxPipe(num_rows) # fan-in (combinatorial)
+        self.inpipe = TestPriorityMuxPipe(num_rows)  # fan-in (combinatorial)
         self.pipe1 = PassThroughPipe()              # stage 1 (clock-sync)
         self.pipe2 = PassThroughPipe()              # stage 2 (clock-sync)
         self.outpipe = TestMuxOutPipe(num_rows)     # fan-out (combinatorial)
 
         self.p = self.inpipe.p  # kinda annoying,
-        self.n = self.outpipe.n # use pipe in/out as this class in/out
+        self.n = self.outpipe.n  # use pipe in/out as this class in/out
         self._ports = self.inpipe.ports() + self.outpipe.ports()
 
     def elaborate(self, platform):
@@ -225,8 +224,9 @@ def test1():
                          test.rcv(3), test.rcv(2),
                          test.send(0), test.send(1),
                          test.send(3), test.send(2),
-                        ],
+                         ],
                    vcd_name="test_inoutmux_pipe.vcd")
 
+
 if __name__ == '__main__':
     test1()
index e843d5987841cd7e0595342f56872753e9c777f7..fd0570c744f63772921f9074e979faf9978a8fda 100644 (file)
@@ -33,16 +33,15 @@ class PassData(Object):
         self.data = Signal(16, reset_less=True)
 
 
-
 class PassThroughStage:
     def ispec(self):
         return PassData()
+
     def ospec(self):
-        return self.ispec() # same as ospec
+        return self.ispec()  # same as ospec
 
     def process(self, i):
-        return i # pass-through
-
+        return i  # pass-through
 
 
 class PassThroughPipe(MaskCancellable):
@@ -62,7 +61,7 @@ class InputTest:
             self.do[muxid] = {}
             self.sent[muxid] = []
             for i in range(self.tlen):
-                self.di[muxid][i] = randint(0, 255) + (muxid<<8)
+                self.di[muxid][i] = randint(0, 255) + (muxid << 8)
                 self.do[muxid][i] = self.di[muxid][i]
 
     def send(self, muxid):
@@ -80,7 +79,7 @@ class InputTest:
                 yield
                 o_p_ready = yield rs.o_ready
 
-            print ("send", muxid, i, hex(op2), op2)
+            print("send", muxid, i, hex(op2), op2)
             self.sent[muxid].append(i)
 
             yield rs.i_valid.eq(0)
@@ -96,16 +95,16 @@ class InputTest:
         yield rs.i_valid.eq(0)
         yield
 
-        print ("send ended", muxid)
+        print("send ended", muxid)
 
-        ## wait random period of time before queueing another value
-        #for i in range(randint(0, 3)):
+        # wait random period of time before queueing another value
+        # for i in range(randint(0, 3)):
         #    yield
 
         #send_range = randint(0, 3)
-        #if send_range == 0:
+        # if send_range == 0:
         #    send = True
-        #else:
+        # else:
         #    send = randint(0, send_range) != 0
 
     def rcv(self, muxid):
@@ -115,16 +114,16 @@ class InputTest:
             # check cancellation
             if self.sent[muxid] and randint(0, 2) == 0:
                 todel = self.sent[muxid].pop()
-                print ("to delete", muxid, self.sent[muxid], todel)
+                print("to delete", muxid, self.sent[muxid], todel)
                 if todel in self.do[muxid]:
                     del self.do[muxid][todel]
                     yield rs.stop_i.eq(1)
-                print ("left", muxid, self.do[muxid])
+                print("left", muxid, self.do[muxid])
                 if len(self.do[muxid]) == 0:
                     break
 
             stall_range = randint(0, 3)
-            for j in range(randint(1,10)):
+            for j in range(randint(1, 10)):
                 stall = randint(0, stall_range) != 0
                 yield self.dut.n[0].i_ready.eq(stall)
                 yield
@@ -132,7 +131,7 @@ class InputTest:
             n = self.dut.n[muxid]
             yield n.i_ready.eq(1)
             yield
-            yield rs.stop_i.eq(0) # resets cancel mask
+            yield rs.stop_i.eq(0)  # resets cancel mask
             o_n_valid = yield n.o_valid
             i_n_ready = yield n.i_ready
             if not o_n_valid or not i_n_ready:
@@ -142,17 +141,17 @@ class InputTest:
             out_i = yield n.o_data.idx
             out_v = yield n.o_data.data
 
-            print ("recv", out_muxid, out_i, hex(out_v), out_v)
+            print("recv", out_muxid, out_i, hex(out_v), out_v)
 
             # see if this output has occurred already, delete it if it has
             assert muxid == out_muxid, \
-                    "out_muxid %d not correct %d" % (out_muxid, muxid)
+                "out_muxid %d not correct %d" % (out_muxid, muxid)
             if out_i not in self.sent[muxid]:
-                print ("cancelled/recv", muxid, out_i)
+                print("cancelled/recv", muxid, out_i)
                 continue
             assert out_i in self.do[muxid], "out_i %d not in array %s" % \
-                                          (out_i, repr(self.do[muxid]))
-            assert self.do[muxid][out_i] == out_v # pass-through data
+                (out_i, repr(self.do[muxid]))
+            assert self.do[muxid][out_i] == out_v  # pass-through data
             del self.do[muxid][out_i]
             todel = self.sent[muxid].index(out_i)
             del self.sent[muxid][todel]
@@ -161,7 +160,7 @@ class InputTest:
             if len(self.do[muxid]) == 0:
                 break
 
-        print ("recv ended", muxid)
+        print("recv ended", muxid)
 
 
 class TestPriorityMuxPipe(PriorityCombMuxInPipe):
@@ -183,7 +182,7 @@ class TestMuxOutPipe(CombMuxOutPipe):
 class TestInOutPipe(Elaboratable):
     def __init__(self, num_rows=4):
         self.num_rows = nr = num_rows
-        self.inpipe = TestPriorityMuxPipe(nr) # fan-in (combinatorial)
+        self.inpipe = TestPriorityMuxPipe(nr)  # fan-in (combinatorial)
         self.pipe1 = PassThroughPipe(nr)      # stage 1 (clock-sync)
         self.pipe2 = PassThroughPipe(nr)      # stage 2 (clock-sync)
         self.pipe3 = PassThroughPipe(nr)      # stage 3 (clock-sync)
@@ -191,7 +190,7 @@ class TestInOutPipe(Elaboratable):
         self.outpipe = TestMuxOutPipe(nr)     # fan-out (combinatorial)
 
         self.p = self.inpipe.p  # kinda annoying,
-        self.n = self.outpipe.n # use pipe in/out as this class in/out
+        self.n = self.outpipe.n  # use pipe in/out as this class in/out
         self._ports = self.inpipe.ports() + self.outpipe.ports()
 
     def elaborate(self, platform):
@@ -228,8 +227,9 @@ def test1():
                          test.rcv(3), test.rcv(2),
                          test.send(0), test.send(1),
                          test.send(3), test.send(2),
-                        ],
+                         ],
                    vcd_name="test_inoutmux_unarycancel_pipe.vcd")
 
+
 if __name__ == '__main__':
     test1()
index d94b6394b55519d3a1f8383f24d3abde4c6e9539..4624a5157d388c3f53d8ede9773a573714fffd60 100644 (file)
@@ -22,7 +22,7 @@ class PassThroughStage:
 
     def ospec(self, name):
         return Signal(16, name="%s_dout" % name, reset_less=True)
-                
+
     def process(self, i):
         return i.data
 
@@ -30,12 +30,12 @@ class PassThroughStage:
 class PassThroughDataStage:
     def ispec(self):
         return PassInData()
+
     def ospec(self):
-        return self.ispec() # same as ospec
+        return self.ispec()  # same as ospec
 
     def process(self, i):
-        return i # pass-through
-
+        return i  # pass-through
 
 
 class PassThroughPipe(PassThroughHandshake):
@@ -54,7 +54,7 @@ class OutputTest:
                 muxid = i
             else:
                 muxid = randint(0, dut.num_rows-1)
-            data = randint(0, 255) + (muxid<<8)
+            data = randint(0, 255) + (muxid << 8)
             if muxid not in self.do:
                 self.do[muxid] = []
             self.di.append((data, muxid))
@@ -74,7 +74,7 @@ class OutputTest:
                 yield
                 o_p_ready = yield rs.o_ready
 
-            print ("send", muxid, i, hex(op2))
+            print("send", muxid, i, hex(op2))
 
             yield rs.i_valid.eq(0)
             # wait random period of time before queueing another value
@@ -100,9 +100,9 @@ class OutputTest:
 
             out_v = yield n.o_data
 
-            print ("recv", muxid, out_i, hex(out_v))
+            print("recv", muxid, out_i, hex(out_v))
 
-            assert self.do[muxid][out_i] == out_v # pass-through data
+            assert self.do[muxid][out_i] == out_v  # pass-through data
 
             out_i += 1
 
@@ -140,11 +140,11 @@ class TestSyncToPriorityPipe(Elaboratable):
 
     def ports(self):
         res = [self.p.i_valid, self.p.o_ready] + \
-                self.p.i_data.ports()
+            self.p.i_data.ports()
         for i in range(len(self.n)):
             res += [self.n[i].i_ready, self.n[i].o_valid] + \
-                    [self.n[i].o_data]
-                    #self.n[i].o_data.ports()
+                [self.n[i].o_data]
+            self.n[i].o_data.ports()
         return res
 
 
@@ -160,5 +160,6 @@ def test1():
                          test.send()],
                    vcd_name="test_outmux_pipe.vcd")
 
+
 if __name__ == '__main__':
     test1()
index 62d2698eeb9cdca7f4b937c8db6df5acde443545..70c8495688046d03f697867b4a7dad31680a95c4 100644 (file)
@@ -33,16 +33,15 @@ class PassData(Object):
         self.data = Signal(16, name="data"+name, reset_less=True)
 
 
-
 class PassThroughStage:
     def ispec(self, name=None):
         return PassData(name=name)
+
     def ospec(self, name=None):
-        return self.ispec(name) # same as ospec
+        return self.ispec(name)  # same as ospec
 
     def process(self, i):
-        return i # pass-through
-
+        return i  # pass-through
 
 
 class PassThroughPipe(SimpleHandshake):
@@ -60,7 +59,7 @@ class InputTest:
             self.di[muxid] = {}
             self.do[muxid] = {}
             for i in range(self.tlen):
-                self.di[muxid][i] = randint(0, 255) + (muxid<<8)
+                self.di[muxid][i] = randint(0, 255) + (muxid << 8)
                 self.do[muxid][i] = self.di[muxid][i]
 
     def send(self, muxid):
@@ -77,7 +76,7 @@ class InputTest:
                 yield
                 o_p_ready = yield rs.o_ready
 
-            print ("send", muxid, i, hex(op2))
+            print("send", muxid, i, hex(op2))
 
             yield rs.i_valid.eq(0)
             # wait random period of time before queueing another value
@@ -87,22 +86,22 @@ class InputTest:
         yield rs.i_valid.eq(0)
         yield
 
-        print ("send ended", muxid)
+        print("send ended", muxid)
 
-        ## wait random period of time before queueing another value
-        #for i in range(randint(0, 3)):
+        # wait random period of time before queueing another value
+        # for i in range(randint(0, 3)):
         #    yield
 
         #send_range = randint(0, 3)
-        #if send_range == 0:
+        # if send_range == 0:
         #    send = True
-        #else:
+        # else:
         #    send = randint(0, send_range) != 0
 
     def rcv(self, muxid):
         while True:
             #stall_range = randint(0, 3)
-            #for j in range(randint(1,10)):
+            # for j in range(randint(1,10)):
             #    stall = randint(0, stall_range) != 0
             #    yield self.dut.n[0].i_ready.eq(stall)
             #    yield
@@ -118,20 +117,20 @@ class InputTest:
             out_i = yield n.o_data.idx
             out_v = yield n.o_data.data
 
-            print ("recv", out_muxid, out_i, hex(out_v))
+            print("recv", out_muxid, out_i, hex(out_v))
 
             # see if this output has occurred already, delete it if it has
             assert muxid == out_muxid, \
-                    "out_muxid %d not correct %d" % (out_muxid, muxid)
+                "out_muxid %d not correct %d" % (out_muxid, muxid)
             assert out_i in self.do[muxid], "out_i %d not in array %s" % \
-                                          (out_i, repr(self.do[muxid]))
-            assert self.do[muxid][out_i] == out_v # pass-through data
+                (out_i, repr(self.do[muxid]))
+            assert self.do[muxid][out_i] == out_v  # pass-through data
             del self.do[muxid][out_i]
 
             # check if there's any more outputs
             if len(self.do[muxid]) == 0:
                 break
-        print ("recv ended", muxid)
+        print("recv ended", muxid)
 
 
 class TestALU(Elaboratable):
@@ -172,8 +171,9 @@ def test1():
                          test.rcv(3), test.rcv(2),
                          test.send(0), test.send(1),
                          test.send(3), test.send(2),
-                        ],
+                         ],
                    vcd_name="test_reservation_stations.vcd")
 
+
 if __name__ == '__main__':
     test1()
index 43fe1af2e2f1e355e99ce453746870b0220c3cb9..68180d449e0e10acdd8e457b56976bade37657d0 100644 (file)
@@ -34,18 +34,20 @@ def treereduce(tree, op, fn=None):
               treereduce(tree, operator.or_, lambda x: getattr(x, "o_data"))
     """
     if fn is None:
-        fn = lambda x: x
+        def fn(x): return x
     if not isinstance(tree, list):
         return tree
     if len(tree) == 1:
         return fn(tree[0])
     if len(tree) == 2:
         return op(fn(tree[0]), fn(tree[1]))
-    s = len(tree) // 2 # splitpoint
+    s = len(tree) // 2  # splitpoint
     return op(treereduce(tree[:s], op, fn),
               treereduce(tree[s:], op, fn))
 
 # chooses assignment of 32 bit or full 64 bit depending on is_32bit
+
+
 def eq32(is_32bit, dest, src):
     return [dest[0:32].eq(src[0:32]),
             dest[32:64].eq(Mux(is_32bit, 0, src[32:64]))]
@@ -71,8 +73,8 @@ def rising_edge(m, sig):
     rising = Signal.like(sig)
     delay.name = "%s_dly" % sig.name
     rising.name = "%s_rise" % sig.name
-    m.d.sync += delay.eq(sig) # 1 clock delay
-    m.d.comb += rising.eq(sig & ~delay) # sig is hi but delay-sig is lo
+    m.d.sync += delay.eq(sig)  # 1 clock delay
+    m.d.comb += rising.eq(sig & ~delay)  # sig is hi but delay-sig is lo
     return rising