Skip to content

Commit

Permalink
sim: fix memory writes with signed shapes.
Browse files Browse the repository at this point in the history
  • Loading branch information
wanda-phi authored and whitequark committed Aug 27, 2024
1 parent be47958 commit fff8f0b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
8 changes: 7 additions & 1 deletion amaranth/sim/pysim.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,11 @@ def __init__(self, state, addr):


class _PyMemoryState(BaseMemoryState):
__slots__ = ("memory", "data", "write_queue", "wakers", "pending")
__slots__ = ("memory", "shape", "data", "write_queue", "wakers", "pending")

def __init__(self, memory, pending):
self.memory = memory
self.shape = Shape.cast(memory.shape)
self.pending = pending
self.wakers = list()
self.reset()
Expand All @@ -419,6 +420,11 @@ def write(self, addr, value, mask=None):
self.write_queue[addr] = self.data[addr]
if mask is not None:
value = (value & mask) | (self.write_queue[addr] & ~mask)
if self.shape.signed:
if value & (1 << (self.shape.width - 1)):
value |= -1 << (self.shape.width)
else:
value &= (1 << (self.shape.width)) - 1
self.write_queue[addr] = value
self.pending.add(self)

Expand Down
7 changes: 6 additions & 1 deletion tests/test_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -1418,15 +1418,20 @@ class MyEnum(enum.Enum, shape=2):
mem1 = MemoryData(shape=8, depth=4, init=[1, 2, 3])
mem2 = MemoryData(shape=MyEnum, depth=4, init=[MyEnum.A, MyEnum.B, MyEnum.C])
mem3 = MemoryData(shape=data.StructLayout({"a": signed(3), "b": 2}), depth=4, init=[{"a": 2, "b": 1}])
mem4 = MemoryData(shape=signed(8), depth=4, init=[1, -2, 3])

async def testbench(ctx):
await ctx.delay(1e-6)
ctx.set(mem1[0], 4)
ctx.set(mem2[3], MyEnum.C)
ctx.set(mem3[2], {"a": -1, "b": 2})
ctx.set(mem4[1][4:], 0)
ctx.set(mem4[3][7], 1)
await ctx.delay(1e-6)
self.assertEqual(ctx.get(mem4[1]), 0xe)
self.assertEqual(ctx.get(mem4[3]), -128)

with self.assertSimulation(Module(), traces=[mem1, mem2, mem3]) as sim:
with self.assertSimulation(Module(), traces=[mem1, mem2, mem3, mem4]) as sim:
sim.add_testbench(testbench)

def test_multiple_modules(self):
Expand Down

0 comments on commit fff8f0b

Please sign in to comment.