Skip to content

Commit

Permalink
test_bitbang: Utilize I2CQueueEntry class
Browse files Browse the repository at this point in the history
Internal-tag: [#69926]
Signed-off-by: Wiktoria Kuna <[email protected]>
  • Loading branch information
wkkuna committed Dec 19, 2024
1 parent 1109ede commit 1ecd58d
Showing 1 changed file with 55 additions and 73 deletions.
128 changes: 55 additions & 73 deletions test/test_bitbang.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from litex.gen.sim import passive
from litex.soc.cores.bitbang import I2CMaster, SPIMaster
from litex.soc.cores.i2c_worker import I2CState
from litex.soc.cores.i2c_worker import I2CQueueEntry, I2CState


@passive
Expand Down Expand Up @@ -41,6 +41,11 @@ def i2c_master_output_bitbang(val):
return (scl_o, scl_oe, sda_o, sda_oe)


def generate_i2c_test_data(length, byte_subset=[0x55, 0xAA, 0xFF, 0x00]):
sub_len = len(byte_subset)
return [(byte_subset[i % sub_len], i & 1) for i in range(length)]


class TestBitBangI2C(unittest.TestCase):

def test_i2c_master_syntax(self):
Expand Down Expand Up @@ -230,7 +235,7 @@ def generator(i2c):
self.assertEqual(fifo_depth, 128)
self.assertEqual((yield i2c.i2c_worker._fifo_w.fields.fifo_entries), 0)
for i in range(fifo_depth):
yield from i2c.i2c_worker._fifo.write(0)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry().pack())
yield
self.assertEqual((yield i2c.i2c_worker._fifo_w.fields.fifo_depth), 128)
self.assertEqual((yield i2c.i2c_worker._fifo_w.fields.fifo_entries), i+1)
Expand All @@ -244,7 +249,7 @@ def generator(i2c):
yield from i2c._sel.write(1)
fifo_depth = (yield i2c.i2c_worker._fifo_w.fields.fifo_depth)
for i in range(fifo_depth):
yield from i2c.i2c_worker._fifo.write(0)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry().pack())
while ((yield i2c.i2c_worker._fifo_w.fields.fifo_entries) != 128):
yield
yield i2c.i2c_worker._ctrl.fields.clr_fifos.eq(1)
Expand Down Expand Up @@ -278,7 +283,7 @@ def generator(i2c):
def test_i2c_master_worker_start(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand All @@ -300,7 +305,7 @@ def generator(i2c):
def test_i2c_master_worker_start_stop(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16 | 1 << 18)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1, s_stop=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -330,8 +335,8 @@ def generator(i2c):
def test_i2c_master_worker_start_then_stop(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16)
yield from i2c.i2c_worker._fifo.write(1 << 18)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_stop=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -364,7 +369,7 @@ def generator(i2c):
def test_i2c_master_worker_start_stop_end(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16 | 1 << 18 | 1 << 19)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1, s_stop=1, s_idle=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -394,8 +399,8 @@ def generator(i2c):
def test_i2c_master_worker_start_stop_then_end(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16 | 1 << 18)
yield from i2c.i2c_worker._fifo.write(1 << 19)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1, s_stop=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_idle=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -428,8 +433,8 @@ def generator(i2c):
def test_i2c_master_worker_start_then_stop_end(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16)
yield from i2c.i2c_worker._fifo.write(1 << 18 | 1 << 19)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_stop=1, s_idle=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -462,9 +467,9 @@ def generator(i2c):
def test_i2c_master_worker_start_then_stop_then_end(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 16)
yield from i2c.i2c_worker._fifo.write(1 << 18)
yield from i2c.i2c_worker._fifo.write(1 << 19)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_stop=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_idle=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -501,7 +506,8 @@ def test_i2c_master_worker_send_data(self):
def generator(i2c, _bytes):
yield from i2c._sel.write(1)
for byte in _bytes:
yield from i2c.i2c_worker._fifo.write(byte | 1 << 17)
data, ack = byte
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(data=data, ack=ack, s_data=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand All @@ -520,30 +526,27 @@ def generator(i2c, _bytes):
self.assertEqual((yield i2c.i2c_worker._state.fields.fsm_state), I2CState.DATA)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.DATA):
yield
data = [0x55, 0x55, 0x96, 0x96, 0x42, 0x42, 0xAA, 0xAA, 0xFF, 0xFF, 0x00, 0x00]
expected_output = []
for i in range(len(data)):
expected_output.append((data[i], i & 1))
data[i] |= (i & 1) << 8 # Allow for response
bytes = [0x55, 0x55, 0x96, 0x96, 0x42, 0x42, 0xAA, 0xAA, 0xFF, 0xFF, 0x00, 0x00]
data = generate_i2c_test_data(len(bytes), bytes)

pads = get_i2c_pads()
i2c_master = I2CMaster(pads=pads, sys_freq=100e6, bus_freq=400e3)
run_simulation(
i2c_master,
[generator(i2c_master, data), loopback(pads),
self.check_clk(pads), self.check_data(pads, expected_output)],
self.check_clk(pads), self.check_data(pads, data)],
)

