2012-02-16 12:02:37 -05:00
|
|
|
from fractions import Fraction
|
|
|
|
|
|
|
|
from migen.fhdl.structure import *
|
2013-02-24 07:07:25 -05:00
|
|
|
from migen.fhdl.specials import Instance
|
2013-03-10 14:32:38 -04:00
|
|
|
from migen.fhdl.module import Module
|
2013-03-28 14:07:17 -04:00
|
|
|
from migen.bank.description import *
|
2012-02-16 12:02:37 -05:00
|
|
|
|
2013-03-28 14:07:17 -04:00
|
|
|
class M1CRG(Module, AutoReg):
|
2013-03-26 12:57:17 -04:00
|
|
|
def __init__(self, pads, outfreq1x):
|
2013-03-15 14:17:05 -04:00
|
|
|
self.clock_domains.cd_sys = ClockDomain()
|
|
|
|
self.clock_domains.cd_sys2x_270 = ClockDomain()
|
|
|
|
self.clock_domains.cd_sys4x_wr = ClockDomain()
|
|
|
|
self.clock_domains.cd_sys4x_rd = ClockDomain()
|
|
|
|
self.clock_domains.cd_eth_rx = ClockDomain()
|
|
|
|
self.clock_domains.cd_eth_tx = ClockDomain()
|
|
|
|
self.clock_domains.cd_vga = ClockDomain()
|
2013-03-26 12:57:17 -04:00
|
|
|
|
|
|
|
self.clk4x_wr_strb = Signal()
|
|
|
|
self.clk4x_rd_strb = Signal()
|
|
|
|
|
2013-03-28 14:07:17 -04:00
|
|
|
self._r_cmd_data = RegisterField(10)
|
|
|
|
self._r_send_cmd_data = RegisterRaw()
|
|
|
|
self._r_send_go = RegisterRaw()
|
|
|
|
self._r_status = RegisterField(3, READ_ONLY, WRITE_ONLY)
|
|
|
|
|
2013-03-26 12:57:17 -04:00
|
|
|
###
|
2012-09-10 17:47:06 -04:00
|
|
|
|
2013-03-26 12:57:17 -04:00
|
|
|
infreq = 50*1000000
|
2012-09-10 17:47:06 -04:00
|
|
|
ratio = Fraction(outfreq1x)/Fraction(infreq)
|
|
|
|
in_period = float(Fraction(1000000000)/Fraction(infreq))
|
|
|
|
|
2013-03-28 14:07:17 -04:00
|
|
|
vga_progdata = Signal()
|
|
|
|
vga_progen = Signal()
|
|
|
|
vga_progdone = Signal()
|
|
|
|
vga_locked = Signal()
|
|
|
|
|
2013-03-26 12:57:17 -04:00
|
|
|
self.specials += Instance("m1crg",
|
2012-09-10 17:47:06 -04:00
|
|
|
Instance.Parameter("in_period", in_period),
|
|
|
|
Instance.Parameter("f_mult", ratio.numerator),
|
|
|
|
Instance.Parameter("f_div", ratio.denominator),
|
2013-03-26 12:57:17 -04:00
|
|
|
Instance.Input("clk50_pad", pads.clk50),
|
|
|
|
Instance.Input("trigger_reset", pads.trigger_reset),
|
2012-09-10 17:47:06 -04:00
|
|
|
|
2013-03-26 12:57:17 -04:00
|
|
|
Instance.Input("eth_rx_clk_pad", pads.eth_rx_clk),
|
|
|
|
Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
|
2013-02-11 12:23:06 -05:00
|
|
|
|
2012-09-10 17:47:06 -04:00
|
|
|
Instance.Output("sys_clk", self.cd_sys.clk),
|
2012-09-10 18:21:07 -04:00
|
|
|
Instance.Output("sys_rst", self.cd_sys.rst),
|
|
|
|
Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
|
|
|
|
Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
|
|
|
|
Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
|
2013-02-11 12:23:06 -05:00
|
|
|
Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
|
|
|
|
Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
|
2013-03-26 12:57:17 -04:00
|
|
|
Instance.Output("vga_clk", self.cd_vga.clk),
|
|
|
|
|
|
|
|
Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
|
|
|
|
Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
|
|
|
|
Instance.Output("norflash_rst_n", pads.norflash_rst_n),
|
|
|
|
Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
|
|
|
|
Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
|
|
|
|
Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk),
|
2013-03-28 14:07:17 -04:00
|
|
|
Instance.Output("vga_clk_pad", pads.vga_clk),
|
|
|
|
|
|
|
|
Instance.Input("vga_progclk", ClockSignal()),
|
|
|
|
Instance.Input("vga_progdata", vga_progdata),
|
|
|
|
Instance.Input("vga_progen", vga_progen),
|
|
|
|
Instance.Output("vga_progdone", vga_progdone),
|
|
|
|
Instance.Output("vga_locked", vga_locked))
|
|
|
|
|
|
|
|
remaining_bits = Signal(max=11)
|
|
|
|
transmitting = Signal()
|
|
|
|
self.comb += transmitting.eq(remaining_bits != 0)
|
|
|
|
sr = Signal(10)
|
|
|
|
self.sync += [
|
|
|
|
If(self._r_send_cmd_data.re,
|
|
|
|
remaining_bits.eq(10),
|
|
|
|
sr.eq(self._r_cmd_data.field.r)
|
|
|
|
).Elif(transmitting,
|
|
|
|
remaining_bits.eq(remaining_bits - 1),
|
|
|
|
sr.eq(sr[1:])
|
|
|
|
)
|
|
|
|
]
|
|
|
|
self.comb += [
|
|
|
|
vga_progdata.eq(transmitting & sr[0]),
|
|
|
|
vga_progen.eq(transmitting | self._r_send_go.re)
|
|
|
|
]
|
|
|
|
|
|
|
|
# enforce gap between commands
|
|
|
|
busy_counter = Signal(max=14)
|
|
|
|
busy = Signal()
|
|
|
|
self.comb += busy.eq(busy_counter != 0)
|
|
|
|
self.sync += If(self._r_send_cmd_data.re,
|
|
|
|
busy_counter.eq(13)
|
|
|
|
).Elif(busy,
|
|
|
|
busy_counter.eq(busy_counter - 1)
|
|
|
|
)
|
|
|
|
|
|
|
|
self.comb += self._r_status.field.w.eq(Cat(busy, vga_progdone, vga_locked))
|