forked from quartiq/urukul
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathurukul_sim.py
122 lines (104 loc) · 3.46 KB
/
urukul_sim.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from collections import namedtuple
from migen import *
from migen.fhdl.specials import Tristate
from migen.build.generic_platform import ConstraintError
from urukul import Urukul
from urukul_cpld import Platform
class SimTristate:
@staticmethod
def lower(dr):
return SimTristateImpl(dr.i, dr.o, dr.oe, dr.target)
class SimTristateImpl(Module):
def __init__(self, i, o, oe, target):
self.i = i
self.o = o
self.oe = oe
self.target = target
self.comb += [
# If(oe, target.eq(o)),
# i.eq(Mux(oe, o, target))
i.eq(target)
]
class SimInstance:
@staticmethod
def lower(dr):
return Module()
class TB(Module):
def __init__(self, platform, dut):
self.platform = platform
self.submodules.dut = dut
for k in "tp dds dds_common dds_sync clk ifc_mode att eem".split():
v = []
while True:
try:
v.append(platform.lookup_request(k, len(v)))
except ConstraintError:
break
if len(v) == 1:
v = v[0]
setattr(self, k, v)
self.cs = Signal(3)
self.comb += [
Cat(self.eem[3].io, self.eem[4].io, self.eem[5].io).eq(
self.cs)
]
def spi(self, cs, n, mosi):
# while (yield self.dut.cd_sck0.clk):
# pass
yield self.cs.eq(cs)
miso = 0
for i in range(n - 1, -1, -1):
yield self.eem[1].io.eq((mosi >> i) & 1)
yield self.eem[0].io.eq(0)
yield
yield self.eem[0].io.eq(1)
# miso = (miso << 1) | (yield self.eem[2].io)
miso = (miso << 1) | (yield self.dut.eem[2].o)
yield
yield self.eem[0].io.eq(0)
yield
yield self.cs.eq(0)
yield
yield
yield
return miso
def test(self):
p = self.platform
dut = self.dut
yield self.ifc_mode[0].eq(1) # en_9910
yield self.ifc_mode[1].eq(0) # en_nu
yield self.ifc_mode[2].eq(1) # en_eemb
yield self.eem[12].io.eq(1) # rf_sw[0]
yield self.dds[1].smp_err.eq(1)
yield self.dds[0].pll_lock.eq(1)
yield
yield from self.spi(1, 24, 0x123456)
for i in range(4):
sw = yield self.dds[i].rf_sw
assert sw == ((0x6 | 1) >> i) & 1, (i, sw)
led = yield self.dds[i].led[1]
assert led == ((0x5 | 0xe | 0x2) >> i) & 1, (i, led)
profile = yield self.dds_common.profile
assert profile == 0x4
att_le = yield self.att.le
assert att_le == 0
ret = yield from self.spi(1, 24, 0x123456)
assert ret & 0xf == 1, hex(ret)
assert ret & 0xff0000 == 0x050000
ret = yield from self.spi(1, 24, 0x123456)
assert ret & 0xf == 0x6 | 1, hex(ret)
assert ret & 0xff0000 == 0x050000
yield from self.spi(2, 32, 0xf0f0f0f0) # ATT
yield from self.spi(4, 16, 0x1234)
yield from self.spi(3, 8 + 64, 0x12345678abcdef0123)
yield
def main():
p = Platform()
dut = Urukul(p)
tb = TB(p, dut)
run_simulation(tb, [tb.test()], vcd_name="urukul.vcd",
# just operate on sck0
clocks={"sys": 8, "sck1": (16, 4), "sck0": (16, 12)},
special_overrides={Tristate: SimTristate, Instance: SimInstance})
if __name__ == "__main__":
main()