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:
parent
d48362b861
commit
dc39714d65
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
fprintf(vvp_out, " %%store/str v%p_0;\n", var);
|
||||
if (res.base > 0)
|
||||
clr_vector(res);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
draw_eval_string(rval);
|
||||
fprintf(vvp_out, " %%store/str v%p_0;\n", var);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
42
vvp/parse.y
42
vvp/parse.y
|
|
@ -883,23 +883,31 @@ operands
|
|||
;
|
||||
|
||||
operand
|
||||
: symbol
|
||||
{ comp_operands_t opa = (comp_operands_t)
|
||||
calloc(1, sizeof(struct comp_operands_s));
|
||||
opa->argc = 1;
|
||||
opa->argv[0].ltype = L_SYMB;
|
||||
opa->argv[0].symb = $1;
|
||||
$$ = opa;
|
||||
}
|
||||
| T_NUMBER
|
||||
{ comp_operands_t opa = (comp_operands_t)
|
||||
calloc(1, sizeof(struct comp_operands_s));
|
||||
opa->argc = 1;
|
||||
opa->argv[0].ltype = L_NUMB;
|
||||
opa->argv[0].numb = $1;
|
||||
$$ = opa;
|
||||
}
|
||||
;
|
||||
: symbol
|
||||
{ comp_operands_t opa = (comp_operands_t)
|
||||
calloc(1, sizeof(struct comp_operands_s));
|
||||
opa->argc = 1;
|
||||
opa->argv[0].ltype = L_SYMB;
|
||||
opa->argv[0].symb = $1;
|
||||
$$ = opa;
|
||||
}
|
||||
| T_NUMBER
|
||||
{ comp_operands_t opa = (comp_operands_t)
|
||||
calloc(1, sizeof(struct comp_operands_s));
|
||||
opa->argc = 1;
|
||||
opa->argv[0].ltype = L_NUMB;
|
||||
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;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/* The argument_list is a list of vpiHandle objects that can be
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
Loading…
Reference in New Issue