import argparse # Import built in I/O, Connectors & Platform template for Humpback from migen.build.platforms.sinara import humpback # Import migen pin record structure from migen.build.generic_platform import * from migen.fhdl.module import Module from migen.fhdl.specials import Instance from migen.genlib.io import * class UrukulConnector(Module): def __init__(self, platform, eem_resource_name): # Include extension spi_mosi = [ ("spi_mosi", 0, Pins("B16"), IOStandard("LVCMOS33")) ] spi_cs = [ ("spi_cs", 0, Pins("B13 B14 B15"), IOStandard("LVCMOS33")) ] io_update = [ ("io_update", 0, Pins("A11"), IOStandard("LVCMOS33")) ] # Add extensions platform.add_extension(spi_cs) platform.add_extension(io_update) platform.add_extension(spi_mosi) # Request EEM I/O & SPI eem = [ platform.request(eem_resource_name, 0), platform.request(eem_resource_name, 1), # Supply EEM pin with negative polarity # See issue/PR: https://github.com/m-labs/migen/pull/181 platform.request(f"{eem_resource_name}_n", 2), platform.request(eem_resource_name, 3), platform.request(eem_resource_name, 4), platform.request(eem_resource_name, 5), platform.request(eem_resource_name, 6) ] spi = platform.request("spi") spi_mosi = platform.request("spi_mosi") spi_cs = platform.request("spi_cs") led = platform.request("user_led") io_update = platform.request("io_update") assert len(spi.clk) == 1 assert len(spi_mosi) == 1 assert len(spi.miso) == 1 assert len(spi_cs) == 3 assert len(io_update) == 1 # Flip negative input to positive output self.miso_n = Signal() # Very similar setup to Diff setup for iCE40 suggested, but gave B pin instead self.specials += Instance("SB_IO", p_PIN_TYPE=C(0b000001, 6), p_IO_STANDARD="SB_LVDS_INPUT", io_PACKAGE_PIN=eem[2], o_D_IN_0=self.miso_n ) # Link EEM to SPI self.comb += [ eem[0].p.eq(spi.clk), eem[0].n.eq(~spi.clk), eem[1].p.eq(spi_mosi), eem[1].n.eq(~spi_mosi), spi.miso.eq(~self.miso_n), eem[3].p.eq(spi_cs[0]), eem[3].n.eq(~spi_cs[0]), eem[4].p.eq(spi_cs[1]), eem[4].n.eq(~spi_cs[1]), eem[5].p.eq(spi_cs[2]), eem[5].n.eq(~spi_cs[2]), eem[6].p.eq(io_update), eem[6].n.eq(~io_update), led.eq(1) ] if __name__ == "__main__": parser = argparse.ArgumentParser(description="Build FPGA bitstream") parser.add_argument( "--eem", type=int, choices=[0, 1, 2], default=0, help="The Humpback EEM port the Urukul board is connected to." ) args = parser.parse_args() platform = humpback.Platform() platform.build(UrukulConnector(platform, f"eem{args.eem}"))