2 from nmigen_soc
import wishbone
, memory
4 from lambdasoc
.cpu
.minerva
import MinervaCPU
5 from lambdasoc
.periph
.intc
import GenericInterruptController
6 from lambdasoc
.periph
.serial
import AsyncSerialPeripheral
7 from lambdasoc
.periph
.sram
import SRAMPeripheral
8 from lambdasoc
.periph
.timer
import TimerPeripheral
9 from lambdasoc
.periph
import Peripheral
10 from lambdasoc
.soc
.cpu
import CPUSoC
12 from gram
.core
import gramCore
13 from gram
.phy
.ecp5ddrphy
import ECP5DDRPHY
14 from gram
.modules
import MT41K256M16
16 from customecpix5
import ECPIX5Platform
18 class PLL(Elaboratable
):
19 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):
21 self
.clkout1
= clkout1
22 self
.clkout2
= clkout2
23 self
.clkout3
= clkout3
24 self
.clkout4
= clkout4
27 self
.CLKI_DIV
= CLKI_DIV
28 self
.CLKFB_DIV
= CLKFB_DIV
29 self
.CLKOP_DIV
= CLK1_DIV
30 self
.CLKOS_DIV
= CLK2_DIV
31 self
.CLKOS2_DIV
= CLK3_DIV
32 self
.CLKOS3_DIV
= CLK4_DIV
43 def elaborate(self
, platform
):
45 pll
= Instance("EHXPLLL",
46 p_PLLRST_ENA
='DISABLED',
47 p_INTFB_WAKE
='DISABLED',
48 p_STDBY_ENABLE
='DISABLED',
51 p_OUTDIVIDER_MUXA
='DIVA',
52 p_CLKOP_ENABLE
='ENABLED',
53 p_CLKOP_DIV
=self
.CLKOP_DIV
, #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
54 p_CLKOS_DIV
=self
.CLKOS_DIV
,
55 p_CLKOS2_DIV
=self
.CLKOS2_DIV
,
56 p_CLKOS3_DIV
=self
.CLKOS3_DIV
,
57 p_CLKFB_DIV
=self
.CLKFB_DIV
, #25
58 p_CLKI_DIV
=self
.CLKI_DIV
, #6
59 p_FEEDBK_PATH
='USERCLOCK',
75 o_CLKOS2
=self
.clkout3
,
76 o_CLKOS3
=self
.clkout4
,
82 with m
.If(self
.clksel
== 0):
83 m
.d
.comb
+= clkfb
.eq(self
.clkout1
)
84 with m
.Elif(self
.clksel
== 1):
85 m
.d
.comb
+= clkfb
.eq(self
.clkout2
)
86 with m
.Elif(self
.clksel
== 2):
87 m
.d
.comb
+= clkfb
.eq(self
.clkout3
)
89 m
.d
.comb
+= clkfb
.eq(self
.clkout4
)
92 class SysClocker(Elaboratable
):
93 def elaborate(self
, platform
):
96 m
.submodules
.pll
= pll
= PLL(ClockSignal("sync"), CLKI_DIV
=1, CLKFB_DIV
=2, CLK1_DIV
=2, CLK2_DIV
=16)
97 cd_sys2x
= ClockDomain("sys2x", local
=False)
98 m
.d
.comb
+= cd_sys2x
.clk
.eq(pll
.clkout1
)
101 cd_init
= ClockDomain("init", local
=False)
102 m
.d
.comb
+= cd_init
.clk
.eq(pll
.clkout2
)
107 class DDR3SoC(CPUSoC
, Elaboratable
):
108 def __init__(self
, *, reset_addr
, clk_freq
,
111 uart_addr
, uart_divisor
, uart_pins
,
112 timer_addr
, timer_width
,
113 ddrphy_addr
, dramcore_addr
):
114 self
._arbiter
= wishbone
.Arbiter(addr_width
=30, data_width
=32, granularity
=8,
115 features
={"cti", "bte"})
116 self
._decoder
= wishbone
.Decoder(addr_width
=30, data_width
=32, granularity
=8,
117 features
={"cti", "bte"})
119 self
.cpu
= MinervaCPU(reset_address
=reset_addr
)
120 self
._arbiter
.add(self
.cpu
.ibus
)
121 self
._arbiter
.add(self
.cpu
.dbus
)
123 self
.rom
= SRAMPeripheral(size
=rom_size
, writable
=False)
124 self
._decoder
.add(self
.rom
.bus
, addr
=rom_addr
)
126 self
.ram
= SRAMPeripheral(size
=ram_size
)
127 self
._decoder
.add(self
.ram
.bus
, addr
=ram_addr
)
129 self
.uart
= AsyncSerialPeripheral(divisor
=uart_divisor
, pins
=uart_pins
)
130 self
._decoder
.add(self
.uart
.bus
, addr
=uart_addr
)
132 self
.timer
= TimerPeripheral(width
=timer_width
)
133 self
._decoder
.add(self
.timer
.bus
, addr
=timer_addr
)
135 self
.intc
= GenericInterruptController(width
=len(self
.cpu
.ip
))
136 self
.intc
.add_irq(self
.timer
.irq
, 0)
137 self
.intc
.add_irq(self
.uart
.irq
, 1)
139 self
.ddrphy
= ECP5DDRPHY(platform
.request("ddr3", 0))
140 self
._decoder
.add(self
.ddrphy
.bus
, addr
=ddrphy_addr
)
142 ddrmodule
= MT41K256M16(clk_freq
, "1:4")
144 self
.dramcore
= gramCore(
146 geom_settings
= ddrmodule
.geom_settings
,
147 timing_settings
= ddrmodule
.timing_settings
,
149 #self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
151 self
.memory_map
= self
._decoder
.bus
.memory_map
153 self
.clk_freq
= clk_freq
155 def elaborate(self
, platform
):
158 m
.submodules
.arbiter
= self
._arbiter
159 m
.submodules
.cpu
= self
.cpu
161 m
.submodules
.decoder
= self
._decoder
162 m
.submodules
.rom
= self
.rom
163 m
.submodules
.ram
= self
.ram
164 m
.submodules
.uart
= self
.uart
165 m
.submodules
.timer
= self
.timer
166 m
.submodules
.intc
= self
.intc
167 m
.submodules
.ddrphy
= self
.ddrphy
169 m
.submodules
.sysclk
= SysClocker()
172 self
._arbiter
.bus
.connect(self
._decoder
.bus
),
173 self
.cpu
.ip
.eq(self
.intc
.ip
),
179 if __name__
== "__main__":
180 platform
= ECPIX5Platform()
182 uart_divisor
= int(platform
.default_clk_frequency
// 115200)
183 uart_pins
= platform
.request("uart", 0)
186 reset_addr
=0x00000000, clk_freq
=int(platform
.default_clk_frequency
),
187 rom_addr
=0x00000000, rom_size
=0x4000,
188 ram_addr
=0x00004000, ram_size
=0x1000,
189 uart_addr
=0x00005000, uart_divisor
=uart_divisor
, uart_pins
=uart_pins
,
190 timer_addr
=0x00006000, timer_width
=32,
191 ddrphy_addr
=0x00007000, dramcore_addr
=0x00008000
194 soc
.build(do_build
=True, do_init
=True)
195 platform
.build(soc
, do_program
=True)