mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #2312 from antmicro/typedef-inout
Add support for user types in IOs
This commit is contained in:
commit
056c12eb6f
|
@ -1330,6 +1330,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) {
|
if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) {
|
||||||
// replace with wire representing the packed structure
|
// replace with wire representing the packed structure
|
||||||
newNode = make_packed_struct(template_node, str);
|
newNode = make_packed_struct(template_node, str);
|
||||||
|
// add original input/output attribute to resolved wire
|
||||||
|
newNode->is_input = this->is_input;
|
||||||
|
newNode->is_output = this->is_output;
|
||||||
current_scope[str] = this;
|
current_scope[str] = this;
|
||||||
goto apply_newNode;
|
goto apply_newNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
|
||||||
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
|
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
|
||||||
|
|
||||||
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
||||||
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type
|
||||||
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
|
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
|
||||||
%type <string> type_name
|
%type <string> type_name
|
||||||
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
|
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
|
||||||
|
@ -619,26 +619,19 @@ non_opt_delay:
|
||||||
delay:
|
delay:
|
||||||
non_opt_delay | %empty;
|
non_opt_delay | %empty;
|
||||||
|
|
||||||
wire_type:
|
io_wire_type:
|
||||||
{
|
{ astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
|
||||||
astbuf3 = new AstNode(AST_WIRE);
|
wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness
|
||||||
current_wire_rand = false;
|
{ $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
|
||||||
current_wire_const = false;
|
|
||||||
} wire_type_token_list {
|
|
||||||
$$ = astbuf3;
|
|
||||||
SET_RULE_LOC(@$, @2, @$);
|
|
||||||
};
|
|
||||||
|
|
||||||
wire_type_token_list:
|
non_io_wire_type:
|
||||||
wire_type_token |
|
{ astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
|
||||||
wire_type_token_list wire_type_token |
|
wire_type_const_rand wire_type_token wire_type_signedness
|
||||||
wire_type_token_io |
|
{ $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
|
||||||
hierarchical_type_id {
|
|
||||||
astbuf3->is_custom_type = true;
|
wire_type:
|
||||||
astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
|
io_wire_type |
|
||||||
astbuf3->children.back()->str = *$1;
|
non_io_wire_type;
|
||||||
delete $1;
|
|
||||||
};
|
|
||||||
|
|
||||||
wire_type_token_io:
|
wire_type_token_io:
|
||||||
TOK_INPUT {
|
TOK_INPUT {
|
||||||
|
@ -652,7 +645,25 @@ wire_type_token_io:
|
||||||
astbuf3->is_output = true;
|
astbuf3->is_output = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wire_type_signedness:
|
||||||
|
TOK_SIGNED { astbuf3->is_signed = true; } |
|
||||||
|
TOK_UNSIGNED { astbuf3->is_signed = false; } |
|
||||||
|
%empty;
|
||||||
|
|
||||||
|
wire_type_const_rand:
|
||||||
|
TOK_CONST { current_wire_const = true; } |
|
||||||
|
TOK_RAND { current_wire_rand = true; } |
|
||||||
|
%empty;
|
||||||
|
|
||||||
|
opt_wire_type_token:
|
||||||
|
wire_type_token | %empty;
|
||||||
|
|
||||||
wire_type_token:
|
wire_type_token:
|
||||||
|
hierarchical_type_id {
|
||||||
|
astbuf3->is_custom_type = true;
|
||||||
|
astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
|
||||||
|
astbuf3->children.back()->str = *$1;
|
||||||
|
} |
|
||||||
TOK_WIRE {
|
TOK_WIRE {
|
||||||
} |
|
} |
|
||||||
TOK_WOR {
|
TOK_WOR {
|
||||||
|
@ -682,15 +693,6 @@ wire_type_token:
|
||||||
astbuf3->is_signed = true;
|
astbuf3->is_signed = true;
|
||||||
astbuf3->range_left = 31;
|
astbuf3->range_left = 31;
|
||||||
astbuf3->range_right = 0;
|
astbuf3->range_right = 0;
|
||||||
} |
|
|
||||||
TOK_SIGNED {
|
|
||||||
astbuf3->is_signed = true;
|
|
||||||
} |
|
|
||||||
TOK_RAND {
|
|
||||||
current_wire_rand = true;
|
|
||||||
} |
|
|
||||||
TOK_CONST {
|
|
||||||
current_wire_const = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
non_opt_range:
|
non_opt_range:
|
||||||
|
@ -1803,7 +1805,7 @@ type_name: TOK_ID // first time seen
|
||||||
;
|
;
|
||||||
|
|
||||||
typedef_decl:
|
typedef_decl:
|
||||||
TOK_TYPEDEF wire_type range type_name range_or_multirange ';' {
|
TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' {
|
||||||
astbuf1 = $2;
|
astbuf1 = $2;
|
||||||
astbuf2 = checkRange(astbuf1, $3);
|
astbuf2 = checkRange(astbuf1, $3);
|
||||||
if (astbuf2)
|
if (astbuf2)
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package p;
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
byte a;
|
||||||
|
byte b;
|
||||||
|
} p_t;
|
||||||
|
|
||||||
|
typedef logic [31:0] l_t;
|
||||||
|
|
||||||
|
endpackage
|
||||||
|
|
||||||
|
module foo1(
|
||||||
|
input p::p_t p,
|
||||||
|
output p::p_t o
|
||||||
|
);
|
||||||
|
assign o = p;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module foo2(p, o);
|
||||||
|
input p::p_t p;
|
||||||
|
output p::p_t o;
|
||||||
|
assign o = p;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module foo3(input p::l_t p, input p::l_t o);
|
||||||
|
assign o = p;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module foo4(input logic [15:0] p, input logic [15:0] o);
|
||||||
|
assign o = p;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module test_parser(a,b,c,d,e,f,g,h,i);
|
||||||
|
input [7:0] a; // no explicit net declaration - net is unsigned
|
||||||
|
input [7:0] b;
|
||||||
|
input signed [7:0] c;
|
||||||
|
input signed [7:0] d; // no explicit net declaration - net is signed
|
||||||
|
output [7:0] e; // no explicit net declaration - net is unsigned
|
||||||
|
output [7:0] f;
|
||||||
|
output signed [7:0] g;
|
||||||
|
output signed [7:0] h; // no explicit net declaration - net is signed
|
||||||
|
output unsigned [7:0] i;
|
||||||
|
wire signed [7:0] b; // port b inherits signed attribute from net decl.
|
||||||
|
wire [7:0] c; // net c inherits signed attribute from port
|
||||||
|
logic signed [7:0] f;// port f inherits signed attribute from logic decl.
|
||||||
|
logic [7:0] g; // logic g inherits signed attribute from port
|
||||||
|
|
||||||
|
assign a = 8'b10001111;
|
||||||
|
assign b = 8'b10001111;
|
||||||
|
assign c = 8'b10001111;
|
||||||
|
assign d = 8'b10001111;
|
||||||
|
assign e = 8'b10001111;
|
||||||
|
assign f = 8'b10001111;
|
||||||
|
assign g = 8'b10001111;
|
||||||
|
assign h = 8'b10001111;
|
||||||
|
assign i = 8'b10001111;
|
||||||
|
always_comb begin
|
||||||
|
assert($unsigned(143) == a);
|
||||||
|
assert($signed(-113) == b);
|
||||||
|
assert($signed(-113) == c);
|
||||||
|
assert($signed(-113) == d);
|
||||||
|
assert($unsigned(143) == e);
|
||||||
|
assert($unsigned(143) == f);
|
||||||
|
assert($signed(-113) == g);
|
||||||
|
assert($signed(-113) == h);
|
||||||
|
assert($unsigned(143) == i);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top;
|
||||||
|
p::p_t ps;
|
||||||
|
assign ps.a = 8'hAA;
|
||||||
|
assign ps.b = 8'h55;
|
||||||
|
foo1 foo(.p(ps));
|
||||||
|
|
||||||
|
p::p_t body;
|
||||||
|
assign body.a = 8'hBB;
|
||||||
|
assign body.b = 8'h66;
|
||||||
|
foo2 foo_b(.p(body));
|
||||||
|
|
||||||
|
typedef p::l_t local_alias;
|
||||||
|
|
||||||
|
local_alias l_s;
|
||||||
|
assign l_s = 32'hAAAAAAAA;
|
||||||
|
foo3 foo_l(.p(l_s));
|
||||||
|
|
||||||
|
typedef logic [15:0] sl_t;
|
||||||
|
|
||||||
|
sl_t sl_s;
|
||||||
|
assign sl_s = 16'hBBBB;
|
||||||
|
foo4 foo_sl(.p(sl_s));
|
||||||
|
|
||||||
|
typedef sl_t local_alias_st;
|
||||||
|
|
||||||
|
local_alias_st lsl_s;
|
||||||
|
assign lsl_s = 16'hCCCC;
|
||||||
|
foo4 foo_lsl(.p(lsl_s));
|
||||||
|
|
||||||
|
const logic j = 1'b1;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
assert(8'hAA == ps.a);
|
||||||
|
assert(8'h55 == ps.b);
|
||||||
|
assert(8'hBB == body.a);
|
||||||
|
assert(8'h66 == body.b);
|
||||||
|
assert(32'hAAAAAAAA == l_s);
|
||||||
|
assert(16'hBBBB == sl_s);
|
||||||
|
assert(16'hCCCC == lsl_s);
|
||||||
|
assert(1'b1 == j);
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,6 @@
|
||||||
|
read_verilog -sv typedef_struct_port.sv
|
||||||
|
hierarchy; proc; opt
|
||||||
|
select -module top
|
||||||
|
sat -verify -seq 1 -tempinduct -prove-asserts -show-all
|
||||||
|
select -module test_parser
|
||||||
|
sat -verify -seq 1 -tempinduct -prove-asserts -show-all
|
Loading…
Reference in New Issue