90ebf3c3ea69eea6e40fcd7373f99dcfd07d09b6
2 from nmigen
.compat
import Case
4 __ALL__
= ["delayed_enter", "RoundRobin", "Timeline"]
6 def delayed_enter(m
, src
, dst
, delay
):
13 statename
= "{}-{}".format(src
, i
)
18 deststate
= "{}-{}".format(src
, i
+1)
20 with m
.State(statename
):
23 # Original nMigen implementation by HarryHo90sHK
24 class RoundRobin(Elaboratable
):
25 """A round-robin scheduler.
29 Maximum number of requests to handle.
33 Signal where a '1' on the i-th bit represents an incoming request from the i-th device.
34 grant : Signal(range(n))
35 Signal that equals to the index of the device which is currently granted access.
37 Strobe signal to enable granting access to the next device requesting. Externally driven.
39 def __init__(self
, n
):
41 self
.request
= Signal(n
)
42 self
.grant
= Signal(range(n
))
45 def elaborate(self
, platform
):
49 with m
.Switch(self
.grant
):
50 for i
in range(self
.n
):
52 for j
in reversed(range(i
+1, i
+self
.n
)):
53 # If i+1 <= j < n, then t == j; (after i)
54 # If n <= j < i+n, then t == j - n (before i)
56 with m
.If(self
.request
[t
]):
57 m
.d
.sync
+= self
.grant
.eq(t
)
61 class Timeline(Elaboratable
):
62 def __init__(self
, events
):
63 self
.trigger
= Signal()
66 def elaborate(self
, platform
):
69 lastevent
= max([e
[0] for e
in self
._events
])
70 counter
= Signal(range(lastevent
+1))
72 # Counter incrementation
73 # (with overflow handling)
74 if (lastevent
& (lastevent
+ 1)) != 0:
75 with m
.If(counter
== lastevent
):
76 m
.d
.sync
+= counter
.eq(0)
78 with m
.If(counter
!= 0):
79 m
.d
.sync
+= counter
.eq(counter
+1)
80 with m
.Elif(self
.trigger
):
81 m
.d
.sync
+= counter
.eq(1)
83 with m
.If(counter
!= 0):
84 m
.d
.sync
+= counter
.eq(counter
+1)
85 with m
.Elif(self
.trigger
):
86 m
.d
.sync
+= counter
.eq(1)
88 for e
in self
._events
:
90 with m
.If(self
.trigger
& (counter
== 0)):
93 with m
.If(counter
== e
[0]):