dvisampler: support differential input
[litex.git] / milkymist / m1crg / __init__.py
1 from fractions import Fraction
2
3 from migen.fhdl.std import *
4 from migen.bank.description import *
5
6 class M1CRG(Module, AutoCSR):
7 def __init__(self, pads, outfreq1x):
8 self.clock_domains.cd_sys = ClockDomain()
9 self.clock_domains.cd_sys2x_270 = ClockDomain()
10 self.clock_domains.cd_sys4x_wr = ClockDomain()
11 self.clock_domains.cd_sys4x_rd = ClockDomain()
12 self.clock_domains.cd_eth_rx = ClockDomain()
13 self.clock_domains.cd_eth_tx = ClockDomain()
14 self.clock_domains.cd_vga = ClockDomain(reset_less=True)
15
16 self.clk4x_wr_strb = Signal()
17 self.clk4x_rd_strb = Signal()
18
19 self._r_cmd_data = CSRStorage(10)
20 self._r_send_cmd_data = CSR()
21 self._r_send_go = CSR()
22 self._r_status = CSRStatus(3)
23
24 ###
25
26 infreq = 50*1000000
27 ratio = Fraction(outfreq1x)/Fraction(infreq)
28 in_period = float(Fraction(1000000000)/Fraction(infreq))
29
30 vga_progdata = Signal()
31 vga_progen = Signal()
32 vga_progdone = Signal()
33 vga_locked = Signal()
34
35 self.specials += Instance("m1crg",
36 Instance.Parameter("in_period", in_period),
37 Instance.Parameter("f_mult", ratio.numerator),
38 Instance.Parameter("f_div", ratio.denominator),
39 Instance.Input("clk50_pad", pads.clk50),
40 Instance.Input("trigger_reset", pads.trigger_reset),
41
42 Instance.Input("eth_rx_clk_pad", pads.eth_rx_clk),
43 Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
44
45 Instance.Output("sys_clk", self.cd_sys.clk),
46 Instance.Output("sys_rst", self.cd_sys.rst),
47 Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
48 Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
49 Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
50 Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
51 Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
52 Instance.Output("vga_clk", self.cd_vga.clk),
53
54 Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
55 Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
56 Instance.Output("norflash_rst_n", pads.norflash_rst_n),
57 Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
58 Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
59 Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk),
60 Instance.Output("vga_clk_pad", pads.vga_clk),
61
62 Instance.Input("vga_progclk", ClockSignal()),
63 Instance.Input("vga_progdata", vga_progdata),
64 Instance.Input("vga_progen", vga_progen),
65 Instance.Output("vga_progdone", vga_progdone),
66 Instance.Output("vga_locked", vga_locked))
67
68 remaining_bits = Signal(max=11)
69 transmitting = Signal()
70 self.comb += transmitting.eq(remaining_bits != 0)
71 sr = Signal(10)
72 self.sync += [
73 If(self._r_send_cmd_data.re,
74 remaining_bits.eq(10),
75 sr.eq(self._r_cmd_data.storage)
76 ).Elif(transmitting,
77 remaining_bits.eq(remaining_bits - 1),
78 sr.eq(sr[1:])
79 )
80 ]
81 self.comb += [
82 vga_progdata.eq(transmitting & sr[0]),
83 vga_progen.eq(transmitting | self._r_send_go.re)
84 ]
85
86 # enforce gap between commands
87 busy_counter = Signal(max=14)
88 busy = Signal()
89 self.comb += busy.eq(busy_counter != 0)
90 self.sync += If(self._r_send_cmd_data.re,
91 busy_counter.eq(13)
92 ).Elif(busy,
93 busy_counter.eq(busy_counter - 1)
94 )
95
96 self.comb += self._r_status.status.eq(Cat(busy, vga_progdone, vga_locked))