1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
4 from nmigen
.build
import Resource
, Pins
, Attrs
, Subsignal
5 from nmigen_soc
import wishbone
, memory
7 from lambdasoc
.periph
import Peripheral
8 from lambdasoc
.soc
.base
import SoC
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
15 from icarusecpix5platform
import IcarusECPIX5Platform
18 class DDR3SoC(SoC
, Elaboratable
):
19 def __init__(self
, *, clk_freq
,
20 ddrphy_addr
, dramcore_addr
,
22 self
.crg
= ECPIX5CRG()
24 self
._decoder
= wishbone
.Decoder(addr_width
=30, data_width
=32, granularity
=8,
25 features
={"cti", "bte"})
27 ddr_pins
= platform
.request("ddr3", 0, dir={"dq":"-", "dqs":"-"},
28 xdr
={"clk":4, "a":4, "ba":4, "clk_en":4, "we_n":4, "odt":4, "ras":4, "cas":4, "we":4})
29 self
.ddrphy
= DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins
))
30 self
._decoder
.add(self
.ddrphy
.bus
, addr
=ddrphy_addr
)
32 ddrmodule
= MT41K256M16(clk_freq
, "1:2")
34 self
.dramcore
= DomainRenamer("dramsync")(gramCore(
36 geom_settings
=ddrmodule
.geom_settings
,
37 timing_settings
=ddrmodule
.timing_settings
,
39 self
._decoder
.add(self
.dramcore
.bus
, addr
=dramcore_addr
)
41 self
.drambone
= DomainRenamer("dramsync")(gramWishbone(self
.dramcore
))
42 self
._decoder
.add(self
.drambone
.bus
, addr
=ddr_addr
)
44 self
.memory_map
= self
._decoder
.bus
.memory_map
46 self
.clk_freq
= clk_freq
48 def elaborate(self
, platform
):
52 Resource("wishbone", 0,
53 Subsignal("adr", Pins("ADDR0 ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 ADDR7"
54 " ADDR8 ADDR9 ADDR10 ADDR11 ADDR12 ADDR13 ADDR14 ADDR15"
55 " ADDR16 ADDR17 ADDR18 ADDR19 ADDR20 ADDR21 ADDR22 ADDR23"
56 " ADDR24 ADDR25 ADDR26 ADDR27 ADDR28 ADDR29 ADDR30 ADDR31", dir="i")),
57 Subsignal("dat_r", Pins("DATR0 DATR1 DATR2 DATR3 DATR4 DATR5 DATR6 DATR7"
58 " DATR8 DATR9 DATR10 DATR11 DATR12 DATR13 DATR14 DATR15"
59 " DATR16 DATR17 DATR18 DATR19 DATR20 DATR21 DATR22 DATR23"
60 " DATR24 DATR25 DATR26 DATR27 DATR28 DATR29 DATR30 DATR31", dir="o")),
61 Subsignal("dat_w", Pins("DATW0 DATW1 DATW2 DATW3 DATW4 DATW5 DATW6 DATW7"
62 " DATW8 DATW9 DATW10 DATW11 DATW12 DATW13 DATW14 DATW15"
63 " DATW16 DATW17 DATW18 DATW19 DATW20 DATW21 DATW22 DATW23"
64 " DATW24 DATW25 DATW26 DATW27 DATW28 DATW29 DATW30 DATW31", dir="i")),
65 Subsignal("cyc", Pins("CYC", dir="i")),
66 Subsignal("stb", Pins("STB", dir="i")),
67 Subsignal("sel", Pins("SEL0 SEL1 SEL2 SEL3", dir="i")),
68 Subsignal("ack", Pins("ACK", dir="o")),
69 Subsignal("we", Pins("WE", dir="i"))),
71 platform
.add_resources(resources
)
73 m
.submodules
.sysclk
= self
.crg
75 m
.submodules
.decoder
= self
._decoder
76 m
.submodules
.ddrphy
= self
.ddrphy
77 m
.submodules
.dramcore
= self
.dramcore
78 m
.submodules
.drambone
= self
.drambone
80 ext_bus
= platform
.request("wishbone", 0)
82 self
._decoder
.bus
.adr
.eq(ext_bus
.adr
.i
),
83 self
._decoder
.bus
.dat_w
.eq(ext_bus
.dat_w
.i
),
84 ext_bus
.dat_r
.o
.eq(self
._decoder
.bus
.dat_r
),
85 self
._decoder
.bus
.cyc
.eq(ext_bus
.cyc
.i
),
86 self
._decoder
.bus
.stb
.eq(ext_bus
.stb
.i
),
87 self
._decoder
.bus
.sel
.eq(ext_bus
.sel
.i
),
88 ext_bus
.ack
.o
.eq(self
._decoder
.bus
.ack
),
89 self
._decoder
.bus
.we
.eq(ext_bus
.we
.i
),
95 if __name__
== "__main__":
96 platform
= IcarusECPIX5Platform()
98 soc
= DDR3SoC(clk_freq
=int(platform
.default_clk_frequency
),
99 ddrphy_addr
=0x00008000, dramcore_addr
=0x00009000,
102 soc
.build(do_build
=True)
103 platform
.build(soc
, build_dir
="build_simsoc")