From 4cd360e6e14540b52e2a71425324715c6e81359e Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 4 Jul 2013 19:19:39 +0200 Subject: [PATCH] Mixxeo support --- Makefile | 21 ------- README | 27 ++++----- build.py | 77 ------------------------ jtag.py | 14 +++++ load.jtag | 3 - make.py | 67 +++++++++++++++++++++ milkymist/{m1crg => mxcrg}/__init__.py | 4 +- top.py | 26 +++++--- verilog/{m1crg/m1crg.v => mxcrg/mxcrg.v} | 6 +- 9 files changed, 115 insertions(+), 130 deletions(-) delete mode 100644 Makefile delete mode 100755 build.py create mode 100644 jtag.py delete mode 100644 load.jtag create mode 100755 make.py rename milkymist/{m1crg => mxcrg}/__init__.py (97%) rename verilog/{m1crg/m1crg.v => mxcrg/mxcrg.v} (98%) diff --git a/Makefile b/Makefile deleted file mode 100644 index 0e60158a..00000000 --- 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 183d6114..1475e615 100644 --- 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 ] -l +This will generate the build/soc-.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 index dc9edce8..00000000 --- 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 index 00000000..6aeaf45a --- /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 index c20825fb..00000000 --- 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 index 00000000..236a9f13 --- /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/mxcrg/__init__.py similarity index 97% rename from milkymist/m1crg/__init__.py rename to milkymist/mxcrg/__init__.py index e163c1bf..7107d023 100644 --- a/milkymist/m1crg/__init__.py +++ b/milkymist/mxcrg/__init__.py @@ -3,7 +3,7 @@ from fractions import Fraction from migen.fhdl.std import * from migen.bank.description import * -class M1CRG(Module, AutoCSR): +class MXCRG(Module, AutoCSR): def __init__(self, pads, outfreq1x): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys2x_270 = ClockDomain() @@ -32,7 +32,7 @@ class M1CRG(Module, AutoCSR): vga_progdone = Signal() vga_locked = Signal() - self.specials += Instance("m1crg", + self.specials += Instance("mxcrg", Instance.Parameter("in_period", in_period), Instance.Parameter("f_mult", ratio.numerator), Instance.Parameter("f_div", ratio.denominator), diff --git a/top.py b/top.py index 25fa2ea8..4935d26f 100644 --- 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/mxcrg/mxcrg.v similarity index 98% rename from verilog/m1crg/m1crg.v rename to verilog/mxcrg/mxcrg.v index 10e30e04..a7dee56a 100644 --- a/verilog/m1crg/m1crg.v +++ b/verilog/mxcrg/mxcrg.v @@ -1,4 +1,4 @@ -module m1crg #( +module mxcrg #( parameter in_period = 0.0, parameter f_mult = 0, parameter f_div = 0, @@ -56,6 +56,8 @@ always @(posedge sys_clk) begin 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 @@ -74,6 +76,8 @@ always @(posedge sys_clk) begin flash_rstcounter <= flash_rstcounter + 8'd1; end +initial flash_rstcounter <= 8'd0; + assign norflash_rst_n = flash_rstcounter[7]; /* -- 2.30.2