Skip to content

Commit 2775558

Browse files
mithrosbourdeauducq
authored andcommittedDec 21, 2016
Adding documentation to the csr modules.
A lot of the documentation is comes from https://github.com/m-labs/migen/blob/legacy/doc/bus.rst
1 parent 25d9e5d commit 2775558

File tree

3 files changed

+248
-7
lines changed

3 files changed

+248
-7
lines changed
 

‎misoc/interconnect/csr.py

+161
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
"""
2+
Configuration and Status Registers
3+
**********************************
4+
5+
The lowest-level description of a register is provided by the ``CSR`` class,
6+
which maps to the value at a single address on the target bus. Also provided
7+
are helper classes for dealing with values larger than the CSR buses data
8+
width.
9+
10+
* ``CSRConstant``, for constant values.
11+
* ``CSRStatus``, for providing information to the CPU.
12+
* ``CSRStorage``, for allowing control via the CPU.
13+
14+
Generating register banks
15+
=========================
16+
A module can provide bus-independent CSRs by implementing a ``get_csrs`` method
17+
that returns a list of instances of the classes described above.
18+
19+
Similarly, bus-independent memories can be returned as a list by a
20+
``get_memories`` method.
21+
22+
To avoid listing those manually, a module can inherit from the ``AutoCSR``
23+
class, which provides ``get_csrs`` and ``get_memories`` methods that scan for
24+
CSR and memory attributes and return their list.
25+
"""
26+
127
from migen import *
228
from migen.util.misc import xdir
329
from migen.fhdl.tracer import get_obj_var_name
@@ -13,6 +39,12 @@ def __init__(self, size, name):
1339

1440

1541
class CSRConstant(DUID):
42+
"""Register which contains a constant value.
43+
44+
Useful for providing information on how a HDL was instantiated to firmware
45+
running on the device.
46+
"""
47+
1648
def __init__(self, value, bits_sign=None, name=None):
1749
DUID.__init__(self)
1850
self.value = Constant(value, bits_sign)
@@ -21,20 +53,49 @@ def __init__(self, value, bits_sign=None, name=None):
2153
raise ValueError("Cannot extract CSR name from code, need to specify.")
2254

2355
def read(self):
56+
"""Read method for simulation."""
2457
return self.value.value
2558

2659

2760
class CSR(_CSRBase):
61+
"""Basic CSR register.
62+
63+
Parameters
64+
----------
65+
size : int
66+
Size of the CSR register in bits.
67+
Must be less than CSR bus width!
68+
69+
name : string
70+
Provide (or override the name) of the CSR register.
71+
72+
Attributes
73+
----------
74+
r : Signal(size), out
75+
Contains the data written from the bus interface.
76+
``r`` is only valid when ``re`` is high.
77+
78+
re : Signal(), out
79+
The strobe signal for ``r``.
80+
It is active for one cycle, after or during a write from the bus.
81+
82+
w : Signal(size), in
83+
The value to be read from the bus.
84+
Must be provided at all times.
85+
"""
86+
2887
def __init__(self, size=1, name=None):
2988
_CSRBase.__init__(self, size, name)
3089
self.re = Signal(name=self.name + "_re")
3190
self.r = Signal(self.size, name=self.name + "_r")
3291
self.w = Signal(self.size, name=self.name + "_w")
3392

3493
def read(self):
94+
"""Read method for simulation."""
3595
return (yield self.w)
3696

3797
def write(self, value):
98+
"""Write method for simulation."""
3899
yield self.r.eq(value)
39100
yield self.re.eq(1)
40101
yield
@@ -56,6 +117,39 @@ def do_finalize(self, busword):
56117

57118

58119
class CSRStatus(_CompoundCSR):
120+
"""Status Register.
121+
122+
The ``CSRStatus`` class is meant to be used as a status register that is
123+
read-only from the CPU.
124+
125+
The user design is expected to drive its ``status`` signal.
126+
127+
The advantage of using ``CSRStatus`` instead of using ``CSR`` and driving
128+
``w`` is that the width of ``CSRStatus`` can be arbitrary.
129+
130+
Status registers larger than the bus word width are automatically broken
131+
down into several ``CSR`` registers to span several addresses.
132+
133+
*Be careful, though:* the atomicity of reads is not guaranteed.
134+
135+
Parameters
136+
----------
137+
size : int
138+
Size of the CSR register in bits.
139+
Can be bigger than the CSR bus width.
140+
141+
reset : string
142+
Value of the register after reset.
143+
144+
name : string
145+
Provide (or override the name) of the ``CSRStatus`` register.
146+
147+
Attributes
148+
----------
149+
status : Signal(size), in
150+
The value of the CSRStatus register.
151+
"""
152+
59153
def __init__(self, size=1, reset=0, name=None):
60154
_CompoundCSR.__init__(self, size, name)
61155
self.status = Signal(self.size, reset=reset)
@@ -69,10 +163,64 @@ def do_finalize(self, busword):
69163
self.simple_csrs.append(sc)
70164

