Merge branch 'master' into cva5

This commit is contained in:
enjoy-digital 2022-05-25 15:18:17 +02:00 committed by GitHub
commit ffcf2fca49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 726 additions and 375 deletions

View File

@ -25,16 +25,16 @@ altera_reserved_jtag_pads = [
class AlteraAsyncResetSynchronizerImpl(Module):
def __init__(self, cd, async_reset):
rst_meta = Signal()
rst_meta = Signal(name_override=f'ars_cd_{cd.name}_rst_meta')
self.specials += [
Instance("DFF",
Instance("DFF", name=f'ars_cd_{cd.name}_ff0',
i_d = 0,
i_clk = cd.clk,
i_clrn = 1,
i_prn = ~async_reset,
o_q = rst_meta
),
Instance("DFF",
Instance("DFF", name=f'ars_cd_{cd.name}_ff1',
i_d = rst_meta,
i_clk = cd.clk,
i_clrn = 1,

View File

@ -156,6 +156,7 @@ def _build_script(build_name, create_rbf):
script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision()
script_file = "build_" + build_name + ".sh"
script_contents += """
set -e -u -x -o pipefail
quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name}
quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}

View File

@ -230,7 +230,18 @@ class ConstraintManager:
except ConstraintError:
break
if not len(r):
raise ValueError
raise ValueError(f"Could not request some pin(s) named '{name}'")
return Cat(r)
def request_remaining(self, name):
r = []
while True:
try:
r.append(self.request(name))
except ConstraintError:
break
if not len(r):
raise ValueError(f"Could not request any pins named '{name}'")
return Cat(r)
def lookup_request(self, name, number=None, loose=False):
@ -321,6 +332,9 @@ class GenericPlatform:
def request_all(self, *args, **kwargs):
return self.constraint_manager.request_all(*args, **kwargs)
def request_remaining(self, *args, **kwargs):
return self.constraint_manager.request_remaining(*args, **kwargs)
def lookup_request(self, *args, **kwargs):
return self.constraint_manager.lookup_request(*args, **kwargs)

View File

@ -1 +0,0 @@
from litex.build.openfpga.platform import OpenFPGAPlatform

View File

@ -1,44 +0,0 @@
#!/usr/bin/env python3
#
# This file is part of LiteX.
#
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
from migen import *
from litex.build.generic_platform import Pins
from litex.build.openfpga import OpenFPGAPlatform
# export LITEX_ENV_OPENFPGA=/home/florent/dev/openfpga/OpenFPGA
# export LITEX_ENV_OPENFPGA_SOFA=/home/florent/dev/openfpga/SOFA
# Minimal Platform ---------------------------------------------------------------------------------
_io = [
("clk", 0, Pins(1)),
("led", 0, Pins(1))
]
class Platform(OpenFPGAPlatform):
def __init__(self):
OpenFPGAPlatform.__init__(self, "FPGA1212_QLSOFA_HD", _io)
# Minimal Design -----------------------------------------------------------------------------------
platform = Platform()
clk = platform.request("clk")
led = platform.request("led")
module = Module()
module.clock_domains.cd_sys = ClockDomain("sys")
module.comb += module.cd_sys.clk.eq(clk)
counter = Signal(26)
module.comb += led.eq(counter[25])
module.sync += counter.eq(counter + 1)
# Build --------------------------------------------------------------------------------------------
platform.build(module, run=True)

View File

@ -1,9 +0,0 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
# OpenFPGA Special Overrides ---------------------------------------------------------------------
openfpga_special_overrides = {}

View File

@ -1,152 +0,0 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
import sys
import subprocess
from shutil import which
from migen.fhdl.structure import _Fragment
from litex.build.generic_platform import *
from litex.build import tools
from litex.build.openfpga import common
# Check Setup --------------------------------------------------------------------------------------
def _check_setup():
if os.getenv("LITEX_ENV_OPENFPGA", False) == False:
msg = "Unable to find OpenFPGA toolchain, please:\n"
msg += "- Set LITEX_ENV_OPENFPGA environment variant to OpenFPGA's settings path.\n"
raise OSError(msg)
if os.getenv("LITEX_ENV_OPENFPGA_SOFA", False) == False:
msg = "Unable to find OpenFPGA's SOFA project, please:\n"
msg += "- Set LITEX_ENV_OPENFPGA_SOFA environment variant to OpenFPGA's SOFA settings path.\n"
raise OSError(msg)
# Task Config -------------------------------------------------------------------------------------
def _build_task_conf(platform, sources, build_dir, build_name):
# Get Environnment variables.
openfpga_path = os.getenv("LITEX_ENV_OPENFPGA")
openfpga_sofa_path = os.getenv("LITEX_ENV_OPENFPGA_SOFA")
# Get PnR/Task directories from OPENFPGA/SOFA paths.
pnr_path = os.path.join(openfpga_sofa_path, platform.device + "_PNR")
task_path = os.path.join(pnr_path, platform.device + "_task")
# Get Config file.
task_conf = os.path.join(task_path, "config", "task_simulation.conf")
# Helpers.
def replace_openfpga_task_section(filename, section, contents):
lines = []
# Read file and replace section with contents.
copy = True
for line in open(filename, "r"):
if not copy and line.startswith("["):
copy = True
if line.startswith(section):
copy = False
lines.append(section + "\n")
for l in contents:
lines.append(l + "\n")
lines.append("\n")
if copy:
lines.append(line)
# Save file to .orig.
os.system(f"mv {filename} {filename}.orig")
# Write file with replaced section.
with open(filename, "w") as f:
f.write("".join(lines))
# Add sources.
bench_sources = []
for filename, language, library in sources:
if language is None:
continue
if language not in ["verilog"]:
raise ValueError("OpenFPGA flow only supports verilog")
bench_sources.append(filename)
replace_openfpga_task_section(task_conf, "[BENCHMARKS]", [f"bench0={' '.join(bench_sources)}"])
# Set Top-Level.
replace_openfpga_task_section(task_conf, "[SYNTHESIS_PARAM]", [f"bench0_top={build_name}"])
def _run_task(device):
# Get Environnment variables.
openfpga_path = os.getenv("LITEX_ENV_OPENFPGA")
openfpga_sofa_path = os.getenv("LITEX_ENV_OPENFPGA_SOFA")
# Get PnR/Task directories from OPENFPGA/SOFA paths.
pnr_path = os.path.join(openfpga_sofa_path, device + "_PNR")
task_path = os.path.join(pnr_path, device + "_task")
# Set OPENFPGA_PATH.
os.environ["OPENFPGA_PATH"] = os.getenv("LITEX_ENV_OPENFPGA")
# Run OpenFPGA flow.
build_cmd = ["make", "-C", pnr_path, "clean", "runOpenFPGA"]
if subprocess.call(build_cmd) != 0:
raise OSError("Error occured during OpenFPGA's flow execution.")
# Copy artifacts.
os.system("rm -rf run001")
os.system(f"cp -r {task_path}/run001 run001")
# Display log. FIXME: Do it during build?
os.system("cat run001/vpr_arch/top/MIN_ROUTE_CHAN_WIDTH/openfpgashell.log")
# OpenFPGAToolchain --------------------------------------------------------------------------------
class OpenFPGAToolchain:
attr_translate = {}
special_overrides = common.openfpga_special_overrides
def __init__(self):
self.clocks = dict()
self.false_paths = set()
def build(self, platform, fragment,
build_dir = "build",
build_name = "top",
run = False,
**kwargs):
# Create Build Directory.
os.makedirs(build_dir, exist_ok=True)
cwd = os.getcwd()
os.chdir(build_dir)
# Finalize Design.
if not isinstance(fragment, _Fragment):
fragment = fragment.get_fragment()
platform.finalize(fragment)
# Generate Verilog.
v_output = platform.get_verilog(fragment, name=build_name, **kwargs)
named_sc, named_pc = platform.resolve_signals(v_output.ns)
top_file = build_name + ".v"
v_output.write(top_file)
platform.add_source(top_file)
# Check Setup.
_check_setup()
# Generate Task Config.
_build_task_conf(platform, platform.sources, build_dir, build_name)
# Run Task.
if run:
_run_task(platform.device)
os.chdir(cwd)
return v_output.ns

View File

@ -1,28 +0,0 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
from litex.build.generic_platform import GenericPlatform
from litex.build.openfpga import common, openfpga
# OpenFPGAPlatform -------------------------------------------------------------------------------
class OpenFPGAPlatform(GenericPlatform):
def __init__(self, device, *args, **kwargs):
GenericPlatform.__init__(self, device, *args, **kwargs)
self.toolchain = openfpga.OpenFPGAToolchain()
def get_verilog(self, *args, special_overrides=dict(), **kwargs):
so = dict(common.openfpga_special_overrides)
so.update(special_overrides)
return GenericPlatform.get_verilog(self, *args,
special_overrides = so,
attr_translate = self.toolchain.attr_translate,
**kwargs)
def build(self, *args, **kwargs):
return self.toolchain.build(self, *args, **kwargs)

View File

@ -26,18 +26,21 @@ def _build_sdc(clocks, vns, build_name):
# Script -------------------------------------------------------------------------------------------
def _build_tcl(name, device, files, build_name):
def _build_tcl(name, device, files, build_name, include_paths):
tcl = []
# Create Design.
tcl.append(f"create_design {build_name}")
# Set Device.
# TODO (Use Macro for now).
tcl.append("set_macro P1=10 P2=20")
# FIXME: Directly pass Devices instead of Macro when possible.
macro = {"test": "P1=10 P2=20"}[device]
tcl.append(f"set_macro {macro}")
# Add Include Path.
# TODO.
tcl.append("add_include_path ./")
for include_path in include_paths:
tcl.append(f"add_include_path {include_path}")
# Add Sources.
for f, typ, lib in files:
@ -107,10 +110,11 @@ class OSFPGAToolchain:
# Generate build script (.tcl)
script = _build_tcl(
name = platform.devicename,
device = platform.device,
files = platform.sources,
build_name = build_name,
name = platform.devicename,
device = platform.device,
files = platform.sources,
build_name = build_name,
include_paths = platform.verilog_include_paths,
)
# Run

View File

@ -22,7 +22,7 @@ _io = [
class Platform(OSFPGAPlatform):
def __init__(self):
OSFPGAPlatform.__init__(self, device=None, toolchain="raptor", io=_io) # FIXME: Add device support.
OSFPGAPlatform.__init__(self, device="test", toolchain="raptor", io=_io)
# Minimal Design -----------------------------------------------------------------------------------

64
litex/build/osfpga/test_soc.py Executable file
View File

@ -0,0 +1,64 @@
#!/usr/bin/env python3
#
# This file is part of LiteX.
#
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
from migen import *
from litex.build.io import CRG
from litex.build.generic_platform import Pins, Subsignal
from litex.build.osfpga import OSFPGAPlatform
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
# Platform ---------------------------------------------------------------------------------
_io = [
# Clk.
("clk", 0, Pins(1)),
# Serial.
("serial", 0,
Subsignal("tx", Pins(1)),
Subsignal("rx", Pins(1)),
),
]
class Platform(OSFPGAPlatform):
def __init__(self, toolchain="foedag"):
OSFPGAPlatform.__init__(self, device="test", toolchain=toolchain, io=_io)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, platform, sys_clk_freq=int(10e6), **kwargs):
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = CRG(platform.request("clk"))
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX Test SoC on OS-FPGA", **kwargs)
# Build --------------------------------------------------------------------------------------------
def main():
from litex.soc.integration.soc import LiteXSoCArgumentParser
parser = LiteXSoCArgumentParser(description="LiteX Test SoC on OS-FPGA")
target_group = parser.add_argument_group(title="Target options")
target_group.add_argument("--build", action="store_true", help="Build design.")
target_group.add_argument("--toolchain", default="foedag", help="FPGA toolchain.")
builder_args(parser)
soc_core_args(parser)
args = parser.parse_args()
platform = Platform(toolchain=args.toolchain)
soc = BaseSoC(platform,**soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args))
if args.build:
builder.build()
if __name__ == "__main__":
main()

View File

@ -70,8 +70,8 @@ class IntelClocking(Module, AutoCSR):
break
if valid:
break
if not valid:
all_valid = False
if not valid:
all_valid = False
else:
all_valid = False
if all_valid:

View File

@ -42,13 +42,13 @@ class CPUNone(CPU):
data_width = 32
endianness = "little"
reset_address = 0x00000000
io_regions = {0x00000000: 0x100000000} # origin, length
io_regions = {0x0000_0000: 0x1_0000_0000} # origin, length
periph_buses = []
memory_buses = []
mem_map = {
"csr" : 0x00000000,
"ethmac" : 0x00020000, # FIXME: Remove.
"spiflash" : 0x10000000, # FIXME: Remove.
"csr" : 0x0000_0000,
"ethmac" : 0x0002_0000, # FIXME: Remove.
"spiflash" : 0x1000_0000, # FIXME: Remove.
}
CPU_GCC_TRIPLE_RISCV64 = (

View File

@ -65,17 +65,17 @@ class BlackParrot(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV64
linker_output_format = "elf64-littleriscv"
nop = "nop"
io_regions = {0x50000000: 0x10000000} # Origin, Length.
io_regions = {0x5000_0000: 0x1000_0000} # Origin, Length.
# Memory Mapping.
@property
def mem_map(self):
# Keep the lower 128MBs for SoC IOs auto-allocation.
return {
"csr" : 0x58000000,
"rom" : 0x70000000,
"sram" : 0x71000000,
"main_ram" : 0x80000000,
"csr" : 0x5800_0000,
"rom" : 0x7000_0000,
"sram" : 0x7100_0000,
"main_ram" : 0x8000_0000,
}
# GCC Flags.
@ -142,7 +142,7 @@ class BlackParrot(CPU):
def set_reset_address(self, reset_address):
self.reset_address = reset_address
assert reset_address == 0x70000000, "cpu_reset_addr hardcoded to 7x00000000!"
assert reset_address == 0x7000_0000, "cpu_reset_addr hardcoded to 7x00000000!"
@staticmethod
def add_sources(platform, variant="standard"):

View File

@ -252,7 +252,7 @@ class CV32E41P(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property

View File

@ -0,0 +1 @@
from litex.soc.cores.cpu.cva6.core import CVA6

View File

@ -0,0 +1,18 @@
.section .text, "ax", @progbits
.global boot_helper
.global smp_ap_args
.global smp_ap_target
.global smp_ap_ready
boot_helper:
// boot core saves args and jump target for ap cores:
sd a0, smp_ap_args, t1
sd a1, smp_ap_args+8, t1
sd a2, smp_ap_args+16, t1
sd a3, smp_ap_target, t1
fence w, w
// notify application cores to proceed with boot:
li t0, 1
sd t0, smp_ap_ready, t1
// boot core now also ready to boot:
jr a3

View File

@ -0,0 +1,186 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2021 Hensoldt Cyber GmbH <www.hensoldt-cyber.com>
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
import re
from migen import *
from litex import get_data_mod
from litex.soc.interconnect import axi
from litex.soc.interconnect import wishbone
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
class Open(Signal): pass
# Variants -----------------------------------------------------------------------------------------
CPU_VARIANTS = ["standard", "full"]
# GCC Flags ----------------------------------------------------------------------------------------
GCC_FLAGS = {
# /-------- Base ISA
# |/------- Hardware Multiply + Divide
# ||/----- Atomics
# |||/---- Compressed ISA
# ||||/--- Single-Precision Floating-Point
# |||||/-- Double-Precision Floating-Point
# imacfd
"standard": "-march=rv64imac -mabi=lp64 ",
"full": "-march=rv64gc -mabi=lp64 ",
}
# Helpers ------------------------------------------------------------------------------------------
def add_manifest_sources(platform, manifest):
basedir = get_data_mod("cpu", "cva6").data_location
with open(os.path.join(basedir, manifest), 'r') as f:
for l in f:
res = re.search('\$\{CVA6_REPO_DIR\}/(.+)', l)
if res and not re.match('//', l):
if re.match('\+incdir\+', l):
platform.add_verilog_include_path(os.path.join(basedir, res.group(1)))
else:
platform.add_source(os.path.join(basedir, res.group(1)))
# CVA6 ---------------------------------------------------------------------------------------------
class CVA6(CPU):
family = "riscv"
name = "cva6"
human_name = "CVA6"
variants = CPU_VARIANTS
data_width = 64
endianness = "little"
gcc_triple = CPU_GCC_TRIPLE_RISCV64
linker_output_format = "elf64-littleriscv"
nop = "nop"
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property
def gcc_flags(self):
flags = GCC_FLAGS[self.variant]
flags += "-D__cva6__ "
flags += f" -DUART_POLLING"
return flags
# Memory Mapping.
@property
def mem_map(self):
return {
"rom" : 0x1000_0000,
"sram" : 0x2000_0000,
"csr" : 0x8000_0000,
}
def __init__(self, platform, variant="standard"):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.interrupt = Signal(32)
self.axi_lite_if = axi.AXILiteInterface(data_width=64, address_width=32)
self.periph_buses = [self.axi_lite_if] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
# # #
# AXI <-> AXILite conversion.
axi_if = axi.AXIInterface(data_width=64, address_width=32, id_width=4)
self.submodules += axi.AXI2AXILite(axi_if, self.axi_lite_if)
# CPU Instance.
self.cpu_params = dict(
# Clk / Rst.
i_clk_i = ClockSignal("sys"),
i_rst_n = ~ResetSignal("sys") | self.reset,
# AXI interface.
o_AWVALID_o = axi_if.aw.valid,
i_AWREADY_i = axi_if.aw.ready,
o_AWID_o = axi_if.aw.id,
o_AWADDR_o = axi_if.aw.addr,
o_AWLEN_o = axi_if.aw.len,
o_AWSIZE_o = axi_if.aw.size,
o_AWBURST_o = axi_if.aw.burst,
o_AWLOCK_o = axi_if.aw.lock,
o_AWCACHE_o = axi_if.aw.cache,
o_AWPROT_o = axi_if.aw.prot,
o_AWQOS_o = axi_if.aw.qos,
o_AWREGION_o = Open(),
o_AWUSER_o = Open(),
o_WVALID_o = axi_if.w.valid,
i_WREADY_i = axi_if.w.ready,
o_WDATA_o = axi_if.w.data,
o_WSTRB_o = axi_if.w.strb,
o_WLAST_o = axi_if.w.last,
o_WUSER_o = Open(),
i_BVALID_i = axi_if.b.valid,
o_BREADY_o = axi_if.b.ready,
i_BID_i = axi_if.b.id,
i_BRESP_i = axi_if.b.resp,
i_BUSER_i = 0,
o_ARVALID_o = axi_if.ar.valid,
i_ARREADY_i = axi_if.ar.ready,
o_ARID_o = axi_if.ar.id,
o_ARADDR_o = axi_if.ar.addr,
o_ARLEN_o = axi_if.ar.len,
o_ARSIZE_o = axi_if.ar.size,
o_ARBURST_o = axi_if.ar.burst,
o_ARLOCK_o = axi_if.ar.lock,
o_ARCACHE_o = axi_if.ar.cache,
o_ARPROT_o = axi_if.ar.prot,
o_ARQOS_o = axi_if.ar.qos,
o_ARUSER_o = Open(),
o_ARREGION_o = Open(),
i_RVALID_i = axi_if.r.valid,
o_RREADY_o = axi_if.r.ready,
i_RID_i = axi_if.r.id,
i_RDATA_i = axi_if.r.data,
i_RRESP_i = axi_if.r.resp,
i_RLAST_i = axi_if.r.last,
i_RUSER_i = 0,
)
# Add Verilog sources.
# TODO: use Flist.cv64a6_imafdc_sv39 and Flist.cv32a6_imac_sv0 instead
add_manifest_sources(platform, "Flist.cv64a6_imafdc_sv39")
add_manifest_sources(platform, "Flist.cva6_wrapper")
def add_jtag(pads):
from migen.fhdl.specials import Tristate
self.jtag_tck = Signal()
self.jtag_tms = Signal()
self.jtag_trst = Signal()
self.jtag_tdi = Signal()
self.jtag_tdo = Signal()
tdo_o = Signal()
tdo_oe = Signal()
self.specials += Tristate(self.jtag_tdo, tdo_o, tdo_oe)
self.cpu_params.update(
i_trst_n = self.jtag_trst,
i_tck = self.jtag_tck,
i_tms = self.jtag_tms,
i_tdi = self.jtag_tdi,
o_tdo = tdo_o,
o_tdo_oe = tdo_oe,
)
def set_reset_address(self, reset_address):
self.reset_address = reset_address
assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!"
def do_finalize(self):
assert hasattr(self, "reset_address")
self.specials += Instance("cva6_wrapper", **self.cpu_params)

View File

@ -0,0 +1,125 @@
.global main
.global isr
.global _start
.global smp_ap_args
.global smp_ap_target
.global smp_ap_ready
_start:
j crt_init
nop
nop
nop
nop
nop
nop
nop
trap_entry:
sd x1, - 1*8(sp)
sd x5, - 2*8(sp)
sd x6, - 3*8(sp)
sd x7, - 4*8(sp)
sd x10, - 5*8(sp)
sd x11, - 6*8(sp)
sd x12, - 7*8(sp)
sd x13, - 8*8(sp)
sd x14, - 9*8(sp)
sd x15, -10*8(sp)
sd x16, -11*8(sp)
sd x17, -12*8(sp)
sd x28, -13*8(sp)
sd x29, -14*8(sp)
sd x30, -15*8(sp)
sd x31, -16*8(sp)
addi sp,sp,-16*8
call isr
ld x1 , 15*8(sp)
ld x5, 14*8(sp)
ld x6, 13*8(sp)
ld x7, 12*8(sp)
ld x10, 11*8(sp)
ld x11, 10*8(sp)
ld x12, 9*8(sp)
ld x13, 8*8(sp)
ld x14, 7*8(sp)
ld x15, 6*8(sp)
ld x16, 5*8(sp)
ld x17, 4*8(sp)
ld x28, 3*8(sp)
ld x29, 2*8(sp)
ld x30, 1*8(sp)
ld x31, 0*8(sp)
addi sp,sp,16*8
mret
.text
crt_init:
la sp, _fstack
sd zero, smp_ap_ready, t0
la t0, trap_entry
csrw mtvec, t0
smp_select_bp:
csrr a0, mhartid
beqz a0, data_init // hart 0 is bp, everyone else is ap
smp_ap_loop:
ld t0, smp_ap_ready
beqz t0, smp_ap_loop
smp_ap_boot:
fence r, r
fence.i // i$ flush
ld a0, smp_ap_args // hart ID (but next-stage loads its own)
ld a1, smp_ap_args+8 // DTB pointer (if provded by litex bios)
ld a2, smp_ap_args+16
ld a3, smp_ap_target
jr a3
smp_ap_done:
data_init:
la t0, _fdata
la t1, _edata
la t2, _fdata_rom
data_loop:
beq t0,t1,data_done
ld t3,0(t2)
sd t3,0(t0)
add t0,t0,8
add t2,t2,8
j data_loop
data_done:
bss_init:
la t0, _fbss
la t1, _ebss
bss_loop:
beq t0,t1,bss_done
sd zero,0(t0)
add t0,t0,8
j bss_loop
bss_done:
// call plic_init // initialize external interrupt controller
li t0, 0x800 // external interrupt sources only (using LiteX timer);
// NOTE: must still enable mstatus.MIE!
csrw mie,t0
call main
inf_loop:
j inf_loop
.bss
.align 8
smp_ap_args:
.dword 0
.dword 0
.dword 0
.align 8
smp_ap_target:
.dword 0
.align 8
smp_ap_ready:
.dword 0

View File

@ -0,0 +1,8 @@
#ifndef CSR_DEFS__H
#define CSR_DEFS__H
#define CSR_MSTATUS_MIE 0x8
#define CSR_DCACHE_INFO 0xCC0
#endif /* CSR_DEFS__H */

View File

@ -0,0 +1,41 @@
#ifndef __IRQ_H
#define __IRQ_H
#ifdef __cplusplus
extern "C" {
#endif
#include <system.h>
#include <generated/csr.h>
#include <generated/soc.h>
static inline unsigned int irq_getie(void)
{
return 0;
}
static inline void irq_setie(unsigned int ie)
{
}
static inline unsigned int irq_getmask(void)
{
return 0;
}
static inline void irq_setmask(unsigned int mask)
{
}
static inline unsigned int irq_pending(void)
{
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* __IRQ_H */

View File

@ -0,0 +1,43 @@
#ifndef __SYSTEM_H
#define __SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((unused)) static void flush_cpu_icache(void){} /* FIXME: do something useful here! */
__attribute__((unused)) static void flush_cpu_dcache(void){}; /* FIXME: do something useful here! */
void flush_l2_cache(void);
void busy_wait(unsigned int ms);
void busy_wait_us(unsigned int us);
#include <csr-defs.h>
#define csrr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define csrw(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
#define csrs(reg, bit) ({ \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \
else \
asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); })
#define csrc(reg, bit) ({ \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \
else \
asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); })
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_H */

View File

@ -55,7 +55,7 @@ class FemtoRV(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property

View File

@ -43,7 +43,7 @@ class FireV(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property

View File

@ -68,10 +68,10 @@ class GowinEMCU(CPU):
@property
def mem_map(self):
return {
"rom": 0x0000_0000,
"sram": 0x2000_0000,
"peripherals": 0x4000_0000,
"csr": 0xA000_0000,
"rom" : 0x0000_0000,
"sram" : 0x2000_0000,
"peripherals" : 0x4000_0000,
"csr" : 0xa000_0000,
}
def __init__(self, platform, variant, *args, **kwargs):

View File

@ -108,7 +108,7 @@ class Ibex(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property

View File

@ -33,7 +33,7 @@ class LM32(CPU):
gcc_triple = "lm32-elf"
linker_output_format = "elf32-lm32"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # origin, length
io_regions = {0x8000_0000: 0x8000_0000} # origin, length
# GCC Flags.
@property

View File

@ -33,7 +33,7 @@ class Marocchino(CPU):
clang_triple = "or1k-linux"
linker_output_format = "elf32-or1k"
nop = "l.nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# Memory Mapping for Linux variant.
@property
@ -42,10 +42,10 @@ class Marocchino(CPU):
# address of 0x0. As we are running Linux from the MAIN_RAM region - move it to satisfy
# that requirement.
return {
"main_ram" : 0x00000000,
"rom" : 0x10000000,
"sram" : 0x50000000,
"csr" : 0xe0000000,
"main_ram" : 0x0000_0000,
"rom" : 0x1000_0000,
"sram" : 0x5000_0000,
"csr" : 0xe000_0000,
}
# GCC Flags.

View File

@ -35,16 +35,16 @@ class Microwatt(CPU):
gcc_triple = ("powerpc64le-linux", "powerpc64le-linux-gnu", "ppc64le-linux", "ppc64le-linux-musl")
linker_output_format = "elf64-powerpcle"
nop = "nop"
io_regions = {0xc0000000: 0x10000000} # Origin, Length.
io_regions = {0xc000_0000: 0x1000_0000} # Origin, Length.
# Memory Mapping.
@property
def mem_map(self):
return {
# Keep the lower 128MBs for SoC IOs auto-allocation.
"csr": 0xc8000000,
"xicsicp": 0xcbff0000,
"xicsics": 0xcbff1000,
"csr": 0xc800_0000,
"xicsicp": 0xcbff_0000,
"xicsics": 0xcbff_1000,
}
# GCC Flags.
@ -131,7 +131,7 @@ class Microwatt(CPU):
def set_reset_address(self, reset_address):
self.reset_address = reset_address
assert reset_address == 0x00000000
assert reset_address == 0x0000_0000
def add_soc_components(self, soc, soc_region_cls):
if "irq" in self.variant:

View File

@ -31,7 +31,7 @@ class Minerva(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property

View File

@ -33,7 +33,7 @@ class MOR1KX(CPU):
clang_triple = "or1k-linux"
linker_output_format = "elf32-or1k"
nop = "l.nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# Memory Mapping for Linux variant.
@property
@ -42,10 +42,10 @@ class MOR1KX(CPU):
# address of 0x0. As we are running Linux from the MAIN_RAM region - move it to satisfy
# that requirement.
return {
"main_ram" : 0x00000000,
"rom" : 0x10000000,
"sram" : 0x50000000,
"csr" : 0xe0000000,
"main_ram" : 0x0000_0000,
"rom" : 0x1000_0000,
"sram" : 0x5000_0000,
"csr" : 0xe000_0000,
}
# GCC Flags.

View File

@ -37,7 +37,7 @@ class NaxRiscv(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# Default parameters.
with_fpu = False
@ -72,12 +72,12 @@ class NaxRiscv(CPU):
@property
def mem_map(self):
return {
"rom": 0x00000000,
"sram": 0x10000000,
"main_ram": 0x40000000,
"csr": 0xf0000000,
"clint": 0xf0010000,
"plic": 0xf0c00000,
"rom": 0x0000_0000,
"sram": 0x1000_0000,
"main_ram": 0x4000_0000,
"csr": 0xf000_0000,
"clint": 0xf001_0000,
"plic": 0xf0c0_0000,
}
# GCC Flags.
@ -284,7 +284,7 @@ class NaxRiscv(CPU):
soc.irq.add("timer0", n=1)
# Add OpenSBI region.
soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f00000, 0x80000, type="cached+linker")
soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f0_0000, 0x8_0000, type="cached+linker")
# Define ISA.
soc.add_constant("CPU_ISA", NaxRiscv.get_arch())
@ -312,7 +312,7 @@ class NaxRiscv(CPU):
o_peripheral_plic_rdata = plicbus.r.data,
o_peripheral_plic_rresp = plicbus.r.resp,
)
soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x400000, cached=False))
soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=False))
if NaxRiscv.jtag_tap:
self.jtag_tms = Signal()
@ -394,7 +394,7 @@ class NaxRiscv(CPU):
o_peripheral_clint_rdata = clintbus.r.data,
o_peripheral_clint_rresp = clintbus.r.resp,
)
soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x10000, cached=False))
soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x1_0000, cached=False))
def add_memory_buses(self, address_width, data_width):
nax_data_width = 64

View File

@ -41,7 +41,7 @@ class NEORV32(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property
@ -147,7 +147,7 @@ class NEORV32(CPU):
def set_reset_address(self, reset_address):
self.reset_address = reset_address
assert reset_address == 0x00000000
assert reset_address == 0x0000_0000
@staticmethod
def add_sources(platform):

View File

@ -47,7 +47,7 @@ class PicoRV32(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # origin, length
io_regions = {0x8000_0000: 0x8000_0000} # origin, length
# GCC Flags.
@property
@ -183,7 +183,7 @@ class PicoRV32(CPU):
self.reset_address = reset_address
self.cpu_params.update(
p_PROGADDR_RESET = reset_address,
p_PROGADDR_IRQ = reset_address + 0x00000010
p_PROGADDR_IRQ = reset_address + 0x0000_0010
)
@staticmethod

View File

@ -105,18 +105,18 @@ class Rocket(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV64
linker_output_format = "elf64-littleriscv"
nop = "nop"
io_regions = {0x12000000: 0x70000000} # Origin, Length.
io_regions = {0x1200_0000: 0x7000_0000} # Origin, Length.
# Memory Mapping.
@property
def mem_map(self):
# Rocket reserves the first 256Mbytes for internal use, so we must change default mem_map.
return {
"rom" : 0x10000000,
"sram" : 0x11000000,
"csr" : 0x12000000,
"ethmac" : 0x30000000,
"main_ram" : 0x80000000,
"rom" : 0x1000_0000,
"sram" : 0x1100_0000,
"csr" : 0x1200_0000,
"ethmac" : 0x3000_0000,
"main_ram" : 0x8000_0000,
}
# GCC Flags.
@ -320,7 +320,7 @@ class Rocket(CPU):
def set_reset_address(self, reset_address):
self.reset_address = reset_address
assert reset_address == 0x10000000, "cpu_reset_addr hardcoded in during elaboration!"
assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!"
@staticmethod
def add_sources(platform, variant="standard"):

View File

@ -44,7 +44,7 @@ class SERV(CPU):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# GCC Flags.
@property

View File

@ -105,17 +105,17 @@ class VexRiscv(CPU, AutoCSR):
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length
# Memory Mapping.
@property
def mem_map(self):
return {
"rom": 0x00000000,
"sram": 0x10000000,
"main_ram": 0x40000000,
"csr": 0xf0000000,
"vexriscv_debug": 0xf00f0000,
"rom": 0x0000_0000,
"sram": 0x1000_0000,
"main_ram": 0x4000_0000,
"csr": 0xf000_0000,
"vexriscv_debug": 0xf00f_0000,
}
# GCC Flags.

View File

@ -20,13 +20,6 @@ import os
class Open(Signal): pass
# Variants -----------------------------------------------------------------------------------------
CPU_VARIANTS = {
"standard": "VexRiscv",
"linux": "VexRiscv", # Similar to standard.
}
# VexRiscv SMP -------------------------------------------------------------------------------------
class VexRiscvSMP(CPU):
@ -34,13 +27,13 @@ class VexRiscvSMP(CPU):
family = "riscv"
name = "vexriscv"
human_name = "VexRiscv SMP"
variants = CPU_VARIANTS
variants = ["standard", "linux"]
data_width = 32
endianness = "little"
gcc_triple = CPU_GCC_TRIPLE_RISCV32
linker_output_format = "elf32-littleriscv"
nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length.
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
# Default parameters.
cpu_count = 1
@ -138,12 +131,12 @@ class VexRiscvSMP(CPU):
@property
def mem_map(self):
return {
"rom": 0x00000000,
"sram": 0x10000000,
"main_ram": 0x40000000,
"csr": 0xf0000000,
"clint": 0xf0010000,
"plic": 0xf0c00000,
"rom": 0x0000_0000,
"sram": 0x1000_0000,
"main_ram": 0x4000_0000,
"csr": 0xf000_0000,
"clint": 0xf001_0000,
"plic": 0xf0c0_0000,
}
# GCC Flags.
@ -271,8 +264,8 @@ class VexRiscvSMP(CPU):
def __init__(self, platform, variant):
self.platform = platform
self.variant = "standard"
self.human_name = self.human_name + "-" + variant.upper()
self.variant = "linux"
self.human_name = self.human_name + "-" + self.variant.upper()
self.reset = Signal()
self.jtag_clk = Signal()
self.jtag_enable = Signal()
@ -353,7 +346,7 @@ class VexRiscvSMP(CPU):
def set_reset_address(self, reset_address):
self.reset_address = reset_address
assert reset_address == 0x00000000
assert reset_address == 0x0000_0000
def add_sources(self, platform):
vdir = get_data_mod("cpu", "vexriscv_smp").data_location
@ -388,7 +381,7 @@ class VexRiscvSMP(CPU):
soc.irq.add("timer0", n=1)
# Add OpenSBI region.
soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f00000, 0x80000, type="cached+linker")
soc.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f0_0000, 0x8_0000, type="cached+linker")
# Define number of CPUs
soc.add_config("CPU_COUNT", VexRiscvSMP.cpu_count)
@ -422,7 +415,7 @@ class VexRiscvSMP(CPU):
o_plicWishbone_DAT_MISO = plicbus.dat_r,
i_plicWishbone_DAT_MOSI = plicbus.dat_w
)
soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x400000, cached=False))
soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=False))
# Add CLINT as Bus Slave
self.clintbus = clintbus = wishbone.Interface()
@ -435,7 +428,7 @@ class VexRiscvSMP(CPU):
o_clintWishbone_DAT_MISO = clintbus.dat_r,
i_clintWishbone_DAT_MOSI = clintbus.dat_w,
)
soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x10000, cached=False))
soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x1_0000, cached=False))
def add_memory_buses(self, address_width, data_width):
VexRiscvSMP.litedram_width = data_width

View File

@ -37,7 +37,7 @@ class Zynq7000(CPU):
@property
def mem_map(self):
return {
"sram": 0x10_0000, # DDR in fact
"sram": 0x0010_0000, # DDR in fact
"rom": 0xfc00_0000,
}

View File

@ -24,7 +24,7 @@ class ZynqMP(CPU):
linker_output_format = "elf64-littleaarch64"
nop = "nop"
io_regions = { # Origin, Length.
0x8000_0000: 0x4000_0000,
0x8000_0000: 0x00_4000_0000,
0xe000_0000: 0xff_2000_0000 # TODO: there are more details here
}
csr_decode = False # AXI address is decoded in AXI2Wishbone (target level).

View File

@ -1216,7 +1216,8 @@ class LiteXSoC(SoC):
self.check_if_exists(name)
if with_build_time:
identifier += " " + build_time()
self.add_config("WITH_BUILD_TIME")
else:
self.add_config("BIOS_NO_BUILD_TIME")
setattr(self.submodules, name, Identifier(identifier))
# Add UART -------------------------------------------------------------------------------------
@ -1774,10 +1775,11 @@ class LiteXSoC(SoC):
self.add_constant("SDCARD_DEBUG")
# Add SATA -------------------------------------------------------------------------------------
def add_sata(self, name="sata", phy=None, mode="read+write"):
def add_sata(self, name="sata", phy=None, mode="read+write", with_identify=True):
# Imports.
from litesata.core import LiteSATACore
from litesata.frontend.arbitration import LiteSATACrossbar
from litesata.frontend.identify import LiteSATAIdentify, LiteSATAIdentifyCSR
from litesata.frontend.dma import LiteSATASector2MemDMA, LiteSATAMem2SectorDMA
# Checks.
@ -1798,6 +1800,12 @@ class LiteXSoC(SoC):
self.check_if_exists("sata_crossbar")
self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core)
# Identify.
if with_identify:
sata_identify = LiteSATAIdentify(self.sata_crossbar.get_port())
self.submodules += sata_identify
self.submodules.sata_identify = LiteSATAIdentifyCSR(sata_identify)
# Sector2Mem DMA.
if "read" in mode:
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width)
@ -1818,6 +1826,20 @@ class LiteXSoC(SoC):
dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
dma_bus.add_master("sata_mem2sector", master=bus)
# Interrupts.
self.submodules.sata_irq = EventManager()
if "read" in mode:
self.sata_irq.sector2mem_dma = EventSourcePulse(description="Sector2Mem DMA terminated.")
if "write" in mode:
self.sata_irq.mem2sector_dma = EventSourcePulse(description="Mem2Sector DMA terminated.")
self.sata_irq.finalize()
if "read" in mode:
self.comb += self.sata_irq.sector2mem_dma.trigger.eq(self.sata_sector2mem.irq)
if "write" in mode:
self.comb += self.sata_irq.mem2sector_dma.trigger.eq(self.sata_mem2sector.irq)
if self.irq.enabled:
self.irq.add("sata", use_loc_if_exists=True)
# Timing constraints.
self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq)
self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_rx.clk, 1e9/sata_clk_freq)

View File

@ -20,7 +20,7 @@
static void sata_init_handler(int nb_params, char **params)
{
printf("Initialize SATA... ");
if (sata_init())
if (sata_init(1))
printf("Successful.\n");
else
printf("Failed.\n");

View File

@ -97,7 +97,7 @@ __attribute__((__used__)) int main(int i, char **c)
i2c_send_init_cmds();
#endif
#ifndef CONFIG_SIM_DISABLE_BIOS_PROMPT
#ifndef CONFIG_BIOS_NO_PROMPT
printf("\n");
printf("\e[1m __ _ __ _ __\e[0m\n");
printf("\e[1m / / (_) /____ | |/_/\e[0m\n");
@ -108,10 +108,12 @@ __attribute__((__used__)) int main(int i, char **c)
printf(" (c) Copyright 2012-2022 Enjoy-Digital\n");
printf(" (c) Copyright 2007-2015 M-Labs\n");
printf("\n");
#ifdef CONFIG_WITH_BUILD_TIME
#ifndef CONFIG_BIOS_NO_BUILD_TIME
printf(" BIOS built on "__DATE__" "__TIME__"\n");
#endif
#ifndef CONFIG_BIOS_NO_CRC
crcbios();
#endif
printf("\n");
printf(" LiteX git sha1: "LITEX_GIT_SHA1"\n");
printf("\n");
@ -149,7 +151,7 @@ __attribute__((__used__)) int main(int i, char **c)
#endif
#endif
printf("\n");
#endif // CONFIG_SIM_DISABLE_BIOS_PROMPT
#endif
sdr_ok = 1;

View File

@ -23,7 +23,7 @@ uint32_t rd_errors;
__attribute__((unused)) static void cdelay(int i)
{
#ifndef CONFIG_DISABLE_DELAYS
#ifndef CONFIG_BIOS_NO_DELAYS
while(i > 0) {
__asm__ volatile(CONFIG_CPU_NOP);
i--;

View File

@ -43,7 +43,7 @@
__attribute__((unused)) void cdelay(int i)
{
#ifndef CONFIG_DISABLE_DELAYS
#ifndef CONFIG_BIOS_NO_DELAYS
while(i > 0) {
__asm__ volatile(CONFIG_CPU_NOP);
i--;

View File

@ -1,4 +1,4 @@
// This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
// This file is Copyright (c) 2020-2022 Florent Kermarrec <florent@enjoy-digital.fr>
// License: BSD
#include <stdio.h>
@ -19,9 +19,14 @@
#ifdef CSR_SATA_PHY_BASE
int sata_init(void) {
int sata_init(int show) {
uint16_t timeout;
uint8_t buf[512];
int i;
uint32_t data;
uint16_t buf[128];
uint8_t model[38];
uint64_t sectors;
uint32_t capacity;
for (timeout=16; timeout>0; timeout--) {
/* Reset SATA PHY */
@ -37,18 +42,50 @@ int sata_init(void) {
/* Re-initialize if failing */
continue;
/* Initiate a SATA Read */
sata_sector2mem_base_write((uint64_t)(uintptr_t) buf);
sata_sector2mem_sector_write(0);
sata_sector2mem_start_write(1);
/* Initiate a SATA Identify */
sata_identify_start_write(1);
/* Wait for 10ms */
busy_wait(10);
/* Wait for 100ms */
busy_wait(100);
/* Check SATA Read status */
if ((sata_sector2mem_done_read() & 0x1) == 0)
/* Check SATA Identify status */
if ((sata_identify_done_read() & 0x1) == 0)
/* Re-initialize if failing */
continue;
if (show)
printf("\n");
/* Dump Idenfify response to buf */
i = 0;
while (sata_identify_source_valid_read() && (i < 128)) {
data = sata_identify_source_data_read();
sata_identify_source_ready_write(1);
buf[i+0] = ((data >> 0) & 0xffff);
buf[i+1] = ((data >> 16) & 0xffff);
i += 2;
}
/* Get Disk Model from buf */
i = 0;
memset(model, 0, 38);
for (i=0; i<18; i++) {
model[2*i + 0] = (buf[27+i] >> 8) & 0xff;
model[2*i + 1] = (buf[27+i] >> 0) & 0xff;
}
if (show)
printf("Model: %s\n", model);
/* Get Disk Capacity from buf */
sectors = 0;
sectors += (((uint64_t) buf[100]) << 0);
sectors += (((uint64_t) buf[101]) << 16);
sectors += (((uint64_t) buf[102]) << 32);
sectors += (((uint64_t) buf[103]) << 48);
capacity = sectors/(1000*1000*500/256);
if (show)
printf("Capacity: %ldGB\n", capacity);
/* Init succeeded */
return 1;
}
@ -127,7 +164,7 @@ static DSTATUS sata_disk_status(BYTE drv) {
static DSTATUS sata_disk_initialize(BYTE drv) {
if (drv) return STA_NOINIT;
if (satastatus)
satastatus = sata_init() ? 0 : STA_NOINIT;
satastatus = sata_init(0) ? 0 : STA_NOINIT;
return satastatus;
}

View File

@ -12,7 +12,7 @@
#ifdef CSR_SATA_PHY_BASE
int sata_init(void);
int sata_init(int show);
void fatfs_set_ops_sata(void);
#endif

View File

@ -33,9 +33,9 @@ def generate_dts(d, initrd_start=None, initrd_size=None, initrd=None, root_devic
# Boot Arguments -------------------------------------------------------------------------------
cpu_architectures = {
"mor1kx": "or1k",
"marocchino": "or1k",
"vexriscv smp-linux": "riscv",
"mor1kx" : "or1k",
"marocchino" : "or1k",
"vexriscv smp-linux" : "riscv",
}
default_initrd_start = {
"or1k": 8*mB,

View File

@ -161,13 +161,20 @@ class SimSoC(SoCCore):
platform = Platform()
sys_clk_freq = int(1e6)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = CRG(platform.request("sys_clk"))
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, clk_freq=sys_clk_freq,
ident = "LiteX Simulation",
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = CRG(platform.request("sys_clk"))
# BIOS Config ------------------------------------------------------------------------------
# FIXME: Expose?
#self.add_config("BIOS_NO_PROMPT")
#self.add_config("BIOS_NO_DELAYS")
#self.add_config("BIOS_NO_BUILD_TIME")
#self.add_config("BIOS_NO_CRC")
# SDRAM ------------------------------------------------------------------------------------
if not self.integrated_main_ram_size and with_sdram:

View File

@ -69,14 +69,17 @@ class GitRepo:
git_repos = {
# HDL.
# ----
"migen": GitRepo(url="https://github.com/m-labs/", clone="recursive"),
# LiteX SoC builder
# LiteX SoC builder.
# ------------------
"pythondata-software-picolibc": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
"pythondata-software-compiler_rt": GitRepo(url="https://github.com/litex-hub/"),
"litex": GitRepo(url="https://github.com/enjoy-digital/", tag=True),
# LiteX Cores Ecosystem.
# ----------------------
"liteeth": GitRepo(url="https://github.com/enjoy-digital/", tag=True),
"litedram": GitRepo(url="https://github.com/enjoy-digital/", tag=True),
"litepcie": GitRepo(url="https://github.com/enjoy-digital/", tag=True),
@ -88,27 +91,39 @@ git_repos = {
"litespi": GitRepo(url="https://github.com/litex-hub/", tag=True),
# LiteX Boards.
# -------------
"litex-boards": GitRepo(url="https://github.com/litex-hub/", clone="regular", tag=True),
# LiteX pythondata.
# -----------------
# Generic.
"pythondata-misc-tapcfg": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-misc-usb_ohci": GitRepo(url="https://github.com/litex-hub/"),
# LM32 CPU(s).
"pythondata-cpu-lm32": GitRepo(url="https://github.com/litex-hub/"),
# OpenRISC CPU(s).
"pythondata-cpu-mor1kx": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-picorv32": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-serv": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-vexriscv": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-vexriscv-smp": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
"pythondata-cpu-naxriscv": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-rocket": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-minerva": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-marocchino": GitRepo(url="https://github.com/litex-hub/"),
# OpenPower CPU(s).
"pythondata-cpu-microwatt": GitRepo(url="https://github.com/litex-hub/", sha1=0xb940b55acff),
# RISC-V CPU(s).
"pythondata-cpu-blackparrot": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-cv32e40p": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
"pythondata-cpu-cv32e41p": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
"pythondata-cpu-cva5": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-cva6": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
"pythondata-cpu-ibex": GitRepo(url="https://github.com/litex-hub/", clone="recursive", sha1=0xd3d53df),
"pythondata-cpu-marocchino": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-minerva": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-naxriscv": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-picorv32": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-rocket": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-serv": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-vexriscv": GitRepo(url="https://github.com/litex-hub/"),
"pythondata-cpu-vexriscv-smp": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
}
# Installs -----------------------------------------------------------------------------------------
@ -118,15 +133,16 @@ minimal_repos = ["migen", "litex"]
# Standard: Migen + LiteX + Cores + Software + Popular CPUs (LM32, Mor1kx, SERV, VexRiscv).
standard_repos = list(git_repos.keys())
standard_repos.remove("pythondata-cpu-picorv32")
standard_repos.remove("pythondata-cpu-rocket")
standard_repos.remove("pythondata-cpu-minerva")
standard_repos.remove("pythondata-cpu-microwatt")
standard_repos.remove("pythondata-cpu-blackparrot")
standard_repos.remove("pythondata-cpu-cv32e40p")
standard_repos.remove("pythondata-cpu-cv32e41p")
standard_repos.remove("pythondata-cpu-cva6")
standard_repos.remove("pythondata-cpu-ibex")
standard_repos.remove("pythondata-cpu-marocchino")
standard_repos.remove("pythondata-cpu-minerva")
standard_repos.remove("pythondata-cpu-microwatt")
standard_repos.remove("pythondata-cpu-picorv32")
standard_repos.remove("pythondata-cpu-rocket")
# Full: Migen + LiteX + Cores + Software + All CPUs.
full_repos = list(git_repos.keys())
@ -254,7 +270,7 @@ def litex_setup_install_repos(config="standard", user_mode=False):
if repo.develop:
print_status(f"Installing {name} Git repository...")
os.chdir(os.path.join(current_path, name))
subprocess.check_call("{python3} -m pip install --editable . {options}".format(
subprocess.check_call("\"{python3}\" -m pip install --editable . {options}".format(
python3 = sys.executable,
options = "--user" if user_mode else "",
), shell=True)

View File

@ -56,6 +56,9 @@ class TestCPU(unittest.TestCase):
def test_picorv32(self):
self.assertTrue(self.boot_test("picorv32"))
#def test_cva6(self):
# self.assertTrue(self.boot_test("cva6"))
# OpenRISC CPUs.
#def test_mor1kx(self):
# self.assertTrue(self.boot_test("mor1kx"))