Merge pull request #54 from orsonmmz/const_array

Update
This commit is contained in:
Stephen Williams 2015-02-20 10:49:53 -08:00
commit a79533ddc9
20 changed files with 416 additions and 65 deletions

View File

@ -2354,6 +2354,11 @@ void pform_module_define_port(const struct vlltype&li,
signed_flag = false;
prange = 0;
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(vtype)) {
data_type = enum_type->base_type;
signed_flag = enum_type->signed_flag;
prange = enum_type->range.get();
} else if (vtype) {
VLerror(li, "sorry: Given type %s not supported here (%s:%d).",
typeid(*vtype).name(), __FILE__, __LINE__);

View File

@ -98,9 +98,8 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
// exists in the component declaration
const InterfacePort*iparm = base->find_generic(cur->first);
if (iparm == 0) {
cerr << get_fileline() << ": error: No generic " << cur->first
cerr << get_fileline() << ": warning: No generic " << cur->first
<< " in component " << cname_ << "." << endl;
errors += 1;
continue;
}
@ -370,9 +369,7 @@ int SignalAssignment::elaborate(Entity*ent, Architecture*arc)
for (list<Expression*>::iterator cur = rval_.begin()
; cur != rval_.end() ; ++cur) {
(*cur)->elaborate_expr(ent, arc, lval_type);
// Handle functions that return unbounded arrays
errors += (*cur)->elaborate_expr(ent, arc, lval_type);
}
return errors;

View File

@ -70,12 +70,12 @@ int Architecture::emit(ostream&out, Entity*entity)
// of the full definition.
typedef_context_t typedef_ctx;
for (map<perm_string,const VType*>::iterator cur = use_types_.begin()
; cur != use_types_.end() ; ++cur) {
//for (map<perm_string,const VType*>::iterator cur = use_types_.begin()
//; cur != use_types_.end() ; ++cur) {
if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
errors += def->emit_typedef(out, typedef_ctx);
}
//if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
//errors += def->emit_typedef(out, typedef_ctx);
//}
for (map<perm_string,const VType*>::iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++cur) {

View File

@ -494,6 +494,11 @@ ExpRelation::~ExpRelation()
{
}
ExpShift::ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2)
: ExpBinary(op1, op2), shift_(op)
{
}
ExpString::ExpString(const char* value)
: value_(strlen(value))
{

View File

@ -692,6 +692,27 @@ class ExpRelation : public ExpBinary {
fun_t fun_;
};
class ExpShift : public ExpBinary {
public:
enum shift_t { SRL, SLL, SRA, SLA, ROL, ROR };
public:
ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2);
Expression*clone() const {
return new ExpShift(shift_, peek_operand1()->clone(), peek_operand2()->clone());
}
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
void write_to_stream(std::ostream&fd) const;
int emit(ostream&out, Entity*ent, ScopeBase*scope);
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
void dump(ostream&out, int indent = 0) const;
private:
shift_t shift_;
};
class ExpString : public Expression {
public:

View File

@ -82,3 +82,33 @@ void ExpNew::dump(ostream&out, int indent) const
out << "New dynamic array size: ";
size_->dump(out, indent);
}
void ExpShift::dump(ostream&out, int indent) const
{
const char*fun_name = "?";
switch (shift_) {
case SRL:
fun_name = "srl";
break;
case SLL:
fun_name = "sll";
break;
case SLA:
fun_name = "sla";
break;
case SRA:
fun_name = "sra";
break;
case ROR:
fun_name = "ror";
break;
case ROL:
fun_name = "rol";
break;
}
out << setw(indent) << "" << "Shift " << fun_name
<< " at " << get_fileline() << endl;
dump_operands(out, indent+4);
}

View File

@ -570,7 +570,7 @@ const VType* ExpAttribute::probe_type(Entity*ent, ScopeBase*scope) const
base_->probe_type(ent, scope);
if (name_ == "length" || name_ == "left" || name_ == "right") {
return &primitive_INTEGER;
return &primitive_NATURAL;
}
return 0;
@ -906,6 +906,10 @@ const VType* ExpName::probe_type(Entity*ent, ScopeBase*scope) const
if (arc && (gtype = arc->probe_genvar_type(name_))) {
return gtype;
}
if (scope->is_enum_name(name_)) {
return &primitive_INTEGER;
}
}
cerr << get_fileline() << ": error: Signal/variable " << name_
@ -918,13 +922,87 @@ const VType* ExpName::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*)co
return probe_type(ent, scope);
}
int ExpName::elaborate_expr(Entity*, ScopeBase*, const VType*ltype)
int ExpName::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
{
const VType*type = NULL;
Expression*exp = NULL;
if (ltype) {
ivl_assert(*this, ltype != 0);
set_type(ltype);
}
// Currently constant arrays of vectors are flattened to single one-dimensional
// localparams. If the user wants to access a particular word, then it is
// necessary to extract the adequate part of the localparam.
// e.g.
// declarations:
// == VHDL ==
// type uns_array is array (natural range <>) of unsigned(7 downto 0);
// constant const_array : uns_array(2 downto 0) :=
// (0 => "00110011", 1 => "101010101", 2=> "00001111");
// == SystemVerilog ==
// localparam const_array = { 8'b00110011, 8'b10101010, 8'b00001111 };
//
// access:
// == VHDL ==
// target_var := const_array(1);
// == SystemVerilog ==
// target_var = const_array[15:8]; // <- indices adjusted to pick the word
if(index_ && scope) {
if(!scope->find_constant(name_, type, exp))
return 0;
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
ivl_assert(*this, arr); // if there is an index, it should be an array, right?
const VType*element = arr->element_type();
const VTypeArray*arr_element = dynamic_cast<const VTypeArray*>(element);
if(!arr_element) {
// index adjustments are not necessary, it is not an array of vectors
return 0;
}
ivl_assert(*this, arr_element->dimensions() == 1);
if(arr_element->dimensions() != 1) {
cerr << get_fileline() << ": Sorry, only one-dimensional constant arrays are handled." << endl;
return 1;
}
int64_t start_val;
bool start_rc = arr_element->dimension(0).msb()->evaluate(ent, scope, start_val);
int64_t finish_val;
bool finish_rc = arr_element->dimension(0).lsb()->evaluate(ent, scope, finish_val);
if(!start_rc || !finish_rc) {
cerr << get_fileline() << ": Could not evaluate the word size." << endl;
return 1;
}
int word_size = abs(start_val - finish_val) + 1;
ExpInteger*size = new ExpInteger(word_size);
Expression*new_index, *new_lsb;
// new indices = [index_ * word_size + word_size : lsb_ * word_size]
if(lsb_) {
ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MULT, index_->clone(), size->clone());
new_index = new ExpArithmetic(ExpArithmetic::PLUS, tmp, size->clone());
new_lsb = new ExpArithmetic(ExpArithmetic::MULT, lsb_->clone(), size->clone());
} else {
new_lsb = new ExpArithmetic(ExpArithmetic::MULT, index_->clone(), size->clone());
new_index = new ExpArithmetic(ExpArithmetic::PLUS, new_lsb->clone(), size->clone());
}
delete index_;
delete lsb_;
delete size;
index_ = new_index;
lsb_ = new_lsb;
}
return 0;
}
@ -957,6 +1035,19 @@ int ExpRelation::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
return errors;
}
int ExpShift::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
{
int errors = 0;
if (ltype == 0) {
ltype = probe_type(ent, scope);
}
ivl_assert(*this, ltype != 0);
errors += elaborate_exprs(ent, scope, ltype);
return errors;
}
/*
* When a string appears in a concatenation, then the type of the
* string is an array with the same element type of the concatenation,

View File

@ -552,7 +552,12 @@ int ExpFunc::emit(ostream&out, Entity*ent, ScopeBase*scope)
{
int errors = 0;
if (name_ == "unsigned" && argv_.size()==1) {
// SystemVerilog takes care of signs, depending on the lvalue
if (name_ == "to_integer" && argv_.size()==1) {
errors += argv_[0]->emit(out, ent, scope);
}
else if (name_ == "unsigned" && argv_.size()==1) {
// Handle the special case that this is a cast to
// unsigned. This function is brought in as part of the
// std numeric library, but we interpret it as the same
@ -625,7 +630,7 @@ int ExpFunc::emit(ostream&out, Entity*ent, ScopeBase*scope)
int ExpInteger::emit(ostream&out, Entity*, ScopeBase*)
{
out << value_;
out << "32'd" << value_;
return 0;
}
@ -766,6 +771,36 @@ int ExpRelation::emit(ostream&out, Entity*ent, ScopeBase*scope)
return errors;
}
int ExpShift::emit(ostream&out, Entity*ent, ScopeBase*scope)
{
int errors = 0;
errors += emit_operand1(out, ent, scope);
switch (shift_) {
case SRL:
out << " >> ";
break;
case SLL:
out << " << ";
break;
case SRA:
out << " >>> ";
break;
case SLA:
out << " <<< ";
break;
case ROR:
case ROL:
out << " /* ?ror/rol? */ ";
break;
}
errors += emit_operand2(out, ent, scope);
return errors;
}
bool ExpString::is_primary(void) const
{
return true;

View File

@ -216,3 +216,37 @@ bool ExpName::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const
return evaluate(scope, val);
}
bool ExpShift::evaluate(ScopeBase*scope, int64_t&val) const
{
int64_t val1, val2;
bool rc;
rc = eval_operand1(scope, val1);
if (rc == false)
return false;
rc = eval_operand2(scope, val2);
if (rc == false)
return false;
switch (shift_) {
case SRL:
val = (uint64_t)val1 >> (uint64_t)val2;
break;
case SLL:
val = (uint64_t)val1 << (uint64_t)val2;
break;
case SRA:
val = (int64_t)val1 >> (int64_t)val2;
break;
case SLA:
val = (int64_t)val1 << (int64_t)val2;
break;
case ROR:
case ROL:
return false;
}
return true;
}

