soc/interconnect/csr: improve ident.
[litex.git] / litex / soc / interconnect / csr.py
1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2016-2019 Tim 'mithro' Ansell <me@mith.ro>
4 # This file is Copyright (c) 2019 Sean Cross <sean@xobs.io>
5 # License: BSD
6
7
8 """
9 Configuration and Status Registers
10 **********************************
11
12 The lowest-level description of a register is provided by the ``CSR`` class,
13 which maps to the value at a single address on the target bus. Also provided
14 are helper classes for dealing with values larger than the CSR buses data
15 width.
16
17 * ``CSRConstant``, for constant values.
18 * ``CSRStatus``, for providing information to the CPU.
19 * ``CSRStorage``, for allowing control via the CPU.
20
21 Generating register banks
22 =========================
23 A module can provide bus-independent CSRs by implementing a ``get_csrs`` method
24 that returns a list of instances of the classes described above.
25
26 Similarly, bus-independent memories can be returned as a list by a
27 ``get_memories`` method.
28
29 To avoid listing those manually, a module can inherit from the ``AutoCSR``
30 class, which provides ``get_csrs`` and ``get_memories`` methods that scan for
31 CSR and memory attributes and return their list.
32 """
33
34 from enum import IntEnum
35
36 from migen import *
37 from migen.util.misc import xdir
38 from migen.fhdl.tracer import get_obj_var_name
39
40 # CSRBase ------------------------------------------------------------------------------------------
41
42 class _CSRBase(DUID):
43 def __init__(self, size, name):
44 DUID.__init__(self)
45 self.name = get_obj_var_name(name)
46 if self.name is None:
47 raise ValueError("Cannot extract CSR name from code, need to specify.")
48 self.size = size
49
50 # CSRConstant --------------------------------------------------------------------------------------
51
52 class CSRConstant(DUID):
53 """Register which contains a constant value.
54
55 Useful for providing information on how a HDL was instantiated to firmware
56 running on the device.
57 """
58
59 def __init__(self, value, bits_sign=None, name=None):
60 DUID.__init__(self)
61 self.value = Constant(value, bits_sign)
62 self.name = get_obj_var_name(name)
63 if self.name is None:
64 raise ValueError("Cannot extract CSR name from code, need to specify.")
65
66 def read(self):
67 """Read method for simulation."""
68 return self.value.value
69
70 # CSR ----------------------------------------------------------------------------------------------
71
72 class CSR(_CSRBase):
73 """Basic CSR register.
74
75 Parameters
76 ----------
77 size : int
78 Size of the CSR register in bits.
79 Must be less than CSR bus width!
80
81 name : string
82 Provide (or override the name) of the CSR register.
83
84 Attributes
85 ----------
86 r : Signal(size), out
87 Contains the data written from the bus interface.
88 ``r`` is only valid when ``re`` is high.
89
90 re : Signal(), out
91 The strobe signal for ``r``.
92 It is active for one cycle, after or during a write from the bus.
93
94 w : Signal(size), in
95 The value to be read from the bus.
96 Must be provided at all times.
97
98 we : Signal(), out
99 The strobe signal for ``w``.
100 It is active for one cycle, after or during a read from the bus.
101 """
102
103 def __init__(self, size=1, name=None):
104 _CSRBase.__init__(self, size, name)
105 self.re = Signal(name=self.name + "_re")
106 self.r = Signal(self.size, name=self.name + "_r")
107 self.we = Signal(name=self.name + "_we")
108 self.w = Signal(self.size, name=self.name + "_w")
109
110 def read(self):
111 """Read method for simulation."""
112 yield self.we.eq(1)
113 value = (yield self.w)
114 yield
115 yield self.we.eq(0)
116 return value
117
118 def write(self, value):
119 """Write method for simulation."""
120 yield self.r.eq(value)
121 yield self.re.eq(1)
122 yield
123 yield self.re.eq(0)
124
125
126 class _CompoundCSR(_CSRBase, Module):
127 def __init__(self, size, name):
128 _CSRBase.__init__(self, size, name)
129 self.simple_csrs = []
130
131 def get_simple_csrs(self):
132 if not self.finalized:
133 raise FinalizeError
134 return self.simple_csrs
135
136 def do_finalize(self, busword):
137 raise NotImplementedError
138
139 # CSRAccess ----------------------------------------------------------------------------------------
140
141 class CSRAccess(IntEnum):
142 WriteOnly = 0
143 ReadOnly = 1
144 ReadWrite = 2
145
146 # CSRField -----------------------------------------------------------------------------------------
147
148 class CSRField(Signal):
149 """CSR Field.
150
151 Parameters / Attributes
152 -----------------------
153 name : string
154 Name of the CSR field.
155
156 size : int
157 Size of the CSR field in bits.
158
159 offset : int (optional)
160 Offset of the CSR field on the CSR register in bits.
161
162 reset: int (optional)
163 Reset value of the CSR field.
164
165 description: string (optional)
166 Description of the CSR Field (can be used to document the code and/or to be reused by tools
167 to create the documentation).
168
169 pulse: boolean (optional)
170 Field value is only valid for one cycle when set to True. Only valid for 1-bit fields.
171
172 access: enum (optional)
173 Access type of the CSR field.
174
175 values: list (optional)
176 A list of supported values.
177 If this is specified, a table will be generated containing the values in the specified order.
178 The `value` must be an integer in order to allow for automatic constant generation in an IDE,
179 except "do not care" bits are allowed.
180 In the three-tuple variation, the middle value represents an enum value that can be displayed
181 instead of the value.
182 [
183 ("0b0000", "disable the timer"),
184 ("0b0001", "slow", "slow timer"),
185 ("0b1xxx", "fast timer"),
186 ]
187 """
188
189 def __init__(self, name, size=1, offset=None, reset=0, description=None, pulse=False, access=None, values=None):
190 assert access is None or (access in CSRAccess.values())
191 self.name = name
192 self.size = size
193 self.offset = offset
194 self.reset_value = reset
195 self.description = description
196 self.access = access
197 self.pulse = pulse
198 self.values = values
199 Signal.__init__(self, size, name=name, reset=reset)
200
201
202 class CSRFieldAggregate:
203 """CSR Field Aggregate."""
204
205 def __init__(self, fields, access):
206 self.check_names(fields)
207 self.check_ordering_overlap(fields)
208 self.fields = fields
209 for field in fields:
210 if field.access is None:
211 field.access = access
212 elif field.access == CSRAccess.ReadOnly:
213 assert not field.pulse
214 assert field.access == CSRAccess.ReadOnly
215 elif field.access == CSRAccess.ReadWrite:
216 assert field.access in [CSRAccess.ReadWrite, CSRAccess.WriteOnly]
217 if field.pulse:
218 field.access = CSRAccess.WriteOnly
219 setattr(self, field.name, field)
220
221 @staticmethod
222 def check_names(fields):
223 names = []
224 for field in fields:
225 if field.name in names:
226 raise ValueError("CSRField \"{}\" name is already used in CSR register".format(field.name))
227 else:
228 names.append(field.name)
229
230 @staticmethod
231 def check_ordering_overlap(fields):
232 offset = 0
233 for field in fields:
234 if field.offset is not None:
235 if field.offset < offset:
236 raise ValueError("CSRField ordering/overlap issue on \"{}\" field".format(field.name))
237 offset = field.offset
238 else:
239 field.offset = offset
240 offset += field.size
241
242 def get_size(self):
243 return self.fields[-1].offset + self.fields[-1].size
244
245 def get_reset(self):
246 reset = 0
247 for field in self.fields:
248 reset |= (field.reset_value << field.offset)
249 return reset
250
251 # CSRStatus ----------------------------------------------------------------------------------------
252
253 class CSRStatus(_CompoundCSR):
254 """Status Register.
255
256 The ``CSRStatus`` class is meant to be used as a status register that is read-only from the CPU.
257
258 The user design is expected to drive its ``status`` signal.
259
260 The advantage of using ``CSRStatus`` instead of using ``CSR`` and driving ``w`` is that the
261 width of ``CSRStatus`` can be arbitrary.
262
263 Status registers larger than the bus word width are automatically broken down into several
264 ``CSR`` registers to span several addresses.
265
266 *Be careful, though:* the atomicity of reads is not guaranteed.
267
268 Parameters
269 ----------
270 size : int
271 Size of the CSR register in bits.
272 Can be bigger than the CSR bus width.
273
274 reset : string
275 Value of the register after reset.
276
277 name : string
278 Provide (or override the name) of the ``CSRStatus`` register.
279
280 Attributes
281 ----------
282 status : Signal(size), in
283 The value of the CSRStatus register.
284 """
285
286 def __init__(self, size=1, reset=0, fields=[], name=None, description=None):
287 if fields != []:
288 self.fields = CSRFieldAggregate(fields, CSRAccess.ReadOnly)
289 size = self.fields.get_size()
290 reset = self.fields.get_reset()
291 _CompoundCSR.__init__(self, size, name)
292 self.description = description
293 self.status = Signal(self.size, reset=reset)
294 self.we = Signal()
295 for field in fields:
296 self.comb += self.status[field.offset:field.offset + field.size].eq(getattr(self.fields, field.name))
297
298 def do_finalize(self, busword):
299 nwords = (self.size + busword - 1)//busword
300 for i in reversed(range(nwords)):
301 nbits = min(self.size - i*busword, busword)
302 sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name)
303 self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
304 self.simple_csrs.append(sc)
305 self.comb += self.we.eq(sc.we)
306
307 def read(self):
308 """Read method for simulation."""
309 yield self.we.eq(1)
310 value = (yield self.status)
311 yield
312 yield self.we.eq(0)
313 return value
314
315 # CSRStorage ---------------------------------------------------------------------------------------
316
317 class CSRStorage(_CompoundCSR):
318 """Control Register.
319
320 The ``CSRStorage`` class provides a memory location that can be read and written by the CPU, and read and optionally written by the design.
321
322 It can span several CSR addresses.
323
324 Parameters
325 ----------
326 size : int
327 Size of the CSR register in bits. Can be bigger than the CSR bus width.
328
329 reset : string
330 Value of the register after reset.
331
332 reset_less : bool
333 If `True`, do not generate reset logic for CSRStorage.
334
335 atomic_write : bool
336 Provide an mechanism for atomic CPU writes is provided. When enabled, writes to the first
337 CSR addresses go to a back-buffer whose contents are atomically copied to the main buffer
338 when the last address is written.
339
340 write_from_dev : bool
341 Allow the design to update the CSRStorage value. *Warning*: The atomicity of reads by the
342 CPU is not guaranteed.
343
344 name : string
345 Provide (or override the name) of the ``CSRStatus`` register.
346
347 Attributes
348 ----------
349 storage : Signal(size), out
350 Signal providing the value of the ``CSRStorage`` object.
351
352 re : Signal(), in
353 The strobe signal indicating a write to the ``CSRStorage`` register from the CPU. It is active
354 for one cycle, after or during a write from the bus.
355
356 we : Signal(), out
357 The strobe signal to write to the ``CSRStorage`` register from the logic. Only available when
358 ``write_from_dev == True``
359
360
361 dat_w : Signal(), out
362 The write data to write to the ``CSRStorage`` register from the logic. Only available when
363 ``write_from_dev == True``
364 """
365
366 def __init__(self, size=1, reset=0, reset_less=False, fields=[], atomic_write=False, write_from_dev=False, name=None, description=None):
367 if fields != []:
368 self.fields = CSRFieldAggregate(fields, CSRAccess.ReadWrite)
369 size = self.fields.get_size()
370 reset = self.fields.get_reset()
371 _CompoundCSR.__init__(self, size, name)
372 self.description = description
373 self.storage = Signal(self.size, reset=reset, reset_less=reset_less)
374 self.atomic_write = atomic_write
375 self.re = Signal()
376 if write_from_dev:
377 self.we = Signal()
378 self.dat_w = Signal(self.size)
379 self.sync += If(self.we, self.storage.eq(self.dat_w))
380 for field in [*fields]:
381 field_assign = getattr(self.fields, field.name).eq(self.storage[field.offset:field.offset + field.size])
382 if field.pulse:
383 self.comb += If(self.re, field_assign)
384 else:
385 self.comb += field_assign
386
387 def do_finalize(self, busword):
388 nwords = (self.size + busword - 1)//busword
389 if nwords > 1 and self.atomic_write:
390 backstore = Signal(self.size - busword, name=self.name + "_backstore")
391 for i in reversed(range(nwords)):
392 nbits = min(self.size - i*busword, busword)
393 sc = CSR(nbits, self.name + str(i) if nwords else self.name)
394 self.simple_csrs.append(sc)
395 lo = i*busword
396 hi = lo+nbits
397 # read
398 self.comb += sc.w.eq(self.storage[lo:hi])
399 # write
400 if nwords > 1 and self.atomic_write:
401 if i:
402 self.sync += If(sc.re, backstore[lo-busword:hi-busword].eq(sc.r))
403 else:
404 self.sync += If(sc.re, self.storage.eq(Cat(sc.r, backstore)))
405 else:
406 self.sync += If(sc.re, self.storage[lo:hi].eq(sc.r))
407 self.sync += self.re.eq(sc.re)
408
409 def read(self):
410 """Read method for simulation."""
411 return (yield self.storage)
412
413 def write(self, value):
414 """Write method for simulation."""
415 yield self.storage.eq(value)
416 yield self.re.eq(1)
417 if hasattr(self, "fields"):
418 for field in [*self.fields.fields]:
419 yield getattr(self.fields, field.name).eq((value >> field.offset) & (2**field.size -1))
420 yield
421 yield self.re.eq(0)
422 if hasattr(self, "fields"):
423 for field in [*self.fields.fields]:
424 if field.pulse:
425 yield getattr(self.fields, field.name).eq(0)
426
427 # AutoCSR & Helpers --------------------------------------------------------------------------------
428
429 def csrprefix(prefix, csrs, done):
430 for csr in csrs:
431 if csr.duid not in done:
432 csr.name = prefix + csr.name
433 done.add(csr.duid)
434
435
436 def memprefix(prefix, memories, done):
437 for memory in memories:
438 if memory.duid not in done:
439 memory.name_override = prefix + memory.name_override
440 done.add(memory.duid)
441
442
443 def _make_gatherer(method, cls, prefix_cb):
444 def gatherer(self):
445 try:
446 exclude = self.autocsr_exclude
447 except AttributeError:
448 exclude = {}
449 try:
450 prefixed = self.__prefixed
451 except AttributeError:
452 prefixed = self.__prefixed = set()
453 r = []
454 for k, v in xdir(self, True):
455 if k not in exclude:
456 if isinstance(v, cls):
457 r.append(v)
458 elif hasattr(v, method) and callable(getattr(v, method)):
459 items = getattr(v, method)()
460 prefix_cb(k + "_", items, prefixed)
461 r += items
462 return sorted(r, key=lambda x: x.duid)
463 return gatherer
464
465
466 class AutoCSR:
467 """MixIn to provide bus independent access to CSR registers.
468
469 A module can inherit from the ``AutoCSR`` class, which provides ``get_csrs``, ``get_memories``
470 and ``get_constants`` methods that scan for CSR and memory attributes and return their list.
471
472 If the module has child objects that implement ``get_csrs``, ``get_memories`` or ``get_constants``,
473 they will be called by the``AutoCSR`` methods and their CSR and memories added to the lists returned,
474 with the child objects' names as prefixes.
475 """
476 get_memories = _make_gatherer("get_memories", Memory, memprefix)
477 get_csrs = _make_gatherer("get_csrs", _CSRBase, csrprefix)
478 get_constants = _make_gatherer("get_constants", CSRConstant, csrprefix)
479
480
481 class GenericBank(Module):
482 def __init__(self, description, busword):
483 # Turn description into simple CSRs and claim ownership of compound CSR modules
484 self.simple_csrs = []
485 for c in description:
486 if isinstance(c, CSR):
487 assert c.size <= busword
488 self.simple_csrs.append(c)
489 else:
490 c.finalize(busword)
491 self.simple_csrs += c.get_simple_csrs()
492 self.submodules += c
493 self.decode_bits = bits_for(len(self.simple_csrs)-1)