arch-riscv: Enable RVV run in Minor and O3 CPU (#228)

Changes in the PR:

1. Change the vset\*vl\* instructions to jump/branch family, and
implement the branchTarget.
2. Move the Vl and Vtype from decoder to PCState
3. get VL, VTYPE and VLENB value from PCState
4. Remove vtype checking in construction so that the minor and o3 cpu
and decode the instructions after the vset\*vl\*
This commit is contained in:
Bobby R. Bruce
2023-09-12 08:31:36 -07:00
committed by GitHub
13 changed files with 365 additions and 124 deletions

View File

@@ -41,17 +41,6 @@ class RiscvCPU:
ArchISA = RiscvISA
class RiscvISANoRVV(RiscvISA):
enable_rvv = False
class RiscvCPUNoRVV:
ArchDecoder = RiscvDecoder
ArchMMU = RiscvMMU
ArchInterrupts = RiscvInterrupts
ArchISA = RiscvISANoRVV
class RiscvAtomicSimpleCPU(BaseAtomicSimpleCPU, RiscvCPU):
mmu = RiscvMMU()
@@ -64,9 +53,9 @@ class RiscvTimingSimpleCPU(BaseTimingSimpleCPU, RiscvCPU):
mmu = RiscvMMU()
class RiscvO3CPU(BaseO3CPU, RiscvCPUNoRVV):
class RiscvO3CPU(BaseO3CPU, RiscvCPU):
mmu = RiscvMMU()
class RiscvMinorCPU(BaseMinorCPU, RiscvCPUNoRVV):
class RiscvMinorCPU(BaseMinorCPU, RiscvCPU):
mmu = RiscvMMU()

View File

@@ -41,8 +41,6 @@ namespace RiscvISA
Decoder::Decoder(const RiscvDecoderParams &p) : InstDecoder(p, &machInst)
{
ISA *isa = dynamic_cast<ISA*>(p.isa);
enableRvv = isa->getEnableRvv();
reset();
}
@@ -50,7 +48,6 @@ void Decoder::reset()
{
aligned = true;
mid = false;
vConfigDone = true;
machInst = 0;
emi = 0;
}
@@ -58,19 +55,6 @@ void Decoder::reset()
void
Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC)
{
// TODO: Current vsetvl instructions stall decode. Future fixes should
// enable speculation, and this code will be removed.
if (GEM5_UNLIKELY(!this->vConfigDone)) {
fatal_if(!enableRvv,
"Vector extension is not enabled for this CPU type\n"
"You can manually enable vector extensions by setting rvv_enabled "
"to true for each ISA object after `createThreads()`\n");
DPRINTF(Decode, "Waiting for vset*vl* to be executed\n");
instDone = false;
outOfBytes = false;
return;
}
// The MSB of the upper and lower halves of a machine instruction.
constexpr size_t max_bit = sizeof(machInst) * 8 - 1;
constexpr size_t mid_bit = sizeof(machInst) * 4 - 1;
@@ -100,14 +84,6 @@ Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC)
instDone = compressed(emi);
}
}
if (instDone) {
emi.vl = this->machVl;
emi.vtype8 = this->machVtype & 0xff;
emi.vill = this->machVtype.vill;
if (vconf(emi)) {
this->vConfigDone = false; // set true when vconfig inst execute
}
}
}
StaticInstPtr
@@ -142,18 +118,12 @@ Decoder::decode(PCStateBase &_next_pc)
next_pc.compressed(false);
}
emi.vl = next_pc.vl();
emi.vtype8 = next_pc.vtype() & 0xff;
emi.vill = next_pc.vtype().vill;
emi.rv_type = static_cast<int>(next_pc.rvType());
return decode(emi, next_pc.instAddr());
}
void
Decoder::setVlAndVtype(uint32_t vl, VTYPE vtype)
{
this->machVtype = vtype;
this->machVl = vl;
this->vConfigDone = true;
}
} // namespace RiscvISA
} // namespace gem5

