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 port connections #30

Merged
merged 10 commits into from
Jun 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -649,6 +649,7 @@ SEEDOPT=""
endif

test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/reference-out && bash run-test.sh
+cd tests/round-trip && bash run-test.sh
+cd tests/simple && bash run-test.sh $(SEEDOPT)
+cd tests/hana && bash run-test.sh $(SEEDOPT)
Expand Down
5 changes: 5 additions & 0 deletions backends/ilang/ilang_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::
f << stringf("\n");
}
for (auto &it : cell->connections()) {
for (auto &it2 : it.second.attributes) {
f << stringf("%s attribute %s ", indent.c_str(), it2.first.c_str());
dump_const(f, it2.second);
f << stringf("\n");
}
f << stringf("%s connect %s ", indent.c_str(), it.first.c_str());
dump_sigspec(f, it.second);
f << stringf("\n");
Expand Down
25 changes: 24 additions & 1 deletion backends/json/json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,24 @@ struct JsonWriter
}
}

void write_connection_attributes(const dict<IdString, Const>& attributes)
{
bool first = true;
for (auto &attr : attributes) {
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: ", 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", attr.second.as_int());
first = false;
}
}

void write_module(Module *module_)
{
module = module_;
Expand Down Expand Up @@ -211,7 +229,12 @@ struct JsonWriter
bool first2 = true;
for (auto &conn : c->connections()) {
f << stringf("%s\n", first2 ? "" : ",");
f << stringf(" %s: %s", get_name(conn.first).c_str(), get_bits(conn.second).c_str());
f << stringf(" %s: {\n", get_name(conn.first).c_str());
f << stringf(" \"bits\": %s,\n", get_bits(conn.second).c_str());
f << stringf(" \"attributes\": {");
write_connection_attributes(conn.second.attributes);
f << stringf("\n }\n");
f << stringf(" }");
first2 = false;
}
f << stringf("\n }\n");
Expand Down
36 changes: 19 additions & 17 deletions backends/verilog/verilog_backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,27 @@ void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool no_decima
}
}

void dump_attributes(std::ostream &f, std::string indent, const dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false)
{
if (noattr)
return;
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str());
f << stringf(" = ");
if (modattr && (it->second == Const(0, 1) || it->second == Const(0)))
f << stringf(" 0 ");
else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
f << stringf(" 1 ");
else
dump_const(f, it->second, -1, 0, false, attr2comment);
f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
}
}

void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
{
dump_attributes(f, "", sig.attributes, ' ');

if (GetSize(sig) == 0) {
f << "\"\"";
return;
Expand All @@ -364,23 +383,6 @@ void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
}
}

void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false)
{
if (noattr)
return;
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str());
f << stringf(" = ");
if (modattr && (it->second == Const(0, 1) || it->second == Const(0)))
f << stringf(" 0 ");
else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
f << stringf(" 1 ");
else
dump_const(f, it->second, -1, 0, false, attr2comment);
f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
}
}

void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
{
dump_attributes(f, indent, wire->attributes);
Expand Down
5 changes: 5 additions & 0 deletions frontends/ast/genrtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec sig;
if (child->children.size() > 0)
sig = child->children[0]->genRTLIL();
for (auto &attr : child->attributes) {
if (attr.second->type != AST_CONSTANT)
log_file_error(filename, linenum, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
sig.attributes[attr.first] = attr.second->asAttrConst();
}
if (child->str.size() == 0) {
char buf[100];
snprintf(buf, 100, "$%d", ++port_counter);
Expand Down
3 changes: 3 additions & 0 deletions frontends/ilang/ilang_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ cell_stmt:
} cell_body TOK_END EOL;

cell_body:
cell_body attr_stmt |
cell_body TOK_PARAMETER TOK_ID constant EOL {
current_cell->parameters[$3] = *$4;
free($3);
Expand All @@ -275,9 +276,11 @@ cell_body:
cell_body TOK_CONNECT TOK_ID sigspec EOL {
if (current_cell->hasPort($3))
rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str());
$4->attributes = attrbuf;
current_cell->setPort($3, *$4);
delete $4;
free($3);
attrbuf.clear();
} |
/* empty */;

Expand Down
24 changes: 14 additions & 10 deletions frontends/verilog/verilog_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1528,27 +1528,31 @@ cell_port_list_rules:
cell_port | cell_port_list_rules ',' cell_port;

cell_port:
/* empty */ {
attr {
AstNode *node = new AstNode(AST_ARGUMENT);
astbuf2->children.push_back(node);
append_attr(node, $1);
} |
expr {
attr expr {
AstNode *node = new AstNode(AST_ARGUMENT);
astbuf2->children.push_back(node);
node->children.push_back($1);
node->children.push_back($2);
append_attr(node, $1);
} |
'.' TOK_ID '(' expr ')' {
attr '.' TOK_ID '(' expr ')' {
AstNode *node = new AstNode(AST_ARGUMENT);
node->str = *$2;
node->str = *$3;
astbuf2->children.push_back(node);
node->children.push_back($4);
delete $2;
node->children.push_back($5);
append_attr(node, $1);
delete $3;
} |
'.' TOK_ID '(' ')' {
attr '.' TOK_ID '(' ')' {
AstNode *node = new AstNode(AST_ARGUMENT);
node->str = *$2;
node->str = *$3;
astbuf2->children.push_back(node);
delete $2;
append_attr(node, $1);
delete $3;
};

always_stmt:
Expand Down
3 changes: 3 additions & 0 deletions kernel/rtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,8 @@ const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
check();
}

attributes = other.attributes;

return *this;
}

Expand Down Expand Up @@ -3021,6 +3023,7 @@ void RTLIL::SigSpec::sort()
unpack();
cover("kernel.rtlil.sigspec.sort");
std::sort(bits_.begin(), bits_.end());
attributes.sort();
}

void RTLIL::SigSpec::sort_and_unify()
Expand Down
4 changes: 3 additions & 1 deletion kernel/rtlil.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ struct RTLIL::SigSpecConstIterator : public std::iterator<std::input_iterator_ta
inline void operator++() { index++; }
};

struct RTLIL::SigSpec
struct RTLIL::SigSpec : public RTLIL::AttrObject
{
private:
int width_;
Expand Down Expand Up @@ -701,13 +701,15 @@ struct RTLIL::SigSpec
hash_ = other.hash_;
chunks_ = std::move(other.chunks_);
bits_ = std::move(other.bits_);
attributes = std::move(other.attributes);
}

const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) {
width_ = other.width_;
hash_ = other.hash_;
chunks_ = std::move(other.chunks_);
bits_ = std::move(other.bits_);
attributes = std::move(other.attributes);
return *this;
}

Expand Down
2 changes: 2 additions & 0 deletions tests/reference-out/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.out*
*.log
21 changes: 21 additions & 0 deletions tests/reference-out/attrib01_module.v.DISABLED
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module bar(clk, rst, inp, out);
input wire clk;
input wire rst;
input wire inp;
output reg out;

always @(posedge clk)
if (rst) out <= 1'd0;
else out <= ~inp;

endmodule

module foo(clk, rst, inp, out);
input wire clk;
input wire rst;
input wire inp;
output wire out;

bar bar_instance (clk, rst, inp, out);
endmodule

25 changes: 25 additions & 0 deletions tests/reference-out/attrib02_port_decl.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module bar(clk, rst, inp, out);
(* this_is_clock = 1 *)
input wire clk;
(* this_is_reset = 1 *)
input wire rst;
input wire inp;
(* an_output_register = 1*)
output reg out;

always @(posedge clk)
if (rst) out <= 1'd0;
else out <= ~inp;

endmodule

module foo(clk, rst, inp, out);
(* this_is_the_master_clock *)
input wire clk;
input wire rst;
input wire inp;
output wire out;

bar bar_instance (clk, rst, inp, out);
endmodule

63 changes: 63 additions & 0 deletions tests/reference-out/attrib02_port_decl/attrib02_port_decl.ref.il
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Generated by Yosys 0.8+498 (git sha1 1bdc7e9d, gcc 7.4.0-1ubuntu1~18.04 -fPIC -Os)
autoidx 3
attribute \cells_not_processed 1
attribute \src "attrib02_port_decl.v:1"
module \bar
attribute \src "attrib02_port_decl.v:10"
wire $0\out[0:0]
attribute \src "attrib02_port_decl.v:12"
wire $not$attrib02_port_decl.v:12$2_Y
attribute \src "attrib02_port_decl.v:3"
attribute \this_is_clock 1
wire input 1 \clk
attribute \src "attrib02_port_decl.v:6"
wire input 3 \inp
attribute \an_output_register 1
attribute \src "attrib02_port_decl.v:8"
wire output 4 \out
attribute \src "attrib02_port_decl.v:5"
attribute \this_is_reset 1
wire input 2 \rst
attribute \src "attrib02_port_decl.v:12"
cell $not $not$attrib02_port_decl.v:12$2
parameter \A_SIGNED 0
parameter \A_WIDTH 1
parameter \Y_WIDTH 1
connect \A \inp
connect \Y $not$attrib02_port_decl.v:12$2_Y
end
attribute \src "attrib02_port_decl.v:10"
process $proc$attrib02_port_decl.v:10$1
assign $0\out[0:0] \out
attribute \src "attrib02_port_decl.v:11"
switch \rst
case 1'1
assign $0\out[0:0] 1'0
case
assign $0\out[0:0] $not$attrib02_port_decl.v:12$2_Y
end
sync posedge \clk
update \out $0\out[0:0]
end
end
attribute \cells_not_processed 1
attribute \src "attrib02_port_decl.v:16"
module \foo
attribute \src "attrib02_port_decl.v:18"
attribute \this_is_the_master_clock 1
wire input 1 \clk
attribute \src "attrib02_port_decl.v:20"
wire input 3 \inp
attribute \src "attrib02_port_decl.v:21"
wire output 4 \out
attribute \src "attrib02_port_decl.v:19"
wire input 2 \rst
attribute \module_not_derived 1
attribute \src "attrib02_port_decl.v:23"
cell \bar \bar_instance
connect $1 \clk
connect $2 \rst
connect $3 \inp
connect $4 \out
end
end
Loading