Add fork and join instructions.

This commit is contained in:
steve 2001-03-30 04:55:22 +00:00
parent f6eb581aff
commit 386958f9a0
6 changed files with 160 additions and 10 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.10 2001/03/29 03:46:36 steve Exp $
* $Id: README.txt,v 1.11 2001/03/30 04:55:22 steve Exp $
*/
VVP SIMULATION ENGINE
@ -29,7 +29,7 @@ semicolon that terminates a statement. Like so:
The semicolon is required, whether the comment is there or not.
Statements may span multiple lines, as long as there is no text (other
then the first character of a label) in the first column of hte
then the first character of a label) in the first column of the
continuation line.
HEADER SYNTAX
@ -54,7 +54,7 @@ Labels and symbols consist of the characters:
a-z
A-Z
0-9
.$_
.$_<>
Labels and symbols may not start with a digit or a '.', so that they
are easily distinguished from keywords and numbers. A Label is a
@ -229,6 +229,25 @@ This statement creates a thread with a starting address at the
instruction given by <symbol>.
THREADS IN GENERAL:
Thread statements create the initial threads of a design. These
include the ``initial'' and ``always'' statements of the original
Verilog, and possibly some other synthetic threads for various
purposes. It is also possible to create transient threads from
behavioral code. These are needed to support such constructs as
fork/join, named blocks and task activation.
A transient thread is created with a %fork instruction. When a
transient thread is created this way, the operand to the %fork gives
the starting address, and the new thread is said to be a child of the
forking thread. The children of a thread are pushed onto a stack of
children.
A transient thread is reaped with a %join instruction. %join waits for
the top thread in the stack of children to complete, then
continues. It is an error to %join when there are no children.
TRUTH TABLES
The logic that a functor represents is expressed as a truth table. The
@ -425,6 +444,17 @@ becomes:
a .var "a", 0, 0;
* named events
Events in general are implemented as functors, but named events in
partinular have no inputs and only the event output. The way to
generate code for these is like so:
a .event "name";
This creates a functor and makes it into a mode-2 functor. Then the
trigger statement, "-> a", cause a ``%set a, 0;'' statement be
generated. This is sufficient to trigger the event.
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)

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.7 2001/03/26 04:00:39 steve Exp $"
#ident "$Id: codes.h,v 1.8 2001/03/30 04:55:22 steve Exp $"
#endif
@ -39,10 +39,12 @@ extern bool of_ASSIGN(vthread_t thr, vvp_code_t code);
extern bool of_CMPU(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_FORK(vthread_t thr, vvp_code_t code);
extern bool of_INV(vthread_t thr, vvp_code_t code);
extern bool of_JMP(vthread_t thr, vvp_code_t code);
extern bool of_JMP0(vthread_t thr, vvp_code_t code);
extern bool of_JMP0XZ(vthread_t thr, vvp_code_t code);
extern bool of_JOIN(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);
@ -93,6 +95,9 @@ extern void codespace_dump(FILE*fd);
/*
* $Log: codes.h,v $
* Revision 1.8 2001/03/30 04:55:22 steve
* Add fork and join instructions.
*
* Revision 1.7 2001/03/26 04:00:39 steve
* Add the .event statement and the %wait instruction.
*

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.18 2001/03/29 03:46:36 steve Exp $"
#ident "$Id: compile.cc,v 1.19 2001/03/30 04:55:22 steve Exp $"
#endif
# include "compile.h"
@ -69,10 +69,12 @@ const static struct opcode_table_s opcode_table[] = {
{ "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%fork", of_FORK, 1, {OA_CODE_PTR, OA_NONE, OA_NONE} },
{ "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%jmp", of_JMP, 1, {OA_CODE_PTR, OA_NONE, OA_NONE} },
{ "%jmp/0", of_JMP0, 2, {OA_CODE_PTR, OA_BIT1, OA_NONE} },
{ "%jmp/0xz",of_JMP0XZ, 2, {OA_CODE_PTR, OA_BIT1, OA_NONE} },
{ "%join", of_JOIN, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%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} },
@ -685,6 +687,9 @@ void compile_dump(FILE*fd)
/*
* $Log: compile.cc,v $
* Revision 1.19 2001/03/30 04:55:22 steve
* Add fork and join instructions.
*
* Revision 1.18 2001/03/29 03:46:36 steve
* Support named events as mode 2 functors.
*

33
vvp/examples/fork.vvp Normal file
View File

@ -0,0 +1,33 @@
: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 sample demonstrates the behavior of %fork and %join.
S_main .scope "main";
child %vpi_call "$display", "I'm a child";
%end;
parent %fork child;
%vpi_call "$display", "I'm a parent";
%join;
%vpi_call "$display", "reaped";
%end;
.thread parent;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: opcodes.txt,v 1.6 2001/03/26 04:00:39 steve Exp $
* $Id: opcodes.txt,v 1.7 2001/03/30 04:55:22 steve Exp $
*/
@ -9,7 +9,9 @@
EXECUTABLE INSTRUCTION OPCODES
Instruction opcodes all start with a % character and have 0 or more
operands. In no case are there more then 3 operands.
operands. In no case are there more then 3 operands. This chapter
describes the specific behavior of each opcode, in hopefully enough
detail that its complete effect can be predicted.
* %assign <var-label>, <delay>, <bit>
@ -68,9 +70,29 @@ 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.
* %fork <code-label>
This instruction is similar to %jmp, except that it creates a new
thread to start executing at the specified address. The new thread is
created and pushed onto the child stack. It is also marked runnable,
but is not necessarily started until the current thread yields.
The %fork instruction has no effect other then to push a child thread.
See also %join.
* %inv <bit>, <wid>
Perform a bitwise invert of the vector starting at <bit>.
Perform a bitwise invert of the vector starting at <bit>. The result
replaces the input. Invert means the following, independently for each
bit:
0 --> 1
1 --> 0
x --> x
z --> x
* %jmp <code-label>
@ -87,6 +109,21 @@ values in the part after the /, the jump is taken. For example:
will jump to T_label if bit 8 is x or z.
* %join
This is the partner to %fork. This instruction causes the thread to
wait for the top thread in the child stack to terminate, then
continues. It has no effect in the current thread other then to wait
until the top child is cleared.
It is an error to execute %join if there are no children in the child
stack. If a child thread terminates before this instruction is called,
it remains in the stack as a zombie until the %join reaps it.
If a thread terminates (i.e. executes %end) all its children are
terminated as well.
* %load <bit>, <functor-label>
This instruction loads a value from the given functor output into the

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.13 2001/03/29 03:46:36 steve Exp $"
#ident "$Id: vthread.cc,v 1.14 2001/03/30 04:55:22 steve Exp $"
#endif
# include "vthread.h"
@ -34,6 +34,10 @@ struct vthread_s {
unsigned long pc;
unsigned char *bits;
unsigned short nbits;
/* This points to the top (youngest) child of the thread. */
struct vthread_s*child;
/* This is set if the parent is waiting for me to end. */
struct vthread_s*reaper;
/* This is used for keeping wait queues. */
struct vthread_s*next;
};
@ -78,6 +82,8 @@ vthread_t v_newthread(unsigned long pc)
thr->pc = pc;
thr->bits = (unsigned char*)malloc(16);
thr->nbits = 16*4;
thr->child = 0;
thr->reaper = 0;
thr->next = 0;
thr_put_bit(thr, 0, 0);
@ -87,6 +93,13 @@ vthread_t v_newthread(unsigned long pc)
return thr;
}
static void vthread_reap(vthread_t thr)
{
assert(thr->next == 0);
assert(thr->child == 0);
free(thr);
}
/*
* This function runs a thread by fetching an instruction,
@ -169,10 +182,21 @@ bool of_DELAY(vthread_t thr, vvp_code_t cp)
bool of_END(vthread_t thr, vvp_code_t cp)
{
//printf("thread %p: %%end\n", thr);
if (thr->reaper)
schedule_vthread(thr->reaper, 0);
thr->reaper = thr;
return false;
}
bool of_FORK(vthread_t thr, vvp_code_t cp)
{
vthread_t child = v_newthread(cp->cptr);
child->child = thr->child;
thr->child = child;
schedule_vthread(child, 0);
return true;
}
bool of_INV(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx1 >= 4);
@ -214,6 +238,19 @@ bool of_JMP0XZ(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_JOIN(vthread_t thr, vvp_code_t cp)
{
assert(thr->child);
if (thr->child->reaper == thr->child) {
vthread_reap(thr->child);
return true;
}
assert(thr->child->reaper == 0);
thr->child->reaper = thr;
return false;
}
bool of_LOAD(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx1 >= 4);
@ -278,6 +315,9 @@ bool of_WAIT(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.14 2001/03/30 04:55:22 steve
* Add fork and join instructions.
*
* Revision 1.13 2001/03/29 03:46:36 steve
* Support named events as mode 2 functors.
*