Skip to content

Commit 58ba6b7

Browse files
committed
More test files
1 parent 678a1c3 commit 58ba6b7

File tree

7 files changed

+759
-60
lines changed

7 files changed

+759
-60
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ VERILOG_SOURCES += $(PWD)/src/dtw_accel.v \
1919
TOPLEVEL = dtw_accel
2020

2121
# MODULE is the basename of the Python test file
22-
MODULE = test_dtw_accel
22+
MODULE = test_dut
2323

2424
# include cocotb's make rules to take care of the simulator setup
2525
include $(shell cocotb-config --makefiles)/Makefile.sim

axilite_driver.py

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
import os
2+
import sys
3+
import time
4+
import cocotb
5+
#from cocotb.result import ReturnValue
6+
from cocotb.clock import Clock
7+
from cocotb.triggers import Timer
8+
from cocotb import logging
9+
#from cocotb_bus.drivers.amba import AXI4LiteMaster
10+
from cocotbext.axi import AxiLiteMaster, AxiLiteBus
11+
12+
class Driver(object):
13+
14+
def __init__(self, dut, name, clock, reset, debug=False):
15+
self.debug = debug
16+
self.dut = dut
17+
self.clock = clock
18+
self.reset = reset
19+
self.axim = AxiLiteMaster(AxiLiteBus.from_prefix(dut, name), self.clock, self.reset)
20+
dut._log.debug ("Started")
21+
22+
async def write(self, address, data):
23+
"""write
24+
25+
Generic write command usd to write data to a Nysa image, this will be
26+
overriden based on the communication method with the specific FPGA board
27+
28+
Args:
29+
address (int): Address of the register/memory to read
30+
data (array of unsigned bytes): Array of raw bytes to send to the
31+
device
32+
disable_auto_inc (bool): if true, auto increment feature will be disabled
33+
Returns:
34+
Nothing
35+
36+
Raises:
37+
AssertionError: This function must be overriden by a board specific
38+
implementation
39+
"""
40+
await self.axim.write(address, data)
41+
42+
async def read_register(self, address):
43+
"""read_register
44+
45+
Reads a single register from the read command and then converts it to an
46+
integer
47+
48+
Args:
49+
address (int): Address of the register/memory to read
50+
51+
Returns:
52+
(int): 32-bit unsigned register value
53+
54+
Raises:
55+
NysaCommError: Error in communication
56+
"""
57+
d = await self.axim.read_dword(address)
58+
return d
59+
60+
async def write_register(self, address, value):
61+
"""write_register
62+
63+
Writes a single register from a 32-bit unsingned integer
64+
65+
Args:
66+
address (int): Address of the register/memory to read
67+
value (int) 32-bit unsigned integer to be written into the register
68+
69+
Returns:
70+
Nothing
71+
72+
Raises:
73+
NysaCommError: Error in communication
74+
"""
75+
await self.axim.write_dword(address, value)
76+
77+
async def enable_register_bit(self, address, bit, enable):
78+
"""enable_register_bit
79+
80+
Pass a bool value to set/clear a bit
81+
82+
Args:
83+
address (int): Address of the register/memory to modify
84+
bit (int): Address of bit to set (31 - 0)
85+
enable (bool): set or clear a bit
86+
87+
Returns:
88+
Nothing
89+
90+
Raises:
91+
NysaCommError: Error in communication
92+
"""
93+
if enable:
94+
await self.set_register_bit(address, bit)
95+
else:
96+
await self.clear_register_bit(address, bit)
97+
98+
async def set_register_bit(self, address, bit):
99+
"""set_register_bit
100+
101+
Sets an individual bit in a register
102+
103+
Args:
104+
address (int): Address of the register/memory to modify
105+
bit (int): Address of bit to set (31 - 0)
106+
107+
Returns:
108+
Nothing
109+
110+
Raises:
111+
NysaCommError: Error in communication
112+
"""
113+
register = await self.read_register(address)
114+
bit_mask = 1 << bit
115+
register |= bit_mask
116+
await self.write_register(address, register)
117+
118+
async def clear_register_bit(self, address, bit):
119+
"""clear_register_bit
120+
121+
Clear an individual bit in a register
122+
123+
Args:
124+
address (int): Address of the register/memory to modify
125+
bit (int): Address of bit to set (31 - 0)
126+
127+
Returns:
128+
Nothing
129+
130+
Raises:
131+
NysaCommError: Error in communication
132+
"""
133+
register = await self.read_register(address)
134+
bit_mask = 1 << bit
135+
register &= ~bit_mask
136+
await self.write_register(address, register)
137+
138+
async def is_register_bit_set(self, address, bit):
139+
"""is_register_bit_set
140+
141+
raise ReturnValues true if an individual bit is set, false if clear
142+
143+
Args:
144+
address (int): Address of the register/memory to read
145+
bit (int): Address of bit to check (31 - 0)
146+
147+
Returns:
148+
(boolean):
149+
True: bit is set
150+
False: bit is not set
151+
152+
Raises:
153+
NysaCommError
154+
"""
155+
register = await self.read_register(address)
156+
bit_mask = 1 << bit
157+
#raise ReturnValue ((register & bit_mask) > 0)
158+
return (register & bit_mask) > 0
159+
160+
async def write_register_bit_range(self, address, high_bit, low_bit, value):
161+
"""
162+
Write data to a range of bits within a register
163+
164+
Register = [XXXXXXXXXXXXXXXXXXXXXXXH---LXXXX]
165+
166+
Write to a range of bits within ia register
167+
168+
Args:
169+
address (unsigned long): Address or the register/memory to write
170+
high_bit (int): the high bit of the bit range to edit
171+
low_bit (int): the low bit of the bit range to edit
172+
value (int): the value to write in the range
173+
174+
Returns:
175+
Nothing
176+
177+
Raises:
178+
NysaCommError
179+
"""
180+
reg = self.read_register(address)
181+
bitmask = (((1 << (high_bit + 1))) - (1 << low_bit))
182+
reg &= ~(bitmask)
183+
reg |= value << low_bit
184+
self.write_register(address, reg)
185+
186+
async def read_register_bit_range(self, address, high_bit, low_bit):
187+
"""
188+
Read a range of bits within a register at address 'address'
189+
190+
Register = [XXXXXXXXXXXXXXXXXXXXXXXH---LXXXX]
191+
192+
Read the value within a register, the top bit is H and bottom is L
193+
194+
Args:
195+
address (unsigned long): Address or the register/memory to read
196+
high_bit (int): the high bit of the bit range to read
197+
low_bit (int): the low bit of the bit range to read
198+
199+
Returns (unsigned integer):
200+
Value within the bitfield
201+
202+
Raises:
203+
NysaCommError
204+
205+
"""
206+
207+
value = await self.read_register(address)
208+
bitmask = (((1 << (high_bit + 1))) - (1 << low_bit))
209+
value = value & bitmask
210+
value = value >> low_bit
211+
return value
212+

