import migen in litex/gen
[litex.git] / litex / soc / misoc / cores / dvi_sampler / clocking.py
1 from migen import *
2 from migen.genlib.cdc import MultiReg
3
4 from misoc.interconnect.csr import *
5
6
7 class Clocking(Module, AutoCSR):
8 def __init__(self, pads):
9 self._pll_reset = CSRStorage(reset=1)
10 self._locked = CSRStatus()
11
12 # DRP
13 self._pll_adr = CSRStorage(5)
14 self._pll_dat_r = CSRStatus(16)
15 self._pll_dat_w = CSRStorage(16)
16 self._pll_read = CSR()
17 self._pll_write = CSR()
18 self._pll_drdy = CSRStatus()
19
20 self.locked = Signal()
21 self.serdesstrobe = Signal()
22 self.clock_domains._cd_pix = ClockDomain()
23 self.clock_domains._cd_pix2x = ClockDomain()
24 self.clock_domains._cd_pix10x = ClockDomain(reset_less=True)
25
26 ###
27
28 clk_se = Signal()
29 self.specials += Instance("IBUFDS", i_I=pads.clk_p, i_IB=pads.clk_n, o_O=clk_se)
30
31 clkfbout = Signal()
32 pll_locked = Signal()
33 pll_clk0 = Signal()
34 pll_clk1 = Signal()
35 pll_clk2 = Signal()
36 pll_drdy = Signal()
37 self.sync += If(self._pll_read.re | self._pll_write.re,
38 self._pll_drdy.status.eq(0)
39 ).Elif(pll_drdy,
40 self._pll_drdy.status.eq(1)
41 )
42 self.specials += Instance("PLL_ADV",
43 p_CLKFBOUT_MULT=10,
44 p_CLKOUT0_DIVIDE=1, # pix10x
45 p_CLKOUT1_DIVIDE=5, # pix2x
46 p_CLKOUT2_DIVIDE=10, # pix
47 p_COMPENSATION="INTERNAL",
48
49 i_CLKINSEL=1,
50 i_CLKIN1=clk_se,
51 o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
52 o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
53 o_LOCKED=pll_locked, i_RST=self._pll_reset.storage,
54
55 i_DADDR=self._pll_adr.storage,
56 o_DO=self._pll_dat_r.status,
57 i_DI=self._pll_dat_w.storage,
58 i_DEN=self._pll_read.re | self._pll_write.re,
59 i_DWE=self._pll_write.re,
60 o_DRDY=pll_drdy,
61 i_DCLK=ClockSignal())
62
63 locked_async = Signal()
64 self.specials += [
65 Instance("BUFPLL", p_DIVIDE=5,
66 i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
67 o_IOCLK=self._cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
68 Instance("BUFG", i_I=pll_clk1, o_O=self._cd_pix2x.clk),
69 Instance("BUFG", i_I=pll_clk2, o_O=self._cd_pix.clk),
70 MultiReg(locked_async, self.locked, "sys")
71 ]
72 self.comb += self._locked.status.eq(self.locked)
73
74 # sychronize pix+pix2x reset
75 pix_rst_n = 1
76 for i in range(2):
77 new_pix_rst_n = Signal()
78 self.specials += Instance("FDCE", i_D=pix_rst_n, i_CE=1, i_C=ClockSignal("pix"),
79 i_CLR=~locked_async, o_Q=new_pix_rst_n)
80 pix_rst_n = new_pix_rst_n
81 self.comb += self._cd_pix.rst.eq(~pix_rst_n), self._cd_pix2x.rst.eq(~pix_rst_n)