mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1241 from YosysHQ/clifford/jsonfix
Improved JSON attr/param encoding
This commit is contained in:
commit
dee8f61781
|
@ -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> ¶meters, bool for_module=false)
|
||||
{
|
||||
bool first = true;
|
||||
for (auto ¶m : 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");
|
||||
|
|
|
@ -25,7 +25,7 @@ struct JsonNode
|
|||
{
|
||||
char type; // S=String, N=Number, A=Array, D=Dict
|
||||
string data_string;
|
||||
int data_number;
|
||||
int64_t data_number;
|
||||
vector<JsonNode*> data_array;
|
||||
dict<string, JsonNode*> data_dict;
|
||||
vector<string> data_dict_keys;
|
||||
|
@ -206,6 +206,38 @@ struct JsonNode
|
|||
}
|
||||
};
|
||||
|
||||
Const json_parse_attr_param_value(JsonNode *node)
|
||||
{
|
||||
Const value;
|
||||
|
||||
if (node->type == 'S') {
|
||||
string &s = node->data_string;
|
||||
size_t cursor = s.find_first_not_of("01xz");
|
||||
if (cursor == string::npos) {
|
||||
value = Const::from_string(s);
|
||||
} else if (s.find_first_not_of(' ', cursor) == string::npos) {
|
||||
value = Const(s.substr(0, GetSize(s)-1));
|
||||
} else {
|
||||
value = Const(s);
|
||||
}
|
||||
} else
|
||||
if (node->type == 'N') {
|
||||
value = Const(node->data_number, 32);
|
||||
if (node->data_number < 0)
|
||||
value.flags |= RTLIL::CONST_FLAG_SIGNED;
|
||||
} else
|
||||
if (node->type == 'A') {
|
||||
log_error("JSON attribute or parameter value is an array.\n");
|
||||
} else
|
||||
if (node->type == 'D') {
|
||||
log_error("JSON attribute or parameter value is a dict.\n");
|
||||
} else {
|
||||
log_abort();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void json_parse_attr_param(dict<IdString, Const> &results, JsonNode *node)
|
||||
{
|
||||
if (node->type != 'D')
|
||||
|
@ -214,28 +246,7 @@ void json_parse_attr_param(dict<IdString, Const> &results, JsonNode *node)
|
|||
for (auto it : node->data_dict)
|
||||
{
|
||||
IdString key = RTLIL::escape_id(it.first.c_str());
|
||||
JsonNode *value_node = it.second;
|
||||
Const value;
|
||||
|
||||
if (value_node->type == 'S') {
|
||||
string &s = value_node->data_string;
|
||||
if (s.find_first_not_of("01xz") == string::npos)
|
||||
value = Const::from_string(s);
|
||||
else
|
||||
value = Const(s);
|
||||
} else
|
||||
if (value_node->type == 'N') {
|
||||
value = Const(value_node->data_number, 32);
|
||||
} else
|
||||
if (value_node->type == 'A') {
|
||||
log_error("JSON attribute or parameter value is an array.\n");
|
||||
} else
|
||||
if (value_node->type == 'D') {
|
||||
log_error("JSON attribute or parameter value is a dict.\n");
|
||||
} else {
|
||||
log_abort();
|
||||
}
|
||||
|
||||
Const value = json_parse_attr_param_value(it.second);
|
||||
results[key] = value;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue