Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for attributes on parameters in Verilog #25

Merged
merged 17 commits into from
May 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
6d9cc86
Added the RTLIL::Parameter struct which stores module parameters and …
mkurc-ant May 15, 2019
fece472
Removed avail_params and added a function which mimics the former fun…
mkurc-ant May 15, 2019
68e3da9
Added appending of parsed attribute list to the Ast node of a parameter
mkurc-ant May 15, 2019
8572a47
Revert "Removed avail_params and added a function which mimics the fo…
mkurc-ant May 17, 2019
f430a06
Attributes for parameters are now stored only if one has them
mkurc-ant May 17, 2019
7dbb65e
Fixed JSON backend to accomodate new parameter info representation.
mkurc-ant May 17, 2019
5115bb8
Updated ilang backend to support attributes on parameters
mkurc-ant May 17, 2019
b08ac3a
Added outputting of module parameters along with their attributes to …
mkurc-ant May 17, 2019
226a3c0
Added parameter attribute support to the ilang frontend. No default v…
mkurc-ant May 17, 2019
42abcfa
Disabled output of parameters starting with '$' in Verilog backend. T…
mkurc-ant May 17, 2019
994a6df
Fixed statement for the CI to pass
mkurc-ant May 17, 2019
0a71def
Added retrieving parameter information to Python wrapper
mkurc-ant May 22, 2019
73e589e
Added escaping of module parameters starting with "$" to the verilog …
mkurc-ant May 23, 2019
b2c430a
Added round-trip tests for Verilog and Ilang frontend/backend
mkurc-ant May 23, 2019
a05a44c
Added support for default value of floating point parameters to the V…
mkurc-ant May 24, 2019
156580e
Added outputting of floating point default values of parameters to th…
mkurc-ant May 24, 2019
326ea4a
Added round-trip test for various Verilog parameter types
mkurc-ant May 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ SEEDOPT=""
endif

test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/round-trip && bash run-test.sh
+cd tests/simple && bash run-test.sh $(SEEDOPT)
+cd tests/hana && bash run-test.sh $(SEEDOPT)
+cd tests/asicworld && bash run-test.sh $(SEEDOPT)
Expand Down
13 changes: 12 additions & 1 deletion backends/ilang/ilang_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,19 @@ void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
if (!module->avail_parameters.empty()) {
if (only_selected)
f << stringf("\n");
for (auto &p : module->avail_parameters)
for (auto &p : module->avail_parameters) {

if (module->parameter_attributes.count(p)) {
f << stringf("\n");
for (auto& attr : module->parameter_attributes.at(p)) {
litghost marked this conversation as resolved.
Show resolved Hide resolved
f << stringf("%s" "attribute %s ", (indent + " ").c_str(), attr.first.c_str());
dump_const(f, attr.second);
f << stringf("\n");
}
}

f << stringf("%s" " parameter %s\n", indent.c_str(), p.c_str());
}
}
}

Expand Down
68 changes: 54 additions & 14 deletions backends/json/json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,56 @@ struct JsonWriter
return str + " ]";
}

void write_parameters(const dict<IdString, Const> &parameters, bool for_module=false)
void write_attributes(const dict<IdString, Const> &attributes, bool for_module=false)
{
bool first = true;
for (auto &param : parameters) {
for (auto &attr : attributes) {
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());
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(attr.first).c_str());
if ((attr.second.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0)
f << get_string(attr.second.decode_string());
else if (GetSize(attr.second.bits) > 32)
f << get_string(attr.second.as_string());
else if ((attr.second.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
f << stringf("%d", attr.second.as_int());
else
f << stringf("%u", param.second.as_int());
f << stringf("%u", attr.second.as_int());
first = false;
}
}

void write_module_parameters(const Module* module)
{
bool first = true;
for (auto &param : module->avail_parameters) {
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(param).c_str());

f << stringf(" \"attributes\": {");
if (module->parameter_attributes.count(param))
write_attributes(module->parameter_attributes.at(param));
f << stringf("\n },\n");

const RTLIL::ParameterInfo& info = module->parameter_information.at(param);

f << stringf(" \"default\": ");

if (info.isReal) {
f << stringf("%f", info.defaultValueReal);
}
else {
if ((info.defaultValue.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) != 0)
f << get_string(info.defaultValue.decode_string());
else if (GetSize(info.defaultValue.bits) > 32)
f << get_string(info.defaultValue.as_string());
else if ((info.defaultValue.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) != 0)
f << stringf("%d", info.defaultValue.as_int());
else
f << stringf("%u", info.defaultValue.as_int());
}
f << stringf("\n");

f << stringf(" }");
first = false;
}
}
Expand All @@ -114,7 +150,11 @@ struct JsonWriter
f << stringf(" %s: {\n", get_name(module->name).c_str());

f << stringf(" \"attributes\": {");
write_parameters(module->attributes, /*for_module=*/true);
write_attributes(module->attributes, /*for_module=*/true);
f << stringf("\n },\n");

f << stringf(" \"parameters\": {");
write_module_parameters(module);
f << stringf("\n },\n");

f << stringf(" \"ports\": {");
Expand Down Expand Up @@ -149,10 +189,10 @@ struct JsonWriter
}
}
f << stringf(" \"parameters\": {");
write_parameters(c->parameters);
write_attributes(c->parameters);
litghost marked this conversation as resolved.
Show resolved Hide resolved
f << stringf("\n },\n");
f << stringf(" \"attributes\": {");
write_parameters(c->attributes);
write_attributes(c->attributes);
f << stringf("\n },\n");
if (c->known()) {
f << stringf(" \"port_directions\": {");
Expand Down Expand Up @@ -190,7 +230,7 @@ struct JsonWriter
f << stringf(" \"hide_name\": %s,\n", w->name[0] == '$' ? "1" : "0");
f << stringf(" \"bits\": %s,\n", get_bits(w).c_str());
f << stringf(" \"attributes\": {");
write_parameters(w->attributes);
write_attributes(w->attributes);
f << stringf("\n }\n");
f << stringf(" }");
first = false;
Expand Down
32 changes: 32 additions & 0 deletions backends/verilog/verilog_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,36 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo
}
}

