Improve write_verilog specify support

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2019-05-04 08:46:24 +02:00
parent e2fb8ebe86
commit 87426f5a06
3 changed files with 75 additions and 16 deletions

View File

@ -183,8 +183,9 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string &reg_name)
return true;
}
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false, bool escape_comment = false)
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool escape_comment = false)
{
bool set_signed = (data.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
if (width < 0)
width = data.bits.size() - offset;
if (width == 0) {
@ -275,7 +276,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
}
}
} else {
f << stringf("\"");
if ((data.flags & RTLIL::CONST_FLAG_REAL) == 0)
f << stringf("\"");
std::string str = data.decode_string();
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '\n')
@ -293,7 +295,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
else
f << str[i];
}
f << stringf("\"");
if ((data.flags & RTLIL::CONST_FLAG_REAL) == 0)
f << stringf("\"");
}
}
@ -373,7 +376,7 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString,
else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
f << stringf(" 1 ");
else
dump_const(f, it->second, -1, 0, false, false, attr2comment);
dump_const(f, it->second, -1, 0, false, attr2comment);
f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
}
}
@ -1287,13 +1290,68 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
dump_sigspec(f, cell->getPort("\\DST"));
}
f << stringf(") = (%d:%d:%d, %d:%d:%d);\n",
cell->getParam("\\T_RISE_MIN").as_int(),
cell->getParam("\\T_RISE_TYP").as_int(),
cell->getParam("\\T_RISE_MAX").as_int(),
cell->getParam("\\T_FALL_MIN").as_int(),
cell->getParam("\\T_FALL_TYP").as_int(),
cell->getParam("\\T_FALL_MAX").as_int());
bool bak_decimal = decimal;
decimal = 1;
f << ") = (";
dump_const(f, cell->getParam("\\T_RISE_MIN"));
f << ":";
dump_const(f, cell->getParam("\\T_RISE_TYP"));
f << ":";
dump_const(f, cell->getParam("\\T_RISE_MAX"));
f << ", ";
dump_const(f, cell->getParam("\\T_FALL_MIN"));
f << ":";
dump_const(f, cell->getParam("\\T_FALL_TYP"));
f << ":";
dump_const(f, cell->getParam("\\T_FALL_MAX"));
f << ");\n";
decimal = bak_decimal;
f << stringf("%s" "endspecify\n", indent.c_str());
return true;
}
if (cell->type == "$specrule")
{
f << stringf("%s" "specify\n%s ", indent.c_str(), indent.c_str());
string spec_type = cell->getParam("\\TYPE").decode_string();
f << stringf("%s(", spec_type.c_str());
if (cell->getParam("\\SRC_PEN").as_bool())
f << (cell->getParam("\\SRC_POL").as_bool() ? "posedge ": "negedge ");
dump_sigspec(f, cell->getPort("\\SRC"));
if (cell->getPort("\\SRC_EN") != State::S1) {
f << " &&& ";
dump_sigspec(f, cell->getPort("\\SRC_EN"));
}
f << ", ";
if (cell->getParam("\\DST_PEN").as_bool())
f << (cell->getParam("\\DST_POL").as_bool() ? "posedge ": "negedge ");
dump_sigspec(f, cell->getPort("\\DST"));
if (cell->getPort("\\DST_EN") != State::S1) {
f << " &&& ";
dump_sigspec(f, cell->getPort("\\DST_EN"));
}
bool bak_decimal = decimal;
decimal = 1;
f << ", ";
dump_const(f, cell->getParam("\\T_LIMIT"));
if (spec_type == "$setuphold" || spec_type == "$recrem" || spec_type == "$fullskew") {
f << ", ";
dump_const(f, cell->getParam("\\T_LIMIT2"));
}
f << ");\n";
decimal = bak_decimal;
f << stringf("%s" "endspecify\n", indent.c_str());
return true;
@ -1321,8 +1379,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (it != cell->parameters.begin())
f << stringf(",");
f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str());
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
dump_const(f, it->second, -1, 0, false, is_signed);
dump_const(f, it->second);
f << stringf(")");
}
f << stringf("\n%s" ")", indent.c_str());
@ -1369,8 +1426,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (defparam && cell->parameters.size() > 0) {
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
f << stringf("%sdefparam %s.%s = ", indent.c_str(), cell_name.c_str(), id(it->first).c_str());
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
dump_const(f, it->second, -1, 0, false, is_signed);
dump_const(f, it->second);
f << stringf(";\n");
}
}

View File

@ -1492,10 +1492,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
continue;
}
if (child->type == AST_PARASET) {
int extra_const_flags = 0;
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
if (child->children[0]->type == AST_REALVALUE) {
log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n",
log_id(cell), log_id(paraname), child->children[0]->realvalue);
extra_const_flags = RTLIL::CONST_FLAG_REAL;
auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue));
strnode->cloneInto(child->children[0]);
delete strnode;
@ -1504,6 +1506,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n",
log_id(cell), log_id(paraname));
cell->parameters[paraname] = child->children[0]->asParaConst();
cell->parameters[paraname].flags |= extra_const_flags;
continue;
}
if (child->type == AST_ARGUMENT) {

View File

@ -50,7 +50,7 @@ namespace RTLIL
CONST_FLAG_NONE = 0,
CONST_FLAG_STRING = 1,
CONST_FLAG_SIGNED = 2, // only used for parameters
CONST_FLAG_REAL = 4 // unused -- to be used for parameters
CONST_FLAG_REAL = 4 // only used for parameters
};
struct Const;