Bunches more SystemVerilog syntax.
This commit is contained in:
parent
8c2e4a0892
commit
da743c3b2c
293
parse.y
293
parse.y
|
|
@ -265,6 +265,41 @@ static void current_task_set_statement(const YYLTYPE&loc, vector<Statement*>*s)
|
||||||
current_task->set_statement(tmp);
|
current_task->set_statement(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>*s)
|
||||||
|
{
|
||||||
|
if (s == 0) {
|
||||||
|
/* if the statement list is null, then the parser
|
||||||
|
detected the case that there are no statements in the
|
||||||
|
task. If this is System Verilog, handle it as an
|
||||||
|
an empty block. */
|
||||||
|
if (!gn_system_verilog()) {
|
||||||
|
yyerror(loc, "error: Support for empty functions requires SystemVerilog.");
|
||||||
|
}
|
||||||
|
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||||
|
FILE_NAME(tmp, loc);
|
||||||
|
current_function->set_statement(tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The parser assures that there is a non-empty vector. */
|
||||||
|
assert(s && !s->empty());
|
||||||
|
|
||||||
|
/* A vector of 1 is handled as a simple statement. */
|
||||||
|
if (s->size() == 1) {
|
||||||
|
current_function->set_statement((*s)[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gn_system_verilog()) {
|
||||||
|
yyerror(loc, "error: Function body with multiple statements requires SystemVerilog.");
|
||||||
|
}
|
||||||
|
|
||||||
|
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||||
|
FILE_NAME(tmp, loc);
|
||||||
|
tmp->set_statement(*s);
|
||||||
|
current_function->set_statement(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
|
|
@ -447,7 +482,7 @@ static void current_task_set_statement(const YYLTYPE&loc, vector<Statement*>*s)
|
||||||
%type <flag> from_exclude
|
%type <flag> from_exclude
|
||||||
%type <number> number pos_neg_number
|
%type <number> number pos_neg_number
|
||||||
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
|
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
|
||||||
%type <flag> K_automatic_opt K_packed_opt K_reg_opt K_virtual_opt
|
%type <flag> K_automatic_opt K_packed_opt K_reg_opt K_static_opt K_virtual_opt
|
||||||
%type <flag> udp_reg_opt edge_operator
|
%type <flag> udp_reg_opt edge_operator
|
||||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
||||||
%type <letter> udp_input_sym udp_output_sym
|
%type <letter> udp_input_sym udp_output_sym
|
||||||
|
|
@ -495,8 +530,8 @@ static void current_task_set_statement(const YYLTYPE&loc, vector<Statement*>*s)
|
||||||
|
|
||||||
%type <pform_name> hierarchy_identifier
|
%type <pform_name> hierarchy_identifier
|
||||||
%type <expr> assignment_pattern expression expr_primary expr_mintypmax
|
%type <expr> assignment_pattern expression expr_primary expr_mintypmax
|
||||||
%type <expr> dynamic_array_new inc_or_dec_expression lpvalue
|
%type <expr> class_new dynamic_array_new inc_or_dec_expression inside_expression lpvalue
|
||||||
%type <expr> branch_probe_expression
|
%type <expr> branch_probe_expression streaming_concatenation
|
||||||
%type <expr> delay_value delay_value_simple
|
%type <expr> delay_value delay_value_simple
|
||||||
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
||||||
%type <exprs> expression_list_with_nuls expression_list_proper
|
%type <exprs> expression_list_with_nuls expression_list_proper
|
||||||
|
|
@ -526,7 +561,7 @@ static void current_task_set_statement(const YYLTYPE&loc, vector<Statement*>*s)
|
||||||
%type <event_expr> event_expression
|
%type <event_expr> event_expression
|
||||||
%type <event_statement> event_control
|
%type <event_statement> event_control
|
||||||
%type <statement> statement statement_or_null compressed_statement
|
%type <statement> statement statement_or_null compressed_statement
|
||||||
%type <statement> loop_statement for_step
|
%type <statement> loop_statement for_step jump_statement
|
||||||
%type <statement_list> statement_or_null_list statement_or_null_list_opt
|
%type <statement_list> statement_or_null_list statement_or_null_list_opt
|
||||||
|
|
||||||
%type <statement> analog_statement
|
%type <statement> analog_statement
|
||||||
|
|
@ -543,7 +578,7 @@ static void current_task_set_statement(const YYLTYPE&loc, vector<Statement*>*s)
|
||||||
%token K_TAND
|
%token K_TAND
|
||||||
%right K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
|
%right K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
|
||||||
%right K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
|
%right K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
|
||||||
%right '?' ':'
|
%right '?' ':' K_inside
|
||||||
%left K_LOR
|
%left K_LOR
|
||||||
%left K_LAND
|
%left K_LAND
|
||||||
%left '|'
|
%left '|'
|
||||||
|
|
@ -609,6 +644,11 @@ class_declaration /* IEEE1800-2005: A.1.2 */
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
class_constraint /* IEEE1800-2005: A.1.8 */
|
||||||
|
: constraint_prototype
|
||||||
|
| constraint_declaration
|
||||||
|
;
|
||||||
|
|
||||||
class_identifier
|
class_identifier
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
{ // Create a synthetic typedef for the class name so that the
|
{ // Create a synthetic typedef for the class name so that the
|
||||||
|
|
@ -690,7 +730,7 @@ class_item /* IEEE1800-2005: A.1.8 */
|
||||||
be K_super ("this.new" makes little sense) but that would
|
be K_super ("this.new" makes little sense) but that would
|
||||||
cause a conflict. */
|
cause a conflict. */
|
||||||
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
|
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
|
||||||
implicit_class_handle '.' K_new '(' ')'
|
implicit_class_handle '.' K_new '(' expression_list_with_nuls ')'
|
||||||
statement_or_null_list_opt
|
statement_or_null_list_opt
|
||||||
K_endfunction endnew_opt
|
K_endfunction endnew_opt
|
||||||
{ yyerror(@3, "sorry: Class constructors not supported yet.");
|
{ yyerror(@3, "sorry: Class constructors not supported yet.");
|
||||||
|
|
@ -708,6 +748,11 @@ class_item /* IEEE1800-2005: A.1.8 */
|
||||||
|
|
||||||
| method_qualifier_opt function_declaration
|
| method_qualifier_opt function_declaration
|
||||||
|
|
||||||
|
|
||||||
|
/* Class constraints... */
|
||||||
|
|
||||||
|
| class_constraint
|
||||||
|
|
||||||
/* Here are some error matching rules to help recover from various
|
/* Here are some error matching rules to help recover from various
|
||||||
syntax errors within a class declaration. */
|
syntax errors within a class declaration. */
|
||||||
|
|
||||||
|
|
@ -739,6 +784,65 @@ class_item_qualifier /* IEEE1800-2005 A.1.8 */
|
||||||
| K_local
|
| K_local
|
||||||
;
|
;
|
||||||
|
|
||||||
|
class_new /* IEEE1800-2005 A.2.4 */
|
||||||
|
: K_new '(' ')'
|
||||||
|
{ yyerror(@1, "sorry: class_new not implemented yet.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_new '(' expression_list_proper ')'
|
||||||
|
{ yyerror(@1, "sorry: class_new not implemented yet.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_block_item /* IEEE1800-2005 A.1.9 */
|
||||||
|
: constraint_expression
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_block_item_list
|
||||||
|
: constraint_block_item_list constraint_block_item
|
||||||
|
| constraint_block_item
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_block_item_list_opt
|
||||||
|
:
|
||||||
|
| constraint_block_item_list
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_declaration /* IEEE1800-2005: A.1.9 */
|
||||||
|
: K_static_opt K_constraint IDENTIFIER '{' constraint_block_item_list_opt '}'
|
||||||
|
{ yyerror(@2, "sorry: Constraint declarations not supported.") }
|
||||||
|
|
||||||
|
/* Error handling rules... */
|
||||||
|
|
||||||
|
| K_static_opt K_constraint IDENTIFIER '{' error '}'
|
||||||
|
{ yyerror(@4, "error: Errors in the constraint block item list."); }
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_expression /* IEEE1800-2005 A.1.9 */
|
||||||
|
: expression ';'
|
||||||
|
| expression K_dist '{' '}' ';'
|
||||||
|
| expression K_TRIGGER constraint_set
|
||||||
|
| K_if '(' expression ')' constraint_set %prec less_than_K_else
|
||||||
|
| K_if '(' expression ')' constraint_set K_else constraint_set
|
||||||
|
| K_foreach '(' IDENTIFIER '[' loop_variables ']' ')' constraint_set
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_expression_list /* */
|
||||||
|
: constraint_expression_list constraint_expression
|
||||||
|
| constraint_expression
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_prototype /* IEEE1800-2005: A.1.9 */
|
||||||
|
: K_static_opt K_constraint IDENTIFIER ';'
|
||||||
|
{ yyerror(@2, "sorry: Constraint prototypes not supported.") }
|
||||||
|
;
|
||||||
|
|
||||||
|
constraint_set /* IEEE1800-2005 A.1.9 */
|
||||||
|
: constraint_expression
|
||||||
|
| '{' constraint_expression_list '}'
|
||||||
|
;
|
||||||
|
|
||||||
data_type /* IEEE1800-2005: A.2.2.1 */
|
data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
: integer_vector_type unsigned_signed_opt range_opt
|
: integer_vector_type unsigned_signed_opt range_opt
|
||||||
{ vector_type_t*tmp = new vector_type_t($1, $2, $3);
|
{ vector_type_t*tmp = new vector_type_t($1, $2, $3);
|
||||||
|
|
@ -830,24 +934,11 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
{ assert(current_function == 0);
|
{ assert(current_function == 0);
|
||||||
current_function = pform_push_function_scope(@1, $4, $2);
|
current_function = pform_push_function_scope(@1, $4, $2);
|
||||||
}
|
}
|
||||||
function_item_list statement_or_null_list
|
function_item_list statement_or_null_list_opt
|
||||||
K_endfunction
|
K_endfunction
|
||||||
{ current_function->set_ports($7);
|
{ current_function->set_ports($7);
|
||||||
current_function->set_return($3);
|
current_function->set_return($3);
|
||||||
assert($8 && $8->size() > 0);
|
current_function_set_statement($8? @8 : @4, $8);
|
||||||
if ($8->size() == 1) {
|
|
||||||
current_function->set_statement((*$8)[0]);
|
|
||||||
delete $8;
|
|
||||||
} else {
|
|
||||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
|
||||||
FILE_NAME(tmp, @8);
|
|
||||||
tmp->set_statement( *$8 );
|
|
||||||
current_function->set_statement(tmp);
|
|
||||||
delete $8;
|
|
||||||
if (!gn_system_verilog()) {
|
|
||||||
yyerror(@8, "error: Function body with multiple statements requres SystemVerilog.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
current_function = 0;
|
current_function = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -869,24 +960,11 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
}
|
}
|
||||||
'(' tf_port_list_opt ')' ';'
|
'(' tf_port_list_opt ')' ';'
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
statement_or_null_list
|
statement_or_null_list_opt
|
||||||
K_endfunction
|
K_endfunction
|
||||||
{ current_function->set_ports($7);
|
{ current_function->set_ports($7);
|
||||||
current_function->set_return($3);
|
current_function->set_return($3);
|
||||||
assert($11 && $11->size() > 0);
|
current_function_set_statement($11? @11 : @4, $11);
|
||||||
if ($11->size() == 1) {
|
|
||||||
current_function->set_statement((*$11)[0]);
|
|
||||||
delete $11;
|
|
||||||
} else {
|
|
||||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
|
||||||
FILE_NAME(tmp, @11);
|
|
||||||
tmp->set_statement( *$11 );
|
|
||||||
current_function->set_statement(tmp);
|
|
||||||
delete $11;
|
|
||||||
if (!gn_system_verilog()) {
|
|
||||||
yyerror(@11, "error: Function body with multiple statements requres SystemVerilog.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
current_function = 0;
|
current_function = 0;
|
||||||
if ($7==0 && !gn_system_verilog()) {
|
if ($7==0 && !gn_system_verilog()) {
|
||||||
|
|
@ -965,6 +1043,13 @@ inc_or_dec_expression /* IEEE1800-2005: A.4.3 */
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
inside_expression /* IEEE1800-2005 A.8.3 */
|
||||||
|
: expression K_inside '{' open_range_list '}'
|
||||||
|
{ yyerror(@2, "sorry: \"inside\" expressions not supported yet.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
integer_vector_type /* IEEE1800-2005: A.2.2.1 */
|
integer_vector_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
: K_reg { $$ = IVL_VT_LOGIC; }
|
: K_reg { $$ = IVL_VT_LOGIC; }
|
||||||
| K_bit { $$ = IVL_VT_BOOL; }
|
| K_bit { $$ = IVL_VT_BOOL; }
|
||||||
|
|
@ -972,6 +1057,21 @@ integer_vector_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
| K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */
|
| K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */
|
||||||
;
|
;
|
||||||
|
|
||||||
|
jump_statement /* IEEE1800-2005: A.6.5 */
|
||||||
|
: K_break ';'
|
||||||
|
{ yyerror(@1, "sorry: break statements not supported.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_return ';'
|
||||||
|
{ yyerror(@1, "sorry: return statements not supported.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_return expression ';'
|
||||||
|
{ yyerror(@1, "sorry: return statements not supported.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/* Loop statements are kinds of statements. */
|
/* Loop statements are kinds of statements. */
|
||||||
|
|
||||||
loop_statement /* IEEE1800-2005: A.6.8 */
|
loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
|
|
@ -1084,13 +1184,6 @@ variable_decl_assignment /* IEEE1800-2005 A.2.3 */
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| IDENTIFIER '[' '$' ']'
|
|
||||||
{ decl_assignment_t*tmp = new decl_assignment_t;
|
|
||||||
tmp->name = lex_strings.make($1);
|
|
||||||
yyerror("sorry: Queue dimensions not yet supported here.");
|
|
||||||
delete[]$1;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1135,6 +1228,11 @@ number : BASED_NUMBER
|
||||||
based_size = 0; }
|
based_size = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
open_range_list /* IEEE1800-2005 A.2.11 */
|
||||||
|
: open_range_list ',' value_range
|
||||||
|
| value_range
|
||||||
|
;
|
||||||
|
|
||||||
port_direction /* IEEE1800-2005 A.1.3 */
|
port_direction /* IEEE1800-2005 A.1.3 */
|
||||||
: K_input { $$ = NetNet::PINPUT; }
|
: K_input { $$ = NetNet::PINPUT; }
|
||||||
| K_output { $$ = NetNet::POUTPUT; }
|
| K_output { $$ = NetNet::POUTPUT; }
|
||||||
|
|
@ -1203,6 +1301,33 @@ statement_or_null /* IEEE1800-2005: A.6.4 */
|
||||||
{ $$ = 0; }
|
{ $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
stream_expression
|
||||||
|
: expression
|
||||||
|
;
|
||||||
|
|
||||||
|
stream_expression_list
|
||||||
|
: stream_expression_list ',' stream_expression
|
||||||
|
| stream_expression
|
||||||
|
;
|
||||||
|
|
||||||
|
stream_operator
|
||||||
|
: K_LS
|
||||||
|
| K_RS
|
||||||
|
;
|
||||||
|
|
||||||
|
streaming_concatenation /* IEEE1800-2005: A.8.1 */
|
||||||
|
: '{' stream_operator '{' stream_expression_list '}' '}'
|
||||||
|
{ /* streaming concatenation is a SystemVerilog thing. */
|
||||||
|
if (gn_system_verilog()) {
|
||||||
|
yyerror(@2, "sorry: Streaming concatenation not supported.");
|
||||||
|
$$ = 0;
|
||||||
|
} else {
|
||||||
|
yyerror(@2, "error: Streaming concatenation requires SystemVerilog");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/* The task declaration rule matches the task declaration
|
/* The task declaration rule matches the task declaration
|
||||||
header, then pushes the function scope. This causes the
|
header, then pushes the function scope. This causes the
|
||||||
definitions in the task_body to take on the scope of the task
|
definitions in the task_body to take on the scope of the task
|
||||||
|
|
@ -1350,7 +1475,8 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
||||||
port_declaration_context.sign_flag = true;
|
port_declaration_context.sign_flag = true;
|
||||||
delete port_declaration_context.range;
|
delete port_declaration_context.range;
|
||||||
port_declaration_context.range = copy_range(range_stub);
|
port_declaration_context.range = copy_range(range_stub);
|
||||||
svector<PWire*>*tmp = pform_make_task_ports(@3, $1, IVL_VT_LOGIC, true,
|
svector<PWire*>*tmp = pform_make_task_ports(@3, use_port_type,
|
||||||
|
IVL_VT_LOGIC, true,
|
||||||
range_stub,
|
range_stub,
|
||||||
list_from_identifier($3), true);
|
list_from_identifier($3), true);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -1424,7 +1550,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
||||||
FILE_NAME($2, @3);
|
FILE_NAME($2, @3);
|
||||||
}
|
}
|
||||||
port_declaration_context.data_type = $2;
|
port_declaration_context.data_type = $2;
|
||||||
tmp = pform_make_task_ports(@3, $1, $2, ilist);
|
tmp = pform_make_task_ports(@3, use_port_type, $2, ilist);
|
||||||
}
|
}
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
if ($4) {
|
if ($4) {
|
||||||
|
|
@ -1437,12 +1563,6 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
| port_direction_opt data_type_or_implicit IDENTIFIER '[' '$' ']'
|
|
||||||
{ yyerror(@5, "sorry: Queues not supported here.");
|
|
||||||
delete[]$3;
|
|
||||||
$$ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rules to match error cases... */
|
/* Rules to match error cases... */
|
||||||
|
|
||||||
| port_direction_opt data_type_or_implicit IDENTIFIER error
|
| port_direction_opt data_type_or_implicit IDENTIFIER error
|
||||||
|
|
@ -1495,6 +1615,13 @@ tf_port_list /* IEEE1800-2005: A.2.7 */
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
value_range /* IEEE1800-2005: A.8.3 */
|
||||||
|
: expression
|
||||||
|
{ }
|
||||||
|
| '[' expression ':' expression ']'
|
||||||
|
{ }
|
||||||
|
;
|
||||||
|
|
||||||
variable_dimension /* IEEE1800-2005: A.2.5 */
|
variable_dimension /* IEEE1800-2005: A.2.5 */
|
||||||
: '[' expression ':' expression ']'
|
: '[' expression ':' expression ']'
|
||||||
{ list<index_component_t> *tmp = new list<index_component_t>;
|
{ list<index_component_t> *tmp = new list<index_component_t>;
|
||||||
|
|
@ -1529,6 +1656,20 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
|
||||||
tmp->push_back(index);
|
tmp->push_back(index);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| '[' '$' ']'
|
||||||
|
{ // SystemVerilog queue
|
||||||
|
list<index_component_t> *tmp = new list<index_component_t>;
|
||||||
|
index_component_t index;
|
||||||
|
index.msb = 0;
|
||||||
|
index.lsb = 0;
|
||||||
|
if (gn_system_verilog()) {
|
||||||
|
yyerror("sorry: Dynamic array ranges not supported.");
|
||||||
|
} else {
|
||||||
|
yyerror("error: Queue declarations require System Verilog.");
|
||||||
|
}
|
||||||
|
tmp->push_back(index);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Verilog-2001 supports attribute lists, which can be attached to a
|
/* Verilog-2001 supports attribute lists, which can be attached to a
|
||||||
|
|
@ -2306,10 +2447,12 @@ branch_probe_expression
|
||||||
;
|
;
|
||||||
|
|
||||||
expression
|
expression
|
||||||
: expr_primary
|
: expr_primary
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| inc_or_dec_expression
|
| inc_or_dec_expression
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
|
| inside_expression
|
||||||
|
{ $$ = $1; }
|
||||||
| '+' expr_primary %prec UNARY_PREC
|
| '+' expr_primary %prec UNARY_PREC
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
| '-' expr_primary %prec UNARY_PREC
|
| '-' expr_primary %prec UNARY_PREC
|
||||||
|
|
@ -2678,6 +2821,11 @@ expr_primary
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| implicit_class_handle '.' hierarchy_identifier
|
||||||
|
{ yyerror(@1, "sorry: Implicit class handles (this/super) are not supported.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Many of the VAMS built-in functions are available as builtin
|
/* Many of the VAMS built-in functions are available as builtin
|
||||||
functions with $system_function equivalents. */
|
functions with $system_function equivalents. */
|
||||||
|
|
||||||
|
|
@ -2881,6 +3029,16 @@ expr_primary
|
||||||
yyerrok;
|
yyerrok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| '{' '}'
|
||||||
|
{ // This is the empty queue syntax.
|
||||||
|
if (gn_system_verilog()) {
|
||||||
|
yyerror(@1, "sorry: Expty queue expressions not supported.");
|
||||||
|
} else {
|
||||||
|
yyerror(@1, "error: Concatenations are not allowed to be empty.");
|
||||||
|
}
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cast expressions are primaries */
|
/* Cast expressions are primaries */
|
||||||
|
|
||||||
| DEC_NUMBER '\'' '(' expression ')'
|
| DEC_NUMBER '\'' '(' expression ')'
|
||||||
|
|
@ -2901,6 +3059,14 @@ expr_primary
|
||||||
| assignment_pattern
|
| assignment_pattern
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
|
|
||||||
|
/* SystemVerilog supports streaming concatenation */
|
||||||
|
| streaming_concatenation
|
||||||
|
{ $$ = $1; }
|
||||||
|
|
||||||
|
| K_null
|
||||||
|
{ yyerror("sorry: null expressions not supported yet.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* A function_item_list borrows the task_port_item run to match
|
/* A function_item_list borrows the task_port_item run to match
|
||||||
|
|
@ -3533,6 +3699,11 @@ lpvalue
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| streaming_concatenation
|
||||||
|
{ yyerror(@1, "sorry: streaming concatenation not supported in l-values.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -5338,6 +5509,8 @@ statement /* This is roughly statement_item in the LRM */
|
||||||
|
|
||||||
| loop_statement { $$ = $1; }
|
| loop_statement { $$ = $1; }
|
||||||
|
|
||||||
|
| jump_statement { $$ = $1; }
|
||||||
|
|
||||||
| K_case '(' expression ')' case_items K_endcase
|
| K_case '(' expression ')' case_items K_endcase
|
||||||
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
|
@ -5495,6 +5668,15 @@ statement /* This is roughly statement_item in the LRM */
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The class new and dynamic array new expressions are special, so
|
||||||
|
sit in rules of their own. */
|
||||||
|
|
||||||
|
| lpvalue '=' class_new ';'
|
||||||
|
{ PAssign*tmp = new PAssign($1,$3);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
| K_wait '(' expression ')' statement_or_null
|
| K_wait '(' expression ')' statement_or_null
|
||||||
{ PEventStatement*tmp;
|
{ PEventStatement*tmp;
|
||||||
PEEvent*etmp = new PEEvent(PEEvent::POSITIVE, $3);
|
PEEvent*etmp = new PEEvent(PEEvent::POSITIVE, $3);
|
||||||
|
|
@ -5980,4 +6162,5 @@ udp_primitive
|
||||||
K_automatic_opt: K_automatic { $$ = true; } | { $$ = false;} ;
|
K_automatic_opt: K_automatic { $$ = true; } | { $$ = false;} ;
|
||||||
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
|
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
|
||||||
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
|
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
|
||||||
|
K_static_opt : K_static { $$ = true; } | { $$ = false; } ;
|
||||||
K_virtual_opt : K_virtual { $$ = true; } | { $$ = false; } ;
|
K_virtual_opt : K_virtual { $$ = true; } | { $$ = false; } ;
|
||||||
|
|
|
||||||
75
pform.cc
75
pform.cc
|
|
@ -2075,39 +2075,6 @@ void pform_makewire(const vlltype&li,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_port_type(perm_string name, NetNet::PortType pt,
|
|
||||||
const char*file, unsigned lineno)
|
|
||||||
{
|
|
||||||
PWire*cur = pform_get_wire_in_scope(name);
|
|
||||||
if (cur == 0) {
|
|
||||||
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_NO_TYPE);
|
|
||||||
FILE_NAME(cur, file, lineno);
|
|
||||||
pform_put_wire_in_scope(name, cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cur->get_port_type()) {
|
|
||||||
case NetNet::PIMPLICIT:
|
|
||||||
if (! cur->set_port_type(pt))
|
|
||||||
VLerror("error setting port direction.");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NetNet::NOT_A_PORT:
|
|
||||||
cerr << file << ":" << lineno << ": error: "
|
|
||||||
<< "port " << name << " is not in the port list."
|
|
||||||
<< endl;
|
|
||||||
error_count += 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
cerr << file << ":" << lineno << ": error: "
|
|
||||||
<< "port " << name << " already has a port declaration."
|
|
||||||
<< endl;
|
|
||||||
error_count += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called by the parser to create task ports. The
|
* This function is called by the parser to create task ports. The
|
||||||
* resulting wire (which should be a register) is put into a list to
|
* resulting wire (which should be a register) is put into a list to
|
||||||
|
|
@ -2155,6 +2122,7 @@ svector<PWire*>*pform_make_task_ports(const struct vlltype&loc,
|
||||||
list<perm_string>*names,
|
list<perm_string>*names,
|
||||||
bool isint)
|
bool isint)
|
||||||
{
|
{
|
||||||
|
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT);
|
||||||
assert(names);
|
assert(names);
|
||||||
svector<PWire*>*res = new svector<PWire*>(0);
|
svector<PWire*>*res = new svector<PWire*>(0);
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
for (list<perm_string>::iterator cur = names->begin()
|
||||||
|
|
@ -2513,12 +2481,48 @@ extern void pform_module_specify_path(PSpecPath*obj)
|
||||||
pform_cur_module->specify_paths.push_back(obj);
|
pform_cur_module->specify_paths.push_back(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void pform_set_port_type(perm_string name, NetNet::PortType pt,
|
||||||
|
const char*file, unsigned lineno)
|
||||||
|
{
|
||||||
|
PWire*cur = pform_get_wire_in_scope(name);
|
||||||
|
if (cur == 0) {
|
||||||
|
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_NO_TYPE);
|
||||||
|
FILE_NAME(cur, file, lineno);
|
||||||
|
pform_put_wire_in_scope(name, cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cur->get_port_type()) {
|
||||||
|
case NetNet::PIMPLICIT:
|
||||||
|
if (! cur->set_port_type(pt))
|
||||||
|
VLerror("error setting port direction.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetNet::NOT_A_PORT:
|
||||||
|
cerr << file << ":" << lineno << ": error: "
|
||||||
|
<< "port " << name << " is not in the port list."
|
||||||
|
<< endl;
|
||||||
|
error_count += 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
cerr << file << ":" << lineno << ": error: "
|
||||||
|
<< "port " << name << " already has a port declaration."
|
||||||
|
<< endl;
|
||||||
|
error_count += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void pform_set_port_type(const struct vlltype&li,
|
void pform_set_port_type(const struct vlltype&li,
|
||||||
list<perm_string>*names,
|
list<perm_string>*names,
|
||||||
list<index_component_t>*range,
|
list<index_component_t>*range,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
NetNet::PortType pt)
|
NetNet::PortType pt)
|
||||||
{
|
{
|
||||||
|
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT);
|
||||||
|
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
for (list<perm_string>::iterator cur = names->begin()
|
||||||
; cur != names->end() ; ++ cur ) {
|
; cur != names->end() ; ++ cur ) {
|
||||||
perm_string txt = *cur;
|
perm_string txt = *cur;
|
||||||
|
|
@ -2636,6 +2640,11 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (class_type_t*class_type = dynamic_cast<class_type_t*> (data_type)) {
|
||||||
|
VLerror(li, "sorry: Class types not supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
pform.h
3
pform.h
|
|
@ -282,8 +282,7 @@ extern void pform_set_port_type(const struct vlltype&li,
|
||||||
list<index_component_t>*range,
|
list<index_component_t>*range,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
NetNet::PortType);
|
NetNet::PortType);
|
||||||
extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
|
||||||
const char*file, unsigned lineno);
|
|
||||||
|
|
||||||
extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r);
|
extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r);
|
||||||
extern void pform_set_reg_integer(list<perm_string>*names);
|
extern void pform_set_reg_integer(list<perm_string>*names);
|
||||||
|
|
|
||||||
|
|
@ -577,7 +577,10 @@ void PAssign::dump(ostream&out, unsigned ind) const
|
||||||
if (delay_) out << "#" << *delay_ << " ";
|
if (delay_) out << "#" << *delay_ << " ";
|
||||||
if (count_) out << "repeat(" << *count_ << ") ";
|
if (count_) out << "repeat(" << *count_ << ") ";
|
||||||
if (event_) out << *event_ << " ";
|
if (event_) out << *event_ << " ";
|
||||||
out << *rval() << ";" << " /* " << get_fileline() << " */" << endl;
|
PExpr*rexpr = rval();
|
||||||
|
if (rexpr) out << *rval() << ";";
|
||||||
|
else out << "<no rval>;";
|
||||||
|
out << " /* " << get_fileline() << " */" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PAssignNB::dump(ostream&out, unsigned ind) const
|
void PAssignNB::dump(ostream&out, unsigned ind) const
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue