soc/cores/hyperbus: Full rewrite of HyperRAM core.

Rewriting the HyperRAM core to improve its design and functionality. The
old core grew complex over time without a clear structure. This new version
offers:
- IO registers on all signals for better performance.
- Flexible clocking options.
- Simplified architecture.
- Easier to extend with new features.

This rewrite provides a base for future development.
This commit is contained in:
Florent Kermarrec 2024-08-26 11:24:16 +02:00
parent ef775e0b8e
commit fac80c3a51
4 changed files with 797 additions and 510 deletions

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ static void hyperram_write_reg(uint16_t reg_addr, uint16_t data) {
reg_addr << CSR_HYPERRAM_REG_CONTROL_ADDR_OFFSET reg_addr << CSR_HYPERRAM_REG_CONTROL_ADDR_OFFSET
); );
/* Wait for write to complete */ /* Wait for write to complete */
while ((hyperram_reg_status_read() & (1 << CSR_HYPERRAM_REG_STATUS_WRITE_DONE_OFFSET)) == 0); while ((hyperram_reg_status_read() & (1 << CSR_HYPERRAM_REG_STATUS_DONE_OFFSET)) == 0);
} }
static uint16_t hyperram_read_reg(uint16_t reg_addr) { static uint16_t hyperram_read_reg(uint16_t reg_addr) {
@ -29,7 +29,7 @@ static uint16_t hyperram_read_reg(uint16_t reg_addr) {
reg_addr << CSR_HYPERRAM_REG_CONTROL_ADDR_OFFSET reg_addr << CSR_HYPERRAM_REG_CONTROL_ADDR_OFFSET
); );
/* Wait for read to complete */ /* Wait for read to complete */
while ((hyperram_reg_status_read() & (1 << CSR_HYPERRAM_REG_STATUS_READ_DONE_OFFSET)) == 0); while ((hyperram_reg_status_read() & (1 << CSR_HYPERRAM_REG_STATUS_DONE_OFFSET)) == 0);
return hyperram_reg_rdata_read(); return hyperram_reg_rdata_read();
} }
@ -55,42 +55,60 @@ static uint16_t hyperram_get_chip_latency_setting(uint32_t clk_freq) {
return 0b0010; /* Default to highest latency for safety */ return 0b0010; /* Default to highest latency for safety */
} }
static void hyperram_configure_latency(void) { void hyperram_init(void) {
uint16_t config_reg_0 = 0x8f2f; uint16_t config_reg_0;
uint8_t core_clk_ratio; uint8_t core_clk_ratio;
uint8_t core_latency_mode;
uint16_t core_latency_setting; uint16_t core_latency_setting;
uint16_t chip_latency_setting; uint16_t chip_latency_setting;
/* Compute Latency settings */ printf("HyperRAM init...\n");
core_clk_ratio = (hyperram_status_read() >> CSR_HYPERRAM_STATUS_CLK_RATIO_OFFSET & 0xf);
printf("HyperRAM Clk Ratio %d:1.\n", core_clk_ratio);
core_latency_setting = hyperram_get_core_latency_setting(CONFIG_CLOCK_FREQUENCY/core_clk_ratio);
chip_latency_setting = hyperram_get_chip_latency_setting(CONFIG_CLOCK_FREQUENCY/core_clk_ratio);
/* Write Latency to HyperRAM Core */ /* Compute Latency settings */
printf("HyperRAM Core Latency: %d CK (X1).\n", core_latency_setting); core_clk_ratio = (hyperram_status_read() >> CSR_HYPERRAM_STATUS_CLK_RATIO_OFFSET) & 0xf;
printf("HyperRAM Clk Ratio %d:1\n", core_clk_ratio);
core_latency_setting = hyperram_get_core_latency_setting(CONFIG_CLOCK_FREQUENCY / core_clk_ratio);
chip_latency_setting = hyperram_get_chip_latency_setting(CONFIG_CLOCK_FREQUENCY / core_clk_ratio);
/* Configure Latency on HyperRAM Core */
core_latency_mode = (hyperram_status_read() >> CSR_HYPERRAM_STATUS_LATENCY_MODE_OFFSET) & 0b1;
printf("HyperRAM %s Latency: %d CK (X1)\n", (core_latency_mode == 0) ? "Fixed" : "Variable", core_latency_setting);
hyperram_config_write(core_latency_setting << CSR_HYPERRAM_CONFIG_LATENCY_OFFSET); hyperram_config_write(core_latency_setting << CSR_HYPERRAM_CONFIG_LATENCY_OFFSET);
/* Configure HyperRAM Chip */
config_reg_0 = (
/* Burst Length */
(HYPERRAM_CONFIG_0_REG_BL_32_BYTES << HYPERRAM_CONFIG_0_REG_BL_OFFSET) |
/* Hybrid Burst Enable */
(HYPERRAM_CONFIG_0_REG_HBE_LEGACY << HYPERRAM_CONFIG_0_REG_HBE_OFFSET) |
/* Initial Latency */
(chip_latency_setting << HYPERRAM_CONFIG_0_REG_IL_OFFSET) |
/* Fixed Latency Enable */
(HYPERRAM_CONFIG_0_REG_FLE_ENABLED << HYPERRAM_CONFIG_0_REG_FLE_OFFSET) |
/* Reserved Bits (Set to 1 for future compatibility) */
(0b1111 << HYPERRAM_CONFIG_0_REG_RSD_OFFSET) |
/* Drive Strength */
(HYPERRAM_CONFIG_0_REG_DS_19_OHM << HYPERRAM_CONFIG_0_REG_DS_OFFSET) |
/* Deep Power Down: Normal operation */
(HYPERRAM_CONFIG_0_REG_DPD_DISABLED << HYPERRAM_CONFIG_0_REG_DPD_OFFSET)
);
/* Enable Variable Latency on HyperRAM Chip */ /* Enable Variable Latency on HyperRAM Chip */
if (hyperram_status_read() & 0x1) if (hyperram_status_read() & 0x1) {
config_reg_0 &= ~(0b1 << 3); /* Enable Variable Latency */ config_reg_0 &= ~(1 << HYPERRAM_CONFIG_0_REG_FLE_OFFSET);
config_reg_0 |= (HYPERRAM_CONFIG_0_REG_FLE_DISABLED << HYPERRAM_CONFIG_0_REG_FLE_OFFSET);
}
hyperram_write_reg(HYPERRAM_CONFIG_0_REG, config_reg_0);
/* Update Latency on HyperRAM Chip */ /* Read current configuration to verify changes */
config_reg_0 &= ~(0b1111 << 4); config_reg_0 = hyperram_read_reg(HYPERRAM_CONFIG_0_REG);
config_reg_0 |= chip_latency_setting << 4; printf("HyperRAM Configuration Register 0: %04x\n", config_reg_0);
printf("\n");
/* Write Configuration Register 0 to HyperRAM Chip */
hyperram_write_reg(2, config_reg_0);
/* Read current configuration */
config_reg_0 = hyperram_read_reg(2);
printf("HyperRAM Configuration Register 0: %08x\n", config_reg_0);
}
void hyperram_init(void) {
printf("HyperRAM init...\n");
hyperram_configure_latency();
printf("\n");
} }
#endif #endif

