Add support for variable vectors.
This commit is contained in:
parent
90ed3dd124
commit
52c7108782
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
57
vvp/parse.y
57
vvp/parse.y
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
17
vvp/vpi.txt
17
vvp/vpi.txt
|
|
@ -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)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue