Handle some different integral types is class properties.

This commit is contained in:
Stephen Williams 2013-01-06 15:42:23 -08:00
parent 59ce217ce2
commit 0375ff3923
9 changed files with 262 additions and 28 deletions

View File

@ -313,6 +313,7 @@ ivl_type_packed_msb
ivl_type_prop_name
ivl_type_prop_type
ivl_type_properties
ivl_type_signed
ivl_udp_init
ivl_udp_file

View 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
* 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
*
* 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 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_signed(ivl_type_t net);
extern const char* ivl_type_name(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);

View File

@ -23,10 +23,10 @@ using namespace std;
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::atom2s16 (IVL_VT_BOOL, 16, 0, true);
netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 16, 0, false);
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 8, 0, true);
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 8, 0, false);
netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true);
netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 15, 0, false);
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 7, 0, true);
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)
: type_(type), signed_(flag), isint_(false), is_scalar_(false)

View File

@ -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);
}
extern "C" int ivl_type_signed(ivl_type_t net)
{
return net->get_signed()? 1 : 0;
}

View File

@ -24,10 +24,48 @@
# include <assert.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)
{
// XXXX: For now, assume all properties are 32bit integers.
fprintf(vvp_out, "\"b32\"");
ivl_variable_type_t data_type = ivl_type_base(ptype);
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)

View File

@ -21,6 +21,7 @@
# include "compile.h"
# include "vpi_priv.h"
# include "config.h"
# include <map>
#ifdef CHECK_WITH_VALGRIND
# include "vvp_cleanup.h"
#endif
@ -28,15 +29,186 @@
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());
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
@ -58,7 +230,7 @@ void compile_class_start(char*lab, char*nam, unsigned ntype)
void compile_class_property(unsigned idx, char*nam, char*typ)
{
assert(compile_class);
compile_class->set_property(idx, nam);
compile_class->set_property(idx, nam, typ);
delete[]nam;
delete[]typ;
}
@ -67,6 +239,8 @@ void compile_class_done(void)
{
struct __vpiScope*scope = vpip_peek_current_scope();
assert(scope);
assert(compile_class);
compile_class->finish_setup();
scope->classes[compile_class->class_name()] = compile_class;
compile_class = 0;
}

View File

@ -23,6 +23,9 @@
# include <vector>
# include "vpi_priv.h"
class class_property_t;
class vvp_vector4_t;
/*
* This represents the TYPE information for a class. A %new operator
* uses this information to figure out how to construct an actual
@ -30,6 +33,10 @@
*/
class class_type : public __vpiHandle {
public:
struct inst_x;
typedef inst_x*inst_t;
public:
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
// parse of the .vvp file to fill in the details of the
// 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;
private:
@ -50,8 +70,10 @@ class class_type : public __vpiHandle {
struct prop_t {
std::string name;
class_property_t*type;
};
std::vector<prop_t> properties_;
size_t instance_size_;
};
#endif

View File

@ -25,33 +25,22 @@
using namespace std;
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()
{
delete[]properties_;
defn_->instance_delete(properties_);
properties_ = 0;
}
void vvp_cobject::set_vec4(size_t pid, const vvp_vector4_t&val)
{
assert(pid < defn_->property_count());
int32_t tmp;
bool flag = vector4_to_value(val, tmp, true, false);
assert(flag);
properties_[pid] = tmp;
defn_->set_vec4(properties_, pid, val);
}
void vvp_cobject::get_vec4(size_t pid, vvp_vector4_t&val)
{
assert(pid < defn_->property_count());
unsigned long tmp[1];
tmp[0] = properties_[pid];
val.resize(32);
val.setarray(0, 32, tmp);
defn_->get_vec4(properties_, pid, val);
}

View File

@ -21,8 +21,8 @@
# include <stdint.h>
# include "vvp_object.h"
# include "class_type.h"
class class_type;
class vvp_vector4_t;
class vvp_cobject : public vvp_object {
@ -37,7 +37,7 @@ class vvp_cobject : public vvp_object {
private:
const class_type* defn_;
// For now, only support 32bit bool signed properties.
int32_t*properties_;
class_type::inst_t properties_;
};
#endif