 |
Cerata
A library to generate structural hardware designs
|
15 #include "cerata/vhdl/declaration.h"
21 #include "cerata/node.h"
22 #include "cerata/expression.h"
23 #include "cerata/parameter.h"
24 #include "cerata/type.h"
25 #include "cerata/graph.h"
26 #include "cerata/vhdl/identifier.h"
27 #include "cerata/vhdl/vhdl_types.h"
28 #include "cerata/vhdl/vhdl.h"
32 static std::string GenerateTypeDecl(
const Type &type, std::optional<Node *> multiplier = std::nullopt) {
33 std::shared_ptr<Node> mult;
35 mult = multiplier.value()->shared_from_this();
42 return "std_logic_vector(" +
ToUpper((mult - 1)->
ToString()) +
" downto 0)";
46 auto &vec =
dynamic_cast<const Vector &
>(type);
47 auto width = vec.width().value()->shared_from_this();
49 auto expr = width->shared_from_this() - 1;
50 return "std_logic_vector(" +
ToUpper(expr->ToString()) +
" downto 0)";
52 auto expr = mult * width - 1;
53 return "std_logic_vector(" +
ToUpper(expr->ToString()) +
" downto 0)";
57 auto record =
dynamic_cast<const Record &
>(type);
79 val_str =
"\"" + val_str +
"\"";
81 l <<
" := " << val_str;
90 for (
const auto &ft : flat_types) {
92 auto port_name_prefix =
port.name();
93 l << ft.name(
NamePart(port_name_prefix,
true)) <<
" : ";
99 l << GenerateTypeDecl(*ft.type_);
111 for (
const auto &ft : flat_types) {
113 auto sig_name_prefix = sig.
name();
114 l <<
"signal " + ft.name(
NamePart(sig_name_prefix,
true)) <<
" : ";
115 if (ft.type_->meta.count(meta::FORCE_VECTOR)) {
116 l << GenerateTypeDecl(*ft.type_,
intl(1).get()) +
";";
118 l << GenerateTypeDecl(*ft.type_) +
";";
130 for (
const auto &ft : flat_types) {
133 l << ft.name(
NamePart(port_name_prefix,
true)) <<
" : ";
139 l << GenerateTypeDecl(*ft.type_,
port_array.size());
150 for (
const auto &ft : flat_types) {
152 auto port_name_prefix = sig_array.
name();
153 l <<
"signal " + ft.name(
NamePart(port_name_prefix,
true)) <<
" : ";
154 l << GenerateTypeDecl(*ft.type_, sig_array.
size()) +
";";
171 hl <<
"entity " + comp.
name() +
" is";
173 hl <<
"component " + comp.
name() +
" is";
180 if (!parameters.empty()) {
189 if (gen != parameters.back()) {
198 ret << gdh << gd << gdf;
203 if (!ports.empty() || !array_ports.empty()) {
211 for (
const auto &
port : ports) {
213 if (
port != ports.back() || !array_ports.empty()) {
221 for (
const auto &array_port : array_ports) {
223 if (array_port != array_ports.back()) {
232 ret << pdh << pd << pdf;
238 fl <<
"end component;";
Type * type() const
Return the type of the nodes in the NodeArray.
std::vector< T * > GetAll() const
Get all objects of a specific type.
An array of signal nodes.
A structure to hold multiple blocks.
Node * value() const
Return the value node.
Convenience struct to generate names in parts.
bool Is(ID type_id) const
Return true if the Type ID is type_id, false otherwise.
static Block Generate(const Parameter &par, int depth=0)
Generate a parameter declaration as VHDL generic.
std::vector< FlatType > FilterForVHDL(const std::vector< FlatType > &list)
Filter abstract types from a list of flattened types.
std::string name() const
Return the name of the object.
static Dir Reverse(Dir dir)
Return the inverse of a direction.
std::shared_ptr< Literal > intl(int64_t i)
Obtain a shared pointer to an integer literal from the default node pool.
std::string ToUpper(std::string str)
Convert string to upper-case.
std::string ToString(const std::vector< Block > &blocks)
Return a vector of blocks as a single string.
std::shared_ptr< Record > record(const std::string &name, const std::vector< std::shared_ptr< Field >> &fields)
Create a new Record type, and return a shared pointer to it.
void Flatten(std::vector< FlatType > *list, Type *type, const std::optional< FlatType > &parent, const std::string &name, bool invert, bool sep)
Flatten any Type.
virtual std::string ToString() const
Return a human-readable string of this node.
Node * size() const
Return the size node.
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.
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.
Type * type() const
Return the node Type.
Contains everything related to the VHDL back-end.