View File

@ -236,6 +236,39 @@ void ExpRelation::write_to_stream(ostream&fd) const
peek_operand2()->write_to_stream(fd);
}
void ExpShift::write_to_stream(ostream&out) const
{
out << "(";
write_to_stream_operand1(out);
out << ")";
switch (shift_) {
case SRL:
out << "srl";
break;
case SLL:
out << "sll";
break;
case SLA:
out << "sla";
break;
case SRA:
out << "sra";
break;
case ROR:
out << "ror";
break;
case ROL:
out << "rol";
break;
}
out << "(";
write_to_stream_operand2(out);
out << ")";
}
void ExpString::write_to_stream(ostream&fd) const
{
fd << "\"";

View File

@ -387,12 +387,11 @@ static void import_std_use(const YYLTYPE&loc, ActiveScope*/*res*/, perm_string p
const VTypePrimitive primitive_BOOLEAN(VTypePrimitive::BOOLEAN, true);
const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true);
const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER);
const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL);
const VTypePrimitive primitive_REAL(VTypePrimitive::REAL);
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true);
const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER);
const VTypeRange primitive_NATURAL(&primitive_INTEGER, INT64_MAX, 0);
static const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
static const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
static const VTypeArray primitive_STRING(&primitive_CHARACTER, vector<VTypeArray::range_t> (1));
@ -417,10 +416,13 @@ bool is_global_type(perm_string name)
if (name == "integer") return true;
if (name == "real") return true;
if (name == "std_logic") return true;
if (name == "std_logic_vector") return true;
if (name == "character") return true;
if (name == "bit_vector") return true;
if (name == "string") return true;
if (name == "natural") return true;
if (name == "signed") return true;
if (name == "unsigned") return true;
return false;
}

