From ee2b5b7ed186414897a8a570a9e503c438803ad8 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Mon, 20 Apr 2020 16:06:53 +0100 Subject: Generate an RTLIL representation of bind constructs This code now takes the AST nodes of type AST_BIND and generates a representation in the RTLIL for them. This is a little tricky, because a binding of the form: bind baz foo_t foo_i (.arg (1 + bar)); means "make an instance of foo_t called foo_i, instantiate it inside baz and connect the port arg to the result of the expression 1+bar". Of course, 1+bar needs a cell for the addition. Where should that cell live? With this patch, the Binding structure that represents the construct is itself an AST::AstModule module. This lets us put the adder cell inside it. We'll pull the contents out and plonk them into 'baz' when we actually do the binding operation as part of the hierarchy pass. Of course, we don't want RTLIL::Binding to contain an AST::AstModule (since kernel code shouldn't depend on a frontend), so we define RTLIL::Binding as an abstract base class and put the AST-specific code into an AST::Binding subclass. This is analogous to the AST::AstModule class. --- kernel/binding.cc | 29 +++++++++++++++++++++++++++ kernel/binding.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.cc | 17 ++++++++++++++++ kernel/rtlil.h | 11 +++++++++- 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 kernel/binding.cc create mode 100644 kernel/binding.h (limited to 'kernel') diff --git a/kernel/binding.cc b/kernel/binding.cc new file mode 100644 index 000000000..621f7007b --- /dev/null +++ b/kernel/binding.cc @@ -0,0 +1,29 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "binding.h" + +YOSYS_NAMESPACE_BEGIN + +RTLIL::Binding::Binding(RTLIL::IdString target_type, + RTLIL::IdString target_name) + : target_type(target_type), target_name(target_name) +{} + +YOSYS_NAMESPACE_END diff --git a/kernel/binding.h b/kernel/binding.h new file mode 100644 index 000000000..3b64e76da --- /dev/null +++ b/kernel/binding.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef BINDING_H +#define BINDING_H + +#include "kernel/rtlil.h" + +YOSYS_NAMESPACE_BEGIN + +struct RTLIL::Binding +{ + // Represents a bind construct. + // + // The target of the binding is represented by target_type and + // target_name (see comments above the fields). + + Binding(RTLIL::IdString target_type, + RTLIL::IdString target_name); + + virtual ~Binding() {} + + // Return a string describing the binding + virtual std::string describe() const = 0; + +protected: + // May be empty. If not, it's the name of the module or interface to + // bind to. + RTLIL::IdString target_type; + + // If target_type is nonempty (the usual case), this is a hierarchical + // reference to the bind target. If target_type is empty, we have to + // wait until the hierarchy pass to figure out whether this was the name + // of a module/interface type or an instance. + RTLIL::IdString target_name; + + // An attribute name which contains an ID that's unique across binding + // instances (used to ensure we don't apply a binding twice to a module) + RTLIL::IdString attr_name; +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b414556f3..40b9b761a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/macc.h" #include "kernel/celltypes.h" +#include "kernel/binding.h" #include "frontends/verilog/verilog_frontend.h" #include "frontends/verilog/preproc.h" #include "backends/rtlil/rtlil_backend.h" @@ -573,6 +574,8 @@ RTLIL::Design::~Design() { for (auto &pr : modules_) delete pr.second; + for (auto n : bindings_) + delete n; for (auto n : verilog_packages) delete n; for (auto n : verilog_globals) @@ -636,6 +639,12 @@ void RTLIL::Design::add(RTLIL::Module *module) } } +void RTLIL::Design::add(RTLIL::Binding *binding) +{ + log_assert(binding != nullptr); + bindings_.push_back(binding); +} + RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) { if (modules_.count(name) != 0) @@ -872,6 +881,8 @@ RTLIL::Module::~Module() delete pr.second; for (auto &pr : processes) delete pr.second; + for (auto binding : bindings_) + delete binding; #ifdef WITH_PYTHON RTLIL::Module::get_all_modules()->erase(hashidx_); #endif @@ -1923,6 +1934,12 @@ void RTLIL::Module::add(RTLIL::Process *process) process->module = this; } +void RTLIL::Module::add(RTLIL::Binding *binding) +{ + log_assert(binding != nullptr); + bindings_.push_back(binding); +} + void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index dc0d5234b..50707c0ae 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -72,6 +72,7 @@ namespace RTLIL struct MemWriteAction; struct SyncRule; struct Process; + struct Binding; typedef std::pair SigSig; @@ -1033,6 +1034,8 @@ struct RTLIL::Design int refcount_modules_; dict modules_; + std::vector bindings_; + std::vector verilog_packages, verilog_globals; std::unique_ptr verilog_defines; @@ -1053,6 +1056,8 @@ struct RTLIL::Design } void add(RTLIL::Module *module); + void add(RTLIL::Binding *binding); + RTLIL::Module *addModule(RTLIL::IdString name); void remove(RTLIL::Module *module); void rename(RTLIL::Module *module, RTLIL::IdString new_name); @@ -1140,7 +1145,9 @@ public: dict wires_; dict cells_; - std::vector connections_; + + std::vector connections_; + std::vector bindings_; RTLIL::IdString name; idict avail_parameters; @@ -1207,6 +1214,8 @@ public: RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } + void add(RTLIL::Binding *binding); + // Removing wires is expensive. If you have to remove wires, remove them all at once. void remove(const pool &wires); void remove(RTLIL::Cell *cell); -- cgit v1.2.3