Add the .event statement and the %wait instruction.

This commit is contained in:
steve 2001-03-26 04:00:39 +00:00
parent f7f5ccce05
commit 79ce94b585
13 changed files with 352 additions and 25 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * 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 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. 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:
Thread statements create the initial threads for a simulation. These Thread statements create the initial threads for a simulation. These

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #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_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_MOV(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_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_NOOP(vthread_t thr, vvp_code_t code);
extern bool of_VPI_CALL(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 $ * $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 * Revision 1.6 2001/03/25 03:54:26 steve
* Add JMP0XZ and postpone net inputs when needed. * Add JMP0XZ and postpone net inputs when needed.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "compile.h" # 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} }, { "%load", of_LOAD, 2, {OA_BIT1, OA_FUNC_PTR, OA_NONE} },
{ "%mov", of_MOV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%mov", of_MOV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%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} } { 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->ival = init;
obj->oval = 2; obj->oval = 2;
obj->mode = 0;
if (strcmp(type, "OR") == 0) { if (strcmp(type, "OR") == 0) {
obj->table = ft_OR; obj->table = ft_OR;
@ -248,6 +250,71 @@ void compile_functor(char*label, char*type, unsigned init,
free(type); 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 * 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 * 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->table = ft_var;
obj->ival = 0x22; obj->ival = 0x22;
obj->oval = 0x02; obj->oval = 0x02;
obj->mode = 0;
} }
/* Make the vpiHandle for the reg. */ /* 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->table = ft_var;
obj->ival = 0x22; obj->ival = 0x22;
obj->oval = 0x02; obj->oval = 0x02;
obj->mode = 0;
} }
assert(argc == wid); assert(argc == wid);
@ -593,6 +662,9 @@ void compile_dump(FILE*fd)
/* /*
* $Log: compile.cc,v $ * $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 * Revision 1.15 2001/03/25 19:38:23 steve
* Support NOR and NOT gates. * Support NOR and NOT gates.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include <stdio.h> # 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 void compile_vpi_symbol(const char*label, vpiHandle obj);
extern vpiHandle compile_vpi_lookup(const char*label); 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 * 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, * 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 $ * $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 * Revision 1.10 2001/03/25 00:35:35 steve
* Add the .net statement. * Add the .net statement.
* *

52
vvp/examples/edge.vvp Normal file
View File

@ -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;

View File

@ -17,11 +17,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "functor.h" # include "functor.h"
# include "schedule.h" # include "schedule.h"
# include "vthread.h"
# include <assert.h> # include <assert.h>
/* /*
@ -131,6 +132,63 @@ functor_t functor_index(vvp_ipoint_t point)
return functor_table[point]->table[index1]->table + index0; 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 * Set the addressed bit of the functor, and recalculate the
* output. If the output changes any, then generate the necessary * 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]; unsigned char mask = mask_table[pp];
fp->ival = (fp->ival & mask) | (bit << (2*pp)); fp->ival = (fp->ival & mask) | (bit << (2*pp));
/* Locate the new output value in the table. */ switch (fp->mode) {
unsigned char out = fp->table[fp->ival >> 2]; case 0:
out >>= 2 * (fp->ival&0x03); functor_set_mode0(ptr, fp);
out &= 0x03; break;
case 1:
/* If the output changes, then create a propagation event. */ functor_set_mode1(fp);
if (out != fp->oval) { break;
fp->oval = out;
schedule_functor(ptr, 0);
} }
} }
@ -226,6 +282,9 @@ const unsigned char ft_var[16] = {
/* /*
* $Log: functor.cc,v $ * $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 * Revision 1.6 2001/03/25 00:35:35 steve
* Add the .net statement. * Add the .net statement.
* *

View File

@ -19,13 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "pointers.h" # include "pointers.h"
# include <stdio.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 * 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'b1 : 01
* 1'bx : 10 * 1'bx : 10
* 1'bz : 11 * 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 { struct functor_s {
/* This is the truth table for the device */ /* This is the truth table for the device */
union {
vvp_truth_t table; vvp_truth_t table;
vvp_event_t event;
};
/* This is the output for the device. */ /* This is the output for the device. */
vvp_ipoint_t out; vvp_ipoint_t out;
/* These are the input ports. */ /* These are the input ports. */
@ -57,10 +70,26 @@ struct functor_s {
/* These are the input values. */ /* These are the input values. */
unsigned char ival; unsigned char ival;
unsigned char oval; unsigned char oval;
/* functor mode: 0 == table ; 1 == event */
unsigned char mode;
}; };
typedef struct functor_s *functor_t; 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 * Initialize the functors address space. This function must be called
* exactly once before any of the other functor functions may be * 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 $ * $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 * Revision 1.5 2001/03/25 19:38:23 steve
* Support NOR and NOT gates. * Support NOR and NOT gates.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -48,6 +48,7 @@
/* These are some keywords that are recognized. */ /* These are some keywords that are recognized. */
".event" { return K_EVENT; }
".functor" { return K_FUNCTOR; } ".functor" { return K_FUNCTOR; }
".net" { return K_NET; } ".net" { return K_NET; }
".scope" { return K_SCOPE; } ".scope" { return K_SCOPE; }
@ -104,6 +105,9 @@ int yywrap()
/* /*
* $Log: lexor.lex,v $ * $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 * Revision 1.8 2001/03/25 19:36:45 steve
* Accept <> characters in labels and symbols. * Accept <> characters in labels and symbols.
* *

View File

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * 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 the call. The instruction contains only the vpiHandle for the
call. See the vpi.txt file for more on system task/function calls. 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 When a thread executes this instruction, it places itself in the
sensitive list for the addressed functor. The functor holds all the sensitive list for the addressed functor. The functor holds all the

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "parse_misc.h" # 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 K_vpi_module
%token <text> T_INSTR %token <text> T_INSTR
@ -106,6 +106,14 @@ statement
| T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';' | T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';'
{ compile_functor($1, $3, $5, 0, 0); } { 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 /* Instructions may have a label, and have zero or more
operands. The meaning of and restrictions on the operands depends operands. The meaning of and restrictions on the operands depends
on the specific instruction. */ on the specific instruction. */
@ -295,6 +303,9 @@ int compile_design(const char*path)
/* /*
* $Log: parse.y,v $ * $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 * Revision 1.12 2001/03/25 00:35:35 steve
* Add the .net statement. * Add the .net statement.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -77,8 +77,26 @@ inline unsigned ipoint_port(vvp_ipoint_t func)
typedef unsigned vvp_cpoint_t; 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 $ * $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 * Revision 1.2 2001/03/20 06:16:24 steve
* Add support for variable vectors. * Add support for variable vectors.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
# include "vthread.h" # include "vthread.h"
@ -34,6 +34,8 @@ struct vthread_s {
unsigned long pc; unsigned long pc;
unsigned char *bits; unsigned char *bits;
unsigned short nbits; 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) 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->pc = pc;
thr->bits = (unsigned char*)malloc(16); thr->bits = (unsigned char*)malloc(16);
thr->nbits = 16*4; thr->nbits = 16*4;
thr->next = 0;
thr_put_bit(thr, 0, 0); thr_put_bit(thr, 0, 0);
thr_put_bit(thr, 1, 1); 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) bool of_ASSIGN(vthread_t thr, vvp_code_t cp)
{ {
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx2); 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; 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 $ * $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 * Revision 1.11 2001/03/25 03:54:26 steve
* Add JMP0XZ and postpone net inputs when needed. * Add JMP0XZ and postpone net inputs when needed.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #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 #endif
/* /*
@ -48,8 +48,19 @@ extern vthread_t v_newthread(unsigned long sa);
*/ */
extern void vthread_run(vthread_t thr); 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 $ * $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 * Revision 1.1 2001/03/11 00:29:39 steve
* Add the vvp engine to cvs. * Add the vvp engine to cvs.
* *