m-labs / nmigen

A refreshed Python toolbox for building complex digital hardware. See https://gitlab.com/nmigen/nmigen
https://nmigen.org
Other
646 stars 55 forks source link

Internal Oscillator Usage ICE40 #321

Closed jchidley closed 4 years ago

jchidley commented 4 years ago

Hi there, I own an Upduino 2.1 and Tinyfpga bx. How do I use the internal oscillators on these boards? I can see that in Migen the upduino v1 board was supported.

whitequark commented 4 years ago

Try something like:

    m = Module()
    m.domains.sync = sync = ClockDomain()
    m.submodules.osc = Instance("SB_HFOSC",
        p_CLKHF_DIV="0b00", # 48 MHz
        o_CLKHF=sync.clk
    )
jchidley commented 4 years ago

It's not helping that I am a complete beginner at this. I am getting this error:

ERROR: Unable to place cell 'osc_OSC' of type 'ICESTORM_HFOSC'

Which I really hope means something to you.

whitequark commented 4 years ago

Are you perhaps trying to use it on TinyFPGA BX? The FPGA on that board does not have oscillators.

jchidley commented 4 years ago

This is what I have right now.

from nmigen import *
import os
import subprocess

from nmigen.build import *
from nmigen.vendor.lattice_ice40 import *
from nmigen_boards.resources import *

class board(LatticeICE40Platform):
    device      = "ICE40UP5K"
    package     = "SG48"
    resources   = [
        *LEDResources(pins="41", attrs=Attrs(IO_STANDARD="SB_LVCMOS")),
    ]

    connectors  = []

    def toolchain_program(self, products, name):
        iceprog = os.environ.get("ICEPROG", "iceprog")
        with products.extract("{}.bin".format(name)) as bitstream_filename:
            subprocess.check_call([iceprog, "-S", bitstream_filename])

class Blinky(Elaboratable):
    def elaborate(self, platform):
        led   = platform.request("led", 0)
        timer = Signal(20)

        m = Module()
        m.domains.sync = sync = ClockDomain()
        m.submodules.osc = Instance(
            "SB_HFOSC",
            p_CLKHF_DIV="0b00",
            o_CLKHF=sync.clk,
        )

        m.d.sync += timer.eq(timer + 1)
        m.d.comb += led.o.eq(timer[-1])
        return m

if __name__ == "__main__":

    platform = board()
    platform.build(Blinky(), do_program=False)
whitequark commented 4 years ago

There is a typo here. This code:

    device      = "ICE40UP5K"

should be:

    device      = "iCE40UP5K"

This counts as a usability bug, feel free to open an issue over at https://github.com/nmigen/nmigen so that no one else hits it in my fork.

jchidley commented 4 years ago

Thank you! Fixing the typo fixed the fixed the ERROR: Unable to place cell 'osc_OSC' of type 'ICESTORM_HFOSC'. I had to read the email on my phone a couple of times before I noticed the incorrect case at the beginning of "iCE40UP5K"!

I still can't get blinky.py to work properly on the Upduino 2.1 board. That is down to my inexperience with both FPGAs and Python: at least I can control that bit. I can't close this issue yet but you might feel it is solved.

I might have more luck if I base the board definition on the FomuPVTPlatform one. My new Fomu should arrive in a month or so, so I can test that too.

I might switch back to the TinyFPGA BX in the meantime until I have learnt more.

jchidley commented 4 years ago

This pull request adds support for the internal oscillators on the Upduino https://github.com/nmigen/nmigen/pull/338