Document memory related opcodes,

parser uses numbv_s structures instead of the
 symbv_s and a mess of unions,
 Add the %is/sub instruction.
       (Stephan Boettcher)
This commit is contained in:
steve 2001-05-02 23:16:50 +00:00
parent 0f9eb13245
commit a225fe304d
8 changed files with 132 additions and 68 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.22 2001/05/02 04:05:17 steve Exp $
* $Id: README.txt,v 1.23 2001/05/02 23:16:50 steve Exp $
*/
VVP SIMULATION ENGINE
@ -170,10 +170,6 @@ A UDP functor instance is created so:
Where <label> identifies the functor, <type> is the label of a UDP
defined earlier, and <symbol_list> is a list of symbols, one for each
input of the UDP.
ATTN: The "<name>" attribute of the UDP is pretty useless, and may go
away in future versions. It may be useful for diagnostic messages,
though.
VARIABLE STATEMENTS:
@ -334,18 +330,15 @@ initializes four memory bits. Two bits form each byte for each memory
bit, in the ususal encoding.
Procedural access to the memory employs an index register to address a
bit location in the mememory, via the commands:
bit location in the memory, via the commands:
%load/mem <bit>, <memid>[<ix>] ;
%set/mem <memid>[<ix>], <bit> ;
%assign/mem <memid>[<ix>], <delay>, <bit> ;
%load/m <bit>, <memid> ;
%set/m <memid>, <bit> ;
%assign/m <memid>, <delay>, <bit> ;
??? is "/mem" required, or shall functors and memories share a
namespace? ???
<ix> identifies one of the four index registers of the current
thread. The value of register <ix> is the index in the memories bit
space, where each data word occupies a multiple of four bits.
The memory bit is addressed by index register 3. The value of
register 3 is the index in the memory's bit space, where each data
word occupies a multiple of four bits.
EVENT STATEMENTS

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.22 2001/05/02 01:57:25 steve Exp $"
#ident "$Id: codes.h,v 1.23 2001/05/02 23:16:50 steve Exp $"
#endif
@ -52,6 +52,7 @@ extern bool of_INV(vthread_t thr, vvp_code_t code);
extern bool of_IX_ADD(vthread_t thr, vvp_code_t code);
extern bool of_IX_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_IX_MUL(vthread_t thr, vvp_code_t code);
extern bool of_IX_SUB(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);
@ -126,6 +127,13 @@ extern void codespace_dump(FILE*fd);
/*
* $Log: codes.h,v $
* Revision 1.23 2001/05/02 23:16:50 steve
* Document memory related opcodes,
* parser uses numbv_s structures instead of the
* symbv_s and a mess of unions,
* Add the %is/sub instruction.
* (Stephan Boettcher)
*
* Revision 1.22 2001/05/02 01:57:25 steve
* Support behavioral subtraction.
*

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.52 2001/05/02 04:05:17 steve Exp $"
#ident "$Id: compile.cc,v 1.53 2001/05/02 23:16:50 steve Exp $"
#endif
# include "compile.h"
@ -56,9 +56,8 @@ enum operand_e {
OA_CODE_PTR,
/* The operand is a variable or net pointer */
OA_FUNC_PTR,
/* The operand is a memory, with index ... */
OA_MEM_X3, /* ... hardwired index register 3 */
OA_MEM_I1 /* ... index register in bit1 */
/* The operand is a pointer to a memory */
OA_MEM_PTR,
};
struct opcode_table_s {
@ -73,7 +72,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%add", of_ADD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%and", of_AND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%assign", of_ASSIGN, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%assign/m",of_ASSIGN_MEM,3,{OA_MEM_X3, OA_BIT1, OA_BIT2} },
{ "%assign/m",of_ASSIGN_MEM,3,{OA_MEM_PTR,OA_BIT1, OA_BIT2} },
{ "%cmp/s", of_CMPS, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/x", of_CMPX, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
@ -84,19 +83,20 @@ const static struct opcode_table_s opcode_table[] = {
{ "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/load",of_IX_LOAD,2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/mul", of_IX_MUL, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/sub", of_IX_SUB, 2, {OA_BIT1, OA_NUMBER, 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} },
{ "%jmp/1", of_JMP1, 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} },
{ "%load/m", of_LOAD_MEM,2, {OA_BIT2, OA_MEM_I1, OA_NONE} },
{ "%load/m", of_LOAD_MEM,2, {OA_BIT1, OA_MEM_PTR, OA_NONE} },
{ "%mov", of_MOV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%noop", of_NOOP, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%nor/r", of_NORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%or", of_OR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%set/m", of_SET_MEM,2, {OA_MEM_I1, OA_BIT1, OA_NONE} },
{ "%set/m", of_SET_MEM,2, {OA_MEM_PTR, OA_BIT1, OA_NONE} },
{ "%sub", of_SUB, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%wait", of_WAIT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%xnor", of_XNOR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
@ -692,8 +692,7 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
code->number = opa->argv[idx].numb;
break;
case OA_MEM_I1:
case OA_MEM_X3:
case OA_MEM_PTR:
if (opa->argv[idx].ltype != L_SYMB) {
yyerror("operand format");
break;
@ -701,26 +700,7 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
code->mem = memory_find(opa->argv[idx].symb.text);
if (code->mem == 0) {
yyerror("functor undefined");
break;
}
if (opa->argv[idx].symb.idx >= 4) {
yyerror("index operand out of range (0..3)");
break;
}
switch(op->argt[idx]) {
case OA_MEM_I1:
code->bit_idx1 = (unsigned short)
opa->argv[idx].symb.idx;
break;
case OA_MEM_X3:
if (opa->argv[idx].symb.idx != 3)
yyerror("index operand must be 3");
break;
default:
break;
yyerror("memory undefined");
}
free(opa->argv[idx].symb.text);
@ -1064,6 +1044,13 @@ void compile_dump(FILE*fd)
/*
* $Log: compile.cc,v $
* Revision 1.53 2001/05/02 23:16:50 steve
* Document memory related opcodes,
* parser uses numbv_s structures instead of the
* symbv_s and a mess of unions,
* Add the %is/sub instruction.
* (Stephan Boettcher)
*
* Revision 1.52 2001/05/02 04:05:17 steve
* Remove the init parameter of functors, and instead use
* the special C<?> symbols to initialize inputs. This is

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: opcodes.txt,v 1.16 2001/05/02 01:57:26 steve Exp $
* $Id: opcodes.txt,v 1.17 2001/05/02 23:16:50 steve Exp $
*/
@ -41,6 +41,15 @@ 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.
* %assign/m <memory-label>, <delay>, <bit>
This instruction does a non-blocking assignment to a bit in a memory
from the specified thread register <bit>. The memory bit is addressed
by index register 3. Bit address zero is the LSB of the first memory
word.
* %cmp/u <bit-l>, <bit-r>, <wid>
* %cmp/s <bit-l>, <bit-r>, <wid>
@ -129,6 +138,16 @@ number. The idx value selects the index register, and may be 0, 1, 2
or 3.
* %ix/add <idx>, <value>
* %ix/sub <idx>, <value>
* %ix/mul <idx>, <value>
This instruction adds, subtracts, or multiplies an immediate value to
the addressed index register. The index register holds numeric values,
so the <value> is a number. The <idx> value selects the index register,
and may be 0, 1, 2 or 3.
* %jmp <code-label>
The %jmp instruction performs an unconditional branch to a given
@ -169,6 +188,14 @@ functor within a vector of functors. This instruction loads only a
single bit.
* %load/m <bit>, <memory-label>
This instruction loads a value from a memory bit into the specified
thread register bit. The memory bit is addressed by index register 3.
Bit address zero is the LSB of the first memory word. This
instruction loads only a single bit.
* %mov <dst>, <src>, <wid>
This instruction copies a vector from one place in register space to
@ -211,6 +238,14 @@ be read out of the variable. The <bit> is the address of the thread
register that contains the bit value to assign.
* %set/m <memory-label>, <bit>
This instruction set a bit in a memory from the specified thread
register bit. The memory bit is addressed by index register 3. Bit
address zero is the LSB of the first memory word. This instruction
sets only a single bit.
* %sub <bit-l>, <bit-r>, <wid>
This instruction arithmetically subtracts the right vector out of the

View File

@ -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.24 2001/05/02 04:05:17 steve Exp $"
#ident "$Id: parse.y,v 1.25 2001/05/02 23:16:50 steve Exp $"
#endif
# include "parse_misc.h"
@ -45,6 +45,8 @@ extern FILE*yyin;
struct symb_s symb;
struct symbv_s symbv;
struct numbv_s numbv;
struct symb_s vect;
struct argv_s argv;
@ -66,7 +68,8 @@ extern FILE*yyin;
%token <vect> T_VECTOR
%type <symb> symbol symbol_opt
%type <symbv> symbols symbols_net numbers
%type <symbv> symbols symbols_net
%type <numbv> numbers
%type <text> label_opt
%type <opa> operand operands operands_opt
%type <table> udp_table
@ -426,6 +429,13 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.25 2001/05/02 23:16:50 steve
* Document memory related opcodes,
* parser uses numbv_s structures instead of the
* symbv_s and a mess of unions,
* Add the %is/sub instruction.
* (Stephan Boettcher)
*
* Revision 1.24 2001/05/02 04:05:17 steve
* Remove the init parameter of functors, and instead use
* the special C<?> symbols to initialize inputs. This is

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse_misc.cc,v 1.4 2001/05/01 01:09:39 steve Exp $"
#ident "$Id: parse_misc.cc,v 1.5 2001/05/02 23:16:50 steve Exp $"
#endif
# include "parse_misc.h"
@ -46,6 +46,12 @@ void symbv_add(struct symbv_s*obj, struct symb_s item)
obj->cnt += 1;
}
void numbv_init(struct numbv_s*obj)
{
obj->cnt = 0;
obj->nvec = 0;
}
void numbv_add(struct numbv_s*obj, long item)
{
obj->nvec = (long*) realloc(obj->nvec, (obj->cnt+1) * sizeof(long));
@ -69,6 +75,13 @@ void argv_add(struct argv_s*obj, vpiHandle item)
/*
* $Log: parse_misc.cc,v $
* Revision 1.5 2001/05/02 23:16:50 steve
* Document memory related opcodes,
* parser uses numbv_s structures instead of the
* symbv_s and a mess of unions,
* Add the %is/sub instruction.
* (Stephan Boettcher)
*
* Revision 1.4 2001/05/01 01:09:39 steve
* Add support for memory objects. (Stephan Boettcher)
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse_misc.h,v 1.4 2001/05/01 01:09:39 steve Exp $"
#ident "$Id: parse_misc.h,v 1.5 2001/05/02 23:16:50 steve Exp $"
#endif
@ -50,17 +50,18 @@ struct symb_s {
struct symbv_s {
unsigned cnt;
union {
struct symb_s*vect;
long*nvec;
};
struct symb_s*vect;
};
extern void symbv_init(struct symbv_s*obj);
extern void symbv_add(struct symbv_s*obj, struct symb_s item);
#define numbv_s symbv_s
#define numbv_init symbv_init
struct numbv_s {
unsigned cnt;
long*nvec;
};
extern void numbv_init(struct numbv_s*obj);
extern void numbv_add(struct numbv_s*obj, long item);
@ -75,6 +76,13 @@ extern void argv_add(struct argv_s*obj, vpiHandle);
/*
* $Log: parse_misc.h,v $
* Revision 1.5 2001/05/02 23:16:50 steve
* Document memory related opcodes,
* parser uses numbv_s structures instead of the
* symbv_s and a mess of unions,
* Add the %is/sub instruction.
* (Stephan Boettcher)
*
* Revision 1.4 2001/05/01 01:09:39 steve
* Add support for memory objects. (Stephan Boettcher)
*

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.33 2001/05/02 01:57:26 steve Exp $"
#ident "$Id: vthread.cc,v 1.34 2001/05/02 23:16:50 steve Exp $"
#endif
# include "vthread.h"
@ -168,6 +168,7 @@ vthread_t vthread_new(unsigned long pc, struct __vpiScope*scope)
thr->is_scheduled = 0;
thr->i_have_ended = 0;
thr->waiting_for_event = 0;
thr->is_scheduled = 0;
thr_put_bit(thr, 0, 0);
thr_put_bit(thr, 1, 1);
@ -626,20 +627,24 @@ bool of_INV(vthread_t thr, vvp_code_t cp)
/*
** Index registers, signed arithmetic.
** Index registers, unsigned arithmetic.
*/
bool of_IX_ADD(vthread_t thr, vvp_code_t cp)
{
int number = (int)cp->number; // signed
thr->index[cp->bit_idx1 & 3] += number;
thr->index[cp->bit_idx1 & 3] += cp->number;
return true;
}
bool of_IX_SUB(vthread_t thr, vvp_code_t cp)
{
thr->index[cp->bit_idx1 & 3] -= cp->number;
return true;
}
bool of_IX_MUL(vthread_t thr, vvp_code_t cp)
{
int number = (int)cp->number; // signed
thr->index[cp->bit_idx1 & 3] *= number;
thr->index[cp->bit_idx1 & 3] *= cp->number;
return true;
}
@ -714,9 +719,8 @@ bool of_LOAD(vthread_t thr, vvp_code_t cp)
bool of_LOAD_MEM(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx1 >= 4);
assert(cp->bit_idx2 < 4);
unsigned char val = memory_get(cp->mem, thr->index[cp->bit_idx1]);
thr_put_bit(thr, cp->bit_idx2, val);
unsigned char val = memory_get(cp->mem, thr->index[3]);
thr_put_bit(thr, cp->bit_idx1, val);
return true;
}
@ -809,9 +813,8 @@ bool of_SET(vthread_t thr, vvp_code_t cp)
bool of_SET_MEM(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx2 < 4);
unsigned char val = thr_get_bit(thr, cp->bit_idx2);
memory_set(cp->mem, thr->index[cp->bit_idx1], val);
unsigned char val = thr_get_bit(thr, cp->bit_idx1);
memory_set(cp->mem, thr->index[3], val);
return true;
}
@ -966,6 +969,13 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
/*
* $Log: vthread.cc,v $
* Revision 1.34 2001/05/02 23:16:50 steve
* Document memory related opcodes,
* parser uses numbv_s structures instead of the
* symbv_s and a mess of unions,
* Add the %is/sub instruction.
* (Stephan Boettcher)
*
* Revision 1.33 2001/05/02 01:57:26 steve
* Support behavioral subtraction.
*