diff options
author | Jerry Zhao <jerryz123@berkeley.edu> | 2022-12-12 16:43:09 -0800 |
---|---|---|
committer | Jerry Zhao <jerryz123@berkeley.edu> | 2022-12-12 17:14:30 -0800 |
commit | 18b8c02b25a9a7ff635ccfe3792d31c43e173ead (patch) | |
tree | b6b3bce71141b8aab0f054c0be81602797e77cab | |
parent | d043952c8b8febcc8ea6c630b1a30ab9c32cef48 (diff) | |
download | riscv-isa-sim-18b8c02b25a9a7ff635ccfe3792d31c43e173ead.zip riscv-isa-sim-18b8c02b25a9a7ff635ccfe3792d31c43e173ead.tar.gz riscv-isa-sim-18b8c02b25a9a7ff635ccfe3792d31c43e173ead.tar.bz2 |
Pull vector unit into separate source/header
-rw-r--r-- | riscv/interactive.cc | 1 | ||||
-rw-r--r-- | riscv/processor.cc | 62 | ||||
-rw-r--r-- | riscv/processor.h | 145 | ||||
-rw-r--r-- | riscv/riscv.mk.in | 2 | ||||
-rw-r--r-- | riscv/v_ext_macros.h | 2 | ||||
-rw-r--r-- | riscv/vector_unit.cc | 101 | ||||
-rw-r--r-- | riscv/vector_unit.h | 135 |
7 files changed, 243 insertions, 205 deletions
diff --git a/riscv/interactive.cc b/riscv/interactive.cc index 8557acc..251a1ca 100644 --- a/riscv/interactive.cc +++ b/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> diff --git a/riscv/processor.cc b/riscv/processor.cc index d161d46..0564610 100644 --- a/riscv/processor.cc +++ b/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; diff --git a/riscv/processor.h b/riscv/processor.h index e6d8a16..a4df3b1 100644 --- a/riscv/processor.h +++ b/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; }; diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 7e38aca..1eee43a 100644 --- a/riscv/riscv.mk.in +++ b/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 = diff --git a/riscv/v_ext_macros.h b/riscv/v_ext_macros.h index 66d8101..3fc0162 100644 --- a/riscv/v_ext_macros.h +++ b/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 // diff --git a/riscv/vector_unit.cc b/riscv/vector_unit.cc new file mode 100644 index 0000000..17c63a9 --- /dev/null +++ b/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); diff --git a/riscv/vector_unit.h b/riscv/vector_unit.h new file mode 100644 index 0000000..b9f706c --- /dev/null +++ b/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 |