Skip to content

Commit 117e18c

Browse files
author
Jean-François Nguyen
committed
periph: add a PeripheralInfo class for metadata.
1 parent 20d0dd7 commit 117e18c

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

nmigen_soc/periph.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from .memory import MemoryMap
2+
from . import event
3+
4+
5+
__all__ = ["PeripheralInfo"]
6+
7+
8+
class PeripheralInfo:
9+
"""Peripheral metadata.
10+
11+
A unified description of the local resources of a peripheral. It may be queried in order to
12+
recover its memory windows, CSR registers and event sources.
13+
14+
Parameters
15+
----------
16+
memory_map : :class:`MemoryMap`
17+
Memory map of the peripheral.
18+
irq : :class:`event.Source`
19+
IRQ line of the peripheral. Optional.
20+
"""
21+
def __init__(self, *, memory_map, irq=None):
22+
if not isinstance(memory_map, MemoryMap):
23+
raise TypeError("Memory map must be an instance of MemoryMap, not {!r}"
24+
.format(memory_map))
25+
memory_map.freeze()
26+
self._memory_map = memory_map
27+
28+
if irq is not None and not isinstance(irq, event.Source):
29+
raise TypeError("IRQ line must be an instance of event.Source, not {!r}"
30+
.format(irq))
31+
self._irq = irq
32+
33+
@property
34+
def memory_map(self):
35+
"""Memory map.
36+
37+
Return value
38+
------------
39+
A :class:`MemoryMap` describing the local address space of the peripheral.
40+
"""
41+
return self._memory_map
42+
43+
@property
44+
def irq(self):
45+
"""IRQ line.
46+
47+
Return value
48+
------------
49+
An :class:`event.Source` used by the peripheral to request interrupts. If provided, its
50+
event map describes local events.
51+
52+
Exceptions
53+
----------
54+
Raises :exn:`NotImplementedError` if the peripheral info does not have an IRQ line.
55+
"""
56+
if self._irq is None:
57+
raise NotImplementedError("Peripheral info does not have an IRQ line"
58+
.format(self))
59+
return self._irq

nmigen_soc/test/test_periph.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import unittest
2+
3+
from ..periph import PeripheralInfo
4+
from ..memory import MemoryMap
5+
from .. import event
6+
7+
8+
class PeripheralInfoTestCase(unittest.TestCase):
9+
def test_memory_map(self):
10+
memory_map = MemoryMap(addr_width=1, data_width=8)
11+
info = PeripheralInfo(memory_map=memory_map)
12+
self.assertIs(info.memory_map, memory_map)
13+
14+
def test_memory_map_frozen(self):
15+
memory_map = MemoryMap(addr_width=1, data_width=8)
16+
info = PeripheralInfo(memory_map=memory_map)
17+
with self.assertRaisesRegex(ValueError,
18+
r"Memory map has been frozen. Address width cannot be extended further"):
19+
memory_map.add_resource("a", size=3, extend=True)
20+
21+
def test_memory_map_wrong(self):
22+
with self.assertRaisesRegex(TypeError,
23+
r"Memory map must be an instance of MemoryMap, not 'foo'"):
24+
info = PeripheralInfo(memory_map="foo")
25+
26+
def test_irq(self):
27+
memory_map = MemoryMap(addr_width=1, data_width=8)
28+
irq = event.Source()
29+
info = PeripheralInfo(memory_map=memory_map, irq=irq)
30+
self.assertIs(info.irq, irq)
31+
32+
def test_irq_none(self):
33+
memory_map = MemoryMap(addr_width=1, data_width=8)
34+
info = PeripheralInfo(memory_map=memory_map, irq=None)
35+
with self.assertRaisesRegex(NotImplementedError,
36+
r"Peripheral info does not have an IRQ line"):
37+
info.irq
38+
39+
def test_irq_default(self):
40+
memory_map = MemoryMap(addr_width=1, data_width=8)
41+
info = PeripheralInfo(memory_map=memory_map)
42+
with self.assertRaisesRegex(NotImplementedError,
43+
r"Peripheral info does not have an IRQ line"):
44+
info.irq
45+
46+
def test_irq_wrong(self):
47+
memory_map = MemoryMap(addr_width=1, data_width=8)
48+
with self.assertRaisesRegex(TypeError,
49+
r"IRQ line must be an instance of event.Source, not 'foo'"):
50+
info = PeripheralInfo(memory_map=memory_map, irq="foo")

0 commit comments

Comments
 (0)