mirror of
https://github.com/Silicon1602/srdl2sv.git
synced 2024-12-22 15:08:39 +00:00
Add first simple test with a simple 2-dimensional array
This commit is contained in:
parent
c4dca87ab5
commit
7d5ddaf47c
@ -1,5 +1,8 @@
|
|||||||
ALL_COCOTB_TESTS = $(shell ls cocotb_tests/test_*.py | sed -E 's|.*?/test_(.*?).py|\1|g')
|
ALL_COCOTB_TESTS = $(shell ls cocotb_tests/test_*.py | sed -E 's|.*?/test_(.*?).py|\1|g')
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
.PRECIOUS: build_dirs/%/compile.f
|
||||||
|
|
||||||
default: $(ALL_COCOTB_TESTS)
|
default: $(ALL_COCOTB_TESTS)
|
||||||
|
|
||||||
# This target will always rebuild, which is fine since we want to be sure to execute any
|
# This target will always rebuild, which is fine since we want to be sure to execute any
|
||||||
@ -31,15 +34,13 @@ default: $(ALL_COCOTB_TESTS)
|
|||||||
@echo "##############################################################################"
|
@echo "##############################################################################"
|
||||||
@echo "##############################################################################"
|
@echo "##############################################################################"
|
||||||
|
|
||||||
build_dirs/%/*.sv: systemrdl/%.rdl
|
build_dirs/%/compile.f: systemrdl/%.rdl
|
||||||
../srdl2sv/main.py $? --out_dir $(shell dirname $@) --file_log_level DEBUG --stream_log_level DEBUG
|
../srdl2sv/main.py $? --out_dir $(shell dirname $@) --file_log_level DEBUG --stream_log_level DEBUG
|
||||||
|
|
||||||
build_dirs/%/compile.f: build_dirs/%/*.sv
|
|
||||||
ls $(PWD)/$(@D)/*_pkg.sv > $@
|
ls $(PWD)/$(@D)/*_pkg.sv > $@
|
||||||
ls $(PWD)/$(@D)/*amba*.sv >> $@
|
ls $(PWD)/$(@D)/*amba*.sv >> $@
|
||||||
ls $(PWD)/$(@D)/*.sv | grep -v '.*_pkg.sv$$' | grep -v '.*amba.*' >> $@
|
ls $(PWD)/$(@D)/*.sv | grep -v '.*_pkg.sv$$' | grep -v '.*amba.*' >> $@
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build_dirs
|
rm -rf build_dirs
|
||||||
|
140
tests/cocotb_tests/libs/AMBA3AHBLiteDriver.py
Normal file
140
tests/cocotb_tests/libs/AMBA3AHBLiteDriver.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
from enum import Enum
|
||||||
|
import math
|
||||||
|
import cocotb
|
||||||
|
from cocotb.triggers import Timer, RisingEdge
|
||||||
|
|
||||||
|
# TODO: Does not yet implement HREADY_OUT == 0
|
||||||
|
# TODO: Add support for HRESP (and throw error if HRESP occurs)
|
||||||
|
|
||||||
|
class HTRANS(Enum):
|
||||||
|
IDLE = 0
|
||||||
|
BUSY = 1
|
||||||
|
NONSEQ = 2
|
||||||
|
SEQ = 3
|
||||||
|
|
||||||
|
class AMBA3AHBLiteDriver:
|
||||||
|
"""Wraps up a collection of functions to drive an AMBA3AHBLite Bus.
|
||||||
|
|
||||||
|
This is not an extensive set of features and merely enough to test
|
||||||
|
out SRDL2SV registers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, dut, nbytes: int):
|
||||||
|
self._nbytes = nbytes
|
||||||
|
self._dut = dut
|
||||||
|
|
||||||
|
@cocotb.coroutine
|
||||||
|
async def reset(self, time: int = 10):
|
||||||
|
"""Resets bus for a given amount of time"""
|
||||||
|
|
||||||
|
self._dut.HRESETn <= 0
|
||||||
|
|
||||||
|
await Timer(time, units='ns')
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
self._dut.HRESETn <= 1
|
||||||
|
|
||||||
|
@cocotb.coroutine
|
||||||
|
async def write(self, address: int, value: int, nbytes = None, step_size = None):
|
||||||
|
if not nbytes:
|
||||||
|
nbytes = self._nbytes
|
||||||
|
|
||||||
|
if not step_size:
|
||||||
|
if (step_size := address % self._nbytes) == 0:
|
||||||
|
step_size = self._nbytes
|
||||||
|
|
||||||
|
# Dictionary to return address/value pairs
|
||||||
|
write_dict = {}
|
||||||
|
|
||||||
|
# Start counting bytes
|
||||||
|
nbytes_cnt = 0
|
||||||
|
|
||||||
|
# Initiate write
|
||||||
|
self._dut.HSEL <= 1
|
||||||
|
self._dut.HWRITE <= 1
|
||||||
|
self._dut.HADDR <= address
|
||||||
|
self._dut.HTRANS <= HTRANS.NONSEQ.value
|
||||||
|
self._dut.HSIZE <= int(math.log2(step_size))
|
||||||
|
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Save address from previous phase
|
||||||
|
previous_address = hex(self._dut.HADDR.value)
|
||||||
|
|
||||||
|
# Set data for dataphase
|
||||||
|
self._dut.HWDATA <= (value >> (nbytes_cnt * 8))
|
||||||
|
|
||||||
|
# Check if we are done in next phase
|
||||||
|
if (nbytes_cnt := nbytes_cnt + step_size) >= nbytes:
|
||||||
|
self._dut.HTRANS <= HTRANS.IDLE.value
|
||||||
|
else:
|
||||||
|
# Update address
|
||||||
|
self._dut.HADDR <= self._dut.HADDR.value + step_size
|
||||||
|
|
||||||
|
# Wait for next clock cycle
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
# Save into dictionary
|
||||||
|
write_dict[previous_address] = hex(self._dut.HWDATA.value)
|
||||||
|
|
||||||
|
if nbytes_cnt >= nbytes:
|
||||||
|
break
|
||||||
|
|
||||||
|
self._dut.HWRITE <= 0
|
||||||
|
self._dut.HSEL <= 0
|
||||||
|
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
return write_dict
|
||||||
|
|
||||||
|
@cocotb.coroutine
|
||||||
|
async def read(self, address: int, nbytes = None, step_size = None):
|
||||||
|
if not nbytes:
|
||||||
|
nbytes = self._nbytes
|
||||||
|
|
||||||
|
if not step_size:
|
||||||
|
if (step_size := address % self._nbytes) == 0:
|
||||||
|
step_size = self._nbytes
|
||||||
|
|
||||||
|
# Dictionary to return address/value pairs
|
||||||
|
read_dict = {}
|
||||||
|
|
||||||
|
# Start counting bytes
|
||||||
|
nbytes_cnt = 0
|
||||||
|
|
||||||
|
# Initiate read
|
||||||
|
self._dut.HSEL <= 1
|
||||||
|
self._dut.HWRITE <= 0
|
||||||
|
self._dut.HADDR <= address
|
||||||
|
self._dut.HTRANS <= HTRANS.NONSEQ.value
|
||||||
|
self._dut.HSIZE <= int(math.log2(step_size))
|
||||||
|
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Save address from previous phase
|
||||||
|
previous_address = hex(self._dut.HADDR.value)
|
||||||
|
|
||||||
|
# Check if we are done in next phase
|
||||||
|
if (nbytes_cnt := nbytes_cnt + step_size) >= nbytes:
|
||||||
|
self._dut.HTRANS <= HTRANS.IDLE.value
|
||||||
|
else:
|
||||||
|
# Update address
|
||||||
|
self._dut.HADDR <= self._dut.HADDR.value + step_size
|
||||||
|
|
||||||
|
# Wait for next clock cycle
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
# Save into dictionary
|
||||||
|
read_dict[previous_address] = hex(self._dut.HRDATA.value)
|
||||||
|
|
||||||
|
if nbytes_cnt >= nbytes:
|
||||||
|
break
|
||||||
|
|
||||||
|
self._dut.HTRANS <= HTRANS.IDLE.value
|
||||||
|
self._dut.HSEL <= 0
|
||||||
|
|
||||||
|
await RisingEdge(self._dut.clk)
|
||||||
|
|
||||||
|
return read_dict
|
0
tests/cocotb_tests/libs/__init__.py
Normal file
0
tests/cocotb_tests/libs/__init__.py
Normal file
51
tests/cocotb_tests/test_simple_rw_reg.py
Normal file
51
tests/cocotb_tests/test_simple_rw_reg.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
from enum import Enum
|
||||||
|
from cocotb.clock import Clock
|
||||||
|
import cocotb
|
||||||
|
import random
|
||||||
|
|
||||||
|
from libs import AMBA3AHBLiteDriver
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def test_simple_rw_reg(dut):
|
||||||
|
"""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!"
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user