 |
Cerata
A library to generate structural hardware designs
|
15 #include "cerata/graph.h"
21 #include "cerata/utils.h"
22 #include "cerata/node.h"
23 #include "cerata/logging.h"
24 #include "cerata/object.h"
25 #include "cerata/pool.h"
26 #include "cerata/edge.h"
27 #include "cerata/parameter.h"
28 #include "cerata/expression.h"
35 if (o->name() == object->name()) {
36 if (o.get() ==
object.get()) {
40 CERATA_LOG(ERROR,
"Graph " +
name() +
" already contains an object with name " + object->name());
46 if (object->parent() && object->parent().value() !=
this) {
47 CERATA_LOG(FATAL,
"Object " + object->name() +
" already has parent " + object->parent().value()->name());
51 std::vector<Object *> references;
52 object->AppendReferences(&references);
53 for (
const auto &ref : references) {
56 if (ref->parent().value() ==
this) {
62 auto gen_node =
dynamic_cast<Node *
>(ref);
64 if (gen_node->IsLiteral()) {
67 if (gen_node->IsExpression()) {
72 CERATA_LOG(ERROR,
"Object [" + ref->name()
73 +
"] bound to object [" + object->name()
74 +
"] is not present on Graph " +
name());
79 object->SetParent(
this);
85 for (
const auto &obj :
objects) {
93 if (o->get() == obj) {
101 for (
const auto &n : GetAll<Node>()) {
102 if (n->name() == node_name) {
110 for (
const auto &n : GetAll<Node>()) {
111 if (n->name() == node_name) {
115 CERATA_LOG(FATAL,
"Node with name " + node_name +
" does not exist on Graph " + this->
name());
120 for (
const auto &n : GetAll<Node>()) {
130 for (
const auto &n : GetAll<NodeArray>()) {
131 if (n->node_id() ==
id) {
139 std::vector<Node *> result;
140 for (
const auto &n : GetAll<Node>()) {
149 std::vector<NodeArray *> result;
150 auto arrays = GetAll<NodeArray>();
151 for (
const auto &a : arrays) {
152 if (a->node_id() ==
id) {
160 return Get<Port>(
name);
164 return Get<Signal>(
name);
168 return Get<Parameter>(
name);
172 return Get<Parameter>(param.
name());
176 return Get<Parameter>(param->name());
180 return Get<PortArray>(
name);
184 return Get<SignalArray>(
name);
188 std::vector<Node *> result;
189 for (
const auto &n : GetAll<Node>()) {
190 for (
const auto &i : n->sources()) {
192 if (!i->src()->parent()) {
193 result.push_back(i->src());
203 std::vector<Node *> result;
204 for (
const auto &n : GetAll<Node>()) {
205 for (
const auto &
id : ids) {
206 if (n->node_id() ==
id) {
216 meta_[key] = std::move(value);
222 if (o->name() ==
name) {
230 std::stringstream ss;
242 child->SetParent(
this);
249 const std::vector<std::shared_ptr<Object>> &objects,
252 auto *ptr =
new Component(std::move(name));
253 auto ret = std::shared_ptr<Component>(ptr);
255 component_pool->
Add(ret);
257 for (
const auto &
object : objects) {
265 return component(std::move(name), {}, component_pool);
269 std::vector<const Component *> ret;
272 if (child->IsComponent()) {
274 auto child_as_comp =
dynamic_cast<Component *
>(child.get());
275 comp = child_as_comp;
276 }
else if (child->IsInstance()) {
277 auto child_as_inst =
dynamic_cast<Instance *
>(child.get());
279 comp = child_as_inst->component();
281 if (comp !=
nullptr) {
299 auto new_name =
name;
300 if (new_name.empty()) {
301 new_name = comp->
name() +
"_inst";
305 new_name = comp->
name() +
"_inst" + std::to_string(i);
312 for (
const auto ¶m : inst->GetAll<
Parameter>()) {
316 auto raw_ptr = inst.get();
323 for (
const auto &g : this->
children()) {
324 if (g->name() ==
name) {
332 for (
const auto &g : this->
children()) {
340 static void ThrowErrorIfInstantiated(
const Graph &g,
bool was_instantiated,
const Object &o) {
341 if (was_instantiated) {
342 bool generate_warning =
false;
344 auto &node =
dynamic_cast<const Node &
>(o);
345 if (node.IsPort() || node.IsParameter()) {
346 generate_warning =
true;
349 auto &array =
dynamic_cast<const NodeArray &
>(o);
350 if (array.base()->IsPort() || array.base()->IsParameter()) {
351 generate_warning =
true;
354 if (generate_warning) {
355 CERATA_LOG(ERROR,
"Mutating port or parameter nodes " + o.
name() +
" of component graph " + g.
name()
356 +
" after instantiation is not allowed.");
375 return std::unique_ptr<Instance>(inst);
379 :
Graph(std::move(name), INSTANCE), component_(comp), parent_(parent) {
397 if (object->IsNode()) {
398 auto node = std::dynamic_pointer_cast<Node>(
object);
399 if (node->IsSignal()) {
400 CERATA_LOG(FATAL,
"Instance Graph cannot own Signal nodes. " + node->ToString());
404 object->SetParent(
this);
bool was_instantiated
Whether this component was instantiated.
virtual std::vector< const Component * > GetAllInstanceComponents() const
Returns all unique Components that are referred to by child Instances of this graph.
Graph * parent_
The parent of this instance.
virtual Graph & Add(const std::shared_ptr< Object > &object)
Add an object to the component.
SignalArray * sig_arr(const std::string &name) const
Shorthand to Get<SignalArray>(...)
std::vector< T * > GetAll() const
Get all objects of a specific type.
An array of signal nodes.
Graph & Add(const std::shared_ptr< Object > &object) override
Add an object to the component.
bool IsNode() const
Return true if this object is a node.
Graph * parent() const
Return the parent graph.
Instance * Instantiate(Component *comp, const std::string &name="")
Add an Instance of another Component to this component.
Component * component() const
Return the component this is an instance of.
A graph representing a hardware structure.
std::unordered_map< std::string, std::string > meta_
KV storage for metadata of tools or specific backend implementations.
Graph & Add(const std::shared_ptr< Object > &obj) override
Add a node to the component, throwing an exception if the node is a signal.
void FilterDuplicates(std::vector< T > *vec)
Filter duplicate entries from a vector.
Contains every Cerata class, function, etc...
size_t CountArrays(Node::NodeID id) const
Count nodes of a specific array type.
std::vector< std::shared_ptr< Object > > objects_
Graph objects.
static std::unique_ptr< Instance > Make(Component *component, const std::string &name, Component *parent)
Create an instance.
std::vector< Node * > GetNodesOfTypes(std::initializer_list< Node::NodeID > ids) const
Obtain all nodes which ids are in a list of Node::IDs.
std::vector< Node * > GetImplicitNodes() const
Return all graph nodes that do not explicitly belong to the graph.
NodeMap comp_to_inst
Mapping from component port and parameter nodes to instantiated nodes.
bool IsArray() const
Return true if this object is an array.
std::vector< Instance * > children() const
Returns all Instance graphs from this Component.
Component * component_
The component that this instance instantiates.
std::string name() const
Return the name of the object.
NodeID
Node type IDs with different properties.
PortArray * prt_arr(const std::string &name) const
Shorthand to Get<PortArray>(...)
Graph & Remove(Object *object) override
Remove an object from the component.
std::shared_ptr< Component > component(std::string name, const std::vector< std::shared_ptr< Object >> &objects, ComponentPool *component_pool)
Construct a Component with initial nodes.
Port * prt(const std::string &name) const
Shorthand to Get<Port>(...)
Parameter * par(const std::string &name) const
Shorthand to Get<Parameter>(...)
Graph & SetParent(Graph *parent)
Set the parent.
Graph & SetMeta(const std::string &key, std::string value)
Set metadata.
A Cerata Object on a graph.
std::vector< std::unique_ptr< Instance > > children_
Instances.
Signal * sig(const std::string &name) const
Shorthand to Get<Signal>(...)
std::vector< NodeArray * > GetArraysOfType(Node::NodeID id) const
Get all arrays of a specific type.
std::optional< Node * > FindNode(const std::string &node_name) const
Find a node with a specific name.
std::string ToStringAllOjects() const
Return a comma separated list of object names.
bool HasChild(const std::string &name) const
Return true if child graph exists on instance.
std::vector< Node * > GetNodesOfType(Node::NodeID id) const
Get all nodes of a specific type.
Component & AddChild(std::unique_ptr< Instance > child)
Add and take ownership of an Instance graph.
bool Contains(const std::vector< std::shared_ptr< T >> &list, const std::shared_ptr< T > &item)
Return true if vector contains item, false otherwise.
bool Has(const std::string &name)
Return true if object with name already exists on graph.
std::vector< Object * > objects() const
Get all objects.
void Add(const std::shared_ptr< T > &object)
Add an object to the pool, taking shared ownership. Object may not already exist in the pool.
Node * GetNode(const std::string &node_name) const
Get a Node of a specific type with a specific name.
size_t CountNodes(Node::NodeID id) const
Count nodes of a specific node type.
virtual Graph & Remove(Object *obj)
Remove an object from the component.
Instance(Component *comp, std::string name, Component *parent)
Construct an Instance of a Component, copying over all its ports and parameters.
std::shared_ptr< PortArray > port_array(const std::string &name, const std::shared_ptr< Type > &type, const std::shared_ptr< Node > &size, Port::Dir dir, const std::shared_ptr< ClockDomain > &domain)
Get a smart pointer to a new ArrayPort.
A port is a terminator node on a graph.
NodeMap inst_to_comp
Mapping for instance nodes that have been connected.
std::shared_ptr< Port > port(const std::string &name, const std::shared_ptr< Type > &type, Term::Dir dir, const std::shared_ptr< ClockDomain > &domain)
Make a new port with some name, type and direction.