Skip to content
Snippets Groups Projects
Commit a589cc21 authored by dam1n19's avatar dam1n19
Browse files

Cocotb work continuation

parent 55869a68
No related branches found
No related tags found
No related merge requests found
# Exclude Simulation Files # Exclude Simulation Files
verif/cocotb/modelsim.ini verif/cocotb/*
verif/cocotb/transcript !verif/cocotb/makefile
!verif/cocotb/*.py
# Exclude Compiled Binaries # Exclude Compiled Binaries
/software/*/*.elf /software/*/*.elf
......
...@@ -45,6 +45,9 @@ endif ...@@ -45,6 +45,9 @@ endif
# Cocotb GUI Variable # Cocotb GUI Variable
GUI ?= 0 GUI ?= 0
# Cocotb Test Location
COCOTB_TEST_DIR := $(SOCLABS_NANOSOC_TECH_DIR)/verif/cocotb
# Cocotb Scratch Directory # Cocotb Scratch Directory
COCOTB_DIR := $(SIM_TOP_DIR)/cocotb COCOTB_DIR := $(SIM_TOP_DIR)/cocotb
COCOTB_SCRATCH_DIR := $(COCOTB_DIR)/scratch COCOTB_SCRATCH_DIR := $(COCOTB_DIR)/scratch
......
pass
\ No newline at end of file
#-----------------------------------------------------------------------------
# NanoSoC CocoTB Simulation Makefile
# A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
#
# Contributors
#
# David Mapstone (d.a.mapstone@soton.ac.uk)
#
# Copyright (C) 2021-3, SoC Labs (www.soclabs.org)
#-----------------------------------------------------------------------------
# Copyright cocotb contributors
# Licensed under the Revised BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-3-Clause
SIM = questa # Simulator to Run
SIM ?= questa
# Python Install to Use
PYTHON_BIN = /usr/bin/python3.8 PYTHON_BIN = /usr/bin/python3.8
include makefile.source
MODULE = test_nanosoc_chip TOPLEVEL_LANG ?= verilog
ifneq ($(TOPLEVEL_LANG),verilog)
all:
@echo "Skipping test due to TOPLEVEL_LANG=$(TOPLEVEL_LANG) not being verilog"
clean::
else
TOPLEVEL := nanosoc_tb
include $(SOCLABS_PROJECT_DIR)/simulate/sim/cocotb/makefile.flist
include $(shell cocotb-config --makefiles)/Makefile.sim
endif
# Copyright cocotb contributors
# Licensed under the Revised BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-3-Clause
TOPLEVEL_LANG ?= verilog
ifneq ($(TOPLEVEL_LANG),verilog)
all:
@echo "Skipping test due to TOPLEVEL_LANG=$(TOPLEVEL_LANG) not being verilog"
clean::
else
TOPLEVEL := nanosoc_tb
PWD=$(shell pwd)
COCOTB?=$(PWD)/../../..
include $(SOCLABS_PROJECT_DIR)/simulate/sim/cocotb/makefile.flist
include $(shell cocotb-config --makefiles)/Makefile.sim
endif
from random import randint, randrange, getrandbits, shuffle
from collections.abc import Iterable
import logging
import cocotb
from cocotb.clock import Clock
from cocotb.regression import TestFactory
from cocotb.result import TestFailure
from cocotb.triggers import ClockCycles, Combine, Join, RisingEdge
# from cocotb_bus.drivers.amba import (
# AXIBurst, AXI4Master, AXIProtocolError, AXIReadBurstLengthMismatch,
# AXIxRESP)
from systemrdltest.python.cmsdk_reg.lib import NormalCallbackSet
from systemrdltest.python.cmsdk_reg.reg_model import cmsdk_reg
from cocotbext.axi import AxiBus, AxiMaster
CLK_PERIOD = (10, "ns")
AXI_PREFIX = "S_AXI"
async def setup_dut(dut):
cocotb.start_soon(Clock(dut.clk, *CLK_PERIOD).start())
axi_bus = AxiBus.from_prefix(dut, AXI_PREFIX)
axi_driver = AxiMaster(axi_bus, dut.clk, dut.rstn, reset_active_level=False)
dut.rstn.value = 0
await ClockCycles(dut.clk, 2)
dut.rstn.value = 1
await ClockCycles(dut.clk, 2)
return axi_driver
def binatodeci(binary):
return sum(val*(2**idx) for idx, val in enumerate(reversed(binary)))
@cocotb.coroutine
async def reg_write(manager, register, data):
print("Writing address: "+str(register.address))
await manager.write(register.address, data)
@cocotb.coroutine
async def reg_read(manager, register, length = 1):
event = manager.init_read(register.address, length)
await event.wait()
return event.data.data
@cocotb.coroutine
async def field_read(manager, register, field, length = 1):
reg_read_val = await reg_read(manager, register, length)
return getattr(register, field).decode_read_value(binatodeci(reg_read_val))
@cocotb.test()
async def test_read(dut):
"""Test Software Readable CMSDK Registers can be read"""
# Connect AXI4 driver into DUT AXI Signals
axim = AxiMaster(AxiBus.from_prefix(dut, AXI_PREFIX), dut.clk, dut.rstn, reset_active_level=False)
reg_address_map = cmsdk_reg.cmsdk_reg_cls(callbacks = NormalCallbackSet())
# Generate a Clock and Perform a Reset
await setup_dut(dut)
# Select a readable register with known reset value
test_addr = reg_address_map.pid.PID_4
expected_result = test_addr.ID.default
#Read Register Field
read_result = await field_read(axim, test_addr, "ID")
print(f"Address: {hex(test_addr.address)} | Read Value: {read_result}, Expected Value: {expected_result}")
assert read_result == expected_result
@cocotb.test()
async def test_read(dut):
"""Test 1 Software Readable CMSDK Register can be read"""
# Connect AXI4 driver into DUT AXI Signals
reg_address_map = cmsdk_reg.cmsdk_reg_cls(callbacks = NormalCallbackSet())
# Generate a Clock and Perform a Reset
axi_driver = await setup_dut(dut)
# Select a readable register with known reset value
test_addr = reg_address_map.pid.PID_4
expected_result = test_addr.ID.default
#Read Register Field
read_result = await field_read(axi_driver, test_addr, "ID")
log = logging.getLogger(f"cocotb.test")
log.info(f"Address: {hex(test_addr.address)} | Read Value: {read_result}, Expected Value: {expected_result}")
assert read_result == expected_result
@cocotb.test()
async def test_readable_regs(dut):
"""Test Software Readable CMSDK Registers can be read"""
# Connect AXI4 driver into DUT AXI Signals
reg_address_map = cmsdk_reg.cmsdk_reg_cls(callbacks = NormalCallbackSet())
# Generate a Clock and Perform a Reset
axi_driver = await setup_dut(dut)
# Setup Logger
log = logging.getLogger(f"cocotb.test")
# Select a readable register with known reset values
sections = list(reg_address_map.get_sections())
# Get a list of readable registers
readable_reg_list = []
for section in sections:
for reg in list(section.get_readable_registers()):
if isinstance(reg, Iterable):
for index in reg:
readable_reg_list.append(index)
else:
readable_reg_list.append(reg)
# Randomly select registers in readable list and perform a read
shuffle(readable_reg_list)
for reg in readable_reg_list:
# Get a list of the fields in the register and randomise
readable_fields_list = list(reg.readable_fields)
shuffle(readable_fields_list)
for field in readable_fields_list:
# Read each field
read_result = await field_read(axi_driver, reg, field.inst_name)
# Get default (reset value) for each field
expected_result = field.default
# Run an assertion against reset values
log.info(f"Field: {field.inst_name} @ Address: {hex(reg.address)} | Read Value: {read_result}, Expected Value: {expected_result}")
assert read_result == expected_result
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment