From 8f5bf6de32bcc478312d8f5410826b4894ebadba Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 23 Sep 2016 13:53:23 +0200 Subject: [PATCH] Added liberty parser support for types within cell decls --- frontends/liberty/liberty.cc | 85 +++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 73d927fab..4666c818c 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -401,6 +401,47 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) cell->setPort("\\E", enable_sig); } +void parse_type_map(std::map> &type_map, LibertyAst *ast) +{ + for (auto type_node : ast->children) + { + if (type_node->id != "type" || type_node->args.size() != 1) + continue; + + std::string type_name = type_node->args.at(0); + int bit_width = -1, bit_from = -1, bit_to = -1; + bool upto = false; + + for (auto child : type_node->children) + { + if (child->id == "base_type" && child->value != "array") + goto next_type; + + if (child->id == "data_type" && child->value != "bit") + goto next_type; + + if (child->id == "bit_width") + bit_width = atoi(child->value.c_str()); + + if (child->id == "bit_from") + bit_from = atoi(child->value.c_str()); + + if (child->id == "bit_to") + bit_to = atoi(child->value.c_str()); + + if (child->id == "downto" && (child->value == "0" || child->value == "false" || child->value == "FALSE")) + upto = true; + } + + if (bit_width != (std::max(bit_from, bit_to) - std::min(bit_from, bit_to) + 1)) + log_error("Incompatible array type '%s': bit_width=%d, bit_from=%d, bit_to=%d.\n", + type_name.c_str(), bit_width, bit_from, bit_to); + + type_map[type_name] = std::tuple(bit_width, std::min(bit_from, bit_to), upto); + next_type:; + } +} + struct LibertyFrontend : public Frontend { LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { } virtual void help() @@ -469,45 +510,8 @@ struct LibertyFrontend : public Frontend { LibertyParser parser(*f); int cell_count = 0; - std::map> type_map; - - for (auto type_node : parser.ast->children) - { - if (type_node->id != "type" || type_node->args.size() != 1) - continue; - - std::string type_name = type_node->args.at(0); - int bit_width = -1, bit_from = -1, bit_to = -1; - bool upto = false; - - for (auto child : type_node->children) - { - if (child->id == "base_type" && child->value != "array") - goto next_type; - - if (child->id == "data_type" && child->value != "bit") - goto next_type; - - if (child->id == "bit_width") - bit_width = atoi(child->value.c_str()); - - if (child->id == "bit_from") - bit_from = atoi(child->value.c_str()); - - if (child->id == "bit_to") - bit_to = atoi(child->value.c_str()); - - if (child->id == "downto" && (child->value == "0" || child->value == "false" || child->value == "FALSE")) - upto = true; - } - - if (bit_width != (std::max(bit_from, bit_to) - std::min(bit_from, bit_to) + 1)) - log_error("Incompatible array type '%s': bit_width=%d, bit_from=%d, bit_to=%d.\n", - type_name.c_str(), bit_width, bit_from, bit_to); - - type_map[type_name] = std::tuple(bit_width, std::min(bit_from, bit_to), upto); - next_type:; - } + std::map> global_type_map; + parse_type_map(global_type_map, parser.ast); for (auto cell : parser.ast->children) { @@ -524,6 +528,9 @@ struct LibertyFrontend : public Frontend { // log("Processing cell type %s.\n", RTLIL::unescape_id(cell_name).c_str()); + std::map> type_map = global_type_map; + parse_type_map(type_map, cell); + RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; -- 2.30.2