Skip to content

Commit 8a4d706

Browse files
committed
update and add testbenches
1 parent 2a23b3c commit 8a4d706

File tree

8 files changed

+238
-6
lines changed

8 files changed

+238
-6
lines changed

problems/getting-started/output-zero/tb/constant_zero.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from cocotb.clock import Timer
23

34

45
class DataError(Exception):
@@ -20,6 +21,7 @@ def get_signals(self):
2021
self.zero = self.dut.zero
2122

2223
async def zero_check(self):
24+
await Timer(1, units="ns")
2325
if int(self.zero.value) != 0:
2426
raise DataError(
2527
f"Output should always be 0, got {self.zero.value} instead."

problems/getting-started/output-zero/tb/test_constant_zero.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import pytest
3+
34
import cocotb
4-
from cocotb.clock import Timer
55
from cocotb.regression import TestFactory
66
from cocotb_test.simulator import run
77

@@ -12,8 +12,6 @@ async def output_stays_zero(dut):
1212
tb = TB(dut)
1313

1414
tb.log.info("Checking output value...")
15-
# Await one nanosecond so the model can start.
16-
await Timer(1, units="ns")
1715
tb.zero_check()
1816

1917

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import logging
2+
from cocotb.clock import Timer
3+
4+
5+
class DataError(Exception):
6+
pass
7+
8+
9+
class TB:
10+
def __init__(self, dut):
11+
self.dut = dut
12+
13+
# Start logging
14+
self.log = logging.getLogger("cocotb.tb")
15+
self.log.setLevel(logging.DEBUG)
16+
17+
# Simulation Signals
18+
self.get_signals()
19+
20+
# Zero out signals
21+
self.zero_signals()
22+
23+
def get_signals(self):
24+
self.a = self.dut.a
25+
self.b = self.dut.b
26+
self.c = self.dut.c
27+
28+
self.w = self.dut.w
29+
self.x = self.dut.x
30+
self.y = self.dut.y
31+
self.z = self.dut.z
32+
33+
def zero_signals(self):
34+
self.a.value = 0
35+
self.b.value = 0
36+
self.c.value = 0
37+
38+
async def set_input_vals(self, val):
39+
self.a.value = val[0]
40+
self.b.value = val[1]
41+
self.c.value = val[2]
42+
await Timer(1, units="ns")
43+
44+
async def is_equal_check(self):
45+
await Timer(1, units="ns")
46+
if int(self.w.value) != int(self.a.value):
47+
raise DataError(
48+
f"w and a should be equal, but {self.w.value} != {self.a.value}."
49+
)
50+
51+
if int(self.x.value) != int(self.b.value):
52+
raise DataError(
53+
f"x and b should be equal, but {self.x.value} != {self.b.value}."
54+
)
55+
56+
if int(self.y.value) != int(self.b.value):
57+
raise DataError(
58+
f"y and b should be equal, but {self.y.value} != {self.b.value}."
59+
)
60+
61+
if int(self.z.value) != int(self.c.value):
62+
raise DataError(
63+
f"z and c should be equal, but {self.z.value} != {self.c.value}."
64+
)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import os
2+
import pytest
3+
4+
import cocotb
5+
from cocotb.regression import TestFactory
6+
from cocotb_test.simulator import run
7+
8+
from multi_wire import TB
9+
10+
11+
async def output_stays_equal(dut):
12+
tb = TB(dut)
13+
14+
test_vals = [
15+
[0, 1, 0],
16+
[1, 1, 0],
17+
[0, 0, 0],
18+
[0, 1, 1],
19+
]
20+
21+
tb.log.info("Checking output value...")
22+
23+
for i in range(len(test_vals)):
24+
tb.set_input_vals(test_vals[i])
25+
tb.is_equal_check()
26+
27+
28+
if cocotb.SIM_NAME:
29+
test1 = TestFactory(output_stays_equal)
30+
test1.generate_tests()
31+
32+
# cocotb-test
33+
34+
tests_dir = os.path.abspath(os.path.dirname(__file__))
35+
rtl_dir = os.path.abspath(os.path.join(tests_dir, "..", "rtl"))
36+
37+
parameter_list = [{}]
38+
39+
40+
@pytest.mark.parametrize("parameters", parameter_list)
41+
def test_constant_zero(request, parameters):
42+
dut = "multi_wire"
43+
module = os.path.splitext(os.path.basename(__file__))[0]
44+
toplevel = dut
45+
46+
verilog_sources = [
47+
os.path.join(rtl_dir, f"{dut}.v"),
48+
]
49+
50+
extra_env = {f"PARAM_{k}": str(v) for k, v in parameters.items()}
51+
52+
sim_build = os.path.join(
53+
tests_dir, "sim_build", request.node.name.replace("[", "-").replace("]", "")
54+
)
55+
56+
run(
57+
python_search=[tests_dir],
58+
verilog_sources=verilog_sources,
59+
toplevel=toplevel,
60+
module=module,
61+
parameters=parameters,
62+
sim_build=sim_build,
63+
extra_env=extra_env,
64+
compile_args=["--timing", "-O3"],
65+
waves=True,
66+
)

problems/verilog-language/basics/simple-wire/rtl/simple_wire.v

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
`default_nettype none
44

55
module simple_wire (
6-
input wire in,
7-
output wire out
6+
input wire i,
7+
output wire o
88
);
99

10-
assign out = in;
10+
assign o = i;
1111

1212
endmodule
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import logging
2+
from cocotb.clock import Timer
3+
4+
5+
class DataError(Exception):
6+
pass
7+
8+
9+
class TB:
10+
def __init__(self, dut):
11+
self.dut = dut
12+
13+
# Start logging
14+
self.log = logging.getLogger("cocotb.tb")
15+
self.log.setLevel(logging.DEBUG)
16+
17+
# Simulation Signals
18+
self.get_signals()
19+
20+
# Zero out signals
21+
self.zero_signals()
22+
23+
def get_signals(self):
24+
self.i = self.dut.i
25+
self.o = self.dut.o
26+
27+
def zero_signals(self):
28+
self.i.value = 0
29+
30+
async def set_input_val(self, val):
31+
self.i.value = val
32+
await Timer(1, units="ns")
33+
34+
async def is_equal_check(self):
35+
await Timer(1, units="ns")
36+
if int(self.i.value) != int(self.o.value):
37+
raise DataError(
38+
f"Output should be equal, but {self.i.value} != {self.o.value}."
39+
)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import os
2+
import pytest
3+
4+
import cocotb
5+
from cocotb.regression import TestFactory
6+
from cocotb_test.simulator import run
7+
8+
from simple_wire import TB
9+
10+
11+
async def output_stays_equal(dut):
12+
tb = TB(dut)
13+
14+
test_vals = [0, 1, 1, 0, 1, 0]
15+
16+
tb.log.info("Checking output value...")
17+
18+
for i in range(len(test_vals)):
19+
tb.set_input_val(test_vals[i])
20+
tb.is_equal_check()
21+
22+
23+
if cocotb.SIM_NAME:
24+
test1 = TestFactory(output_stays_equal)
25+
test1.generate_tests()
26+
27+
# cocotb-test
28+
29+
tests_dir = os.path.abspath(os.path.dirname(__file__))
30+
rtl_dir = os.path.abspath(os.path.join(tests_dir, "..", "rtl"))
31+
32+
parameter_list = [{}]
33+
34+
35+
@pytest.mark.parametrize("parameters", parameter_list)
36+
def test_constant_zero(request, parameters):
37+
dut = "simple_wire"
38+
module = os.path.splitext(os.path.basename(__file__))[0]
39+
toplevel = dut
40+
41+
verilog_sources = [
42+
os.path.join(rtl_dir, f"{dut}.v"),
43+
]
44+
45+
extra_env = {f"PARAM_{k}": str(v) for k, v in parameters.items()}
46+
47+
sim_build = os.path.join(
48+
tests_dir, "sim_build", request.node.name.replace("[", "-").replace("]", "")
49+
)
50+
51+
run(
52+
python_search=[tests_dir],
53+
verilog_sources=verilog_sources,
54+
toplevel=toplevel,
55+
module=module,
56+
parameters=parameters,
57+
sim_build=sim_build,
58+
extra_env=extra_env,
59+
compile_args=["--timing", "-O3"],
60+
waves=True,
61+
)

pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ log_file_level = DEBUG
99
testpaths =
1010
problems/getting-started/getting-started/tb/test_constant_one.py
1111
problems/getting-started/output-zero/tb/test_constant_zero.py
12+
problems/verilog-language/basics/simple-wire/tb/test_simple_wire.py
13+
problems/verilog-language/basics/multi-wire/tb/test_multi_wire.py

0 commit comments

Comments
 (0)