Skip to content

Commit c49b211

Browse files
committed
Handle strings as class object properties.
While we are at it, fix a handling of null strings in string expressions.
1 parent 106850c commit c49b211

15 files changed

+205
-8
lines changed

elab_type.cc

+5
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,8 @@ ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const
8080
}
8181
return 0;
8282
}
83+
84+
ivl_type_s* string_type_t::elaborate_type(Design*, NetScope*) const
85+
{
86+
return &netstring_t::type_string;
87+
}

netscalar.cc

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ using namespace std;
2323

2424
netreal_t netreal_t::type_real;
2525
netreal_t netreal_t::type_shortreal;
26+
netstring_t netstring_t::type_string;
2627

2728
netreal_t::~netreal_t()
2829
{
@@ -32,3 +33,12 @@ ivl_variable_type_t netreal_t::base_type() const
3233
{
3334
return IVL_VT_REAL;
3435
}
36+
37+
netstring_t::~netstring_t()
38+
{
39+
}
40+
41+
ivl_variable_type_t netstring_t::base_type() const
42+
{
43+
return IVL_VT_STRING;
44+
}

netscalar.h

+12
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,16 @@ class netreal_t : public ivl_type_s {
3434
static netreal_t type_shortreal;
3535
};
3636

37+
class netstring_t : public ivl_type_s {
38+
39+
public:
40+
inline explicit netstring_t() { }
41+
~netstring_t();
42+
43+
ivl_variable_type_t base_type() const;
44+
45+
public:
46+
static netstring_t type_string;
47+
};
48+
3749
#endif

pform_types.h

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ struct real_type_t : public data_type_t {
181181
struct string_type_t : public data_type_t {
182182
inline explicit string_type_t() { }
183183
~string_type_t();
184+
185+
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
184186
};
185187

186188
struct class_type_t : public data_type_t {

tgt-stub/expression.c

+3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ static void show_property_expression(ivl_expr_t net, unsigned ind)
214214
if (ivl_expr_value(net) == IVL_VT_REAL) {
215215
fprintf(out, "%*s<property base=%s, prop=%s, real>\n", ind, "",
216216
ivl_signal_basename(sig), pnam);
217+
} else if (ivl_expr_value(net) == IVL_VT_STRING) {
218+
fprintf(out, "%*s<property base=%s, prop=%s, string>\n", ind, "",
219+
ivl_signal_basename(sig), pnam);
217220
} else {
218221
fprintf(out, "%*s<property base=%s, prop=%s, width=%u, %s>\n", ind, "",
219222
ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag);

tgt-vvp/eval_string.c

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012 Stephen Williams ([email protected])
2+
* Copyright (c) 2012-2013 Stephen Williams ([email protected])
33
*
44
* This source code is free software; you can redistribute it
55
* and/or modify it in source code form under the terms of the GNU
@@ -60,6 +60,15 @@ static void string_ex_concat(ivl_expr_t expr)
6060
}
6161
}
6262

63+
static void string_ex_property(ivl_expr_t expr)
64+
{
65+
ivl_signal_t sig = ivl_expr_signal(expr);
66+
unsigned pidx = ivl_expr_property_idx(expr);
67+
68+
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
69+
fprintf(vvp_out, " %%prop/str %u;\n", pidx);
70+
}
71+
6372
static void string_ex_signal(ivl_expr_t expr)
6473
{
6574
ivl_signal_t sig = ivl_expr_signal(expr);
@@ -100,6 +109,22 @@ static void string_ex_select(ivl_expr_t expr)
100109
fprintf(vvp_out, " %%load/dar/str v%p_0;\n", sig);
101110
}
102111

112+
static void string_ex_string(ivl_expr_t expr)
113+
{
114+
const char*val = ivl_expr_string(expr);
115+
116+
/* Special case: The elaborator converts the string "" to an
117+
8-bit zero, which is in turn escaped to the 4-character
118+
string \000. Detect this special case and convert it back
119+
to an empty string. [Perhaps elaboration should be fixed?] */
120+
if (ivl_expr_width(expr)==8 && (strcmp(val,"\\000") == 0)) {
121+
fprintf(vvp_out, " %%pushi/str \"\";\n");
122+
return;
123+
}
124+
125+
fprintf(vvp_out, " %%pushi/str \"%s\";\n", val);
126+
}
127+
103128
static void string_ex_substr(ivl_expr_t expr)
104129
{
105130
ivl_expr_t arg;
@@ -129,7 +154,7 @@ void draw_eval_string(ivl_expr_t expr)
129154

130155
switch (ivl_expr_type(expr)) {
131156
case IVL_EX_STRING:
132-
fprintf(vvp_out, " %%pushi/str \"%s\";\n", ivl_expr_string(expr));
157+
string_ex_string(expr);
133158
break;
134159

135160
case IVL_EX_SIGNAL:
@@ -140,6 +165,10 @@ void draw_eval_string(ivl_expr_t expr)
140165
string_ex_concat(expr);
141166
break;
142167

168+
case IVL_EX_PROPERTY:
169+
string_ex_property(expr);
170+
break;
171+
143172
case IVL_EX_SELECT:
144173
string_ex_select(expr);
145174
break;

tgt-vvp/stmt_assign.c

+10
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,16 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
869869
fprintf(vvp_out, " %%store/prop/r %d;\n", prop_idx);
870870
fprintf(vvp_out, " %%pop/obj 1;\n");
871871

872+
} else if (ivl_type_base(prop_type) == IVL_VT_STRING) {
873+
874+
/* Calculate the real value into the real value
875+
stack. The %store/prop/r will pop the stack
876+
value. */
877+
draw_eval_string(rval);
878+
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
879+
fprintf(vvp_out, " %%store/prop/str %d;\n", prop_idx);
880+
fprintf(vvp_out, " %%pop/obj 1;\n");
881+
872882
} else {
873883
assert(0);
874884
}

vvp/class_type.cc

+63
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class class_property_t {
5353
virtual void set_real(char*buf, double val);
5454
virtual double get_real(char*buf);
5555

56+
virtual void set_string(char*buf, const std::string&val);
57+
virtual string get_string(char*buf);
58+
5659
protected:
5760
size_t offset_;
5861
};
@@ -90,6 +93,17 @@ double class_property_t::get_real(char*)
9093
return 0.0;
9194
}
9295

96+
void class_property_t::set_string(char*, const string&)
97+
{
98+
assert(0);
99+
}
100+
101+
string class_property_t::get_string(char*)
102+
{
103+
assert(0);
104+
return "";
105+
}
106+
93107
/*
94108
*/
95109
template <class T> class property_atom : public class_property_t {
@@ -126,6 +140,26 @@ template <class T> class property_real : public class_property_t {
126140
double get_real(char*buf);
127141
};
128142

143+
class property_string : public class_property_t {
144+
public:
145+
inline explicit property_string(void) { }
146+
~property_string() { }
147+
148+
size_t instance_size() const { return sizeof(std::string); }
149+
150+
public:
151+
void construct(char*buf) const
152+
{ /* string*tmp = */ new (buf+offset_) string; }
153+
154+
void destruct(char*buf) const
155+
{ string*tmp = reinterpret_cast<string*> (buf+offset_);
156+
tmp->~string();
157+
}
158+
159+
void set_string(char*buf, const string&);
160+
string get_string(char*buf);
161+
};
162+
129163
template <class T> void property_atom<T>::set_vec4(char*buf, const vvp_vector4_t&val)
130164
{
131165
T*tmp = reinterpret_cast<T*> (buf+offset_);
@@ -158,6 +192,18 @@ template <class T> double property_real<T>::get_real(char*buf)
158192
return *tmp;
159193
}
160194

195+
void property_string::set_string(char*buf, const string&val)
196+
{
197+
string*tmp = reinterpret_cast<string*>(buf+offset_);
198+
*tmp = val;
199+
}
200+
201+
string property_string::get_string(char*buf)
202+
{
203+
string*tmp = reinterpret_cast<string*>(buf+offset_);
204+
return *tmp;
205+
}
206+
161207
/* **** */
162208

163209
class_type::class_type(const string&nam, size_t nprop)
@@ -189,6 +235,8 @@ void class_type::set_property(size_t idx, const string&name, const string&type)
189235
properties_[idx].type = new property_atom<int64_t>;
190236
else if (type == "r")
191237
properties_[idx].type = new property_real<double>;
238+
else if (type == "S")
239+
properties_[idx].type = new property_string;
192240
else
193241
properties_[idx].type = 0;
194242
}
@@ -275,6 +323,21 @@ double class_type::get_real(class_type::inst_t obj, size_t pid) const
275323
return properties_[pid].type->get_real(buf);
276324
}
277325

326+
void class_type::set_string(class_type::inst_t obj, size_t pid,
327+
const string&val) const
328+
{
329+
char*buf = reinterpret_cast<char*> (obj);
330+
assert(pid < properties_.size());
331+
properties_[pid].type->set_string(buf, val);
332+
}
333+
334+
string class_type::get_string(class_type::inst_t obj, size_t pid) const
335+
{
336+
char*buf = reinterpret_cast<char*> (obj);
337+
assert(pid < properties_.size());
338+
return properties_[pid].type->get_string(buf);
339+
}
340+
278341
int class_type::get_type_code(void) const
279342
{
280343
return vpiClassDefn;

vvp/class_type.h

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class class_type : public __vpiHandle {
6363
void get_vec4(inst_t inst, size_t pid, vvp_vector4_t&val) const;
6464
void set_real(inst_t inst, size_t pid, double val) const;
6565
double get_real(inst_t inst, size_t pid) const;
66+
void set_string(inst_t inst, size_t pid, const std::string&val) const;
67+
std::string get_string(inst_t inst, size_t pid) const;
6668

6769
public: // VPI related methods
6870
int get_type_code(void) const;

vvp/codes.h

+2
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ extern bool of_POW(vthread_t thr, vvp_code_t code);
166166
extern bool of_POW_S(vthread_t thr, vvp_code_t code);
167167
extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
168168
extern bool of_PROP_R(vthread_t thr, vvp_code_t code);
169+
extern bool of_PROP_STR(vthread_t thr, vvp_code_t code);
169170
extern bool of_PROP_V(vthread_t thr, vvp_code_t code);
170171
extern bool of_PUSHI_STR(vthread_t thr, vvp_code_t code);
171172
extern bool of_PUSHI_REAL(vthread_t thr, vvp_code_t code);
@@ -186,6 +187,7 @@ extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code);
186187
extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code);
187188
extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code);
188189
extern bool of_STORE_PROP_R(vthread_t thr, vvp_code_t code);
190+
extern bool of_STORE_PROP_STR(vthread_t thr, vvp_code_t code);
189191
extern bool of_STORE_PROP_V(vthread_t thr, vvp_code_t code);
190192
extern bool of_STORE_REAL(vthread_t thr, vvp_code_t code);
191193
extern bool of_STORE_REALA(vthread_t thr, vvp_code_t code);

vvp/compile.cc

+6-4
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ static const struct opcode_table_s opcode_table[] = {
213213
{ "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
214214
{ "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
215215
{ "%pow/wr", of_POW_WR, 0, {OA_NONE, OA_NONE, OA_NONE} },
216-
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
217-
{ "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
216+
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
217+
{ "%prop/str",of_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} },
218+
{ "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
218219
{ "%pushi/real",of_PUSHI_REAL,2,{OA_BIT1, OA_BIT2, OA_NONE} },
219220
{ "%pushi/str", of_PUSHI_STR, 1,{OA_STRING, OA_NONE, OA_NONE} },
220221
{ "%pushv/str", of_PUSHV_STR, 2, {OA_BIT1,OA_BIT2, OA_NONE} },
@@ -232,8 +233,9 @@ static const struct opcode_table_s opcode_table[] = {
232233
{ "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
233234
{ "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
234235
{ "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
235-
{ "%store/prop/r",of_STORE_PROP_R,1, {OA_NUMBER, OA_NONE, OA_NONE} },
236-
{ "%store/prop/v",of_STORE_PROP_V,3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
236+
{ "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
237+
{ "%store/prop/str",of_STORE_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} },
238+
{ "%store/prop/v", of_STORE_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
237239
{ "%store/real", of_STORE_REAL, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
238240
{ "%store/reala", of_STORE_REALA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
239241
{ "%store/str", of_STORE_STR, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },

vvp/opcodes.txt

+5-2
Original file line numberDiff line numberDiff line change
@@ -890,9 +890,11 @@ the result.
890890

891891
* %prop/v <pid>, <base>, <wid>
892892
* %prop/r <pid>
893+
* %prop/str <pid>
893894

894-
Write the vector (/v) or real value (/r) into property number <pid> of
895-
the class object on the top of the object stack. The real value is popped.
895+
Write the vector (/v) or real value (/r) or string (/str) into
896+
property number <pid> of the class object on the top of the object
897+
stack. The real value is popped.
896898

897899
The class object stack is NOT popped.
898900

@@ -1015,6 +1017,7 @@ variable given by the label.
10151017
See also %load/obj.
10161018

10171019
* %store/prop/r <index>
1020+
* %store/prop/str <index>
10181021
* %store/prop/v <index>, <bit>, <wid>
10191022

10201023
The %store/prop/r pops a real value from the real stack and stores it

vvp/vthread.cc

+40
Original file line numberDiff line numberDiff line change
@@ -4552,6 +4552,25 @@ bool of_PROP_R(vthread_t thr, vvp_code_t cp)
45524552
return true;
45534553
}
45544554

4555+
/*
4556+
* %prop/str <pid>
4557+
*
4558+
* Load a string value from the cobject and push it onto the real value
4559+
* stack.
4560+
*/
4561+
bool of_PROP_STR(vthread_t thr, vvp_code_t cp)
4562+
{
4563+
unsigned pid = cp->number;
4564+
4565+
vvp_object_t&obj = thr->peek_object();
4566+
vvp_cobject*cobj = obj.peek<vvp_cobject>();
4567+
4568+
string val = cobj->get_string(pid);
4569+
thr->push_str(val);
4570+
4571+
return true;
4572+
}
4573+
45554574
/*
45564575
* %prop/v <pid> <base> <wid>
45574576
*
@@ -5114,6 +5133,27 @@ bool of_STORE_PROP_R(vthread_t thr, vvp_code_t cp)
51145133
return true;
51155134
}
51165135

5136+
/*
5137+
* %store/prop/str <id>
5138+
*
5139+
* Pop a string value from the string stack, and store the value into
5140+
* the property of the object references by the top of the stack. Do NOT
5141+
* pop the object stack.
5142+
*/
5143+
bool of_STORE_PROP_STR(vthread_t thr, vvp_code_t cp)
5144+
{
5145+
size_t pid = cp->number;
5146+
string val = thr->pop_str();
5147+
5148+
vvp_object_t&obj = thr->peek_object();
5149+
vvp_cobject*cobj = obj.peek<vvp_cobject>();
5150+
assert(cobj);
5151+
5152+
cobj->set_string(pid, val);
5153+
5154+
return true;
5155+
}
5156+
51175157
/*
51185158
* %store/prop/v <id> <base> <wid>
51195159
*

vvp/vvp_cobject.cc

+10
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,13 @@ double vvp_cobject::get_real(size_t pid)
5454
{
5555
return defn_->get_real(properties_, pid);
5656
}
57+
58+
void vvp_cobject::set_string(size_t pid, const string&val)
59+
{
60+
defn_->set_string(properties_, pid, val);
61+
}
62+
63+
string vvp_cobject::get_string(size_t pid)
64+
{
65+
return defn_->get_string(properties_, pid);
66+
}

0 commit comments

Comments
 (0)