update HyperRAM module and add unit test
[lambdasoc.git] / lambdasoc / test / test_hyperbus.py
1 # Test of HyperRAM class
2 #
3 # Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
4 # Copyright (c) 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5 # Based on code from Kermarrec, Licensed BSD-2-Clause
6 #
7 # Modifications for the Libre-SOC Project funded by NLnet and NGI POINTER
8 # under EU Grants 871528 and 957073, under the LGPLv3+ License
9
10 import unittest
11
12 from nmigen import (Record, Module, Signal, Elaboratable)
13 from nmigen.compat.sim import run_simulation
14
15 from lambdasoc.periph.hyperram import HyperRAM
16
17 def c2bool(c):
18 return {"-": 1, "_": 0}[c]
19
20
21 def wb_write(bus, addr, data, sel):
22 yield bus.adr.eq(addr)
23 yield bus.dat_w.eq(data)
24 yield bus.sel.eq(sel)
25 yield bus.we.eq(1)
26 yield bus.cyc.eq(1)
27 yield bus.stb.eq(1)
28 yield
29 while not (yield bus.ack):
30 yield
31 yield bus.cyc.eq(0)
32 yield bus.stb.eq(0)
33
34
35 def wb_read(bus, addr, sel):
36 yield bus.adr.eq(addr)
37 yield bus.sel.eq(sel)
38 yield bus.cyc.eq(1)
39 yield bus.stb.eq(1)
40 yield
41 while not (yield bus.ack):
42 yield
43 yield bus.cyc.eq(0)
44 yield bus.stb.eq(0)
45
46 return (yield bus.dat_r)
47
48
49 class Pads: pass
50
51
52 class HyperRamPads:
53 def __init__(self, dw=8):
54 self.clk = Signal()
55 self.cs_n = Signal()
56 self.dq = Record([("oe", 1), ("o", dw), ("i", dw)])
57 self.rwds = Record([("oe", 1), ("o", dw//8), ("i", dw//8)])
58
59
60 class TestHyperRAMPHY(Elaboratable):
61 def __init__(self, pads):
62 self.pads = pads
63 self.clk = pads.clk
64 self.cs = Signal()
65 self.dq_o = pads.dq.o
66 self.dq_i = pads.dq.i
67 self.dq_oe = pads.dq.oe
68 self.rwds_o = pads.rwds.o
69 self.rwds_oe = Signal()
70
71 def elaborate(self, platform):
72 m = Module()
73 m.d.comb += self.pads.cs_n.eq(~self.cs)
74 m.d.comb += self.pads.rwds.oe.eq(self.rwds_oe)
75 return m
76
77
78 class TestHyperBusWrite(unittest.TestCase):
79
80 def test_hyperram_write(self):
81 def fpga_gen(dut):
82 yield from wb_write(dut.bus, 0x1234, 0xdeadbeef, sel=0b1001)
83 yield
84
85 def hyperram_gen(dut):
86 clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
87 cs_n = "--________________________________________________________________------"
88 dq_oe = "__------------____________________________________________--------______"
89 dq_o = "002000048d000000000000000000000000000000000000000000000000deadbeef000000"
90 rwds_oe = "__________________________________________________________--------______"
91 rwds_o = "____________________________________________________________----________"
92
93 #clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
94 #cs_n = "--________________________________________________________________------"
95 #dq_oe = "__------------____________________________________________--------______"
96 #dq_o = "002000048d000000000000000000000000000000000000000000000000deadbeef000000"
97 #rwds_oe = "__________________________________________________________--------______"
98 #rwds_o = "________________________________________________________________________"
99 for i in range(3):
100 yield
101 if False: # useful for printing out expected vs results
102 for i in range(len(clk)):
103 print ("i", i)
104 print ("clk", c2bool(clk[i]), (yield dut.phy.pads.clk))
105 print ("cs_n", c2bool(cs_n[i]), (yield dut.phy.pads.cs_n))
106 print ("dq_oe", c2bool(dq_oe[i]), (yield dut.phy.pads.dq.oe))
107 print ("dq_o", hex(int(dq_o[2*(i//2):2*(i//2)+2], 16)),
108 hex((yield dut.phy.pads.dq.o)))
109 print ("rwds_oe", c2bool(rwds_oe[i]),
110 (yield dut.phy.pads.rwds.oe))
111 print ("rwds_o", c2bool(rwds_o[i]),
112 (yield dut.phy.pads.rwds.o))
113 yield
114 for i in range(len(clk)):
115 self.assertEqual(c2bool(clk[i]), (yield dut.phy.pads.clk))
116 self.assertEqual(c2bool(cs_n[i]), (yield dut.phy.pads.cs_n))
117 self.assertEqual(c2bool(dq_oe[i]), (yield dut.phy.pads.dq.oe))
118 self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16),
119 (yield dut.phy.pads.dq.o))
120 self.assertEqual(c2bool(rwds_oe[i]),
121 (yield dut.phy.pads.rwds.oe))
122 self.assertEqual(c2bool(rwds_o[i]),
123 (yield dut.phy.pads.rwds.o))
124 yield
125
126 dut = HyperRAM(io=HyperRamPads(), phy_kls=TestHyperRAMPHY)
127 run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)],
128 vcd_name="sim.vcd")
129
130 def test_hyperram_read(self):
131 def fpga_gen(dut):
132 dat = yield from wb_read(dut.bus, 0x1234, 0b1111)
133 self.assertEqual(dat, 0xdeadbeef)
134 dat = yield from wb_read(dut.bus, 0x1235, 0b1111)
135 self.assertEqual(dat, 0xcafefade)
136
137 def hyperram_gen(dut):
138 clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_"
139 cs_n = "--________________________________________________________________________________"
140 dq_oe = "__------------____________________________________________________________________"
141 dq_o = "00a000048d000000000000000000000000000000000000000000000000000000000000000000000000"
142 dq_i = "0000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
143 rwds_oe = "__________________________________________________________________________________"
144
145 for i in range(3):
146 print ("prep", i)
147 yield
148 for i in range(len(clk)):
149 print ("i", i)
150 yield dut.phy.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
151 print ("clk", c2bool(clk[i]), (yield dut.phy.pads.clk))
152 print ("cs_n", c2bool(cs_n[i]), (yield dut.phy.pads.cs_n))
153 yield
154 continue
155 self.assertEqual(c2bool(clk[i]), (yield dut.phy.pads.clk))
156 self.assertEqual(c2bool(cs_n[i]), (yield dut.phy.pads.cs_n))
157 self.assertEqual(c2bool(dq_oe[i]), (yield dut.phy.pads.dq.oe))
158 self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16),
159 (yield dut.phy.pads.dq.o))
160 self.assertEqual(c2bool(rwds_oe[i]),
161 (yield dut.phy.pads.rwds.oe))
162 yield
163
164 dut = HyperRAM(io=HyperRamPads(), phy_kls=TestHyperRAMPHY)
165 run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)],
166 vcd_name="rd_sim.vcd")
167
168 class TestHyperBusRead(unittest.TestCase):
169 def test_hyperram_read(self):
170 def fpga_gen(dut):
171 dat = yield from wb_read(dut.bus, 0x1234, 0b1111)
172 self.assertEqual(dat, 0xdeadbeef)
173 dat = yield from wb_read(dut.bus, 0x1235, 0b1111)
174 self.assertEqual(dat, 0xcafefade)
175 yield
176 yield
177 yield
178 yield
179 yield
180
181 def hyperram_gen(dut):
182 clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_"
183 cs_n = "--________________________________________________________________________________"
184 dq_oe = "__------------____________________________________________________________________"
185 dq_o = "00a000048d000000000000000000000000000000000000000000000000000000000000000000000000"
186 dq_i = "0000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
187 rwds_oe = "__________________________________________________________________________________"
188
189 for i in range(3):
190 print ("prep", i)
191 yield
192 for i in range(len(clk)):
193 print ("i", i)
194 yield dut.phy.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
195 print ("clk", c2bool(clk[i]), (yield dut.phy.pads.clk))
196 print ("cs_n", c2bool(cs_n[i]), (yield dut.phy.pads.cs_n))
197 print ("dq_oe", c2bool(dq_oe[i]), (yield dut.phy.pads.dq.oe))
198 print ("dq_o", hex(int(dq_o[2*(i//2):2*(i//2)+2], 16)),
199 hex((yield dut.phy.pads.dq.o)))
200 print ("rwds_oe", c2bool(rwds_oe[i]),
201 (yield dut.phy.pads.rwds.oe))
202 self.assertEqual(c2bool(clk[i]), (yield dut.phy.pads.clk))
203 self.assertEqual(c2bool(cs_n[i]), (yield dut.phy.pads.cs_n))
204 self.assertEqual(c2bool(dq_oe[i]), (yield dut.phy.pads.dq.oe))
205 self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16),
206 (yield dut.phy.pads.dq.o))
207 self.assertEqual(c2bool(rwds_oe[i]),
208 (yield dut.phy.pads.rwds.oe))
209 yield
210
211 dut = HyperRAM(io=HyperRamPads(), phy_kls=TestHyperRAMPHY)
212 run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)],
213 vcd_name="rd_sim.vcd")
214
215 if __name__ == '__main__':
216 unittest.main()
217 #t = TestHyperBusRead()
218 #t.test_hyperram_read()
219 #t = TestHyperBusWrite()
220 #t.test_hyperram_write()