Mixxeo support
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 4 Jul 2013 17:19:39 +0000 (19:19 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 4 Jul 2013 17:19:39 +0000 (19:19 +0200)
Makefile [deleted file]
README
build.py [deleted file]
jtag.py [new file with mode: 0644]
load.jtag [deleted file]
make.py [new file with mode: 0755]
milkymist/m1crg/__init__.py [deleted file]
milkymist/mxcrg/__init__.py [new file with mode: 0644]
top.py
verilog/m1crg/m1crg.v [deleted file]
verilog/mxcrg/mxcrg.v [new file with mode: 0644]

diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 0e60158..0000000
--- a/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-RM ?= rm -f
-
-all: build/soc.bit build/soc.fpg
-
-build/soc.bit build/soc.bin:
-       ./build.py
-
-build/soc.fpg: build/soc.bin
-       $(MAKE) -C tools
-       tools/byteswap $< $@
-
-load: build/soc.bit
-       jtag -n load.jtag
-
-flash: build/soc.fpg
-       m1nor-ng build/soc.fpg
-
-clean:
-       $(RM) -r build/*
-
-.PHONY: all load clean flash
diff --git a/README b/README
index 183d61149bde659bfdde9fa01890dfc81a807b03..1475e615f64444a2215c12cf8d4be57dce3cd248 100644 (file)
--- a/README
+++ b/README
@@ -2,17 +2,16 @@
 ------------------------------
 
 This is the next-generation Milkymist(tm) system-on-chip design,
-introducing two key innovations:
+introducing two key features:
  * Built on the powerful Migen VLSI logic design system.
- * Increased system memory performance thanks to a new architecture
-   (ASMI) containing a transaction-reordering and superscalar controller.
+ * Increased system memory performance thanks to LASMI.
 
-The Milkymist-NG SoC supports the Milkymist One board. Obtain yours at:
-  http://milkymist.org
+This translates to more development productivity, better video resolution
+and quality, ease of designing complex hardware accelerators, and much
+more flexibility in hardware designs.
 
-Note that the -NG version is still experimental work in progress. For the
-production version of Milkymist SoC, visit:
-  https://github.com/milkymist/milkymist
+The Milkymist-NG SoC supports the Mixxeo and the Milkymist One.
+Obtain yours at http://milkymist.org
 
 [> Instructions (software)
 --------------------------
@@ -50,15 +49,11 @@ First, download and install Migen from:
   https://github.com/milkymist/migen
 
 Once this is done, build the bitstream with:
-  make
-This will generate the build/soc.bit programming file.
-Use:
-  make load
-to load it with UrJTAG.
+  ./make.py [-p <platform>] -l
+This will generate the build/soc-<platform>.bit programming file
+and load it with UrJTAG.
 
-The SoC expects a bootloader to be located in flash at 0x860000, just
-like the legacy SoC did. However, there is no binary compatibility and a
-new BIOS needs to be built and flashed for the -NG SoC.
+A new BIOS needs to be built and flashed for the -NG SoC.
 
 Enjoy!
 
diff --git a/build.py b/build.py
deleted file mode 100755 (executable)
index dc9edce..0000000
--- a/build.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-
-from mibuild.platforms import m1
-from mibuild.tools import write_to_file
-
-from milkymist import cif
-
-import top
-
-def main():
-       platform = m1.Platform()
-       soc = top.SoC(platform)
-       
-       platform.add_platform_command("""
-NET "{clk50}" TNM_NET = "GRPclk50";
-TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
-""", clk50=platform.lookup_request("clk50"))
-
-       platform.add_platform_command("""
-INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
-INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
-
-PIN "m1crg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
-""")
-
-       if hasattr(soc, "fb"):
-               platform.add_platform_command("""
-NET "vga_clk" TNM_NET = "GRPvga_clk";
-NET "sys_clk" TNM_NET = "GRPsys_clk";
-TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG;
-TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
-""")
-
-       if hasattr(soc, "minimac"):
-               platform.add_platform_command("""
-NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk";
-NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk";
-TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%;
-TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%;
-TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns;
-TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns;
-""",
-               phy_rx_clk=platform.lookup_request("eth_clocks").rx,
-               phy_tx_clk=platform.lookup_request("eth_clocks").tx,)
-
-       if hasattr(soc, "dvisampler0"):
-               platform.add_platform_command("""
-NET "{dviclk0}" TNM_NET = "GRPdviclk0";
-NET "{dviclk0}" CLOCK_DEDICATED_ROUTE = FALSE;
-TIMESPEC "TSdviclk0" = PERIOD "GRPdviclk0" 26.7 ns HIGH 50%;
-""", dviclk0=platform.lookup_request("dvi_in", 0).clk)
-       if hasattr(soc, "dvisampler1"):
-               platform.add_platform_command("""
-NET "{dviclk1}" TNM_NET = "GRPdviclk1";
-NET "{dviclk1}" CLOCK_DEDICATED_ROUTE = FALSE;
-TIMESPEC "TSdviclk1" = PERIOD "GRPdviclk1" 26.7 ns HIGH 50%;
-""", dviclk1=platform.lookup_request("dvi_in", 1).clk)
-       
-       for d in ["m1crg", "s6ddrphy", "minimac3"]:
-               platform.add_source_dir(os.path.join("verilog", d))
-       platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), 
-               "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
-               "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
-               "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
-               "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
-               "lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
-               "jtag_tap_spartan6.v", "lm32_itlb.v", "lm32_dtlb.v")
-       platform.add_sources(os.path.join("verilog", "lm32"), "lm32_config.v")
-
-       platform.build_cmdline(soc, build_name="soc")
-       csr_header = cif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
-       write_to_file("software/include/hw/csr.h", csr_header)
-
-if __name__ == "__main__":
-       main()
diff --git a/jtag.py b/jtag.py
new file mode 100644 (file)
index 0000000..6aeaf45
--- /dev/null
+++ b/jtag.py
@@ -0,0 +1,14 @@
+import subprocess
+
+def load(bitstream):
+       cmds = """cable milkymist
+detect
+pld load {bitstream}
+quit
+""".format(bitstream=bitstream)
+       process = subprocess.Popen("jtag", stdin=subprocess.PIPE)
+       process.stdin.write(cmds.encode("ASCII"))
+       process.communicate()
+
+def flash(bitstream):
+       subprocess.call(["m1nor-ng", bitstream])
diff --git a/load.jtag b/load.jtag
deleted file mode 100644 (file)
index c20825f..0000000
--- a/load.jtag
+++ /dev/null
@@ -1,3 +0,0 @@
-cable milkymist
-detect
-pld load build/soc.bit
diff --git a/make.py b/make.py
new file mode 100755 (executable)
index 0000000..236a9f1
--- /dev/null
+++ b/make.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+
+import argparse, os, importlib, subprocess
+
+from mibuild.tools import write_to_file
+
+from milkymist import cif
+import top, jtag
+
+def build(platform_name, build_bitstream, build_header):
+       platform_module = importlib.import_module("mibuild.platforms."+platform_name)
+       platform = platform_module.Platform()
+       soc = top.SoC(platform, platform_name)
+       
+       platform.add_platform_command("""
+INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
+INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
+
+PIN "mxcrg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
+""")
+
+       if hasattr(soc, "fb"):
+               platform.add_platform_command("""
+NET "vga_clk" TNM_NET = "GRPvga_clk";
+NET "sys_clk" TNM_NET = "GRPsys_clk";
+TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG;
+TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
+""")
+
+       for d in ["mxcrg", "s6ddrphy", "minimac3"]:
+               platform.add_source_dir(os.path.join("verilog", d))
+       platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), 
+               "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
+               "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
+               "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
+               "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
+               "lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
+               "jtag_tap_spartan6.v", "lm32_itlb.v", "lm32_dtlb.v")
+       platform.add_sources(os.path.join("verilog", "lm32"), "lm32_config.v")
+
+       if build_bitstream:
+               build_name = "soc-"+platform_name
+               platform.build(soc, build_name=build_name)
+               subprocess.call(["tools/byteswap", build_name+".bin", build_name+".fpg"])
+       else:
+               soc.finalize()
+       if build_header:
+               csr_header = cif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
+               write_to_file("software/include/hw/csr.h", csr_header)
+
+def main():
+       parser = argparse.ArgumentParser(description="milkymist-ng - a high performance SoC built on Migen technology.")
+       parser.add_argument("-p", "--platform", default="mixxeo", help="platform to build for")
+       parser.add_argument("-B", "--no-bitstream", default=False, action="store_true", help="do not build bitstream file")
+       parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header file with CSR/IRQ defs")
+       parser.add_argument("-l", "--load", default=False, action="store_true", help="load bitstream to SRAM")
+       parser.add_argument("-f", "--flash", default=False, action="store_true", help="load bitstream to flash")
+       args = parser.parse_args()
+
+       build(args.platform, not args.no_bitstream, not args.no_header)
+       if args.load:
+               jtag.load("build/soc-"+args.platform+".bit")
+       if args.flash:
+               jtag.flash("build/soc-"+args.platform+".fpg")
+
+if __name__ == "__main__":
+       main()
diff --git a/milkymist/m1crg/__init__.py b/milkymist/m1crg/__init__.py
deleted file mode 100644 (file)
index e163c1b..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-from fractions import Fraction
-
-from migen.fhdl.std import *
-from migen.bank.description import *
-
-class M1CRG(Module, AutoCSR):
-       def __init__(self, pads, outfreq1x):
-               self.clock_domains.cd_sys = ClockDomain()
-               self.clock_domains.cd_sys2x_270 = ClockDomain()
-               self.clock_domains.cd_sys4x_wr = ClockDomain()
-               self.clock_domains.cd_sys4x_rd = ClockDomain()
-               self.clock_domains.cd_eth_rx = ClockDomain()
-               self.clock_domains.cd_eth_tx = ClockDomain()
-               self.clock_domains.cd_vga = ClockDomain(reset_less=True)
-
-               self.clk4x_wr_strb = Signal()
-               self.clk4x_rd_strb = Signal()
-
-               self._r_cmd_data = CSRStorage(10)
-               self._r_send_cmd_data = CSR()
-               self._r_send_go = CSR()
-               self._r_status = CSRStatus(3)
-
-               ###
-               
-               infreq = 50*1000000
-               ratio = Fraction(outfreq1x)/Fraction(infreq)
-               in_period = float(Fraction(1000000000)/Fraction(infreq))
-
-               vga_progdata = Signal()
-               vga_progen = Signal()
-               vga_progdone = Signal()
-               vga_locked = Signal()
-
-               self.specials += Instance("m1crg",
-                       Instance.Parameter("in_period", in_period),
-                       Instance.Parameter("f_mult", ratio.numerator),
-                       Instance.Parameter("f_div", ratio.denominator),
-                       Instance.Input("clk50_pad", pads.clk50),
-                       Instance.Input("trigger_reset", pads.trigger_reset),
-                       
-                       Instance.Input("eth_rx_clk_pad", pads.eth_rx_clk),
-                       Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
-                       
-                       Instance.Output("sys_clk", self.cd_sys.clk),
-                       Instance.Output("sys_rst", self.cd_sys.rst),
-                       Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
-                       Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
-                       Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
-                       Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
-                       Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
-                       Instance.Output("vga_clk", self.cd_vga.clk),
-
-                       Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
-                       Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
-                       Instance.Output("norflash_rst_n", pads.norflash_rst_n),
-                       Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
-                       Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
-                       Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk),
-                       Instance.Output("vga_clk_pad", pads.vga_clk),
-
-                       Instance.Input("vga_progclk", ClockSignal()),
-                       Instance.Input("vga_progdata", vga_progdata),
-                       Instance.Input("vga_progen", vga_progen),
-                       Instance.Output("vga_progdone", vga_progdone),
-                       Instance.Output("vga_locked", vga_locked))
-
-               remaining_bits = Signal(max=11)
-               transmitting = Signal()
-               self.comb += transmitting.eq(remaining_bits != 0)
-               sr = Signal(10)
-               self.sync += [
-                       If(self._r_send_cmd_data.re,
-                               remaining_bits.eq(10),
-                               sr.eq(self._r_cmd_data.storage)
-                       ).Elif(transmitting,
-                               remaining_bits.eq(remaining_bits - 1),
-                               sr.eq(sr[1:])
-                       )
-               ]
-               self.comb += [
-                       vga_progdata.eq(transmitting & sr[0]),
-                       vga_progen.eq(transmitting | self._r_send_go.re)
-               ]
-
-               # enforce gap between commands
-               busy_counter = Signal(max=14)
-               busy = Signal()
-               self.comb += busy.eq(busy_counter != 0)
-               self.sync += If(self._r_send_cmd_data.re,
-                               busy_counter.eq(13)
-                       ).Elif(busy,
-                               busy_counter.eq(busy_counter - 1)
-                       )
-
-               self.comb += self._r_status.status.eq(Cat(busy, vga_progdone, vga_locked))
diff --git a/milkymist/mxcrg/__init__.py b/milkymist/mxcrg/__init__.py
new file mode 100644 (file)
index 0000000..7107d02
--- /dev/null
@@ -0,0 +1,96 @@
+from fractions import Fraction
+
+from migen.fhdl.std import *
+from migen.bank.description import *
+
+class MXCRG(Module, AutoCSR):
+       def __init__(self, pads, outfreq1x):
+               self.clock_domains.cd_sys = ClockDomain()
+               self.clock_domains.cd_sys2x_270 = ClockDomain()
+               self.clock_domains.cd_sys4x_wr = ClockDomain()
+               self.clock_domains.cd_sys4x_rd = ClockDomain()
+               self.clock_domains.cd_eth_rx = ClockDomain()
+               self.clock_domains.cd_eth_tx = ClockDomain()
+               self.clock_domains.cd_vga = ClockDomain(reset_less=True)
+
+               self.clk4x_wr_strb = Signal()
+               self.clk4x_rd_strb = Signal()
+
+               self._r_cmd_data = CSRStorage(10)
+               self._r_send_cmd_data = CSR()
+               self._r_send_go = CSR()
+               self._r_status = CSRStatus(3)
+
+               ###
+               
+               infreq = 50*1000000
+               ratio = Fraction(outfreq1x)/Fraction(infreq)
+               in_period = float(Fraction(1000000000)/Fraction(infreq))
+
+               vga_progdata = Signal()
+               vga_progen = Signal()
+               vga_progdone = Signal()
+               vga_locked = Signal()
+
+               self.specials += Instance("mxcrg",
+                       Instance.Parameter("in_period", in_period),
+                       Instance.Parameter("f_mult", ratio.numerator),
+                       Instance.Parameter("f_div", ratio.denominator),
+                       Instance.Input("clk50_pad", pads.clk50),
+                       Instance.Input("trigger_reset", pads.trigger_reset),
+                       
+                       Instance.Input("eth_rx_clk_pad", pads.eth_rx_clk),
+                       Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
+                       
+                       Instance.Output("sys_clk", self.cd_sys.clk),
+                       Instance.Output("sys_rst", self.cd_sys.rst),
+                       Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
+                       Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
+                       Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
+                       Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
+                       Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
+                       Instance.Output("vga_clk", self.cd_vga.clk),
+
+                       Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
+                       Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
+                       Instance.Output("norflash_rst_n", pads.norflash_rst_n),
+                       Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
+                       Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
+                       Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk),
+                       Instance.Output("vga_clk_pad", pads.vga_clk),
+
+                       Instance.Input("vga_progclk", ClockSignal()),
+                       Instance.Input("vga_progdata", vga_progdata),
+                       Instance.Input("vga_progen", vga_progen),
+                       Instance.Output("vga_progdone", vga_progdone),
+                       Instance.Output("vga_locked", vga_locked))
+
+               remaining_bits = Signal(max=11)
+               transmitting = Signal()
+               self.comb += transmitting.eq(remaining_bits != 0)
+               sr = Signal(10)
+               self.sync += [
+                       If(self._r_send_cmd_data.re,
+                               remaining_bits.eq(10),
+                               sr.eq(self._r_cmd_data.storage)
+                       ).Elif(transmitting,
+                               remaining_bits.eq(remaining_bits - 1),
+                               sr.eq(sr[1:])
+                       )
+               ]
+               self.comb += [
+                       vga_progdata.eq(transmitting & sr[0]),
+                       vga_progen.eq(transmitting | self._r_send_go.re)
+               ]
+
+               # enforce gap between commands
+               busy_counter = Signal(max=14)
+               busy = Signal()
+               self.comb += busy.eq(busy_counter != 0)
+               self.sync += If(self._r_send_cmd_data.re,
+                               busy_counter.eq(13)
+                       ).Elif(busy,
+                               busy_counter.eq(busy_counter - 1)
+                       )
+
+               self.comb += self._r_status.status.eq(Cat(busy, vga_progdone, vga_locked))
diff --git a/top.py b/top.py
index 25fa2ea8f67ccd79b01ce433ec07927d950f262f..4935d26f24524781c8cb441799bacd4b5f58083a 100644 (file)
--- a/top.py
+++ b/top.py
@@ -6,8 +6,9 @@ from migen.fhdl.std import *
 from migen.bus import wishbone, csr, lasmibus, dfi
 from migen.bus import wishbone2lasmi, wishbone2csr
 from migen.bank import csrgen
+from mibuild.generic_platform import ConstraintError
 
-from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, lasmicon, \
+from milkymist import mxcrg, lm32, norflash, uart, s6ddrphy, dfii, lasmicon, \
        identifier, timer, minimac3, framebuffer, dvisampler, \
        counteradc, gpio
 from milkymist.cif import get_macros
@@ -51,10 +52,14 @@ sdram_timing = lasmicon.TimingSettings(
        write_time=16
 )
 
-class M1ClockPads:
+class MXClockPads:
        def __init__(self, platform):
                self.clk50 = platform.request("clk50")
-               self.trigger_reset = platform.request("user_btn", 1)
+               self.trigger_reset = 0
+               try:
+                       self.trigger_reset = platform.request("user_btn", 1)
+               except ConstraintError:
+                       pass
                self.norflash_rst_n = platform.request("norflash_rst_n")
                self.vga_clk = platform.request("vga_clock")
                ddram_clock = platform.request("ddram_clock")
@@ -93,7 +98,7 @@ class SoC(Module):
                "dvisampler1":  4,
        }
 
-       def __init__(self, platform):
+       def __init__(self, platform, platform_name):
                #
                # LASMI
                #
@@ -142,18 +147,19 @@ class SoC(Module):
                #
                # CSR
                #
-               self.submodules.crg = m1crg.M1CRG(M1ClockPads(platform), clk_freq)
+               self.submodules.crg = mxcrg.MXCRG(MXClockPads(platform), clk_freq)
                self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
                self.submodules.identifier = identifier.Identifier(0x4D31, version, int(clk_freq))
                self.submodules.timer0 = timer.Timer()
                self.submodules.fb = framebuffer.MixFramebuffer(platform.request("vga"), lasmim_fb0, lasmim_fb1)
                self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), lasmim_dvi0)
                self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), lasmim_dvi1)
-               pots_pads = platform.request("dvi_pots")
-               self.submodules.pots = counteradc.CounterADC(pots_pads.charge,
-                       [pots_pads.blackout, pots_pads.crossfade])
-               self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), platform.request("user_btn", 2)))
-               self.submodules.leds = gpio.GPIOOut(Cat(*[platform.request("user_led", i) for i in range(2)]))
+               if platform_name == "m1":
+                       pots_pads = platform.request("dvi_pots")
+                       self.submodules.pots = counteradc.CounterADC(pots_pads.charge,
+                               [pots_pads.blackout, pots_pads.crossfade])
+                       self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), platform.request("user_btn", 2)))
+                       self.submodules.leds = gpio.GPIOOut(Cat(*[platform.request("user_led", i) for i in range(2)]))
 
                self.submodules.csrbankarray = csrgen.BankArray(self,
                        lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])
diff --git a/verilog/m1crg/m1crg.v b/verilog/m1crg/m1crg.v
deleted file mode 100644 (file)
index 10e30e0..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-module m1crg #(
-       parameter in_period = 0.0,
-       parameter f_mult = 0,
-       parameter f_div = 0,
-       parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
-) (
-       input clk50_pad,
-       input trigger_reset,
-       
-       output sys_clk,
-       output reg sys_rst,
-       
-       /* Reset NOR flash */
-       output norflash_rst_n,
-       
-       /* DDR PHY clocks */
-       output clk2x_270,
-       output clk4x_wr,
-       output clk4x_wr_strb,
-       output clk4x_rd,
-       output clk4x_rd_strb,
-
-       /* DDR off-chip clocking */
-       output ddr_clk_pad_p,
-       output ddr_clk_pad_n,
-       
-       /* Ethernet PHY clocks */
-       output reg eth_phy_clk_pad,
-       input eth_rx_clk_pad,
-       input eth_tx_clk_pad,
-       output eth_rx_clk,
-       output eth_tx_clk,
-       
-       /* VGA clock */
-       output vga_clk,         /* < buffered, to internal clock network */
-       output vga_clk_pad,     /* < forwarded through ODDR2, to I/O */
-
-       /* VGA clock control */
-       input vga_progclk,
-       input vga_progdata,
-       input vga_progen,
-       output vga_progdone,
-       output vga_locked
-);
-
-/*
- * Reset
- */
-
-reg [19:0] rst_debounce;
-always @(posedge sys_clk) begin
-       if(trigger_reset)
-               rst_debounce <= 20'hFFFFF;
-       else if(rst_debounce != 20'd0)
-               rst_debounce <= rst_debounce - 20'd1;
-       sys_rst <= rst_debounce != 20'd0;
-end
-
-/*
- * We must release the Flash reset before the system reset
- * because the Flash needs some time to come out of reset
- * and the CPU begins fetching instructions from it
- * as soon as the system reset is released.
- * From datasheet, minimum reset pulse width is 100ns
- * and reset-to-read time is 150ns.
- */
-
-reg [7:0] flash_rstcounter;
-
-always @(posedge sys_clk) begin
-       if(trigger_reset)
-               flash_rstcounter <= 8'd0;
-       else if(~flash_rstcounter[7])
-               flash_rstcounter <= flash_rstcounter + 8'd1;
-end
-
-assign norflash_rst_n = flash_rstcounter[7];
-
-/*
- * Clock management. Inspired by the NWL reference design.
- */
-
-wire sdr_clk50;
-wire clkdiv;
-
-IBUF #(
-       .IOSTANDARD("DEFAULT")
-) clk2_iob (
-       .I(clk50_pad),
-       .O(sdr_clk50)
-);
-
-BUFIO2 #(
-       .DIVIDE(1),
-       .DIVIDE_BYPASS("FALSE"),
-       .I_INVERT("FALSE")
-) bufio2_inst2 (
-       .I(sdr_clk50),
-       .IOCLK(),
-       .DIVCLK(clkdiv),
-       .SERDESSTROBE()
-);
-
-wire pll_lckd;
-wire buf_pll_fb_out;
-wire pllout0;
-wire pllout1;
-wire pllout2;
-wire pllout3;
-wire pllout4;
-wire pllout5;
-
-PLL_ADV #(
-       .BANDWIDTH("OPTIMIZED"),
-       .CLKFBOUT_MULT(4*f_mult),
-       .CLKFBOUT_PHASE(0.0),
-       .CLKIN1_PERIOD(in_period),
-       .CLKIN2_PERIOD(in_period),
-
-       .CLKOUT0_DIVIDE(f_div),
-       .CLKOUT0_DUTY_CYCLE(0.5),
-       .CLKOUT0_PHASE(0.0),
-       
-       .CLKOUT1_DIVIDE(f_div),
-       .CLKOUT1_DUTY_CYCLE(0.5),
-       .CLKOUT1_PHASE(0.0),
-       
-       .CLKOUT2_DIVIDE(2*f_div),
-       .CLKOUT2_DUTY_CYCLE(0.5),
-       .CLKOUT2_PHASE(270.0),
-       
-       .CLKOUT3_DIVIDE(4*f_div),
-       .CLKOUT3_DUTY_CYCLE(0.5),
-       .CLKOUT3_PHASE(0.0),
-       
-       .CLKOUT4_DIVIDE(4*f_mult),
-       .CLKOUT4_DUTY_CYCLE(0.5),
-       .CLKOUT4_PHASE(0.0),
-       
-       .CLKOUT5_DIVIDE(2*f_div),
-       .CLKOUT5_DUTY_CYCLE(0.5),
-       .CLKOUT5_PHASE(250.0),
-       
-       .COMPENSATION("INTERNAL"),
-       .DIVCLK_DIVIDE(1),
-       .REF_JITTER(0.100),
-       .CLK_FEEDBACK("CLKFBOUT"),
-       .SIM_DEVICE("SPARTAN6")
-) pll (
-       .CLKFBDCM(),
-       .CLKFBOUT(buf_pll_fb_out),
-       .CLKOUT0(pllout0), /* < x4 clock for writes */
-       .CLKOUT1(pllout1), /* < x4 clock for reads */
-       .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */
-       .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
-       .CLKOUT4(pllout4), /* < buffered clk50 */
-       .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */
-       .CLKOUTDCM0(),
-       .CLKOUTDCM1(),
-       .CLKOUTDCM2(),
-       .CLKOUTDCM3(),
-       .CLKOUTDCM4(),
-       .CLKOUTDCM5(),
-       .DO(),
-       .DRDY(),
-       .LOCKED(pll_lckd),
-       .CLKFBIN(buf_pll_fb_out),
-       .CLKIN1(clkdiv),
-       .CLKIN2(1'b0),
-       .CLKINSEL(1'b1),
-       .DADDR(5'b00000),
-       .DCLK(1'b0),
-       .DEN(1'b0),
-       .DI(16'h0000),
-       .DWE(1'b0),
-       .RST(1'b0),
-       .REL(1'b0)
-);
-
-BUFPLL #(
-       .DIVIDE(4)
-) wr_bufpll (
-       .PLLIN(pllout0),
-       .GCLK(sys_clk),
-       .LOCKED(pll_lckd),
-       .IOCLK(clk4x_wr),
-       .LOCK(),
-       .SERDESSTROBE(clk4x_wr_strb)
-);
-
-BUFPLL #(
-       .DIVIDE(4)
-) rd_bufpll (
-       .PLLIN(pllout1),
-       .GCLK(sys_clk),
-       .LOCKED(pll_lckd),
-       .IOCLK(clk4x_rd),
-       .LOCK(),
-       .SERDESSTROBE(clk4x_rd_strb)
-);
-
-BUFG bufg_x2_2(
-       .I(pllout2),
-       .O(clk2x_270)
-);
-
-BUFG bufg_x1(
-       .I(pllout3),
-       .O(sys_clk)
-);
-
-wire clk50g;
-BUFG bufg_50(
-       .I(pllout4),
-       .O(clk50g)
-);
-
-wire clk2x_off;
-BUFG bufg_x2_offclk(
-       .I(pllout5),
-       .O(clk2x_off)
-);
-
-
-/* 
- * SDRAM clock
- */
-
-ODDR2 #(
-       .DDR_ALIGNMENT("NONE"),
-       .INIT(1'b0),
-       .SRTYPE("SYNC")
-) sd_clk_forward_p (
-       .Q(ddr_clk_pad_p),
-       .C0(clk2x_off),
-       .C1(~clk2x_off),
-       .CE(1'b1),
-       .D0(1'b1),
-       .D1(1'b0),
-       .R(1'b0),
-       .S(1'b0)
-);
-ODDR2 #(
-       .DDR_ALIGNMENT("NONE"),
-       .INIT(1'b0),
-       .SRTYPE("SYNC")
-) sd_clk_forward_n (
-       .Q(ddr_clk_pad_n),
-       .C0(clk2x_off),
-       .C1(~clk2x_off),
-       .CE(1'b1),
-       .D0(1'b0),
-       .D1(1'b1),
-       .R(1'b0),
-       .S(1'b0)
-);
-
-/*
- * Ethernet PHY 
- */
-
-always @(posedge clk50g)
-       eth_phy_clk_pad <= ~eth_phy_clk_pad;
-
-/* Let the synthesizer insert the appropriate buffers */
-assign eth_rx_clk = eth_rx_clk_pad;
-assign eth_tx_clk = eth_tx_clk_pad;
-
-/*
- * VGA clock
- */
-
-DCM_CLKGEN #(
-       .CLKFXDV_DIVIDE(2),
-       .CLKFX_DIVIDE(4),
-       .CLKFX_MD_MAX(3.0),
-       .CLKFX_MULTIPLY(2),
-       .CLKIN_PERIOD(20.0),
-       .SPREAD_SPECTRUM("NONE"),
-       .STARTUP_WAIT("FALSE")
-) vga_clock_gen (
-       .CLKFX(vga_clk),
-       .CLKFX180(),
-       .CLKFXDV(),
-       .STATUS(),
-       .CLKIN(clk50g),
-       .FREEZEDCM(1'b0),
-       .PROGCLK(vga_progclk),
-       .PROGDATA(vga_progdata),
-       .PROGEN(vga_progen),
-       .PROGDONE(vga_progdone),
-       .LOCKED(vga_locked),
-       .RST(~pll_lckd | sys_rst)
-);
-
-ODDR2 #(
-       .DDR_ALIGNMENT("NONE"),
-       .INIT(1'b0),
-       .SRTYPE("SYNC")
-) vga_clock_forward (
-       .Q(vga_clk_pad),
-       .C0(vga_clk),
-       .C1(~vga_clk),
-       .CE(1'b1),
-       .D0(1'b1),
-       .D1(1'b0),
-       .R(1'b0),
-       .S(1'b0)
-);
-endmodule
diff --git a/verilog/mxcrg/mxcrg.v b/verilog/mxcrg/mxcrg.v
new file mode 100644 (file)
index 0000000..a7dee56
--- /dev/null
@@ -0,0 +1,315 @@
+module mxcrg #(
+       parameter in_period = 0.0,
+       parameter f_mult = 0,
+       parameter f_div = 0,
+       parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
+) (
+       input clk50_pad,
+       input trigger_reset,
+       
+       output sys_clk,
+       output reg sys_rst,
+       
+       /* Reset NOR flash */
+       output norflash_rst_n,
+       
+       /* DDR PHY clocks */
+       output clk2x_270,
+       output clk4x_wr,
+       output clk4x_wr_strb,
+       output clk4x_rd,
+       output clk4x_rd_strb,
+
+       /* DDR off-chip clocking */
+       output ddr_clk_pad_p,
+       output ddr_clk_pad_n,
+       
+       /* Ethernet PHY clocks */
+       output reg eth_phy_clk_pad,
+       input eth_rx_clk_pad,
+       input eth_tx_clk_pad,
+       output eth_rx_clk,
+       output eth_tx_clk,
+       
+       /* VGA clock */
+       output vga_clk,         /* < buffered, to internal clock network */
+       output vga_clk_pad,     /* < forwarded through ODDR2, to I/O */
+
+       /* VGA clock control */
+       input vga_progclk,
+       input vga_progdata,
+       input vga_progen,
+       output vga_progdone,
+       output vga_locked
+);
+
+/*
+ * Reset
+ */
+
+reg [19:0] rst_debounce;
+always @(posedge sys_clk) begin
+       if(trigger_reset)
+               rst_debounce <= 20'hFFFFF;
+       else if(rst_debounce != 20'd0)
+               rst_debounce <= rst_debounce - 20'd1;
+       sys_rst <= rst_debounce != 20'd0;
+end
+
+initial rst_debounce <= 20'hFFFFF;
+
+/*
+ * We must release the Flash reset before the system reset
+ * because the Flash needs some time to come out of reset
+ * and the CPU begins fetching instructions from it
+ * as soon as the system reset is released.
+ * From datasheet, minimum reset pulse width is 100ns
+ * and reset-to-read time is 150ns.
+ */
+
+reg [7:0] flash_rstcounter;
+
+always @(posedge sys_clk) begin
+       if(trigger_reset)
+               flash_rstcounter <= 8'd0;
+       else if(~flash_rstcounter[7])
+               flash_rstcounter <= flash_rstcounter + 8'd1;
+end
+
+initial flash_rstcounter <= 8'd0;
+
+assign norflash_rst_n = flash_rstcounter[7];
+
+/*
+ * Clock management. Inspired by the NWL reference design.
+ */
+
+wire sdr_clk50;
+wire clkdiv;
+
+IBUF #(
+       .IOSTANDARD("DEFAULT")
+) clk2_iob (
+       .I(clk50_pad),
+       .O(sdr_clk50)
+);
+
+BUFIO2 #(
+       .DIVIDE(1),
+       .DIVIDE_BYPASS("FALSE"),
+       .I_INVERT("FALSE")
+) bufio2_inst2 (
+       .I(sdr_clk50),
+       .IOCLK(),
+       .DIVCLK(clkdiv),
+       .SERDESSTROBE()
+);
+
+wire pll_lckd;
+wire buf_pll_fb_out;
+wire pllout0;
+wire pllout1;
+wire pllout2;
+wire pllout3;
+wire pllout4;
+wire pllout5;
+
+PLL_ADV #(
+       .BANDWIDTH("OPTIMIZED"),
+       .CLKFBOUT_MULT(4*f_mult),
+       .CLKFBOUT_PHASE(0.0),
+       .CLKIN1_PERIOD(in_period),
+       .CLKIN2_PERIOD(in_period),
+
+       .CLKOUT0_DIVIDE(f_div),
+       .CLKOUT0_DUTY_CYCLE(0.5),
+       .CLKOUT0_PHASE(0.0),
+       
+       .CLKOUT1_DIVIDE(f_div),
+       .CLKOUT1_DUTY_CYCLE(0.5),
+       .CLKOUT1_PHASE(0.0),
+       
+       .CLKOUT2_DIVIDE(2*f_div),
+       .CLKOUT2_DUTY_CYCLE(0.5),
+       .CLKOUT2_PHASE(270.0),
+       
+       .CLKOUT3_DIVIDE(4*f_div),
+       .CLKOUT3_DUTY_CYCLE(0.5),
+       .CLKOUT3_PHASE(0.0),
+       
+       .CLKOUT4_DIVIDE(4*f_mult),
+       .CLKOUT4_DUTY_CYCLE(0.5),
+       .CLKOUT4_PHASE(0.0),
+       
+       .CLKOUT5_DIVIDE(2*f_div),
+       .CLKOUT5_DUTY_CYCLE(0.5),
+       .CLKOUT5_PHASE(250.0),
+       
+       .COMPENSATION("INTERNAL"),
+       .DIVCLK_DIVIDE(1),
+       .REF_JITTER(0.100),
+       .CLK_FEEDBACK("CLKFBOUT"),
+       .SIM_DEVICE("SPARTAN6")
+) pll (
+       .CLKFBDCM(),
+       .CLKFBOUT(buf_pll_fb_out),
+       .CLKOUT0(pllout0), /* < x4 clock for writes */
+       .CLKOUT1(pllout1), /* < x4 clock for reads */
+       .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */
+       .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
+       .CLKOUT4(pllout4), /* < buffered clk50 */
+       .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */
+       .CLKOUTDCM0(),
+       .CLKOUTDCM1(),
+       .CLKOUTDCM2(),
+       .CLKOUTDCM3(),
+       .CLKOUTDCM4(),
+       .CLKOUTDCM5(),
+       .DO(),
+       .DRDY(),
+       .LOCKED(pll_lckd),
+       .CLKFBIN(buf_pll_fb_out),
+       .CLKIN1(clkdiv),
+       .CLKIN2(1'b0),
+       .CLKINSEL(1'b1),
+       .DADDR(5'b00000),
+       .DCLK(1'b0),
+       .DEN(1'b0),
+       .DI(16'h0000),
+       .DWE(1'b0),
+       .RST(1'b0),
+       .REL(1'b0)
+);
+
+BUFPLL #(
+       .DIVIDE(4)
+) wr_bufpll (
+       .PLLIN(pllout0),
+       .GCLK(sys_clk),
+       .LOCKED(pll_lckd),
+       .IOCLK(clk4x_wr),
+       .LOCK(),
+       .SERDESSTROBE(clk4x_wr_strb)
+);
+
+BUFPLL #(
+       .DIVIDE(4)
+) rd_bufpll (
+       .PLLIN(pllout1),
+       .GCLK(sys_clk),
+       .LOCKED(pll_lckd),
+       .IOCLK(clk4x_rd),
+       .LOCK(),
+       .SERDESSTROBE(clk4x_rd_strb)
+);
+
+BUFG bufg_x2_2(
+       .I(pllout2),
+       .O(clk2x_270)
+);
+
+BUFG bufg_x1(
+       .I(pllout3),
+       .O(sys_clk)
+);
+
+wire clk50g;
+BUFG bufg_50(
+       .I(pllout4),
+       .O(clk50g)
+);
+
+wire clk2x_off;
+BUFG bufg_x2_offclk(
+       .I(pllout5),
+       .O(clk2x_off)
+);
+
+
+/* 
+ * SDRAM clock
+ */
+
+ODDR2 #(
+       .DDR_ALIGNMENT("NONE"),
+       .INIT(1'b0),
+       .SRTYPE("SYNC")
+) sd_clk_forward_p (
+       .Q(ddr_clk_pad_p),
+       .C0(clk2x_off),
+       .C1(~clk2x_off),
+       .CE(1'b1),
+       .D0(1'b1),
+       .D1(1'b0),
+       .R(1'b0),
+       .S(1'b0)
+);
+ODDR2 #(
+       .DDR_ALIGNMENT("NONE"),
+       .INIT(1'b0),
+       .SRTYPE("SYNC")
+) sd_clk_forward_n (
+       .Q(ddr_clk_pad_n),
+       .C0(clk2x_off),
+       .C1(~clk2x_off),
+       .CE(1'b1),
+       .D0(1'b0),
+       .D1(1'b1),
+       .R(1'b0),
+       .S(1'b0)
+);
+
+/*
+ * Ethernet PHY 
+ */
+
+always @(posedge clk50g)
+       eth_phy_clk_pad <= ~eth_phy_clk_pad;
+
+/* Let the synthesizer insert the appropriate buffers */
+assign eth_rx_clk = eth_rx_clk_pad;
+assign eth_tx_clk = eth_tx_clk_pad;
+
+/*
+ * VGA clock
+ */
+
+DCM_CLKGEN #(
+       .CLKFXDV_DIVIDE(2),
+       .CLKFX_DIVIDE(4),
+       .CLKFX_MD_MAX(3.0),
+       .CLKFX_MULTIPLY(2),
+       .CLKIN_PERIOD(20.0),
+       .SPREAD_SPECTRUM("NONE"),
+       .STARTUP_WAIT("FALSE")
+) vga_clock_gen (
+       .CLKFX(vga_clk),
+       .CLKFX180(),
+       .CLKFXDV(),
+       .STATUS(),
+       .CLKIN(clk50g),
+       .FREEZEDCM(1'b0),
+       .PROGCLK(vga_progclk),
+       .PROGDATA(vga_progdata),
+       .PROGEN(vga_progen),
+       .PROGDONE(vga_progdone),
+       .LOCKED(vga_locked),
+       .RST(~pll_lckd | sys_rst)
+);
+
+ODDR2 #(
+       .DDR_ALIGNMENT("NONE"),
+       .INIT(1'b0),
+       .SRTYPE("SYNC")
+) vga_clock_forward (
+       .Q(vga_clk_pad),
+       .C0(vga_clk),
+       .C1(~vga_clk),
+       .CE(1'b1),
+       .D0(1'b1),
+       .D1(1'b0),
+       .R(1'b0),
+       .S(1'b0)
+);
+endmodule