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) {
|
||||
// replace with wire representing the packed structure
|
||||
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;
|
||||
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
|
||||
|
||||
%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> type_name
|
||||
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
|
||||
|
@ -619,26 +619,19 @@ non_opt_delay:
|
|||
delay:
|
||||
non_opt_delay | %empty;
|
||||
|
||||
wire_type:
|
||||
{
|
||||
astbuf3 = new AstNode(AST_WIRE);
|
||||
current_wire_rand = false;
|
||||
current_wire_const = false;
|
||||
} wire_type_token_list {
|
||||
$$ = astbuf3;
|
||||
SET_RULE_LOC(@$, @2, @$);
|
||||
};
|
||||
io_wire_type:
|
||||
{ astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
|
||||
wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness
|
||||
{ $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
|
||||
|
||||
wire_type_token_list:
|
||||
wire_type_token |
|
||||
wire_type_token_list wire_type_token |
|
||||
wire_type_token_io |
|
||||
hierarchical_type_id {
|
||||
astbuf3->is_custom_type = true;
|
||||
astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
|
||||
astbuf3->children.back()->str = *$1;
|
||||
delete $1;
|
||||
};
|
||||
non_io_wire_type:
|
||||
{ astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
|
||||
wire_type_const_rand wire_type_token wire_type_signedness
|
||||
{ $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
|
||||
|
||||
wire_type:
|
||||
io_wire_type |
|
||||
non_io_wire_type;
|
||||
|
||||
wire_type_token_io:
|
||||
TOK_INPUT {
|
||||
|
@ -652,7 +645,25 @@ wire_type_token_io:
|
|||
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:
|
||||
hierarchical_type_id {
|
||||
astbuf3->is_custom_type = true;
|
||||
astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
|
||||
astbuf3->children.back()->str = *$1;
|
||||
} |
|
||||
TOK_WIRE {
|
||||
} |
|
||||
TOK_WOR {
|
||||
|
@ -682,15 +693,6 @@ wire_type_token:
|
|||
astbuf3->is_signed = true;
|
||||
astbuf3->range_left = 31;
|
||||
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:
|
||||
|
@ -1803,7 +1805,7 @@ type_name: TOK_ID // first time seen
|
|||
;
|
||||
|
||||
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;
|
||||
astbuf2 = checkRange(astbuf1, $3);
|
||||
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