7 changed files with 243 additions and 205 deletions
@ -0,0 +1,101 @@ |
|||
// See LICENSE for license details
|
|||
|
|||
#include "config.h" |
|||
#include "vector_unit.h" |
|||
#include "processor.h" |
|||
#include "arith.h" |
|||
|
|||
void vectorUnit_t::vectorUnit_t::reset() |
|||
{ |
|||
free(reg_file); |
|||
VLEN = get_vlen(); |
|||
ELEN = get_elen(); |
|||
reg_file = malloc(NVPR * vlenb); |
|||
memset(reg_file, 0, NVPR * vlenb); |
|||
|
|||
auto& csrmap = p->get_state()->csrmap; |
|||
csrmap[CSR_VXSAT] = vxsat = std::make_shared<vxsat_csr_t>(p, CSR_VXSAT); |
|||
csrmap[CSR_VSTART] = vstart = std::make_shared<vector_csr_t>(p, CSR_VSTART, /*mask*/ VLEN - 1); |
|||
csrmap[CSR_VXRM] = vxrm = std::make_shared<vector_csr_t>(p, CSR_VXRM, /*mask*/ 0x3ul); |
|||
csrmap[CSR_VL] = vl = std::make_shared<vector_csr_t>(p, CSR_VL, /*mask*/ 0); |
|||
csrmap[CSR_VTYPE] = vtype = std::make_shared<vector_csr_t>(p, CSR_VTYPE, /*mask*/ 0); |
|||
csrmap[CSR_VLENB] = std::make_shared<vector_csr_t>(p, CSR_VLENB, /*mask*/ 0, /*init*/ vlenb); |
|||
assert(VCSR_VXSAT_SHIFT == 0); // composite_csr_t assumes vxsat begins at bit 0
|
|||
csrmap[CSR_VCSR] = std::make_shared<composite_csr_t>(p, CSR_VCSR, vxrm, vxsat, VCSR_VXRM_SHIFT); |
|||
|
|||
vtype->write_raw(0); |
|||
set_vl(0, 0, 0, -1); // default to illegal configuration
|
|||
} |
|||
|
|||
reg_t vectorUnit_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t newType) |
|||
{ |
|||
int new_vlmul = 0; |
|||
if (vtype->read() != newType) { |
|||
vsew = 1 << (extract64(newType, 3, 3) + 3); |
|||
new_vlmul = int8_t(extract64(newType, 0, 3) << 5) >> 5; |
|||
vflmul = new_vlmul >= 0 ? 1 << new_vlmul : 1.0 / (1 << -new_vlmul); |
|||
vlmax = (VLEN/vsew) * vflmul; |
|||
vta = extract64(newType, 6, 1); |
|||
vma = extract64(newType, 7, 1); |
|||
|
|||
vill = !(vflmul >= 0.125 && vflmul <= 8) |
|||
|| vsew > std::min(vflmul, 1.0f) * ELEN |
|||
|| (newType >> 8) != 0; |
|||
|
|||
if (vill) { |
|||
vlmax = 0; |
|||
vtype->write_raw(UINT64_MAX << (p->get_xlen() - 1)); |
|||
} else { |
|||
vtype->write_raw(newType); |
|||
} |
|||
} |
|||
|
|||
// set vl
|
|||
if (vlmax == 0) { |
|||
vl->write_raw(0); |
|||
} else if (rd == 0 && rs1 == 0) { |
|||
vl->write_raw(vl->read() > vlmax ? vlmax : vl->read()); |
|||
} else if (rd != 0 && rs1 == 0) { |
|||
vl->write_raw(vlmax); |
|||
} else if (rs1 != 0) { |
|||
vl->write_raw(reqVL > vlmax ? vlmax : reqVL); |
|||
} |
|||
|
|||
vstart->write_raw(0); |
|||
setvl_count++; |
|||
return vl->read(); |
|||
} |
|||
|
|||
template<class T> T& vectorUnit_t::elt(reg_t vReg, reg_t n, bool UNUSED is_write) { |
|||
assert(vsew != 0); |
|||
assert((VLEN >> 3)/sizeof(T) > 0); |
|||
reg_t elts_per_reg = (VLEN >> 3) / (sizeof(T)); |
|||
vReg += n / elts_per_reg; |
|||
n = n % elts_per_reg; |
|||
#ifdef WORDS_BIGENDIAN |
|||
// "V" spec 0.7.1 requires lower indices to map to lower significant
|
|||
// bits when changing SEW, thus we need to index from the end on BE.
|
|||
n ^= elts_per_reg - 1; |
|||
#endif |
|||
reg_referenced[vReg] = 1; |
|||
|
|||
#ifdef RISCV_ENABLE_COMMITLOG |
|||
if (is_write) |
|||
p->get_state()->log_reg_write[((vReg) << 4) | 2] = {0, 0}; |
|||
#endif |
|||
|
|||
T *regStart = (T*)((char*)reg_file + vReg * (VLEN >> 3)); |
|||
return regStart[n]; |
|||
} |
|||
|
|||
template signed char& vectorUnit_t::elt<signed char>(reg_t, reg_t, bool); |
|||
template short& vectorUnit_t::elt<short>(reg_t, reg_t, bool); |
|||
template int& vectorUnit_t::elt<int>(reg_t, reg_t, bool); |
|||
template long& vectorUnit_t::elt<long>(reg_t, reg_t, bool); |
|||
template uint8_t& vectorUnit_t::elt<uint8_t>(reg_t, reg_t, bool); |
|||
template uint16_t& vectorUnit_t::elt<uint16_t>(reg_t, reg_t, bool); |
|||
template uint32_t& vectorUnit_t::elt<uint32_t>(reg_t, reg_t, bool); |
|||
template uint64_t& vectorUnit_t::elt<uint64_t>(reg_t, reg_t, bool); |
|||
template float16_t& vectorUnit_t::elt<float16_t>(reg_t, reg_t, bool); |
|||
template float32_t& vectorUnit_t::elt<float32_t>(reg_t, reg_t, bool); |
|||
template float64_t& vectorUnit_t::elt<float64_t>(reg_t, reg_t, bool); |
|||
@ -0,0 +1,135 @@ |
|||
// See LICENSE for license details.
|
|||
#ifndef _RISCV_VECTOR_UNIT_H |
|||
#define _RISCV_VECTOR_UNIT_H |
|||
|
|||
#include "decode.h" |
|||
#include "csrs.h" |
|||
|
|||
class processor_t; |
|||
|
|||
enum VRM{ |
|||
RNU = 0, |
|||
RNE, |
|||
RDN, |
|||
ROD, |
|||
INVALID_RM |
|||
}; |
|||
|
|||
template<uint64_t N> |
|||
struct type_usew_t; |
|||
|
|||
template<> |
|||
struct type_usew_t<8> |
|||
{ |
|||
using type=uint8_t; |
|||
}; |
|||
|
|||
template<> |
|||
struct type_usew_t<16> |
|||
{ |
|||
using type=uint16_t; |
|||
}; |
|||
|
|||
template<> |
|||
struct type_usew_t<32> |
|||
{ |
|||
using type=uint32_t; |
|||
}; |
|||
|
|||
template<> |
|||
struct type_usew_t<64> |
|||
{ |
|||
using type=uint64_t; |
|||
}; |
|||
|
|||
template<uint64_t N> |
|||
struct type_sew_t; |
|||
|
|||
template<> |
|||
struct type_sew_t<8> |
|||
{ |
|||
using type=int8_t; |
|||
}; |
|||
|
|||
template<> |
|||
struct type_sew_t<16> |
|||
{ |
|||
using type=int16_t; |
|||
}; |
|||
|
|||
template<> |
|||
struct type_sew_t<32> |
|||
{ |
|||
using type=int32_t; |
|||
}; |
|||
|
|||
template<> |
|||
struct type_sew_t<64> |
|||
{ |
|||
using type=int64_t; |
|||
}; |
|||
|
|||
|
|||
class vectorUnit_t |
|||
{ |
|||
public: |
|||
processor_t* p; |
|||
void *reg_file; |
|||
char reg_referenced[NVPR]; |
|||
int setvl_count; |
|||
reg_t vlmax; |
|||
reg_t vlenb; |
|||
csr_t_p vxsat; |
|||
vector_csr_t_p vxrm, vstart, vl, vtype; |
|||
reg_t vma, vta; |
|||
reg_t vsew; |
|||
float vflmul; |
|||
reg_t ELEN, VLEN; |
|||
bool vill; |
|||
bool vstart_alu; |
|||
|
|||
// vector element for varies SEW
|
|||
template<class T> T& elt(reg_t vReg, reg_t n, bool is_write = false); |
|||
|
|||
public: |
|||
|
|||
void reset(); |
|||
|
|||
vectorUnit_t(): |
|||
p(0), |
|||
reg_file(0), |
|||
reg_referenced{0}, |
|||
setvl_count(0), |
|||
vlmax(0), |
|||
vlenb(0), |
|||
vxsat(0), |
|||
vxrm(0), |
|||
vstart(0), |
|||
vl(0), |
|||
vtype(0), |
|||
vma(0), |
|||
vta(0), |
|||
vsew(0), |
|||
vflmul(0), |
|||
ELEN(0), |
|||
VLEN(0), |
|||
vill(false), |
|||
vstart_alu(false) { |
|||
} |
|||
|
|||
~vectorUnit_t() { |
|||
free(reg_file); |
|||
reg_file = 0; |
|||
} |
|||
|
|||
reg_t set_vl(int rd, int rs1, reg_t reqVL, reg_t newType); |
|||
|
|||
reg_t get_vlen() { return VLEN; } |
|||
reg_t get_elen() { return ELEN; } |
|||
reg_t get_slen() { return VLEN; } |
|||
|
|||
VRM get_vround_mode() { |
|||
return (VRM)(vxrm->read()); |
|||
} |
|||
}; |
|||
#endif |
|||
Loading…
Reference in new issue