Browse Source

Pull vector unit into separate source/header

pull/1173/head
Jerry Zhao 3 years ago
parent
commit
18b8c02b25
  1. 1
      riscv/interactive.cc
  2. 62
      riscv/processor.cc
  3. 145
      riscv/processor.h
  4. 2
      riscv/riscv.mk.in
  5. 2
      riscv/v_ext_macros.h
  6. 101
      riscv/vector_unit.cc
  7. 135
      riscv/vector_unit.h

1
riscv/interactive.cc

@ -4,6 +4,7 @@
#include "decode.h"
#include "disasm.h"
#include "mmu.h"
#include "vector_unit.h"
#include <sys/mman.h>
#include <termios.h>
#include <map>

62
riscv/processor.cc

@ -9,6 +9,7 @@
#include "mmu.h"
#include "disasm.h"
#include "platform.h"
#include "vector_unit.h"
#include <cinttypes>
#include <cmath>
#include <cstdlib>
@ -511,67 +512,6 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
#endif
}
void processor_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 processor_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();
}
void processor_t::set_debug(bool value)
{
debug = value;

145
riscv/processor.h

@ -17,6 +17,7 @@
#include "isa_parser.h"
#include "triggers.h"
#include "memif.h"
#include "vector_unit.h"
#define N_HPMCOUNTERS 29
@ -59,68 +60,6 @@ typedef std::unordered_map<reg_t, freg_t> commit_log_reg_t;
// addr, value, size
typedef std::vector<std::tuple<reg_t, uint64_t, uint8_t>> commit_log_mem_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;
};
// architectural state of a RISC-V hart
struct state_t
{
@ -385,88 +324,6 @@ public:
reg_t lg_pmp_granularity;
reg_t pmp_tor_mask() { return -(reg_t(1) << (lg_pmp_granularity - PMP_SHIFT)); }
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 UNUSED is_write = false) {
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];
}
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());
}
};
vectorUnit_t VU;
triggers::module_t TM;
};

2
riscv/riscv.mk.in

@ -42,6 +42,7 @@ riscv_hdrs = \
jtag_dtm.h \
csrs.h \
triggers.h \
vector_unit.h
riscv_install_hdrs = \
abstract_device.h \
@ -94,6 +95,7 @@ riscv_srcs = \
jtag_dtm.cc \
csrs.cc \
triggers.cc \
vector_unit.cc \
$(riscv_gen_srcs) \
riscv_test_srcs =

2
riscv/v_ext_macros.h

@ -3,6 +3,8 @@
#ifndef _RISCV_V_EXT_MACROS_H
#define _RISCV_V_EXT_MACROS_H
#include "vector_unit.h"
//
// vector: masking skip helper
//

101
riscv/vector_unit.cc

@ -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);

135
riscv/vector_unit.h

@ -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…
Cancel
Save