Skip to content

Commit

Permalink
Merge pull request #97 from elmsfu/cocotb_tests
Browse files Browse the repository at this point in the history
Add Cocotb test framework for testing sim.v files
  • Loading branch information
mithro committed May 7, 2018
2 parents d3038f3 + ff91c2f commit 42717cd
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 26 deletions.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ all: | redir .git/info/exclude
.PHONY: all
.DEFAULT_GOAL := all

test:
test: simtest
$(call heading,Running Python utils tests)
@$(MAKE) -C utils tests $(result)

Expand All @@ -38,8 +38,15 @@ test:
$(call heading,$(PURPLE)Test Arch:$(NC)Running Verilog to Routing tests)
@$(MAKE) ARCH=testarch -C tests $(result)


.PHONY: test

simtest: | $(CONDA_COCOTB)
$(call heading,Running simulation tests)
@for ii in `find . -type d -name simtest -a ! -wholename "./.deps/*"`; do echo $$ii; $(MAKE) -C $$ii TOP_DIR=$(TOP_DIR) > /dev/null; [ `grep -c failure $$ii/results.xml` == 0 ]; done

.PHONY: simtest

clean:
@true

Expand Down
12 changes: 12 additions & 0 deletions artix7/primitives/slicel/Nlut/simtest/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include $(TOP_DIR)/make/inc/env.mk

VERILOG_SOURCES = $(CURDIR)/../alut.sim.v
TOPLEVEL := ALUT
MODULE := test_alut
COMPILE_ARGS += -PALUT.INIT=64\'b0101010101010101010101010101010101010101010101010101010101010101

include $(COCOTB)/makefiles/Makefile.inc

PYTHONPATH := $(CURDIR):$(PYTHONPATH):$(PYTHON_DYNLIBDIR)

