Autopep8 on example code
[gram.git] / examples / ecpix5.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.cpu.minerva import MinervaCPU
7 from lambdasoc.periph.intc import GenericInterruptController
8 from lambdasoc.periph.serial import AsyncSerialPeripheral
9 from lambdasoc.periph.sram import SRAMPeripheral
10 from lambdasoc.periph.timer import TimerPeripheral
11 from lambdasoc.periph import Peripheral
12 from lambdasoc.soc.cpu import CPUSoC
13
14 from gram.core import gramCore
15 from gram.phy.ecp5ddrphy import ECP5DDRPHY
16 from gram.modules import MT41K256M16
17 from gram.frontend.wishbone import gramWishbone
18
19 from customecpix5 import ECPIX5Platform
20
21
22 class PLL(Elaboratable):
23 def __init__(self, clkin, clksel=Signal(shape=2, reset=2), clkout1=Signal(), clkout2=Signal(), clkout3=Signal(), clkout4=Signal(), lock=Signal(), CLKI_DIV=1, CLKFB_DIV=1, CLK1_DIV=3, CLK2_DIV=4, CLK3_DIV=5, CLK4_DIV=6):
24 self.clkin = clkin
25 self.clkout1 = clkout1
26 self.clkout2 = clkout2
27 self.clkout3 = clkout3
28 self.clkout4 = clkout4
29 self.clksel = clksel
30 self.lock = lock
31 self.CLKI_DIV = CLKI_DIV
32 self.CLKFB_DIV = CLKFB_DIV
33 self.CLKOP_DIV = CLK1_DIV
34 self.CLKOS_DIV = CLK2_DIV
35 self.CLKOS2_DIV = CLK3_DIV
36 self.CLKOS3_DIV = CLK4_DIV
37 self.ports = [
38 self.clkin,
39 self.clkout1,
40 self.clkout2,
41 self.clkout3,
42 self.clkout4,
43 self.clksel,
44 self.lock,
45 ]
46
47 def elaborate(self, platform):
48 clkfb = Signal()
49 pll = Instance("EHXPLLL",
50 p_PLLRST_ENA='DISABLED',
51 p_INTFB_WAKE='DISABLED',
52 p_STDBY_ENABLE='DISABLED',
53 p_CLKOP_FPHASE=0,
54 p_CLKOP_CPHASE=11,
55 p_OUTDIVIDER_MUXA='DIVA',
56 p_CLKOP_ENABLE='ENABLED',
57 # Max 948 MHz at OP=79 FB=1 I=1 F_in=12 MHz, Min 30 MHz (28 MHz locks sometimes, lock LED blinks) Hmm... /3*82/25
58 p_CLKOP_DIV=self.CLKOP_DIV,
59 p_CLKOS_DIV=self.CLKOS_DIV,
60 p_CLKOS2_DIV=self.CLKOS2_DIV,
61 p_CLKOS3_DIV=self.CLKOS3_DIV,
62 p_CLKFB_DIV=self.CLKFB_DIV, # 25
63 p_CLKI_DIV=self.CLKI_DIV, # 6
64 p_FEEDBK_PATH='USERCLOCK',
65 i_CLKI=self.clkin,
66 i_CLKFB=clkfb,
67 i_RST=0,
68 i_STDBY=0,
69 i_PHASESEL0=0,
70 i_PHASESEL1=0,
71 i_PHASEDIR=0,
72 i_PHASESTEP=0,
73 i_PLLWAKESYNC=0,
74 i_ENCLKOP=0,
75 i_ENCLKOS=0,
76 i_ENCLKOS2=0,
77 i_ENCLKOS3=0,
78 o_CLKOP=self.clkout1,
79 o_CLKOS=self.clkout2,
80 o_CLKOS2=self.clkout3,
81 o_CLKOS3=self.clkout4,
82 o_LOCK=self.lock,
83 # o_LOCK=pll_lock
84 )
85 m = Module()
86 m.submodules += pll
87 with m.If(self.clksel == 0):
88 m.d.comb += clkfb.eq(self.clkout1)
89 with m.Elif(self.clksel == 1):
90 m.d.comb += clkfb.eq(self.clkout2)
91 with m.Elif(self.clksel == 2):
92 m.d.comb += clkfb.eq(self.clkout3)
93 with m.Else():
94 m.d.comb += clkfb.eq(self.clkout4)
95 return m
96
97
98 class SysClocker(Elaboratable):
99 def elaborate(self, platform):
100 m = Module()
101
102 m.submodules.pll = pll = PLL(ClockSignal(
103 "sync"), CLKI_DIV=1, CLKFB_DIV=2, CLK1_DIV=2, CLK2_DIV=16)
104 cd_sys2x = ClockDomain("sys2x", local=False)
105 m.d.comb += cd_sys2x.clk.eq(pll.clkout1)
106 m.domains += cd_sys2x
107
108 cd_init = ClockDomain("init", local=False)
109 m.d.comb += cd_init.clk.eq(pll.clkout2)
110 m.domains += cd_init
111
112 return m
113
114
115 class DDR3SoC(CPUSoC, Elaboratable):
116 def __init__(self, *, reset_addr, clk_freq,
117 rom_addr, rom_size,
118 rom2_addr, rom2_size,
119 ram_addr, ram_size,
120 uart_addr, uart_divisor, uart_pins,
121 timer_addr, timer_width,
122 ddrphy_addr, dramcore_addr,
123 ddr_addr):
124 self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
125 features={"cti", "bte"})
126 self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
127 features={"cti", "bte"})
128
129 self.cpu = MinervaCPU(reset_address=reset_addr)
130 self._arbiter.add(self.cpu.ibus)
131 self._arbiter.add(self.cpu.dbus)
132
133 self.rom = SRAMPeripheral(size=rom_size, writable=False)
134 self._decoder.add(self.rom.bus, addr=rom_addr)
135
136 self.rom2 = SRAMPeripheral(size=rom2_size)
137 self._decoder.add(self.rom2.bus, addr=rom2_addr)
138
139 self.ram = SRAMPeripheral(size=ram_size)
140 self._decoder.add(self.ram.bus, addr=ram_addr)
141
142 self.uart = AsyncSerialPeripheral(divisor=uart_divisor, pins=uart_pins)
143 self._decoder.add(self.uart.bus, addr=uart_addr)
144
145 self.timer = TimerPeripheral(width=timer_width)
146 self._decoder.add(self.timer.bus, addr=timer_addr)
147
148 self.intc = GenericInterruptController(width=len(self.cpu.ip))
149 self.intc.add_irq(self.timer.irq, 0)
150 self.intc.add_irq(self.uart .irq, 1)
151
152 self.ddrphy = ECP5DDRPHY(platform.request("ddr3", 0))
153 self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr)
154
155 ddrmodule = MT41K256M16(clk_freq, "1:4")
156
157 self.dramcore = gramCore(
158 phy=self.ddrphy,
159 geom_settings=ddrmodule.geom_settings,
160 timing_settings=ddrmodule.timing_settings,
161 clk_freq=clk_freq)
162 self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
163
164 self.drambone = gramWishbone(self.dramcore)
165 self._decoder.add(self.drambone.bus, addr=ddr_addr)
166
167 self.memory_map = self._decoder.bus.memory_map
168
169 self.clk_freq = clk_freq
170
171 def elaborate(self, platform):
172 m = Module()
173
174 m.submodules.arbiter = self._arbiter
175 m.submodules.cpu = self.cpu
176
177 m.submodules.decoder = self._decoder
178 m.submodules.rom = self.rom
179 m.submodules.ram = self.ram
180 m.submodules.uart = self.uart
181 m.submodules.timer = self.timer
182 m.submodules.intc = self.intc
183 m.submodules.ddrphy = self.ddrphy
184 m.submodules.dramcore = self.dramcore
185 m.submodules.drambone = self.drambone
186
187 m.submodules.sysclk = SysClocker()
188
189 m.d.comb += [
190 self._arbiter.bus.connect(self._decoder.bus),
191 self.cpu.ip.eq(self.intc.ip),
192 ]
193
194 return m
195
196
197 if __name__ == "__main__":
198 platform = ECPIX5Platform()
199
200 uart_divisor = int(platform.default_clk_frequency // 115200)
201 uart_pins = platform.request("uart", 0)
202
203 soc = DDR3SoC(
204 reset_addr=0x00000000, clk_freq=int(platform.default_clk_frequency),
205 rom_addr=0x00000000, rom_size=0x4000,
206 rom2_addr=0x7000, rom2_size=0x1000,
207 ram_addr=0x00004000, ram_size=0x1000,
208 uart_addr=0x00005000, uart_divisor=uart_divisor, uart_pins=uart_pins,
209 timer_addr=0x00006000, timer_width=32,
210 ddrphy_addr=0x00008000, dramcore_addr=0x00009000,
211 ddr_addr=0x10000000
212 )
213
214 soc.build(do_build=True, do_init=True)
215 platform.build(soc, do_program=True)