Skip to content

Commit

Permalink
Use Simulation.add_testbench for i2c tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedcharles committed Jan 19, 2025
1 parent 5e719a4 commit df76ff5
Showing 1 changed file with 62 additions and 57 deletions.
119 changes: 62 additions & 57 deletions software/tests/gateware/test_i2c.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest
from amaranth import *
from amaranth import Elaboratable, Module, Signal
from amaranth.lib import io
from amaranth.sim import Tick

from glasgow.gateware import simulation_test
from glasgow.gateware.i2c import I2CInitiator, I2CTarget
Expand Down Expand Up @@ -35,11 +36,11 @@ def dut_state(self):

def half_period(self):
for _ in range(self.period_cyc // 2):
yield
yield Tick()

def wait_for(self, fn):
for _ in range(self.wait_cyc):
yield
yield Tick()
if (yield from fn()):
return True
return False
Expand All @@ -62,9 +63,9 @@ def __init__(self):

def strobe(self, signal):
yield signal.eq(1)
yield
yield Tick()
yield signal.eq(0)
yield
yield Tick()

def start(self):
yield from self.strobe(self.dut.start)
Expand Down Expand Up @@ -95,8 +96,8 @@ def test_start(self, tb):
@simulation_test
def test_repeated_start(self, tb):
yield tb.dut.bus.sda_o.eq(0)
yield
yield
yield Tick()
yield Tick()
yield from tb.start()
yield from self.assertState(tb, "START-SCL-L")
yield from self.assertCondition(tb, lambda: (yield tb.dut.bus.start))
Expand All @@ -109,8 +110,8 @@ def start(self, tb):
@simulation_test
def test_stop(self, tb):
yield tb.dut.bus.sda_o.eq(0)
yield
yield
yield Tick()
yield Tick()
yield from tb.stop()
yield from self.assertState(tb, "STOP-SDA-H")
yield from self.assertCondition(tb, lambda: (yield tb.dut.bus.stop))
Expand All @@ -123,44 +124,45 @@ def stop(self, tb):
def write(self, tb, data, bits, ack):
yield from tb.write(data)
for n, bit in enumerate(bits):
yield
yield
yield Tick()
yield Tick()
yield from self.assertState(tb, "WRITE-DATA-SCL-L" if n == 0 else "WRITE-DATA-SDA-N")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 0)
yield from self.assertState(tb, "WRITE-DATA-SDA-X")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 1)
self.assertEqual((yield tb.sda_i), bit)
yield
yield Tick()
yield from self.tb.half_period()
yield
yield
yield Tick()
yield Tick()
yield from self.assertState(tb, "WRITE-ACK-SCL-L")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 0)
yield tb.sda_o.eq(not ack)
yield from self.assertState(tb, "WRITE-ACK-SDA-H")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 1)
yield Tick()
yield tb.sda_o.eq(1)
self.assertEqual((yield tb.dut.busy), 1)
yield from self.tb.half_period()
yield
yield
yield
yield
yield Tick()
yield Tick()
yield Tick()
yield Tick()
self.assertEqual((yield tb.dut.busy), 0)
self.assertEqual((yield tb.dut.ack_o), ack)

@simulation_test
def test_write_ack(self, tb):
yield tb.dut.bus.sda_o.eq(0)
yield
yield
yield Tick()
yield Tick()
yield from self.write(tb, 0xA5, [1, 0, 1, 0, 0, 1, 0, 1], 1)

@simulation_test
def test_write_nak(self, tb):
yield tb.dut.bus.sda_o.eq(0)
yield
yield
yield Tick()
yield Tick()
yield from self.write(tb, 0x5A, [0, 1, 0, 1, 1, 0, 1, 0], 0)

@simulation_test
Expand All @@ -169,52 +171,52 @@ def test_write_tx(self, tb):
yield from self.write(tb, 0x55, [0, 1, 0, 1, 0, 1, 0, 1], 1)
yield from self.write(tb, 0x33, [0, 0, 1, 1, 0, 0, 1, 1], 0)
yield from self.stop(tb)
yield
yield
yield Tick()
yield Tick()
self.assertEqual((yield tb.sda_i), 1)
self.assertEqual((yield tb.scl_i), 1)

def read(self, tb, data, bits, ack):
yield from tb.read(ack)
for n, bit in enumerate(bits):
yield
yield
yield Tick()
yield Tick()
yield from self.assertState(tb, "READ-DATA-SCL-L" if n == 0 else "READ-DATA-SDA-N")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 0)
yield tb.sda_o.eq(bit)
yield from self.assertState(tb, "READ-DATA-SDA-H")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 1)
yield
yield Tick()
yield tb.sda_o.eq(1)
yield from tb.half_period()
yield
yield
yield Tick()
yield Tick()
yield from self.assertState(tb, "READ-ACK-SCL-L")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 0)
yield from self.assertState(tb, "READ-ACK-SDA-X")
yield from self.assertCondition(tb, lambda: (yield tb.scl_i) == 1)
self.assertEqual((yield tb.sda_i), not ack)
self.assertEqual((yield tb.dut.busy), 1)
yield from self.tb.half_period()
yield
yield
yield
yield
yield Tick()
yield Tick()
yield Tick()
yield Tick()
self.assertEqual((yield tb.dut.busy), 0)
self.assertEqual((yield tb.dut.data_o), data)

@simulation_test
def test_read_ack(self, tb):
yield tb.dut.bus.sda_o.eq(0)
yield
yield
yield Tick()
yield Tick()
yield from self.read(tb, 0xA5, [1, 0, 1, 0, 0, 1, 0, 1], 1)

