Vortex 2.0 changes:
+ Microarchitecture optimizations + 64-bit support + Xilinx FPGA support + LLVM-16 support + Refactoring and quality control fixes
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
// Copyright © 2019-2023
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -10,21 +23,25 @@
|
||||
|
||||
using namespace vortex;
|
||||
|
||||
Warp::Warp(Core *core, uint32_t id)
|
||||
: id_(id)
|
||||
Warp::Warp(Core *core, uint32_t warp_id)
|
||||
: warp_id_(warp_id)
|
||||
, arch_(core->arch())
|
||||
, core_(core)
|
||||
, ireg_file_(core->arch().num_threads(), std::vector<Word>(core->arch().num_regs()))
|
||||
, freg_file_(core->arch().num_threads(), std::vector<FWord>(core->arch().num_regs()))
|
||||
, freg_file_(core->arch().num_threads(), std::vector<uint64_t>(core->arch().num_regs()))
|
||||
, vreg_file_(core->arch().num_threads(), std::vector<Byte>(core->arch().vsize()))
|
||||
{
|
||||
this->clear();
|
||||
this->reset();
|
||||
}
|
||||
|
||||
void Warp::clear() {
|
||||
active_ = false;
|
||||
PC_ = STARTUP_ADDR;
|
||||
void Warp::reset() {
|
||||
PC_ = core_->dcrs().base_dcrs.read(VX_DCR_BASE_STARTUP_ADDR0);
|
||||
#if (XLEN == 64)
|
||||
PC_ = (uint64_t(core_->dcrs().base_dcrs.read(VX_DCR_BASE_STARTUP_ADDR1)) << 32) | PC_;
|
||||
#endif
|
||||
tmask_.reset();
|
||||
for (uint32_t i = 0, n = core_->arch().num_threads(); i < n; ++i) {
|
||||
issued_instrs_ = 0;
|
||||
for (uint32_t i = 0, n = arch_.num_threads(); i < n; ++i) {
|
||||
for (auto& reg : ireg_file_.at(i)) {
|
||||
reg = 0;
|
||||
}
|
||||
@@ -35,31 +52,44 @@ void Warp::clear() {
|
||||
reg = 0;
|
||||
}
|
||||
}
|
||||
uui_gen_.reset();
|
||||
}
|
||||
|
||||
void Warp::eval(pipeline_trace_t *trace) {
|
||||
pipeline_trace_t* Warp::eval() {
|
||||
assert(tmask_.any());
|
||||
|
||||
DPH(2, "Fetch: coreid=" << core_->id() << ", wid=" << id_ << ", tmask=");
|
||||
for (uint32_t i = 0, n = core_->arch().num_threads(); i < n; ++i)
|
||||
DPN(2, tmask_.test(n-i-1));
|
||||
DPN(2, ", PC=0x" << std::hex << PC_ << " (#" << std::dec << trace->uuid << ")" << std::endl);
|
||||
|
||||
/* Fetch and decode. */
|
||||
#ifndef NDEBUG
|
||||
uint32_t instr_uuid = uui_gen_.get_uuid(PC_);
|
||||
uint32_t g_wid = core_->id() * arch_.num_warps() + warp_id_;
|
||||
uint32_t instr_id = instr_uuid & 0xffff;
|
||||
uint32_t instr_ref = instr_uuid >> 16;
|
||||
uint64_t uuid = (uint64_t(instr_ref) << 32) | (g_wid << 16) | instr_id;
|
||||
#else
|
||||
uint64_t uuid = 0;
|
||||
#endif
|
||||
|
||||
DPH(1, "Fetch: cid=" << core_->id() << ", wid=" << warp_id_ << ", tmask=");
|
||||
for (uint32_t i = 0, n = arch_.num_threads(); i < n; ++i)
|
||||
DPN(1, tmask_.test(i));
|
||||
DPN(1, ", PC=0x" << std::hex << PC_ << " (#" << std::dec << uuid << ")" << std::endl);
|
||||
|
||||
// Fetch
|
||||
uint32_t instr_code = 0;
|
||||
core_->icache_read(&instr_code, PC_, sizeof(uint32_t));
|
||||
auto instr = core_->decoder().decode(instr_code);
|
||||
|
||||
// Decode
|
||||
auto instr = core_->decoder_.decode(instr_code);
|
||||
if (!instr) {
|
||||
std::cout << std::hex << "Error: invalid instruction 0x" << instr_code << ", at PC=" << PC_ << std::endl;
|
||||
std::cout << std::hex << "Error: invalid instruction 0x" << instr_code << ", at PC=0x" << PC_ << " (#" << std::dec << uuid << ")" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
DP(2, "Instr 0x" << std::hex << instr_code << ": " << *instr);
|
||||
DP(1, "Instr 0x" << std::hex << instr_code << ": " << *instr);
|
||||
|
||||
// Update trace
|
||||
// Create trace
|
||||
auto trace = new pipeline_trace_t(uuid, arch_);
|
||||
trace->cid = core_->id();
|
||||
trace->wid = id_;
|
||||
trace->wid = warp_id_;
|
||||
trace->PC = PC_;
|
||||
trace->tmask = tmask_;
|
||||
trace->rdest = instr->getRDest();
|
||||
@@ -68,18 +98,20 @@ void Warp::eval(pipeline_trace_t *trace) {
|
||||
// Execute
|
||||
this->execute(*instr, trace);
|
||||
|
||||
DP(4, "Register state:");
|
||||
for (uint32_t i = 0; i < core_->arch().num_regs(); ++i) {
|
||||
DPN(4, " %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':');
|
||||
DP(5, "Register state:");
|
||||
for (uint32_t i = 0; i < arch_.num_regs(); ++i) {
|
||||
DPN(5, " %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':');
|
||||
// Integer register file
|
||||
for (uint32_t j = 0; j < core_->arch().num_threads(); ++j) {
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(XLEN/4) << std::hex << ireg_file_.at(j).at(i) << std::setfill(' ') << ' ');
|
||||
for (uint32_t j = 0; j < arch_.num_threads(); ++j) {
|
||||
DPN(5, ' ' << std::setfill('0') << std::setw(XLEN/4) << std::hex << ireg_file_.at(j).at(i) << std::setfill(' ') << ' ');
|
||||
}
|
||||
DPN(4, '|');
|
||||
DPN(5, '|');
|
||||
// Floating point register file
|
||||
for (uint32_t j = 0; j < core_->arch().num_threads(); ++j) {
|
||||
DPN(4, ' ' << std::setfill('0') << std::setw(16) << std::hex << freg_file_.at(j).at(i) << std::setfill(' ') << ' ');
|
||||
for (uint32_t j = 0; j < arch_.num_threads(); ++j) {
|
||||
DPN(5, ' ' << std::setfill('0') << std::setw(16) << std::hex << freg_file_.at(j).at(i) << std::setfill(' ') << ' ');
|
||||
}
|
||||
DPN(4, std::endl);
|
||||
DPN(5, std::endl);
|
||||
}
|
||||
|
||||
return trace;
|
||||
}
|
||||
Reference in New Issue
Block a user