2021-10-04 06:24:16 +00:00
|
|
|
from enum import Enum
|
|
|
|
from cocotb.clock import Clock
|
2021-10-12 06:49:31 +00:00
|
|
|
from cocotb.triggers import RisingEdge
|
2021-10-04 06:24:16 +00:00
|
|
|
import cocotb
|
|
|
|
import random
|
|
|
|
|
|
|
|
from libs import AMBA3AHBLiteDriver
|
|
|
|
|
|
|
|
@cocotb.test()
|
2021-10-12 06:49:31 +00:00
|
|
|
async def test_ahb_access(dut):
|
2021-10-04 06:24:16 +00:00
|
|
|
"""Test writing via the bus and reading back"""
|
|
|
|
|
|
|
|
clock = Clock(dut.clk, 1, units="ns") # Create a 10us period clock on port clk
|
|
|
|
cocotb.fork(clock.start()) # Start the clock
|
|
|
|
|
|
|
|
bus = AMBA3AHBLiteDriver.AMBA3AHBLiteDriver(dut=dut, nbytes=4)
|
|
|
|
await bus.reset()
|
|
|
|
|
|
|
|
# Write in 1, 2, and 4 byte steps
|
|
|
|
for step_size in (1, 2, 4):
|
|
|
|
dut._log.info(f"Writing in {step_size} steps.")
|
|
|
|
|
|
|
|
write_dict = {}
|
|
|
|
read_dict = {}
|
|
|
|
|
|
|
|
for addr in range(0, 8, step_size):
|
|
|
|
rand_val = random.randint(0, (1 << (step_size * 8))-1)
|
|
|
|
|
|
|
|
dut._log.info(f"Write value {rand_val} to addres {addr}.")
|
|
|
|
|
|
|
|
write_dict.update(
|
|
|
|
await bus.write(
|
|
|
|
address=addr,
|
|
|
|
value=rand_val,
|
|
|
|
nbytes=step_size,
|
|
|
|
step_size=step_size))
|
|
|
|
|
|
|
|
for addr in range(0, 8, step_size):
|
|
|
|
read_dict.update(
|
|
|
|
await bus.read(
|
|
|
|
address=addr,
|
|
|
|
nbytes=step_size,
|
|
|
|
step_size=step_size))
|
|
|
|
|
|
|
|
# Check at end of every step_size
|
|
|
|
dut._log.info(f"Wrote dictionary {write_dict}")
|
|
|
|
dut._log.info(f"Read back dictionary {read_dict}")
|
|
|
|
|
|
|
|
assert write_dict == read_dict, "Read and write values differ!"
|
|
|
|
|
2021-10-12 06:49:31 +00:00
|
|
|
@cocotb.test()
|
|
|
|
async def test_hw_access(dut):
|
|
|
|
"""Test writing via the hardware interface
|
|
|
|
and reading it back.
|
|
|
|
"""
|
|
|
|
|
|
|
|
clock = Clock(dut.clk, 1, units="ns") # Create a 10us period clock on port clk
|
|
|
|
cocotb.fork(clock.start()) # Start the clock
|
|
|
|
|
|
|
|
bus = AMBA3AHBLiteDriver.AMBA3AHBLiteDriver(dut=dut, nbytes=4)
|
|
|
|
|
|
|
|
await bus.reset()
|
|
|
|
|
|
|
|
write_dict = {}
|
|
|
|
read_dict = {}
|
|
|
|
|
|
|
|
# TODO: At this point, CocoTB has issues with single dimension unpacked but
|
|
|
|
# multidimensional packed arrays. Only check first dimension
|
|
|
|
dut.register_0__f1_hw_wr <= 1
|
|
|
|
dut.register_0__f2_hw_wr <= 1
|
|
|
|
|
|
|
|
rand_val = []
|
|
|
|
|
|
|
|
for addr in (0, 2):
|
|
|
|
# Save value that was written in dictionary
|
|
|
|
write_dict[addr] = random.randint(0, (1 << 16)-1)
|
|
|
|
|
|
|
|
dut.register_0__f2_in <= [write_dict[2], 0] #, write_dict[6]]
|
|
|
|
dut.register_0__f1_in <= [write_dict[0], 0] #, write_dict[4]]
|
|
|
|
|
|
|
|
await RisingEdge(dut.clk)
|
|
|
|
|
|
|
|
dut.register_0__f1_hw_wr <= 0
|
|
|
|
dut.register_0__f2_hw_wr <= 0
|
|
|
|
|
|
|
|
for addr in range(0, 4, 2):
|
|
|
|
read_dict.update(
|
|
|
|
await bus.read(
|
|
|
|
address=addr,
|
|
|
|
nbytes=2,
|
|
|
|
step_size=2))
|
|
|
|
|
|
|
|
dut._log.info(f"Wrote dictionary {write_dict}")
|
|
|
|
dut._log.info(f"Read back dictionary {read_dict}")
|
|
|
|
assert write_dict == read_dict, "Read and write values differ!"
|
|
|
|
|
|
|
|
@cocotb.test()
|
|
|
|
async def test_hw_access_hw_wr_inactive(dut):
|
|
|
|
"""Test writing via the hardware interface but
|
|
|
|
keeping the write-enable 0. The value that is
|
|
|
|
read back should *not* be the same as the value
|
|
|
|
that was fed by the testbench.
|
|
|
|
"""
|
|
|
|
|
|
|
|
clock = Clock(dut.clk, 1, units="ns") # Create a 10us period clock on port clk
|
|
|
|
cocotb.fork(clock.start()) # Start the clock
|
|
|
|
|
|
|
|
bus = AMBA3AHBLiteDriver.AMBA3AHBLiteDriver(dut=dut, nbytes=4)
|
|
|
|
|
|
|
|
await bus.reset()
|
|
|
|
|
|
|
|
write_dict = {}
|
|
|
|
read_dict = {}
|
|
|
|
|
|
|
|
# Force initial value
|
|
|
|
dut.register_0__f1_q <= [0, 0]
|
|
|
|
dut.register_0__f2_q <= [0, 0]
|
|
|
|
|
|
|
|
# Disable write
|
|
|
|
dut.register_0__f1_hw_wr <= 0
|
|
|
|
dut.register_0__f2_hw_wr <= 0
|
|
|
|
|
|
|
|
rand_val = []
|
|
|
|
|
|
|
|
for addr in (0, 2, 4, 6):
|
|
|
|
# Save value that was written in dictionary
|
|
|
|
write_dict[addr] = random.randint(0, (1 << 16)-1)
|
|
|
|
|
|
|
|
dut.register_0__f2_in <= [write_dict[2], write_dict[6]]
|
|
|
|
dut.register_0__f1_in <= [write_dict[0], write_dict[4]]
|
|
|
|
|
|
|
|
await RisingEdge(dut.clk)
|
|
|
|
|
|
|
|
dut.register_0__f1_hw_wr <= 0
|
|
|
|
dut.register_0__f2_hw_wr <= 0
|
|
|
|
|
|
|
|
for addr in range(0, 8, 2):
|
|
|
|
read_dict.update(
|
|
|
|
await bus.read(
|
|
|
|
address=addr,
|
|
|
|
nbytes=2,
|
|
|
|
step_size=2))
|
|
|
|
|
|
|
|
dut._log.info(f"Wrote dictionary {write_dict}")
|
|
|
|
dut._log.info(f"Read back dictionary {read_dict}")
|
|
|
|
assert write_dict != read_dict, "Read and write values differ!"
|
|
|
|
|
|
|
|
@cocotb.test()
|
|
|
|
async def test_illegal_address(dut):
|
|
|
|
"""Test reading and writing to an illegal address.
|
|
|
|
The logic should return a correct error sequence.
|
|
|
|
"""
|
|
|
|
|
|
|
|
clock = Clock(dut.clk, 1, units="ns") # Create a 10us period clock on port clk
|
|
|
|
cocotb.fork(clock.start()) # Start the clock
|
|
|
|
|
|
|
|
bus = AMBA3AHBLiteDriver.AMBA3AHBLiteDriver(dut=dut, nbytes=4)
|
|
|
|
await bus.reset()
|
|
|
|
|
|
|
|
rand_addr = random.randint(8, 1337)
|
|
|
|
rand_val = random.randint(0, (1 << 32)-1)
|
|
|
|
|
|
|
|
dut._log.info(f"Write value {rand_val} to illegal addres {rand_addr}.")
|
|
|
|
|
|
|
|
write_error = False
|
|
|
|
|
|
|
|
try:
|
|
|
|
await bus.write(
|
|
|
|
address=rand_addr,
|
|
|
|
value=rand_val,
|
|
|
|
nbytes=4,
|
|
|
|
step_size=4)
|
|
|
|
except AMBA3AHBLiteDriver.BusErrorResponse:
|
|
|
|
write_error = True
|
|
|
|
|
|
|
|
assert write_error == True, "Write to illegal address did not return an error!"
|
|
|
|
|
|
|
|
read_error = False
|
2021-10-04 06:24:16 +00:00
|
|
|
|
2021-10-12 06:49:31 +00:00
|
|
|
try:
|
|
|
|
await bus.read(
|
|
|
|
address=rand_addr,
|
|
|
|
nbytes=4,
|
|
|
|
step_size=4)
|
|
|
|
except AMBA3AHBLiteDriver.BusErrorResponse:
|
|
|
|
read_error = True
|
2021-10-04 06:24:16 +00:00
|
|
|
|
2021-10-12 06:49:31 +00:00
|
|
|
assert read_error == True, "Read from illegal address did not return an error!"
|