Fix implicit casts in assignments (part 3).

This patch adds support for bool/bit vector types on the LHS of
a parameter declaration and ensures implicit casts in parameter
declarations are performed where necessary.
This commit is contained in:
Martin Whitaker 2013-02-26 22:36:37 +00:00 committed by Stephen Williams
parent bc2a4c01c9
commit faece5816c
3 changed files with 23 additions and 52 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2013 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
@ -452,7 +452,8 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
lv_width = (msb >= lsb) ? 1 + msb - lsb : 1 + lsb - msb; lv_width = (msb >= lsb) ? 1 + msb - lsb : 1 + lsb - msb;
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, lv_width, true, NetExpr*expr = elab_and_eval(des, val_scope, val_expr, lv_width, true,
(*cur).second.is_annotatable); (*cur).second.is_annotatable,
(*cur).second.type);
if (! expr) if (! expr)
return; return;
@ -491,15 +492,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
sure the type is set right. Note that if the parameter sure the type is set right. Note that if the parameter
doesn't have an explicit type or range, then it will get doesn't have an explicit type or range, then it will get
the signedness from the expression itself. */ the signedness from the expression itself. */
if (range_flag) { if ((*cur).second.type != IVL_VT_NO_TYPE) {
/* If we have a real value convert it to an integer. */
if(NetECReal*tmp = dynamic_cast<NetECReal*>(expr)) {
verinum nval(tmp->value().as_long64(), (unsigned)lv_width);
expr = new NetEConst(nval);
expr->set_line(*((*cur).second.val));
(*cur).second.val = expr;
}
(*cur).second.val->cast_signed((*cur).second.signed_flag); (*cur).second.val->cast_signed((*cur).second.signed_flag);
} else if ((*cur).second.signed_flag) { } else if ((*cur).second.signed_flag) {
(*cur).second.val->cast_signed(true); (*cur).second.val->cast_signed(true);
@ -574,7 +567,8 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
NetScope*val_scope = (*cur).second.val_scope; NetScope*val_scope = (*cur).second.val_scope;
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, -1, true, NetExpr*expr = elab_and_eval(des, val_scope, val_expr, -1, true,
(*cur).second.is_annotatable); (*cur).second.is_annotatable,
(*cur).second.type);
if (! expr) if (! expr)
return; return;
@ -594,26 +588,10 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
} }
break; break;
case IVL_VT_LOGIC:
case IVL_VT_BOOL:
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
verireal val (tmp->value().as_long());
res = new NetECReal(val);
res->set_line(*tmp);
} else {
cerr << expr->get_fileline()
<< ": error: "
<< "Unable to evaluate parameter "
<< (*cur).first << " value: " << *expr << endl;
des->errors += 1;
return;
}
break;
default: default:
cerr << expr->get_fileline() cerr << expr->get_fileline()
<< ": internal error: " << ": internal error: "
<< "Unhandled expression type?" << endl; << "Failed to cast expression?" << endl;
des->errors += 1; des->errors += 1;
return; return;
break; break;
@ -683,6 +661,7 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
} else { } else {
cur->second.solving = true; cur->second.solving = true;
switch (cur->second.type) { switch (cur->second.type) {
case IVL_VT_NO_TYPE:
case IVL_VT_BOOL: case IVL_VT_BOOL:
case IVL_VT_LOGIC: case IVL_VT_LOGIC:
evaluate_parameter_logic_(des, cur); evaluate_parameter_logic_(des, cur);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2013 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
@ -138,8 +138,6 @@ void NetScope::set_parameter(perm_string key, bool is_annotatable,
ref.range = range_list; ref.range = range_list;
ref.val = 0; ref.val = 0;
ref.set_line(file_line); ref.set_line(file_line);
ivl_assert(file_line, type__ != IVL_VT_NO_TYPE);
} }
/* /*

32
parse.y
View File

@ -573,7 +573,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <nettype> net_type var_type net_type_opt %type <nettype> net_type var_type net_type_opt
%type <gatetype> gatetype switchtype %type <gatetype> gatetype switchtype
%type <porttype> port_direction port_direction_opt %type <porttype> port_direction port_direction_opt
%type <vartype> bit_logic %type <vartype> bit_logic bit_logic_opt
%type <vartype> integer_vector_type %type <vartype> integer_vector_type
%type <parmvalue> parameter_value_opt %type <parmvalue> parameter_value_opt
@ -4449,9 +4449,15 @@ net_decl_assigns
bit_logic bit_logic
: K_logic { $$ = IVL_VT_LOGIC; } : K_logic { $$ = IVL_VT_LOGIC; }
| K_bool { $$ = IVL_VT_BOOL; /* Icarus misc */}
| K_bit { $$ = IVL_VT_BOOL; /* IEEE1800 / IEEE1364-2009 */} | K_bit { $$ = IVL_VT_BOOL; /* IEEE1800 / IEEE1364-2009 */}
; ;
bit_logic_opt
: bit_logic
| { $$ = IVL_VT_NO_TYPE; }
;
net_type net_type
: K_wire { $$ = NetNet::WIRE; } : K_wire { $$ = NetNet::WIRE; }
| K_tri { $$ = NetNet::TRI; } | K_tri { $$ = NetNet::TRI; }
@ -4476,25 +4482,13 @@ var_type
; ;
param_type param_type
: : bit_logic_opt unsigned_signed_opt range_opt
{ param_active_range = 0; { param_active_range = $3;
param_active_signed = false; param_active_signed = $2;
param_active_type = IVL_VT_LOGIC; if (($1 == IVL_VT_NO_TYPE) && ($3 != 0))
}
| range
{ param_active_range = $1;
param_active_signed = false;
param_active_type = IVL_VT_LOGIC;
}
| K_signed
{ param_active_range = 0;
param_active_signed = true;
param_active_type = IVL_VT_LOGIC;
}
| K_signed range
{ param_active_range = $2;
param_active_signed = true;
param_active_type = IVL_VT_LOGIC; param_active_type = IVL_VT_LOGIC;
else
param_active_type = $1;
} }
| K_integer | K_integer
{ param_active_range = make_range_from_width(integer_width); { param_active_range = make_range_from_width(integer_width);