71165
def read(self):
166+
"""Read method for simulation."""
72167
return (yield self.status)
73168

74169

75170
class CSRStorage(_CompoundCSR):
171+
"""Control Register.
172+
173+
The ``CSRStorage`` class provides a memory location that can be read and
174+
written by the CPU, and read and optionally written by the design.
175+
176+
It can span several CSR addresses.
177+
178+
Parameters
179+
----------
180+
size : int
181+
Size of the CSR register in bits.
182+
Can be bigger than the CSR bus width.
183+
184+
reset : string
185+
Value of the register after reset.
186+
187+
atomic_write : bool
188+
Provide an mechanism for atomic CPU writes is provided.
189+
When enabled, writes to the first CSR addresses go to a back-buffer
190+
whose contents are atomically copied to the main buffer when the last
191+
address is written.
192+
193+
write_from_dev : bool
194+
Allow the design to update the CSRStorage value.
195+
*Warning*: The atomicity of reads by the CPU is not guaranteed.
196+
197+
alignment_bits : int
198+
???
199+
200+
name : string
201+
Provide (or override the name) of the ``CSRStatus`` register.
202+
203+
Attributes
204+
----------
205+
storage_full : Signal(size), out
206+
???
207+
208+
storage : Signal(size), out
209+
Signal providing the value of the ``CSRStorage`` object.
210+
211+
re : Signal(), in
212+
The strobe signal indicating a write to the ``CSRStorage`` register.
213+
It is active for one cycle, after or during a write from the bus.
214+
215+
we : Signal(), out
216+
Only available when ``write_from_dev == True``
217+
???
218+
219+
dat_w : Signal(), out
220+
Only available when ``write_from_dev == True``
221+
???
222+
"""
223+
76224
def __init__(self, size=1, reset=0, atomic_write=False, write_from_dev=False, alignment_bits=0, name=None):
77225
_CompoundCSR.__init__(self, size, name)
78226
self.alignment_bits = alignment_bits
@@ -115,9 +263,11 @@ def do_finalize(self, busword):
115263
self.sync += self.re.eq(sc.re)
116264

117265
def read(self):
266+
"""Read method for simulation."""
118267
return (yield self.storage) << self.alignment_bits
119268

120269
def write(self, value):
270+
"""Write method for simulation."""
121271
yield self.storage.eq(value >> self.alignment_bits)
122272
yield self.re.eq(1)
123273
yield
@@ -162,6 +312,17 @@ def gatherer(self):
162312

163313

164314
class AutoCSR:
315+
"""MixIn to provide bus independent access to CSR registers.
316+
317+
A module can inherit from the ``AutoCSR`` class, which provides
318+
``get_csrs``, ``get_memories`` and ``get_constants`` methods that scan for
319+
CSR and memory attributes and return their list.
320+
321+
If the module has child objects that implement ``get_csrs``,
322+
``get_memories`` or ``get_constants``, they will be called by the
323+
``AutoCSR`` methods and their CSR and memories added to the lists returned,
324+
with the child objects' names as prefixes.
325+
"""
165326
get_memories = _make_gatherer("get_memories", Memory, memprefix)
166327
get_csrs = _make_gatherer("get_csrs", _CSRBase, csrprefix)
167328
get_constants = _make_gatherer("get_constants", CSRConstant, csrprefix)

‎misoc/interconnect/csr_bus.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
"""
2+
CSR-2 bus
3+
=========
4+
5+
The CSR-2 bus is a low-bandwidth, resource-sensitive bus designed for accessing
6+
the configuration and status registers of cores from software.
7+
"""
8+
19
from migen import *
210
from migen.genlib.record import *
311
from migen.genlib.misc import chooser

‎misoc/interconnect/csr_eventmanager.py