View File

@@ -54,17 +54,12 @@ class Decoder : public InstDecoder
decode_cache::InstMap<ExtMachInst> instMap;
bool aligned;
bool mid;
bool vConfigDone;
protected:
//The extended machine instruction being generated
ExtMachInst emi;
uint32_t machInst;
bool enableRvv = false;
VTYPE machVtype;
uint32_t machVl;
StaticInstPtr decodeInst(ExtMachInst mach_inst);
/// Decode a machine instruction.
@@ -78,17 +73,12 @@ class Decoder : public InstDecoder
void reset() override;
inline bool compressed(ExtMachInst inst) { return inst.quadRant < 0x3; }
inline bool vconf(ExtMachInst inst) {
return inst.opcode == 0b1010111u && inst.funct3 == 0b111u;
}
//Use this to give data to the decoder. This should be used
//when there is control flow.
void moreBytes(const PCStateBase &pc, Addr fetchPC) override;
StaticInstPtr decode(PCStateBase &nextPC) override;
void setVlAndVtype(uint32_t vl, VTYPE vtype);
};
} // namespace RiscvISA

View File

@@ -183,6 +183,10 @@ Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
std::unique_ptr<PCState> new_pc(dynamic_cast<PCState *>(
tc->getIsaPtr()->newPCState(workload->getEntry())));
panic_if(!new_pc, "Failed create new PCState from ISA pointer");
VTYPE vtype = 0;
vtype.vill = 1;
new_pc->vtype(vtype);
new_pc->vl(0);
tc->pcState(*new_pc);
// Reset PMP Cfg

View File

@@ -100,7 +100,7 @@ class VectorNonSplitInst : public RiscvStaticInst
OpClass __opClass)
: RiscvStaticInst(mnem, _machInst, __opClass),
vl(_machInst.vl),
vtype(checked_vtype(_machInst.vill, _machInst.vtype8))
vtype(_machInst.vtype8)
{
this->flags[IsVector] = true;
}
@@ -118,7 +118,7 @@ class VectorMacroInst : public RiscvMacroInst
OpClass __opClass)
: RiscvMacroInst(mnem, _machInst, __opClass),
vl(_machInst.vl),
vtype(checked_vtype(_machInst.vill, _machInst.vtype8))
vtype(_machInst.vtype8)
{
this->flags[IsVector] = true;
}

View File

