genlib/misc: fix missing *args in Counter
[litex.git] / migen / genlib / misc.py
1 from migen.fhdl.std import *
2 from migen.fhdl.structure import _Operator
3
4 def optree(op, operands, lb=None, ub=None, default=None):
5 if lb is None:
6 lb = 0
7 if ub is None:
8 ub = len(operands)
9 l = ub - lb
10 if l == 0:
11 if default is None:
12 raise AttributeError
13 else:
14 return default
15 elif l == 1:
16 return operands[lb]
17 else:
18 s = lb + l//2
19 return _Operator(op,
20 [optree(op, operands, lb, s, default),
21 optree(op, operands, s, ub, default)])
22
23 def split(v, *counts):
24 r = []
25 offset = 0
26 for n in counts:
27 if n != 0:
28 r.append(v[offset:offset+n])
29 else:
30 r.append(None)
31 offset += n
32 return tuple(r)
33
34 def displacer(signal, shift, output, n=None, reverse=False):
35 if shift is None:
36 return output.eq(signal)
37 if n is None:
38 n = 2**flen(shift)
39 w = flen(signal)
40 if reverse:
41 r = reversed(range(n))
42 else:
43 r = range(n)
44 l = [Replicate(shift == i, w) & signal for i in r]
45 return output.eq(Cat(*l))
46
47 def chooser(signal, shift, output, n=None, reverse=False):
48 if shift is None:
49 return output.eq(signal)
50 if n is None:
51 n = 2**flen(shift)
52 w = flen(output)
53 cases = {}
54 for i in range(n):
55 if reverse:
56 s = n - i - 1
57 else:
58 s = i
59 cases[i] = [output.eq(signal[s*w:(s+1)*w])]
60 return Case(shift, cases).makedefault()
61
62 def timeline(trigger, events):
63 lastevent = max([e[0] for e in events])
64 counter = Signal(max=lastevent+1)
65
66 counterlogic = If(counter != 0,
67 counter.eq(counter + 1)
68 ).Elif(trigger,
69 counter.eq(1)
70 )
71 # insert counter reset if it doesn't naturally overflow
72 # (test if lastevent+1 is a power of 2)
73 if (lastevent & (lastevent + 1)) != 0:
74 counterlogic = If(counter == lastevent,
75 counter.eq(0)
76 ).Else(
77 counterlogic
78 )
79
80 def get_cond(e):
81 if e[0] == 0:
82 return trigger & (counter == 0)
83 else:
84 return counter == e[0]
85 sync = [If(get_cond(e), *e[1]) for e in events]
86 sync.append(counterlogic)
87 return sync
88
89 @DecorateModule(InsertReset)
90 @DecorateModule(InsertCE)
91 class FlipFlop(Module):
92 def __init__(self, *args, **kwargs):
93 self.d = Signal(*args, **kwargs)
94 self.q = Signal(*args, **kwargs)
95 self.sync += self.q.eq(self.d)
96
97 @DecorateModule(InsertReset)
98 @DecorateModule(InsertCE)
99 class Counter(Module):
100 def __init__(self, *args, **kwargs):
101 self.value = Signal(*args, **kwargs)
102 self.width = flen(self.value)
103 self.sync += self.value.eq(self.value+1)
104
105 @DecorateModule(InsertReset)
106 @DecorateModule(InsertCE)
107 class Timeout(Module):
108 def __init__(self, length):
109 self.reached = Signal()
110 ###
111 value = Signal(max=length)
112 self.sync += If(~self.reached, value.eq(value+1))
113 self.comb += self.reached.eq(value == (length-1))