Implement improved JSON attr/param encoding
authorClifford Wolf <clifford@clifford.at>
Thu, 1 Aug 2019 10:34:52 +0000 (12:34 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 1 Aug 2019 10:34:52 +0000 (12:34 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
backends/json/json.cc

index dda4dfeddafc5bbb087b41eda58a543f3f53edd1..107009ee4e80bc9d904cf75ade9f22776741fee9 100644 (file)
@@ -83,20 +83,43 @@ struct JsonWriter
                return str + " ]";
        }
 
+       void write_parameter_value(const Const &value)
+       {
+               if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0) {
+                       string str = value.decode_string();
+                       int state = 0;
+                       for (char c : str) {
+                               if (state == 0) {
+                                       if (c == '0' || c == '1' || c == 'x' || c == 'z')
+                                               state = 0;
+                                       else if (c == ' ')
+                                               state = 1;
+                                       else
+                                               state = 2;
+                               } else if (state == 1 && c != ' ')
+                                       state = 2;
+                       }
+                       if (state < 2)
+                               str += " ";
+                       f << get_string(str);
+               } else
+               if (GetSize(value) == 32 && value.is_fully_def()) {
+                       if ((value.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
+                               f << stringf("%d", value.as_int());
+                       else
+                               f << stringf("%u", value.as_int());
+               } else {
+                       f << get_string(value.as_string());
+               }
+       }
+
        void write_parameters(const dict<IdString, Const> &parameters, bool for_module=false)
        {
                bool first = true;
                for (auto &param : parameters) {
                        f << stringf("%s\n", first ? "" : ",");
                        f << stringf("        %s%s: ", for_module ? "" : "    ", get_name(param.first).c_str());
-                       if ((param.second.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0)
-                               f << get_string(param.second.decode_string());
-                       else if (GetSize(param.second.bits) > 32)
-                               f << get_string(param.second.as_string());
-                       else if ((param.second.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
-                               f << stringf("%d", param.second.as_int());
-                       else
-                               f << stringf("%u", param.second.as_int());
+                       write_parameter_value(param.second);
                        first = false;
                }
        }
@@ -342,12 +365,13 @@ struct JsonBackend : public Backend {
                log("Module and cell ports and nets can be single bit wide or vectors of multiple\n");
                log("bits. Each individual signal bit is assigned a unique integer. The <bit_vector>\n");
                log("values referenced above are vectors of this integers. Signal bits that are\n");
-               log("connected to a constant driver are denoted as string \"0\" or \"1\" instead of\n");
-               log("a number.\n");
+               log("connected to a constant driver are denoted as string \"0\", \"1\", \"x\", or\n");
+               log("\"z\" instead of a number.\n");
                log("\n");
-               log("Numeric parameter and attribute values up to 32 bits are written as decimal\n");
-               log("values. Numbers larger than that are written as string holding the binary\n");
-               log("representation of the value.\n");
+               log("Numeric 32-bit parameter and attribute values are written as decimal values.\n");
+               log("Bit verctors of different sizes, or ones containing 'x' or 'z' bits, are written\n");
+               log("as string holding the binary representation of the value. Strings are written\n");
+               log("as strings, with an appended blank in cases of strings of the form /[01xz]* */.\n");
                log("\n");
                log("For example the following Verilog code:\n");
                log("\n");