@@ -40,6 +40,7 @@
#include "arch/riscv/mmu.hh"
#include "arch/riscv/pagetable.hh"
#include "arch/riscv/pmp.hh"
#include "arch/riscv/pcstate.hh"
#include "arch/riscv/regs/float.hh"
#include "arch/riscv/regs/int.hh"
#include "arch/riscv/regs/misc.hh"
@@ -503,9 +504,19 @@ ISA::readMiscReg(RegIndex idx)
}
case MISCREG_VLENB:
{
return VLENB;
auto rpc = tc->pcState().as<PCState>();
return rpc.vlenb();
}
case MISCREG_VTYPE:
{
auto rpc = tc->pcState().as<PCState>();
return rpc.vtype();
}
case MISCREG_VL:
{
auto rpc = tc->pcState().as<PCState>();
return (RegVal)rpc.vl();
}
break;
case MISCREG_VCSR:
{
return readMiscRegNoEffect(MISCREG_VXSAT) &

View File

@@ -92,7 +92,7 @@ class ISA : public BaseISA
PCStateBase*
newPCState(Addr new_inst_addr=0) const override
{
return new PCState(new_inst_addr, _rvType);
return new PCState(new_inst_addr, _rvType, VLENB);
}
public:

View File

@@ -4359,28 +4359,47 @@ decode QUADRANT default Unknown::unknown() {
uint64_t rs1_bits = RS1;
uint64_t requested_vl = Rs1_ud;
uint64_t requested_vtype = zimm11;
Rd_ud = 0;
}}, VectorConfigOp, IsSerializeAfter, IsNonSpeculative);
uint32_t vlen = VlenbBits * 8;
uint32_t vlmax = getVlmax(Vtype, vlen);
uint32_t current_vl = VL;
}}, {{
Rd_ud = new_vl;
VL = new_vl;
Vtype = new_vtype;
}}, VSetVlDeclare, VSetVliBranchTarget
, VectorConfigOp, IsUncondControl
, IsIndirectControl);
0x1: decode BIT30 {
0x0: vsetvl({{
uint64_t rd_bits = RD;
uint64_t rs1_bits = RS1;
uint64_t requested_vl = Rs1_ud;
uint64_t requested_vtype = Rs2_ud;
Rd_ud = 0;
}}, VectorConfigOp, IsSerializeAfter,
IsNonSpeculative);
uint32_t vlen = VlenbBits * 8;
uint32_t vlmax = getVlmax(Vtype, vlen);
uint32_t current_vl = VL;
}}, {{
Rd_ud = new_vl;
VL = new_vl;
Vtype = new_vtype;
}}, VSetVlDeclare, VSetVlBranchTarget
, VectorConfigOp, IsUncondControl
, IsIndirectControl);
0x1: vsetivli({{
uint64_t rd_bits = RD;
uint64_t rs1_bits = -1;
uint64_t requested_vl = uimm;
uint64_t requested_vtype = zimm10;
Rd_ud = 0;
}}, VectorConfigOp, IsSerializeAfter,
IsNonSpeculative);
uint32_t vlen = VlenbBits * 8;
uint32_t vlmax = getVlmax(Vtype, vlen);
uint32_t current_vl = VL;
}}, {{
Rd_ud = new_vl;
VL = new_vl;
Vtype = new_vtype;
}}, VSetiVliDeclare, VSetiVliBranchTarget
, VectorConfigOp, IsUncondControl
, IsDirectControl);
}
}
}

View File

