blob: 4e3d70c351b62d6ec3e1cf1b2c8f122ff0432564 [file] [log] [blame]
import cocotb
import numpy as np
from kelvin_test_utils.core_mini_axi_interface import CoreMiniAxiInterface
from bazel_tools.tools.python.runfiles import runfiles
@cocotb.test()
async def core_mini_rvv_load(dut):
"""Testbench to test RVV load intrinsics.
This test loads 16 bytes of data and read back from the input address.
Todo: update the test with store unit.
"""
# Test bench setup
core_mini_axi = CoreMiniAxiInterface(dut)
await core_mini_axi.init()
await core_mini_axi.reset()
cocotb.start_soon(core_mini_axi.clock.start())
r = runfiles.Create()
elf_path = r.Rlocation("kelvin_hw/tests/cocotb/rvv/rvv_load.elf")
num_test_bytes = 16
intial_pass = True
if not elf_path:
raise ValueError("elf_path must consist a valid path")
with open(elf_path, "rb") as f:
entry_point = await core_mini_axi.load_elf(f)
#Write your program inputs
with open(elf_path, "rb") as f:
input_1_addr = core_mini_axi.lookup_symbol(f, "input_1")
output_1_addr = core_mini_axi.lookup_symbol(f, "output_1")
for data_type in [np.int8, np.int16, np.int32]:
num_bytes = np.dtype(data_type).itemsize
min_value = np.iinfo(data_type).min
max_value = np.iinfo(data_type).max
num_values = int(num_test_bytes / num_bytes)
input_1_data = np.random.randint(min_value, max_value, num_values, dtype=data_type)
await core_mini_axi.write(input_1_addr, input_1_data)
if intial_pass:
intial_pass = False
await core_mini_axi.execute_from(entry_point)
await core_mini_axi.wait_for_wfi()
routputs = (await core_mini_axi.read(input_1_addr, num_test_bytes)).view(data_type)
print(f"loaded inputs are {routputs}", flush=True)
print(f" number of values supposed to be printed {num_values}", flush=True)
await core_mini_axi.raise_irq()
await core_mini_axi.wait_for_halted()
@cocotb.test()
async def core_mini_rvv_add(dut):
"""Testbench to test RVV add intrinsics.
This test loads 16 bytes of data from each input buffer and saved result into a register.
Todo: update the test with store unit.
"""
# Test bench setup
core_mini_axi = CoreMiniAxiInterface(dut)
await core_mini_axi.init()
await core_mini_axi.reset()
cocotb.start_soon(core_mini_axi.clock.start())
r = runfiles.Create()
elf_path = r.Rlocation("kelvin_hw/tests/cocotb/rvv/rvv_add.elf")
num_test_bytes = 16
intial_pass = True
if not elf_path:
raise ValueError("elf_path must consist a valid path ")
with open(elf_path, "rb") as f:
entry_point = await core_mini_axi.load_elf(f)
#Write your program inputs
with open(elf_path, "rb") as f:
input_1_addr = core_mini_axi.lookup_symbol(f, "input_1")
input_2_addr = core_mini_axi.lookup_symbol(f, "input_2")
output_1_addr = core_mini_axi.lookup_symbol(f, "output_1")
# todo ,np.uint8, np.uint16, np.uint32
for data_type in [np.int8, np.int16, np.int32]:
num_bytes = np.dtype(data_type).itemsize
min_value = np.iinfo(data_type).min
max_value = np.iinfo(data_type).max
num_values = int(num_test_bytes / num_bytes)
input_1_data = np.random.randint(min_value, max_value, num_values, dtype=data_type)
input_2_data = np.random.randint(min_value, max_value, num_values, dtype=data_type)
await core_mini_axi.write(input_1_addr, input_1_data)
if intial_pass:
intial_pass = False
await core_mini_axi.execute_from(entry_point)
await core_mini_axi.wait_for_wfi()
routputs = (await core_mini_axi.read(input_1_addr, num_test_bytes)).view(data_type)
print(f"loaded inputs are {routputs}", flush=True)
routputs2 = (await core_mini_axi.read(input_1_addr, num_test_bytes)).view(data_type)
print(f"loaded inputs are {routputs2}", flush=True)
print(f" number of values supposed to be printed {num_values}", flush=True)
await core_mini_axi.raise_irq()
await core_mini_axi.wait_for_halted()
@cocotb.test()
async def core_mini_vstart_store(dut):
"""Testbench to test vstart store.
"""
# Test bench setup
core_mini_axi = CoreMiniAxiInterface(dut)
await core_mini_axi.init()
await core_mini_axi.reset()
cocotb.start_soon(core_mini_axi.clock.start())
r = runfiles.Create()
elf_path = r.Rlocation("kelvin_hw/tests/cocotb/rvv/vstart_store.elf")
if not elf_path:
raise ValueError("elf_path must consist a valid path")
with open(elf_path, "rb") as f:
entry_point = await core_mini_axi.load_elf(f)
#Write your program inputs
with open(elf_path, "rb") as f:
input_addr = core_mini_axi.lookup_symbol(f, "input_data")
output_addr = core_mini_axi.lookup_symbol(f, "output_data")
input_data = np.random.randint(
np.iinfo(np.uint8).min, np.iinfo(np.uint8).max, 16, dtype=np.uint8)
await core_mini_axi.write(input_addr, input_data)
await core_mini_axi.write(output_addr, np.zeros(16, dtype=np.uint8))
await core_mini_axi.execute_from(entry_point)
await core_mini_axi.wait_for_wfi()
output_data = (await core_mini_axi.read(output_addr, 16)).view(np.uint8)
# vstart is 4, so first 4 elements are skipped.
# 12 elements are stored.
assert np.array_equal(output_data[0:4], np.zeros(4, dtype=np.uint8))
assert np.array_equal(output_data[4:], input_data[4:])
await core_mini_axi.raise_irq()
await core_mini_axi.wait_for_halted()
@cocotb.test()
async def core_mini_vcsr_test(dut):
"""Testbench to test vstart store.
"""
# Test bench setup
core_mini_axi = CoreMiniAxiInterface(dut)
await core_mini_axi.init()
await core_mini_axi.reset()
cocotb.start_soon(core_mini_axi.clock.start())
r = runfiles.Create()
elf_path = r.Rlocation("kelvin_hw/tests/cocotb/rvv/vcsr_test.elf")
if not elf_path:
raise ValueError("elf_path must consist a valid path")
with open(elf_path, "rb") as f:
entry_point = await core_mini_axi.load_elf(f)
vma_addr = core_mini_axi.lookup_symbol(f, "vma")
vta_addr = core_mini_axi.lookup_symbol(f, "vta")
sew_addr = core_mini_axi.lookup_symbol(f, "sew")
lmul_addr = core_mini_axi.lookup_symbol(f, "lmul")
vl_addr = core_mini_axi.lookup_symbol(f, "vl")
vtype_addr = core_mini_axi.lookup_symbol(f, "vtype")
SEWS = [
0b000, # SEW8
0b001, # SEW16
0b010, # SEW32
]
LMULS = [
0b101, # LMUL1/8
0b110, # LMUL1/4
0b111, # LMUL1/2
0b000, # LMUL1
0b001, # LMUL2
0b010, # LMUL4
0b011, # LMUL8
]
for ma in range(2):
for ta in range(2):
for sew in SEWS:
for lmul in LMULS:
await core_mini_axi.write_word(vma_addr, ma)
await core_mini_axi.write_word(vta_addr, ta)
await core_mini_axi.write_word(sew_addr, sew)
await core_mini_axi.write_word(lmul_addr, lmul)
# TODO(derekjchow): Pick random VL
await core_mini_axi.write_word(vl_addr, 1)
await core_mini_axi.execute_from(entry_point)
await core_mini_axi.wait_for_halted()
vtype_result = (
await core_mini_axi.read_word(vtype_addr)).view(np.uint32)[0]
ma_result = (vtype_result & (1 << 7)) >> 7
ta_result = (vtype_result & (1 << 6)) >> 6
sew_result = (vtype_result & (0b111 << 3)) >> 3
lmul_result = (vtype_result & 0b111)
assert (ma == ma_result)
assert (ta == ta_result)
assert (sew == sew_result)
assert (lmul == lmul_result)