Initial commit
[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
10 from gram.common import *
11 from gram.phy import dfi
12 from gram.core.refresher import Refresher
13 from gram.core.bankmachine import BankMachine
14 from gram.core.multiplexer import Multiplexer
15
16 # Settings -----------------------------------------------------------------------------------------
17
18 class ControllerSettings(Settings):
19 def __init__(self,
20 # Command buffers
21 cmd_buffer_depth = 8,
22 cmd_buffer_buffered = False,
23
24 # Read/Write times
25 read_time = 32,
26 write_time = 16,
27
28 # Bandwidth
29 with_bandwidth = False,
30
31 # Refresh
32 with_refresh = True,
33 refresh_cls = Refresher,
34 refresh_zqcs_freq = 1e0,
35 refresh_postponing = 1,
36
37 # Auto-Precharge
38 with_auto_precharge = True,
39
40 # Address mapping
41 address_mapping = "ROW_BANK_COL"):
42 self.set_attributes(locals())
43
44 # Controller ---------------------------------------------------------------------------------------
45
46 class LiteDRAMController(Module):
47 def __init__(self, phy_settings, geom_settings, timing_settings, clk_freq,
48 controller_settings=ControllerSettings()):
49 address_align = log2_int(burst_lengths[phy_settings.memtype])
50
51 # Settings ---------------------------------------------------------------------------------
52 self.settings = controller_settings
53 self.settings.phy = phy_settings
54 self.settings.geom = geom_settings
55 self.settings.timing = timing_settings
56
57 nranks = phy_settings.nranks
58 nbanks = 2**geom_settings.bankbits
59
60 # LiteDRAM Interface (User) ----------------------------------------------------------------
61 self.interface = interface = LiteDRAMInterface(address_align, self.settings)
62
63 # DFI Interface (Memory) -------------------------------------------------------------------
64 self.dfi = dfi.Interface(
65 addressbits = geom_settings.addressbits,
66 bankbits = geom_settings.bankbits,
67 nranks = phy_settings.nranks,
68 databits = phy_settings.dfi_databits,
69 nphases = phy_settings.nphases)
70
71 # # #
72
73 # Refresher --------------------------------------------------------------------------------
74 self.submodules.refresher = self.settings.refresh_cls(self.settings,
75 clk_freq = clk_freq,
76 zqcs_freq = self.settings.refresh_zqcs_freq,
77 postponing = self.settings.refresh_postponing)
78
79 # Bank Machines ----------------------------------------------------------------------------
80 bank_machines = []
81 for n in range(nranks*nbanks):
82 bank_machine = BankMachine(n,
83 address_width = interface.address_width,
84 address_align = address_align,
85 nranks = nranks,
86 settings = self.settings)
87 bank_machines.append(bank_machine)
88 self.submodules += bank_machine
89 self.comb += getattr(interface, "bank"+str(n)).connect(bank_machine.req)
90
91 # Multiplexer ------------------------------------------------------------------------------
92 self.submodules.multiplexer = Multiplexer(
93 settings = self.settings,
94 bank_machines = bank_machines,
95 refresher = self.refresher,
96 dfi = self.dfi,
97 interface = interface)
98
99 def get_csrs(self):
100 return self.multiplexer.get_csrs()