2022-03-01 02:59:00 -05:00
|
|
|
#
|
|
|
|
# This file is part of LiteHyperBus
|
|
|
|
#
|
|
|
|
# Copyright (c) 2019-2022 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
from migen import *
|
|
|
|
|
|
|
|
from litex.soc.cores.hyperbus import HyperRAM
|
|
|
|
|
|
|
|
def c2bool(c):
|
|
|
|
return {"-": 1, "_": 0}[c]
|
|
|
|
|
|
|
|
|
|
|
|
class Pads: pass
|
|
|
|
|
|
|
|
|
|
|
|
class HyperRamPads:
|
|
|
|
def __init__(self, dw=8):
|
|
|
|
self.clk = Signal()
|
|
|
|
self.cs_n = Signal()
|
|
|
|
self.dq = Record([("oe", 1), ("o", dw), ("i", dw)])
|
|
|
|
self.rwds = Record([("oe", 1), ("o", dw//8), ("i", dw//8)])
|
|
|
|
|
|
|
|
|
|
|
|
class TestHyperBus(unittest.TestCase):
|
|
|
|
def test_hyperram_syntax(self):
|
|
|
|
pads = Record([("clk", 1), ("cs_n", 1), ("dq", 8), ("rwds", 1)])
|
|
|
|
hyperram = HyperRAM(pads)
|
|
|
|
|
|
|
|
pads = Record([("clk_p", 1), ("clk_n", 1), ("cs_n", 1), ("dq", 8), ("rwds", 1)])
|
|
|
|
hyperram = HyperRAM(pads)
|
|
|
|
|
2024-04-15 04:32:13 -04:00
|
|
|
def test_hyperram_write_latency_5_2x(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
yield from dut.bus.write(0x1234, 0xdeadbeef, sel=0b1001)
|
|
|
|
yield
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
|
|
|
|
cs_n = "--________________________________________________________------"
|
|
|
|
dq_oe = "__------------____________________________________--------______"
|
|
|
|
dq_o = "002000048d0000000000000000000000000000000000000000deadbeef000000"
|
|
|
|
rwds_oe = "__________________________________________________--------______"
|
|
|
|
rwds_o = "____________________________________________________----________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), latency=5)
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
|
|
|
|
|
|
|
def test_hyperram_write_latency_6_2x(self):
|
2022-03-01 02:59:00 -05:00
|
|
|
def fpga_gen(dut):
|
|
|
|
yield from dut.bus.write(0x1234, 0xdeadbeef, sel=0b1001)
|
|
|
|
yield
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
|
|
|
|
cs_n = "--________________________________________________________________------"
|
|
|
|
dq_oe = "__------------____________________________________________--------______"
|
|
|
|
dq_o = "002000048d000000000000000000000000000000000000000000000000deadbeef000000"
|
|
|
|
rwds_oe = "__________________________________________________________--------______"
|
|
|
|
rwds_o = "____________________________________________________________----________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
|
|
|
|
yield
|
|
|
|
|
2024-04-15 04:32:13 -04:00
|
|
|
dut = HyperRAM(HyperRamPads(), latency=6)
|
2022-03-01 02:59:00 -05:00
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
|
|
|
|
2024-04-15 04:32:13 -04:00
|
|
|
def test_hyperram_write_latency_7_2x(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
yield from dut.bus.write(0x1234, 0xdeadbeef, sel=0b1001)
|
|
|
|
yield
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
|
|
|
|
cs_n = "--________________________________________________________________________------"
|
|
|
|
dq_oe = "__------------____________________________________________________--------______"
|
|
|
|
dq_o = "002000048d00000000000000000000000000000000000000000000000000000000deadbeef000000"
|
|
|
|
rwds_oe = "__________________________________________________________________--------______"
|
|
|
|
rwds_o = "____________________________________________________________________----________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), latency=7)
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
|
|
|
|
|
|
|
def test_hyperram_write_latency_7_1x(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
yield from dut.bus.write(0x1234, 0xdeadbeef, sel=0b1001)
|
|
|
|
yield
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--_______"
|
|
|
|
cs_n = "--____________________________________________------"
|
|
|
|
dq_oe = "__------------________________________--------______"
|
|
|
|
dq_o = "002000048d0000000000000000000000000000deadbeef000000"
|
|
|
|
rwds_oe = "______________________________________--------______"
|
|
|
|
rwds_o = "________________________________________----________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), latency=7, latency_mode="variable")
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
|
|
|
|
|
|
|
def test_hyperram_read_latency_5_2x(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
dat = yield from dut.bus.read(0x1234)
|
|
|
|
self.assertEqual(dat, 0xdeadbeef)
|
|
|
|
dat = yield from dut.bus.read(0x1235)
|
|
|
|
self.assertEqual(dat, 0xcafefade)
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_"
|
|
|
|
cs_n = "--________________________________________________________________________"
|
|
|
|
dq_oe = "__------------____________________________________________________________"
|
|
|
|
dq_o = "00a000048d0000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
dq_i = "00000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
|
|
|
|
rwds_oe = "__________________________________________________________________________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), latency=5)
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
|
|
|
|
|
|
|
def test_hyperram_read_latency_6_2x(self):
|
2022-03-01 02:59:00 -05:00
|
|
|
def fpga_gen(dut):
|
|
|
|
dat = yield from dut.bus.read(0x1234)
|
|
|
|
self.assertEqual(dat, 0xdeadbeef)
|
|
|
|
dat = yield from dut.bus.read(0x1235)
|
|
|
|
self.assertEqual(dat, 0xcafefade)
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_"
|
|
|
|
cs_n = "--________________________________________________________________________________"
|
|
|
|
dq_oe = "__------------____________________________________________________________________"
|
|
|
|
dq_o = "00a000048d000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
dq_i = "0000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
|
|
|
|
rwds_oe = "__________________________________________________________________________________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
yield
|
|
|
|
|
2024-04-15 04:32:13 -04:00
|
|
|
dut = HyperRAM(HyperRamPads(), latency=6)
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
|
|
|
|
|
|
|
def test_hyperram_read_latency_7_2x(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
dat = yield from dut.bus.read(0x1234)
|
|
|
|
self.assertEqual(dat, 0xdeadbeef)
|
|
|
|
dat = yield from dut.bus.read(0x1235)
|
|
|
|
self.assertEqual(dat, 0xcafefade)
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_"
|
|
|
|
cs_n = "--________________________________________________________________________________________"
|
|
|
|
dq_oe = "__------------____________________________________________________________________________"
|
|
|
|
dq_o = "00a000048d00000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
dq_i = "000000000000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
|
|
|
|
rwds_oe = "__________________________________________________________________________________________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), latency=7)
|
2022-03-01 02:59:00 -05:00
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
2024-04-12 09:21:57 -04:00
|
|
|
|
2024-04-15 04:32:13 -04:00
|
|
|
def test_hyperram_read_latency_7_1x(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
dat = yield from dut.bus.read(0x1234)
|
|
|
|
self.assertEqual(dat, 0xdeadbeef)
|
|
|
|
dat = yield from dut.bus.read(0x1235)
|
|
|
|
self.assertEqual(dat, 0xcafefade)
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_"
|
|
|
|
cs_n = "--____________________________________________________________"
|
|
|
|
dq_oe = "__------------________________________________________________"
|
|
|
|
dq_o = "00a000048d0000000000000000000000000000000000000000000000000000"
|
|
|
|
dq_i = "00000000000000000000000000000000000000deadbeefcafefade00000000"
|
|
|
|
rwds_oe = "______________________________________________________________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), latency=7, latency_mode="variable")
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|
2024-04-12 09:21:57 -04:00
|
|
|
|
|
|
|
def test_hyperram_reg_write(self):
|
|
|
|
def fpga_gen(dut):
|
|
|
|
yield dut.reg_addr.eq(2)
|
|
|
|
yield dut.reg_write_data.eq(0x1234)
|
|
|
|
yield
|
|
|
|
yield dut.reg_write.eq(1)
|
|
|
|
yield
|
|
|
|
yield dut.reg_write.eq(0)
|
|
|
|
for i in range(128):
|
|
|
|
yield
|
|
|
|
|
|
|
|
def hyperram_gen(dut):
|
|
|
|
clk = "___--__--__--__--___________"
|
|
|
|
cs_n = "--________________----------"
|
|
|
|
dq_oe = "__----------------__________"
|
2024-04-12 10:06:26 -04:00
|
|
|
dq_o = "0060000100000012340000000000"
|
2024-04-12 09:21:57 -04:00
|
|
|
rwds_oe = "____________________________"
|
|
|
|
rwds_o = "____________________________"
|
|
|
|
for i in range(3):
|
|
|
|
yield
|
|
|
|
for i in range(len(clk)):
|
|
|
|
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
|
|
|
|
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
|
|
|
|
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
|
|
|
|
self.assertEqual(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
|
|
|
|
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
|
|
|
|
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
|
|
|
|
yield
|
|
|
|
|
|
|
|
dut = HyperRAM(HyperRamPads(), with_csr=False)
|
|
|
|
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
|