Skip to content

Commit

Permalink
Merge a86e887 into 9a94ff5
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardt committed Jun 24, 2020
2 parents 9a94ff5 + a86e887 commit 2e58f32
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 56 deletions.
33 changes: 27 additions & 6 deletions include/verilogAST.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,17 +748,13 @@ class Always : public StructuralStatement {
std::variant<std::unique_ptr<Identifier>, std::unique_ptr<PosEdge>,
std::unique_ptr<NegEdge>, std::unique_ptr<Star>>>
sensitivity_list;
std::vector<std::variant<std::unique_ptr<BehavioralStatement>,
std::unique_ptr<Declaration>>>
body;
std::vector<std::unique_ptr<BehavioralStatement>> body;

Always(std::vector<
std::variant<std::unique_ptr<Identifier>, std::unique_ptr<PosEdge>,
std::unique_ptr<NegEdge>, std::unique_ptr<Star>>>
sensitivity_list,
std::vector<std::variant<std::unique_ptr<BehavioralStatement>,
std::unique_ptr<Declaration>>>
body)
std::vector<std::unique_ptr<BehavioralStatement>> body)
: body(std::move(body)) {
if (sensitivity_list.empty()) {
throw std::runtime_error(
Expand All @@ -770,6 +766,31 @@ class Always : public StructuralStatement {
~Always(){};
};

class If : public BehavioralStatement {
public:
std::unique_ptr<Expression> cond;
std::vector<std::unique_ptr<BehavioralStatement>> true_body;
// pair of cond + body for else if cases
std::vector<std::pair<std::unique_ptr<Expression>,
std::vector<std::unique_ptr<BehavioralStatement>>>>
else_ifs;
std::vector<std::unique_ptr<BehavioralStatement>> else_body;

If(std::unique_ptr<Expression> cond,
std::vector<std::unique_ptr<BehavioralStatement>> true_body,
std::vector<std::pair<std::unique_ptr<Expression>,
std::vector<std::unique_ptr<BehavioralStatement>>>>
else_ifs,
std::vector<std::unique_ptr<BehavioralStatement>> else_body)
: cond(std::move(cond)),
true_body(std::move(true_body)),
else_ifs(std::move(else_ifs)),
else_body(std::move(else_body)){};

std::string toString();
~If(){};
};

class AbstractModule : public Node {};

class Module : public AbstractModule {
Expand Down
15 changes: 15 additions & 0 deletions include/verilogAST/assign_inliner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class AssignMapBuilder : public Transformer {
std::set<std::string> &output_ports;
std::set<std::string> &input_ports;

template <typename T>
std::unique_ptr<T> process_assign(std::unique_ptr<T> node);

public:
AssignMapBuilder(
std::map<std::string, int> &assign_count,
Expand All @@ -30,13 +33,18 @@ class AssignMapBuilder : public Transformer {
virtual std::unique_ptr<Port> visit(std::unique_ptr<Port> node);
virtual std::unique_ptr<ContinuousAssign> visit(
std::unique_ptr<ContinuousAssign> node);
virtual std::unique_ptr<BlockingAssign> visit(
std::unique_ptr<BlockingAssign> node);
};

class WireReadCounter : public Transformer {
// Counts number of times a wire is read
//
std::map<std::string, int> &read_count;

template <typename T>
std::unique_ptr<T> process_assign(std::unique_ptr<T> node);

public:
WireReadCounter(std::map<std::string, int> &read_count)
: read_count(read_count){};
Expand All @@ -47,6 +55,8 @@ class WireReadCounter : public Transformer {
// Skip target of assign (not read)
virtual std::unique_ptr<ContinuousAssign> visit(
std::unique_ptr<ContinuousAssign> node);
virtual std::unique_ptr<BlockingAssign> visit(
std::unique_ptr<BlockingAssign> node);
// Skip declarations (not read)
virtual std::unique_ptr<Declaration> visit(std::unique_ptr<Declaration> node);
};
Expand Down Expand Up @@ -88,6 +98,9 @@ class AssignInliner : public Transformer {

bool can_inline(std::string key);

template <typename T>
std::unique_ptr<T> process_assign(std::unique_ptr<T> node);

public:
AssignInliner() : wire_blacklist(){};
explicit AssignInliner(std::set<std::string> wire_blacklist)
Expand All @@ -96,6 +109,8 @@ class AssignInliner : public Transformer {
virtual std::unique_ptr<Expression> visit(std::unique_ptr<Expression> node);
virtual std::unique_ptr<ContinuousAssign> visit(
std::unique_ptr<ContinuousAssign> node);
virtual std::unique_ptr<BlockingAssign> visit(
std::unique_ptr<BlockingAssign> node);
virtual std::unique_ptr<Wire> visit(std::unique_ptr<Wire> node);
virtual std::unique_ptr<Module> visit(std::unique_ptr<Module> node);
};
Expand Down
2 changes: 2 additions & 0 deletions include/verilogAST/transformer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class Transformer {
virtual std::unique_ptr<BlockComment> visit(
std::unique_ptr<BlockComment> node);

virtual std::unique_ptr<If> visit(std::unique_ptr<If> node);

virtual std::unique_ptr<InlineVerilog> visit(
std::unique_ptr<InlineVerilog> node);

Expand Down
45 changes: 37 additions & 8 deletions src/assign_inliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,22 @@ std::unique_ptr<Declaration> WireReadCounter::visit(
return node;
}

std::unique_ptr<ContinuousAssign> WireReadCounter::visit(
std::unique_ptr<ContinuousAssign> node) {
template <typename T>
std::unique_ptr<T> WireReadCounter::process_assign(std::unique_ptr<T> node) {
node->value = this->visit(std::move(node->value));
return node;
}

std::unique_ptr<ContinuousAssign> WireReadCounter::visit(
std::unique_ptr<ContinuousAssign> node) {
return this->process_assign(std::move(node));
}

std::unique_ptr<BlockingAssign> WireReadCounter::visit(
std::unique_ptr<BlockingAssign> node) {
return this->process_assign(std::move(node));
}

std::unique_ptr<Port> AssignMapBuilder::visit(std::unique_ptr<Port> node) {
std::string port_str = std::visit(
[](auto&& value) -> std::string {
Expand All @@ -57,9 +67,8 @@ std::unique_ptr<Port> AssignMapBuilder::visit(std::unique_ptr<Port> node) {
}
return node;
}

std::unique_ptr<ContinuousAssign> AssignMapBuilder::visit(
std::unique_ptr<ContinuousAssign> node) {
template <typename T>
std::unique_ptr<T> AssignMapBuilder::process_assign(std::unique_ptr<T> node) {
node = Transformer::visit(std::move(node));
std::string key =
std::visit([](auto&& value) -> std::string { return value->toString(); },
Expand All @@ -69,6 +78,16 @@ std::unique_ptr<ContinuousAssign> AssignMapBuilder::visit(
return node;
}

std::unique_ptr<BlockingAssign> AssignMapBuilder::visit(
std::unique_ptr<BlockingAssign> node) {
return this->process_assign(std::move(node));
}

std::unique_ptr<ContinuousAssign> AssignMapBuilder::visit(
std::unique_ptr<ContinuousAssign> node) {
return this->process_assign(std::move(node));
}

bool AssignInliner::can_inline(std::string key) {
if (this->wire_blacklist.count(key)) {
return false;
Expand Down Expand Up @@ -112,8 +131,8 @@ std::unique_ptr<Wire> AssignInliner::visit(std::unique_ptr<Wire> node) {
return node;
}

std::unique_ptr<ContinuousAssign> AssignInliner::visit(
std::unique_ptr<ContinuousAssign> node) {
template <typename T>
std::unique_ptr<T> AssignInliner::process_assign(std::unique_ptr<T> node) {
node->value = this->visit(std::move(node->value));
std::string key =
std::visit([](auto&& value) -> std::string { return value->toString(); },
Expand All @@ -131,11 +150,21 @@ std::unique_ptr<ContinuousAssign> AssignInliner::visit(
},
node->target);
if (remove) {
return std::unique_ptr<ContinuousAssign>{};
return std::unique_ptr<T>{};
}
return node;
}

std::unique_ptr<ContinuousAssign> AssignInliner::visit(
std::unique_ptr<ContinuousAssign> node) {
return this->process_assign(std::move(node));
}

std::unique_ptr<BlockingAssign> AssignInliner::visit(
std::unique_ptr<BlockingAssign> node) {
return this->process_assign(std::move(node));
}

std::vector<std::variant<std::unique_ptr<StructuralStatement>,
std::unique_ptr<Declaration>>>
AssignInliner::do_inline(
Expand Down
45 changes: 38 additions & 7 deletions src/transformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,12 @@ std::unique_ptr<Identifier> Transformer::visit(
return node;
}

std::unique_ptr<Cast> Transformer::visit(
std::unique_ptr<Cast> node) {
std::unique_ptr<Cast> Transformer::visit(std::unique_ptr<Cast> node) {
node->expr = this->visit(std::move(node->expr));
return node;
}

std::unique_ptr<Attribute> Transformer::visit(
std::unique_ptr<Attribute> node) {
std::unique_ptr<Attribute> Transformer::visit(std::unique_ptr<Attribute> node) {
node->value = this->visit(std::move(node->value));
return node;
}
Expand Down Expand Up @@ -199,6 +197,37 @@ std::unique_ptr<BlockComment> Transformer::visit(
return node;
}

std::unique_ptr<If> Transformer::visit(std::unique_ptr<If> node) {
node->cond = this->visit(std::move(node->cond));

std::vector<std::unique_ptr<BehavioralStatement>> new_true_body;
for (auto&& item : node->true_body) {
new_true_body.push_back(this->visit(std::move(item)));
}
node->true_body = std::move(new_true_body);

std::vector<std::pair<std::unique_ptr<Expression>,
std::vector<std::unique_ptr<BehavioralStatement>>>>
new_else_ifs;
for (auto&& item : node->else_ifs) {
std::vector<std::unique_ptr<BehavioralStatement>> new_body;
for (auto&& inner_statement : item.second) {
new_body.push_back(this->visit(std::move(inner_statement)));
}
new_else_ifs.push_back(
{this->visit(std::move(item.first)), std::move(new_body)});
}
node->else_ifs = std::move(new_else_ifs);

std::vector<std::unique_ptr<BehavioralStatement>> new_else_body;
for (auto&& item : node->else_body) {
new_else_body.push_back(this->visit(std::move(item)));
}
node->else_body = std::move(new_else_body);

return node;
}

std::unique_ptr<InlineVerilog> Transformer::visit(
std::unique_ptr<InlineVerilog> node) {
return node;
Expand Down Expand Up @@ -269,6 +298,10 @@ std::unique_ptr<BehavioralStatement> Transformer::visit(
node.release();
return this->visit(std::unique_ptr<BlockComment>(ptr));
}
if (auto ptr = dynamic_cast<If*>(node.get())) {
node.release();
return this->visit(std::unique_ptr<If>(ptr));
}
throw std::runtime_error("Unreachable"); // LCOV_EXCL_LINE
return node; // LCOV_EXCL_LINE
}
Expand Down Expand Up @@ -309,9 +342,7 @@ std::unique_ptr<Always> Transformer::visit(std::unique_ptr<Always> node) {
new_sensitivity_list.push_back(this->visit(std::move(item)));
}
node->sensitivity_list = std::move(new_sensitivity_list);
std::vector<std::variant<std::unique_ptr<BehavioralStatement>,
std::unique_ptr<Declaration>>>
new_body;
std::vector<std::unique_ptr<BehavioralStatement>> new_body;
for (auto&& item : node->body) {
new_body.push_back(this->visit(std::move(item)));
}
Expand Down
49 changes: 45 additions & 4 deletions src/verilogAST.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "verilogAST.hpp"

#include <regex>
#include <sstream>
#include <unordered_set>

template <typename... Ts>
Expand Down Expand Up @@ -127,7 +128,7 @@ std::string Identifier::toString() {
}

std::string Cast::toString() {
return std::to_string(this->width) + "'(" + this->expr->toString() + ")";
return std::to_string(this->width) + "'(" + this->expr->toString() + ")";
}

std::string Attribute::toString() {
Expand Down Expand Up @@ -417,15 +418,55 @@ std::string Always::toString() {

// emit body
for (auto &statement : body) {
always_str += variant_to_string<std::unique_ptr<BehavioralStatement>,
std::unique_ptr<Declaration>>(statement) +
"\n";
always_str += statement->toString() + "\n";
}

always_str += "end\n";
return always_str;
}

std::string add_tab(std::string block) {
// Indents each line by four spaces, adds an extra newline at the end
std::istringstream block_stream(block);
std::string new_block;
while (!block_stream.eof()) {
std::string line;
std::getline(block_stream, line);
new_block += " " + line + "\n";
}
return new_block;
}

std::string If::toString() {
std::string if_str = "";
if_str += "if (";
if_str += this->cond->toString();
if_str += ") begin\n";

for (auto &statement : this->true_body) {
if_str += add_tab(statement->toString());
}

if_str += "end";

for (auto &entry : this->else_ifs) {
if_str += " else if (" + entry.first->toString() + ") begin\n";
for (auto &statement : entry.second) {
if_str += add_tab(statement->toString());
}
if_str += "end";
}

if (this->else_body.size()) {
if_str += " else begin\n";
for (auto &statement : else_body) {
if_str += add_tab(statement->toString());
}
if_str += "end";
}
return if_str;
}

std::string File::toString() {
std::string file_str = "";

Expand Down
Loading

0 comments on commit 2e58f32

Please sign in to comment.