Skip to content

Commit fa90c62

Browse files
committed
csr.reg: add support for reserved fields.
1 parent db45b84 commit fa90c62

File tree

4 files changed

+113
-4
lines changed

4 files changed

+113
-4
lines changed

amaranth_soc/csr/action.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .reg import FieldPort
66

77

8-
__all__ = ["R", "W", "RW", "RW1C", "RW1S"]
8+
__all__ = ["R", "W", "RW", "RW1C", "RW1S", "ResRAW0", "ResRAWL", "ResR0WA", "ResR0W0"]
99

1010

1111
class R(wiring.Component):
@@ -216,3 +216,48 @@ def elaborate(self, platform):
216216
]
217217

218218
return m
219+
220+
221+
class _Reserved(wiring.Component):
222+
_doc_template = """
223+
{description}
224+
225+
Parameters
226+
----------
227+
shape : :ref:`shape-castable <lang-shapecasting>`
228+
Shape of the field.
229+
230+
Interface attributes
231+
--------------------
232+
port : :class:`FieldPort`
233+
Field port.
234+
"""
235+
def __init__(self, shape):
236+
super().__init__({"port": In(FieldPort.Signature(shape, access="nc"))})
237+
238+
def elaborate(self, platform):
239+
return Module()
240+
241+
242+
class ResRAW0(_Reserved):
243+
__doc__ = _Reserved._doc_template.format(description="""
244+
A reserved read-any/write-zero field action.
245+
""")
246+
247+
248+
class ResRAWL(_Reserved):
249+
__doc__ = _Reserved._doc_template.format(description="""
250+
A reserved read-any/write-last field action.
251+
""")
252+
253+
254+
class ResR0WA(_Reserved):
255+
__doc__ = _Reserved._doc_template.format(description="""
256+
A reserved read-zero/write-any field action.
257+
""")
258+
259+
260+
class ResR0W0(_Reserved):
261+
__doc__ = _Reserved._doc_template.format(description="""
262+
A reserved read-zero/write-zero field action.
263+
""")

amaranth_soc/csr/reg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Access(enum.Enum):
1616
R = "r"
1717
W = "w"
1818
RW = "rw"
19+
NC = "nc"
1920

2021
def readable(self):
2122
return self == self.R or self == self.RW

tests/test_csr_action.py

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class RTestCase(unittest.TestCase):
1111
def test_simple(self):
1212
f = action.R(unsigned(4))
1313
self.assertEqual(f.r_data.shape(), unsigned(4))
14+
self.assertTrue(f.port.access.readable())
15+
self.assertFalse(f.port.access.writable())
1416

1517
def test_sim(self):
1618
dut = action.R(unsigned(4))
@@ -30,6 +32,8 @@ class WTestCase(unittest.TestCase):
3032
def test_simple(self):
3133
f = action.W(unsigned(4))
3234
self.assertEqual(f.w_data.shape(), unsigned(4))
35+
self.assertFalse(f.port.access.readable())
36+
self.assertTrue(f.port.access.writable())
3337

3438
def test_sim(self):
3539
dut = action.W(unsigned(4))
@@ -48,11 +52,16 @@ def process():
4852
class RWTestCase(unittest.TestCase):
4953
def test_simple(self):
5054
f4 = action.RW(unsigned(4), reset=0x5)
51-
f8 = action.RW(signed(8))
5255
self.assertEqual(f4.data.shape(), unsigned(4))
5356
self.assertEqual(f4.reset, 0x5)
57+
self.assertTrue(f4.port.access.readable())
58+
self.assertTrue(f4.port.access.writable())
59+
60+
f8 = action.RW(signed(8))
5461
self.assertEqual(f8.data.shape(), signed(8))
5562
self.assertEqual(f8.reset, 0)
63+
self.assertTrue(f8.port.access.readable())
64+
self.assertTrue(f8.port.access.writable())
5665

