1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
4 from nmigen
.asserts
import Assert
, Assume
5 from nmigen_soc
import wishbone
, memory
6 from nmigen
.lib
.cdc
import ResetSynchronizer
8 from lambdasoc
.periph
import Peripheral
9 from lambdasoc
.soc
.base
import SoC
11 from gram
.common
import *
12 from gram
.core
import gramCore
13 from gram
.phy
.fakephy
import FakePHY
, SDRAM_VERBOSE_STD
, SDRAM_VERBOSE_DBG
14 from gram
.modules
import MT41K256M16
15 from gram
.frontend
.wishbone
import gramWishbone
17 from gram
.core
.multiplexer
import _AntiStarvation
20 class DDR3SoC(SoC
, Elaboratable
):
21 def __init__(self
, *, clk_freq
, dramcore_addr
,
23 self
._arbiter
= wishbone
.Arbiter(addr_width
=30, data_width
=32, granularity
=8,
24 features
={"cti", "bte"})
25 self
._decoder
= wishbone
.Decoder(addr_width
=30, data_width
=32, granularity
=8,
26 features
={"cti", "bte"})
28 self
.bus
= wishbone
.Interface(addr_width
=30, data_width
=32, granularity
=32)
29 self
._arbiter
.add(self
.bus
)
37 cl
, cwl
= get_cl_cw("DDR3", tck
)
38 cl_sys_latency
= get_sys_latency(nphases
, cl
)
39 cwl_sys_latency
= get_sys_latency(nphases
, cwl
)
40 rdcmdphase
, rdphase
= get_sys_phases(nphases
, cl_sys_latency
, cl
)
41 wrcmdphase
, wrphase
= get_sys_phases(nphases
, cwl_sys_latency
, cwl
)
42 physettings
= PhySettings(
46 dfi_databits
=4*databits
,
51 rdcmdphase
=rdcmdphase
,
52 wrcmdphase
=wrcmdphase
,
55 read_latency
=2 + cl_sys_latency
+ 2 + log2_int(4//nphases
) + 4,
56 write_latency
=cwl_sys_latency
59 ddrmodule
= MT41K256M16(clk_freq
, "1:4")
60 self
.ddrphy
= FakePHY(module
=ddrmodule
,
62 verbosity
=SDRAM_VERBOSE_DBG
)
64 self
.dramcore
= gramCore(
66 geom_settings
=ddrmodule
.geom_settings
,
67 timing_settings
=ddrmodule
.timing_settings
,
69 self
._decoder
.add(self
.dramcore
.bus
, addr
=dramcore_addr
)
71 self
.drambone
= gramWishbone(self
.dramcore
)
72 self
._decoder
.add(self
.drambone
.bus
, addr
=ddr_addr
)
74 self
.memory_map
= self
._decoder
.bus
.memory_map
76 self
.clk_freq
= clk_freq
78 def elaborate(self
, platform
):
81 m
.submodules
.arbiter
= self
._arbiter
83 m
.submodules
.decoder
= self
._decoder
84 m
.submodules
.ddrphy
= self
.ddrphy
85 m
.submodules
.dramcore
= self
.dramcore
86 m
.submodules
.drambone
= self
.drambone
89 self
._arbiter
.bus
.connect(self
._decoder
.bus
),
94 class SocTestCase(FHDLTestCase
):
97 soc
= DDR3SoC(clk_freq
=100e6
,
98 dramcore_addr
=0x00000000,
103 yield from wb_write(soc
.bus
, 0x0, 0xE, 0xF) # DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
104 yield from wb_write(soc
.bus
, 0xC >> 2, 0x0, 0xF)
105 yield from wb_write(soc
.bus
, 0x10 >> 2, 0x0, 0xF)
106 yield from wb_write(soc
.bus
, 0x0, 0xC, 0xF)
108 yield from wb_write(soc
.bus
, 0x0, 0xE, 0xF)
111 yield from wb_write(soc
.bus
, 0xC >> 2, 0x200, 0xF)
112 yield from wb_write(soc
.bus
, 0x10 >> 2, 0x2, 0xF)
113 yield from wb_write(soc
.bus
, 0x4 >> 2, 0xF, 0xF)
114 yield from wb_write(soc
.bus
, 0x8 >> 2, 0x1, 0xF)
117 yield from wb_write(soc
.bus
, 0xC >> 2, 0x0, 0xF)
118 yield from wb_write(soc
.bus
, 0x10 >> 2, 0x3, 0xF)
119 yield from wb_write(soc
.bus
, 0x4 >> 2, 0xF, 0xF)
120 yield from wb_write(soc
.bus
, 0x8 >> 2, 0x1, 0xF)
123 yield from wb_write(soc
.bus
, 0xC >> 2, 0x6, 0xF)
124 yield from wb_write(soc
.bus
, 0x10 >> 2, 0x1, 0xF)
125 yield from wb_write(soc
.bus
, 0x4 >> 2, 0xF, 0xF)
126 yield from wb_write(soc
.bus
, 0x8 >> 2, 0x1, 0xF)
129 yield from wb_write(soc
.bus
, 0xC >> 2, 0x320, 0xF)
130 yield from wb_write(soc
.bus
, 0x10 >> 2, 0x0, 0xF)
131 yield from wb_write(soc
.bus
, 0x4 >> 2, 0xF, 0xF)
132 yield from wb_write(soc
.bus
, 0x8 >> 2, 0x1, 0xF)
138 yield from wb_write(soc
.bus
, 0xC >> 2, 0x400, 0xF)
139 yield from wb_write(soc
.bus
, 0x10 >> 2, 0x0, 0xF)
140 yield from wb_write(soc
.bus
, 0x4 >> 2, 0x3, 0xF)
141 yield from wb_write(soc
.bus
, 0x8 >> 2, 0x1, 0xF)
146 yield from wb_write(soc
.bus
, 0, 0x1, 0xF)
148 for i
in range(2000):
151 res
= yield from wb_read(soc
.bus
, 0x10000000 >> 2, 0xF, 16384)
152 self
.assertEqual(res
, 0xDEADBEEF)
154 runSimulation(m
, process
, "test_soc.vcd")