+79-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
The event manager provides a systematic way to generate standard interrupt
3+
controllers.
4+
"""
5+
16
from functools import reduce
27
from operator import or_
38

@@ -8,16 +13,44 @@
813

914

1015
class _EventSource(DUID):
16+
"""Base class for EventSources.
17+
18+
Attributes
19+
----------
20+
trigger : Signal(), in
21+
Signal which interfaces with the user design.
22+
23+
status : Signal(), out
24+
Contains the current level of the trigger signal.
25+
This value ends up in the ``status`` register.
26+
27+
pending : Signal(), out
28+
A trigger event has occurred and not yet cleared.
29+
This value ends up in the ``pending`` register.
30+
31+
clear : Signal(), in
32+
Clear after a trigger event.
33+
Ignored by some event sources.
34+
"""
35+
1136
def __init__(self):
1237
DUID.__init__(self)
13-
self.status = Signal() # value in the status register
14-
self.pending = Signal() # value in the pending register + assert irq if unmasked
15-
self.trigger = Signal() # trigger signal interface to the user design
16-
self.clear = Signal() # clearing attempt by W1C to pending register, ignored by some event sources
38+
self.status = Signal()
39+
self.pending = Signal()
40+
self.trigger = Signal()
41+
self.clear = Signal()
1742

1843

19-
# set on a positive trigger pulse
2044
class EventSourcePulse(Module, _EventSource):
45+
"""EventSource which triggers on a pulse.
46+
47+
The event stays asserted after the ``trigger`` signal goes low, and until
48+
software acknowledges it.
49+
50+
An example use is to pulse ``trigger`` high for 1 cycle after the reception
51+
of a character in a UART.
52+
"""
53+
2154
def __init__(self):
2255
_EventSource.__init__(self)
2356
self.comb += self.status.eq(0)
@@ -27,8 +60,15 @@ def __init__(self):
2760
]
2861

2962

30-
# set on the falling edge of the trigger, status = trigger
3163
class EventSourceProcess(Module, _EventSource):
64+
"""EventSource which triggers on a falling edge.
65+
66+
The purpose of this event source is to monitor the status of processes and
67+
generate an interrupt on their completion.
68+
69+
The signal ``trigger`` can be connected to the ``busy`` signal of a
70+
dataflow actor, for example.
71+
"""
3272
def __init__(self):
3373
_EventSource.__init__(self)
3474
self.comb += self.status.eq(self.trigger)
@@ -40,8 +80,13 @@ def __init__(self):
4080
]
4181

4282

43-
# all status set by external trigger
4483
class EventSourceLevel(Module, _EventSource):
84+
"""EventSource which trigger contains the instantaneous state of the event.
85+
86+
It must be set and released by the user design. For example, a DMA
87+
controller with several slots can use this event source to signal that one
88+
or more slots require CPU attention.
89+
"""
4590
def __init__(self):
4691
_EventSource.__init__(self)
4792
self.comb += [
@@ -51,6 +96,31 @@ def __init__(self):
5196

5297

5398
class EventManager(Module, AutoCSR):
99+
"""Provide an IRQ and CSR registers for a set of event sources.
100+
101+
Each event source is assigned one bit in each of those registers.
102+
103+
Attributes
104+
----------
105+
irq : Signal(), out
106+
A signal which is driven high whenever there is a pending and unmasked
107+
event.
108+
It is typically connected to an interrupt line of a CPU.
109+
110+
status : CSR(n), read-only
111+
Contains the current level of the trigger line of
112+
``EventSourceProcess`` and ``EventSourceLevel`` sources.
113+
It is always 0 for ``EventSourcePulse``
114+
115+
pending : CSR(n), read-write
116+
Contains the currently asserted events. Writing 1 to the bit assigned
117+
to an event clears it.
118+
119+
enable : CSR(n), read-write
120+
Defines which asserted events will cause the ``irq`` line to be
121+
asserted.
122+
"""
123+
54124
def __init__(self):
55125
self.irq = Signal()
56126

@@ -81,6 +151,8 @@ def __setattr__(self, name, value):
81151

82152

83153
class SharedIRQ(Module):
154+
"""Allow an IRQ signal to be shared between multiple EventManager objects."""
155+
84156
def __init__(self, *event_managers):
85157
self.irq = Signal()
86158
self.comb += self.irq.eq(reduce(or_, [ev.irq for ev in event_managers]))

0 commit comments

Comments
 (0)
Please sign in to comment.