implement %load, %inv, %jum/0 and %cmp/u

This commit is contained in:
steve 2001-03-22 05:08:00 +00:00
parent 565088160e
commit aacce5ef1b
8 changed files with 298 additions and 23 deletions

View File

@ -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.3 2001/03/20 06:16:23 steve Exp $"
#ident "$Id: codes.cc,v 1.4 2001/03/22 05:08:00 steve Exp $"
#endif
# include "codes.h"
@ -94,11 +94,11 @@ void codespace_dump(FILE*fd)
vvp_code_t cop = codespace_index(idx);
if (cop->opcode == &of_ASSIGN) {
fprintf(fd, "%%assign 0x%u, %lu, %u\n",
fprintf(fd, "%%assign 0x%u, %u, %u\n",
cop->iptr, cop->bit_idx1, cop->bit_idx2);
} else if (cop->opcode == &of_DELAY) {
fprintf(fd, "%%delay %lu\n", cop->number);
fprintf(fd, "%%delay %lu\n", (unsigned long)cop->number);
} else if (cop->opcode == &of_END) {
fprintf(fd, "%%end\n");
@ -107,8 +107,7 @@ void codespace_dump(FILE*fd)
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);
fprintf(fd, "%%set 0x%u, %u\n", cop->iptr, cop->bit_idx1);
} else {
fprintf(fd, "opcode %p\n", cop->opcode);
@ -119,6 +118,9 @@ void codespace_dump(FILE*fd)
/*
* $Log: codes.cc,v $
* Revision 1.4 2001/03/22 05:08:00 steve
* implement %load, %inv, %jum/0 and %cmp/u
*
* Revision 1.3 2001/03/20 06:16:23 steve
* Add support for variable vectors.
*

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.4 2001/03/20 06:16:24 steve Exp $"
#ident "$Id: codes.h,v 1.5 2001/03/22 05:08:00 steve Exp $"
#endif
@ -36,9 +36,14 @@ typedef bool (*vvp_code_fun)(vthread_t thr, vvp_code_t code);
* access to the thread context.
*/
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_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_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_NOOP(vthread_t thr, vvp_code_t code);
extern bool of_VPI_CALL(vthread_t thr, vvp_code_t code);
@ -86,6 +91,9 @@ extern void codespace_dump(FILE*fd);
/*
* $Log: codes.h,v $
* Revision 1.5 2001/03/22 05:08:00 steve
* implement %load, %inv, %jum/0 and %cmp/u
*
* Revision 1.4 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*

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.8 2001/03/21 05:13:03 steve Exp $"
#ident "$Id: compile.cc,v 1.9 2001/03/22 05:08:00 steve Exp $"
#endif
# include "compile.h"
@ -63,11 +63,16 @@ struct opcode_table_s {
};
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} },
{ "%assign", of_ASSIGN, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%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} },
{ "%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} },
{ "%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} },
{ 0, of_NOOP, 0, {OA_NONE, OA_NONE, OA_NONE} }
};
@ -471,6 +476,9 @@ void compile_dump(FILE*fd)
/*
* $Log: compile.cc,v $
* Revision 1.9 2001/03/22 05:08:00 steve
* implement %load, %inv, %jum/0 and %cmp/u
*
* Revision 1.8 2001/03/21 05:13:03 steve
* Allow var objects as vpiHandle arguments to %vpi_call.
*

View File

@ -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.3 2001/03/20 06:16:24 steve Exp $"
#ident "$Id: functor.cc,v 1.4 2001/03/22 05:08:00 steve Exp $"
#endif
# include "functor.h"
@ -160,6 +160,13 @@ void functor_set(vvp_ipoint_t ptr, unsigned bit)
}
}
unsigned functor_get(vvp_ipoint_t ptr)
{
functor_t fp = functor_index(ptr);
assert(fp);
return fp->oval & 3;
}
/*
* This function is used by the scheduler to implement the propagation
* event. The input is the pointer to the functor who's output is to
@ -219,6 +226,9 @@ const unsigned char ft_var[16] = {
/*
* $Log: functor.cc,v $
* Revision 1.4 2001/03/22 05:08:00 steve
* implement %load, %inv, %jum/0 and %cmp/u
*
* Revision 1.3 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*

View File

@ -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.3 2001/03/20 06:16:24 steve Exp $"
#ident "$Id: functor.h,v 1.4 2001/03/22 05:08:00 steve Exp $"
#endif
# include "pointers.h"
@ -85,6 +85,8 @@ extern vvp_ipoint_t functor_allocate(unsigned wid);
*/
extern void functor_set(vvp_ipoint_t point, unsigned val);
extern unsigned functor_get(vvp_ipoint_t ptr);
/*
* When a propagation event happens, this function is called with the
* address of the affected functor. It propagates the output to all
@ -111,6 +113,9 @@ extern const unsigned char ft_var[];
/*
* $Log: functor.h,v $
* Revision 1.4 2001/03/22 05:08:00 steve
* implement %load, %inv, %jum/0 and %cmp/u
*
* Revision 1.3 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*

View File

@ -1,3 +1,10 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: opcodes.txt,v 1.5 2001/03/22 05:08:00 steve Exp $
*/
EXECUTABLE INSTRUCTION OPCODES
@ -13,6 +20,46 @@ the assignment takes place. The delay may be 0. For blocking
assignments, see %set. The <bit> is the address of the thread register
that contains the bit value to assign.
* %cmp/u <bit-l>, <bit-r>, <wid>
* %cmp/s <bit-l>, <bit-r>, <wid>
These instructions perform a generic comparison of two vectors of equal
size. The <bit-l> and <bit-r> numbers address the least-significant
bit of each vector, and <wid> is the width. If either operator is 0,
1, 2 or 3 then it is taken to be a constant replicated to the selected
width.
The results of the comparison go into bits 4, 5, 6 and 7:
4: eq (equal)
5: lt (less than)
6: eeq (case equal)
The eeq bit is set to 1 if all the bits in the vectors are exactly the
same, or 0 otherwise. The eq bit is true if the values are logically
the same. That is, x and z are considered equal. In other words the eq
bit is the same as ``=='' and the eeq bit ``===''.
The lt bit is 1 if the left vector is less then the right vector, or 0
if greater then or equal to the right vector. It is the equivilent of
the Verilog < operator. Combinations of these three bits can be used
to implement all the Verilog comparison operators.
The %cmp/u and %cmp/s differ only in the handling of the lt bit. The
%cmp/u does an unsigned compare, whereas the %cmp/s does a signed
compare.
* %cmp/z <bit-l>, <bit-r>, <wid>
* %cmp/x <bit-l>, <bit-r>, <wid>
These instructions are for implementing the casez and casex
comparisons. These work similar to the %cmp/u instructions, except
only an eq bit is calculated. These comparisons both treat z values in
the left or right operand as don't care positions. The %cmp/x
instruction will also treat x values in either operand as don't care.
Only bit 4 is set by these instructions.
* %delay <delay>
This opcode pauses the thread, and causes it to be rescheduled for a
@ -21,16 +68,38 @@ 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.
* %inv <bit>, <wid>
Perform a bitwise invert of the vector starting at <bit>.
* %jmp <code-label>
The %jmp instruction performs an unconditional branch to a given
location. The parameter is the label of the destination instruction.
* %jmp/[01xz] <code-label>, <bit>
This is a conditional version of the %jmp instruction. In this case,
a single bit (addressed by <bit>) is tested. If it is one of the
values in the part after the /, the jump is taken. For example:
%jmp/xz T_label, 8;
will jump to T_label if bit 8 is x or z.
* %load <bit>, <functor-label>
This instruction loads a value from the given functor output into the
specified thread register bit.
* %mov <dst>, <src>, <wid>
This instruction copies a vector from one place in register space to
another. The destination and source vectors are assumed to be the same
width and non-overlapping. The <dst> may not be 0-3, but if the <src>
is one of the 4 constant bits, the effect is to replicate the value
into the destination vector. Useful for filling a vector.
* %set <var-label>, <bit>
This sets a bit of a variable, and is used to implement blocking
@ -53,3 +122,22 @@ sensitive list for the addressed functor. The functor holds all the
threads that await the functor. When the defined sort of event occurs
on the functor, a thread schedule event is created for all the threads
in its list and the list is cleared.
/*
* 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
*/

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.6 2001/03/20 06:16:24 steve Exp $"
#ident "$Id: vthread.cc,v 1.7 2001/03/22 05:08:00 steve Exp $"
#endif
# include "vthread.h"
@ -25,13 +25,35 @@
# include "schedule.h"
# include "functor.h"
# include "vpi_priv.h"
# include <malloc.h>
# include <assert.h>
struct vthread_s {
/* This is the program counter. */
unsigned long pc;
unsigned char *bits;
unsigned short nbits;
};
static inline unsigned thr_get_bit(struct vthread_s*thr, unsigned addr)
{
assert(addr < thr->nbits);
unsigned idx = addr % 4;
addr /= 4;
return (thr->bits[addr] >> (idx*2)) & 3;
}
static inline void thr_put_bit(struct vthread_s*thr,
unsigned addr, unsigned val)
{
assert(addr < thr->nbits);
unsigned idx = addr % 4;
addr /= 4;
unsigned mask = 3 << (idx*2);
thr->bits[addr] = (thr->bits[addr] & ~mask) | (val << (idx*2));
}
/*
* Create a new thread with the given start address.
*/
@ -39,7 +61,13 @@ vthread_t v_newthread(unsigned long pc)
{
vthread_t thr = new struct vthread_s;
thr->pc = pc;
thr->bits = (unsigned char*)malloc(16);
thr->nbits = 16*4;
thr_put_bit(thr, 0, 0);
thr_put_bit(thr, 1, 1);
thr_put_bit(thr, 2, 2);
thr_put_bit(thr, 3, 3);
return thr;
}
@ -81,6 +109,31 @@ bool of_ASSIGN(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_CMPU(vthread_t thr, vvp_code_t cp)
{
unsigned eq = 1;
unsigned eeq = 1;
unsigned lt = 2;
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
unsigned lv = thr_get_bit(thr, cp->bit_idx1+idx);
unsigned rv = thr_get_bit(thr, cp->bit_idx2+idx);
if (lv != rv)
eeq = 0;
if ((lv == 0) && (rv != 0))
eq = 0;
if ((lv == 1) && (rv != 1))
eq = 0;
}
thr_put_bit(thr, 4, eq);
thr_put_bit(thr, 5, lt);
thr_put_bit(thr, 6, eeq);
return true;
}
bool of_DELAY(vthread_t thr, vvp_code_t cp)
{
//printf("thread %p: %%delay %lu\n", thr, cp->number);
@ -94,12 +147,67 @@ bool of_END(vthread_t thr, vvp_code_t cp)
return false;
}
bool of_INV(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx1 >= 4);
for (unsigned idx = 0 ; idx < cp->bit_idx2 ; idx += 1) {
unsigned val = thr_get_bit(thr, cp->bit_idx1+idx);
switch (val) {
case 0:
val = 1;
break;
case 1:
val = 0;
break;
default:
val = 2;
break;
}
thr_put_bit(thr, cp->bit_idx1+idx, val);
}
return true;
}
bool of_JMP(vthread_t thr, vvp_code_t cp)
{
thr->pc = cp->cptr;
return true;
}
bool of_JMP0(vthread_t thr, vvp_code_t cp)
{
if (thr_get_bit(thr, cp->bit_idx1) == 0)
thr->pc = cp->cptr;
return true;
}
bool of_LOAD(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx1 >= 4);
thr_put_bit(thr, cp->bit_idx1, functor_get(cp->iptr));
return true;
}
bool of_MOV(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx1 >= 4);
if (cp->bit_idx2 >= 4) {
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
thr_put_bit(thr,
cp->bit_idx1+idx,
thr_get_bit(thr, cp->bit_idx2+idx));
} else {
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
thr_put_bit(thr,
cp->bit_idx1+idx,
thr_get_bit(thr, cp->bit_idx2));
}
return true;
}
bool of_NOOP(vthread_t thr, vvp_code_t cp)
{
return true;
@ -131,6 +239,9 @@ bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.7 2001/03/22 05:08:00 steve
* implement %load, %inv, %jum/0 and %cmp/u
*
* Revision 1.6 2001/03/20 06:16:24 steve
* Add support for variable vectors.
*

View File

@ -1,17 +1,60 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: vthread.txt,v 1.2 2001/03/22 05:08:00 steve Exp $
*/
THREAD DETAILS
Thread objects in vvp are created by ``.thread'' statements in the
input source file. These cause
input source file.
A thread object includes a program counter and private bit
registers. The program counter is used to step the processor through
the code space as it executes instructions. The bit registers are for
use by the arithmetic operators as they operate.
the code space as it executes instructions. The bit registers each
hold Verilog-style 4-value bits and are for use by the arithmetic
operators as they operate.
The program counter normally increments by one instruction after the
instruction is fetched. If the instruction is a branching instruction,
then the execution of the instruction sets a new value for the pc.
Instructions that use the bit registers have as an operand a <bit>
value. There is space in the instruction for 2 <bit> operands. The
special values 0, 1, 2 and 3 are special constant bits 0, 1, x and z
and are used as immediate values for instructions that take single-bit
values. The remaining of 64K possible <bit> values are read-write bit
registers that can be accessed singly or as vectors.
value. There is usually space in the instruction for 2 <bit>
operands. Instructions that work on vectors pull the vector values
from the bit registers starting with the LSB and up.
The bit addresses 0, 1, 2 and 3 are special constant bits 0, 1, x and
z, and are used as read-only immediate values. If the instruction
takes a single bit operand, the the appropriate value is simply read
out. If the instruction expects a vector, then a vector of the
expected width is created by replicating the constant value.
Bits 4, 5, 6 and 7 are read/write bits but are reserved by many
instructions for special purposes. Comparison operators, for example,
use these as comparison flag bits.
The remaining 64K-8 possible <bit> values are read-write bit registers
that can be accessed singly or as vectors. This obviously implies that
a bit address is 16 bits.
/*
* 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
*/