Mixxeo support

This commit is contained in:
Sebastien Bourdeauducq 2013-07-04 19:19:39 +02:00
parent eff7882721
commit 4cd360e6e1
9 changed files with 115 additions and 130 deletions

View file

@ -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

27
README
View file

@ -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!

View file

@ -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()

14
jtag.py Normal file
View file

@ -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])

View file

@ -1,3 +0,0 @@
cable milkymist
detect
pld load build/soc.bit

67
make.py Executable file
View file

@ -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()

View file

@ -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),

14
top.py
View file

@ -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 = 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,13 +147,14 @@ 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)
if platform_name == "m1":
pots_pads = platform.request("dvi_pots")
self.submodules.pots = counteradc.CounterADC(pots_pads.charge,
[pots_pads.blackout, pots_pads.crossfade])

View file

@ -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];
/*