86 lines
2.3 KiB
Python
86 lines
2.3 KiB
Python
|
# SPDX-License-Identifier: AGPL-3.0-Only
|
||
|
# Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
|
||
|
|
||
|
import cocotb
|
||
|
from cocotb.clock import Clock
|
||
|
from cocotb.triggers import FallingEdge, Timer
|
||
|
from cocotb.types import LogicArray
|
||
|
|
||
|
from .util import BIT, GENMASK
|
||
|
|
||
|
ADDR_WIDTH = 5
|
||
|
DATA_WIDTH = 16
|
||
|
SLAVES = 4
|
||
|
|
||
|
def get(signal, slave, width):
|
||
|
return (signal.value >> (slave * width)) & GENMASK(width - 1, 0)
|
||
|
|
||
|
def check(mux):
|
||
|
selected = False
|
||
|
for i in range(SLAVES):
|
||
|
cyc = get(mux.s_cyc, i, 1)
|
||
|
assert cyc == mux.m_cyc.value
|
||
|
if mux.m_addr.value & BIT(i + ADDR_WIDTH) and not selected:
|
||
|
selected = True
|
||
|
stb = bool(mux.s_stb.value & BIT(i))
|
||
|
assert stb == mux.m_stb.value
|
||
|
if not cyc and stb:
|
||
|
continue
|
||
|
|
||
|
assert get(mux.s_addr, i, ADDR_WIDTH) == mux.m_addr.value & GENMASK(ADDR_WIDTH - 1, 0)
|
||
|
we = get(mux.s_we, i, 1)
|
||
|
assert we == mux.m_we.value
|
||
|
if we:
|
||
|
assert get(mux.s_data_write, i, DATA_WIDTH) == mux.m_data_write.value
|
||
|
|
||
|
assert mux.m_ack.value == get(mux.s_ack, i, 1)
|
||
|
assert mux.m_err.value == get(mux.s_err, i, 1)
|
||
|
assert mux.m_data_read.value == get(mux.s_data_read, i, DATA_WIDTH)
|
||
|
else:
|
||
|
assert not get(mux.s_stb, i, 1)
|
||
|
|
||
|
if not selected and mux.m_cyc.value and mux.m_stb.value:
|
||
|
assert not mux.m_ack.value
|
||
|
assert mux.m_err.value
|
||
|
|
||
|
@cocotb.test(timeout_time=1, timeout_unit='us')
|
||
|
async def test_mdio(mux):
|
||
|
mux.m_cyc.value = 1
|
||
|
mux.m_stb.value = 1
|
||
|
mux.m_we.value = 1
|
||
|
mux.m_data_write.value = 0x1364
|
||
|
mux.s_ack.value = 0
|
||
|
mux.s_err.value = 0
|
||
|
mux.s_data_read.value = 0x0123456789abcdef
|
||
|
|
||
|
for i in range(4):
|
||
|
mux.m_addr.value = BIT(i + 5) | 0x15
|
||
|
mux.s_ack.value = BIT(i)
|
||
|
mux.s_err.value = GENMASK(SLAVES - 1, 0) ^ BIT(i)
|
||
|
await Timer(1)
|
||
|
check(mux)
|
||
|
|
||
|
mux.s_ack.value = GENMASK(SLAVES - 1, 0) ^ BIT(i)
|
||
|
mux.s_err.value = BIT(i)
|
||
|
await Timer(1)
|
||
|
check(mux)
|
||
|
|
||
|
mux.m_addr.value = 0
|
||
|
await Timer(1)
|
||
|
check(mux)
|
||
|
|
||
|
mux.m_stb.value = 0
|
||
|
await Timer(1)
|
||
|
check(mux)
|
||
|
|
||
|
mux.m_cyc.value = 0
|
||
|
mux.m_stb.value = 1
|
||
|
await Timer(1)
|
||
|
check(mux)
|
||
|
|
||
|
mux.m_cyc.value = 1
|
||
|
mux.m_addr.value = 0x1ff
|
||
|
mux.m_we.value = 0
|
||
|
await Timer(1)
|
||
|
check(mux)
|