Move the iCE40 pll logic to a separate file
This commit is contained in:
parent
b865a8d19a
commit
a9c023eb6a
@ -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
|
||||
|
0
fpga/stdio/__init__.py
Normal file
0
fpga/stdio/__init__.py
Normal file
68
fpga/stdio/ice40pll.dg
Normal file
68
fpga/stdio/ice40pll.dg
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user