SimX multiports support fixes
Some checks are pending
CI / setup (push) Waiting to run
CI / build (32) (push) Blocked by required conditions
CI / build (64) (push) Blocked by required conditions
CI / tests (cache, 32) (push) Blocked by required conditions
CI / tests (cache, 64) (push) Blocked by required conditions
CI / tests (config1, 32) (push) Blocked by required conditions
CI / tests (config1, 64) (push) Blocked by required conditions
CI / tests (config2, 32) (push) Blocked by required conditions
CI / tests (config2, 64) (push) Blocked by required conditions
CI / tests (debug, 32) (push) Blocked by required conditions
CI / tests (debug, 64) (push) Blocked by required conditions
CI / tests (opencl, 32) (push) Blocked by required conditions
CI / tests (opencl, 64) (push) Blocked by required conditions
CI / tests (regression, 32) (push) Blocked by required conditions
CI / tests (regression, 64) (push) Blocked by required conditions
CI / tests (scope, 32) (push) Blocked by required conditions
CI / tests (scope, 64) (push) Blocked by required conditions
CI / tests (stress, 32) (push) Blocked by required conditions
CI / tests (stress, 64) (push) Blocked by required conditions
CI / tests (synthesis, 32) (push) Blocked by required conditions
CI / tests (synthesis, 64) (push) Blocked by required conditions
CI / tests (vm, 32) (push) Blocked by required conditions
CI / tests (vm, 64) (push) Blocked by required conditions
CI / complete (push) Blocked by required conditions

This commit is contained in:
tinebp 2024-12-03 05:46:33 -08:00
parent 24ca4f03aa
commit 30b0daf050
7 changed files with 142 additions and 179 deletions

View file