@@ -27,15 +27,118 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
def format VConfOp(code, *flags) {{
iop = InstObjParams(name, Name, 'VConfOp', code, flags)
header_output = BasicDeclare.subst(iop)
def format VConfOp(code, write_code, declare_class, branch_class, *flags) {{
iop = InstObjParams(
name,
Name,
'VConfOp',
{
'code': code,
'write_code': write_code,
},
flags
)
declareTemplate = eval(declare_class)
branchTargetTemplate = eval(branch_class)
header_output = declareTemplate.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = VConfExecute.subst(iop)
exec_output = VConfExecute.subst(iop) + branchTargetTemplate.subst(iop)
}};
def template VSetVlDeclare {{
//
// Static instruction class for "%(mnemonic)s".
//
class %(class_name)s : public %(base_class)s
{
private:
%(reg_idx_arr_decl)s;
VTYPE getNewVtype(VTYPE, VTYPE, uint32_t) const;
uint32_t getNewVL(
uint32_t, uint32_t, uint32_t, uint64_t, uint64_t) const;
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst);
Fault execute(ExecContext *, trace::InstRecord *) const override;
std::unique_ptr<PCStateBase> branchTarget(
ThreadContext *tc) const override;
using StaticInst::branchTarget;
using %(base_class)s::generateDisassembly;
};
}};
def template VSetiVliDeclare {{
//
// Static instruction class for "%(mnemonic)s".
//
class %(class_name)s : public %(base_class)s
{
private:
%(reg_idx_arr_decl)s;
VTYPE getNewVtype(VTYPE, VTYPE, uint32_t) const;
uint32_t getNewVL(
uint32_t, uint32_t, uint32_t, uint64_t, uint64_t) const;
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst);
Fault execute(ExecContext *, trace::InstRecord *) const override;
std::unique_ptr<PCStateBase> branchTarget(
const PCStateBase &branch_pc) const override;
using StaticInst::branchTarget;
using %(base_class)s::generateDisassembly;
};
}};
def template VConfExecute {{
VTYPE
%(class_name)s::getNewVtype(
VTYPE oldVtype, VTYPE reqVtype, uint32_t vlen) const
{
VTYPE newVtype = oldVtype;
if (oldVtype != reqVtype) {
newVtype = reqVtype;
float vflmul = getVflmul(newVtype.vlmul);
uint32_t sew = getSew(newVtype.vsew);
uint32_t newVill =
!(vflmul >= 0.125 && vflmul <= 8) ||
sew > std::min(vflmul, 1.0f) * ELEN ||
bits(reqVtype, 62, 8) != 0;
if (newVill) {
newVtype = 0;
newVtype.vill = 1;
}
}
return newVtype;
}
uint32_t
%(class_name)s::getNewVL(uint32_t currentVl, uint32_t reqVl,
uint32_t vlmax, uint64_t rdBits, uint64_t rs1Bits) const
{
uint32_t newVl = 0;
if (vlmax == 0) {
newVl = 0;
} else if (rdBits == 0 && rs1Bits == 0) {
newVl = currentVl > vlmax ? vlmax : currentVl;
} else if (rdBits != 0 && rs1Bits == 0) {
newVl = vlmax;
} else if (rs1Bits != 0) {
newVl = reqVl > vlmax ? vlmax : reqVl;
}
return newVl;
}
Fault
%(class_name)s::execute(ExecContext *xc,
trace::InstRecord *traceData) const
@@ -54,49 +157,91 @@ def template VConfExecute {{
tc->setMiscReg(MISCREG_VSTART, 0);
uint32_t vlen = xc->readMiscReg(MISCREG_VLENB) * 8;
uint32_t vlmax = getVlmax(xc->readMiscReg(MISCREG_VTYPE), vlen);
VTYPE new_vtype = getNewVtype(Vtype, requested_vtype, vlen);
vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen);
uint32_t new_vl = getNewVL(
current_vl, requested_vl, vlmax, rd_bits, rs1_bits);
VTYPE new_vtype = requested_vtype;
if (xc->readMiscReg(MISCREG_VTYPE) != new_vtype) {
vlmax = getVlmax(new_vtype, vlen);
float vflmul = getVflmul(new_vtype.vlmul);
uint32_t sew = getSew(new_vtype.vsew);
uint32_t new_vill =
!(vflmul >= 0.125 && vflmul <= 8) ||
sew > std::min(vflmul, 1.0f) * ELEN ||
bits(requested_vtype, 30, 8) != 0;
if (new_vill) {
vlmax = 0;
new_vtype = 0;
new_vtype.vill = 1;
}
xc->setMiscReg(MISCREG_VTYPE, new_vtype);
}
uint32_t current_vl = xc->readMiscReg(MISCREG_VL);
uint32_t new_vl = 0;
if (vlmax == 0) {
new_vl = 0;
} else if (rd_bits == 0 && rs1_bits == 0) {
new_vl = current_vl > vlmax ? vlmax : current_vl;
} else if (rd_bits != 0 && rs1_bits == 0) {
new_vl = vlmax;
} else if (rs1_bits != 0) {
new_vl = requested_vl > vlmax ? vlmax : requested_vl;
}
xc->setMiscReg(MISCREG_VL, new_vl);
tc->getDecoderPtr()->as<Decoder>().setVlAndVtype(new_vl, new_vtype);
Rd = new_vl;
%(write_code)s;
%(op_wb)s;
return NoFault;
}
}};
def template VSetiVliBranchTarget {{
std::unique_ptr<PCStateBase>
%(class_name)s::branchTarget(const PCStateBase &branch_pc) const
{
auto &rpc = branch_pc.as<RiscvISA::PCState>();
uint64_t rd_bits = machInst.rd;
uint64_t rs1_bits = -1;
uint64_t requested_vl = uimm;
uint64_t requested_vtype = zimm10;
uint32_t vlen = rpc.vlenb() * 8;
VTYPE new_vtype = getNewVtype(rpc.vtype(), requested_vtype, vlen);
uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen);
uint32_t new_vl = getNewVL(
rpc.vl(), requested_vl, vlmax, rd_bits, rs1_bits);
std::unique_ptr<PCState> npc(dynamic_cast<PCState*>(rpc.clone()));
npc->vtype(new_vtype);
npc->vl(new_vl);
return npc;
}
}};
def template VSetVliBranchTarget {{
std::unique_ptr<PCStateBase>
%(class_name)s::branchTarget(ThreadContext *tc) const
{
PCStateBase *pc_ptr = tc->pcState().clone();
uint64_t rd_bits = machInst.rd;
uint64_t rs1_bits = machInst.rs1;
uint64_t requested_vl = tc->getReg(srcRegIdx(0));
uint64_t requested_vtype = zimm11;
uint32_t vlen = pc_ptr->as<PCState>().vlenb() * 8;
VTYPE new_vtype = getNewVtype(
pc_ptr->as<PCState>().vtype(), requested_vtype, vlen);
uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen);
uint32_t new_vl = getNewVL(
pc_ptr->as<PCState>().vl(), requested_vl, vlmax, rd_bits, rs1_bits);
pc_ptr->as<PCState>().vtype(new_vtype);
pc_ptr->as<PCState>().vl(new_vl);
return std::unique_ptr<PCStateBase>{pc_ptr};
}
}};
def template VSetVlBranchTarget {{
std::unique_ptr<PCStateBase>
%(class_name)s::branchTarget(ThreadContext *tc) const
{
PCStateBase *pc_ptr = tc->pcState().clone();
uint64_t rd_bits = machInst.rd;
uint64_t rs1_bits = machInst.rs1;
uint64_t requested_vl = tc->getReg(srcRegIdx(0));
uint64_t requested_vtype = tc->getReg(srcRegIdx(1));
uint32_t vlen = pc_ptr->as<PCState>().vlenb() * 8;
VTYPE new_vtype = getNewVtype(
pc_ptr->as<PCState>().vtype(), requested_vtype, vlen);
uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen);
uint32_t new_vl = getNewVL(
pc_ptr->as<PCState>().vl(), requested_vl, vlmax, rd_bits, rs1_bits);
pc_ptr->as<PCState>().vtype(new_vtype);
pc_ptr->as<PCState>().vl(new_vl);
return std::unique_ptr<PCStateBase>{pc_ptr};
}
}};

