ivl_target access to type information.

This commit is contained in:
Stephen Williams 2012-09-23 09:28:49 -07:00
parent 494dc876a5
commit 4e76912331
27 changed files with 269 additions and 79 deletions

View File

@ -141,7 +141,7 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
return o; return o;
} }
ostream& nettype_base_t::debug_dump(ostream&o) const ostream& ivl_type_s::debug_dump(ostream&o) const
{ {
o << typeid(*this).name(); o << typeid(*this).name();
return o; return o;

View File

@ -2355,7 +2355,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
if (netdarray_t*darray = net? net->darray_type() : 0) { if (netdarray_t*darray = net? net->darray_type() : 0) {
if (use_sel == index_component_t::SEL_BIT) { if (use_sel == index_component_t::SEL_BIT) {
expr_type_ = darray->data_type(); expr_type_ = darray->element_base_type();
expr_width_ = darray->vector_width(); expr_width_ = darray->vector_width();
min_width_ = expr_width_; min_width_ = expr_width_;
signed_flag_ = net->get_signed(); signed_flag_ = net->get_signed();
@ -3970,7 +3970,7 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
return node; return node;
} }
unsigned PENew::test_width(Design*des, NetScope*, width_mode_t&) unsigned PENew::test_width(Design*, NetScope*, width_mode_t&)
{ {
expr_type_ = IVL_VT_DARRAY; expr_type_ = IVL_VT_DARRAY;
expr_width_ = 1; expr_width_ = 1;

View File

@ -914,8 +914,8 @@ static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
return res; return res;
} }
static nettype_base_t*elaborate_type(Design*des, NetScope*scope, static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
data_type_t*pform_type) data_type_t*pform_type)
{ {
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) { if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) {
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type); netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
@ -1256,7 +1256,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
<< " in scope " << scope_path(scope) << endl; << " in scope " << scope_path(scope) << endl;
} }
nettype_base_t*base_type = elaborate_type(des, scope, parray_type->base_type); ivl_type_s*base_type = elaborate_type(des, scope, parray_type->base_type);
#if 0 #if 0
cerr << get_fileline() << ": sorry: Packed array of " cerr << get_fileline() << ": sorry: Packed array of "
<< typeid(*parray_type->base_type).name() << typeid(*parray_type->base_type).name()

View File

@ -21,12 +21,19 @@
# include <inttypes.h> # include <inttypes.h>
/* Re the _CLASS define: clang++ wants this to be class to match the
* definition, but clang (the C) compiler needs it to be a struct
* since class is not defined in C. They are effecively both pointers
* to an object so everything works out. */
#ifdef __cplusplus #ifdef __cplusplus
#define _BEGIN_DECL extern "C" { #define _BEGIN_DECL extern "C" {
#define _END_DECL } #define _END_DECL }
#define _CLASS class
#else #else
#define _BEGIN_DECL #define _BEGIN_DECL
#define _END_DECL #define _END_DECL
#define _CLASS struct
#endif #endif
#ifndef __GNUC__ #ifndef __GNUC__
@ -157,21 +164,8 @@ typedef struct ivl_array_s *ivl_array_t;
typedef struct ivl_branch_s *ivl_branch_t; typedef struct ivl_branch_s *ivl_branch_t;
typedef struct ivl_delaypath_s*ivl_delaypath_t; typedef struct ivl_delaypath_s*ivl_delaypath_t;
typedef struct ivl_design_s *ivl_design_t; typedef struct ivl_design_s *ivl_design_t;
/* clang++ wants this to be class to match the definition, but clang typedef _CLASS ivl_discipline_s*ivl_discipline_t;
* (the C) compiler needs it to be a struct since class is not defined typedef _CLASS netenum_t *ivl_enumtype_t;
* in C. They are effecively both pointers to an object so everything
* works out. */
#ifdef __cplusplus
typedef class ivl_discipline_s*ivl_discipline_t;
#else
typedef struct ivl_discipline_s*ivl_discipline_t;
#endif
/* See the comments above. */
#ifdef __cplusplus
typedef class netenum_t *ivl_enumtype_t;
#else
typedef struct netenum_t *ivl_enumtype_t;
#endif
typedef struct ivl_event_s *ivl_event_t; typedef struct ivl_event_s *ivl_event_t;
typedef struct ivl_expr_s *ivl_expr_t; typedef struct ivl_expr_s *ivl_expr_t;
typedef struct ivl_island_s *ivl_island_t; typedef struct ivl_island_s *ivl_island_t;
@ -180,12 +174,7 @@ typedef struct ivl_lval_s *ivl_lval_t;
typedef struct ivl_net_const_s*ivl_net_const_t; typedef struct ivl_net_const_s*ivl_net_const_t;
typedef struct ivl_net_logic_s*ivl_net_logic_t; typedef struct ivl_net_logic_s*ivl_net_logic_t;
typedef struct ivl_udp_s *ivl_udp_t; typedef struct ivl_udp_s *ivl_udp_t;
/* See the comments above. */ typedef _CLASS ivl_nature_s *ivl_nature_t;
#ifdef __cplusplus
typedef class ivl_nature_s *ivl_nature_t;
#else
typedef struct ivl_nature_s *ivl_nature_t;
#endif
typedef struct ivl_net_probe_s*ivl_net_probe_t; typedef struct ivl_net_probe_s*ivl_net_probe_t;
typedef struct ivl_nexus_s *ivl_nexus_t; typedef struct ivl_nexus_s *ivl_nexus_t;
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t; typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
@ -193,10 +182,11 @@ typedef struct ivl_parameter_s*ivl_parameter_t;
typedef struct ivl_process_s *ivl_process_t; typedef struct ivl_process_s *ivl_process_t;
typedef struct ivl_scope_s *ivl_scope_t; typedef struct ivl_scope_s *ivl_scope_t;
typedef struct ivl_signal_s *ivl_signal_t; typedef struct ivl_signal_s *ivl_signal_t;
typedef struct ivl_port_info_s *ivl_port_info_t; typedef struct ivl_port_info_s*ivl_port_info_t;
typedef struct ivl_switch_s *ivl_switch_t; typedef struct ivl_switch_s *ivl_switch_t;
typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated)); typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated));
typedef struct ivl_statement_s*ivl_statement_t; typedef struct ivl_statement_s*ivl_statement_t;
typedef const _CLASS ivl_type_s*ivl_type_t;
/* /*
* These are types that are defined as enumerations. These have * These are types that are defined as enumerations. These have
@ -1907,6 +1897,7 @@ extern unsigned ivl_signal_npath(ivl_signal_t net);
extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx); extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx);
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net); extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net); extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net);
extern ivl_type_t ivl_signal_net_type(ivl_signal_t net);
extern const char* ivl_signal_name(ivl_signal_t net); extern const char* ivl_signal_name(ivl_signal_t net);
extern const char* ivl_signal_basename(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net);
extern const char* ivl_signal_attr(ivl_signal_t net, const char*key); extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
@ -1994,7 +1985,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
* Statements that have event arguments (TRIGGER and WAIT) make * Statements that have event arguments (TRIGGER and WAIT) make
* those event objects available through these methods. * those event objects available through these methods.
* *
* ivl_stmt_lval * ivl_stmt_lval
* ivl_stmt_lvals * ivl_stmt_lvals
* Return the number of l-values for an assignment statement, or * Return the number of l-values for an assignment statement, or
* the specific l-value. If there is more than 1 l-value, then the * the specific l-value. If there is more than 1 l-value, then the
@ -2195,6 +2186,21 @@ extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx);
extern const char* ivl_switch_file(ivl_switch_t net); extern const char* ivl_switch_file(ivl_switch_t net);
extern unsigned ivl_switch_lineno(ivl_switch_t net); extern unsigned ivl_switch_lineno(ivl_switch_t net);
/* TYPES
*
* ivl_type_base
* This returns the base type for the type. See the
* ivl_variable_type_t definition for the various base types.
*
* ivl_type_element
* Return the type of the element of an array.
*
* SEMANTIC NOTES
*/
extern ivl_variable_type_t ivl_type_base(ivl_type_t net);
extern ivl_type_t ivl_type_element(ivl_type_t net);
#if defined(__MINGW32__) || defined (__CYGWIN32__) #if defined(__MINGW32__) || defined (__CYGWIN32__)
# define DLLEXPORT __declspec(dllexport) # define DLLEXPORT __declspec(dllexport)
#else #else

