migen: take nmigen place

master
occheung 2020-08-09 02:03:47 +08:00
parent 37d960669a
commit 3793d6d67c
7 changed files with 176 additions and 43 deletions

34
migen/fpga_config.py Normal file
View File

@ -0,0 +1,34 @@
from humpback import HumpbackPlatform
from migen.fhdl.module import Module
class UrukulConnector(Module):
def __init__(self, platform):
# Request EEM I/O & SPI
eem = platform.request("eem", 1)
spi = platform.request("spi")
# Assert signal length
assert len(eem.p) == 8
assert len(eem.n) == 8
assert len(spi.sclk) == 1
assert len(spi.mosi) == 1
assert len(spi.miso) == 1
assert len(spi.cs) == 3
# Flip positive signal as negative output
self.comb += eem.n.eq(~eem.p)
# Link EEM to SPI
self.comb += [
eem.p[0].eq(spi.sclk),
eem.p[1].eq(spi.mosi),
eem.p[2].eq(spi.miso),
eem.p[3].eq(spi.cs[0]),
eem.p[4].eq(spi.cs[1]),
eem.p[5].eq(spi.cs[2]),
]
if __name__ == "__main__":
platform = HumpbackPlatform()
platform.build(UrukulConnector(platform))

42
migen/humpback.py Normal file
View File

@ -0,0 +1,42 @@
# Import built in I/O, Connectors & Platform template
from migen.build.platforms.sinara.humpback import _io, _connectors, Platform
# Import migen platform for Lattice Products
from migen.build.lattice import LatticePlatform
# Import migen pin record structure
from migen.build.generic_platform import *
# Modify the SPI record, to include all 3 CS pins
'''
sclk -> PA5 : C8
mosi -> PB5 : N5
miso -> PA6 : T2
cs_0 -> PB12: B13
cs_1 -> PA15: B14
cs_2 -> PC7 : B15
'''
# Filter out SPI record
_io = [record for record in _io if record[0] != "spi"]
# Reinsert new SPI record
_io.append(
("spi", 0,
Subsignal("cs" , Pins("B13 B14 B15")),
Subsignal("sclk", Pins("C8")),
Subsignal("mosi", Pins("N5")),
Subsignal("miso", Pins("T2")),
IOStandard("LVCMOS33"),
)
)
# Inherit Platform to gain the programmed clock attribute
class HumpbackPlatform(Platform):
def __init__(self):
LatticePlatform.__init__(self, "ice40-hx8k-ct256", _io, _connectors, toolchain="icestorm")
# Syntax check for direct execution
if __name__ == "__main__":
platform = HumpbackPlatform()

22
nix/migen.nix Normal file
View File

@ -0,0 +1,22 @@
{ stdenv, fetchFromGitHub, python3Packages }:
python3Packages.buildPythonPackage rec {
name = "migen";
src = fetchFromGitHub {
owner = "m-labs";
repo = "migen";
rev = "7bc4eb1387b39159a74c1dbd1b820728e0bfbbaa";
sha256 = "039jk8y7f0vhr32svg3nd23i88c0bhws8ngxwk9bdznfxvhiy1h6";
fetchSubmodules = true;
};
propagatedBuildInputs = with python3Packages; [ colorama ];
meta = with stdenv.lib; {
description = "A refreshed Python toolbox for building complex digital hardware";
homepage = "https://m-labs.hk";
license = licenses.bsd2;
maintainers = [ maintainers.sb0 ];
};
}

View File

@ -6,19 +6,38 @@ from nmigen import *
from humpback import *
class SimpleBlink(Elaboratable):
def elaborate(self, platform):
led = platform.request("user_led", 0)
counter = Signal(24)
pin = platform.request("gpioa", 0)
#class SimpleBlinky(Elaboratable):
# def elaborate(self, platform):
# led = platform.request("user_led", 0)
# counter = Signal(24)
# m = Module()
# m.d.sync += counter.eq(counter + 1)
# m.d.comb += led.o.eq(counter[23])
# return m
# Simple connector from STM32 SPI to Humpback SPI
class UrukulConnector(Elaboratable):
def elaborate(self, platform):
# Acquire SPI slave, EEM port 1 output
spi = platform.request("spi")
print(spi)
eem = platform.request("eem", 1)
print(eem)
clk25 = platform.request("clk25")
counter = Signal(25)
m = Module()
m.domains.sync = ClockDomain()
m.d.comb += ClockSignal().eq(clk25.i)
m.d.sync += counter.eq(counter + 1)
return m
m = Module()
m.d.sync += counter.eq(counter + 1)
m.d.comb += led.o.eq(counter[23])
m.d.comb += pin.o.eq(led)
return m
if __name__ == "__main__":
platform = HumpbackPlatform()
platform.build(SimpleBlink(), do_program=False)
platform = HumpbackPlatform()
platform.add_resources(platform.eem_to_urukul)
platform.add_resources(platform.spi)
platform.build(UrukulConnector(), do_program=False)

View File

