6e7462418fab40a3910b302cc07316eaf8c24ea9
[litex.git] / liteeth / test / mac_wishbone_tb.py
1 from migen.fhdl.std import *
2 from migen.bus import wishbone
3 from migen.bus.transactions import *
4 from migen.sim.generic import run_simulation
5
6 from liteeth.common import *
7 from liteeth.mac import LiteEthMAC
8
9 from liteeth.test.common import *
10 from liteeth.test.model import phy, mac
11
12 class WishboneMaster:
13 def __init__(self, obj):
14 self.obj = obj
15 self.dat = 0
16
17 def write(self, adr, dat):
18 self.obj.cyc = 1
19 self.obj.stb = 1
20 self.obj.adr = adr
21 self.obj.we = 1
22 self.obj.sel = 0xF
23 self.obj.dat_w = dat
24 while self.obj.ack == 0:
25 yield
26 self.obj.cyc = 0
27 self.obj.stb = 0
28 yield
29
30 def read(self, adr):
31 self.obj.cyc = 1
32 self.obj.stb = 1
33 self.obj.adr = adr
34 self.obj.we = 0
35 self.obj.sel = 0xF
36 self.obj.dat_w = 0
37 while self.obj.ack == 0:
38 yield
39 self.dat = self.obj.dat_r
40 self.obj.cyc = 0
41 self.obj.stb = 0
42 yield
43
44 class SRAMReaderDriver:
45 def __init__(self, obj):
46 self.obj = obj
47
48 def start(self, slot, length):
49 self.obj._slot.storage = slot
50 self.obj._length.storage = length
51 self.obj._start.re = 1
52 yield
53 self.obj._start.re = 0
54 yield
55
56 def wait_done(self):
57 while self.obj.ev.done.pending == 0:
58 yield
59
60 def clear_done(self):
61 self.obj.ev.done.clear = 1
62 yield
63 self.obj.ev.done.clear = 0
64 yield
65
66 class SRAMWriterDriver:
67 def __init__(self, obj):
68 self.obj = obj
69
70 def wait_available(self):
71 while self.obj.ev.available.pending == 0:
72 yield
73
74 def clear_available(self):
75 self.obj.ev.available.clear = 1
76 yield
77 self.obj.ev.available.clear = 0
78 yield
79
80 class TB(Module):
81 def __init__(self):
82 self.submodules.phy_model = phy.PHY(8, debug=False)
83 self.submodules.mac_model = mac.MAC(self.phy_model, debug=False, loopback=True)
84 self.submodules.ethmac = LiteEthMAC(phy=self.phy_model, dw=32, interface="wishbone", with_hw_preamble_crc=True)
85
86 # use sys_clk for each clock_domain
87 self.clock_domains.cd_eth_rx = ClockDomain()
88 self.clock_domains.cd_eth_tx = ClockDomain()
89 self.comb += [
90 self.cd_eth_rx.clk.eq(ClockSignal()),
91 self.cd_eth_rx.rst.eq(ResetSignal()),
92 self.cd_eth_tx.clk.eq(ClockSignal()),
93 self.cd_eth_tx.rst.eq(ResetSignal()),
94 ]
95
96 def gen_simulation(self, selfp):
97 selfp.cd_eth_rx.rst = 1
98 selfp.cd_eth_tx.rst = 1
99 yield
100 selfp.cd_eth_rx.rst = 0
101 selfp.cd_eth_tx.rst = 0
102
103 wishbone_master = WishboneMaster(selfp.ethmac.bus)
104 sram_reader_driver = SRAMReaderDriver(selfp.ethmac.interface.sram.reader)
105 sram_writer_driver = SRAMWriterDriver(selfp.ethmac.interface.sram.writer)
106
107 sram_writer_slots_offset = [0x000, 0x200]
108 sram_reader_slots_offset = [0x400, 0x600]
109
110 length = 150+2
111
112 tx_payload = [seed_to_data(i, True) % 0xFF for i in range(length)] + [0, 0, 0, 0]
113
114 errors = 0
115
116 while True:
117 for slot in range(2):
118 print("slot {}:".format(slot))
119 # fill tx memory
120 for i in range(length//4+1):
121 dat = int.from_bytes(tx_payload[4*i:4*(i+1)], "big")
122 yield from wishbone_master.write(sram_reader_slots_offset[slot]+i, dat)
123
124 # send tx payload & wait
125 yield from sram_reader_driver.start(slot, length)
126 yield from sram_reader_driver.wait_done()
127 yield from sram_reader_driver.clear_done()
128
129 # wait rx
130 yield from sram_writer_driver.wait_available()
131 yield from sram_writer_driver.clear_available()
132
133 # get rx payload (loopback on PHY Model)
134 rx_payload = []
135 for i in range(length//4+1):
136 yield from wishbone_master.read(sram_writer_slots_offset[slot]+i)
137 dat = wishbone_master.dat
138 rx_payload += list(dat.to_bytes(4, byteorder='big'))
139
140 # check results
141 s, l, e = check(tx_payload[:length], rx_payload[:min(length, len(rx_payload))])
142 print("shift "+ str(s) + " / length " + str(l) + " / errors " + str(e))
143
144 if __name__ == "__main__":
145 run_simulation(TB(), ncycles=3000, vcd_name="my.vcd", keep_files=True)