ast/simplify: improve enum handling.
authorwhitequark <whitequark@whitequark.org>
Tue, 14 Apr 2020 03:25:22 +0000 (03:25 +0000)
committerwhitequark <whitequark@whitequark.org>
Wed, 15 Apr 2020 14:14:50 +0000 (14:14 +0000)
Before this commit, enum values were serialized as attributes of form
  \enum_<width>_<value>
where <value> was a decimal signed integer.

This has multiple drawbacks:
  * Enums with large values would be hard to process for downstream
    tooling that cannot parse arbitrary precision decimals. (In fact
    Yosys also did not correctly process enums with large values,
    and would overflow `int`.)
  * Enum value attributes were not confined to their own namespace,
    making it harder for downstream tooling to enumerate all such
    attributes, as opposed to looking up any specific value.
  * Enum values could not include x or z, which are explicitly
    permitted in the SystemVerilog standard.

After this commit, enum values are serialized as attributes of form
  \enum_value_<value>
where <value> is a bit sequence of the appropriate width.

README.md
frontends/ast/simplify.cc

index ce7b264110386a883af32ebfe6a4d0b540d42c8d..0a81d8bb957898b2c5c0496c53277f2f4ab8778f 100644 (file)
--- a/README.md
+++ b/README.md
@@ -443,8 +443,8 @@ Verilog Attributes and non-standard features
 - The ``wiretype`` attribute is added by the verilog parser for wires of a
   typedef'd type to indicate the type identifier.
 
-- Various ``enum_{width}_{value}`` attributes are added to wires of an
-  enumerated type to give a map of possible enum items to their values.
+- Various ``enum_value_{value}`` attributes are added to wires of an enumerated type
+  to give a map of possible enum items to their values.
 
 - The ``enum_base_type`` attribute is added to enum items to indicate which
   enum they belong to (enums -- anonymous and otherwise -- are
index b87af0f8c645b2c7986b329cf1240e9ae8f8635a..5e7518f68c109c81ea3a612648366c5c2e579987 100644 (file)
@@ -907,9 +907,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                                                );
                                        }
                                        //start building attribute string
-                                       std::string enum_item_str = "\\enum_";
-                                       enum_item_str.append(std::to_string(width));
-                                       enum_item_str.append("_");
+                                       std::string enum_item_str = "\\enum_value_";
                                        //get enum item value
                                        if(enum_item->children[0]->type != AST_CONSTANT){
                                                log_error("expected const, got %s for %s (%s)\n",
@@ -917,8 +915,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                                                                  enum_item->str.c_str(), enum_node->str.c_str()
                                                                );
                                        }
-                                       int val = enum_item->children[0]->asInt(is_signed);
-                                       enum_item_str.append(std::to_string(val));
+                                       RTLIL::Const val = enum_item->children[0]->bitsAsConst(width, is_signed);
+                                       enum_item_str.append(val.as_string());
                                        //set attribute for available val to enum item name mappings
                                        attributes[enum_item_str.c_str()] = mkconst_str(enum_item->str);
                                }