diff --git a/fpga/icebreaker_vga.dg b/fpga/icebreaker_vga.dg index 2033581..c364eee 100644 --- a/fpga/icebreaker_vga.dg +++ b/fpga/icebreaker_vga.dg @@ -1,43 +1,12 @@ -import "/collections/namedtuple" -import "/nmigen/lib/cdc/ResetSynchronizer" import "/nmigen_boards.icebreaker/ICEBreakerPlatform" import "/nmigen_dg/*" -import "/subprocess" import "/sys" -import "common/pipeline" import "common/to_signed" import "modules/vga/DviController12" +import "stdio/ice40pll/add_domain_from_pll" import "resources/pmod" -run_icepll = current target -> - current /= 1e6 # Hz -> MHz - target /= 1e6 # Hz -> MHz - out = subprocess.run ["icepll", "-i", str current, "-o", str target] - capture_output: True - check: True - - get_field = field substring:None -> - pipeline out.stdout.decode!.splitlines! - bind filter $ x -> x.startswith field - if - substring => bind filter $ x -> substring in x - otherwise => x -> x # nop - head - str.split - tail - head - - (namedtuple "icepll_config" "FEEDBACK FILTER_RANGE DIVR DIVF DIVQ given requested achieved") - str$ get_field "FEEDBACK" - int$ get_field "FILTER_RANGE" - int$ get_field "DIVR" - int$ get_field "DIVF" - int$ get_field "DIVQ" - (*) 1e6 $ float $ get_field "F_PLLIN" - (*) 1e6 $ float $ get_field "F_PLLOUT" "(requested)" - (*) 1e6 $ float $ get_field "F_PLLOUT" "(achieved)" - Top = subclass Elaboratable where __init__ = x y fps ~> None where @@ -48,39 +17,8 @@ Top = subclass Elaboratable where # Configure DVI controller dvi = Submodule.dvi$ DviController12 @x @y @fps - # setup PLL clock - - default_clk = platform.request platform.default_clk dir:"-" - default_freq = platform.default_clk_frequency - default_reset = if - platform.default_rst => platform.request platform.default_rst - otherwise => Const 0 - - pll_config = run_icepll - default_freq - dvi.pix_freq - print dvi.timings - print pll_config - - pll_clk, pll_lock = Signal!, Signal! - Submodule.pll$ Instance "SB_PLL40_PAD" # or "SB_PLL40_CORE" - i_PACKAGEPIN : default_clk # or i_REFERENCECLK - i_BYPASS : (Const 0) - i_RESETB : ~default_reset - o_LOCK : pll_lock - o_PLLOUTGLOBAL : pll_clk - p_FEEDBACK_PATH : pll_config.FEEDBACK - p_FILTER_RANGE : pll_config.FILTER_RANGE - p_DIVR : pll_config.DIVR - p_DIVF : pll_config.DIVF - p_DIVQ : pll_config.DIVQ - - Domains.sync = ClockDomain "sync" - Comb$ ClockSignal "sync" ::= pll_clk - - Submodule.rs$ ResetSynchronizer - ~pll_lock - domain: "sync" + # setup clock + pll_config = add_domain_from_pll platform dvi.pix_freq # Feed a picture to the DVI controller diff --git a/fpga/stdio/__init__.py b/fpga/stdio/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fpga/stdio/ice40pll.dg b/fpga/stdio/ice40pll.dg new file mode 100644 index 0000000..7c72e40 --- /dev/null +++ b/fpga/stdio/ice40pll.dg @@ -0,0 +1,68 @@ +import "/collections/namedtuple" +import "/nmigen/lib/cdc/ResetSynchronizer" +import "/nmigen_dg/*" +import "/subprocess" +import "../common/pipeline" + +run_icepll = current target -> + current /= 1e6 # Hz -> MHz + target /= 1e6 # Hz -> MHz + out = subprocess.run ["icepll", "-i", str current, "-o", str target] + capture_output: True + check: True + + get_field = field substring:None -> + pipeline out.stdout.decode!.splitlines! + bind filter $ x -> x.startswith field + if + substring => bind filter $ x -> substring in x + otherwise => x -> x # nop + head + str.split + tail + head + + (namedtuple "icepll_config" "feedback filter_range divr divf divq given requested achieved") + str$ get_field "FEEDBACK" + int$ get_field "FILTER_RANGE" + int$ get_field "DIVR" + int$ get_field "DIVF" + int$ get_field "DIVQ" + (*) 1e6 $ float $ get_field "F_PLLIN" + (*) 1e6 $ float $ get_field "F_PLLOUT" "(requested)" + (*) 1e6 $ float $ get_field "F_PLLOUT" "(achieved)" + + +add_domain_from_pll = platform target_freq domain:"sync" -> pll_config where + + default_clk = platform.request platform.default_clk dir:"-" + default_freq = platform.default_clk_frequency + default_reset = if + platform.default_rst => platform.request platform.default_rst + otherwise => Const 0 + + pll_config = run_icepll + default_freq + target_freq + print pll_config + + pll_clk = Signal! + pll_lock = Signal! + Submodule.pll$ Instance "SB_PLL40_PAD" # or "SB_PLL40_CORE" + i_PACKAGEPIN : default_clk # or i_REFERENCECLK + i_BYPASS : (Const 0) + i_RESETB : ~default_reset + o_LOCK : pll_lock + o_PLLOUTGLOBAL : pll_clk + p_FEEDBACK_PATH : pll_config.feedback + p_FILTER_RANGE : pll_config.filter_range + p_DIVR : pll_config.divr + p_DIVF : pll_config.divf + p_DIVQ : pll_config.divq + + setattr Domains domain (ClockDomain domain) + Comb$ ClockSignal domain ::= pll_clk + + Submodule.rs$ ResetSynchronizer + ~pll_lock + domain: domain