void dump_parameters(std::ostream &f, std::string indent, RTLIL::Module *module)
{
for (auto& param : module->avail_parameters) {
std::string paramName;

RTLIL::ParameterInfo& info = module->parameter_information.at(param);

if (module->parameter_attributes.count(param)) {
dump_attributes(f, indent, module->parameter_attributes.at(param), '\n');
}

// Prefix the parameter name if needed
if (param.str().find("$") == 0) {
paramName = std::string("\\") + std::string(param.c_str());
}
else {
paramName = std::string(param.c_str());
}

f << stringf("%s" "parameter %s = ", indent.c_str(), paramName.c_str());
if (info.isReal) {
f << stringf("%f", info.defaultValueReal);
}
else {
dump_const(f, info.defaultValue);
}
f << stringf(";\n");
}
}

void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
{
reg_wires.clear();
Expand Down Expand Up @@ -1680,6 +1710,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
}
f << stringf(");\n");

dump_parameters(f, indent + " ", module);

for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it)
dump_wire(f, indent + " ", it->second);

Expand Down
1 change: 0 additions & 1 deletion frontends/ast/ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,6 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
new_children.push_back(child);
} else if (child->type == AST_PARAMETER) {
child->delete_children();
child->children.push_back(AstNode::mkconst_int(0, false, 0));
new_children.push_back(child);
} else if (child->type == AST_CELL && child->children.size() > 0 && child->children[0]->type == AST_CELLTYPE &&
Expand Down
41 changes: 38 additions & 3 deletions frontends/ast/genrtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -892,9 +892,44 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_INTERFACEPORTTYPE:
break;

// remember the parameter, needed for example in techmap
case AST_PARAMETER:
current_module->avail_parameters.insert(str);
// create an RTLIL::Parameter for an AST_PARAMETER node
case AST_PARAMETER: {
current_module->avail_parameters.insert(str);

// Add parameter information
log_assert(children.size() >= 1);

AstNode* child = children[0];
log_assert(child->type == AST_CONSTANT || child->type == AST_REALVALUE);

RTLIL::ParameterInfo info;

if (child->type == AST_CONSTANT) {
info.defaultValue = child->asAttrConst();
}
else {
info.defaultValueReal = child->realvalue;
info.isReal = true;
}

#ifdef WITH_PYTHON
info.name = str;
#endif
current_module->parameter_information.insert(std::pair<RTLIL::IdString, RTLIL::ParameterInfo>(str, info));

// Add parameter attributes (if any)
if (!attributes.empty()) {
dict<RTLIL::IdString,RTLIL::Const> param_attrs;

for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
param_attrs[attr.first] = attr.second->asAttrConst();
}

current_module->parameter_attributes[str] = param_attrs;
}
}
break;

// create an RTLIL::Wire for an AST_WIRE node
Expand Down
16 changes: 16 additions & 0 deletions frontends/ilang/ilang_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,22 @@ module_stmt:
param_stmt:
TOK_PARAMETER TOK_ID EOL {
current_module->avail_parameters.insert($2);

// Assume that a parameter has default value of 0
RTLIL::ParameterInfo info;
info.defaultValue = 0;
#ifdef WITH_PYTHON
info.name = $2;
#endif

current_module->parameter_information.insert(std::pair<RTLIL::IdString,RTLIL::ParameterInfo>($2, info));

// Append attributes
if (!attrbuf.empty()) {
current_module->parameter_attributes[$2] = attrbuf;
attrbuf.clear();
}

free($2);
};

Expand Down
2 changes: 2 additions & 0 deletions frontends/verilog/verilog_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,7 @@ param_decl:
attr TOK_PARAMETER {
astbuf1 = new AstNode(AST_PARAMETER);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
} param_signed param_integer param_real param_range param_decl_list ';' {
delete astbuf1;
};
Expand All @@ -1213,6 +1214,7 @@ localparam_decl:
attr TOK_LOCALPARAM {
astbuf1 = new AstNode(AST_LOCALPARAM);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
} param_signed param_integer param_real param_range param_decl_list ';' {
delete astbuf1;
};
Expand Down
37 changes: 37 additions & 0 deletions kernel/rtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,17 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const

