corelogic -> genlib
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Feb 2013 22:19:37 +0000 (23:19 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Feb 2013 22:19:37 +0000 (23:19 +0100)
34 files changed:
examples/basic/complex.py
examples/basic/fsm.py
examples/basic/namer.py
examples/basic/two_dividers.py
examples/basic/using_record.py
examples/sim/fir.py
migen/actorlib/dma_asmi.py
migen/actorlib/misc.py
migen/bank/eventmanager.py
migen/bus/asmibus.py
migen/bus/simple.py
migen/bus/wishbone.py
migen/bus/wishbone2asmi.py
migen/bus/wishbone2csr.py
migen/corelogic/__init__.py [deleted file]
migen/corelogic/buffers.py [deleted file]
migen/corelogic/complex.py [deleted file]
migen/corelogic/divider.py [deleted file]
migen/corelogic/fsm.py [deleted file]
migen/corelogic/misc.py [deleted file]
migen/corelogic/record.py [deleted file]
migen/corelogic/roundrobin.py [deleted file]
migen/flow/actor.py
migen/flow/network.py
migen/flow/plumbing.py
migen/genlib/__init__.py [new file with mode: 0644]
migen/genlib/buffers.py [new file with mode: 0644]
migen/genlib/complex.py [new file with mode: 0644]
migen/genlib/divider.py [new file with mode: 0644]
migen/genlib/fsm.py [new file with mode: 0644]
migen/genlib/misc.py [new file with mode: 0644]
migen/genlib/record.py [new file with mode: 0644]
migen/genlib/roundrobin.py [new file with mode: 0644]
migen/pytholite/fsm.py

index d0e61e5e9e228c56a7e2ff7b827979529082c88b..8404cec5725b59e72cb39dea840245ef4fea8792 100644 (file)
@@ -1,4 +1,4 @@
-from migen.corelogic.complex import *
+from migen.genlib.complex import *
 from migen.fhdl import verilog
 
 w = Complex(32, 42)
index f1716aea69230376bd8b3f555d3c70fa76587576..4eedd97e8d219bd587a5a3c5ebf5f9c49c77b167 100644 (file)
@@ -1,6 +1,6 @@
 from migen.fhdl.structure import *
 from migen.fhdl import verilog
-from migen.corelogic.fsm import FSM
+from migen.genlib.fsm import FSM
 
 s = Signal()
 myfsm = FSM("FOO", "BAR")
index 2928c84066035f2f5c765290bd8c661354218228..80f86b5444b9a26fc4c4f000ed9440d02b851418 100644 (file)
@@ -1,6 +1,6 @@
 from migen.fhdl.structure import *
 from migen.fhdl import verilog
-from migen.corelogic.misc import optree
+from migen.genlib.misc import optree
 
 def gen_list(n):
        s = [Signal() for i in range(n)]
index d82f8af1cf472d6c3844e39b2c8008b1072f8b62..1d15aea2db6c13523f54baae125b711e4724e6b9 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl import verilog
-from migen.corelogic import divider
+from migen.genlib import divider
 
 d1 = divider.Divider(16)
 d2 = divider.Divider(16)
index 8e715a517e27bddc5496ccdf1cab24a255af81f9..15988e8350c49c4fba4c6794b5f8fbb5d1204300 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.structure import *
-from migen.corelogic.record import *
+from migen.genlib.record import *
 
 L = [
        ("x", 10, 8),
index a2369503f980810190f12fc2e9ef6882946091b3..e113154ac777e52a90c0f9b708b3e403958653ab 100644 (file)
@@ -7,7 +7,7 @@ import matplotlib.pyplot as plt
 
 from migen.fhdl.structure import *
 from migen.fhdl import verilog
-from migen.corelogic.misc import optree
+from migen.genlib.misc import optree
 from migen.fhdl import autofragment
 from migen.sim.generic import Simulator, PureSimulable
 
index 1f6d5d0b8d11ab2d9b574477a596c6edf595b215..65d05ca8dc0189965f2c5319da898a8fe36886a3 100644 (file)
@@ -1,6 +1,6 @@
 from migen.fhdl.structure import *
 from migen.flow.actor import *
-from migen.corelogic.buffers import ReorderBuffer
+from migen.genlib.buffers import ReorderBuffer
 
 class SequentialReader(Actor):
        def __init__(self, port):
index 0115f56feea40a9396a25d3d598ecef73dcc280a..b0799706c162d5d3bec9d0c1a21e60756de102a5 100644 (file)
@@ -1,6 +1,6 @@
 from migen.fhdl.structure import *
-from migen.corelogic.record import *
-from migen.corelogic.fsm import *
+from migen.genlib.record import *
+from migen.genlib.fsm import *
 from migen.flow.actor import *
 
 # Generates integers from start to maximum-1
index 298ec44ab02d2ee7348631c20a0da4b0345d5ce1..200803eda926016acf95bd5778b25720ff29d416 100644 (file)
@@ -1,6 +1,6 @@
 from migen.fhdl.structure import *
 from migen.bank.description import *
-from migen.corelogic.misc import optree
+from migen.genlib.misc import optree
 
 class EventSource:
        def __init__(self):
index ff7b192726c39a8ae3e03a639a6f0dbe11239942..cab327a7d5239d7724706984d4f5d08a0a8fb470 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.structure import *
-from migen.corelogic.misc import optree
+from migen.genlib.misc import optree
 from migen.bus.transactions import *
 from migen.sim.generic import Proxy, PureSimulable
 
index 062b9e757f6e0de775dfcbf81835f5eb77d27c67..8c6e0d68a483976e239084b8432a27e1e3bf5581 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.structure import *
-from migen.corelogic.misc import optree
+from migen.genlib.misc import optree
 
 (S_TO_M, M_TO_S) = range(2)
 
index fb7ec125d7425adac0e484c393d21507806c0a25..23abfa6e75de72800f1cf93cfd2a1e74ee182af1 100644 (file)
@@ -1,7 +1,7 @@
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Memory
-from migen.corelogic import roundrobin
-from migen.corelogic.misc import optree
+from migen.genlib import roundrobin
+from migen.genlib.misc import optree
 from migen.bus.simple import *
 from migen.bus.transactions import *
 from migen.sim.generic import Proxy, PureSimulable
index 0fccefccd01f8d3d6ac2bacfa5df4dae44c79b98..c68999cb606a50df499800547c0d83411ea75937 100644 (file)
@@ -1,9 +1,9 @@
 from migen.fhdl.structure import *
 from migen.fhdl.specials import Memory
 from migen.bus import wishbone
-from migen.corelogic.fsm import FSM
-from migen.corelogic.misc import split, displacer, chooser
-from migen.corelogic.record import Record
+from migen.genlib.fsm import FSM
+from migen.genlib.misc import split, displacer, chooser
+from migen.genlib.record import Record
 
 # cachesize (in 32-bit words) is the size of the data store, must be a power of 2
 class WB2ASMI:
index b801866276290c522c1ff9febe02dc15e10456eb..5e62de847bdb4e96a82edddbe723e69d792c14f3 100644 (file)
@@ -1,7 +1,7 @@
 from migen.bus import wishbone
 from migen.bus import csr
 from migen.fhdl.structure import *
-from migen.corelogic.misc import timeline
+from migen.genlib.misc import timeline
 
 class WB2CSR:
        def __init__(self):
diff --git a/migen/corelogic/__init__.py b/migen/corelogic/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/migen/corelogic/buffers.py b/migen/corelogic/buffers.py
deleted file mode 100644 (file)
index 29cee98..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-from migen.fhdl.structure import *
-
-class ReorderSlot:
-       def __init__(self, tag_width, data_width):
-               self.wait_data = Signal()
-               self.has_data = Signal()
-               self.tag = Signal(tag_width)
-               self.data = Signal(data_width)
-
-class ReorderBuffer:
-       def __init__(self, tag_width, data_width, depth):
-               self.depth = depth
-               
-               # issue
-               self.can_issue = Signal()
-               self.issue = Signal()
-               self.tag_issue = Signal(tag_width)
-               
-               # call
-               self.call = Signal()
-               self.tag_call = Signal(tag_width)
-               self.data_call = Signal(data_width)
-               
-               # readback
-               self.can_read = Signal()
-               self.read = Signal()
-               self.data_read = Signal(data_width)
-               
-               self._empty_count = Signal(max=self.depth+1, reset=self.depth)
-               self._produce = Signal(max=self.depth)
-               self._consume = Signal(max=self.depth)
-               self._slots = Array(ReorderSlot(tag_width, data_width)
-                       for n in range(self.depth))
-       
-       def get_fragment(self):
-               # issue
-               comb = [
-                       self.can_issue.eq(self._empty_count != 0)
-               ]
-               sync = [
-                       If(self.issue & self.can_issue,
-                               self._empty_count.eq(self._empty_count - 1),
-                               If(self._produce == self.depth - 1,
-                                       self._produce.eq(0)
-                               ).Else(
-                                       self._produce.eq(self._produce + 1)
-                               ),
-                               self._slots[self._produce].wait_data.eq(1),
-                               self._slots[self._produce].tag.eq(self.tag_issue)
-                       )
-               ]
-               
-               # call
-               for n, slot in enumerate(self._slots):
-                       sync.append(
-                               If(self.call & slot.wait_data & (self.tag_call == slot.tag),
-                                       slot.wait_data.eq(0),
-                                       slot.has_data.eq(1),
-                                       slot.data.eq(self.data_call)
-                               )
-                       )
-               
-               # readback
-               comb += [
-                       self.can_read.eq(self._slots[self._consume].has_data),
-                       self.data_read.eq(self._slots[self._consume].data)
-               ]
-               sync += [
-                       If(self.read & self.can_read,
-                               self._empty_count.eq(self._empty_count + 1),
-                               If(self._consume == self.depth - 1,
-                                       self._consume.eq(0)
-                               ).Else(
-                                       self._consume.eq(self._consume + 1)
-                               ),
-                               self._slots[self._consume].has_data.eq(0)
-                       )
-               ]
-               
-               # do not touch empty count when issuing and reading at the same time
-               sync += [
-                       If(self.issue & self.can_issue & self.read & self.can_read,
-                               self._empty_count.eq(self._empty_count)
-                       )
-               ]
-               
-               return Fragment(comb, sync)
diff --git a/migen/corelogic/complex.py b/migen/corelogic/complex.py
deleted file mode 100644 (file)
index 34c9822..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-from migen.fhdl.structure import *
-
-class Complex:
-       def __init__(self, real, imag):
-               self.real = real
-               self.imag = imag
-       
-       def __neg__(self):
-               return Complex(-self.real, -self.imag)
-       
-       def __add__(self, other):
-               if isinstance(other, Complex):
-                       return Complex(self.real + other.real, self.imag + other.imag)
-               else:
-                       return Complex(self.real + other, self.imag)
-       __radd__ = __add__
-       def __sub__(self, other):
-               if isinstance(other, Complex):
-                       return Complex(self.real - other.real, self.imag - other.imag)
-               else:
-                       return Complex(self.real - other, self.imag)
-       def __rsub__(self, other):
-               if isinstance(other, Complex):
-                       return Complex(other.real - self.real, other.imag - self.imag)
-               else:
-                       return Complex(other - self.real, -self.imag)
-       def __mul__(self, other):
-               if isinstance(other, Complex):
-                       return Complex(self.real*other.real - self.imag*other.imag,
-                               self.real*other.imag + self.imag*other.real)
-               else:
-                       return Complex(self.real*other, self.imag*other)
-       __rmul__ = __mul__
-       
-       def __lshift__(self, other):
-               return Complex(self.real << other, self.imag << other)
-       def __rshift__(self, other):
-               return Complex(self.real >> other, self.imag >> other)
-
-       def __repr__(self):
-               return repr(self.real) + " + " + repr(self.imag) + "j"
-       
-       def eq(self, r):
-               if isinstance(r, Complex):
-                       return self.real.eq(r.real), self.imag.eq(r.imag)
-               else:
-                       return self.real.eq(r), self.imag.eq(0)
-
-def SignalC(*args, **kwargs):
-       real = Signal(*args, **kwargs)
-       imag = Signal(*args, **kwargs)
-       return Complex(real, imag)
diff --git a/migen/corelogic/divider.py b/migen/corelogic/divider.py
deleted file mode 100644 (file)
index 62b87c2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-from migen.fhdl.structure import *
-
-class Divider:
-       def __init__(self, w):
-               self.w = w
-               
-               self.start_i = Signal()
-               self.dividend_i = Signal(w)
-               self.divisor_i = Signal(w)
-               self.ready_o = Signal()
-               self.quotient_o = Signal(w)
-               self.remainder_o = Signal(w)
-       
-       def get_fragment(self):
-               w = self.w
-               
-               qr = Signal(2*w)
-               counter = Signal(max=w+1)
-               divisor_r = Signal(w)
-               diff = Signal(w+1)
-               
-               comb = [
-                       self.quotient_o.eq(qr[:w]),
-                       self.remainder_o.eq(qr[w:]),
-                       self.ready_o.eq(counter == 0),
-                       diff.eq(self.remainder_o - divisor_r)
-               ]
-               sync = [
-                       If(self.start_i,
-                               counter.eq(w),
-                               qr.eq(self.dividend_i),
-                               divisor_r.eq(self.divisor_i)
-                       ).Elif(~self.ready_o,
-                                       If(diff[w],
-                                               qr.eq(Cat(0, qr[:2*w-1]))
-                                       ).Else(
-                                               qr.eq(Cat(1, qr[:w-1], diff[:w]))
-                                       ),
-                                       counter.eq(counter - 1)
-                       )
-               ]
-               return Fragment(comb, sync)
diff --git a/migen/corelogic/fsm.py b/migen/corelogic/fsm.py
deleted file mode 100644 (file)
index 85f3a40..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from migen.fhdl.structure import *
-
-class FSM:
-       def __init__(self, *states, delayed_enters=[]):
-               nstates = len(states) + sum([d[2] for d in delayed_enters])
-               
-               self._state = Signal(max=nstates)
-               self._next_state = Signal(max=nstates)
-               for n, state in enumerate(states):
-                       setattr(self, state, n)
-               self.actions = [[] for i in range(len(states))]
-               
-               for name, target, delay in delayed_enters:
-                       target_state = getattr(self, target)
-                       if delay:
-                               name_state = len(self.actions)
-                               setattr(self, name, name_state)
-                               for i in range(delay-1):
-                                       self.actions.append([self.next_state(name_state+i+1)])
-                               self.actions.append([self.next_state(target_state)])
-                       else:
-                               # alias
-                               setattr(self, name, getattr(self, target_state))
-       
-       def reset_state(self, state):
-               self._state.reset = state
-       
-       def next_state(self, state):
-               return self._next_state.eq(state)
-       
-       def act(self, state, *statements):
-               self.actions[state] += statements
-       
-       def get_fragment(self):
-               cases = dict((s, a) for s, a in enumerate(self.actions) if a)
-               comb = [
-                       self._next_state.eq(self._state),
-                       Case(self._state, cases)
-               ]
-               sync = [self._state.eq(self._next_state)]
-               return Fragment(comb, sync)
diff --git a/migen/corelogic/misc.py b/migen/corelogic/misc.py
deleted file mode 100644 (file)
index fc0469d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Operator
-
-def optree(op, operands, lb=None, ub=None, default=None):
-       if lb is None:
-               lb = 0
-       if ub is None:
-               ub = len(operands)
-       l = ub - lb
-       if l == 0:
-               if default is None:
-                       raise AttributeError
-               else:
-                       return default
-       elif l == 1:
-               return operands[lb]
-       else:
-               s = lb + l//2
-               return _Operator(op,
-                       [optree(op, operands, lb, s, default),
-                       optree(op, operands, s, ub, default)])
-
-def split(v, *counts):
-       r = []
-       offset = 0
-       for n in counts:
-               r.append(v[offset:offset+n])
-               offset += n
-       return tuple(r)
-
-def displacer(signal, shift, output, n=None, reverse=False):
-       if n is None:
-               n = 2**len(shift)
-       w = len(signal)
-       if reverse:
-               r = reversed(range(n))
-       else:
-               r = range(n)
-       l = [Replicate(shift == i, w) & signal for i in r]
-       return output.eq(Cat(*l))
-
-def chooser(signal, shift, output, n=None, reverse=False):
-       if n is None:
-               n = 2**len(shift)
-       w = len(output)
-       cases = {}
-       for i in range(n):
-               if reverse:
-                       s = n - i - 1
-               else:
-                       s = i
-               cases[i] = [output.eq(signal[s*w:(s+1)*w])]
-       return Case(shift, cases).makedefault()
-
-def timeline(trigger, events):
-       lastevent = max([e[0] for e in events])
-       counter = Signal(max=lastevent+1)
-       
-       counterlogic = If(counter != 0,
-               counter.eq(counter + 1)
-       ).Elif(trigger,
-               counter.eq(1)
-       )
-       # insert counter reset if it doesn't naturally overflow
-       # (test if lastevent+1 is a power of 2)
-       if (lastevent & (lastevent + 1)) != 0:
-               counterlogic = If(counter == lastevent,
-                       counter.eq(0)
-               ).Else(
-                       counterlogic
-               )
-       
-       def get_cond(e):
-               if e[0] == 0:
-                       return trigger & (counter == 0)
-               else:
-                       return counter == e[0]
-       sync = [If(get_cond(e), *e[1]) for e in events]
-       sync.append(counterlogic)
-       return sync
diff --git a/migen/corelogic/record.py b/migen/corelogic/record.py
deleted file mode 100644 (file)
index 74bd830..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.tools import value_bits_sign
-
-class Record:
-       def __init__(self, layout, name=""):
-               self.name = name
-               self.field_order = []
-               if self.name:
-                       prefix = self.name + "_"
-               else:
-                       prefix = ""
-               for f in layout:
-                       if isinstance(f, tuple):
-                               if isinstance(f[1], (int, tuple)):
-                                       setattr(self, f[0], Signal(f[1], prefix + f[0]))
-                               elif isinstance(f[1], Signal) or isinstance(f[1], Record):
-                                       setattr(self, f[0], f[1])
-                               elif isinstance(f[1], list):
-                                       setattr(self, f[0], Record(f[1], prefix + f[0]))
-                               else:
-                                       raise TypeError
-                               if len(f) == 3:
-                                       self.field_order.append((f[0], f[2]))
-                               else:
-                                       self.field_order.append((f[0], 1))
-                       else:
-                               setattr(self, f, Signal(1, prefix + f))
-                               self.field_order.append((f, 1))
-
-       def layout(self):
-               l = []
-               for key, alignment in self.field_order:
-                       e = self.__dict__[key]
-                       if isinstance(e, Signal):
-                               l.append((key, (e.nbits, e.signed), alignment))
-                       elif isinstance(e, Record):
-                               l.append((key, e.layout(), alignment))
-               return l
-       
-       def copy(self, name=None):
-               return Record(self.layout(), name)
-       
-       def get_alignment(self, name):
-               return list(filter(lambda x: x[0] == name, self.field_order))[0][1]
-       
-       def subrecord(self, *descr):
-               fields = []
-               for item in descr:
-                       path = item.split("/")
-                       last = path.pop()
-                       pos_self = self
-                       pos_fields = fields
-                       for hop in path:
-                               pos_self = getattr(pos_self, hop)
-                               lu = list(filter(lambda x: x[0] == hop, pos_fields))
-                               try:
-                                       pos_fields = lu[0][1]
-                               except IndexError:
-                                       n = []
-                                       pos_fields.append((hop, n))
-                                       pos_fields = n
-                               if not isinstance(pos_fields, list):
-                                       raise ValueError
-                       if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
-                               raise ValueError
-                       pos_fields.append((last, getattr(pos_self, last), pos_self.get_alignment(last)))
-               return Record(fields, "subrecord")
-       
-       def compatible(self, other):
-               tpl1 = self.flatten()
-               tpl2 = other.flatten()
-               return len(tpl1) == len(tpl2)
-       
-       def flatten(self, align=False, offset=0, return_offset=False):
-               l = []
-               for key, alignment in self.field_order:
-                       if align:
-                               pad_size = alignment - (offset % alignment)
-                               if pad_size < alignment:
-                                       l.append(Replicate(0, pad_size))
-                                       offset += pad_size
-                       
-                       e = self.__dict__[key]
-                       if isinstance(e, Signal):
-                               added = [e]
-                       elif isinstance(e, Record):
-                               added = e.flatten(align, offset)
-                       else:
-                               raise TypeError
-                       for x in added:
-                               offset += value_bits_sign(x)[0]
-                       l += added
-               if return_offset:
-                       return (l, offset)
-               else:
-                       return l
-       
-       def to_signal(self, assignment_list, sig_out, align=False):
-               flattened, length = self.flatten(align, return_offset=True)
-               raw = Signal(length)
-               if sig_out:
-                       assignment_list.append(raw.eq(Cat(*flattened)))
-               else:
-                       assignment_list.append(Cat(*flattened).eq(raw))
-               return raw
-       
-       def __repr__(self):
-               return "<Record " + repr(self.layout()) + ">"
diff --git a/migen/corelogic/roundrobin.py b/migen/corelogic/roundrobin.py
deleted file mode 100644 (file)
index f55b3fe..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from migen.fhdl.structure import *
-
-(SP_WITHDRAW, SP_CE) = range(2)
-
-class RoundRobin:
-       def __init__(self, n, switch_policy=SP_WITHDRAW):
-               self.n = n
-               self.request = Signal(self.n)
-               self.grant = Signal(max=self.n)
-               self.switch_policy = switch_policy
-               if self.switch_policy == SP_CE:
-                       self.ce = Signal()
-       
-       def get_fragment(self):
-               if self.n > 1:
-                       cases = {}
-                       for i in range(self.n):
-                               switch = []
-                               for j in reversed(range(i+1,i+self.n)):
-                                       t = j % self.n
-                                       switch = [
-                                               If(self.request[t],
-                                                       self.grant.eq(t)
-                                               ).Else(
-                                                       *switch
-                                               )
-                                       ]
-                               if self.switch_policy == SP_WITHDRAW:
-                                       case = [If(~self.request[i], *switch)]
-                               else:
-                                       case = switch
-                               cases[i] = case
-                       statement = Case(self.grant, cases)
-                       if self.switch_policy == SP_CE:
-                               statement = If(self.ce, statement)
-                       return Fragment(sync=[statement])
-               else:
-                       return Fragment([self.grant.eq(0)])
index 15eee8c2a131dd008c0f712722eb4b5250507133..ce46638d22aab126a7f1eafa355364d3090efb10 100644 (file)
@@ -1,6 +1,6 @@
 from migen.fhdl.structure import *
-from migen.corelogic.misc import optree
-from migen.corelogic.record import *
+from migen.genlib.misc import optree
+from migen.genlib.record import *
 
 class Endpoint:
        def __init__(self, token):
index 494d906ef44263d17c50efef9d0467ef08e9248f..df739eef248162c2850d7a97e38cb0c526441f35 100644 (file)
@@ -1,7 +1,7 @@
 from networkx import MultiDiGraph
 
 from migen.fhdl.structure import *
-from migen.corelogic.misc import optree
+from migen.genlib.misc import optree
 from migen.flow.actor import *
 from migen.flow import plumbing
 from migen.flow.isd import DFGReporter
index 7c30f760d0abc7d4e0afd7d0637b3ca2cfb63b34..04fc5d128c69a282b23b04d7b641b61163c4e7f2 100644 (file)
@@ -1,7 +1,7 @@
 from migen.fhdl.structure import *
 from migen.flow.actor import *
-from migen.corelogic.record import *
-from migen.corelogic.misc import optree
+from migen.genlib.record import *
+from migen.genlib.misc import optree
 
 class Buffer(PipelinedActor):
        def __init__(self, layout):
diff --git a/migen/genlib/__init__.py b/migen/genlib/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/migen/genlib/buffers.py b/migen/genlib/buffers.py
new file mode 100644 (file)
index 0000000..29cee98
--- /dev/null
@@ -0,0 +1,87 @@
+from migen.fhdl.structure import *
+
+class ReorderSlot:
+       def __init__(self, tag_width, data_width):
+               self.wait_data = Signal()
+               self.has_data = Signal()
+               self.tag = Signal(tag_width)
+               self.data = Signal(data_width)
+
+class ReorderBuffer:
+       def __init__(self, tag_width, data_width, depth):
+               self.depth = depth
+               
+               # issue
+               self.can_issue = Signal()
+               self.issue = Signal()
+               self.tag_issue = Signal(tag_width)
+               
+               # call
+               self.call = Signal()
+               self.tag_call = Signal(tag_width)
+               self.data_call = Signal(data_width)
+               
+               # readback
+               self.can_read = Signal()
+               self.read = Signal()
+               self.data_read = Signal(data_width)
+               
+               self._empty_count = Signal(max=self.depth+1, reset=self.depth)
+               self._produce = Signal(max=self.depth)
+               self._consume = Signal(max=self.depth)
+               self._slots = Array(ReorderSlot(tag_width, data_width)
+                       for n in range(self.depth))
+       
+       def get_fragment(self):
+               # issue
+               comb = [
+                       self.can_issue.eq(self._empty_count != 0)
+               ]
+               sync = [
+                       If(self.issue & self.can_issue,
+                               self._empty_count.eq(self._empty_count - 1),
+                               If(self._produce == self.depth - 1,
+                                       self._produce.eq(0)
+                               ).Else(
+                                       self._produce.eq(self._produce + 1)
+                               ),
+                               self._slots[self._produce].wait_data.eq(1),
+                               self._slots[self._produce].tag.eq(self.tag_issue)
+                       )
+               ]
+               
+               # call
+               for n, slot in enumerate(self._slots):
+                       sync.append(
+                               If(self.call & slot.wait_data & (self.tag_call == slot.tag),
+                                       slot.wait_data.eq(0),
+                                       slot.has_data.eq(1),
+                                       slot.data.eq(self.data_call)
+                               )
+                       )
+               
+               # readback
+               comb += [
+                       self.can_read.eq(self._slots[self._consume].has_data),
+                       self.data_read.eq(self._slots[self._consume].data)
+               ]
+               sync += [
+                       If(self.read & self.can_read,
+                               self._empty_count.eq(self._empty_count + 1),
+                               If(self._consume == self.depth - 1,
+                                       self._consume.eq(0)
+                               ).Else(
+                                       self._consume.eq(self._consume + 1)
+                               ),
+                               self._slots[self._consume].has_data.eq(0)
+                       )
+               ]
+               
+               # do not touch empty count when issuing and reading at the same time
+               sync += [
+                       If(self.issue & self.can_issue & self.read & self.can_read,
+                               self._empty_count.eq(self._empty_count)
+                       )
+               ]
+               
+               return Fragment(comb, sync)
diff --git a/migen/genlib/complex.py b/migen/genlib/complex.py
new file mode 100644 (file)
index 0000000..34c9822
--- /dev/null
@@ -0,0 +1,52 @@
+from migen.fhdl.structure import *
+
+class Complex:
+       def __init__(self, real, imag):
+               self.real = real
+               self.imag = imag
+       
+       def __neg__(self):
+               return Complex(-self.real, -self.imag)
+       
+       def __add__(self, other):
+               if isinstance(other, Complex):
+                       return Complex(self.real + other.real, self.imag + other.imag)
+               else:
+                       return Complex(self.real + other, self.imag)
+       __radd__ = __add__
+       def __sub__(self, other):
+               if isinstance(other, Complex):
+                       return Complex(self.real - other.real, self.imag - other.imag)
+               else:
+                       return Complex(self.real - other, self.imag)
+       def __rsub__(self, other):
+               if isinstance(other, Complex):
+                       return Complex(other.real - self.real, other.imag - self.imag)
+               else:
+                       return Complex(other - self.real, -self.imag)
+       def __mul__(self, other):
+               if isinstance(other, Complex):
+                       return Complex(self.real*other.real - self.imag*other.imag,
+                               self.real*other.imag + self.imag*other.real)
+               else:
+                       return Complex(self.real*other, self.imag*other)
+       __rmul__ = __mul__
+       
+       def __lshift__(self, other):
+               return Complex(self.real << other, self.imag << other)
+       def __rshift__(self, other):
+               return Complex(self.real >> other, self.imag >> other)
+
+       def __repr__(self):
+               return repr(self.real) + " + " + repr(self.imag) + "j"
+       
+       def eq(self, r):
+               if isinstance(r, Complex):
+                       return self.real.eq(r.real), self.imag.eq(r.imag)
+               else:
+                       return self.real.eq(r), self.imag.eq(0)
+
+def SignalC(*args, **kwargs):
+       real = Signal(*args, **kwargs)
+       imag = Signal(*args, **kwargs)
+       return Complex(real, imag)
diff --git a/migen/genlib/divider.py b/migen/genlib/divider.py
new file mode 100644 (file)
index 0000000..62b87c2
--- /dev/null
@@ -0,0 +1,42 @@
+from migen.fhdl.structure import *
+
+class Divider:
+       def __init__(self, w):
+               self.w = w
+               
+               self.start_i = Signal()
+               self.dividend_i = Signal(w)
+               self.divisor_i = Signal(w)
+               self.ready_o = Signal()
+               self.quotient_o = Signal(w)
+               self.remainder_o = Signal(w)
+       
+       def get_fragment(self):
+               w = self.w
+               
+               qr = Signal(2*w)
+               counter = Signal(max=w+1)
+               divisor_r = Signal(w)
+               diff = Signal(w+1)
+               
+               comb = [
+                       self.quotient_o.eq(qr[:w]),
+                       self.remainder_o.eq(qr[w:]),
+                       self.ready_o.eq(counter == 0),
+                       diff.eq(self.remainder_o - divisor_r)
+               ]
+               sync = [
+                       If(self.start_i,
+                               counter.eq(w),
+                               qr.eq(self.dividend_i),
+                               divisor_r.eq(self.divisor_i)
+                       ).Elif(~self.ready_o,
+                                       If(diff[w],
+                                               qr.eq(Cat(0, qr[:2*w-1]))
+                                       ).Else(
+                                               qr.eq(Cat(1, qr[:w-1], diff[:w]))
+                                       ),
+                                       counter.eq(counter - 1)
+                       )
+               ]
+               return Fragment(comb, sync)
diff --git a/migen/genlib/fsm.py b/migen/genlib/fsm.py
new file mode 100644 (file)
index 0000000..85f3a40
--- /dev/null
@@ -0,0 +1,41 @@
+from migen.fhdl.structure import *
+
+class FSM:
+       def __init__(self, *states, delayed_enters=[]):
+               nstates = len(states) + sum([d[2] for d in delayed_enters])
+               
+               self._state = Signal(max=nstates)
+               self._next_state = Signal(max=nstates)
+               for n, state in enumerate(states):
+                       setattr(self, state, n)
+               self.actions = [[] for i in range(len(states))]
+               
+               for name, target, delay in delayed_enters:
+                       target_state = getattr(self, target)
+                       if delay:
+                               name_state = len(self.actions)
+                               setattr(self, name, name_state)
+                               for i in range(delay-1):
+                                       self.actions.append([self.next_state(name_state+i+1)])
+                               self.actions.append([self.next_state(target_state)])
+                       else:
+                               # alias
+                               setattr(self, name, getattr(self, target_state))
+       
+       def reset_state(self, state):
+               self._state.reset = state
+       
+       def next_state(self, state):
+               return self._next_state.eq(state)
+       
+       def act(self, state, *statements):
+               self.actions[state] += statements
+       
+       def get_fragment(self):
+               cases = dict((s, a) for s, a in enumerate(self.actions) if a)
+               comb = [
+                       self._next_state.eq(self._state),
+                       Case(self._state, cases)
+               ]
+               sync = [self._state.eq(self._next_state)]
+               return Fragment(comb, sync)
diff --git a/migen/genlib/misc.py b/migen/genlib/misc.py
new file mode 100644 (file)
index 0000000..fc0469d
--- /dev/null
@@ -0,0 +1,80 @@
+from migen.fhdl.structure import *
+from migen.fhdl.structure import _Operator
+
+def optree(op, operands, lb=None, ub=None, default=None):
+       if lb is None:
+               lb = 0
+       if ub is None:
+               ub = len(operands)
+       l = ub - lb
+       if l == 0:
+               if default is None:
+                       raise AttributeError
+               else:
+                       return default
+       elif l == 1:
+               return operands[lb]
+       else:
+               s = lb + l//2
+               return _Operator(op,
+                       [optree(op, operands, lb, s, default),
+                       optree(op, operands, s, ub, default)])
+
+def split(v, *counts):
+       r = []
+       offset = 0
+       for n in counts:
+               r.append(v[offset:offset+n])
+               offset += n
+       return tuple(r)
+
+def displacer(signal, shift, output, n=None, reverse=False):
+       if n is None:
+               n = 2**len(shift)
+       w = len(signal)
+       if reverse:
+               r = reversed(range(n))
+       else:
+               r = range(n)
+       l = [Replicate(shift == i, w) & signal for i in r]
+       return output.eq(Cat(*l))
+
+def chooser(signal, shift, output, n=None, reverse=False):
+       if n is None:
+               n = 2**len(shift)
+       w = len(output)
+       cases = {}
+       for i in range(n):
+               if reverse:
+                       s = n - i - 1
+               else:
+                       s = i
+               cases[i] = [output.eq(signal[s*w:(s+1)*w])]
+       return Case(shift, cases).makedefault()
+
+def timeline(trigger, events):
+       lastevent = max([e[0] for e in events])
+       counter = Signal(max=lastevent+1)
+       
+       counterlogic = If(counter != 0,
+               counter.eq(counter + 1)
+       ).Elif(trigger,
+               counter.eq(1)
+       )
+       # insert counter reset if it doesn't naturally overflow
+       # (test if lastevent+1 is a power of 2)
+       if (lastevent & (lastevent + 1)) != 0:
+               counterlogic = If(counter == lastevent,
+                       counter.eq(0)
+               ).Else(
+                       counterlogic
+               )
+       
+       def get_cond(e):
+               if e[0] == 0:
+                       return trigger & (counter == 0)
+               else:
+                       return counter == e[0]
+       sync = [If(get_cond(e), *e[1]) for e in events]
+       sync.append(counterlogic)
+       return sync
diff --git a/migen/genlib/record.py b/migen/genlib/record.py
new file mode 100644 (file)
index 0000000..74bd830
--- /dev/null
@@ -0,0 +1,108 @@
+from migen.fhdl.structure import *
+from migen.fhdl.tools import value_bits_sign
+
+class Record:
+       def __init__(self, layout, name=""):
+               self.name = name
+               self.field_order = []
+               if self.name:
+                       prefix = self.name + "_"
+               else:
+                       prefix = ""
+               for f in layout:
+                       if isinstance(f, tuple):
+                               if isinstance(f[1], (int, tuple)):
+                                       setattr(self, f[0], Signal(f[1], prefix + f[0]))
+                               elif isinstance(f[1], Signal) or isinstance(f[1], Record):
+                                       setattr(self, f[0], f[1])
+                               elif isinstance(f[1], list):
+                                       setattr(self, f[0], Record(f[1], prefix + f[0]))
+                               else:
+                                       raise TypeError
+                               if len(f) == 3:
+                                       self.field_order.append((f[0], f[2]))
+                               else:
+                                       self.field_order.append((f[0], 1))
+                       else:
+                               setattr(self, f, Signal(1, prefix + f))
+                               self.field_order.append((f, 1))
+
+       def layout(self):
+               l = []
+               for key, alignment in self.field_order:
+                       e = self.__dict__[key]
+                       if isinstance(e, Signal):
+                               l.append((key, (e.nbits, e.signed), alignment))
+                       elif isinstance(e, Record):
+                               l.append((key, e.layout(), alignment))
+               return l
+       
+       def copy(self, name=None):
+               return Record(self.layout(), name)
+       
+       def get_alignment(self, name):
+               return list(filter(lambda x: x[0] == name, self.field_order))[0][1]
+       
+       def subrecord(self, *descr):
+               fields = []
+               for item in descr:
+                       path = item.split("/")
+                       last = path.pop()
+                       pos_self = self
+                       pos_fields = fields
+                       for hop in path:
+                               pos_self = getattr(pos_self, hop)
+                               lu = list(filter(lambda x: x[0] == hop, pos_fields))
+                               try:
+                                       pos_fields = lu[0][1]
+                               except IndexError:
+                                       n = []
+                                       pos_fields.append((hop, n))
+                                       pos_fields = n
+                               if not isinstance(pos_fields, list):
+                                       raise ValueError
+                       if len(list(filter(lambda x: x[0] == last, pos_fields))) > 0:
+                               raise ValueError
+                       pos_fields.append((last, getattr(pos_self, last), pos_self.get_alignment(last)))
+               return Record(fields, "subrecord")
+       
+       def compatible(self, other):
+               tpl1 = self.flatten()
+               tpl2 = other.flatten()
+               return len(tpl1) == len(tpl2)
+       
+       def flatten(self, align=False, offset=0, return_offset=False):
+               l = []
+               for key, alignment in self.field_order:
+                       if align:
+                               pad_size = alignment - (offset % alignment)
+                               if pad_size < alignment:
+                                       l.append(Replicate(0, pad_size))
+                                       offset += pad_size
+                       
+                       e = self.__dict__[key]
+                       if isinstance(e, Signal):
+                               added = [e]
+                       elif isinstance(e, Record):
+                               added = e.flatten(align, offset)
+                       else:
+                               raise TypeError
+                       for x in added:
+                               offset += value_bits_sign(x)[0]
+                       l += added
+               if return_offset:
+                       return (l, offset)
+               else:
+                       return l
+       
+       def to_signal(self, assignment_list, sig_out, align=False):
+               flattened, length = self.flatten(align, return_offset=True)
+               raw = Signal(length)
+               if sig_out:
+                       assignment_list.append(raw.eq(Cat(*flattened)))
+               else:
+                       assignment_list.append(Cat(*flattened).eq(raw))
+               return raw
+       
+       def __repr__(self):
+               return "<Record " + repr(self.layout()) + ">"
diff --git a/migen/genlib/roundrobin.py b/migen/genlib/roundrobin.py
new file mode 100644 (file)
index 0000000..f55b3fe
--- /dev/null
@@ -0,0 +1,38 @@
+from migen.fhdl.structure import *
+
+(SP_WITHDRAW, SP_CE) = range(2)
+
+class RoundRobin:
+       def __init__(self, n, switch_policy=SP_WITHDRAW):
+               self.n = n
+               self.request = Signal(self.n)
+               self.grant = Signal(max=self.n)
+               self.switch_policy = switch_policy
+               if self.switch_policy == SP_CE:
+                       self.ce = Signal()
+       
+       def get_fragment(self):
+               if self.n > 1:
+                       cases = {}
+                       for i in range(self.n):
+                               switch = []
+                               for j in reversed(range(i+1,i+self.n)):
+                                       t = j % self.n
+                                       switch = [
+                                               If(self.request[t],
+                                                       self.grant.eq(t)
+                                               ).Else(
+                                                       *switch
+                                               )
+                                       ]
+                               if self.switch_policy == SP_WITHDRAW:
+                                       case = [If(~self.request[i], *switch)]
+                               else:
+                                       case = switch
+                               cases[i] = case
+                       statement = Case(self.grant, cases)
+                       if self.switch_policy == SP_CE:
+                               statement = If(self.ce, statement)
+                       return Fragment(sync=[statement])
+               else:
+                       return Fragment([self.grant.eq(0)])
index 305a0cd4e6b965ec912efdff9211c6196fcd9c19..7bc6c4c227f5f62e7c1567098201b796e5c8c42d 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl import visit as fhdl
-from migen.corelogic.fsm import FSM
+from migen.genlib.fsm import FSM
 
 class AbstractNextState:
        def __init__(self, target_state):