Scopes and processes are accessible randomly from
the design, and signals and logic are accessible from scopes. Remove the target calls that are no longer needed. Add the ivl_nexus_ptr_t and the means to get at them from nexus objects. Give names to methods that manipulate the ivl_design_t type more consistent names.
This commit is contained in:
parent
7ee46bc621
commit
2dedd6c067
229
ivl_target.h
229
ivl_target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_target.h,v 1.19 2000/10/13 03:39:27 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.20 2000/10/15 04:46:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -78,6 +78,13 @@ _BEGIN_DECL
|
|||
* single output, including logic gates and nmos, pmos and cmon
|
||||
* devices. There is also the occasional Icarus Verilog creation.
|
||||
*
|
||||
* ivl_nexus_t
|
||||
* Structural links within an elaborated design are connected
|
||||
* together at each bit. The connection point is a nexus, so pins
|
||||
* of devices refer to an ivl_nexus_t. Furthermore, from a nexus
|
||||
* there are backward references to all the device pins that point
|
||||
* to it.
|
||||
*
|
||||
* ivl_process_t
|
||||
* A Verilog process is represented by one of these. A process may
|
||||
* be an "initial" or an "always" process. These come from initial
|
||||
|
|
@ -111,6 +118,7 @@ typedef struct ivl_net_event_s*ivl_net_event_t;
|
|||
typedef struct ivl_net_logic_s*ivl_net_logic_t;
|
||||
typedef struct ivl_net_probe_s*ivl_net_probe_t;
|
||||
typedef struct ivl_nexus_s *ivl_nexus_t;
|
||||
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
|
||||
typedef struct ivl_process_s *ivl_process_t;
|
||||
typedef struct ivl_scope_s *ivl_scope_t;
|
||||
typedef struct ivl_signal_s *ivl_signal_t;
|
||||
|
|
@ -200,21 +208,45 @@ typedef enum ivl_statement_type_e {
|
|||
IVL_ST_WHILE
|
||||
} ivl_statement_type_t;
|
||||
|
||||
/* This is the type of the function to apply to a process. */
|
||||
typedef int (*ivl_process_f)(ivl_process_t net);
|
||||
|
||||
/* This function returns the string value of the named flag. The key
|
||||
is used to select the flag. If the key does not exist or the flag
|
||||
does not have a value, this function returns 0.
|
||||
/* This is the type of a function to apply to a scope. */
|
||||
typedef int (ivl_scope_f)(ivl_scope_t net);
|
||||
|
||||
Flags come from the "-fkey=value" options to the iverilog command
|
||||
line.
|
||||
|
||||
The key "-o" is special and is the argument to the -o flag of the
|
||||
iverilog command. This is generally how the target learns the name
|
||||
of the output file. */
|
||||
extern const char* ivl_get_flag(ivl_design_t, const char*key);
|
||||
/* DESIGN
|
||||
* When handed a design (ivl_design_t) there are a few things that you
|
||||
* can do with it. The Verilog program has one design that carries the
|
||||
* entire program. Use the design methods to iterate over the elements
|
||||
* of the design.
|
||||
*
|
||||
* ivl_design_flag
|
||||
* This function returns the string value of a named flag. Flags
|
||||
* come from the "-fkey=value" options to the iverilog command and
|
||||
* are stored in a map for this function. Given the key, this
|
||||
* function returns the value.
|
||||
*
|
||||
* The special key "-o" is the argument to the -o flag of the
|
||||
* command line (or the default if the -o flag is not used) and is
|
||||
* generally how the target learns the name of the output file.
|
||||
*
|
||||
* ivl_design_process
|
||||
* This function scans the processes (threads) in the design. It
|
||||
* calls the user suplied function on each of the processes until
|
||||
* one of the functors returns non-0 or all the processes are
|
||||
* scanned. This function will return 0, or the non-zero value that
|
||||
* was returned from the last scanned process.
|
||||
*
|
||||
* ivl_design_root
|
||||
* A design has a root named scope that is an instance of the top
|
||||
* level module in the design. This is a hook for naming the
|
||||
* design, or for starting the scope scan.
|
||||
*/
|
||||
|
||||
/* Get the name of the root module. This can be used as the design name. */
|
||||
extern const char* ivl_get_root_name(ivl_design_t net);
|
||||
extern const char* ivl_design_flag(ivl_design_t des, const char*key);
|
||||
extern int ivl_design_process(ivl_design_t des, ivl_process_f fun);
|
||||
extern ivl_scope_t ivl_design_root(ivl_design_t des);
|
||||
|
||||
/*
|
||||
* These methods apply to ivl_net_const_t objects.
|
||||
|
|
@ -256,25 +288,96 @@ extern unsigned ivl_expr_width(ivl_expr_t net);
|
|||
* ivl_logic_t enumeration identifies the various kinds of gates that
|
||||
* the ivl_net_logic_t can represent. The various functions then
|
||||
* provide access to the bits of information for a given logic device.
|
||||
*
|
||||
* ivl_logic_type
|
||||
* This method returns the type of logic gate that the cookie
|
||||
* represents.
|
||||
*
|
||||
* ivl_logic_name
|
||||
* This method returns the complete name of the logic gate. Every
|
||||
* gate has a complete name (that includes the scope) even if the
|
||||
* Verilog source doesn't include one. The compiler will choose one
|
||||
* if necessary.
|
||||
*
|
||||
* ivl_logic_basename
|
||||
* This is the name of the gate without the scope part.
|
||||
*
|
||||
* ivl_logic_pins
|
||||
* ivl_logic_pin
|
||||
*/
|
||||
|
||||
extern const char* ivl_logic_name(ivl_net_logic_t net);
|
||||
extern const char* ivl_logic_basename(ivl_net_logic_t net);
|
||||
extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net);
|
||||
extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin);
|
||||
extern unsigned ivl_logic_pins(ivl_net_logic_t net);
|
||||
|
||||
/* NEXUS
|
||||
* connections of signals and nodes is handled by single-bit
|
||||
* nexus. These functions manage the ivl_nexus_t object.
|
||||
* nexus. These functions manage the ivl_nexus_t object. They also
|
||||
* manage the ivl_nexus_ptr_t objects that are closely related to the
|
||||
* nexus.
|
||||
*
|
||||
* ivl_nexus_name
|
||||
* Each nexus is given a name, typically derived from the signals
|
||||
* connected to it, but completely made up if need be. The name of
|
||||
* every nexus is unique.
|
||||
*
|
||||
* ivl_nexus_ptrs
|
||||
* This function returns the number of pointers that are held by
|
||||
* the nexus. It should always return at least 1. The pointer
|
||||
* proper is accessed by index.
|
||||
*
|
||||
* ivl_nexus_ptr
|
||||
* Return a nexus pointer given the nexus and an index.
|
||||
*/
|
||||
|
||||
extern const char* ivl_nexus_name(ivl_nexus_t net);
|
||||
extern const char* ivl_nexus_name(ivl_nexus_t net);
|
||||
extern unsigned ivl_nexus_ptrs(ivl_nexus_t net);
|
||||
extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx);
|
||||
|
||||
|
||||
/* SCOPE
|
||||
* Scopes of various sort have these properties. Use these methods to
|
||||
* access them.
|
||||
* access them. Scopes come to exist in the elaborated design
|
||||
* generally when a module is instantiated, though they also come from
|
||||
* named blocks, tasks and functions.
|
||||
*
|
||||
* (NOTE: Module scopes are *instances* of modules, and not the module
|
||||
* definition. A definition may apply to many instances.)
|
||||
*
|
||||
* ivl_scope_children
|
||||
* A scope may in turn contain other scopes. This method iterates
|
||||
* through all the child scopes of a given scope. If the function
|
||||
* returns any value other then 0, the iteration stops and the
|
||||
* method returns that value. Otherwise, iteration continues until
|
||||
* the children run out.
|
||||
*
|
||||
* If the scope has no children, this method will return 0 and
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* ivl_scope_log
|
||||
* ivl_scope_logs
|
||||
* Scopes have 0 or more logic devices in them. A logic device is
|
||||
* represented by ivl_logic_t.
|
||||
*
|
||||
* ivl_scope_name
|
||||
* Every scope has a hierarchical name. This name is also a prefix
|
||||
* of all the names of objects contained within the scope.
|
||||
*
|
||||
* ivl_scope_sig
|
||||
* ivl_scope_sigs
|
||||
* Scopes have 0 or more signals in them. These signals are
|
||||
* anything that can become and ivl_signal_t, include synthetic
|
||||
* signals generated by the compiler.
|
||||
*/
|
||||
extern const char* ivl_scope_name(ivl_scope_t net);
|
||||
|
||||
extern int ivl_scope_children(ivl_scope_t net, ivl_scope_f func);
|
||||
extern unsigned ivl_scope_logs(ivl_scope_t net);
|
||||
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
|
||||
extern const char* ivl_scope_name(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_sigs(ivl_scope_t net);
|
||||
extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx);
|
||||
|
||||
|
||||
/* SIGNALS
|
||||
|
|
@ -403,14 +506,6 @@ typedef int (*net_const_f)(const char*name, ivl_net_const_t net);
|
|||
typedef int (*net_event_f)(const char*name, ivl_net_event_t net);
|
||||
|
||||
|
||||
/* target_net_logic
|
||||
|
||||
This function is called for each logic gate in the design. The name
|
||||
parameter is the name of the gate in the design. If the gate is
|
||||
part of an array of gates, the name includes its index. */
|
||||
typedef int (*net_logic_f)(const char*name, ivl_net_logic_t net);
|
||||
|
||||
|
||||
/* target_net_probe
|
||||
|
||||
This is the probe, or structural trigger, of an event. The
|
||||
|
|
@ -418,41 +513,23 @@ typedef int (*net_logic_f)(const char*name, ivl_net_logic_t net);
|
|||
before this probe is called. */
|
||||
typedef int (*net_probe_f)(const char*name, ivl_net_probe_t net);
|
||||
|
||||
/* target_net_signal
|
||||
|
||||
Signals are things like "wire foo" or "reg bar;" that is, declared
|
||||
signals in the verilog source. These are not memories, which are
|
||||
handled elsewhere. */
|
||||
typedef int (*net_signal_f)(const char*name, ivl_signal_t net);
|
||||
|
||||
|
||||
/* target_process
|
||||
|
||||
The "target_process" function is called for each always and initial
|
||||
block in the design. In principle, the target creates a thread for
|
||||
each process in the Verilog original.
|
||||
|
||||
This function is called with the entire thread generated. The
|
||||
process and statement access methods can be used to randomly
|
||||
(read-only) access all the code of the thread. Also, the module may
|
||||
hold on to the process, the core will not delete it. */
|
||||
typedef int (*process_f)(ivl_process_t net);
|
||||
|
||||
|
||||
/* target_scope (optional)
|
||||
|
||||
If the "target_scope" function is implemented in the module, it is
|
||||
called to introduce a new scope in the design. If scopes are
|
||||
nested, this method is always called for the containing scope
|
||||
before the contained scope. Also, this is guaranteed to be called
|
||||
before functions for any objects contained in this scope. */
|
||||
typedef void (*scope_f)(ivl_scope_t net);
|
||||
|
||||
|
||||
_END_DECL
|
||||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.20 2000/10/15 04:46:23 steve
|
||||
* Scopes and processes are accessible randomly from
|
||||
* the design, and signals and logic are accessible
|
||||
* from scopes. Remove the target calls that are no
|
||||
* longer needed.
|
||||
*
|
||||
* Add the ivl_nexus_ptr_t and the means to get at
|
||||
* them from nexus objects.
|
||||
*
|
||||
* Give names to methods that manipulate the ivl_design_t
|
||||
* type more consistent names.
|
||||
*
|
||||
* Revision 1.19 2000/10/13 03:39:27 steve
|
||||
* Include constants in nexus targets.
|
||||
*
|
||||
|
|
@ -476,49 +553,5 @@ _END_DECL
|
|||
* Revision 1.14 2000/09/30 02:18:15 steve
|
||||
* ivl_expr_t support for binary operators,
|
||||
* Create a proper ivl_scope_t object.
|
||||
*
|
||||
* Revision 1.13 2000/09/26 00:30:07 steve
|
||||
* Add EX_NUMBER and ST_TRIGGER to dll-api.
|
||||
*
|
||||
* Revision 1.12 2000/09/24 15:46:00 steve
|
||||
* API access to signal type and port type.
|
||||
*
|
||||
* Revision 1.11 2000/09/24 02:21:53 steve
|
||||
* Add support for signal expressions.
|
||||
*
|
||||
* Revision 1.10 2000/09/23 05:15:07 steve
|
||||
* Add enough tgt-verilog code to support hello world.
|
||||
*
|
||||
* Revision 1.9 2000/09/22 03:58:30 steve
|
||||
* Access to the name of a system task call.
|
||||
*
|
||||
* Revision 1.8 2000/09/19 04:15:27 steve
|
||||
* Introduce the means to get statement types.
|
||||
*
|
||||
* Revision 1.7 2000/09/18 01:24:32 steve
|
||||
* Get the structure for ivl_statement_t worked out.
|
||||
*
|
||||
* Revision 1.6 2000/08/27 15:51:50 steve
|
||||
* t-dll iterates signals, and passes them to the
|
||||
* target module.
|
||||
*
|
||||
* Some of NetObj should return char*, not string.
|
||||
*
|
||||
* Revision 1.5 2000/08/26 00:54:03 steve
|
||||
* Get at gate information for ivl_target interface.
|
||||
*
|
||||
* Revision 1.4 2000/08/20 04:13:57 steve
|
||||
* Add ivl_target support for logic gates, and
|
||||
* make the interface more accessible.
|
||||
*
|
||||
* Revision 1.3 2000/08/19 18:12:42 steve
|
||||
* Add target calls for scope, events and logic.
|
||||
*
|
||||
* Revision 1.2 2000/08/14 04:39:56 steve
|
||||
* add th t-dll functions for net_const, net_bufz and processes.
|
||||
*
|
||||
* Revision 1.1 2000/08/12 16:34:37 steve
|
||||
* Start stub for loadable targets.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
110
t-dll-api.cc
110
t-dll-api.cc
|
|
@ -17,13 +17,34 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll-api.cc,v 1.11 2000/10/08 04:01:54 steve Exp $"
|
||||
#ident "$Id: t-dll-api.cc,v 1.12 2000/10/15 04:46:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "t-dll.h"
|
||||
|
||||
/* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
|
||||
|
||||
extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key)
|
||||
{
|
||||
return des->self->get_flag(key).c_str();
|
||||
}
|
||||
|
||||
extern "C" int ivl_design_process(ivl_design_t des, ivl_process_f func)
|
||||
{
|
||||
for (ivl_process_t idx = des->threads_; idx; idx = idx->next_) {
|
||||
int rc = (func)(idx);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" ivl_scope_t ivl_design_root(ivl_design_t des)
|
||||
{
|
||||
return des->root_;
|
||||
}
|
||||
|
||||
extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net)
|
||||
{
|
||||
if (net == 0)
|
||||
|
|
@ -31,16 +52,6 @@ extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net)
|
|||
return net->type_;
|
||||
}
|
||||
|
||||
extern "C" const char*ivl_get_flag(ivl_design_t des, const char*key)
|
||||
{
|
||||
return des->self->get_flag(key).c_str();
|
||||
}
|
||||
|
||||
extern "C" const char*ivl_get_root_name(ivl_design_t des)
|
||||
{
|
||||
return des->root_->name_;
|
||||
}
|
||||
|
||||
extern "C" const char*ivl_const_bits(ivl_net_const_t net)
|
||||
{
|
||||
assert(net);
|
||||
|
|
@ -153,6 +164,21 @@ extern "C" unsigned ivl_expr_width(ivl_expr_t net)
|
|||
return net->width_;
|
||||
}
|
||||
|
||||
extern "C" const char* ivl_logic_name(ivl_net_logic_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->name_;
|
||||
}
|
||||
|
||||
extern "C" const char* ivl_logic_basename(ivl_net_logic_t net)
|
||||
{
|
||||
const char*nam = net->name_;
|
||||
nam += strlen(ivl_scope_name(net->scope_));
|
||||
assert(*nam == '.');
|
||||
nam += 1;
|
||||
return nam;
|
||||
}
|
||||
|
||||
extern "C" ivl_logic_t ivl_logic_type(ivl_net_logic_t net)
|
||||
{
|
||||
return net->type_;
|
||||
|
|
@ -175,6 +201,19 @@ extern "C" const char* ivl_nexus_name(ivl_nexus_t net)
|
|||
return net->name_;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->nptr_;
|
||||
}
|
||||
|
||||
extern "C" ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx)
|
||||
{
|
||||
assert(net);
|
||||
assert(idx < net->nptr_);
|
||||
return net->ptrs_ + idx;
|
||||
}
|
||||
|
||||
extern "C" ivl_process_type_t ivl_process_type(ivl_process_t net)
|
||||
{
|
||||
return net->type_;
|
||||
|
|
@ -185,11 +224,48 @@ extern "C" ivl_statement_t ivl_process_stmt(ivl_process_t net)
|
|||
return net->stmt_;
|
||||
}
|
||||
|
||||
extern "C" int ivl_scope_children(ivl_scope_t net, ivl_scope_f func)
|
||||
{
|
||||
for (ivl_scope_t cur = net->child_; cur; cur = cur->sibling_) {
|
||||
int rc = func(cur);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_scope_logs(ivl_scope_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->nlog_;
|
||||
}
|
||||
|
||||
extern "C" ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx)
|
||||
{
|
||||
assert(net);
|
||||
assert(idx < net->nlog_);
|
||||
return net->log_[idx];
|
||||
}
|
||||
|
||||
extern "C" const char* ivl_scope_name(ivl_scope_t net)
|
||||
{
|
||||
return net->name_;
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_scope_sigs(ivl_scope_t net)
|
||||
{
|
||||
assert(net);
|
||||
return net->nsigs_;
|
||||
}
|
||||
|
||||
extern "C" ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx)
|
||||
{
|
||||
assert(net);
|
||||
assert(idx < net->nsigs_);
|
||||
return net->sigs_[idx];
|
||||
}
|
||||
|
||||
extern "C" const char* ivl_signal_basename(ivl_signal_t net)
|
||||
{
|
||||
const char*nam = net->name_;
|
||||
|
|
@ -340,6 +416,18 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
|
|||
|
||||
/*
|
||||
* $Log: t-dll-api.cc,v $
|
||||
* Revision 1.12 2000/10/15 04:46:23 steve
|
||||
* Scopes and processes are accessible randomly from
|
||||
* the design, and signals and logic are accessible
|
||||
* from scopes. Remove the target calls that are no
|
||||
* longer needed.
|
||||
*
|
||||
* Add the ivl_nexus_ptr_t and the means to get at
|
||||
* them from nexus objects.
|
||||
*
|
||||
* Give names to methods that manipulate the ivl_design_t
|
||||
* type more consistent names.
|
||||
*
|
||||
* Revision 1.11 2000/10/08 04:01:54 steve
|
||||
* Back pointers in the nexus objects into the devices
|
||||
* that point to it.
|
||||
|
|
|
|||
92
t-dll.cc
92
t-dll.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll.cc,v 1.14 2000/10/13 03:39:27 steve Exp $"
|
||||
#ident "$Id: t-dll.cc,v 1.15 2000/10/15 04:46:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "compiler.h"
|
||||
|
|
@ -40,12 +40,12 @@ static ivl_scope_t find_scope(ivl_scope_t root, const NetScope*cur)
|
|||
parent = find_scope(root, par);
|
||||
|
||||
} else {
|
||||
assert(root->self == cur);
|
||||
assert(strcmp(root->name_, cur->name().c_str()) == 0);
|
||||
return root;
|
||||
}
|
||||
|
||||
for (tmp = parent->child_ ; tmp ; tmp = tmp->sibling_)
|
||||
if (tmp->self == cur)
|
||||
if (strcmp(tmp->name_, cur->name().c_str()) == 0)
|
||||
return tmp;
|
||||
|
||||
return 0;
|
||||
|
|
@ -55,7 +55,8 @@ static ivl_nexus_t nexus_sig_make(ivl_signal_t net, unsigned pin)
|
|||
{
|
||||
ivl_nexus_t tmp = new struct ivl_nexus_s;
|
||||
tmp->nptr_ = 1;
|
||||
tmp->ptrs_ = (struct __nexus_ptr*) malloc(sizeof(struct __nexus_ptr));
|
||||
tmp->ptrs_ = (struct ivl_nexus_ptr_s*)
|
||||
malloc(sizeof(struct ivl_nexus_ptr_s));
|
||||
tmp->ptrs_[0].pin_ = pin;
|
||||
tmp->ptrs_[0].type_ = __NEXUS_PTR_SIG;
|
||||
tmp->ptrs_[0].l.sig = net;
|
||||
|
|
@ -65,8 +66,8 @@ static ivl_nexus_t nexus_sig_make(ivl_signal_t net, unsigned pin)
|
|||
static void nexus_sig_add(ivl_nexus_t nex, ivl_signal_t net, unsigned pin)
|
||||
{
|
||||
unsigned top = nex->nptr_ + 1;
|
||||
nex->ptrs_ = (struct __nexus_ptr*)
|
||||
realloc(nex->ptrs_, top * sizeof(struct __nexus_ptr));
|
||||
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
|
||||
realloc(nex->ptrs_, top * sizeof(struct ivl_nexus_ptr_s));
|
||||
nex->nptr_ = top;
|
||||
|
||||
nex->ptrs_[top-1].type_= __NEXUS_PTR_SIG;
|
||||
|
|
@ -77,8 +78,8 @@ static void nexus_sig_add(ivl_nexus_t nex, ivl_signal_t net, unsigned pin)
|
|||
static void nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin)
|
||||
{
|
||||
unsigned top = nex->nptr_ + 1;
|
||||
nex->ptrs_ = (struct __nexus_ptr*)
|
||||
realloc(nex->ptrs_, top * sizeof(struct __nexus_ptr));
|
||||
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
|
||||
realloc(nex->ptrs_, top * sizeof(struct ivl_nexus_ptr_s));
|
||||
nex->nptr_ = top;
|
||||
|
||||
nex->ptrs_[top-1].type_= __NEXUS_PTR_LOG;
|
||||
|
|
@ -89,8 +90,8 @@ static void nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin)
|
|||
static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin)
|
||||
{
|
||||
unsigned top = nex->nptr_ + 1;
|
||||
nex->ptrs_ = (struct __nexus_ptr*)
|
||||
realloc(nex->ptrs_, top * sizeof(struct __nexus_ptr));
|
||||
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
|
||||
realloc(nex->ptrs_, top * sizeof(struct ivl_nexus_ptr_s));
|
||||
nex->nptr_ = top;
|
||||
|
||||
nex->ptrs_[top-1].type_= __NEXUS_PTR_CON;
|
||||
|
|
@ -130,18 +131,13 @@ bool dll_target::start_design(const Design*des)
|
|||
des_.self = des;
|
||||
des_.root_ = new struct ivl_scope_s;
|
||||
des_.root_->name_ = strdup(des->find_root_scope()->name().c_str());
|
||||
des_.root_->self = des->find_root_scope();
|
||||
|
||||
start_design_ = (start_design_f)dlsym(dll_, LU "target_start_design" TU);
|
||||
end_design_ = (end_design_f) dlsym(dll_, LU "target_end_design" TU);
|
||||
|
||||
net_const_ = (net_const_f) dlsym(dll_, LU "target_net_const" TU);
|
||||
net_event_ = (net_event_f) dlsym(dll_, LU "target_net_event" TU);
|
||||
net_logic_ = (net_logic_f) dlsym(dll_, LU "target_net_logic" TU);
|
||||
net_probe_ = (net_probe_f) dlsym(dll_, LU "target_net_probe" TU);
|
||||
net_signal_ = (net_signal_f)dlsym(dll_, LU "target_net_signal" TU);
|
||||
process_ = (process_f) dlsym(dll_, LU "target_process" TU);
|
||||
scope_ = (scope_f) dlsym(dll_, LU "target_scope" TU);
|
||||
|
||||
(start_design_)(&des_);
|
||||
return true;
|
||||
|
|
@ -153,17 +149,6 @@ bool dll_target::start_design(const Design*des)
|
|||
*/
|
||||
void dll_target::end_design(const Design*)
|
||||
{
|
||||
if (process_) {
|
||||
for (ivl_process_t idx = des_.threads_; idx; idx = idx->next_) {
|
||||
process_(idx);
|
||||
}
|
||||
|
||||
} else {
|
||||
cerr << dll_path_ << ": internal error: target DLL lacks "
|
||||
<< "target_process function." << endl;
|
||||
}
|
||||
|
||||
|
||||
(end_design_)(&des_);
|
||||
dlclose(dll_);
|
||||
}
|
||||
|
|
@ -186,7 +171,6 @@ bool dll_target::bufz(const NetBUFZ*net)
|
|||
obj->npins_ = 2;
|
||||
obj->pins_ = new ivl_nexus_t[2];
|
||||
|
||||
|
||||
/* Get the ivl_nexus_t objects connected to the two pins.
|
||||
|
||||
(We know a priori that the ivl_nexus_t objects have been
|
||||
|
|
@ -208,13 +192,10 @@ bool dll_target::bufz(const NetBUFZ*net)
|
|||
ivl_scope_t scope = find_scope(des_.root_, net->scope());
|
||||
assert(scope);
|
||||
|
||||
obj->scope_ = scope;
|
||||
obj->name_ = strdup(net->name());
|
||||
scope_add_logic(scope, obj);
|
||||
|
||||
if (net_logic_) {
|
||||
(net_logic_)(net->name(), obj);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -270,12 +251,10 @@ void dll_target::logic(const NetLogic*net)
|
|||
ivl_scope_t scope = find_scope(des_.root_, net->scope());
|
||||
assert(scope);
|
||||
|
||||
obj->scope_= scope;
|
||||
obj->name_ = strdup(net->name());
|
||||
|
||||
scope_add_logic(scope, obj);
|
||||
|
||||
if (net_logic_) {
|
||||
(net_logic_)(net->name(), obj);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool dll_target::net_const(const NetConst*net)
|
||||
|
|
@ -358,12 +337,11 @@ void dll_target::scope(const NetScope*net)
|
|||
ivl_scope_t scope;
|
||||
|
||||
if (net->parent() == 0) {
|
||||
assert(des_.root_->self == net);
|
||||
assert(strcmp(des_.root_->name_, net->name().c_str()) == 0);
|
||||
scope = des_.root_;
|
||||
|
||||
} else {
|
||||
scope = new struct ivl_scope_s;
|
||||
scope->self = net;
|
||||
scope->name_ = strdup(net->name().c_str());
|
||||
|
||||
ivl_scope_t parent = find_scope(des_.root_, net->parent());
|
||||
|
|
@ -372,9 +350,6 @@ void dll_target::scope(const NetScope*net)
|
|||
scope->sibling_= parent->child_;
|
||||
parent->child_ = scope;
|
||||
}
|
||||
|
||||
if (scope_)
|
||||
(scope_)(scope);
|
||||
}
|
||||
|
||||
void dll_target::signal(const NetNet*net)
|
||||
|
|
@ -401,13 +376,13 @@ void dll_target::signal(const NetNet*net)
|
|||
obj->scope_->sigs_ = (ivl_signal_t*)
|
||||
realloc(obj->scope_->sigs_,
|
||||
obj->scope_->nsigs_*sizeof(ivl_signal_t));
|
||||
obj->scope_->sigs_[obj->scope_->nsigs_-1] = obj;
|
||||
}
|
||||
|
||||
obj->scope_->sigs_[obj->scope_->nsigs_-1] = obj;
|
||||
|
||||
#ifndef NDEBUG
|
||||
{ const char*scope_name = obj->scope_->self->name().c_str();
|
||||
size_t name_len = strlen(scope_name);
|
||||
assert(0 == strncmp(scope_name, obj->name_, name_len));
|
||||
{ size_t name_len = strlen(obj->scope_->name_);
|
||||
assert(0 == strncmp(obj->scope_->name_, obj->name_, name_len));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -531,19 +506,6 @@ void dll_target::signal(const NetNet*net)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Invoke the target_net_signal function of the loaded target
|
||||
module, if it exists. */
|
||||
|
||||
if (net_signal_) {
|
||||
int rc = (net_signal_)(obj->name_, obj);
|
||||
return;
|
||||
|
||||
} else {
|
||||
cerr << dll_path_ << ": internal error: target DLL lacks "
|
||||
<< "target_net_signal function." << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
||||
|
|
@ -551,6 +513,18 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
|||
|
||||
/*
|
||||
* $Log: t-dll.cc,v $
|
||||
* Revision 1.15 2000/10/15 04:46:23 steve
|
||||
* Scopes and processes are accessible randomly from
|
||||
* the design, and signals and logic are accessible
|
||||
* from scopes. Remove the target calls that are no
|
||||
* longer needed.
|
||||
*
|
||||
* Add the ivl_nexus_ptr_t and the means to get at
|
||||
* them from nexus objects.
|
||||
*
|
||||
* Give names to methods that manipulate the ivl_design_t
|
||||
* type more consistent names.
|
||||
*
|
||||
* Revision 1.14 2000/10/13 03:39:27 steve
|
||||
* Include constants in nexus targets.
|
||||
*
|
||||
|
|
|
|||
28
t-dll.h
28
t-dll.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll.h,v 1.12 2000/10/13 03:39:27 steve Exp $"
|
||||
#ident "$Id: t-dll.h,v 1.13 2000/10/15 04:46:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -66,12 +66,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
|||
|
||||
net_const_f net_const_;
|
||||
net_event_f net_event_;
|
||||
net_logic_f net_logic_;
|
||||
net_probe_f net_probe_;
|
||||
net_signal_f net_signal_;
|
||||
|
||||
process_f process_;
|
||||
scope_f scope_;
|
||||
|
||||
/* These methods and members are used for forming the
|
||||
statements of a thread. */
|
||||
|
|
@ -160,6 +155,10 @@ struct ivl_net_const_s {
|
|||
*/
|
||||
struct ivl_net_logic_s {
|
||||
ivl_logic_t type_;
|
||||
|
||||
char* name_;
|
||||
ivl_scope_t scope_;
|
||||
|
||||
unsigned npins_;
|
||||
ivl_nexus_t*pins_;
|
||||
};
|
||||
|
|
@ -170,7 +169,7 @@ struct ivl_net_logic_s {
|
|||
* devices. the __nexus_ptr structure is a helper that actually does
|
||||
* the pointing.
|
||||
*/
|
||||
struct __nexus_ptr {
|
||||
struct ivl_nexus_ptr_s {
|
||||
unsigned pin_ :24;
|
||||
unsigned type_ : 8;
|
||||
union {
|
||||
|
|
@ -185,7 +184,7 @@ struct __nexus_ptr {
|
|||
|
||||
struct ivl_nexus_s {
|
||||
unsigned nptr_;
|
||||
struct __nexus_ptr*ptrs_;
|
||||
struct ivl_nexus_ptr_s*ptrs_;
|
||||
char*name_;
|
||||
};
|
||||
|
||||
|
|
@ -210,7 +209,6 @@ struct ivl_scope_s {
|
|||
ivl_scope_t child_, sibling_;
|
||||
|
||||
char* name_;
|
||||
const NetScope*self;
|
||||
|
||||
unsigned nsigs_;
|
||||
ivl_signal_t*sigs_;
|
||||
|
|
@ -300,6 +298,18 @@ struct ivl_statement_s {
|
|||
|
||||
/*
|
||||
* $Log: t-dll.h,v $
|
||||
* Revision 1.13 2000/10/15 04:46:23 steve
|
||||
* Scopes and processes are accessible randomly from
|
||||
* the design, and signals and logic are accessible
|
||||
* from scopes. Remove the target calls that are no
|
||||
* longer needed.
|
||||
*
|
||||
* Add the ivl_nexus_ptr_t and the means to get at
|
||||
* them from nexus objects.
|
||||
*
|
||||
* Give names to methods that manipulate the ivl_design_t
|
||||
* type more consistent names.
|
||||
*
|
||||
* Revision 1.12 2000/10/13 03:39:27 steve
|
||||
* Include constants in nexus targets.
|
||||
*
|
||||
|
|
|
|||
37
t-dll.txt
37
t-dll.txt
|
|
@ -18,6 +18,9 @@ The target module loader is invoked with the ivl flag "-tdll". That
|
|||
is, the DLL loader is a linked in target type. The name of the target
|
||||
module to load is then specified with the DLL flag, i.e. "-fDLL=<path>".
|
||||
|
||||
COMPILING TARGET MODULES
|
||||
|
||||
<write me>
|
||||
|
||||
LOADABLE TARGET MODULE API
|
||||
|
||||
|
|
@ -25,37 +28,3 @@ The target module API is defined in the ivl_target.h header file. This
|
|||
declares all the type and functions that a loadable module needs to
|
||||
access the design.
|
||||
|
||||
|
||||
PROCESSES
|
||||
|
||||
A process is an always or initial construct with its associated
|
||||
statement. The target gets from the compiler an ivl_process_t object,
|
||||
that holds the process type (always or initial) and the statement,
|
||||
which is an ivl_statement_t.
|
||||
|
||||
All the interesting stuff happens in the ivl_statement_t object. This
|
||||
is a generic object that represents any single Verilog statement. If
|
||||
the statement is compound, then it also holds references to the
|
||||
contained statements. The target module can access statements in any
|
||||
way it chooses, once it is handed the process that contains the
|
||||
statement.
|
||||
|
||||
|
||||
EXPRESSIONS
|
||||
|
||||
In behavioral code (and some combinational code) expressions are
|
||||
passed on to the target as ivl_expr_t objects. Each object is a node
|
||||
in a tree that represents the expression from the source. All the
|
||||
issues of width and sign are taken care of so that it is clear an easy
|
||||
to know exactly what you have.
|
||||
|
||||
All expressions have a width, available with the ivl_expr_width()
|
||||
function. Each node in an expression tree may have a different width,
|
||||
the compiler figures out everything and eliminates the ambiguity.
|
||||
|
||||
All expressions are also "signed" or "unsigned" -- mostly
|
||||
unsigned. The ivl_expr_signed() function returns true if the
|
||||
expression node is signed. A node may be signed, for example, if it is
|
||||
a reference to an integer or a signed wire. The compiler figures out
|
||||
whether or not each node is signed, the target need not guess.
|
||||
|
||||
|
|
|
|||
334
tgt-stub/stub.c
334
tgt-stub/stub.c
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: stub.c,v 1.16 2000/10/08 05:00:04 steve Exp $"
|
||||
#ident "$Id: stub.c,v 1.17 2000/10/15 04:46:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -32,135 +32,6 @@
|
|||
|
||||
static FILE*out;
|
||||
|
||||
int target_start_design(ivl_design_t des)
|
||||
{
|
||||
const char*path = ivl_get_flag(des, "-o");
|
||||
if (path == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
out = fopen(path, "w");
|
||||
if (out == 0) {
|
||||
perror(path);
|
||||
return -2;
|
||||
}
|
||||
|
||||
fprintf(out, "root module = %s;\n", ivl_get_root_name(des));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void target_end_design(ivl_design_t des)
|
||||
{
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int target_net_const(const char*name, ivl_net_const_t net)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned wid = ivl_const_pins(net);
|
||||
const char*bits = ivl_const_bits(net);
|
||||
|
||||
fprintf(out, "LPM_CONSTANT %s: %s%u'b", name,
|
||||
ivl_const_signed(net)? "+- ":"",
|
||||
wid);
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1)
|
||||
fprintf(out, "%c", bits[wid-1-idx]);
|
||||
|
||||
fprintf(out, " (%s", ivl_nexus_name(ivl_const_pin(net, 0)));
|
||||
for (idx = 1 ; idx < wid ; idx += 1)
|
||||
fprintf(out, ", %s", ivl_nexus_name(ivl_const_pin(net, idx)));
|
||||
|
||||
fprintf(out, ")\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_event(const char*name, ivl_net_event_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: event\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_logic(const char*name, ivl_net_logic_t net)
|
||||
{
|
||||
unsigned npins, idx;
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
case IVL_LO_AND:
|
||||
fprintf(out, "and %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_BUF:
|
||||
fprintf(out, "buf %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_BUFZ:
|
||||
fprintf(out, "bufz %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
fprintf(out, "or %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
fprintf(out, "xor %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
default:
|
||||
fprintf(out, "unsupported gate %s: \n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
npins = ivl_logic_pins(net);
|
||||
for (idx = 1 ; idx < npins ; idx += 1)
|
||||
fprintf(out, ", %s", ivl_nexus_name(ivl_logic_pin(net,idx)));
|
||||
|
||||
fprintf(out, ");\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_probe(const char*name, ivl_net_probe_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: probe\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_signal(const char*name, ivl_signal_t net)
|
||||
{
|
||||
const char*type = "?";
|
||||
const char*port = "";
|
||||
|
||||
switch (ivl_signal_type(net)) {
|
||||
case IVL_SIT_REG:
|
||||
type = "reg";
|
||||
break;
|
||||
case IVL_SIT_WIRE:
|
||||
type = "wire";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ivl_signal_port(net)) {
|
||||
|
||||
case IVL_SIP_INPUT:
|
||||
port = "input ";
|
||||
break;
|
||||
|
||||
case IVL_SIP_OUTPUT:
|
||||
port = "output ";
|
||||
break;
|
||||
|
||||
case IVL_SIP_INOUT:
|
||||
port = "inout ";
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(out, "%s %s[%u] %s\n", type, port,
|
||||
ivl_signal_pins(net), name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_expression(ivl_expr_t net, unsigned ind)
|
||||
{
|
||||
const ivl_expr_type_t code = ivl_expr_type(net);
|
||||
|
|
@ -281,7 +152,7 @@ static void show_statement(ivl_statement_t net, unsigned ind)
|
|||
}
|
||||
}
|
||||
|
||||
int target_process(ivl_process_t net)
|
||||
static int show_process(ivl_process_t net)
|
||||
{
|
||||
switch (ivl_process_type(net)) {
|
||||
case IVL_PR_INITIAL:
|
||||
|
|
@ -297,8 +168,168 @@ int target_process(ivl_process_t net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void show_signal(ivl_signal_t net)
|
||||
{
|
||||
const char*type = "?";
|
||||
const char*port = "";
|
||||
|
||||
switch (ivl_signal_type(net)) {
|
||||
case IVL_SIT_REG:
|
||||
type = "reg";
|
||||
break;
|
||||
case IVL_SIT_WIRE:
|
||||
type = "wire";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ivl_signal_port(net)) {
|
||||
|
||||
case IVL_SIP_INPUT:
|
||||
port = "input ";
|
||||
break;
|
||||
|
||||
case IVL_SIP_OUTPUT:
|
||||
port = "output ";
|
||||
break;
|
||||
|
||||
case IVL_SIP_INOUT:
|
||||
port = "inout ";
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(out, " %s %s[%u] %s\n", type, port,
|
||||
ivl_signal_pins(net), ivl_signal_basename(net));
|
||||
}
|
||||
|
||||
static void show_logic(ivl_net_logic_t net)
|
||||
{
|
||||
unsigned npins, idx;
|
||||
const char*name = ivl_logic_basename(net);
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
case IVL_LO_AND:
|
||||
fprintf(out, " and %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_BUF:
|
||||
fprintf(out, " buf %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_BUFZ:
|
||||
fprintf(out, " bufz %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
fprintf(out, " or %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
fprintf(out, " xor %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
default:
|
||||
fprintf(out, " unsupported gate %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
return;
|
||||
}
|
||||
|
||||
npins = ivl_logic_pins(net);
|
||||
for (idx = 1 ; idx < npins ; idx += 1)
|
||||
fprintf(out, ", %s", ivl_nexus_name(ivl_logic_pin(net,idx)));
|
||||
|
||||
fprintf(out, ");\n");
|
||||
}
|
||||
|
||||
static int show_scope(ivl_scope_t net)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
fprintf(out, "scope: %s (%u signals, %u logic)\n", ivl_scope_name(net),
|
||||
ivl_scope_sigs(net), ivl_scope_logs(net));
|
||||
|
||||
for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1)
|
||||
show_signal(ivl_scope_sig(net, idx));
|
||||
|
||||
for (idx = 0 ; idx < ivl_scope_logs(net) ; idx += 1)
|
||||
show_logic(ivl_scope_log(net, idx));
|
||||
|
||||
fprintf(out, "end scope %s\n", ivl_scope_name(net));
|
||||
return ivl_scope_children(net, show_scope);
|
||||
}
|
||||
|
||||
int target_start_design(ivl_design_t des)
|
||||
{
|
||||
const char*path = ivl_design_flag(des, "-o");
|
||||
if (path == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
out = fopen(path, "w");
|
||||
if (out == 0) {
|
||||
perror(path);
|
||||
return -2;
|
||||
}
|
||||
|
||||
fprintf(out, "root module = %s;\n",
|
||||
ivl_scope_name(ivl_design_root(des)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void target_end_design(ivl_design_t des)
|
||||
{
|
||||
show_scope(ivl_design_root(des));
|
||||
ivl_design_process(des, show_process);
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int target_net_const(const char*name, ivl_net_const_t net)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned wid = ivl_const_pins(net);
|
||||
const char*bits = ivl_const_bits(net);
|
||||
|
||||
fprintf(out, "LPM_CONSTANT %s: %s%u'b", name,
|
||||
ivl_const_signed(net)? "+- ":"",
|
||||
wid);
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1)
|
||||
fprintf(out, "%c", bits[wid-1-idx]);
|
||||
|
||||
fprintf(out, " (%s", ivl_nexus_name(ivl_const_pin(net, 0)));
|
||||
for (idx = 1 ; idx < wid ; idx += 1)
|
||||
fprintf(out, ", %s", ivl_nexus_name(ivl_const_pin(net, idx)));
|
||||
|
||||
fprintf(out, ")\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_event(const char*name, ivl_net_event_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: event\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_probe(const char*name, ivl_net_probe_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: probe\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: stub.c,v $
|
||||
* Revision 1.17 2000/10/15 04:46:23 steve
|
||||
* Scopes and processes are accessible randomly from
|
||||
* the design, and signals and logic are accessible
|
||||
* from scopes. Remove the target calls that are no
|
||||
* longer needed.
|
||||
*
|
||||
* Add the ivl_nexus_ptr_t and the means to get at
|
||||
* them from nexus objects.
|
||||
*
|
||||
* Give names to methods that manipulate the ivl_design_t
|
||||
* type more consistent names.
|
||||
*
|
||||
* Revision 1.16 2000/10/08 05:00:04 steve
|
||||
* Missing stream in call to fprintf.
|
||||
*
|
||||
|
|
@ -312,46 +343,5 @@ int target_process(ivl_process_t net)
|
|||
*
|
||||
* Revision 1.13 2000/10/05 05:03:01 steve
|
||||
* xor and constant devices.
|
||||
*
|
||||
* Revision 1.12 2000/09/26 00:30:07 steve
|
||||
* Add EX_NUMBER and ST_TRIGGER to dll-api.
|
||||
*
|
||||
* Revision 1.11 2000/09/24 15:46:00 steve
|
||||
* API access to signal type and port type.
|
||||
*
|
||||
* Revision 1.10 2000/09/24 02:21:53 steve
|
||||
* Add support for signal expressions.
|
||||
*
|
||||
* Revision 1.9 2000/09/22 03:58:30 steve
|
||||
* Access to the name of a system task call.
|
||||
*
|
||||
* Revision 1.8 2000/09/19 04:15:27 steve
|
||||
* Introduce the means to get statement types.
|
||||
*
|
||||
* Revision 1.7 2000/09/18 01:24:32 steve
|
||||
* Get the structure for ivl_statement_t worked out.
|
||||
*
|
||||
* Revision 1.6 2000/08/27 15:51:51 steve
|
||||
* t-dll iterates signals, and passes them to the
|
||||
* target module.
|
||||
*
|
||||
* Some of NetObj should return char*, not string.
|
||||
*
|
||||
* Revision 1.5 2000/08/26 00:54:03 steve
|
||||
* Get at gate information for ivl_target interface.
|
||||
*
|
||||
* Revision 1.4 2000/08/20 04:13:57 steve
|
||||
* Add ivl_target support for logic gates, and
|
||||
* make the interface more accessible.
|
||||
*
|
||||
* Revision 1.3 2000/08/19 18:12:42 steve
|
||||
* Add target calls for scope, events and logic.
|
||||
*
|
||||
* Revision 1.2 2000/08/14 04:39:57 steve
|
||||
* add th t-dll functions for net_const, net_bufz and processes.
|
||||
*
|
||||
* Revision 1.1 2000/08/12 16:34:37 steve
|
||||
* Start stub for loadable targets.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: verilog.c,v 1.10 2000/10/08 04:01:55 steve Exp $"
|
||||
#ident "$Id: verilog.c,v 1.11 2000/10/15 04:46:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -32,106 +32,6 @@
|
|||
|
||||
static FILE*out;
|
||||
|
||||
int target_start_design(ivl_design_t des)
|
||||
{
|
||||
const char*path = ivl_get_flag(des, "-o");
|
||||
if (path == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
out = fopen(path, "w");
|
||||
if (out == 0) {
|
||||
perror(path);
|
||||
return -2;
|
||||
}
|
||||
|
||||
fprintf(out, "module %s;\n", ivl_get_root_name(des));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void target_end_design(ivl_design_t des)
|
||||
{
|
||||
fprintf(out, "endmodule\n");
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int target_net_const(const char*name, ivl_net_const_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: constant\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_event(const char*name, ivl_net_event_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: event\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_logic(const char*name, ivl_net_logic_t net)
|
||||
{
|
||||
unsigned npins, idx;
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
case IVL_LO_AND:
|
||||
fprintf(out, " and %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_BUF:
|
||||
fprintf(out, " buf %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
fprintf(out, " or %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
fprintf(out, " xor %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
default:
|
||||
fprintf(out, "STUB: %s: unsupported gate\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
npins = ivl_logic_pins(net);
|
||||
for (idx = 1 ; idx < npins ; idx += 1)
|
||||
fprintf(out, ", %s", ivl_nexus_name(ivl_logic_pin(net,idx)));
|
||||
|
||||
fprintf(out, ");\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_probe(const char*name, ivl_net_probe_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: probe\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_signal(const char*name, ivl_signal_t net)
|
||||
{
|
||||
unsigned cnt = ivl_signal_pins(net);
|
||||
|
||||
switch (ivl_signal_type(net)) {
|
||||
|
||||
case IVL_SIT_REG:
|
||||
fprintf(out, " reg [%u:0] %s; // %s\n", cnt-1,
|
||||
ivl_signal_basename(net), name);
|
||||
break;
|
||||
|
||||
case IVL_SIT_WIRE:
|
||||
fprintf(out, " wire [%u:0] %s; // %s\n", cnt-1,
|
||||
ivl_signal_basename(net), name);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(out, " <huh!?> [%u:0] %s;\n", cnt-1, name);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_expression(ivl_expr_t net)
|
||||
{
|
||||
if (net == 0)
|
||||
|
|
@ -268,7 +168,7 @@ static void show_statement(ivl_statement_t net, unsigned ind)
|
|||
}
|
||||
}
|
||||
|
||||
int target_process(ivl_process_t net)
|
||||
static int show_process(ivl_process_t net)
|
||||
{
|
||||
switch (ivl_process_type(net)) {
|
||||
case IVL_PR_INITIAL:
|
||||
|
|
@ -284,8 +184,122 @@ int target_process(ivl_process_t net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int target_start_design(ivl_design_t des)
|
||||
{
|
||||
const char*path = ivl_design_flag(des, "-o");
|
||||
if (path == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
out = fopen(path, "w");
|
||||
if (out == 0) {
|
||||
perror(path);
|
||||
return -2;
|
||||
}
|
||||
|
||||
fprintf(out, "module %s;\n", ivl_scope_name(ivl_design_root(des)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void target_end_design(ivl_design_t des)
|
||||
{
|
||||
ivl_design_process(des, show_process);
|
||||
|
||||
fprintf(out, "endmodule\n");
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int target_net_const(const char*name, ivl_net_const_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: constant\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_event(const char*name, ivl_net_event_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: event\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_logic(const char*name, ivl_net_logic_t net)
|
||||
{
|
||||
unsigned npins, idx;
|
||||
|
||||
switch (ivl_logic_type(net)) {
|
||||
case IVL_LO_AND:
|
||||
fprintf(out, " and %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_BUF:
|
||||
fprintf(out, " buf %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_OR:
|
||||
fprintf(out, " or %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
case IVL_LO_XOR:
|
||||
fprintf(out, " xor %s (%s", name,
|
||||
ivl_nexus_name(ivl_logic_pin(net, 0)));
|
||||
break;
|
||||
default:
|
||||
fprintf(out, "STUB: %s: unsupported gate\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
npins = ivl_logic_pins(net);
|
||||
for (idx = 1 ; idx < npins ; idx += 1)
|
||||
fprintf(out, ", %s", ivl_nexus_name(ivl_logic_pin(net,idx)));
|
||||
|
||||
fprintf(out, ");\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_probe(const char*name, ivl_net_probe_t net)
|
||||
{
|
||||
fprintf(out, "STUB: %s: probe\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int target_net_signal(const char*name, ivl_signal_t net)
|
||||
{
|
||||
unsigned cnt = ivl_signal_pins(net);
|
||||
|
||||
switch (ivl_signal_type(net)) {
|
||||
|
||||
case IVL_SIT_REG:
|
||||
fprintf(out, " reg [%u:0] %s; // %s\n", cnt-1,
|
||||
ivl_signal_basename(net), name);
|
||||
break;
|
||||
|
||||
case IVL_SIT_WIRE:
|
||||
fprintf(out, " wire [%u:0] %s; // %s\n", cnt-1,
|
||||
ivl_signal_basename(net), name);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(out, " <huh!?> [%u:0] %s;\n", cnt-1, name);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: verilog.c,v $
|
||||
* Revision 1.11 2000/10/15 04:46:23 steve
|
||||
* Scopes and processes are accessible randomly from
|
||||
* the design, and signals and logic are accessible
|
||||
* from scopes. Remove the target calls that are no
|
||||
* longer needed.
|
||||
*
|
||||
* Add the ivl_nexus_ptr_t and the means to get at
|
||||
* them from nexus objects.
|
||||
*
|
||||
* Give names to methods that manipulate the ivl_design_t
|
||||
* type more consistent names.
|
||||
*
|
||||
* Revision 1.10 2000/10/08 04:01:55 steve
|
||||
* Back pointers in the nexus objects into the devices
|
||||
* that point to it.
|
||||
|
|
|
|||
Loading…
Reference in New Issue