ast: Use better parameter serialization for paramod names.
authorMarcelina Kościelnicka <mwk@0x04.net>
Wed, 17 Mar 2021 17:30:49 +0000 (18:30 +0100)
committerMarcelina Kościelnicka <mwk@0x04.net>
Wed, 17 Mar 2021 23:52:00 +0000 (00:52 +0100)
Calling log_signal is problematic for several reasons:

- with recent changes, empty string is serialized as { }, which violates
  the "no spaces in IdString" rule
- the type (plain / real / signed / string) is dropped, wrongly conflating
  functionally different values and potentially introducing a subtle
  elaboration bug

Instead, use a custom simple serialization scheme.

frontends/ast/ast.cc
tests/arch/xilinx/abc9_dff.ys

index 7aa391c93ac2c1ee094da9ded72d860df680f2b1..84a4de41c7a634c8d16e55f61ea00790934c8406 100644 (file)
@@ -1575,6 +1575,29 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
        return modname;
 }
 
+static std::string serialize_param_value(const RTLIL::Const &val) {
+       std::string res;
+       if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING)
+               res.push_back('t');
+       if (val.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED)
+               res.push_back('s');
+       if (val.flags & RTLIL::ConstFlags::CONST_FLAG_REAL)
+               res.push_back('r');
+       res += stringf("%d", GetSize(val));
+       res.push_back('\'');
+       for (int i = GetSize(val) - 1; i >= 0; i--) {
+               switch (val.bits[i]) {
+                       case RTLIL::State::S0: res.push_back('0'); break;
+                       case RTLIL::State::S1: res.push_back('1'); break;
+                       case RTLIL::State::Sx: res.push_back('x'); break;
+                       case RTLIL::State::Sz: res.push_back('z'); break;
+                       case RTLIL::State::Sa: res.push_back('?'); break;
+                       case RTLIL::State::Sm: res.push_back('m'); break;
+               }
+       }
+       return res;
+}
+
 // create a new parametric module (when needed) and return the name of the generated module
 std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet)
 {
@@ -1594,14 +1617,14 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id
                if (it != parameters.end()) {
                        if (!quiet)
                                log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second));
-                       para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second));
+                       para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str());
                        continue;
                }
                it = parameters.find(stringf("$%d", para_counter));
                if (it != parameters.end()) {
                        if (!quiet)
                                log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second));
-                       para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second));
+                       para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str());
                        continue;
                }
        }
index 210e87477ce1270a9c10124ba4957cae2caec1be..0ba3901f703add7031c7736ebec55376f62e807e 100644 (file)
@@ -50,10 +50,10 @@ FDCE_1 /*#(.INIT(1))*/ fd7(.C(C), .CE(1'b0), .D(D), .CLR(1'b0), .Q(Q[6]));
 FDPE_1 #(.INIT(1)) fd8(.C(C), .CE(1'b0), .D(D), .PRE(1'b0), .Q(Q[7]));
 endmodule
 EOT
-logger -expect warning "Whitebox '\$paramod\\FDRE\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
-logger -expect warning "Whitebox '\$paramod\\FDRE_1\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
+logger -expect warning "Whitebox '\$paramod\\FDRE\\INIT=.*1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
+logger -expect warning "Whitebox '\$paramod\\FDRE_1\\INIT=.*1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
 logger -expect warning "Whitebox 'FDSE' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
-logger -expect warning "Whitebox '\$paramod\\FDSE_1\\INIT=1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
+logger -expect warning "Whitebox '\$paramod\\FDSE_1\\INIT=.*1' with \(\* abc9_flop \*\) contains a \$dff cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox\." 1
 equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
 design -load postopt
 select -assert-count 8 t:FD*