@simulation_test
def test_read_nak(self, tb):
yield tb.dut.bus.sda_o.eq(0)
yield
yield
yield Tick()
yield Tick()
yield from self.read(tb, 0x5A, [0, 1, 0, 1, 1, 0, 1, 0], 0)

@simulation_test
Expand All @@ -223,8 +225,8 @@ def test_read_tx(self, tb):
yield from self.read(tb, 0x55, [0, 1, 0, 1, 0, 1, 0, 1], 1)
yield from self.read(tb, 0x33, [0, 0, 1, 1, 0, 0, 1, 1], 0)
yield from self.stop(tb)
yield
yield
yield Tick()
yield Tick()
self.assertEqual((yield tb.sda_i), 1)
self.assertEqual((yield tb.scl_i), 1)

Expand All @@ -246,7 +248,7 @@ def rep_start(self):
assert (yield self.scl_i) == 1
assert (yield self.sda_i) == 0
yield self.scl_o.eq(0)
yield # tHD;DAT
yield Tick() # tHD;DAT
yield self.sda_o.eq(1)
yield from self.half_period()
yield self.scl_o.eq(1)
Expand All @@ -255,7 +257,7 @@ def rep_start(self):

def stop(self):
yield self.scl_o.eq(0)
yield # tHD;DAT
yield Tick() # tHD;DAT
yield self.sda_o.eq(0)
yield from self.half_period()
yield self.scl_o.eq(1)
Expand All @@ -266,7 +268,7 @@ def stop(self):
def write_bit(self, bit):
assert (yield self.scl_i) == 1
yield self.scl_o.eq(0)
yield # tHD;DAT
yield Tick() # tHD;DAT
yield self.sda_o.eq(bit)
yield from self.half_period()
yield self.scl_o.eq(1)
Expand Down Expand Up @@ -330,9 +332,10 @@ def test_addr_r_ack(self, tb):
yield from tb.write_octet(0b01010001)
yield tb.scl_o.eq(0)
yield from self.assertCondition(tb, lambda: (yield tb.dut.start))
yield
yield Tick()
yield from self.assertState(tb, "ADDR-ACK")
self.assertEqual((yield tb.sda_i), 0)
yield Tick()
yield tb.scl_o.eq(1)
yield from tb.half_period()
yield from self.assertState(tb, "READ-SHIFT")
Expand All @@ -343,9 +346,10 @@ def test_addr_w_ack(self, tb):
yield from tb.write_octet(0b01010000)
yield tb.scl_o.eq(0)
yield from self.assertCondition(tb, lambda: (yield tb.dut.start))
yield
yield Tick()
yield from self.assertState(tb, "ADDR-ACK")
self.assertEqual((yield tb.sda_i), 0)
yield Tick()
yield tb.scl_o.eq(1)
yield from tb.half_period()
yield tb.scl_o.eq(0)
Expand All @@ -364,7 +368,7 @@ def test_write_shift(self, tb):
yield tb.scl_o.eq(0)
yield from self.assertCondition(tb, lambda: (yield tb.dut.write))
self.assertEqual((yield tb.dut.data_i), 0b10100101)
yield
yield Tick()
yield from self.assertState(tb, "WRITE-ACK")

@simulation_test
Expand All @@ -375,19 +379,20 @@ def test_read_shift(self, tb):
yield from tb.half_period()
self.assertEqual((yield tb.sda_i), 0)
# this sequence ensures combinatorial feedback works
yield Tick()
yield tb.scl_o.eq(1)
yield
yield
yield Tick()
yield tb.dut.data_o.eq(0b10100101)
yield
yield Tick()
self.assertEqual((yield tb.dut.read), 1)
yield Tick()
yield tb.dut.data_o.eq(0)
yield
yield Tick()
self.assertEqual((yield tb.dut.read), 0)
yield from tb.half_period()
yield tb.scl_o.eq(1)
self.assertEqual((yield from tb.read_octet()), 0b10100101)
yield
yield Tick()
yield from self.assertState(tb, "READ-ACK")

@simulation_test
Expand All @@ -413,14 +418,14 @@ def test_write_ack(self, tb):
yield from tb.write_octet(0b10100101)
# this sequence ensures combinatorial feedback works
yield tb.scl_o.eq(0)
yield
yield
yield
yield Tick()
yield Tick()
yield Tick()
yield tb.dut.ack_o.eq(1)
yield
self.assertEqual((yield tb.dut.write), 1)
yield Tick()
yield tb.dut.ack_o.eq(0)
yield
yield Tick()
self.assertEqual((yield tb.dut.write), 0)
yield from tb.half_period()
yield tb.scl_o.eq(1)
Expand All @@ -444,7 +449,7 @@ def test_write_ack_stop(self, tb):
yield from tb.half_period()
yield tb.sda_o.eq(1)
yield from self.assertCondition(tb, lambda: (yield tb.dut.stop))
yield
yield Tick()
yield from self.assertState(tb, "IDLE")

@simulation_test
Expand Down Expand Up @@ -473,7 +478,7 @@ def test_read_nak_stop(self, tb):
yield from self.assertState(tb, "READ-ACK")
yield tb.scl_o.eq(1)
yield from self.assertCondition(tb, lambda: (yield tb.dut.stop))
yield
yield Tick()
yield from self.assertState(tb, "IDLE")

@simulation_test
Expand Down

0 comments on commit df76ff5

Please sign in to comment.