View File

@ -101,7 +101,7 @@ ivl_variable_type_t NetAssign_::expr_type() const
if (word_ == 0) if (word_ == 0)
return IVL_VT_DARRAY; return IVL_VT_DARRAY;
else else
return darray->data_type(); return darray->element_base_type();
} }
return sig_->data_type(); return sig_->data_type();

View File

@ -30,3 +30,8 @@ netdarray_t::~netdarray_t()
{ {
delete elem_type_; delete elem_type_;
} }
ivl_variable_type_t netdarray_t::base_type(void) const
{
return IVL_VT_DARRAY;
}

View File

@ -26,13 +26,23 @@
class netvector_t; class netvector_t;
class netdarray_t : public nettype_base_t { class netdarray_t : public ivl_type_s {
public: public:
explicit netdarray_t(netvector_t*vec); explicit netdarray_t(netvector_t*vec);
~netdarray_t(); ~netdarray_t();
inline ivl_variable_type_t data_type() const { return elem_type_->base_type(); } // This is the "base_type()" virtual method of the
// nettype_base_t. The ivl_target api expects this to return
// IVL_VT_DARRAY for dynamic arrays?
ivl_variable_type_t base_type() const;
// The ivl_target.h API uses this method to get the type of
// the element of the array.
inline const ivl_type_s* element_type() const { return elem_type_; }
// This is the base_type() of the element of the array.
inline ivl_variable_type_t element_base_type() const { return elem_type_->base_type(); }
inline unsigned long vector_width(void) const { return elem_type_->packed_width(); } inline unsigned long vector_width(void) const { return elem_type_->packed_width(); }
std::ostream& debug_dump(std::ostream&) const; std::ostream& debug_dump(std::ostream&) const;

View File

@ -29,7 +29,7 @@
class NetScope; class NetScope;
class netenum_t : public LineInfo, public nettype_base_t { class netenum_t : public LineInfo, public ivl_type_s {
public: public:
explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag, explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag,

View File

@ -566,22 +566,22 @@ void NetNet::calculate_slice_widths_from_packed_dims_(void)
NetNet::NetNet(NetScope*s, perm_string n, Type t, NetNet::NetNet(NetScope*s, perm_string n, Type t,
const list<netrange_t>&packed, const list<netrange_t>&packed,
const list<netrange_t>&unpacked, const list<netrange_t>&unpacked,
nettype_base_t*net_type) ivl_type_s*use_net_type)
: NetObj(s, n, calculate_count(unpacked)), : NetObj(s, n, calculate_count(unpacked)),
type_(t), port_type_(NOT_A_PORT), type_(t), port_type_(NOT_A_PORT),
local_flag_(false), net_type_(net_type), local_flag_(false), net_type_(use_net_type),
discipline_(0), unpacked_dims_(unpacked.size()), discipline_(0), unpacked_dims_(unpacked.size()),
eref_count_(0), lref_count_(0) eref_count_(0), lref_count_(0)
{ {
packed_dims_ = packed; packed_dims_ = packed;
// Special case: This is an enum, so it is its own packed vector. // Special case: This is an enum, so it is its own packed vector.
if (netenum_t*et = dynamic_cast<netenum_t*>(net_type)) { if (netenum_t*et = dynamic_cast<netenum_t*>(use_net_type)) {
ivl_assert(*this, packed_dims_.empty()); ivl_assert(*this, packed_dims_.empty());
packed_dims_.push_back(netrange_t(calculate_count(et)-1, 0)); packed_dims_.push_back(netrange_t(calculate_count(et)-1, 0));
} }
// Special case: netstruct types are like another packed // Special case: netstruct types are like another packed
// dimension. // dimension.
if (netstruct_t*st = dynamic_cast<netstruct_t*>(net_type)) { if (netstruct_t*st = dynamic_cast<netstruct_t*>(use_net_type)) {
packed_dims_.push_back(netrange_t(calculate_count(st)-1, 0)); packed_dims_.push_back(netrange_t(calculate_count(st)-1, 0));
} }

View File

@ -609,7 +609,7 @@ class NetNet : public NetObj, public PortType {
explicit NetNet(NetScope*s, perm_string n, Type t, explicit NetNet(NetScope*s, perm_string n, Type t,
const std::list<netrange_t>&packed, const std::list<netrange_t>&packed,
const std::list<netrange_t>&unpacked, const std::list<netrange_t>&unpacked,
nettype_base_t*type =0); ivl_type_s*type =0);
// This form builds a NetNet from its record/enum definition. // This form builds a NetNet from its record/enum definition.
explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type); explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type);
@ -641,6 +641,7 @@ class NetNet : public NetObj, public PortType {
bool get_scalar() const; bool get_scalar() const;
inline const ivl_type_s* net_type(void) const { return net_type_; }
netenum_t*enumeration(void) const; netenum_t*enumeration(void) const;
netstruct_t*struct_type(void) const; netstruct_t*struct_type(void) const;
netdarray_t*darray_type(void) const; netdarray_t*darray_type(void) const;
@ -729,7 +730,7 @@ class NetNet : public NetObj, public PortType {
Type type_ : 5; Type type_ : 5;
PortType port_type_ : 3; PortType port_type_ : 3;
bool local_flag_: 1; bool local_flag_: 1;
nettype_base_t*net_type_; ivl_type_s*net_type_;
ivl_discipline_t discipline_; ivl_discipline_t discipline_;
std::list<netrange_t> packed_dims_; std::list<netrange_t> packed_dims_;

View File

@ -27,7 +27,7 @@
/* /*
* Packed arrays. * Packed arrays.
*/ */
class netparray_t : public nettype_base_t, public LineInfo { class netparray_t : public ivl_type_s, public LineInfo {
public: public:
explicit netparray_t(const std::list<netrange_t>&packed); explicit netparray_t(const std::list<netrange_t>&packed);

View File

@ -24,7 +24,7 @@
# include "ivl_target.h" # include "ivl_target.h"
# include "nettypes.h" # include "nettypes.h"
class netstruct_t : public LineInfo, public nettype_base_t { class netstruct_t : public LineInfo, public ivl_type_s {
public: public:
struct member_t { struct member_t {

View File

@ -22,21 +22,21 @@
using namespace std; using namespace std;
nettype_base_t::~nettype_base_t() ivl_type_s::~ivl_type_s()
{ {
} }
long nettype_base_t::packed_width(void) const long ivl_type_s::packed_width(void) const
{ {
return 0; return 1;
} }
ivl_variable_type_t nettype_base_t::base_type() const ivl_variable_type_t ivl_type_s::base_type() const
{ {
return IVL_VT_NO_TYPE; return IVL_VT_NO_TYPE;
} }
bool nettype_base_t::get_signed() const bool ivl_type_s::get_signed() const
{ {
return false; return false;
} }

View File

@ -29,9 +29,9 @@
* This is a fully abstract type that is a type that can be attached * This is a fully abstract type that is a type that can be attached
* to a NetNet object. * to a NetNet object.
*/ */
class nettype_base_t { class ivl_type_s {
public: public:
virtual ~nettype_base_t() =0; virtual ~ivl_type_s() =0;
virtual long packed_width(void) const; virtual long packed_width(void) const;
// Some types have a base variable type. // Some types have a base variable type.
@ -41,7 +41,7 @@ class nettype_base_t {
virtual std::ostream& debug_dump(std::ostream&) const; virtual std::ostream& debug_dump(std::ostream&) const;
}; };
inline static std::ostream& operator << (std::ostream&out, const nettype_base_t&obj) inline static std::ostream& operator << (std::ostream&out, const ivl_type_s&obj)
{ {
return obj.debug_dump(out); return obj.debug_dump(out);
} }

View File

@ -41,5 +41,5 @@ ivl_variable_type_t netvector_t::base_type() const
long netvector_t::packed_width() const long netvector_t::packed_width() const
{ {
netrange_width(packed_dims_); return netrange_width(packed_dims_);
} }

View File

@ -23,7 +23,7 @@
# include "ivl_target.h" # include "ivl_target.h"
# include <vector> # include <vector>
class netvector_t : public nettype_base_t { class netvector_t : public ivl_type_s {
public: public:
explicit netvector_t(const std::list<netrange_t>&packed, explicit netvector_t(const std::list<netrange_t>&packed,

View File

@ -153,6 +153,28 @@ void parray_type_t::pform_dump(ostream&out, unsigned indent) const
base_type->pform_dump(out, indent+4); base_type->pform_dump(out, indent+4);
} }
void struct_type_t::pform_dump(ostream&out, unsigned indent) const
{
out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked")
<< " with " << members->size() << " members" << endl;
for (list<struct_member_t*>::iterator cur = members->begin()
; cur != members->end() ; ++ cur) {
struct_member_t*curp = *cur;
curp->pform_dump(out, indent+4);
}
}
void struct_member_t::pform_dump(ostream&out, unsigned indent) const
{
out << setw(indent) << "" << type;
for (list<decl_assignment_t*>::iterator cur = names->begin()
; cur != names->end() ; ++cur) {
decl_assignment_t*curp = *cur;
out << " " << curp->name;
}
out << ";" << endl;
}
static void dump_attributes_map(ostream&out, static void dump_attributes_map(ostream&out,
const map<perm_string,PExpr*>&attributes, const map<perm_string,PExpr*>&attributes,
int ind) int ind)

View File

@ -97,10 +97,13 @@ struct struct_member_t : public LineInfo {
ivl_variable_type_t type; ivl_variable_type_t type;
std::auto_ptr< list<pform_range_t> > range; std::auto_ptr< list<pform_range_t> > range;
std::auto_ptr< list<decl_assignment_t*> > names; std::auto_ptr< list<decl_assignment_t*> > names;
void pform_dump(std::ostream&out, unsigned indent) const;
}; };
struct struct_type_t : public data_type_t { struct struct_type_t : public data_type_t {
virtual ivl_variable_type_t figure_packed_base_type(void)const; virtual ivl_variable_type_t figure_packed_base_type(void)const;
virtual void pform_dump(std::ostream&out, unsigned indent) const;
bool packed_flag; bool packed_flag;
std::auto_ptr< list<struct_member_t*> > members; std::auto_ptr< list<struct_member_t*> > members;
}; };

View File

@ -21,7 +21,9 @@
# include "StringHeap.h" # include "StringHeap.h"
# include "t-dll.h" # include "t-dll.h"
# include "discipline.h" # include "discipline.h"
# include "netdarray.h"
# include "netenum.h" # include "netenum.h"
# include "netvector.h"
# include <cstdlib> # include <cstdlib>
# include <cstdio> # include <cstdio>
# include <cstring> # include <cstring>
@ -1422,7 +1424,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
case IVL_LPM_REPEAT: case IVL_LPM_REPEAT:
return 0; return 0;
case IVL_LPM_ARRAY: // Array ports take the signedness of the array. case IVL_LPM_ARRAY: // Array ports take the signedness of the array.
return net->u_.array.sig->signed_; return net->u_.array.sig->net_type->get_signed()? 1 : 0;
default: default:
assert(0); assert(0);
return 0; return 0;
@ -2231,7 +2233,7 @@ extern "C" ivl_scope_t ivl_signal_scope(ivl_signal_t net)
extern "C" unsigned ivl_signal_width(ivl_signal_t net) extern "C" unsigned ivl_signal_width(ivl_signal_t net)
{ {
return net->width_; return net->net_type->packed_width();
} }
extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net) extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net)
@ -2251,7 +2253,7 @@ extern "C" int ivl_signal_local(ivl_signal_t net)
extern "C" int ivl_signal_signed(ivl_signal_t net) extern "C" int ivl_signal_signed(ivl_signal_t net)
{ {
return net->signed_; return net->net_type->get_signed()? 1 : 0;
} }
extern "C" unsigned ivl_signal_forced_net(ivl_signal_t net) extern "C" unsigned ivl_signal_forced_net(ivl_signal_t net)
@ -2273,12 +2275,20 @@ extern "C" unsigned ivl_signal_lineno(ivl_signal_t net)
extern "C" int ivl_signal_integer(ivl_signal_t net) extern "C" int ivl_signal_integer(ivl_signal_t net)
{ {
return net->isint_; if (const netvector_t*vec = dynamic_cast<const netvector_t*> (net->net_type))
return vec->get_isint()? 1 : 0;
else
return 0;
} }
extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net) extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net)
{ {
return net->data_type; return net->net_type->base_type();
}
extern "C" ivl_type_t ivl_signal_net_type(ivl_signal_t net)
{
return net->net_type;
} }
extern "C" unsigned ivl_signal_npath(ivl_signal_t net) extern "C" unsigned ivl_signal_npath(ivl_signal_t net)
@ -2773,3 +2783,18 @@ extern "C" unsigned ivl_switch_lineno(ivl_switch_t net)
{ {
return net->lineno; return net->lineno;
} }
extern "C" ivl_variable_type_t ivl_type_base(ivl_type_t net)
{
if (net == 0) return IVL_VT_NO_TYPE;
else return net->base_type();
}
extern "C" ivl_type_t ivl_type_element(ivl_type_t net)
{
if (const netdarray_t*da = dynamic_cast<const netdarray_t*> (net))
return da->element_type();
assert(0);
return 0;
}

View File

@ -2382,9 +2382,7 @@ void dll_target::signal(const NetNet*net)
} }
} }
obj->width_ = net->vector_width(); obj->net_type = net->net_type();
obj->signed_= net->get_signed()? 1 : 0;
obj->isint_ = false;
obj->local_ = net->local_flag()? 1 : 0; obj->local_ = net->local_flag()? 1 : 0;
obj->forced_net_ = (net->type() != NetNet::REG) && obj->forced_net_ = (net->type() != NetNet::REG) &&
(net->peek_lref() > 0) ? 1 : 0; (net->peek_lref() > 0) ? 1 : 0;
@ -2418,7 +2416,6 @@ void dll_target::signal(const NetNet*net)
case NetNet::REG: case NetNet::REG:
obj->type_ = IVL_SIT_REG; obj->type_ = IVL_SIT_REG;
obj->isint_ = net->get_isint();
break; break;
/* The SUPPLY0/1 net types are replaced with pulldown/up /* The SUPPLY0/1 net types are replaced with pulldown/up
@ -2469,15 +2466,9 @@ void dll_target::signal(const NetNet*net)
obj->npath = 0; obj->npath = 0;
obj->path = 0; obj->path = 0;
obj->data_type = net->data_type();
obj->nattr = net->attr_cnt(); obj->nattr = net->attr_cnt();
obj->attr = fill_in_attributes(net); obj->attr = fill_in_attributes(net);
/* If this is a dynamic array, then set the type to DARRAY. */
if (net->darray_type()) {
obj->data_type = IVL_VT_DARRAY;
}
/* Get the nexus objects for all the pins of the signal. If /* Get the nexus objects for all the pins of the signal. If
the signal has only one pin, then write the single the signal has only one pin, then write the single
ivl_nexus_t object into n.pin_. Otherwise, make an array of ivl_nexus_t object into n.pin_. Otherwise, make an array of

View File

@ -677,14 +677,12 @@ struct ivl_signal_s {
ivl_signal_type_t type_; ivl_signal_type_t type_;
ivl_signal_port_t port_; ivl_signal_port_t port_;
int module_port_index_; int module_port_index_;
ivl_variable_type_t data_type;
ivl_discipline_t discipline; ivl_discipline_t discipline;
perm_string file; perm_string file;
unsigned lineno; unsigned lineno;
unsigned width_; // This is the type for the signal
unsigned signed_ : 1; ivl_type_t net_type;
unsigned isint_ : 1;
unsigned local_ : 1; unsigned local_ : 1;
unsigned forced_net_ : 1; unsigned forced_net_ : 1;

View File

@ -44,7 +44,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
O = stub.o enumerate.o expression.o statement.o switches.o O = stub.o enumerate.o expression.o statement.o switches.o types.o
all: dep stub.tgt all: dep stub.tgt

View File

@ -169,6 +169,7 @@ static void show_select_expression(ivl_expr_t net, unsigned ind)
{ {
unsigned width = ivl_expr_width(net); unsigned width = ivl_expr_width(net);
const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*sign = ivl_expr_signed(net)? "signed" : "unsigned";
const char*vt = vt_type_string(net);
ivl_expr_t oper1 = ivl_expr_oper1(net); ivl_expr_t oper1 = ivl_expr_oper1(net);
ivl_expr_t oper2 = ivl_expr_oper2(net); ivl_expr_t oper2 = ivl_expr_oper2(net);
@ -186,8 +187,8 @@ static void show_select_expression(ivl_expr_t net, unsigned ind)
/* If oper2 is present, then it is the base of a part /* If oper2 is present, then it is the base of a part
select. The width of the expression defines the range select. The width of the expression defines the range
of the part select. */ of the part select. */
fprintf(out, "%*s<select: width=%u, %s>\n", ind, "", fprintf(out, "%*s<select: width=%u, %s, type=%s>\n", ind, "",
width, sign); width, sign, vt);
show_expression(oper1, ind+3); show_expression(oper1, ind+3);
show_expression(oper2, ind+3); show_expression(oper2, ind+3);
@ -233,6 +234,14 @@ static void show_signal_expression(ivl_expr_t net, unsigned ind)
fprintf(out, "%*sERROR: Missing word expression\n", ind+2, ""); fprintf(out, "%*sERROR: Missing word expression\n", ind+2, "");
stub_errors += 1; stub_errors += 1;
} }
/* If this is not an array, then the expression with must
match the signal width. We have IVL_EX_SELECT expressions
for casting signal widths. */
if (dimensions == 0 && ivl_signal_width(sig) != width) {
fprintf(out, "%*sERROR: Expression width (%u) doesn't match ivl_signal_width(sig)=%u\n",
ind+2, "", width, ivl_signal_width(sig));
stub_errors += 1;
}
if (word != 0) { if (word != 0) {
fprintf(out, "%*sAddress-0 word address:\n", ind+2, ""); fprintf(out, "%*sAddress-0 word address:\n", ind+2, "");

View File

@ -61,6 +61,11 @@ extern void show_expression(ivl_expr_t net, unsigned ind);
*/ */
extern void show_statement(ivl_statement_t net, unsigned ind); extern void show_statement(ivl_statement_t net, unsigned ind);
/*
* Show the type of the signal, in one line.
*/
extern void show_type_of_signal(ivl_signal_t);
extern void show_switch(ivl_switch_t net); extern void show_switch(ivl_switch_t net);
/* /*

View File

@ -1298,13 +1298,9 @@ static void show_signal(ivl_signal_t net)
for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) { for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) {
ivl_nexus_t nex = ivl_signal_nex(net, idx); ivl_nexus_t nex = ivl_signal_nex(net, idx);
unsigned dim;
fprintf(out, " %s %s %s%s", type, sign, port, data_type); fprintf(out, " %s %s %s", type, sign, port);
for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) { show_type_of_signal(net);
fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim),
ivl_signal_packed_lsb(net,dim));
}
fprintf(out, " %s[word=%u, adr=%d] <width=%u%s> <discipline=%s> ", fprintf(out, " %s[word=%u, adr=%d] <width=%u%s> <discipline=%s> ",
ivl_signal_basename(net), ivl_signal_basename(net),
idx, ivl_signal_array_base(net)+idx, idx, ivl_signal_array_base(net)+idx,

116
tgt-stub/types.c Normal file
View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "config.h"
# include "priv.h"
# include <string.h>
static void show_net_type(ivl_type_t net_type);
static void show_net_type_darray(ivl_type_t net_type)
{
/* Dynamic arrays have a single element type. */
ivl_type_t element_type = ivl_type_element(net_type);
fprintf(out, "darray of ");
show_net_type(element_type);
}
static void show_net_type(ivl_type_t net_type)
{
ivl_variable_type_t data_type = ivl_type_base(net_type);
switch (data_type) {
case IVL_VT_NO_TYPE:
fprintf(out, "<ERROR-no-type>");
stub_errors += 1;
break;
case IVL_VT_BOOL:
fprintf(out, "bool");
break;
case IVL_VT_LOGIC:
fprintf(out, "logic");
break;
case IVL_VT_REAL:
fprintf(out, "real");
break;
case IVL_VT_STRING:
fprintf(out, "string");
break;
case IVL_VT_DARRAY:
show_net_type_darray(net_type);
break;
case IVL_VT_VOID:
fprintf(out, "void");
break;
}
}
void show_type_of_signal(ivl_signal_t net)
{
unsigned dim;
/* The data_type is the base type of the signal. This the the
starting point for the type. In the long run I think I want
to remove this in favor of the ivl_signal_net_type below. */
ivl_variable_type_t data_type = ivl_signal_data_type(net);
/* This gets the more general type description. This is a
newer form so doesn't yet handle all the cases. Newer
types, such DARRAY types, REQUIRE this method to get at the
type details. */
ivl_type_t net_type = ivl_signal_net_type(net);
if (net_type) {
show_net_type(net_type);
return;
}
switch (data_type) {
case IVL_VT_NO_TYPE:
fprintf(out, "<no-type>");
break;
case IVL_VT_BOOL:
fprintf(out, "bool");
break;
case IVL_VT_LOGIC:
fprintf(out, "logic");
break;
case IVL_VT_REAL:
fprintf(out, "real");
break;
case IVL_VT_STRING:
fprintf(out, "string");
break;
case IVL_VT_DARRAY:
/* The DARRAY type MUST be described by an
ivl_signal_net_type object. */
fprintf(out, "ERROR-DARRAY");
stub_errors += 1;
break;
case IVL_VT_VOID:
fprintf(out, "void");
break;
}
for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) {
fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim),
ivl_signal_packed_lsb(net,dim));
}
}

View File

@ -411,6 +411,9 @@ static void draw_vpi_taskfunc_args(const char*call_string,
buffer[0] = 0; buffer[0] = 0;
break; break;
default: default:
fprintf(vvp_out, "\nXXXX Unexpected argument: call_string=<%s>, arg=%d, type=%d\n",
call_string, idx, ivl_expr_value(expr));
fflush(vvp_out);
assert(0); assert(0);
} }
args[idx].text = strdup(buffer); args[idx].text = strdup(buffer);