Add fork and join instructions.
This commit is contained in:
parent
f6eb581aff
commit
386958f9a0
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue