Support string literal strings in the vvp runtime.

This also advances support for string expressions in general.
Handle assignments to string variables in the code generator by
trying to calculate a string expression. This involves the new
string object thread details.
This commit is contained in:
Stephen Williams 2012-06-17 18:43:25 -07:00
parent d48362b861
commit dc39714d65
10 changed files with 113 additions and 35 deletions

View File

@ -49,7 +49,7 @@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@
O = vvp.o draw_enum.o draw_mux.o draw_net_input.o draw_switch.o draw_ufunc.o draw_vpi.o \
eval_bool.o eval_expr.o eval_real.o modpath.o stmt_assign.o vector.o \
eval_bool.o eval_expr.o eval_real.o eval_string.o modpath.o stmt_assign.o vector.o \
vvp_process.o vvp_scope.o
all: dep vvp.tgt vvp.conf vvp-s.conf

51
tgt-vvp/eval_string.c Normal file
View File

@ -0,0 +1,51 @@
/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "vvp_priv.h"
# include <assert.h>
void draw_eval_string(ivl_expr_t expr)
{
struct vector_info res;
switch (ivl_expr_type(expr)) {
case IVL_EX_STRING:
fprintf(vvp_out, " %%pushi/str \"%s\";\n", ivl_expr_string(expr));
break;
default:
switch (ivl_expr_value(expr)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
res = draw_eval_expr(expr, 0);
fprintf(vvp_out, " %%pushv/str %u, %u; Cast BOOL/LOGIC to string\n",
res.base, res.wid);
if (res.base > 0)
clr_vector(res);
break;
default:
assert(0);
break;
}
break;
}
}

View File

@ -733,7 +733,6 @@ static int show_stmt_assign_sig_real(ivl_statement_t net)
static int show_stmt_assign_sig_string(ivl_statement_t net)
{
struct vector_info res;
ivl_lval_t lval = ivl_stmt_lval(net, 0);
ivl_expr_t rval = ivl_stmt_rval(net);
ivl_signal_t var;
@ -742,20 +741,8 @@ static int show_stmt_assign_sig_string(ivl_statement_t net)
var = ivl_lval_sig(lval);
switch (ivl_expr_value(rval)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
res = draw_eval_expr(rval, 0);
fprintf(vvp_out, " %%pushv/str %u, %u;\n",
res.base, res.wid);
draw_eval_string(rval);
fprintf(vvp_out, " %%store/str v%p_0;\n", var);
if (res.base > 0)
clr_vector(res);
break;
default:
assert(0);
break;
}
return 0;
}

View File

@ -313,6 +313,12 @@ extern int draw_eval_real(ivl_expr_t ex);
*/
extern int draw_eval_bool64(ivl_expr_t ex);
/*
* The draw_eval_string functio evaluates the expression as a string,
* and pushes the string onto the string stack.
*/
extern void draw_eval_string(ivl_expr_t ex);
extern int show_stmt_assign(ivl_statement_t net);
extern void show_stmt_file_line(ivl_statement_t net, const char*desc);

View File

@ -148,6 +148,7 @@ extern bool of_PAD(vthread_t thr, vvp_code_t code);
extern bool of_POW(vthread_t thr, vvp_code_t code);
extern bool of_POW_S(vthread_t thr, vvp_code_t code);
extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
extern bool of_PUSHI_STR(vthread_t thr, vvp_code_t code);
extern bool of_PUSHV_STR(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code);
@ -191,6 +192,7 @@ struct vvp_code_s {
vvp_array_t array;
class __vpiHandle*handle;
struct __vpiScope*scope;
const char*text;
};
union {

View File

@ -70,7 +70,9 @@ enum operand_e {
/* The operand is a second functor pointer */
OA_FUNC_PTR2,
/* The operand is a VPI handle */
OA_VPI_PTR
OA_VPI_PTR,
/* String */
OA_STRING
};
struct opcode_table_s {
@ -194,6 +196,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/wr", of_POW_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%pushi/str",of_PUSHI_STR,1,{OA_STRING, OA_NONE, OA_NONE} },
{ "%pushv/str", of_PUSHV_STR, 2, {OA_BIT1,OA_BIT2, OA_NONE} },
{ "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
{ "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
@ -1669,6 +1672,15 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
compile_vpi_lookup(&code->handle, opa->argv[idx].symb.text);
break;
case OA_STRING:
if (opa->argv[idx].ltype != L_STRING) {
yyerror("operand format");
break;
}
code->text = opa->argv[idx].text;
break;
}
}

View File

@ -388,7 +388,7 @@ extern void compile_named_event(char*label, char*type);
*/
#define OPERAND_MAX 3
enum ltype_e { L_NUMB, L_SYMB };
enum ltype_e { L_NUMB, L_SYMB, L_STRING };
struct comp_operands_s {
unsigned argc;
@ -397,6 +397,7 @@ struct comp_operands_s {
union {
unsigned long numb;
struct symb_s symb;
const char *text;
};
} argv[OPERAND_MAX];
};

View File

@ -750,6 +750,10 @@ replaces the left operand.
This opcode raises <bit-l> (real) to the power of <bit-r> (real). The
result replaces the left operand.
* %pushi/str <text>
Push a literal string to the string stack.
* %pushv/str <src>, <wid>
Convert a vector to a string and push the string to the string stack.

View File

@ -899,6 +899,14 @@ operand
opa->argv[0].numb = $1;
$$ = opa;
}
| T_STRING
{ comp_operands_t opa = (comp_operands_t)
calloc(1, sizeof(struct comp_operands_s));
opa->argc = 1;
opa->argv[0].ltype = L_STRING;
opa->argv[0].text = $1;
$$ = opa;
}
;

View File

@ -4148,6 +4148,13 @@ bool of_POW_WR(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_PUSHI_STR(vthread_t thr, vvp_code_t cp)
{
const char*text = cp->text;
thr->stack_str.push_back(string(text));
return true;
}
bool of_PUSHV_STR(vthread_t thr, vvp_code_t cp)
{
unsigned src = cp->bit_idx[0];