@ -285,27 +285,49 @@ class HumpbackPlatform(LatticeICE40Platform):
}),
]
# Half completed, second EEM resource to be added
# Appears that DiffPairs cause build problem
# eem_to_urukul_diffpairs = [
# Resource("eem", 1,
# Subsignal("sclk", DiffPairs("L6", "L3", dir="o")),
# Subsignal("mosi", DiffPairs("H6", "F1", dir="o")),
# Subsignal("miso", DiffPairs("H4", "G2", dir="i"),
# Attrs(IO_STANDARD="SB_LVDS_INPUT")),
# Subsignal("cs", DiffPairs("K1 J2 J4", "K3 J1 H2", dir="o")),
# Subsignal("io_update", DiffPairs("L4", "L1", dir="o")),
# Subsignal("sync_out", DiffPairs("K4", "M1", dir="o")),
# Attrs(IO_STANDARD="SB_LVCMOS")
# )
# ]
eem_to_urukul = [
Resource("eem", 1,
Subsignal("sclk", DiffPairs("L6", "L3", dir="o", conn=("eem", 1))),
Subsignal("mosi", DiffPairs("H6", "F1", dir="o", conn=("eem", 1))),
Subsignal("miso", DiffPairs("H4", "G2", dir="i", conn=("eem", 1)),
Attrs(IO_STANDARD="SB_LVDS_INPUT")),
Subsignal("cs", DiffPairs("J4 J2 K1", "H2 J1 K3", dir="o", conn=("eem", 1))),
Subsignal("io_update", DiffPairs("L4", "L1", dir="o", conn=("eem", 1))),
Subsignal("sync_out", DiffPairs("K4", "M1", dir="o", conn=("emm", 1))),
Attrs(IO_STANDARD="SB_LVCMOS")
)
Subsignal("sclk_p", Pins("L6", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("sclk_n", Pins("L3", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
# Subsignal("sclk", DiffPairs("L6", "L3", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("mosi_p", Pins("H6", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("mosi_n", Pins("F1", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
# Subsignal("miso_p", Pins("H4", dir="i"), Attrs(IO_STANDARD="SB_IDK")),
# Subsignal("miso_n", Pins("G2", dir="i"), Attrs(IO_STANDARD="SB_LOL")),
Subsignal("miso", DiffPairs("H4", "G2", dir="i"), Attrs(IO_STANDARD="SB_LVDS_INPUT")),
Subsignal("cs_p", Pins("J4 J2 K1", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("cs_n", Pins("H2 J1 K3", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("io_update_p", Pins("L4", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("io_update_n", Pins("L1", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("sync_out_p", Pins("K4", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
Subsignal("sync_out_n", Pins("M1", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")),
),
]
# SPI Connection
# SPI Connection to Urukul, using (PD14, PA15, PC7) as connection pins
spi = [
Resource("spi", 0,
Subsignal("cs", PinsN("R2", dir="i", conn=("stm32", 0))),
Subsignal("mosi", Pins("N5", dir="i", conn=("stm32", 0))),
Subsignal("miso", Pins("T2", dir="oe", conn=("stm32", 0))),
Subsignal("sck", Pins("C8", dir="i", conn=("stn32", 0))),
Subsignal("cs", Pins("R2 B14 B15", dir="i")),
Subsignal("mosi", Pins("N5", dir="i")),
Subsignal("miso", Pins("T2", dir="oe")),
Subsignal("sck", Pins("C8", dir="i"),
Attrs(GLOBAL=True)),
Attrs(IO_STANDARD="SB_LVCMOS")
)
]
@ -315,11 +337,3 @@ class HumpbackPlatform(LatticeICE40Platform):
iceprog = os.environ.get("ICEPROG", "iceprog")
with products.extract("{}.bin".format(name)) as bitstream_filename:
subprocess.check_call([iceprog, "-S", bitstream_filename])
if __name__ == "__main__":
from nmigen_boards.test.blinky import *
platform = HumpbackPlatform()
platform.add_resources(platform.eem_to_urukul)
platform.add_resources(platform.spi)
platform.build(Blinky(), do_program=False)

View File

@ -1,7 +1,7 @@
from nmigen.build import *
__all__ = ["I2CResource", "GPIOResources", "DiffResources"]
__all__ = ["I2CResource"]
def I2CResource(*args, sda, scl, conn=None, attrs=None, role="host"):
@ -22,6 +22,7 @@ def I2CResource(*args, sda, scl, conn=None, attrs=None, role="host"):
io.append(attrs)
return Resource.family(*args, default_name="i2c", ios=io)
'''
# Auto create a resource list given a set of iCE40 pins and STM32 pin names (pins_dict)
def GPIOResources(*args, pins_dict, dir = "o", invert=False, conn=None, attrs=None):
@ -79,8 +80,7 @@ if __name__ == "__main__":
DiffResources(eem_pins = eem, dir = "o",
attrs=Attrs(IO_STANDARD="SB_LVCMOS")
)
'''

View File

@ -3,11 +3,13 @@ let
pkgs = import <nixpkgs> {overlays = [mozillaOverlay];};
in with pkgs;
let
nmigen = callPackage ./nix/nmigen.nix {};
nmigen-boards = callPackage ./nix/nmigen-boards.nix { inherit nmigen; };
openocd = callPackage ./nix/openocd.nix {};
rustPlatform = callPackage ./nix/rustPlatform.nix {};
itm = callPackage ./nix/itm.nix {inherit rustPlatform;};
migen = callPackage ./nix/migen.nix {};
# nMigen support for DiffPairs and IO_STANDARD="SB_LVDS_INPUT" seems questionable
nmigen = callPackage ./nix/nmigen.nix {};
nmigen-boards = callPackage ./nix/nmigen-boards.nix { inherit nmigen; };
openocd = callPackage ./nix/openocd.nix {};
rustPlatform = callPackage ./nix/rustPlatform.nix {};
itm = callPackage ./nix/itm.nix {inherit rustPlatform;};
runOpenOcd = writeShellScriptBin "run-openocd" ''
openocd \
@ -70,7 +72,7 @@ in
stdenv.mkDerivation {
name = "nix-shell";
buildInputs = with rustPlatform.rust; [
(pkgs.python3.withPackages(ps: [nmigen nmigen-boards]))
(pkgs.python3.withPackages(ps: [ migen nmigen nmigen-boards]))
pkgs.yosys
pkgs.nextpnr
pkgs.icestorm