mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Mixxeo support
This commit is contained in:
parent
eff7882721
commit
4cd360e6e1
9 changed files with 115 additions and 130 deletions
21
Makefile
21
Makefile
|
@ -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
27
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!
|
||||
|
||||
|
|
77
build.py
77
build.py
|
@ -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
14
jtag.py
Normal 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])
|
|
@ -1,3 +0,0 @@
|
|||
cable milkymist
|
||||
detect
|
||||
pld load build/soc.bit
|
67
make.py
Executable file
67
make.py
Executable 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()
|
|
@ -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),
|
26
top.py
26
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])
|
||||
|
|
|
@ -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];
|
||||
|
||||
/*
|
Loading…
Reference in a new issue