not for any good reason, separate adding the uart16550 verilog source
[ls2.git] / examples / crg.py
1 # Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2 # Copyright (c) 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3
4 from nmigen import (Module, Elaboratable, Instance, Signal, ClockDomain,
5 ClockSignal, ResetSignal)
6
7 __ALL__ = ["ECPIX5CRG"]
8
9
10 class PLL(Elaboratable):
11 def __init__(self, clkin, clksel=Signal(shape=2, reset=2),
12 clkout1=Signal(), clkout2=Signal(),
13 clkout3=Signal(), clkout4=Signal(), lock=Signal(),
14 CLKI_DIV=1, CLKFB_DIV=2, CLK1_DIV=3, CLK2_DIV=24):
15 self.clkin = clkin
16 self.clkout1 = clkout1
17 self.clkout2 = clkout2
18 self.clkout3 = clkout3
19 self.clkout4 = clkout4
20 self.clksel = clksel
21 self.lock = lock
22 self.CLKI_DIV = CLKI_DIV
23 self.CLKFB_DIV = CLKFB_DIV
24 self.CLKOP_DIV = CLK1_DIV
25 self.CLKOS_DIV = CLK2_DIV
26 self.ports = [
27 self.clkin,
28 self.clkout1,
29 self.clkout2,
30 self.clkout3,
31 self.clkout4,
32 self.clksel,
33 self.lock,
34 ]
35
36 def elaborate(self, platform):
37 clkfb = Signal()
38 pll = Instance("EHXPLLL",
39 p_OUTDIVIDER_MUXA='DIVA',
40 p_OUTDIVIDER_MUXB='DIVB',
41 p_CLKOP_ENABLE='ENABLED',
42 p_CLKOS_ENABLE='ENABLED',
43 p_CLKOS2_ENABLE='DISABLED',
44 p_CLKOS3_ENABLE='DISABLED',
45 p_CLKOP_DIV=self.CLKOP_DIV,
46 p_CLKOS_DIV=self.CLKOS_DIV,
47 p_CLKFB_DIV=self.CLKFB_DIV,
48 p_CLKI_DIV=self.CLKI_DIV,
49 p_FEEDBK_PATH='INT_OP',
50 p_CLKOP_TRIM_POL="FALLING",
51 p_CLKOP_TRIM_DELAY=0,
52 p_CLKOS_TRIM_POL="FALLING",
53 p_CLKOS_TRIM_DELAY=0,
54 i_CLKI=self.clkin,
55 i_RST=0,
56 i_STDBY=0,
57 i_PHASESEL0=0,
58 i_PHASESEL1=0,
59 i_PHASEDIR=0,
60 i_PHASESTEP=0,
61 i_PHASELOADREG=0,
62 i_PLLWAKESYNC=0,
63 i_ENCLKOP=1,
64 i_ENCLKOS=1,
65 i_ENCLKOS2=0,
66 i_ENCLKOS3=0,
67 o_CLKOP=self.clkout1,
68 o_CLKOS=self.clkout2,
69 o_CLKOS2=self.clkout3,
70 o_CLKOS3=self.clkout4,
71 o_LOCK=self.lock,
72 )
73 m = Module()
74 m.submodules += pll
75 return m
76
77
78 class ECPIX5CRG(Elaboratable):
79 def __init__(self):
80 ...
81
82 def elaborate(self, platform):
83 m = Module()
84
85 # Get 100Mhz from oscillator
86 clk100 = platform.request("clk100")
87 cd_rawclk = ClockDomain("rawclk", local=True, reset_less=True)
88 m.d.comb += cd_rawclk.clk.eq(clk100)
89 m.domains += cd_rawclk
90
91 # Reset
92 reset = platform.request(platform.default_rst).i
93 gsr0 = Signal()
94 gsr1 = Signal()
95
96 m.submodules += [
97 Instance("FD1S3AX", p_GSR="DISABLED", i_CK=ClockSignal("rawclk"),
98 i_D=~reset, o_Q=gsr0),
99 Instance("FD1S3AX", p_GSR="DISABLED", i_CK=ClockSignal("rawclk"),
100 i_D=gsr0, o_Q=gsr1),
101 Instance("SGSR", i_CLK=ClockSignal("rawclk"), i_GSR=gsr1),
102 ]
103
104 # Power-on delay (655us)
105 podcnt = Signal(16, reset=2**16-1)
106 pod_done = Signal()
107 with m.If(podcnt != 0):
108 m.d.rawclk += podcnt.eq(podcnt-1)
109 m.d.rawclk += pod_done.eq(podcnt == 0)
110
111 # Generating sync2x (200Mhz) and init (25Mhz) from clk100
112 cd_sync2x = ClockDomain("sync2x", local=False)
113 cd_sync2x_unbuf = ClockDomain("sync2x_unbuf", local=False,
114 reset_less=True)
115 cd_init = ClockDomain("init", local=False)
116 cd_sync = ClockDomain("sync", local=False)
117 cd_dramsync = ClockDomain("dramsync", local=False)
118 m.submodules.pll = pll = PLL(ClockSignal("rawclk"),
119 CLKI_DIV=1, CLKFB_DIV=2,
120 CLK1_DIV=3, CLK2_DIV=24,
121 clkout1=ClockSignal("sync2x_unbuf"),
122 clkout2=ClockSignal("init"))
123 m.submodules += Instance("ECLKSYNCB",
124 i_ECLKI = ClockSignal("sync2x_unbuf"),
125 i_STOP = 0,
126 o_ECLKO = ClockSignal("sync2x"))
127 m.domains += cd_sync2x_unbuf
128 m.domains += cd_sync2x
129 m.domains += cd_init
130 m.domains += cd_sync
131 m.domains += cd_dramsync
132 m.d.comb += ResetSignal("init").eq(~pll.lock|~pod_done)
133 m.d.comb += ResetSignal("sync").eq(~pll.lock|~pod_done)
134 m.d.comb += ResetSignal("dramsync").eq(~pll.lock|~pod_done)
135
136 # # Generating sync (100Mhz) from sync2x
137
138 m.submodules += Instance("CLKDIVF",
139 p_DIV="2.0",
140 i_ALIGNWD=0,
141 i_CLKI=ClockSignal("sync2x"),
142 i_RST=0,
143 o_CDIVX=ClockSignal("sync"))
144 m.d.comb += ClockSignal("dramsync").eq(ClockSignal("sync"))
145
146 return m