Use RoundRobin implementation from nMigen
[gram.git] / gram / compat.py
1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2
3 import unittest
4
5 from nmigen import *
6 from nmigen import tracer
7 from nmigen.compat import Case
8 from nmigen.back.pysim import *
9
10 __ALL__ = ["delayed_enter", "Timeline", "CSRPrefixProxy"]
11
12
13 def delayed_enter(m, src, dst, delay):
14 assert delay > 0
15
16 for i in range(delay):
17 if i == 0:
18 statename = src
19 else:
20 statename = "{}-{}".format(src, i)
21
22 if i == delay-1:
23 deststate = dst
24 else:
25 deststate = "{}-{}".format(src, i+1)
26
27 with m.State(statename):
28 m.next = deststate
29
30
31 class Timeline(Elaboratable):
32 def __init__(self, events):
33 self.trigger = Signal()
34 self._events = events
35
36 def elaborate(self, platform):
37 m = Module()
38
39 lastevent = max([e[0] for e in self._events])
40 counter = Signal(range(lastevent+1))
41
42 # Counter incrementation
43 # (with overflow handling)
44 if (lastevent & (lastevent + 1)) != 0:
45 with m.If(counter == lastevent):
46 m.d.sync += counter.eq(0)
47 with m.Else():
48 with m.If(counter != 0):
49 m.d.sync += counter.eq(counter+1)
50 with m.Elif(self.trigger):
51 m.d.sync += counter.eq(1)
52 else:
53 with m.If(counter != 0):
54 m.d.sync += counter.eq(counter+1)
55 with m.Elif(self.trigger):
56 m.d.sync += counter.eq(1)
57
58 for e in self._events:
59 if e[0] == 0:
60 with m.If(self.trigger & (counter == 0)):
61 m.d.sync += e[1]
62 else:
63 with m.If(counter == e[0]):
64 m.d.sync += e[1]
65
66 return m
67
68
69 class CSRPrefixProxy:
70 def __init__(self, bank, prefix):
71 self._bank = bank
72 self._prefix = prefix
73
74 def csr(self, width, access, *, addr=None, alignment=None, name=None,
75 src_loc_at=0):
76 if name is not None and not isinstance(name, str):
77 raise TypeError("Name must be a string, not {!r}".format(name))
78 name = name or tracer.get_var_name(depth=2 + src_loc_at).lstrip("_")
79
80 prefixed_name = "{}_{}".format(self._prefix, name)
81 return self._bank.csr(width=width, access=access, addr=addr,
82 alignment=alignment, name=prefixed_name)