VVP support for memories in expressions,
including general support for thread bit vectors as system task parameters. (Stephan Boettcher)
This commit is contained in:
parent
91d65d0e4e
commit
44a182d92c
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: eval_expr.c,v 1.24 2001/05/06 17:54:33 steve Exp $"
|
||||
#ident "$Id: eval_expr.c,v 1.25 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -738,7 +738,7 @@ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae)
|
|||
{
|
||||
int root = ivl_memory_root(mem);
|
||||
unsigned width = ivl_memory_width(mem);
|
||||
width = (width+7) & ~7;
|
||||
width = (width+3) & ~3;
|
||||
|
||||
switch (ivl_expr_type(ae)) {
|
||||
case IVL_EX_NUMBER: {
|
||||
|
|
@ -772,9 +772,9 @@ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae)
|
|||
addr.base, addr.wid);
|
||||
clr_vector(addr);
|
||||
if (root>0)
|
||||
fprintf(vvp_out, " %%ix/sub 3, %u\n", root);
|
||||
fprintf(vvp_out, " %%ix/sub 3, %u;\n", root);
|
||||
if (width>1)
|
||||
fprintf(vvp_out, " %%ix/mul 3, %u\n", width);
|
||||
fprintf(vvp_out, " %%ix/mul 3, %u;\n", width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -967,6 +967,12 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
|
|||
|
||||
/*
|
||||
* $Log: eval_expr.c,v $
|
||||
* Revision 1.25 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.24 2001/05/06 17:54:33 steve
|
||||
* Behavioral code to read memories. (Stephan Boettcher)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vvp_process.c,v 1.32 2001/05/08 23:59:33 steve Exp $"
|
||||
#ident "$Id: vvp_process.c,v 1.33 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include <malloc.h>
|
||||
|
||||
static int show_statement(ivl_statement_t net, ivl_scope_t sscope);
|
||||
|
||||
|
|
@ -585,12 +586,39 @@ static int show_system_task_call(ivl_statement_t net)
|
|||
{
|
||||
unsigned idx;
|
||||
unsigned parm_count = ivl_stmt_parm_count(net);
|
||||
struct vector_info *vec = 0x0;
|
||||
unsigned int vecs= 0;
|
||||
unsigned int veci= 0;
|
||||
|
||||
if (parm_count == 0) {
|
||||
fprintf(vvp_out, " %%vpi_call \"%s\";\n", ivl_stmt_name(net));
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < parm_count ; idx += 1) {
|
||||
ivl_expr_t expr = ivl_stmt_parm(net, idx);
|
||||
|
||||
switch (ivl_expr_type(expr)) {
|
||||
case IVL_EX_NUMBER:
|
||||
case IVL_EX_SIGNAL:
|
||||
case IVL_EX_STRING:
|
||||
case IVL_EX_SCOPE:
|
||||
case IVL_EX_SFUNC:
|
||||
continue;
|
||||
case IVL_EX_MEMORY:
|
||||
if (!ivl_expr_oper1(expr)) {
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vec = (struct vector_info *)
|
||||
realloc(vec, (vecs+1)*sizeof(struct vector_info));
|
||||
vec[vecs] = draw_eval_expr(expr);
|
||||
vecs++;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%vpi_call \"%s\"", ivl_stmt_name(net));
|
||||
for (idx = 0 ; idx < parm_count ; idx += 1) {
|
||||
ivl_expr_t expr = ivl_stmt_parm(net, idx);
|
||||
|
|
@ -604,43 +632,56 @@ static int show_system_task_call(ivl_statement_t net)
|
|||
fprintf(vvp_out, ", %u'b", wid);
|
||||
for (bit = wid ; bit > 0 ; bit -= 1)
|
||||
fputc(bits[bit-1], vvp_out);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
case IVL_EX_SIGNAL:
|
||||
fprintf(vvp_out, ", V_%s", ivl_expr_name(expr));
|
||||
break;
|
||||
|
||||
case IVL_EX_MEMORY:
|
||||
if (!ivl_expr_oper1(expr))
|
||||
fprintf(vvp_out, ", M_%s", ivl_expr_name(expr));
|
||||
else
|
||||
fprintf(vvp_out, ", M_%s[?]", ivl_expr_name(expr));
|
||||
break;
|
||||
continue;
|
||||
|
||||
case IVL_EX_STRING:
|
||||
fprintf(vvp_out, ", \"%s\"", ivl_expr_string(expr));
|
||||
break;
|
||||
continue;
|
||||
|
||||
case IVL_EX_SCOPE:
|
||||
fprintf(vvp_out, ", S_%s",
|
||||
ivl_scope_name(ivl_expr_scope(expr)));
|
||||
break;
|
||||
continue;
|
||||
|
||||
case IVL_EX_SFUNC:
|
||||
if (strcmp("$time", ivl_expr_name(expr)) == 0)
|
||||
fprintf(vvp_out, ", $time");
|
||||
else
|
||||
fprintf(vvp_out, ", ?");
|
||||
continue;
|
||||
|
||||
case IVL_EX_MEMORY:
|
||||
if (!ivl_expr_oper1(expr)) {
|
||||
fprintf(vvp_out, ", M_%s", ivl_expr_name(expr));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(vvp_out, ", ?");
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, ", T<%u,%u>",
|
||||
vec[veci].base,
|
||||
vec[veci].wid);
|
||||
veci++;
|
||||
}
|
||||
|
||||
assert(veci == vecs);
|
||||
|
||||
if (vecs) {
|
||||
for (idx = 0; idx < vecs; idx++)
|
||||
clr_vector(vec[idx]);
|
||||
free(vec);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, ";\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -813,6 +854,12 @@ int draw_func_definition(ivl_scope_t scope)
|
|||
|
||||
/*
|
||||
* $Log: vvp_process.c,v $
|
||||
* Revision 1.33 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.32 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.18 2001/05/09 02:53:25 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.19 2001/05/10 00:26:53 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -59,7 +59,8 @@ check: all
|
|||
./vvp -M../vpi $(srcdir)/examples/hello.vvp | grep 'Hello, World.'
|
||||
|
||||
V = vpi_modules.o vpi_const.o vpi_iter.o vpi_mcd.o vpi_priv.o \
|
||||
vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o
|
||||
vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \
|
||||
vpi_vthr_vector.o
|
||||
|
||||
O = main.o parse.o parse_misc.o lexor.o compile.o debug.o functor.o \
|
||||
resolv.o symbols.o codes.o vthread.o schedule.o tables.o udp.o memory.o $V
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.cc,v 1.61 2001/05/09 04:23:18 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.62 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
|
|
@ -83,7 +83,7 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
|
||||
{ "%ix/get", of_IX_GET, 2, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%ix/get", of_IX_GET, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%ix/load",of_IX_LOAD,2, {OA_BIT1, OA_NUMBER, OA_NONE} },
|
||||
{ "%ix/mul", of_IX_MUL, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
|
||||
{ "%ix/sub", of_IX_SUB, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
|
||||
|
|
@ -922,6 +922,21 @@ vpiHandle compile_vpi_lookup(const char*label)
|
|||
symbol_value_t val;
|
||||
|
||||
val = sym_get_value(sym_vpi, label);
|
||||
if (!val.ptr) {
|
||||
// check for thread vector T<base,wid>
|
||||
unsigned base, wid;
|
||||
unsigned n;
|
||||
if (2 <= sscanf(label, "T<%u,%u>%n", &base, &wid, &n)
|
||||
&& n == strlen(label)) {
|
||||
val.ptr = vpip_make_vthr_vector(base, wid);
|
||||
sym_set_value(sym_vpi, label, val);
|
||||
}
|
||||
}
|
||||
|
||||
if (!val.ptr) {
|
||||
// check for memory word M<mem,base,wid>
|
||||
}
|
||||
|
||||
return (vpiHandle) val.ptr;
|
||||
}
|
||||
|
||||
|
|
@ -1126,6 +1141,12 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.62 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.61 2001/05/09 04:23:18 steve
|
||||
* Now that the interactive debugger exists,
|
||||
* there is no use for the output dump.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: lexor.lex,v 1.16 2001/05/09 02:53:25 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.17 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -110,6 +110,12 @@
|
|||
yylval.text = strdup(yytext);
|
||||
return T_SYMBOL; }
|
||||
|
||||
/* Symbols may include komma `,' in certain constructs */
|
||||
|
||||
[A-Z]"<"[.$_a-zA-Z0-9/,]*">" {
|
||||
yylval.text = strdup(yytext);
|
||||
return T_SYMBOL; }
|
||||
|
||||
|
||||
/* Accept the common assembler style comments, treat them as white
|
||||
space. Of course, also skip white space. The semi-colon is
|
||||
|
|
@ -133,6 +139,12 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.17 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.16 2001/05/09 02:53:25 steve
|
||||
* Implement the .resolv syntax.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_priv.h,v 1.14 2001/05/08 23:59:33 steve Exp $"
|
||||
#ident "$Id: vpi_priv.h,v 1.15 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
|
@ -168,6 +168,13 @@ struct __vpiBinaryConst {
|
|||
|
||||
vpiHandle vpip_make_binary_const(unsigned wid, char*bits);
|
||||
|
||||
/*
|
||||
* This one looks like a constant, but really is a vector in the current
|
||||
* thread.
|
||||
*/
|
||||
|
||||
vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid);
|
||||
|
||||
/*
|
||||
* This function is called before any compilation to load VPI
|
||||
* modules. This gives the modules a chance to announce their
|
||||
|
|
@ -194,7 +201,9 @@ extern vpiHandle vpip_build_vpi_call(const char*name,
|
|||
unsigned argc,
|
||||
vpiHandle*argv);
|
||||
|
||||
extern void vpip_execute_vpi_call(vpiHandle obj);
|
||||
extern vthread_t vpip_current_vthread;
|
||||
|
||||
extern void vpip_execute_vpi_call(vthread_t thr, vpiHandle obj);
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -206,6 +215,12 @@ vpiHandle vpip_sim_time(void);
|
|||
|
||||
/*
|
||||
* $Log: vpi_priv.h,v $
|
||||
* Revision 1.15 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.14 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_tasks.cc,v 1.5 2001/04/18 04:21:23 steve Exp $"
|
||||
#ident "$Id: vpi_tasks.cc,v 1.6 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -172,8 +172,13 @@ vpiHandle vpip_build_vpi_call(const char*name,
|
|||
* place the call to the system task/function. For now, only support
|
||||
* calls to system tasks.
|
||||
*/
|
||||
void vpip_execute_vpi_call(vpiHandle ref)
|
||||
|
||||
vthread_t vpip_current_vthread;
|
||||
|
||||
void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref)
|
||||
{
|
||||
vpip_current_vthread = thr;
|
||||
|
||||
assert(ref->vpi_type->type_code == vpiSysTaskCall);
|
||||
|
||||
vpip_cur_task = (struct __vpiSysTaskCall*)ref;
|
||||
|
|
@ -197,6 +202,12 @@ void vpi_register_systf(const struct t_vpi_systf_data*ss)
|
|||
|
||||
/*
|
||||
* $Log: vpi_tasks.cc,v $
|
||||
* Revision 1.6 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/04/18 04:21:23 steve
|
||||
* Put threads into scopes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vpi_vthr_vector.cc,v 1.1 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* vpiReg handles are handled here. These objects represent vectors of
|
||||
* .var objects that can be manipulated by the VPI module.
|
||||
*/
|
||||
|
||||
# include "vpi_priv.h"
|
||||
# include "vthread.h"
|
||||
# include <stdio.h>
|
||||
# include <malloc.h>
|
||||
# include <assert.h>
|
||||
|
||||
struct __vpiVThrVec {
|
||||
struct __vpiHandle base;
|
||||
unsigned short bas;
|
||||
unsigned short wid;
|
||||
char *name;
|
||||
};
|
||||
|
||||
inline static
|
||||
unsigned get_bit(struct __vpiVThrVec *rfp, unsigned idx)
|
||||
{
|
||||
return vthread_get_bit(vpip_current_vthread, rfp->bas+idx);
|
||||
}
|
||||
|
||||
inline static
|
||||
void set_bit(struct __vpiVThrVec *rfp, unsigned idx, unsigned bit)
|
||||
{
|
||||
return vthread_put_bit(vpip_current_vthread, rfp->bas+idx, bit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hex digits that represent 4-value bits of Verilog are not as
|
||||
* trivially obvious to display as if the bits were the usual 2-value
|
||||
* bits. So, although it is possible to write a function that
|
||||
* generates a correct character for 4*4-value bits, it is easier to
|
||||
* just perform the lookup in a table. This only takes 256 bytes,
|
||||
* which is not many executable instructions:-)
|
||||
*
|
||||
* The table is calculated as compile time, therefore, by the
|
||||
* draw_tt.c program.
|
||||
*/
|
||||
|
||||
extern const char hex_digits[256];
|
||||
|
||||
extern const char oct_digits[256];
|
||||
|
||||
/*
|
||||
* vpi_get
|
||||
*/
|
||||
static int vthr_vec_get(int code, vpiHandle ref)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg)
|
||||
|| (ref->vpi_type->type_code==vpiConstant));
|
||||
|
||||
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiSigned:
|
||||
return 0;
|
||||
|
||||
case vpiSize:
|
||||
return rfp->wid;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static char* vthr_vec_get_str(int code, vpiHandle ref)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg));
|
||||
|
||||
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiFullName:
|
||||
return (char*)rfp->name;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char buf[4096];
|
||||
|
||||
static void vthr_vec_DecStrVal(struct __vpiVThrVec*rfp, s_vpi_value*vp)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
unsigned count_x = 0, count_z = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < rfp->wid ; idx += 1) {
|
||||
val *= 2;
|
||||
switch (get_bit(rfp, idx)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
val += 1;
|
||||
break;
|
||||
case 2:
|
||||
count_x += 1;
|
||||
break;
|
||||
case 3:
|
||||
count_z += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count_x == rfp->wid) {
|
||||
buf[0] = 'x';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_x > 0) {
|
||||
buf[0] = 'X';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_z == rfp->wid) {
|
||||
buf[0] = 'z';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (count_z > 0) {
|
||||
buf[0] = 'Z';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buf, "%lu", val);
|
||||
}
|
||||
|
||||
/*
|
||||
* The get_value method reads the values of the functors and returns
|
||||
* the vector to the caller. This causes no side-effect, and reads the
|
||||
* variables like a %load would.
|
||||
*/
|
||||
static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg)
|
||||
|| (ref->vpi_type->type_code==vpiConstant));
|
||||
|
||||
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
||||
|
||||
unsigned wid = rfp->wid;
|
||||
|
||||
switch (vp->format) {
|
||||
|
||||
case vpiBinStrVal:
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
buf[wid-idx-1] = "01xz"[get_bit(rfp, idx)];
|
||||
}
|
||||
buf[wid] = 0;
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
case vpiHexStrVal: {
|
||||
unsigned hval, hwid;
|
||||
hwid = (wid + 3) / 4;
|
||||
buf[hwid] = 0;
|
||||
hval = 0;
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
hval = hval | (get_bit(rfp, idx) << 2*(idx % 4));
|
||||
|
||||
if (idx%4 == 3) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = hex_digits[hval];
|
||||
hval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hwid > 0) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = hex_digits[hval];
|
||||
hval = 0;
|
||||
}
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiOctStrVal: {
|
||||
unsigned hval, hwid;
|
||||
hwid = (wid + 2) / 3;
|
||||
buf[hwid] = 0;
|
||||
hval = 0;
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
hval = hval | (get_bit(rfp,idx) << 2*(idx % 3));
|
||||
|
||||
if (idx%3 == 2) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = oct_digits[hval];
|
||||
hval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hwid > 0) {
|
||||
hwid -= 1;
|
||||
buf[hwid] = oct_digits[hval];
|
||||
hval = 0;
|
||||
}
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiDecStrVal:
|
||||
vthr_vec_DecStrVal(rfp, vp);
|
||||
vp->value.str = buf;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* XXXX Not implemented yet. */
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The put_value method writes the value into the vector.
|
||||
*/
|
||||
static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp,
|
||||
p_vpi_time when, int flags)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg));
|
||||
|
||||
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
||||
|
||||
/* XXXX delays are not yet supported. */
|
||||
assert(flags == vpiNoDelay);
|
||||
|
||||
unsigned wid = rfp->wid;
|
||||
|
||||
switch (vp->format) {
|
||||
|
||||
case vpiIntVal: {
|
||||
assert(wid <= sizeof(long));
|
||||
|
||||
long val = vp->value.integer;
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
set_bit(rfp, idx, val&1);
|
||||
val >>= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiScalarVal:
|
||||
switch (vp->value.scalar) {
|
||||
case vpi0:
|
||||
set_bit(rfp, 0, 0);
|
||||
break;
|
||||
case vpi1:
|
||||
set_bit(rfp, 0, 1);
|
||||
break;
|
||||
case vpiX:
|
||||
set_bit(rfp, 0, 2);
|
||||
break;
|
||||
case vpiZ:
|
||||
set_bit(rfp, 0, 3);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case vpiVectorVal: {
|
||||
assert(wid <= sizeof (unsigned long));
|
||||
|
||||
unsigned long aval = vp->value.vector->aval;
|
||||
unsigned long bval = vp->value.vector->bval;
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
int bit = (aval&1) | (((bval^aval)<<1)&2);
|
||||
set_bit(rfp, idx, bit);
|
||||
aval >>= 1;
|
||||
bval >>= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
// The code fully supports vpiReg, vpi_Net, but we do not
|
||||
// create such things, yet. Lacking a neme, for example.
|
||||
|
||||
static const struct __vpirt vpip_vthr_const_rt = {
|
||||
vpiConstant,
|
||||
vthr_vec_get,
|
||||
vthr_vec_get_str,
|
||||
vthr_vec_get_value,
|
||||
vthr_vec_put_value,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
* Construct a vpiReg object. Give the object specified dimensions,
|
||||
* and point to the specified functor for the lsb.
|
||||
*/
|
||||
vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid)
|
||||
{
|
||||
struct __vpiVThrVec*obj = (struct __vpiVThrVec*)
|
||||
malloc(sizeof(struct __vpiVThrVec));
|
||||
obj->base.vpi_type = &vpip_vthr_const_rt;
|
||||
obj->bas = base;
|
||||
obj->wid = wid;
|
||||
obj->name = "T<>";
|
||||
|
||||
return &obj->base;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: vpi_vthr_vector.cc,v $
|
||||
* Revision 1.1 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vthread.cc,v 1.38 2001/05/08 23:59:33 steve Exp $"
|
||||
#ident "$Id: vthread.cc,v 1.39 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vthread.h"
|
||||
|
|
@ -131,6 +131,18 @@ static inline void thr_put_bit(struct vthread_s*thr,
|
|||
thr->bits[addr] = (thr->bits[addr] & ~mask) | (val << (idx*2));
|
||||
}
|
||||
|
||||
unsigned vthread_get_bit(struct vthread_s*thr, unsigned addr)
|
||||
{
|
||||
return thr_get_bit(thr, addr);
|
||||
}
|
||||
|
||||
void vthread_put_bit(struct vthread_s*thr, unsigned addr, unsigned bit)
|
||||
{
|
||||
assert(addr < thr->nbits);
|
||||
thr_put_bit(thr, addr, bit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new thread with the given start address.
|
||||
*/
|
||||
|
|
@ -886,7 +898,7 @@ bool of_SUB(vthread_t thr, vvp_code_t cp)
|
|||
bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
// printf("thread %p: %%vpi_call\n", thr);
|
||||
vpip_execute_vpi_call(cp->handle);
|
||||
vpip_execute_vpi_call(thr, cp->handle);
|
||||
return schedule_finished()? false : true;
|
||||
}
|
||||
|
||||
|
|
@ -993,6 +1005,12 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
|
|||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.39 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.38 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vthread.h,v 1.5 2001/04/21 00:34:39 steve Exp $"
|
||||
#ident "$Id: vthread.h,v 1.6 2001/05/10 00:26:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -63,8 +63,20 @@ extern void vthread_run(vthread_t thr);
|
|||
extern void vthread_schedule_list(vthread_t thr);
|
||||
|
||||
|
||||
/*
|
||||
** Return a bit from the thread's bit space;
|
||||
*/
|
||||
unsigned vthread_get_bit(struct vthread_s*thr, unsigned addr);
|
||||
void vthread_put_bit(struct vthread_s*thr, unsigned addr, unsigned bit);
|
||||
|
||||
/*
|
||||
* $Log: vthread.h,v $
|
||||
* Revision 1.6 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/04/21 00:34:39 steve
|
||||
* Working %disable and reap handling references from scheduler.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue