Add support for variable vectors.

This commit is contained in:
steve 2001-03-20 06:16:23 +00:00
parent 90ed3dd124
commit 52c7108782
18 changed files with 402 additions and 81 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.7 2001/03/19 04:37:59 steve Exp $"
#ident "$Id: Makefile.in,v 1.8 2001/03/20 06:16:23 steve Exp $"
#
#
SHELL = /bin/sh
@ -55,7 +55,7 @@ distclean: clean
rm -f config.h Makefile config.cache config.log config.status
V = vpi_modules.o vpi_const.o vpi_iter.o vpi_mcd.o vpi_priv.o \
vpi_scope.o vpi_tasks.o
vpi_scope.o vpi_signal.o vpi_tasks.o
O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \
codes.o vthread.o schedule.o tables.o $V

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.4 2001/03/14 19:26:15 steve Exp $
* $Id: README.txt,v 1.5 2001/03/20 06:16:23 steve Exp $
*/
VVP SIMULATION ENGINE
@ -52,7 +52,13 @@ keyword.
Symbols are references to labels. It is not necessary for a label to
be declared before its use in a symbol, but it must be declared
eventually.
eventually. When symbols refer to functors, the symbol represents the
vvp_ipoint_t pointer to the output. (Inputs cannot, and need not, be
references symbolically.)
If the functor is part of a vector, then the symbol is the
vvp_ipoint_t for the first functor. The [] operator can then be used
to reference a functor other then the first in the vector.
FUNCTOR STATEMENTS:
@ -81,20 +87,30 @@ combining up to four inputs down to one output.
VARIABLE STATEMENTS:
A variable is a bit that can be written by behavioral code (so has no
structural input) and propagates its output to a functor. The general
syntax of a variable is:
A variable is a bit vector that can be written by behavioral code (so
has no structural input) and propagates its output to a functor. The
general syntax of a variable is:
<label> .var
<label> .var "name", <msb>, <lsb>;
The "name" is the declared base name of the original variable, for the
sake of VPI code that might access it. The variable is placed in the
current scope. The variable also has a width, defined by the indices
for the mst significant and lest significant bits. If the indices are
equal (normally 0) the vector has width of one. If the width is greater
then one, a contiguous array of functors is created and the value of
the label is the address of the least significant bit.
A variable does not take inputs, since its value is set behaviorally
by assignment events. It does have an output, though, and its output
is propagated into the net of functors in the usual way.
by assignment events. It does have output, though, and its output is
propagated into the net of functors in the usual way.
Therefore, the .var statement implicitly also creates a .functor of
the same name as the variable. It is in fact the functor that
behavioral code reads when the value of the variable (or net) is read
by behavioral code.
Therefore, the .var statement implicitly also creates .functors
addressed by the label of the variable. It is in fact the functors
that behavioral code reads when the value of the variable (or net) is
read by behavioral code. If the .var represents a vector of .functors,
the index of the LSB is always, from the perspective of vvp, ZERO. The
<msb>,<lsb> details are there only for the benefit of VPI support.
The variable .functor implicitly has three inputs. The first is the
value that gets set by assignments or procedural continuous
@ -103,6 +119,9 @@ force expression (as a functor) when a value is being forced. And the
third input selects the source to use. The default is to select the
assignment input.
The variable statement also creates a VPI object of the appropriate
type. See the vpi.txt file for details about that object.
Note that nets in a design do not necessarily have a specific functor
or object allocated to them. Nets are just something that behavioral
code can read, so it is enough to give to the behavioral code the

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: codes.cc,v 1.2 2001/03/11 23:06:49 steve Exp $"
#ident "$Id: codes.cc,v 1.3 2001/03/20 06:16:23 steve Exp $"
#endif
# include "codes.h"
@ -103,6 +103,9 @@ void codespace_dump(FILE*fd)
} else if (cop->opcode == &of_END) {
fprintf(fd, "%%end\n");
} else if (cop->opcode == &of_JMP) {
fprintf(fd, "%%jmp 0x%u\n", cop->cptr);
} else if (cop->opcode == &of_SET) {
fprintf(fd, "%%set 0x%lu, %u\n",
cop->iptr, cop->bit_idx1);
@ -116,6 +119,9 @@ void codespace_dump(FILE*fd)
/*
* $Log: codes.cc,v $
* Revision 1.3 2001/03/20 06:16:23 steve
* Add support for variable vectors.
*
* Revision 1.2 2001/03/11 23:06:49 steve
* Compact the vvp_code_s structure.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: codes.h,v 1.3 2001/03/16 01:44:34 steve Exp $"
#ident "$Id: codes.h,v 1.4 2001/03/20 06:16:24 steve Exp $"
#endif
@ -38,6 +38,7 @@ typedef bool (*vvp_code_fun)(vthread_t thr, vvp_code_t code);
extern bool of_ASSIGN(vthread_t thr, vvp_code_t code);
extern bool of_DELAY(vthread_t thr, vvp_code_t code);
extern bool of_END(vthread_t thr, vvp_code_t code);
extern bool of_JMP(vthread_t thr, vvp_code_t code);
extern bool of_SET(vthread_t thr, vvp_code_t code);
extern bool of_NOOP(vthread_t thr, vvp_code_t code);
extern bool of_VPI_CALL(vthread_t thr, vvp_code_t code);
@ -85,6 +86,9 @@ extern void codespace_dump(FILE*fd);
/*
* $Log: codes.h,v $
* Revision 1.4 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.3 2001/03/16 01:44:34 steve
* Add structures for VPI support, and all the %vpi_call
* instruction. Get linking of VPI modules to work.

View File

@ -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.6 2001/03/18 04:35:18 steve Exp $"
#ident "$Id: compile.cc,v 1.7 2001/03/20 06:16:24 steve Exp $"
#endif
# include "compile.h"
@ -66,6 +66,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%assign", of_ASSIGN, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%jmp", of_JMP, 1, {OA_CODE_PTR, OA_NONE, OA_NONE} },
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ 0, of_NOOP, 0, {OA_NONE, OA_NONE, OA_NONE} }
};
@ -100,7 +101,9 @@ static symbol_table_t sym_functors = 0;
struct resolv_list_s {
struct resolv_list_s*next;
vvp_ipoint_t port;
char*source;
unsigned idx;
};
static struct resolv_list_s*resolv_list = 0;
@ -129,9 +132,9 @@ void compile_init(void)
* functor. Also resolve the inputs to the functor.
*/
void compile_functor(char*label, char*type, unsigned init,
unsigned argc, char**argv)
unsigned argc, struct symb_s*argv)
{
vvp_ipoint_t fdx = functor_allocate();
vvp_ipoint_t fdx = functor_allocate(1);
functor_t obj = functor_index(fdx);
{ symbol_value_t val;
@ -151,22 +154,24 @@ void compile_functor(char*label, char*type, unsigned init,
the link yet. Save the reference to be resolved later. */
for (unsigned idx = 0 ; idx < argc ; idx += 1) {
symbol_value_t val = sym_get_value(sym_functors, argv[idx]);
symbol_value_t val = sym_get_value(sym_functors, argv[idx].text);
vvp_ipoint_t tmp = val.num;
if (tmp) {
tmp = ipoint_index(tmp, argv[idx].idx);
functor_t fport = functor_index(tmp);
obj->port[idx] = fport->out;
fport->out = ipoint_make(fdx, idx);
free(argv[idx]);
free(argv[idx].text);
} else {
struct resolv_list_s*res = (struct resolv_list_s*)
calloc(1, sizeof(struct resolv_list_s));
res->port = ipoint_make(fdx, idx);
res->source = argv[idx];
res->source = argv[idx].text;
res->idx = argv[idx].idx;
res->next = resolv_list;
resolv_list = res;
}
@ -260,35 +265,36 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
break;
case OA_CODE_PTR:
if (opa->argv[idx].ltype != L_TEXT) {
if (opa->argv[idx].ltype != L_SYMB) {
yyerror("operand format");
break;
}
tmp = sym_get_value(sym_codespace, opa->argv[idx].text);
assert(opa->argv[idx].symb.idx == 0);
tmp = sym_get_value(sym_codespace, opa->argv[idx].symb.text);
code->cptr = tmp.num;
if (code->cptr == 0) {
yyerror("functor undefined");
break;
}
free(opa->argv[idx].text);
free(opa->argv[idx].symb.text);
break;
case OA_FUNC_PTR:
if (opa->argv[idx].ltype != L_TEXT) {
if (opa->argv[idx].ltype != L_SYMB) {
yyerror("operand format");
break;
}
tmp = sym_get_value(sym_functors, opa->argv[idx].text);
code->iptr = tmp.num;
if (code->iptr == 0) {
tmp = sym_get_value(sym_functors, opa->argv[idx].symb.text);
if (tmp.num == 0) {
yyerror("functor undefined");
break;
}
code->iptr = ipoint_index(tmp.num, opa->argv[idx].symb.idx);
free(opa->argv[idx].text);
free(opa->argv[idx].symb.text);
break;
case OA_NUMBER:
@ -357,19 +363,24 @@ void compile_thread(char*start_sym)
* A variable is a special functor, so we allocate that functor and
* write the label into the symbol table.
*/
void compile_variable(char*label)
void compile_variable(char*label, char*name, int msb, int lsb)
{
vvp_ipoint_t fdx = functor_allocate();
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_ipoint_t fdx = functor_allocate(wid);
symbol_value_t val;
val.num = fdx;
sym_set_value(sym_functors, label, val);
functor_t obj = functor_index(fdx);
obj->table = ft_var;
obj->ival = 0x22;
obj->oval = 0x02;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
functor_t obj = functor_index(ipoint_index(fdx,idx));
obj->table = ft_var;
obj->ival = 0x22;
obj->oval = 0x02;
}
free(label);
/* Make the vpiHandle for the reg. */
vpip_make_reg(name, msb, lsb, fdx);
}
/*
@ -398,6 +409,8 @@ void compile_cleanup(void)
if (tmp != 0) {
/* The symbol is defined, link the functor input
to the resolved output. */
tmp = ipoint_index(tmp, res->idx);
functor_t fport = functor_index(tmp);
obj->port[idx] = fport->out;
fport->out = res->port;
@ -434,6 +447,9 @@ void compile_dump(FILE*fd)
/*
* $Log: compile.cc,v $
* Revision 1.7 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.6 2001/03/18 04:35:18 steve
* Add support for string constants to VPI.
*

View File

@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: compile.h,v 1.5 2001/03/18 04:35:18 steve Exp $"
#ident "$Id: compile.h,v 1.6 2001/03/20 06:16:24 steve Exp $"
#endif
# include <stdio.h>
# include "parse_misc.h"
# include "vpi_user.h"
/*
@ -49,7 +50,7 @@ extern void compile_cleanup(void);
* to existing functors to manage the linking.
*/
extern void compile_functor(char*label, char*type, unsigned init,
unsigned argc, char**argv);
unsigned argc, struct symb_s*argv);
/*
@ -62,7 +63,7 @@ extern void compile_functor(char*label, char*type, unsigned init,
*/
#define OPERAND_MAX 3
enum ltype_e { L_NUMB, L_TEXT };
enum ltype_e { L_NUMB, L_SYMB };
struct comp_operands_s {
unsigned argc;
@ -70,7 +71,7 @@ struct comp_operands_s {
enum ltype_e ltype;
union {
unsigned long numb;
char*text;
struct symb_s symb;
};
} argv[OPERAND_MAX];
};
@ -95,9 +96,9 @@ extern void compile_scope_recall(char*sym);
extern void compile_thread(char*start_sym);
/*
* This function is called to create a var bit with the given name.
* This function is called to create a var vector with the given name.
*/
extern void compile_variable(char*label);
extern void compile_variable(char*label, char*name, int msb, int lsb);
/*
* This is a diagnostic aid. Dump all the compiler tables to the file
@ -107,6 +108,9 @@ extern void compile_dump(FILE*fd);
/*
* $Log: compile.h,v $
* Revision 1.6 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.5 2001/03/18 04:35:18 steve
* Add support for string constants to VPI.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.cc,v 1.2 2001/03/11 22:42:11 steve Exp $"
#ident "$Id: functor.cc,v 1.3 2001/03/20 06:16:24 steve Exp $"
#endif
# include "functor.h"
@ -74,7 +74,7 @@ void functor_init(void)
* if we overrun a chunk or an index, we need to allocate the needed
* bits first.
*/
vvp_ipoint_t functor_allocate(void)
static vvp_ipoint_t functor_allocate_(void)
{
vvp_ipoint_t idx = functor_count;
@ -96,6 +96,20 @@ vvp_ipoint_t functor_allocate(void)
return res * 4;
}
vvp_ipoint_t functor_allocate(unsigned wid)
{
assert(wid > 0);
vvp_ipoint_t res = functor_allocate_();
wid -= 1;
while (wid > 0) {
functor_allocate_();
wid -= 1;
}
return res;
}
/*
* Given a vvp_ipoint_t pointer, return a pointer to the detailed
* functor structure. This does not use the low 2 bits, which address
@ -205,6 +219,9 @@ const unsigned char ft_var[16] = {
/*
* $Log: functor.cc,v $
* Revision 1.3 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.h,v 1.2 2001/03/11 22:42:11 steve Exp $"
#ident "$Id: functor.h,v 1.3 2001/03/20 06:16:24 steve Exp $"
#endif
# include "pointers.h"
@ -72,8 +72,11 @@ extern void functor_init(void);
* This function allocates a functor and returns the vvp_ipoint_t
* address for it. Every call to functor_allocate is guaranteed to
* return a different vvp_ipoint_t address. The ipoint port bits are 0.
*
* If the wid is >1, a bunch of contiguous functors is created, and
* the return value is the address of the first in the vector.
*/
extern vvp_ipoint_t functor_allocate(void);
extern vvp_ipoint_t functor_allocate(unsigned wid);
/*
* functor_set sets the addressed input to the specified value, and
@ -108,6 +111,9 @@ extern const unsigned char ft_var[];
/*
* $Log: functor.h,v $
* Revision 1.3 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.2 2001/03/11 22:42:11 steve
* Functor values and propagation.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: main.cc,v 1.3 2001/03/18 04:35:18 steve Exp $"
#ident "$Id: main.cc,v 1.4 2001/03/20 06:16:24 steve Exp $"
#endif
# include "config.h"
@ -80,6 +80,7 @@ int main(int argc, char*argv[])
if (dump_path) {
FILE*fd = fopen(dump_path, "w");
compile_dump(fd);
fclose(fd);
}
schedule_simulate();
@ -89,6 +90,9 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.4 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.3 2001/03/18 04:35:18 steve
* Add support for string constants to VPI.
*

View File

@ -21,6 +21,11 @@ future to reschedule, and is >= 0. If the %delay is zero, then the
thread yields the processor for another thread, but will be resumed in
the current time step.
* %jmp <code-label>
The %jmp instruction performs an unconditional branch to a given
location. The parameter is the label of the destination instruction.
* %load <bit>, <functor-label>
This instruction loads a value from the given functor output into the

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.8 2001/03/20 02:48:40 steve Exp $"
#ident "$Id: parse.y,v 1.9 2001/03/20 06:16:24 steve Exp $"
#endif
# include "parse_misc.h"
@ -38,9 +38,12 @@ extern FILE*yyin;
%union {
char*text;
long numb;
struct textv_s textv;
comp_operands_t opa;
struct symb_s symb;
struct symbv_s symbv;
struct argv_s argv;
vpiHandle vpi;
};
@ -54,7 +57,8 @@ extern FILE*yyin;
%token <text> T_STRING
%token <text> T_SYMBOL
%type <textv> symbols
%type <symb> symbol
%type <symbv> symbols
%type <text> label_opt
%type <opa> operand operands operands_opt
@ -81,8 +85,8 @@ statement
label and a type name, and may have operands. */
: T_LABEL K_FUNCTOR T_SYMBOL ',' T_NUMBER ',' symbols ';'
{ struct textv_s obj = $7;
compile_functor($1, $3, $5, obj.cnt, obj.text);
{ struct symbv_s obj = $7;
compile_functor($1, $3, $5, obj.cnt, obj.vect);
}
| T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';'
{ compile_functor($1, $3, $5, 0, 0); }
@ -125,8 +129,8 @@ statement
creates a functor with the same name that acts as the output of
the variable in the netlist. */
| T_LABEL K_VAR ';'
{ compile_variable($1); }
| T_LABEL K_VAR T_STRING ',' T_NUMBER ',' T_NUMBER ';'
{ compile_variable($1, $3, $5, $7); }
/* Oh and by the way, empty statements are OK as well. */
@ -162,12 +166,12 @@ operands
;
operand
: T_SYMBOL
: symbol
{ comp_operands_t opa = (comp_operands_t)
calloc(1, sizeof(struct comp_operands_s));
opa->argc = 1;
opa->argv[0].ltype = L_TEXT;
opa->argv[0].text = $1;
opa->argv[0].ltype = L_SYMB;
opa->argv[0].symb = $1;
$$ = opa;
}
| T_NUMBER
@ -218,19 +222,35 @@ argument
/* functor operands can only be a list of symbols. */
symbols
: T_SYMBOL
{ struct textv_s obj;
textv_init(&obj);
textv_add(&obj, $1);
: symbol
{ struct symbv_s obj;
symbv_init(&obj);
symbv_add(&obj, $1);
$$ = obj;
}
| symbols ',' T_SYMBOL
{ struct textv_s obj = $1;
textv_add(&obj, $3);
| symbols ',' symbol
{ struct symbv_s obj = $1;
symbv_add(&obj, $3);
$$ = obj;
}
;
/* In some cases, simple pointer arithmetic is allowed. In
particular, functor vectors can be indexed with the [] syntax,
with values from 0 up. */
symbol
: T_SYMBOL
{ $$.text = $1;
$$.idx = 0;
}
| T_SYMBOL '[' T_NUMBER ']'
{ $$.text = $1;
$$.idx = $3;
}
;
%%
int compile_design(const char*path)
@ -245,6 +265,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.9 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.8 2001/03/20 02:48:40 steve
* Copyright notices.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse_misc.cc,v 1.2 2001/03/18 04:35:18 steve Exp $"
#ident "$Id: parse_misc.cc,v 1.3 2001/03/20 06:16:24 steve Exp $"
#endif
# include "parse_misc.h"
@ -32,16 +32,17 @@ void yyerror(const char*msg)
fprintf(stderr, "%s:%u: %s\n", yypath, yyline, msg);
}
void textv_init(struct textv_s*obj)
void symbv_init(struct symbv_s*obj)
{
obj->cnt = 0;
obj->text = 0;
obj->vect = 0;
}
void textv_add(struct textv_s*obj, char*item)
void symbv_add(struct symbv_s*obj, struct symb_s item)
{
obj->text = (char**)realloc(obj->text, (obj->cnt+1) * sizeof(char*));
obj->text[obj->cnt] = item;
obj->vect = (struct symb_s*)
realloc(obj->vect, (obj->cnt+1) * sizeof(struct symb_s));
obj->vect[obj->cnt] = item;
obj->cnt += 1;
}
@ -61,6 +62,9 @@ void argv_add(struct argv_s*obj, vpiHandle item)
/*
* $Log: parse_misc.cc,v $
* Revision 1.3 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.2 2001/03/18 04:35:18 steve
* Add support for string constants to VPI.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse_misc.h,v 1.2 2001/03/18 04:35:18 steve Exp $"
#ident "$Id: parse_misc.h,v 1.3 2001/03/20 06:16:24 steve Exp $"
#endif
@ -43,13 +43,18 @@ extern void yyerror(const char*msg);
extern const char*yypath;
extern unsigned yyline;
struct textv_s {
unsigned cnt;
char**text;
struct symb_s {
char*text;
unsigned idx;
};
extern void textv_init(struct textv_s*obj);
extern void textv_add(struct textv_s*obj, char*item);
struct symbv_s {
unsigned cnt;
struct symb_s*vect;
};
extern void symbv_init(struct symbv_s*obj);
extern void symbv_add(struct symbv_s*obj, struct symb_s item);
@ -63,6 +68,9 @@ extern void argv_add(struct argv_s*obj, vpiHandle);
/*
* $Log: parse_misc.h,v $
* Revision 1.3 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.2 2001/03/18 04:35:18 steve
* Add support for string constants to VPI.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pointers.h,v 1.1 2001/03/11 00:29:39 steve Exp $"
#ident "$Id: pointers.h,v 1.2 2001/03/20 06:16:24 steve Exp $"
#endif
/*
@ -57,6 +57,15 @@ inline vvp_ipoint_t ipoint_make(vvp_ipoint_t func, unsigned port)
return (func & ~3) | (port & 3);
}
/*
* This implements pointer arithmetic for vvp_point_t pointers. Add
* the given index to the functor part of the pointer.
*/
inline vvp_ipoint_t ipoint_index(vvp_ipoint_t base, unsigned idx)
{
return base + (idx<<2);
}
/*
* This function returns the port index of a functor given a complete
* vvp_ipoint_t pointer.
@ -70,6 +79,9 @@ typedef unsigned vvp_cpoint_t;
/*
* $Log: pointers.h,v $
* Revision 1.2 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.1 2001/03/11 00:29:39 steve
* Add the vvp engine to cvs.
*

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: vpi.txt,v 1.4 2001/03/18 04:35:18 steve Exp $
* $Id: vpi.txt,v 1.5 2001/03/20 06:16:24 steve Exp $
*/
@ -126,6 +126,21 @@ In this case, the <symbol> is the label of a previous scope directive,
and is used to identify the scope to be resumed. A scope resume
directive cannot have a label.
VARIABLES
Reg vectors (scalers are vectors of length 1) are created by .var
statements in the source. The .var statement includes the declared
name of the variable, and the indices of the MSB and LSB of the
vector. The vpiHandle is then created with this information, and the
vpi_ipoint_t pointer to the LSB functor of the variable. VPI programs
access the vector through the vpiHandle and related functions. The VPI
code gets access to the declared indices.
The VPI interface to variable (vpiReg objects) uses the MSB and LSB
values that the user defined to describe the dimensions of the
object.
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*

View File

@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_priv.h,v 1.3 2001/03/18 04:35:18 steve Exp $"
#ident "$Id: vpi_priv.h,v 1.4 2001/03/20 06:16:24 steve Exp $"
#endif
# include "vpi_user.h"
# include "pointers.h"
/*
* This header file contains the internal definitions that the vvp
@ -88,6 +89,24 @@ struct __vpiScope {
extern vpiHandle vpip_peek_current_scope(void);
extern void vpip_attach_to_current_scope(vpiHandle obj);
/*
* Signals include the variable types (reg, integer, time) and are
* distinguished by the vpiType code. They also have a parent scope,
* a declared name and declaration indices.
*/
struct __vpiSignal {
struct __vpiHandle base;
vpiHandle scope;
/* The name of this reg/net object */
char*name;
/* The indices that define the width and access offset. */
int msb, lsb;
/* The represented value is here. */
vvp_ipoint_t bits;
};
extern vpiHandle vpip_make_reg(char*name, int msb, int lsb,
vvp_ipoint_t base);
/*
* When a loaded VPI module announces a system task/function, one
* __vpiUserSystf object is created to hold the definition of that
@ -163,6 +182,9 @@ extern void scope_cleanup(void);
/*
* $Log: vpi_priv.h,v $
* Revision 1.4 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.3 2001/03/18 04:35:18 steve
* Add support for string constants to VPI.
*

147
vvp/vpi_signal.cc Normal file
View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2001 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
*/
#if !defined(WINNT)
#ident "$Id: vpi_signal.cc,v 1.1 2001/03/20 06:16:24 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 <malloc.h>
# include <assert.h>
/*
* implement vpi_get for vpiReg objects.
*/
static int signal_get(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
switch (code) {
case vpiSigned:
return 0;
case vpiSize:
if (rfp->msb >= rfp->lsb)
return rfp->msb - rfp->lsb + 1;
else
return rfp->lsb - rfp->msb + 1;
default:
return 0;
}
}
static char* signal_get_str(int code, vpiHandle ref)
{
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
switch (code) {
case vpiFullName:
return (char*)rfp->name;
}
return 0;
}
/*
* 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 signal_get_value(vpiHandle ref, s_vpi_value*vp)
{
assert((ref->vpi_type->type_code==vpiNet)
|| (ref->vpi_type->type_code==vpiReg));
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
/* XXXX Not implemented yet. */
assert(0);
}
/*
* The put_value method writes the value into the vector, and returns
* the affected ref. This operation works much like the %set or
* %assign instructions and causes all the side-effects that the
* equivilent instruction would cause.
*/
static vpiHandle signal_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 __vpiSignal*rfp = (struct __vpiSignal*)ref;
/* XXXX Not implemented yet. */
assert(0);
return ref;
}
static const struct __vpirt vpip_reg_rt = {
vpiReg,
signal_get,
signal_get_str,
signal_get_value,
signal_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_reg(char*name, int msb, int lsb, vvp_ipoint_t base)
{
struct __vpiSignal*obj = (struct __vpiSignal*)
malloc(sizeof(struct __vpiSignal));
obj->base.vpi_type = &vpip_reg_rt;
obj->name = name;
obj->msb = msb;
obj->lsb = lsb;
obj->bits = base;
obj->scope = vpip_peek_current_scope();
return &obj->base;
}
/*
* $Log: vpi_signal.cc,v $
* Revision 1.1 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
*/

View File

@ -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.5 2001/03/19 01:55:38 steve Exp $"
#ident "$Id: vthread.cc,v 1.6 2001/03/20 06:16:24 steve Exp $"
#endif
# include "vthread.h"
@ -94,6 +94,12 @@ bool of_END(vthread_t thr, vvp_code_t cp)
return false;
}
bool of_JMP(vthread_t thr, vvp_code_t cp)
{
thr->pc = cp->cptr;
return true;
}
bool of_NOOP(vthread_t thr, vvp_code_t cp)
{
return true;
@ -125,6 +131,9 @@ bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.6 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*
* Revision 1.5 2001/03/19 01:55:38 steve
* Add support for the vpiReset sim control.
*