View File

@ -73,12 +73,6 @@ void Package::write_to_stream(ostream&fd) const
// Do not include global types in types dump
if (is_global_type(cur->first))
continue;
if (cur->first == "std_logic_vector")
continue;
if (cur->first == "signed")
continue;
if (cur->first == "unsigned")
continue;
fd << "type " << cur->first << " is ";
cur->second->write_type_to_stream(fd);
@ -90,8 +84,6 @@ void Package::write_to_stream(ostream&fd) const
// Do not include global types in types dump
if (is_global_type(cur->first))
continue;
if (cur->first == "std_logic_vector")
continue;
fd << "type " << cur->first << " is ";
cur->second->write_type_to_stream(fd);

View File

@ -32,26 +32,22 @@ int Package::emit_package(ostream&fd) const
if (cur_types_.empty() && cur_constants_.empty() && cur_subprograms_.empty())
return 0;
// If this package was imported from a library, then do not
// emit it again.
if (from_library_.str() != 0) {
fd << "/* Suppress package " << name()
<< " from library " << from_library_ << " */" << endl;
return 0;
}
int errors = 0;
fd << "package \\" << name() << " ;" << endl;
fd << "`ifndef package_" << name() << endl;
fd << "`define package_" << name() << endl;
// Only emit types that were defined within this package. Skip
// the types that were imported from elsewhere.
typedef_context_t typedef_ctx;
for (map<perm_string,const VType*>::const_iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++ cur) {
fd << "typedef ";
errors += cur->second->emit_def(fd,
dynamic_cast<const VTypeDef*>(cur->second) ? empty_perm_string : cur->first);
fd << " ;" << endl;
if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
errors += def->emit_typedef(fd, typedef_ctx);
//fd << "typedef ";
//errors += cur->second->emit_def(fd,
//dynamic_cast<const VTypeDef*>(cur->second) ? empty_perm_string : cur->first);
//fd << " ;" << endl;
}
//for (map<perm_string,struct const_t*>::const_iterator cur = use_constants_.begin()
@ -67,14 +63,19 @@ int Package::emit_package(ostream&fd) const
//fd << ";" << endl;
//}
fd << "package \\" << name() << " ;" << endl;
for (map<perm_string,Subprogram*>::const_iterator cur = cur_subprograms_.begin()
; cur != cur_subprograms_.end() ; ++ cur) {
// Do not emit unbounded functions, we will just need fixed instances later
if(!cur->second->unbounded())
errors += cur->second->emit_package(fd);
else
fd << "/* function " << cur->second->name() <<
" has to be instantiated, skipping */" << endl;
}
fd << "endpackage" << endl;
fd << "endpackage /* " << name() << " */" << endl;
fd << "`endif" << endl;
return errors;
}

