Skip to content

Commit 7117de6

Browse files
committed
Add cocotb testbench for ptp_perout
1 parent 0171afb commit 7117de6

File tree

2 files changed

+260
-0
lines changed

2 files changed

+260
-0
lines changed

tb/ptp_perout/Makefile

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Copyright (c) 2020 Alex Forencich
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
# THE SOFTWARE.
20+
21+
TOPLEVEL_LANG = verilog
22+
23+
SIM ?= icarus
24+
WAVES ?= 0
25+
26+
COCOTB_HDL_TIMEUNIT = 1ns
27+
COCOTB_HDL_TIMEPRECISION = 1ps
28+
29+
DUT = ptp_perout
30+
TOPLEVEL = $(DUT)
31+
MODULE = test_$(DUT)
32+
VERILOG_SOURCES += ../../rtl/$(DUT).v
33+
34+
# module parameters
35+
export PARAM_FNS_ENABLE ?= 1
36+
export PARAM_OUT_START_S ?= 0
37+
export PARAM_OUT_START_NS ?= 0
38+
export PARAM_OUT_START_FNS ?= 0
39+
export PARAM_OUT_PERIOD_S ?= 1
40+
export PARAM_OUT_PERIOD_NS ?= 0
41+
export PARAM_OUT_PERIOD_FNS ?= 0
42+
export PARAM_OUT_WIDTH_S ?= 0
43+
export PARAM_OUT_WIDTH_NS ?= 1000
44+
export PARAM_OUT_WIDTH_FNS ?= 0
45+
46+
ifeq ($(SIM), icarus)
47+
PLUSARGS += -fst
48+
49+
COMPILE_ARGS += -P $(TOPLEVEL).FNS_ENABLE=$(PARAM_FNS_ENABLE)
50+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_START_S=$(PARAM_OUT_START_S)
51+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_START_NS=$(PARAM_OUT_START_NS)
52+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_START_FNS=$(PARAM_OUT_START_FNS)
53+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_PERIOD_S=$(PARAM_OUT_PERIOD_S)
54+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_PERIOD_NS=$(PARAM_OUT_PERIOD_NS)
55+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_PERIOD_FNS=$(PARAM_OUT_PERIOD_FNS)
56+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_WIDTH_S=$(PARAM_OUT_WIDTH_S)
57+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_WIDTH_NS=$(PARAM_OUT_WIDTH_NS)
58+
COMPILE_ARGS += -P $(TOPLEVEL).OUT_WIDTH_FNS=$(PARAM_OUT_WIDTH_FNS)
59+
60+
ifeq ($(WAVES), 1)
61+
VERILOG_SOURCES += iverilog_dump.v
62+
COMPILE_ARGS += -s iverilog_dump
63+
endif
64+
else ifeq ($(SIM), verilator)
65+
COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH
66+
67+
COMPILE_ARGS += -GFNS_ENABLE=$(PARAM_FNS_ENABLE)
68+
COMPILE_ARGS += -GOUT_START_S=$(PARAM_OUT_START_S)
69+
COMPILE_ARGS += -GOUT_START_NS=$(PARAM_OUT_START_NS)
70+
COMPILE_ARGS += -GOUT_START_FNS=$(PARAM_OUT_START_FNS)
71+
COMPILE_ARGS += -GOUT_PERIOD_S=$(PARAM_OUT_PERIOD_S)
72+
COMPILE_ARGS += -GOUT_PERIOD_NS=$(PARAM_OUT_PERIOD_NS)
73+
COMPILE_ARGS += -GOUT_PERIOD_FNS=$(PARAM_OUT_PERIOD_FNS)
74+
COMPILE_ARGS += -GOUT_WIDTH_S=$(PARAM_OUT_WIDTH_S)
75+
COMPILE_ARGS += -GOUT_WIDTH_NS=$(PARAM_OUT_WIDTH_NS)
76+
COMPILE_ARGS += -GOUT_WIDTH_FNS=$(PARAM_OUT_WIDTH_FNS)
77+
78+
ifeq ($(WAVES), 1)
79+
COMPILE_ARGS += --trace-fst
80+
endif
81+
endif
82+
83+
include $(shell cocotb-config --makefiles)/Makefile.sim
84+
85+
iverilog_dump.v:
86+
echo 'module iverilog_dump();' > $@
87+
echo 'initial begin' >> $@
88+
echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@
89+
echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@
90+
echo 'end' >> $@
91+
echo 'endmodule' >> $@
92+
93+
clean::
94+
@rm -rf iverilog_dump.v
95+
@rm -rf dump.fst $(TOPLEVEL).fst

