From 808f29ed2e92430ac0ab4e6bbe13b912cb59c164 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 25 May 2022 10:20:09 +0200 Subject: [PATCH] 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. --- litex/soc/cores/cpu/cva6/core.py | 192 +++++++++++++++---------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/litex/soc/cores/cpu/cva6/core.py b/litex/soc/cores/cpu/cva6/core.py index fe0691dbb..e9f13a1f4 100644 --- a/litex/soc/cores/cpu/cva6/core.py +++ b/litex/soc/cores/cpu/cva6/core.py @@ -2,18 +2,17 @@ # This file is part of LiteX. # # Copyright (c) 2021 Hensoldt Cyber GmbH +# Copyright (c) 2022 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause import os import re from migen import * -from migen.fhdl.specials import Tristate from litex import get_data_mod from litex.soc.interconnect import axi -from litex.soc.interconnect import wishbone, stream -from litex.soc.interconnect.csr import * +from litex.soc.interconnect import wishbone from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64 class Open(Signal): pass @@ -32,14 +31,13 @@ GCC_FLAGS = { # ||||/--- Single-Precision Floating-Point # |||||/-- Double-Precision Floating-Point # imacfd - "standard": "-march=rv64imac -mabi=lp64 ", + "standard": "-march=rv64imac -mabi=lp64 ", "full": "-march=rv64gc -mabi=lp64 ", } # Helpers ------------------------------------------------------------------------------------------ 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 with open(os.path.join(basedir, manifest), 'r') as f: for l in f: @@ -50,7 +48,7 @@ def add_manifest_sources(platform, manifest): else: platform.add_source(os.path.join(basedir, res.group(1))) -# CVA6 ----------------------------------------------------------------------------------------- +# CVA6 --------------------------------------------------------------------------------------------- class CVA6(CPU): family = "riscv" @@ -64,8 +62,6 @@ class CVA6(CPU): nop = "nop" io_regions = {0x80000000: 0x80000000} # Origin, Length. - has_fpu = ["full"] - # GCC Flags. @property def gcc_flags(self): @@ -78,114 +74,118 @@ class CVA6(CPU): @property def mem_map(self): return { - "rom" : 0x10000000, - "sram" : 0x20000000, - "csr" : 0x80000000 + "rom" : 0x10000000, + "sram" : 0x20000000, + "csr" : 0x80000000 } - jtag_layout = [ - ("tck", 1), - ("tms", 1), - ("trst", 1), - ("tdi", 1), - ("tdo", 1), - ] - - def __init__(self, platform, variant="standard"): + def __init__(self, platform, variant="standard", use_wishbone=True): self.platform = platform 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.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) - self.pads = pads - self.specials += Tristate(pads.tdo, tdo_o, tdo_oe, tdo_i) + # AXI <-> Wishbone/AXILite conversion. + axi_if = axi.AXIInterface(data_width=64, address_width=32, id_width=4) + 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( # Clk / Rst. - i_clk_i = ClockSignal("sys"), - i_rst_n = ~ResetSignal("sys"), + i_clk_i = ClockSignal("sys"), + i_rst_n = ~ResetSignal("sys") | self.reset, - # Interrupts + # Interrupts. i_irq_sources = self.interrupt, - # AXI interface - o_AWID_o = axi_if.aw.id, - o_AWADDR_o = axi_if.aw.addr, - o_AWLEN_o = axi_if.aw.len, - o_AWSIZE_o = axi_if.aw.size, - o_AWBURST_o = axi_if.aw.burst, - o_AWLOCK_o = axi_if.aw.lock, - o_AWCACHE_o = axi_if.aw.cache, - o_AWPROT_o = axi_if.aw.prot, - o_AWQOS_o = axi_if.aw.qos, - o_AWREGION_o = Open(), - o_AWUSER_o = Open(), - o_AWVALID_o = axi_if.aw.valid, - o_WDATA_o = axi_if.w.data, - o_WSTRB_o = axi_if.w.strb, - o_WLAST_o = axi_if.w.last, - o_WUSER_o = Open(), - o_WVALID_o = axi_if.w.valid, - o_BREADY_o = axi_if.b.ready, - o_ARID_o = axi_if.ar.id, - o_ARADDR_o = axi_if.ar.addr, - o_ARLEN_o = axi_if.ar.len, - o_ARSIZE_o = axi_if.ar.size, - o_ARBURST_o = axi_if.ar.burst, - o_ARLOCK_o = axi_if.ar.lock, - o_ARCACHE_o = axi_if.ar.cache, - o_ARPROT_o = axi_if.ar.prot, - o_ARQOS_o = axi_if.ar.qos, - o_ARUSER_o = Open(), - o_ARREGION_o = Open(), - o_ARVALID_o = axi_if.ar.valid, - o_RREADY_o = axi_if.r.ready, + # AXI interface. + o_AWVALID_o = axi_if.aw.valid, + i_AWREADY_i = axi_if.aw.ready, + o_AWID_o = axi_if.aw.id, + o_AWADDR_o = axi_if.aw.addr, + o_AWLEN_o = axi_if.aw.len, + o_AWSIZE_o = axi_if.aw.size, + o_AWBURST_o = axi_if.aw.burst, + o_AWLOCK_o = axi_if.aw.lock, + o_AWCACHE_o = axi_if.aw.cache, + o_AWPROT_o = axi_if.aw.prot, + o_AWQOS_o = axi_if.aw.qos, + o_AWREGION_o = Open(), + o_AWUSER_o = Open(), - 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_RID_i = axi_if.r.id, - i_RDATA_i = axi_if.r.data, - i_RRESP_i = axi_if.r.resp, - i_RLAST_i = axi_if.r.last, - i_RUSER_i = 0, + o_WVALID_o = axi_if.w.valid, + i_WREADY_i = axi_if.w.ready, + o_WDATA_o = axi_if.w.data, + o_WSTRB_o = axi_if.w.strb, + o_WLAST_o = axi_if.w.last, + o_WUSER_o = Open(), - # 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, + i_BVALID_i = axi_if.b.valid, + o_BREADY_o = axi_if.b.ready, + i_BID_i = axi_if.b.id, + i_BRESP_i = axi_if.b.resp, + i_BUSER_i = 0, - # TODO: add trace interface + o_ARVALID_o = axi_if.ar.valid, + i_ARREADY_i = axi_if.ar.ready, + o_ARID_o = axi_if.ar.id, + o_ARADDR_o = axi_if.ar.addr, + o_ARLEN_o = axi_if.ar.len, + o_ARSIZE_o = axi_if.ar.size, + o_ARBURST_o = axi_if.ar.burst, + o_ARLOCK_o = axi_if.ar.lock, + o_ARCACHE_o = axi_if.ar.cache, + o_ARPROT_o = axi_if.ar.prot, + o_ARQOS_o = axi_if.ar.qos, + o_ARUSER_o = Open(), + o_ARREGION_o = Open(), + + i_RVALID_i = axi_if.r.valid, + o_RREADY_o = axi_if.r.ready, + i_RID_i = axi_if.r.id, + i_RDATA_i = axi_if.r.data, + i_RRESP_i = axi_if.r.resp, + i_RLAST_i = axi_if.r.last, + i_RUSER_i = 0, ) # Add Verilog sources. # TODO: use Flist.cv64a6_imafdc_sv39 and Flist.cv32a6_imac_sv0 instead - add_manifest_sources(platform, 'Flist.cv64a6_imafdc_sv39') - add_manifest_sources(platform, 'Flist.cva6_wrapper') + add_manifest_sources(platform, "Flist.cv64a6_imafdc_sv39") + add_manifest_sources(platform, "Flist.cva6_wrapper") + + def add_jtag(pads): + from migen.fhdl.specials import Tristate + self.jtag_tck = Signal() + self.jtag_tms = Signal() + self.jtag_trst = Signal() + self.jtag_tdi = Signal() + self.jtag_tdo = Signal() + + tdo_o = Signal() + tdo_oe = Signal() + self.specials += Tristate(self.jtag_tdo, tdo_o, tdo_oe) + + self.cpu_params.update( + i_trst_n = self.jtag_trst, + i_tck = self.jtag_tck, + i_tms = self.jtag_tms, + i_tdi = self.jtag_tdi, + o_tdo = tdo_o, + o_tdo_oe = tdo_oe, + ) def set_reset_address(self, reset_address): self.reset_address = reset_address