View File

@ -314,7 +314,7 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
%type <arch_statement> concurrent_statement component_instantiation_statement
%type <arch_statement> concurrent_conditional_signal_assignment
%type <arch_statement> concurrent_signal_assignment_statement
%type <arch_statement> concurrent_signal_assignment_statement concurrent_simple_signal_assignment
%type <arch_statement> for_generate_statement generate_statement if_generate_statement
%type <arch_statement> process_statement
%type <arch_statement_list> architecture_statement_part generate_statement_body
@ -348,14 +348,14 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
%type <text> architecture_body_start package_declaration_start
%type <text> package_body_start
%type <text> identifier_opt identifier_colon_opt logical_name suffix
%type <text> identifier_opt identifier_colon_opt logical_name suffix instantiated_unit
%type <name_list> logical_name_list identifier_list
%type <name_list> enumeration_literal_list enumeration_literal
%type <sequ_list> if_statement_else sequence_of_statements subprogram_statement_part
%type <sequ> sequential_statement if_statement signal_assignment_statement
%type <sequ> sequential_statement if_statement signal_assignment signal_assignment_statement
%type <sequ> case_statement procedure_call procedure_call_statement
%type <sequ> loop_statement variable_assignment_statement
%type <sequ> loop_statement variable_assignment variable_assignment_statement
%type <sequ> return_statement
%type <range> range
@ -677,22 +677,27 @@ component_declaration
}
;
instantiated_unit
: IDENTIFIER
| K_component IDENTIFIER { $$ = $2; }
;
component_instantiation_statement
: IDENTIFIER ':' K_component_opt IDENTIFIER generic_map_aspect_opt port_map_aspect_opt ';'
: IDENTIFIER ':' instantiated_unit generic_map_aspect_opt port_map_aspect_opt ';'
{ perm_string iname = lex_strings.make($1);
perm_string cname = lex_strings.make($4);
ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $5, $6);
perm_string cname = lex_strings.make($3);
ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $4, $5);
delete $4;
delete $5;
delete $6;
FILE_NAME(tmp, @1);
delete[]$1;
delete[]$4;
delete[]$3;
$$ = tmp;
}
| IDENTIFIER ':' K_component_opt IDENTIFIER error ';'
| IDENTIFIER ':' instantiated_unit error ';'
{ errormsg(@4, "Errors in component instantiation.\n");
delete[]$1;
delete[]$4;
delete[]$3;
$$ = 0;
}
;
@ -726,7 +731,6 @@ composite_type_definition
{ $$ = $1; }
;
/* The when...else..when...else syntax is not a general expression
in VHDL but a specific sort of assignment statement model. We
create Exppression objects for it, but the parser will only
@ -763,6 +767,17 @@ concurrent_conditional_signal_assignment /* IEEE 1076-2008 P11.6 */
}
;
concurrent_simple_signal_assignment
: name LEQ waveform ';'
{ ExpName*name = dynamic_cast<ExpName*> ($1);
assert(name);
SignalAssignment*tmp = new SignalAssignment(name, *$3);
FILE_NAME(tmp, @1);
$$ = tmp;
delete $3;
}
else_when_waveforms
: else_when_waveforms else_when_waveform
{ list<ExpConditional::else_t*>*tmp = $1;
@ -790,18 +805,14 @@ else_when_waveform
;
concurrent_signal_assignment_statement /* IEEE 1076-2008 P11.6 */
: name LEQ waveform ';'
{ ExpName*name = dynamic_cast<ExpName*> ($1);
assert(name);
SignalAssignment*tmp = new SignalAssignment(name, *$3);
FILE_NAME(tmp, @1);
: concurrent_simple_signal_assignment
$$ = tmp;
delete $3;
}
| IDENTIFIER ':' concurrent_simple_signal_assignment { $$ = $3; }
| concurrent_conditional_signal_assignment
| IDENTIFIER ':' concurrent_conditional_signal_assignment { $$ = $3; }
| name LEQ error ';'
{ errormsg(@2, "Syntax error in signal assignment waveform.\n");
delete $1;
@ -2128,7 +2139,41 @@ sequential_statement
}
;
shift_expression : simple_expression { $$ = $1; } ;
shift_expression
: simple_expression
| simple_expression K_srl simple_expression
{ ExpShift*tmp = new ExpShift(ExpShift::SRL, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| simple_expression K_sll simple_expression
{ ExpShift*tmp = new ExpShift(ExpShift::SLL, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| simple_expression K_sra simple_expression
{ ExpShift*tmp = new ExpShift(ExpShift::SRA, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| simple_expression K_sla simple_expression
{ ExpShift*tmp = new ExpShift(ExpShift::SLA, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| simple_expression K_ror simple_expression
{ sorrymsg(@2, "ROR is not supported.\n");
ExpShift*tmp = new ExpShift(ExpShift::ROR, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| simple_expression K_rol simple_expression
{ sorrymsg(@2, "ROL is not supported.\n");
ExpShift*tmp = new ExpShift(ExpShift::ROL, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
;
sign
: '+'
@ -2206,7 +2251,7 @@ simple_expression_terms
}
;
signal_assignment_statement
signal_assignment
: name LEQ waveform ';'
{ SignalSeqAssignment*tmp = new SignalSeqAssignment($1, $3);
FILE_NAME(tmp, @1);
@ -2221,6 +2266,10 @@ signal_assignment_statement
}
;
signal_assignment_statement
: signal_assignment
| IDENTIFIER ':' signal_assignment { $$ = $3; }
subprogram_body_start
: subprogram_specification K_is
{ assert(!active_sub);
@ -2393,6 +2442,9 @@ type_declaration
tmp->set_definition($4);
active_scope->incomplete_types.erase(cur);
}
if(const VTypeEnum*enum_type = dynamic_cast<const VTypeEnum*>($4)) {
active_scope->use_enum(enum_type);
}
}
delete[]$2;
}
@ -2449,6 +2501,10 @@ use_clauses_opt
;
variable_assignment_statement /* IEEE 1076-2008 P10.6.1 */
: variable_assignment
| IDENTIFIER ':' variable_assignment { $$ = $3; }
variable_assignment
: name VASSIGN expression ';'
{ VariableSeqAssignment*tmp = new VariableSeqAssignment($1, $3);
FILE_NAME(tmp, @1);
@ -2515,7 +2571,6 @@ waveform_element
/* Some keywords are optional in some contexts. In all such cases, a
similar rule is used, as described here. */
K_architecture_opt : K_architecture | ;
K_component_opt : K_component | ;
K_configuration_opt: K_configuration| ;
K_entity_opt : K_entity | ;
K_is_opt : K_is | ;

View File

@ -59,6 +59,8 @@ ScopeBase::ScopeBase(const ActiveScope&ref)
use_subprograms_ = ref.use_subprograms_;
cur_subprograms_ = ref.cur_subprograms_;
use_enums_ = ref.use_enums_;
// This constructor is invoked when the parser is finished with
// an active scope and is making the actual scope. At this point
// we know that "this" is the parent scope for the subprograms,
@ -102,8 +104,11 @@ const VType*ScopeBase::find_type(perm_string by_name)
return cur->second;
}
bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp)
bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const
{
typ = NULL;
exp = NULL;
map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.find(by_name);
if (cur == cur_constants_.end()) {
cur = use_constants_.find(by_name);
@ -119,6 +124,8 @@ bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*
exp = cur->second->val;
return true;
}
return false;
}
Signal* ScopeBase::find_signal(perm_string by_name) const
@ -181,6 +188,17 @@ Subprogram* ScopeBase::find_subprogram(perm_string name) const
return 0;
}
bool ScopeBase::is_enum_name(perm_string name) const
{
for(list<const VTypeEnum*>::const_iterator it = use_enums_.begin();
it != use_enums_.end(); ++it) {
if((*it)->has_name(name))
return true;
}
return false;
}
/*
* This method is only used by the ActiveScope derived class to import
* definition from another scope.
@ -219,6 +237,8 @@ void ScopeBase::do_use_from(const ScopeBase*that)
; cur != that->cur_constants_.end() ; ++ cur) {
use_constants_[cur->first] = cur->second;
}
use_enums_ = that->use_enums_;
}
void ScopeBase::transfer_from(ScopeBase&ref)
@ -266,6 +286,11 @@ bool ActiveScope::is_vector_name(perm_string name) const
if (find_variable(name))
return true;
const VType*dummy_type;
Expression*dummy_exp;
if (find_constant(name, dummy_type, dummy_exp))
return true;
if (context_entity_ && context_entity_->find_port(name))
return true;

View File

@ -53,11 +53,12 @@ class ScopeBase {
virtual ~ScopeBase() =0;
const VType* find_type(perm_string by_name);
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp);
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
Signal* find_signal(perm_string by_name) const;
Variable* find_variable(perm_string by_name) const;
virtual const InterfacePort* find_param(perm_string by_name) const;
Subprogram* find_subprogram(perm_string by_name) const;
bool is_enum_name(perm_string name) const;
// Moves all signals, variables and components from another scope to
// this one. After the transfer new_* maps are emptied in the another scope.
void transfer_from(ScopeBase&ref);
@ -114,6 +115,8 @@ class ScopeBase {
std::map<perm_string, Subprogram*> use_subprograms_; //imported
std::map<perm_string, Subprogram*> cur_subprograms_; //current
std::list<const VTypeEnum*> use_enums_;
void do_use_from(const ScopeBase*that);
};
@ -199,6 +202,9 @@ class ActiveScope : public ScopeBase {
cur_types_[name] = t;
}
inline void use_enum(const VTypeEnum* t)
{ use_enums_.push_back(t); }
inline void use_name(perm_string name, const VType* t)
{ use_types_[name] = t; }

View File

@ -23,6 +23,7 @@
# include <map>
# include <typeinfo>
# include <cassert>
# include <algorithm>
using namespace std;
@ -66,11 +67,14 @@ void VTypePrimitive::show(ostream&out) const
case INTEGER:
out << "INTEGER";
break;
case NATURAL:
out << "NATURAL";
break;
case REAL:
out << "REAL";
break;
case STDLOGIC:
out << "std_logic";
out << "STD_LOGIC";
break;
}
}
@ -251,6 +255,11 @@ void VTypeEnum::show(ostream&out) const
out << ")";
}
bool VTypeEnum::has_name(perm_string name) const
{
return std::find(names_.begin(), names_.end(), name) != names_.end();
}
VTypeRecord::VTypeRecord(std::list<element_t*>*elements)
: elements_(elements->size())
{

View File

@ -151,7 +151,7 @@ class VTypeERROR : public VType {
class VTypePrimitive : public VType {
public:
enum type_t { BOOLEAN, BIT, INTEGER, REAL, STDLOGIC, CHARACTER };
enum type_t { BOOLEAN, BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER };
public:
VTypePrimitive(type_t tt, bool packed = false);
@ -177,6 +177,7 @@ class VTypePrimitive : public VType {
extern const VTypePrimitive primitive_BOOLEAN;
extern const VTypePrimitive primitive_BIT;
extern const VTypePrimitive primitive_INTEGER;
extern const VTypePrimitive primitive_NATURAL;
extern const VTypePrimitive primitive_REAL;
extern const VTypePrimitive primitive_STDLOGIC;
extern const VTypePrimitive primitive_CHARACTER;
@ -295,6 +296,9 @@ class VTypeEnum : public VType {
void show(std::ostream&) const;
int emit_def(std::ostream&out, perm_string name) const;
// Checks if the name is stored in the enum.
bool has_name(perm_string name) const;
private:
std::vector<perm_string>names_;
};

View File

@ -154,6 +154,9 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const
case STDLOGIC:
out << "logic";
break;
case NATURAL:
out << "int unsigned";
break;
case INTEGER:
out << "int";
break;

View File

@ -140,6 +140,9 @@ void VTypePrimitive::write_to_stream(ostream&fd) const
case INTEGER:
fd << "integer";
break;
case NATURAL:
fd << "natural";
break;
case REAL:
fd << "real";
break;