5766
def test_sim(self):
5867
dut = action.RW(unsigned(4), reset=0x5)
@@ -77,13 +86,18 @@ def process():
7786
class RW1CTestCase(unittest.TestCase):
7887
def test_simple(self):
7988
f4 = action.RW1C(unsigned(4), reset=0x5)
80-
f8 = action.RW1C(signed(8))
8189
self.assertEqual(f4.data.shape(), unsigned(4))
8290
self.assertEqual(f4.set .shape(), unsigned(4))
8391
self.assertEqual(f4.reset, 0x5)
92+
self.assertTrue(f4.port.access.readable())
93+
self.assertTrue(f4.port.access.writable())
94+
95+
f8 = action.RW1C(signed(8))
8496
self.assertEqual(f8.data.shape(), signed(8))
8597
self.assertEqual(f8.set .shape(), signed(8))
8698
self.assertEqual(f8.reset, 0)
99+
self.assertTrue(f8.port.access.readable())
100+
self.assertTrue(f8.port.access.writable())
87101

88102
def test_sim(self):
89103
dut = action.RW1C(unsigned(4), reset=0xf)
@@ -115,13 +129,18 @@ def process():
115129
class RW1STestCase(unittest.TestCase):
116130
def test_simple(self):
117131
f4 = action.RW1S(unsigned(4), reset=0x5)
118-
f8 = action.RW1S(signed(8))
119132
self.assertEqual(f4.data .shape(), unsigned(4))
120133
self.assertEqual(f4.clear.shape(), unsigned(4))
121134
self.assertEqual(f4.reset, 0x5)
135+
self.assertTrue(f4.port.access.readable())
136+
self.assertTrue(f4.port.access.writable())
137+
138+
f8 = action.RW1S(signed(8))
122139
self.assertEqual(f8.data .shape(), signed(8))
123140
self.assertEqual(f8.clear.shape(), signed(8))
124141
self.assertEqual(f8.reset, 0)
142+
self.assertTrue(f8.port.access.readable())
143+
self.assertTrue(f8.port.access.writable())
125144

126145
def test_sim(self):
127146
dut = action.RW1S(unsigned(4), reset=0x5)
@@ -148,3 +167,36 @@ def process():
148167
sim.add_sync_process(process)
149168
with sim.write_vcd(vcd_file=open("test.vcd", "w")):
150169
sim.run()
170+
171+
172+
class ResRAW0TestCase(unittest.TestCase):
173+
def test_simple(self):
174+
f = action.ResRAW0(unsigned(4))
175+
self.assertEqual(f.port.shape, unsigned(4))
176+
self.assertFalse(f.port.access.readable())
177+
self.assertFalse(f.port.access.writable())
178+
self.assertIsInstance(f.elaborate(platform=None), Module)
179+
180+
class ResRAWLTestCase(unittest.TestCase):
181+
def test_simple(self):
182+
f = action.ResRAWL(unsigned(4))
183+
self.assertEqual(f.port.shape, unsigned(4))
184+
self.assertFalse(f.port.access.readable())
185+
self.assertFalse(f.port.access.writable())
186+
self.assertIsInstance(f.elaborate(platform=None), Module)
187+
188+
class ResR0WATestCase(unittest.TestCase):
189+
def test_simple(self):
190+
f = action.ResR0WA(unsigned(4))
191+
self.assertEqual(f.port.shape, unsigned(4))
192+
self.assertFalse(f.port.access.readable())
193+
self.assertFalse(f.port.access.writable())
194+
self.assertIsInstance(f.elaborate(platform=None), Module)
195+
196+
class ResR0W0TestCase(unittest.TestCase):
197+
def test_simple(self):
198+
f = action.ResR0W0(unsigned(4))
199+
self.assertEqual(f.port.shape, unsigned(4))
200+
self.assertFalse(f.port.access.readable())
201+
self.assertFalse(f.port.access.writable())
202+
self.assertIsInstance(f.elaborate(platform=None), Module)

tests/test_csr_reg.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ def test_shape_0_rw(self):
6969
"w_stb": Out(1),
7070
}).members)
7171

72+
def test_shape_8_nc(self):
73+
sig = FieldPort.Signature(8, "nc")
74+
self.assertEqual(sig.shape, unsigned(8))
75+
self.assertEqual(sig.access, FieldPort.Access.NC)
76+
self.assertEqual(sig.members, wiring.Signature({
77+
"r_data": In(unsigned(8)),
78+
"r_stb": Out(1),
79+
"w_data": Out(unsigned(8)),
80+
"w_stb": Out(1),
81+
}).members)
82+
7283
def test_create(self):
7384
sig = FieldPort.Signature(unsigned(8), "rw")
7485
port = sig.create(path=("foo", "bar"))

0 commit comments

Comments
 (0)