new_mod->avail_parameters = avail_parameters;

for (auto &info : parameter_information)
new_mod->parameter_information.insert(info);

for (auto &attrs : parameter_attributes)
{
dict<RTLIL::IdString,RTLIL::Const> attrs_copy;
for (auto &attr : attrs.second)
attrs_copy[attr.first] = attr.second;
new_mod->parameter_attributes[attrs.first] = attrs_copy;
}

for (auto &conn : connections_)
new_mod->connect(conn);

Expand Down Expand Up @@ -2312,6 +2323,32 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string
return sig;
}

RTLIL::ParameterInfo::ParameterInfo()
{
static unsigned int hashidx_count = 123456789;
hashidx_count = mkhash_xorshift(hashidx_count);
hashidx_ = hashidx_count;

#ifdef WITH_PYTHON
RTLIL::ParameterInfo::get_all_parameterinfos()->insert(std::pair<unsigned int, RTLIL::ParameterInfo*>(hashidx_, this));
mithro marked this conversation as resolved.
Show resolved Hide resolved
#endif
}

RTLIL::ParameterInfo::~ParameterInfo()
{
#ifdef WITH_PYTHON
RTLIL::ParameterInfo::get_all_parameterinfos()->erase(hashidx_);
#endif
}

#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::ParameterInfo*> all_parameter_infos;
std::map<unsigned int, RTLIL::ParameterInfo*> *RTLIL::ParameterInfo::get_all_parameterinfos(void)
{
return &all_parameter_infos;
}
#endif

RTLIL::Wire::Wire()
{
static unsigned int hashidx_count = 123456789;
Expand Down
25 changes: 25 additions & 0 deletions kernel/rtlil.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace RTLIL
struct Monitor;
struct Design;
struct Module;
struct ParameterInfo;
struct Wire;
struct Memory;
struct Cell;
Expand Down Expand Up @@ -968,6 +969,7 @@ struct RTLIL::Module : public RTLIL::AttrObject
RTLIL::Design *design;
pool<RTLIL::Monitor*> monitors;

int refcount_parameters_;
int refcount_wires_;
int refcount_cells_;

Expand All @@ -977,6 +979,8 @@ struct RTLIL::Module : public RTLIL::AttrObject

RTLIL::IdString name;
pool<RTLIL::IdString> avail_parameters;
dict<RTLIL::IdString, RTLIL::ParameterInfo> parameter_information;
dict<RTLIL::IdString, dict<RTLIL::IdString,RTLIL::Const>> parameter_attributes;
litghost marked this conversation as resolved.
Show resolved Hide resolved
dict<RTLIL::IdString, RTLIL::Memory*> memories;
dict<RTLIL::IdString, RTLIL::Process*> processes;

Expand Down Expand Up @@ -1216,6 +1220,27 @@ struct RTLIL::Module : public RTLIL::AttrObject
#endif
};

struct RTLIL::ParameterInfo
{
unsigned int hashidx_;
unsigned int hash() const { return hashidx_; }

ParameterInfo ();
~ParameterInfo ();

#ifdef WITH_PYTHON
RTLIL::IdString name;
#endif
RTLIL::Const defaultValue = 0;

double defaultValueReal = 0.0;
bool isReal = false;

#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::ParameterInfo*> *get_all_parameterinfos(void);
#endif
};

struct RTLIL::Wire : public RTLIL::AttrObject
{
unsigned int hashidx_;
Expand Down
3 changes: 2 additions & 1 deletion misc/py_wrap_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,8 @@ def contains_default_constr(self):
WClass("Wire", link_types.global_list, Attribute(WType("unsigned int"), "hashidx_"), "name.c_str()", "hash()"),
WClass("Memory", link_types.global_list, Attribute(WType("unsigned int"), "hashidx_"), "name.c_str()", "hash()"),
WClass("Module", link_types.global_list, Attribute(WType("unsigned int"), "hashidx_"), "name.c_str()", "hash()"),
WClass("Design", link_types.global_list, Attribute(WType("unsigned int"), "hashidx_"), "hashidx_", "hash()")
WClass("Design", link_types.global_list, Attribute(WType("unsigned int"), "hashidx_"), "hashidx_", "hash()"),
WClass("ParameterInfo", link_types.global_list, Attribute(WType("unsigned int"), "hashidx_"), "name.c_str()", "hash()"),
]
),
#Source("kernel/satgen",[
Expand Down
11 changes: 11 additions & 0 deletions tests/round-trip/parameter_types.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module box (I, O);
input wire I;
output wire O;

parameter PARAM_STRING = "A string.";
parameter PARAM_INTEGER = 10;
parameter PARAM_REAL = 3.14;

assign O = I;

endmodule
Loading