Skip to content

Commit 9d6bd2c

Browse files
committed
wishbone.sram: fix behavior of back-to-back classic cycles.
Support for bursts has been removed, however a correct implementation may be added later. Fixes #96.
1 parent d99c8ee commit 9d6bd2c

File tree

2 files changed

+38
-94
lines changed

2 files changed

+38
-94
lines changed

amaranth_soc/wishbone/sram.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
class WishboneSRAM(wiring.Component):
1515
"""Wishbone-attached SRAM.
1616
17-
Wishbone bus accesses have a latency of one clock cycle. Incremental and constant address
18-
bursts are supported.
17+
Wishbone bus accesses have a latency of one clock cycle.
1918
2019
Arguments
2120
---------
@@ -63,8 +62,7 @@ def __init__(self, *, size, data_width, granularity=None, writable=True, init=()
6362
self._mem = Memory(self._mem_data)
6463

6564
super().__init__({"wb_bus": In(Signature(addr_width=exact_log2(self._mem.depth),
66-
data_width=data_width, granularity=granularity,
67-
features=("cti", "bte")))})
65+
data_width=data_width, granularity=granularity))})
6866

6967
self.wb_bus.memory_map = MemoryMap(addr_width=exact_log2(size), data_width=granularity)
7068
self.wb_bus.memory_map.add_resource(self._mem, name=("mem",), size=size)
@@ -103,11 +101,11 @@ def elaborate(self, platform):
103101
write_port.data.eq(self.wb_bus.dat_w),
104102
]
105103

106-
with m.If(self.wb_bus.cyc & self.wb_bus.stb):
104+
with m.If(self.wb_bus.ack):
105+
m.d.sync += self.wb_bus.ack.eq(0)
106+
with m.Elif(self.wb_bus.cyc & self.wb_bus.stb):
107107
if self.writable:
108108
m.d.comb += write_port.en.eq(Mux(self.wb_bus.we, self.wb_bus.sel, 0))
109109
m.d.sync += self.wb_bus.ack.eq(1)
110-
with m.Else():
111-
m.d.sync += self.wb_bus.ack.eq(0)
112110

113111
return m

tests/test_wishbone_sram.py

Lines changed: 33 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ def test_init(self):
1818
self.assertEqual(dut_1.wb_bus.addr_width, 10)
1919
self.assertEqual(dut_1.wb_bus.data_width, 32)
2020
self.assertEqual(dut_1.wb_bus.granularity, 32)
21-
self.assertEqual(dut_1.wb_bus.features,
22-
{wishbone.Feature.CTI, wishbone.Feature.BTE})
21+
self.assertEqual(dut_1.wb_bus.features, frozenset())
2322
self.assertEqual(dut_1.wb_bus.memory_map.addr_width, 10)
2423
self.assertEqual(dut_1.wb_bus.memory_map.data_width, 32)
2524
self.assertEqual(dut_1.wb_bus.memory_map.alignment, 0)
@@ -34,8 +33,7 @@ def test_init(self):
3433
self.assertEqual(dut_2.wb_bus.addr_width, 1)
3534
self.assertEqual(dut_2.wb_bus.data_width, 16)
3635
self.assertEqual(dut_2.wb_bus.granularity, 8)
37-
self.assertEqual(dut_2.wb_bus.features,
38-
{wishbone.Feature.CTI, wishbone.Feature.BTE})
36+
self.assertEqual(dut_2.wb_bus.features, frozenset())
3937
self.assertEqual(dut_2.wb_bus.memory_map.addr_width, 2)
4038
self.assertEqual(dut_2.wb_bus.memory_map.data_width, 8)
4139
self.assertEqual(dut_2.wb_bus.memory_map.alignment, 0)
@@ -75,109 +73,57 @@ def test_init_size_smaller_than_data_width(self):
7573
def test_sim_writable(self):
7674
dut = WishboneSRAM(size=128, data_width=32, granularity=8, writable=True, init=range(32))
7775

78-
async def wb_cycle(ctx, *, adr, sel, we, dat_w, cti, bte=0, assert_dat_r=None):
79-
ctx.set(dut.wb_bus.cyc, 1)
80-
ctx.set(dut.wb_bus.stb, 1)
81-
ctx.set(dut.wb_bus.adr, adr)
82-
ctx.set(dut.wb_bus.sel, sel)
83-
ctx.set(dut.wb_bus.we, we)
84-
ctx.set(dut.wb_bus.dat_w, dat_w)
85-
ctx.set(dut.wb_bus.cti, cti)
86-
ctx.set(dut.wb_bus.bte, bte)
87-
88-
await ctx.tick()
89-
self.assertEqual(ctx.get(dut.wb_bus.ack), 1)
90-
if assert_dat_r is not None:
91-
self.assertEqual(ctx.get(dut.wb_bus.dat_r), assert_dat_r)
92-
93-
ctx.set(dut.wb_bus.cyc, 0)
94-
ctx.set(dut.wb_bus.stb, 0)
95-
9676
async def testbench(ctx):
9777
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
9878
for i in range(32):
9979
self.assertEqual(ctx.get(dut._mem_data[i]), i)
10080

101-
# cti = CLASSIC =======================================================================
81+
await ctx.tick()
10282

10383
# - left shift all values by 24 bits:
84+
10485
for i in range(32):
105-
await wb_cycle(ctx, cti=wishbone.CycleType.CLASSIC,
106-
adr=i, sel=0b1001, we=1, dat_w=(i << 24) | 0x00ffff00,
107-
assert_dat_r=i)
86+
ctx.set(dut.wb_bus.cyc, 1)
87+
ctx.set(dut.wb_bus.stb, 1)
88+
ctx.set(dut.wb_bus.adr, i)
89+
ctx.set(dut.wb_bus.sel, 0b1001)
90+
ctx.set(dut.wb_bus.we, 1)
91+
ctx.set(dut.wb_bus.dat_w, (i << 24) | 0x00ffff00)
92+
await ctx.tick()
93+
self.assertEqual(ctx.get(dut.wb_bus.ack), 1)
94+
self.assertEqual(ctx.get(dut.wb_bus.dat_r), i)
10895
await ctx.tick()
10996
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
97+
ctx.set(dut.wb_bus.cyc, 0)
98+
ctx.set(dut.wb_bus.stb, 0)
99+
await ctx.tick()
110100

111101
for i in range(32):
112102
self.assertEqual(ctx.get(dut._mem_data[i]), i << 24)
113103

114-
# cti = INCR_BURST, bte = LINEAR ======================================================
115-
116-
# - right shift all values by 24 bits:
117-
for i in range(32):
118-
cti = wishbone.CycleType.END_OF_BURST if i == 31 else wishbone.CycleType.INCR_BURST
119-
await wb_cycle(ctx, cti=cti, bte=wishbone.BurstTypeExt.LINEAR,
120-
adr=i, sel=0b1001, we=1, dat_w=i | 0x00ffff00,
121-
assert_dat_r=i << 24)
122-
123104
await ctx.tick()
124-
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
125-
for i in range(32):
126-
self.assertEqual(ctx.get(dut._mem_data[i]), i)
127-
128-
# cti = INCR_BURST, bte = WRAP_4 ======================================================
129-
130-
# - increment values at addresses 0..15:
131-
for i in (1,2,3,0, 5,6,7,4, 9,10,11,8, 13,14,15,12):
132-
cti = wishbone.CycleType.END_OF_BURST if i == 12 else wishbone.CycleType.INCR_BURST
133-
await wb_cycle(ctx, cti=cti, bte=wishbone.BurstTypeExt.WRAP_4,
134-
adr=i, sel=0b0001, we=1, dat_w=i + 1,
135-
assert_dat_r=i)
136105

137-
await ctx.tick()
138-
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
139-
for i in range(16):
140-
self.assertEqual(ctx.get(dut._mem_data[i]), i + 1)
141-
142-
# cti = INCR_BURST, bte = WRAP_8 ======================================================
143-
144-
# - increment values at addresses 0..15:
145-
for i in (1,2,3,4,5,6,7,0, 9,10,11,12,13,14,15,8):
146-
cti = wishbone.CycleType.END_OF_BURST if i == 8 else wishbone.CycleType.INCR_BURST
147-
await wb_cycle(ctx, cti=cti, bte=wishbone.BurstTypeExt.WRAP_8,
148-
adr=i, sel=0b0001, we=1, dat_w=i + 2,
149-
assert_dat_r=i + 1)
150-
151-
await ctx.tick()
152-
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
153-
for i in range(16):
154-
self.assertEqual(ctx.get(dut._mem_data[i]), i + 2)
155-
156-
# cti = INCR_BURST, bte = WRAP_16 =====================================================
157-
158-
# - increment values at addresses 0..15:
159-
for i in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0):
160-
cti = wishbone.CycleType.END_OF_BURST if i == 0 else wishbone.CycleType.INCR_BURST
161-
await wb_cycle(ctx, cti=cti, bte=wishbone.BurstTypeExt.WRAP_16,
162-
adr=i, sel=0b0001, we=1, dat_w=i + 3,
163-
assert_dat_r=i + 2)
106+
# - right shift all values by 24 bits:
164107

165-
await ctx.tick()
166-
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
167-
for i in range(16):
168-
self.assertEqual(ctx.get(dut._mem_data[i]), i + 3)
108+
ctx.set(dut.wb_bus.cyc, 1)
109+
ctx.set(dut.wb_bus.stb, 1)
169110

170-
# cti = CONST_BURST ===================================================================
111+
for i in range(32):
112+
ctx.set(dut.wb_bus.adr, i)
113+
ctx.set(dut.wb_bus.sel, 0b1001)
114+
ctx.set(dut.wb_bus.we, 1)
115+
ctx.set(dut.wb_bus.dat_w, i | 0x00ffff00)
116+
await ctx.tick()
117+
self.assertEqual(ctx.get(dut.wb_bus.ack), 1)
118+
self.assertEqual(ctx.get(dut.wb_bus.dat_r), i << 24)
119+
await ctx.tick()
120+
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
171121

172-
# - increment value at address 31, 16 times in a row:
173-
for i in range(16):
174-
cti = wishbone.CycleType.END_OF_BURST if i == 15 else wishbone.CycleType.CONST_BURST
175-
await wb_cycle(ctx, cti=cti, adr=31, sel=0b0001, we=1, dat_w=31 + i + 1,
176-
assert_dat_r=31 + i)
122+
ctx.set(dut.wb_bus.cyc, 0)
123+
ctx.set(dut.wb_bus.stb, 0)
177124

178-
await ctx.tick()
179-
self.assertEqual(ctx.get(dut.wb_bus.ack), 0)
180-
self.assertEqual(ctx.get(dut._mem_data[31]), 31 + 16)
125+
for i in range(32):
126+
self.assertEqual(ctx.get(dut._mem_data[i]), i)
181127

182128
sim = Simulator(dut)
183129
sim.add_clock(1e-6)

0 commit comments

Comments
 (0)