From 7ccb0b17ba726b37da1591113495948e27f43acb Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 13 Aug 2019 08:20:45 -0400 Subject: [PATCH] Add Mercury platform. --- nmigen_boards/mercury.py | 225 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 nmigen_boards/mercury.py diff --git a/nmigen_boards/mercury.py b/nmigen_boards/mercury.py new file mode 100644 index 0000000..8f072b0 --- /dev/null +++ b/nmigen_boards/mercury.py @@ -0,0 +1,225 @@ +import os +import subprocess + +from nmigen.build import * +from nmigen.vendor.xilinx_spartan_3_6 import * +from .dev import * + + +__all__ = ["MercuryPlatform"] + + +class MercuryPlatform(XilinxSpartan3APlatform): + """ + Original Mercury Board from Micro-Nova: https://www.micro-nova.com + + Mercury Manual: https://www.micro-nova.com/s/mercury_rm.pdf + Mercury Schematic: https://www.micro-nova.com/s/mercury_schematic.pdf + + The Mercury board is often paired with an extension board called the + Baseboard, which provides an ample set of I/O for FPGA beginners. + + Baseboard Manual: https://www.micro-nova.com/s/baseboard_rm.pdf + Baseboard Schematics: https://www.micro-nova.com/s/baseboard_schematic.pdf + + Mercury and Baseboard Resources: https://www.micro-nova.com/resources-mercury + """ + + device = "xc3s200a" + package = "vq100" + speed = "4" + + default_clk = "clk50" + resources = [ + Resource("clk50", 0, Pins("P43", dir="i"), + Attrs(IOSTANDARD="LVCMOS33"), Clock(50e6)), + + Resource("user_btn", 0, Pins("P41", dir="i"), + Attrs(IOSTANDARD="LVTTL")), + + # The serial interface and flash memory have a shared SPI bus. + # FPGA is secondary. + SPIResource("spi_serial", 0, role="device", + cs="P39", clk="P53", mosi="P46", miso="P51", + attrs=Attrs(IOSTANDARD="LVTTL"), + ), + + # FPGA is primary. + *SPIFlashResources(0, + cs="P27", clk="P53", mosi="P46", miso="P51", + attrs=Attrs(IOSTANDARD="LVTTL") + ), + + # ADC over SPI- FPGA is primary. + SPIResource("spi_adc", 0, role="host", + cs="P12", clk="P9", mosi="P10", miso="P21", + attrs=Attrs(IOSTANDARD="LVTTL"), + ), + + # GPIO/SRAM Control + # 5V tolerant GPIO is shared w/ the SRAM (on 200k gate devices) using + # this pin. All GPIO except gpio:30 (and gpio:20, though see comment + # under SRAMResource) interface to the SRAM. On assertion, this signal + # will tristate the level-shifters, preventing any output on the 5V + # GPIO pins (including gpio:30 and gpio:20). + Resource("bussw_oe", 0, PinsN("P30N", dir="o"), + Attrs(IOSTANDARD="LVTTL")) + ] + + # Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO + # bus with data, peripheral-select, and control signals? + connectors = [ + Connector("gpio", 0, """P59 P60 P61 P62 P64 P57 + P56 P52 P50 P49 P85 P84 + P83 P78 P77 P65 P70 P71 + P72 P73 P5 P4 P6 P98 + P94 P93 P90 P89 P88 P86"""), # 5V I/O- LVTTL. + Connector("dio", 0, "P20 P32 P33 P34 P35 P36 P37"), # Fast 3.3V IO + # (Directly attached to FPGA)- LVCMOS33. + Connector("clkio", 0, "P40 P44"), # Clock IO (Can be used as GPIO)- + # LVCMOS33. + Connector("input", 0, "P68 P97 P7 P82"), # Input-only pins- LVCMOS33. + Connector("led", 0, "P13 P15 P16 P19"), # LEDs can be used as pins + # as well- LVTTL. + Connector("pmod", 0, "P5 P4 P6 P98 P94 P93 P90 P89") # Baseboard PMOD. + # Overlaps w/ GPIO bus. + ] + + # Some default useful extensions. Attach to platform using: + # p.add_resources(p.leds) + # pmod_btn = plat.request("user_led") + leds = [ + Resource("user_led", 0, Pins("1", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_led", 1, Pins("2", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_led", 2, Pins("3", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_led", 3, Pins("4", dir="o", conn=("led", 0)), + Attrs(IOSTANDARD="LVTTL")), + ] + + sram = [ + SRAMResource(0, + cs="P3", we="gpio_0:29", + # According to the schematic, A19/Pin 25 on the SRAM is wired to + # gpio-0:20. However, according to the SRAM's datasheet, pin 25 is + # a NC. Do not expose for now. + a=""" gpio_0:1 gpio_0:2 gpio_0:3 gpio_0:4 gpio_0:5 gpio_0:6 + gpio_0:7 gpio_0:8 gpio_0:9 gpio_0:10 gpio_0:11 gpio_0:12 + gpio_0:13 gpio_0:14 gpio_0:15 gpio_0:16 gpio_0:17 gpio_0:18 + gpio_0:19""", + d="""gpio_0:21 gpio_0:22 gpio_0:23 gpio_0:24 gpio_0:25 gpio_0:26 + gpio_0:27 gpio_0:28""", + attrs=Attrs(IOSTANDARD="LVTTL", SLEW="FAST") + ) + ] + + # The "serial port" is in fact over SPI. The creators of the board provide + # a VHDL file for talking over this interface. In light of space + # constraints and the fact that both the FT245RL and FPGA can BOTH be + # SPI primaries, however, it may be necessary to sacrifice two "high-speed" + # (DIO, INPUT) pins instead. + serial = [ + # RX: FTDI D0, TX: FTDI D1 + UARTResource(0, rx="input_0:1", tx="dio_0:1", + attrs=Attrs(IOSTANDARD="LVCMOS33")) + ] + + # The remaining peripherals only make sense w/ the Baseboard installed. + # See: http://www.micro-nova.com/mercury-baseboard/ + _user_sw = [ + Resource("user_sw", 0, Pins("1", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 1, Pins("2", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 2, Pins("3", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 3, Pins("4", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 4, Pins("5", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 5, Pins("6", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 6, Pins("7", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_sw", 7, Pins("8", dir="i", conn=("gpio", 0)), + Attrs(IOSTANDARD="LVTTL")) + ] + + _user_btn = [ + Resource("user_btn", 1, Pins("1", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_btn", 2, Pins("2", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_btn", 3, Pins("3", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")), + Resource("user_btn", 4, Pins("4", dir="i", conn=("input", 0)), + Attrs(IOSTANDARD="LVTTL")) + ] + + _vga = [ + Resource("vga_out", 0, + Subsignal("hsync", PinsN("led_0:3", dir="o")), + Subsignal("vsync", PinsN("led_0:4", dir="o")), + + Subsignal("r", Pins("dio_0:1 dio_0:2 dio_0:3", dir="o")), + Subsignal("g", Pins("dio_0:4 dio_0:5 dio_0:6", dir="o")), + Subsignal("b", Pins("dio_0:7 clkio_0:1", dir="o")), + Attrs(IOSTANDARD="LVCMOS33", SLEW="FAST") + ) + ] + + _extclk = [ + Resource("extclk", 0, Pins("1", dir="i", conn=("clkio", 1)), + Attrs(IOSTANDARD="LVCMOS33")) + ] + + _sevenseg = [ + Resource("sevenseg", 0, + Subsignal("a", PinsN("13", dir="o", conn=("gpio", 0))), + Subsignal("b", PinsN("14", dir="o", conn=("gpio", 0))), + Subsignal("c", PinsN("15", dir="o", conn=("gpio", 0))), + Subsignal("d", PinsN("16", dir="o", conn=("gpio", 0))), + Subsignal("e", PinsN("17", dir="o", conn=("gpio", 0))), + Subsignal("f", PinsN("18", dir="o", conn=("gpio", 0))), + Subsignal("g", PinsN("19", dir="o", conn=("gpio", 0))), + Subsignal("dp", PinsN("20", dir="o", conn=("gpio", 0))), + Subsignal("en", Pins("9 10 11 12", dir="o", + conn=("gpio", 0))), + Attrs(IOSTANDARD="LVTTL") + ) + ] + + _ps2 = [ + Resource("ps2", 0, + Subsignal("clk", Pins("2", dir="io", conn=("led", 0))), + Subsignal("data", Pins("1", dir="io", conn=("led", 0))), + Attrs(IOSTANDARD="LVTTL") + ) + ] + + _audio = [ + Resource("audio", 0, + Subsignal("l", Pins("30", dir="o", conn=("gpio", 0))), + Subsignal("r", Pins("29", dir="o", conn=("gpio", 0))), + Attrs(IOSTANDARD="LVTTL") + ) + ] + + baseboard_sram = _user_btn + _vga + _extclk + _ps2 + baseboard_no_sram = _user_btn + _vga + _extclk + _ps2 + \ + _user_sw + _sevenseg + _audio + + def toolchain_program(self, products, name): + # https://github.com/cr1901/mercpcl + mercpcl = os.environ.get("MERCPCL", "mercpcl") + with products.extract("{}.bin".format(name)) as bitstream_filename: + subprocess.check_call([mercpcl, bitstream_filename]) + + +if __name__ == "__main__": + from ._blinky import Blinky + plat = MercuryPlatform() + plat.add_resources(plat.leds) + plat.build(Blinky(), do_program=True) -- 2.30.2