From fefe0fc0430f4f173a25e674708aa0f4f0854b31 Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Thu, 3 Nov 2016 23:18:00 +0100 Subject: Imported yosys 0.7 --- frontends/liberty/liberty.cc | 85 ++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 39 deletions(-) (limited to 'frontends/liberty/liberty.cc') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 73d927fa..4666c818 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; -- cgit v1.2.3