diff options
author | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-06-06 02:52:20 -0700 |
---|---|---|
committer | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-06-14 07:42:30 -0700 |
commit | 9de0cdda3f089bf1a73d39eb1abb1dafe8cdbbab (patch) | |
tree | 963768de702045d785abf1218da9901c1fdb25f7 | |
parent | 004649e9e5d71d0a3ebb1e4d70711999aca91cbf (diff) | |
download | spike-9de0cdda3f089bf1a73d39eb1abb1dafe8cdbbab.zip spike-9de0cdda3f089bf1a73d39eb1abb1dafe8cdbbab.tar.gz spike-9de0cdda3f089bf1a73d39eb1abb1dafe8cdbbab.tar.bz2 |
rvv: add vector unit structure
Signed-off-by: Bruce Hoult <bruce@hoult.org>
Signed-off-by: Dave Wen <dave.wen@sifive.com>
-rw-r--r-- | riscv/processor.cc | 26 | ||||
-rw-r--r-- | riscv/processor.h | 118 |
2 files changed, 144 insertions, 0 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc index 189b7db..4118825 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -130,6 +130,32 @@ void state_t::reset(reg_t max_isa) pmpaddr[0] = ~reg_t(0); } +void vectorUnit_t::reset(){ + free(reg_file); + VLEN = get_vlen(); + ELEN = get_elen(); + SLEN = get_slen(); // registers are simply concatenated + reg_file = malloc(NVPR * (VLEN/8)); + vtype = -1; + set_vl(-1, 0, 0); // vsew8, vlmul1 +} + +reg_t vectorUnit_t::set_vl(uint64_t regId, reg_t reqVL, reg_t newType){ + if (vtype != newType){ + vtype = newType; + vsew = 1 << (BITS(newType, 4, 2) + 3); + vlmul = 1 << BITS(newType, 1, 0); + vediv = 1 << BITS(newType, 6, 5); + vlmax = VLEN/vsew * vlmul; + vmlen = vsew / vlmul; + reg_mask = (NVPR-1) & ~(vlmul-1); + } + vl = reqVL <= vlmax ? (regId == 0)? vlmax: reqVL : vlmax; + vstart = 0; + setvl_count++; + return vl; +} + void processor_t::set_debug(bool value) { debug = value; diff --git a/riscv/processor.h b/riscv/processor.h index de0be78..cd4355d 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -9,6 +9,7 @@ #include <string> #include <vector> #include <map> +#include <cassert> #include "debug_rom_defines.h" class processor_t; @@ -83,6 +84,121 @@ typedef struct bool load; } mcontrol_t; +inline reg_t BITS(reg_t v, int hi, int lo){ + return (v >> lo) & ((2 << (hi - lo)) - 1); +} + +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 reg_mask, vlmax, vmlen; + reg_t vstart, vxrm, vxsat, vl, vtype; + reg_t vediv, vsew, vlmul; + reg_t ELEN, VLEN, SLEN; + bool vill; + + // vector element for varies SEW + template<class T> + T& elt(reg_t vReg, reg_t n){ + 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; + reg_referenced[vReg] = 1; + + T *regStart = (T*)((char*)reg_file + vReg * (VLEN >> 3)); + return regStart[n]; + } + public: + + void reset(); + + vectorUnit_t(){ + reg_file = 0; + } + + ~vectorUnit_t(){ + free(reg_file); + reg_file = 0; + } + + reg_t set_vl(uint64_t regId, reg_t reqVL, reg_t newType); + + reg_t get_vlen() { return VLEN; } + reg_t get_elen() { return ELEN; } + reg_t get_slen() { return SLEN; } + + VRM get_vround_mode() { + return (VRM)vxrm; + } +}; + // architectural state of a RISC-V hart struct state_t { @@ -337,6 +453,8 @@ private: // Track repeated executions for processor_t::disasm() uint64_t last_pc, last_bits, executions; +public: + vectorUnit_t VU; }; reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc); |