@ -21,68 +21,64 @@ class CacheCluster : public SimObject<CacheCluster> {
public:
std::vector<std::vector<SimPort<MemReq>>> CoreReqPorts;
std::vector<std::vector<SimPort<MemRsp>>> CoreRspPorts;
SimPort<MemReq> MemReqPort;
SimPort<MemRsp> MemRspPort;
std::vector<SimPort<MemReq>> MemReqPorts;
std::vector<SimPort<MemRsp>> MemRspPorts;
CacheCluster(const SimContext& ctx,
const char* name,
uint32_t num_inputs,
uint32_t num_caches,
uint32_t num_requests,
uint32_t num_units,
const CacheSim::Config& cache_config)
: SimObject(ctx, name)
, CoreReqPorts(num_inputs, std::vector<SimPort<MemReq>>(num_requests, this))
, CoreRspPorts(num_inputs, std::vector<SimPort<MemRsp>>(num_requests, this))
, MemReqPort(this)
, MemRspPort(this)
, caches_(MAX(num_caches, 0x1)) {
, CoreReqPorts(num_inputs, std::vector<SimPort<MemReq>>(cache_config.num_inputs, this))
, CoreRspPorts(num_inputs, std::vector<SimPort<MemRsp>>(cache_config.num_inputs, this))
, MemReqPorts(cache_config.mem_ports, this)
, MemRspPorts(cache_config.mem_ports, this)
, caches_(MAX(num_units, 0x1)) {
CacheSim::Config cache_config2(cache_config);
if (0 == num_caches) {
num_caches = 1;
if (0 == num_units) {
num_units = 1;
cache_config2.bypass = true;
}
char sname[100];
std::vector<MemArbiter::Ptr> input_arbs(num_inputs);
for (uint32_t j = 0; j < num_inputs; ++j) {
snprintf(sname, 100, "%s-input-arb%d", name, j);
input_arbs.at(j) = MemArbiter::Create(sname, ArbiterType::RoundRobin, num_requests, cache_config.num_inputs);
for (uint32_t i = 0; i < num_requests; ++i) {
this->CoreReqPorts.at(j).at(i).bind(&input_arbs.at(j)->ReqIn.at(i));
input_arbs.at(j)->RspIn.at(i).bind(&this->CoreRspPorts.at(j).at(i));
}
}
std::vector<MemArbiter::Ptr> mem_arbs(cache_config.num_inputs);
// Arbitrate incoming core interfaces
std::vector<MemArbiter::Ptr> input_arbs(cache_config.num_inputs);
for (uint32_t i = 0; i < cache_config.num_inputs; ++i) {
snprintf(sname, 100, "%s-mem-arb%d", name, i);
mem_arbs.at(i) = MemArbiter::Create(sname, ArbiterType::RoundRobin, num_inputs, num_caches);
snprintf(sname, 100, "%s-input-arb%d", name, i);
input_arbs.at(i) = MemArbiter::Create(sname, ArbiterType::RoundRobin, num_inputs, num_units);
for (uint32_t j = 0; j < num_inputs; ++j) {
input_arbs.at(j)->ReqOut.at(i).bind(&mem_arbs.at(i)->ReqIn.at(j));
mem_arbs.at(i)->RspIn.at(j).bind(&input_arbs.at(j)->RspOut.at(i));
this->CoreReqPorts.at(j).at(i).bind(&input_arbs.at(i)->ReqIn.at(j));
input_arbs.at(i)->RspIn.at(j).bind(&this->CoreRspPorts.at(j).at(i));
}
}
snprintf(sname, 100, "%s-cache-arb", name);
auto cache_arb = MemArbiter::Create(sname, ArbiterType::RoundRobin, num_caches, 1);
// Arbitrate outgoing memory interfaces
std::vector<MemArbiter::Ptr> mem_arbs(cache_config.mem_ports);
for (uint32_t i = 0; i < cache_config.mem_ports; ++i) {
snprintf(sname, 100, "%s-mem-arb%d", name, i);
mem_arbs.at(i) = MemArbiter::Create(sname, ArbiterType::RoundRobin, num_units, 1);
mem_arbs.at(i)->ReqOut.at(0).bind(&this->MemReqPorts.at(i));
this->MemRspPorts.at(i).bind(&mem_arbs.at(i)->RspOut.at(0));
}
for (uint32_t i = 0; i < num_caches; ++i) {
// Connect caches
for (uint32_t i = 0; i < num_units; ++i) {
snprintf(sname, 100, "%s-cache%d", name, i);
caches_.at(i) = CacheSim::Create(sname, cache_config2);
for (uint32_t j = 0; j < cache_config.num_inputs; ++j) {
mem_arbs.at(j)->ReqOut.at(i).bind(&caches_.at(i)->CoreReqPorts.at(j));
caches_.at(i)->CoreRspPorts.at(j).bind(&mem_arbs.at(j)->RspOut.at(i));
input_arbs.at(j)->ReqOut.at(i).bind(&caches_.at(i)->CoreReqPorts.at(j));
caches_.at(i)->CoreRspPorts.at(j).bind(&input_arbs.at(j)->RspOut.at(i));
}
caches_.at(i)->MemReqPorts.at(0).bind(&cache_arb->ReqIn.at(i));
cache_arb->RspIn.at(i).bind(&caches_.at(i)->MemRspPorts.at(0));
for (uint32_t j = 0; j < cache_config.mem_ports; ++j) {
caches_.at(i)->MemReqPorts.at(j).bind(&mem_arbs.at(j)->ReqIn.at(i));
mem_arbs.at(j)->RspIn.at(i).bind(&caches_.at(i)->MemRspPorts.at(j));
}
}
cache_arb->ReqOut.at(0).bind(&this->MemReqPort);
this->MemRspPort.bind(&cache_arb->RspOut.at(0));
}
~CacheCluster() {}

View file

@ -19,7 +19,6 @@
#include <vector>
#include <list>
#include <queue>
#include <string.h>
using namespace vortex;
@ -306,7 +305,7 @@ private:
params_t params_;
std::vector<bank_t> banks_;
MemArbiter::Ptr bank_arb_;
MemArbiter::Ptr bypass_arb_;
std::vector<MemArbiter::Ptr> nc_arbs_;
std::vector<SimPort<MemReq>> mem_req_ports_;
std::vector<SimPort<MemRsp>> mem_rsp_ports_;
std::vector<bank_req_t> pipeline_reqs_;
@ -322,88 +321,51 @@ public:
, config_(config)
, params_(config)
, banks_((1 << config.B), {config, params_})
, nc_arbs_(config.mem_ports)
, mem_req_ports_((1 << config.B), simobject)
, mem_rsp_ports_((1 << config.B), simobject)
, pipeline_reqs_((1 << config.B), config.ports_per_bank)
{
char sname[100];
snprintf(sname, 100, "%s-bypass-arb", simobject->name().c_str());
if (config_.bypass) {
bypass_arb_ = MemArbiter::Create(sname, ArbiterType::RoundRobin, config_.num_inputs);
snprintf(sname, 100, "%s-bypass-arb", simobject->name().c_str());
auto bypass_arb = MemArbiter::Create(sname, ArbiterType::RoundRobin, config_.num_inputs, config_.mem_ports);
for (uint32_t i = 0; i < config_.num_inputs; ++i) {
simobject->CoreReqPorts.at(i).bind(&bypass_arb_->ReqIn.at(i));
bypass_arb_->RspIn.at(i).bind(&simobject->CoreRspPorts.at(i));
simobject->CoreReqPorts.at(i).bind(&bypass_arb->ReqIn.at(i));
bypass_arb->RspIn.at(i).bind(&simobject->CoreRspPorts.at(i));
}
for (uint32_t i = 0; i < config_.mem_ports; ++i) {
bypass_arb->ReqOut.at(i).bind(&simobject->MemReqPorts.at(i));
simobject->MemRspPorts.at(i).bind(&bypass_arb->RspOut.at(i));
}
bypass_arb_->ReqOut.at(0).bind(&simobject->MemReqPorts.at(0));
simobject->MemRspPorts.at(0).bind(&bypass_arb_->RspOut.at(0));
return;
}
if (strcmp(simobject->name().c_str(), "l3cache")) {
bypass_arb_ = MemArbiter::Create(sname, ArbiterType::Priority, 2);
bypass_arb_->ReqOut.at(0).bind(&simobject->MemReqPorts.at(0));
simobject->MemRspPorts.at(0).bind(&bypass_arb_->RspOut.at(0));
// create non-cacheable arbiter
for (uint32_t i = 0; i < config_.mem_ports; ++i) {
snprintf(sname, 100, "%s-nc-arb%d", simobject->name().c_str(), i);
nc_arbs_.at(i) = MemArbiter::Create(sname, ArbiterType::Priority, 2, 1);
}
if (config.B != 0) {
snprintf(sname, 100, "%s-bank-arb", simobject->name().c_str());
bank_arb_ = MemArbiter::Create(sname, ArbiterType::RoundRobin, (1 << config.B));
for (uint32_t i = 0, n = (1 << config.B); i < n; ++i) {
mem_req_ports_.at(i).bind(&bank_arb_->ReqIn.at(i));
bank_arb_->RspIn.at(i).bind(&mem_rsp_ports_.at(i));
}
bank_arb_->ReqOut.at(0).bind(&bypass_arb_->ReqIn.at(0));
bypass_arb_->RspIn.at(0).bind(&bank_arb_->RspOut.at(0));
} else {
mem_req_ports_.at(0).bind(&bypass_arb_->ReqIn.at(0));
bypass_arb_->RspIn.at(0).bind(&mem_rsp_ports_.at(0));
}
} else {
// TODO: Change this into a crossbar
uint32_t max = MAX(2, config_.num_inputs);
//printf("%s connecting\n", simobject_->name().c_str());
//3
if (config.B != 0) {
bypass_arb_ = MemArbiter::Create(sname, ArbiterType::Priority, max, max);
for (uint32_t i = 0; i < max; ++i) {
//printf("%s connecting input=%d to MemPorts\n", simobject_->name().c_str(), i);
bypass_arb_->ReqOut.at(i).bind(&simobject->MemReqPorts.at(i % (1 << config.B)));
simobject->MemRspPorts.at(i % (1 << config.B)).bind(&bypass_arb_->RspOut.at(i));
}
} else {
bypass_arb_ = MemArbiter::Create(sname, ArbiterType::Priority, 2);
bypass_arb_->ReqOut.at(0).bind(&simobject->MemReqPorts.at(0));
simobject->MemRspPorts.at(0).bind(&bypass_arb_->RspOut.at(0));
}
// Connect non-cacheable arbiter output to outgoing memory ports
for (uint32_t i = 0; i < config_.mem_ports; ++i) {
nc_arbs_.at(i)->ReqOut.at(0).bind(&simobject->MemReqPorts.at(i));
simobject->MemRspPorts.at(i).bind(&nc_arbs_.at(i)->RspOut.at(0));
}
if (config.B != 0)
{
snprintf(sname, 100, "%s-bank-arb", simobject->name().c_str());
bank_arb_ = MemArbiter::Create(sname, ArbiterType::RoundRobin, (1 << config.B), (1 << config.B));
for (uint32_t i = 0, n = (1 << config.B); i < n; ++i)
{
//1
//printf("%s Connecting memory ports to bank=%d\n", simobject_->name().c_str(), i);
mem_req_ports_.at(i).bind(&bank_arb_->ReqIn.at(i));
bank_arb_->RspIn.at(i).bind(&mem_rsp_ports_.at(i));
}
//2
if (config_.num_inputs > 1) {
for (uint32_t i = 0; i < max; ++i) {
//printf("%s connecting bank and bypass port=%d\n", simobject_->name().c_str(), i);
bank_arb_->ReqOut.at(i % (1 << config.B)).bind(&bypass_arb_->ReqIn.at(i));
bypass_arb_->RspIn.at(i).bind(&bank_arb_->RspOut.at(i % (1 << config.B)));
}
} else {
bank_arb_->ReqOut.at(0).bind(&bypass_arb_->ReqIn.at(0));
bypass_arb_->RspIn.at(0).bind(&bank_arb_->RspOut.at(0));
}
}
else
{
mem_req_ports_.at(0).bind(&bypass_arb_->ReqIn.at(0));
bypass_arb_->RspIn.at(0).bind(&mem_rsp_ports_.at(0));
}
// Create bank's memory arbiter
snprintf(sname, 100, "%s-bank-arb", simobject->name().c_str());
auto bank_mem_arb = MemArbiter::Create(sname, ArbiterType::RoundRobin, (1 << config.B), config_.mem_ports);
for (uint32_t i = 0, n = (1 << config.B); i < n; ++i) {
mem_req_ports_.at(i).bind(&bank_mem_arb->ReqIn.at(i));
bank_mem_arb->RspIn.at(i).bind(&mem_rsp_ports_.at(i));
}
// Connect bank's memory arbiter to non-cacheable arbiter's input 0
for (uint32_t i = 0; i < config_.mem_ports; ++i) {
bank_mem_arb->ReqOut.at(i).bind(&nc_arbs_.at(i)->ReqIn.at(0));
nc_arbs_.at(i)->RspIn.at(0).bind(&bank_mem_arb->RspOut.at(i));
}
// calculate cache initialization cycles
@ -434,8 +396,8 @@ public:
}
// handle cache bypasss responses
{
auto& bypass_port = bypass_arb_->RspIn.at(1);
for (uint32_t i = 0, n = config_.mem_ports; i < n; ++i) {
auto& bypass_port = nc_arbs_.at(i)->RspIn.at(1);
if (!bypass_port.empty()) {
auto& mem_rsp = bypass_port.front();
this->processBypassResponse(mem_rsp);
@ -568,7 +530,8 @@ private:
{
MemReq mem_req(core_req);
mem_req.tag = (core_req.tag << params_.log2_num_inputs) + req_id;
bypass_arb_->ReqIn.at(1).push(mem_req, 1);
uint32_t mem_port = req_id % config_.mem_ports;
nc_arbs_.at(mem_port)->ReqIn.at(1).push(mem_req, 1);
DT(3, simobject_->name() << " bypass-dram-req: " << mem_req);
}

View file

@ -21,8 +21,8 @@ Cluster::Cluster(const SimContext& ctx,
const Arch &arch,
const DCRS &dcrs)
: SimObject(ctx, "cluster")
, mem_req_port(this)
, mem_rsp_port(this)
, mem_req_ports(L2_MEM_PORTS, this)
, mem_rsp_ports(L2_MEM_PORTS, this)
, cluster_id_(cluster_id)
, processor_(processor)
, sockets_(NUM_SOCKETS)
@ -35,26 +35,9 @@ Cluster::Cluster(const SimContext& ctx,
// create sockets
snprintf(sname, 100, "cluster%d-icache-arb", cluster_id);
auto icache_arb = MemArbiter::Create(sname, ArbiterType::RoundRobin, sockets_per_cluster);
snprintf(sname, 100, "cluster%d-dcache-arb", cluster_id);
auto dcache_arb = MemArbiter::Create(sname, ArbiterType::RoundRobin, sockets_per_cluster);
for (uint32_t i = 0; i < sockets_per_cluster; ++i) {
uint32_t socket_id = cluster_id * sockets_per_cluster + i;
auto socket = Socket::Create(socket_id,
this,
arch,
dcrs);
socket->icache_mem_req_port.bind(&icache_arb->ReqIn.at(i));
icache_arb->RspIn.at(i).bind(&socket->icache_mem_rsp_port);
socket->dcache_mem_req_port.bind(&dcache_arb->ReqIn.at(i));
dcache_arb->RspIn.at(i).bind(&socket->dcache_mem_rsp_port);
sockets_.at(i) = socket;
sockets_.at(i) = Socket::Create(socket_id, this, arch, dcrs);
}
// Create l2cache
@ -77,14 +60,19 @@ Cluster::Cluster(const SimContext& ctx,
2, // pipeline latency
});
l2cache_->MemReqPorts.at(0).bind(&this->mem_req_port);
this->mem_rsp_port.bind(&l2cache_->MemRspPorts.at(0));
// connect l2cache core interfaces
for (uint32_t i = 0; i < sockets_per_cluster; ++i) {
for (uint32_t j = 0; j < L1_MEM_PORTS; ++j) {
sockets_.at(i)->mem_req_ports.at(j).bind(&l2cache_->CoreReqPorts.at(i * L1_MEM_PORTS + j));
l2cache_->CoreRspPorts.at(i * L1_MEM_PORTS + j).bind(&sockets_.at(i)->mem_rsp_ports.at(j));
}
}
icache_arb->ReqOut.at(0).bind(&l2cache_->CoreReqPorts.at(0));
l2cache_->CoreRspPorts.at(0).bind(&icache_arb->RspOut.at(0));
dcache_arb->ReqOut.at(0).bind(&l2cache_->CoreReqPorts.at(1));
l2cache_->CoreRspPorts.at(1).bind(&dcache_arb->RspOut.at(0));
// connect l2cache memory interfaces
for (uint32_t i = 0; i < L2_MEM_PORTS; ++i) {
l2cache_->MemReqPorts.at(i).bind(&this->mem_req_ports.at(i));
this->mem_rsp_ports.at(i).bind(&l2cache_->MemRspPorts.at(i));
}
}
Cluster::~Cluster() {

View file

@ -1,10 +1,10 @@
// 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.
@ -32,13 +32,13 @@ public:
CacheSim::PerfStats l2cache;
};
SimPort<MemReq> mem_req_port;
SimPort<MemRsp> mem_rsp_port;
std::vector<SimPort<MemReq>> mem_req_ports;
std::vector<SimPort<MemRsp>> mem_rsp_ports;
Cluster(const SimContext& ctx,
Cluster(const SimContext& ctx,
uint32_t cluster_id,
ProcessorImpl* processor,
const Arch &arch,
ProcessorImpl* processor,
const Arch &arch,
const DCRS &dcrs);
~Cluster();
@ -63,16 +63,16 @@ public:
bool running() const;
int get_exitcode() const;
int get_exitcode() const;
void barrier(uint32_t bar_id, uint32_t count, uint32_t core_id);
PerfStats perf_stats() const;
private:
uint32_t cluster_id_;
ProcessorImpl* processor_;
std::vector<Socket::Ptr> sockets_;
std::vector<Socket::Ptr> sockets_;
std::vector<CoreMask> barriers_;
CacheSim::Ptr l2cache_;
uint32_t cores_per_socket_;

View file

@ -28,6 +28,11 @@ ProcessorImpl::ProcessorImpl(const Arch& arch)
uint32_t(arch.num_cores()) * arch.num_clusters()
});
// create clusters
for (uint32_t i = 0; i < arch.num_clusters(); ++i) {
clusters_.at(i) = Cluster::Create(i, this, arch, dcrs_);
}
// create L3 cache
l3cache_ = CacheSim::Create("l3cache", CacheSim::Config{
!L3_ENABLED,
@ -47,20 +52,20 @@ ProcessorImpl::ProcessorImpl(const Arch& arch)
}
);
// connect L3 memory ports
// connect L3 core interfaces
for (uint32_t i = 0; i < arch.num_clusters(); ++i) {
for (uint32_t j = 0; j < L2_MEM_PORTS; ++j) {
clusters_.at(i)->mem_req_ports.at(j).bind(&l3cache_->CoreReqPorts.at(i * L2_MEM_PORTS + j));
l3cache_->CoreRspPorts.at(i * L2_MEM_PORTS + j).bind(&clusters_.at(i)->mem_rsp_ports.at(j));
}
}
// connect L3 memory interfaces
for (uint32_t i = 0; i < L3_MEM_PORTS; ++i) {
l3cache_->MemReqPorts.at(i).bind(&memsim_->MemReqPorts.at(i));
memsim_->MemRspPorts.at(i).bind(&l3cache_->MemRspPorts.at(i));
}
// create clusters
for (uint32_t i = 0; i < arch.num_clusters(); ++i) {
clusters_.at(i) = Cluster::Create(i, this, arch, dcrs_);
// connect L3 core ports
clusters_.at(i)->mem_req_port.bind(&l3cache_->CoreReqPorts.at(i));
l3cache_->CoreRspPorts.at(i).bind(&clusters_.at(i)->mem_rsp_port);
}
// set up memory profiling
for (uint32_t i = 0; i < L3_MEM_PORTS; ++i) {
memsim_->MemReqPorts.at(i).tx_callback([&](const MemReq& req, uint64_t cycle){

View file

@ -22,10 +22,8 @@ Socket::Socket(const SimContext& ctx,
const Arch &arch,
const DCRS &dcrs)
: SimObject(ctx, "socket")
, icache_mem_req_port(this)
, icache_mem_rsp_port(this)
, dcache_mem_req_port(this)
, dcache_mem_rsp_port(this)
, mem_req_ports(L1_MEM_PORTS, this)
, mem_rsp_ports(L1_MEM_PORTS, this)
, socket_id_(socket_id)
, cluster_(cluster)
, cores_(arch.socket_size())
@ -34,7 +32,7 @@ Socket::Socket(const SimContext& ctx,
char sname[100];
snprintf(sname, 100, "socket%d-icaches", socket_id);
icaches_ = CacheCluster::Create(sname, cores_per_socket, NUM_ICACHES, 1, CacheSim::Config{
icaches_ = CacheCluster::Create(sname, cores_per_socket, NUM_ICACHES, CacheSim::Config{
!ICACHE_ENABLED,
log2ceil(ICACHE_SIZE), // C
log2ceil(L1_LINE_SIZE), // L
@ -51,11 +49,8 @@ Socket::Socket(const SimContext& ctx,
2, // pipeline latency
});
icaches_->MemReqPort.bind(&icache_mem_req_port);
icache_mem_rsp_port.bind(&icaches_->MemRspPort);
snprintf(sname, 100, "socket%d-dcaches", socket_id);
dcaches_ = CacheCluster::Create(sname, cores_per_socket, NUM_DCACHES, DCACHE_NUM_REQS, CacheSim::Config{
dcaches_ = CacheCluster::Create(sname, cores_per_socket, NUM_DCACHES, CacheSim::Config{
!DCACHE_ENABLED,
log2ceil(DCACHE_SIZE), // C
log2ceil(L1_LINE_SIZE), // L
@ -72,15 +67,34 @@ Socket::Socket(const SimContext& ctx,
2, // pipeline latency
});
dcaches_->MemReqPort.bind(&dcache_mem_req_port);
dcache_mem_rsp_port.bind(&dcaches_->MemRspPort);
// connect l1 caches to outgoing memory interfaces
for (uint32_t i = 0; i < L1_MEM_PORTS; ++i) {
if (i == 0) {
snprintf(sname, 100, "socket%d-l1_arb%d", socket_id, i);
auto l1_arb = MemArbiter::Create(sname, ArbiterType::RoundRobin, 2, 1);
icaches_->MemReqPorts.at(0).bind(&l1_arb->ReqIn.at(1));
l1_arb->RspIn.at(1).bind(&icaches_->MemRspPorts.at(0));
dcaches_->MemReqPorts.at(0).bind(&l1_arb->ReqIn.at(0));
l1_arb->RspIn.at(0).bind(&dcaches_->MemRspPorts.at(0));
l1_arb->ReqOut.at(0).bind(&this->mem_req_ports.at(0));
this->mem_rsp_ports.at(0).bind(&l1_arb->RspOut.at(0));
} else {
this->mem_req_ports.at(i).bind(&dcaches_->MemReqPorts.at(i));
dcaches_->MemRspPorts.at(i).bind(&this->mem_rsp_ports.at(i));
}
}
// create cores
for (uint32_t i = 0; i < cores_per_socket; ++i) {
uint32_t core_id = socket_id * cores_per_socket + i;
cores_.at(i) = Core::Create(core_id, this, arch, dcrs);
}
// connect cores to caches
for (uint32_t i = 0; i < cores_per_socket; ++i) {
cores_.at(i)->icache_req_ports.at(0).bind(&icaches_->CoreReqPorts.at(i).at(0));
icaches_->CoreRspPorts.at(i).at(0).bind(&cores_.at(i)->icache_rsp_ports.at(0));

View file

@ -1,10 +1,10 @@
// 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.
@ -32,16 +32,13 @@ public:
CacheSim::PerfStats dcache;
};
SimPort<MemReq> icache_mem_req_port;
SimPort<MemRsp> icache_mem_rsp_port;
std::vector<SimPort<MemReq>> mem_req_ports;
std::vector<SimPort<MemRsp>> mem_rsp_ports;
SimPort<MemReq> dcache_mem_req_port;
SimPort<MemRsp> dcache_mem_rsp_port;
Socket(const SimContext& ctx,
Socket(const SimContext& ctx,
uint32_t socket_id,
Cluster* cluster,
const Arch &arch,
Cluster* cluster,
const Arch &arch,
const DCRS &dcrs);
~Socket();
@ -66,14 +63,14 @@ public:
bool running() const;
int get_exitcode() const;
int get_exitcode() const;
void barrier(uint32_t bar_id, uint32_t count, uint32_t core_id);
void resume(uint32_t core_id);
PerfStats perf_stats() const;
private:
uint32_t socket_id_;
Cluster* cluster_;