mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Merge branch 'master' into rdimm_bside_init
This commit is contained in:
commit
13db89ebd2
152 changed files with 3336 additions and 3414 deletions
|
@ -1,9 +1,5 @@
|
|||
jobs:
|
||||
include:
|
||||
- os: linux
|
||||
dist: xenial
|
||||
language: python
|
||||
python: "3.5"
|
||||
- os: linux
|
||||
dist: xenial
|
||||
language: python
|
||||
|
|
19
CHANGES
19
CHANGES
|
@ -1,3 +1,22 @@
|
|||
[> 2020.XX, planned for July 2020
|
||||
---------------------------------
|
||||
|
||||
[> Issues resolved
|
||||
------------------
|
||||
- Fix flush_cpu_icache on VexRiscv.
|
||||
|
||||
[> Added Features
|
||||
------------------
|
||||
- BIOS history, autocomplete.
|
||||
- Pluggable CPUs.
|
||||
- Add nMigen dependency.
|
||||
- Properly integrate Minerva CPU.
|
||||
|
||||
[> API changes/Deprecation
|
||||
--------------------------
|
||||
- NA
|
||||
|
||||
|
||||
[> 2020.04, released April 28th, 2020
|
||||
-------------------------------------
|
||||
|
||||
|
|
10
MANIFEST.in
10
MANIFEST.in
|
@ -1 +1,11 @@
|
|||
graft litex/build/sim
|
||||
graft litex/soc/software
|
||||
graft litex/soc/cores/cpu/blackparrot
|
||||
graft litex/soc/cores/cpu/lm32
|
||||
graft litex/soc/cores/cpu/microwatt
|
||||
graft litex/soc/cores/cpu/minerva
|
||||
graft litex/soc/cores/cpu/mor1kx
|
||||
graft litex/soc/cores/cpu/picorv32
|
||||
graft litex/soc/cores/cpu/rocket
|
||||
graft litex/soc/cores/cpu/serv
|
||||
graft litex/soc/cores/cpu/vexriscv
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
import sys
|
||||
|
||||
# retro-compat 2019-09-30
|
||||
from litex.soc.interconnect import packet
|
||||
sys.modules["litex.soc.interconnect.stream_packet"] = packet
|
||||
|
||||
# retro-compat 2019-09-29
|
||||
from litex.soc.integration import export
|
||||
sys.modules["litex.soc.integration.cpu_interface"] = export
|
||||
|
||||
from litex.tools.litex_client import RemoteClient
|
||||
|
||||
def get_data_mod(data_type, data_name):
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
# License: BSD
|
||||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
from litex.build.xilinx import XilinxPlatform
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -257,4 +258,9 @@ class Platform(XilinxPlatform):
|
|||
self.add_platform_command("set_property INTERNAL_VREF 0.675 [get_iobanks 34]")
|
||||
|
||||
def create_programmer(self):
|
||||
return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4")
|
||||
bscan_spi = "bscan_spi_xc7a100t.bit" if "xc7a100t" in self.device else "bscan_spi_xc7a35t.bit"
|
||||
return OpenOCD("openocd_xc7_ft2232.cfg", bscan_spi)
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)
|
||||
|
|
|
@ -92,3 +92,8 @@ class Platform(MicrosemiPlatform):
|
|||
|
||||
def __init__(self):
|
||||
MicrosemiPlatform.__init__(self, "MPF300TS_ES-FCG484-1", _io)
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
MicrosemiPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk50", 0, loose=True), 1e9/50e6)
|
||||
self.add_period_constraint(self.lookup_request("clk50", 1, loose=True), 1e9/50e6)
|
||||
|
|
|
@ -114,3 +114,7 @@ class Platform(AlteraPlatform):
|
|||
|
||||
def create_programmer(self):
|
||||
return USBBlaster()
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
AlteraPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -116,11 +117,9 @@ class Platform(XilinxPlatform):
|
|||
XilinxPlatform.__init__(self, "xc7k325t-ffg900-2", _io, _connectors, toolchain="vivado")
|
||||
|
||||
def create_programmer(self):
|
||||
return VivadoProgrammer()
|
||||
return OpenOCD("openocd_xc7_ft2232.cfg", "bscan_spi_xc7a325t.bit")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
try:
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks").rx, 1e9/125e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
self.add_period_constraint(self.lookup_request("clk200", loose=True), 1e9/200e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:rx", loose=True), 1e9/125e6)
|
||||
|
|
|
@ -86,3 +86,7 @@ class Platform(LatticePlatform):
|
|||
|
||||
def create_programmer(self):
|
||||
return IceStormProgrammer()
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
LatticePlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk12", loose=True), 1e9/12e6)
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
# This file is Copyright (c) 2015 Yann Sionneau <ys@m-labs.hk>
|
||||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
from litex.build.xilinx import XilinxPlatform
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -548,20 +549,11 @@ set_property CONFIG_VOLTAGE 2.5 [current_design]
|
|||
self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
|
||||
|
||||
def create_programmer(self):
|
||||
return VivadoProgrammer()
|
||||
return OpenOCD("openocd_xc7_ft2232.cfg", "bscan_spi_xc7a325t.bit")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
try:
|
||||
self.add_period_constraint(self.lookup_request("clk200").p, 1e9/200e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
try:
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks").rx, 1e9/125e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
try:
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks").tx, 1e9/125e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
self.add_period_constraint(self.lookup_request("clk200", loose=True), 1e9/200e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:rx", loose=True), 1e9/125e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:tx", loose=True), 1e9/125e6)
|
||||
self.add_platform_command("set_property DCI_CASCADE {{32 34}} [get_iobanks 33]")
|
||||
|
|
|
@ -498,6 +498,8 @@ class Platform(XilinxPlatform):
|
|||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk125", loose=True), 1e9/125e6)
|
||||
self.add_period_constraint(self.lookup_request("clk300", loose=True), 1e9/300e6)
|
||||
self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 44]")
|
||||
self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 45]")
|
||||
self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 46]")
|
||||
|
|
|
@ -92,3 +92,7 @@ class Platform(LatticePlatform):
|
|||
</ispXCF>
|
||||
"""
|
||||
return LatticeProgrammer(_xcf_template)
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
LatticePlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk12", loose=True), 1e9/12e6)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform
|
||||
from litex.build.xilinx.programmer import FpgaProg
|
||||
from litex.build.xilinx.programmer import XC3SProg
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -136,4 +136,9 @@ class Platform(XilinxPlatform):
|
|||
XilinxPlatform.__init__(self, device+"-3-ftg256", _io, _connectors)
|
||||
|
||||
def create_programmer(self):
|
||||
return FpgaProg()
|
||||
return XC3SProg(cable="ftdi")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk32", loose=True), 1e9/32e6)
|
||||
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
# License: BSD
|
||||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
from litex.build.xilinx import XilinxPlatform
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -191,3 +192,12 @@ class Platform(XilinxPlatform):
|
|||
def __init__(self, device="xc7a35t"):
|
||||
assert device in ["xc7a35t", "xc7a100t"]
|
||||
XilinxPlatform.__init__(self, device + "-fgg484-2", _io, toolchain="vivado")
|
||||
|
||||
def create_programmer(self):
|
||||
bscan_spi = "bscan_spi_xc7a100t.bit" if "xc7a100t" in self.device else "bscan_spi_xc7a35t.bit"
|
||||
return OpenOCD("openocd_netv2_rpi.cfg", bscan_spi)
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:ref_clk", loose=True), 1e9/50e6)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -131,4 +132,9 @@ class Platform(XilinxPlatform):
|
|||
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 34]")
|
||||
|
||||
def create_programmer(self):
|
||||
return VivadoProgrammer()
|
||||
return OpenOCD("openocd_xc7_ft2232.cfg", "bscan_spi_xc7a100t.bit")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:ref_clk", loose=True), 1e9/50e6)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -230,9 +231,8 @@ class Platform(XilinxPlatform):
|
|||
"-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
|
||||
self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 35]")
|
||||
|
||||
|
||||
def create_programmer(self):
|
||||
return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4")
|
||||
return OpenOCD("openocd_xc7_ft2232.cfg", "bscan_spi_xc7a200t.bit")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
|
@ -240,3 +240,8 @@ class Platform(XilinxPlatform):
|
|||
self.add_period_constraint(self.lookup_request("eth_clocks").rx, 1e9/125e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
XilinxPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:rx", loose=True), 1e9/125e6)
|
||||
|
|
|
@ -67,3 +67,7 @@ class Platform(LatticePlatform):
|
|||
|
||||
def create_programmer(self):
|
||||
return TinyProgProgrammer()
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
LatticePlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk16", loose=True), 1e9/16e6)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.lattice import LatticePlatform
|
||||
from litex.build.lattice.programmer import UJProg
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -84,6 +85,13 @@ _io = [
|
|||
Subsignal("n", Pins("C10")),
|
||||
IOStandard("LVCMOS33")
|
||||
),
|
||||
|
||||
("usb", 0,
|
||||
Subsignal("d_p", Pins("D15")),
|
||||
Subsignal("d_n", Pins("E15")),
|
||||
Subsignal("pullup", Pins("B12 C12")),
|
||||
IOStandard("LVCMOS33")
|
||||
),
|
||||
]
|
||||
|
||||
# Platform -----------------------------------------------------------------------------------------
|
||||
|
@ -94,3 +102,10 @@ class Platform(LatticePlatform):
|
|||
|
||||
def __init__(self, device="LFE5U-45F", **kwargs):
|
||||
LatticePlatform.__init__(self, device + "-6BG381C", _io, **kwargs)
|
||||
|
||||
def create_programmer(self):
|
||||
return UJProg()
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
LatticePlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/25e6)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.lattice import LatticePlatform
|
||||
from litex.build.lattice.programmer import LatticeProgrammer
|
||||
from litex.build.lattice.programmer import OpenOCDJTAGProgrammer
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -224,12 +224,10 @@ class Platform(LatticePlatform):
|
|||
def __init__(self, **kwargs):
|
||||
LatticePlatform.__init__(self, "LFE5UM5G-45F-8BG381C", _io, _connectors, **kwargs)
|
||||
|
||||
def create_programmer(self):
|
||||
return OpenOCDJTAGProgrammer("openocd_versa_ecp5.cfg")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
try:
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks", 0).rx, 1e9/125e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
try:
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks", 1).rx, 1e9/125e6)
|
||||
except ConstraintError:
|
||||
pass
|
||||
self.add_period_constraint(self.lookup_request("clk100", loose=True), 1e9/100e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:rx", 0, loose=True), 1e9/125e6)
|
||||
self.add_period_constraint(self.lookup_request("eth_clocks:rx", 1, loose=True), 1e9/125e6)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -96,20 +97,25 @@ class BaseSoC(SoCCore):
|
|||
# Build --------------------------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Arty")
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Arty A7")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
vivado_build_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="enable Ethernet support")
|
||||
parser.add_argument("--with-etherbone", action="store_true", help="enable Etherbone support")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
parser.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
|
||||
args = parser.parse_args()
|
||||
|
||||
assert not (args.with_ethernet and args.with_etherbone)
|
||||
soc = BaseSoC(with_ethernet=args.with_ethernet, with_etherbone=args.with_etherbone,
|
||||
**soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build(**vivado_build_argdict(args))
|
||||
builder.build(**vivado_build_argdict(args), run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -31,7 +32,6 @@ class _CRG(Module):
|
|||
|
||||
# Clk / Rst
|
||||
clk50 = platform.request("clk50")
|
||||
platform.add_period_constraint(clk50, 1e9/50e6)
|
||||
|
||||
# PLL
|
||||
self.submodules.pll = pll = CycloneIVPLL(speedgrade="-6")
|
||||
|
@ -71,14 +71,19 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on DE0 Nano")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(**soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.sof"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -55,7 +56,8 @@ class BaseSoC(SoCCore):
|
|||
self.submodules.ddrphy = s7ddrphy.K7DDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR3",
|
||||
nphases = 4,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
sys_clk_freq = sys_clk_freq,
|
||||
cmd_latency = 1)
|
||||
self.add_csr("ddrphy")
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
|
@ -87,6 +89,8 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Genesys2")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="enable Ethernet support")
|
||||
|
@ -97,8 +101,11 @@ def main():
|
|||
soc = BaseSoC(with_ethernet=args.with_ethernet, with_etherbone=args.with_etherbone,
|
||||
**soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
# with more features, examples to run C/Rust code on the RISC-V CPU and documentation can be found
|
||||
# at: https://github.com/icebreaker-fpga/icebreaker-litex-examples
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -115,18 +116,24 @@ def flash(bios_flash_offset):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on iCEBreaker")
|
||||
parser.add_argument("--bios-flash-offset", default=0x40000, help="BIOS offset in SPI Flash")
|
||||
parser.add_argument("--flash", action="store_true", help="Load Bitstream")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
parser.add_argument("--bios-flash-offset", default=0x40000, help="BIOS offset in SPI Flash")
|
||||
parser.add_argument("--flash", action="store_true", help="Flash Bitstream")
|
||||
builder_args(parser)
|
||||
soc_core_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(args.bios_flash_offset, **soc_core_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bin"))
|
||||
|
||||
if args.flash:
|
||||
flash(args.bios_flash_offset)
|
||||
|
||||
soc = BaseSoC(args.bios_flash_offset, **soc_core_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# This file is Copyright (c) 2014-2015 Yann Sionneau <ys@m-labs.hk>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -83,16 +84,20 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on KC705")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(with_ethernet=args.with_ethernet, **soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -67,7 +68,6 @@ class BaseSoC(SoCCore):
|
|||
iodelay_clk_freq = 200e6,
|
||||
cmd_latency = 1)
|
||||
self.add_csr("ddrphy")
|
||||
self.add_constant("USDDRPHY_DEBUG")
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
module = EDY4016A(sys_clk_freq, "1:4"),
|
||||
|
@ -92,16 +92,20 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on KCU105")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(with_ethernet=args.with_ethernet, **soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# This file is Copyright (c) 2014 Yann Sionneau <ys@m-labs.hk>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
from fractions import Fraction
|
||||
|
||||
|
@ -69,14 +70,19 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on MiniSpartan6")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(**soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -95,18 +96,21 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on NeTV2")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("--with-spi-xip", action="store_true",
|
||||
help="enable SPI XIP support")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
parser.add_argument("--with-spi-xip", action="store_true", help="Enable SPI XIP support")
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(with_ethernet=args.with_ethernet, with_spi_xip=args.with_spi_xip, **soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -117,16 +118,14 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Nexys4DDR")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
parser.add_argument("--sys-clk-freq", default=75e6,
|
||||
help="system clock frequency (default=75MHz)")
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("--with-spi-sdcard", action="store_true",
|
||||
help="enable SPI-mode SDCard support")
|
||||
parser.add_argument("--with-sdcard", action="store_true",
|
||||
help="enable SDCard support")
|
||||
parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default=75MHz)")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
parser.add_argument("--with-spi-sdcard", action="store_true", help="enable SPI-mode SDCard support")
|
||||
parser.add_argument("--with-sdcard", action="store_true", help="enable SDCard support")
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(sys_clk_freq=int(float(args.sys_clk_freq)),
|
||||
|
@ -139,8 +138,11 @@ def main():
|
|||
raise ValueError("'--with-spi-sdcard' and '--with-sdcard' are mutually exclusive!")
|
||||
soc.add_sdcard()
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -83,16 +84,20 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Nexys Video")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(with_ethernet=args.with_ethernet, **soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.bit"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
import importlib
|
||||
|
||||
|
@ -41,14 +42,12 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Generic LiteX SoC")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
builder_args(parser)
|
||||
soc_core_args(parser)
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("platform",
|
||||
help="module name of the platform to build for")
|
||||
parser.add_argument("--gateware-toolchain", default=None,
|
||||
help="FPGA gateware toolchain used for build")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
parser.add_argument("platform", help="Module name of the platform to build for")
|
||||
parser.add_argument("--gateware-toolchain", default=None, help="FPGA gateware toolchain used for build")
|
||||
args = parser.parse_args()
|
||||
|
||||
platform_module = importlib.import_module(args.platform)
|
||||
|
@ -58,7 +57,7 @@ def main():
|
|||
platform = platform_module.Platform()
|
||||
soc = BaseSoC(platform, with_ethernet=args.with_ethernet, **soc_core_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder.build()
|
||||
builder.build(run=args.build)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# This file is Copyright (c) 2018 David Shah <dave@ds0.me>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
|
@ -27,7 +28,7 @@ from litedram.phy import GENSDRPHY
|
|||
# CRG ----------------------------------------------------------------------------------------------
|
||||
|
||||
class _CRG(Module):
|
||||
def __init__(self, platform, sys_clk_freq):
|
||||
def __init__(self, platform, sys_clk_freq, with_usb_pll=False):
|
||||
self.clock_domains.cd_sys = ClockDomain()
|
||||
self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)
|
||||
|
||||
|
@ -36,7 +37,6 @@ class _CRG(Module):
|
|||
# Clk / Rst
|
||||
clk25 = platform.request("clk25")
|
||||
rst = platform.request("rst")
|
||||
platform.add_period_constraint(clk25, 1e9/25e6)
|
||||
|
||||
# PLL
|
||||
self.submodules.pll = pll = ECP5PLL()
|
||||
|
@ -46,6 +46,15 @@ class _CRG(Module):
|
|||
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90)
|
||||
self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked | rst)
|
||||
|
||||
# USB PLL
|
||||
if with_usb_pll:
|
||||
self.submodules.usb_pll = usb_pll = ECP5PLL()
|
||||
usb_pll.register_clkin(clk25, 25e6)
|
||||
self.clock_domains.cd_usb_12 = ClockDomain()
|
||||
self.clock_domains.cd_usb_48 = ClockDomain()
|
||||
usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0)
|
||||
usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0)
|
||||
|
||||
# SDRAM clock
|
||||
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), ClockSignal("sys_ps"))
|
||||
|
||||
|
@ -64,7 +73,8 @@ class BaseSoC(SoCCore):
|
|||
SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)
|
||||
|
||||
# CRG --------------------------------------------------------------------------------------
|
||||
self.submodules.crg = _CRG(platform, sys_clk_freq)
|
||||
with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
|
||||
self.submodules.crg = _CRG(platform, sys_clk_freq, with_usb_pll)
|
||||
|
||||
# SDR SDRAM --------------------------------------------------------------------------------
|
||||
if not self.integrated_main_ram_size:
|
||||
|
@ -83,14 +93,12 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on ULX3S")
|
||||
parser.add_argument("--gateware-toolchain", dest="toolchain", default="trellis",
|
||||
help="gateware toolchain to use, trellis (default) or diamond")
|
||||
parser.add_argument("--device", dest="device", default="LFE5U-45F",
|
||||
help="FPGA device, ULX3S can be populated with LFE5U-12F, LFE5U-25F, LFE5U-45F (default) or LFE5U-85F")
|
||||
parser.add_argument("--sys-clk-freq", default=50e6,
|
||||
help="system clock frequency (default=50MHz)")
|
||||
parser.add_argument("--sdram-module", default="MT48LC16M16",
|
||||
help="SDRAM module: MT48LC16M16, AS4C32M16 or AS4C16M16 (default=MT48LC16M16)")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
parser.add_argument("--gateware-toolchain", dest="toolchain", default="trellis", help="Gateware toolchain to use, trellis (default) or diamond")
|
||||
parser.add_argument("--device", dest="device", default="LFE5U-45F", help="FPGA device, ULX3S can be populated with LFE5U-45F (default) or LFE5U-85F")
|
||||
parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default=50MHz)")
|
||||
parser.add_argument("--sdram-module", default="MT48LC16M16", help="SDRAM module: MT48LC16M16, AS4C32M16 or AS4C16M16 (default=MT48LC16M16)")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
trellis_args(parser)
|
||||
|
@ -102,7 +110,11 @@ def main():
|
|||
**soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {}
|
||||
builder.build(**builder_kargs)
|
||||
builder.build(**builder_kargs, run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.svf"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# This file is Copyright (c) 2018-2019 David Shah <dave@ds0.me>
|
||||
# License: BSD
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from migen import *
|
||||
|
@ -40,7 +41,6 @@ class _CRG(Module):
|
|||
# Clk / Rst
|
||||
clk100 = platform.request("clk100")
|
||||
rst_n = platform.request("rst_n")
|
||||
platform.add_period_constraint(clk100, 1e9/100e6)
|
||||
|
||||
# Power on reset
|
||||
por_count = Signal(16, reset=2**16-1)
|
||||
|
@ -110,21 +110,24 @@ class BaseSoC(SoCCore):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="LiteX SoC on Versa ECP5")
|
||||
parser.add_argument("--gateware-toolchain", dest="toolchain", default="trellis",
|
||||
help="gateware toolchain to use, trellis (default) or diamond")
|
||||
parser.add_argument("--build", action="store_true", help="Build bitstream")
|
||||
parser.add_argument("--load", action="store_true", help="Load bitstream")
|
||||
parser.add_argument("--gateware-toolchain", dest="toolchain", default="trellis", help="Gateware toolchain to use, trellis (default) or diamond")
|
||||
builder_args(parser)
|
||||
soc_sdram_args(parser)
|
||||
trellis_args(parser)
|
||||
parser.add_argument("--sys-clk-freq", default=75e6,
|
||||
help="system clock frequency (default=75MHz)")
|
||||
parser.add_argument("--with-ethernet", action="store_true",
|
||||
help="enable Ethernet support")
|
||||
parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default=75MHz)")
|
||||
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
|
||||
args = parser.parse_args()
|
||||
|
||||
soc = BaseSoC(sys_clk_freq=int(float(args.sys_clk_freq)), with_ethernet=args.with_ethernet, toolchain=args.toolchain, **soc_sdram_argdict(args))
|
||||
builder = Builder(soc, **builder_argdict(args))
|
||||
builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {}
|
||||
builder.build(**builder_kargs)
|
||||
builder.build(**builder_kargs, run=args.build)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer()
|
||||
prog.load_bitstream(os.path.join(builder.gateware_dir, "top.svf"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -33,6 +33,7 @@ class AlteraPlatform(GenericPlatform):
|
|||
return self.toolchain.build(self, *args, **kwargs)
|
||||
|
||||
def add_period_constraint(self, clk, period):
|
||||
if clk is None: return
|
||||
if hasattr(clk, "p"):
|
||||
clk = clk.p
|
||||
self.toolchain.add_period_constraint(self, clk, period)
|
||||
|
|
|
@ -205,13 +205,21 @@ class ConstraintManager:
|
|||
self.matched.append((resource, obj))
|
||||
return obj
|
||||
|
||||
def lookup_request(self, name, number=None):
|
||||
def lookup_request(self, name, number=None, loose=False):
|
||||
subname = None
|
||||
if ":" in name: name, subname = name.split(":")
|
||||
for resource, obj in self.matched:
|
||||
if resource[0] == name and (number is None or
|
||||
resource[1] == number):
|
||||
return obj
|
||||
if subname is not None:
|
||||
return getattr(obj, subname)
|
||||
else:
|
||||
return obj
|
||||
|
||||
raise ConstraintError("Resource not found: {}:{}".format(name, number))
|
||||
if loose:
|
||||
return None
|
||||
else:
|
||||
raise ConstraintError("Resource not found: {}:{}".format(name, number))
|
||||
|
||||
def add_platform_command(self, command, **signals):
|
||||
self.platform_commands.append((command, signals))
|
||||
|
|
|
@ -20,7 +20,10 @@ class GenericProgrammer:
|
|||
self.flash_proxy_repos = [
|
||||
"https://github.com/quartiq/bscan_spi_bitstreams/raw/master/",
|
||||
]
|
||||
self.flash_proxy_local = "flash_proxies"
|
||||
self.config_repos = [
|
||||
"https://raw.githubusercontent.com/litex-hub/litex-boards/master/litex_boards/prog/",
|
||||
]
|
||||
self.prog_local = "prog"
|
||||
|
||||
def set_flash_proxy_dir(self, flash_proxy_dir):
|
||||
if flash_proxy_dir is not None:
|
||||
|
@ -34,23 +37,48 @@ class GenericProgrammer:
|
|||
if os.path.exists(fullname):
|
||||
return fullname
|
||||
# Search in local flash_proxy directory
|
||||
fullname = tools.cygpath(os.path.join(self.flash_proxy_local, self.flash_proxy_basename))
|
||||
fullname = tools.cygpath(os.path.join(self.prog_local, self.flash_proxy_basename))
|
||||
if os.path.exists(fullname):
|
||||
return fullname
|
||||
# Search in repositories and download it
|
||||
import requests
|
||||
os.makedirs(self.flash_proxy_local, exist_ok=True)
|
||||
os.makedirs(self.prog_local, exist_ok=True)
|
||||
for d in self.flash_proxy_repos:
|
||||
fullname = tools.cygpath(os.path.join(self.flash_proxy_local, self.flash_proxy_basename))
|
||||
fullname = tools.cygpath(os.path.join(self.prog_local, self.flash_proxy_basename))
|
||||
try:
|
||||
r = requests.get(d + self.flash_proxy_basename)
|
||||
with open(fullname, "wb") as f:
|
||||
f.write(r.content)
|
||||
return fullname
|
||||
if r.status_code != 404:
|
||||
with open(fullname, "wb") as f:
|
||||
f.write(r.content)
|
||||
return fullname
|
||||
except:
|
||||
pass
|
||||
raise OSError("Failed to find flash proxy bitstream")
|
||||
|
||||
def find_config(self):
|
||||
# Search in local directory
|
||||
fullname = tools.cygpath(self.config)
|
||||
if os.path.exists(fullname):
|
||||
return self.config
|
||||
# Search in local config directory
|
||||
fullname = tools.cygpath(os.path.join(self.prog_local, self.config))
|
||||
if os.path.exists(fullname):
|
||||
return fullname
|
||||
# Search in repositories and download it
|
||||
import requests
|
||||
os.makedirs(self.prog_local, exist_ok=True)
|
||||
for d in self.config_repos:
|
||||
fullname = tools.cygpath(os.path.join(self.prog_local, self.config))
|
||||
try:
|
||||
r = requests.get(d + self.config)
|
||||
if r.status_code != 404:
|
||||
with open(fullname, "wb") as f:
|
||||
f.write(r.content)
|
||||
return fullname
|
||||
except:
|
||||
pass
|
||||
raise OSError("Failed to find config file")
|
||||
|
||||
# Must be overloaded by specific programmer
|
||||
def load_bitstream(self, bitstream_file):
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -93,32 +93,35 @@ def parse_device(device):
|
|||
_build_template = [
|
||||
"yosys -l {build_name}.rpt {build_name}.ys",
|
||||
"nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf --asc {build_name}.txt \
|
||||
--pre-pack {build_name}_pre_pack.py --{architecture} --package {package} {timefailarg}",
|
||||
--pre-pack {build_name}_pre_pack.py --{architecture} --package {package} {timefailarg} {ignoreloops} --seed {seed}",
|
||||
"icepack -s {build_name}.txt {build_name}.bin"
|
||||
]
|
||||
|
||||
def _build_script(build_template, build_name, architecture, package, timingstrict):
|
||||
def _build_script(build_template, build_name, architecture, package, timingstrict, ignoreloops, seed):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
script_ext = ".bat"
|
||||
build_script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
|
||||
script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
|
||||
fail_stmt = " || exit /b"
|
||||
else:
|
||||
script_ext = ".sh"
|
||||
build_script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\nset -e\n"
|
||||
script_contents = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\nset -e\n"
|
||||
fail_stmt = ""
|
||||
|
||||
for s in build_template:
|
||||
s_fail = s + "{fail_stmt}\n" # Required so Windows scripts fail early.
|
||||
build_script_contents += s_fail.format(
|
||||
script_contents += s_fail.format(
|
||||
build_name = build_name,
|
||||
architecture = architecture,
|
||||
package = package,
|
||||
timefailarg = "--timing-allow-fail" if not timingstrict else "",
|
||||
fail_stmt = fail_stmt)
|
||||
ignoreloops = "--ignore-loops" if ignoreloops else "",
|
||||
fail_stmt = fail_stmt,
|
||||
seed = seed)
|
||||
|
||||
build_script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(build_script_file, build_script_contents,force_unix=False)
|
||||
return build_script_file
|
||||
script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(script_file, script_contents, force_unix=False)
|
||||
|
||||
return script_file
|
||||
|
||||
def _run_script(script):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
|
@ -158,6 +161,8 @@ class LatticeIceStormToolchain:
|
|||
synth_opts = "",
|
||||
run = True,
|
||||
timingstrict = False,
|
||||
ignoreloops = False,
|
||||
seed = 1,
|
||||
**kwargs):
|
||||
|
||||
# Create build directory
|
||||
|
@ -190,7 +195,7 @@ class LatticeIceStormToolchain:
|
|||
(family, architecture, package) = parse_device(platform.device)
|
||||
|
||||
# Generate build script
|
||||
script = _build_script(self.build_template, build_name, architecture, package, timingstrict)
|
||||
script = _build_script(self.build_template, build_name, architecture, package, timingstrict, ignoreloops, seed)
|
||||
|
||||
# Run
|
||||
if run:
|
||||
|
@ -207,3 +212,18 @@ class LatticeIceStormToolchain:
|
|||
raise ValueError("Clock already constrained to {:.2f}ns, new constraint to {:.2f}ns"
|
||||
.format(self.clocks[clk], period))
|
||||
self.clocks[clk] = period
|
||||
|
||||
def icestorm_args(parser):
|
||||
parser.add_argument("--nextpnr-timingstrict", action="store_true",
|
||||
help="fail if timing not met, i.e., do NOT pass '--timing-allow-fail' to nextpnr")
|
||||
parser.add_argument("--nextpnr-ignoreloops", action="store_true",
|
||||
help="ignore combinational loops in timing analysis, i.e. pass '--ignore-loops' to nextpnr")
|
||||
parser.add_argument("--nextpnr-seed", default=1, type=int,
|
||||
help="seed to pass to nextpnr")
|
||||
|
||||
def icestorm_argdict(args):
|
||||
return {
|
||||
"timingstrict": args.nextpnr_timingstrict,
|
||||
"ignoreloops": args.nextpnr_ignoreloops,
|
||||
"seed": args.nextpnr_seed,
|
||||
}
|
|
@ -34,6 +34,7 @@ class LatticePlatform(GenericPlatform):
|
|||
return self.toolchain.build(self, *args, **kwargs)
|
||||
|
||||
def add_period_constraint(self, clk, period):
|
||||
if clk is None: return
|
||||
if hasattr(clk, "p"):
|
||||
clk = clk.p
|
||||
self.toolchain.add_period_constraint(self, clk, period)
|
||||
|
|
|
@ -25,39 +25,31 @@ class LatticeProgrammer(GenericProgrammer):
|
|||
# OpenOCDJTAGProgrammer --------------------------------------------------------------------------------
|
||||
|
||||
class OpenOCDJTAGProgrammer(GenericProgrammer):
|
||||
def __init__(self, openocd_config, flash_proxy_basename=None):
|
||||
GenericProgrammer.__init__(self, flash_proxy_basename=flash_proxy_basename)
|
||||
self.openocd_config = openocd_config
|
||||
def __init__(self, config, flash_proxy_basename=None):
|
||||
GenericProgrammer.__init__(self, flash_proxy_basename)
|
||||
self.config = config
|
||||
|
||||
def load_bitstream(self, bitstream_file):
|
||||
config = self.find_config()
|
||||
svf_file = bitstream_file.replace(".bit", ".svf")
|
||||
subprocess.call(["openocd", "-f", config, "-c", "transport select jtag; init; svf quiet progress \"{}\"; exit".format(svf_file)])
|
||||
|
||||
subprocess.call(["openocd", "-f", self.openocd_config , "-c", "transport select jtag; init; svf \"{}\"; exit".format(svf_file)])
|
||||
|
||||
def flash(self, address, data, erase=False, verify=True):
|
||||
if self.flash_proxy_basename is None:
|
||||
flash_proxy = None
|
||||
else:
|
||||
flash_proxy = self.find_flash_proxy()
|
||||
|
||||
if erase:
|
||||
erase = "erase"
|
||||
else:
|
||||
erase = ""
|
||||
|
||||
def flash(self, address, data, verify=True):
|
||||
config = self.find_config()
|
||||
flash_proxy = self.find_flash_proxy()
|
||||
script = "; ".join([
|
||||
"transport select jtag",
|
||||
"target create ecp5.spi0.proxy testee -chain-position ecp5.tap",
|
||||
"flash bank spi0 jtagspi 0 0 0 0 ecp5.spi0.proxy 0x32",
|
||||
"init",
|
||||
"svf \"{}\"" if flash_proxy is not None else "".format(flash_proxy),
|
||||
"svf quiet progress \"{}\"".format(flash_proxy),
|
||||
"reset halt",
|
||||
"flash probe spi0",
|
||||
"flash write_image {0} \"{1}\" 0x{2:x}".format(erase, data, address),
|
||||
"flash write_image erase \"{0}\" 0x{1:x}".format(data, address),
|
||||
"flash verify_bank spi0 \"{0}\" 0x{1:x}" if verify else "".format(data, address),
|
||||
"exit"
|
||||
])
|
||||
subprocess.call(["openocd", "-f", self.openocd_config, "-c", script])
|
||||
subprocess.call(["openocd", "-f", config, "-c", script])
|
||||
|
||||
# IceStormProgrammer -------------------------------------------------------------------------------
|
||||
|
||||
|
@ -138,3 +130,11 @@ class MyStormProgrammer(GenericProgrammer):
|
|||
with serial.Serial(self.serial_port) as port:
|
||||
with open(bitstream_file, "rb") as f:
|
||||
port.write(f.read())
|
||||
|
||||
# UJProg -------------------------------------------------------------------------------------------
|
||||
|
||||
class UJProg(GenericProgrammer):
|
||||
needs_bitreverse = False
|
||||
|
||||
def load_bitstream(self, bitstream_file):
|
||||
subprocess.call(["ujprog", bitstream_file])
|
||||
|
|
|
@ -117,11 +117,11 @@ nextpnr_ecp5_architectures = {
|
|||
_build_template = [
|
||||
"yosys -l {build_name}.rpt {build_name}.ys",
|
||||
"nextpnr-ecp5 --json {build_name}.json --lpf {build_name}.lpf --textcfg {build_name}.config \
|
||||
--{architecture} --package {package} --speed {speed_grade} {timefailarg} {ignoreloops}",
|
||||
--{architecture} --package {package} --speed {speed_grade} {timefailarg} {ignoreloops} --seed {seed}",
|
||||
"ecppack {build_name}.config --svf {build_name}.svf --bit {build_name}.bit"
|
||||
]
|
||||
|
||||
def _build_script(source, build_template, build_name, architecture, package, speed_grade, timingstrict, ignoreloops):
|
||||
def _build_script(source, build_template, build_name, architecture, package, speed_grade, timingstrict, ignoreloops, seed):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
script_ext = ".bat"
|
||||
script_contents = "@echo off\nrem Autogenerated by LiteX / git: " + tools.get_litex_git_revision() + "\n\n"
|
||||
|
@ -134,13 +134,14 @@ def _build_script(source, build_template, build_name, architecture, package, spe
|
|||
for s in build_template:
|
||||
s_fail = s + "{fail_stmt}\n" # Required so Windows scripts fail early.
|
||||
script_contents += s_fail.format(
|
||||
build_name = build_name,
|
||||
architecture = architecture,
|
||||
package = package,
|
||||
speed_grade = speed_grade,
|
||||
timefailarg = "--timing-allow-fail" if not timingstrict else "",
|
||||
ignoreloops = "--ignore-loops" if ignoreloops else "",
|
||||
fail_stmt = fail_stmt)
|
||||
build_name = build_name,
|
||||
architecture = architecture,
|
||||
package = package,
|
||||
speed_grade = speed_grade,
|
||||
timefailarg = "--timing-allow-fail" if not timingstrict else "",
|
||||
ignoreloops = "--ignore-loops" if ignoreloops else "",
|
||||
fail_stmt = fail_stmt,
|
||||
seed = seed)
|
||||
|
||||
script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(script_file, script_contents, force_unix=False)
|
||||
|
@ -186,6 +187,7 @@ class LatticeTrellisToolchain:
|
|||
nowidelut = False,
|
||||
timingstrict = False,
|
||||
ignoreloops = False,
|
||||
seed = 1,
|
||||
**kwargs):
|
||||
|
||||
# Create build directory
|
||||
|
@ -217,7 +219,7 @@ class LatticeTrellisToolchain:
|
|||
|
||||
# Generate build script
|
||||
script = _build_script(False, self.build_template, build_name, architecture, package,
|
||||
speed_grade, timingstrict, ignoreloops)
|
||||
speed_grade, timingstrict, ignoreloops, seed)
|
||||
|
||||
# Run
|
||||
if run:
|
||||
|
@ -244,10 +246,13 @@ def trellis_args(parser):
|
|||
help="fail if timing not met, i.e., do NOT pass '--timing-allow-fail' to nextpnr")
|
||||
parser.add_argument("--nextpnr-ignoreloops", action="store_true",
|
||||
help="ignore combinational loops in timing analysis, i.e. pass '--ignore-loops' to nextpnr")
|
||||
parser.add_argument("--nextpnr-seed", default=1, type=int,
|
||||
help="seed to pass to nextpnr")
|
||||
|
||||
def trellis_argdict(args):
|
||||
return {
|
||||
"nowidelut": args.yosys_nowidelut,
|
||||
"timingstrict": args.nextpnr_timingstrict,
|
||||
"ignoreloops": args.nextpnr_ignoreloops,
|
||||
"seed": args.nextpnr_seed,
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ class MicrosemiPlatform(GenericPlatform):
|
|||
return self.toolchain.build(self, *args, **kwargs)
|
||||
|
||||
def add_period_constraint(self, clk, period):
|
||||
if clk is None: return
|
||||
clk.attr.add("keep")
|
||||
if hasattr(clk, "p"):
|
||||
clk = clk.p
|
||||
|
|
|
@ -17,14 +17,16 @@ class OpenOCD(GenericProgrammer):
|
|||
self.config = config
|
||||
|
||||
def load_bitstream(self, bitstream):
|
||||
config = self.find_config()
|
||||
script = "; ".join([
|
||||
"init",
|
||||
"pld load 0 {{{}}}".format(bitstream),
|
||||
"exit",
|
||||
])
|
||||
subprocess.call(["openocd", "-f", self.config, "-c", script])
|
||||
subprocess.call(["openocd", "-f", config, "-c", script])
|
||||
|
||||
def flash(self, address, data, set_qe=False):
|
||||
config = self.find_config()
|
||||
flash_proxy = self.find_flash_proxy()
|
||||
script = "; ".join([
|
||||
"init",
|
||||
|
@ -34,7 +36,7 @@ class OpenOCD(GenericProgrammer):
|
|||
"fpga_program",
|
||||
"exit"
|
||||
])
|
||||
subprocess.call(["openocd", "-f", self.config, "-c", script])
|
||||
subprocess.call(["openocd", "-f", config, "-c", script])
|
||||
|
||||
|
||||
def stream(self, port=20000):
|
||||
|
|
|
@ -15,7 +15,7 @@ class XilinxPlatform(GenericPlatform):
|
|||
def __init__(self, *args, toolchain="ise", **kwargs):
|
||||
GenericPlatform.__init__(self, *args, **kwargs)
|
||||
self.edifs = set()
|
||||
self.ips = set()
|
||||
self.ips = {}
|
||||
if toolchain == "ise":
|
||||
self.toolchain = ise.XilinxISEToolchain()
|
||||
elif toolchain == "vivado":
|
||||
|
@ -26,8 +26,8 @@ class XilinxPlatform(GenericPlatform):
|
|||
def add_edif(self, filename):
|
||||
self.edifs.add((os.path.abspath(filename)))
|
||||
|
||||
def add_ip(self, filename):
|
||||
self.ips.add((os.path.abspath(filename)))
|
||||
def add_ip(self, filename, disable_constraints=False):
|
||||
self.ips.update({os.path.abspath(filename): disable_constraints})
|
||||
|
||||
def get_verilog(self, *args, special_overrides=dict(), **kwargs):
|
||||
so = dict(common.xilinx_special_overrides)
|
||||
|
@ -48,6 +48,7 @@ class XilinxPlatform(GenericPlatform):
|
|||
return self.toolchain.build(self, *args, **kwargs)
|
||||
|
||||
def add_period_constraint(self, clk, period):
|
||||
if clk is None: return
|
||||
if hasattr(clk, "p"):
|
||||
clk = clk.p
|
||||
self.toolchain.add_period_constraint(self, clk, period)
|
||||
|
|
|
@ -155,7 +155,7 @@ class XilinxVivadoToolchain:
|
|||
|
||||
# Add IPs
|
||||
tcl.append("\n# Add IPs\n")
|
||||
for filename in platform.ips:
|
||||
for filename, disable_constraints in platform.ips.items():
|
||||
filename_tcl = "{" + filename + "}"
|
||||
ip = os.path.splitext(os.path.basename(filename))[0]
|
||||
tcl.append("read_ip " + filename_tcl)
|
||||
|
@ -163,10 +163,13 @@ class XilinxVivadoToolchain:
|
|||
tcl.append("generate_target all [get_ips {}]".format(ip))
|
||||
tcl.append("synth_ip [get_ips {}] -force".format(ip))
|
||||
tcl.append("get_files -all -of_objects [get_files {}]".format(filename_tcl))
|
||||
if disable_constraints:
|
||||
tcl.append("set_property is_enabled false [get_files -of_objects [get_files {}] -filter {{FILE_TYPE == XDC}}]".format(filename_tcl))
|
||||
|
||||
# Add constraints
|
||||
tcl.append("\n# Add constraints\n")
|
||||
tcl.append("read_xdc {}.xdc".format(build_name))
|
||||
tcl.append("set_property PROCESSING_ORDER EARLY [get_files {}.xdc]".format(build_name))
|
||||
|
||||
# Add pre-synthesis commands
|
||||
tcl.append("\n# Add pre-synthesis commands\n")
|
||||
|
@ -276,7 +279,7 @@ class XilinxVivadoToolchain:
|
|||
"-to [get_pins -filter {{REF_PIN_NAME == PRE}} "
|
||||
"-of_objects [get_cells -hierarchical -filter {{ars_ff1 == TRUE || ars_ff2 == TRUE}}]]"
|
||||
)
|
||||
# clock_period-2ns to resolve metastability on the wire between the AsyncResetSynchronizer FFs
|
||||
# clock_period-2ns to resolve metastability on the wire between the AsyncResetSynchronizer FFs
|
||||
platform.add_platform_command(
|
||||
"set_max_delay 2 -quiet "
|
||||
"-from [get_pins -filter {{REF_PIN_NAME == C}} "
|
||||
|
|
|
@ -236,17 +236,17 @@ def _printheader(f, ios, name, ns, attr_translate,
|
|||
sig.type = "wire"
|
||||
if sig in inouts:
|
||||
sig.direction = "inout"
|
||||
r += "\tinout " + _printsig(ns, sig)
|
||||
r += "\tinout wire " + _printsig(ns, sig)
|
||||
elif sig in targets:
|
||||
sig.direction = "output"
|
||||
if sig in wires:
|
||||
r += "\toutput " + _printsig(ns, sig)
|
||||
r += "\toutput wire " + _printsig(ns, sig)
|
||||
else:
|
||||
sig.type = "reg"
|
||||
r += "\toutput reg " + _printsig(ns, sig)
|
||||
else:
|
||||
sig.direction = "input"
|
||||
r += "\tinput " + _printsig(ns, sig)
|
||||
r += "\tinput wire " + _printsig(ns, sig)
|
||||
r += "\n);\n\n"
|
||||
for sig in sorted(sigs - ios, key=lambda x: x.duid):
|
||||
attr = _printattr(sig.attr, attr_translate)
|
||||
|
|
|
@ -676,6 +676,7 @@ class ECP5PLL(Module):
|
|||
clkfb = Signal()
|
||||
self.params.update(
|
||||
attr=[
|
||||
("FREQUENCY_PIN_CLKI", str(self.clkin_freq/1e6)),
|
||||
("ICP_CURRENT", "6"),
|
||||
("LPF_RESISTOR", "16"),
|
||||
("MFG_ENABLE_FILTEROPAMP", "1"),
|
||||
|
|
|
@ -29,46 +29,73 @@ class CPUNone(CPU):
|
|||
periph_buses = []
|
||||
memory_buses = []
|
||||
|
||||
CPU_GCC_TRIPLE_RISCV32 = (
|
||||
"riscv64-unknown-elf",
|
||||
"riscv32-unknown-elf",
|
||||
"riscv-none-embed",
|
||||
"riscv64-linux",
|
||||
"riscv-sifive-elf",
|
||||
"riscv64-none-elf",
|
||||
)
|
||||
|
||||
CPU_GCC_TRIPLE_RISCV64 = (
|
||||
"riscv64-unknown-elf",
|
||||
"riscv64-linux",
|
||||
"riscv-sifive-elf",
|
||||
"riscv64-none-elf",
|
||||
)
|
||||
|
||||
# CPUS ---------------------------------------------------------------------------------------------
|
||||
|
||||
from litex.soc.cores.cpu.lm32 import LM32
|
||||
from litex.soc.cores.cpu.mor1kx import MOR1KX
|
||||
from litex.soc.cores.cpu.picorv32 import PicoRV32
|
||||
from litex.soc.cores.cpu.vexriscv import VexRiscv
|
||||
from litex.soc.cores.cpu.minerva import Minerva
|
||||
from litex.soc.cores.cpu.rocket import RocketRV64
|
||||
from litex.soc.cores.cpu.microwatt import Microwatt
|
||||
from litex.soc.cores.cpu.blackparrot import BlackParrotRV64
|
||||
from litex.soc.cores.cpu.serv import SERV
|
||||
from litex.soc.cores.cpu.picorv32 import PicoRV32
|
||||
from litex.soc.cores.cpu.minerva import Minerva
|
||||
from litex.soc.cores.cpu.vexriscv import VexRiscv
|
||||
from litex.soc.cores.cpu.rocket import RocketRV64
|
||||
from litex.soc.cores.cpu.blackparrot import BlackParrotRV64
|
||||
|
||||
CPUS = {
|
||||
# None
|
||||
"None" : CPUNone,
|
||||
|
||||
# LM32
|
||||
"lm32" : LM32,
|
||||
|
||||
# OpenRisc
|
||||
"mor1kx" : MOR1KX,
|
||||
"picorv32" : PicoRV32,
|
||||
"vexriscv" : VexRiscv,
|
||||
"minerva" : Minerva,
|
||||
"rocket" : RocketRV64,
|
||||
|
||||
# Open Power
|
||||
"microwatt" : Microwatt,
|
||||
|
||||
# RISC-V 32-bit
|
||||
"serv" : SERV,
|
||||
"picorv32" : PicoRV32,
|
||||
"minerva" : Minerva,
|
||||
"vexriscv" : VexRiscv,
|
||||
|
||||
# RISC-V 64-bit
|
||||
"rocket" : RocketRV64,
|
||||
"blackparrot" : BlackParrotRV64,
|
||||
"serv" : SERV
|
||||
}
|
||||
|
||||
# CPU Variants/Extensions Definition ---------------------------------------------------------------
|
||||
|
||||
CPU_VARIANTS = {
|
||||
# "official name": ["alias 1", "alias 2"],
|
||||
"minimal" : ["min",],
|
||||
"lite" : ["light", "zephyr", "nuttx"],
|
||||
"standard": [None, "std"],
|
||||
"full": [],
|
||||
"linux" : [],
|
||||
"linuxd" : [],
|
||||
"linuxq" : [],
|
||||
"minimal" : ["min",],
|
||||
"lite" : ["light", "zephyr", "nuttx"],
|
||||
"standard": [None, "std"],
|
||||
"imac": [],
|
||||
"full": [],
|
||||
"linux" : [],
|
||||
"linuxd" : [],
|
||||
"linuxq" : [],
|
||||
}
|
||||
CPU_VARIANTS_EXTENSIONS = ["debug", "no-dsp"]
|
||||
|
||||
|
||||
class InvalidCPUVariantError(ValueError):
|
||||
def __init__(self, variant):
|
||||
msg = """\
|
||||
|
|
24
litex/soc/cores/cpu/blackparrot/GETTING_STARTED.md
Normal file
24
litex/soc/cores/cpu/blackparrot/GETTING_STARTED.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Getting started (TODO:update)
|
||||
|
||||
## Running BP in LiteX
|
||||
|
||||
cd $LITEX/litex/tools # the folder where litex simulator resides
|
||||
|
||||
./litex_sim.py --cpu-type blackparrot --cpu-variant standard --integrated-rom-size 40960 --output-dir build/BP --threads 4 --opt-level=O0 --trace --trace-start 0
|
||||
|
||||
#The above command will generate a dut.vcd file under build/BP/gateware folder. gtkwave works fine with the generated dut.vcd.
|
||||
|
||||
## Additional Information
|
||||
|
||||
The BlackParrot resides in $BP/pre-alpha-release/
|
||||
|
||||
core.py in $BP folder is the wrapper that integrates BP into LiteX.
|
||||
|
||||
flist.verilator in $BP is all the files that litex_sim fetches for simulation.
|
||||
|
||||
The top module is $BP_FPGA_DIR/ExampleBlackParrotSystem.v
|
||||
|
||||
The transducer for wishbone communication is $BP_FPGA_DIR/bp2wb_convertor.v
|
||||
|
||||
if args.sdram_init is not None: #instead of ram_init for sdram init boot
|
||||
soc.add_constant("ROM_BOOT_ADDRESS", 0x80000000)
|
|
@ -1,12 +1,60 @@
|
|||
TODO: Edit
|
||||
git submodule update --init --recursive (for blackparrot pre-alpha repo)
|
||||
cd pre_alpha_release
|
||||
follow getting_started to install blackparrot
|
||||
cd ..
|
||||
# BlackParrot in LiteX
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
TODO: modify getting started [Getting Started (Full)](GETTING_STARTED.md)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
```
|
||||
BP sources (https://github.com/litex-hub/pythondata-cpu-blackparrot)
|
||||
RISC-V toolchain built for IA architecture (prebuilt binaries provided by LiteX works fine)
|
||||
Verilator (tested with Verilator 4.031)
|
||||
```
|
||||
|
||||
### Installing
|
||||
|
||||
```
|
||||
https://github.com/litex-hub/pythondata-cpu-blackparrot is required to run BP in LiteX.
|
||||
source ./setEnvironment.sh #should be sourced each time you open a terminal or just add this line to bashrc
|
||||
Add $BP_TOP/external/bin to $PATH for verilator and riscv-gnu tools
|
||||
./update_BP.sh #to modify some of the files in Blackparrot repo (one-time process)
|
||||
Currently, we could simulate the LITEX-BIOS on BP processor.
|
||||
```
|
||||
|
||||
## Running BIOS
|
||||
|
||||
### Simulation
|
||||
```
|
||||
cd $LITEX/litex/tools
|
||||
./litex_sim.py --cpu-type blackparrot --cpu-variant standard --output-dir build/BP_Trial
|
||||
```
|
||||
[![asciicast](https://asciinema.org/a/326077.svg)](https://asciinema.org/a/326077)
|
||||
|
||||
### FPGA
|
||||
```
|
||||
Coming soon!
|
||||
```
|
||||
|
||||
## Running Linux
|
||||
|
||||
|
||||
### Simulation
|
||||
```
|
||||
Modify litex_sim.py by replacing soc.add_constant("ROM_BOOT_ADDRESS", 0x40000000) with soc.add_constant("ROM_BOOT_ADDRESS", 0x80000000)
|
||||
|
||||
./litex_sim.py --cpu-type blackparrot --cpu-variant standard --integrated-rom-size 40960 --output-dir build/BP_newversion_linux_ram/ --threads 4 --ram-init build/tests/boot.bin.uart.simu.trial
|
||||
|
||||
TODO: add prebuilt bbl files into python-data repository
|
||||
|
||||
```
|
||||
|
||||
### FPGA
|
||||
|
||||
```
|
||||
Coming soon!
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[![asciicast](https://asciinema.org/a/286568.svg)](https://asciinema.org/a/286568)
|
||||
|
||||
|
|
|
@ -1,434 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* ExampleBlackParrotSystem For Simulating With Litex
|
||||
*
|
||||
*/
|
||||
|
||||
`include "bsg_noc_links.vh"
|
||||
|
||||
module ExampleBlackParrotSystem
|
||||
import bp_common_pkg::*;
|
||||
import bp_common_aviary_pkg::*;
|
||||
import bp_be_pkg::*;
|
||||
import bp_common_rv64_pkg::*;
|
||||
import bp_cce_pkg::*;
|
||||
import bp_cfg_link_pkg::*;
|
||||
#(parameter bp_cfg_e cfg_p = e_bp_single_core_cfg // Replaced by the flow with a specific bp_cfg
|
||||
`declare_bp_proc_params(cfg_p)
|
||||
`declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p)
|
||||
|
||||
// Tracing parameters
|
||||
, parameter calc_trace_p = 1
|
||||
, parameter cce_trace_p = 0
|
||||
, parameter cmt_trace_p = 0
|
||||
, parameter dram_trace_p = 0
|
||||
, parameter skip_init_p = 0
|
||||
|
||||
, parameter mem_load_p = 1
|
||||
, parameter mem_file_p = "prog.mem"
|
||||
, parameter mem_cap_in_bytes_p = 2**20
|
||||
, parameter [paddr_width_p-1:0] mem_offset_p = paddr_width_p'(32'h8000_0000)
|
||||
|
||||
)
|
||||
(input clk_i
|
||||
, input reset_i
|
||||
//Wishbone interface
|
||||
, input [63:0] wbm_dat_i
|
||||
, output [63:0] wbm_dat_o
|
||||
, input wbm_ack_i
|
||||
// , input wbm_err_i
|
||||
// , input wbm_rty_i
|
||||
, output [36:0] wbm_adr_o //TODO parametrize this
|
||||
, output wbm_stb_o
|
||||
, output wbm_cyc_o
|
||||
, output wbm_sel_o //TODO: how many bits ? check 3.5 table 3-1
|
||||
, output wbm_we_o
|
||||
, output [2:0] wbm_cti_o //TODO: hardwire in Litex
|
||||
, output [1:0] wbm_bte_o //TODO: hardwire in Litex
|
||||
, output all_finished_debug_o //SC_add
|
||||
, output core_passed_debug
|
||||
, output core_failed_debug
|
||||
, input [3:0] interrupts
|
||||
);
|
||||
|
||||
`declare_bsg_ready_and_link_sif_s(mem_noc_flit_width_p, bsg_ready_and_link_sif_s);
|
||||
`declare_bp_me_if(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p)
|
||||
|
||||
bsg_ready_and_link_sif_s cmd_link_li, cmd_link_lo;
|
||||
bsg_ready_and_link_sif_s resp_link_li, resp_link_lo;
|
||||
|
||||
bsg_ready_and_link_sif_s mem_cmd_link_li, mem_cmd_link_lo, mem_resp_link_li, mem_resp_link_lo;
|
||||
bsg_ready_and_link_sif_s cfg_cmd_link_li, cfg_cmd_link_lo, cfg_resp_link_li, cfg_resp_link_lo;
|
||||
|
||||
assign mem_cmd_link_li = cmd_link_li;
|
||||
assign cfg_cmd_link_li = '{ready_and_rev: cmd_link_li.ready_and_rev, default: '0};
|
||||
assign cmd_link_lo = '{data: cfg_cmd_link_lo.data
|
||||
,v : cfg_cmd_link_lo.v
|
||||
,ready_and_rev: mem_cmd_link_lo.ready_and_rev
|
||||
};
|
||||
|
||||
assign mem_resp_link_li = '{ready_and_rev: resp_link_li.ready_and_rev, default: '0};
|
||||
assign cfg_resp_link_li = resp_link_li;
|
||||
assign resp_link_lo = '{data: mem_resp_link_lo.data
|
||||
,v : mem_resp_link_lo.v
|
||||
,ready_and_rev: cfg_resp_link_lo.ready_and_rev
|
||||
};
|
||||
|
||||
bp_cce_mem_msg_s mem_resp_li;
|
||||
logic mem_resp_v_li, mem_resp_ready_lo;
|
||||
bp_cce_mem_msg_s mem_cmd_lo;
|
||||
logic mem_cmd_v_lo, mem_cmd_yumi_li;
|
||||
|
||||
bp_cce_mem_msg_s dram_resp_lo;
|
||||
logic dram_resp_v_lo, dram_resp_ready_li;
|
||||
bp_cce_mem_msg_s dram_cmd_li;
|
||||
logic dram_cmd_v_li, dram_cmd_yumi_lo;
|
||||
|
||||
bp_cce_mem_msg_s host_resp_lo;
|
||||
logic host_resp_v_lo, host_resp_ready_li;
|
||||
bp_cce_mem_msg_s host_cmd_li;
|
||||
logic host_cmd_v_li, host_cmd_yumi_lo;
|
||||
|
||||
bp_cce_mem_msg_s cfg_cmd_lo;
|
||||
logic cfg_cmd_v_lo, cfg_cmd_ready_li;
|
||||
bp_cce_mem_msg_s cfg_resp_li;
|
||||
logic cfg_resp_v_li, cfg_resp_ready_lo;
|
||||
|
||||
logic [mem_noc_cord_width_p-1:0] dram_cord_lo, mmio_cord_lo, host_cord_lo;
|
||||
logic [num_core_p-1:0][mem_noc_cord_width_p-1:0] tile_cord_lo;
|
||||
logic [num_mem_p-1:0][mem_noc_cord_width_p-1:0] mem_cord_lo;
|
||||
|
||||
assign mmio_cord_lo[0+:mem_noc_x_cord_width_p] = mmio_x_pos_p;
|
||||
assign mmio_cord_lo[mem_noc_x_cord_width_p+:mem_noc_y_cord_width_p] = '0;
|
||||
assign dram_cord_lo[0+:mem_noc_x_cord_width_p] = mem_noc_x_dim_p+2;
|
||||
assign dram_cord_lo[mem_noc_x_cord_width_p+:mem_noc_y_cord_width_p] = '0;
|
||||
assign host_cord_lo[0+:mem_noc_x_cord_width_p] = mem_noc_x_dim_p+2;
|
||||
assign host_cord_lo[mem_noc_x_cord_width_p+:mem_noc_y_cord_width_p] = '0;
|
||||
|
||||
for (genvar j = 0; j < mem_noc_y_dim_p; j++)
|
||||
begin : y
|
||||
for (genvar i = 0; i < mem_noc_x_dim_p; i++)
|
||||
begin : x
|
||||
localparam idx = j*mem_noc_x_dim_p + i;
|
||||
assign tile_cord_lo[idx][0+:mem_noc_x_cord_width_p] = i+1;
|
||||
assign tile_cord_lo[idx][mem_noc_x_cord_width_p+:mem_noc_y_cord_width_p] = j+1;
|
||||
end
|
||||
end
|
||||
for (genvar i = 0; i < num_mem_p; i++)
|
||||
begin : x
|
||||
assign mem_cord_lo[i][0+:mem_noc_x_cord_width_p] = i;
|
||||
assign mem_cord_lo[i][mem_noc_x_cord_width_p+:mem_noc_y_cord_width_p] = '0;
|
||||
end
|
||||
|
||||
// Chip
|
||||
bp_chip
|
||||
#(.cfg_p(cfg_p))
|
||||
chip
|
||||
(.core_clk_i(clk_i)
|
||||
,.core_reset_i(reset_i)
|
||||
|
||||
,.coh_clk_i(clk_i)
|
||||
,.coh_reset_i(reset_i)
|
||||
|
||||
,.mem_clk_i(clk_i)
|
||||
,.mem_reset_i(reset_i)
|
||||
|
||||
,.mem_cord_i(mem_cord_lo)
|
||||
,.tile_cord_i(tile_cord_lo)
|
||||
,.dram_cord_i(dram_cord_lo)
|
||||
,.mmio_cord_i(mmio_cord_lo)
|
||||
,.host_cord_i(host_cord_lo)
|
||||
|
||||
,.prev_cmd_link_i('0)
|
||||
,.prev_cmd_link_o()
|
||||
|
||||
,.prev_resp_link_i('0)
|
||||
,.prev_resp_link_o()
|
||||
|
||||
,.next_cmd_link_i(cmd_link_lo)
|
||||
,.next_cmd_link_o(cmd_link_li)
|
||||
|
||||
,.next_resp_link_i(resp_link_lo)
|
||||
,.next_resp_link_o(resp_link_li)
|
||||
);
|
||||
|
||||
bind bp_be_top
|
||||
bp_nonsynth_commit_tracer
|
||||
#(.cfg_p(cfg_p))
|
||||
commit_tracer
|
||||
(.clk_i(clk_i & (ExampleBlackParrotSystem.cmt_trace_p == 1))
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mhartid_i('0)
|
||||
|
||||
,.commit_v_i(be_calculator.instret_mem3_o)
|
||||
,.commit_pc_i(be_calculator.pc_mem3_o)
|
||||
,.commit_instr_i(be_calculator.instr_mem3_o)
|
||||
|
||||
,.rd_w_v_i(be_calculator.int_regfile.rd_w_v_i)
|
||||
,.rd_addr_i(be_calculator.int_regfile.rd_addr_i)
|
||||
,.rd_data_i(be_calculator.int_regfile.rd_data_i)
|
||||
);
|
||||
|
||||
|
||||
bind bp_be_top
|
||||
bp_be_nonsynth_tracer
|
||||
#(.cfg_p(cfg_p))
|
||||
tracer
|
||||
// Workaround for verilator binding by accident
|
||||
// TODO: Figure out why tracing is always enabled
|
||||
(.clk_i(clk_i & (ExampleBlackParrotSystem.calc_trace_p == 1))
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mhartid_i(be_calculator.proc_cfg.core_id)
|
||||
|
||||
,.issue_pkt_i(be_calculator.issue_pkt)
|
||||
,.issue_pkt_v_i(be_calculator.issue_pkt_v_i)
|
||||
|
||||
,.fe_nop_v_i(be_calculator.fe_nop_v)
|
||||
,.be_nop_v_i(be_calculator.be_nop_v)
|
||||
,.me_nop_v_i(be_calculator.me_nop_v)
|
||||
,.dispatch_pkt_i(be_calculator.dispatch_pkt)
|
||||
|
||||
,.ex1_br_tgt_i(be_calculator.calc_status.int1_br_tgt)
|
||||
,.ex1_btaken_i(be_calculator.calc_status.int1_btaken)
|
||||
,.iwb_result_i(be_calculator.comp_stage_n[3])
|
||||
,.fwb_result_i(be_calculator.comp_stage_n[4])
|
||||
|
||||
,.cmt_trace_exc_i(be_calculator.exc_stage_n[1+:5])
|
||||
|
||||
,.trap_v_i(be_mem.csr.trap_v_o)
|
||||
,.mtvec_i(be_mem.csr.mtvec_n)
|
||||
,.mtval_i(be_mem.csr.mtval_n[0+:vaddr_width_p])
|
||||
,.ret_v_i(be_mem.csr.ret_v_o)
|
||||
,.mepc_i(be_mem.csr.mepc_n[0+:vaddr_width_p])
|
||||
,.mcause_i(be_mem.csr.mcause_n)
|
||||
|
||||
,.priv_mode_i(be_mem.csr.priv_mode_n)
|
||||
,.mpp_i(be_mem.csr.mstatus_n.mpp)
|
||||
);
|
||||
|
||||
/*bind bp_be_top
|
||||
bp_be_nonsynth_perf
|
||||
#(.cfg_p(cfg_p))
|
||||
perf
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mhartid_i(be_calculator.proc_cfg.core_id)
|
||||
|
||||
,.fe_nop_i(be_calculator.exc_stage_r[2].fe_nop_v)
|
||||
,.be_nop_i(be_calculator.exc_stage_r[2].be_nop_v)
|
||||
,.me_nop_i(be_calculator.exc_stage_r[2].me_nop_v)
|
||||
,.poison_i(be_calculator.exc_stage_r[2].poison_v)
|
||||
,.roll_i(be_calculator.exc_stage_r[2].roll_v)
|
||||
,.instr_cmt_i(be_calculator.calc_status.mem3_cmt_v)
|
||||
|
||||
,.program_finish_i(testbench.program_finish)
|
||||
);
|
||||
*/
|
||||
/*if (dram_trace_p)
|
||||
bp_mem_nonsynth_tracer
|
||||
#(.cfg_p(cfg_p))
|
||||
bp_mem_tracer
|
||||
(.clk_i(clk_i & (testbench.dram_trace_p == 1))
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mem_cmd_i(dram_cmd_li)
|
||||
,.mem_cmd_v_i(dram_cmd_v_li)
|
||||
,.mem_cmd_yumi_i(dram_cmd_yumi_lo)
|
||||
|
||||
,.mem_resp_i(dram_resp_lo)
|
||||
,.mem_resp_v_i(dram_resp_v_lo)
|
||||
,.mem_resp_ready_i(dram_resp_ready_li)
|
||||
);
|
||||
|
||||
if (cce_trace_p)
|
||||
bind bp_cce_top
|
||||
bp_cce_nonsynth_tracer
|
||||
#(.cfg_p(cfg_p))
|
||||
bp_cce_tracer
|
||||
(.clk_i(clk_i & (testbench.cce_trace_p == 1))
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.cce_id_i(cce_id_i)
|
||||
|
||||
// To CCE
|
||||
,.lce_req_i(lce_req_to_cce)
|
||||
,.lce_req_v_i(lce_req_v_to_cce)
|
||||
,.lce_req_yumi_i(lce_req_yumi_from_cce)
|
||||
,.lce_resp_i(lce_resp_to_cce)
|
||||
,.lce_resp_v_i(lce_resp_v_to_cce)
|
||||
,.lce_resp_yumi_i(lce_resp_yumi_from_cce)
|
||||
|
||||
// From CCE
|
||||
,.lce_cmd_i(lce_cmd_o)
|
||||
,.lce_cmd_v_i(lce_cmd_v_o)
|
||||
,.lce_cmd_ready_i(lce_cmd_ready_i)
|
||||
|
||||
// To CCE
|
||||
,.mem_resp_i(mem_resp_to_cce)
|
||||
,.mem_resp_v_i(mem_resp_v_to_cce)
|
||||
,.mem_resp_yumi_i(mem_resp_yumi_from_cce)
|
||||
|
||||
// From CCE
|
||||
,.mem_cmd_i(mem_cmd_from_cce)
|
||||
,.mem_cmd_v_i(mem_cmd_v_from_cce)
|
||||
,.mem_cmd_ready_i(mem_cmd_ready_to_cce)
|
||||
);
|
||||
*/
|
||||
// DRAM + link
|
||||
bp_me_cce_to_wormhole_link_client
|
||||
#(.cfg_p(cfg_p))
|
||||
client_link
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mem_cmd_o(mem_cmd_lo)
|
||||
,.mem_cmd_v_o(mem_cmd_v_lo)
|
||||
,.mem_cmd_yumi_i(mem_cmd_yumi_li)
|
||||
|
||||
,.mem_resp_i(mem_resp_li)
|
||||
,.mem_resp_v_i(mem_resp_v_li)
|
||||
,.mem_resp_ready_o(mem_resp_ready_lo)
|
||||
|
||||
,.my_cord_i(dram_cord_lo)
|
||||
,.my_cid_i(mem_noc_cid_width_p'(0))
|
||||
|
||||
,.cmd_link_i(mem_cmd_link_li)
|
||||
,.cmd_link_o(mem_cmd_link_lo)
|
||||
|
||||
,.resp_link_i(mem_resp_link_li)
|
||||
,.resp_link_o(mem_resp_link_lo)
|
||||
);
|
||||
|
||||
bp2wb_convertor
|
||||
#(.cfg_p(cfg_p))
|
||||
bp2wb
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
,.mem_cmd_i(dram_cmd_li)
|
||||
,.mem_cmd_v_i(dram_cmd_v_li)
|
||||
,.mem_cmd_yumi_o(dram_cmd_yumi_lo)
|
||||
,.mem_resp_o(dram_resp_lo)
|
||||
,.mem_resp_v_o(dram_resp_v_lo)
|
||||
,.mem_resp_ready_i(dram_resp_ready_li)
|
||||
,.dat_i(wbm_dat_i)
|
||||
,.dat_o(wbm_dat_o)
|
||||
,.ack_i(wbm_ack_i)
|
||||
,.adr_o(wbm_adr_o)
|
||||
,.stb_o(wbm_stb_o)
|
||||
,.cyc_o(wbm_cyc_o)
|
||||
,.sel_o(wbm_sel_o )
|
||||
,.we_o(wbm_we_o)
|
||||
,.cti_o(wbm_cti_o)
|
||||
,.bte_o(wbm_bte_o )
|
||||
);
|
||||
|
||||
logic [num_core_p-1:0] program_finish;
|
||||
|
||||
bp_nonsynth_host
|
||||
#(.cfg_p(cfg_p))
|
||||
host_mmio
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mem_cmd_i(host_cmd_li)
|
||||
,.mem_cmd_v_i(host_cmd_v_li)
|
||||
,.mem_cmd_yumi_o(host_cmd_yumi_lo)
|
||||
|
||||
,.mem_resp_o(host_resp_lo)
|
||||
,.mem_resp_v_o(host_resp_v_lo)
|
||||
,.mem_resp_ready_i(host_resp_ready_li)
|
||||
|
||||
,.program_finish_o(program_finish)
|
||||
,.all_finished_debug_o(all_finished_debug_o)
|
||||
,.core_passed_debug(core_passed_debug)
|
||||
,.core_failed_debug(core_failed_debug)
|
||||
);
|
||||
|
||||
/*bp_nonsynth_if_verif
|
||||
#(.cfg_p(cfg_p))
|
||||
if_verif
|
||||
();
|
||||
*/
|
||||
// MMIO arbitration
|
||||
// Should this be on its own I/O router?
|
||||
logic req_outstanding_r;
|
||||
bsg_dff_reset_en
|
||||
#(.width_p(1))
|
||||
req_outstanding_reg
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
,.en_i(mem_cmd_yumi_li | mem_resp_v_li)
|
||||
|
||||
,.data_i(mem_cmd_yumi_li)
|
||||
,.data_o(req_outstanding_r)
|
||||
);
|
||||
|
||||
wire host_cmd_not_dram = mem_cmd_v_lo & (mem_cmd_lo.addr < 39'h00_4000_0000 );//dram_base_addr_gp
|
||||
|
||||
assign host_cmd_li = mem_cmd_lo;
|
||||
assign host_cmd_v_li = mem_cmd_v_lo & host_cmd_not_dram & ~req_outstanding_r;
|
||||
assign dram_cmd_li = mem_cmd_lo;
|
||||
assign dram_cmd_v_li = mem_cmd_v_lo & ~host_cmd_not_dram & ~req_outstanding_r;
|
||||
assign mem_cmd_yumi_li = host_cmd_not_dram
|
||||
? host_cmd_yumi_lo
|
||||
: dram_cmd_yumi_lo;
|
||||
|
||||
assign mem_resp_li = host_resp_v_lo ? host_resp_lo : dram_resp_lo;
|
||||
assign mem_resp_v_li = host_resp_v_lo | dram_resp_v_lo;
|
||||
assign host_resp_ready_li = mem_resp_ready_lo;
|
||||
assign dram_resp_ready_li = mem_resp_ready_lo;
|
||||
|
||||
// CFG loader + rom + link
|
||||
bp_me_cce_to_wormhole_link_master
|
||||
#(.cfg_p(cfg_p))
|
||||
master_link
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mem_cmd_i(cfg_cmd_lo)
|
||||
,.mem_cmd_v_i(cfg_cmd_ready_li & cfg_cmd_v_lo)
|
||||
,.mem_cmd_ready_o(cfg_cmd_ready_li)
|
||||
|
||||
,.mem_resp_o(cfg_resp_li)
|
||||
,.mem_resp_v_o(cfg_resp_v_li)
|
||||
,.mem_resp_yumi_i(cfg_resp_ready_lo & cfg_resp_v_li)
|
||||
|
||||
,.my_cord_i(dram_cord_lo)
|
||||
,.my_cid_i(mem_noc_cid_width_p'(0))
|
||||
,.dram_cord_i(dram_cord_lo)
|
||||
,.mmio_cord_i(mmio_cord_lo)
|
||||
,.host_cord_i(host_cord_lo)
|
||||
|
||||
,.cmd_link_i(cfg_cmd_link_li)
|
||||
,.cmd_link_o(cfg_cmd_link_lo)
|
||||
|
||||
,.resp_link_i(cfg_resp_link_li)
|
||||
,.resp_link_o(cfg_resp_link_lo)
|
||||
);
|
||||
|
||||
localparam cce_instr_ram_addr_width_lp = `BSG_SAFE_CLOG2(num_cce_instr_ram_els_p);
|
||||
bp_cce_mmio_cfg_loader
|
||||
#(.cfg_p(cfg_p)
|
||||
,.inst_width_p(`bp_cce_inst_width)
|
||||
,.inst_ram_addr_width_p(cce_instr_ram_addr_width_lp)
|
||||
,.inst_ram_els_p(num_cce_instr_ram_els_p)
|
||||
,.skip_ram_init_p(skip_init_p)
|
||||
)
|
||||
cfg_loader
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.mem_cmd_o(cfg_cmd_lo)
|
||||
,.mem_cmd_v_o(cfg_cmd_v_lo)
|
||||
,.mem_cmd_yumi_i(cfg_cmd_ready_li & cfg_cmd_v_lo)
|
||||
|
||||
,.mem_resp_i(cfg_resp_li)
|
||||
,.mem_resp_v_i(cfg_resp_v_li)
|
||||
,.mem_resp_ready_o(cfg_resp_ready_lo)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
/**
|
||||
* bp2wb_convertor.v
|
||||
* DESCRIPTION: THIS MODULE ADAPTS BP MEMORY BUS TO 64-BIT WISHBONE
|
||||
*/
|
||||
|
||||
module bp2wb_convertor
|
||||
import bp_common_pkg::*;
|
||||
import bp_common_aviary_pkg::*;
|
||||
import bp_cce_pkg::*;
|
||||
import bp_me_pkg::*;
|
||||
#(parameter bp_cfg_e cfg_p = e_bp_single_core_cfg
|
||||
`declare_bp_proc_params(cfg_p)
|
||||
`declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p)
|
||||
|
||||
// , parameter [paddr_width_p-1:0] dram_offset_p = '0
|
||||
, localparam num_block_words_lp = cce_block_width_p / 64
|
||||
, localparam num_block_bytes_lp = cce_block_width_p / 8
|
||||
, localparam num_word_bytes_lp = dword_width_p / 8
|
||||
, localparam block_offset_bits_lp = `BSG_SAFE_CLOG2(num_block_bytes_lp)
|
||||
, localparam word_offset_bits_lp = `BSG_SAFE_CLOG2(num_block_words_lp)
|
||||
, localparam byte_offset_bits_lp = `BSG_SAFE_CLOG2(num_word_bytes_lp)
|
||||
, localparam wbone_data_width = 64
|
||||
, localparam wbone_addr_ubound = paddr_width_p
|
||||
, localparam mem_granularity = 64 //TODO: adapt selection bit parametrized
|
||||
, localparam wbone_addr_lbound = 3 //`BSG_SAFE_CLOG2(wbone_data_width / mem_granularity) //dword granularity
|
||||
, localparam total_datafetch_cycle_lp = cce_block_width_p / wbone_data_width
|
||||
, localparam total_datafetch_cycle_width = `BSG_SAFE_CLOG2(total_datafetch_cycle_lp)
|
||||
, localparam cached_addr_base = 32'h4000_4000// 32'h5000_0000
|
||||
)
|
||||
(input clk_i
|
||||
,(* mark_debug = "true" *) input reset_i
|
||||
|
||||
// BP side
|
||||
,(* mark_debug = "true" *) input [cce_mem_msg_width_lp-1:0] mem_cmd_i
|
||||
,(* mark_debug = "true" *) input mem_cmd_v_i
|
||||
,(* mark_debug = "true" *) output mem_cmd_yumi_o
|
||||
|
||||
, (* mark_debug = "true" *) output [cce_mem_msg_width_lp-1:0] mem_resp_o
|
||||
, (* mark_debug = "true" *) output mem_resp_v_o
|
||||
, (* mark_debug = "true" *) input mem_resp_ready_i
|
||||
|
||||
// Wishbone side
|
||||
, (* mark_debug = "true" *) input [63:0] dat_i
|
||||
, (* mark_debug = "true" *) output logic [63:0] dat_o
|
||||
, (* mark_debug = "true" *) input ack_i
|
||||
// , input err_i
|
||||
// , input rty_i
|
||||
, (* mark_debug = "true" *) output logic [wbone_addr_ubound-wbone_addr_lbound-1:0] adr_o//TODO: Double check!!!
|
||||
, (* mark_debug = "true" *) output logic stb_o
|
||||
, output cyc_o
|
||||
, output sel_o //TODO: double check!!!
|
||||
, (* mark_debug = "true" *) output we_o
|
||||
, output [2:0] cti_o //TODO: hardwire in Litex
|
||||
, output [1:0] bte_o //TODO: hardwire in Litex
|
||||
|
||||
);
|
||||
|
||||
`declare_bp_me_if(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p);
|
||||
|
||||
//locals
|
||||
(* mark_debug = "true" *) logic [total_datafetch_cycle_width:0] ack_ctr = 0;
|
||||
(* mark_debug = "true" *) bp_cce_mem_msg_s mem_cmd_cast_i, mem_resp_cast_o, mem_cmd_r;
|
||||
(* mark_debug = "true" *) logic ready_li, v_li, stb_justgotack;
|
||||
(* mark_debug = "true" *) logic [cce_block_width_p-1:0] data_lo;
|
||||
(* mark_debug = "true" *) logic [cce_block_width_p-1:0] data_li;
|
||||
(* mark_debug = "true" *) wire [paddr_width_p-1:0] mem_cmd_addr_l;
|
||||
(* mark_debug = "true" *) logic [paddr_width_p-1:0] addr_lo;
|
||||
(* mark_debug = "true" *) logic set_stb;
|
||||
(* mark_debug = "true" *) wire [63:0] data_little_end;
|
||||
|
||||
|
||||
//reset
|
||||
//TODO: reset ack_ctr here
|
||||
//Handshaking between Wishbone and BlackParrot through convertor
|
||||
//3.1.3:At every rising edge of [CLK_I] the terminating signal(ACK) is sampled. If it
|
||||
//is asserted, then [STB_O] is negated.
|
||||
|
||||
assign ready_li = ( ack_ctr == 0 );
|
||||
assign mem_cmd_yumi_o = mem_cmd_v_i && ready_li;//!stb_o then ready to take!
|
||||
// assign v_li = (ack_ctr == total_datafetch_cycle_lp-1);
|
||||
assign mem_resp_v_o = mem_resp_ready_i & v_li;
|
||||
assign stb_o = (set_stb) && !stb_justgotack; //addresi mem_cmd_rdan aldigimiz icin 1 cycle geriden geliyo
|
||||
assign cyc_o = stb_o;
|
||||
assign sel_o = 0;
|
||||
assign cti_o = 0;
|
||||
assign bte_o = 0;
|
||||
|
||||
initial begin
|
||||
ack_ctr = 0;
|
||||
//stb_reset_lo =0;
|
||||
end
|
||||
|
||||
/* always_ff @(posedge clk_i)
|
||||
if ( mem_cmd_yumi_o )// || (ack_ctr > 0))
|
||||
begin
|
||||
data_li <= 0;
|
||||
set_stb <= 1;
|
||||
end
|
||||
*/
|
||||
|
||||
|
||||
//Flip stb after each ack--->RULE 3.20:
|
||||
|
||||
// Every time we get an ACK from WB, increment counter until the counter reaches to total_datafetch_cycle_lp
|
||||
assign data_little_end = dat_i;
|
||||
always_ff @(posedge clk_i)
|
||||
begin
|
||||
|
||||
if(reset_i)
|
||||
begin
|
||||
ack_ctr <= 0;
|
||||
set_stb <= 0;
|
||||
v_li <=0;
|
||||
end
|
||||
|
||||
else if (mem_cmd_yumi_o)
|
||||
begin
|
||||
data_li <= 0;
|
||||
set_stb <= 1;
|
||||
v_li <= 0;
|
||||
stb_justgotack <= 0;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if (ack_i)//stb should be negated after ack
|
||||
begin
|
||||
stb_justgotack <= 1;
|
||||
data_li[(ack_ctr*wbone_data_width) +: wbone_data_width] <= data_little_end;
|
||||
if ((ack_ctr == total_datafetch_cycle_lp-1) || (mem_cmd_addr_l < cached_addr_base && mem_cmd_r.msg_type == e_cce_mem_uc_wr )) //if uncached store, just one cycle is fine
|
||||
begin
|
||||
ack_ctr <= 0;
|
||||
v_li <=1;
|
||||
set_stb <= 0;
|
||||
end
|
||||
else
|
||||
ack_ctr <= ack_ctr + 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
stb_justgotack <= 0;
|
||||
v_li <=0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//Packet Pass from BP to BP2WB
|
||||
assign mem_cmd_cast_i = mem_cmd_i;
|
||||
|
||||
bsg_dff_reset_en
|
||||
#(.width_p(cce_mem_msg_width_lp))
|
||||
mshr_reg
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
,.en_i(mem_cmd_yumi_o)//when
|
||||
,.data_i(mem_cmd_i)
|
||||
,.data_o(mem_cmd_r)
|
||||
);
|
||||
|
||||
|
||||
//Addr && Data && Command Pass from BP2WB to WB
|
||||
logic [wbone_addr_lbound-1:0] throw_away;
|
||||
assign mem_cmd_addr_l = mem_cmd_r.addr;
|
||||
assign data_lo = mem_cmd_r.data;
|
||||
logic [39:0] mem_cmd_addr_l_zero64;
|
||||
logic [7:0] partial;
|
||||
always_comb begin
|
||||
if( mem_cmd_addr_l < cached_addr_base )
|
||||
begin
|
||||
adr_o = mem_cmd_addr_l[wbone_addr_ubound-1:wbone_addr_lbound];//no need to change address for uncached stores/loads
|
||||
dat_o = data_lo[(0*wbone_data_width) +: wbone_data_width];//unchached data is stored in LS 64bits
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
mem_cmd_addr_l_zero64 = mem_cmd_addr_l >> 6 << 6;
|
||||
// addr_lo =
|
||||
{adr_o,throw_away} = mem_cmd_addr_l_zero64 + (ack_ctr*8);//TODO:careful
|
||||
// adr_o = addr_lo[wbone_addr_ubound-1:wbone_addr_lbound];
|
||||
dat_o = data_lo[(ack_ctr*wbone_data_width) +: wbone_data_width];
|
||||
end
|
||||
end
|
||||
|
||||
assign we_o = (mem_cmd_r.msg_type inside {e_cce_mem_uc_wr, e_cce_mem_wb});
|
||||
|
||||
//DEBUG
|
||||
|
||||
wire [3:0] typean;
|
||||
assign typean = mem_cmd_r.msg_type;
|
||||
wire [2:0] debug1;
|
||||
assign debug1 = (mem_cmd_r.addr[5:0]>>3);
|
||||
|
||||
//Data Pass from BP2WB to BP
|
||||
|
||||
wire [cce_block_width_p-1:0] rd_word_offset = mem_cmd_r.addr[3+:3];
|
||||
//wire [cce_block_width_p-1:0] rd_byte_offset = mem_cmd_r.addr[0+:3];
|
||||
wire [cce_block_width_p-1:0] rd_bit_shift = rd_word_offset*64; // We rely on receiver to adjust bits
|
||||
|
||||
wire [cce_block_width_p-1:0] data_li_resp = (mem_cmd_r.msg_type == e_cce_mem_uc_rd)
|
||||
? data_li >> rd_bit_shift
|
||||
: data_li;
|
||||
|
||||
assign mem_resp_cast_o = '{data : data_li_resp
|
||||
,payload : mem_cmd_r.payload
|
||||
,size : mem_cmd_r.size
|
||||
,addr : mem_cmd_r.addr
|
||||
,msg_type: mem_cmd_r.msg_type
|
||||
};
|
||||
|
||||
assign mem_resp_o = mem_resp_cast_o;
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* bsg_mem_1rw_sync_mask_write_bit.v
|
||||
*
|
||||
* distributed synchronous 1-port ram for xilinx ultrascale or ultrascale plus FPGA
|
||||
* Write mode: No-change | Read mode: No-change
|
||||
* Note:
|
||||
* There are 2 basic BRAM library primitives, RAMB18E2 and RAMB36E2 in Vivado.
|
||||
* But none of them support bit-wise mask. They have Byte-wide write enable ports though.
|
||||
* So we use the RAM_STYLE attribute to instruct the tool to infer distributed LUT RAM instead.
|
||||
*
|
||||
* To save resources, the code is written to be inferred as Signle-port distributed ram RAM64X1S.
|
||||
* https://www.xilinx.com/support/documentation/user_guides/ug574-ultrascale-clb.pdf
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
module bsg_mem_1rw_sync_mask_write_bit #(
|
||||
parameter width_p = "inv"
|
||||
, parameter els_p = "inv"
|
||||
, parameter latch_last_read_p=0
|
||||
, parameter enable_clock_gating_p=0
|
||||
, localparam addr_width_lp = `BSG_SAFE_CLOG2(els_p)
|
||||
) (
|
||||
input clk_i
|
||||
, input reset_i
|
||||
, input [ width_p-1:0] data_i
|
||||
, input [addr_width_lp-1:0] addr_i
|
||||
, input v_i
|
||||
, input [ width_p-1:0] w_mask_i
|
||||
, input w_i
|
||||
, output [ width_p-1:0] data_o
|
||||
);
|
||||
|
||||
wire unused = reset_i;
|
||||
|
||||
(* ram_style = "distributed" *) logic [width_p-1:0] mem [els_p-1:0];
|
||||
|
||||
logic [width_p-1:0] data_r;
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (v_i & ~w_i)
|
||||
data_r <= mem[addr_i];
|
||||
end
|
||||
|
||||
assign data_o = data_r;
|
||||
|
||||
for (genvar i=0; i<width_p; i=i+1) begin
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (v_i)
|
||||
if (w_i & w_mask_i[i])
|
||||
mem[addr_i][i] <= data_i[i];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Name:
|
||||
* bp_cce_mmio_cfg_loader.v
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
*/
|
||||
|
||||
module bp_cce_mmio_cfg_loader
|
||||
import bp_common_pkg::*;
|
||||
import bp_common_aviary_pkg::*;
|
||||
import bp_cce_pkg::*;
|
||||
import bp_cfg_link_pkg::*;
|
||||
import bp_be_pkg::*;
|
||||
import bp_be_dcache_pkg::*;
|
||||
import bp_me_pkg::*;
|
||||
#(parameter bp_cfg_e cfg_p = e_bp_inv_cfg
|
||||
`declare_bp_proc_params(cfg_p)
|
||||
`declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p)
|
||||
|
||||
, parameter inst_width_p = "inv"
|
||||
, parameter inst_ram_addr_width_p = "inv"
|
||||
, parameter inst_ram_els_p = "inv"
|
||||
, parameter cce_ucode_filename_p = "/tmp/cce_ucode.mem"
|
||||
, parameter skip_ram_init_p = 0
|
||||
|
||||
, localparam bp_pc_entry_point_gp=39'h00_5000_0000 //SC_add
|
||||
)
|
||||
(input clk_i
|
||||
, input reset_i
|
||||
|
||||
// Config channel
|
||||
, output logic [cce_mem_msg_width_lp-1:0] mem_cmd_o
|
||||
, output logic mem_cmd_v_o
|
||||
, input mem_cmd_yumi_i
|
||||
|
||||
// We don't need a response from the cfg network
|
||||
, input [cce_mem_msg_width_lp-1:0] mem_resp_i
|
||||
, input mem_resp_v_i
|
||||
, output mem_resp_ready_o
|
||||
);
|
||||
|
||||
wire unused0 = &{mem_resp_i, mem_resp_v_i};
|
||||
assign mem_resp_ready_o = 1'b1;
|
||||
|
||||
`declare_bp_me_if(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p);
|
||||
|
||||
bp_cce_mem_msg_s mem_cmd_cast_o;
|
||||
|
||||
assign mem_cmd_o = mem_cmd_cast_o;
|
||||
|
||||
logic [`bp_cce_inst_width-1:0] cce_inst_boot_rom [0:inst_ram_els_p-1];
|
||||
logic [inst_ram_addr_width_p-1:0] cce_inst_boot_rom_addr;
|
||||
logic [`bp_cce_inst_width-1:0] cce_inst_boot_rom_data;
|
||||
|
||||
initial $readmemb(cce_ucode_filename_p, cce_inst_boot_rom);
|
||||
|
||||
assign cce_inst_boot_rom_data = cce_inst_boot_rom[cce_inst_boot_rom_addr];
|
||||
|
||||
logic cfg_v_lo;
|
||||
logic [cfg_core_width_p-1:0] cfg_core_lo;
|
||||
logic [cfg_addr_width_p-1:0] cfg_addr_lo;
|
||||
logic [cfg_data_width_p-1:0] cfg_data_lo;
|
||||
|
||||
(* mark_debug = "true" *) enum logic [3:0] {
|
||||
RESET
|
||||
,BP_RESET_SET
|
||||
,BP_FREEZE_SET
|
||||
,BP_RESET_CLR
|
||||
,SEND_RAM_LO
|
||||
,SEND_RAM_HI
|
||||
,SEND_CCE_NORMAL
|
||||
,SEND_ICACHE_NORMAL
|
||||
,SEND_DCACHE_NORMAL
|
||||
,SEND_PC_LO
|
||||
,SEND_PC_HI
|
||||
,BP_FREEZE_CLR
|
||||
,DONE
|
||||
} state_n, state_r;
|
||||
|
||||
logic [cfg_addr_width_p-1:0] ucode_cnt_r;
|
||||
logic ucode_cnt_clr, ucode_cnt_inc;
|
||||
bsg_counter_clear_up
|
||||
#(.max_val_p(2**cfg_addr_width_p-1)
|
||||
,.init_val_p(0)
|
||||
)
|
||||
ucode_counter
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.clear_i(ucode_cnt_clr)
|
||||
,.up_i(ucode_cnt_inc & mem_cmd_yumi_i)
|
||||
|
||||
,.count_o(ucode_cnt_r)
|
||||
);
|
||||
|
||||
wire ucode_prog_done = (ucode_cnt_r == cfg_addr_width_p'(inst_ram_els_p-1));
|
||||
|
||||
always_ff @(posedge clk_i)
|
||||
begin
|
||||
if (reset_i)
|
||||
state_r <= RESET;
|
||||
else if (mem_cmd_yumi_i || (state_r == RESET))
|
||||
state_r <= state_n;
|
||||
end
|
||||
|
||||
wire [7:0] unused;
|
||||
assign {unused, cce_inst_boot_rom_addr} = cfg_addr_lo >> 1'b1;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
mem_cmd_v_o = cfg_v_lo;
|
||||
|
||||
// uncached store
|
||||
mem_cmd_cast_o.msg_type = e_cce_mem_uc_wr;
|
||||
mem_cmd_cast_o.addr = bp_cfg_base_addr_gp;
|
||||
mem_cmd_cast_o.payload = '0;
|
||||
mem_cmd_cast_o.size = e_mem_size_8;
|
||||
mem_cmd_cast_o.data = cce_block_width_p'({cfg_core_lo, cfg_addr_lo, cfg_data_lo});
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
ucode_cnt_clr = 1'b0;
|
||||
ucode_cnt_inc = 1'b0;
|
||||
|
||||
cfg_v_lo = '0;
|
||||
cfg_core_lo = 8'hff;
|
||||
cfg_addr_lo = '0;
|
||||
cfg_data_lo = '0;
|
||||
|
||||
case (state_r)
|
||||
RESET: begin
|
||||
state_n = skip_ram_init_p ? BP_FREEZE_CLR : BP_RESET_SET;
|
||||
|
||||
ucode_cnt_clr = 1'b1;
|
||||
end
|
||||
BP_RESET_SET: begin
|
||||
state_n = BP_FREEZE_SET;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = bp_cfg_reg_reset_gp;
|
||||
cfg_data_lo = cfg_data_width_p'(1);
|
||||
end
|
||||
BP_FREEZE_SET: begin
|
||||
state_n = BP_RESET_CLR;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = bp_cfg_reg_freeze_gp;
|
||||
cfg_data_lo = cfg_data_width_p'(1);
|
||||
end
|
||||
BP_RESET_CLR: begin
|
||||
state_n = SEND_RAM_LO;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = bp_cfg_reg_reset_gp;
|
||||
cfg_data_lo = cfg_data_width_p'(0);
|
||||
end
|
||||
SEND_RAM_LO: begin
|
||||
state_n = SEND_RAM_HI;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_mem_base_cce_ucode_gp) + (ucode_cnt_r << 1);
|
||||
cfg_data_lo = cce_inst_boot_rom_data[0+:cfg_data_width_p];
|
||||
// TODO: This is nonsynth, won't work on FPGA
|
||||
cfg_data_lo = (|cfg_data_lo === 'X) ? '0 : cfg_data_lo;
|
||||
end
|
||||
SEND_RAM_HI: begin
|
||||
state_n = ucode_prog_done ? SEND_CCE_NORMAL : SEND_RAM_LO;
|
||||
|
||||
ucode_cnt_inc = 1'b1;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_mem_base_cce_ucode_gp) + (ucode_cnt_r << 1) + 1'b1;
|
||||
cfg_data_lo = cfg_data_width_p'(cce_inst_boot_rom_data[inst_width_p-1:cfg_data_width_p]);
|
||||
// TODO: This is nonsynth, won't work on FPGA
|
||||
cfg_data_lo = (|cfg_data_lo === 'X) ? '0 : cfg_data_lo;
|
||||
end
|
||||
SEND_CCE_NORMAL: begin
|
||||
state_n = SEND_ICACHE_NORMAL;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = bp_cfg_reg_cce_mode_gp;
|
||||
cfg_data_lo = cfg_data_width_p'(e_cce_mode_normal);
|
||||
end
|
||||
SEND_ICACHE_NORMAL: begin
|
||||
state_n = SEND_DCACHE_NORMAL;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_reg_icache_mode_gp);
|
||||
cfg_data_lo = cfg_data_width_p'(e_dcache_lce_mode_normal); // TODO: tapeout hack, change to icache
|
||||
end
|
||||
SEND_DCACHE_NORMAL: begin
|
||||
state_n = SEND_PC_LO;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_reg_dcache_mode_gp);
|
||||
cfg_data_lo = cfg_data_width_p'(e_dcache_lce_mode_normal);
|
||||
end
|
||||
SEND_PC_LO: begin
|
||||
state_n = SEND_PC_HI;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_reg_start_pc_lo_gp);
|
||||
cfg_data_lo = bp_pc_entry_point_gp[0+:cfg_data_width_p];
|
||||
end
|
||||
SEND_PC_HI: begin
|
||||
state_n = BP_FREEZE_CLR;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_reg_start_pc_hi_gp);
|
||||
cfg_data_lo = cfg_data_width_p'(bp_pc_entry_point_gp[vaddr_width_p-1:cfg_data_width_p]);
|
||||
end
|
||||
BP_FREEZE_CLR: begin
|
||||
state_n = DONE;
|
||||
|
||||
cfg_v_lo = 1'b1;
|
||||
cfg_addr_lo = cfg_addr_width_p'(bp_cfg_reg_freeze_gp);
|
||||
cfg_data_lo = cfg_data_width_p'(0);;
|
||||
end
|
||||
DONE: begin
|
||||
state_n = DONE;
|
||||
end
|
||||
default: begin
|
||||
state_n = RESET;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* bp_common_pkg.vh
|
||||
*
|
||||
* Contains the interface structures used for communicating between FE, BE, ME in BlackParrot.
|
||||
* Additionally contains global parameters used to configure the system. In the future, when
|
||||
* multiple configurations are supported, these global parameters will belong to groups
|
||||
* e.g. SV39, VM-disabled, ...
|
||||
*
|
||||
*/
|
||||
|
||||
package bp_common_pkg;
|
||||
|
||||
`include "bsg_defines.v"
|
||||
`include "bp_common_defines.vh"
|
||||
`include "bp_common_fe_be_if.vh"
|
||||
`include "bp_common_me_if.vh"
|
||||
|
||||
/*
|
||||
* RV64 specifies a 64b effective address and 32b instruction.
|
||||
* BlackParrot supports SV39 virtual memory, which specifies 39b virtual / 56b physical address.
|
||||
* Effective addresses must have bits 39-63 match bit 38
|
||||
* or a page fault exception will occur during translation.
|
||||
* Currently, we only support a very limited number of parameter configurations.
|
||||
* Thought: We could have a `define surrounding core instantiations of each parameter and then
|
||||
* when they import this package, `declare the if structs. No more casting!
|
||||
*/
|
||||
|
||||
localparam bp_eaddr_width_gp = 64;
|
||||
localparam bp_instr_width_gp = 32;
|
||||
|
||||
parameter bp_sv39_page_table_depth_gp = 3;
|
||||
parameter bp_sv39_pte_width_gp = 64;
|
||||
parameter bp_sv39_vaddr_width_gp = 39;
|
||||
parameter bp_sv39_paddr_width_gp = 56;
|
||||
parameter bp_sv39_ppn_width_gp = 44;
|
||||
parameter bp_page_size_in_bytes_gp = 4096;
|
||||
parameter bp_page_offset_width_gp = `BSG_SAFE_CLOG2(bp_page_size_in_bytes_gp);
|
||||
|
||||
parameter bp_data_resp_num_flit_gp = 4;
|
||||
parameter bp_data_cmd_num_flit_gp = 4;
|
||||
|
||||
localparam dram_base_addr_gp = 32'h5000_0000;
|
||||
|
||||
localparam cfg_link_dev_base_addr_gp = 32'h01??_????;
|
||||
localparam clint_dev_base_addr_gp = 32'h02??_????;
|
||||
localparam host_dev_base_addr_gp = 32'h03??_????;
|
||||
localparam plic_dev_base_addr_gp = 32'h0c??_????;
|
||||
|
||||
localparam mipi_reg_base_addr_gp = 32'h0200_0???;
|
||||
localparam mtimecmp_reg_base_addr_gp = 32'h0200_4???;
|
||||
localparam mtime_reg_addr_gp = 32'h0200_bff8;
|
||||
localparam plic_reg_base_addr_gp = 32'h0c00_0???;
|
||||
|
||||
endpackage : bp_common_pkg
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
|
||||
module bp_nonsynth_host
|
||||
import bp_common_pkg::*;
|
||||
import bp_common_aviary_pkg::*;
|
||||
import bp_be_pkg::*;
|
||||
import bp_common_rv64_pkg::*;
|
||||
import bp_cce_pkg::*;
|
||||
import bsg_noc_pkg::*;
|
||||
import bp_cfg_link_pkg::*;
|
||||
#(parameter bp_cfg_e cfg_p = e_bp_inv_cfg
|
||||
`declare_bp_proc_params(cfg_p)
|
||||
`declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p)
|
||||
)
|
||||
(input clk_i
|
||||
, input reset_i
|
||||
|
||||
, input [cce_mem_msg_width_lp-1:0] mem_cmd_i
|
||||
, input mem_cmd_v_i
|
||||
, output logic mem_cmd_yumi_o
|
||||
|
||||
, output logic [cce_mem_msg_width_lp-1:0] mem_resp_o
|
||||
, output logic mem_resp_v_o
|
||||
, input mem_resp_ready_i
|
||||
|
||||
, output [num_core_p-1:0] program_finish_o
|
||||
,(* mark_debug = "true" *) output logic all_finished_debug_o //SC_add
|
||||
, (* mark_debug = "true" *) output logic core_passed_debug
|
||||
, (* mark_debug = "true" *) output logic core_failed_debug
|
||||
);
|
||||
|
||||
`declare_bp_me_if(paddr_width_p, cce_block_width_p, num_lce_p, lce_assoc_p);
|
||||
|
||||
// HOST I/O mappings
|
||||
//localparam host_dev_base_addr_gp = 32'h03??_????;
|
||||
|
||||
// Host I/O mappings (arbitrarily decided for now)
|
||||
// Overall host controls 32'h0300_0000-32'h03FF_FFFF
|
||||
|
||||
localparam hprint_base_addr_gp = paddr_width_p'(32'h0300_0???);
|
||||
localparam cprint_base_addr_gp = paddr_width_p'(64'h0300_1???);
|
||||
localparam finish_base_addr_gp = paddr_width_p'(64'h0300_2???);
|
||||
|
||||
bp_cce_mem_msg_s mem_cmd_cast_i;
|
||||
|
||||
assign mem_cmd_cast_i = mem_cmd_i;
|
||||
|
||||
localparam lg_num_core_lp = `BSG_SAFE_CLOG2(num_core_p);
|
||||
|
||||
logic hprint_data_cmd_v;
|
||||
logic cprint_data_cmd_v;
|
||||
logic finish_data_cmd_v;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
hprint_data_cmd_v = 1'b0;
|
||||
cprint_data_cmd_v = 1'b0;
|
||||
finish_data_cmd_v = 1'b0;
|
||||
|
||||
unique
|
||||
casez (mem_cmd_cast_i.addr)
|
||||
hprint_base_addr_gp: hprint_data_cmd_v = mem_cmd_v_i;
|
||||
cprint_base_addr_gp: cprint_data_cmd_v = mem_cmd_v_i;
|
||||
finish_base_addr_gp: finish_data_cmd_v = mem_cmd_v_i;
|
||||
default: begin end
|
||||
endcase
|
||||
end
|
||||
|
||||
logic [num_core_p-1:0] hprint_w_v_li;
|
||||
logic [num_core_p-1:0] cprint_w_v_li;
|
||||
logic [num_core_p-1:0] finish_w_v_li;
|
||||
|
||||
// Memory-mapped I/O is 64 bit aligned
|
||||
localparam byte_offset_width_lp = 3;
|
||||
wire [lg_num_core_lp-1:0] mem_cmd_core_enc =
|
||||
mem_cmd_cast_i.addr[byte_offset_width_lp+:lg_num_core_lp];
|
||||
|
||||
bsg_decode_with_v
|
||||
#(.num_out_p(num_core_p))
|
||||
hprint_data_cmd_decoder
|
||||
(.v_i(hprint_data_cmd_v)
|
||||
,.i(mem_cmd_core_enc)
|
||||
|
||||
,.o(hprint_w_v_li)
|
||||
);
|
||||
|
||||
bsg_decode_with_v
|
||||
#(.num_out_p(num_core_p))
|
||||
cprint_data_cmd_decoder
|
||||
(.v_i(cprint_data_cmd_v)
|
||||
,.i(mem_cmd_core_enc)
|
||||
|
||||
,.o(cprint_w_v_li)
|
||||
);
|
||||
|
||||
bsg_decode_with_v
|
||||
#(.num_out_p(num_core_p))
|
||||
finish_data_cmd_decoder
|
||||
(.v_i(finish_data_cmd_v)
|
||||
,.i(mem_cmd_core_enc)
|
||||
|
||||
,.o(finish_w_v_li)
|
||||
);
|
||||
|
||||
logic [num_core_p-1:0] finish_r;
|
||||
bsg_dff_reset
|
||||
#(.width_p(num_core_p))
|
||||
finish_accumulator
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.data_i(finish_r | finish_w_v_li)
|
||||
,.data_o(finish_r)
|
||||
);
|
||||
|
||||
logic all_finished_r;
|
||||
bsg_dff_reset
|
||||
#(.width_p(1))
|
||||
all_finished_reg
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.data_i(&finish_r)
|
||||
,.data_o(all_finished_r)
|
||||
);
|
||||
|
||||
assign program_finish_o = finish_r;
|
||||
|
||||
always_ff @(negedge clk_i)
|
||||
begin
|
||||
for (integer i = 0; i < num_core_p; i++)
|
||||
begin
|
||||
if (hprint_w_v_li[i] & mem_cmd_yumi_o)
|
||||
$display("[CORE%0x PRT] %x", i, mem_cmd_cast_i.data[0+:8]);
|
||||
if (cprint_w_v_li[i] & mem_cmd_yumi_o)
|
||||
$display("[CORE%0x PRT] %c", i, mem_cmd_cast_i.data[0+:8]);
|
||||
if (finish_w_v_li[i] & mem_cmd_yumi_o & ~mem_cmd_cast_i.data[0])
|
||||
begin
|
||||
$display("[CORE%0x FSH] PASS", i);
|
||||
core_passed_debug <= 1;
|
||||
end
|
||||
if (finish_w_v_li[i] & mem_cmd_yumi_o & mem_cmd_cast_i.data[0])
|
||||
begin
|
||||
$display("[CORE%0x FSH] FAIL", i);
|
||||
core_failed_debug <=1;
|
||||
end
|
||||
end
|
||||
|
||||
if (all_finished_r)
|
||||
begin
|
||||
$display("All cores finished! Terminating...");
|
||||
$finish();
|
||||
all_finished_debug_o <= 1;
|
||||
end
|
||||
if (reset_i)
|
||||
begin
|
||||
all_finished_debug_o <= 0;
|
||||
core_passed_debug <= 0;
|
||||
core_failed_debug <= 0;
|
||||
end
|
||||
end
|
||||
bp_cce_mem_msg_s mem_resp_lo;
|
||||
logic mem_resp_v_lo, mem_resp_ready_lo;
|
||||
assign mem_cmd_yumi_o = mem_cmd_v_i & mem_resp_ready_lo;
|
||||
bsg_one_fifo
|
||||
#(.width_p(cce_mem_msg_width_lp))
|
||||
mem_resp_buffer
|
||||
(.clk_i(clk_i)
|
||||
,.reset_i(reset_i)
|
||||
|
||||
,.data_i(mem_resp_lo)
|
||||
,.v_i(mem_cmd_yumi_o)
|
||||
,.ready_o(mem_resp_ready_lo)
|
||||
|
||||
,.data_o(mem_resp_o)
|
||||
,.v_o(mem_resp_v_lo)
|
||||
,.yumi_i(mem_resp_ready_i & mem_resp_v_lo)
|
||||
);
|
||||
assign mem_resp_v_o = mem_resp_v_lo & mem_resp_ready_i;
|
||||
|
||||
assign mem_resp_lo =
|
||||
'{msg_type : mem_cmd_cast_i.msg_type
|
||||
,addr : mem_cmd_cast_i.addr
|
||||
,payload : mem_cmd_cast_i.payload
|
||||
,size : mem_cmd_cast_i.size
|
||||
,data : '0
|
||||
};
|
||||
|
||||
|
||||
endmodule : bp_nonsynth_host
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
010001000001111100000000000000000000000001000000
|
||||
001000000001111100000000000010110000000000000000
|
||||
000001000000000011111000000000000000100000000000
|
||||
010001000011111100000000000000000000000000000010
|
||||
001000000011111100000000000000010000000000000000
|
||||
000001000010000111111000000000000000100000000000
|
||||
010001000101111100000000000000000000000000001000
|
||||
001000000101111100000000000001000000000000000000
|
||||
000001000100001011111000000000000000100000000000
|
||||
101001000000010010100110100000000000000000000000
|
||||
001111000000000000000000000001110000000000000000
|
||||
010001000001111100000000000000000000000000000000
|
||||
010001000011111100000000000000000000000000000010
|
||||
001101000010000000000000000110000000000000000000
|
||||
010001000101111100000000000000000000000000000000
|
||||
010001000111111100000000000000000000000001000000
|
||||
010001001001111100000000000000000000000000000000
|
||||
001101000110001000000000000101100000000000000000
|
||||
111001000001000001001100100100000000000000000000
|
||||
000000000100001011111000000000000000100000000000
|
||||
000000001000010011111000000000100000000000000000
|
||||
001111000000000000000000000100010000000000000000
|
||||
000000000000000011111000000000000000100000000000
|
||||
001111000000000000000000000011010000000000000000
|
||||
010001000001111100000000000000000000000000000000
|
||||
010001000011111100000000000000000000000000000010
|
||||
010001000111111100000000000000000000000000000000
|
||||
001101000010000000000000001000010000000000000000
|
||||
111001000000000010101100100100000000000000000000
|
||||
111010011001000000000000000000000000000000000000
|
||||
001001000110010000000000010111110000000000000000
|
||||
000000000000000011111000000000000000100000000000
|
||||
001111000000000000000000000110110000000000000000
|
||||
111000010000000000000000000000000000000000000000
|
||||
110001000000000000000000000000000000000000000000
|
||||
111011000000000000000000000000000000000000000000
|
||||
001010000011111100000000010110010000000000000001
|
||||
100000100000000000000000000000000000000000000000
|
||||
001010001001111100000000001000010000000000000001
|
||||
111010000000000000000000000000000000000000000000
|
||||
100001100010000000100000000000000000000000000000
|
||||
110000000000000000000000000000000000000000000000
|
||||
001010000001111100000000001100010000000000000001
|
||||
001010000101111100000000001011110000000000000001
|
||||
001010001101111100000000001011110000000000000001
|
||||
010100000001111100000000000000000000000000000010
|
||||
001111000000000000000000001100100000000000000000
|
||||
010100000001111100000000000000000000000000000001
|
||||
001111000000000000000000001100100000000000000000
|
||||
010100000001111100000000000000000000000000000110
|
||||
001010011011111100000000010000110000000000000000
|
||||
010001000001111100000000000000000000000000000000
|
||||
010001000011111100000000000000000000000000000010
|
||||
010001000101111100000000000000000000000000000000
|
||||
010001000111111100000000000000000000000000000001
|
||||
001101000010000000000000001111110000000000000000
|
||||
001011000001111100000000001111010000000000000000
|
||||
001011010000000000000000001111010000000000000000
|
||||
000000000100001011111000000000000000100000000000
|
||||
111001000110000010001010100100000000000000000000
|
||||
101010100000001010100100000000000000000000000000
|
||||
000000000000000011111000000000000000100000000000
|
||||
001111000000000000000000001101110000000000000000
|
||||
001000000101111100000000010000110000000000000000
|
||||
111010011001000000000000000000000000000000000000
|
||||
000001000100001011111000000000000000100000000000
|
||||
001111000000000000000000001111110000000000000000
|
||||
001010011001111100000000010001110000000000000000
|
||||
101010100010001000100000000000000000000000000000
|
||||
111001000101100010001000100100000000000000000000
|
||||
001111000000000000000000001000010000000000000000
|
||||
101001100010001001100010000000000000000000000000
|
||||
001010010111111100000000010011110000000000000000
|
||||
111001000011100010011011100100000000000000000000
|
||||
111011011000000000000000000000000000000000000000
|
||||
001010011101111100000000010011010000000000000001
|
||||
111001010100101010101100100000000000000000000000
|
||||
111010011000000000000000000000000000000000000000
|
||||
011000010110000000000000000000000000000000000000
|
||||
001010010101111100000000010101110000000000000000
|
||||
111001000010100110001001100100000000000000000000
|
||||
111001000011100110001001100100000000000000000000
|
||||
111011011000000000000000000000000000000000000000
|
||||
001010011101111100000000010101010000000000000001
|
||||
111001010100101010101100100100000000000000000000
|
||||
111010011000000000000000000000000000000000000000
|
||||
001111000000000000000000001000010000000000000000
|
||||
111001010000101010101100100100000000000000000000
|
||||
001111000000000000000000001000010000000000000000
|
||||
111010000000000000000000000000000000000000000000
|
||||
001010000001111100000000010111010000000000000001
|
||||
111001010000101010101100100100000000000000000000
|
||||
001111000000000000000000001000010000000000000000
|
||||
111001010000101010101100100100000000000000000000
|
||||
001111000000000000000000001000010000000000000000
|
||||
110111000000000000000000000000000000000000000000
|
|
@ -1,358 +0,0 @@
|
|||
/* ===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is dual licensed under the MIT and the University of Illinois Open
|
||||
* Source Licenses. See LICENSE.TXT for details.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*
|
||||
* This file implements __udivmoddi4 for the compiler_rt library.
|
||||
*
|
||||
* ===----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef __blackparrot__
|
||||
#include "int_lib.h"
|
||||
|
||||
/* Effects: if rem != 0, *rem = a % b
|
||||
* Returns: a / b
|
||||
*/
|
||||
|
||||
/* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */
|
||||
|
||||
COMPILER_RT_ABI du_int
|
||||
__udivmoddi4(du_int a, du_int b, du_int* rem)
|
||||
{
|
||||
const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
|
||||
const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
|
||||
udwords n;
|
||||
n.all = a;
|
||||
udwords d;
|
||||
d.all = b;
|
||||
udwords q;
|
||||
udwords r;
|
||||
unsigned sr;
|
||||
/* special cases, X is unknown, K != 0 */
|
||||
if (n.s.high == 0)
|
||||
{
|
||||
if (d.s.high == 0)
|
||||
{
|
||||
/* 0 X
|
||||
* ---
|
||||
* 0 X
|
||||
*/
|
||||
if (rem)
|
||||
*rem = n.s.low % d.s.low;
|
||||
return n.s.low / d.s.low;
|
||||
}
|
||||
/* 0 X
|
||||
* ---
|
||||
* K X
|
||||
*/
|
||||
if (rem)
|
||||
*rem = n.s.low;
|
||||
return 0;
|
||||
}
|
||||
/* n.s.high != 0 */
|
||||
if (d.s.low == 0)
|
||||
{
|
||||
if (d.s.high == 0)
|
||||
{
|
||||
/* K X
|
||||
* ---
|
||||
* 0 0
|
||||
*/
|
||||
if (rem)
|
||||
*rem = n.s.high % d.s.low;
|
||||
return n.s.high / d.s.low;
|
||||
}
|
||||
/* d.s.high != 0 */
|
||||
if (n.s.low == 0)
|
||||
{
|
||||
/* K 0
|
||||
* ---
|
||||
* K 0
|
||||
*/
|
||||
if (rem)
|
||||
{
|
||||
r.s.high = n.s.high % d.s.high;
|
||||
r.s.low = 0;
|
||||
*rem = r.all;
|
||||
}
|
||||
return n.s.high / d.s.high;
|
||||
}
|
||||
/* K K
|
||||
* ---
|
||||
* K 0
|
||||
*/
|
||||
if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */
|
||||
{
|
||||
if (rem)
|
||||
{
|
||||
r.s.low = n.s.low;
|
||||
r.s.high = n.s.high & (d.s.high - 1);
|
||||
*rem = r.all;
|
||||
}
|
||||
return n.s.high >> __builtin_ctz(d.s.high);
|
||||
}
|
||||
/* K K
|
||||
* ---
|
||||
* K 0
|
||||
*/
|
||||
sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);
|
||||
/* 0 <= sr <= n_uword_bits - 2 or sr large */
|
||||
if (sr > n_uword_bits - 2)
|
||||
{
|
||||
if (rem)
|
||||
*rem = n.all;
|
||||
return 0;
|
||||
}
|
||||
++sr;
|
||||
/* 1 <= sr <= n_uword_bits - 1 */
|
||||
/* q.all = n.all << (n_udword_bits - sr); */
|
||||
q.s.low = 0;
|
||||
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||
/* r.all = n.all >> sr; */
|
||||
r.s.high = n.s.high >> sr;
|
||||
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
}
|
||||
else /* d.s.low != 0 */
|
||||
{
|
||||
if (d.s.high == 0)
|
||||
{
|
||||
/* K X
|
||||
* ---
|
||||
* 0 K
|
||||
*/
|
||||
if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */
|
||||
{
|
||||
if (rem)
|
||||
*rem = n.s.low & (d.s.low - 1);
|
||||
if (d.s.low == 1)
|
||||
return n.all;
|
||||
sr = __builtin_ctz(d.s.low);
|
||||
q.s.high = n.s.high >> sr;
|
||||
q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
return q.all;
|
||||
}
|
||||
/* K X
|
||||
* ---
|
||||
* 0 K
|
||||
*/
|
||||
sr = 1 + n_uword_bits + __builtin_clz(d.s.low) - __builtin_clz(n.s.high);
|
||||
/* 2 <= sr <= n_udword_bits - 1
|
||||
* q.all = n.all << (n_udword_bits - sr);
|
||||
* r.all = n.all >> sr;
|
||||
*/
|
||||
if (sr == n_uword_bits)
|
||||
{
|
||||
q.s.low = 0;
|
||||
q.s.high = n.s.low;
|
||||
r.s.high = 0;
|
||||
r.s.low = n.s.high;
|
||||
}
|
||||
else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
|
||||
{
|
||||
q.s.low = 0;
|
||||
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||
r.s.high = n.s.high >> sr;
|
||||
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
}
|
||||
else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
|
||||
{
|
||||
q.s.low = n.s.low << (n_udword_bits - sr);
|
||||
q.s.high = (n.s.high << (n_udword_bits - sr)) |
|
||||
(n.s.low >> (sr - n_uword_bits));
|
||||
r.s.high = 0;
|
||||
r.s.low = n.s.high >> (sr - n_uword_bits);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* K X
|
||||
* ---
|
||||
* K K
|
||||
*/
|
||||
sr = __builtin_clz(d.s.high) - __builtin_clz(n.s.high);
|
||||
/* 0 <= sr <= n_uword_bits - 1 or sr large */
|
||||
if (sr > n_uword_bits - 1)
|
||||
{
|
||||
if (rem)
|
||||
*rem = n.all;
|
||||
return 0;
|
||||
}
|
||||
++sr;
|
||||
/* 1 <= sr <= n_uword_bits */
|
||||
/* q.all = n.all << (n_udword_bits - sr); */
|
||||
q.s.low = 0;
|
||||
if (sr == n_uword_bits)
|
||||
{
|
||||
q.s.high = n.s.low;
|
||||
r.s.high = 0;
|
||||
r.s.low = n.s.high;
|
||||
}
|
||||
else
|
||||
{
|
||||
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||
r.s.high = n.s.high >> sr;
|
||||
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Not a special case
|
||||
* q and r are initialized with:
|
||||
* q.all = n.all << (n_udword_bits - sr);
|
||||
* r.all = n.all >> sr;
|
||||
* 1 <= sr <= n_udword_bits - 1
|
||||
*/
|
||||
su_int carry = 0;
|
||||
for (; sr > 0; --sr)
|
||||
{
|
||||
/* r:q = ((r:q) << 1) | carry */
|
||||
r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1));
|
||||
r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1));
|
||||
q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1));
|
||||
q.s.low = (q.s.low << 1) | carry;
|
||||
/* carry = 0;
|
||||
* if (r.all >= d.all)
|
||||
* {
|
||||
* r.all -= d.all;
|
||||
* carry = 1;
|
||||
* }
|
||||
*/
|
||||
const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1);
|
||||
carry = s & 1;
|
||||
r.all -= d.all & s;
|
||||
}
|
||||
q.all = (q.all << 1) | carry;
|
||||
if (rem)
|
||||
*rem = r.all;
|
||||
return q.all;
|
||||
}
|
||||
#else
|
||||
|
||||
/* More subroutines needed by GCC output code on some machines. */
|
||||
/* Compile this one with gcc. */
|
||||
/* Copyright (C) 1989-2014 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This is extracted from gcc's libgcc/libgcc2.c with these typedefs added: */
|
||||
typedef short Wtype;
|
||||
typedef int DWtype;
|
||||
typedef unsigned int UWtype;
|
||||
typedef unsigned long long UDWtype;
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
struct DWstruct {Wtype high, low;};
|
||||
#else
|
||||
struct DWstruct {Wtype low, high;};
|
||||
#endif
|
||||
typedef union {
|
||||
struct DWstruct s;
|
||||
DWtype ll;
|
||||
} DWunion;
|
||||
|
||||
UDWtype
|
||||
__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
|
||||
{
|
||||
UDWtype q = 0, r = n, y = d;
|
||||
UWtype lz1, lz2, i, k;
|
||||
|
||||
/* Implements align divisor shift dividend method. This algorithm
|
||||
aligns the divisor under the dividend and then perform number of
|
||||
test-subtract iterations which shift the dividend left. Number of
|
||||
iterations is k + 1 where k is the number of bit positions the
|
||||
divisor must be shifted left to align it under the dividend.
|
||||
quotient bits can be saved in the rightmost positions of the dividend
|
||||
as it shifts left on each test-subtract iteration. */
|
||||
|
||||
if (y <= r)
|
||||
{
|
||||
lz1 = __builtin_clzll (d);
|
||||
lz2 = __builtin_clzll (n);
|
||||
|
||||
k = lz1 - lz2;
|
||||
y = (y << k);
|
||||
|
||||
/* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the
|
||||
aligned divisor. Normal iteration can drops the high order bit
|
||||
of the dividend. Therefore, first test-subtract iteration is a
|
||||
special case, saving its quotient bit in a separate location and
|
||||
not shifting the dividend. */
|
||||
if (r >= y)
|
||||
{
|
||||
r = r - y;
|
||||
q = (1ULL << k);
|
||||
}
|
||||
|
||||
if (k > 0)
|
||||
{
|
||||
y = y >> 1;
|
||||
|
||||
/* k additional iterations where k regular test subtract shift
|
||||
dividend iterations are done. */
|
||||
i = k;
|
||||
do
|
||||
{
|
||||
if (r >= y)
|
||||
r = ((r - y) << 1) + 1;
|
||||
else
|
||||
r = (r << 1);
|
||||
i = i - 1;
|
||||
} while (i != 0);
|
||||
|
||||
/* First quotient bit is combined with the quotient bits resulting
|
||||
from the k regular iterations. */
|
||||
q = q + r;
|
||||
r = r >> k;
|
||||
q = q - (r << k);
|
||||
}
|
||||
}
|
||||
|
||||
if (rp)
|
||||
*rp = r;
|
||||
return q;
|
||||
}
|
||||
|
||||
DWtype
|
||||
__moddi3 (DWtype u, DWtype v)
|
||||
{
|
||||
Wtype c = 0;
|
||||
DWunion uu = {.ll = u};
|
||||
DWunion vv = {.ll = v};
|
||||
DWtype w;
|
||||
|
||||
if (uu.s.high < 0)
|
||||
c = ~c,
|
||||
uu.ll = -uu.ll;
|
||||
if (vv.s.high < 0)
|
||||
vv.ll = -vv.ll;
|
||||
|
||||
(void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
|
||||
if (c)
|
||||
w = -w;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -35,32 +35,33 @@ 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
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
|
||||
|
||||
CPU_VARIANTS = {
|
||||
"standard": "freechips.rocketchip.system.LitexConfig",
|
||||
}
|
||||
|
||||
GCC_FLAGS = {
|
||||
"standard": "-march=rv64ia -mabi=lp64 -O0 ",
|
||||
"standard": "-march=rv64ia -mabi=lp64 -O0 ",
|
||||
}
|
||||
|
||||
class BlackParrotRV64(CPU):
|
||||
name = "blackparrot"
|
||||
human_name = "BlackParrotRV64[ia]"
|
||||
data_width = 64
|
||||
endianness = "little"
|
||||
gcc_triple = ("riscv64-unknown-elf", "riscv64-linux", "riscv-sifive-elf",
|
||||
"riscv64-none-elf")
|
||||
gcc_triple = CPU_GCC_TRIPLE_RISCV64
|
||||
linker_output_format = "elf64-littleriscv"
|
||||
io_regions = {0x30000000: 0x20000000} # origin, length
|
||||
nop = "nop"
|
||||
io_regions = {0x50000000: 0x10000000} # origin, length
|
||||
|
||||
@property
|
||||
def mem_map(self):
|
||||
return {
|
||||
"ethmac" : 0x30000000,
|
||||
"csr" : 0x40000000,
|
||||
"rom" : 0x50000000,
|
||||
"sram" : 0x51000000,
|
||||
"csr" : 0x50000000,
|
||||
# "ethmac" : 0x55000000,
|
||||
"rom" : 0x70000000,
|
||||
"sram" : 0x71000000,
|
||||
"main_ram" : 0x80000000,
|
||||
}
|
||||
|
||||
|
@ -77,48 +78,53 @@ class BlackParrotRV64(CPU):
|
|||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.interrupt = Signal(4)
|
||||
# self.interrupt = Signal(4)
|
||||
self.idbus = idbus = wishbone.Interface(data_width=64, adr_width=37)
|
||||
self.periph_buses = [idbus]
|
||||
self.memory_buses = []
|
||||
|
||||
# # #
|
||||
# self.buses = [wbn]
|
||||
|
||||
self.cpu_params = dict(
|
||||
# clock, reset
|
||||
i_clk_i = ClockSignal(),
|
||||
i_reset_i = ResetSignal() | self.reset,
|
||||
i_clk_i = ClockSignal(),
|
||||
i_reset_i = ResetSignal() | self.reset,
|
||||
|
||||
# irq
|
||||
i_interrupts = self.interrupt,
|
||||
#i_interrupts = self.interrupt,
|
||||
|
||||
# wishbone
|
||||
i_wbm_dat_i = idbus.dat_r,
|
||||
o_wbm_dat_o = idbus.dat_w,
|
||||
i_wbm_ack_i = idbus.ack,
|
||||
i_wbm_err_i = 0,
|
||||
i_wbm_rty_i = 0,
|
||||
o_wbm_adr_o = idbus.adr,
|
||||
o_wbm_stb_o = idbus.stb,
|
||||
o_wbm_cyc_o = idbus.cyc,
|
||||
o_wbm_sel_o = idbus.sel,
|
||||
o_wbm_we_o = idbus.we,
|
||||
o_wbm_cti_o = idbus.cti,
|
||||
o_wbm_bte_o = idbus.bte,
|
||||
)
|
||||
#wishbone
|
||||
i_wbm_dat_i = idbus.dat_r,
|
||||
o_wbm_dat_o = idbus.dat_w,
|
||||
i_wbm_ack_i = idbus.ack,
|
||||
i_wbm_err_i = idbus.err,
|
||||
#i_wbm_rty_i = 0,
|
||||
o_wbm_adr_o = idbus.adr,
|
||||
o_wbm_stb_o = idbus.stb,
|
||||
o_wbm_cyc_o = idbus.cyc,
|
||||
o_wbm_sel_o = idbus.sel,
|
||||
o_wbm_we_o = idbus.we,
|
||||
o_wbm_cti_o = idbus.cti,
|
||||
o_wbm_bte_o = idbus.bte,
|
||||
)
|
||||
|
||||
# add verilog sources
|
||||
# add verilog sources
|
||||
self.add_sources(platform, variant)
|
||||
|
||||
def set_reset_address(self, reset_address):
|
||||
assert not hasattr(self, "reset_address")
|
||||
self.reset_address = reset_address
|
||||
assert reset_address == 0x00000000, "cpu_reset_addr hardcoded to 0x00000000!"
|
||||
#FIXME: set reset addr to 0x70000000
|
||||
#assert reset_address == 0x00000000, "cpu_reset_addr hardcoded to 0x00000000!"
|
||||
|
||||
@staticmethod
|
||||
def add_sources(platform, variant="standard"):
|
||||
filename = get_data_mod("cpu", "blackparrot").data_file(
|
||||
"flist_litex.verilator")
|
||||
vdir = get_data_mod("cpu", "blackparrot").data_location
|
||||
bp_litex_dir = os.path.join(vdir,"bp_litex")
|
||||
simulation = 1
|
||||
if (simulation == 1):
|
||||
filename= os.path.join(bp_litex_dir,"flist.verilator")
|
||||
else:
|
||||
filename= os.path.join(bp_litex_dir,"flist.fpga")
|
||||
with open(filename) as openfileobject:
|
||||
for line in openfileobject:
|
||||
temp = line
|
||||
|
@ -131,7 +137,6 @@ class BlackParrotRV64(CPU):
|
|||
a = os.popen('echo '+ str(dir_))
|
||||
dir_start = a.read()
|
||||
vdir = dir_start[:-1] + line[s2:-1]
|
||||
print("INCDIR" + vdir)
|
||||
platform.add_verilog_include_path(vdir) #this line might be changed
|
||||
elif (temp[0]=='$') :
|
||||
s2 = line.find('/')
|
||||
|
@ -139,7 +144,6 @@ class BlackParrotRV64(CPU):
|
|||
a = os.popen('echo '+ str(dir_))
|
||||
dir_start = a.read()
|
||||
vdir = dir_start[:-1]+ line[s2:-1]
|
||||
print(vdir)
|
||||
platform.add_source(vdir) #this line might be changed
|
||||
elif (temp[0] == '/'):
|
||||
assert("No support for absolute path for now")
|
||||
|
|
|
@ -68,7 +68,7 @@ bss_loop:
|
|||
bss_done:
|
||||
|
||||
// call plic_init // initialize external interrupt controller
|
||||
# li a0, 0x800 // external interrupt sources only (using LiteX timer);
|
||||
li a0, 0x800 // external interrupt sources only (using LiteX timer);
|
||||
// NOTE: must still enable mstatus.MIE!
|
||||
csrw mie,a0
|
||||
|
8
litex/soc/cores/cpu/blackparrot/csr-defs.h
Normal file
8
litex/soc/cores/cpu/blackparrot/csr-defs.h
Normal 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 */
|
|
@ -1,228 +0,0 @@
|
|||
//// Includes
|
||||
// bsg_ip_cores includes
|
||||
+incdir+$BASEJUMP_STL_DIR/bsg_dataflow
|
||||
+incdir+$BASEJUMP_STL_DIR/bsg_mem
|
||||
+incdir+$BASEJUMP_STL_DIR/bsg_misc
|
||||
+incdir+$BASEJUMP_STL_DIR/bsg_test
|
||||
+incdir+$BASEJUMP_STL_DIR/bsg_noc
|
||||
// common includes
|
||||
+incdir+$BP_COMMON_DIR/src/include
|
||||
// fe includes
|
||||
+incdir+$BP_FE_DIR/src/include
|
||||
// be includes
|
||||
+incdir+$BP_BE_DIR/src/include
|
||||
+incdir+$BP_BE_DIR/src/include/bp_be_dcache
|
||||
// me includes
|
||||
+incdir+$BP_ME_DIR/src/include/v
|
||||
// top includes
|
||||
+incdir+$BP_TOP_DIR/src/include
|
||||
//// Packages
|
||||
// bsg_ip_cores packages
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_noc_pkg.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_pkg.v
|
||||
// Interface packages
|
||||
$BP_COMMON_DIR/src/include/bp_common_rv64_pkg.vh
|
||||
$BP_COMMON_DIR/src/include/bp_common_pkg.vh
|
||||
$BP_COMMON_DIR/src/include/bp_common_aviary_pkg.vh
|
||||
// FE packages
|
||||
$BP_FE_DIR/src/include/bp_fe_icache_pkg.vh
|
||||
$BP_FE_DIR/src/include/bp_fe_pkg.vh
|
||||
// BE packages
|
||||
$BP_BE_DIR/src/include/bp_be_pkg.vh
|
||||
$BP_BE_DIR/src/include/bp_be_dcache/bp_be_dcache_pkg.vh
|
||||
// ME packages
|
||||
$BP_ME_DIR/src/include/v/bp_cce_pkg.v
|
||||
$BP_ME_DIR/src/include/v/bp_me_pkg.vh
|
||||
// Top packages
|
||||
$BP_TOP_DIR/src/include/bp_cfg_link_pkg.vh
|
||||
//// bsg_ip_cores files
|
||||
$BASEJUMP_STL_DIR/bsg_async/bsg_async_fifo.v
|
||||
$BASEJUMP_STL_DIR/bsg_async/bsg_launch_sync_sync.v
|
||||
$BASEJUMP_STL_DIR/bsg_async/bsg_async_ptr_gray.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_channel_tunnel.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_channel_tunnel_in.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_channel_tunnel_out.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_1_to_n_tagged_fifo.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_1_to_n_tagged.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_fifo_1r1w_large.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_fifo_1rw_large.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_serial_in_parallel_out.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_one_fifo.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_round_robin_2_to_2.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_fifo_1r1w_pseudo_large.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_fifo_1r1w_small.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_fifo_tracker.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_flow_counter.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_parallel_in_serial_out_dynamic.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_round_robin_n_to_1.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_serial_in_parallel_out_dynamic.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_shift_reg.v
|
||||
$BASEJUMP_STL_DIR/bsg_dataflow/bsg_two_fifo.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_cam_1r1w.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1r1w.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1r1w_sync.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1r1w_sync_synth.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1r1w_synth.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1rw_sync.v
|
||||
// $BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1rw_sync_mask_write_bit.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1rw_sync_mask_write_bit_synth.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1rw_sync_mask_write_byte.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1rw_sync_mask_write_byte_synth.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_1rw_sync_synth.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_2r1w_sync.v
|
||||
$BASEJUMP_STL_DIR/bsg_mem/bsg_mem_2r1w_sync_synth.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_adder_ripple_carry.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_arb_fixed.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_array_concentrate_static.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_circular_ptr.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_concentrate_static.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_counter_clear_up.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_counter_set_down.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_counter_up_down.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_counter_up_down_variable.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_crossbar_o_by_i.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_cycle_counter.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_decode.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_decode_with_v.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_dff.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_dff_en_bypass.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_dff_chain.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_dff_en.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_dff_reset.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_dff_reset_en.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_encode_one_hot.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_lfsr.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_lru_pseudo_tree_decode.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_lru_pseudo_tree_encode.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_mux.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_mux_butterfly.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_mux_one_hot.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_mux_segmented.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_priority_encode.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_priority_encode_one_hot_out.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_round_robin_arb.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_scan.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_swap.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_thermometer_count.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_transpose.v
|
||||
$BASEJUMP_STL_DIR/bsg_misc/bsg_unconcentrate_static.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_mesh_router.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_mesh_router_buffered.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_noc_repeater_node.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_concentrator.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_concentrator_in.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_concentrator_out.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_adapter.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_adapter_in.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_adapter_out.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_decoder_dor.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_input_control.v
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_wormhole_router_output_control.v
|
||||
// Common files
|
||||
$BP_COMMON_DIR/src/v/bsg_fifo_1r1w_fence.v
|
||||
$BP_COMMON_DIR/src/v/bsg_fifo_1r1w_rolly.v
|
||||
$BP_COMMON_DIR/src/v/bp_tlb.v
|
||||
$BP_COMMON_DIR/src/v/bp_tlb_replacement.v
|
||||
// BE files
|
||||
$BP_BE_DIR/src/v/bp_be_top.v
|
||||
// Calculator
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_bypass.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_calculator_top.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_instr_decoder.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_int_alu.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_pipe_fp.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_pipe_int.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_pipe_mem.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_pipe_mul.v
|
||||
$BP_BE_DIR/src/v/bp_be_calculator/bp_be_regfile.v
|
||||
// Checker
|
||||
$BP_BE_DIR/src/v/bp_be_checker/bp_be_checker_top.v
|
||||
$BP_BE_DIR/src/v/bp_be_checker/bp_be_detector.v
|
||||
$BP_BE_DIR/src/v/bp_be_checker/bp_be_director.v
|
||||
$BP_BE_DIR/src/v/bp_be_checker/bp_be_scheduler.v
|
||||
// MMU
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_ptw.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_csr.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_dcache/bp_be_dcache.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_dcache/bp_be_dcache_lce_cmd.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_dcache/bp_be_dcache_lce.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_dcache/bp_be_dcache_lce_req.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_dcache/bp_be_dcache_wbuf.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_dcache/bp_be_dcache_wbuf_queue.v
|
||||
$BP_BE_DIR/src/v/bp_be_mem/bp_be_mem_top.v
|
||||
//// FE files
|
||||
$BP_FE_DIR/src/v/bp_fe_bht.v
|
||||
$BP_FE_DIR/src/v/bp_fe_btb.v
|
||||
$BP_FE_DIR/src/v/bp_fe_lce_cmd.v
|
||||
$BP_FE_DIR/src/v/bp_fe_icache.v
|
||||
$BP_FE_DIR/src/v/bp_fe_instr_scan.v
|
||||
$BP_FE_DIR/src/v/bp_fe_lce.v
|
||||
$BP_FE_DIR/src/v/bp_fe_lce_req.v
|
||||
$BP_FE_DIR/src/v/bp_fe_mem.v
|
||||
$BP_FE_DIR/src/v/bp_fe_pc_gen.v
|
||||
$BP_FE_DIR/src/v/bp_fe_top.v
|
||||
//// ME files
|
||||
// CCE
|
||||
$BP_ME_DIR/src/v/cce/bp_cce.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_alu.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_dir.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_dir_tag_checker.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_dir_lru_extract.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_gad.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_inst_decode.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_msg.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_msg_cached.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_msg_uncached.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_pc.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_pending.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_reg.v
|
||||
$BP_ME_DIR/src/v/cce/bp_cce_top.v
|
||||
// Network
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_cce_id_to_cord.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_cce_to_wormhole_link_client.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_cce_to_wormhole_link_master.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_lce_id_to_cord.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_wormhole_packet_encode_lce_cmd.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_wormhole_packet_encode_lce_req.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_wormhole_packet_encode_lce_resp.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_wormhole_packet_encode_mem_cmd.v
|
||||
$BP_ME_DIR/src/v/wormhole/bp_me_wormhole_packet_encode_mem_resp.v
|
||||
//// TOP
|
||||
$BP_TOP_DIR/src/v/bp_chip.v
|
||||
$BP_TOP_DIR/src/v/bp_core.v
|
||||
$BP_TOP_DIR/src/v/bp_core_complex.v
|
||||
$BP_TOP_DIR/src/v/bp_mem_complex.v
|
||||
$BP_TOP_DIR/src/v/bp_mmio_enclave.v
|
||||
$BP_TOP_DIR/src/v/bp_mmio_node.v
|
||||
$BP_TOP_DIR/src/v/bp_tile.v
|
||||
$BP_TOP_DIR/src/v/bp_tile_node.v
|
||||
//// Common
|
||||
$BP_COMMON_DIR/src/v/bp_addr_map.v
|
||||
|
||||
// bsg_ip_cores files
|
||||
$BASEJUMP_STL_DIR/bsg_fsb/bsg_fsb_node_trace_replay.v
|
||||
// be files
|
||||
$BP_BE_DIR/test/common/bp_be_nonsynth_tracer.v
|
||||
// $BP_BE_DIR/test/common/bp_be_nonsynth_perf.v
|
||||
// me files
|
||||
// $BP_ME_DIR/test/common/bp_mem.v
|
||||
// $BP_ME_DIR/test/common/bp_mem_delay_model.v
|
||||
// $BP_ME_DIR/test/common/bp_mem_transducer.v
|
||||
// $BP_ME_DIR/test/common/bp_mem_storage_sync.v
|
||||
// $BP_ME_DIR/test/common/dramsim2_wrapper.cpp
|
||||
$BP_ME_DIR/test/common/bp_cce_mmio_cfg_loader.v
|
||||
// $BP_ME_DIR/test/common/bp_mem_nonsynth_tracer.v
|
||||
// $BP_ME_DIR/test/common/bp_cce_nonsynth_tracer.v
|
||||
// $BP_ME_DIR/test/common/bp_mem_utils.cpp
|
||||
// top files
|
||||
$BP_TOP_DIR/test/common/bp_nonsynth_host.v
|
||||
// $BP_TOP_DIR/test/common/bp_nonsynth_if_verif.v
|
||||
$BP_TOP_DIR/test/common/bp_nonsynth_commit_tracer.v
|
||||
// /home/scanakci/Research_sado/litex/litex/litex/soc/cores/cpu/blackparrot/pre-alpha-release/bp_top/syn/results/verilator/bp_top_trace_demo.e_bp_single_core_cfg.build/wrapper.v
|
||||
// /home/scanakci/Research_sado/litex/litex/litex/soc/cores/cpu/blackparrot/pre-alpha-release/bp_top/syn/results/verilator/bp_top_trace_demo.e_bp_single_core_cfg.build/test_bp.cpp
|
||||
$BP_FPGA_DIR/bp2wb_convertor.v
|
||||
$BP_FPGA_DIR/ExampleBlackParrotSystem.v
|
||||
$BP_FPGA_DIR/bsg_mem_1rw_sync_mask_write_bit.v
|
||||
// Recent
|
||||
$BASEJUMP_STL_DIR/bsg_noc/bsg_mesh_stitch.v
|
51
litex/soc/cores/cpu/blackparrot/irq.h
Normal file
51
litex/soc/cores/cpu/blackparrot/irq.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <system.h>
|
||||
#include <generated/csr.h>
|
||||
#include <generated/soc.h>
|
||||
|
||||
// The RocketChip uses a Platform-Level Interrupt Controller (PLIC) which
|
||||
// is programmed and queried via a set of MMIO registers.
|
||||
// TODO: How about Blackparrot? Should be probably included in linux version
|
||||
|
||||
#define PLIC_BASE 0x0c000000L // Base address and per-pin priority array
|
||||
#define PLIC_PENDING 0x0c001000L // Bit field matching currently pending pins
|
||||
#define PLIC_ENABLED 0x0c002000L // Bit field corresponding to the current mask
|
||||
#define PLIC_THRSHLD 0x0c200000L // Per-pin priority must be >= this to trigger
|
||||
#define PLIC_CLAIM 0x0c200004L // Claim & completion register address
|
||||
|
||||
static inline unsigned int irq_getie(void)
|
||||
{
|
||||
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; /* FIXME */
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); /* FIXME */
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
return 0; /* FIXME */
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
return csr_readl(PLIC_PENDING) >> 1; /* FIXME */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
|
@ -1,97 +1,24 @@
|
|||
#!/bin/bash
|
||||
## Set common environment variables
|
||||
export LITEX=$(git rev-parse --show-toplevel)
|
||||
export BP=$PWD
|
||||
cp bp_software/cce_ucode.mem /tmp/.
|
||||
cd pre-alpha-release
|
||||
TOP=$(git rev-parse --show-toplevel)
|
||||
export BP_COMMON_DIR=$TOP/bp_common
|
||||
export BP_FE_DIR=$TOP/bp_fe
|
||||
export BP_BE_DIR=$TOP/bp_be
|
||||
export BP_ME_DIR=$TOP/bp_me
|
||||
export BP_TOP_DIR=$TOP/bp_top
|
||||
export BP_EXTERNAL_DIR=$TOP/external
|
||||
export BP=$LITEX/../pythondata-cpu-blackparrot/pythondata_cpu_blackparrot/system_verilog
|
||||
export BP_LITEX_DIR=$BP/bp_litex
|
||||
export LITEX_SOFTWARE_COMPILER_RT=$LITEX/../pythondata-software-compiler_rt
|
||||
|
||||
#TODO: check if BP exists and warn user
|
||||
export BP_COMMON_DIR=$BP/bp_common
|
||||
export BP_FE_DIR=$BP/bp_fe
|
||||
export BP_BE_DIR=$BP/bp_be
|
||||
export BP_ME_DIR=$BP/bp_me
|
||||
export BP_TOP_DIR=$BP/bp_top
|
||||
export BP_EXTERNAL_DIR=$BP/external
|
||||
export BASEJUMP_STL_DIR=$BP_EXTERNAL_DIR/basejump_stl
|
||||
export BP_FPGA_DIR=$TOP/bp_fpga
|
||||
## Setup CAD tools
|
||||
export LITEX_FPGA_DIR=$BP_LITEX_DIR/fpga
|
||||
export LITEX_SIMU_DIR=$BP_LITEX_DIR/simulation
|
||||
export BP_LITEX_SOFTWARE=$BP_LITEX_DIR/software
|
||||
|
||||
# If the machine you are working on is bsg_cadenv compliant, then you do not
|
||||
# need to setup the cad tools, simply put bsg_cadenv in the same root dir.
|
||||
#BSG_CADENV_DIR=$(TOP)/external/bsg_cadenv
|
||||
#-include $(BSG_CADENV_DIR)/cadenv.mk
|
||||
##SOFTWARE CHANGES##
|
||||
|
||||
## Sepcify license path if needed
|
||||
#LM_LICENSE_FILE ?=
|
||||
#for a reason, provided udivmoddi4.c is not functionally correct when used with either BP or Rocket under IA extension. Another version of udivmoddi4.c is a workaround to run BIOS on these architectures.
|
||||
cp $BP_LITEX_SOFTWARE/udivmoddi4.c $LITEX_SOFTWARE_COMPILER_RT/pythondata_software_compiler_rt/data/lib/builtins/.
|
||||
|
||||
## Override tool paths if needed
|
||||
#GCC ?= gcc
|
||||
#VCS_HOME ?=
|
||||
#VCS ?= vcs
|
||||
#URG ?= urg
|
||||
#VERILATOR ?= verilator
|
||||
#DC_SHELL ?= dc_shell
|
||||
#DVE ?= dve
|
||||
#PYTHON ?= python
|
||||
|
||||
## Needed for verilator g++ compilations
|
||||
export SYSTEMC_INCLUDE=$BP_EXTERNAL_DIR/include
|
||||
export SYSTEMC_LIBDIR=$BP_EXTERNAL_DIR/lib-linux64
|
||||
|
||||
## Add external tools and libraries to environment
|
||||
export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH
|
||||
#export PATH=$(BP_EXTERNAL_DIR)/bin:$(PATH)
|
||||
#export SYN_PATH=$(BP_TOP_DIR)/syn
|
||||
#export TB_PATH=$(BP_TOP_DIR)/test/tb
|
||||
#export MEM_PATH=$(BP_COMMON_DIR)/test/mem
|
||||
|
||||
#export LOG_PATH=$(BP_TOP_DIR)/syn/logs
|
||||
#export RESULTS_PATH=$(BP_TOP_DIR)/syn/results
|
||||
#export REPORT_PATH=$(BP_TOP_DIR)/syn/reports
|
||||
|
||||
TB="bp_top_trace_demo"
|
||||
CFG="e_bp_single_core_cfg"
|
||||
START_PC=0x80000000
|
||||
TOLERANCE=2
|
||||
|
||||
# Select CCE ROM based on CFG and Coherence Protocol
|
||||
# TODO: is there a more scalable way to do this?
|
||||
if [ $CFG = "e_bp_half_core_cfg" ]
|
||||
then
|
||||
NUM_LCE_P=1
|
||||
N_WG=64
|
||||
elif [ $CFG = "e_bp_single_core_cfg" ]
|
||||
then
|
||||
NUM_LCE_P=2
|
||||
N_WG=64
|
||||
#echo "Single Core config"
|
||||
#elif ($CFG -eq e_bp_dual_core_cfg)
|
||||
# NUM_LCE_P=4
|
||||
# N_WG=32
|
||||
#elif ($CFG -eq e_bp_quad_core_cfg)
|
||||
# NUM_LCE_P=8
|
||||
# N_WG=16
|
||||
#elif ($CFG -eq e_bp_oct_core_cfg)
|
||||
# NUM_LCE_P=16
|
||||
# N_WG=8
|
||||
#elif ($(CFG), e_bp_sexta_core_cfg)
|
||||
# NUM_LCE_P=32
|
||||
# N_WG=4
|
||||
#elif ($(CFG), e_bp_quad_core_2d_cfg)
|
||||
# NUM_LCE_P=8
|
||||
# N_WG=16
|
||||
#elif ($(CFG), e_bp_oct_core_2d_cfg)
|
||||
# NUM_LCE_P=16
|
||||
# N_WG=8
|
||||
fi
|
||||
|
||||
COH_PROTO="mesi"
|
||||
CCE_MEM_PATH=$BP_ME_DIR/src/asm/roms/$COH_PROTO
|
||||
CCE_MEM=bp_cce_inst_rom_$COH_PROTO_lce$NUM_LCE_P_wg$N_WG_assoc8.mem
|
||||
#DRAMSIM_CH_CFG=DDR2_micron_16M_8b_x8_sg3E.ini
|
||||
#DRAMSIM_SYS_CFG=system.ini
|
||||
#$include $BP_COMMON_DIR/syn/Makefile.verilator
|
||||
#iinclude $(BP_COMMON_DIR)/syn/Makefile.common
|
||||
#include $(BP_COMMON_DIR)/syn/Makefile.dc
|
||||
#include $(BP_COMMON_DIR)/syn/Makefile.regress
|
||||
#include $(BP_COMMON_DIR)/syn/Makefile.vcs
|
||||
cd ../
|
||||
|
|
41
litex/soc/cores/cpu/blackparrot/system.h
Normal file
41
litex/soc/cores/cpu/blackparrot/system.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#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);
|
||||
|
||||
#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 */
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
##SOFTWARE CHANGES##
|
||||
|
||||
#for a reason, provided udivmoddi4.c is not functionally correct when used with either BP or Rocket under IA extension. Another version of udivmoddi4.c is a workaround to run BIOS on these architectures.
|
||||
cp bp_software/udivmoddi4.c $LITEX/litex/soc/software/compiler_rt/lib/builtins/.
|
||||
cp bp_software/cce_ucode.mem /tmp/.
|
||||
|
||||
##HARDWARE CHANGES##
|
||||
#Need to change some files because of memory map differences and proper syntesis
|
||||
cp bp_hardware/bp_common_pkg.vh $BP_COMMON_DIR/src/include/.
|
||||
cp bp_hardware/bp_cce_mmio_cfg_loader.v $BP_ME_DIR/test/common/.
|
||||
cp bp_hardware/bp_nonsynth_host.v $BP_TOP_DIR/test/common/.
|
||||
|
||||
# Neccessary files for FPGA Implementations
|
||||
cp -r bp_fpga $BP_TOP/DIR
|
|
@ -18,10 +18,12 @@ CPU_VARIANTS = ["minimal", "lite", "standard"]
|
|||
|
||||
class LM32(CPU):
|
||||
name = "lm32"
|
||||
human_name = "LM32"
|
||||
data_width = 32
|
||||
endianness = "big"
|
||||
gcc_triple = "lm32-elf"
|
||||
linker_output_format = "elf32-lm32"
|
||||
nop = "nop"
|
||||
io_regions = {0x80000000: 0x80000000} # origin, length
|
||||
|
||||
@property
|
||||
|
|
0
litex/soc/software/libbase/crt0-lm32.S → litex/soc/cores/cpu/lm32/crt0.S
Executable file → Normal file
0
litex/soc/software/libbase/crt0-lm32.S → litex/soc/cores/cpu/lm32/crt0.S
Executable file → Normal file
47
litex/soc/cores/cpu/lm32/irq.h
Normal file
47
litex/soc/cores/cpu/lm32/irq.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#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)
|
||||
{
|
||||
unsigned int ie;
|
||||
__asm__ __volatile__("rcsr %0, IE" : "=r" (ie));
|
||||
return ie;
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
__asm__ __volatile__("wcsr IE, %0" : : "r" (ie));
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
unsigned int mask;
|
||||
__asm__ __volatile__("rcsr %0, IM" : "=r" (mask));
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
__asm__ __volatile__("wcsr IM, %0" : : "r" (mask));
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
unsigned int pending;
|
||||
__asm__ __volatile__("rcsr %0, IP" : "=r" (pending));
|
||||
return pending;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
35
litex/soc/cores/cpu/lm32/system.h
Normal file
35
litex/soc/cores/cpu/lm32/system.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef __SYSTEM_H
|
||||
#define __SYSTEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void)
|
||||
{
|
||||
asm volatile(
|
||||
"wcsr ICC, r0\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
"nop\n"
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void)
|
||||
{
|
||||
asm volatile(
|
||||
"wcsr DCC, r0\n"
|
||||
"nop\n"
|
||||
);
|
||||
}
|
||||
|
||||
void flush_l2_cache(void);
|
||||
|
||||
void busy_wait(unsigned int ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
|
@ -16,10 +16,12 @@ CPU_VARIANTS = ["standard"]
|
|||
|
||||
class Microwatt(CPU):
|
||||
name = "microwatt"
|
||||
human_name = "Microwatt"
|
||||
data_width = 64
|
||||
endianness = "little"
|
||||
gcc_triple = ("powerpc64le-linux")
|
||||
gcc_triple = ("powerpc64le-linux", "powerpc64le-linux-gnu")
|
||||
linker_output_format = "elf64-powerpcle"
|
||||
nop = "nop"
|
||||
io_regions = {0xc0000000: 0x10000000} # origin, length
|
||||
|
||||
@property
|
||||
|
@ -45,8 +47,8 @@ class Microwatt(CPU):
|
|||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.wb_insn = wb_insn = wishbone.Interface(data_width=64, adr_width=28)
|
||||
self.wb_data = wb_data = wishbone.Interface(data_width=64, adr_width=28)
|
||||
self.wb_insn = wb_insn = wishbone.Interface(data_width=64, adr_width=29)
|
||||
self.wb_data = wb_data = wishbone.Interface(data_width=64, adr_width=29)
|
||||
self.periph_buses = [wb_insn, wb_data]
|
||||
self.memory_buses = []
|
||||
|
||||
|
@ -62,7 +64,7 @@ class Microwatt(CPU):
|
|||
i_wishbone_insn_ack = wb_insn.ack,
|
||||
i_wishbone_insn_stall = wb_insn.cyc & ~wb_insn.ack, # No burst support
|
||||
|
||||
o_wishbone_insn_adr = Cat(Signal(4), wb_insn.adr),
|
||||
o_wishbone_insn_adr = Cat(Signal(3), wb_insn.adr),
|
||||
o_wishbone_insn_dat_w = wb_insn.dat_w,
|
||||
o_wishbone_insn_cyc = wb_insn.cyc,
|
||||
o_wishbone_insn_stb = wb_insn.stb,
|
||||
|
@ -74,7 +76,7 @@ class Microwatt(CPU):
|
|||
i_wishbone_data_ack = wb_data.ack,
|
||||
i_wishbone_data_stall = wb_data.cyc & ~wb_data.ack, # No burst support
|
||||
|
||||
o_wishbone_data_adr = Cat(Signal(4), wb_data.adr),
|
||||
o_wishbone_data_adr = Cat(Signal(3), wb_data.adr),
|
||||
o_wishbone_data_dat_w = wb_data.dat_w,
|
||||
o_wishbone_data_cyc = wb_data.cyc,
|
||||
o_wishbone_data_stb = wb_data.stb,
|
||||
|
@ -100,9 +102,7 @@ class Microwatt(CPU):
|
|||
|
||||
@staticmethod
|
||||
def add_sources(platform):
|
||||
sdir = os.path.join(
|
||||
get_data_mod("cpu", "microwatt").data_location,
|
||||
"sources")
|
||||
sdir = get_data_mod("cpu", "microwatt").data_location
|
||||
platform.add_sources(sdir,
|
||||
# Common / Types / Helpers
|
||||
"decode_types.vhdl",
|
||||
|
@ -155,7 +155,7 @@ class Microwatt(CPU):
|
|||
"core_debug.vhdl",
|
||||
"core.vhdl",
|
||||
)
|
||||
platform.add_source(os.path.join(sdir, "..", "microwatt_wrapper.vhdl"))
|
||||
platform.add_source(os.path.join(os.path.dirname(__file__), "microwatt_wrapper.vhdl"))
|
||||
|
||||
def do_finalize(self):
|
||||
self.specials += Instance("microwatt_wrapper", **self.cpu_params)
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define STACK_TOP 0xffff4000
|
||||
|
||||
#define FIXUP_ENDIAN \
|
||||
tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
|
||||
b 191f; /* Skip trampoline if endian is good */ \
|
||||
|
@ -38,24 +36,17 @@
|
|||
oris r,r, (e)@h; \
|
||||
ori r,r, (e)@l;
|
||||
|
||||
.section ".head","ax"
|
||||
|
||||
. = 0
|
||||
.global _start
|
||||
_start:
|
||||
FIXUP_ENDIAN
|
||||
|
||||
/* setup stack */
|
||||
LOAD_IMM64(%r1, STACK_TOP - 0x100)
|
||||
LOAD_IMM64(%r1, _fstack - 0x100)
|
||||
LOAD_IMM64(%r12, main)
|
||||
mtctr %r12,
|
||||
bctrl
|
||||
ba 0
|
||||
|
||||
/* XXX: litedram init should not take exceptions, maybe we could get
|
||||
* rid of these to save space, along with a core tweak to suppress
|
||||
* exceptions in case they happen (just terminate ?)
|
||||
*/
|
||||
b .
|
||||
|
||||
#define EXCEPTION(nr) \
|
||||
.= nr; \
|
4
litex/soc/cores/cpu/microwatt/irq.h
Normal file
4
litex/soc/cores/cpu/microwatt/irq.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#endif /* __IRQ_H */
|
18
litex/soc/cores/cpu/microwatt/system.h
Normal file
18
litex/soc/cores/cpu/microwatt/system.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
|
@ -7,19 +7,21 @@ import subprocess
|
|||
|
||||
from migen import *
|
||||
|
||||
from litex import get_data_mod
|
||||
from litex.soc.interconnect import wishbone
|
||||
from litex.soc.cores.cpu import CPU
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32
|
||||
|
||||
CPU_VARIANTS = ["standard"]
|
||||
|
||||
|
||||
class Minerva(CPU):
|
||||
name = "minerva"
|
||||
human_name = "Minerva"
|
||||
data_width = 32
|
||||
endianness = "little"
|
||||
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed",
|
||||
"riscv64-linux", "riscv-sifive-elf", "riscv64-none-elf")
|
||||
gcc_triple = CPU_GCC_TRIPLE_RISCV32
|
||||
linker_output_format = "elf32-littleriscv"
|
||||
nop = "nop"
|
||||
io_regions = {0x80000000: 0x80000000} # origin, length
|
||||
|
||||
@property
|
||||
|
@ -98,8 +100,8 @@ class Minerva(CPU):
|
|||
cli_params.append("--with-dcache")
|
||||
if with_muldiv:
|
||||
cli_params.append("--with-muldiv")
|
||||
_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
if subprocess.call(["python3", os.path.join(_dir, "verilog", "cli.py"), *cli_params, "generate"],
|
||||
sdir = get_data_mod("cpu", "minerva").data_location
|
||||
if subprocess.call(["python3", os.path.join(sdir, "cli.py"), *cli_params, "generate"],
|
||||
stdout=open(verilog_filename, "w")):
|
||||
raise OSError("Unable to elaborate Minerva CPU, please check your nMigen/Yosys install")
|
||||
|
||||
|
|
|
@ -3,15 +3,8 @@
|
|||
|
||||
#define CSR_MSTATUS_MIE 0x8
|
||||
|
||||
#if defined (__vexriscv__)
|
||||
#define CSR_IRQ_MASK 0xBC0
|
||||
#define CSR_IRQ_PENDING 0xFC0
|
||||
#endif
|
||||
|
||||
#if defined (__minerva__)
|
||||
#define CSR_IRQ_MASK 0x330
|
||||
#define CSR_IRQ_PENDING 0x360
|
||||
#endif
|
||||
|
||||
#define CSR_DCACHE_INFO 0xCC0
|
||||
|
45
litex/soc/cores/cpu/minerva/irq.h
Normal file
45
litex/soc/cores/cpu/minerva/irq.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#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 (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
unsigned int mask;
|
||||
asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK));
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask));
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
unsigned int pending;
|
||||
asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING));
|
||||
return pending;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
41
litex/soc/cores/cpu/minerva/system.h
Normal file
41
litex/soc/cores/cpu/minerva/system.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#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);
|
||||
|
||||
#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 */
|
|
@ -17,11 +17,13 @@ CPU_VARIANTS = ["standard", "linux"]
|
|||
|
||||
class MOR1KX(CPU):
|
||||
name = "mor1kx"
|
||||
human_name = "MOR1KX"
|
||||
data_width = 32
|
||||
endianness = "big"
|
||||
gcc_triple = "or1k-elf"
|
||||
clang_triple = "or1k-linux"
|
||||
linker_output_format = "elf32-or1k"
|
||||
nop = "l.nop"
|
||||
io_regions = {0x80000000: 0x80000000} # origin, length
|
||||
|
||||
@property
|
||||
|
|
44
litex/soc/cores/cpu/mor1kx/irq.h
Normal file
44
litex/soc/cores/cpu/mor1kx/irq.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#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 !!(mfspr(SPR_SR) & SPR_SR_IEE);
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
if (ie & 0x1)
|
||||
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
|
||||
else
|
||||
mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
return mfspr(SPR_PICMR);
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
mtspr(SPR_PICMR, mask);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
return mfspr(SPR_PICSR);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
|
@ -1,8 +1,8 @@
|
|||
/* spr-defs.h - Special purpose registers definitions file
|
||||
|
||||
|
||||
Copyright (C) 2000 Damjan Lampret
|
||||
Copyright (C) 2008, 2010 Embecosm Limited
|
||||
|
||||
|
||||
Contributor Damjan Lampret <lampret@opencores.org>
|
||||
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
|
@ -184,10 +184,10 @@
|
|||
#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */
|
||||
#define SPR_CPUCFGR_ND 0x00000400 /* No delay-slot */
|
||||
#define SPR_CPUCFGR_AVRP 0x00000800 /* Architecture version register present */
|
||||
#define SPR_CPUCFGR_EVBARP 0x00001000 /* Exception vector base address register
|
||||
#define SPR_CPUCFGR_EVBARP 0x00001000 /* Exception vector base address register
|
||||
present */
|
||||
#define SPR_CPUCFGR_ISRP 0x00002000 /* Implementation-specific registers present */
|
||||
#define SPR_CPUCFGR_AECSRP 0x00004000 /* Arithmetic exception control/status
|
||||
#define SPR_CPUCFGR_AECSRP 0x00004000 /* Arithmetic exception control/status
|
||||
registers present */
|
||||
#define SPR_CPUCFGR_RES 0xffff8000 /* Reserved */
|
||||
|
||||
|
@ -628,7 +628,7 @@
|
|||
#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */
|
||||
#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Bit definitions for the Power management register
|
||||
*
|
||||
*/
|
70
litex/soc/cores/cpu/mor1kx/system.h
Normal file
70
litex/soc/cores/cpu/mor1kx/system.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
#ifndef __SYSTEM_H
|
||||
#define __SYSTEM_H
|
||||
|
||||
#include <spr-defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline unsigned long mfspr(unsigned long add)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
__asm__ __volatile__ ("l.mfspr %0,%1,0" : "=r" (ret) : "r" (add));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void mtspr(unsigned long add, unsigned long val)
|
||||
{
|
||||
__asm__ __volatile__ ("l.mtspr %0,%1,0" : : "r" (add), "r" (val));
|
||||
}
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void)
|
||||
{
|
||||
unsigned long iccfgr;
|
||||
unsigned long cache_set_size;
|
||||
unsigned long cache_ways;
|
||||
unsigned long cache_block_size;
|
||||
unsigned long cache_size;
|
||||
int i;
|
||||
|
||||
iccfgr = mfspr(SPR_ICCFGR);
|
||||
cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
|
||||
cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
|
||||
cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
|
||||
cache_size = cache_set_size * cache_ways * cache_block_size;
|
||||
|
||||
for (i = 0; i < cache_size; i += cache_block_size)
|
||||
mtspr(SPR_ICBIR, i);
|
||||
}
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void)
|
||||
{
|
||||
unsigned long dccfgr;
|
||||
unsigned long cache_set_size;
|
||||
unsigned long cache_ways;
|
||||
unsigned long cache_block_size;
|
||||
unsigned long cache_size;
|
||||
int i;
|
||||
|
||||
dccfgr = mfspr(SPR_DCCFGR);
|
||||
cache_ways = 1 << (dccfgr & SPR_ICCFGR_NCW);
|
||||
cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
|
||||
cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
|
||||
cache_size = cache_set_size * cache_ways * cache_block_size;
|
||||
|
||||
for (i = 0; i < cache_size; i += cache_block_size)
|
||||
mtspr(SPR_DCBIR, i);
|
||||
}
|
||||
|
||||
void flush_l2_cache(void);
|
||||
|
||||
void busy_wait(unsigned int ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
|
@ -13,7 +13,7 @@ from migen import *
|
|||
|
||||
from litex import get_data_mod
|
||||
from litex.soc.interconnect import wishbone
|
||||
from litex.soc.cores.cpu import CPU
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
|
||||
|
||||
|
||||
CPU_VARIANTS = ["minimal", "standard"]
|
||||
|
@ -33,11 +33,12 @@ GCC_FLAGS = {
|
|||
|
||||
class PicoRV32(CPU):
|
||||
name = "picorv32"
|
||||
human_name = "PicoRV32"
|
||||
data_width = 32
|
||||
endianness = "little"
|
||||
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed",
|
||||
"riscv64-linux", "riscv-sifive-elf", "riscv64-none-elf")
|
||||
gcc_triple = CPU_GCC_TRIPLE_RISCV64
|
||||
linker_output_format = "elf32-littleriscv"
|
||||
nop = "nop"
|
||||
io_regions = {0x80000000: 0x80000000} # origin, length
|
||||
|
||||
@property
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* purpose with or without fee is hereby granted.
|
||||
*/
|
||||
|
||||
#include "picorv32-extraops.S"
|
||||
#include "extraops.S"
|
||||
|
||||
/*
|
||||
* Interrupt vector.
|
67
litex/soc/cores/cpu/picorv32/irq.h
Normal file
67
litex/soc/cores/cpu/picorv32/irq.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <system.h>
|
||||
#include <generated/csr.h>
|
||||
#include <generated/soc.h>
|
||||
|
||||
// PicoRV32 has a very limited interrupt support, implemented via custom
|
||||
// instructions. It also doesn't have a global interrupt enable/disable, so
|
||||
// we have to emulate it via saving and restoring a mask and using 0/~1 as a
|
||||
// hardware mask.
|
||||
// Due to all this somewhat low-level mess, all of the glue is implemented in
|
||||
// the RiscV crt0, and this header is kept as a thin wrapper. Since interrupts
|
||||
// managed by this layer, do not call interrupt instructions directly, as the
|
||||
// state will go out of sync with the hardware.
|
||||
|
||||
// Read only.
|
||||
extern unsigned int _irq_pending;
|
||||
// Read only.
|
||||
extern unsigned int _irq_mask;
|
||||
// Read only.
|
||||
extern unsigned int _irq_enabled;
|
||||
extern void _irq_enable(void);
|
||||
extern void _irq_disable(void);
|
||||
extern void _irq_setmask(unsigned int);
|
||||
|
||||
static inline unsigned int irq_getie(void)
|
||||
{
|
||||
return _irq_enabled != 0;
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
if (ie & 0x1)
|
||||
_irq_enable();
|
||||
else
|
||||
_irq_disable();
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
// PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how
|
||||
// LiteX sees things.
|
||||
return ~_irq_mask;
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
// PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how
|
||||
// LiteX sees things.
|
||||
_irq_setmask(~mask);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
return _irq_pending;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
18
litex/soc/cores/cpu/picorv32/system.h
Normal file
18
litex/soc/cores/cpu/picorv32/system.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef __SYSTEM_H
|
||||
#define __SYSTEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void){}; /* No instruction cache */
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void){}; /* No instruction cache */
|
||||
void flush_l2_cache(void);
|
||||
|
||||
void busy_wait(unsigned int ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
|
@ -36,7 +36,7 @@ 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
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
|
||||
|
||||
|
||||
CPU_VARIANTS = {
|
||||
|
@ -66,11 +66,12 @@ AXI_DATA_WIDTHS = {
|
|||
|
||||
class RocketRV64(CPU):
|
||||
name = "rocket"
|
||||
human_name = "RocketRV64[imac]"
|
||||
data_width = 64
|
||||
endianness = "little"
|
||||
gcc_triple = ("riscv64-unknown-elf", "riscv64-linux", "riscv-sifive-elf",
|
||||
"riscv64-none-elf")
|
||||
gcc_triple = CPU_GCC_TRIPLE_RISCV64
|
||||
linker_output_format = "elf64-littleriscv"
|
||||
nop = "nop"
|
||||
io_regions = {0x10000000: 0x70000000} # origin, length
|
||||
|
||||
@property
|
||||
|
|
8
litex/soc/cores/cpu/rocket/csr-defs.h
Normal file
8
litex/soc/cores/cpu/rocket/csr-defs.h
Normal 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 */
|
50
litex/soc/cores/cpu/rocket/irq.h
Normal file
50
litex/soc/cores/cpu/rocket/irq.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <system.h>
|
||||
#include <generated/csr.h>
|
||||
#include <generated/soc.h>
|
||||
|
||||
// The RocketChip uses a Platform-Level Interrupt Controller (PLIC) which
|
||||
// is programmed and queried via a set of MMIO registers.
|
||||
|
||||
#define PLIC_BASE 0x0c000000L // Base address and per-pin priority array
|
||||
#define PLIC_PENDING 0x0c001000L // Bit field matching currently pending pins
|
||||
#define PLIC_ENABLED 0x0c002000L // Bit field corresponding to the current mask
|
||||
#define PLIC_THRSHLD 0x0c200000L // Per-pin priority must be >= this to trigger
|
||||
#define PLIC_CLAIM 0x0c200004L // Claim & completion register address
|
||||
|
||||
static inline unsigned int irq_getie(void)
|
||||
{
|
||||
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
return *((unsigned int *)PLIC_ENABLED) >> 1;
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
*((unsigned int *)PLIC_ENABLED) = mask << 1;
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
return *((unsigned int *)PLIC_PENDING) >> 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
|
@ -5,31 +5,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void flush_cpu_icache(void);
|
||||
void flush_cpu_dcache(void);
|
||||
__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);
|
||||
|
||||
#ifdef __or1k__
|
||||
#include <spr-defs.h>
|
||||
static inline unsigned long mfspr(unsigned long add)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
__asm__ __volatile__ ("l.mfspr %0,%1,0" : "=r" (ret) : "r" (add));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void mtspr(unsigned long add, unsigned long val)
|
||||
{
|
||||
__asm__ __volatile__ ("l.mtspr %0,%1,0" : : "r" (add), "r" (val));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__vexriscv__) || defined(__minerva__) || defined(__rocket__) || defined(__blackparrot__)
|
||||
#include <csr-defs.h>
|
||||
|
||||
#define csrr(reg) ({ unsigned long __tmp; \
|
||||
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
|
||||
__tmp; })
|
||||
|
@ -51,7 +34,6 @@ static inline void mtspr(unsigned long add, unsigned long val)
|
|||
asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); })
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue