1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
6 from nmigen
import tracer
7 from nmigen
.compat
import Case
8 from nmigen
.back
.pysim
import *
10 __ALL__
= ["delayed_enter", "Timeline", "CSRPrefixProxy"]
13 def delayed_enter(m
, src
, dst
, delay
):
16 for i
in range(delay
):
20 statename
= "{}-{}".format(src
, i
)
25 deststate
= "{}-{}".format(src
, i
+1)
27 with m
.State(statename
):
31 class Timeline(Elaboratable
):
32 def __init__(self
, events
):
33 self
.trigger
= Signal()
36 def elaborate(self
, platform
):
39 lastevent
= max([e
[0] for e
in self
._events
])
40 counter
= Signal(range(lastevent
+1))
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)
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)
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)
58 for e
in self
._events
:
60 with m
.If(self
.trigger
& (counter
== 0)):
63 with m
.If(counter
== e
[0]):
70 def __init__(self
, bank
, prefix
):
74 def csr(self
, width
, access
, *, addr
=None, alignment
=None, name
=None,
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("_")
80 prefixed_name
= "{}_{}".format(self
._prefix
, name
)
81 return self
._bank
.csr(width
=width
, access
=access
, addr
=addr
,
82 alignment
=alignment
, name
=prefixed_name
)