aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2019-06-06 02:52:20 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2019-06-14 07:42:30 -0700
commit9de0cdda3f089bf1a73d39eb1abb1dafe8cdbbab (patch)
tree963768de702045d785abf1218da9901c1fdb25f7
parent004649e9e5d71d0a3ebb1e4d70711999aca91cbf (diff)
downloadspike-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.cc26
-rw-r--r--riscv/processor.h118
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);