5ca7ba9065fcc4f7e038e2c74375f7cc7e4fa6b3
3 * PLL @ 300mhz input generates a div-6 "test" output
4 * clock select sets the source
5 - 0b000 - CLK_24 (direct)
11 - 0b110 - ZERO (direct driving in combination with ONE)
13 * this is all assumed to be driven by the "PLL CLK".
14 the CLK_24 is the default in case PLL is unstable
17 from nmigen
import (Module
, Array
, Signal
, Mux
, Elaboratable
, ClockSignal
,
19 from nmigen
.cli
import rtlil
21 CLK_24
= 0b000 # this is the default (clk_sel_i = 0 on reset)
31 class ClockSelect(Elaboratable
):
34 self
.clk_24_i
= Signal() # 24 mhz external incoming
35 self
.pll_48_o
= Signal() # 6-divide (test signal) from PLL
36 self
.clk_sel_i
= Signal(3) # clock source selection
37 self
.core_clk_o
= Signal() # main core clock (selectable)
39 def elaborate(self
, platform
):
41 comb
, sync
= m
.d
.comb
, m
.d
.sync
43 # array of clocks (selectable by clk_sel_i)
44 clkgen
= Array([Signal(name
="clk%d" % i
) for i
in range(8)])
45 counter3
= Signal(2) # for divide-by-3
47 # set up system, zero and one clocks
48 comb
+= clkgen
[CLK_24
].eq(self
.clk_24_i
) # 1st is external 24mhz
49 comb
+= clkgen
[ZERO
].eq(0) # LOW (use with ONE for direct driving)
50 comb
+= clkgen
[ONE
].eq(1) # HI
52 # (always) generate PLL-driven signals: /2/3/4/6
53 sync
+= clkgen
[PLL2
].eq(~clkgen
[PLL2
]) # half PLL rate
54 with m
.If(clkgen
[PLL2
]):
55 sync
+= clkgen
[PLL4
].eq(~clkgen
[PLL4
]) # quarter PLL rate
56 with m
.If(counter3
== 2):
57 sync
+= counter3
.eq(0)
58 sync
+= clkgen
[PLL3
].eq(~clkgen
[PLL3
]) # 1/3 PLL rate
59 with m
.If(clkgen
[PLL3
]):
60 sync
+= clkgen
[PLL6
].eq(~clkgen
[PLL6
]) # 1/6 PLL rate
62 sync
+= counter3
.eq(counter3
+1)
64 # select from available array of clock sources
65 comb
+= self
.core_clk_o
.eq(clkgen
[self
.clk_sel_i
])
67 # 48mhz output is PLL/6
68 comb
+= self
.pll_48_o
.eq(clkgen
[PLL6
])
73 return [self
.clk_24_i
, self
.pll_48_o
, self
.clk_sel_i
, self
.core_clk_o
]
76 class DummyPLL(Elaboratable
):
78 self
.clk_24_i
= Signal() # 24 mhz external incoming
79 self
.clk_pll_o
= Signal() # output fake PLL clock
81 def elaborate(self
, platform
):
83 m
.d
.comb
+= self
.clk_pll_o
.eq(self
.clk_24_i
) # just pass through
88 return [self
.clk_24_i
, self
.clk_pll_o
]
91 if __name__
== '__main__':
94 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
95 with
open("test_clk_sel.il", "w") as f
: