Skip to content

Commit

Permalink
Add else if logic
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardt committed Jun 4, 2020
1 parent 187e5fa commit bddf270
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 14 deletions.
14 changes: 11 additions & 3 deletions include/verilogAST.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,14 +774,22 @@ class If : public BehavioralStatement {
public:
std::unique_ptr<Expression> cond;
std::vector<std::unique_ptr<BehavioralStatement>> true_body;
std::vector<std::unique_ptr<BehavioralStatement>> false_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::unique_ptr<BehavioralStatement>> false_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)),
false_body(std::move(false_body)){};
else_ifs(std::move(else_ifs)),
else_body(std::move(else_body)){};

std::string toString();
~If(){};
Expand Down
23 changes: 18 additions & 5 deletions src/transformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,24 @@ std::unique_ptr<If> Transformer::visit(std::unique_ptr<If> node) {
}
node->true_body = std::move(new_true_body);

std::vector<std::unique_ptr<BehavioralStatement>> new_false_body;
for (auto&& item : node->false_body) {
new_false_body.push_back(this->visit(std::move(item)));
}
node->false_body = std::move(new_false_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;
}
Expand Down
13 changes: 11 additions & 2 deletions src/verilogAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,18 @@ std::string If::toString() {
}

if_str += "end";
if (this->false_body.size()) {

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 : false_body) {
for (auto &statement : else_body) {
if_str += add_tab(statement->toString());
}
if_str += "end";
Expand Down
8 changes: 8 additions & 0 deletions tests/basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ TEST(BasicTests, TestAlways) {
"$display(\"b=%d, c=%d\", b, c);\n"
"if (b) begin\n"
" e = f;\n"
"end else if (x0) begin\n"
" e = g0;\n"
"end else if (x1) begin\n"
" e = g1;\n"
"end else begin\n"
" e = g;\n"
"end\n"
Expand All @@ -467,6 +471,10 @@ TEST(BasicTests, TestAlwaysStar) {
"$display(\"b=%d, c=%d\", b, c);\n"
"if (b) begin\n"
" e = f;\n"
"end else if (x0) begin\n"
" e = g0;\n"
"end else if (x1) begin\n"
" e = g1;\n"
"end else begin\n"
" e = g;\n"
"end\n"
Expand Down
23 changes: 19 additions & 4 deletions tests/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,28 @@ make_simple_always_body() {
std::make_unique<vAST::Identifier>("e"),
std::make_unique<vAST::Identifier>("f")));

std::vector<std::unique_ptr<vAST::BehavioralStatement>> false_body;
false_body.push_back(std::make_unique<vAST::BlockingAssign>(
std::vector<
std::pair<std::unique_ptr<vAST::Expression>,
std::vector<std::unique_ptr<vAST::BehavioralStatement>>>>
else_ifs;
for (int i = 0; i < 2; i++) {
std::unique_ptr<vAST::Expression> cond =
vAST::make_id("x" + std::to_string(i));
std::vector<std::unique_ptr<vAST::BehavioralStatement>> body;
body.push_back(std::make_unique<vAST::BlockingAssign>(
std::make_unique<vAST::Identifier>("e"),
std::make_unique<vAST::Identifier>("g" + std::to_string(i))));
else_ifs.push_back({std::move(cond), std::move(body)});
}

std::vector<std::unique_ptr<vAST::BehavioralStatement>> else_body;
else_body.push_back(std::make_unique<vAST::BlockingAssign>(
std::make_unique<vAST::Identifier>("e"),
std::make_unique<vAST::Identifier>("g")));

body.push_back(std::make_unique<vAST::If>(
vAST::make_id("b"), std::move(true_body), std::move(false_body)));
body.push_back(
std::make_unique<vAST::If>(vAST::make_id("b"), std::move(true_body),
std::move(else_ifs), std::move(else_body)));

return body;
}
8 changes: 8 additions & 0 deletions tests/transformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ TEST(TransformerTests, TestAlways) {
"$display(\"b=%d, c=%d\", y, c);\n"
"if (y) begin\n"
" w = f;\n"
"end else if (x0) begin\n"
" w = g0;\n"
"end else if (x1) begin\n"
" w = g1;\n"
"end else begin\n"
" w = g;\n"
"end\n"
Expand Down Expand Up @@ -218,6 +222,10 @@ TEST(TransformerTests, TestModule) {
"$display(\"b=%d, c=%d\", b, g);\n"
"if (b) begin\n"
" e = f;\n"
"end else if (x0) begin\n"
" e = g0;\n"
"end else if (x1) begin\n"
" e = g1;\n"
"end else begin\n"
" e = g;\n"
"end\n"
Expand Down

0 comments on commit bddf270

Please sign in to comment.