blob: 3e9a4766b77e8221cbcd2480e97e9d1624095e7a [file]
// Copyright 2023 Google LLC
//
// 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
//
// https://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.
#ifndef MPACT_SIM_GENERIC_COMPLEX_RESOURCE_H_
#define MPACT_SIM_GENERIC_COMPLEX_RESOURCE_H_
#include <string>
#include "absl/status/status.h"
#include "absl/types/span.h"
#include "mpact/sim/generic/arch_state.h"
// The complex resource is a resource that is not reserved continuously from
// the beginning of the execution of an instruction, but for one or more cycles
// during the execution. The resource can be reserved ahead of time, thus there
// is a need to maintain a vector of free/used bits. While simple resources can
// be grouped into a "horizontal" vector of free/used bits across resources,
// a complex resource each represents a "vertical" vector of free/used bits
// across cycles, and therefore cannot be grouped with other complex resources.
// Instead, each complex resource must be acquired/released individually.
// This should be fine, as the number of complex resources should be relatively
// manageable, and in general less common that simple resources.
// Since the complex resource uses a cycle vector, it needs to be shifted
// appropriately as time advances. Instead of advancing the resource on each
// cycle, which may not be needed, it is instead advanced by the number of
// cycles since last Acquire/Release/IsFree operation.
namespace mpact {
namespace sim {
namespace generic {
class ComplexResource {
public:
static inline const int kMaxDepth = 512;
ComplexResource(ArchState *state, std::string name, size_t cycle_depth);
ComplexResource() = delete;
~ComplexResource();
// Returns true if the resource is free for the cycles in the vector that are
// set to 1.
bool IsFree(absl::Span<const uint64_t> bit_span);
// Acquires the resource for the cycles specified by bit_span.
void Acquire(absl::Span<const uint64_t> bit_span);
// Release the resource for the cycles specified by the bit_span.
void Release(absl::Span<const uint64_t> bit_span);
// Return printable representation.
std::string AsString() const { return name(); }
// Accessors.
const std::string &name() const { return name_; }
const absl::Span<uint64_t> bit_array() const {
return absl::MakeSpan(bit_array_, array_size_);
}
size_t cycle_depth() const { return cycle_depth_; }
private:
// Advance the cycle vector to current time.
void Advance();
// Pointer to the arch state. This is needed to obtain current time.
ArchState *state_;
// Name of resource.
std::string name_;
// Last time the cycle vector was shifted.
uint64_t last_cycle_ = 0;
// How many cycles are kept in the vector.
size_t cycle_depth_;
// How many uint64_t elements in the array.
size_t array_size_;
// Pointer to the arrays.
uint64_t *bit_array_ = nullptr;
uint64_t *mask_array_ = nullptr;
};
} // namespace generic
} // namespace sim
} // namespace mpact
#endif // MPACT_SIM_GENERIC_COMPLEX_RESOURCE_H_