Fix handling of some formal cells in btor back-end
[yosys.git] / backends / json / json.cc
index 5c67cb857e34aae90a49222398a3f345df459d84..42eedc606273c15ea477b7c6269b6dff00af0515 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  yosys -- Yosys Open SYnthesis Suite
  *
- *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
  *
  *  Permission to use, copy, modify, and/or distribute this software for any
  *  purpose with or without fee is hereby granted, provided that the above
@@ -52,8 +52,23 @@ struct JsonWriter
                string newstr = "\"";
                for (char c : str) {
                        if (c == '\\')
+                               newstr += "\\\\";
+                       else if (c == '"')
+                               newstr += "\\\"";
+                       else if (c == '\b')
+                               newstr += "\\b";
+                       else if (c == '\f')
+                               newstr += "\\f";
+                       else if (c == '\n')
+                               newstr += "\\n";
+                       else if (c == '\r')
+                               newstr += "\\r";
+                       else if (c == '\t')
+                               newstr += "\\t";
+                       else if (c < 0x20)
+                               newstr += stringf("\\u%04X", c);
+                       else
                                newstr += c;
-                       newstr += c;
                }
                return newstr + "\"";
        }
@@ -104,7 +119,7 @@ struct JsonWriter
                        if (state < 2)
                                str += " ";
                        f << get_string(str);
