Require explicit delay node from source.

This commit is contained in:
steve 2006-01-02 05:32:06 +00:00
parent 1721799050
commit b7861fa6e8
8 changed files with 224 additions and 58 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.74 2005/11/25 17:55:26 steve Exp $
* $Id: README.txt,v 1.75 2006/01/02 05:32:06 steve Exp $
*/
VVP SIMULATION ENGINE
@ -128,7 +128,8 @@ label is required for functors.
The general syntax of a functor is:
<label> .functor <type> [ (<delay>) ], symbol_list ;
<label> .functor <type>, symbol_list ;
<label> .functor <type> [<drive0> <drive1>], symbol_list ;
The symbol list is 4 names of labels of other functors. These connect
inputs of the functor of the statement to the output of other
@ -309,7 +310,7 @@ that arrive through them, while .net nodes reduce strength values to
information really is possible.
The <label> is required and is used to locate the net object that is
represents. This label does not map to a functor, so only references
vrepresents. This label does not map to a functor, so only references
that know they want to access .nets are able to locate the symbol. In
particular, this includes behavioral %load and %wait instructions. The
references to net and reg objects are done through the .net label
@ -320,6 +321,23 @@ The .alias statements do not create new nodes, but instead create net
names that are aliases of an existing node. This handles special cases
where a net has different names, possibly in different scopes.
DELAY STATEMENTS:
Delay nodes are structural net delay nodes that carry and manage
propagation delays. Delay nodes can have fixed delays or variable
delays. Fixed delay nodes have only the input that is to be
delayed. The delay amount is given on the node line. Variable delay
nodes have three extra inputs to receive the rise, fall and decay
times that are used for delay.
.delay ( <rise>, <fall>, <decay> ) <input> ;
.delay <input>, <rise>, <fall>, <decay> ;
The first form above takes three constant numbers as the initial
delay, and takes a single input. The second form takes 4 net inputs,
with the first being the value to delay, and the remaining to be the
delay values to use.
MEMORY STATEMENTS:
Memories are arrays of words, each word a vvp_vector4_t vector of the

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.215 2005/11/26 17:16:05 steve Exp $"
#ident "$Id: compile.cc,v 1.216 2006/01/02 05:32:06 steve Exp $"
#endif
# include "arith.h"
@ -1025,6 +1025,35 @@ void compile_cmp_gt(char*label, long wid, bool signed_flag,
make_arith(arith, label, argc, argv);
}
void compile_delay(char*label, vvp_delay_t*delay, struct symb_s arg)
{
vvp_net_t*net = new vvp_net_t;
vvp_fun_delay*obj = new vvp_fun_delay(net, BIT4_X, *delay);
net->fun = obj;
delete delay;
input_connect(net, 0, arg.text);
define_functor_symbol(label, net);
free(label);
}
void compile_delay(char*label, unsigned argc, struct symb_s*argv)
{
vvp_delay_t stub (0, 0, 0);
vvp_net_t*net = new vvp_net_t;
vvp_fun_delay*obj = new vvp_fun_delay(net, BIT4_X, stub);
net->fun = obj;
inputs_connect(net, argc, argv);
free(argv);
define_functor_symbol(label, net);
free(label);
}
/*
* Extend nodes.
*/
@ -1482,6 +1511,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.216 2006/01/02 05:32:06 steve
* Require explicit delay node from source.
*
* Revision 1.215 2005/11/26 17:16:05 steve
* Force instruction that can be indexed.
*

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.77 2005/11/25 17:55:26 steve Exp $"
#ident "$Id: compile.h,v 1.78 2006/01/02 05:32:07 steve Exp $"
#endif
# include <stdio.h>
@ -90,8 +90,7 @@ extern void compile_vpi_time_precision(long pre);
* to existing functors to manage the linking.
*/
extern void compile_functor(char*label, char*type, unsigned width,
vvp_delay_t*delay, unsigned ostr0,
unsigned ostr1,
unsigned ostr0, unsigned ostr1,
unsigned argc, struct symb_s*argv);
@ -108,6 +107,12 @@ extern void compile_concat(char*label, unsigned w0, unsigned w1,
unsigned w2, unsigned w3,
unsigned argc, struct symb_s*argv);
/*
* Compile delay nodes of various form.
*/
extern void compile_delay(char*label, vvp_delay_t*del, struct symb_s input);
extern void compile_delay(char*label, unsigned argc, struct symb_s*argv);
/*
* This is called by the parser to create a part select node.
* See the PART SELECT STATEMENT section in the README.txt
@ -337,6 +342,9 @@ extern void compile_alias_real(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.78 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.77 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*

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.11 2005/11/10 13:27:16 steve Exp $"
#ident "$Id: delay.cc,v 1.12 2006/01/02 05:32:07 steve Exp $"
#endif
#include "delay.h"
@ -25,6 +25,15 @@
#include <iostream>
#include <assert.h>
void vvp_delay_t::calculate_min_delay_()
{
min_delay_ = rise_;
if (fall_ < min_delay_)
min_delay_ = fall_;
if (decay_ < min_delay_)
min_delay_ = decay_;
}
vvp_delay_t::vvp_delay_t(vvp_time64_t rise, vvp_time64_t fall)
{
rise_ = rise;
@ -39,11 +48,7 @@ vvp_delay_t::vvp_delay_t(vvp_time64_t rise, vvp_time64_t fall, vvp_time64_t deca
fall_ = fall;
decay_= decay;
min_delay_ = rise_;
if (fall_ < min_delay_)
min_delay_ = fall_;
if (decay_ < min_delay_)
min_delay_ = decay_;
calculate_min_delay_();
}
vvp_delay_t::~vvp_delay_t()
@ -96,12 +101,38 @@ vvp_time64_t vvp_delay_t::get_min_delay() const
return min_delay_;
}
void vvp_delay_t::set_rise(vvp_time64_t val)
{
rise_ = val;
if (val < min_delay_)
min_delay_ = val;
else
calculate_min_delay_();
}
void vvp_delay_t::set_fall(vvp_time64_t val)
{
fall_ = val;
if (val < min_delay_)
min_delay_ = val;
else
calculate_min_delay_();
}
void vvp_delay_t::set_decay(vvp_time64_t val)
{
decay_ = val;
if (val < min_delay_)
min_delay_ = val;
else
calculate_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;
run_run_ptr_ = 0;
}
vvp_fun_delay::~vvp_fun_delay()
@ -117,6 +148,26 @@ vvp_fun_delay::~vvp_fun_delay()
*/
void vvp_fun_delay::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
if (port.port() > 0) {
// Get the integer value of the bit vector, or 0 if
// there are X or Z bits.
unsigned long val = 0;
vector4_to_value(bit, val);
switch (port.port()) {
case 1:
delay_.set_rise(val);
return;
case 2:
delay_.set_fall(val);
return;
case 3:
delay_.set_decay(val);
return;
}
return;
}
if (cur_vec4_.eeq(bit))
return;
@ -142,8 +193,27 @@ void vvp_fun_delay::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
if (use_delay == 0) {
vvp_send_vec4(net_->out, cur_vec4_);
} else {
flag_vec4_ = true;
flag_real_ = false;
run_run_ptr_ = &vvp_fun_delay::run_run_vec4_;
schedule_generic(this, use_delay, false);
}
}
void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit)
{
assert(port.port() == 0);
if (cur_vec8_.eeq(bit))
return;
/* XXXX FIXME: For now, just use the minimum delay. */
vvp_time64_t use_delay;
use_delay = delay_.get_min_delay();
cur_vec8_ = bit;
if (use_delay == 0) {
vvp_send_vec8(net_->out, cur_vec8_);
} else {
run_run_ptr_ = &vvp_fun_delay::run_run_vec8_;
schedule_generic(this, use_delay, false);
}
}
@ -160,26 +230,37 @@ void vvp_fun_delay::recv_real(vvp_net_ptr_t port, double bit)
if (use_delay == 0) {
vvp_send_real(net_->out, cur_real_);
} else {
flag_vec4_ = false;
flag_real_ = true;
run_run_ptr_ = &vvp_fun_delay::run_run_real_;
schedule_generic(this, use_delay, false);
}
}
void vvp_fun_delay::run_run()
{
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;
}
(this->*run_run_ptr_)();
}
void vvp_fun_delay::run_run_vec4_()
{
vvp_send_vec4(net_->out, cur_vec4_);
}
void vvp_fun_delay::run_run_vec8_()
{
vvp_send_vec8(net_->out, cur_vec8_);
}
void vvp_fun_delay::run_run_real_()
{
vvp_send_real(net_->out, cur_real_);
}
/*
* $Log: delay.cc,v $
* Revision 1.12 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.11 2005/11/10 13:27:16 steve
* Handle very wide % and / operations using expanded vector2 support.
*

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.9 2005/07/06 04:29:25 steve Exp $"
#ident "$Id: delay.h,v 1.10 2006/01/02 05:32:07 steve Exp $"
#endif
/*
@ -43,9 +43,15 @@ class vvp_delay_t {
vvp_time64_t get_delay(vvp_bit4_t from, vvp_bit4_t to);
vvp_time64_t get_min_delay() const;
void set_rise(vvp_time64_t val);
void set_fall(vvp_time64_t val);
void set_decay(vvp_time64_t val);
private:
vvp_time64_t rise_, fall_, decay_;
vvp_time64_t min_delay_;
void calculate_min_delay_();
};
/* vvp_fun_delay
@ -68,23 +74,33 @@ 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_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
void recv_real(vvp_net_ptr_t port, double bit);
//void recv_long(vvp_net_ptr_t port, long bit);
private:
virtual void run_run();
void run_run_vec4_();
void run_run_vec8_();
void run_run_real_();
private:
vvp_net_t*net_;
vvp_delay_t delay_;
bool flag_vec4_, flag_real_;
void (vvp_fun_delay::*run_run_ptr_)();
vvp_vector4_t cur_vec4_;
vvp_vector8_t cur_vec8_;
double cur_real_;
};
/*
* $Log: delay.h,v $
* Revision 1.10 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.9 2005/07/06 04:29:25 steve
* Implement real valued signals and arith nodes.
*

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.57 2005/11/25 17:55:26 steve Exp $"
#ident "$Id: lexor.lex,v 1.58 2006/01/02 05:32:07 steve Exp $"
#endif
# include "parse_misc.h"
@ -103,6 +103,7 @@
".cmp/gt" { return K_CMP_GT; }
".cmp/gt.s" { return K_CMP_GT_S; }
".concat" { return K_CONCAT; }
".delay" { return K_DELAY; }
".dff" { return K_DFF; }
".event" { return K_EVENT; }
".event/or" { return K_EVENT_OR; }
@ -204,6 +205,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.58 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.57 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*

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.35 2005/09/19 22:47:28 steve Exp $"
#ident "$Id: logic.cc,v 1.36 2006/01/02 05:32:07 steve Exp $"
#endif
# include "logic.h"
@ -473,7 +473,7 @@ void vvp_fun_xor::run_run()
*/
void compile_functor(char*label, char*type, unsigned width,
vvp_delay_t*delay, unsigned ostr0, unsigned ostr1,
unsigned ostr0, unsigned ostr1,
unsigned argc, struct symb_s*argv)
{
vvp_net_fun_t* obj = 0;
@ -566,29 +566,19 @@ void compile_functor(char*label, char*type, unsigned width,
/* If both the strengths are the default strong drive, then
there is no need for a specialized driver. Attach the label
to this node and we are finished. */
if (strength_aware || ostr0 == 6 && ostr1 == 6 && delay == 0) {
if (strength_aware || ostr0 == 6 && ostr1 == 6) {
define_functor_symbol(label, net);
free(label);
return;
}
vvp_net_t*net_drv = new vvp_net_t;
vvp_net_fun_t*obj_drv;
if (ostr0 == 6 && ostr1 == 6 && delay != 0) {
obj_drv = new vvp_fun_delay(net_drv, BIT4_X, *delay);
} else {
obj_drv = new vvp_fun_drive(BIT4_X, ostr0, ostr1);
}
vvp_net_fun_t*obj_drv = new vvp_fun_drive(BIT4_X, ostr0, ostr1);
net_drv->fun = obj_drv;
/* Point the gate to the drive node. */
net->out = vvp_net_ptr_t(net_drv, 0);
if (delay)
delete delay;
define_functor_symbol(label, net_drv);
free(label);
}
@ -596,6 +586,9 @@ void compile_functor(char*label, char*type, unsigned width,
/*
* $Log: logic.cc,v $
* Revision 1.36 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.35 2005/09/19 22:47:28 steve
* Prevent some excess scheduling of logic propagation events.
*

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.79 2005/11/25 17:55:26 steve Exp $"
#ident "$Id: parse.y,v 1.80 2006/01/02 05:32:07 steve Exp $"
#endif
# include "parse_misc.h"
@ -61,7 +61,7 @@ extern FILE*yyin;
%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_CONCAT K_DELAY K_DFF
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_NET K_NET_S K_NET_R
%token K_NET8 K_NET8_S
%token K_PARAM K_PART K_PART_PV
@ -91,7 +91,7 @@ extern FILE*yyin;
%type <argv> argument_opt argument_list
%type <vpi> argument
%type <cdelay> delay
%type <cdelay> delay delay_opt
%%
@ -131,15 +131,15 @@ statement
label and a type name, and may have operands. The functor may
also have a delay specification and output strengths. */
: T_LABEL K_FUNCTOR T_SYMBOL T_NUMBER delay ',' symbols ';'
{ compile_functor($1, $3, $4, $5, 6, 6, $7.cnt, $7.vect); }
: T_LABEL K_FUNCTOR T_SYMBOL T_NUMBER ',' symbols ';'
{ compile_functor($1, $3, $4, 6, 6, $6.cnt, $6.vect); }
| T_LABEL K_FUNCTOR T_SYMBOL T_NUMBER delay
| T_LABEL K_FUNCTOR T_SYMBOL T_NUMBER
'[' T_NUMBER T_NUMBER ']' ',' symbols ';'
{ unsigned str0 = $7;
unsigned str1 = $8;
compile_functor($1, $3, $4, $5, str0, str1,
$11.cnt, $11.vect);
{ unsigned str0 = $6;
unsigned str1 = $7;
compile_functor($1, $3, $4, str0, str1,
$10.cnt, $10.vect);
}
@ -153,7 +153,7 @@ statement
| T_LABEL K_UDP_C T_STRING ',' T_NUMBER ',' udp_table ';'
{ compile_udp_def(0, $1, $3, $5, 0, $7); }
| T_LABEL K_UDP T_SYMBOL delay ',' symbols ';'
| T_LABEL K_UDP T_SYMBOL delay_opt ',' symbols ';'
{ compile_udp_functor($1, $3, $4, $6.cnt, $6.vect); }
@ -285,6 +285,17 @@ statement
compile_cmp_gt($1, $3, true, obj.cnt, obj.vect);
}
/* Delay nodes take a set of numbers or a set of inputs. The delay
node takes two form, one with an array of constants and a single
input, and another with an array of inputs. */
| T_LABEL K_DELAY delay symbol ';'
{ compile_delay($1, $3, $4); }
| T_LABEL K_DELAY symbols ';'
{ struct symbv_s obj = $3;
compile_delay($1, obj.cnt, obj.vect);
}
/* DFF nodes have an output and take exactly 4 inputs. */
| T_LABEL K_DFF symbol ',' symbol ',' symbol ',' symbol ';'
@ -692,10 +703,10 @@ signed_t_number
| '-' T_NUMBER { $$ = -$2; }
;
delay_opt : delay { $$=$1; } | /* empty */ { $$=0; } ;
delay
: /* empty */
{ $$ = 0; }
| '(' T_NUMBER ')'
: '(' T_NUMBER ')'
{ $$ = new vvp_delay_t($2, $2); }
| '(' T_NUMBER ',' T_NUMBER ')'
{ $$ = new vvp_delay_t($2, $4); }
@ -722,6 +733,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.80 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*
* Revision 1.79 2005/11/25 17:55:26 steve
* Put vec8 and vec4 nets into seperate net classes.
*