Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: amaranth-lang/amaranth
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 28f5eba9fb31
Choose a base ref
...
head repository: amaranth-lang/amaranth
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a0d279850e3f
Choose a head ref
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Mar 20, 2020

  1. vendor.lattice_ice40: add support for SB_[LH]FOSC as default_clk.

    These oscillators are only available on iCE40 UltraPlus devices.
    WRansohoff authored Mar 20, 2020

    Verified

    This commit was signed with the committer’s verified signature.
    JounQin JounQin
    Copy the full SHA
    a0d2798 View commit details
Showing with 45 additions and 4 deletions.
  1. +45 −4 nmigen/vendor/lattice_ice40.py
49 changes: 45 additions & 4 deletions nmigen/vendor/lattice_ice40.py
Original file line number Diff line number Diff line change
@@ -334,6 +334,17 @@ def command_templates(self):
return self._synplify_icecube2_command_templates
assert False

@property
def default_clk_constraint(self):
# Internal high-speed oscillator: 48 MHz / (2 ^ div)
if self.default_clk == "SB_HFOSC":
return Clock(48e6 / 2 ** self.hfosc_div)
# Internal low-speed oscillator: 10 KHz
elif self.default_clk == "SB_LFOSC":
return Clock(10e3)
# Otherwise, use the defined Clock resource.
return super().default_clk_constraint

def create_missing_domain(self, name):
# For unknown reasons (no errata was ever published, and no documentation mentions this
# issue), iCE40 BRAMs read as zeroes for ~3 us after configuration and release of internal
@@ -347,20 +358,50 @@ def create_missing_domain(self, name):
# (We add a margin of 5x to allow for PVT variation.) If the board includes a dedicated
# reset line, this line is ORed with the power on reset.
#
# If an internal oscillator is selected as the default clock source, the power-on-reset
# delay is increased to 100 us, since the oscillators are only stable after that long.
#
# The power-on reset timer counts up because the vendor tools do not support initialization
# of flip-flops.
if name == "sync" and self.default_clk is not None:
clk_i = self.request(self.default_clk).i
m = Module()

# Internal high-speed clock: 6 MHz, 12 MHz, 24 MHz, or 48 MHz depending on the divider.
if self.default_clk == "SB_HFOSC":
if not hasattr(self, "hfosc_div"):
raise ValueError("SB_HFOSC divider exponent (hfosc_div) must be an integer "
"between 0 and 3")
if not isinstance(self.hfosc_div, int) or self.hfosc_div < 0 or self.hfosc_div > 3:
raise ValueError("SB_HFOSC divider exponent (hfosc_div) must be an integer "
"between 0 and 3, not {!r}"
.format(self.hfosc_div))
clk_i = Signal()
m.submodules += Instance("SB_HFOSC",
i_CLKHFEN=1,
i_CLKHFPU=1,
p_CLKHF_DIV="0b{0:b}".format(self.hfosc_div),
o_CLKHF=clk_i)
delay = int(100e-6 * self.default_clk_frequency)
# Internal low-speed clock: 10 KHz.
elif self.default_clk == "SB_LFOSC":
clk_i = Signal()
m.submodules += Instance("SB_LFOSC",
i_CLKLFEN=1,
i_CLKLFPU=1,
o_CLKLF=clk_i)
delay = int(100e-6 * self.default_clk_frequency)
# User-defined clock signal.
else:
clk_i = self.request(self.default_clk).i
delay = int(15e-6 * self.default_clk_frequency)

if self.default_rst is not None:
rst_i = self.request(self.default_rst).i
else:
rst_i = Const(0)

m = Module()

# Power-on-reset domain
m.domains += ClockDomain("por", reset_less=True, local=True)
delay = int(15e-6 * self.default_clk_frequency)
timer = Signal(range(delay))
ready = Signal()
m.d.comb += ClockSignal("por").eq(clk_i)