Add force/cassign/release/deassign support. (Stephan Boettcher)
This commit is contained in:
parent
75e78e86d3
commit
82c0a2ebac
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.29 2001/10/21 21:59:50 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.30 2001/11/01 03:00:19 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -65,7 +65,7 @@ vpi_vthr_vector.o vvp_vpi.o
|
|||
|
||||
O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \
|
||||
functor.o fvectors.o npmos.o resolv.o symbols.o codes.o vthread.o schedule.o \
|
||||
tables.o udp.o memory.o $V
|
||||
tables.o udp.o memory.o force.o $V
|
||||
|
||||
vvp: $O
|
||||
$(CXX) $(rdynamic) $(CXXFLAGS) $(LDFLAGS) -o vvp $O $(LIBS) $(dllib)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.37 2001/10/16 02:47:37 steve Exp $
|
||||
* $Id: README.txt,v 1.38 2001/11/01 03:00:19 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -218,12 +218,13 @@ read by behavioral code. If the .var represents a vector of .functors,
|
|||
the index of the LSB is always, from the perspective of vvp, ZERO. The
|
||||
<msb>,<lsb> details are there only for the benefit of VPI support.
|
||||
|
||||
The variable .functor implicitly has three inputs. The first is the
|
||||
value that gets set by assignments or procedural continuous
|
||||
assignments. The second is a forced value that can be connected to a
|
||||
force expression (as a functor) when a value is being forced. And the
|
||||
third input selects the source to use. The default is to select the
|
||||
assignment input.
|
||||
The variable .functor implicitly has two inputs. The first is the
|
||||
value that gets set by assignments. The second input is connected to
|
||||
the driving expression of a procedural continuous assignments.
|
||||
Variable functors have an extra internal bit that tells if a
|
||||
procedural continuous assignment is active. The %cassign opcode
|
||||
connects and activates the procedural continuous assignment. The
|
||||
%deassign opcode disconnects and deactivates it.
|
||||
|
||||
The variable statement also creates a VPI object of the appropriate
|
||||
type. See the vpi.txt file for details about that object. The msb and
|
||||
|
|
@ -397,6 +398,29 @@ resolution function.
|
|||
<label> .resolv tri1, <symbols_list>;
|
||||
|
||||
|
||||
FORCE STATEMENTS:
|
||||
|
||||
A force statement creates functors that represent a Verilog force
|
||||
statement.
|
||||
|
||||
<label> .force <signal>, <symbol_list>;
|
||||
|
||||
The symbol <signal> represents the signal which is to be forced. The
|
||||
<symbol_list> specifies the bits of the expression that is to be
|
||||
forced on the <signal>. The <label> identifies the force functors.
|
||||
There will be as many force functors as there are symbols in the
|
||||
<symbol_list>.
|
||||
|
||||
To activate and deactivate a force on a single bit, use:
|
||||
|
||||
%force <label>, <width>;
|
||||
%release <signal>;
|
||||
|
||||
<label>/<width> is the label/width of a vector of force functors.
|
||||
<signal> is the label of the functor that drives the signal that is
|
||||
being forced.
|
||||
|
||||
|
||||
STRUCTURAL ARITHMETIC STATEMENTS:
|
||||
|
||||
The various Verilog arithmetic opeators (+-*/%) are available to
|
||||
|
|
|
|||
29
vvp/codes.h
29
vvp/codes.h
|
|
@ -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.35 2001/10/16 01:26:54 steve Exp $"
|
||||
#ident "$Id: codes.h,v 1.36 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -42,15 +42,18 @@ extern bool of_ASSIGN(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_ASSIGN_MEM(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_X0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_BREAKPOINT(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CASSIGN(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPS(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPU(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPX(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPZ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_DEASSIGN(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_DELAY(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_DELAYX(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_DISABLE(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_DIV(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_END(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FORCE(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_IX_ADD(vthread_t thr, vvp_code_t code);
|
||||
|
|
@ -74,6 +77,7 @@ extern bool of_NOOP(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_NORR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_OR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ORR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RELEASE(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_MEM(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_X(vthread_t thr, vvp_code_t code);
|
||||
|
|
@ -101,25 +105,27 @@ struct vvp_code_s {
|
|||
vvp_cpoint_t cptr;
|
||||
vvp_memory_t mem;
|
||||
struct __vpiHandle*handle;
|
||||
struct fork_extend*fork;
|
||||
struct __vpiScope*scope;
|
||||
};
|
||||
|
||||
unsigned short bit_idx1;
|
||||
unsigned short bit_idx2;
|
||||
union {
|
||||
unsigned short bit_idx[2];
|
||||
vvp_ipoint_t iptr2;
|
||||
vvp_cpoint_t cptr2;
|
||||
};
|
||||
};
|
||||
|
||||
struct fork_extend {
|
||||
vvp_cpoint_t cptr;
|
||||
struct __vpiScope*scope;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This function clears the code space, ready for initialization. This
|
||||
* needs to be done exactly once before any instructions are created.
|
||||
*/
|
||||
extern void codespace_init(void);
|
||||
|
||||
/*
|
||||
** Return the number of codes
|
||||
*/
|
||||
extern unsigned code_limit();
|
||||
|
||||
/*
|
||||
* This function returns a pointer to the next free instruction in the
|
||||
* code address space.
|
||||
|
|
@ -141,6 +147,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
|
|||
|
||||
/*
|
||||
* $Log: codes.h,v $
|
||||
* Revision 1.36 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.35 2001/10/16 01:26:54 steve
|
||||
* Add %div support (Anthony Bybell)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.110 2001/10/31 04:27:46 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.111 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -27,7 +27,8 @@
|
|||
# include "functor.h"
|
||||
# include "resolv.h"
|
||||
# include "udp.h"
|
||||
# include "memory.h"
|
||||
# include "memory.h"
|
||||
# include "force.h"
|
||||
# include "symbols.h"
|
||||
# include "codes.h"
|
||||
# include "schedule.h"
|
||||
|
|
@ -59,14 +60,16 @@ enum operand_e {
|
|||
OA_NONE,
|
||||
/* The operand is a number, an immediate unsigned integer */
|
||||
OA_NUMBER,
|
||||
/* The operand is a thread bit index */
|
||||
/* The operand is a thread bit index or short integer */
|
||||
OA_BIT1,
|
||||
OA_BIT2,
|
||||
/* The operand is a pointer to code space */
|
||||
OA_CODE_PTR,
|
||||
/* The operand is a variable or net pointer */
|
||||
OA_FUNC_PTR,
|
||||
/* The operand is a pointer to a memory */
|
||||
/* The operand is a second functor pointer */
|
||||
OA_FUNC_PTR2,
|
||||
/* The operand is a pointer to a memory */
|
||||
OA_MEM_PTR,
|
||||
};
|
||||
|
||||
|
|
@ -86,14 +89,17 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%assign/m",of_ASSIGN_MEM,3,{OA_MEM_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/x0",of_ASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%breakpoint", of_BREAKPOINT, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%cassign",of_CASSIGN,2, {OA_FUNC_PTR, OA_FUNC_PTR2,OA_NONE} },
|
||||
{ "%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} },
|
||||
{ "%cmp/z", of_CMPZ, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%deassign",of_DEASSIGN,2,{OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%div", of_DIV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%end", of_END, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%force", of_FORCE, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
|
||||
{ "%ix/get", of_IX_GET, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
|
|
@ -116,6 +122,7 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%nor/r", of_NORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%or", of_OR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%or/r", of_ORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%release",of_RELEASE,1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%set/m", of_SET_MEM,2, {OA_MEM_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%set/x", of_SET_X, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
|
|
@ -399,7 +406,7 @@ bool code_label_resolv_list_s::resolve(bool mes)
|
|||
symbol_value_t val = sym_get_value(sym_codespace, label);
|
||||
if (val.num) {
|
||||
if (code->opcode == of_FORK)
|
||||
code->fork->cptr = val.num;
|
||||
code->cptr2 = val.num;
|
||||
else
|
||||
code->cptr = val.num;
|
||||
free(label);
|
||||
|
|
@ -954,6 +961,28 @@ void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
|
|||
free(argv);
|
||||
}
|
||||
|
||||
void compile_force(char*label, struct symb_s signal,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
vvp_ipoint_t ifofu = functor_allocate(argc);
|
||||
define_functor_symbol(label, ifofu);
|
||||
|
||||
for (unsigned i=0; i<argc; i++) {
|
||||
functor_t obj = new force_functor_s;
|
||||
vvp_ipoint_t iobj = ipoint_index(ifofu, i);
|
||||
functor_define(iobj, obj);
|
||||
|
||||
functor_ref_lookup(&obj->out, strdup(signal.text), signal.idx + i);
|
||||
|
||||
// connect the force expression, one bit.
|
||||
inputs_connect(iobj, 1, &argv[i]);
|
||||
}
|
||||
|
||||
free(argv);
|
||||
free(signal.text);
|
||||
free(label);
|
||||
}
|
||||
|
||||
void compile_udp_def(int sequ, char *label, char *name,
|
||||
unsigned nin, unsigned init, char **table)
|
||||
{
|
||||
|
|
@ -1176,7 +1205,7 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
|||
break;
|
||||
}
|
||||
|
||||
code->bit_idx1 = opa->argv[idx].numb;
|
||||
code->bit_idx[0] = opa->argv[idx].numb;
|
||||
break;
|
||||
|
||||
case OA_BIT2:
|
||||
|
|
@ -1185,7 +1214,7 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
|||
break;
|
||||
}
|
||||
|
||||
code->bit_idx2 = opa->argv[idx].numb;
|
||||
code->bit_idx[1] = opa->argv[idx].numb;
|
||||
break;
|
||||
|
||||
case OA_CODE_PTR:
|
||||
|
|
@ -1212,6 +1241,20 @@ void compile_code(char*label, char*mnem, comp_operands_t opa)
|
|||
opa->argv[idx].symb.idx);
|
||||
break;
|
||||
|
||||
case OA_FUNC_PTR2:
|
||||
/* The operand is a functor. Resolve the label to
|
||||
a functor pointer, or postpone the resolution
|
||||
if it is not defined yet. */
|
||||
if (opa->argv[idx].ltype != L_SYMB) {
|
||||
yyerror("operand format");
|
||||
break;
|
||||
}
|
||||
|
||||
functor_ref_lookup(&code->iptr2,
|
||||
opa->argv[idx].symb.text,
|
||||
opa->argv[idx].symb.idx);
|
||||
break;
|
||||
|
||||
case OA_NUMBER:
|
||||
if (opa->argv[idx].ltype != L_NUMB) {
|
||||
yyerror("operand format");
|
||||
|
|
@ -1285,13 +1328,12 @@ void compile_fork(char*label, struct symb_s dest, struct symb_s scope)
|
|||
/* Fill in the basics of the %fork in the instruction. */
|
||||
vvp_code_t code = codespace_index(ptr);
|
||||
code->opcode = of_FORK;
|
||||
code->fork = new struct fork_extend;
|
||||
|
||||
/* Figure out the target PC. */
|
||||
code_label_lookup(code, dest.text);
|
||||
|
||||
/* Figure out the target SCOPE. */
|
||||
compile_vpi_lookup((vpiHandle*)&code->fork->scope, scope.text);
|
||||
compile_vpi_lookup((vpiHandle*)&code->scope, scope.text);
|
||||
}
|
||||
|
||||
void compile_vpi_call(char*label, char*name, unsigned argc, vpiHandle*argv)
|
||||
|
|
@ -1422,6 +1464,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.111 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.110 2001/10/31 04:27:46 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.h,v 1.35 2001/10/31 04:27:46 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.36 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -71,6 +71,12 @@ extern void compile_functor(char*label, char*type,
|
|||
extern void compile_resolver(char*label, char*type,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
|
||||
/*
|
||||
* This is called by the parser to make force functors.
|
||||
*/
|
||||
extern void compile_force(char*label, struct symb_s signal,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
|
||||
/*
|
||||
* This is called by the parser to make the various arithmetic and
|
||||
* comparison functors.
|
||||
|
|
@ -202,6 +208,9 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.36 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.35 2001/10/31 04:27:46 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: force.cc,v 1.1 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "codes.h"
|
||||
# include "force.h"
|
||||
|
||||
# include <assert.h>
|
||||
|
||||
inline bool functor_s::disable(vvp_ipoint_t ptr)
|
||||
{
|
||||
bool r = inhibit;
|
||||
inhibit = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline bool functor_s::enable(vvp_ipoint_t ptr)
|
||||
{
|
||||
unsigned val;
|
||||
if (ostr == 0)
|
||||
val = 3;
|
||||
else switch (ostr & 0x88) {
|
||||
case 0x00: val = 0; break;
|
||||
case 0x88: val = 1; break;
|
||||
default: val = 2;
|
||||
}
|
||||
if (val != oval) {
|
||||
oval = val;
|
||||
propagate(true);
|
||||
}
|
||||
bool r = inhibit;
|
||||
inhibit = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void functor_s::force(unsigned val, unsigned str)
|
||||
{
|
||||
if (ostr != str || oval != val) {
|
||||
unsigned save = ostr;
|
||||
oval = val;
|
||||
ostr = str;
|
||||
propagate(true);
|
||||
ostr = save;
|
||||
}
|
||||
}
|
||||
|
||||
void force_functor_s::set(vvp_ipoint_t i, bool, unsigned val, unsigned str)
|
||||
{
|
||||
put(i, val);
|
||||
if (ipoint_port(i) == 0) {
|
||||
if (active && out) {
|
||||
functor_t tgt = functor_index(out);
|
||||
tgt->force(ival&3, get_ostr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool release_force(vvp_ipoint_t itgt, functor_t tgt)
|
||||
{
|
||||
vvp_ipoint_t *ref = &tgt->out;
|
||||
while (*ref) {
|
||||
functor_t fofu = functor_index(*ref);
|
||||
unsigned pp = ipoint_port(*ref);
|
||||
|
||||
if (pp == 3 && fofu->out == itgt) {
|
||||
force_functor_s *ff = dynamic_cast<force_functor_s *>(fofu);
|
||||
|
||||
if (ff && ff->active) {
|
||||
ff->active = 0;
|
||||
*ref = fofu->port[pp];
|
||||
fofu->port[pp] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ref = &fofu->port[pp];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool of_FORCE(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned wid = cp->bit_idx[0];
|
||||
|
||||
for (unsigned i=0; i<wid; i++) {
|
||||
vvp_ipoint_t ifofu = ipoint_index(cp->iptr, i);
|
||||
functor_t fofu = functor_index(ifofu);
|
||||
force_functor_s *ff = dynamic_cast<force_functor_s *>(fofu);
|
||||
|
||||
assert(ff);
|
||||
|
||||
if (ff->active)
|
||||
return true;
|
||||
|
||||
ff->active = 1;
|
||||
|
||||
vvp_ipoint_t itgt = fofu->out;
|
||||
functor_t tgt = functor_index(itgt);
|
||||
|
||||
if (tgt->disable(itgt))
|
||||
release_force(itgt, tgt);
|
||||
|
||||
fofu->port[3] = tgt->out;
|
||||
tgt->out = ipoint_make(ifofu, 3);
|
||||
|
||||
fofu->set(ifofu, false, fofu->ival&3, fofu->get_ostr());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_RELEASE(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_ipoint_t itgt = cp->iptr;
|
||||
functor_t tgt = functor_index(itgt);
|
||||
|
||||
if (release_force(itgt, tgt))
|
||||
tgt->enable(itgt);
|
||||
// bug: a strength change will not be propagated.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Variable functors receive %set or %assign-ed values at port[0].
|
||||
** Continuous assignments are connected to port[1].
|
||||
**
|
||||
** port[3] points back to the functor that drives the continuous
|
||||
** assignment. This also serves as a flag if assignment is active.
|
||||
**
|
||||
** A constant is assigned if the expr ipoint is < 4, i.e. a port of
|
||||
** the NULL functor. port[3] is set to 3.
|
||||
*/
|
||||
|
||||
void var_functor_s::set(vvp_ipoint_t ptr, bool push, unsigned val, unsigned)
|
||||
{
|
||||
unsigned pp = ipoint_port(ptr);
|
||||
|
||||
if (assigned() && pp==1 || !assigned() && pp==0) {
|
||||
put_oval(ptr, push, val);
|
||||
}
|
||||
}
|
||||
|
||||
bool var_functor_s::deassign(vvp_ipoint_t itgt)
|
||||
{
|
||||
if (!assigned())
|
||||
return false;
|
||||
|
||||
vvp_ipoint_t ipt = port[3];
|
||||
|
||||
if (ipt == ipoint_make(0, 3)) {
|
||||
port[3] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
functor_t fp = functor_index(ipt);
|
||||
vvp_ipoint_t *ref = &fp->out;
|
||||
|
||||
itgt = ipoint_make(itgt, 1);
|
||||
|
||||
while (*ref) {
|
||||
if (*ref == itgt) {
|
||||
*ref = port[1];
|
||||
port[1] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
functor_t fu = functor_index(*ref);
|
||||
unsigned pp = ipoint_port(*ref);
|
||||
ref = &fu->port[pp];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool of_CASSIGN(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_ipoint_t itgt = cp->iptr;
|
||||
vvp_ipoint_t iexp = cp->iptr2;
|
||||
|
||||
functor_t tgt = functor_index(itgt);
|
||||
|
||||
var_functor_s *var = dynamic_cast<var_functor_s *>(tgt);
|
||||
assert(var);
|
||||
var->deassign(itgt);
|
||||
|
||||
// a constant expression?
|
||||
if (ipoint_make(iexp, 0) == 0) {
|
||||
tgt->port[3] = ipoint_make(0, 3);
|
||||
tgt->set(ipoint_make(itgt, 1), true, ipoint_port(iexp));
|
||||
return true;
|
||||
}
|
||||
|
||||
functor_t fu = functor_index(iexp);
|
||||
|
||||
tgt->port[3] = iexp;
|
||||
tgt->port[1] = fu->out;
|
||||
fu->out = ipoint_make(itgt, 1);
|
||||
|
||||
tgt->set(ipoint_make(itgt, 1), true, fu->get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_DEASSIGN(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_ipoint_t itgt = cp->iptr;
|
||||
unsigned wid = cp->bit_idx[0];
|
||||
|
||||
for (unsigned i = 0; i<wid; i++) {
|
||||
vvp_ipoint_t ipt = ipoint_index(itgt, i);
|
||||
functor_t tgt = functor_index(ipt);
|
||||
|
||||
var_functor_s *var = dynamic_cast<var_functor_s *>(tgt);
|
||||
assert(var);
|
||||
|
||||
var->deassign(ipt);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: force.cc,v $
|
||||
* Revision 1.1 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef __force_H
|
||||
#define __force_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: force.h,v 1.1 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "functor.h"
|
||||
|
||||
/*
|
||||
* Force functors
|
||||
*/
|
||||
|
||||
class force_functor_s : public functor_s
|
||||
{
|
||||
public:
|
||||
force_functor_s() : active(0) {}
|
||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
unsigned active : 1;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Variable functors
|
||||
*/
|
||||
|
||||
struct var_functor_s: public functor_s {
|
||||
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
|
||||
bool assigned() { return !!port[3]; };
|
||||
bool deassign(vvp_ipoint_t itgt);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* $Log: force.h,v $
|
||||
* Revision 1.1 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
@ -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.29 2001/10/31 04:27:46 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.30 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
|
@ -158,21 +158,6 @@ void event_functor_s::set(vvp_ipoint_t ptr, bool, unsigned val, unsigned)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Variable functors receive %assign-ed values at port[0].
|
||||
* Continuous assignments are connected to port[1].
|
||||
*/
|
||||
|
||||
void var_functor_s::set(vvp_ipoint_t ptr, bool push, unsigned val, unsigned)
|
||||
{
|
||||
unsigned pp = ipoint_port(ptr);
|
||||
|
||||
if (assigned && pp==1 || !assigned && pp==0) {
|
||||
put_oval(ptr, push, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void extra_outputs_functor_s::set(vvp_ipoint_t i, bool push,
|
||||
unsigned val, unsigned)
|
||||
{
|
||||
|
|
@ -201,6 +186,9 @@ void extra_inputs_functor_s::set(vvp_ipoint_t i, bool push,
|
|||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.30 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.29 2001/10/31 04:27:46 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
|
|
|||
|
|
@ -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.35 2001/10/31 04:27:46 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.36 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "pointers.h"
|
||||
|
|
@ -197,12 +197,14 @@ struct functor_s {
|
|||
unsigned val, unsigned str = 0) = 0;
|
||||
|
||||
inline unsigned char get() { return oval; }
|
||||
inline unsigned char get_ostr() { return ostr; }
|
||||
void put(vvp_ipoint_t ipt, unsigned val);
|
||||
void put_oval(vvp_ipoint_t ptr, bool push, unsigned val);
|
||||
void put_ostr(vvp_ipoint_t ptr, bool push, unsigned val, unsigned str);
|
||||
bool disable(vvp_ipoint_t ptr);
|
||||
bool enable(vvp_ipoint_t ptr);
|
||||
void propagate(bool push);
|
||||
void force(unsigned val, unsigned str);
|
||||
};
|
||||
|
||||
inline functor_s::functor_s()
|
||||
|
|
@ -292,31 +294,6 @@ inline void functor_s::put_ostr(vvp_ipoint_t ptr, bool push,
|
|||
}
|
||||
}
|
||||
|
||||
inline bool functor_s::disable(vvp_ipoint_t ptr)
|
||||
{
|
||||
bool r = inhibit;
|
||||
inhibit = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline bool functor_s::enable(vvp_ipoint_t ptr)
|
||||
{
|
||||
unsigned val;
|
||||
if (ostr == 0)
|
||||
val = 3;
|
||||
else switch (ostr & 0x88) {
|
||||
case 0x00: val = 0; break;
|
||||
case 0x88: val = 1; break;
|
||||
default: val = 2;
|
||||
}
|
||||
if (val != oval) {
|
||||
schedule_functor(ptr, 0);
|
||||
}
|
||||
bool r = inhibit;
|
||||
inhibit = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* functor_set sets the addressed input to the specified value, and
|
||||
* calculates a new output value. If there is any propagation to do,
|
||||
|
|
@ -472,17 +449,6 @@ const event_functor_s::edge_t vvp_edge_negedge
|
|||
const event_functor_s::edge_t vvp_edge_anyedge = 0x7bde;
|
||||
const event_functor_s::edge_t vvp_edge_none = 0;
|
||||
|
||||
/*
|
||||
* Variable functors
|
||||
*/
|
||||
|
||||
struct var_functor_s: public functor_s {
|
||||
var_functor_s() : assigned(0) {};
|
||||
virtual void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
unsigned assigned : 1;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Callback functors.
|
||||
*/
|
||||
|
|
@ -502,6 +468,9 @@ extern vvp_fvector_t vvp_fvector_continuous_new(unsigned size, vvp_ipoint_t p);
|
|||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.36 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.35 2001/10/31 04:27:46 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: lexor.lex,v 1.27 2001/10/16 02:47:37 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.28 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -90,6 +90,7 @@
|
|||
".mem" { return K_MEM; }
|
||||
".mem/p"(ort)? { return K_MEM_P; }
|
||||
".mem/i"(nit)? { return K_MEM_I; }
|
||||
".force" { return K_FORCE; }
|
||||
|
||||
/* instructions start with a % character. The compiler decides what
|
||||
kind of instruction this really is. The few exceptions (that have
|
||||
|
|
@ -149,6 +150,9 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.28 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.27 2001/10/16 02:47:37 steve
|
||||
* Add arith/div object.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: opcodes.txt,v 1.30 2001/10/16 01:26:55 steve Exp $
|
||||
* $Id: opcodes.txt,v 1.31 2001/11/01 03:00:19 steve Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -82,6 +82,21 @@ This may not work on all platforms. If run-time debugging is compiled
|
|||
out, then this function is a no-op.
|
||||
|
||||
|
||||
* %cassign <var-label>, <expr-label>
|
||||
|
||||
Connect and active a procedural continuous assignment to a
|
||||
variable. The <var-label> identifies the affected variable, and the
|
||||
<expr-label> is the functor that drives the expression to the
|
||||
variable. This opcode affects only a single bit.
|
||||
|
||||
|
||||
* %deassign <var-label>, <wid>
|
||||
|
||||
Deactive and disconnect a procedural continuous assignment to a
|
||||
variable. The <var-label> identifies the affected variable. <wid>
|
||||
specifies the how many bits to deassign.
|
||||
|
||||
|
||||
* %cmp/u <bit-l>, <bit-r>, <wid>
|
||||
* %cmp/s <bit-l>, <bit-r>, <wid>
|
||||
|
||||
|
|
@ -151,6 +166,14 @@ This instruction arithmetically divides the <bit-l> vector by the
|
|||
the bits in either vector are x or z, the entire result is x.
|
||||
|
||||
|
||||
* %force <fofu-label>, <width>
|
||||
|
||||
Activate a force represented by the force functors <fofu-label>, which
|
||||
were created with a .force directive. If any force was active on the
|
||||
signal, that force is released first. A vector of force functors may
|
||||
be specified with <width> greater than 1.
|
||||
|
||||
|
||||
* %fork <code-label>, <scope-label>
|
||||
|
||||
This instruction is similar to %jmp, except that it creates a new
|
||||
|
|
@ -309,6 +332,7 @@ truth table:
|
|||
0 or 0 --> 0
|
||||
otherwise x
|
||||
|
||||
|
||||
* %or/r <dst>, <src>, <wid>
|
||||
|
||||
This is a reduction version of the %or opcode. The <src> is a vector,
|
||||
|
|
@ -316,6 +340,22 @@ and the <dst> is a writeable scaler. The <dst> gets the value of the
|
|||
or of all the bits of the src vector.
|
||||
|
||||
|
||||
* %release <functor-label>
|
||||
|
||||
Release the force on the signal that is represented by the functor
|
||||
<functor-label>. The force was previously activated with a %force
|
||||
statement. If no force was active on this functor the statement does
|
||||
nothing. %release restores and propagates the normal value of the
|
||||
previously forced functor. In case of a forced Verilog register, the
|
||||
current value of the force expression should be %set to the .var
|
||||
functor before the force is released, to comply with Verilog release
|
||||
semantics. Like:
|
||||
|
||||
%load <bit>, <functor-label> ; get the forced value
|
||||
%set <functor-label>, <bit> ; set the .var value
|
||||
%release <functor-label> ; remove the force
|
||||
|
||||
|
||||
* %set <var-label>, <bit>
|
||||
|
||||
This sets a bit of a variable, and is used to implement blocking
|
||||
|
|
|
|||
14
vvp/parse.y
14
vvp/parse.y
|
|
@ -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.39 2001/10/31 04:27:47 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.40 2001/11/01 03:00:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -59,6 +59,7 @@ extern FILE*yyin;
|
|||
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD
|
||||
%token K_UDP K_UDP_C K_UDP_S
|
||||
%token K_MEM K_MEM_P K_MEM_I
|
||||
%token K_FORCE
|
||||
%token K_VAR K_VAR_S K_vpi_call K_vpi_func K_disable K_fork
|
||||
%token K_vpi_module K_vpi_time_precision
|
||||
|
||||
|
|
@ -158,6 +159,14 @@ statement
|
|||
compile_resolver($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
/* Force statements are very much like functors. They are
|
||||
compiled to functors of a different mode. */
|
||||
|
||||
| T_LABEL K_FORCE symbol ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_force($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
/* Arithmetic statements generate functor arrays of a given width
|
||||
that take like size input vectors. */
|
||||
|
||||
|
|
@ -505,6 +514,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.40 2001/11/01 03:00:19 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.39 2001/10/31 04:27:47 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
|
|
|||
227
vvp/vthread.cc
227
vvp/vthread.cc
|
|
@ -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.62 2001/10/31 04:27:47 steve Exp $"
|
||||
#ident "$Id: vthread.cc,v 1.63 2001/11/01 03:00:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vthread.h"
|
||||
|
|
@ -305,10 +305,10 @@ void vthread_schedule_list(vthread_t thr)
|
|||
|
||||
bool of_AND(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -336,10 +336,10 @@ bool of_AND(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_ADD(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned long*lva = vector_to_array(thr, cp->bit_idx1, cp->number);
|
||||
unsigned long*lvb = vector_to_array(thr, cp->bit_idx2, cp->number);
|
||||
unsigned long*lva = vector_to_array(thr, cp->bit_idx[0], cp->number);
|
||||
unsigned long*lvb = vector_to_array(thr, cp->bit_idx[1], cp->number);
|
||||
if (lva == 0 || lvb == 0)
|
||||
goto x_out;
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ bool of_ADD(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
unsigned bit = lva[idx/CPU_BITS] >> (idx % CPU_BITS);
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, (bit&1) ? 1 : 0);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, (bit&1) ? 1 : 0);
|
||||
}
|
||||
|
||||
delete[]lva;
|
||||
|
|
@ -375,30 +375,30 @@ bool of_ADD(vthread_t thr, vvp_code_t cp)
|
|||
delete[]lvb;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_ASSIGN(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx2);
|
||||
schedule_assign(cp->iptr, bit_val, cp->bit_idx1);
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]);
|
||||
schedule_assign(cp->iptr, bit_val, cp->bit_idx[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_ASSIGN_X0(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_idx[1]);
|
||||
vvp_ipoint_t itmp = ipoint_index(cp->iptr, thr->index[0]);
|
||||
schedule_assign(itmp, bit_val, cp->bit_idx1);
|
||||
schedule_assign(itmp, bit_val, cp->bit_idx[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_ASSIGN_MEM(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx2);
|
||||
schedule_memory(cp->mem, thr->index[3], bit_val, cp->bit_idx1);
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]);
|
||||
schedule_memory(cp->mem, thr->index[3], bit_val, cp->bit_idx[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -416,8 +416,8 @@ bool of_CMPS(vthread_t thr, vvp_code_t cp)
|
|||
unsigned eeq = 1;
|
||||
unsigned lt = 0;
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
unsigned sig1 = thr_get_bit(thr, idx1 + cp->number - 1);
|
||||
unsigned sig2 = thr_get_bit(thr, idx2 + cp->number - 1);
|
||||
|
|
@ -466,8 +466,8 @@ bool of_CMPU(vthread_t thr, vvp_code_t cp)
|
|||
unsigned eeq = 1;
|
||||
unsigned lt = 0;
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
unsigned lv = thr_get_bit(thr, idx1);
|
||||
|
|
@ -507,8 +507,8 @@ bool of_CMPX(vthread_t thr, vvp_code_t cp)
|
|||
{
|
||||
unsigned eq = 1;
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
unsigned lv = thr_get_bit(thr, idx1);
|
||||
|
|
@ -532,8 +532,8 @@ bool of_CMPZ(vthread_t thr, vvp_code_t cp)
|
|||
{
|
||||
unsigned eq = 1;
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
unsigned lv = thr_get_bit(thr, idx1);
|
||||
|
|
@ -625,11 +625,11 @@ bool of_DISABLE(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_DIV(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
if(cp->number <= 8*sizeof(unsigned long)) {
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
unsigned long lv = 0, rv = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
|
@ -653,7 +653,7 @@ bool of_DIV(vthread_t thr, vvp_code_t cp)
|
|||
lv /= rv;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, (lv&1) ? 1 : 0);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, (lv&1) ? 1 : 0);
|
||||
lv >>= 1;
|
||||
}
|
||||
|
||||
|
|
@ -675,8 +675,8 @@ bool of_DIV(vthread_t thr, vvp_code_t cp)
|
|||
int i;
|
||||
int current, copylen;
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
unsigned lb = thr_get_bit(thr, idx1);
|
||||
|
|
@ -751,7 +751,7 @@ bool of_DIV(vthread_t thr, vvp_code_t cp)
|
|||
tally:
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
// n.b., z[] has the remainder...
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, b[idx]);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, b[idx]);
|
||||
}
|
||||
|
||||
delete []t;
|
||||
|
|
@ -763,7 +763,7 @@ bool of_DIV(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
x_out:
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -850,7 +850,7 @@ bool of_END(vthread_t thr, vvp_code_t)
|
|||
*/
|
||||
bool of_FORK(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vthread_t child = vthread_new(cp->fork->cptr, cp->fork->scope);
|
||||
vthread_t child = vthread_new(cp->cptr2, cp->scope);
|
||||
|
||||
child->child = thr->child;
|
||||
child->parent = thr;
|
||||
|
|
@ -865,9 +865,9 @@ bool of_FORK(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
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);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
for (unsigned idx = 0 ; idx < cp->bit_idx[1] ; idx += 1) {
|
||||
unsigned val = thr_get_bit(thr, cp->bit_idx[0]+idx);
|
||||
switch (val) {
|
||||
case 0:
|
||||
val = 1;
|
||||
|
|
@ -879,7 +879,7 @@ bool of_INV(vthread_t thr, vvp_code_t cp)
|
|||
val = 2;
|
||||
break;
|
||||
}
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, val);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -891,25 +891,25 @@ bool of_INV(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_IX_ADD(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
thr->index[cp->bit_idx1 & 3] += cp->number;
|
||||
thr->index[cp->bit_idx[0] & 3] += cp->number;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_IX_SUB(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
thr->index[cp->bit_idx1 & 3] -= cp->number;
|
||||
thr->index[cp->bit_idx[0] & 3] -= cp->number;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_IX_MUL(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
thr->index[cp->bit_idx1 & 3] *= cp->number;
|
||||
thr->index[cp->bit_idx[0] & 3] *= cp->number;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_IX_LOAD(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
thr->index[cp->bit_idx1 & 3] = cp->number;
|
||||
thr->index[cp->bit_idx[0] & 3] = cp->number;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -917,14 +917,14 @@ bool of_IX_GET(vthread_t thr, vvp_code_t cp)
|
|||
{
|
||||
unsigned long v = 0;
|
||||
for (unsigned i = 0; i<cp->number; i++) {
|
||||
unsigned char vv = thr_get_bit(thr, cp->bit_idx2 + i);
|
||||
unsigned char vv = thr_get_bit(thr, cp->bit_idx[1] + i);
|
||||
if (vv&2) {
|
||||
v = ~0UL;
|
||||
break;
|
||||
}
|
||||
v |= vv << i;
|
||||
}
|
||||
thr->index[cp->bit_idx1 & 3] = v;
|
||||
thr->index[cp->bit_idx[0] & 3] = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -942,21 +942,21 @@ bool of_JMP(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_JMP0(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
if (thr_get_bit(thr, cp->bit_idx1) == 0)
|
||||
if (thr_get_bit(thr, cp->bit_idx[0]) == 0)
|
||||
thr->pc = cp->cptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_JMP0XZ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
if (thr_get_bit(thr, cp->bit_idx1) != 1)
|
||||
if (thr_get_bit(thr, cp->bit_idx[0]) != 1)
|
||||
thr->pc = cp->cptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_JMP1(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
if (thr_get_bit(thr, cp->bit_idx1) == 1)
|
||||
if (thr_get_bit(thr, cp->bit_idx[0]) == 1)
|
||||
thr->pc = cp->cptr;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -985,36 +985,36 @@ bool of_JOIN(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
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));
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
thr_put_bit(thr, cp->bit_idx[0], functor_get(cp->iptr));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_LOAD_MEM(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
unsigned char val = memory_get(cp->mem, thr->index[3]);
|
||||
thr_put_bit(thr, cp->bit_idx1, val);
|
||||
thr_put_bit(thr, cp->bit_idx[0], val);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_LOAD_X(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx2 < 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
assert(cp->bit_idx[1] < 4);
|
||||
|
||||
vvp_ipoint_t ptr = ipoint_index(cp->iptr, thr->index[cp->bit_idx2]);
|
||||
thr_put_bit(thr, cp->bit_idx1, functor_get(ptr));
|
||||
vvp_ipoint_t ptr = ipoint_index(cp->iptr, thr->index[cp->bit_idx[1]]);
|
||||
thr_put_bit(thr, cp->bit_idx[0], functor_get(ptr));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_MOD(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
if(cp->number <= 8*sizeof(unsigned long)) {
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
unsigned long lv = 0, rv = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
|
@ -1038,7 +1038,7 @@ if(cp->number <= 8*sizeof(unsigned long)) {
|
|||
lv %= rv;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, (lv&1) ? 1 : 0);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, (lv&1) ? 1 : 0);
|
||||
lv >>= 1;
|
||||
}
|
||||
|
||||
|
|
@ -1059,8 +1059,8 @@ if(cp->number <= 8*sizeof(unsigned long)) {
|
|||
int i;
|
||||
int current, copylen;
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
unsigned lb = thr_get_bit(thr, idx1);
|
||||
|
|
@ -1136,7 +1136,7 @@ if(cp->number <= 8*sizeof(unsigned long)) {
|
|||
|
||||
tally:
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, z[idx]);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, z[idx]);
|
||||
}
|
||||
|
||||
delete []t;
|
||||
|
|
@ -1147,24 +1147,24 @@ tally:
|
|||
|
||||
x_out:
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_MOV(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
if (cp->bit_idx2 >= 4) {
|
||||
if (cp->bit_idx[1] >= 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));
|
||||
cp->bit_idx[0]+idx,
|
||||
thr_get_bit(thr, cp->bit_idx[1]+idx));
|
||||
|
||||
} else {
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, cp->bit_idx2);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, cp->bit_idx[1]);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1172,11 +1172,11 @@ bool of_MOV(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_MUL(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
if(cp->number <= 8*sizeof(unsigned long)) {
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
unsigned long lv = 0, rv = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
|
@ -1197,14 +1197,14 @@ bool of_MUL(vthread_t thr, vvp_code_t cp)
|
|||
lv *= rv;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, (lv&1) ? 1 : 0);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, (lv&1) ? 1 : 0);
|
||||
lv >>= 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
unsigned char *a, *b, *sum;
|
||||
a = new unsigned char[cp->number];
|
||||
|
|
@ -1254,7 +1254,7 @@ bool of_MUL(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, sum[idx]);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, sum[idx]);
|
||||
}
|
||||
|
||||
delete[]sum;
|
||||
|
|
@ -1265,7 +1265,7 @@ bool of_MUL(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
x_out:
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1277,10 +1277,10 @@ bool of_NOOP(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_NORR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned lb = 1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1294,17 +1294,17 @@ bool of_NORR(vthread_t thr, vvp_code_t cp)
|
|||
lb = 2;
|
||||
}
|
||||
|
||||
thr_put_bit(thr, cp->bit_idx1, lb);
|
||||
thr_put_bit(thr, cp->bit_idx[0], lb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_ANDR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned lb = 1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1318,17 +1318,17 @@ bool of_ANDR(vthread_t thr, vvp_code_t cp)
|
|||
lb = 2;
|
||||
}
|
||||
|
||||
thr_put_bit(thr, cp->bit_idx1, lb);
|
||||
thr_put_bit(thr, cp->bit_idx[0], lb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_NANDR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned lb = 0;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1342,17 +1342,17 @@ bool of_NANDR(vthread_t thr, vvp_code_t cp)
|
|||
lb = 2;
|
||||
}
|
||||
|
||||
thr_put_bit(thr, cp->bit_idx1, lb);
|
||||
thr_put_bit(thr, cp->bit_idx[0], lb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_ORR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned lb = 0;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1366,17 +1366,17 @@ bool of_ORR(vthread_t thr, vvp_code_t cp)
|
|||
lb = 2;
|
||||
}
|
||||
|
||||
thr_put_bit(thr, cp->bit_idx1, lb);
|
||||
thr_put_bit(thr, cp->bit_idx[0], lb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_XORR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned lb = 0;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1389,17 +1389,17 @@ bool of_XORR(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
}
|
||||
|
||||
thr_put_bit(thr, cp->bit_idx1, lb);
|
||||
thr_put_bit(thr, cp->bit_idx[0], lb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_XNORR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned lb = 1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1412,17 +1412,17 @@ bool of_XNORR(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
}
|
||||
|
||||
thr_put_bit(thr, cp->bit_idx1, lb);
|
||||
thr_put_bit(thr, cp->bit_idx[0], lb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_OR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1451,7 +1451,7 @@ static const unsigned char strong_values[4] = {St0, St1, StX, HiZ};
|
|||
|
||||
bool of_SET(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx1);
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[0]);
|
||||
functor_set(cp->iptr, bit_val, strong_values[bit_val], true);
|
||||
|
||||
return true;
|
||||
|
|
@ -1459,7 +1459,7 @@ bool of_SET(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_SET_MEM(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned char val = thr_get_bit(thr, cp->bit_idx1);
|
||||
unsigned char val = thr_get_bit(thr, cp->bit_idx[0]);
|
||||
memory_set(cp->mem, thr->index[3], val);
|
||||
|
||||
return true;
|
||||
|
|
@ -1467,8 +1467,8 @@ bool of_SET_MEM(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_SET_X(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx1);
|
||||
vvp_ipoint_t itmp = ipoint_index(cp->iptr, thr->index[cp->bit_idx2&3]);
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[0]);
|
||||
vvp_ipoint_t itmp = ipoint_index(cp->iptr, thr->index[cp->bit_idx[1]&3]);
|
||||
functor_set(itmp, bit_val, strong_values[bit_val], true);
|
||||
|
||||
return true;
|
||||
|
|
@ -1476,7 +1476,7 @@ bool of_SET_X(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned base = cp->bit_idx1;
|
||||
unsigned base = cp->bit_idx[0];
|
||||
unsigned wid = cp->number;
|
||||
unsigned long shift = thr->index[0];
|
||||
|
||||
|
|
@ -1501,7 +1501,7 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp)
|
|||
*/
|
||||
bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned base = cp->bit_idx1;
|
||||
unsigned base = cp->bit_idx[0];
|
||||
unsigned wid = cp->number;
|
||||
unsigned long shift = thr->index[0];
|
||||
|
||||
|
|
@ -1523,10 +1523,10 @@ bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_SUB(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned long*lva = vector_to_array(thr, cp->bit_idx1, cp->number);
|
||||
unsigned long*lvb = vector_to_array(thr, cp->bit_idx2, cp->number);
|
||||
unsigned long*lva = vector_to_array(thr, cp->bit_idx[0], cp->number);
|
||||
unsigned long*lvb = vector_to_array(thr, cp->bit_idx[1], cp->number);
|
||||
if (lva == 0 || lvb == 0)
|
||||
goto x_out;
|
||||
|
||||
|
|
@ -1544,7 +1544,7 @@ bool of_SUB(vthread_t thr, vvp_code_t cp)
|
|||
sum += 1 & ~(tmp >> (idx%CPU_BITS));
|
||||
|
||||
carry = sum / 2;
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, (sum&1) ? 1 : 0);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, (sum&1) ? 1 : 0);
|
||||
}
|
||||
|
||||
delete[]lva;
|
||||
|
|
@ -1557,7 +1557,7 @@ bool of_SUB(vthread_t thr, vvp_code_t cp)
|
|||
delete[]lvb;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||
thr_put_bit(thr, cp->bit_idx[0]+idx, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1588,10 +1588,10 @@ bool of_WAIT(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_XNOR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1625,10 +1625,10 @@ bool of_XNOR(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
bool of_XOR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
assert(cp->bit_idx1 >= 4);
|
||||
assert(cp->bit_idx[0] >= 4);
|
||||
|
||||
unsigned idx1 = cp->bit_idx1;
|
||||
unsigned idx2 = cp->bit_idx2;
|
||||
unsigned idx1 = cp->bit_idx[0];
|
||||
unsigned idx2 = cp->bit_idx[1];
|
||||
|
||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||
|
||||
|
|
@ -1671,6 +1671,9 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
|
|||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.63 2001/11/01 03:00:20 steve
|
||||
* Add force/cassign/release/deassign support. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.62 2001/10/31 04:27:47 steve
|
||||
* Rewrite the functor type to have fewer functor modes,
|
||||
* and use objects to manage the different types.
|
||||
|
|
|
|||
Loading…
Reference in New Issue