-               } else if (compat_int_mode && GetSize(value) == 32 && value.is_fully_def()) {
+               } else if (compat_int_mode && GetSize(value) <= 32 && value.is_fully_def()) {
                        if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
                                f << stringf("%d", value.as_int());
                        else
@@ -135,12 +150,22 @@ struct JsonWriter
                // reserve 0 and 1 to avoid confusion with "0" and "1"
                sigidcounter = 2;
 
+               if (module->has_processes()) {
+                       log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", log_id(module));
+               }
+
                f << stringf("    %s: {\n", get_name(module->name).c_str());
 
                f << stringf("      \"attributes\": {");
                write_parameters(module->attributes, /*for_module=*/true);
                f << stringf("\n      },\n");
 
+               if (module->parameter_default_values.size()) {
+                       f << stringf("      \"parameter_default_values\": {");
+                       write_parameters(module->parameter_default_values, /*for_module=*/true);
+                       f << stringf("\n      },\n");
+               }
+
                f << stringf("      \"ports\": {");
                bool first = true;
                for (auto n : module->ports) {
@@ -154,6 +179,8 @@ struct JsonWriter
                                f << stringf("          \"offset\": %d,\n", w->start_offset);
                        if (w->upto)
                                f << stringf("          \"upto\": 1,\n");
+                       if (w->is_signed)
+                               f << stringf("          \"signed\": %d,\n", w->is_signed);
                        f << stringf("          \"bits\": %s\n", get_bits(w).c_str());
                        f << stringf("        }");
                        first = false;
@@ -208,6 +235,27 @@ struct JsonWriter
                }
                f << stringf("\n      },\n");
 
+               if (!module->memories.empty()) {
+                       f << stringf("      \"memories\": {");
+                       first = true;
+                       for (auto &it : module->memories) {
+                               if (use_selection && !module->selected(it.second))
+                                       continue;
+                               f << stringf("%s\n", first ? "" : ",");
+                               f << stringf("        %s: {\n", get_name(it.second->name).c_str());
+                               f << stringf("          \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0");
+                               f << stringf("          \"attributes\": {");
+                               write_parameters(it.second->attributes);
+                               f << stringf("\n          },\n");
+                               f << stringf("          \"width\": %d,\n", it.second->width);
+                               f << stringf("          \"start_offset\": %d,\n", it.second->start_offset);
+                               f << stringf("          \"size\": %d\n", it.second->size);
+                               f << stringf("        }");
+                               first = false;
+                       }
+                       f << stringf("\n      },\n");
+               }
+
                f << stringf("      \"netnames\": {");
                first = true;
                for (auto w : module->wires()) {
@@ -221,6 +269,8 @@ struct JsonWriter
                                f << stringf("          \"offset\": %d,\n", w->start_offset);
                        if (w->upto)
                                f << stringf("          \"upto\": 1,\n");
+                       if (w->is_signed)
+                               f << stringf("          \"signed\": %d,\n", w->is_signed);
                        f << stringf("          \"attributes\": {");
                        write_parameters(w->attributes);
                        f << stringf("\n          }\n");
@@ -284,7 +334,7 @@ struct JsonWriter
 
 struct JsonBackend : public Backend {
        JsonBackend() : Backend("json", "write design to a JSON file") { }
-       void help() YS_OVERRIDE
+       void help() override
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
@@ -296,15 +346,24 @@ struct JsonBackend : public Backend {
                log("        include AIG models for the different gate types\n");
                log("\n");
                log("    -compat-int\n");
-               log("        emit 32-bit fully-defined parameter values directly\n");
+               log("        emit 32-bit or smaller fully-defined parameter values directly\n");
                log("        as JSON numbers (for compatibility with old parsers)\n");
                log("\n");
                log("\n");
                log("The general syntax of the JSON output created by this command is as follows:\n");
                log("\n");
                log("    {\n");
+               log("      \"creator\": \"Yosys <version info>\",\n");
                log("      \"modules\": {\n");
                log("        <module_name>: {\n");
+               log("          \"attributes\": {\n");
+               log("            <attribute_name>: <attribute_value>,\n");
+               log("            ...\n");
+               log("          },\n");
+               log("          \"parameter_default_values\": {\n");
+               log("            <parameter_name>: <parameter_value>,\n");
+               log("            ...\n");
+               log("          },\n");
                log("          \"ports\": {\n");
                log("            <port_name>: <port_details>,\n");
                log("            ...\n");
@@ -313,6 +372,10 @@ struct JsonBackend : public Backend {
                log("            <cell_name>: <cell_details>,\n");
                log("            ...\n");
                log("          },\n");
+               log("          \"memories\": {\n");
+               log("            <memory_name>: <memory_details>,\n");
+               log("            ...\n");
+               log("          },\n");
                log("          \"netnames\": {\n");
                log("            <net_name>: <net_details>,\n");
                log("            ...\n");
@@ -329,13 +392,19 @@ struct JsonBackend : public Backend {
                log("    {\n");
                log("      \"direction\": <\"input\" | \"output\" | \"inout\">,\n");
                log("      \"bits\": <bit_vector>\n");
+               log("      \"offset\": <the lowest bit index in use, if non-0>\n");
+               log("      \"upto\": <1 if the port bit indexing is MSB-first>\n");
                log("    }\n");
                log("\n");
+               log("The \"offset\" and \"upto\" fields are skipped if their value would be 0.");
+               log("They don't affect connection semantics, and are only used to preserve original");
+               log("HDL bit indexing.");
                log("And <cell_details> is:\n");
                log("\n");
                log("    {\n");
                log("      \"hide_name\": <1 | 0>,\n");
                log("      \"type\": <cell_type>,\n");
+               log("      \"model\": <AIG model name, if -aig option used>,\n");
                log("      \"parameters\": {\n");
                log("        <parameter_name>: <parameter_value>,\n");
                log("        ...\n");
@@ -354,11 +423,26 @@ struct JsonBackend : public Backend {
                log("      },\n");
                log("    }\n");
                log("\n");
+               log("And <memory_details> is:\n");
+               log("\n");
+               log("    {\n");
+               log("      \"hide_name\": <1 | 0>,\n");
+               log("      \"attributes\": {\n");
+               log("        <attribute_name>: <attribute_value>,\n");
+               log("        ...\n");
+               log("      },\n");
+               log("      \"width\": <memory width>\n");
+               log("      \"start_offset\": <the lowest valid memory address>\n");
+               log("      \"size\": <memory size>\n");
+               log("    }\n");
+               log("\n");
                log("And <net_details> is:\n");
                log("\n");
                log("    {\n");
                log("      \"hide_name\": <1 | 0>,\n");
                log("      \"bits\": <bit_vector>\n");
+               log("      \"offset\": <the lowest bit index in use, if non-0>\n");
+               log("      \"upto\": <1 if the port bit indexing is MSB-first>\n");
                log("    }\n");
                log("\n");
                log("The \"hide_name\" fields are set to 1 when the name of this cell or net is\n");
@@ -386,9 +470,15 @@ struct JsonBackend : public Backend {
                log("\n");
                log("Translates to the following JSON output:\n");
                log("\n");
+
                log("    {\n");
+               log("      \"creator\": \"Yosys 0.9+2406 (git sha1 fb1168d8, clang 9.0.1 -fPIC -Os)\",\n");
                log("      \"modules\": {\n");
                log("        \"test\": {\n");
+               log("          \"attributes\": {\n");
+               log("            \"cells_not_processed\": \"00000000000000000000000000000001\",\n");
+               log("            \"src\": \"test.v:1.1-4.10\"\n");
+               log("          },\n");
                log("          \"ports\": {\n");
                log("            \"x\": {\n");
                log("              \"direction\": \"input\",\n");
@@ -404,33 +494,34 @@ struct JsonBackend : public Backend {
                log("              \"hide_name\": 0,\n");
                log("              \"type\": \"foo\",\n");
                log("              \"parameters\": {\n");
-               log("                \"Q\": 1337,\n");
-               log("                \"P\": 42\n");
+               log("                \"P\": \"00000000000000000000000000101010\",\n");
+               log("                \"Q\": \"00000000000000000000010100111001\"\n");
                log("              },\n");
                log("              \"attributes\": {\n");
-               log("                \"keep\": 1,\n");
-               log("                \"src\": \"test.v:2\"\n");
+               log("                \"keep\": \"00000000000000000000000000000001\",\n");
+               log("                \"module_not_derived\": \"00000000000000000000000000000001\",\n");
+               log("                \"src\": \"test.v:3.1-3.55\"\n");
                log("              },\n");
                log("              \"connections\": {\n");
-               log("                \"C\": [ 2, 2, 2, 2, \"0\", \"1\", \"0\", \"1\" ],\n");
+               log("                \"A\": [ 3, 2 ],\n");
                log("                \"B\": [ 2, 3 ],\n");
-               log("                \"A\": [ 3, 2 ]\n");
+               log("                \"C\": [ 2, 2, 2, 2, \"0\", \"1\", \"0\", \"1\" ]\n");
                log("              }\n");
                log("            }\n");
                log("          },\n");
                log("          \"netnames\": {\n");
-               log("            \"y\": {\n");
+               log("            \"x\": {\n");
                log("              \"hide_name\": 0,\n");
-               log("              \"bits\": [ 3 ],\n");
+               log("              \"bits\": [ 2 ],\n");
                log("              \"attributes\": {\n");
-               log("                \"src\": \"test.v:1\"\n");
+               log("                \"src\": \"test.v:1.19-1.20\"\n");
                log("              }\n");
                log("            },\n");
-               log("            \"x\": {\n");
+               log("            \"y\": {\n");
                log("              \"hide_name\": 0,\n");
-               log("              \"bits\": [ 2 ],\n");
+               log("              \"bits\": [ 3 ],\n");
                log("              \"attributes\": {\n");
-               log("                \"src\": \"test.v:1\"\n");
+               log("                \"src\": \"test.v:1.22-1.23\"\n");
                log("              }\n");
                log("            }\n");
                log("          }\n");
@@ -496,7 +587,7 @@ struct JsonBackend : public Backend {
                log("format. A program processing this format must ignore all unknown fields.\n");
                log("\n");
        }
-       void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
        {
                bool aig_mode = false;
                bool compat_int_mode = false;
@@ -525,7 +616,7 @@ struct JsonBackend : public Backend {
 
 struct JsonPass : public Pass {
        JsonPass() : Pass("json", "write design in JSON format") { }
-       void help() YS_OVERRIDE
+       void help() override
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
@@ -540,13 +631,13 @@ struct JsonPass : public Pass {
                log("        also include AIG models for the different gate types\n");
                log("\n");
                log("    -compat-int\n");
-               log("        emit 32-bit fully-defined parameter values directly\n");
+               log("        emit 32-bit or smaller fully-defined parameter values directly\n");
                log("        as JSON numbers (for compatibility with old parsers)\n");
                log("\n");
                log("See 'help write_json' for a description of the JSON format used.\n");
                log("\n");
        }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override
        {
                std::string filename;
                bool aig_mode = false;