mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
Improve write_verilog specify support
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
e2fb8ebe86
commit
87426f5a06
|
@ -183,8 +183,9 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name)
|
||||||
return true;
|
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)
|
if (width < 0)
|
||||||
width = data.bits.size() - offset;
|
width = data.bits.size() - offset;
|
||||||
if (width == 0) {
|
if (width == 0) {
|
||||||
|
@ -275,7 +276,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f << stringf("\"");
|
if ((data.flags & RTLIL::CONST_FLAG_REAL) == 0)
|
||||||
|
f << stringf("\"");
|
||||||
std::string str = data.decode_string();
|
std::string str = data.decode_string();
|
||||||
for (size_t i = 0; i < str.size(); i++) {
|
for (size_t i = 0; i < str.size(); i++) {
|
||||||
if (str[i] == '\n')
|
if (str[i] == '\n')
|
||||||
|
@ -293,7 +295,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
|
||||||
else
|
else
|
||||||
f << str[i];
|
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)))
|
else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
|
||||||
f << stringf(" 1 ");
|
f << stringf(" 1 ");
|
||||||
else
|
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);
|
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"));
|
dump_sigspec(f, cell->getPort("\\DST"));
|
||||||
}
|
}
|
||||||
|
|
||||||
f << stringf(") = (%d:%d:%d, %d:%d:%d);\n",
|
bool bak_decimal = decimal;
|
||||||
cell->getParam("\\T_RISE_MIN").as_int(),
|
decimal = 1;
|
||||||
cell->getParam("\\T_RISE_TYP").as_int(),
|
|
||||||
cell->getParam("\\T_RISE_MAX").as_int(),
|
f << ") = (";
|
||||||
cell->getParam("\\T_FALL_MIN").as_int(),
|
dump_const(f, cell->getParam("\\T_RISE_MIN"));
|
||||||
cell->getParam("\\T_FALL_TYP").as_int(),
|
f << ":";
|
||||||
cell->getParam("\\T_FALL_MAX").as_int());
|
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());
|
f << stringf("%s" "endspecify\n", indent.c_str());
|
||||||
return true;
|
return true;
|
||||||
|
@ -1321,8 +1379,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
||||||
if (it != cell->parameters.begin())
|
if (it != cell->parameters.begin())
|
||||||
f << stringf(",");
|
f << stringf(",");
|
||||||
f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str());
|
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);
|
||||||
dump_const(f, it->second, -1, 0, false, is_signed);
|
|
||||||
f << stringf(")");
|
f << stringf(")");
|
||||||
}
|
}
|
||||||
f << stringf("\n%s" ")", indent.c_str());
|
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) {
|
if (defparam && cell->parameters.size() > 0) {
|
||||||
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
|
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());
|
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);
|
||||||
dump_const(f, it->second, -1, 0, false, is_signed);
|
|
||||||
f << stringf(";\n");
|
f << stringf(";\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1492,10 +1492,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (child->type == AST_PARASET) {
|
if (child->type == AST_PARASET) {
|
||||||
|
int extra_const_flags = 0;
|
||||||
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
|
IdString paraname = child->str.empty() ? stringf("$%d", ++para_counter) : child->str;
|
||||||
if (child->children[0]->type == AST_REALVALUE) {
|
if (child->children[0]->type == AST_REALVALUE) {
|
||||||
log_file_warning(filename, linenum, "Replacing floating point parameter %s.%s = %f with string.\n",
|
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);
|
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));
|
auto strnode = AstNode::mkconst_str(stringf("%f", child->children[0]->realvalue));
|
||||||
strnode->cloneInto(child->children[0]);
|
strnode->cloneInto(child->children[0]);
|
||||||
delete strnode;
|
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_file_error(filename, linenum, "Parameter %s.%s with non-constant value!\n",
|
||||||
log_id(cell), log_id(paraname));
|
log_id(cell), log_id(paraname));
|
||||||
cell->parameters[paraname] = child->children[0]->asParaConst();
|
cell->parameters[paraname] = child->children[0]->asParaConst();
|
||||||
|
cell->parameters[paraname].flags |= extra_const_flags;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (child->type == AST_ARGUMENT) {
|
if (child->type == AST_ARGUMENT) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace RTLIL
|
||||||
CONST_FLAG_NONE = 0,
|
CONST_FLAG_NONE = 0,
|
||||||
CONST_FLAG_STRING = 1,
|
CONST_FLAG_STRING = 1,
|
||||||
CONST_FLAG_SIGNED = 2, // only used for parameters
|
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;
|
struct Const;
|
||||||
|
|
Loading…
Reference in a new issue