Make memory test code more verbose
[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.rom2 = self.rom2
180 m.submodules.ram = self.ram
181 m.submodules.uart = self.uart
182 m.submodules.timer = self.timer
183 m.submodules.intc = self.intc
184 m.submodules.ddrphy = self.ddrphy
185 m.submodules.dramcore = self.dramcore
186 m.submodules.drambone = self.drambone
187
188 m.submodules.sysclk = SysClocker()
189
190 m.d.comb += [
191 self._arbiter.bus.connect(self._decoder.bus),
192 self.cpu.ip.eq(self.intc.ip),
193 ]
194
195 return m
196
197
198 if __name__ == "__main__":
199 platform = ECPIX5Platform()
200
201 uart_divisor = int(platform.default_clk_frequency // 115200)
202 uart_pins = platform.request("uart", 0)
203
204 soc = DDR3SoC(
205 reset_addr=0x00000000, clk_freq=int(platform.default_clk_frequency),
206 rom_addr=0x00000000, rom_size=0x4000,
207 rom2_addr=0x7000, rom2_size=0x1000,
208 ram_addr=0x00004000, ram_size=0x1000,
209 uart_addr=0x00005000, uart_divisor=uart_divisor, uart_pins=uart_pins,
210 timer_addr=0x00006000, timer_width=32,
211 ddrphy_addr=0x00008000, dramcore_addr=0x00009000,
212 ddr_addr=0x10000000
213 )
214
215 soc.build(do_build=True, do_init=True)
216 platform.build(soc, do_program=True)