axis_driver.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import logging
2+
import itertools
3+
import time
4+
import cocotb
5+
from array import array as Array
6+
7+
from cocotb.clock import Clock
8+
from cocotb.result import TestFailure
9+
from cocotb.triggers import Timer
10+
from cocotb.triggers import RisingEdge
11+
from cocotb.triggers import FallingEdge
12+
13+
from cocotbext.axi import AxiStreamFrame
14+
from cocotbext.axi import AxiStreamBus
15+
from cocotbext.axi import AxiStreamSource
16+
from cocotbext.axi import AxiStreamSink
17+
from cocotbext.axi import AxiStreamMonitor
18+
19+
class AXISSource:
20+
21+
def __init__(self, dut, BUS_NAME, clk, rst):
22+
self.dut = dut
23+
self.clk = clk
24+
self.rst = rst
25+
self.cycle_list = None
26+
self.log = logging.getLogger("cocotb.tb")
27+
self.log.setLevel(logging.DEBUG)
28+
self.cur_id = 1
29+
30+
self.source = AxiStreamSource(AxiStreamBus.from_prefix(dut, BUS_NAME), clk, rst)
31+
32+
async def reset(self):
33+
self.rst.setimmediatevalue(0)
34+
await RisingEdge(self.clk)
35+
await RisingEdge(self.clk)
36+
self.rst <= 1
37+
await RisingEdge(self.clk)
38+
await RisingEdge(self.clk)
39+
self.rst <= 0
40+
await RisingEdge(self.clk)
41+
await RisingEdge(self.clk)
42+
43+
def insert_idle_list(self, cycle_list = None):
44+
if type(cycle_list) is not list:
45+
print ("Cycle List needs to be a list")
46+
self.source.set_pause_generator(itertools.cycle(cycle_list))
47+
48+
async def send_raw_data(self, data_list):
49+
for data in data_list:
50+
d = AxiStreamFrame(data, tid = self.cur_id, tdest = self.cur_id)
51+
await self.source.send(d)
52+
self.cur_id += 1
53+
54+
async def send_frame_data(self, frame):
55+
first = True
56+
for data in data_list:
57+
u = [0] * len(data)
58+
if first:
59+
u[0] = 1
60+
first = False
61+
62+
d = AxiStreamFrame(data, tid = self.cur_id, tdest = self.cur_id, tuser = u)
63+
await self.source.send(d)
64+
self.cur_id += 1
65+
66+
class AXISSink:
67+
def __init__(self, dut, BUS_NAME, clk, rst):
68+
self.dut = dut
69+
self.clk = clk
70+
self.rst = rst
71+
self.log = logging.getLogger("cocotb.tb")
72+
self.log.setLevel(logging.DEBUG)
73+
self.recv_frames = []
74+
75+
self.sink = AxiStreamSink(AxiStreamBus.from_prefix(dut, BUS_NAME), clk, rst)
76+
77+
def set_backpressure_generator(self, generator=None):
78+
if generator:
79+
self.sink.set_pause_generator(generator())
80+
81+
async def reset(self):
82+
self.recv_frames = []
83+
self.rst.setimmediatevalue(0)
84+
await RisingEdge(self.clk)
85+
await RisingEdge(self.clk)
86+
self.rst <= 1
87+
await RisingEdge(self.clk)
88+
await RisingEdge(self.clk)
89+
self.rst <= 0
90+
await RisingEdge(self.clk)
91+
await RisingEdge(self.clk)
92+
93+
def insert_backpreassure_list(self, cycle_list = None):
94+
if type(cycle_list) is not list:
95+
print ("Cycle List needs to be a list")
96+
self.sink.set_pause_generator(itertools.cycle(cycle_list))
97+
98+
async def receive(self):
99+
self.recv_frames.append(await self.sink.recv())
100+
101+
def read_data(self):
102+
frames = [d for d in self.recv_frames]
103+
data = []
104+
for f in frames:
105+
data.append([d for d in f])
106+
return data
107+
108+
class AXISMonitor:
109+
def __init__(self, dut, BUS_NAME, clk, rst):
110+
self.dut = dut
111+
self.clk = clk
112+
self.rst = rst
113+
self.log = logging.getLogger("cocotb.tb")
114+
self.log.setLevel(logging.DEBUG)
115+
116+
self.monitor = AxiStreamMonitor(AxiStreamBus.from_prefix(dut, BUS_NAME), clk, rst)
117+
118+
async def reset(self):
119+
self.rst.setimmediatevalue(0)
120+
await RisingEdge(self.clk)
121+
await RisingEdge(self.clk)
122+
self.rst <= 1
123+
await RisingEdge(self.clk)
124+
await RisingEdge(self.clk)
125+
self.rst <= 0
126+
await RisingEdge(self.clk)
127+
await RisingEdge(self.clk)
128+

0 commit comments

Comments
 (0)