-from migen.corelogic.complex import *
+from migen.genlib.complex import *
from migen.fhdl import verilog
w = Complex(32, 42)
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")
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)]
from migen.fhdl import verilog
-from migen.corelogic import divider
+from migen.genlib import divider
d1 = divider.Divider(16)
d2 = divider.Divider(16)
from migen.fhdl.structure import *
-from migen.corelogic.record import *
+from migen.genlib.record import *
L = [
("x", 10, 8),
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
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):
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
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):
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
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)
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
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:
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):
+++ /dev/null
-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)
+++ /dev/null
-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)
+++ /dev/null
-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)
+++ /dev/null
-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)
+++ /dev/null
-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
+++ /dev/null
-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()) + ">"
+++ /dev/null
-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)])
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):
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
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):
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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
--- /dev/null
+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()) + ">"
--- /dev/null
+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)])
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):