tb/ptp_perout/test_ptp_perout.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/env python
2+
"""
3+
4+
Copyright (c) 2020 Alex Forencich
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.
23+
24+
"""
25+
26+
import logging
27+
import os
28+
29+
import cocotb_test.simulator
30+
31+
import cocotb
32+
from cocotb.clock import Clock
33+
from cocotb.triggers import RisingEdge, Timer
34+
35+
from cocotbext.eth import PtpClock
36+
37+
38+
class TB:
39+
def __init__(self, dut):
40+
self.dut = dut
41+
42+
self.log = logging.getLogger("cocotb.tb")
43+
self.log.setLevel(logging.DEBUG)
44+
45+
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
46+
47+
self.ptp_clock = PtpClock(
48+
ts_96=dut.input_ts_96,
49+
ts_step=dut.input_ts_step,
50+
clock=dut.clk,
51+
reset=dut.rst,
52+
period_ns=6.4
53+
)
54+
55+
dut.enable.setimmediatevalue(0)
56+
dut.input_start.setimmediatevalue(0)
57+
dut.input_start_valid.setimmediatevalue(0)
58+
dut.input_period.setimmediatevalue(0)
59+
dut.input_period_valid.setimmediatevalue(0)
60+
dut.input_width.setimmediatevalue(0)
61+
dut.input_width_valid.setimmediatevalue(0)
62+
63+
async def reset(self):
64+
self.dut.rst.setimmediatevalue(0)
65+
await RisingEdge(self.dut.clk)
66+
await RisingEdge(self.dut.clk)
67+
self.dut.rst <= 1
68+
await RisingEdge(self.dut.clk)
69+
await RisingEdge(self.dut.clk)
70+
self.dut.rst <= 0
71+
await RisingEdge(self.dut.clk)
72+
await RisingEdge(self.dut.clk)
73+
74+
75+
@cocotb.test()
76+
async def run_test(dut):
77+
78+
tb = TB(dut)
79+
80+
await tb.reset()
81+
82+
dut.enable <= 1
83+
84+
await RisingEdge(dut.clk)
85+
86+
dut.input_start <= 100 << 16
87+
dut.input_start_valid <= 1
88+
dut.input_period <= 100 << 16
89+
dut.input_period_valid <= 1
90+
dut.input_width <= 50 << 16
91+
dut.input_width_valid <= 1
92+
93+
await RisingEdge(dut.clk)
94+
95+
dut.input_start_valid <= 0
96+
dut.input_period_valid <= 0
97+
dut.input_width_valid <= 0
98+
99+
await Timer(10000, 'ns')
100+
101+
await RisingEdge(dut.clk)
102+
103+
dut.input_start <= 0 << 16
104+
dut.input_start_valid <= 1
105+
dut.input_period <= 100 << 16
106+
dut.input_period_valid <= 1
107+
dut.input_width <= 50 << 16
108+
dut.input_width_valid <= 1
109+
110+
await RisingEdge(dut.clk)
111+
112+
dut.input_start_valid <= 0
113+
dut.input_period_valid <= 0
114+
dut.input_width_valid <= 0
115+
116+
await Timer(10000, 'ns')
117+
118+
await RisingEdge(dut.clk)
119+
await RisingEdge(dut.clk)
120+
121+
122+
# cocotb-test
123+
124+
tests_dir = os.path.abspath(os.path.dirname(__file__))
125+
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
126+
lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib'))
127+
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl'))
128+
129+
130+
def test_ptp_perout(request):
131+
dut = "ptp_perout"
132+
module = os.path.splitext(os.path.basename(__file__))[0]
133+
toplevel = dut
134+
135+
verilog_sources = [
136+
os.path.join(rtl_dir, f"{dut}.v"),
137+
]
138+
139+
parameters = {}
140+
141+
parameters['FNS_ENABLE'] = 1
142+
parameters['OUT_START_S'] = 0
143+
parameters['OUT_START_NS'] = 0
144+
parameters['OUT_START_FNS'] = 0x0000
145+
parameters['OUT_PERIOD_S'] = 1
146+
parameters['OUT_PERIOD_NS'] = 0
147+
parameters['OUT_PERIOD_FNS'] = 0x0000
148+
parameters['OUT_WIDTH_S'] = 0
149+
parameters['OUT_WIDTH_NS'] = 1000
150+
parameters['OUT_WIDTH_FNS'] = 0x0000
151+
152+
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
153+
154+
sim_build = os.path.join(tests_dir, "sim_build",
155+
request.node.name.replace('[', '-').replace(']', ''))
156+
157+
cocotb_test.simulator.run(
158+
python_search=[tests_dir],
159+
verilog_sources=verilog_sources,
160+
toplevel=toplevel,
161+
module=module,
162+
parameters=parameters,
163+
sim_build=sim_build,
164+
extra_env=extra_env,
165+
)

0 commit comments

Comments
 (0)