allow DDR3 reset (rst) signal to be controlled by DFI commands,
[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.build import Resource, Pins, Attrs, Subsignal
5 from nmigen_soc import wishbone, memory
6
7 from lambdasoc.periph import Peripheral
8 from lambdasoc.soc.base import SoC
9
10 from gram.core import gramCore
11 from gram.phy.ecp5ddrphy import ECP5DDRPHY
12 from gram.modules import MT41K256M16
13 from gram.frontend.wishbone import gramWishbone
14
15 from icarusecpix5platform import IcarusECPIX5Platform
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._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
25 features={"cti", "bte"})
26
27 ddr_pins = platform.request("ddr3", 0, dir={"dq":"-", "dqs":"-"},
28 xdr={"rst": 4, "clk":4, "a":4, "ba":4, "clk_en":4, "we_n":4,
29 "odt":4, "ras":4, "cas":4, "we":4})
30 self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins))
31 self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr)
32
33 ddrmodule = MT41K256M16(clk_freq, "1:2")
34
35 self.dramcore = DomainRenamer("dramsync")(gramCore(
36 phy=self.ddrphy,
37 geom_settings=ddrmodule.geom_settings,
38 timing_settings=ddrmodule.timing_settings,
39 clk_freq=clk_freq))
40 self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
41
42 self.drambone = DomainRenamer("dramsync")(gramWishbone(self.dramcore))
43 self._decoder.add(self.drambone.bus, addr=ddr_addr)
44
45 self.memory_map = self._decoder.bus.memory_map
46
47 self.clk_freq = clk_freq
48
49 def elaborate(self, platform):
50 m = Module()
51
52 resources = [
53 Resource("wishbone", 0,
54 Subsignal("adr", Pins("ADDR0 ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 ADDR7"
55 " ADDR8 ADDR9 ADDR10 ADDR11 ADDR12 ADDR13 ADDR14 ADDR15"
56 " ADDR16 ADDR17 ADDR18 ADDR19 ADDR20 ADDR21 ADDR22 ADDR23"
57 " ADDR24 ADDR25 ADDR26 ADDR27 ADDR28 ADDR29 ADDR30 ADDR31", dir="i")),
58 Subsignal("dat_r", Pins("DATR0 DATR1 DATR2 DATR3 DATR4 DATR5 DATR6 DATR7"
59 " DATR8 DATR9 DATR10 DATR11 DATR12 DATR13 DATR14 DATR15"
60 " DATR16 DATR17 DATR18 DATR19 DATR20 DATR21 DATR22 DATR23"
61 " DATR24 DATR25 DATR26 DATR27 DATR28 DATR29 DATR30 DATR31", dir="o")),
62 Subsignal("dat_w", Pins("DATW0 DATW1 DATW2 DATW3 DATW4 DATW5 DATW6 DATW7"
63 " DATW8 DATW9 DATW10 DATW11 DATW12 DATW13 DATW14 DATW15"
64 " DATW16 DATW17 DATW18 DATW19 DATW20 DATW21 DATW22 DATW23"
65 " DATW24 DATW25 DATW26 DATW27 DATW28 DATW29 DATW30 DATW31", dir="i")),
66 Subsignal("cyc", Pins("CYC", dir="i")),
67 Subsignal("stb", Pins("STB", dir="i")),
68 Subsignal("sel", Pins("SEL0 SEL1 SEL2 SEL3", dir="i")),
69 Subsignal("ack", Pins("ACK", dir="o")),
70 Subsignal("we", Pins("WE", dir="i"))),
71 ]
72 platform.add_resources(resources)
73
74 m.submodules.sysclk = self.crg
75
76 m.submodules.decoder = self._decoder
77 m.submodules.ddrphy = self.ddrphy
78 m.submodules.dramcore = self.dramcore
79 m.submodules.drambone = self.drambone
80
81 ext_bus = platform.request("wishbone", 0)
82 m.d.comb += [
83 self._decoder.bus.adr.eq(ext_bus.adr.i),
84 self._decoder.bus.dat_w.eq(ext_bus.dat_w.i),
85 ext_bus.dat_r.o.eq(self._decoder.bus.dat_r),
86 self._decoder.bus.cyc.eq(ext_bus.cyc.i),
87 self._decoder.bus.stb.eq(ext_bus.stb.i),
88 self._decoder.bus.sel.eq(ext_bus.sel.i),
89 ext_bus.ack.o.eq(self._decoder.bus.ack),
90 self._decoder.bus.we.eq(ext_bus.we.i),
91 ]
92
93 return m
94
95
96 if __name__ == "__main__":
97 platform = IcarusECPIX5Platform()
98
99 soc = DDR3SoC(clk_freq=int(platform.default_clk_frequency),
100 ddrphy_addr=0x00008000, dramcore_addr=0x00009000,
101 ddr_addr=0x10000000)
102
103 soc.build(do_build=True)
104 platform.build(soc, build_dir="build_simsoc")