| // 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/arch_state.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "absl/strings/string_view.h" |
| #include "mpact/sim/generic/fifo.h" |
| #include "mpact/sim/generic/register.h" |
| |
| namespace mpact { |
| namespace sim { |
| namespace generic { |
| |
| ArchState::ArchState(Component* parent, absl::string_view id, |
| SourceOperandInterface* pc_operand) |
| : Component(std::string(id), parent), pc_operand_(pc_operand) { |
| // Create DataBufferFactory to be used for this ArchState instance. |
| db_factory_ = new DataBufferFactory(); |
| |
| // Create the two default delay lines for this ArchState instance. |
| data_buffer_delay_line_ = CreateAndAddDelayLine<DataBufferDelayLine>(); |
| function_delay_line_ = CreateAndAddDelayLine<FunctionDelayLine>(); |
| |
| // Create the program error controller. |
| program_error_controller_ = |
| new ProgramErrorController(absl::StrCat(id, "Errors")); |
| } |
| |
| void ArchState::AddRegister(RegisterBase* reg) { |
| AddRegister(reg->name(), reg); |
| } |
| |
| void ArchState::AddRegister(absl::string_view name, RegisterBase* reg) { |
| registers_.insert(std::make_pair(std::string(name), reg)); |
| } |
| |
| void ArchState::RemoveRegister(absl::string_view name) { |
| registers_.erase(std::string(name)); |
| } |
| |
| void ArchState::AddFifo(FifoBase* fifo) { AddFifo(fifo->name(), fifo); } |
| |
| void ArchState::AddFifo(absl::string_view name, FifoBase* fifo) { |
| fifos_.insert(std::make_pair(std::string(name), fifo)); |
| } |
| |
| void ArchState::RemoveFifo(absl::string_view name) { |
| fifos_.erase(std::string(name)); |
| } |
| |
| ArchState::~ArchState() { |
| for (auto dl : delay_lines_) { |
| delete dl; |
| } |
| delay_lines_.clear(); |
| |
| // Since registers and fifos may have been inserted with aliases, we need to |
| // keep track of the pointers that are deleted, so that we don't delete a |
| // pointer more than once. |
| absl::flat_hash_set<void*> pointer_set; |
| |
| for (const auto& reg : registers_) { |
| if (pointer_set.contains(reg.second)) continue; |
| pointer_set.insert(reg.second); |
| delete reg.second; |
| } |
| registers_.clear(); |
| pointer_set.clear(); |
| |
| for (const auto& fifo : fifos_) { |
| if (pointer_set.contains(fifo.second)) continue; |
| pointer_set.insert(fifo.second); |
| delete fifo.second; |
| } |
| fifos_.clear(); |
| pointer_set.clear(); |
| delete db_factory_; |
| |
| delete program_error_controller_; |
| } |
| |
| } // namespace generic |
| } // namespace sim |
| } // namespace mpact |