View File

@@ -98,4 +98,10 @@ def operands {{
#Program Counter Operands
'PC': PCStateOp('ud', 'pc', (None, None, 'IsControl'), 7),
'NPC': PCStateOp('ud', 'npc', (None, None, 'IsControl'), 8),
# VL and VTYPE
'Vtype': PCStateOp('ud', 'vtype', (None, None, 'IsControl'), 10),
'VL': PCStateOp('uw', 'vl', (None, None, 'IsControl'), 11),
#VLENB, actually the CSR is read only.
'VlenbBits': PCStateOp('ud', 'vlenb', (None, None, 'IsControl'), 12),
}};

View File

@@ -43,6 +43,7 @@
#define __ARCH_RISCV_PCSTATE_HH__
#include "arch/generic/pcstate.hh"
#include "arch/riscv/regs/vector.hh"
#include "enums/RiscvType.hh"
namespace gem5
@@ -56,15 +57,28 @@ constexpr enums::RiscvType RV64 = enums::RV64;
class PCState : public GenericISA::UPCState<4>
{
private:
protected:
typedef GenericISA::UPCState<4> Base;
bool _compressed = false;
RiscvType _rvType = RV64;
uint64_t _vlenb = VLENB;
VTYPE _vtype = (1ULL << 63); // vtype.vill = 1 at initial;
uint32_t _vl = 0;
public:
PCState(const PCState &other) : Base(other),
_rvType(other._rvType), _vlenb(other._vlenb),
_vtype(other._vtype), _vl(other._vl)
{}
PCState &operator=(const PCState &other) = default;
PCState() = default;
PCState(const PCState &other) = default;
PCState(Addr addr, RiscvType rvType) : UPCState(addr), _rvType(rvType)
explicit PCState(Addr addr) { set(addr); }
explicit PCState(Addr addr, RiscvType rvType, uint64_t vlenb = VLENB)
{
set(addr);
_rvType = rvType;
_vlenb = vlenb;
}
PCStateBase *clone() const override { return new PCState(*this); }
@@ -76,6 +90,9 @@ class PCState : public GenericISA::UPCState<4>
auto &pcstate = other.as<PCState>();
_compressed = pcstate._compressed;
_rvType = pcstate._rvType;
_vlenb = pcstate._vlenb;
_vtype = pcstate._vtype;
_vl = pcstate._vl;
}
void compressed(bool c) { _compressed = c; }
@@ -84,14 +101,53 @@ class PCState : public GenericISA::UPCState<4>
void rvType(RiscvType rvType) { _rvType = rvType; }
RiscvType rvType() const { return _rvType; }
void vlenb(uint64_t v) { _vlenb = v; }
uint64_t vlenb() const { return _vlenb; }
void vtype(VTYPE v) { _vtype = v; }
VTYPE vtype() const { return _vtype; }
void vl(uint32_t v) { _vl = v; }
uint32_t vl() const { return _vl; }
uint64_t size() const { return _compressed ? 2 : 4; }
bool
branching() const override
{
if (_compressed) {
return npc() != pc() + 2 || nupc() != upc() + 1;
} else {
return npc() != pc() + 4 || nupc() != upc() + 1;
}
return npc() != pc() + size() || nupc() != upc() + 1;
}
bool
equals(const PCStateBase &other) const override
{
auto &opc = other.as<PCState>();
return Base::equals(other) &&
_vlenb == opc._vlenb &&
_vtype == opc._vtype &&
_vl == opc._vl;
}
void
serialize(CheckpointOut &cp) const override
{
Base::serialize(cp);
SERIALIZE_SCALAR(_rvType);
SERIALIZE_SCALAR(_vlenb);
SERIALIZE_SCALAR(_vtype);
SERIALIZE_SCALAR(_vl);
SERIALIZE_SCALAR(_compressed);
}
void
unserialize(CheckpointIn &cp) override
{
Base::unserialize(cp);
UNSERIALIZE_SCALAR(_rvType);
UNSERIALIZE_SCALAR(_vlenb);
UNSERIALIZE_SCALAR(_vtype);
UNSERIALIZE_SCALAR(_vl);
UNSERIALIZE_SCALAR(_compressed);
}
};

View File

@@ -75,8 +75,8 @@ inline constexpr RegClass vecRegClass =
ops(vecRegClassOps).
regType<VecRegContainer>();
BitUnion32(VTYPE)
Bitfield<31> vill;
BitUnion64(VTYPE)
Bitfield<63> vill;
Bitfield<7, 0> vtype8;
Bitfield<7> vma;
Bitfield<6> vta;

View File

@@ -0,0 +1,51 @@
# Copyright (c) 2023 Google LLC
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
def upgrader(cpt):
# Update the RISC-V pcstate to match the new version of
# PCState
for sec in cpt.sections():
import re
if re.search(".*processor.*\.core.*\.xc.*", sec):
if cpt.get(sec, "_rvType", fallback="") == "":
cpt.set(sec, "_rvType", "1")
if cpt.get(sec, "_vlenb", fallback="") == "":
cpt.set(sec, "_vlenb", "32")
if cpt.get(sec, "_vtype", fallback="") == "":
cpt.set(sec, "_vtype", str(1 << 63))
if cpt.get(sec, "_vl", fallback="") == "":
cpt.set(sec, "_vl", "0")
if cpt.get(sec, "_compressed", fallback="") == "":
cpt.set(sec, "_compressed", "false")