cores/clock: add initial NX-OSCA support.
This commit is contained in:
parent
e441bd60fa
commit
cf13833e3c
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
# Copyright (c) 2018-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# Copyright (c) 2019 Michael Betz <michibetz@gmail.com>
|
||||
# Copyright (c) 2020 Piense <piense@gmail.com>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
"""Clock Abstraction Modules"""
|
||||
|
@ -756,6 +757,86 @@ class ECP5PLL(Module):
|
|||
self.params["o_CLKO{}".format(n_to_l[n])] = clk
|
||||
self.specials += Instance("EHXPLLL", **self.params)
|
||||
|
||||
# Lattice / NX -------------------------------------------------------------------------------------
|
||||
# NOTE This clock has +/- 15% accuracy
|
||||
class NXOSCA(Module):
|
||||
nclkouts_max = 2
|
||||
clk_hf_div_range = (0, 255)
|
||||
clk_hf_freq_range = (1.76, 450e6)
|
||||
clk_hf_freq = 450e6
|
||||
|
||||
def __init__(self):
|
||||
self.logger = logging.getLogger("NXOSCA")
|
||||
self.logger.info("Creating NXOSCA.")
|
||||
|
||||
self.hf_clk_out = {}
|
||||
self.hfsdc_clk_out = {}
|
||||
self.lf_clk_out = None
|
||||
self.params = {}
|
||||
|
||||
def create_hf_clk(self, cd, freq, margin=.05):
|
||||
"""450 - 1.7 Mhz Clk"""
|
||||
(clko_freq_min, clko_freq_max) = self.clk_hf_freq_range
|
||||
assert freq >= clko_freq_min
|
||||
assert freq <= clko_freq_max
|
||||
clkout = Signal()
|
||||
self.hf_clk_out = (clkout, freq, margin)
|
||||
self.comb += cd.clk.eq(clkout)
|
||||
create_clkout_log(self.logger, cd.name, freq, margin, -1)
|
||||
|
||||
def create_hfsdc_clk(self, cd, freq, margin=.05):
|
||||
"""450 - 1.7 Mhz Clk. Can only be connected to the SEDC_CLK port of CONFIG_CLKRST_CORE"""
|
||||
(clko_freq_min, clko_freq_max) = self.clk_hf_freq_range
|
||||
assert freq >= clko_freq_min
|
||||
assert freq <= clko_freq_max
|
||||
clkout = Signal()
|
||||
self.hfsdc_clk_out = (clkout, freq, margin)
|
||||
self.comb += cd.clk.eq(clkout)
|
||||
create_clkout_log(self.logger, cd.name, freq, margin, -1)
|
||||
|
||||
def create_lf_clk(self, cd):
|
||||
"""128 kHz Clock"""
|
||||
clkout = Signal()
|
||||
self.lf_clk_out = (clkout)
|
||||
self.comb += cd.clk.eq(clkout)
|
||||
create_clkout_log(self.logger, cd.name, 128e3, 19e3, -1)
|
||||
|
||||
def compute_divisor(self, freq, margin):
|
||||
config = {}
|
||||
|
||||
for divisor in range(*self.clk_hf_div_range):
|
||||
clk_freq = self.clk_hf_freq/(divisor+1)
|
||||
if abs(clk_freq - freq) <= freq*margin:
|
||||
config["freq"] = clk_freq
|
||||
config["div"] = str(divisor)
|
||||
break
|
||||
|
||||
if config:
|
||||
compute_config_log(self.logger, config)
|
||||
return config["div"]
|
||||
|
||||
raise ValueError("Bad OSC freq.")
|
||||
|
||||
def do_finalize(self):
|
||||
if self.hf_clk_out:
|
||||
divisor = self.compute_divisor(self.hf_clk_out[1], self.hf_clk_out[2])
|
||||
self.params["i_HFOUTEN"] = 0b1
|
||||
self.params["p_HF_CLK_DIV"] = divisor
|
||||
self.params["o_HFCLKOUT"] = self.hf_clk_out[0]
|
||||
self.params["p_HF_OSC_EN"] = "ENABLED"
|
||||
|
||||
if self.hfsdc_clk_out:
|
||||
divisor = self.compute_divisor(self.hfsdc_clk_out[1], self.hfsdc_clk_out[2])
|
||||
self.params["i_HFSDSCEN"] = 0b1
|
||||
self.params["p_HF_SED_SEC_DIV"] = divisor
|
||||
self.params["o_HFSDCOUT"] = self.hfsdc_clk_out[0]
|
||||
|
||||
if self.lf_clk_out is not None:
|
||||
self.params["o_LFCLKOUT"] = self.lf_clk_out[0]
|
||||
self.params["p_LF_OUTPUT_EN"] = "ENABLED"
|
||||
|
||||
self.specials += Instance("OSCA", **self.params)
|
||||
|
||||
# Intel / Generic ---------------------------------------------------------------------------------
|
||||
|
||||
class IntelClocking(Module, AutoCSR):
|
||||
|
|
Loading…
Reference in New Issue