commit
cce30e89bb
5
PExpr.cc
5
PExpr.cc
|
|
@ -126,9 +126,8 @@ PEBinary::~PEBinary()
|
||||||
|
|
||||||
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||||
{
|
{
|
||||||
assert(left_ && right_);
|
if (left_) left_->declare_implicit_nets(scope, type);
|
||||||
left_->declare_implicit_nets(scope, type);
|
if (right_) right_->declare_implicit_nets(scope, type);
|
||||||
right_->declare_implicit_nets(scope, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,8 @@ const pform_name_t& PCallTask::path() const
|
||||||
return path_;
|
return path_;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
PCase::PCase(ivl_case_quality_t q, NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||||
: type_(t), expr_(ex), items_(l)
|
: quality_(q), type_(t), expr_(ex), items_(l)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ class PCase : public Statement {
|
||||||
Statement*stat;
|
Statement*stat;
|
||||||
};
|
};
|
||||||
|
|
||||||
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
||||||
~PCase();
|
~PCase();
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
|
|
@ -263,6 +263,7 @@ class PCase : public Statement {
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ivl_case_quality_t quality_;
|
||||||
NetCase::TYPE type_;
|
NetCase::TYPE type_;
|
||||||
PExpr*expr_;
|
PExpr*expr_;
|
||||||
|
|
||||||
|
|
|
||||||
11
compiler.h
11
compiler.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_compiler_H
|
#ifndef IVL_compiler_H
|
||||||
#define IVL_compiler_H
|
#define IVL_compiler_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -177,9 +177,12 @@ extern bool gn_icarus_misc_flag;
|
||||||
is false, then skip elaboration of specify behavior. */
|
is false, then skip elaboration of specify behavior. */
|
||||||
extern bool gn_specify_blocks_flag;
|
extern bool gn_specify_blocks_flag;
|
||||||
|
|
||||||
/* If this flag is true, then elaborate assertions. If this flag is
|
/* If this flag is true, then elaborate supported assertion statements. If
|
||||||
false, then stub out assertion statements. */
|
this flag is false, then stub out supported assertion statements. */
|
||||||
extern bool gn_assertions_flag;
|
extern bool gn_supported_assertions_flag;
|
||||||
|
/* If this flag is true, then error on unsupported assertion statements. If
|
||||||
|
this flag is false, then stub out unsupported assertion statements. */
|
||||||
|
extern bool gn_unsupported_assertions_flag;
|
||||||
|
|
||||||
/* If this flag is true, then support/elaborate Verilog-AMS. */
|
/* If this flag is true, then support/elaborate Verilog-AMS. */
|
||||||
extern bool gn_verilog_ams_flag;
|
extern bool gn_verilog_ams_flag;
|
||||||
|
|
|
||||||
|
|
@ -1150,15 +1150,29 @@ void NetBlock::dump(ostream&o, unsigned ind) const
|
||||||
|
|
||||||
void NetCase::dump(ostream&o, unsigned ind) const
|
void NetCase::dump(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
|
o << setw(ind) << "";
|
||||||
|
switch (quality_) {
|
||||||
|
case IVL_CASE_QUALITY_BASIC:
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_UNIQUE:
|
||||||
|
o << "unique ";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_UNIQUE0:
|
||||||
|
o << "unique0 ";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_PRIORITY:
|
||||||
|
o << "priority ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case EQ:
|
case EQ:
|
||||||
o << setw(ind) << "" << "case (" << *expr_ << ")" << endl;
|
o << "case (" << *expr_ << ")" << endl;
|
||||||
break;
|
break;
|
||||||
case EQX:
|
case EQX:
|
||||||
o << setw(ind) << "" << "casex (" << *expr_ << ")" << endl;
|
o << "casex (" << *expr_ << ")" << endl;
|
||||||
break;
|
break;
|
||||||
case EQZ:
|
case EQZ:
|
||||||
o << setw(ind) << "" << "casez (" << *expr_ << ")" << endl;
|
o << "casez (" << *expr_ << ")" << endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
.TH iverilog 1 "Sep 20th, 2019" "" "Version %M.%n%E"
|
.TH iverilog 1 "Oct 5th, 2019" "" "Version %M.%n%E"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
iverilog - Icarus Verilog compiler
|
iverilog - Icarus Verilog compiler
|
||||||
|
|
||||||
|
|
@ -80,10 +80,11 @@ use any of the new \fIIEEE1800\fP keywords.
|
||||||
Enable or disable (default) support for Verilog\-AMS.
|
Enable or disable (default) support for Verilog\-AMS.
|
||||||
Very little Verilog\-AMS specific functionality is currently supported.
|
Very little Verilog\-AMS specific functionality is currently supported.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -gassertions\fI|\fP-gno-assertions
|
.B -gassertions\fI|\fP-gsupported-assertions\fI|\fP-gno-assertions
|
||||||
Enable (default) or disable SystemVerilog assertions. When enabled,
|
Enable (default) or disable SystemVerilog assertions. When enabled,
|
||||||
assertion statements are elaborated. When disabled, assertion statements
|
assertion statements are elaborated. When disabled, assertion statements
|
||||||
are parsed but ignored.
|
are parsed but ignored. The \fB\-gsupported-assertions\fP option only
|
||||||
|
enables assertions that are currently supported by the compiler.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -gspecify\fI|\fP-gno-specify
|
.B -gspecify\fI|\fP-gno-specify
|
||||||
Enable or disable (default) specify block support. When enabled,
|
Enable or disable (default) specify block support. When enabled,
|
||||||
|
|
@ -129,7 +130,7 @@ default, parts of the expression that do not depend on the changed
|
||||||
input value(s) are not re-evaluated. If an expression contains a call
|
input value(s) are not re-evaluated. If an expression contains a call
|
||||||
to a function that doesn't depend solely on its input values or that
|
to a function that doesn't depend solely on its input values or that
|
||||||
has side effects, the resulting behavior will differ from that
|
has side effects, the resulting behavior will differ from that
|
||||||
required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
|
required by the standard. Using \fB\-gstrict\-ca\-eval\fP will force
|
||||||
standard compliant behavior (with some loss in performance).
|
standard compliant behavior (with some loss in performance).
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -748,6 +748,9 @@ static int process_generation(const char*name)
|
||||||
else if (strcmp(name,"assertions") == 0)
|
else if (strcmp(name,"assertions") == 0)
|
||||||
gen_assertions = "assertions";
|
gen_assertions = "assertions";
|
||||||
|
|
||||||
|
else if (strcmp(name,"supported-assertions") == 0)
|
||||||
|
gen_assertions = "supported-assertions";
|
||||||
|
|
||||||
else if (strcmp(name,"no-assertions") == 0)
|
else if (strcmp(name,"no-assertions") == 0)
|
||||||
gen_assertions = "no-assertions";
|
gen_assertions = "no-assertions";
|
||||||
|
|
||||||
|
|
@ -804,6 +807,7 @@ static int process_generation(const char*name)
|
||||||
" 2009 -- IEEE1800-2009\n"
|
" 2009 -- IEEE1800-2009\n"
|
||||||
" 2012 -- IEEE1800-2012\n"
|
" 2012 -- IEEE1800-2012\n"
|
||||||
"Other generation flags:\n"
|
"Other generation flags:\n"
|
||||||
|
" assertions | supported-assertions | no-assertions\n"
|
||||||
" specify | no-specify\n"
|
" specify | no-specify\n"
|
||||||
" verilog-ams | no-verilog-ams\n"
|
" verilog-ams | no-verilog-ams\n"
|
||||||
" std-include | no-std-include\n"
|
" std-include | no-std-include\n"
|
||||||
|
|
@ -1176,7 +1180,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (version_flag || verbose_flag) {
|
if (version_flag || verbose_flag) {
|
||||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||||
printf("Copyright 1998-2017 Stephen Williams\n\n");
|
printf("Copyright 1998-2019 Stephen Williams\n\n");
|
||||||
puts(NOTICE);
|
puts(NOTICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2321,8 +2321,6 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
if (!is_constant_ || !rv) return rv;
|
if (!is_constant_ || !rv) return rv;
|
||||||
|
|
||||||
if (dynamic_cast<NetENew*>(rv)) return rv;
|
|
||||||
|
|
||||||
cerr << get_fileline() << ": error: "
|
cerr << get_fileline() << ": error: "
|
||||||
"The RHS expression must be constant." << endl;
|
"The RHS expression must be constant." << endl;
|
||||||
cerr << get_fileline() << " : "
|
cerr << get_fileline() << " : "
|
||||||
|
|
@ -3129,7 +3127,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
||||||
icount += cur->expr.size();
|
icount += cur->expr.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetCase*res = new NetCase(type_, expr, icount);
|
NetCase*res = new NetCase(quality_, type_, expr, icount);
|
||||||
res->set_line(*this);
|
res->set_line(*this);
|
||||||
|
|
||||||
/* Iterate over all the case items (guard/statement pairs)
|
/* Iterate over all the case items (guard/statement pairs)
|
||||||
|
|
|
||||||
10
ivl_target.h
10
ivl_target.h
|
|
@ -434,6 +434,14 @@ typedef enum ivl_statement_type_e {
|
||||||
IVL_ST_WHILE = 23
|
IVL_ST_WHILE = 23
|
||||||
} ivl_statement_type_t;
|
} ivl_statement_type_t;
|
||||||
|
|
||||||
|
/* Case statements can be tagged as unique/unique0/priority. */
|
||||||
|
typedef enum ivl_case_quality_t {
|
||||||
|
IVL_CASE_QUALITY_BASIC = 0, /* no quality flags */
|
||||||
|
IVL_CASE_QUALITY_UNIQUE = 1,
|
||||||
|
IVL_CASE_QUALITY_UNIQUE0 = 2,
|
||||||
|
IVL_CASE_QUALITY_PRIORITY = 3
|
||||||
|
} ivl_case_quality_t;
|
||||||
|
|
||||||
/* SystemVerilog allows a system function to be called as a task. */
|
/* SystemVerilog allows a system function to be called as a task. */
|
||||||
typedef enum ivl_sfunc_as_task_e {
|
typedef enum ivl_sfunc_as_task_e {
|
||||||
IVL_SFUNC_AS_TASK_ERROR = 0,
|
IVL_SFUNC_AS_TASK_ERROR = 0,
|
||||||
|
|
@ -2222,6 +2230,8 @@ extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
|
||||||
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
||||||
/* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
/* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
||||||
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
|
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
|
||||||
|
/* IVL+ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
||||||
|
extern ivl_case_quality_t ivl_stmt_case_quality(ivl_statement_t net);
|
||||||
/* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
/* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */
|
||||||
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
|
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
|
||||||
/* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */
|
/* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */
|
||||||
|
|
|
||||||
15
main.cc
15
main.cc
|
|
@ -1,5 +1,5 @@
|
||||||
const char COPYRIGHT[] =
|
const char COPYRIGHT[] =
|
||||||
"Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)";
|
"Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -104,7 +104,8 @@ generation_t generation_flag = GN_DEFAULT;
|
||||||
bool gn_icarus_misc_flag = true;
|
bool gn_icarus_misc_flag = true;
|
||||||
bool gn_cadence_types_flag = true;
|
bool gn_cadence_types_flag = true;
|
||||||
bool gn_specify_blocks_flag = true;
|
bool gn_specify_blocks_flag = true;
|
||||||
bool gn_assertions_flag = true;
|
bool gn_supported_assertions_flag = true;
|
||||||
|
bool gn_unsupported_assertions_flag = true;
|
||||||
bool gn_io_range_error_flag = true;
|
bool gn_io_range_error_flag = true;
|
||||||
bool gn_strict_ca_eval_flag = false;
|
bool gn_strict_ca_eval_flag = false;
|
||||||
bool gn_strict_expr_width_flag = false;
|
bool gn_strict_expr_width_flag = false;
|
||||||
|
|
@ -331,10 +332,16 @@ static void process_generation_flag(const char*gen)
|
||||||
gn_specify_blocks_flag = false;
|
gn_specify_blocks_flag = false;
|
||||||
|
|
||||||
} else if (strcmp(gen,"assertions") == 0) {
|
} else if (strcmp(gen,"assertions") == 0) {
|
||||||
gn_assertions_flag = true;
|
gn_supported_assertions_flag = true;
|
||||||
|
gn_unsupported_assertions_flag = true;
|
||||||
|
|
||||||
|
} else if (strcmp(gen,"supported-assertions") == 0) {
|
||||||
|
gn_supported_assertions_flag = true;
|
||||||
|
gn_unsupported_assertions_flag = false;
|
||||||
|
|
||||||
} else if (strcmp(gen,"no-assertions") == 0) {
|
} else if (strcmp(gen,"no-assertions") == 0) {
|
||||||
gn_assertions_flag = false;
|
gn_supported_assertions_flag = false;
|
||||||
|
gn_unsupported_assertions_flag = false;
|
||||||
|
|
||||||
} else if (strcmp(gen,"verilog-ams") == 0) {
|
} else if (strcmp(gen,"verilog-ams") == 0) {
|
||||||
gn_verilog_ams_flag = true;
|
gn_verilog_ams_flag = true;
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,8 @@ const NetProc* NetBlock::proc_next(const NetProc*cur) const
|
||||||
return cur->next_;
|
return cur->next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetCase::NetCase(NetCase::TYPE c, NetExpr*ex, unsigned cnt)
|
NetCase::NetCase(ivl_case_quality_t q, NetCase::TYPE c, NetExpr*ex, unsigned cnt)
|
||||||
: type_(c), expr_(ex), items_(cnt)
|
: quality_(q), type_(c), expr_(ex), items_(cnt)
|
||||||
{
|
{
|
||||||
ivl_assert(*this, expr_);
|
ivl_assert(*this, expr_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3050,6 +3050,9 @@ class NetBlock : public NetProc {
|
||||||
* way the comparisons are performed. Also, it is likely that the
|
* way the comparisons are performed. Also, it is likely that the
|
||||||
* target may be able to optimize differently.
|
* target may be able to optimize differently.
|
||||||
*
|
*
|
||||||
|
* Case statements can have unique, unique0, or priority attached to
|
||||||
|
* them. If not otherwise adorned, it is QBASIC.
|
||||||
|
*
|
||||||
* Case can be one of three types:
|
* Case can be one of three types:
|
||||||
* EQ -- All bits must exactly match
|
* EQ -- All bits must exactly match
|
||||||
* EQZ -- z bits are don't care
|
* EQZ -- z bits are don't care
|
||||||
|
|
@ -3059,13 +3062,15 @@ class NetCase : public NetProc {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum TYPE { EQ, EQX, EQZ };
|
enum TYPE { EQ, EQX, EQZ };
|
||||||
NetCase(TYPE c, NetExpr*ex, unsigned cnt);
|
|
||||||
|
NetCase(ivl_case_quality_t q, TYPE c, NetExpr*ex, unsigned cnt);
|
||||||
~NetCase();
|
~NetCase();
|
||||||
|
|
||||||
void set_case(unsigned idx, NetExpr*ex, NetProc*st);
|
void set_case(unsigned idx, NetExpr*ex, NetProc*st);
|
||||||
|
|
||||||
void prune();
|
void prune();
|
||||||
|
|
||||||
|
inline ivl_case_quality_t case_quality() const { return quality_; }
|
||||||
TYPE type() const;
|
TYPE type() const;
|
||||||
const NetExpr*expr() const { return expr_; }
|
const NetExpr*expr() const { return expr_; }
|
||||||
inline unsigned nitems() const { return items_.size(); }
|
inline unsigned nitems() const { return items_.size(); }
|
||||||
|
|
@ -3097,6 +3102,7 @@ class NetCase : public NetProc {
|
||||||
NexusSet&nex_map, NetBus&nex_out,
|
NexusSet&nex_map, NetBus&nex_out,
|
||||||
NetBus&enables, vector<mask_t>&bitmasks);
|
NetBus&enables, vector<mask_t>&bitmasks);
|
||||||
|
|
||||||
|
ivl_case_quality_t quality_;
|
||||||
TYPE type_;
|
TYPE type_;
|
||||||
|
|
||||||
struct Item {
|
struct Item {
|
||||||
|
|
|
||||||
356
parse.y
356
parse.y
|
|
@ -408,6 +408,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
|
|
||||||
svector<PEEvent*>*event_expr;
|
svector<PEEvent*>*event_expr;
|
||||||
|
|
||||||
|
ivl_case_quality_t case_quality;
|
||||||
NetNet::Type nettype;
|
NetNet::Type nettype;
|
||||||
PGBuiltin::Type gatetype;
|
PGBuiltin::Type gatetype;
|
||||||
NetNet::PortType porttype;
|
NetNet::PortType porttype;
|
||||||
|
|
@ -575,6 +576,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
%type <expr> udp_initial_expr_opt
|
%type <expr> udp_initial_expr_opt
|
||||||
|
|
||||||
%type <text> register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt
|
%type <text> register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt
|
||||||
|
%type <text> block_identifier_opt
|
||||||
%type <perm_strings> register_variable_list net_variable_list event_variable_list
|
%type <perm_strings> register_variable_list net_variable_list event_variable_list
|
||||||
%type <perm_strings> list_of_identifiers loop_variables
|
%type <perm_strings> list_of_identifiers loop_variables
|
||||||
%type <port_list> list_of_port_identifiers list_of_variable_port_identifiers
|
%type <port_list> list_of_port_identifiers list_of_variable_port_identifiers
|
||||||
|
|
@ -652,6 +654,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
%type <statement> statement statement_item statement_or_null
|
%type <statement> statement statement_item statement_or_null
|
||||||
%type <statement> compressed_statement
|
%type <statement> compressed_statement
|
||||||
%type <statement> loop_statement for_step jump_statement
|
%type <statement> loop_statement for_step jump_statement
|
||||||
|
%type <statement> concurrent_assertion_statement
|
||||||
|
%type <statement> deferred_immediate_assertion_statement
|
||||||
|
%type <statement> simple_immediate_assertion_statement
|
||||||
%type <statement> procedural_assertion_statement
|
%type <statement> procedural_assertion_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
|
||||||
|
|
||||||
|
|
@ -667,11 +672,14 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
|
|
||||||
%type <real_type> non_integer_type
|
%type <real_type> non_integer_type
|
||||||
%type <int_val> assert_or_assume
|
%type <int_val> assert_or_assume
|
||||||
|
%type <int_val> deferred_mode
|
||||||
%type <int_val> atom2_type
|
%type <int_val> atom2_type
|
||||||
%type <int_val> module_start module_end
|
%type <int_val> module_start module_end
|
||||||
|
|
||||||
%type <lifetime> lifetime lifetime_opt
|
%type <lifetime> lifetime lifetime_opt
|
||||||
|
|
||||||
|
%type <case_quality> unique_priority
|
||||||
|
|
||||||
%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
|
||||||
|
|
@ -724,6 +732,7 @@ assert_or_assume
|
||||||
|
|
||||||
assertion_item /* IEEE1800-2012: A.6.10 */
|
assertion_item /* IEEE1800-2012: A.6.10 */
|
||||||
: concurrent_assertion_item
|
: concurrent_assertion_item
|
||||||
|
| deferred_immediate_assertion_item
|
||||||
;
|
;
|
||||||
|
|
||||||
assignment_pattern /* IEEE1800-2005: A.6.7.1 */
|
assignment_pattern /* IEEE1800-2005: A.6.7.1 */
|
||||||
|
|
@ -744,7 +753,9 @@ assignment_pattern /* IEEE1800-2005: A.6.7.1 */
|
||||||
implements it in a LALR way. */
|
implements it in a LALR way. */
|
||||||
block_identifier_opt /* */
|
block_identifier_opt /* */
|
||||||
: IDENTIFIER ':'
|
: IDENTIFIER ':'
|
||||||
|
{ $$ = $1; }
|
||||||
|
|
|
|
||||||
|
{ $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
class_declaration /* IEEE1800-2005: A.1.2 */
|
class_declaration /* IEEE1800-2005: A.1.2 */
|
||||||
|
|
@ -988,16 +999,98 @@ class_new /* IEEE1800-2005 A.2.4 */
|
||||||
concurrent_assertion_statement and checker_instantiation rules. */
|
concurrent_assertion_statement and checker_instantiation rules. */
|
||||||
|
|
||||||
concurrent_assertion_item /* IEEE1800-2012 A.2.10 */
|
concurrent_assertion_item /* IEEE1800-2012 A.2.10 */
|
||||||
: block_identifier_opt K_assert K_property '(' property_spec ')' statement_or_null
|
: block_identifier_opt concurrent_assertion_statement
|
||||||
|
{ delete $1;
|
||||||
|
delete $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
concurrent_assertion_statement /* IEEE1800-2012 A.2.10 */
|
||||||
|
: assert_or_assume K_property '(' property_spec ')' statement_or_null %prec less_than_K_else
|
||||||
{ /* */
|
{ /* */
|
||||||
if (gn_assertions_flag) {
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: concurrent_assertion_item not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume K_property '(' property_spec ')' K_else statement_or_null
|
||||||
|
{ /* */
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: concurrent_assertion_item not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume K_property '(' property_spec ')' statement_or_null K_else statement_or_null
|
||||||
|
{ /* */
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: concurrent_assertion_item not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_cover K_property '(' property_spec ')' statement_or_null
|
||||||
|
{ /* */
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: concurrent_assertion_item not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
/* For now, cheat, and use property_spec for the sequence specification.
|
||||||
|
They are syntactically identical. */
|
||||||
|
| K_cover K_sequence '(' property_spec ')' statement_or_null
|
||||||
|
{ /* */
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: concurrent_assertion_item not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_restrict K_property '(' property_spec ')' ';'
|
||||||
|
{ /* */
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
yyerror(@2, "sorry: concurrent_assertion_item not supported."
|
yyerror(@2, "sorry: concurrent_assertion_item not supported."
|
||||||
" Try -gno-assertion to turn this message off.");
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
}
|
}
|
||||||
|
$$ = 0;
|
||||||
}
|
}
|
||||||
| block_identifier_opt K_assert K_property '(' error ')' statement_or_null
|
| assert_or_assume K_property '(' error ')' statement_or_null %prec less_than_K_else
|
||||||
{ yyerrok;
|
{ yyerrok;
|
||||||
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume K_property '(' error ')' K_else statement_or_null
|
||||||
|
{ yyerrok;
|
||||||
|
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume K_property '(' error ')' statement_or_null K_else statement_or_null
|
||||||
|
{ yyerrok;
|
||||||
|
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_cover K_property '(' error ')' statement_or_null
|
||||||
|
{ yyerrok;
|
||||||
|
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_cover K_sequence '(' error ')' statement_or_null
|
||||||
|
{ yyerrok;
|
||||||
|
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_restrict K_property '(' error ')' ';'
|
||||||
|
{ yyerrok;
|
||||||
|
yyerror(@2, "error: Error in property_spec of concurrent assertion item.");
|
||||||
|
$$ = 0;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -1061,6 +1154,7 @@ data_declaration /* IEEE1800-2005: A.2.1.3 */
|
||||||
| attribute_list_opt K_event event_variable_list ';'
|
| attribute_list_opt K_event event_variable_list ';'
|
||||||
{ if ($3) pform_make_events($3, @2.text, @2.first_line);
|
{ if ($3) pform_make_events($3, @2.text, @2.first_line);
|
||||||
}
|
}
|
||||||
|
| attribute_list_opt package_import_declaration
|
||||||
;
|
;
|
||||||
|
|
||||||
data_type /* IEEE1800-2005: A.2.2.1 */
|
data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
|
|
@ -1166,6 +1260,84 @@ data_type_or_implicit_or_void
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
deferred_immediate_assertion_item /* IEEE1800-2012: A.6.10 */
|
||||||
|
: block_identifier_opt deferred_immediate_assertion_statement
|
||||||
|
{ delete $1;
|
||||||
|
delete $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
deferred_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */
|
||||||
|
: assert_or_assume deferred_mode '(' expression ')' statement_or_null %prec less_than_K_else
|
||||||
|
{
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: Deferred assertions are not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
delete $4;
|
||||||
|
delete $6;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume deferred_mode '(' expression ')' K_else statement_or_null
|
||||||
|
{
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: Deferred assertions are not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
delete $4;
|
||||||
|
delete $7;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume deferred_mode '(' expression ')' statement_or_null K_else statement_or_null
|
||||||
|
{
|
||||||
|
if (gn_unsupported_assertions_flag) {
|
||||||
|
yyerror(@1, "sorry: Deferred assertions are not supported."
|
||||||
|
" Try -gno-assertions or -gsupported-assertions"
|
||||||
|
" to turn this message off.");
|
||||||
|
}
|
||||||
|
delete $4;
|
||||||
|
delete $6;
|
||||||
|
delete $8;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| K_cover deferred_mode '(' expression ')' statement_or_null
|
||||||
|
{
|
||||||
|
/* Coverage collection is not currently supported. */
|
||||||
|
delete $4;
|
||||||
|
delete $6;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume deferred_mode '(' error ')' statement_or_null %prec less_than_K_else
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $6;
|
||||||
|
}
|
||||||
|
| assert_or_assume deferred_mode '(' error ')' K_else statement_or_null
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $7;
|
||||||
|
}
|
||||||
|
| assert_or_assume deferred_mode '(' error ')' statement_or_null K_else statement_or_null
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $6;
|
||||||
|
}
|
||||||
|
| K_cover deferred_mode '(' error ')' statement_or_null
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $6;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
deferred_mode
|
||||||
|
: '#' DEC_NUMBER
|
||||||
|
{ if (!$2->is_zero()) {
|
||||||
|
yyerror(@2, "error: Delay value must be zero for deferred assertion.");
|
||||||
|
}
|
||||||
|
delete $2;
|
||||||
|
$$ = 0; }
|
||||||
|
| K_final
|
||||||
|
{ $$ = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
/* NOTE: The "module" rule of the description combines the
|
/* NOTE: The "module" rule of the description combines the
|
||||||
module_declaration, program_declaration, and interface_declaration
|
module_declaration, program_declaration, and interface_declaration
|
||||||
rules from the standard description. */
|
rules from the standard description. */
|
||||||
|
|
@ -1574,12 +1746,10 @@ variable_decl_assignment /* IEEE1800-2005 A.2.3 */
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| IDENTIFIER '=' K_new '(' ')'
|
| IDENTIFIER '=' class_new
|
||||||
{ decl_assignment_t*tmp = new decl_assignment_t;
|
{ decl_assignment_t*tmp = new decl_assignment_t;
|
||||||
tmp->name = lex_strings.make($1);
|
tmp->name = lex_strings.make($1);
|
||||||
PENewClass*expr = new PENewClass;
|
tmp->expr .reset($3);
|
||||||
FILE_NAME(expr, @3);
|
|
||||||
tmp->expr .reset(expr);
|
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -1845,65 +2015,17 @@ port_direction_opt
|
||||||
| { $$ = NetNet::PIMPLICIT; }
|
| { $$ = NetNet::PIMPLICIT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
property_expr /* IEEE1800-2012 A.2.10 */
|
procedural_assertion_statement /* IEEE1800-2012 A.6.10 */
|
||||||
: expression
|
: concurrent_assertion_statement
|
||||||
|
{ $$ = $1; }
|
||||||
|
| simple_immediate_assertion_statement
|
||||||
|
{ $$ = $1; }
|
||||||
|
| deferred_immediate_assertion_statement
|
||||||
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
procedural_assertion_statement /* IEEE1800-2012 A.6.10 */
|
property_expr /* IEEE1800-2012 A.2.10 */
|
||||||
// $assertcontrol is not yet supported.
|
: expression
|
||||||
: assert_or_assume '(' expression ')' statement_or_null %prec less_than_K_else
|
|
||||||
{
|
|
||||||
if (gn_assertions_flag) {
|
|
||||||
list<PExpr*>arg_list;
|
|
||||||
PCallTask*tmp1 = new PCallTask(lex_strings.make("$error"), arg_list);
|
|
||||||
FILE_NAME(tmp1, @1);
|
|
||||||
PCondit*tmp2 = new PCondit($3, $5, tmp1);
|
|
||||||
FILE_NAME(tmp2, @1);
|
|
||||||
$$ = tmp2;
|
|
||||||
} else {
|
|
||||||
$$ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| assert_or_assume '(' expression ')' K_else statement_or_null
|
|
||||||
{
|
|
||||||
if (gn_assertions_flag) {
|
|
||||||
PCondit*tmp = new PCondit($3, 0, $6);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
} else {
|
|
||||||
$$ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| assert_or_assume '(' expression ')' statement_or_null K_else statement_or_null
|
|
||||||
{
|
|
||||||
if (gn_assertions_flag) {
|
|
||||||
PCondit*tmp = new PCondit($3, $5, $7);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
} else {
|
|
||||||
$$ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| K_cover '(' expression ')' statement_or_null
|
|
||||||
// Coverage collection is not currently supported.
|
|
||||||
{ $$ = 0; }
|
|
||||||
|
|
||||||
| assert_or_assume '(' error ')' statement_or_null %prec less_than_K_else
|
|
||||||
{ yyerror(@1, "error: Malformed conditional expression.");
|
|
||||||
$$ = $5;
|
|
||||||
}
|
|
||||||
| assert_or_assume '(' error ')' K_else statement_or_null
|
|
||||||
{ yyerror(@1, "error: Malformed conditional expression.");
|
|
||||||
$$ = $6;
|
|
||||||
}
|
|
||||||
| assert_or_assume '(' error ')' statement_or_null K_else statement_or_null
|
|
||||||
{ yyerror(@1, "error: Malformed conditional expression.");
|
|
||||||
$$ = $5;
|
|
||||||
}
|
|
||||||
| K_cover '(' error ')' statement_or_null
|
|
||||||
{ yyerror(@1, "error: Malformed conditional expression.");
|
|
||||||
$$ = $5;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
/* The property_qualifier rule is as literally described in the LRM,
|
/* The property_qualifier rule is as literally described in the LRM,
|
||||||
|
|
@ -1956,6 +2078,72 @@ signing /* IEEE1800-2005: A.2.2.1 */
|
||||||
| K_unsigned { $$ = false; }
|
| K_unsigned { $$ = false; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
simple_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */
|
||||||
|
: assert_or_assume '(' expression ')' statement_or_null %prec less_than_K_else
|
||||||
|
{
|
||||||
|
if (gn_supported_assertions_flag) {
|
||||||
|
list<PExpr*>arg_list;
|
||||||
|
PCallTask*tmp1 = new PCallTask(lex_strings.make("$error"), arg_list);
|
||||||
|
FILE_NAME(tmp1, @1);
|
||||||
|
PCondit*tmp2 = new PCondit($3, $5, tmp1);
|
||||||
|
FILE_NAME(tmp2, @1);
|
||||||
|
$$ = tmp2;
|
||||||
|
} else {
|
||||||
|
delete $3;
|
||||||
|
delete $5;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| assert_or_assume '(' expression ')' K_else statement_or_null
|
||||||
|
{
|
||||||
|
if (gn_supported_assertions_flag) {
|
||||||
|
PCondit*tmp = new PCondit($3, 0, $6);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
$$ = tmp;
|
||||||
|
} else {
|
||||||
|
delete $3;
|
||||||
|
delete $6;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| assert_or_assume '(' expression ')' statement_or_null K_else statement_or_null
|
||||||
|
{
|
||||||
|
if (gn_supported_assertions_flag) {
|
||||||
|
PCondit*tmp = new PCondit($3, $5, $7);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
$$ = tmp;
|
||||||
|
} else {
|
||||||
|
delete $3;
|
||||||
|
delete $5;
|
||||||
|
delete $7;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| K_cover '(' expression ')' statement_or_null
|
||||||
|
{
|
||||||
|
/* Coverage collection is not currently supported. */
|
||||||
|
delete $3;
|
||||||
|
delete $5;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| assert_or_assume '(' error ')' statement_or_null %prec less_than_K_else
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $5;
|
||||||
|
}
|
||||||
|
| assert_or_assume '(' error ')' K_else statement_or_null
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $6;
|
||||||
|
}
|
||||||
|
| assert_or_assume '(' error ')' statement_or_null K_else statement_or_null
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $5;
|
||||||
|
}
|
||||||
|
| K_cover '(' error ')' statement_or_null
|
||||||
|
{ yyerror(@1, "error: Malformed conditional expression.");
|
||||||
|
$$ = $5;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
|
simple_type_or_string /* IEEE1800-2005: A.2.2.1 */
|
||||||
: integer_vector_type
|
: integer_vector_type
|
||||||
{ ivl_variable_type_t use_vtype = $1;
|
{ ivl_variable_type_t use_vtype = $1;
|
||||||
|
|
@ -6433,27 +6621,28 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
|
|
||||||
| jump_statement { $$ = $1; }
|
| jump_statement { $$ = $1; }
|
||||||
|
|
||||||
| K_case '(' expression ')' case_items K_endcase
|
| unique_priority K_case '(' expression ')' case_items K_endcase
|
||||||
{ PCase*tmp = new PCase(NetCase::EQ, $3, $5);
|
{ PCase*tmp = new PCase($1, NetCase::EQ, $4, $6);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| unique_priority K_casex '(' expression ')' case_items K_endcase
|
||||||
|
{ PCase*tmp = new PCase($1, NetCase::EQX, $4, $6);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| unique_priority K_casez '(' expression ')' case_items K_endcase
|
||||||
|
{ PCase*tmp = new PCase($1, NetCase::EQZ, $4, $6);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_casex '(' expression ')' case_items K_endcase
|
| unique_priority K_case '(' expression ')' error K_endcase
|
||||||
{ PCase*tmp = new PCase(NetCase::EQX, $3, $5);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| K_casez '(' expression ')' case_items K_endcase
|
|
||||||
{ PCase*tmp = new PCase(NetCase::EQZ, $3, $5);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| K_case '(' expression ')' error K_endcase
|
|
||||||
{ yyerrok; }
|
{ yyerrok; }
|
||||||
| K_casex '(' expression ')' error K_endcase
|
| unique_priority K_casex '(' expression ')' error K_endcase
|
||||||
{ yyerrok; }
|
{ yyerrok; }
|
||||||
| K_casez '(' expression ')' error K_endcase
|
| unique_priority K_casez '(' expression ')' error K_endcase
|
||||||
{ yyerrok; }
|
{ yyerrok; }
|
||||||
|
|
||||||
| K_if '(' expression ')' statement_or_null %prec less_than_K_else
|
| K_if '(' expression ')' statement_or_null %prec less_than_K_else
|
||||||
{ PCondit*tmp = new PCondit($3, $5, 0);
|
{ PCondit*tmp = new PCondit($3, $5, 0);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
|
@ -7108,6 +7297,13 @@ udp_primitive
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
unique_priority
|
||||||
|
: { $$ = IVL_CASE_QUALITY_BASIC; }
|
||||||
|
| K_unique { $$ = IVL_CASE_QUALITY_UNIQUE; }
|
||||||
|
| K_unique0 { $$ = IVL_CASE_QUALITY_UNIQUE0; }
|
||||||
|
| K_priority { $$ = IVL_CASE_QUALITY_PRIORITY; }
|
||||||
|
;
|
||||||
|
|
||||||
/* Many keywords can be optional in the syntax, although their
|
/* Many keywords can be optional in the syntax, although their
|
||||||
presence is significant. This is a fairly common pattern so
|
presence is significant. This is a fairly common pattern so
|
||||||
collect those rules here. */
|
collect those rules here. */
|
||||||
|
|
|
||||||
17
pform.cc
17
pform.cc
|
|
@ -2356,7 +2356,22 @@ void pform_make_modgates(const struct vlltype&loc,
|
||||||
svector<lgate>*gates,
|
svector<lgate>*gates,
|
||||||
std::list<named_pexpr_t>*attr)
|
std::list<named_pexpr_t>*attr)
|
||||||
{
|
{
|
||||||
|
// The grammer should not allow module gates to happen outside
|
||||||
|
// an active module. But if really bad input errors combine in
|
||||||
|
// an ugly way with error recovery, then catch this
|
||||||
|
// implausible situation and return an error.
|
||||||
|
if (pform_cur_module.empty()) {
|
||||||
|
cerr << loc << ": internal error: "
|
||||||
|
<< "Module instantiations outside module scope are not possible."
|
||||||
|
<< endl;
|
||||||
|
error_count += 1;
|
||||||
|
delete gates;
|
||||||
|
return;
|
||||||
|
}
|
||||||
assert(! pform_cur_module.empty());
|
assert(! pform_cur_module.empty());
|
||||||
|
|
||||||
|
// Detect some more realistic errors.
|
||||||
|
|
||||||
if (pform_cur_module.front()->program_block) {
|
if (pform_cur_module.front()->program_block) {
|
||||||
cerr << loc << ": error: Module instantiations are not allowed in "
|
cerr << loc << ": error: Module instantiations are not allowed in "
|
||||||
<< "program blocks." << endl;
|
<< "program blocks." << endl;
|
||||||
|
|
@ -2492,7 +2507,7 @@ void pform_make_var_init(const struct vlltype&li,
|
||||||
|
|
||||||
PEIdent*lval = new PEIdent(name);
|
PEIdent*lval = new PEIdent(name);
|
||||||
FILE_NAME(lval, li);
|
FILE_NAME(lval, li);
|
||||||
PAssign*ass = new PAssign(lval, expr, true);
|
PAssign*ass = new PAssign(lval, expr, !gn_system_verilog());
|
||||||
FILE_NAME(ass, li);
|
FILE_NAME(ass, li);
|
||||||
|
|
||||||
lexical_scope->var_inits.push_back(ass);
|
lexical_scope->var_inits.push_back(ass);
|
||||||
|
|
|
||||||
|
|
@ -840,6 +840,19 @@ void PCallTask::dump(ostream&out, unsigned ind) const
|
||||||
void PCase::dump(ostream&out, unsigned ind) const
|
void PCase::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << setw(ind) << "";
|
out << setw(ind) << "";
|
||||||
|
switch (quality_) {
|
||||||
|
case IVL_CASE_QUALITY_BASIC:
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_UNIQUE:
|
||||||
|
out << "unique ";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_UNIQUE0:
|
||||||
|
out << "unique0 ";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_PRIORITY:
|
||||||
|
out << "priority ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case NetCase::EQ:
|
case NetCase::EQ:
|
||||||
out << "case";
|
out << "case";
|
||||||
|
|
|
||||||
16
t-dll-api.cc
16
t-dll-api.cc
|
|
@ -2728,6 +2728,22 @@ extern "C" ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" ivl_case_quality_t ivl_stmt_case_quality(ivl_statement_t net)
|
||||||
|
{
|
||||||
|
assert(net);
|
||||||
|
switch (net->type_) {
|
||||||
|
case IVL_ST_CASE:
|
||||||
|
case IVL_ST_CASER:
|
||||||
|
case IVL_ST_CASEX:
|
||||||
|
case IVL_ST_CASEZ:
|
||||||
|
return net->u_.case_.quality;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return IVL_CASE_QUALITY_BASIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx)
|
extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx)
|
||||||
{
|
{
|
||||||
assert(net);
|
assert(net);
|
||||||
|
|
|
||||||
|
|
@ -497,6 +497,7 @@ void dll_target::proc_case(const NetCase*net)
|
||||||
}
|
}
|
||||||
assert(stmt_cur_->type_ != IVL_ST_NONE);
|
assert(stmt_cur_->type_ != IVL_ST_NONE);
|
||||||
|
|
||||||
|
stmt_cur_->u_.case_.quality = net->case_quality();
|
||||||
assert(expr_ == 0);
|
assert(expr_ == 0);
|
||||||
assert(net->expr());
|
assert(net->expr());
|
||||||
net->expr()->expr_scan(this);
|
net->expr()->expr_scan(this);
|
||||||
|
|
|
||||||
1
t-dll.h
1
t-dll.h
|
|
@ -810,6 +810,7 @@ struct ivl_statement_s {
|
||||||
} block_;
|
} block_;
|
||||||
|
|
||||||
struct { /* IVL_ST_CASE, IVL_ST_CASEX, IVL_ST_CASEZ */
|
struct { /* IVL_ST_CASE, IVL_ST_CASEX, IVL_ST_CASEZ */
|
||||||
|
ivl_case_quality_t quality;
|
||||||
ivl_expr_t cond;
|
ivl_expr_t cond;
|
||||||
unsigned ncase;
|
unsigned ncase;
|
||||||
ivl_expr_t*case_ex;
|
ivl_expr_t*case_ex;
|
||||||
|
|
|
||||||
|
|
@ -375,8 +375,24 @@ void show_statement(ivl_statement_t net, unsigned ind)
|
||||||
case IVL_ST_CASEZ:
|
case IVL_ST_CASEZ:
|
||||||
case IVL_ST_CASER:
|
case IVL_ST_CASER:
|
||||||
case IVL_ST_CASE: {
|
case IVL_ST_CASE: {
|
||||||
|
ivl_case_quality_t qual = ivl_stmt_case_quality(net);
|
||||||
unsigned cnt = ivl_stmt_case_count(net);
|
unsigned cnt = ivl_stmt_case_count(net);
|
||||||
fprintf(out, "%*scase (...) <%u cases>\n", ind, "", cnt);
|
const char*qual_txt = "";
|
||||||
|
switch (qual) {
|
||||||
|
case IVL_CASE_QUALITY_BASIC:
|
||||||
|
qual_txt = "basic";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_UNIQUE:
|
||||||
|
qual_txt = "unique";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_UNIQUE0:
|
||||||
|
qual_txt = "unique0";
|
||||||
|
break;
|
||||||
|
case IVL_CASE_QUALITY_PRIORITY:
|
||||||
|
qual_txt = "priority";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(out, "%*scase (...) <%u cases, %s>\n", ind, "", cnt, qual_txt);
|
||||||
show_expression(ivl_stmt_cond_expr(net), ind+4);
|
show_expression(ivl_stmt_cond_expr(net), ind+4);
|
||||||
|
|
||||||
for (idx = 0 ; idx < cnt ; idx += 1) {
|
for (idx = 0 ; idx < cnt ; idx += 1) {
|
||||||
|
|
|
||||||
|
|
@ -1084,8 +1084,9 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
|
||||||
ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx);
|
ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx);
|
||||||
|
|
||||||
if (ivl_type_base(prop_type) == IVL_VT_BOOL) {
|
if (ivl_type_base(prop_type) == IVL_VT_BOOL) {
|
||||||
assert(ivl_type_packed_dimensions(prop_type) == 1);
|
assert(ivl_type_packed_dimensions(prop_type) == 0 ||
|
||||||
assert(ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0));
|
(ivl_type_packed_dimensions(prop_type) == 1 &&
|
||||||
|
ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0)));
|
||||||
|
|
||||||
draw_eval_vec4(rval);
|
draw_eval_vec4(rval);
|
||||||
if (ivl_expr_value(rval)!=IVL_VT_BOOL)
|
if (ivl_expr_value(rval)!=IVL_VT_BOOL)
|
||||||
|
|
@ -1097,8 +1098,9 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
|
||||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||||
|
|
||||||
} else if (ivl_type_base(prop_type) == IVL_VT_LOGIC) {
|
} else if (ivl_type_base(prop_type) == IVL_VT_LOGIC) {
|
||||||
assert(ivl_type_packed_dimensions(prop_type) == 1);
|
assert(ivl_type_packed_dimensions(prop_type) == 0 ||
|
||||||
assert(ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0));
|
(ivl_type_packed_dimensions(prop_type) == 1 &&
|
||||||
|
ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0)));
|
||||||
|
|
||||||
draw_eval_vec4(rval);
|
draw_eval_vec4(rval);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -644,6 +644,7 @@ static int show_stmt_block_named(ivl_statement_t net, ivl_scope_t scope)
|
||||||
static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
|
static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
ivl_case_quality_t qual = ivl_stmt_case_quality(net);
|
||||||
ivl_expr_t expr = ivl_stmt_cond_expr(net);
|
ivl_expr_t expr = ivl_stmt_cond_expr(net);
|
||||||
unsigned count = ivl_stmt_case_count(net);
|
unsigned count = ivl_stmt_case_count(net);
|
||||||
|
|
||||||
|
|
@ -651,6 +652,12 @@ static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
|
||||||
|
|
||||||
unsigned idx, default_case;
|
unsigned idx, default_case;
|
||||||
|
|
||||||
|
if (qual != IVL_CASE_QUALITY_BASIC) {
|
||||||
|
fprintf(stderr, "%s:%u: tgt-vvp sorry: "
|
||||||
|
"Case unique/unique0/priority qualities are ignored.\n",
|
||||||
|
ivl_stmt_file(net), ivl_stmt_lineno(net));
|
||||||
|
}
|
||||||
|
|
||||||
show_stmt_file_line(net, "Case statement.");
|
show_stmt_file_line(net, "Case statement.");
|
||||||
|
|
||||||
local_count += count + 1;
|
local_count += count + 1;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue