463852cf93500f23713d3377e2d021bd51c18818
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)
38 self
.rst
= Signal() # reset
40 def elaborate(self
, platform
):
42 comb
, sync
= m
.d
.comb
, m
.d
.sync
43 m
.d
.comb
+= ResetSignal().eq(self
.rst
)
45 # array of clocks (selectable by clk_sel_i)
46 clkgen
= Array([Signal(name
="clk%d" % i
) for i
in range(8)])
47 counter3
= Signal(2) # for divide-by-3
49 # set up system, zero and one clocks
50 comb
+= clkgen
[CLK_24
].eq(self
.clk_24_i
) # 1st is external 24mhz
51 comb
+= clkgen
[ZERO
].eq(0) # LOW (use with ONE for direct driving)
52 comb
+= clkgen
[ONE
].eq(1) # HI
54 # (always) generate PLL-driven signals: /2/3/4/6
55 sync
+= clkgen
[PLL2
].eq(~clkgen
[PLL2
]) # half PLL rate
56 with m
.If(clkgen
[PLL2
]):
57 sync
+= clkgen
[PLL4
].eq(~clkgen
[PLL4
]) # quarter PLL rate
58 with m
.If(counter3
== 2):
59 sync
+= counter3
.eq(0)
60 sync
+= clkgen
[PLL3
].eq(~clkgen
[PLL3
]) # 1/3 PLL rate
61 with m
.If(clkgen
[PLL3
]):
62 sync
+= clkgen
[PLL6
].eq(~clkgen
[PLL6
]) # 1/6 PLL rate
64 sync
+= counter3
.eq(counter3
+1)
66 # select from available array of clock sources
67 comb
+= self
.core_clk_o
.eq(clkgen
[self
.clk_sel_i
])
69 # 48mhz output is PLL/6
70 comb
+= self
.pll_48_o
.eq(clkgen
[PLL6
])
75 return [self
.clk_24_i
, self
.pll_48_o
, self
.clk_sel_i
, self
.core_clk_o
]
78 class DummyPLL(Elaboratable
):
80 self
.clk_24_i
= Signal() # 24 mhz external incoming
81 self
.clk_pll_o
= Signal() # output fake PLL clock
82 self
.rst
= Signal() # reset
84 def elaborate(self
, platform
):
86 m
.d
.comb
+= self
.clk_pll_o
.eq(self
.clk_24_i
) # just pass through
87 m
.d
.comb
+= ResetSignal().eq(self
.rst
)
92 if __name__
== '__main__':
95 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
96 with
open("test_clk_sel.il", "w") as f
: