Handle some different integral types is class properties.
This commit is contained in:
parent
59ce217ce2
commit
0375ff3923
1
ivl.def
1
ivl.def
|
|
@ -313,6 +313,7 @@ ivl_type_packed_msb
|
||||||
ivl_type_prop_name
|
ivl_type_prop_name
|
||||||
ivl_type_prop_type
|
ivl_type_prop_type
|
||||||
ivl_type_properties
|
ivl_type_properties
|
||||||
|
ivl_type_signed
|
||||||
|
|
||||||
ivl_udp_init
|
ivl_udp_init
|
||||||
ivl_udp_file
|
ivl_udp_file
|
||||||
|
|
|
||||||
|
|
@ -2232,6 +2232,10 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net);
|
||||||
* Return the type of the element of an array. This is only valid
|
* Return the type of the element of an array. This is only valid
|
||||||
* for array types.
|
* for array types.
|
||||||
*
|
*
|
||||||
|
* ivl_type_signed
|
||||||
|
* Return TRUE if the type represents a signed packed vector or
|
||||||
|
* signed atomic type, and FALSE otherwise.
|
||||||
|
*
|
||||||
* SEMANTIC NOTES
|
* SEMANTIC NOTES
|
||||||
*
|
*
|
||||||
* Class types have names and properties.
|
* Class types have names and properties.
|
||||||
|
|
@ -2241,6 +2245,7 @@ extern ivl_type_t ivl_type_element(ivl_type_t net);
|
||||||
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
||||||
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
||||||
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
||||||
|
extern int ivl_type_signed(ivl_type_t net);
|
||||||
extern const char* ivl_type_name(ivl_type_t net);
|
extern const char* ivl_type_name(ivl_type_t net);
|
||||||
extern int ivl_type_properties(ivl_type_t net);
|
extern int ivl_type_properties(ivl_type_t net);
|
||||||
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ using namespace std;
|
||||||
|
|
||||||
netvector_t netvector_t::atom2s32 (IVL_VT_BOOL, 31, 0, true);
|
netvector_t netvector_t::atom2s32 (IVL_VT_BOOL, 31, 0, true);
|
||||||
netvector_t netvector_t::atom2u32 (IVL_VT_BOOL, 31, 0, false);
|
netvector_t netvector_t::atom2u32 (IVL_VT_BOOL, 31, 0, false);
|
||||||
netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 16, 0, true);
|
netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true);
|
||||||
netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 16, 0, false);
|
netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 15, 0, false);
|
||||||
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 8, 0, true);
|
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 7, 0, true);
|
||||||
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 8, 0, false);
|
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 7, 0, false);
|
||||||
|
|
||||||
netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb, bool flag)
|
netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb, bool flag)
|
||||||
: type_(type), signed_(flag), isint_(false), is_scalar_(false)
|
: type_(type), signed_(flag), isint_(false), is_scalar_(false)
|
||||||
|
|
|
||||||
|
|
@ -2896,3 +2896,8 @@ extern "C" ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx)
|
||||||
|
|
||||||
return class_type->get_prop_type(idx);
|
return class_type->get_prop_type(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int ivl_type_signed(ivl_type_t net)
|
||||||
|
{
|
||||||
|
return net->get_signed()? 1 : 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,48 @@
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
|
|
||||||
|
static void show_prop_type_vector(ivl_type_t ptype)
|
||||||
|
{
|
||||||
|
ivl_variable_type_t data_type = ivl_type_base(ptype);
|
||||||
|
unsigned packed_dimensions = ivl_type_packed_dimensions(ptype);
|
||||||
|
assert(packed_dimensions < 2);
|
||||||
|
|
||||||
|
char*signed_flag = ivl_type_signed(ptype)? "s" : "";
|
||||||
|
char code = data_type==IVL_VT_BOOL? 'b' : 'L';
|
||||||
|
|
||||||
|
if (packed_dimensions == 0) {
|
||||||
|
fprintf(vvp_out, "\"%s%c1\"", signed_flag, code);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
assert(packed_dimensions == 1);
|
||||||
|
assert(ivl_type_packed_lsb(ptype,0) == 0);
|
||||||
|
assert(ivl_type_packed_msb(ptype,0) >= 0);
|
||||||
|
|
||||||
|
fprintf(vvp_out, "\"%s%c%d\"", signed_flag, code,
|
||||||
|
ivl_type_packed_msb(ptype,0)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void show_prop_type(ivl_type_t ptype)
|
static void show_prop_type(ivl_type_t ptype)
|
||||||
{
|
{
|
||||||
// XXXX: For now, assume all properties are 32bit integers.
|
ivl_variable_type_t data_type = ivl_type_base(ptype);
|
||||||
fprintf(vvp_out, "\"b32\"");
|
|
||||||
|
switch (data_type) {
|
||||||
|
case IVL_VT_REAL:
|
||||||
|
fprintf(vvp_out, "\"r\"");
|
||||||
|
break;
|
||||||
|
case IVL_VT_STRING:
|
||||||
|
fprintf(vvp_out, "\"S\"");
|
||||||
|
break;
|
||||||
|
case IVL_VT_BOOL:
|
||||||
|
case IVL_VT_LOGIC:
|
||||||
|
show_prop_type_vector(ptype);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
fprintf(vvp_out, "\"<ERROR-no-type>\"");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_class_in_scope(ivl_type_t classtype)
|
void draw_class_in_scope(ivl_type_t classtype)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
# include "compile.h"
|
# include "compile.h"
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
# include <map>
|
||||||
#ifdef CHECK_WITH_VALGRIND
|
#ifdef CHECK_WITH_VALGRIND
|
||||||
# include "vvp_cleanup.h"
|
# include "vvp_cleanup.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -28,15 +29,186 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class_type::class_type(const string&nam, size_t nprop)
|
/*
|
||||||
: class_name_(nam), properties_(nprop)
|
* This class_property_t class is an abstract base class for
|
||||||
|
* representing a property of an instance. The definition keeps and
|
||||||
|
* array (of pointers) of these in order to define the the class.
|
||||||
|
*/
|
||||||
|
class class_property_t {
|
||||||
|
public:
|
||||||
|
explicit inline class_property_t() { }
|
||||||
|
virtual ~class_property_t() =0;
|
||||||
|
// How much space does an instance of this property require?
|
||||||
|
virtual size_t instance_size() const =0;
|
||||||
|
|
||||||
|
void set_offset(size_t off) { offset_ = off; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void construct(char*buf) const;
|
||||||
|
virtual void destruct(char*buf) const;
|
||||||
|
|
||||||
|
virtual void set_vec4(char*buf, const vvp_vector4_t&val);
|
||||||
|
virtual void get_vec4(char*buf, vvp_vector4_t&val);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t offset_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class_property_t::~class_property_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void class_type::set_property(size_t idx, const string&name)
|
void class_property_t::construct(char*) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_property_t::destruct(char*) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_property_t::set_vec4(char*, const vvp_vector4_t&)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_property_t::get_vec4(char*, vvp_vector4_t&)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
template <class T> class property_atom : public class_property_t {
|
||||||
|
public:
|
||||||
|
inline explicit property_atom(void) { }
|
||||||
|
~property_atom() { }
|
||||||
|
|
||||||
|
size_t instance_size() const { return sizeof(T); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void construct(char*buf) const
|
||||||
|
{ T*tmp = reinterpret_cast<T*> (buf+offset_);
|
||||||
|
*tmp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_vec4(char*buf, const vvp_vector4_t&val)
|
||||||
|
{
|
||||||
|
T*tmp = reinterpret_cast<T*> (buf+offset_);
|
||||||
|
bool flag = vector4_to_value(val, *tmp, true, false);
|
||||||
|
assert(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_vec4(char*buf, vvp_vector4_t&val)
|
||||||
|
{
|
||||||
|
T*src = reinterpret_cast<T*> (buf+offset_);
|
||||||
|
const size_t tmp_cnt = (sizeof(T) + sizeof(unsigned long)-1)/sizeof(unsigned long);
|
||||||
|
unsigned long tmp[tmp_cnt];
|
||||||
|
tmp[0] = src[0];
|
||||||
|
for (size_t idx = 1 ; idx < tmp_cnt ; idx += 1)
|
||||||
|
tmp[idx] = 0;
|
||||||
|
|
||||||
|
val.resize(8*sizeof(T));
|
||||||
|
val.setarray(0, val.size(), tmp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* **** */
|
||||||
|
|
||||||
|
class_type::class_type(const string&nam, size_t nprop)
|
||||||
|
: class_name_(nam), properties_(nprop)
|
||||||
|
{
|
||||||
|
instance_size_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_type::set_property(size_t idx, const string&name, const string&type)
|
||||||
{
|
{
|
||||||
assert(idx < properties_.size());
|
assert(idx < properties_.size());
|
||||||
properties_[idx].name = name;
|
properties_[idx].name = name;
|
||||||
|
|
||||||
|
if (type == "b8")
|
||||||
|
properties_[idx].type = new property_atom<uint8_t>;
|
||||||
|
else if (type == "b16")
|
||||||
|
properties_[idx].type = new property_atom<uint16_t>;
|
||||||
|
else if (type == "b32")
|
||||||
|
properties_[idx].type = new property_atom<uint32_t>;
|
||||||
|
else if (type == "b64")
|
||||||
|
properties_[idx].type = new property_atom<uint64_t>;
|
||||||
|
else if (type == "sb8")
|
||||||
|
properties_[idx].type = new property_atom<int8_t>;
|
||||||
|
else if (type == "sb16")
|
||||||
|
properties_[idx].type = new property_atom<int16_t>;
|
||||||
|
else if (type == "sb32")
|
||||||
|
properties_[idx].type = new property_atom<int32_t>;
|
||||||
|
else if (type == "sb64")
|
||||||
|
properties_[idx].type = new property_atom<int64_t>;
|
||||||
|
else
|
||||||
|
properties_[idx].type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_type::finish_setup(void)
|
||||||
|
{
|
||||||
|
map<size_t, vector<size_t> > size_map;
|
||||||
|
// Add up all the sizes to get a total instance size. This
|
||||||
|
// figures out how much memory a complete instance will need.
|
||||||
|
size_t accum = 0;
|
||||||
|
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1) {
|
||||||
|
size_t instance_size = properties_[idx].type->instance_size();
|
||||||
|
accum += instance_size;
|
||||||
|
size_map[instance_size].push_back(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance_size_ = accum;
|
||||||
|
|
||||||
|
// Now allocate the properties to offsets within an instance
|
||||||
|
// space. Allocate the properties largest objects first so
|
||||||
|
// that they are assured better alignment.
|
||||||
|
accum = 0;
|
||||||
|
for (map<size_t, vector<size_t> >::reverse_iterator cur = size_map.rbegin()
|
||||||
|
; cur != size_map.rend() ; ++ cur) {
|
||||||
|
for (size_t idx = 0 ; idx < cur->second.size() ; idx += 1) {
|
||||||
|
size_t pid = cur->second[idx];
|
||||||
|
class_property_t*ptype = properties_[pid].type;
|
||||||
|
assert(ptype->instance_size() == cur->first);
|
||||||
|
ptype->set_offset(accum);
|
||||||
|
accum += cur->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class_type::inst_t class_type::instance_new() const
|
||||||
|
{
|
||||||
|
char*buf = new char [instance_size_];
|
||||||
|
|
||||||
|
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1)
|
||||||
|
properties_[idx].type->construct(buf);
|
||||||
|
|
||||||
|
return reinterpret_cast<inst_t> (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_type::instance_delete(class_type::inst_t obj) const
|
||||||
|
{
|
||||||
|
char*buf = reinterpret_cast<char*> (obj);
|
||||||
|
|
||||||
|
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1)
|
||||||
|
properties_[idx].type->destruct(buf);
|
||||||
|
|
||||||
|
delete[]buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_type::set_vec4(class_type::inst_t obj, size_t pid,
|
||||||
|
const vvp_vector4_t&val) const
|
||||||
|
{
|
||||||
|
char*buf = reinterpret_cast<char*> (obj);
|
||||||
|
assert(pid < properties_.size());
|
||||||
|
properties_[pid].type->set_vec4(buf, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void class_type::get_vec4(class_type::inst_t obj, size_t pid,
|
||||||
|
vvp_vector4_t&val) const
|
||||||
|
{
|
||||||
|
char*buf = reinterpret_cast<char*> (obj);
|
||||||
|
assert(pid < properties_.size());
|
||||||
|
properties_[pid].type->get_vec4(buf, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int class_type::get_type_code(void) const
|
int class_type::get_type_code(void) const
|
||||||
|
|
@ -58,7 +230,7 @@ void compile_class_start(char*lab, char*nam, unsigned ntype)
|
||||||
void compile_class_property(unsigned idx, char*nam, char*typ)
|
void compile_class_property(unsigned idx, char*nam, char*typ)
|
||||||
{
|
{
|
||||||
assert(compile_class);
|
assert(compile_class);
|
||||||
compile_class->set_property(idx, nam);
|
compile_class->set_property(idx, nam, typ);
|
||||||
delete[]nam;
|
delete[]nam;
|
||||||
delete[]typ;
|
delete[]typ;
|
||||||
}
|
}
|
||||||
|
|
@ -67,6 +239,8 @@ void compile_class_done(void)
|
||||||
{
|
{
|
||||||
struct __vpiScope*scope = vpip_peek_current_scope();
|
struct __vpiScope*scope = vpip_peek_current_scope();
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
assert(compile_class);
|
||||||
|
compile_class->finish_setup();
|
||||||
scope->classes[compile_class->class_name()] = compile_class;
|
scope->classes[compile_class->class_name()] = compile_class;
|
||||||
compile_class = 0;
|
compile_class = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
# include <vector>
|
# include <vector>
|
||||||
# include "vpi_priv.h"
|
# include "vpi_priv.h"
|
||||||
|
|
||||||
|
class class_property_t;
|
||||||
|
class vvp_vector4_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This represents the TYPE information for a class. A %new operator
|
* This represents the TYPE information for a class. A %new operator
|
||||||
* uses this information to figure out how to construct an actual
|
* uses this information to figure out how to construct an actual
|
||||||
|
|
@ -30,6 +33,10 @@
|
||||||
*/
|
*/
|
||||||
class class_type : public __vpiHandle {
|
class class_type : public __vpiHandle {
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct inst_x;
|
||||||
|
typedef inst_x*inst_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit class_type(const std::string&nam, size_t nprop);
|
explicit class_type(const std::string&nam, size_t nprop);
|
||||||
|
|
||||||
|
|
@ -41,8 +48,21 @@ class class_type : public __vpiHandle {
|
||||||
// Set the details about the property. This is used during
|
// Set the details about the property. This is used during
|
||||||
// parse of the .vvp file to fill in the details of the
|
// parse of the .vvp file to fill in the details of the
|
||||||
// property for the class definition.
|
// property for the class definition.
|
||||||
void set_property(size_t idx, const std::string&name);
|
void set_property(size_t idx, const std::string&name, const std::string&type);
|
||||||
|
|
||||||
|
// This method is called after all the properties are
|
||||||
|
// defined. This calculates information about the defintion.
|
||||||
|
void finish_setup(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructures and destructors for making instances.
|
||||||
|
inst_t instance_new() const;
|
||||||
|
void instance_delete(inst_t) const;
|
||||||
|
|
||||||
|
void set_vec4(inst_t inst, size_t pid, const vvp_vector4_t&val) const;
|
||||||
|
void get_vec4(inst_t inst, size_t pid, vvp_vector4_t&val) const;
|
||||||
|
|
||||||
|
public: // VPI related methods
|
||||||
int get_type_code(void) const;
|
int get_type_code(void) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -50,8 +70,10 @@ class class_type : public __vpiHandle {
|
||||||
|
|
||||||
struct prop_t {
|
struct prop_t {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
class_property_t*type;
|
||||||
};
|
};
|
||||||
std::vector<prop_t> properties_;
|
std::vector<prop_t> properties_;
|
||||||
|
size_t instance_size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -25,33 +25,22 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
vvp_cobject::vvp_cobject(const class_type*defn)
|
vvp_cobject::vvp_cobject(const class_type*defn)
|
||||||
: defn_(defn), properties_(new int32_t[defn->property_count()])
|
: defn_(defn), properties_(defn->instance_new())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_cobject::~vvp_cobject()
|
vvp_cobject::~vvp_cobject()
|
||||||
{
|
{
|
||||||
delete[]properties_;
|
defn_->instance_delete(properties_);
|
||||||
properties_ = 0;
|
properties_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vvp_cobject::set_vec4(size_t pid, const vvp_vector4_t&val)
|
void vvp_cobject::set_vec4(size_t pid, const vvp_vector4_t&val)
|
||||||
{
|
{
|
||||||
assert(pid < defn_->property_count());
|
defn_->set_vec4(properties_, pid, val);
|
||||||
|
|
||||||
int32_t tmp;
|
|
||||||
bool flag = vector4_to_value(val, tmp, true, false);
|
|
||||||
assert(flag);
|
|
||||||
|
|
||||||
properties_[pid] = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vvp_cobject::get_vec4(size_t pid, vvp_vector4_t&val)
|
void vvp_cobject::get_vec4(size_t pid, vvp_vector4_t&val)
|
||||||
{
|
{
|
||||||
assert(pid < defn_->property_count());
|
defn_->get_vec4(properties_, pid, val);
|
||||||
|
|
||||||
unsigned long tmp[1];
|
|
||||||
tmp[0] = properties_[pid];
|
|
||||||
val.resize(32);
|
|
||||||
val.setarray(0, 32, tmp);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include "vvp_object.h"
|
# include "vvp_object.h"
|
||||||
|
# include "class_type.h"
|
||||||
|
|
||||||
class class_type;
|
|
||||||
class vvp_vector4_t;
|
class vvp_vector4_t;
|
||||||
|
|
||||||
class vvp_cobject : public vvp_object {
|
class vvp_cobject : public vvp_object {
|
||||||
|
|
@ -37,7 +37,7 @@ class vvp_cobject : public vvp_object {
|
||||||
private:
|
private:
|
||||||
const class_type* defn_;
|
const class_type* defn_;
|
||||||
// For now, only support 32bit bool signed properties.
|
// For now, only support 32bit bool signed properties.
|
||||||
int32_t*properties_;
|
class_type::inst_t properties_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue