Implement real valued signals and arith nodes.

This commit is contained in:
steve 2005-07-06 04:29:25 +00:00
parent e7f3340513
commit 3ac79c294a
19 changed files with 741 additions and 333 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.68 2005/06/17 03:46:52 steve Exp $
* $Id: README.txt,v 1.69 2005/07/06 04:29:25 steve Exp $
*/
VVP SIMULATION ENGINE
@ -244,6 +244,7 @@ general syntax of a variable is:
<label> .var "name", <msb>, <lsb>;
<label> .var/s "name", <msb>, <lsb>;
<label> .var/real "name", <msb>, <lsb>;
The "name" is the declared base name of the original variable, for the
sake of VPI code that might access it. The variable is placed in the
@ -280,6 +281,7 @@ exactly the same as the .var statement:
<label> .net "name", <msb>, <lsb>, <symbol>;
<label> .net/s "name", <msb>, <lsb>, <symbol>;
<label> .net/real "name", <msb>, <lsb>, <symbol>;
Like a .var statement, the .net statement creates a VPI object with
the basename and dimensions given as parameters. The symbol is a
@ -420,7 +422,7 @@ to trigger this event. Only one of the input events needs to trigger
to make this one go.
WORD STATEMENTS:
WORD STATEMENTS (deprecated):
Verilog includes some scalar word types available to the programmer,
including real variables, and possible extension types that the code
@ -602,6 +604,9 @@ fixed.
NOTE: The .arith/mult inputs are not necessarily the width of the
output. I have not decided how to handle this.
These devices support .s and .r suffixes. The .s means the node is a
signed vector device, the .r a real valued device.
STRUCTURAL COMPARE STATEMENTS:
The arithmetic statements handle various arithmetic operators that

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: arith.cc,v 1.44 2005/06/22 00:04:48 steve Exp $"
#ident "$Id: arith.cc,v 1.45 2005/07/06 04:29:25 steve Exp $"
#endif
# include "arith.h"
@ -701,8 +701,62 @@ void vvp_shiftr::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
}
vvp_arith_real_::vvp_arith_real_()
{
}
void vvp_arith_real_::dispatch_operand_(vvp_net_ptr_t ptr, double bit)
{
switch (ptr.port()) {
case 0:
op_a_ = bit;
break;
case 1:
op_b_ = bit;
break;
default:
assert(0);
}
}
vvp_arith_div_real::vvp_arith_div_real()
{
}
vvp_arith_div_real::~vvp_arith_div_real()
{
}
void vvp_arith_div_real::recv_real(vvp_net_ptr_t ptr, double bit)
{
dispatch_operand_(ptr, bit);
double val = op_a_ / op_b_;
vvp_send_real(ptr.ptr()->out, val);
}
vvp_arith_sub_real::vvp_arith_sub_real()
{
}
vvp_arith_sub_real::~vvp_arith_sub_real()
{
}
void vvp_arith_sub_real::recv_real(vvp_net_ptr_t ptr, double bit)
{
dispatch_operand_(ptr, bit);
double val = op_a_ - op_b_;
vvp_send_real(ptr.ptr()->out, val);
}
/*
* $Log: arith.cc,v $
* Revision 1.45 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.44 2005/06/22 00:04:48 steve
* Reduce vvp_vector4 copies by using const references.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: arith.h,v 1.31 2005/06/22 00:04:48 steve Exp $"
#ident "$Id: arith.h,v 1.32 2005/07/06 04:29:25 steve Exp $"
#endif
# include "vvp_net.h"
@ -196,8 +196,46 @@ class vvp_shiftr : public vvp_arith_ {
virtual void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
};
/*
* Base class for real valued expressions. These are similar to the
* vector expression classes, but the inputs are collected from the
* recv_real method.
*/
class vvp_arith_real_ : public vvp_net_fun_t {
public:
explicit vvp_arith_real_();
protected:
void dispatch_operand_(vvp_net_ptr_t ptr, double bit);
protected:
double op_a_;
double op_b_;
};
class vvp_arith_div_real : public vvp_arith_real_ {
public:
explicit vvp_arith_div_real();
~vvp_arith_div_real();
void recv_real(vvp_net_ptr_t ptr, double bit);
};
class vvp_arith_sub_real : public vvp_arith_real_ {
public:
explicit vvp_arith_sub_real();
~vvp_arith_sub_real();
void recv_real(vvp_net_ptr_t ptr, double bit);
};
/*
* $Log: arith.h,v $
* Revision 1.32 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.31 2005/06/22 00:04:48 steve
* Reduce vvp_vector4 copies by using const references.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.cc,v 1.209 2005/06/14 01:44:09 steve Exp $"
#ident "$Id: compile.cc,v 1.210 2005/07/06 04:29:25 steve Exp $"
#endif
# include "arith.h"
@ -245,6 +245,11 @@ static vvp_net_t* vvp_net_lookup(const char*label)
return sig->node;
}
case vpiRealVar: {
__vpiRealVar*sig = (__vpiRealVar*)vpi;
return sig->net;
}
case vpiNamedEvent: {
__vpiNamedEvent*tmp = (__vpiNamedEvent*)vpi;
return tmp->funct;
@ -757,6 +762,20 @@ void input_connect(vvp_net_t*fdx, unsigned port, char*label)
return;
}
if ((strncmp(label, "Cr<", 3) == 0)
&& ((tp = strchr(label,'>')))
&& (tp[1] == 0)
&& (strspn(label+3, "0123456789.-e") == tp-label-3)) {
double tmp;
sscanf(label+3, "%lg", &tmp);
schedule_set_vector(ifdx, tmp);
free(label);
return;
}
/* Handle the general case that this is a label for a node in
the vvp net. This arranges for the label to be preserved in
a linker list, and linked when the symbol table is
@ -797,9 +816,8 @@ void wide_inputs_connect(vvp_wide_fun_core*core,
}
}
static void make_arith(vvp_arith_ *arith,
char*label, long wid,
unsigned argc, struct symb_s*argv)
template <class T_> void make_arith(T_ *arith, char*label,
unsigned argc, struct symb_s*argv)
{
vvp_net_t* ptr = new vvp_net_t;
ptr->fun = arith;
@ -825,7 +843,19 @@ void compile_arith_div(char*label, long wid, bool signed_flag,
}
vvp_arith_ *arith = new vvp_arith_div(wid, signed_flag);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_arith_div_r(char*label, unsigned argc, struct symb_s*argv)
{
if (argc != 2) {
fprintf(stderr, "%s; .arith/divr has wrong number of symbols\n", label);
compile_errors += 1;
return;
}
vvp_arith_real_ *arith = new vvp_arith_div_real;
make_arith(arith, label, argc, argv);
}
void compile_arith_mod(char*label, long wid,
@ -841,7 +871,7 @@ void compile_arith_mod(char*label, long wid,
vvp_arith_ *arith = new vvp_arith_mod(wid, false);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_arith_mult(char*label, long wid,
@ -856,7 +886,7 @@ void compile_arith_mult(char*label, long wid,
}
vvp_arith_ *arith = new vvp_arith_mult(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_arith_sub(char*label, long wid, unsigned argc, struct symb_s*argv)
@ -870,7 +900,19 @@ void compile_arith_sub(char*label, long wid, unsigned argc, struct symb_s*argv)
}
vvp_arith_ *arith = new vvp_arith_sub(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_arith_sub_r(char*label, unsigned argc, struct symb_s*argv)
{
if (argc != 2) {
fprintf(stderr, "%s; .arith/sub.r has wrong number of symbols\n", label);
compile_errors += 1;
return;
}
vvp_arith_real_ *arith = new vvp_arith_sub_real;
make_arith(arith, label, argc, argv);
}
void compile_arith_sum(char*label, long wid, unsigned argc, struct symb_s*argv)
@ -884,7 +926,7 @@ void compile_arith_sum(char*label, long wid, unsigned argc, struct symb_s*argv)
}
vvp_arith_ *arith = new vvp_arith_sum(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_cmp_eeq(char*label, long wid,
@ -900,7 +942,7 @@ void compile_cmp_eeq(char*label, long wid,
vvp_arith_ *arith = new vvp_cmp_eeq(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_cmp_nee(char*label, long wid,
@ -916,7 +958,7 @@ void compile_cmp_nee(char*label, long wid,
vvp_arith_ *arith = new vvp_cmp_nee(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_cmp_eq(char*label, long wid, unsigned argc, struct symb_s*argv)
@ -930,7 +972,7 @@ void compile_cmp_eq(char*label, long wid, unsigned argc, struct symb_s*argv)
}
vvp_arith_ *arith = new vvp_cmp_eq(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_cmp_ne(char*label, long wid, unsigned argc, struct symb_s*argv)
@ -944,7 +986,7 @@ void compile_cmp_ne(char*label, long wid, unsigned argc, struct symb_s*argv)
}
vvp_arith_ *arith = new vvp_cmp_ne(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_cmp_ge(char*label, long wid, bool signed_flag,
@ -960,7 +1002,7 @@ void compile_cmp_ge(char*label, long wid, bool signed_flag,
vvp_arith_ *arith = new vvp_cmp_ge(wid, signed_flag);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_cmp_gt(char*label, long wid, bool signed_flag,
@ -976,7 +1018,7 @@ void compile_cmp_gt(char*label, long wid, bool signed_flag,
vvp_arith_ *arith = new vvp_cmp_gt(wid, signed_flag);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
/*
@ -1006,7 +1048,7 @@ void compile_shiftl(char*label, long wid, unsigned argc, struct symb_s*argv)
assert( wid > 0 );
vvp_arith_ *arith = new vvp_shiftl(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_shiftr(char*label, long wid, unsigned argc, struct symb_s*argv)
@ -1014,7 +1056,7 @@ void compile_shiftr(char*label, long wid, unsigned argc, struct symb_s*argv)
assert( wid > 0 );
vvp_arith_ *arith = new vvp_shiftr(wid);
make_arith(arith, label, wid, argc, argv);
make_arith(arith, label, argc, argv);
}
void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
@ -1422,68 +1464,6 @@ void compile_thread(char*start_sym, char*flag)
free(flag);
}
/*
* A variable is a special functor, so we allocate that functor and
* write the label into the symbol table.
*/
void compile_variable(char*label, char*name, int msb, int lsb,
char signed_flag)
{
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_fun_signal*vsig = new vvp_fun_signal(wid);
vvp_net_t*node = new vvp_net_t;
node->fun = vsig;
define_functor_symbol(label, node);
/* Make the vpiHandle for the reg. */
vpiHandle obj = (signed_flag > 1) ?
vpip_make_int(name, msb, lsb, node) :
vpip_make_reg(name, msb, lsb, signed_flag!=0, node);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
free(name);
}
/*
* Here we handle .net records from the vvp source:
*
* <label> .net <name>, <msb>, <lsb>, <input> ;
* <label> .net/s <name>, <msb>, <lsb>, <input> ;
*
* Create a VPI handle to represent it, and fill that handle in with
* references into the net.
*/
void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
unsigned argc, struct symb_s*argv)
{
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_net_t*node = new vvp_net_t;
vvp_fun_signal*vsig = new vvp_fun_signal(wid);
node->fun = vsig;
/* Add the label into the functor symbol table. */
define_functor_symbol(label, node);
assert(argc == 1);
/* Connect the source to my input. */
inputs_connect(node, 1, argv);
/* Make the vpiHandle for the reg. */
vpiHandle obj = vpip_make_net(name, msb, lsb, signed_flag, node);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
free(name);
free(argv);
}
void compile_param_string(char*label, char*name, char*str, char*value)
{
assert(strcmp(str,"string") == 0);
@ -1498,6 +1478,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.210 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.209 2005/06/14 01:44:09 steve
* Add the assign_v0_d instruction.
*
@ -1523,63 +1506,5 @@ void compile_param_string(char*label, char*name, char*str, char*value)
*
* Revision 1.202 2005/05/24 01:43:27 steve
* Add a sign-extension node.
*
* Revision 1.201 2005/05/18 03:46:01 steve
* Fixup structural GT comparators.
*
* Revision 1.200 2005/05/07 03:15:42 steve
* Implement non-blocking part assign.
*
* Revision 1.199 2005/05/01 22:05:21 steve
* Add cassign/link instruction.
*
* Revision 1.198 2005/04/28 04:59:53 steve
* Remove dead functor code.
*
* Revision 1.197 2005/04/24 20:07:26 steve
* Add DFF nodes.
*
* Revision 1.196 2005/04/01 06:02:45 steve
* Reimplement combinational UDPs.
*
* Revision 1.195 2005/03/22 05:18:34 steve
* The indexed set can write a vector, not just a bit.
*
* Revision 1.194 2005/03/19 06:23:49 steve
* Handle LPM shifts.
*
* Revision 1.193 2005/03/12 06:42:28 steve
* Implement .arith/mod.
*
* Revision 1.192 2005/03/12 04:27:42 steve
* Implement VPI access to signal strengths,
* Fix resolution of ambiguous drive pairs,
* Fix spelling of scalar.
*
* Revision 1.191 2005/03/09 05:52:04 steve
* Handle case inequality in netlists.
*
* Revision 1.190 2005/03/09 04:52:40 steve
* reimplement memory ports.
*
* Revision 1.189 2005/03/03 04:33:10 steve
* Rearrange how memories are supported as vvp_vector4 arrays.
*
* Revision 1.188 2005/02/19 01:32:53 steve
* Implement .arith/div.
*
* Revision 1.187 2005/02/14 01:50:23 steve
* Signals may receive part vectors from %set/x0
* instructions. Re-implement the %set/x0 to do
* just that. Remove the useless %set/x0/x instruction.
*
* Revision 1.186 2005/02/12 03:27:18 steve
* Support C8 constants.
*
* Revision 1.185 2005/01/30 05:06:49 steve
* Get .arith/sub working.
*
* Revision 1.184 2005/01/29 17:53:25 steve
* Use scheduler to initialize constant functor inputs.
*/

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.h,v 1.73 2005/06/17 03:46:52 steve Exp $"
#ident "$Id: compile.h,v 1.74 2005/07/06 04:29:25 steve Exp $"
#endif
# include <stdio.h>
@ -142,6 +142,10 @@ extern void compile_cmp_ge(char*label, long width, bool signed_flag,
unsigned argc, struct symb_s*argv);
extern void compile_cmp_gt(char*label, long width, bool signed_flag,
unsigned argc, struct symb_s*argv);
extern void compile_arith_div_r(char*label, unsigned argc, struct symb_s*argv);
extern void compile_arith_sub_r(char*label, unsigned argc, struct symb_s*argv);
extern void compile_dff(char*label,
struct symb_s arg_d,
struct symb_s arg_c,
@ -240,10 +244,13 @@ extern void compile_event(char*label, char*type,
unsigned argc, struct symb_s*argv);
extern void compile_named_event(char*label, char*type);
#if 0
/*
* Word declarations include a label, a type symbol, and a vpi name.
* TAKEN OVER BY compile_var_real.
*/
extern void compile_word(char*label, char*type, char*name);
#endif
/*
* A code statement is a label, an opcode and up to 3 operands. There
@ -306,13 +313,21 @@ extern void compile_thread(char*start_sym, char*flag);
*/
extern void compile_variable(char*label, char*name,
int msb, int lsb, char signed_flag);
extern void compile_var_real(char*label, char*nane,
int msb, int lsb);
extern void compile_net(char*label, char*name,
int msb, int lsb, bool signed_flag,
unsigned argc, struct symb_s*argv);
extern void compile_net_real(char*label, char*name,
int msb, int lsb,
unsigned argc, struct symb_s*argv);
/*
* $Log: compile.h,v $
* Revision 1.74 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.73 2005/06/17 03:46:52 steve
* Make functors know their own width.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: delay.cc,v 1.8 2005/06/22 00:04:49 steve Exp $"
#ident "$Id: delay.cc,v 1.9 2005/07/06 04:29:25 steve Exp $"
#endif
#include "delay.h"
@ -92,10 +92,17 @@ vvp_time64_t vvp_delay_t::get_delay(vvp_bit4_t from, vvp_bit4_t to)
return 0;
}
vvp_fun_delay::vvp_fun_delay(vvp_net_t*n, vvp_bit4_t init, const vvp_delay_t&d)
: net_(n), delay_(d), cur_(1)
vvp_time64_t vvp_delay_t::get_min_delay() const
{
cur_.set_bit(0, init);
return min_delay_;
}
vvp_fun_delay::vvp_fun_delay(vvp_net_t*n, vvp_bit4_t init, const vvp_delay_t&d)
: net_(n), delay_(d), cur_vec4_(1)
{
cur_vec4_.set_bit(0, init);
flag_real_ = false;
flag_vec4_ = false;
}
vvp_fun_delay::~vvp_fun_delay()
@ -110,26 +117,57 @@ vvp_fun_delay::~vvp_fun_delay()
*/
void vvp_fun_delay::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
if (cur_.eeq(bit))
if (cur_vec4_.eeq(bit))
return;
vvp_time64_t use_delay;
use_delay = delay_.get_delay(cur_.value(0), bit.value(0));
use_delay = delay_.get_delay(cur_vec4_.value(0), bit.value(0));
cur_ = bit;
if (use_delay == 0)
vvp_send_vec4(net_->out, cur_);
else
cur_vec4_ = bit;
if (use_delay == 0) {
vvp_send_vec4(net_->out, cur_vec4_);
} else {
flag_vec4_ = true;
flag_real_ = false;
schedule_generic(this, use_delay, false);
}
}
void vvp_fun_delay::recv_real(vvp_net_ptr_t port, double bit)
{
if (cur_real_ == bit)
return;
vvp_time64_t use_delay;
use_delay = delay_.get_min_delay();
cur_real_ = bit;
if (use_delay == 0) {
vvp_send_real(net_->out, cur_real_);
} else {
flag_vec4_ = false;
flag_real_ = true;
schedule_generic(this, use_delay, false);
}
}
void vvp_fun_delay::run_run()
{
vvp_send_vec4(net_->out, cur_);
if (flag_vec4_) {
vvp_send_vec4(net_->out, cur_vec4_);
flag_vec4_ = false;
}
if (flag_real_) {
vvp_send_real(net_->out, cur_real_);
flag_real_ = false;
}
}
/*
* $Log: delay.cc,v $
* Revision 1.9 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.8 2005/06/22 00:04:49 steve
* Reduce vvp_vector4 copies by using const references.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: delay.h,v 1.8 2005/06/22 00:04:49 steve Exp $"
#ident "$Id: delay.h,v 1.9 2005/07/06 04:29:25 steve Exp $"
#endif
/*
@ -41,6 +41,7 @@ class vvp_delay_t {
~vvp_delay_t();
vvp_time64_t get_delay(vvp_bit4_t from, vvp_bit4_t to);
vvp_time64_t get_min_delay() const;
private:
vvp_time64_t rise_, fall_, decay_;
@ -55,6 +56,10 @@ class vvp_delay_t {
*
* The node needs a pointer to the vvp_net_t input so that it knows
* how to find its output when propaging delayed output.
*
* NOTE: This node supports vec4 and real by repeating whatever was
* input. This is a bit of a hack, as it may be more efficient to
* create the right type of vvp_fun_delay_real.
*/
class vvp_fun_delay : public vvp_net_fun_t, private vvp_gen_event_s {
@ -63,6 +68,7 @@ class vvp_fun_delay : public vvp_net_fun_t, private vvp_gen_event_s {
~vvp_fun_delay();
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
void recv_real(vvp_net_ptr_t port, double bit);
//void recv_long(vvp_net_ptr_t port, long bit);
private:
@ -71,11 +77,17 @@ class vvp_fun_delay : public vvp_net_fun_t, private vvp_gen_event_s {
private:
vvp_net_t*net_;
vvp_delay_t delay_;
vvp_vector4_t cur_;
bool flag_vec4_, flag_real_;
vvp_vector4_t cur_vec4_;
double cur_real_;
};
/*
* $Log: delay.h,v $
* Revision 1.9 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.8 2005/06/22 00:04:49 steve
* Reduce vvp_vector4 copies by using const references.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.54 2005/05/24 01:43:27 steve Exp $"
#ident "$Id: lexor.lex,v 1.55 2005/07/06 04:29:25 steve Exp $"
#endif
# include "parse_misc.h"
@ -84,10 +84,12 @@
/* These are some keywords that are recognized. */
".arith/div" { return K_ARITH_DIV; }
".arith/div.r" { return K_ARITH_DIV_R; }
".arith/div.s" { return K_ARITH_DIV_S; }
".arith/mod" { return K_ARITH_MOD; }
".arith/mult" { return K_ARITH_MULT; }
".arith/sub" { return K_ARITH_SUB; }
".arith/sub.r" { return K_ARITH_SUB_R; }
".arith/sum" { return K_ARITH_SUM; }
".cmp/eeq" { return K_CMP_EEQ; }
".cmp/eq" { return K_CMP_EQ; }
@ -104,6 +106,7 @@
".extend/s" { return K_EXTEND_S; }
".functor" { return K_FUNCTOR; }
".net" { return K_NET; }
".net/real" { return K_NET_R; }
".net/s" { return K_NET_S; }
".param" { return K_PARAM; }
".part" { return K_PART; }
@ -124,9 +127,9 @@
".timescale" { return K_TIMESCALE; }
".ufunc" { return K_UFUNC; }
".var" { return K_VAR; }
".var/real" { return K_VAR_R; }
".var/s" { return K_VAR_S; }
".var/i" { return K_VAR_I; /* integer */ }
".word" { return K_WORD; }
".udp" { return K_UDP; }
".udp/c"(omb)? { return K_UDP_C; }
".udp/s"(equ)? { return K_UDP_S; }
@ -196,6 +199,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.55 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.54 2005/05/24 01:43:27 steve
* Add a sign-extension node.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: logic.cc,v 1.31 2005/06/26 21:08:38 steve Exp $"
#ident "$Id: logic.cc,v 1.32 2005/07/06 04:29:25 steve Exp $"
#endif
# include "logic.h"
@ -175,6 +175,14 @@ void vvp_fun_bufz::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
vvp_send_vec4(ptr.ptr()->out, bit);
}
void vvp_fun_bufz::recv_real(vvp_net_ptr_t ptr, double bit)
{
if (ptr.port() != 0)
return;
vvp_send_real(ptr.ptr()->out, bit);
}
vvp_fun_muxz::vvp_fun_muxz(unsigned wid)
: a_(wid), b_(wid)
{
@ -377,6 +385,9 @@ void compile_functor(char*label, char*type, unsigned width,
/*
* $Log: logic.cc,v $
* Revision 1.32 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.31 2005/06/26 21:08:38 steve
* AND functor explicitly knows its width.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: logic.h,v 1.21 2005/06/26 21:08:38 steve Exp $"
#ident "$Id: logic.h,v 1.22 2005/07/06 04:29:25 steve Exp $"
#endif
# include "vvp_net.h"
@ -99,6 +99,7 @@ class vvp_fun_bufz: public vvp_net_fun_t {
virtual ~vvp_fun_bufz();
void recv_vec4(vvp_net_ptr_t p, const vvp_vector4_t&bit);
void recv_real(vvp_net_ptr_t p, double bit);
private:
};
@ -143,6 +144,9 @@ extern const unsigned char ft_XOR[];
/*
* $Log: logic.h,v $
* Revision 1.22 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.21 2005/06/26 21:08:38 steve
* AND functor explicitly knows its width.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: parse.y,v 1.76 2005/06/17 03:46:53 steve Exp $"
#ident "$Id: parse.y,v 1.77 2005/07/06 04:29:25 steve Exp $"
#endif
# include "parse_misc.h"
@ -57,20 +57,19 @@ extern FILE*yyin;
};
%token K_ARITH_DIV K_ARITH_DIV_S K_ARITH_MOD K_ARITH_MULT
%token K_ARITH_SUB K_ARITH_SUM
%token K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD K_ARITH_MULT
%token K_ARITH_SUB K_ARITH_SUB_R K_ARITH_SUM
%token K_CMP_EEQ K_CMP_EQ K_CMP_NEE K_CMP_NE
%token K_CMP_GE K_CMP_GE_S K_CMP_GT K_CMP_GT_S
%token K_CONCAT K_DFF
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_NET K_NET_S
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_NET K_NET_S K_NET_R
%token K_PARAM K_PART K_PART_PV
%token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
%token K_UDP K_UDP_C K_UDP_S
%token K_MEM K_MEM_P K_MEM_I
%token K_WORD
%token K_VAR K_VAR_S K_VAR_I K_vpi_call K_vpi_func K_vpi_func_r
%token K_VAR K_VAR_S K_VAR_I K_VAR_R K_vpi_call K_vpi_func K_vpi_func_r
%token K_disable K_fork
%token K_vpi_module K_vpi_time_precision
@ -211,6 +210,11 @@ statement
compile_arith_div($1, $3, false, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_DIV_R T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_div_r($1, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_DIV_S T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_div($1, $3, true, obj.cnt, obj.vect);
@ -231,6 +235,11 @@ statement
compile_arith_sub($1, $3, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_SUB_R T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_sub_r($1, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_SUM T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_sum($1, $3, obj.cnt, obj.vect);
@ -335,11 +344,6 @@ statement
{ compile_event($1, 0, $3.cnt, $3.vect); }
/* match word statements. */
| T_LABEL K_WORD T_SYMBOL ',' T_STRING ';'
{ compile_word($1, $3, $5); }
/* Instructions may have a label, and have zero or more
operands. The meaning of and restrictions on the operands depends
on the specific instruction. */
@ -441,6 +445,9 @@ statement
| T_LABEL K_VAR_I T_STRING ',' T_NUMBER ',' T_NUMBER ';'
{ compile_variable($1, $3, $5, $7, 2 /* integer */); }
| T_LABEL K_VAR_R T_STRING ',' signed_t_number ',' signed_t_number ';'
{ compile_var_real($1, $3, $5, $7); }
/* Net statements are similar to .var statements, except that they
declare nets, and they have an input list. */
@ -452,6 +459,10 @@ statement
',' symbols_net ';'
{ compile_net($1, $3, $5, $7, true, $9.cnt, $9.vect); }
| T_LABEL K_NET_R T_STRING ',' signed_t_number ',' signed_t_number
',' symbols_net ';'
{ compile_net_real($1, $3, $5, $7, $9.cnt, $9.vect); }
/* Parameter statements come in a few simple forms. The most basic
is the string parameter. */
@ -690,6 +701,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.77 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.76 2005/06/17 03:46:53 steve
* Make functors know their own width.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: schedule.cc,v 1.38 2005/06/22 18:30:12 steve Exp $"
#ident "$Id: schedule.cc,v 1.39 2005/07/06 04:29:25 steve Exp $"
#endif
# include "schedule.h"
@ -116,6 +116,18 @@ void assign_vector8_event_s::run_run(void)
vvp_send_vec8(ptr, val);
}
struct assign_real_event_s : public event_s {
vvp_net_ptr_t ptr;
double val;
void run_run(void);
};
void assign_real_event_s::run_run(void)
{
count_assign_events += 1;
vvp_send_real(ptr, val);
}
struct assign_memory_word_s : public event_s {
vvp_memory_t mem;
unsigned adr;
@ -475,6 +487,14 @@ void schedule_set_vector(vvp_net_ptr_t ptr, vvp_vector8_t bit)
schedule_event_(cur, 0, SEQ_ACTIVE);
}
void schedule_set_vector(vvp_net_ptr_t ptr, double bit)
{
struct assign_real_event_s*cur = new struct assign_real_event_s;
cur->ptr = ptr;
cur->val = bit;
schedule_event_(cur, 0, SEQ_ACTIVE);
}
void schedule_generic(vvp_gen_event_t obj, vvp_time64_t delay, bool sync_flag)
{
struct generic_event_s*cur = new generic_event_s;
@ -581,6 +601,9 @@ void schedule_simulate(void)
/*
* $Log: schedule.cc,v $
* Revision 1.39 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.38 2005/06/22 18:30:12 steve
* Inline more simple stuff, and more vector4_t by const reference for performance.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: schedule.h,v 1.24 2005/06/22 18:30:12 steve Exp $"
#ident "$Id: schedule.h,v 1.25 2005/07/06 04:29:25 steve Exp $"
#endif
# include "vthread.h"
@ -66,6 +66,7 @@ extern void schedule_assign_memory_word(vvp_memory_t mem,
*/
extern void schedule_set_vector(vvp_net_ptr_t ptr, vvp_vector4_t val);
extern void schedule_set_vector(vvp_net_ptr_t ptr, vvp_vector8_t val);
extern void schedule_set_vector(vvp_net_ptr_t ptr, double val);
/*
@ -131,6 +132,9 @@ extern unsigned long count_event_pool;
/*
* $Log: schedule.h,v $
* Revision 1.25 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.24 2005/06/22 18:30:12 steve
* Inline more simple stuff, and more vector4_t by const reference for performance.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_callback.cc,v 1.38 2005/06/12 01:10:26 steve Exp $"
#ident "$Id: vpi_callback.cc,v 1.39 2005/07/06 04:29:25 steve Exp $"
#endif
/*
@ -29,6 +29,7 @@
# include <vpi_user.h>
# include "vpi_priv.h"
# include "vvp_net.h"
# include "schedule.h"
# include "event.h"
# include <stdio.h>
@ -134,8 +135,7 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
assert(sig_fun);
/* Attach the __vpiCallback object to the signal. */
obj->next = sig_fun->vpi_callbacks;
sig_fun->vpi_callbacks = obj;
sig_fun->add_vpi_callback(obj);
break;
case vpiRealVar:
@ -427,15 +427,31 @@ void callback_execute(struct __vpiCallback*cur)
vpi_mode_flag = save_mode;
}
vvp_vpi_callback::vvp_vpi_callback()
{
vpi_callbacks_ = 0;
}
vvp_vpi_callback::~vvp_vpi_callback()
{
assert(vpi_callbacks_ == 0);
}
void vvp_vpi_callback::add_vpi_callback(__vpiCallback*cb)
{
cb->next = vpi_callbacks_;
vpi_callbacks_ = cb;
}
/*
* A vvp_fun_signal uses this method to run its callbacks whenever it
* has a value change. If the cb_rtn is non-nil, then call the
* callback function. If the cb_rtn pointer is nil, then the object
* has been marked for deletion. Free it.
*/
void vvp_fun_signal::run_vpi_callbacks()
void vvp_vpi_callback::run_vpi_callbacks()
{
struct __vpiCallback *next = vpi_callbacks;
struct __vpiCallback *next = vpi_callbacks_;
struct __vpiCallback *prev = 0;
while (next) {
@ -443,26 +459,15 @@ void vvp_fun_signal::run_vpi_callbacks()
next = cur->next;
if (cur->cb_data.cb_rtn != 0) {
if (cur->cb_data.value) {
switch (cur->cb_data.value->format) {
case vpiScalarVal:
cur->cb_data.value->value.scalar = value(0);
break;
case vpiSuppressVal:
break;
default:
fprintf(stderr, "vpi_callback: value "
"format %d not supported\n",
cur->cb_data.value->format);
}
}
if (cur->cb_data.value)
get_value(cur->cb_data.value);
callback_execute(cur);
prev = cur;
} else if (prev == 0) {
vpi_callbacks = next;
vpi_callbacks_ = next;
cur->next = 0;
vpi_free_object(&cur->base);
@ -475,9 +480,84 @@ void vvp_fun_signal::run_vpi_callbacks()
}
}
void vvp_fun_signal::get_value(struct t_vpi_value*vp)
{
switch (vp->format) {
case vpiScalarVal:
vp->value.scalar = value(0);
break;
case vpiSuppressVal:
break;
default:
fprintf(stderr, "vpi_callback: value "
"format %d not supported\n",
vp->format);
}
}
void vvp_fun_signal_real::get_value(struct t_vpi_value*vp)
{
char*rbuf = need_result_buf(64 + 1, RBUF_VAL);
switch (vp->format) {
case vpiObjTypeVal:
vp->format = vpiRealVal;
case vpiRealVal:
vp->value.real = real_value();
break;
case vpiIntVal:
vp->value.integer = (int)(real_value() + 0.5);
break;
case vpiDecStrVal:
sprintf(rbuf, "%0.0f", real_value());
vp->value.str = rbuf;
break;
case vpiHexStrVal:
sprintf(rbuf, "%lx", (long)real_value());
vp->value.str = rbuf;
break;
case vpiBinStrVal: {
unsigned long val = (unsigned long)real_value();
unsigned len = 0;
while (val > 0) {
len += 1;
val /= 2;
}
val = (unsigned long)real_value();
for (unsigned idx = 0 ; idx < len ; idx += 1) {
rbuf[len-idx-1] = (val & 1)? '1' : '0';
val /= 2;
}
rbuf[len] = 0;
if (len == 0) {
rbuf[0] = '0';
rbuf[1] = 0;
}
vp->value.str = rbuf;
break;
}
default:
fprintf(stderr, "vpi_callback: value "
"format %d not supported\n",
vp->format);
}
}
/*
* $Log: vpi_callback.cc,v $
* Revision 1.39 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.38 2005/06/12 01:10:26 steve
* Remove useless references to functor.h
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_priv.h,v 1.63 2005/06/13 00:54:04 steve Exp $"
#ident "$Id: vpi_priv.h,v 1.64 2005/07/06 04:29:25 steve Exp $"
#endif
# include "vpi_user.h"
@ -187,6 +187,7 @@ extern vpiHandle vpip_make_reg(const char*name, int msb, int lsb,
extern vpiHandle vpip_make_net(const char*name, int msb, int lsb,
bool signed_flag, vvp_net_t*node);
/*
* These methods support the vpi creation of events. The name string
* passed in will be saved, so the caller must allocate it (or not
@ -221,7 +222,13 @@ extern vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name);
/*
* These are the various variable types.
*/
extern vpiHandle vpip_make_real_var(const char*name);
struct __vpiRealVar {
struct __vpiHandle base;
const char*name;
vvp_net_t*net;
};
extern vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net);
/*
* When a loaded VPI module announces a system task/function, one
@ -422,6 +429,9 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type);
/*
* $Log: vpi_priv.h,v $
* Revision 1.64 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.63 2005/06/13 00:54:04 steve
* More unified vec4 to hex string functions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_real.cc,v 1.9 2004/05/19 03:26:25 steve Exp $"
#ident "$Id: vpi_real.cc,v 1.10 2005/07/06 04:29:25 steve Exp $"
#endif
# include "vpi_priv.h"
@ -31,14 +31,6 @@
# include <assert.h>
struct __vpiRealVar {
struct __vpiHandle base;
const char*name;
double value;
struct __vpiCallback*cb;
};
static char* real_var_get_str(int code, vpiHandle ref)
{
assert(ref->vpi_type->type_code == vpiRealVar);
@ -63,79 +55,27 @@ static void real_var_get_value(vpiHandle ref, s_vpi_value*vp)
{
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
char*rbuf = need_result_buf(64 + 1, RBUF_VAL);
struct __vpiRealVar*rfp
= (struct __vpiRealVar*)ref;
vvp_fun_signal_real*fun
= dynamic_cast<vvp_fun_signal_real*>(rfp->net->fun);
switch (vp->format) {
case vpiObjTypeVal:
vp->format = vpiRealVal;
case vpiRealVal:
vp->value.real = rfp->value;
break;
case vpiIntVal:
vp->value.integer = (int)(rfp->value + 0.5);
break;
case vpiDecStrVal:
sprintf(rbuf, "%0.0f", rfp->value);
vp->value.str = rbuf;
break;
case vpiHexStrVal:
sprintf(rbuf, "%lx", (long)rfp->value);
vp->value.str = rbuf;
break;
case vpiBinStrVal: {
unsigned long val = (unsigned long)rfp->value;
unsigned len = 0;
while (val > 0) {
len += 1;
val /= 2;
}
val = (unsigned long)rfp->value;
for (unsigned idx = 0 ; idx < len ; idx += 1) {
rbuf[len-idx-1] = (val & 1)? '1' : '0';
val /= 2;
}
rbuf[len] = 0;
if (len == 0) {
rbuf[0] = '0';
rbuf[1] = 0;
}
vp->value.str = rbuf;
break;
}
default:
fprintf(stderr, "ERROR: Unsupported format code: %d\n",
vp->format);
assert(0);
}
fun->get_value(vp);
}
static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp)
{
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
struct __vpiRealVar*rfp
= (struct __vpiRealVar*)ref;
vvp_fun_signal_real*fun
= dynamic_cast<vvp_fun_signal_real*>(rfp->net->fun);
vvp_net_ptr_t destination (rfp->net, 0);
assert(vp->format == vpiRealVal);
rfp->value = vp->value.real;
for (struct __vpiCallback*cur = rfp->cb ; cur ; cur = cur->next) {
cur->cb_data.time->type = vpiSimTime;
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
assert(cur->cb_data.cb_rtn != 0);
(cur->cb_data.cb_rtn)(&cur->cb_data);
}
vvp_send_real(destination, vp->value.real);
return 0;
}
@ -158,26 +98,31 @@ static const struct __vpirt vpip_real_var_rt = {
void vpip_real_value_change(struct __vpiCallback*cbh,
vpiHandle ref)
{
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
cbh->next = rfp->cb;
rfp->cb = cbh;
struct __vpiRealVar*rfp
= (struct __vpiRealVar*)ref;
vvp_fun_signal_real*fun
= dynamic_cast<vvp_fun_signal_real*>(rfp->net->fun);
fun->add_vpi_callback(cbh);
}
vpiHandle vpip_make_real_var(const char*name)
vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net)
{
struct __vpiRealVar*obj = (struct __vpiRealVar*)
malloc(sizeof(struct __vpiRealVar));
obj->base.vpi_type = &vpip_real_var_rt;
obj->name = vpip_name_string(name);
obj->value = 0.0;
obj->cb = 0;
obj->net = net;
return &obj->base;
}
/*
* $Log: vpi_real.cc,v $
* Revision 1.10 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.9 2004/05/19 03:26:25 steve
* Support delayed/non-blocking assignment to reals and others.
*

View File

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: vvp_net.cc,v 1.40 2005/06/27 21:13:14 steve Exp $"
#ident "$Id: vvp_net.cc,v 1.41 2005/07/06 04:29:25 steve Exp $"
# include "config.h"
# include "vvp_net.h"
@ -677,13 +677,52 @@ void vvp_fun_drive::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
/* **** vvp_fun_signal methods **** */
vvp_fun_signal::vvp_fun_signal(unsigned wid)
: bits4_(wid), needs_init_(true)
vvp_fun_signal_base::vvp_fun_signal_base()
{
force_link = 0;
vpi_callbacks = 0;
needs_init_ = true;
continuous_assign_active_ = false;
force_active_ = false;
force_link = 0;
}
void vvp_fun_signal_base::deassign()
{
continuous_assign_active_ = false;
}
/*
* The signal functor takes commands as long values to port-3. This
* method interprets those commands.
*/
void vvp_fun_signal_base::recv_long(vvp_net_ptr_t ptr, long bit)
{
switch (ptr.port()) {
case 3: // Command port
switch (bit) {
case 1: // deassign command
deassign();
break;
case 2: // release/net
release(ptr, true);
break;
case 3: // release/reg
release(ptr, false);
break;
default:
assert(0);
break;
}
break;
default: // Other ports ar errors.
assert(0);
break;
}
}
vvp_fun_signal::vvp_fun_signal(unsigned wid)
: bits4_(wid)
{
}
/*
@ -783,11 +822,6 @@ void vvp_fun_signal::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
}
}
void vvp_fun_signal::deassign()
{
continuous_assign_active_ = false;
}
void vvp_fun_signal::release(vvp_net_ptr_t ptr, bool net)
{
force_active_ = false;
@ -799,36 +833,6 @@ void vvp_fun_signal::release(vvp_net_ptr_t ptr, bool net)
}
}
/*
* The signal functor takes commands as long values to port-3. This
* method interprets those commands.
*/
void vvp_fun_signal::recv_long(vvp_net_ptr_t ptr, long bit)
{
switch (ptr.port()) {
case 3: // Command port
switch (bit) {
case 1: // deassign command
deassign();
break;
case 2: // release/net
release(ptr, true);
break;
case 3: // release/reg
release(ptr, false);
break;
default:
assert(0);
break;
}
break;
default: // Other ports ar errors.
assert(0);
break;
}
}
unsigned vvp_fun_signal::size() const
{
if (force_active_)
@ -869,6 +873,63 @@ vvp_vector4_t vvp_fun_signal::vec4_value() const
return bits4_;
}
vvp_fun_signal_real::vvp_fun_signal_real()
{
}
double vvp_fun_signal_real::real_value() const
{
if (force_active_)
return force_;
else
return bits_;
}
void vvp_fun_signal_real::recv_real(vvp_net_ptr_t ptr, double bit)
{
switch (ptr.port()) {
case 0:
if (!continuous_assign_active_) {
if (needs_init_ || (bits_ != bit)) {
bits_ = bit;
needs_init_ = false;
vvp_send_real(ptr.ptr()->out, bit);
run_vpi_callbacks();
}
}
break;
case 1: // Continuous assign value
continuous_assign_active_ = true;
bits_ = bit;
vvp_send_real(ptr.ptr()->out, bit);
run_vpi_callbacks();
break;
case 2: // Force value
force_active_ = true;
force_ = bit;
vvp_send_real(ptr.ptr()->out, bit);
run_vpi_callbacks();
break;
default:
assert(0);
break;
}
}
void vvp_fun_signal_real::release(vvp_net_ptr_t ptr, bool net)
{
force_active_ = false;
if (net) {
vvp_send_real(ptr.ptr()->out, bits_);
run_vpi_callbacks();
} else {
bits_ = force_;
}
}
/* **** vvp_wide_fun_* methods **** */
vvp_wide_fun_core::vvp_wide_fun_core(vvp_net_t*net, unsigned nports)
@ -1329,6 +1390,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
/*
* $Log: vvp_net.cc,v $
* Revision 1.41 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.40 2005/06/27 21:13:14 steve
* Make vector2 multiply more portable.
*

View File

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: vvp_net.h,v 1.41 2005/06/26 01:57:22 steve Exp $"
#ident "$Id: vvp_net.h,v 1.42 2005/07/06 04:29:25 steve Exp $"
# include "config.h"
# include <stddef.h>
@ -739,14 +739,53 @@ class vvp_fun_part_var : public vvp_net_fun_t {
* to port-0 (or port-1 if continuous assing is active) will
* propagate starting at the next input change.
*/
class vvp_fun_signal : public vvp_net_fun_t {
class vvp_vpi_callback {
public:
vvp_vpi_callback();
virtual ~vvp_vpi_callback();
void run_vpi_callbacks();
void add_vpi_callback(struct __vpiCallback*);
virtual void get_value(struct t_vpi_value*value) =0;
private:
struct __vpiCallback*vpi_callbacks_;
};
class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_vpi_callback {
public:
vvp_fun_signal_base();
void recv_long(vvp_net_ptr_t port, long bit);
public:
/* The %force/link instruction needs a place to write the
source node of the force, so that subsequent %force and
%release instructions can undo the link as needed. */
struct vvp_net_t*force_link;
protected:
// This is true until at least one propagation happens.
bool needs_init_;
bool continuous_assign_active_;
bool force_active_;
void deassign();
virtual void release(vvp_net_ptr_t ptr, bool net) =0;
};
class vvp_fun_signal : public vvp_fun_signal_base {
public:
explicit vvp_fun_signal(unsigned wid);
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
void recv_long(vvp_net_ptr_t port, long bit);
// Part select variants of above
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
@ -759,32 +798,37 @@ class vvp_fun_signal : public vvp_net_fun_t {
vvp_vector4_t vec4_value() const;
// Commands
void deassign();
void release(vvp_net_ptr_t port, bool net);
public:
struct __vpiCallback*vpi_callbacks;
/* The %force/link instruction needs a place to write the
source node of the force, so that subsequent %force and
%release instructions can undo the link as needed. */
struct vvp_net_t*force_link;
void get_value(struct t_vpi_value*value);
private:
vvp_vector4_t bits4_;
vvp_vector8_t bits8_;
bool type_is_vector8_() const { return bits8_.size() > 0; }
// This is true until at least one propagation happens.
bool needs_init_;
bool continuous_assign_active_;
vvp_vector4_t force_;
bool force_active_;
};
class vvp_fun_signal_real : public vvp_fun_signal_base {
public:
explicit vvp_fun_signal_real();
//void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
void recv_real(vvp_net_ptr_t port, double bit);
// Get information about the vector value.
double real_value() const;
// Commands
void release(vvp_net_ptr_t port, bool net);
void get_value(struct t_vpi_value*value);
private:
void run_vpi_callbacks();
double bits_;
double force_;
};
/*
@ -910,6 +954,9 @@ inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val,
/*
* $Log: vvp_net.h,v $
* Revision 1.42 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.41 2005/06/26 01:57:22 steve
* Make bit masks of vector4_t 64bit aware.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: words.cc,v 1.2 2003/02/11 05:20:45 steve Exp $"
#ident "$Id: words.cc,v 1.3 2005/07/06 04:29:25 steve Exp $"
#endif
# include "compile.h"
@ -30,13 +30,35 @@
#endif
# include <assert.h>
#if 0
void compile_word(char*label, char*type, char*name)
{
assert(strcmp(type, "real") == 0);
free(type);
vpiHandle obj = vpip_make_real_var(name);
vvp_fun_signal_real*fun = new vvp_fun_signal_real;
vvp_net_t*net = new vvp_net_t;
net->fun = fun;
define_functor_symbol(label, net);
vpiHandle obj = vpip_make_real_var(name, net);
free(name);
compile_vpi_symbol(label, obj);
free(label);
vpip_attach_to_current_scope(obj);
}
#endif
void compile_var_real(char*label, char*name, int msb, int lsb)
{
vvp_fun_signal_real*fun = new vvp_fun_signal_real;
vvp_net_t*net = new vvp_net_t;
net->fun = fun;
define_functor_symbol(label, net);
vpiHandle obj = vpip_make_real_var(name, net);
free(name);
compile_vpi_symbol(label, obj);
@ -45,8 +67,99 @@ void compile_word(char*label, char*type, char*name)
vpip_attach_to_current_scope(obj);
}
/*
* A variable is a special functor, so we allocate that functor and
* write the label into the symbol table.
*/
void compile_variable(char*label, char*name, int msb, int lsb,
char signed_flag)
{
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_fun_signal*vsig = new vvp_fun_signal(wid);
vvp_net_t*node = new vvp_net_t;
node->fun = vsig;
define_functor_symbol(label, node);
/* Make the vpiHandle for the reg. */
vpiHandle obj = (signed_flag > 1) ?
vpip_make_int(name, msb, lsb, node) :
vpip_make_reg(name, msb, lsb, signed_flag!=0, node);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
free(name);
}
/*
* Here we handle .net records from the vvp source:
*
* <label> .net <name>, <msb>, <lsb>, <input> ;
* <label> .net/s <name>, <msb>, <lsb>, <input> ;
*
* Create a VPI handle to represent it, and fill that handle in with
* references into the net.
*/
void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
unsigned argc, struct symb_s*argv)
{
unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
vvp_net_t*node = new vvp_net_t;
vvp_fun_signal*vsig = new vvp_fun_signal(wid);
node->fun = vsig;
/* Add the label into the functor symbol table. */
define_functor_symbol(label, node);
assert(argc == 1);
/* Connect the source to my input. */
inputs_connect(node, 1, argv);
/* Make the vpiHandle for the reg. */
vpiHandle obj = vpip_make_net(name, msb, lsb, signed_flag, node);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
free(name);
free(argv);
}
void compile_net_real(char*label, char*name, int msb, int lsb,
unsigned argc, struct symb_s*argv)
{
vvp_net_t*net = new vvp_net_t;
vvp_fun_signal_real*fun = new vvp_fun_signal_real;
net->fun = fun;
/* Add the label into the functor symbol table. */
define_functor_symbol(label, net);
assert(argc == 1);
/* Connect the source to my input. */
inputs_connect(net, 1, argv);
/* Make the vpiHandle for the reg. */
vpiHandle obj = vpip_make_real_var(name, net);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
free(name);
free(argv);
}
/*
* $Log: words.cc,v $
* Revision 1.3 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*
* Revision 1.2 2003/02/11 05:20:45 steve
* Include vpiRealVar objects in vpiVariables scan.
*