Skip to content

Commit

Permalink
Merge pull request #30 from antmicro/attrs_on_port_conns
Browse files Browse the repository at this point in the history
Support for attributes on port connections
  • Loading branch information
mithro committed Jun 12, 2019
2 parents 8d943b4 + 296ecde commit 5f900f7
Show file tree
Hide file tree
Showing 48 changed files with 2,687 additions and 29 deletions.
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

0 comments on commit 5f900f7

Please sign in to comment.