Correct nMigen transition bugs
[gram.git] / gram / core / controller.py
1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2016-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
4 # License: BSD
5
6 """LiteDRAM Controller."""
7
8 from nmigen import *
9 from nmigen.utils import log2_int
10
11 from gram.common import *
12 from gram.phy import dfi
13 from gram.core.refresher import Refresher
14 from gram.core.bankmachine import BankMachine
15 from gram.core.multiplexer import Multiplexer
16
17 # Settings -----------------------------------------------------------------------------------------
18
19 class ControllerSettings(Settings):
20 def __init__(self,
21 # Command buffers
22 cmd_buffer_depth = 8,
23 cmd_buffer_buffered = False,
24
25 # Read/Write times
26 read_time = 32,
27 write_time = 16,
28
29 # Bandwidth
30 with_bandwidth = False,
31
32 # Refresh
33 with_refresh = True,
34 refresh_cls = Refresher,
35 refresh_zqcs_freq = 1e0,
36 refresh_postponing = 1,
37
38 # Auto-Precharge
39 with_auto_precharge = True,
40
41 # Address mapping
42 address_mapping = "ROW_BANK_COL"):
43 self.set_attributes(locals())
44
45 # Controller ---------------------------------------------------------------------------------------
46
47 class gramController(Elaboratable):
48 def __init__(self, phy_settings, geom_settings, timing_settings, clk_freq,
49 controller_settings=ControllerSettings()):
50 self._address_align = log2_int(burst_lengths[phy_settings.memtype])
51
52 # Settings ---------------------------------------------------------------------------------
53 self.settings = controller_settings
54 self.settings.phy = phy_settings
55 self.settings.geom = geom_settings
56 self.settings.timing = timing_settings
57
58 # LiteDRAM Interface (User) ----------------------------------------------------------------
59 self.interface = interface = gramInterface(self._address_align, self.settings)
60
61 # DFI Interface (Memory) -------------------------------------------------------------------
62 self.dfi = dfi.Interface(
63 addressbits = geom_settings.addressbits,
64 bankbits = geom_settings.bankbits,
65 nranks = phy_settings.nranks,
66 databits = phy_settings.dfi_databits,
67 nphases = phy_settings.nphases)
68
69 self._clk_freq = clk_freq
70
71 def elaborate(self, platform):
72 m = Module()
73
74 nranks = self.settings.phy.nranks
75 nbanks = 2**self.settings.geom.bankbits
76
77 # Refresher --------------------------------------------------------------------------------
78 m.submodules.refresher = self.settings.refresh_cls(self.settings,
79 clk_freq = self._clk_freq,
80 zqcs_freq = self.settings.refresh_zqcs_freq,
81 postponing = self.settings.refresh_postponing)
82
83 # Bank Machines ----------------------------------------------------------------------------
84 bank_machines = []
85 for n in range(nranks*nbanks):
86 bank_machine = BankMachine(n,
87 address_width = self.interface.address_width,
88 address_align = self._address_align,
89 nranks = nranks,
90 settings = self.settings)
91 bank_machines.append(bank_machine)
92 m.submodules += bank_machine
93 m.d.comb += getattr(self.interface, "bank"+str(n)).connect(bank_machine.req)
94
95 # Multiplexer ------------------------------------------------------------------------------
96 m.submodules.multiplexer = Multiplexer(
97 settings = self.settings,
98 bank_machines = bank_machines,
99 refresher = m.submodules.refresher,
100 dfi = self.dfi,
101 interface = self.interface)
102
103 return m
104
105 def get_csrs(self):
106 return self.multiplexer.get_csrs()