Basic support for specify timing.

This commit is contained in:
steve 2006-09-23 04:57:19 +00:00
parent ceb6bf4afd
commit 0edb5a7547
26 changed files with 966 additions and 47 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.177 2006/09/20 22:31:45 steve Exp $"
#ident "$Id: Makefile.in,v 1.178 2006/09/23 04:57:19 steve Exp $"
#
#
SHELL = /bin/sh
@ -111,7 +111,7 @@ parse.o parse_misc.o pform.o pform_dump.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o PGenerate.o \
PExpr.o PGate.o PGenerate.o PSpec.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.40 2006/04/10 00:37:42 steve Exp $"
#ident "$Id: Module.h,v 1.41 2006/09/23 04:57:19 steve Exp $"
#endif
# include <list>
@ -35,6 +35,7 @@ class PExpr;
class PEIdent;
class PGate;
class PGenerate;
class PSpecPath;
class PTask;
class PFunction;
class PWire;
@ -122,6 +123,8 @@ class Module : public LineInfo {
the module definition. These are used at elaboration time. */
list<PGenerate*> generate_schemes;
list<PSpecPath*> specify_paths;
perm_string mod_name() const { return name_; }
void add_gate(PGate*gate);
@ -173,6 +176,9 @@ class Module : public LineInfo {
/*
* $Log: Module.h,v $
* Revision 1.41 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.40 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*

48
PSpec.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __PSpec_H
#define __PSpec_H
/*
* Copyright (c) 2006 Stephen Williams <steve@icarus.com>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.h,v 1.1 2006/09/23 04:57:19 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include <vector>
class PSpecPath : public LineInfo {
public:
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
~PSpecPath();
void elaborate(class Design*des, class NetScope*scope) const;
void dump(std::ostream&out, unsigned ind) const;
public:
// Ordered set of source nodes of a path
std::vector<perm_string> src;
// Ordered set of destination nodes of a path
std::vector<perm_string> dst;
std::vector<class PExpr*>delays;
};
#endif

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.167 2006/07/31 03:50:17 steve Exp $"
#ident "$Id: design_dump.cc,v 1.168 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -90,6 +90,25 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
return o;
}
void NetDelaySrc::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "specify delay src "
<< "(" << transition_delays_[IVL_PE_01]
<< "," << transition_delays_[IVL_PE_10]
<< "," << transition_delays_[IVL_PE_0z]
<< "/" << transition_delays_[IVL_PE_z1]
<< "," << transition_delays_[IVL_PE_1z]
<< "," << transition_delays_[IVL_PE_z0]
<< "/" << transition_delays_[IVL_PE_0x]
<< "," << transition_delays_[IVL_PE_x1]
<< "," << transition_delays_[IVL_PE_1x]
<< "/" << transition_delays_[IVL_PE_x0]
<< "," << transition_delays_[IVL_PE_xz]
<< "," << transition_delays_[IVL_PE_zx]
<< "): " << endl;
dump_node_pins(o, ind+4);
}
/* Dump a net. This can be a wire or register. */
void NetNet::dump_net(ostream&o, unsigned ind) const
{
@ -139,6 +158,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << setw(ind+4) << "" << "[" << idx << "]: " << nex
<< " " << nex->name() << endl;
}
for (unsigned idx = 0 ; idx < delay_paths_.size() ; idx += 1) {
const NetDelaySrc*cur = delay_paths_[idx];
cur->dump(o, ind+4);
}
dump_obj_attr(o, ind+4);
}
@ -1183,6 +1208,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.168 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.167 2006/07/31 03:50:17 steve
* Add support for power in constant expressions.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2006 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.342 2006/09/22 22:14:27 steve Exp $"
#ident "$Id: elaborate.cc,v 1.343 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -35,6 +35,7 @@
# include "pform.h"
# include "PEvent.h"
# include "PGenerate.h"
# include "PSpec.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
@ -2872,6 +2873,108 @@ NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
return loop;
}
void PSpecPath::elaborate(Design*des, NetScope*scope) const
{
uint64_t delay_value[12];
unsigned ndelays = 0;
ndelays = delays.size();
if (ndelays > 12)
ndelays = 12;
/* Elaborate the delay values themselves. */
for (unsigned idx = 0 ; idx < ndelays ; idx += 1) {
PExpr*exp = delays[idx];
NetExpr*cur = elab_and_eval(des, scope, exp, 0);
if (NetEConst*cur_con = dynamic_cast<NetEConst*> (cur)) {
delay_value[idx] = cur_con->value().as_ulong();
} else {
cerr << cur->get_line() << ": error: Path delay value "
<< "must be constant." << endl;
delay_value[idx] = 0;
des->errors += 1;
}
delete cur;
}
switch (ndelays) {
case 1:
case 2:
case 3:
case 6:
case 12:
break;
default:
cerr << get_line() << ": error: Incorrect delay configuration."
<< endl;
ndelays = 1;
des->errors += 1;
break;
}
/* Create all the various paths from the path specifier. */
typedef std::vector<perm_string>::const_iterator str_vector_iter;
for (str_vector_iter cur = dst.begin()
; cur != dst.end() ; cur ++) {
if (debug_elaborate) {
cerr << get_line() << ": debug: Path to " << (*cur) << endl;
}
NetNet*dst_sig = scope->find_signal(*cur);
if (dst_sig == 0) {
cerr << get_line() << ": error: No such wire "
<< *cur << " in this module." << endl;
des->errors += 1;
continue;
}
NetDelaySrc*path = new NetDelaySrc(scope, scope->local_symbol(),
src.size());
path->set_line(*this);
switch (ndelays) {
case 12:
path->set_delays(delay_value[0], delay_value[1],
delay_value[2], delay_value[3],
delay_value[4], delay_value[5],
delay_value[6], delay_value[7],
delay_value[8], delay_value[9],
delay_value[10], delay_value[11]);
break;
case 6:
path->set_delays(delay_value[0], delay_value[1],
delay_value[2], delay_value[3],
delay_value[4], delay_value[5]);
break;
case 3:
path->set_delays(delay_value[0], delay_value[1],
delay_value[2]);
break;
case 2:
path->set_delays(delay_value[0], delay_value[1]);
break;
case 1:
path->set_delays(delay_value[0]);
break;
}
unsigned idx = 0;
for (str_vector_iter cur_src = src.begin()
; cur_src != src.end() ; cur_src ++) {
NetNet*src_sig = scope->find_signal(*cur_src);
assert(src_sig);
connect(src_sig->pin(0), path->pin(idx));
idx += 1;
}
dst_sig->add_delay_path(path);
}
}
/*
* When a module is instantiated, it creates the scope then uses this
* method to elaborate the contents of the module.
@ -3003,6 +3106,14 @@ bool Module::elaborate(Design*des, NetScope*scope) const
}
// Elaborate the specify paths of the module.
for (list<PSpecPath*>::const_iterator sp = specify_paths.begin()
; sp != specify_paths.end() ; sp ++) {
(*sp)->elaborate(des, scope);
}
return result_flag;
}
@ -3144,6 +3255,9 @@ Design* elaborate(list<perm_string>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.343 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.342 2006/09/22 22:14:27 steve
* Proper error message when logic array pi count is bad.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.170 2006/08/08 05:11:37 steve Exp $"
#ident "$Id: ivl_target.h,v 1.171 2006/09/23 04:57:19 steve Exp $"
#endif
# include <stdint.h>
@ -137,6 +137,7 @@ _BEGIN_DECL
* scope. These names are unique within a scope, but not necessarily
* throughout the design.
*/
typedef struct ivl_delaypath_s*ivl_delaypath_t;
typedef struct ivl_design_s *ivl_design_t;
typedef struct ivl_event_s *ivl_event_t;
typedef struct ivl_expr_s *ivl_expr_t;
@ -255,6 +256,16 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_UFUNC = 14
} ivl_lpm_type_t;
/* The path edge type is the edge type used to select a specific
delay. */
typedef enum ivl_path_edge_e {
IVL_PE_01 = 0, IVL_PE_10, IVL_PE_0z,
IVL_PE_z1, IVL_PE_1z, IVL_PE_z0,
IVL_PE_0x, IVL_PE_x1, IVL_PE_1x,
IVL_PE_x0, IVL_PE_xz, IVL_PE_zx,
IVL_PE_COUNT
} ivl_path_edge_t;
/* Processes are initial or always blocks with a statement. This is
the type of the ivl_process_t object. */
typedef enum ivl_process_type_e {
@ -361,6 +372,19 @@ struct ivl_attribute_s {
};
typedef const struct ivl_attribute_s*ivl_attribute_t;
/* DELAYPATH
* Delaypath objects represent delay paths called out by a specify
* block in the verilog source file. The destination signal references
* the path object, which in turn points to the source for the path.
*
* ivl_path_source
* This returns the nexus that is the source end of the delay
* path. Transitions on the source are the start of the delay time
* for this path.
*/
extern ivl_nexus_t ivl_path_source(ivl_delaypath_t obj);
extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t pt);
/* DESIGN
* When handed a design (ivl_design_t) there are a few things that you
@ -1450,6 +1474,12 @@ extern int ivl_scope_time_units(ivl_scope_t net);
* etc. All the signals connected to a nexus should have the same
* data type
*
* ivl_signal_npath
* ivl_signal_path
* This function returns the delay path object for the signal. The
* delay path has this signal as the output, the source is attached
* to the delay path itself.
*
* ivl_signal_name (DEPRECATED)
* This function returns the fully scoped hierarchical name for the
* signal. The name refers to the entire vector that is the signal.
@ -1481,6 +1511,8 @@ extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net);
extern int ivl_signal_signed(ivl_signal_t net);
extern int ivl_signal_integer(ivl_signal_t net);
extern int ivl_signal_local(ivl_signal_t net);
extern unsigned ivl_signal_npath(ivl_signal_t net);
extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx);
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net);
extern const char* ivl_signal_name(ivl_signal_t net);
@ -1720,6 +1752,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.171 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.170 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.cc,v 1.248 2005/09/14 02:53:14 steve Exp $"
#ident "$Id: netlist.cc,v 1.249 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -237,6 +237,99 @@ NetBus::~NetBus()
{
}
NetDelaySrc::NetDelaySrc(NetScope*s, perm_string n, unsigned npins)
: NetObj(s, n, npins)
{
for (unsigned idx = 0 ; idx < npins ; idx += 1) {
pin(idx).set_name(perm_string::literal("I"), idx);
pin(idx).set_dir(Link::INPUT);
}
}
NetDelaySrc::~NetDelaySrc()
{
}
void NetDelaySrc::set_delays(uint64_t del)
{
for (unsigned idx = 0 ; idx < 12 ; idx += 1)
transition_delays_[idx] = del;
}
void NetDelaySrc::set_delays(uint64_t trise, uint64_t tfall)
{
transition_delays_[IVL_PE_01] = trise;
transition_delays_[IVL_PE_10] = tfall;
transition_delays_[IVL_PE_0z] = trise;
transition_delays_[IVL_PE_z1] = trise;
transition_delays_[IVL_PE_1z] = tfall;
transition_delays_[IVL_PE_z0] = tfall;
transition_delays_[IVL_PE_0x] = trise;
transition_delays_[IVL_PE_x1] = trise;
transition_delays_[IVL_PE_1x] = tfall;
transition_delays_[IVL_PE_x0] = tfall;
transition_delays_[IVL_PE_xz] = max(trise,tfall);
transition_delays_[IVL_PE_zx] = min(trise,tfall);
}
void NetDelaySrc::set_delays(uint64_t trise, uint64_t tfall, uint64_t tz)
{
transition_delays_[IVL_PE_01] = trise;
transition_delays_[IVL_PE_10] = tfall;
transition_delays_[IVL_PE_0z] = tz;
transition_delays_[IVL_PE_z1] = trise;
transition_delays_[IVL_PE_1z] = tz;
transition_delays_[IVL_PE_z0] = tfall;
transition_delays_[IVL_PE_0x] = min(trise,tz);
transition_delays_[IVL_PE_x1] = trise;
transition_delays_[IVL_PE_1x] = min(tfall,tz);
transition_delays_[IVL_PE_x0] = tfall;
transition_delays_[IVL_PE_xz] = tz;
transition_delays_[IVL_PE_zx] = min(trise,tfall);
}
void NetDelaySrc::set_delays(uint64_t t01, uint64_t t10, uint64_t t0z,
uint64_t tz1, uint64_t t1z, uint64_t tz0)
{
transition_delays_[IVL_PE_01] = t01;
transition_delays_[IVL_PE_10] = t10;
transition_delays_[IVL_PE_0z] = t0z;
transition_delays_[IVL_PE_z1] = tz1;
transition_delays_[IVL_PE_1z] = t1z;
transition_delays_[IVL_PE_z0] = tz0;
transition_delays_[IVL_PE_0x] = min(t01,t0z);
transition_delays_[IVL_PE_x1] = max(t01,tz1);
transition_delays_[IVL_PE_1x] = min(t10,t1z);
transition_delays_[IVL_PE_x0] = max(t10,tz0);
transition_delays_[IVL_PE_xz] = max(t1z,t0z);
transition_delays_[IVL_PE_zx] = min(tz1,tz0);
}
void NetDelaySrc::set_delays(uint64_t t01, uint64_t t10, uint64_t t0z,
uint64_t tz1, uint64_t t1z, uint64_t tz0,
uint64_t t0x, uint64_t tx1, uint64_t t1x,
uint64_t tx0, uint64_t txz, uint64_t tzx)
{
transition_delays_[IVL_PE_01] = t01;
transition_delays_[IVL_PE_10] = t10;
transition_delays_[IVL_PE_0z] = t0z;
transition_delays_[IVL_PE_z1] = tz1;
transition_delays_[IVL_PE_1z] = t1z;
transition_delays_[IVL_PE_z0] = tz0;
transition_delays_[IVL_PE_0x] = t0x;
transition_delays_[IVL_PE_x1] = tx1;
transition_delays_[IVL_PE_1x] = t1x;
transition_delays_[IVL_PE_x0] = tx0;
transition_delays_[IVL_PE_xz] = txz;
transition_delays_[IVL_PE_zx] = tzx;
}
uint64_t NetDelaySrc::get_delay(unsigned idx) const
{
assert(idx < 12);
return transition_delays_[idx];
}
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
: NetObj(s, n, 1), sig_next_(0), sig_prev_(0),
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
@ -477,6 +570,21 @@ unsigned NetNet::get_refs() const
return lref_count_ + eref_count_;
}
void NetNet::add_delay_path(NetDelaySrc*path)
{
delay_paths_.push_back(path);
}
unsigned NetNet::delay_paths(void)const
{
return delay_paths_.size();
}
const NetDelaySrc* NetNet::delay_path(unsigned idx) const
{
assert(idx < delay_paths_.size());
return delay_paths_[idx];
}
NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
NetPartSelect::dir_t dir)
@ -2228,6 +2336,9 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.249 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.248 2005/09/14 02:53:14 steve
* Support bool expressions and compares handle them optimally.
*

View File

@ -1,7 +1,7 @@
#ifndef __netlist_H
#define __netlist_H
/*
* Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2006 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.360 2006/08/08 05:11:37 steve Exp $"
#ident "$Id: netlist.h,v 1.361 2006/09/23 04:57:19 steve Exp $"
#endif
/*
@ -31,6 +31,7 @@
# include <string>
# include <map>
# include <list>
# include <vector>
# include <stdint.h>
# include "ivl_target.h"
# include "verinum.h"
@ -369,6 +370,46 @@ class NetNode : public NetObj {
Design*design_;
};
/*
* A NetDelaySrc is an input-only device that calculates a path delay
* based on the time that the inputs change. This class is used by the
* NetNet class, and NetDelaySrc objects cannot exist outside of its
* association with NetNet objects.
*/
class NetDelaySrc : public NetObj {
public:
explicit NetDelaySrc(NetScope*s, perm_string n, unsigned npins);
~NetDelaySrc();
// These functions set the delays from the values in the
// source. These set_delays functions implement the various
// rules wrt collections of transitions.
// One transition specified.
void set_delays(uint64_t del);
// Two transitions: rise and fall
void set_delays(uint64_t rise, uint64_t fall);
// Three transitions
void set_delays(uint64_t rise, uint64_t fall, uint64_t tz);
void set_delays(uint64_t t01, uint64_t t10, uint64_t t0z,
uint64_t tz1, uint64_t t1z, uint64_t tz0);
void set_delays(uint64_t t01, uint64_t t10, uint64_t t0z,
uint64_t tz1, uint64_t t1z, uint64_t tz0,
uint64_t t0x, uint64_t tx1, uint64_t t1x,
uint64_t tx0, uint64_t txz, uint64_t tzx);
uint64_t get_delay(unsigned pe) const;
void dump(ostream&, unsigned ind) const;
private:
uint64_t transition_delays_[12];
private: // Not implemented
NetDelaySrc(const NetDelaySrc&);
NetDelaySrc& operator= (const NetDelaySrc&);
};
/*
* NetNet is a special kind of NetObj that doesn't really do anything,
@ -463,6 +504,11 @@ class NetNet : public NetObj {
unsigned get_refs() const;
/* Manage path delays */
void add_delay_path(class NetDelaySrc*path);
unsigned delay_paths(void) const;
const class NetDelaySrc*delay_path(unsigned idx) const;
virtual void dump_net(ostream&, unsigned) const;
private:
@ -482,6 +528,8 @@ class NetNet : public NetObj {
bool local_flag_;
unsigned eref_count_;
unsigned lref_count_;
vector<class NetDelaySrc*> delay_paths_;
};
/*
@ -3510,6 +3558,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.361 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.360 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*

45
parse.y
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.219 2006/08/08 05:11:37 steve Exp $"
#ident "$Id: parse.y,v 1.220 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -30,6 +30,8 @@
# include "Statement.h"
# include <sstream>
class PSpecPath;
extern void lex_start_table();
extern void lex_end_table();
@ -141,6 +143,8 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
verinum* number;
verireal* realtime;
PSpecPath* specpath;
};
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING
@ -215,7 +219,7 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
%type <expr> expression expr_primary
%type <expr> lpvalue
%type <expr> delay_value delay_value_simple
%type <exprs> delay1 delay3 delay3_opt
%type <exprs> delay1 delay3 delay3_opt delay_value_list
%type <exprs> expression_list
%type <exprs> assign assign_list
%type <indexed_identifier> indexed_identifier
@ -237,6 +241,8 @@ static list<perm_string>* list_from_identifier(list<perm_string>*tmp, char*id)
%type <letter> spec_polarity
%type <perm_strings> specify_path_identifiers
%type <specpath> specify_simple_path specify_simple_path_decl
%token K_TAND
%right '?' ':'
%left K_LOR
@ -550,6 +556,19 @@ delay3_opt
| { $$ = 0; }
;
delay_value_list
: delay_value
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
(*tmp)[0] = $1;
$$ = tmp;
}
| delay_value_list ',' delay_value
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, $3);
delete $1;
$$ = tmp;
}
;
delay_value
: expression
{ PExpr*tmp = $1;
@ -2444,7 +2463,7 @@ register_variable_list
specify_item
: K_specparam specparam_list ';'
| specify_simple_path_decl ';'
{
{ pform_module_specify_path($1);
}
| specify_edge_path_decl ';'
{
@ -2494,18 +2513,14 @@ specify_item
}
;
specify_delay_value_list
: delay_value { }
| specify_delay_value_list ',' delay_value { }
;
specify_item_list
: specify_item
| specify_item_list specify_item
;
specify_edge_path_decl
: specify_edge_path '=' '(' specify_delay_value_list ')'
: specify_edge_path '=' '(' delay_value_list ')'
{ delete $4; }
| specify_edge_path '=' delay_value_simple
;
@ -2527,21 +2542,27 @@ polarity_operator
;
specify_simple_path_decl
: specify_simple_path '=' '(' specify_delay_value_list ')'
: specify_simple_path '=' '(' delay_value_list ')'
{ $$ = pform_assign_path_delay($1, $4); }
| specify_simple_path '=' delay_value_simple
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
(*tmp)[0] = $3;
$$ = pform_assign_path_delay($1, tmp);
}
| specify_simple_path '=' '(' error ')'
{ yyerror(@2, "Syntax error in delay value list.");
yyerrok;
$$ = 0;
}
;
specify_simple_path
: '(' specify_path_identifiers spec_polarity
K_EG specify_path_identifiers ')'
{ pform_make_specify_path($2, $3, false, $5); }
{ $$ = pform_make_specify_path(@1, $2, $3, false, $5); }
| '(' specify_path_identifiers spec_polarity
K_SG specify_path_identifiers ')'
{ pform_make_specify_path($2, $3, true, $5); }
{ $$ = pform_make_specify_path(@1, $2, $3, true, $5); }
| '(' error ')'
{ yyerror(@2, "Invalid simple path");
yyerrok;

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform.cc,v 1.136 2006/08/08 05:11:37 steve Exp $"
#ident "$Id: pform.cc,v 1.137 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -29,6 +29,7 @@
# include "PEvent.h"
# include "PUdp.h"
# include "PGenerate.h"
# include "PSpec.h"
# include <list>
# include <map>
# include <assert.h>
@ -1535,13 +1536,52 @@ void pform_set_defparam(const hname_t&name, PExpr*expr)
}
/*
* XXXX Not implemented yet.
* Specify paths.
*/
extern void pform_make_specify_path(list<perm_string>*src, char pol,
bool full_flag, list<perm_string>*dst)
extern PSpecPath* pform_make_specify_path(const struct vlltype&li,
list<perm_string>*src, char pol,
bool full_flag, list<perm_string>*dst)
{
PSpecPath*path = new PSpecPath(src->size(), dst->size());
path->set_file(li.text);
path->set_lineno(li.first_line);
unsigned idx;
list<perm_string>::const_iterator cur;
idx = 0;
for (idx = 0, cur = src->begin() ; cur != src->end() ; idx++, cur++) {
path->src[idx] = *cur;
}
assert(idx == path->src.size());
delete src;
for (idx = 0, cur = dst->begin() ; cur != dst->end() ; idx++, cur++) {
path->dst[idx] = *cur;
}
assert(idx == path->dst.size());
delete dst;
return path;
}
extern PSpecPath* pform_assign_path_delay(PSpecPath*path, svector<PExpr*>*del)
{
assert(path->delays.size() == 0);
path->delays.resize(del->count());
for (unsigned idx = 0 ; idx < path->delays.size() ; idx += 1)
path->delays[idx] = (*del)[idx];
delete del;
return path;
}
extern void pform_module_specify_path(PSpecPath*obj)
{
pform_cur_module->specify_paths.push_back(obj);
}
void pform_set_port_type(const struct vlltype&li,
@ -1707,6 +1747,9 @@ int pform_parse(const char*path, FILE*file)
/*
* $Log: pform.cc,v $
* Revision 1.137 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.136 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*

14
pform.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: pform.h,v 1.86 2006/04/10 00:37:42 steve Exp $"
#ident "$Id: pform.h,v 1.87 2006/09/23 04:57:19 steve Exp $"
#endif
# include "netlist.h"
@ -57,6 +57,7 @@
*/
class PGate;
class PExpr;
class PSpecPath;
struct vlltype;
/*
@ -260,8 +261,12 @@ extern void pform_set_defparam(const hname_t&name, PExpr*expr);
* Functions related to specify blocks.
*/
extern void pform_set_specparam(perm_string name, PExpr*expr);
extern void pform_make_specify_path(list<perm_string>*src, char pol,
bool full_flag, list<perm_string>*dst);
extern PSpecPath*pform_make_specify_path(const struct vlltype&li,
list<perm_string>*src, char pol,
bool full_flag, list<perm_string>*dst);
extern PSpecPath*pform_assign_path_delay(PSpecPath*obj, svector<PExpr*>*delays);
extern void pform_module_specify_path(PSpecPath*obj);
/*
* pform_make_behavior creates processes that are declared with always
@ -323,6 +328,9 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.87 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.86 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_dump.cc,v 1.93 2006/04/28 04:19:31 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.94 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -31,6 +31,7 @@
# include "pform.h"
# include "PEvent.h"
# include "PGenerate.h"
# include "PSpec.h"
# include <iostream>
# include <iomanip>
# include <typeinfo>
@ -739,6 +740,33 @@ void PProcess::dump(ostream&out, unsigned ind) const
statement_->dump(out, ind+2);
}
void PSpecPath::dump(std::ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "specify path (";
for (unsigned idx = 0 ; idx < src.size() ; idx += 1) {
if (idx > 0) out << ", ";
assert(src[idx]);
out << src[idx];
}
out << " => ";
for (unsigned idx = 0 ; idx < dst.size() ; idx += 1) {
if (idx > 0) out << ", ";
assert(dst[idx]);
out << dst[idx];
}
out << ") = (";
for (unsigned idx = 0 ; idx < delays.size() ; idx += 1) {
if (idx > 0) out << ", ";
assert(delays[idx]);
out << *delays[idx];
}
out << ");" << endl;
}
void PGenerate::dump(ostream&out) const
{
out << " generate(" << id_number << ")";
@ -920,6 +948,13 @@ void Module::dump(ostream&out) const
(*behav)->dump(out, 4);
}
for (list<PSpecPath*>::const_iterator spec = specify_paths.begin()
; spec != specify_paths.end()
; spec ++ ) {
(*spec)->dump(out, 4);
}
out << "endmodule" << endl;
}
@ -972,6 +1007,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.94 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.93 2006/04/28 04:19:31 steve
* Dump indexes of ident expressions
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-api.cc,v 1.136 2006/09/20 22:31:23 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.137 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -1283,6 +1283,17 @@ extern "C" ivl_scope_t ivl_parameter_scope(ivl_parameter_t net)
return net->scope;
}
extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t edg)
{
assert(obj);
return obj->delay[edg];
}
extern ivl_nexus_t ivl_path_source(ivl_delaypath_t net)
{
return net->src;
}
extern "C" ivl_process_type_t ivl_process_type(ivl_process_t net)
{
return net->type_;
@ -1606,6 +1617,17 @@ extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net)
return net->data_type;
}
extern "C" unsigned ivl_signal_npath(ivl_signal_t net)
{
return net->npath;
}
extern "C" ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx)
{
assert(idx < net->npath);
return net->path + idx;
}
extern "C" ivl_signal_type_t ivl_signal_type(ivl_signal_t net)
{
return net->type_;
@ -1954,6 +1976,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.137 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.136 2006/09/20 22:31:23 steve
* Remove dead code.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.157 2006/06/18 04:15:50 steve Exp $"
#ident "$Id: t-dll.cc,v 1.158 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
@ -2174,6 +2174,28 @@ void dll_target::signal(const NetNet*net)
break;
}
/* Collect the delay paths for this signal. */
obj->npath = net->delay_paths();
if (obj->npath > 0) {
obj->path = new struct ivl_delaypath_s[obj->npath];
for (unsigned idx = 0 ; idx < obj->npath ; idx += 1) {
const NetDelaySrc*src = net->delay_path(idx);
// For now, only handle single-source paths.
assert(src->pin_count() == 1);
const Nexus*nex = src->pin(0).nexus();
assert(nex->t_cookie());
obj->path[idx].src = (ivl_nexus_t) nex->t_cookie();
for (unsigned pe = 0 ; pe < 12 ; pe += 1) {
obj->path[idx].delay[pe] = src->get_delay(pe);
}
}
} else {
obj->path = 0;
}
obj->data_type = net->data_type();
obj->nattr = net->attr_cnt();
obj->attr = fill_in_attributes(net);
@ -2207,6 +2229,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.158 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.157 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*

13
t-dll.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: t-dll.h,v 1.132 2006/08/08 05:11:37 steve Exp $"
#ident "$Id: t-dll.h,v 1.133 2006/09/23 04:57:19 steve Exp $"
#endif
# include "target.h"
@ -177,6 +177,11 @@ struct dll_target : public target_t, public expr_scan_t {
* These are various private declarations used by the t-dll target.
*/
struct ivl_delaypath_s {
ivl_nexus_t src;
uint64_t delay[12];
};
struct ivl_event_s {
perm_string name;
ivl_scope_t scope;
@ -585,6 +590,9 @@ struct ivl_signal_s {
ivl_nexus_t pin_;
ivl_delaypath_s*path;
unsigned npath;
struct ivl_attribute_s*attr;
unsigned nattr;
};
@ -671,6 +679,9 @@ struct ivl_statement_s {
/*
* $Log: t-dll.h,v $
* Revision 1.133 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.132 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*

View File

@ -17,12 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.140 2006/07/30 02:51:36 steve Exp $"
#ident "$Id: stub.c,v 1.141 2006/09/23 04:57:19 steve Exp $"
#endif
# include "config.h"
# include "priv.h"
# include <stdlib.h>
# include <inttypes.h>
# include <assert.h>
FILE*out;
@ -1331,6 +1332,29 @@ static void show_signal(ivl_signal_t net)
}
}
for (idx = 0 ; idx < ivl_signal_npath(net) ; idx += 1) {
ivl_delaypath_t path = ivl_signal_path(net,idx);
ivl_nexus_t nex = ivl_path_source(path);
fprintf(out, " path %s", ivl_nexus_name(nex));
fprintf(out, " %" PRIu64 ",%" PRIu64 ",%" PRIu64
" %" PRIu64 ",%" PRIu64 ",%" PRIu64
" %" PRIu64 ",%" PRIu64 ",%" PRIu64
" %" PRIu64 ",%" PRIu64 ",%" PRIu64 "\n",
ivl_path_delay(path, IVL_PE_01),
ivl_path_delay(path, IVL_PE_10),
ivl_path_delay(path, IVL_PE_0z),
ivl_path_delay(path, IVL_PE_z1),
ivl_path_delay(path, IVL_PE_1z),
ivl_path_delay(path, IVL_PE_z0),
ivl_path_delay(path, IVL_PE_0x),
ivl_path_delay(path, IVL_PE_x1),
ivl_path_delay(path, IVL_PE_1x),
ivl_path_delay(path, IVL_PE_x0),
ivl_path_delay(path, IVL_PE_xz),
ivl_path_delay(path, IVL_PE_zx));
}
for (idx = 0 ; idx < ivl_signal_attr_cnt(net) ; idx += 1) {
ivl_attribute_t atr = ivl_signal_attr_val(net, idx);
@ -1647,6 +1671,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.141 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.140 2006/07/30 02:51:36 steve
* Fix/implement signed right shift.
*

View File

@ -17,16 +17,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.146 2006/07/30 02:51:36 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.147 2006/09/23 04:57:19 steve Exp $"
#endif
# include "vvp_priv.h"
# include <assert.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <inttypes.h>
# include <assert.h>
struct vvp_nexus_data {
/* draw_net_input uses this */
@ -376,6 +377,28 @@ static int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr)
return 1;
}
/*
* Given a nexus, look for a signal that has module delay
* paths. Return that signal. (There should be no more then 1.) If we
* don't find any, then return nil.
*/
static ivl_signal_t find_modpath(ivl_nexus_t nex)
{
unsigned idx;
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex,idx);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig == 0)
continue;
if (ivl_signal_npath(sig) == 0)
continue;
return sig;
}
return 0;
}
static void draw_C4_to_string(char*result, size_t nresult,
ivl_net_const_t cptr)
{
@ -894,6 +917,39 @@ static void draw_reg_in_scope(ivl_signal_t sig)
vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb);
}
static void draw_modpath(const char*label, const char*driver,
ivl_signal_t path_sig)
{
unsigned idx;
fprintf(vvp_out, "%s .modpath %s", label, driver);
for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) {
ivl_delaypath_t path = ivl_signal_path(path_sig, idx);
ivl_nexus_t src = ivl_path_source(path);
const char*src_driver = draw_net_input(src);
fprintf(vvp_out, ",\n %s", src_driver);
fprintf(vvp_out,
" (%"PRIu64",%"PRIu64",%"PRIu64
", %"PRIu64",%"PRIu64",%"PRIu64
", %"PRIu64",%"PRIu64",%"PRIu64
", %"PRIu64",%"PRIu64",%"PRIu64")",
ivl_path_delay(path, IVL_PE_01),
ivl_path_delay(path, IVL_PE_10),
ivl_path_delay(path, IVL_PE_0z),
ivl_path_delay(path, IVL_PE_z1),
ivl_path_delay(path, IVL_PE_1z),
ivl_path_delay(path, IVL_PE_z0),
ivl_path_delay(path, IVL_PE_0x),
ivl_path_delay(path, IVL_PE_x1),
ivl_path_delay(path, IVL_PE_1x),
ivl_path_delay(path, IVL_PE_x0),
ivl_path_delay(path, IVL_PE_xz),
ivl_path_delay(path, IVL_PE_zx));
}
fprintf(vvp_out, ";\n");
}
/*
* This function draws a net. This is a bit more complicated as we
* have to find an appropriate functor to connect to the input.
@ -904,6 +960,8 @@ static void draw_net_in_scope(ivl_signal_t sig)
int lsb = ivl_signal_lsb(sig);
typedef const char*const_charp;
const char* arg;
const char* driver;
char modpath_label[64];
const char*datatype_flag = ivl_signal_signed(sig)? "/s" : "";
@ -916,7 +974,8 @@ static void draw_net_in_scope(ivl_signal_t sig)
/* Connect the pin of the signal to something. */
{
ivl_nexus_t nex = ivl_signal_nex(sig);
arg = draw_net_input(nex);
driver = draw_net_input(nex);
arg = driver;
nex_data = (struct vvp_nexus_data*)ivl_nexus_get_private(nex);
assert(nex_data);
@ -930,6 +989,18 @@ static void draw_net_in_scope(ivl_signal_t sig)
break;
}
/* If there are module delay paths, then we are going to need
a modpath node between the drivers and the net. the
path_sig is the signal that carries the paths. There should
be 0 or one of these. */
ivl_signal_t path_sig = find_modpath(ivl_signal_nex(sig));
if (path_sig) {
snprintf(modpath_label, sizeof modpath_label,
"V_%p/m", path_sig);
arg = modpath_label;
}
if (nex_data->net == 0) {
const char*vec8 = "";
if (nex_data->drivers_count > 1)
@ -945,6 +1016,11 @@ static void draw_net_in_scope(ivl_signal_t sig)
nex_data->drivers_count,
nex_data->flags&VVP_NEXUS_DATA_STR?", strength-aware":"");
nex_data->net = sig;
if (path_sig) {
draw_modpath(modpath_label, driver, path_sig);
}
} else {
/* Detect that this is an alias of nex_data->net. Create
a different kind of node that refers to the alias
@ -2251,6 +2327,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.147 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.146 2006/07/30 02:51:36 steve
* Fix/implement signed right shift.
*

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.77 2006/03/18 22:51:10 steve Exp $
* $Id: README.txt,v 1.78 2006/09/23 04:57:19 steve Exp $
*/
VVP SIMULATION ENGINE
@ -342,6 +342,14 @@ 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.
MODULE PATH DELAY STATEMENTS:
A module path delay takes data from its input, then a list of module
path delays. The <src> for each possible delay set is a trigger that
activates the delay.
.modpath <input> , [ <src> (<delays>) ] ;
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.223 2006/08/09 05:19:08 steve Exp $"
#ident "$Id: compile.cc,v 1.224 2006/09/23 04:57:19 steve Exp $"
#endif
# include "arith.h"
@ -1048,6 +1048,45 @@ void compile_extend_signed(char*label, long wid, struct symb_s arg)
input_connect(ptr, 0, arg.text);
}
vvp_fun_modpath* compile_modpath(char*label, struct symb_s src)
{
vvp_net_t*net = new vvp_net_t;
vvp_fun_modpath*obj = new vvp_fun_modpath(net);
net->fun = obj;
input_connect(net, 0, src.text);
define_functor_symbol(label, net);
free(label);
return obj;
}
void compile_modpath_src(vvp_fun_modpath*dst,
struct symb_s src,
struct numbv_s vals)
{
vvp_time64_t use_delay = 0;
assert(vals.cnt == 12);
// FIXME: For now, only support single uniform time value.
use_delay = vals.nvec[0];
for (unsigned idx = 1 ; idx < vals.cnt ; idx += 1) {
assert(use_delay == vals.nvec[idx]);
}
numbv_clear(&vals);
vvp_net_t*net = new vvp_net_t;
vvp_fun_modpath_src*obj = new vvp_fun_modpath_src(use_delay);
net->fun = obj;
input_connect(net, 0, src.text);
dst->add_modpath_src(obj);
}
/*
* A .shift/l statement creates an array of functors for the
* width. The 0 input is the data vector to be shifted and the 1 input
@ -1497,6 +1536,9 @@ void compile_param_string(char*label, char*name, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.224 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.223 2006/08/09 05:19:08 steve
* Add support for real valued modulus.
*

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.82 2006/07/30 02:51:36 steve Exp $"
#ident "$Id: compile.h,v 1.83 2006/09/23 04:57:19 steve Exp $"
#endif
# include <stdio.h>
@ -160,6 +160,13 @@ extern void compile_dff(char*label,
struct symb_s arg_c,
struct symb_s arg_e,
struct symb_s arg_a);
class vvp_fun_modpath;
extern vvp_fun_modpath* compile_modpath(char*label, struct symb_s src);
extern void compile_modpath_src(vvp_fun_modpath*dst,
struct symb_s input,
struct numbv_s d);
extern void compile_reduce_and(char*label, struct symb_s arg);
extern void compile_reduce_or(char*label, struct symb_s arg);
extern void compile_reduce_xor(char*label, struct symb_s arg);
@ -345,6 +352,9 @@ extern void compile_alias_real(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.83 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.82 2006/07/30 02:51:36 steve
* Fix/implement signed right shift.
*

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.13 2006/07/08 21:48:00 steve Exp $"
#ident "$Id: delay.cc,v 1.14 2006/09/23 04:57:19 steve Exp $"
#endif
#include "delay.h"
@ -276,9 +276,93 @@ void vvp_fun_delay::run_run_real_()
vvp_send_real(net_->out, cur_real_);
}
vvp_fun_modpath::vvp_fun_modpath(vvp_net_t*net)
: net_(net), src_list_(0)
{
}
vvp_fun_modpath::~vvp_fun_modpath()
{
// Delete the source probes.
while (src_list_) {
vvp_fun_modpath_src*tmp = src_list_;
src_list_ = tmp->next_;
delete tmp;
}
}
void vvp_fun_modpath::add_modpath_src(vvp_fun_modpath_src*that)
{
assert(that->next_ == 0);
that->next_ = src_list_;
src_list_ = that;
}
void vvp_fun_modpath::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
/* Only the first port is used. */
if (port.port() > 0)
return;
if (cur_vec4_.eeq(bit))
return;
/* Select a time delay source that applies. */
vvp_fun_modpath_src*src = 0;
vvp_time64_t out_at = 0;
for (vvp_fun_modpath_src*cur = src_list_ ; cur ; cur=cur->next_) {
if (src == 0) {
src = cur;
} else if (cur->wake_time_ > src->wake_time_) {
src = cur;
} else {
continue; /* Skip this entry. */
}
out_at = src->wake_time_ + src->delay_;
}
/* Given the scheduled output time, create an output event. */
vvp_time64_t use_delay = 0;
vvp_time64_t now = schedule_simtime();
if (out_at <= now)
use_delay = 0;
else
use_delay = out_at - now;
cur_vec4_ = bit;
schedule_generic(this, use_delay, false);
}
void vvp_fun_modpath::run_run()
{
vvp_send_vec4(net_->out, cur_vec4_);
}
vvp_fun_modpath_src::vvp_fun_modpath_src(vvp_time64_t del)
{
delay_ = del;
next_ = 0;
wake_time_ = 0;
}
vvp_fun_modpath_src::~vvp_fun_modpath_src()
{
}
void vvp_fun_modpath_src::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
if (port.port() != 0)
return;
wake_time_ = schedule_simtime();
}
/*
* $Log: delay.cc,v $
* Revision 1.14 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.13 2006/07/08 21:48:00 steve
* Delay object supports real valued delays.
*

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.10 2006/01/02 05:32:07 steve Exp $"
#ident "$Id: delay.h,v 1.11 2006/09/23 04:57:20 steve Exp $"
#endif
/*
@ -96,8 +96,64 @@ class vvp_fun_delay : public vvp_net_fun_t, private vvp_gen_event_s {
double cur_real_;
};
class vvp_fun_modpath;
class vvp_fun_modpath_src;
class vvp_fun_modpath : public vvp_net_fun_t, private vvp_gen_event_s {
public:
vvp_fun_modpath(vvp_net_t*net);
~vvp_fun_modpath();
void add_modpath_src(vvp_fun_modpath_src*that);
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
private:
virtual void run_run();
private:
vvp_net_t*net_;
vvp_vector4_t cur_vec4_;
vvp_fun_modpath_src*src_list_;
private: // not implemented
vvp_fun_modpath(const vvp_fun_modpath&);
vvp_fun_modpath& operator= (const vvp_fun_modpath&);
};
class vvp_fun_modpath_src : public vvp_net_fun_t {
friend class vvp_fun_modpath;
public:
vvp_fun_modpath_src(vvp_time64_t d);
private:
~vvp_fun_modpath_src();
public:
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
private:
// FIXME: Needs to be a 12-value array
vvp_time64_t delay_;
// Used by vvp_fun_modpath to keep a list of modpath_src objects.
vvp_fun_modpath_src*next_;
vvp_time64_t wake_time_;
private:
vvp_fun_modpath_src(const vvp_fun_modpath_src&);
vvp_fun_modpath_src& operator = (const vvp_fun_modpath_src&);
};
/*
* $Log: delay.h,v $
* Revision 1.11 2006/09/23 04:57:20 steve
* Basic support for specify timing.
*
* Revision 1.10 2006/01/02 05:32:07 steve
* Require explicit delay node from source.
*

View File

@ -21,7 +21,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.62 2006/07/30 02:51:36 steve Exp $"
#ident "$Id: lexor.lex,v 1.63 2006/09/23 04:57:20 steve Exp $"
#endif
# include "parse_misc.h"
@ -111,6 +111,7 @@
".event/or" { return K_EVENT_OR; }
".extend/s" { return K_EXTEND_S; }
".functor" { return K_FUNCTOR; }
".modpath" { return K_MODPATH; }
".net" { return K_NET; }
".net8" { return K_NET8; }
".net8/s" { return K_NET8_S; }
@ -210,6 +211,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.63 2006/09/23 04:57:20 steve
* Basic support for specify timing.
*
* Revision 1.62 2006/07/30 02:51:36 steve
* Fix/implement signed right shift.
*

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.84 2006/07/30 02:51:36 steve Exp $"
#ident "$Id: parse.y,v 1.85 2006/09/23 04:57:20 steve Exp $"
#endif
# include "parse_misc.h"
@ -34,6 +34,15 @@
*/
extern FILE*yyin;
/*
* Local variables.
*/
/*
* When parsing a modpath list, this is the processed destination that
* the source items will attach themselves to.
*/
static vvp_fun_modpath*modpath_dst = 0;
%}
%union {
@ -62,7 +71,7 @@ extern FILE*yyin;
%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_DELAY K_DFF
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_NET K_NET_S K_NET_R
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_MODPATH K_NET K_NET_S K_NET_R
%token K_NET8 K_NET8_S
%token K_PARAM_STR K_PARAM_L K_PART K_PART_PV
%token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
@ -297,6 +306,11 @@ statement
compile_delay($1, obj.cnt, obj.vect);
}
| T_LABEL K_MODPATH symbol ','
{ modpath_dst = compile_modpath($1, $3); }
modpath_src_list ';'
{ modpath_dst = 0; }
/* DFF nodes have an output and take exactly 4 inputs. */
| T_LABEL K_DFF symbol ',' symbol ',' symbol ',' symbol ';'
@ -695,6 +709,20 @@ symbol_opt
}
;
/* This rule is invoked within the rule for a modpath statement. The
beginning of that run has already created the modpath dst object
and saved it in the modpath_dst variable. The modpath_src rule,
then simply needs to attach the items it creates. */
modpath_src_list
: modpath_src
| modpath_src_list ',' modpath_src
;
modpath_src
: symbol '(' numbers ')'
{ compile_modpath_src(modpath_dst, $1, $3); }
;
udp_table
: T_STRING
{ $$ = compile_udp_table(0x0, $1); }
@ -750,6 +778,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.85 2006/09/23 04:57:20 steve
* Basic support for specify timing.
*
* Revision 1.84 2006/07/30 02:51:36 steve
* Fix/implement signed right shift.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: parse_misc.cc,v 1.8 2002/08/12 01:35:08 steve Exp $"
#ident "$Id: parse_misc.cc,v 1.9 2006/09/23 04:57:20 steve Exp $"
#endif
# include "parse_misc.h"
@ -63,6 +63,13 @@ void numbv_add(struct numbv_s*obj, long item)
obj->cnt += 1;
}
void numbv_clear(struct numbv_s*obj)
{
free(obj->nvec);
obj->nvec = 0;
obj->cnt = 0;
}
void argv_init(struct argv_s*obj)
{
obj->argc = 0;
@ -98,6 +105,9 @@ void argv_sym_lookup(struct argv_s*obj)
/*
* $Log: parse_misc.cc,v $
* Revision 1.9 2006/09/23 04:57:20 steve
* Basic support for specify timing.
*
* Revision 1.8 2002/08/12 01:35:08 steve
* conditional ident string using autoconfig.
*

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_misc.h,v 1.7 2002/08/12 01:35:08 steve Exp $"
#ident "$Id: parse_misc.h,v 1.8 2006/09/23 04:57:20 steve Exp $"
#endif
@ -63,6 +63,7 @@ struct numbv_s {
extern void numbv_init(struct numbv_s*obj);
extern void numbv_add(struct numbv_s*obj, long item);
extern void numbv_clear(struct numbv_s*obj);
struct argv_s {
unsigned argc;
@ -77,6 +78,9 @@ extern void argv_sym_lookup(struct argv_s*obj);
/*
* $Log: parse_misc.h,v $
* Revision 1.8 2006/09/23 04:57:20 steve
* Basic support for specify timing.
*
* Revision 1.7 2002/08/12 01:35:08 steve
* conditional ident string using autoconfig.
*