-
Notifications
You must be signed in to change notification settings - Fork 2
/
designtemplate_tb.py
73 lines (60 loc) · 2.67 KB
/
designtemplate_tb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from migen.fhdl.std import *
from migen.sim.generic import run_simulation
import designtemplate
import riffa
from virtmem_tb import TBMemory
# memory initialization function
def generate_data(addr):
return (addr & 0x3FFF)>>2
class TB(Module):
def __init__(self):
c_pci_data_width = 128
num_chnls = 3
self.wordsize = 32
self.ptrsize = 64
combined_interface_tx = riffa.Interface(data_width=c_pci_data_width, num_chnls=num_chnls)
combined_interface_rx = riffa.Interface(data_width=c_pci_data_width, num_chnls=num_chnls)
# instantiate test "memory" module that responds to page fetch/writeback requests
self.submodules.channelsplitter = riffa.ChannelSplitter(combined_interface_tx, combined_interface_rx)
tx0, rx0 = self.channelsplitter.get_channel(0)
tx1, rx1 = self.channelsplitter.get_channel(1)
self.submodules.tbmem = TBMemory(tx0, rx0, tx1, rx1, c_pci_data_width=c_pci_data_width, init_fn=generate_data)
# instantiate design under test
self.submodules.dut = designtemplate.DesignTemplate(combined_interface_rx=combined_interface_rx, combined_interface_tx=combined_interface_tx, c_pci_data_width=c_pci_data_width, wordsize=self.wordsize, ptrsize=self.ptrsize, drive_clocks=False)
# channel to send args / receive results
# remember rx/tx from FPGA side -> write to rx, read from tx
self.tx, self.rx = self.channelsplitter.get_channel(2)
def gen_simulation(self, selfp):
# memory area to work on
baseaddr = ?? ## TODO
size = ?? ## TODO
# function argument to send (as list of 32 bit words)
arg_struct = [baseaddr, size, ??] ## TODO
# expected return value (as list of 32 bit words)
expected_ret = [??] ## TODO
# expected memory modifications (in memory words of size 'wordsize')
expected_results = [??] ## TODO
# send arguments to DUT
yield from riffa.channel_write(selfp.simulator, self.rx, arg_struct)
# wait for return value
ret = yield from riffa.channel_read(selfp.simulator, self.tx)
# check return value
if ret != expected_ret:
## TODO
print("Wrong return value! Expected " + str(expected_ret) + ", received " + str(ret))
# check memory modifications
num_errors = 0
for i in range(size):
# address "i"th word in range
addr = baseaddr + i << log2_int(self.wordsize//8)
# compare to expected
if self.tbmem.read_mem(addr) != expected_results[i]:
num_errors += 1
# print a few errors but not too many
if num_errors <= 10:
print(hex(addr) + ": " + str(self.tbmem.read_mem(addr)) + " (expected " + str(expected_results[i]) + ")")
if num_errors > 10:
print("And " + str(num_errors-10) + " more.")
if __name__ == "__main__":
tb = TB()
run_simulation(tb, vcd_name="tb.vcd", keep_files=True, ncycles=100000)