Put off array bound evaluation / describe entity generics as parameters
Entity generics are easily implemented as module parameters, so make it so. Give the parameters their default values from the generic declaration. Array bounds may use values that cannot be evaluated right away, so put off their evaluation.
This commit is contained in:
parent
a6f63b8a54
commit
d9acfe57b1
|
|
@ -55,6 +55,27 @@ void dump_design_entities(ostream&file)
|
|||
}
|
||||
}
|
||||
|
||||
void ComponentBase::dump_generics(ostream&out, int indent) const
|
||||
{
|
||||
if (parms_.empty()) {
|
||||
out << setw(indent) << "" << "No generics" << endl;
|
||||
} else {
|
||||
out << setw(indent) << "" << "GENERICS:" << endl;
|
||||
for (vector<InterfacePort*>::const_iterator cur = parms_.begin()
|
||||
; cur != parms_.end() ; ++cur) {
|
||||
InterfacePort*item = *cur;
|
||||
out << setw(indent+2) << "" << item->name
|
||||
<< " : " << item->mode
|
||||
<< ", type=";
|
||||
if (item->type)
|
||||
item->type->show(out);
|
||||
else
|
||||
out << "<nil>";
|
||||
out << ", file=" << item->get_fileline() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentBase::dump_ports(ostream&out, int indent) const
|
||||
{
|
||||
if (ports_.empty()) {
|
||||
|
|
@ -122,6 +143,7 @@ void Scope::dump_scope(ostream&out) const
|
|||
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_generics(out);
|
||||
cur->second->dump_ports(out);
|
||||
out << " end component " << cur->first << endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ const InterfacePort* ComponentBase::find_port(perm_string my_name) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
const InterfacePort* ComponentBase::find_generic(perm_string my_name) const
|
||||
{
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx]->name == my_name)
|
||||
return parms_[idx];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Entity::Entity(perm_string name)
|
||||
: ComponentBase(name)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,7 +60,9 @@ class ComponentBase : public LineInfo {
|
|||
|
||||
// Entities have names.
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
const InterfacePort* find_port(perm_string by_name) const;
|
||||
const InterfacePort* find_generic(perm_string by_name) const;
|
||||
|
||||
// Declare the ports for the entity. The parser calls this
|
||||
// method with a list of interface elements that were parsed
|
||||
|
|
@ -73,14 +75,12 @@ class ComponentBase : public LineInfo {
|
|||
void write_to_stream(std::ostream&fd) const;
|
||||
|
||||
public:
|
||||
void dump_generics(std::ostream&out, int indent =0) const;
|
||||
void dump_ports(std::ostream&out, int indent = 0) const;
|
||||
|
||||
protected:
|
||||
// This is really only used by the Entity derived class.
|
||||
const std::vector<InterfacePort*>&get_ports() const { return ports_; }
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
protected:
|
||||
std::vector<InterfacePort*> parms_;
|
||||
std::vector<InterfacePort*> ports_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -87,10 +87,8 @@ int Entity::elaborate()
|
|||
int Entity::elaborate_ports_(void)
|
||||
{
|
||||
int errors = 0;
|
||||
const std::vector<InterfacePort*>&ports = get_ports();
|
||||
|
||||
for (std::vector<InterfacePort*>::const_iterator cur = ports.begin()
|
||||
; cur != ports.end() ; ++cur) {
|
||||
for (std::vector<InterfacePort*>::const_iterator cur = ports_.begin()
|
||||
; cur != ports_.end() ; ++cur) {
|
||||
|
||||
InterfacePort*cur_port = *cur;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
# include <iostream>
|
||||
# include <fstream>
|
||||
# include <iomanip>
|
||||
# include <ivl_assert.h>
|
||||
|
||||
int emit_entities(void)
|
||||
{
|
||||
|
|
@ -39,16 +40,30 @@ int Entity::emit(ostream&out)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
const std::vector<InterfacePort*>&ports = get_ports();
|
||||
out << "module ";
|
||||
// If there are generics, emit them
|
||||
if (parms_.size() > 0) {
|
||||
out << "#(";
|
||||
for (vector<InterfacePort*>::const_iterator cur = parms_.begin()
|
||||
; cur != parms_.end() ; ++cur) {
|
||||
const InterfacePort*curp = *cur;
|
||||
if (cur != parms_.begin())
|
||||
out << ", ";
|
||||
out << "parameter \\" << curp->name << " = ";
|
||||
ivl_assert(*this, curp->expr);
|
||||
errors += curp->expr->emit(out, this, 0);
|
||||
}
|
||||
out << ") ";
|
||||
}
|
||||
|
||||
out << "module " << get_name();
|
||||
out << get_name();
|
||||
|
||||
// If there are ports, emit them.
|
||||
if (ports.size() > 0) {
|
||||
if (ports_.size() > 0) {
|
||||
out << "(";
|
||||
const char*sep = 0;
|
||||
for (vector<InterfacePort*>::const_iterator cur = ports.begin()
|
||||
; cur != ports.end() ; ++cur) {
|
||||
for (vector<InterfacePort*>::const_iterator cur = ports_.begin()
|
||||
; cur != ports_.end() ; ++cur) {
|
||||
InterfacePort*port = *cur;
|
||||
|
||||
VType::decl_t&decl = declarations_[port->name];
|
||||
|
|
|
|||
|
|
@ -42,11 +42,6 @@ void Expression::set_type(const VType*typ)
|
|||
type_ = typ;
|
||||
}
|
||||
|
||||
bool Expression::evaluate(ScopeBase*, int64_t&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Expression::symbolic_compare(const Expression*) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
|
|
@ -87,40 +82,6 @@ ExpAttribute::~ExpAttribute()
|
|||
delete base_;
|
||||
}
|
||||
|
||||
bool ExpAttribute::evaluate(ScopeBase*, int64_t&val) const
|
||||
{
|
||||
/* Special Case: The length attribute can be calculated all
|
||||
the down to a literal integer at compile time, and all it
|
||||
needs is the type of the base expression. (The base
|
||||
expression doesn't even need to be evaluated.) */
|
||||
if (name_ == "length") {
|
||||
const VType*base_type = base_->peek_type();
|
||||
//if (base_type == 0)
|
||||
// base_type = base_->probe_type(ent,arc);
|
||||
|
||||
ivl_assert(*this, base_type);
|
||||
|
||||
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(base_type);
|
||||
if (arr == 0) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Cannot apply the 'length attribute to non-array objects"
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t size = 1;
|
||||
for (size_t idx = 0 ; idx < arr->dimensions() ; idx += 1) {
|
||||
const VTypeArray::range_t&dim = arr->dimension(idx);
|
||||
ivl_assert(*this, ! dim.is_box());
|
||||
size *= 1 + labs(dim.msb() - dim.lsb());
|
||||
}
|
||||
val = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ExpBinary::ExpBinary(Expression*op1, Expression*op2)
|
||||
: operand1_(op1), operand2_(op2)
|
||||
{
|
||||
|
|
@ -402,18 +363,6 @@ const char* ExpName::name() const
|
|||
return name_;
|
||||
}
|
||||
|
||||
bool ExpName::evaluate(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
const VType*type;
|
||||
Expression*exp;
|
||||
|
||||
bool rc = scope->find_constant(name_, type, exp);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
return exp->evaluate(scope, val);
|
||||
}
|
||||
|
||||
ExpRelation::ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2)
|
||||
: ExpBinary(op1, op2), fun_(ty)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ class Expression : public LineInfo {
|
|||
// argument if the evaluation works, or return false if it
|
||||
// cannot be done.
|
||||
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
virtual bool evaluate(Entity*ent, Architecture*arc, int64_t&val) const;
|
||||
|
||||
|
||||
// The symbolic compare returns true if the two expressions
|
||||
// are equal without actually calculating the value.
|
||||
|
|
@ -266,6 +268,7 @@ class ExpAttribute : public Expression {
|
|||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
// Some attributes can be evaluated at compile time
|
||||
bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
bool evaluate(Entity*ent, Architecture*arc, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
|
|
@ -427,6 +430,7 @@ class ExpName : public Expression {
|
|||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
bool is_primary(void) const;
|
||||
bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
bool evaluate(Entity*ent, Architecture*arc, int64_t&val) const;
|
||||
bool symbolic_compare(const Expression*that) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
const char* name() const;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ using namespace std;
|
|||
|
||||
int Expression::elaborate_lval(Entity*, Architecture*, bool)
|
||||
{
|
||||
cerr << get_fileline() << ": error: Expression is not a valie l-value." << endl;
|
||||
cerr << get_fileline() << ": error: Expression is not a valid l-value." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +57,13 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
|
|||
|
||||
found_type = cur->type;
|
||||
|
||||
} else if (ent->find_generic(name_)) {
|
||||
|
||||
cerr << get_fileline() << ": error: Assignment to generic "
|
||||
<< name_ << " from entity "
|
||||
<< ent->get_name() << "." << endl;
|
||||
return 1;
|
||||
|
||||
} else if (Signal*sig = arc->find_signal(name_)) {
|
||||
// Tell the target signal that this may be a sequential l-value.
|
||||
if (is_sequ) sig->count_ref_sequ();
|
||||
|
|
@ -93,8 +100,10 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
|
|||
flag = lsb_->evaluate(arc, use_lsb);
|
||||
ivl_assert(*this, flag);
|
||||
|
||||
Expression*exp_msb = new ExpInteger(use_msb);
|
||||
Expression*exp_lsb = new ExpInteger(use_lsb);
|
||||
vector<VTypeArray::range_t> use_dims (1);
|
||||
use_dims[0] = VTypeArray::range_t(use_msb, use_lsb);
|
||||
use_dims[0] = VTypeArray::range_t(exp_msb, exp_lsb);
|
||||
found_type = new VTypeArray(array->element_type(), use_dims);
|
||||
}
|
||||
}
|
||||
|
|
@ -366,8 +375,15 @@ int ExpLogical::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype)
|
|||
|
||||
const VType* ExpName::probe_type(Entity*ent, Architecture*arc) const
|
||||
{
|
||||
if (const InterfacePort*cur = ent->find_port(name_))
|
||||
if (const InterfacePort*cur = ent->find_port(name_)) {
|
||||
ivl_assert(*this, cur->type);
|
||||
return cur->type;
|
||||
}
|
||||
|
||||
if (const InterfacePort*cur = ent->find_generic(name_)) {
|
||||
ivl_assert(*this, cur->type);
|
||||
return cur->type;
|
||||
}
|
||||
|
||||
if (Signal*sig = arc->find_signal(name_))
|
||||
return sig->peek_type();
|
||||
|
|
|
|||
|
|
@ -87,11 +87,38 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V
|
|||
const VTypeArray::range_t&rang = atype->dimension(0);
|
||||
assert(! rang.is_box());
|
||||
|
||||
int asize = abs(rang.msb() - rang.lsb()) + 1;
|
||||
int64_t use_msb;
|
||||
int64_t use_lsb;
|
||||
bool rc_msb, rc_lsb;
|
||||
rc_msb = rang.msb()->evaluate(ent, arc, use_msb);
|
||||
rc_lsb = rang.lsb()->evaluate(ent, arc, use_lsb);
|
||||
|
||||
out << "{" << asize << "{";
|
||||
errors += aggregate_[0].expr->emit(out, ent, arc);
|
||||
out << "}}";
|
||||
if (rc_msb && rc_lsb) {
|
||||
int asize = abs(use_msb - use_lsb) + 1;
|
||||
out << "{" << asize << "{";
|
||||
errors += aggregate_[0].expr->emit(out, ent, arc);
|
||||
out << "}}";
|
||||
} else {
|
||||
out << "{(";
|
||||
if (rc_msb) {
|
||||
out << use_msb;
|
||||
} else {
|
||||
out << "(";
|
||||
errors += rang.msb()->emit(out, ent, arc);
|
||||
out << ")";
|
||||
}
|
||||
if (rc_lsb && use_lsb==0) {
|
||||
} else if (rc_lsb) {
|
||||
out << "-" << use_lsb;
|
||||
} else {
|
||||
out << "-(";
|
||||
errors += rang.lsb()->emit(out, ent, arc);
|
||||
out << ")";
|
||||
}
|
||||
out << "+1){";
|
||||
errors += aggregate_[0].expr->emit(out, ent, arc);
|
||||
out << "}}";
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +137,7 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V
|
|||
|
||||
Expression*tmp = aggregate_[idx].choice->simple_expression(false);
|
||||
int64_t tmp_val;
|
||||
if (! tmp->evaluate(arc, tmp_val)) {
|
||||
if (! tmp->evaluate(ent, arc, tmp_val)) {
|
||||
cerr << tmp->get_fileline() << ": error: Unable to evaluate aggregate choice expression." << endl;
|
||||
errors += 1;
|
||||
continue;
|
||||
|
|
@ -119,16 +146,22 @@ int ExpAggregate::emit_array_(ostream&out, Entity*ent, Architecture*arc, const V
|
|||
element_map[tmp_val] = &aggregate_[idx];
|
||||
}
|
||||
|
||||
ivl_assert(*this, rang.msb() >= rang.lsb());
|
||||
int64_t use_msb, use_lsb;
|
||||
bool rc;
|
||||
rc = rang.msb()->evaluate(ent, arc, use_msb);
|
||||
ivl_assert(*this, rc);
|
||||
rc = rang.lsb()->evaluate(ent, arc, use_lsb);
|
||||
ivl_assert(*this, rc);
|
||||
ivl_assert(*this, use_msb >= use_lsb);
|
||||
|
||||
out << "{";
|
||||
for (int idx = rang.msb() ; idx >= rang.lsb() ; idx -= 1) {
|
||||
for (int64_t idx = use_msb ; idx >= use_lsb ; idx -= 1) {
|
||||
choice_element*cur = element_map[idx];
|
||||
if (cur == 0)
|
||||
cur = element_other;
|
||||
ivl_assert(*this, cur != 0);
|
||||
|
||||
if (idx < rang.msb())
|
||||
if (idx < use_msb)
|
||||
out << ", ";
|
||||
errors += cur->expr->emit(out, ent, arc);
|
||||
}
|
||||
|
|
@ -154,7 +187,7 @@ int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
expression doesn't even need to be evaluated.) */
|
||||
if (name_ == "length") {
|
||||
int64_t val;
|
||||
bool rc = evaluate(arc, val);
|
||||
bool rc = evaluate(ent, arc, val);
|
||||
out << val;
|
||||
if (rc)
|
||||
return errors;
|
||||
|
|
@ -356,7 +389,7 @@ int ExpFunc::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
} else if (name_ == "to_unsigned" && argv_.size() == 2) {
|
||||
int64_t use_size;
|
||||
bool rc = argv_[1]->evaluate(arc, use_size);
|
||||
bool rc = argv_[1]->evaluate(ent, arc, use_size);
|
||||
ivl_assert(*this, rc);
|
||||
|
||||
out << "$unsigned(" << use_size << "'(";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "expression.h"
|
||||
# include "architec.h"
|
||||
# include <ivl_assert.h>
|
||||
|
||||
bool Expression::evaluate(ScopeBase*, int64_t&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Expression::evaluate(Entity*, Architecture*arc, int64_t&val) const
|
||||
{
|
||||
return evaluate(arc, val);
|
||||
}
|
||||
|
||||
|
||||
bool ExpAttribute::evaluate(ScopeBase*, int64_t&val) const
|
||||
{
|
||||
/* Special Case: The length attribute can be calculated all
|
||||
the down to a literal integer at compile time, and all it
|
||||
needs is the type of the base expression. (The base
|
||||
expression doesn't even need to be evaluated.) */
|
||||
if (name_ == "length") {
|
||||
const VType*base_type = base_->peek_type();
|
||||
//if (base_type == 0)
|
||||
// base_type = base_->probe_type(ent,arc);
|
||||
|
||||
ivl_assert(*this, base_type);
|
||||
|
||||
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(base_type);
|
||||
if (arr == 0) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Cannot apply the 'length attribute to non-array objects"
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t size = 1;
|
||||
for (size_t idx = 0 ; idx < arr->dimensions() ; idx += 1) {
|
||||
const VTypeArray::range_t&dim = arr->dimension(idx);
|
||||
ivl_assert(*this, ! dim.is_box());
|
||||
size *= 1 + labs(dim.msb() - dim.lsb());
|
||||
}
|
||||
val = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExpAttribute::evaluate(Entity*, Architecture*arc, int64_t&val) const
|
||||
{
|
||||
return evaluate(arc, val);
|
||||
}
|
||||
|
||||
bool ExpName::evaluate(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
const VType*type;
|
||||
Expression*exp;
|
||||
|
||||
bool rc = scope->find_constant(name_, type, exp);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
return exp->evaluate(scope, val);
|
||||
}
|
||||
|
||||
bool ExpName::evaluate(Entity*ent, Architecture*arc, int64_t&val) const
|
||||
{
|
||||
const InterfacePort*gen = ent->find_generic(name_);
|
||||
if (gen) {
|
||||
cerr << get_fileline() << ": sorry: I don't necessarily handle generic overrides." << endl;
|
||||
|
||||
// Evaluate the default expression and use that.
|
||||
if (gen->expr)
|
||||
return gen->expr->evaluate(ent, arc, val);
|
||||
}
|
||||
|
||||
return evaluate(arc, val);
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# define __STDC_LIMIT_MACROS
|
||||
# include "parse_misc.h"
|
||||
# include "compiler.h"
|
||||
# include "package.h"
|
||||
|
|
@ -24,6 +25,7 @@
|
|||
# include <list>
|
||||
# include <map>
|
||||
# include <string>
|
||||
# include <stdint.h>
|
||||
# include <sys/stat.h>
|
||||
# include <cassert>
|
||||
|
||||
|
|
@ -312,6 +314,8 @@ const VTypePrimitive* primitive_BIT = new VTypePrimitive(VTypePrimitive::BI
|
|||
const VTypePrimitive* primitive_INTEGER = new VTypePrimitive(VTypePrimitive::INTEGER);
|
||||
const VTypePrimitive* primitive_STDLOGIC = new VTypePrimitive(VTypePrimitive::STDLOGIC);
|
||||
|
||||
const VTypeRange* primitive_NATURAL = new VTypeRange(primitive_INTEGER, INT64_MAX, 0);
|
||||
|
||||
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));
|
||||
|
||||
|
|
@ -322,6 +326,7 @@ void generate_global_types(ActiveScope*res)
|
|||
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("natural"), primitive_NATURAL);
|
||||
}
|
||||
|
||||
void library_set_work_path(const char*path)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
# include <map>
|
||||
# include <vector>
|
||||
# include "parse_types.h"
|
||||
# include <ivl_assert.h>
|
||||
# include <assert.h>
|
||||
|
||||
inline void FILE_NAME(LineInfo*tmp, const struct yyltype&where)
|
||||
|
|
@ -1095,6 +1096,7 @@ interface_element
|
|||
port->name = *(cur);
|
||||
port->type = $4;
|
||||
port->expr = $5;
|
||||
ivl_assert(*port, port->type);
|
||||
tmp->push_back(port);
|
||||
}
|
||||
delete $1;
|
||||
|
|
@ -1746,6 +1748,9 @@ subtype_declaration
|
|||
subtype_indication
|
||||
: IDENTIFIER
|
||||
{ const VType*tmp = parse_type_by_name(lex_strings.make($1));
|
||||
if (tmp == 0) {
|
||||
errormsg(@1, "Can't find type name `%s'\n", $1);
|
||||
}
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void bind_architecture_to_entity(const char*ename, Architecture*arch)
|
|||
}
|
||||
|
||||
const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
|
||||
ScopeBase*scope,
|
||||
ScopeBase* /* scope */,
|
||||
Expression*array_left,
|
||||
bool /* downto*/ ,
|
||||
Expression*array_right)
|
||||
|
|
@ -89,17 +89,7 @@ const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
|
|||
// For now, I only know how to handle 1 dimension
|
||||
assert(base_array->dimensions() == 1);
|
||||
|
||||
int64_t left_val;
|
||||
int64_t right_val;
|
||||
bool rc = array_left->evaluate(scope, left_val);
|
||||
if (rc == false)
|
||||
return 0;
|
||||
|
||||
rc = array_right->evaluate(scope, right_val);
|
||||
if (rc == false)
|
||||
return 0;
|
||||
|
||||
range[0] = VTypeArray::range_t(left_val, right_val);
|
||||
range[0] = VTypeArray::range_t(array_left, array_right);
|
||||
|
||||
VTypeArray*subtype = new VTypeArray(base_array->element_type(), range, base_array->signed_vector());
|
||||
return subtype;
|
||||
|
|
|
|||
|
|
@ -195,10 +195,10 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
ivl_assert(*this, range_);
|
||||
|
||||
int64_t start_val;
|
||||
bool start_rc = range_->msb()->evaluate(arc, start_val);
|
||||
bool start_rc = range_->msb()->evaluate(ent, arc, start_val);
|
||||
|
||||
int64_t finish_val;
|
||||
bool finish_rc = range_->lsb()->evaluate(arc, finish_val);
|
||||
bool finish_rc = range_->lsb()->evaluate(ent, arc, finish_val);
|
||||
|
||||
ivl_assert(*this, start_rc);
|
||||
ivl_assert(*this, finish_rc);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
# include <inttypes.h>
|
||||
# include "StringHeap.h"
|
||||
|
||||
class Expression;
|
||||
|
||||
/*
|
||||
* A description of a VHDL type consists of a graph of VType
|
||||
* objects. Derived types are specific kinds of types, and those that
|
||||
|
|
@ -123,17 +125,17 @@ class VTypeArray : public VType {
|
|||
public:
|
||||
class range_t {
|
||||
public:
|
||||
range_t() : msb_(INT_MAX), lsb_(INT_MIN) { }
|
||||
range_t(int m, int l) : msb_(m), lsb_(l) { }
|
||||
range_t() : msb_(0), lsb_(0) { }
|
||||
range_t(Expression*m, Expression*l) : msb_(m), lsb_(l) { }
|
||||
|
||||
bool is_box() const { return msb_==INT_MAX && lsb_==INT_MIN; }
|
||||
bool is_box() const { return msb_==0 && lsb_==0; }
|
||||
|
||||
int msb() const { return msb_; }
|
||||
int lsb() const { return lsb_; }
|
||||
Expression* msb() const { return msb_; }
|
||||
Expression* lsb() const { return lsb_; }
|
||||
|
||||
private:
|
||||
int msb_;
|
||||
int lsb_;
|
||||
Expression* msb_;
|
||||
Expression* lsb_;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
|
||||
# include "vtype.h"
|
||||
# include <iostream>
|
||||
# include "expression.h"
|
||||
# include <iostream>
|
||||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
|
||||
|
|
@ -43,7 +44,11 @@ int VTypeArray::emit_def(ostream&out, perm_string name) const
|
|||
if (signed_flag_)
|
||||
out << "signed ";
|
||||
|
||||
out << "[" << dimension(0).msb() << ":" << dimension(0).lsb() << "] ";
|
||||
out << "[";
|
||||
errors += dimension(0).msb()->emit(out, 0, 0);
|
||||
out << ":";
|
||||
errors += dimension(0).lsb()->emit(out, 0, 0);
|
||||
out << "] ";
|
||||
|
||||
out << "\\" << name << " ";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue