Process Verilog escape sequences much earlier.

This commit is contained in:
steve 2007-02-25 23:08:24 +00:00
parent 1f54f128c1
commit d2ba78559a
4 changed files with 140 additions and 24 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.176 2007/02/02 04:33:00 steve Exp $"
#ident "$Id: ivl_target.h,v 1.177 2007/02/25 23:08:24 steve Exp $"
#endif
# include <inttypes.h>
@ -612,6 +612,18 @@ extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx);
*
* Bit and part selects are not done here. The IVL_EX_SELECT
* expression does bit/part selects on the word read from the signal.
*
* - IVL_EX_STRING
* This expression refers to a string constant. The ivl_expr_string
* function returns a pointer to the first byte of the string. The
* compiler has translated it to a "vvp escaped string" which has
* quoting and escapes eliminated. The string may contain octal
* escapes (\<oct>) so that the string text returned by
* ivl_expr_string will only contain graphical characters. It is up to
* the target to change the escaped \NNN to the proper byte value when
* using this string. No other escape sequences will appear in the
* string. Quote (") and slash (\) characters will be delivered in
* \NNN form.
*/
extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
@ -1756,6 +1768,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.177 2007/02/25 23:08:24 steve
* Process Verilog escape sequences much earlier.
*
* Revision 1.176 2007/02/02 04:33:00 steve
* Use inttypes.h instead of stdint.h for portability.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: verinum.cc,v 1.51 2007/01/27 05:36:11 steve Exp $"
#ident "$Id: verinum.cc,v 1.52 2007/02/25 23:08:24 steve Exp $"
#endif
# include "config.h"
@ -41,9 +41,63 @@ verinum::verinum(const V*bits, unsigned nbits, bool has_len)
}
}
verinum::verinum(const string&str)
static string process_verilog_string_quotes(const string&str)
{
string res;
int idx = 0;
int str_len = str.length();
while (idx < str_len) {
if (str[idx] == '\\') {
idx += 1;
assert(idx < str_len);
switch (str[idx]) {
case 'n':
res = res + '\n';
idx += 1;
break;
case 't':
res = res + '\t';
idx += 1;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
char byte_val = 0;
int odx = 0;
while (odx < 3 && idx+odx < str_len
&& str[idx+odx] >= '0'
&& str[idx+odx] <= '7') {
byte_val = 8*byte_val + str[idx+odx]-'0';
odx += 1;
}
idx += odx;
res = res + byte_val;
break;
}
default:
res = res + str[idx];
idx += 1;
break;
}
} else {
res = res + str[idx];
idx += 1;
}
}
return res;
}
verinum::verinum(const string&s)
: has_len_(true), has_sign_(false), string_flag_(true)
{
string str = process_verilog_string_quotes(s);
nbits_ = str.length() * 8;
// Special case: The string "" is 8 bits of 0.
@ -284,29 +338,37 @@ string verinum::as_string() const
if (nbits_ == 0)
return "";
char*tmp = new char[nbits_/8+1];
char*cp = tmp;
string res;
bool leading_nuls = true;
for (unsigned idx = nbits_ ; idx > 0 ; idx -= 8) {
char char_val = 0;
V*bp = bits_+idx;
*cp = 0;
if (*(--bp) == V1) *cp |= 0x80;
if (*(--bp) == V1) *cp |= 0x40;
if (*(--bp) == V1) *cp |= 0x20;
if (*(--bp) == V1) *cp |= 0x10;
if (*(--bp) == V1) *cp |= 0x08;
if (*(--bp) == V1) *cp |= 0x04;
if (*(--bp) == V1) *cp |= 0x02;
if (*(--bp) == V1) *cp |= 0x01;
if (*cp != 0) {
cp += 1;
*cp = 0;
if (*(--bp) == V1) char_val |= 0x80;
if (*(--bp) == V1) char_val |= 0x40;
if (*(--bp) == V1) char_val |= 0x20;
if (*(--bp) == V1) char_val |= 0x10;
if (*(--bp) == V1) char_val |= 0x08;
if (*(--bp) == V1) char_val |= 0x04;
if (*(--bp) == V1) char_val |= 0x02;
if (*(--bp) == V1) char_val |= 0x01;
if (char_val == 0 && leading_nuls)
continue;
if (char_val == '"' || char_val == '\\') {
char tmp[5];
snprintf(tmp, sizeof tmp, "\\\%03o", char_val);
res = res + tmp;
} else if (char_val == ' ' || isgraph(char_val)) {
res = res + char_val;
} else {
char tmp[5];
snprintf(tmp, sizeof tmp, "\\\%03o", char_val);
res = res + tmp;
}
}
tmp[nbits_/8] = 0;
string result = string(tmp);
delete[]tmp;
return result;
return res;
}
bool verinum::is_before(const verinum&that) const
@ -1062,6 +1124,9 @@ verinum::V operator ^ (verinum::V l, verinum::V r)
/*
* $Log: verinum.cc,v $
* Revision 1.52 2007/02/25 23:08:24 steve
* Process Verilog escape sequences much earlier.
*
* Revision 1.51 2007/01/27 05:36:11 steve
* Fix padding of x when literal is sized and unsigned.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_const.cc,v 1.36 2006/06/18 04:15:50 steve Exp $"
#ident "$Id: vpi_const.cc,v 1.37 2007/02/25 23:08:24 steve Exp $"
#endif
# include "vpi_priv.h"
@ -168,6 +168,30 @@ static const struct __vpirt vpip_string_temp_rt = {
free_temp_string
};
static void vpip_process_string(struct __vpiStringConst*obj)
{
char*chr = obj->value;
char*dp = obj->value;
while (*chr) {
char next_char = *chr;
/* Process octal escapes that I might find. */
if (*chr == '\\') {
for (int idx = 1 ; idx <= 3 ; idx += 1) {
assert(chr[idx] != 0);
assert(chr[idx] < '8');
assert(chr[idx] >= '0');
next_char = next_char*8 + chr[idx] - '0';
}
chr += 3;
}
*dp++ = next_char;
chr += 1;
}
*dp = 0;
obj->value_len = dp - obj->value;
}
vpiHandle vpip_make_string_const(char*text, bool persistent_flag)
{
@ -179,6 +203,8 @@ vpiHandle vpip_make_string_const(char*text, bool persistent_flag)
? &vpip_string_rt
: &vpip_string_temp_rt;
obj->value = text;
obj->value_len = 0;
vpip_process_string(obj);
return &obj->base;
}
@ -244,9 +270,12 @@ vpiHandle vpip_make_string_param(char*name, char*text)
malloc(sizeof (struct __vpiStringParam));
obj->base.vpi_type = &vpip_string_param_rt;
obj->value = text;
obj->value_len = 0;
obj->basename = name;
obj->scope = vpip_peek_current_scope();
vpip_process_string(obj);
return &obj->base;
}
@ -589,6 +618,9 @@ vpiHandle vpip_make_real_const(double value)
/*
* $Log: vpi_const.cc,v $
* Revision 1.37 2007/02/25 23:08:24 steve
* Process Verilog escape sequences much earlier.
*
* Revision 1.36 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_priv.h,v 1.72 2007/01/16 05:44:16 steve Exp $"
#ident "$Id: vpi_priv.h,v 1.73 2007/02/25 23:08:24 steve Exp $"
#endif
# include "vpi_user.h"
@ -293,6 +293,7 @@ extern struct __vpiSysTaskCall*vpip_cur_task;
struct __vpiStringConst {
struct __vpiHandle base;
char*value;
size_t value_len;
};
vpiHandle vpip_make_string_const(char*text, bool persistent =true);
@ -450,6 +451,9 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type);
/*
* $Log: vpi_priv.h,v $
* Revision 1.73 2007/02/25 23:08:24 steve
* Process Verilog escape sequences much earlier.
*
* Revision 1.72 2007/01/16 05:44:16 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory