c05300650fdc7d9cd8956a7715e2abfdd0e6c5ab
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
):
14 if not isinstance(m
, Module
):
15 raise ValueError("m must be a module object, not {!r}".format(m
))
16 if not isinstance(delay
, int):
17 raise ValueError("Delay must be an integer, not {!r}".format(delay
))
19 raise ValueError("Delay must be at least one cycle, not {!r}".format(delay
))
21 for i
in range(delay
):
25 statename
= "{}-{}".format(src
, i
)
30 deststate
= "{}-{}".format(src
, i
+1)
32 with m
.State(statename
):
36 class Timeline(Elaboratable
):
37 def __init__(self
, events
):
38 self
.trigger
= Signal()
41 def elaborate(self
, platform
):
44 lastevent
= max([e
[0] for e
in self
._events
])
45 counter
= Signal(range(lastevent
+1))
47 # Counter incrementation
48 # (with overflow handling)
49 if (lastevent
& (lastevent
+ 1)) != 0:
50 with m
.If(counter
== lastevent
):
51 m
.d
.sync
+= counter
.eq(0)
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 with m
.If(counter
!= 0):
59 m
.d
.sync
+= counter
.eq(counter
+1)
60 with m
.Elif(self
.trigger
):
61 m
.d
.sync
+= counter
.eq(1)
63 for e
in self
._events
:
65 with m
.If(self
.trigger
& (counter
== 0)):
68 with m
.If(counter
== e
[0]):
75 def __init__(self
, bank
, prefix
):
79 def csr(self
, width
, access
, *, addr
=None, alignment
=None, name
=None,
81 if name
is not None and not isinstance(name
, str):
82 raise TypeError("Name must be a string, not {!r}".format(name
))
83 name
= name
or tracer
.get_var_name(depth
=2 + src_loc_at
).lstrip("_")
85 prefixed_name
= "{}_{}".format(self
._prefix
, name
)
86 return self
._bank
.csr(width
=width
, access
=access
, addr
=addr
,
87 alignment
=alignment
, name
=prefixed_name
)