blob: a4cacf547fbb819da7431ba7688076d3f3cd78dd [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.
#include "mpact/sim/generic/fifo.h"
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
namespace mpact {
namespace sim {
namespace generic {
FifoBase::FifoBase(class ArchState *arch_state, absl::string_view name,
const std::vector<int> &shape, int element_size,
int default_capacity)
: StateItemBase(arch_state, name, shape, element_size),
Component(std::string(name), arch_state),
depth_("depth", default_capacity),
overflow_program_error_(nullptr),
underflow_program_error_(nullptr),
name_(name),
capacity_(default_capacity),
reserved_(0) {
// empty
}
FifoBase::~FifoBase() {
for (auto ptr : fifo_) {
ptr->DecRef();
}
fifo_.clear();
}
bool FifoBase::IsFull() const { return fifo_.size() + reserved_ >= capacity_; }
bool FifoBase::IsEmpty() const { return fifo_.empty() && (reserved_ == 0); }
bool FifoBase::IsOverSubscribed() const {
return fifo_.size() + reserved_ > capacity_;
}
void FifoBase::Reserve(int count) { reserved_ += count; }
bool FifoBase::Push(DataBuffer *db) {
// If any slots are reserved, decrement first before checking for full.
if (reserved_ > 0) {
reserved_--;
}
if (IsFull()) {
if (nullptr != overflow_program_error_) {
overflow_program_error_->Raise("Overflow in fifo " + name_);
}
return false;
} else {
db->IncRef();
fifo_.push_back(db);
return true;
}
}
void FifoBase::Pop() {
if (fifo_.empty()) {
if (nullptr != underflow_program_error_) {
underflow_program_error_->Raise("Underflow in fifo " + name_);
}
return;
}
fifo_.front()->DecRef();
fifo_.pop_front();
}
DataBuffer *FifoBase::Front() const {
if (fifo_.empty()) {
if (nullptr != underflow_program_error_) {
underflow_program_error_->Raise("Underflow in fifo " + name_);
}
return nullptr;
} else {
return fifo_.front();
}
}
unsigned FifoBase::Available() const { return fifo_.size(); }
void FifoBase::SetDataBuffer(DataBuffer *db) { Push(db); }
absl::Status FifoBase::ImportSelf(
const mpact::sim::proto::ComponentData &component_data) {
auto status = Component::ImportSelf(component_data);
if (!status.ok()) return status;
capacity_ = depth_.GetValue();
return absl::OkStatus();
}
} // namespace generic
} // namespace sim
} // namespace mpact