Skip to content

Commit

Permalink
csr.reg: add support for reserved fields.
Browse files Browse the repository at this point in the history
  • Loading branch information
jfng committed Jan 12, 2024
1 parent 4923bb4 commit 24e7ee7
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 4 deletions.
47 changes: 46 additions & 1 deletion amaranth_soc/csr/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .reg import FieldPort


__all__ = ["R", "W", "RW", "RW1C", "RW1S"]
__all__ = ["R", "W", "RW", "RW1C", "RW1S", "ResRAW0", "ResRAWL", "ResR0WA", "ResR0W0"]


class R(wiring.Component):
Expand Down Expand Up @@ -216,3 +216,48 @@ def elaborate(self, platform):
]

return m


class _Reserved(wiring.Component):
_doc_template = """
{description}
Parameters
----------
shape : :ref:`shape-castable <lang-shapecasting>`
Shape of the field.
Interface attributes
--------------------
port : :class:`FieldPort`
Field port.
"""
def __init__(self, shape):
super().__init__({"port": In(FieldPort.Signature(shape, access="nc"))})

def elaborate(self, platform):
return Module()


class ResRAW0(_Reserved):
__doc__ = _Reserved._doc_template.format(description="""
A reserved read-any/write-zero field action.
""")


class ResRAWL(_Reserved):
__doc__ = _Reserved._doc_template.format(description="""
A reserved read-any/write-last field action.
""")


class ResR0WA(_Reserved):
__doc__ = _Reserved._doc_template.format(description="""
A reserved read-zero/write-any field action.
""")


class ResR0W0(_Reserved):
__doc__ = _Reserved._doc_template.format(description="""
A reserved read-zero/write-zero field action.
""")
1 change: 1 addition & 0 deletions amaranth_soc/csr/reg.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Access(enum.Enum):
R = "r"
W = "w"
RW = "rw"
NC = "nc"

def readable(self):
return self == self.R or self == self.RW
Expand Down
58 changes: 55 additions & 3 deletions tests/test_csr_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class RTestCase(unittest.TestCase):
def test_simple(self):
f = action.R(unsigned(4))
self.assertEqual(f.r_data.shape(), unsigned(4))
self.assertTrue(f.port.access.readable())
self.assertFalse(f.port.access.writable())

def test_sim(self):
dut = action.R(unsigned(4))
Expand All @@ -30,6 +32,8 @@ class WTestCase(unittest.TestCase):
def test_simple(self):
f = action.W(unsigned(4))
self.assertEqual(f.w_data.shape(), unsigned(4))
self.assertFalse(f.port.access.readable())
self.assertTrue(f.port.access.writable())

def test_sim(self):
dut = action.W(unsigned(4))
Expand All @@ -48,11 +52,16 @@ def process():
class RWTestCase(unittest.TestCase):
def test_simple(self):
f4 = action.RW(unsigned(4), reset=0x5)
f8 = action.RW(signed(8))
self.assertEqual(f4.data.shape(), unsigned(4))
self.assertEqual(f4.reset, 0x5)
self.assertTrue(f4.port.access.readable())
self.assertTrue(f4.port.access.writable())

f8 = action.RW(signed(8))
self.assertEqual(f8.data.shape(), signed(8))
self.assertEqual(f8.reset, 0)
self.assertTrue(f8.port.access.readable())
self.assertTrue(f8.port.access.writable())

def test_sim(self):
dut = action.RW(unsigned(4), reset=0x5)
Expand All @@ -77,13 +86,18 @@ def process():
class RW1CTestCase(unittest.TestCase):
def test_simple(self):
f4 = action.RW1C(unsigned(4), reset=0x5)
f8 = action.RW1C(signed(8))
self.assertEqual(f4.data.shape(), unsigned(4))
self.assertEqual(f4.set .shape(), unsigned(4))
self.assertEqual(f4.reset, 0x5)
self.assertTrue(f4.port.access.readable())
self.assertTrue(f4.port.access.writable())

f8 = action.RW1C(signed(8))
self.assertEqual(f8.data.shape(), signed(8))
self.assertEqual(f8.set .shape(), signed(8))
self.assertEqual(f8.reset, 0)
self.assertTrue(f8.port.access.readable())
self.assertTrue(f8.port.access.writable())

def test_sim(self):
dut = action.RW1C(unsigned(4), reset=0xf)
Expand Down Expand Up @@ -115,13 +129,18 @@ def process():
class RW1STestCase(unittest.TestCase):
def test_simple(self):
f4 = action.RW1S(unsigned(4), reset=0x5)
f8 = action.RW1S(signed(8))
self.assertEqual(f4.data .shape(), unsigned(4))
self.assertEqual(f4.clear.shape(), unsigned(4))
self.assertEqual(f4.reset, 0x5)
self.assertTrue(f4.port.access.readable())
self.assertTrue(f4.port.access.writable())

f8 = action.RW1S(signed(8))
self.assertEqual(f8.data .shape(), signed(8))
self.assertEqual(f8.clear.shape(), signed(8))
self.assertEqual(f8.reset, 0)
self.assertTrue(f8.port.access.readable())
self.assertTrue(f8.port.access.writable())

def test_sim(self):
dut = action.RW1S(unsigned(4), reset=0x5)
Expand All @@ -148,3 +167,36 @@ def process():
sim.add_sync_process(process)
with sim.write_vcd(vcd_file=open("test.vcd", "w")):
sim.run()


class ResRAW0TestCase(unittest.TestCase):
def test_simple(self):
f = action.ResRAW0(unsigned(4))
self.assertEqual(f.port.shape, unsigned(4))
self.assertFalse(f.port.access.readable())
self.assertFalse(f.port.access.writable())
self.assertIsInstance(f.elaborate(platform=None), Module)

class ResRAWLTestCase(unittest.TestCase):
def test_simple(self):
f = action.ResRAWL(unsigned(4))
self.assertEqual(f.port.shape, unsigned(4))
self.assertFalse(f.port.access.readable())
self.assertFalse(f.port.access.writable())
self.assertIsInstance(f.elaborate(platform=None), Module)

class ResR0WATestCase(unittest.TestCase):
def test_simple(self):
f = action.ResR0WA(unsigned(4))
self.assertEqual(f.port.shape, unsigned(4))
self.assertFalse(f.port.access.readable())
self.assertFalse(f.port.access.writable())
self.assertIsInstance(f.elaborate(platform=None), Module)

class ResR0W0TestCase(unittest.TestCase):
def test_simple(self):
f = action.ResR0W0(unsigned(4))
self.assertEqual(f.port.shape, unsigned(4))
self.assertFalse(f.port.access.readable())
self.assertFalse(f.port.access.writable())
self.assertIsInstance(f.elaborate(platform=None), Module)
11 changes: 11 additions & 0 deletions tests/test_csr_reg.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ def test_shape_0_rw(self):
"w_stb": Out(1),
}).members)

def test_shape_8_nc(self):
sig = FieldPort.Signature(8, "nc")
self.assertEqual(sig.shape, unsigned(8))
self.assertEqual(sig.access, FieldPort.Access.NC)
self.assertEqual(sig.members, wiring.Signature({
"r_data": In(unsigned(8)),
"r_stb": Out(1),
"w_data": Out(unsigned(8)),
"w_stb": Out(1),
}).members)

def test_create(self):
sig = FieldPort.Signature(unsigned(8), "rw")
port = sig.create(path=("foo", "bar"))
Expand Down

0 comments on commit 24e7ee7

Please sign in to comment.