Externalize CRG into its own file
[gram.git] / gram / simulation / simsoc.py
1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2
3 from nmigen import *
4 from nmigen_soc import wishbone, memory
5
6 from lambdasoc.periph import Peripheral
7 from lambdasoc.soc.base import SoC
8
9 from gram.core import gramCore
10 from gram.phy.ecp5ddrphy import ECP5DDRPHY
11 from gram.modules import MT41K256M16
12 from gram.frontend.wishbone import gramWishbone
13
14 from icarusecpix5platform import IcarusECPIX5Platform
15 from uartbridge import UARTBridge
16 from crg import *
17
18 class DDR3SoC(SoC, Elaboratable):
19 def __init__(self, *, clk_freq,
20 ddrphy_addr, dramcore_addr,
21 ddr_addr):
22 self.crg = ECPIX5CRG()
23
24 self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
25 features={"cti", "bte"})
26 self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
27 features={"cti", "bte"})
28
29 self.ub = UARTBridge(divisor=868, pins=platform.request("uart", 0))
30 self._arbiter.add(self.ub.bus)
31
32 self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(platform.request("ddr3", 0, dir={"dq":"-", "dqs":"-"})))
33 self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr)
34
35 ddrmodule = MT41K256M16(clk_freq, "1:4")
36
37 self.dramcore = DomainRenamer("dramsync")(gramCore(
38 phy=self.ddrphy,
39 geom_settings=ddrmodule.geom_settings,
40 timing_settings=ddrmodule.timing_settings,
41 clk_freq=clk_freq))
42 self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
43
44 self.drambone = DomainRenamer("dramsync")(gramWishbone(self.dramcore))
45 self._decoder.add(self.drambone.bus, addr=ddr_addr)
46
47 self.memory_map = self._decoder.bus.memory_map
48
49 self.clk_freq = clk_freq
50
51 def elaborate(self, platform):
52 m = Module()
53
54 m.submodules.sysclk = self.crg
55
56 m.submodules.arbiter = self._arbiter
57 m.submodules.ub = self.ub
58
59 m.submodules.decoder = self._decoder
60 m.submodules.ddrphy = self.ddrphy
61 m.submodules.dramcore = self.dramcore
62 m.submodules.drambone = self.drambone
63
64 m.d.comb += [
65 self._arbiter.bus.connect(self._decoder.bus),
66 ]
67
68 return m
69
70
71 if __name__ == "__main__":
72 platform = IcarusECPIX5Platform()
73
74 soc = DDR3SoC(clk_freq=int(platform.default_clk_frequency),
75 ddrphy_addr=0x00008000, dramcore_addr=0x00009000,
76 ddr_addr=0x10000000)
77
78 soc.build(do_build=True)
79 platform.build(soc, build_dir="build_simsoc")