ivl: Added PECastType to handle type casting.

This commit is contained in:
Maciej Suminski 2014-10-31 09:55:36 +01:00
parent ac2e8dd6cd
commit 13f861a963
4 changed files with 94 additions and 0 deletions

View File

@ -146,6 +146,15 @@ PECastSize::~PECastSize()
{
}
PECastType::PECastType(data_type_t*t, PExpr*b)
: target_(t), base_(b)
{
}
PECastType::~PECastType()
{
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{

22
PExpr.h
View File

@ -986,6 +986,28 @@ class PECastSize : public PExpr {
PExpr* base_;
};
/*
* Support the SystemVerilog cast to a different type.
*/
class PECastType : public PExpr {
public:
explicit PECastType(data_type_t*target, PExpr*base);
~PECastType();
void dump(ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
private:
data_type_t* target_;
PExpr* base_;
};
/*
* This class is used for error recovery. All methods do nothing and return
* null or default values.

View File

@ -36,6 +36,7 @@
# include "netmisc.h"
# include "netdarray.h"
# include "netstruct.h"
# include "netscalar.h"
# include "util.h"
# include "ivl_assert.h"
@ -2431,6 +2432,60 @@ NetExpr* PECastSize::elaborate_expr(Design*des, NetScope*scope,
return sel;
}
unsigned PECastType::test_width(Design*des, NetScope*scope, width_mode_t&wid)
{
ivl_type_t t = target_->elaborate_type(des, scope);
base_->test_width(des, scope, wid);
if(const netdarray_t*use_darray = dynamic_cast<const netdarray_t*> (t)) {
expr_type_ = use_darray->element_base_type();
expr_width_ = use_darray->element_width();
signed_flag_= false;
}
else if(const netstring_t*use_string = dynamic_cast<const netstring_t*> (t)) {
expr_type_ = use_string->base_type();
expr_width_ = 1;
signed_flag_= false;
}
else if(const netstruct_t*use_struct = dynamic_cast<const netstruct_t*> (t)) {
ivl_assert(*this, use_struct->packed());
expr_type_ = use_struct->base_type();
expr_width_ = use_struct->packed_width();
signed_flag_= false;
}
else if(const netvector_t*use_vector = dynamic_cast<const netvector_t*> (t)) {
ivl_assert(*this, use_vector->packed());
expr_type_ = use_vector->base_type();
expr_width_ = use_vector->packed_width();
signed_flag_= false;
}
else {
expr_width_ = t->packed_width();
}
min_width_ = expr_width_;
return expr_width_;
}
NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope,
unsigned, unsigned) const
{
if(dynamic_cast<const real_type_t*>(target_))
{
NetExpr*expr = base_->elaborate_expr(des, scope, base_->expr_width(), NO_FLAGS);
return cast_to_real(expr);
}
cerr << get_fileline() << "sorry: I don't know how to cast expression." << endl;
ivl_assert(*this, false);
return expr;
}
unsigned PEConcat::test_width(Design*des, NetScope*scope, width_mode_t&)
{
expr_width_ = 0;

View File

@ -323,6 +323,14 @@ void PECastSize::dump(ostream &out) const
out << ")";
}
void PECastType::dump(ostream &out) const
{
target_->pform_dump(out, 0);
out << "'(";
base_->dump(out);
out << ")";
}
void PEEvent::dump(ostream&out) const
{
switch (type_) {