Merge branch 'master' into work7
This commit is contained in:
commit
116d9f5f54
|
|
@ -152,6 +152,21 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
verinum cur_value (0);
|
||||
verinum one_value (1);
|
||||
size_t name_idx = 0;
|
||||
// Find the minimum and maximum allowed enumeration values.
|
||||
verinum min_value (0);
|
||||
verinum max_value (0);
|
||||
if (enum_type->signed_flag) {
|
||||
min_value = v_not((pow(verinum(2),
|
||||
verinum(use_enum->base_width()-1)))) +
|
||||
one_value;
|
||||
max_value = pow(verinum(2), verinum(use_enum->base_width()-1)) -
|
||||
one_value;
|
||||
} else {
|
||||
max_value = pow(verinum(2), verinum(use_enum->base_width())) -
|
||||
one_value;
|
||||
}
|
||||
min_value.has_sign(true);
|
||||
max_value.has_sign(enum_type->signed_flag);
|
||||
for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin()
|
||||
; cur != enum_type->names->end() ; ++ cur, name_idx += 1) {
|
||||
|
||||
|
|
@ -159,38 +174,60 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
if (cur->parm) {
|
||||
// There is an explicit value. elaborate/evaluate
|
||||
// the value and assign it to the enumeration name.
|
||||
NetExpr*val = elab_and_eval(des, scope, cur->parm,
|
||||
use_enum->base_width());
|
||||
NetExpr*val = elab_and_eval(des, scope, cur->parm, -1);
|
||||
NetEConst*val_const = dynamic_cast<NetEConst*> (val);
|
||||
if (val_const == 0) {
|
||||
cerr << "<>:0: error: Enumeration expression is not constant." << endl;
|
||||
cerr << "<>:0: error: Enumeration expression is not "
|
||||
"constant." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
cur_value = val_const->value();
|
||||
|
||||
if (enum_type->base_type==IVL_VT_BOOL && ! cur_value.is_defined()) {
|
||||
if (enum_type->base_type==IVL_VT_BOOL &&
|
||||
! cur_value.is_defined()) {
|
||||
cerr << "<>:0: error: Enumeration name " << cur->name
|
||||
<< " cannot have a logic value." << endl;
|
||||
<< " cannot have an undefined value." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (! cur_value.is_defined()) {
|
||||
cerr << "<>:0: error: Enumeration name " << cur->name
|
||||
<< " cannot have an inferred value." << endl;
|
||||
<< " cannot have an undefined inferred value." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The enumeration value must fit into the enumeration bits.
|
||||
if ((cur_value > max_value) ||
|
||||
(cur_value.has_sign() && (cur_value < min_value))) {
|
||||
cerr << "<>:0: error: Enumeration name " << cur->name
|
||||
<< " cannot have a value equal to " << cur_value
|
||||
<< "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// The values are explicitly sized to the width of the
|
||||
// base type of the enumeration.
|
||||
verinum tmp_val (cur_value, use_enum->base_width());
|
||||
verinum tmp_val (0);
|
||||
if (cur_value.len() < use_enum->base_width()) {
|
||||
// Pad the current value if it is narrower than the final
|
||||
// width of the enum.
|
||||
tmp_val = pad_to_width (cur_value, use_enum->base_width());
|
||||
tmp_val.has_len(true);
|
||||
} else {
|
||||
// Truncate an oversized value. We report out of bound
|
||||
// values above. This may create duplicates.
|
||||
tmp_val = verinum(cur_value, use_enum->base_width());
|
||||
}
|
||||
tmp_val.has_sign(enum_type->signed_flag);
|
||||
|
||||
rc_flag = use_enum->insert_name(name_idx, cur->name, tmp_val);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
if (! rc_flag) {
|
||||
cerr << "<>:0: error: Duplicate enumeration name " << cur->name << endl;
|
||||
cerr << "<>:0: error: Duplicate enumeration name "
|
||||
<< cur->name << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
27
lexor.lex
27
lexor.lex
|
|
@ -145,6 +145,20 @@ TU [munpf]
|
|||
"<=" { return K_LE; }
|
||||
">=" { return K_GE; }
|
||||
"=>" { return K_EG; }
|
||||
"+=>"|"-=>" {
|
||||
/*
|
||||
* Resolve the ambiguity between the += assignment
|
||||
* operator and +=> polarity edge path operator
|
||||
*
|
||||
* +=> should be treated as two separate tokens '+' and
|
||||
* '=>' (K_EG), therefore we only consume the first
|
||||
* character of the matched pattern i.e. either + or -
|
||||
* and push back the rest of the matches text (=>) in
|
||||
* the input stream.
|
||||
*/
|
||||
yyless(1);
|
||||
return yytext[0];
|
||||
}
|
||||
"*>" { return K_SG; }
|
||||
"==" { return K_EQ; }
|
||||
"!=" { return K_NE; }
|
||||
|
|
@ -161,6 +175,19 @@ TU [munpf]
|
|||
"+:" { return K_PO_POS; }
|
||||
"-:" { return K_PO_NEG; }
|
||||
"<+" { return K_CONTRIBUTE; }
|
||||
"+=" { return K_PLUS_EQ; }
|
||||
"-=" { return K_MINUS_EQ; }
|
||||
"*=" { return K_MUL_EQ; }
|
||||
"/=" { return K_DIV_EQ; }
|
||||
"%=" { return K_MOD_EQ; }
|
||||
"&=" { return K_AND_EQ; }
|
||||
"|=" { return K_OR_EQ; }
|
||||
"^=" { return K_XOR_EQ; }
|
||||
"<<=" { return K_LS_EQ; }
|
||||
">>=" { return K_RS_EQ; }
|
||||
"<<<=" { return K_LS_EQ; }
|
||||
">>>=" { return K_RSS_EQ; }
|
||||
|
||||
|
||||
/* Watch out for the tricky case of (*). Cannot parse this as "(*"
|
||||
and ")", but since I know that this is really ( * ), replace it
|
||||
|
|
|
|||
10
netmisc.cc
10
netmisc.cc
|
|
@ -184,7 +184,15 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src)
|
|||
|
||||
NetExpr* cast_to_int2(NetExpr*expr)
|
||||
{
|
||||
NetECast*cast = new NetECast('2', expr, expr->expr_width(),
|
||||
// Special case: The expression is alreadt BOOL
|
||||
if (expr->expr_type() == IVL_VT_BOOL)
|
||||
return expr;
|
||||
|
||||
unsigned use_width = expr->expr_width();
|
||||
if (expr->expr_type() == IVL_VT_REAL)
|
||||
use_width = 64;
|
||||
|
||||
NetECast*cast = new NetECast('2', expr, use_width,
|
||||
expr->has_sign());
|
||||
cast->set_line(*expr);
|
||||
return cast;
|
||||
|
|
|
|||
194
parse.y
194
parse.y
|
|
@ -197,14 +197,26 @@ static list<named_pexpr_t>* make_named_numbers(perm_string name, long first, lon
|
|||
{
|
||||
list<named_pexpr_t>*lst = new list<named_pexpr_t>;
|
||||
named_pexpr_t tmp;
|
||||
assert(first <= last);
|
||||
for (long idx = first ; idx <= last ; idx += 1) {
|
||||
ostringstream buf;
|
||||
buf << name.str() << idx << ends;
|
||||
tmp.name = lex_strings.make(buf.str());
|
||||
tmp.parm = val;
|
||||
val = 0;
|
||||
lst->push_back(tmp);
|
||||
// We are counting up.
|
||||
if (first <= last) {
|
||||
for (long idx = first ; idx <= last ; idx += 1) {
|
||||
ostringstream buf;
|
||||
buf << name.str() << idx << ends;
|
||||
tmp.name = lex_strings.make(buf.str());
|
||||
tmp.parm = val;
|
||||
val = 0;
|
||||
lst->push_back(tmp);
|
||||
}
|
||||
// We are counting down.
|
||||
} else {
|
||||
for (long idx = first ; idx >= last ; idx -= 1) {
|
||||
ostringstream buf;
|
||||
buf << name.str() << idx << ends;
|
||||
tmp.name = lex_strings.make(buf.str());
|
||||
tmp.parm = val;
|
||||
val = 0;
|
||||
lst->push_back(tmp);
|
||||
}
|
||||
}
|
||||
return lst;
|
||||
}
|
||||
|
|
@ -219,6 +231,28 @@ static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
|
|||
return lst;
|
||||
}
|
||||
|
||||
static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
|
||||
{
|
||||
long value = 1;
|
||||
// We can never have an undefined value in an enumeration name
|
||||
// declaration sequence.
|
||||
if (! arg->is_defined()) {
|
||||
yyerror(loc, "error: undefined value used in enum name sequence.");
|
||||
// We can never have a negative value in an enumeration name
|
||||
// declaration sequence.
|
||||
} else if (arg->is_negative()) {
|
||||
yyerror(loc, "error: negative value used in enum name sequence.");
|
||||
} else {
|
||||
value = arg->as_ulong();
|
||||
// We cannot have a zero enumeration name declaration count.
|
||||
if (! zero_ok && (value == 0)) {
|
||||
yyerror(loc, "error: zero count used in enum name sequence.");
|
||||
value = 1;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
|
|
@ -296,6 +330,7 @@ static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
|
|||
%token <text> PATHPULSE_IDENTIFIER
|
||||
%token <number> BASED_NUMBER DEC_NUMBER
|
||||
%token <realtime> REALTIME
|
||||
%token K_PLUS_EQ K_MINUS_EQ
|
||||
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_RSS K_SG
|
||||
/* K_CONTRIBUTE is <+, the contribution assign. */
|
||||
%token K_CONTRIBUTE
|
||||
|
|
@ -387,7 +422,7 @@ static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
|
|||
%token K_zi_nd K_zi_np K_zi_zd K_zi_zp
|
||||
|
||||
%type <flag> from_exclude
|
||||
%type <number> number
|
||||
%type <number> number pos_neg_number
|
||||
%type <flag> unsigned_signed_opt signed_unsigned_opt reg_opt
|
||||
%type <flag> udp_reg_opt edge_operator automatic_opt
|
||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
||||
|
|
@ -455,7 +490,7 @@ static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
|
|||
%type <event_expr> event_expression_list
|
||||
%type <event_expr> event_expression
|
||||
%type <event_statement> event_control
|
||||
%type <statement> statement statement_or_null
|
||||
%type <statement> statement statement_or_null compressed_statement
|
||||
%type <statement_list> statement_list
|
||||
|
||||
%type <statement> analog_statement
|
||||
|
|
@ -469,6 +504,8 @@ static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
|
|||
%type <int_val> atom2_type
|
||||
|
||||
%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_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
|
||||
%right '?' ':'
|
||||
%left K_LOR
|
||||
%left K_LAND
|
||||
|
|
@ -774,22 +811,34 @@ enum_name_list
|
|||
}
|
||||
;
|
||||
|
||||
pos_neg_number
|
||||
: number
|
||||
{ $$ = $1;
|
||||
}
|
||||
| '-' number
|
||||
{ verinum tmp = v_not(*($2)) + verinum(1);
|
||||
*($2) = tmp;
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
enum_name
|
||||
: IDENTIFIER
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
delete[]$1;
|
||||
$$ = make_named_number(name);
|
||||
}
|
||||
| IDENTIFIER '[' DEC_NUMBER ']'
|
||||
| IDENTIFIER '[' pos_neg_number ']'
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
long count = $3->as_ulong();
|
||||
long count = check_enum_seq_value(@1, $3, false);
|
||||
delete[]$1;
|
||||
$$ = make_named_numbers(name, 0, count-1);
|
||||
delete $3;
|
||||
}
|
||||
| IDENTIFIER '[' DEC_NUMBER ':' DEC_NUMBER ']'
|
||||
| IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']'
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
$$ = make_named_numbers(name, $3->as_long(), $5->as_long());
|
||||
$$ = make_named_numbers(name, check_enum_seq_value(@1, $3, true),
|
||||
check_enum_seq_value(@1, $5, true));
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
delete $5;
|
||||
|
|
@ -799,16 +848,17 @@ enum_name
|
|||
delete[]$1;
|
||||
$$ = make_named_number(name, $3);
|
||||
}
|
||||
| IDENTIFIER '[' DEC_NUMBER ']' '=' expression
|
||||
| IDENTIFIER '[' pos_neg_number ']' '=' expression
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
long count = $3->as_ulong();
|
||||
long count = check_enum_seq_value(@1, $3, false);
|
||||
$$ = make_named_numbers(name, 0, count-1, $6);
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
}
|
||||
| IDENTIFIER '[' DEC_NUMBER ':' DEC_NUMBER ']' '=' expression
|
||||
| IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']' '=' expression
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
$$ = make_named_numbers(name, $3->as_long(), $5->as_long(), $8);
|
||||
$$ = make_named_numbers(name, check_enum_seq_value(@1, $3, true),
|
||||
check_enum_seq_value(@1, $5, true), $8);
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
delete $5;
|
||||
|
|
@ -976,21 +1026,21 @@ delay_value_simple
|
|||
delete[]$1;
|
||||
}
|
||||
| TIME_LITERAL
|
||||
{
|
||||
int unit;
|
||||
{ int unit;
|
||||
|
||||
based_size = 0;
|
||||
$$ = 0;
|
||||
if ($1 == 0 || !get_time_unit($1, unit))
|
||||
yyerror(@1, "internal error: delay.");
|
||||
else {
|
||||
double p = pow(10, unit - pform_get_timeunit());
|
||||
double time = atof($1) * p;
|
||||
based_size = 0;
|
||||
$$ = 0;
|
||||
if ($1 == 0 || !get_time_unit($1, unit))
|
||||
yyerror(@1, "internal error: delay.");
|
||||
else {
|
||||
double p = pow(10.0,
|
||||
(double)(unit - pform_get_timeunit()));
|
||||
double time = atof($1) * p;
|
||||
|
||||
verireal *v = new verireal(time);
|
||||
$$ = new PEFNumber(v);
|
||||
FILE_NAME($$, @1);
|
||||
}
|
||||
verireal *v = new verireal(time);
|
||||
$$ = new PEFNumber(v);
|
||||
FILE_NAME($$, @1);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -4278,6 +4328,8 @@ statement
|
|||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in while loop condition.");
|
||||
}
|
||||
| compressed_statement ';'
|
||||
{ $$ = $1; }
|
||||
| delay1 statement_or_null
|
||||
{ PExpr*del = $1->front();
|
||||
assert($1->size() == 1);
|
||||
|
|
@ -4421,6 +4473,86 @@ statement
|
|||
}
|
||||
;
|
||||
|
||||
compressed_statement
|
||||
: lpvalue K_PLUS_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('+', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_MINUS_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('-', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_MUL_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('*', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_DIV_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('/', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_MOD_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('%', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_AND_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('&', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_OR_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('|', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_XOR_EQ expression
|
||||
{
|
||||
PEBinary *t = new PEBinary('^', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_LS_EQ expression
|
||||
{
|
||||
PEBShift *t = new PEBShift('l', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_RS_EQ expression
|
||||
{
|
||||
PEBShift *t = new PEBShift('r', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| lpvalue K_RSS_EQ expression
|
||||
{
|
||||
PEBShift *t = new PEBShift('R', $1, $3);
|
||||
PAssign *tmp = new PAssign($1, t);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
statement_list
|
||||
: statement_list statement
|
||||
{ svector<Statement*>*tmp = new svector<Statement*>(*$1, $2);
|
||||
|
|
|
|||
|
|
@ -1542,3 +1542,128 @@ void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig)
|
|||
assert(0);
|
||||
|
||||
}
|
||||
|
||||
static void dump_drive(ivl_drive_t drive)
|
||||
{
|
||||
switch (drive) {
|
||||
case IVL_DR_HiZ: fprintf(stderr, "highz"); break;
|
||||
case IVL_DR_SMALL: fprintf(stderr, "small"); break;
|
||||
case IVL_DR_MEDIUM: fprintf(stderr, "medium"); break;
|
||||
case IVL_DR_WEAK: fprintf(stderr, "weak"); break;
|
||||
case IVL_DR_LARGE: fprintf(stderr, "large"); break;
|
||||
case IVL_DR_PULL: fprintf(stderr, "pull"); break;
|
||||
case IVL_DR_STRONG: fprintf(stderr, "strong"); break;
|
||||
case IVL_DR_SUPPLY: fprintf(stderr, "supply"); break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine to dump the nexus information.
|
||||
*/
|
||||
void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex)
|
||||
{
|
||||
unsigned idx, count = ivl_nexus_ptrs(nex);
|
||||
fprintf(stderr, "Dumping nexus from scope: %s\n",
|
||||
ivl_scope_name(scope));
|
||||
for (idx = 0; idx < count; idx += 1) {
|
||||
ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx);
|
||||
ivl_lpm_t lpm = ivl_nexus_ptr_lpm(nex_ptr);
|
||||
ivl_net_const_t net_const = ivl_nexus_ptr_con(nex_ptr);
|
||||
ivl_net_logic_t net_logic = ivl_nexus_ptr_log(nex_ptr);
|
||||
ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr);
|
||||
fprintf(stderr, " %u (", idx);
|
||||
dump_drive(ivl_nexus_ptr_drive1(nex_ptr));
|
||||
fprintf(stderr, "1 ,");
|
||||
dump_drive(ivl_nexus_ptr_drive0(nex_ptr));
|
||||
fprintf(stderr, "0) ");
|
||||
if (lpm) {
|
||||
ivl_scope_t lpm_scope = ivl_lpm_scope(lpm);
|
||||
assert(! net_const);
|
||||
assert(! net_logic);
|
||||
assert(! sig);
|
||||
fprintf(stderr, "LPM: ");
|
||||
fprintf(stderr, "%s:%d ", ivl_lpm_file(lpm),
|
||||
ivl_lpm_lineno(lpm));
|
||||
if (scope != lpm_scope) fprintf(stderr, "%s ",
|
||||
ivl_scope_name(lpm_scope));
|
||||
switch (ivl_lpm_type(lpm)) {
|
||||
case IVL_LPM_ABS: fprintf(stderr, "abs"); break;
|
||||
case IVL_LPM_ADD: fprintf(stderr, "add"); break;
|
||||
case IVL_LPM_ARRAY: fprintf(stderr, "array"); break;
|
||||
case IVL_LPM_CAST_INT: fprintf(stderr, "<int>"); break;
|
||||
case IVL_LPM_CAST_INT2: fprintf(stderr, "<int2>"); break;
|
||||
case IVL_LPM_CAST_REAL: fprintf(stderr, "<real>"); break;
|
||||
case IVL_LPM_CONCAT: fprintf(stderr, "concat"); break;
|
||||
case IVL_LPM_CMP_EEQ: fprintf(stderr, "eeq"); break;
|
||||
case IVL_LPM_CMP_EQ: fprintf(stderr, "eq"); break;
|
||||
case IVL_LPM_CMP_GE: fprintf(stderr, "ge"); break;
|
||||
case IVL_LPM_CMP_GT: fprintf(stderr, "gt"); break;
|
||||
case IVL_LPM_CMP_NE: fprintf(stderr, "ne"); break;
|
||||
case IVL_LPM_CMP_NEE: fprintf(stderr, "nee"); break;
|
||||
case IVL_LPM_DIVIDE: fprintf(stderr, "divide"); break;
|
||||
case IVL_LPM_FF: fprintf(stderr, "dff"); break;
|
||||
case IVL_LPM_MOD: fprintf(stderr, "mod"); break;
|
||||
case IVL_LPM_MULT: fprintf(stderr, "mult"); break;
|
||||
case IVL_LPM_MUX: fprintf(stderr, "mux"); break;
|
||||
case IVL_LPM_PART_VP: fprintf(stderr, "part-VP"); break;
|
||||
case IVL_LPM_PART_PV: fprintf(stderr, "part-PV"); break;
|
||||
case IVL_LPM_POW: fprintf(stderr, "pow"); break;
|
||||
case IVL_LPM_RE_AND: fprintf(stderr, "R-AND"); break;
|
||||
case IVL_LPM_RE_NAND: fprintf(stderr, "R-NAND"); break;
|
||||
case IVL_LPM_RE_OR: fprintf(stderr, "R-OR"); break;
|
||||
case IVL_LPM_RE_NOR: fprintf(stderr, "R-NOR"); break;
|
||||
case IVL_LPM_RE_XNOR: fprintf(stderr, "R-XNOR"); break;
|
||||
case IVL_LPM_RE_XOR: fprintf(stderr, "R-XOR"); break;
|
||||
case IVL_LPM_REPEAT: fprintf(stderr, "repeat"); break;
|
||||
case IVL_LPM_SFUNC: fprintf(stderr, "S-func"); break;
|
||||
case IVL_LPM_SHIFTL: fprintf(stderr, "shiftl"); break;
|
||||
case IVL_LPM_SHIFTR: fprintf(stderr, "shiftr"); break;
|
||||
case IVL_LPM_SIGN_EXT: fprintf(stderr, "sign"); break;
|
||||
case IVL_LPM_SUB: fprintf(stderr, "sub"); break;
|
||||
case IVL_LPM_UFUNC: fprintf(stderr, "U-func"); break;
|
||||
}
|
||||
} else if (net_const) {
|
||||
assert(! net_logic);
|
||||
assert(! sig);
|
||||
fprintf(stderr, "Const: ");
|
||||
} else if (net_logic) {
|
||||
assert(! sig);
|
||||
fprintf(stderr, "Logic: ");
|
||||
} else if (sig) {
|
||||
ivl_scope_t sig_scope = ivl_signal_scope(sig);
|
||||
fprintf(stderr, "Signal: ");
|
||||
if (scope != sig_scope) fprintf(stderr, "%s.",
|
||||
ivl_scope_name(sig_scope));
|
||||
fprintf(stderr, "%s", ivl_signal_basename(sig));
|
||||
// HERE: Do we need to add support for an array word or is that an LPM.
|
||||
if (ivl_signal_local(sig)) fprintf(stderr, " (local)");
|
||||
switch (ivl_signal_port(sig)) {
|
||||
case IVL_SIP_INPUT: fprintf(stderr, " input"); break;
|
||||
case IVL_SIP_OUTPUT: fprintf(stderr, " output"); break;
|
||||
case IVL_SIP_INOUT: fprintf(stderr, " inout"); break;
|
||||
case IVL_SIP_NONE: break;
|
||||
}
|
||||
switch (ivl_signal_type(sig)) {
|
||||
case IVL_SIT_NONE: fprintf(stderr, " <no type>"); break;
|
||||
case IVL_SIT_REG: fprintf(stderr, " reg"); break;
|
||||
case IVL_SIT_TRI: fprintf(stderr, " tri"); break;
|
||||
case IVL_SIT_TRI0: fprintf(stderr, " tri0"); break;
|
||||
case IVL_SIT_TRI1: fprintf(stderr, " tri1"); break;
|
||||
case IVL_SIT_TRIAND: fprintf(stderr, " triand"); break;
|
||||
case IVL_SIT_TRIOR: fprintf(stderr, " trior"); break;
|
||||
case IVL_SIT_UWIRE: fprintf(stderr, " uwire"); break;
|
||||
}
|
||||
switch (ivl_signal_data_type(sig)) {
|
||||
case IVL_VT_VOID: fprintf(stderr, " <void>"); break;
|
||||
case IVL_VT_NO_TYPE: fprintf(stderr, " <no type>"); break;
|
||||
case IVL_VT_REAL: fprintf(stderr, " real"); break;
|
||||
case IVL_VT_BOOL: fprintf(stderr, " bool"); break;
|
||||
case IVL_VT_LOGIC: fprintf(stderr, " logic"); break;
|
||||
case IVL_VT_STRING: fprintf(stderr, " string"); break;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error: No/missing information!");
|
||||
}
|
||||
fprintf(stderr, " (%u)\n", ivl_nexus_ptr_pin(nex_ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ static void emit_number_as_string(ivl_net_const_t net_const)
|
|||
if (val == '"') fprintf(vlog_out, "\\\"");
|
||||
else if (val == '\\') fprintf(vlog_out, "\\\\");
|
||||
/* Print the printable characters. */
|
||||
else if (isprint(val)) fprintf(vlog_out, "%c", val);
|
||||
else if (isprint((int)val)) fprintf(vlog_out, "%c", val);
|
||||
/* Print the non-printable characters as an octal escape. */
|
||||
else fprintf(vlog_out, "\\%03o", val);
|
||||
}
|
||||
|
|
@ -641,6 +641,7 @@ void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex)
|
|||
/* It is possible that the nexus does not have a name. For this
|
||||
* case do not print an actual name. */
|
||||
fprintf(vlog_out, "/* Empty */");
|
||||
dump_nexus_information(scope, nex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -122,4 +122,9 @@ extern uint64_t get_uint64_from_number(ivl_expr_t expr, int *return_type);
|
|||
*/
|
||||
extern void free_emitted_scope_list();
|
||||
|
||||
/*
|
||||
* Debug routine to dump the various pieces of nexus information.
|
||||
*/
|
||||
extern void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex);
|
||||
|
||||
#endif /* __vlog95_priv_H */
|
||||
|
|
|
|||
|
|
@ -3118,19 +3118,37 @@ static struct vector_info draw_unary_expr(ivl_expr_t expr, unsigned wid)
|
|||
local_count += 1;
|
||||
break;
|
||||
|
||||
case '2': /* Cast logic to bool */
|
||||
assert(ivl_expr_value(sub) == IVL_VT_LOGIC);
|
||||
res = draw_eval_expr_wid(sub, wid, 0);
|
||||
case '2': /* Cast expression to bool */
|
||||
switch (ivl_expr_value(sub)) {
|
||||
case IVL_VT_BOOL:
|
||||
res = draw_eval_expr_wid(sub, wid, 0);
|
||||
break;
|
||||
|
||||
/* Handle special case that value is 0 or 1. */
|
||||
if (res.base == 0 || res.base == 1)
|
||||
case IVL_VT_LOGIC:
|
||||
res = draw_eval_expr_wid(sub, wid, 0);
|
||||
|
||||
/* Handle special case that value is 0 or 1. */
|
||||
if (res.base == 0 || res.base == 1)
|
||||
break;
|
||||
if (res.base == 2 || res.base == 2) {
|
||||
res.base = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%cast2 %d, %d, %u;\n", res.base, res.base, res.wid);
|
||||
break;
|
||||
if (res.base == 2 || res.base == 2) {
|
||||
res.base = 0;
|
||||
|
||||
case IVL_VT_REAL:
|
||||
word = draw_eval_real(sub);
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
fprintf(vvp_out, " %%cvt/vr %d, %d, %u;\n", res.base, word, wid);
|
||||
clr_word(word);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%cast2 %d, %d, %u;\n", res.base, res.base, res.wid);
|
||||
break;
|
||||
|
||||
case 'i': /* Cast a real value to an integer. */
|
||||
|
|
|
|||
38
verinum.cc
38
verinum.cc
|
|
@ -804,7 +804,8 @@ verinum::V operator <= (const verinum&left, const verinum&right)
|
|||
{
|
||||
verinum::V left_pad = verinum::V0;
|
||||
verinum::V right_pad = verinum::V0;
|
||||
if (left.has_sign() && right.has_sign()) {
|
||||
bool signed_calc = left.has_sign() && right.has_sign();
|
||||
if (signed_calc) {
|
||||
left_pad = left.get(left.len()-1);
|
||||
right_pad = right.get(right.len()-1);
|
||||
|
||||
|
|
@ -816,11 +817,23 @@ verinum::V operator <= (const verinum&left, const verinum&right)
|
|||
|
||||
unsigned idx;
|
||||
for (idx = left.len() ; idx > right.len() ; idx -= 1) {
|
||||
if (left[idx-1] != right_pad) return verinum::V0;
|
||||
if (left[idx-1] != right_pad) {
|
||||
// A change of padding for a negative left argument
|
||||
// denotes the left value is less than the right.
|
||||
return (signed_calc &&
|
||||
(left_pad == verinum::V1)) ? verinum::V1 :
|
||||
verinum::V0;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = right.len() ; idx > left.len() ; idx -= 1) {
|
||||
if (right[idx-1] != left_pad) return verinum::V1;
|
||||
if (right[idx-1] != left_pad) {
|
||||
// A change of padding for a negative right argument
|
||||
// denotes the left value is not less than the right.
|
||||
return (signed_calc &&
|
||||
(right_pad == verinum::V1)) ? verinum::V0 :
|
||||
verinum::V1;
|
||||
}
|
||||
}
|
||||
|
||||
idx = right.len();
|
||||
|
|
@ -843,7 +856,8 @@ verinum::V operator < (const verinum&left, const verinum&right)
|
|||
{
|
||||
verinum::V left_pad = verinum::V0;
|
||||
verinum::V right_pad = verinum::V0;
|
||||
if (left.has_sign() && right.has_sign()) {
|
||||
bool signed_calc = left.has_sign() && right.has_sign();
|
||||
if (signed_calc) {
|
||||
left_pad = left.get(left.len()-1);
|
||||
right_pad = right.get(right.len()-1);
|
||||
|
||||
|
|
@ -855,11 +869,23 @@ verinum::V operator < (const verinum&left, const verinum&right)
|
|||
|
||||
unsigned idx;
|
||||
for (idx = left.len() ; idx > right.len() ; idx -= 1) {
|
||||
if (left[idx-1] != right_pad) return verinum::V0;
|
||||
if (left[idx-1] != right_pad) {
|
||||
// A change of padding for a negative left argument
|
||||
// denotes the left value is less than the right.
|
||||
return (signed_calc &&
|
||||
(left_pad == verinum::V1)) ? verinum::V1 :
|
||||
verinum::V0;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = right.len() ; idx > left.len() ; idx -= 1) {
|
||||
if (right[idx-1] != left_pad) return verinum::V1;
|
||||
if (right[idx-1] != left_pad) {
|
||||
// A change of padding for a negative right argument
|
||||
// denotes the left value is not less than the right.
|
||||
return (signed_calc &&
|
||||
(right_pad == verinum::V1)) ? verinum::V0 :
|
||||
verinum::V1;
|
||||
}
|
||||
}
|
||||
|
||||
while (idx > 0) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ Architecture::Architecture(perm_string name, const ScopeBase&ref,
|
|||
|
||||
Architecture::~Architecture()
|
||||
{
|
||||
delete_all(statements_);
|
||||
ScopeBase::cleanup();
|
||||
}
|
||||
|
||||
Architecture::Statement::Statement()
|
||||
|
|
@ -69,12 +71,15 @@ ComponentInstantiation::ComponentInstantiation(perm_string i, perm_string c,
|
|||
while (! ports->empty()) {
|
||||
named_expr_t*cur = ports->front();
|
||||
ports->pop_front();
|
||||
port_map_[cur->name()] = cur->expr();
|
||||
port_map_.insert(make_pair(cur->name(), cur->expr()));
|
||||
}
|
||||
}
|
||||
|
||||
ComponentInstantiation::~ComponentInstantiation()
|
||||
{
|
||||
for(map<perm_string, Expression*>::iterator it = port_map_.begin()
|
||||
; it != port_map_.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
ProcessStatement::ProcessStatement(perm_string iname,
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class ComponentInstantiation : public Architecture::Statement {
|
|||
perm_string iname_;
|
||||
perm_string cname_;
|
||||
|
||||
std::map<perm_string,Expression*> port_map_;
|
||||
std::multimap<perm_string,Expression*> port_map_;
|
||||
};
|
||||
|
||||
class ProcessStatement : public Architecture::Statement {
|
||||
|
|
|
|||
|
|
@ -54,10 +54,12 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
map<perm_string,const InterfacePort*> port_match;
|
||||
|
||||
for (map<perm_string,Expression*>::iterator cur = port_map_.begin()
|
||||
for (multimap<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
||||
; cur != port_map_.end() ; ++cur) {
|
||||
/* check if a port from component instantiation
|
||||
exists in the component declaration
|
||||
*/
|
||||
const InterfacePort*iport = base->find_port(cur->first);
|
||||
if (iport == 0) {
|
||||
cerr << get_fileline() << ": error: No port " << cur->first
|
||||
|
|
@ -66,12 +68,25 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
|
|||
continue;
|
||||
}
|
||||
|
||||
ExpName* tmp;
|
||||
if (cur->second && (tmp = dynamic_cast<ExpName*>(cur->second)))
|
||||
errors += tmp->elaborate_rval(ent, arc, iport);
|
||||
/* It is possible for the port to be explicitly
|
||||
unconnected. In that case, the Expression will be nil */
|
||||
|
||||
if (cur->second)
|
||||
cur->second->elaborate_expr(ent, arc, iport->type);
|
||||
}
|
||||
|
||||
//each formal (component's) port should be associated at most once
|
||||
for(multimap<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
||||
; cur != port_map_.end() ; ++cur)
|
||||
if(port_map_.count(cur->first) != 1) {
|
||||
//at least one port is associated twice or more
|
||||
cerr << cur->second->get_fileline() << ": error: At least one port is associated"
|
||||
<< " twice or more in a single component instantiation." << endl;
|
||||
errors += 1;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,12 +30,16 @@ int Scope::emit_signals(ostream&out, Entity*entity, Architecture*arc)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,Signal*>::iterator cur = signals_.begin()
|
||||
; cur != signals_.end() ; ++cur) {
|
||||
for (map<perm_string,Signal*>::iterator cur = old_signals_.begin()
|
||||
; cur != old_signals_.end() ; ++cur) {
|
||||
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
for (map<perm_string,Signal*>::iterator cur = new_signals_.begin()
|
||||
; cur != new_signals_.end() ; ++cur) {
|
||||
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -43,12 +47,19 @@ int Architecture::emit(ostream&out, Entity*entity)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,struct const_t>::iterator cur = constants_.begin()
|
||||
; cur != constants_.end() ; ++cur) {
|
||||
for (map<perm_string,struct const_t*>::iterator cur = old_constants_.begin()
|
||||
; cur != old_constants_.end() ; ++cur) {
|
||||
|
||||
out << "localparam " << cur->first << " = ";
|
||||
errors += cur->second.val->emit(out, entity, this);
|
||||
out << ";" << endl;
|
||||
out << "localparam " << cur->first << " = ";
|
||||
errors += cur->second->val->emit(out, entity, this);
|
||||
out << ";" << endl;
|
||||
}
|
||||
for (map<perm_string,struct const_t*>::iterator cur = new_constants_.begin()
|
||||
; cur != new_constants_.end() ; ++cur) {
|
||||
|
||||
out << "localparam " << cur->first << " = ";
|
||||
errors += cur->second->val->emit(out, entity, this);
|
||||
out << ";" << endl;
|
||||
}
|
||||
|
||||
errors += emit_signals(out, entity, this);
|
||||
|
|
@ -94,7 +105,7 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
out << cname_ << " " << iname_ << "(";
|
||||
const char*comma = "";
|
||||
for (map<perm_string,Expression*>::iterator cur = port_map_.begin()
|
||||
for (multimap<perm_string,Expression*>::iterator cur = port_map_.begin()
|
||||
; cur != port_map_.end() ; ++cur) {
|
||||
// Skip unconnected ports
|
||||
if (cur->second == 0)
|
||||
|
|
|
|||
|
|
@ -79,36 +79,58 @@ void ComponentBase::dump_ports(ostream&out, int indent) const
|
|||
void Scope::dump_scope(ostream&out) const
|
||||
{
|
||||
// Dump types
|
||||
for (map<perm_string,const VType*>::const_iterator cur = types_.begin()
|
||||
; cur != types_.end() ; ++cur) {
|
||||
for (map<perm_string,const VType*>::const_iterator cur = old_types_.begin()
|
||||
; cur != old_types_.end() ; ++cur) {
|
||||
out << " " << cur->first << ": ";
|
||||
cur->second->show(out);
|
||||
out << endl;
|
||||
}
|
||||
for (map<perm_string,const VType*>::const_iterator cur = new_types_.begin()
|
||||
; cur != new_types_.end() ; ++cur) {
|
||||
out << " " << cur->first << ": ";
|
||||
cur->second->show(out);
|
||||
out << endl;
|
||||
}
|
||||
|
||||
// Dump constants
|
||||
for (map<perm_string,const_t>::const_iterator cur = constants_.begin()
|
||||
; cur != constants_.end() ; ++cur) {
|
||||
for (map<perm_string,const_t*>::const_iterator cur = old_constants_.begin()
|
||||
; cur != old_constants_.end() ; ++cur) {
|
||||
out << " constant " << cur->first << " = ";
|
||||
out << endl;
|
||||
}
|
||||
|
||||
// Dump signal declarations
|
||||
for (map<perm_string,Signal*>::const_iterator cur = signals_.begin()
|
||||
; cur != signals_.end() ; ++cur) {
|
||||
if (cur->second)
|
||||
cur->second->dump(out, 3);
|
||||
else
|
||||
out << " signal " << cur->first.str() << ": ???" << endl;
|
||||
for (map<perm_string,const_t*>::const_iterator cur = new_constants_.begin()
|
||||
; cur != new_constants_.end() ; ++cur) {
|
||||
out << " constant " << cur->first << " = ";
|
||||
out << endl;
|
||||
}
|
||||
// Dump signal declarations
|
||||
for (map<perm_string,Signal*>::const_iterator cur = old_signals_.begin()
|
||||
; cur != old_signals_.end() ; ++cur) {
|
||||
if (cur->second)
|
||||
cur->second->dump(out, 3);
|
||||
else
|
||||
out << " signal " << cur->first.str() << ": ???" << endl;
|
||||
}
|
||||
for (map<perm_string,Signal*>::const_iterator cur = new_signals_.begin()
|
||||
; cur != new_signals_.end() ; ++cur) {
|
||||
if (cur->second)
|
||||
cur->second->dump(out, 3);
|
||||
else
|
||||
out << " signal " << cur->first.str() << ": ???" << endl;
|
||||
}
|
||||
|
||||
// Dump component declarations
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = components_.begin()
|
||||
; cur != components_.end() ; ++cur) {
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = old_components_.begin()
|
||||
; cur != old_components_.end() ; ++cur) {
|
||||
out << " component " << cur->first << " is" << endl;
|
||||
cur->second->dump_ports(out);
|
||||
out << " end component " << cur->first << endl;
|
||||
}
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = new_components_.begin()
|
||||
; cur != new_components_.end() ; ++cur) {
|
||||
out << " component " << cur->first << " is" << endl;
|
||||
cur->second->dump_ports(out);
|
||||
out << " end component " << cur->first << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::dump(ostream&out, int indent) const
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ ComponentBase::ComponentBase(perm_string name)
|
|||
|
||||
ComponentBase::~ComponentBase()
|
||||
{
|
||||
for(std::vector<InterfacePort*>::iterator it = ports_.begin()
|
||||
; it != ports_.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
void ComponentBase::set_interface(std::list<InterfacePort*>*ports)
|
||||
|
|
@ -60,6 +63,9 @@ Entity::Entity(perm_string name)
|
|||
|
||||
Entity::~Entity()
|
||||
{
|
||||
for(map<perm_string,Architecture*>::reverse_iterator it = arch_.rbegin()
|
||||
; it != arch_.rend(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
Architecture* Entity::add_architecture(Architecture*that)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
# include "StringHeap.h"
|
||||
# include "LineInfo.h"
|
||||
# include "entity.h"
|
||||
# include <inttypes.h>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
|
|
@ -322,6 +323,7 @@ class ExpName : public Expression {
|
|||
|
||||
public: // Base methods
|
||||
int elaborate_lval(Entity*ent, Architecture*arc, bool);
|
||||
int elaborate_rval(Entity*ent, Architecture*arc, const InterfacePort*);
|
||||
const VType* probe_type(Entity*ent, Architecture*arc) const;
|
||||
int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype);
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,44 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int ExpName::elaborate_rval(Entity*ent, Architecture*arc, const InterfacePort*lval)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
if (const InterfacePort*cur = ent->find_port(name_)) {
|
||||
/* IEEE 1076-2008, p.80:
|
||||
* For a formal port IN, associated port should be IN, OUT, INOUT or BUFFER
|
||||
* For a formal port OUT, associated port should be OUT, INOUT or BUFFER
|
||||
* For a formal port INOUT, associated prot should be OUT, INOUT or BUFFER
|
||||
* For a formal port BUFFER, associated port should be OUT, INOUT or BUFFER
|
||||
*/
|
||||
switch(lval->mode) {
|
||||
case PORT_OUT:
|
||||
//case PORT_INOUT:
|
||||
if (cur->mode == PORT_IN) {
|
||||
cerr << get_fileline() << ": error: Connecting "
|
||||
"formal output port " << lval->name << " to actual input port "
|
||||
<< name_ << "." << endl;
|
||||
errors += 1;
|
||||
}
|
||||
break;
|
||||
case PORT_IN:
|
||||
case PORT_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (Signal* fs = arc->find_signal(name_)) {
|
||||
/* OK */
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: No port or signal " << name_
|
||||
<< " to be used as r-value." << endl;
|
||||
errors += 1;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ExpNameALL::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
|
||||
{
|
||||
return Expression::elaborate_lval(ent, arc, is_sequ);
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ static void import_ieee_use_std_logic_1164(ActiveScope*res, perm_string name)
|
|||
if (all_flag || name == "std_logic_vector") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("std_logic_vector"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, false));
|
||||
new VTypeArray(primitive_STDLOGIC, dims, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,12 +176,12 @@ static void import_ieee_use_numeric_bit(ActiveScope*res, perm_string name)
|
|||
if (all_flag || name == "signed") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("signed"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, true));
|
||||
new VTypeArray(primitive_STDLOGIC, dims, true));
|
||||
}
|
||||
if (all_flag || name == "unsigned") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("unsigned"),
|
||||
new VTypeArray(&primitive_BIT, dims, false));
|
||||
new VTypeArray(primitive_BIT, dims, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,12 +192,12 @@ static void import_ieee_use_numeric_std(ActiveScope*res, perm_string name)
|
|||
if (all_flag || name == "signed") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("signed"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, true));
|
||||
new VTypeArray(primitive_STDLOGIC, dims, true));
|
||||
}
|
||||
if (all_flag || name == "unsigned") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("unsigned"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, false));
|
||||
new VTypeArray(primitive_STDLOGIC, dims, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -219,22 +219,21 @@ static void import_ieee_use(ActiveScope*res, perm_string package, perm_string na
|
|||
}
|
||||
}
|
||||
|
||||
const VTypePrimitive* primitive_BOOLEAN = new VTypePrimitive(VTypePrimitive::BOOLEAN);
|
||||
const VTypePrimitive* primitive_BIT = new VTypePrimitive(VTypePrimitive::BIT);
|
||||
const VTypePrimitive* primitive_INTEGER = new VTypePrimitive(VTypePrimitive::INTEGER);
|
||||
const VTypePrimitive* primitive_STDLOGIC = new VTypePrimitive(VTypePrimitive::STDLOGIC);
|
||||
|
||||
const VTypePrimitive primitive_BOOLEAN (VTypePrimitive::BOOLEAN);
|
||||
const VTypePrimitive primitive_BIT (VTypePrimitive::BIT);
|
||||
const VTypePrimitive primitive_INTEGER (VTypePrimitive::INTEGER);
|
||||
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC);
|
||||
|
||||
const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
|
||||
const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
|
||||
const VTypeArray* primitive_BIT_VECTOR = new VTypeArray(primitive_BIT, vector<VTypeArray::range_t> (1));
|
||||
const VTypeArray* primitive_BOOL_VECTOR = new VTypeArray(primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
|
||||
|
||||
void generate_global_types(ActiveScope*res)
|
||||
{
|
||||
res->bind_name(perm_string::literal("boolean"), &primitive_BOOLEAN);
|
||||
res->bind_name(perm_string::literal("bit"), &primitive_BIT);
|
||||
res->bind_name(perm_string::literal("integer"), &primitive_INTEGER);
|
||||
res->bind_name(perm_string::literal("std_logic"), &primitive_STDLOGIC);
|
||||
res->bind_name(perm_string::literal("bit_vector"),&primitive_BOOL_VECTOR);
|
||||
res->bind_name(perm_string::literal("boolean"), primitive_BOOLEAN);
|
||||
res->bind_name(perm_string::literal("bit"), primitive_BIT);
|
||||
res->bind_name(perm_string::literal("integer"), primitive_INTEGER);
|
||||
res->bind_name(perm_string::literal("std_logic"), primitive_STDLOGIC);
|
||||
res->bind_name(perm_string::literal("bit_vector"),primitive_BOOL_VECTOR);
|
||||
}
|
||||
|
||||
void library_set_work_path(const char*path)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ const char*dump_libraries_path = 0;
|
|||
|
||||
|
||||
extern void dump_libraries(ostream&file);
|
||||
extern void parser_cleanup();
|
||||
|
||||
static void process_debug_token(const char*word)
|
||||
{
|
||||
|
|
@ -158,21 +159,25 @@ int main(int argc, char*argv[])
|
|||
dump_design_entities(file);
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
if (errors > 0) {
|
||||
parser_cleanup();
|
||||
return 2;
|
||||
}
|
||||
|
||||
errors = elaborate_entities();
|
||||
if (errors > 0) {
|
||||
fprintf(stderr, "%d errors elaborating design.\n", errors);
|
||||
parser_cleanup();
|
||||
return 3;
|
||||
}
|
||||
|
||||
errors = emit_entities();
|
||||
if (errors > 0) {
|
||||
fprintf(stderr, "%d errors emitting design.\n", errors);
|
||||
parser_cleanup();
|
||||
return 4;
|
||||
}
|
||||
|
||||
lex_strings.cleanup();
|
||||
parser_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,20 @@ Package::Package(perm_string n, const ScopeBase&ref)
|
|||
|
||||
Package::~Package()
|
||||
{
|
||||
ScopeBase::cleanup();
|
||||
}
|
||||
|
||||
void Package::write_to_stream(ostream&fd) const
|
||||
{
|
||||
fd << "package " << name_ << " is" << endl;
|
||||
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = components_.begin()
|
||||
; cur != components_.end() ; ++cur) {
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = old_components_.begin()
|
||||
; cur != old_components_.end() ; ++cur) {
|
||||
|
||||
cur->second->write_to_stream(fd);
|
||||
}
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = new_components_.begin()
|
||||
; cur != new_components_.end() ; ++cur) {
|
||||
|
||||
cur->second->write_to_stream(fd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
# include <cstdarg>
|
||||
# include <cstring>
|
||||
# include <list>
|
||||
# include <stack>
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include "parse_types.h"
|
||||
|
|
@ -77,7 +78,7 @@ extern int yylex(union YYSTYPE*yylvalp,YYLTYPE*yyllocp,yyscan_t yyscanner);
|
|||
* manage lexical scopes.
|
||||
*/
|
||||
static ActiveScope*active_scope = new ActiveScope;
|
||||
static list<ActiveScope*> scope_stack;
|
||||
static stack<ActiveScope*> scope_stack;
|
||||
|
||||
/*
|
||||
* When a scope boundary starts, call the push_scope function to push
|
||||
|
|
@ -89,7 +90,7 @@ static list<ActiveScope*> scope_stack;
|
|||
static void push_scope(void)
|
||||
{
|
||||
assert(active_scope);
|
||||
scope_stack.push_front(active_scope);
|
||||
scope_stack.push(active_scope);
|
||||
active_scope = new ActiveScope (active_scope);
|
||||
}
|
||||
|
||||
|
|
@ -97,8 +98,8 @@ static void pop_scope(void)
|
|||
{
|
||||
delete active_scope;
|
||||
assert(scope_stack.size() > 0);
|
||||
active_scope = scope_stack.front();
|
||||
scope_stack.pop_front();
|
||||
active_scope = scope_stack.top();
|
||||
scope_stack.pop();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -107,6 +108,31 @@ void preload_global_types(void)
|
|||
generate_global_types(active_scope);
|
||||
}
|
||||
|
||||
//Remove the scope created at the beginning of parser's work.
|
||||
//After the parsing active_scope should keep it's address
|
||||
|
||||
static void delete_global_scope(void)
|
||||
{
|
||||
active_scope->destroy_global_scope();
|
||||
delete active_scope;
|
||||
}
|
||||
|
||||
//delete global entities that were gathered over the parsing process
|
||||
static void delete_design_entities(void)
|
||||
{
|
||||
for(map<perm_string,Entity*>::iterator cur = design_entities.begin()
|
||||
; cur != design_entities.end(); ++cur)
|
||||
delete cur->second;
|
||||
}
|
||||
|
||||
//clean the mess caused by the parser
|
||||
void parser_cleanup(void)
|
||||
{
|
||||
delete_design_entities();
|
||||
delete_global_scope();
|
||||
lex_strings.cleanup();
|
||||
}
|
||||
|
||||
const VType*parse_type_by_name(perm_string name)
|
||||
{
|
||||
return active_scope->find_type(name);
|
||||
|
|
@ -473,7 +499,10 @@ component_declaration
|
|||
}
|
||||
|
||||
ComponentBase*comp = new ComponentBase(name);
|
||||
if ($4) comp->set_interface($4);
|
||||
if ($4) {
|
||||
comp->set_interface($4);
|
||||
delete $4;
|
||||
}
|
||||
active_scope->bind_name(name, comp);
|
||||
delete[]$2;
|
||||
if ($7) delete[] $7;
|
||||
|
|
@ -492,6 +521,7 @@ component_instantiation_statement
|
|||
{ perm_string iname = lex_strings.make($1);
|
||||
perm_string cname = lex_strings.make($4);
|
||||
ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $5);
|
||||
delete $5;
|
||||
FILE_NAME(tmp, @1);
|
||||
delete[]$1;
|
||||
delete[]$4;
|
||||
|
|
@ -681,7 +711,7 @@ entity_declaration
|
|||
errormsg(@1, "Syntax error in entity clause. Closing name doesn't match.\n");
|
||||
yyerrok;
|
||||
}
|
||||
delete $7;
|
||||
delete[]$7;
|
||||
}
|
||||
}
|
||||
| K_entity error K_end K_entity_opt identifier_opt ';'
|
||||
|
|
|
|||
134
vhdlpp/scope.cc
134
vhdlpp/scope.cc
|
|
@ -18,61 +18,122 @@
|
|||
*/
|
||||
|
||||
# include "scope.h"
|
||||
# include <algorithm>
|
||||
# include <iostream>
|
||||
# include <iterator>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ScopeBase::ScopeBase(const ScopeBase&ref)
|
||||
{
|
||||
constants_ = ref.constants_;
|
||||
signals_ = ref.signals_;
|
||||
components_ = ref.components_;
|
||||
types_ = ref.types_;
|
||||
merge(ref.old_constants_.begin(), ref.old_constants_.end(),
|
||||
ref.new_constants_.begin(), ref.new_constants_.end(),
|
||||
insert_iterator<map<perm_string, struct const_t*> >(
|
||||
old_constants_, old_constants_.end())
|
||||
);
|
||||
merge(ref.old_signals_.begin(), ref.old_signals_.end(),
|
||||
ref.new_signals_.begin(), ref.new_signals_.end(),
|
||||
insert_iterator<map<perm_string, Signal*> >(
|
||||
old_signals_, old_signals_.end())
|
||||
);
|
||||
merge(ref.old_components_.begin(), ref.old_components_.end(),
|
||||
ref.new_components_.begin(), ref.new_components_.end(),
|
||||
insert_iterator<map<perm_string, ComponentBase*> >(
|
||||
old_components_, old_components_.end())
|
||||
);
|
||||
merge(ref.old_types_.begin(), ref.old_types_.end(),
|
||||
ref.new_types_.begin(), ref.new_types_.end(),
|
||||
insert_iterator<map<perm_string, const VType*> >(
|
||||
old_types_, old_types_.end())
|
||||
);
|
||||
}
|
||||
|
||||
ScopeBase::~ScopeBase()
|
||||
{
|
||||
//freeing of member objects is performed by child classes
|
||||
}
|
||||
|
||||
void ScopeBase::cleanup()
|
||||
{
|
||||
/*
|
||||
* A parent scope is destroyed only if all child scopes
|
||||
* were previously destroyed. There for we can delete all
|
||||
* objects that were defined in this scope, leaving
|
||||
* objects from the other scopes untouched.
|
||||
*/
|
||||
delete_all(new_signals_);
|
||||
delete_all(new_components_);
|
||||
delete_all(new_types_);
|
||||
delete_all(new_constants_);
|
||||
}
|
||||
|
||||
const VType*ScopeBase::find_type(perm_string by_name)
|
||||
{
|
||||
map<perm_string,const VType*>::const_iterator cur = types_.find(by_name);
|
||||
if (cur == types_.end())
|
||||
return 0;
|
||||
else
|
||||
map<perm_string,const VType*>::const_iterator cur = new_types_.find(by_name);
|
||||
if (cur == new_types_.end()) {
|
||||
cur = old_types_.find(by_name);
|
||||
if (cur == old_types_.end())
|
||||
return 0;
|
||||
else
|
||||
return cur->second;
|
||||
} else
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp)
|
||||
{
|
||||
map<perm_string,const_t>::const_iterator cur = constants_.find(by_name);
|
||||
if (cur == constants_.end())
|
||||
return false;
|
||||
|
||||
typ = cur->second.typ;
|
||||
exp = cur->second.val;
|
||||
return true;
|
||||
map<perm_string,struct const_t*>::const_iterator cur = new_constants_.find(by_name);
|
||||
if (cur == new_constants_.end()) {
|
||||
cur = old_constants_.find(by_name);
|
||||
if (cur == old_constants_.end())
|
||||
return false;
|
||||
else {
|
||||
typ = cur->second->typ;
|
||||
exp = cur->second->val;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
typ = cur->second->typ;
|
||||
exp = cur->second->val;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ScopeBase::do_use_from(const ScopeBase*that)
|
||||
{
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = that->components_.begin()
|
||||
; cur != that->components_.end() ; ++ cur) {
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = that->old_components_.begin()
|
||||
; cur != that->old_components_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
components_[cur->first] = cur->second;
|
||||
old_components_[cur->first] = cur->second;
|
||||
}
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = that->new_components_.begin()
|
||||
; cur != that->new_components_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
old_components_[cur->first] = cur->second;
|
||||
}
|
||||
|
||||
for (map<perm_string,const VType*>::const_iterator cur = that->types_.begin()
|
||||
; cur != that->types_.end() ; ++ cur) {
|
||||
for (map<perm_string,const VType*>::const_iterator cur = that->old_types_.begin()
|
||||
; cur != that->old_types_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
types_[cur->first] = cur->second;
|
||||
old_types_[cur->first] = cur->second;
|
||||
}
|
||||
for (map<perm_string,const VType*>::const_iterator cur = that->new_types_.begin()
|
||||
; cur != that->new_types_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
old_types_[cur->first] = cur->second;
|
||||
}
|
||||
|
||||
for (map<perm_string,const_t>::const_iterator cur = that->constants_.begin()
|
||||
; cur != that->constants_.end() ; ++ cur) {
|
||||
constants_[cur->first] = cur->second;
|
||||
for (map<perm_string,const_t*>::const_iterator cur = that->old_constants_.begin()
|
||||
; cur != that->old_constants_.end() ; ++ cur) {
|
||||
old_constants_[cur->first] = cur->second;
|
||||
}
|
||||
for (map<perm_string,const_t*>::const_iterator cur = that->new_constants_.begin()
|
||||
; cur != that->new_constants_.end() ; ++ cur) {
|
||||
old_constants_[cur->first] = cur->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,18 +148,27 @@ Scope::~Scope()
|
|||
|
||||
ComponentBase* Scope::find_component(perm_string by_name)
|
||||
{
|
||||
map<perm_string,ComponentBase*>::const_iterator cur = components_.find(by_name);
|
||||
if (cur == components_.end())
|
||||
return 0;
|
||||
else
|
||||
map<perm_string,ComponentBase*>::const_iterator cur = new_components_.find(by_name);
|
||||
if (cur == new_components_.end()) {
|
||||
cur = old_components_.find(by_name);
|
||||
if (cur == old_components_.end())
|
||||
return 0;
|
||||
else
|
||||
return cur->second;
|
||||
} else
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
Signal* Scope::find_signal(perm_string by_name)
|
||||
{
|
||||
map<perm_string,Signal*>::const_iterator cur = signals_.find(by_name);
|
||||
if (cur == signals_.end())
|
||||
return 0;
|
||||
else
|
||||
map<perm_string,Signal*>::const_iterator cur = new_signals_.find(by_name);
|
||||
if (cur == new_signals_.end()) {
|
||||
cur = old_signals_.find(by_name);
|
||||
if (cur == old_signals_.end())
|
||||
return 0;
|
||||
else
|
||||
return cur->second;
|
||||
} else {
|
||||
return cur->second;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,28 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include <algorithm>
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
# include "entity.h"
|
||||
# include "expression.h"
|
||||
# include "vsignal.h"
|
||||
|
||||
class Architecture;
|
||||
class ComponentBase;
|
||||
class Entity;
|
||||
class Expression;
|
||||
class Signal;
|
||||
class VType;
|
||||
|
||||
template<typename T>
|
||||
struct delete_object{
|
||||
void operator()(T* item) { delete item; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct delete_pair_second{
|
||||
void operator()(pair<perm_string, T*> item){ delete item.second; }
|
||||
};
|
||||
|
||||
class ScopeBase {
|
||||
|
||||
public:
|
||||
|
|
@ -40,18 +51,37 @@ class ScopeBase {
|
|||
const VType* find_type(perm_string by_name);
|
||||
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp);
|
||||
protected:
|
||||
void cleanup();
|
||||
|
||||
//containers' cleaning helper functions
|
||||
template<typename T> void delete_all(list<T*>& c)
|
||||
{
|
||||
for_each(c.begin(), c.end(), ::delete_object<T>());
|
||||
}
|
||||
template<typename T> void delete_all(map<perm_string, T*>& c)
|
||||
{
|
||||
for_each(c.begin(), c.end(), ::delete_pair_second<T>());
|
||||
}
|
||||
|
||||
// Signal declarations...
|
||||
std::map<perm_string,Signal*> signals_;
|
||||
std::map<perm_string,Signal*> old_signals_; //previous scopes
|
||||
std::map<perm_string,Signal*> new_signals_; //current scope
|
||||
// Component declarations...
|
||||
std::map<perm_string,ComponentBase*> components_;
|
||||
std::map<perm_string,ComponentBase*> old_components_; //previous scopes
|
||||
std::map<perm_string,ComponentBase*> new_components_; //current scope
|
||||
// Type declarations...
|
||||
std::map<perm_string,const VType*> types_;
|
||||
std::map<perm_string,const VType*> old_types_; //previous scopes
|
||||
std::map<perm_string,const VType*> new_types_; //current scope
|
||||
// Constant declarations...
|
||||
struct const_t {
|
||||
~const_t() {delete typ; delete val;}
|
||||
const_t(const VType*t, Expression* v) : typ(t), val(v) {};
|
||||
|
||||
const VType*typ;
|
||||
Expression*val;
|
||||
};
|
||||
std::map<perm_string, struct const_t> constants_;
|
||||
std::map<perm_string, struct const_t*> old_constants_; //previous scopes
|
||||
std::map<perm_string, struct const_t*> new_constants_; //current scope
|
||||
|
||||
void do_use_from(const ScopeBase*that);
|
||||
};
|
||||
|
|
@ -90,20 +120,44 @@ class ActiveScope : public ScopeBase {
|
|||
|
||||
void use_from(const ScopeBase*that) { do_use_from(that); }
|
||||
|
||||
|
||||
/* All bind_name function check if the given name was present
|
||||
* in previous scopes. If it is found, it is erased (but the pointer
|
||||
* is not freed), in order to implement name shadowing. The pointer
|
||||
* be freed only in the scope where the object was defined. This is
|
||||
* done in ScopeBase::cleanup() function .*/
|
||||
|
||||
void bind_name(perm_string name, Signal*obj)
|
||||
{ signals_[name] = obj; }
|
||||
{ map<perm_string, Signal*>::iterator it;
|
||||
if((it = old_signals_.find(name)) != old_signals_.end() )
|
||||
old_signals_.erase(it);
|
||||
new_signals_[name] = obj;
|
||||
}
|
||||
|
||||
void bind_name(perm_string name, ComponentBase*obj)
|
||||
{ components_[name] = obj; }
|
||||
{ map<perm_string, ComponentBase*>::iterator it;
|
||||
if((it = old_components_.find(name)) != old_components_.end() )
|
||||
old_components_.erase(it);
|
||||
new_components_[name] = obj;
|
||||
}
|
||||
|
||||
void bind_name(perm_string name, const VType*obj)
|
||||
{ types_[name] = obj; }
|
||||
void bind_name(perm_string name, const VType* t)
|
||||
{ map<perm_string, const VType*>::iterator it;
|
||||
if((it = old_types_.find(name)) != old_types_.end() )
|
||||
old_types_.erase(it);
|
||||
new_types_[name] = t;
|
||||
}
|
||||
|
||||
void bind_name(perm_string name, const VType*obj, Expression*val)
|
||||
{ map<perm_string, const_t*>::iterator it;
|
||||
if((it = old_constants_.find(name)) != old_constants_.end() )
|
||||
old_constants_.erase(it);
|
||||
new_constants_[name] = new const_t(obj, val);
|
||||
}
|
||||
|
||||
void destroy_global_scope()
|
||||
{
|
||||
const_t&tmp = constants_[name];
|
||||
tmp.typ = obj;
|
||||
tmp.val = val;
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -89,10 +89,10 @@ class VTypePrimitive : public VType {
|
|||
type_t type_;
|
||||
};
|
||||
|
||||
extern const VTypePrimitive primitive_BOOLEAN;
|
||||
extern const VTypePrimitive primitive_BIT;
|
||||
extern const VTypePrimitive primitive_INTEGER;
|
||||
extern const VTypePrimitive primitive_STDLOGIC;
|
||||
extern const VTypePrimitive* primitive_BOOLEAN;
|
||||
extern const VTypePrimitive* primitive_BIT;
|
||||
extern const VTypePrimitive* primitive_INTEGER;
|
||||
extern const VTypePrimitive* primitive_STDLOGIC;
|
||||
|
||||
/*
|
||||
* An array is a compound N-dimensional array of element type. The
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ void VType::write_to_stream(ostream&fd) const
|
|||
void VTypeArray::write_to_stream(ostream&fd) const
|
||||
{
|
||||
// Special case: std_logic_vector
|
||||
if (etype_ == &primitive_STDLOGIC) {
|
||||
if (etype_ == primitive_STDLOGIC) {
|
||||
fd << "std_logic_vector";
|
||||
if (ranges_.size() > 0) {
|
||||
assert(ranges_.size() < 2);
|
||||
|
|
|
|||
Loading…
Reference in New Issue