def test_i2c_master_worker_recv_data(self):
def generator(i2c, _bytes):
yield from i2c._sel.write(1)
for _ in range(len(_bytes)):
yield from i2c.i2c_worker._fifo.write(0x1ff | 1 << 17)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(data=0xff, ack=1, s_data=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
yield
for _ in range(len(_bytes)):
for i in range(len(_bytes)):
self.assertEqual((yield i2c.i2c_worker._state.fields.fsm_state), I2CState.RUN_I2C)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.RUN_I2C):
yield
Expand All @@ -561,21 +564,19 @@ def generator(i2c, _bytes):
i = 0
while (yield i2c.i2c_worker._fifo_r.fields.fifo_entries) > 0:
data = yield from i2c.i2c_worker._fifo.read()
self.assertEqual(data, _bytes[i])
byte, ack = _bytes[i]
self.assertEqual(data, I2CQueueEntry(data=byte, ack=ack).pack())
i += 1
yield

data = [0x55, 0x55, 0x96, 0x96, 0x42, 0x42, 0xAA, 0xAA, 0xFF, 0xFF, 0x00, 0x00]
expected_output = []
for i in range(len(data)):
expected_output.append(data[i] | (i & 1) << 8)
data[i] = (data[i], (i & 1))
bytes = [0x55, 0x55, 0x96, 0x96, 0x42, 0x42, 0xAA, 0xAA, 0xFF, 0xFF, 0x00, 0x00]
data = generate_i2c_test_data(len(bytes), bytes)

pads = get_i2c_pads()
i2c_master = I2CMaster(pads=pads, sys_freq=100e6, bus_freq=400e3)
run_simulation(
i2c_master,
[generator(i2c_master, expected_output), self.clk_pullup(pads),
[generator(i2c_master, data), self.clk_pullup(pads),
self.check_clk(pads), self.send_data(pads, data)],
)

Expand All @@ -585,7 +586,8 @@ def generator(i2c, _bytes):
self.assertEqual((yield i2c.i2c_worker._fifo_r.fields.fifo_depth), 128)
self.assertEqual((yield i2c.i2c_worker._fifo_r.fields.fifo_entries), 0)
for byte in _bytes:
yield from i2c.i2c_worker._fifo.write(byte | 1 << 17)
data, ack = byte
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(data=data, ack=ack, s_data=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand All @@ -608,34 +610,28 @@ def generator(i2c, _bytes):
i = 0
while (yield i2c.i2c_worker._fifo_r.fields.fifo_entries) > 0:
data = yield from i2c.i2c_worker._fifo.read()
self.assertEqual(data, _bytes[i])
byte, ack = _bytes[i]
self.assertEqual(data, I2CQueueEntry(data=byte, ack=ack).pack())
i += 1
yield

data = []
for _ in range(32):
for val in [0x55, 0xAA, 0xFF, 0x00]:
data.append(val)
expected_output = []
for i in range(len(data)):
expected_output.append((data[i], i & 1))
data[i] |= (i & 1) << 8 # Allow for response

data = generate_i2c_test_data(128)
pads = get_i2c_pads()
i2c_master = I2CMaster(pads=pads, sys_freq=100e6, bus_freq=400e3)
run_simulation(
i2c_master,
[generator(i2c_master, data), loopback(pads),
self.check_clk(pads), self.check_data(pads, expected_output)],
self.check_clk(pads), self.check_data(pads, data)],
)

def test_i2c_master_worker_read_fifo_over_fill(self):
@passive
def fill(i2c, _bytes):
i = 0
while i < len(_bytes):
data, ack = _bytes[i]
if (yield i2c.i2c_worker._fifo_w.fields.fifo_entries) < 128:
yield from i2c.i2c_worker._fifo.write(_bytes[i] | 1 << 17)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(data=data, ack=ack, s_data=1).pack())
i += 1
yield