View File

@ -8,6 +8,57 @@
extern "C" { extern "C" {
#endif #endif
/* HyperRAM Registers */
#define HYPERRAM_ID_0_REG 0x0 /* Identification Register 0 */
#define HYPERRAM_ID_1_REG 0x1 /* Identification Register 1 */
#define HYPERRAM_CONFIG_0_REG 0x2 /* Configuration Register 0 */
#define HYPERRAM_CONFIG_1_REG 0x3 /* Configuration Register 1 */
/* Configuration Register 0 Field Offsets */
#define HYPERRAM_CONFIG_0_REG_BL_OFFSET 0 /* Burst Length */
#define HYPERRAM_CONFIG_0_REG_HBE_OFFSET 2 /* Hybrid Burst Enable */
#define HYPERRAM_CONFIG_0_REG_FLE_OFFSET 3 /* Fixed Latency Enable */
#define HYPERRAM_CONFIG_0_REG_IL_OFFSET 4 /* Initial Latency */
#define HYPERRAM_CONFIG_0_REG_RSD_OFFSET 8 /* Reserved bits */
#define HYPERRAM_CONFIG_0_REG_DS_OFFSET 12 /* Drive Strength */
#define HYPERRAM_CONFIG_0_REG_DPD_OFFSET 15 /* Deep Power Down */
/* Configuration Register 0 Field Values */
/* Burst Length */
#define HYPERRAM_CONFIG_0_REG_BL_128_BYTES 0b00
#define HYPERRAM_CONFIG_0_REG_BL_64_BYTES 0b01
#define HYPERRAM_CONFIG_0_REG_BL_16_BYTES 0b10
#define HYPERRAM_CONFIG_0_REG_BL_32_BYTES 0b11
/* Hybrid Burst Enable */
#define HYPERRAM_CONFIG_0_REG_HBE_WRAPPED 0b0
#define HYPERRAM_CONFIG_0_REG_HBE_LEGACY 0b1
/* Fixed Latency Enable */
#define HYPERRAM_CONFIG_0_REG_FLE_DISABLED 0b0
#define HYPERRAM_CONFIG_0_REG_FLE_ENABLED 0b1
/* Initial Latency */
#define HYPERRAM_CONFIG_0_REG_IL_3_CLOCKS 0b1110
#define HYPERRAM_CONFIG_0_REG_IL_4_CLOCKS 0b1111
#define HYPERRAM_CONFIG_0_REG_IL_5_CLOCKS 0b0000
#define HYPERRAM_CONFIG_0_REG_IL_6_CLOCKS 0b0001
#define HYPERRAM_CONFIG_0_REG_IL_7_CLOCKS 0b0010
/* Drive Strength */
#define HYPERRAM_CONFIG_0_REG_DS_34_OHM 0b000
#define HYPERRAM_CONFIG_0_REG_DS_115_OHM 0b001
#define HYPERRAM_CONFIG_0_REG_DS_67_OHM 0b010
#define HYPERRAM_CONFIG_0_REG_DS_46_OHM 0b011
#define HYPERRAM_CONFIG_0_REG_DS_27_OHM 0b101
#define HYPERRAM_CONFIG_0_REG_DS_22_OHM 0b110
#define HYPERRAM_CONFIG_0_REG_DS_19_OHM 0b111
/* Deep Power Down */
#define HYPERRAM_CONFIG_0_REG_DPD_DISABLED 0b1
#define HYPERRAM_CONFIG_0_REG_DPD_ENABLED 0b0
void hyperram_init(void); void hyperram_init(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,7 +1,8 @@
# #
# This file is part of LiteHyperBus # This file is part of LiteX
# #
# Copyright (c) 2019-2022 Florent Kermarrec <florent@enjoy-digital.fr> # Copyright (c) 2019-2024 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2024 MoTeC <www.motec.com.au>
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
import unittest import unittest
@ -16,21 +17,20 @@ def c2bool(c):
class Pads: pass class Pads: pass
class HyperRamPads: class HyperRamPads:
def __init__(self, dw=8): def __init__(self, dw=8):
self.clk = Signal() self.clk = Signal()
self.cs_n = Signal() self.rst_n = Signal()
self.dq = Record([("oe", 1), ("o", dw), ("i", dw)]) self.cs_n = Signal()
self.rwds = Record([("oe", 1), ("o", dw//8), ("i", dw//8)]) self.dq = Record([("oe", 1), ("o", dw), ("i", dw)])
self.rwds = Record([("oe", 1), ("o", dw//8), ("i", dw//8)])
class TestHyperRAM(unittest.TestCase):
class TestHyperBus(unittest.TestCase):
def test_hyperram_syntax(self): def test_hyperram_syntax(self):
pads = Record([("clk", 1), ("cs_n", 1), ("dq", 8), ("rwds", 1)]) pads = Record([("clk", 1), ("rst_n", 1), ("cs_n", 1), ("dq", 8), ("rwds", 1)])
hyperram = HyperRAM(pads) hyperram = HyperRAM(pads)
pads = Record([("clk_p", 1), ("clk_n", 1), ("cs_n", 1), ("dq", 8), ("rwds", 1)]) pads = Record([("clk_p", 1), ("clk_n", 1), ("rst_n", 1), ("cs_n", 1), ("dq", 8), ("rwds", 1)])
hyperram = HyperRAM(pads) hyperram = HyperRAM(pads)
def test_hyperram_write_latency_5_2x(self): def test_hyperram_write_latency_5_2x(self):
@ -39,15 +39,16 @@ class TestHyperBus(unittest.TestCase):
yield yield
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--_______" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
cs_n = "--________________________________________________________------" cs_n = "----__________________________________________________________------"
dq_oe = "__------------____________________________________--------______" dq_oe = "______------------____________________________________--------______"
dq_o = "002000048d0000000000000000000000000000000000000000deadbeef000000" dq_o = "0000002000048d0000000000000000000000000000000000000000deadbeef000000"
rwds_oe = "__________________________________________________--------______" rwds_oe = "______________________________________________________--------______"
rwds_o = "____________________________________________________----________" rwds_o = "________________________________________________________----________"
yield
for i in range(len(clk)): for i in range(len(clk)):
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe)) self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
if (yield dut.pads.dq.oe): if (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(int(dq_o[2*(i//2):2*(i//2)+2], 16), (yield dut.pads.dq.o))
@ -55,7 +56,7 @@ class TestHyperBus(unittest.TestCase):
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o)) self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
yield yield
dut = HyperRAM(HyperRamPads(), latency=5, latency_mode="fixed") dut = HyperRAM(HyperRamPads(dw=8), latency=5, latency_mode="fixed")
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd") run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")
def test_hyperram_write_latency_5_2x_sys2x(self): def test_hyperram_write_latency_5_2x_sys2x(self):
@ -64,12 +65,12 @@ class TestHyperBus(unittest.TestCase):
yield yield
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "____--__--__--__--__--__--__--__--__--__--__--__--__--__--_______" clk = "________________--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
cs_n = "--________________________________________________________-------" cs_n = "_------------__________________________________________________________------"
dq_oe = "___------------____________________________________--------______" dq_oe = "_______________------------____________________________________--------______"
dq_o = "0002000048d0000000000000000000000000000000000000000deadbeef000000" dq_o = "0000000000000002000048d0000000000000000000000000000000000000000deadbeef000000"
rwds_oe = "___________________________________________________--------______" rwds_oe = "_______________________________________________________________--------______"
rwds_o = "_____________________________________________________----________" rwds_o = "_________________________________________________________________----________"
for i in range(len(clk)): for i in range(len(clk)):
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
@ -79,6 +80,8 @@ class TestHyperBus(unittest.TestCase):
self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe)) self.assertEqual(c2bool(rwds_oe[i]), (yield dut.pads.rwds.oe))
self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o)) self.assertEqual(c2bool(rwds_o[i]), (yield dut.pads.rwds.o))
yield yield
for i in range(128):
yield
dut = HyperRAM(HyperRamPads(), latency=5, latency_mode="fixed", clk_ratio="2:1") dut = HyperRAM(HyperRamPads(), latency=5, latency_mode="fixed", clk_ratio="2:1")
generators = { generators = {
@ -97,12 +100,13 @@ class TestHyperBus(unittest.TestCase):
yield yield
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
cs_n = "--________________________________________________________________------" cs_n = "----__________________________________________________________________------"
dq_oe = "__------------____________________________________________--------______" dq_oe = "______------------____________________________________________--------______"
dq_o = "002000048d000000000000000000000000000000000000000000000000deadbeef000000" dq_o = "0000002000048d000000000000000000000000000000000000000000000000deadbeef000000"
rwds_oe = "__________________________________________________________--------______" rwds_oe = "______________________________________________________________--------______"
rwds_o = "____________________________________________________________----________" rwds_o = "________________________________________________________________----________"
yield
for i in range(len(clk)): for i in range(len(clk)):
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
@ -122,12 +126,13 @@ class TestHyperBus(unittest.TestCase):
yield yield
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_______"
cs_n = "--________________________________________________________________________------" cs_n = "----__________________________________________________________________________------"
dq_oe = "__------------____________________________________________________--------______" dq_oe = "______------------____________________________________________________--------______"
dq_o = "002000048d00000000000000000000000000000000000000000000000000000000deadbeef000000" dq_o = "0000002000048d00000000000000000000000000000000000000000000000000000000deadbeef000000"
rwds_oe = "__________________________________________________________________--------______" rwds_oe = "______________________________________________________________________--------______"
rwds_o = "____________________________________________________________________----________" rwds_o = "________________________________________________________________________----________"
yield
for i in range(len(clk)): for i in range(len(clk)):
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
@ -147,12 +152,13 @@ class TestHyperBus(unittest.TestCase):
yield yield
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--_______" clk = "_______--__--__--__--__--__--__--__--__--__--__--_______"
cs_n = "--____________________________________________------" cs_n = "----______________________________________________------"
dq_oe = "__------------________________________--------______" dq_oe = "______------------________________________--------______"
dq_o = "002000048d0000000000000000000000000000deadbeef000000" dq_o = "0000002000048d0000000000000000000000000000deadbeef000000"
rwds_oe = "______________________________________--------______" rwds_oe = "__________________________________________--------______"
rwds_o = "________________________________________----________" rwds_o = "____________________________________________----________"
yield
for i in range(len(clk)): for i in range(len(clk)):
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
@ -170,18 +176,19 @@ class TestHyperBus(unittest.TestCase):
def fpga_gen(dut): def fpga_gen(dut):
dat = yield from dut.bus.read(0x1234) dat = yield from dut.bus.read(0x1234)
self.assertEqual(dat, 0xdeadbeef) self.assertEqual(dat, 0xdeadbeef)
dat = yield from dut.bus.read(0x1235)
self.assertEqual(dat, 0xcafefade)
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
cs_n = "--________________________________________________________________________" cs_n = "----______________________________________________________________________----"
dq_oe = "__------------____________________________________________________________" dq_oe = "______------------____________________________________________________________"
dq_o = "00a000048d0000000000000000000000000000000000000000000000000000000000000000" dq_o = "000000a000048d0000000000000000000000000000000000000000000000000000000000000000"
dq_i = "00000000000000000000000000000000000000000000000000deadbeefcafefade00000000" dq_i = "000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
rwds_oe = "__________________________________________________________________________" rwds_oe = "______________________________________________________________________________"
rwds_i = "______________________________________________________--__--__--__--__________"
yield
for i in range(len(clk)): for i in range(len(clk)):
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16)) yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
yield dut.pads.rwds.i.eq(c2bool(rwds_i[i]))
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe)) self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
@ -197,18 +204,19 @@ class TestHyperBus(unittest.TestCase):
def fpga_gen(dut): def fpga_gen(dut):
dat = yield from dut.bus.read(0x1234) dat = yield from dut.bus.read(0x1234)
self.assertEqual(dat, 0xdeadbeef) self.assertEqual(dat, 0xdeadbeef)
dat = yield from dut.bus.read(0x1235)
self.assertEqual(dat, 0xcafefade)
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
cs_n = "--________________________________________________________________________________" cs_n = "----______________________________________________________________________________----"
dq_oe = "__------------____________________________________________________________________" dq_oe = "______------------____________________________________________________________________"
dq_o = "00a000048d000000000000000000000000000000000000000000000000000000000000000000000000" dq_o = "000000a000048d000000000000000000000000000000000000000000000000000000000000000000000000"
dq_i = "0000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000" dq_i = "00000000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
rwds_oe = "__________________________________________________________________________________" rwds_oe = "______________________________________________________________________________________"
rwds_i = "______________________________________________________________--__--__--__--__________"
yield
for i in range(len(clk)): for i in range(len(clk)):
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16)) yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
yield dut.pads.rwds.i.eq(c2bool(rwds_i[i]))
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe)) self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
@ -224,18 +232,19 @@ class TestHyperBus(unittest.TestCase):
def fpga_gen(dut): def fpga_gen(dut):
dat = yield from dut.bus.read(0x1234) dat = yield from dut.bus.read(0x1234)
self.assertEqual(dat, 0xdeadbeef) self.assertEqual(dat, 0xdeadbeef)
dat = yield from dut.bus.read(0x1235)
self.assertEqual(dat, 0xcafefade)
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_____"
cs_n = "--________________________________________________________________________________________" cs_n = "----______________________________________________________________________________________----"
dq_oe = "__------------____________________________________________________________________________" dq_oe = "______------------____________________________________________________________________________"
dq_o = "00a000048d00000000000000000000000000000000000000000000000000000000000000000000000000000000" dq_o = "000000a000048d00000000000000000000000000000000000000000000000000000000000000000000000000000000"
dq_i = "000000000000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000" dq_i = "0000000000000000000000000000000000000000000000000000000000000000000000deadbeefcafefade00000000"
rwds_oe = "__________________________________________________________________________________________" rwds_oe = "______________________________________________________________________________________________"
rwds_i = "______________________________________________________________________--__--__--__--__________"
yield
for i in range(len(clk)): for i in range(len(clk)):
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16)) yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
yield dut.pads.rwds.i.eq(c2bool(rwds_i[i]))
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe)) self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
@ -251,18 +260,19 @@ class TestHyperBus(unittest.TestCase):
def fpga_gen(dut): def fpga_gen(dut):
dat = yield from dut.bus.read(0x1234) dat = yield from dut.bus.read(0x1234)
self.assertEqual(dat, 0xdeadbeef) self.assertEqual(dat, 0xdeadbeef)
dat = yield from dut.bus.read(0x1235)
self.assertEqual(dat, 0xcafefade)
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "___--__--__--__--__--__--__--__--__--__--__--__--__--__--__--_" clk = "_______--__--__--__--__--__--__--__--__--__--__--__--__--__-______"
cs_n = "--____________________________________________________________" cs_n = "----________________________________________________________------"
dq_oe = "__------------________________________________________________" dq_oe = "______------------________________________________________________"
dq_o = "00a000048d0000000000000000000000000000000000000000000000000000" dq_o = "000000a000048d0000000000000000000000000000000000000000000000000000"
dq_i = "00000000000000000000000000000000000000deadbeefcafefade00000000" dq_i = "0000000000000000000000000000000000000000deadbeefcafefade0000000000"
rwds_oe = "______________________________________________________________" rwds_oe = "__________________________________________________________________"
rwds_i = "________________________________________--__--__--__--____________"
yield
for i in range(len(clk)): for i in range(len(clk)):
yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16)) yield dut.pads.dq.i.eq(int(dq_i[2*(i//2):2*(i//2)+2], 16))
yield dut.pads.rwds.i.eq(c2bool(rwds_i[i]))
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe)) self.assertEqual(c2bool(dq_oe[i]), (yield dut.pads.dq.oe))
@ -276,22 +286,23 @@ class TestHyperBus(unittest.TestCase):
def test_hyperram_reg_write(self): def test_hyperram_reg_write(self):
def fpga_gen(dut): def fpga_gen(dut):
yield dut.reg_addr.eq(2) yield dut.core.reg.adr.eq(2)
yield dut.reg_write_data.eq(0x1234) yield dut.core.reg.dat_w.eq(0x1234)
yield yield
yield dut.reg_write.eq(1) yield dut.core.reg.stb.eq(1)
yield yield dut.core.reg.we.eq(1)
yield dut.reg_write.eq(0) while (yield dut.core.reg.ack) == 0:
for i in range(128):
yield yield
yield dut.core.reg.stb.eq(0)
def hyperram_gen(dut): def hyperram_gen(dut):
clk = "_____--__--__--__--___________" clk = "___________--__--__--__--___________"
cs_n = "----________________----------" cs_n = "--------__________________----------"
dq_oe = "____----------------__________" dq_oe = "__________----------------__________"
dq_o = "000060000100000012340000000000" dq_o = "000000000060000100000012340000000000"
rwds_oe = "______________________________" rwds_oe = "____________________________________"
rwds_o = "______________________________" rwds_o = "____________________________________"
yield
for i in range(len(clk)): for i in range(len(clk)):
self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk)) self.assertEqual(c2bool(clk[i]), (yield dut.pads.clk))
self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n)) self.assertEqual(c2bool(cs_n[i]), (yield dut.pads.cs_n))
@ -303,4 +314,4 @@ class TestHyperBus(unittest.TestCase):
yield yield
dut = HyperRAM(HyperRamPads(), with_csr=False) dut = HyperRAM(HyperRamPads(), with_csr=False)
run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd") run_simulation(dut, [fpga_gen(dut), hyperram_gen(dut)], vcd_name="sim.vcd")#