include $(COCOTB)/makefiles/Makefile.sim
49 changes: 49 additions & 0 deletions artix7/primitives/slicel/Nlut/simtest/test_alut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Test alut to cover all Nlut
"""

import cocotb
from cocotb.binary import BinaryValue
from cocotb.regression import TestFactory
from cocotb.result import TestFailure
from cocotb.triggers import Timer


class LutModel(object):
"""
Model for LUT
"""
def __init__(self, init, inputs):
self.init = init
self.inputs = BinaryValue(inputs)

@property
def O5(self):
return eval(self.init.binstr[-1-self.inputs.integer])

@property
def O6(self):
return eval(self.init.binstr[-1-self.inputs.integer])

@cocotb.coroutine
def lut_basic_test(dut, inputs):
"""Test for LUT options"""

yield Timer(1)

for i in range(6):
setattr(dut, 'A%d'%(i + 1), inputs & (1 << i))
yield Timer(1)
model = LutModel(dut.INIT.value, inputs)

if dut.O5 != model.O5 or dut.O6 != model.O6:
raise TestFailure('No match (dut:model) O5(%d:%d) O6(%d:%d)' % \
(dut.O5, model.O5, dut.O6, model.O6))
else:
dut._log.info('Match')


factory = TestFactory(lut_basic_test)
input_permutations = range(2**6)
factory.add_option("inputs", input_permutations)
factory.generate_tests()
8 changes: 7 additions & 1 deletion make/env.mk
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,19 @@ $(CONDA_NODE): | $(CONDA_SETUP)
$(CONDA_NPM): | $(CONDA_SETUP)
$(CONDA_BIN) install nodejs

$(CONDA_IVERILOG): | $(CONDA_SETUP)
$(CONDA_BIN) install iverilog

$(CONDA_COCOTB): | $(CONDA_SETUP)
$(CONDA_PIP) install cocotb

make:
make -C $(TOP_DIR) -f $(TOP_DIR)/make/env.mk $(CONDA_MAKE)

.PHONY: make

env:
make -C $(TOP_DIR) -f $(TOP_DIR)/make/env.mk $(CONDA_YOSYS) $(CONDA_VPR) $(CONDA_DIR)/lib/python3.6/site-packages/lxml
make -C $(TOP_DIR) -f $(TOP_DIR)/make/env.mk $(CONDA_YOSYS) $(CONDA_VPR) $(CONDA_IVERILOG) $(CONDA_DIR)/lib/python3.6/site-packages/lxml

.PHONY: env

Expand Down
62 changes: 38 additions & 24 deletions make/inc/env.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,42 @@ INC_ENV_MK := 1
ENV_DIR := $(abspath $(TOP_DIR)/env)
CONDA_DIR := $(ENV_DIR)/conda

CONDA_BIN := $(CONDA_DIR)/bin/conda
CONDA_YOSYS := $(CONDA_DIR)/bin/yosys
CONDA_VPR := $(CONDA_DIR)/bin/vpr
CONDA_MAKE := $(CONDA_DIR)/bin/make
CONDA_XSLT := $(CONDA_DIR)/bin/xsltproc
CONDA_PYTEST:= $(CONDA_DIR)/bin/pytest
CONDA_YAPF := $(CONDA_DIR)/bin/yapf
CONDA_NODE := $(CONDA_DIR)/bin/node
CONDA_NPM := $(CONDA_DIR)/bin/npm
CONDA_BIN := $(CONDA_DIR)/bin/conda
CONDA_YOSYS := $(CONDA_DIR)/bin/yosys
CONDA_VPR := $(CONDA_DIR)/bin/vpr
CONDA_MAKE := $(CONDA_DIR)/bin/make
CONDA_XSLT := $(CONDA_DIR)/bin/xsltproc
CONDA_PYTEST := $(CONDA_DIR)/bin/pytest
CONDA_YAPF := $(CONDA_DIR)/bin/yapf
CONDA_NODE := $(CONDA_DIR)/bin/node
CONDA_NPM := $(CONDA_DIR)/bin/npm
CONDA_IVERILOG := $(CONDA_DIR)/bin/iverilog
CONDA_PYTHON3 := $(CONDA_DIR)/bin/python3
CONDA_PIP := $(CONDA_DIR)/bin/pip
CONDA_COCOTB = $(PYTHON_SITEPACKAGES)/cocotb

# If the environment exists, put it into the path and use it.
ifneq (,$(wildcard $(abspath $(ENV_DIR))))
PATH := $(CONDA_DIR)/bin:$(PATH)
YOSYS ?= $(CONDA_YOSYS)
VPR ?= $(CONDA_VPR)
XSLT ?= $(CONDA_XSLT)
PYTEST ?= $(CONDA_PYTEST)
YAPF ?= $(CONDA_YAPF)
NODE ?= $(CONDA_NODE)
NPM ?= $(CONDA_NPM)
PATH := $(CONDA_DIR)/bin:$(PATH)
YOSYS ?= $(CONDA_YOSYS)
VPR ?= $(CONDA_VPR)
XSLT ?= $(CONDA_XSLT)
PYTEST ?= $(CONDA_PYTEST)
YAPF ?= $(CONDA_YAPF)
NODE ?= $(CONDA_NODE)
NPM ?= $(CONDA_NPM)
IVERILOG ?= $(CONDA_IVERILOG)
PYTHON ?= $(CONDA_PYTHON3)
else
YOSYS ?= yosys
VPR ?= vpr
XSLT ?= xsltproc
PYTEST ?= pytest-3
YAPF ?= yapf
NODE ?= node
NPM ?= npm
YOSYS ?= yosys
VPR ?= vpr
XSLT ?= xsltproc
PYTEST ?= pytest-3
YAPF ?= yapf
NODE ?= node
NPM ?= npm
IVERILOG ?= iverilog
PYTHON ?= python3
endif

# Tools in third_party
Expand All @@ -40,4 +48,10 @@ NETLISTSVG = $(TOP_DIR)/third_party/netlistsvg
# Tools not part of the environment yet.
INKSCAPE ?= inkscape

# TODO: Should this live somewhere else
PYTHON_SITEPACKAGES = $(shell $(PYTHON) -c "import site; print(site.getsitepackages()[0])")
TOPLEVEL_LANG ?= verilog
COCOTB = $(dir $(CONDA_COCOTB))
ICARUS_BIN_DIR ?= $(dir $(shell which $(IVERILOG)))

endif
6 changes: 6 additions & 0 deletions pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[MESSAGES CONTROL]
enable=bad-indentation,eval-used,invalid-name,missing-docstring,old-style-class,protected-access,unused-import

[REPORTS]
output-format=colorized
reports=no
11 changes: 11 additions & 0 deletions vpr/muxes/logic/mux2/simtest/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
include $(TOP_DIR)/make/inc/env.mk

VERILOG_SOURCES = $(CURDIR)/../mux2.sim.v
TOPLEVEL := MUX2
MODULE := test_mux2

include $(COCOTB)/makefiles/Makefile.inc

PYTHONPATH := $(CURDIR):$(PYTHONPATH):$(PYTHON_DYNLIBDIR)

include $(COCOTB)/makefiles/Makefile.sim
37 changes: 37 additions & 0 deletions vpr/muxes/logic/mux2/simtest/test_mux2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
Test mux2 correctness
"""

import cocotb
from cocotb.regression import TestFactory
from cocotb.result import TestFailure
from cocotb.triggers import Timer


@cocotb.coroutine
def mux2_basic_test(dut, inputs=(1, 0, 0)):
"""Test for MUX2 options."""

yield Timer(2)
I0, I1, S0 = inputs
dut.I0 = I0
dut.I1 = I1
dut.S0 = S0
if S0:
expected = I1
else:
expected = I0
yield Timer(2)

if dut.O != expected:
raise TestFailure(
'Result is incorrect for I0(%d) I1(%d) S0(%d): %s(O) != %s (expected)'\
% (I0, I1, S0, dut.O, expected))
else:
dut._log.info('I0(%d) I1(%d) S0(%d) output(%d) Ok!'%(I0, I1, S0, dut.O))


factory = TestFactory(mux2_basic_test)
input_permutations = [(x, y, z) for x in [0, 1] for y in [0, 1] for z in [0, 1]]
factory.add_option("inputs", input_permutations)
factory.generate_tests()

0 comments on commit 42717cd

Please sign in to comment.