Expand All @@ -660,13 +656,7 @@ def generator(i2c):
self.assertEqual((yield i2c.i2c_worker._fifo_r.fields.fifo_entries), 128)
self.assertEqual((yield i2c.i2c_worker._fifo_w.fields.fifo_entries), 4)

data = []
for _ in range(33):
for val in [0x55, 0xAA, 0xFF, 0x00]:
data.append(val)
for i in range(len(data)):
data[i] |= (i & 1) << 8 # Allow for response

data = generate_i2c_test_data(132)
pads = get_i2c_pads()
i2c_master = I2CMaster(pads=pads, sys_freq=100e6, bus_freq=400e3)
run_simulation(
Expand All @@ -677,9 +667,9 @@ def generator(i2c):
def test_i2c_master_worker_read_fifo_clr(self):
@passive
def fill(i2c, _bytes):
for byte in _bytes:
for data, ack in _bytes:
if (yield i2c.i2c_worker._fifo_w.fields.fifo_entries) < 128:
yield from i2c.i2c_worker._fifo.write(byte | 1 << 17)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(data=data, ack=ack, s_data=1).pack())
yield

def generator(i2c):
Expand All @@ -689,7 +679,7 @@ def generator(i2c):
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
yield
for _ in range(128):
for i in range(128):
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.RUN_I2C):
yield
for _ in range(9):
Expand All @@ -715,15 +705,7 @@ def generator(i2c):
yield
self.assertEqual((yield i2c.i2c_worker._fifo_r.fields.fifo_entries), 0)

data = []
for _ in range(32):
for val in [0x55, 0xAA, 0xFF, 0x00]:
data.append(val)
expected_output = []
for i in range(len(data)):
expected_output.append(data[i] << 1 | (i & 1))
data[i] |= (i & 1) << 8 # Allow for response

data = generate_i2c_test_data(128)
pads = get_i2c_pads()
i2c_master = I2CMaster(pads=pads, sys_freq=100e6, bus_freq=400e3)
run_simulation(
Expand All @@ -734,7 +716,7 @@ def generator(i2c):
def test_i2c_master_worker_data_stop(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 17 | 1 << 18)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_data=1, s_stop=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -769,8 +751,8 @@ def generator(i2c):
def test_i2c_master_worker_data_then_stop(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 17)
yield from i2c.i2c_worker._fifo.write(1 << 18)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_data=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_stop=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -808,8 +790,8 @@ def generator(i2c):
def test_i2c_master_worker_data_nack_then_stop(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 8 | 1 << 17)
yield from i2c.i2c_worker._fifo.write(1 << 18)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(ack=1, s_data=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_stop=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -850,8 +832,8 @@ def generator(i2c):
def test_i2c_master_worker_data_then_start(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 17)
yield from i2c.i2c_worker._fifo.write(1 << 16)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_data=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -895,8 +877,8 @@ def generator(i2c):
def test_i2c_master_worker_data_nack_then_start(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 8 | 1 << 17)
yield from i2c.i2c_worker._fifo.write(1 << 16)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(ack=1, s_data=1).pack())
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(s_start=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down Expand Up @@ -937,7 +919,7 @@ def generator(i2c):
def test_i2c_master_worker_data_nack_abort(self):
def generator(i2c):
yield from i2c._sel.write(1)
yield from i2c.i2c_worker._fifo.write(1 << 8 | 1 << 17 | 1 << 20)
yield from i2c.i2c_worker._fifo.write(I2CQueueEntry(ack=1, s_data=1, abort_on_nack=1).pack())
yield
yield from i2c.i2c_worker._start.write(1)
while ((yield i2c.i2c_worker._state.fields.fsm_state) == I2CState.IDLE):
Expand Down

0 comments on commit 1ecd58d

Please sign in to comment.