Add the .event statement and the %wait instruction.
This commit is contained in:
parent
f7f5ccce05
commit
79ce94b585
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.8 2001/03/24 22:59:28 steve Exp $
|
||||
* $Id: README.txt,v 1.9 2001/03/26 04:00:39 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -186,6 +186,28 @@ position for that bit blank. Bits of .nets are initialized to
|
|||
z. Unconnected bits keep the value z throughout the simulation.
|
||||
|
||||
|
||||
EVENT STATEMENTS
|
||||
|
||||
Threads need to interact with the functors of a netlist synchronously,
|
||||
as well as asynchronously. There are cases where the web of functors
|
||||
needs to wake up a waiting thread. The web of functors signals threads
|
||||
through .event objects, that are declare like so:
|
||||
|
||||
<label> .event <type>, <symbols_list>;
|
||||
<label> .event "name";
|
||||
|
||||
|
||||
This event statement declares an object that a %waitfor instruction
|
||||
can take as an operand. When a thread executes a %waitfor, it puts
|
||||
itself in the notification list of the event and suspends. The
|
||||
<symbols_list> is a set of inputs that can trigger the event.
|
||||
|
||||
The <type> describes the conditions needed to trigger the event. It
|
||||
may be posedge, negedge or edge. If the type is instead a "name"
|
||||
string, then this is a named event which receives events by the %set
|
||||
instruction instead of from the output of a functor.
|
||||
|
||||
|
||||
THREAD STATEMENTS:
|
||||
|
||||
Thread statements create the initial threads for a simulation. These
|
||||
|
|
|
|||
|
|
@ -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.6 2001/03/25 03:54:26 steve Exp $"
|
||||
#ident "$Id: codes.h,v 1.7 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -46,6 +46,7 @@ extern bool of_JMP0XZ(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_LOAD(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_MOV(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_WAIT(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);
|
||||
|
||||
|
|
@ -92,6 +93,9 @@ extern void codespace_dump(FILE*fd);
|
|||
|
||||
/*
|
||||
* $Log: codes.h,v $
|
||||
* Revision 1.7 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.6 2001/03/25 03:54:26 steve
|
||||
* Add JMP0XZ and postpone net inputs when needed.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.15 2001/03/25 19:38:23 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.16 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compile.h"
|
||||
|
|
@ -75,6 +75,7 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%load", of_LOAD, 2, {OA_BIT1, OA_FUNC_PTR, OA_NONE} },
|
||||
{ "%mov", of_MOV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%wait", of_WAIT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ 0, of_NOOP, 0, {OA_NONE, OA_NONE, OA_NONE} }
|
||||
};
|
||||
|
||||
|
|
@ -226,6 +227,7 @@ void compile_functor(char*label, char*type, unsigned init,
|
|||
|
||||
obj->ival = init;
|
||||
obj->oval = 2;
|
||||
obj->mode = 0;
|
||||
|
||||
if (strcmp(type, "OR") == 0) {
|
||||
obj->table = ft_OR;
|
||||
|
|
@ -248,6 +250,71 @@ void compile_functor(char*label, char*type, unsigned init,
|
|||
free(type);
|
||||
}
|
||||
|
||||
void compile_event(char*label, char*type,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
functor_t obj = functor_index(fdx);
|
||||
|
||||
{ symbol_value_t val;
|
||||
val.num = fdx;
|
||||
sym_set_value(sym_functors, label, val);
|
||||
}
|
||||
|
||||
assert(argc <= 4);
|
||||
|
||||
/* Run through the arguments looking for the functors that are
|
||||
connected to my input ports. For each source functor that I
|
||||
find, connect the output of that functor to the indexed
|
||||
input by inserting myself (complete with the port number in
|
||||
the vvp_ipoint_t) into the list that the source heads.
|
||||
|
||||
If the source functor is not declared yet, then don't do
|
||||
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].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].text);
|
||||
|
||||
} else {
|
||||
postpone_functor_input(ipoint_make(fdx, idx),
|
||||
argv[idx].text,
|
||||
argv[idx].idx);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
free(argv);
|
||||
|
||||
obj->ival = 0xaa;
|
||||
obj->oval = 2;
|
||||
obj->mode = 1;
|
||||
|
||||
obj->event = (struct vvp_event_s*) malloc(sizeof (struct vvp_event_s));
|
||||
obj->event->threads = 0;
|
||||
obj->event->ival = obj->ival;
|
||||
|
||||
if (strcmp(type,"posedge") == 0)
|
||||
obj->event->vvp_edge_tab = vvp_edge_posedge;
|
||||
else if (strcmp(type,"negedge") == 0)
|
||||
obj->event->vvp_edge_tab = vvp_edge_negedge;
|
||||
else if (strcmp(type,"edge") == 0)
|
||||
obj->event->vvp_edge_tab = vvp_edge_anyedge;
|
||||
else
|
||||
obj->event->vvp_edge_tab = 0;
|
||||
|
||||
free(type);
|
||||
free(label);
|
||||
}
|
||||
|
||||
/*
|
||||
* The parser uses this function to compile an link an executable
|
||||
* opcode. I do this by looking up the opcode in the opcode_table. The
|
||||
|
|
@ -453,6 +520,7 @@ void compile_variable(char*label, char*name, int msb, int lsb)
|
|||
obj->table = ft_var;
|
||||
obj->ival = 0x22;
|
||||
obj->oval = 0x02;
|
||||
obj->mode = 0;
|
||||
}
|
||||
|
||||
/* Make the vpiHandle for the reg. */
|
||||
|
|
@ -477,6 +545,7 @@ void compile_net(char*label, char*name, int msb, int lsb,
|
|||
obj->table = ft_var;
|
||||
obj->ival = 0x22;
|
||||
obj->oval = 0x02;
|
||||
obj->mode = 0;
|
||||
}
|
||||
|
||||
assert(argc == wid);
|
||||
|
|
@ -593,6 +662,9 @@ void compile_dump(FILE*fd)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.16 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.15 2001/03/25 19:38:23 steve
|
||||
* Support NOR and NOT gates.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.h,v 1.10 2001/03/25 00:35:35 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.11 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -65,6 +65,15 @@ extern void compile_functor(char*label, char*type, unsigned init,
|
|||
extern void compile_vpi_symbol(const char*label, vpiHandle obj);
|
||||
extern vpiHandle compile_vpi_lookup(const char*label);
|
||||
|
||||
/*
|
||||
* The compile_event function takes the parts of the event statement
|
||||
* and makes the various objects needed to simulate it. This includes
|
||||
* the functor that receives the signals and the event_t that holds
|
||||
* the threads.
|
||||
*/
|
||||
extern void compile_event(char*label, char*type,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
|
||||
/*
|
||||
* A code statement is a label, an opcode and up to 3 operands. There
|
||||
* are a few lexical types that the parser recognizes of the operands,
|
||||
|
|
@ -123,6 +132,9 @@ extern void compile_dump(FILE*fd);
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.11 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.10 2001/03/25 00:35:35 steve
|
||||
* Add the .net statement.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
:vpi_module "system";
|
||||
|
||||
; 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
|
||||
|
||||
|
||||
; This example tests the operation of a simple posedge event. The module
|
||||
; that would generate code like this would be:
|
||||
;
|
||||
; module main;
|
||||
; reg a;
|
||||
;
|
||||
; initial begin
|
||||
; a = 0;
|
||||
; #1 a = 1;
|
||||
; end
|
||||
;
|
||||
; always @(posedge a) $display("Got a posedge.");
|
||||
;
|
||||
; endmodule
|
||||
;
|
||||
|
||||
main .scope "main";
|
||||
|
||||
V_main.a .var "a", 0, 0;
|
||||
V_main.b .event posedge, V_main.a;
|
||||
|
||||
code
|
||||
%set V_main.a, 0;
|
||||
%delay 1;
|
||||
%set V_main.a, 1;
|
||||
%end;
|
||||
.thread code;
|
||||
|
||||
loop %wait V_main.b;
|
||||
%vpi_call "$display", "Got a posedge.";
|
||||
%jmp loop;
|
||||
.thread loop;
|
||||
|
|
@ -17,11 +17,12 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.cc,v 1.6 2001/03/25 00:35:35 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.7 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
# include "schedule.h"
|
||||
# include "vthread.h"
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
|
|
@ -131,6 +132,63 @@ functor_t functor_index(vvp_ipoint_t point)
|
|||
return functor_table[point]->table[index1]->table + index0;
|
||||
}
|
||||
|
||||
static void functor_set_mode0(vvp_ipoint_t ptr, functor_t fp)
|
||||
{
|
||||
/* Locate the new output value in the table. */
|
||||
unsigned char out = fp->table[fp->ival >> 2];
|
||||
out >>= 2 * (fp->ival&0x03);
|
||||
out &= 0x03;
|
||||
|
||||
/* If the output changes, then create a propagation event. */
|
||||
if (out != fp->oval) {
|
||||
fp->oval = out;
|
||||
schedule_functor(ptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned char vvp_edge_posedge[16] = {
|
||||
0, 1, 1, 1, // 0 -> ...
|
||||
0, 0, 0, 0, // 1 -> ...
|
||||
0, 1, 0, 0, // x -> ...
|
||||
0, 1, 0, 0 // z -> ...
|
||||
};
|
||||
|
||||
const unsigned char vvp_edge_negedge[16] = {
|
||||
0, 0, 0, 0, // 0 -> ...
|
||||
1, 0, 1, 1, // 1 -> ...
|
||||
1, 0, 0, 0, // x -> ...
|
||||
1, 0, 0, 0 // z -> ...
|
||||
};
|
||||
|
||||
const unsigned char vvp_edge_anyedge[16] = {
|
||||
0, 1, 1, 1, // 0 -> ...
|
||||
1, 0, 1, 1, // 1 -> ...
|
||||
1, 1, 0, 1, // x -> ...
|
||||
1, 1, 1, 0 // z -> ...
|
||||
};
|
||||
|
||||
static void functor_set_mode1(functor_t fp)
|
||||
{
|
||||
vvp_event_t ep = fp->event;
|
||||
|
||||
for (unsigned idx = 0 ; ep->threads && (idx < 4) ; idx += 1) {
|
||||
unsigned oval = (ep->ival >> 2*idx) & 3;
|
||||
unsigned nval = (fp->ival >> 2*idx) & 3;
|
||||
|
||||
unsigned val = (oval << 2) | nval;
|
||||
unsigned char edge_p = ep->vvp_edge_tab[val];
|
||||
|
||||
if (edge_p) {
|
||||
vthread_t tmp = ep->threads;
|
||||
ep->threads = 0;
|
||||
vthread_schedule_list(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* the new value is the new old value. */
|
||||
ep->ival = fp->ival;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the addressed bit of the functor, and recalculate the
|
||||
* output. If the output changes any, then generate the necessary
|
||||
|
|
@ -148,15 +206,13 @@ void functor_set(vvp_ipoint_t ptr, unsigned bit)
|
|||
unsigned char mask = mask_table[pp];
|
||||
fp->ival = (fp->ival & mask) | (bit << (2*pp));
|
||||
|
||||
/* Locate the new output value in the table. */
|
||||
unsigned char out = fp->table[fp->ival >> 2];
|
||||
out >>= 2 * (fp->ival&0x03);
|
||||
out &= 0x03;
|
||||
|
||||
/* If the output changes, then create a propagation event. */
|
||||
if (out != fp->oval) {
|
||||
fp->oval = out;
|
||||
schedule_functor(ptr, 0);
|
||||
switch (fp->mode) {
|
||||
case 0:
|
||||
functor_set_mode0(ptr, fp);
|
||||
break;
|
||||
case 1:
|
||||
functor_set_mode1(fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,6 +282,9 @@ const unsigned char ft_var[16] = {
|
|||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.7 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.6 2001/03/25 00:35:35 steve
|
||||
* Add the .net statement.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,13 +19,12 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: functor.h,v 1.5 2001/03/25 19:38:23 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.6 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "pointers.h"
|
||||
# include <stdio.h>
|
||||
|
||||
typedef const unsigned char*vvp_truth_t;
|
||||
|
||||
/*
|
||||
* The vvp_ipoint_t is an integral type that is 32bits. The low 2 bits
|
||||
|
|
@ -45,11 +44,25 @@ typedef const unsigned char*vvp_truth_t;
|
|||
* 1'b1 : 01
|
||||
* 1'bx : 10
|
||||
* 1'bz : 11
|
||||
*
|
||||
* The function of the functor is defined by the table/event
|
||||
* union. Normally, the truth table is the behavior and the functor
|
||||
* output value is picked from the lookup table that the table pointer
|
||||
* points to.
|
||||
*
|
||||
* If the functor is an event functor, however, the event member
|
||||
* points to an extended structure where thread state is stored.
|
||||
*
|
||||
* The major mode is selected by the mode parameter.
|
||||
*/
|
||||
|
||||
struct functor_s {
|
||||
/* This is the truth table for the device */
|
||||
union {
|
||||
vvp_truth_t table;
|
||||
vvp_event_t event;
|
||||
};
|
||||
|
||||
/* This is the output for the device. */
|
||||
vvp_ipoint_t out;
|
||||
/* These are the input ports. */
|
||||
|
|
@ -57,10 +70,26 @@ struct functor_s {
|
|||
/* These are the input values. */
|
||||
unsigned char ival;
|
||||
unsigned char oval;
|
||||
/* functor mode: 0 == table ; 1 == event */
|
||||
unsigned char mode;
|
||||
};
|
||||
|
||||
typedef struct functor_s *functor_t;
|
||||
|
||||
/*
|
||||
* If functor mode is 1, the event member is valid and the vvp_event_s
|
||||
* points to the extended event information.
|
||||
*/
|
||||
extern const unsigned char vvp_edge_posedge[16];
|
||||
extern const unsigned char vvp_edge_negedge[16];
|
||||
extern const unsigned char vvp_edge_anyedge[16];
|
||||
|
||||
struct vvp_event_s {
|
||||
vthread_t threads;
|
||||
unsigned char ival;
|
||||
const unsigned char*vvp_edge_tab;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the functors address space. This function must be called
|
||||
* exactly once before any of the other functor functions may be
|
||||
|
|
@ -115,6 +144,9 @@ extern const unsigned char ft_var[];
|
|||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.6 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.5 2001/03/25 19:38:23 steve
|
||||
* Support NOR and NOT gates.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.8 2001/03/25 19:36:45 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.9 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
|
||||
/* These are some keywords that are recognized. */
|
||||
".event" { return K_EVENT; }
|
||||
".functor" { return K_FUNCTOR; }
|
||||
".net" { return K_NET; }
|
||||
".scope" { return K_SCOPE; }
|
||||
|
|
@ -104,6 +105,9 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.9 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.8 2001/03/25 19:36:45 steve
|
||||
* Accept <> characters in labels and symbols.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: opcodes.txt,v 1.5 2001/03/22 05:08:00 steve Exp $
|
||||
* $Id: opcodes.txt,v 1.6 2001/03/26 04:00:39 steve Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ declared using VPI. The operands are compiled down to a vpiHandle for
|
|||
the call. The instruction contains only the vpiHandle for the
|
||||
call. See the vpi.txt file for more on system task/function calls.
|
||||
|
||||
* %waitfor <functor-label>
|
||||
* %wait <functor-label>
|
||||
|
||||
When a thread executes this instruction, it places itself in the
|
||||
sensitive list for the addressed functor. The functor holds all the
|
||||
|
|
|
|||
15
vvp/parse.y
15
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.12 2001/03/25 00:35:35 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.13 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -49,7 +49,7 @@ extern FILE*yyin;
|
|||
};
|
||||
|
||||
|
||||
%token K_FUNCTOR K_NET K_SCOPE K_THREAD K_VAR K_vpi_call
|
||||
%token K_EVENT K_FUNCTOR K_NET K_SCOPE K_THREAD K_VAR K_vpi_call
|
||||
%token K_vpi_module
|
||||
|
||||
%token <text> T_INSTR
|
||||
|
|
@ -106,6 +106,14 @@ statement
|
|||
| T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';'
|
||||
{ compile_functor($1, $3, $5, 0, 0); }
|
||||
|
||||
/* Event statements take a label, a type (the first T_SYMBOL) and a
|
||||
list of inputs. */
|
||||
|
||||
| T_LABEL K_EVENT T_SYMBOL ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_event($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
/* Instructions may have a label, and have zero or more
|
||||
operands. The meaning of and restrictions on the operands depends
|
||||
on the specific instruction. */
|
||||
|
|
@ -295,6 +303,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.13 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.12 2001/03/25 00:35:35 steve
|
||||
* Add the .net statement.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.2 2001/03/20 06:16:24 steve Exp $"
|
||||
#ident "$Id: pointers.h,v 1.3 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -77,8 +77,26 @@ inline unsigned ipoint_port(vvp_ipoint_t func)
|
|||
|
||||
typedef unsigned vvp_cpoint_t;
|
||||
|
||||
/*
|
||||
* The truth table that functors point to are addressed with this
|
||||
* typedef.
|
||||
*/
|
||||
typedef const unsigned char*vvp_truth_t;
|
||||
|
||||
/*
|
||||
* The functor event mode uses a pointer of this type to point to the
|
||||
* extended event data.
|
||||
*/
|
||||
typedef struct vvp_event_s *vvp_event_t;
|
||||
|
||||
|
||||
typedef struct vthread_s*vthread_t;
|
||||
|
||||
/*
|
||||
* $Log: pointers.h,v $
|
||||
* Revision 1.3 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.2 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.11 2001/03/25 03:54:26 steve Exp $"
|
||||
#ident "$Id: vthread.cc,v 1.12 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vthread.h"
|
||||
|
|
@ -34,6 +34,8 @@ struct vthread_s {
|
|||
unsigned long pc;
|
||||
unsigned char *bits;
|
||||
unsigned short nbits;
|
||||
/* This is used for keeping wait queues. */
|
||||
struct vthread_s*next;
|
||||
};
|
||||
|
||||
static void thr_check_addr(struct vthread_s*thr, unsigned addr)
|
||||
|
|
@ -76,6 +78,7 @@ vthread_t v_newthread(unsigned long pc)
|
|||
thr->pc = pc;
|
||||
thr->bits = (unsigned char*)malloc(16);
|
||||
thr->nbits = 16*4;
|
||||
thr->next = 0;
|
||||
|
||||
thr_put_bit(thr, 0, 0);
|
||||
thr_put_bit(thr, 1, 1);
|
||||
|
|
@ -106,6 +109,15 @@ void vthread_run(vthread_t thr)
|
|||
}
|
||||
}
|
||||
|
||||
void vthread_schedule_list(vthread_t thr)
|
||||
{
|
||||
while (thr) {
|
||||
vthread_t tmp = thr;
|
||||
thr = thr->next;
|
||||
schedule_vthread(tmp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool of_ASSIGN(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx2);
|
||||
|
|
@ -249,8 +261,26 @@ bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
|
|||
return schedule_finished()? false : true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the wait by locating the functor for the event, and
|
||||
* adding this thread to the threads list for the event.
|
||||
*/
|
||||
bool of_WAIT(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
functor_t fp = functor_index(cp->iptr);
|
||||
assert(fp->mode == 1);
|
||||
vvp_event_t ep = fp->event;
|
||||
thr->next = ep->threads;
|
||||
ep->threads = thr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.12 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.11 2001/03/25 03:54:26 steve
|
||||
* Add JMP0XZ and postpone net inputs when needed.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.1 2001/03/11 00:29:39 steve Exp $"
|
||||
#ident "$Id: vthread.h,v 1.2 2001/03/26 04:00:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -48,8 +48,19 @@ extern vthread_t v_newthread(unsigned long sa);
|
|||
*/
|
||||
extern void vthread_run(vthread_t thr);
|
||||
|
||||
/*
|
||||
* This function schedules all the threads in the list to be scheduled
|
||||
* for execution with delay 0. the thr pointer is taken to be the head
|
||||
* of a list.
|
||||
*/
|
||||
extern void vthread_schedule_list(vthread_t thr);
|
||||
|
||||
|
||||
/*
|
||||
* $Log: vthread.h,v $
|
||||
* Revision 1.2 2001/03/26 04:00:39 steve
|
||||
* Add the .event statement and the %wait instruction.
|
||||
*
|
||||
* Revision 1.1 2001/03/11 00:29:39 steve
|
||||
* Add the vvp engine to cvs.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue