cpu/cva6/core: Cleanup/Simplify integration.

- Cosmetic changes and increase similarities with other CPUs.
- Simplification.
- Allow converting AXI to Wishbone or AXI-Lite (Still keep wishbone as default).
- Connect reset from SoC.
- Reorder AXI signals by channels.
- Move JTAG integration to add_jtag method.
This commit is contained in:
Florent Kermarrec 2022-05-25 10:20:09 +02:00
parent 69451fad09
commit 808f29ed2e
1 changed files with 96 additions and 96 deletions

View File

@ -2,18 +2,17 @@
# This file is part of LiteX. # This file is part of LiteX.
# #
# Copyright (c) 2021 Hensoldt Cyber GmbH <www.hensoldt-cyber.com> # Copyright (c) 2021 Hensoldt Cyber GmbH <www.hensoldt-cyber.com>
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
import os import os
import re import re
from migen import * from migen import *
from migen.fhdl.specials import Tristate
from litex import get_data_mod from litex import get_data_mod
from litex.soc.interconnect import axi from litex.soc.interconnect import axi
from litex.soc.interconnect import wishbone, stream from litex.soc.interconnect import wishbone
from litex.soc.interconnect.csr import *
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64 from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
class Open(Signal): pass class Open(Signal): pass
@ -39,7 +38,6 @@ GCC_FLAGS = {
# Helpers ------------------------------------------------------------------------------------------ # Helpers ------------------------------------------------------------------------------------------
def add_manifest_sources(platform, manifest): def add_manifest_sources(platform, manifest):
# TODO: create a pythondata-cpu-cva6 package to be installed with litex, then use this generic comment
basedir = get_data_mod("cpu", "cva6").data_location basedir = get_data_mod("cpu", "cva6").data_location
with open(os.path.join(basedir, manifest), 'r') as f: with open(os.path.join(basedir, manifest), 'r') as f:
for l in f: for l in f:
@ -50,7 +48,7 @@ def add_manifest_sources(platform, manifest):
else: else:
platform.add_source(os.path.join(basedir, res.group(1))) platform.add_source(os.path.join(basedir, res.group(1)))
# CVA6 ----------------------------------------------------------------------------------------- # CVA6 ---------------------------------------------------------------------------------------------
class CVA6(CPU): class CVA6(CPU):
family = "riscv" family = "riscv"
@ -64,8 +62,6 @@ class CVA6(CPU):
nop = "nop" nop = "nop"
io_regions = {0x80000000: 0x80000000} # Origin, Length. io_regions = {0x80000000: 0x80000000} # Origin, Length.
has_fpu = ["full"]
# GCC Flags. # GCC Flags.
@property @property
def gcc_flags(self): def gcc_flags(self):
@ -83,48 +79,40 @@ class CVA6(CPU):
"csr" : 0x80000000 "csr" : 0x80000000
} }
jtag_layout = [ def __init__(self, platform, variant="standard", use_wishbone=True):
("tck", 1),
("tms", 1),
("trst", 1),
("tdi", 1),
("tdo", 1),
]
def __init__(self, platform, variant="standard"):
self.platform = platform self.platform = platform
self.variant = variant self.variant = variant
data_width = 64
self.axi_if = axi_if = axi.AXIInterface(data_width=data_width, address_width=data_width, id_width=4)
wb_if = wishbone.Interface(data_width=data_width, adr_width=data_width-log2_int(data_width//8))
a2w = axi.AXI2Wishbone(axi_if, wb_if, base_address=0x00000000)
self.submodules += a2w
self.memory_buses = []
self.periph_buses = [wb_if]
self.interrupt = Signal(32)
self.reset = Signal() self.reset = Signal()
self.interrupt = Signal(32)
if use_wishbone:
self.wb_if = wishbone.Interface(data_width=64, adr_width=29)
self.periph_buses = [self.wb_if] # Peripheral buses (Connected to main SoC's bus).
else:
self.axi_lite_if = axi.AXILiteInterface(data_width=64, address_width=32)
self.periph_buses = [self.axi_lite_if] # Peripheral buses (Connected to main SoC's bus).
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
tdo_i = Signal() # # #
tdo_o = Signal()
tdo_oe = Signal()
pads = Record(self.jtag_layout) # AXI <-> Wishbone/AXILite conversion.
self.pads = pads axi_if = axi.AXIInterface(data_width=64, address_width=32, id_width=4)
self.specials += Tristate(pads.tdo, tdo_o, tdo_oe, tdo_i) if use_wishbone:
self.submodules += axi.AXI2Wishbone(axi_if, self.wb_if)
else:
self.submodules += axi.AXI2AXILite(axi_if, self.axi_lite_if)
# CPU Instance.
self.cpu_params = dict( self.cpu_params = dict(
# Clk / Rst. # Clk / Rst.
i_clk_i = ClockSignal("sys"), i_clk_i = ClockSignal("sys"),
i_rst_n = ~ResetSignal("sys"), i_rst_n = ~ResetSignal("sys") | self.reset,
# Interrupts # Interrupts.
i_irq_sources = self.interrupt, i_irq_sources = self.interrupt,
# AXI interface # AXI interface.
o_AWVALID_o = axi_if.aw.valid,
i_AWREADY_i = axi_if.aw.ready,
o_AWID_o = axi_if.aw.id, o_AWID_o = axi_if.aw.id,
o_AWADDR_o = axi_if.aw.addr, o_AWADDR_o = axi_if.aw.addr,
o_AWLEN_o = axi_if.aw.len, o_AWLEN_o = axi_if.aw.len,
@ -136,13 +124,22 @@ class CVA6(CPU):
o_AWQOS_o = axi_if.aw.qos, o_AWQOS_o = axi_if.aw.qos,
o_AWREGION_o = Open(), o_AWREGION_o = Open(),
o_AWUSER_o = Open(), o_AWUSER_o = Open(),
o_AWVALID_o = axi_if.aw.valid,
o_WVALID_o = axi_if.w.valid,
i_WREADY_i = axi_if.w.ready,
o_WDATA_o = axi_if.w.data, o_WDATA_o = axi_if.w.data,
o_WSTRB_o = axi_if.w.strb, o_WSTRB_o = axi_if.w.strb,
o_WLAST_o = axi_if.w.last, o_WLAST_o = axi_if.w.last,
o_WUSER_o = Open(), o_WUSER_o = Open(),
o_WVALID_o = axi_if.w.valid,
i_BVALID_i = axi_if.b.valid,
o_BREADY_o = axi_if.b.ready, o_BREADY_o = axi_if.b.ready,
i_BID_i = axi_if.b.id,
i_BRESP_i = axi_if.b.resp,
i_BUSER_i = 0,
o_ARVALID_o = axi_if.ar.valid,
i_ARREADY_i = axi_if.ar.ready,
o_ARID_o = axi_if.ar.id, o_ARID_o = axi_if.ar.id,
o_ARADDR_o = axi_if.ar.addr, o_ARADDR_o = axi_if.ar.addr,
o_ARLEN_o = axi_if.ar.len, o_ARLEN_o = axi_if.ar.len,
@ -154,38 +151,41 @@ class CVA6(CPU):
o_ARQOS_o = axi_if.ar.qos, o_ARQOS_o = axi_if.ar.qos,
o_ARUSER_o = Open(), o_ARUSER_o = Open(),
o_ARREGION_o = Open(), o_ARREGION_o = Open(),
o_ARVALID_o = axi_if.ar.valid,
o_RREADY_o = axi_if.r.ready,
i_AWREADY_i = axi_if.aw.ready,
i_ARREADY_i = axi_if.ar.ready,
i_WREADY_i = axi_if.w.ready,
i_BVALID_i = axi_if.b.valid,
i_BID_i = axi_if.b.id,
i_BRESP_i = axi_if.b.resp,
i_BUSER_i = 0,
i_RVALID_i = axi_if.r.valid, i_RVALID_i = axi_if.r.valid,
o_RREADY_o = axi_if.r.ready,
i_RID_i = axi_if.r.id, i_RID_i = axi_if.r.id,
i_RDATA_i = axi_if.r.data, i_RDATA_i = axi_if.r.data,
i_RRESP_i = axi_if.r.resp, i_RRESP_i = axi_if.r.resp,
i_RLAST_i = axi_if.r.last, i_RLAST_i = axi_if.r.last,
i_RUSER_i = 0, i_RUSER_i = 0,
# JTAG.
i_trst_n = pads.trst,
i_tck = pads.tck,
i_tms = pads.tms,
i_tdi = pads.tdi,
o_tdo = tdo_o,
o_tdo_oe = tdo_oe,
# TODO: add trace interface
) )
# Add Verilog sources. # Add Verilog sources.
# TODO: use Flist.cv64a6_imafdc_sv39 and Flist.cv32a6_imac_sv0 instead # TODO: use Flist.cv64a6_imafdc_sv39 and Flist.cv32a6_imac_sv0 instead
add_manifest_sources(platform, 'Flist.cv64a6_imafdc_sv39') add_manifest_sources(platform, "Flist.cv64a6_imafdc_sv39")
add_manifest_sources(platform, 'Flist.cva6_wrapper') add_manifest_sources(platform, "Flist.cva6_wrapper")
def add_jtag(pads):
from migen.fhdl.specials import Tristate
self.jtag_tck = Signal()
self.jtag_tms = Signal()
self.jtag_trst = Signal()
self.jtag_tdi = Signal()
self.jtag_tdo = Signal()
tdo_o = Signal()
tdo_oe = Signal()
self.specials += Tristate(self.jtag_tdo, tdo_o, tdo_oe)
self.cpu_params.update(
i_trst_n = self.jtag_trst,
i_tck = self.jtag_tck,
i_tms = self.jtag_tms,
i_tdi = self.jtag_tdi,
o_tdo = tdo_o,
o_tdo_oe = tdo_oe,
)
def set_reset_address(self, reset_address): def set_reset_address(self, reset_address):
self.reset_address = reset_address self.reset_address = reset_address