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
, MT41K64M16
)
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(clk_freq
, dram_clk_freq
=clk_freq
)
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
={"rst": 4, "clk":4, "a":4, "ba":4, "clk_en":4, "we_n":4,
29 "cs": 4, "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
)
33 #ddrmodule = MT41K256M16(clk_freq, "1:2")
34 ddrmodule
= MT41K64M16(clk_freq
, "1:2")
36 self
.dramcore
= DomainRenamer("dramsync")(gramCore(
38 geom_settings
=ddrmodule
.geom_settings
,
39 timing_settings
=ddrmodule
.timing_settings
,
41 self
._decoder
.add(self
.dramcore
.bus
, addr
=dramcore_addr
)
43 self
.drambone
= DomainRenamer("dramsync")(gramWishbone(self
.dramcore
))
44 self
._decoder
.add(self
.drambone
.bus
, addr
=ddr_addr
)
46 self
.memory_map
= self
._decoder
.bus
.memory_map
48 self
.clk_freq
= clk_freq
50 def elaborate(self
, platform
):
54 Resource("wishbone", 0,
55 Subsignal("adr", Pins("ADDR0 ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 ADDR7"
56 " ADDR8 ADDR9 ADDR10 ADDR11 ADDR12 ADDR13 ADDR14 ADDR15"
57 " ADDR16 ADDR17 ADDR18 ADDR19 ADDR20 ADDR21 ADDR22 ADDR23"
58 " ADDR24 ADDR25 ADDR26 ADDR27 ADDR28 ADDR29 ADDR30 ADDR31", dir="i")),
59 Subsignal("dat_r", Pins("DATR0 DATR1 DATR2 DATR3 DATR4 DATR5 DATR6 DATR7"
60 " DATR8 DATR9 DATR10 DATR11 DATR12 DATR13 DATR14 DATR15"
61 " DATR16 DATR17 DATR18 DATR19 DATR20 DATR21 DATR22 DATR23"
62 " DATR24 DATR25 DATR26 DATR27 DATR28 DATR29 DATR30 DATR31", dir="o")),
63 Subsignal("dat_w", Pins("DATW0 DATW1 DATW2 DATW3 DATW4 DATW5 DATW6 DATW7"
64 " DATW8 DATW9 DATW10 DATW11 DATW12 DATW13 DATW14 DATW15"
65 " DATW16 DATW17 DATW18 DATW19 DATW20 DATW21 DATW22 DATW23"
66 " DATW24 DATW25 DATW26 DATW27 DATW28 DATW29 DATW30 DATW31", dir="i")),
67 Subsignal("cyc", Pins("CYC", dir="i")),
68 Subsignal("stb", Pins("STB", dir="i")),
69 Subsignal("sel", Pins("SEL0 SEL1 SEL2 SEL3", dir="i")),
70 Subsignal("ack", Pins("ACK", dir="o")),
71 Subsignal("we", Pins("WE", dir="i"))),
73 platform
.add_resources(resources
)
75 m
.submodules
.sysclk
= self
.crg
77 m
.submodules
.decoder
= self
._decoder
78 m
.submodules
.ddrphy
= self
.ddrphy
79 m
.submodules
.dramcore
= self
.dramcore
80 m
.submodules
.drambone
= self
.drambone
82 ext_bus
= platform
.request("wishbone", 0)
84 self
._decoder
.bus
.adr
.eq(ext_bus
.adr
.i
),
85 self
._decoder
.bus
.dat_w
.eq(ext_bus
.dat_w
.i
),
86 ext_bus
.dat_r
.o
.eq(self
._decoder
.bus
.dat_r
),
87 self
._decoder
.bus
.cyc
.eq(ext_bus
.cyc
.i
),
88 self
._decoder
.bus
.stb
.eq(ext_bus
.stb
.i
),
89 self
._decoder
.bus
.sel
.eq(ext_bus
.sel
.i
),
90 ext_bus
.ack
.o
.eq(self
._decoder
.bus
.ack
),
91 self
._decoder
.bus
.we
.eq(ext_bus
.we
.i
),
97 if __name__
== "__main__":
98 platform
= IcarusECPIX5Platform()
100 soc
= DDR3SoC(clk_freq
=int(platform
.default_clk_frequency
),
101 ddrphy_addr
=0x00008000, dramcore_addr
=0x00009000,
104 soc
.build(do_build
=True)
105 platform
.build(soc
, build_dir
="build_simsoc")