blob: f2c7cacd4a178c9c95a2b58c253c5395e29e7a9d [file]
// Copyright 2024 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_UTIL_MEMORY_MEMORY_ROUTER_H_
#define MPACT_SIM_UTIL_MEMORY_MEMORY_ROUTER_H_
#include <cstdint>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/ref_count.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/memory/tagged_memory_interface.h"
// This file defines a general memory router class that connects multiple
// initiators to one or more memory targets according to the memory addresses
// used in the load/store/memory op calls. The class uses instances of the
// SingleInitiatorRouter class to achieve this.
namespace mpact {
namespace sim {
namespace util {
using ::mpact::sim::generic::DataBuffer;
using ::mpact::sim::generic::Instruction;
using ::mpact::sim::generic::ReferenceCount;
class SingleInitiatorRouter;
class MemoryRouter {
public:
// Convenient map types shorthand.
using InitiatorMap = absl::flat_hash_map<std::string, SingleInitiatorRouter*>;
template <typename Interface>
using TargetMap = absl::flat_hash_map<std::string, Interface*>;
MemoryRouter();
MemoryRouter(const MemoryRouter&) = delete;
MemoryRouter& operator=(const MemoryRouter&) = delete;
~MemoryRouter();
// The following three methods add initiators with a given name. Depending
// on the method that is called, the returned interface differs. However, the
// underlying object is the same type for each. Thus if the same name is
// passed in two different calls, the object is the same instance of
// SingleInitiatorRouter, but the returned interfaces differ.
// Add an initiator with name 'name', returning pointer to MemoryInterface.
MemoryInterface* AddMemoryInitiator(const std::string& name);
// Add an initiator with name 'name', returning pointer to
// TaggedMemoryInterface.
TaggedMemoryInterface* AddTaggedInitiator(const std::string& name);
// Add an initiator with name 'name', returning pointer to MemoryInterface.
AtomicMemoryOpInterface* AddAtomicInitiator(const std::string& name);
// The following three methods add target memory interfaces with the given
// name and type. Two different interfaces may not use the same name.
// Add 'memory' interface with name 'name'.
absl::Status AddTarget(const std::string& name, MemoryInterface* memory);
// Add 'tagged_memory' interface with name 'name'.
absl::Status AddTarget(const std::string& name,
TaggedMemoryInterface* tagged_memory);
// Add 'atomic_memory' interface with name 'name'.
absl::Status AddTarget(const std::string& name,
AtomicMemoryOpInterface* atomic_memory);
// Map a target to an initiator for the given address range (inclusive).
absl::Status AddMapping(const std::string& initiator_name,
const std::string& target_name, uint64_t base,
uint64_t top);
private:
// Containers of initiators and target interfaces.
InitiatorMap initiators_;
absl::flat_hash_set<std::string> target_names_;
TargetMap<MemoryInterface> memory_targets_;
TargetMap<TaggedMemoryInterface> tagged_targets_;
TargetMap<AtomicMemoryOpInterface> atomic_targets_;
};
} // namespace util
} // namespace sim
} // namespace mpact
#endif // MPACT_SIM_UTIL_MEMORY_MEMORY_ROUTER_H_