Generate code for task calls.
This commit is contained in:
parent
e6c36597eb
commit
f40d006c26
15
elaborate.cc
15
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: elaborate.cc,v 1.208 2001/02/15 06:59:36 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.209 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1366,7 +1366,8 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
||||||
NetScope*scope = des->find_scope(path);
|
NetScope*scope = des->find_scope(path);
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
NetTaskDef*def = des->find_task(scope, name_);
|
NetScope*task = des->find_task(scope, name_);
|
||||||
|
NetTaskDef*def = task->task_def();
|
||||||
if (def == 0) {
|
if (def == 0) {
|
||||||
cerr << get_line() << ": error: Enable of unknown task ``" <<
|
cerr << get_line() << ": error: Enable of unknown task ``" <<
|
||||||
scope->name() << "." << name_ << "''." << endl;
|
scope->name() << "." << name_ << "''." << endl;
|
||||||
|
|
@ -1386,7 +1387,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
||||||
/* Handle tasks with no parameters specially. There is no need
|
/* Handle tasks with no parameters specially. There is no need
|
||||||
to make a sequential block to hold the generated code. */
|
to make a sequential block to hold the generated code. */
|
||||||
if (nparms() == 0) {
|
if (nparms() == 0) {
|
||||||
cur = new NetUTask(def);
|
cur = new NetUTask(task);
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1425,7 +1426,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the task call proper... */
|
/* Generate the task call proper... */
|
||||||
cur = new NetUTask(def);
|
cur = new NetUTask(task);
|
||||||
block->append(cur);
|
block->append(cur);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2171,7 +2172,8 @@ NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
||||||
|
|
||||||
void PTask::elaborate(Design*des, const string&path) const
|
void PTask::elaborate(Design*des, const string&path) const
|
||||||
{
|
{
|
||||||
NetTaskDef*def = des->find_task(path);
|
NetScope*task = des->find_task(path);
|
||||||
|
NetTaskDef*def = task->task_def();
|
||||||
assert(def);
|
assert(def);
|
||||||
|
|
||||||
NetProc*st;
|
NetProc*st;
|
||||||
|
|
@ -2367,6 +2369,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.209 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.208 2001/02/15 06:59:36 steve
|
* Revision 1.208 2001/02/15 06:59:36 steve
|
||||||
* FreeBSD port has a maintainer now.
|
* FreeBSD port has a maintainer now.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
7
emit.cc
7
emit.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: emit.cc,v 1.56 2001/03/27 03:31:06 steve Exp $"
|
#ident "$Id: emit.cc,v 1.57 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -357,7 +357,7 @@ void NetScope::emit_defs(struct target_t*tgt) const
|
||||||
tgt->func_def(this->func_def());
|
tgt->func_def(this->func_def());
|
||||||
break;
|
break;
|
||||||
case TASK:
|
case TASK:
|
||||||
tgt->task_def(this->task_def());
|
tgt->task_def(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,6 +478,9 @@ bool emit(const Design*des, const char*type)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: emit.cc,v $
|
* $Log: emit.cc,v $
|
||||||
|
* Revision 1.57 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.56 2001/03/27 03:31:06 steve
|
* Revision 1.56 2001/03/27 03:31:06 steve
|
||||||
* Support error code from target_t::end_design method.
|
* Support error code from target_t::end_design method.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
15
ivl_target.h
15
ivl_target.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: ivl_target.h,v 1.44 2001/04/02 00:28:35 steve Exp $"
|
#ident "$Id: ivl_target.h,v 1.45 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -249,6 +249,7 @@ typedef enum ivl_statement_type_e {
|
||||||
IVL_ST_FORK,
|
IVL_ST_FORK,
|
||||||
IVL_ST_STASK,
|
IVL_ST_STASK,
|
||||||
IVL_ST_TRIGGER,
|
IVL_ST_TRIGGER,
|
||||||
|
IVL_ST_UTASK,
|
||||||
IVL_ST_WAIT,
|
IVL_ST_WAIT,
|
||||||
IVL_ST_WHILE
|
IVL_ST_WHILE
|
||||||
} ivl_statement_type_t;
|
} ivl_statement_type_t;
|
||||||
|
|
@ -540,6 +541,10 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||||
* If the scope has no children, this method will return 0 and
|
* If the scope has no children, this method will return 0 and
|
||||||
* otherwise do nothing.
|
* otherwise do nothing.
|
||||||
*
|
*
|
||||||
|
* ivl_scope_def
|
||||||
|
* Task definition scopes carry a task definition, in the form of
|
||||||
|
* a statement. This method accesses that definition.
|
||||||
|
*
|
||||||
* ivl_scope_event
|
* ivl_scope_event
|
||||||
* ivl_scope_events
|
* ivl_scope_events
|
||||||
* Scopes have 0 or more event objects in them.
|
* Scopes have 0 or more event objects in them.
|
||||||
|
|
@ -569,6 +574,9 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||||
|
|
||||||
extern int ivl_scope_children(ivl_scope_t net,
|
extern int ivl_scope_children(ivl_scope_t net,
|
||||||
ivl_scope_f func, void*cd);
|
ivl_scope_f func, void*cd);
|
||||||
|
|
||||||
|
extern ivl_statement_t ivl_scope_def(ivl_scope_t net);
|
||||||
|
|
||||||
extern unsigned ivl_scope_events(ivl_scope_t net);
|
extern unsigned ivl_scope_events(ivl_scope_t net);
|
||||||
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
|
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
|
||||||
extern unsigned ivl_scope_logs(ivl_scope_t net);
|
extern unsigned ivl_scope_logs(ivl_scope_t net);
|
||||||
|
|
@ -674,6 +682,8 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
|
||||||
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
|
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
|
||||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||||
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
|
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
|
||||||
|
/* IVL_ST_UTASK */
|
||||||
|
extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
|
||||||
/* IVL_ST_CASE */
|
/* IVL_ST_CASE */
|
||||||
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
||||||
/* IVL_ST_CASE */
|
/* IVL_ST_CASE */
|
||||||
|
|
@ -725,6 +735,9 @@ _END_DECL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: ivl_target.h,v $
|
* $Log: ivl_target.h,v $
|
||||||
|
* Revision 1.45 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.44 2001/04/02 00:28:35 steve
|
* Revision 1.44 2001/04/02 00:28:35 steve
|
||||||
* Support the scope expression node.
|
* Support the scope expression node.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: net_design.cc,v 1.18 2001/01/14 23:04:56 steve Exp $"
|
#ident "$Id: net_design.cc,v 1.19 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -393,20 +393,20 @@ NetFuncDef* Design::find_function(const string&key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetTaskDef* Design::find_task(NetScope*scope, const string&name)
|
NetScope* Design::find_task(NetScope*scope, const string&name)
|
||||||
{
|
{
|
||||||
NetScope*task = find_scope(scope, name);
|
NetScope*task = find_scope(scope, name);
|
||||||
if (task && (task->type() == NetScope::TASK))
|
if (task && (task->type() == NetScope::TASK))
|
||||||
return task->task_def();
|
return task;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetTaskDef* Design::find_task(const string&key)
|
NetScope* Design::find_task(const string&key)
|
||||||
{
|
{
|
||||||
NetScope*task = find_scope(key);
|
NetScope*task = find_scope(key);
|
||||||
if (task && (task->type() == NetScope::TASK))
|
if (task && (task->type() == NetScope::TASK))
|
||||||
return task->task_def();
|
return task;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -473,6 +473,9 @@ void Design::delete_process(NetProcTop*top)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: net_design.cc,v $
|
* $Log: net_design.cc,v $
|
||||||
|
* Revision 1.19 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.18 2001/01/14 23:04:56 steve
|
* Revision 1.18 2001/01/14 23:04:56 steve
|
||||||
* Generalize the evaluation of floating point delays, and
|
* Generalize the evaluation of floating point delays, and
|
||||||
* get it working with delay assignment statements.
|
* get it working with delay assignment statements.
|
||||||
|
|
|
||||||
17
netlist.cc
17
netlist.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: netlist.cc,v 1.157 2001/02/10 21:20:38 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.158 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -1752,7 +1752,7 @@ NetEUFunc* NetEUFunc::dup_expr() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetUTask::NetUTask(NetTaskDef*def)
|
NetUTask::NetUTask(NetScope*def)
|
||||||
: task_(def)
|
: task_(def)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -1761,6 +1761,16 @@ NetUTask::~NetUTask()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string& NetUTask::name() const
|
||||||
|
{
|
||||||
|
return task_->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
const NetScope* NetUTask::task() const
|
||||||
|
{
|
||||||
|
return task_;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr::NetExpr(unsigned w)
|
NetExpr::NetExpr(unsigned w)
|
||||||
: width_(w)
|
: width_(w)
|
||||||
{
|
{
|
||||||
|
|
@ -2460,6 +2470,9 @@ bool NetUDP::sequ_glob_(string input, char output)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.158 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.157 2001/02/10 21:20:38 steve
|
* Revision 1.157 2001/02/10 21:20:38 steve
|
||||||
* Binary operators with operands of indefinite width
|
* Binary operators with operands of indefinite width
|
||||||
* has itself an indefinite width.
|
* has itself an indefinite width.
|
||||||
|
|
|
||||||
17
netlist.h
17
netlist.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: netlist.h,v 1.200 2001/03/29 02:52:01 steve Exp $"
|
#ident "$Id: netlist.h,v 1.201 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1979,16 +1979,18 @@ class NetEUFunc : public NetExpr {
|
||||||
class NetUTask : public NetProc {
|
class NetUTask : public NetProc {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetUTask(NetTaskDef*);
|
NetUTask(NetScope*);
|
||||||
~NetUTask();
|
~NetUTask();
|
||||||
|
|
||||||
const string& name() const { return task_->name(); }
|
const string& name() const;
|
||||||
|
|
||||||
|
const NetScope* task() const;
|
||||||
|
|
||||||
virtual bool emit_proc(struct target_t*) const;
|
virtual bool emit_proc(struct target_t*) const;
|
||||||
virtual void dump(ostream&, unsigned ind) const;
|
virtual void dump(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetTaskDef*task_;
|
NetScope*task_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2784,8 +2786,8 @@ class Design {
|
||||||
NetFuncDef* find_function(const string&path);
|
NetFuncDef* find_function(const string&path);
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
NetTaskDef* find_task(NetScope*scope, const string&name);
|
NetScope* find_task(NetScope*scope, const string&name);
|
||||||
NetTaskDef* find_task(const string&key);
|
NetScope* find_task(const string&key);
|
||||||
|
|
||||||
// NODES
|
// NODES
|
||||||
void add_node(NetNode*);
|
void add_node(NetNode*);
|
||||||
|
|
@ -2870,6 +2872,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.201 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.200 2001/03/29 02:52:01 steve
|
* Revision 1.200 2001/03/29 02:52:01 steve
|
||||||
* Add const probe method to NetEvent.
|
* Add const probe method to NetEvent.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
22
t-dll-api.cc
22
t-dll-api.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: t-dll-api.cc,v 1.31 2001/04/02 00:28:35 steve Exp $"
|
#ident "$Id: t-dll-api.cc,v 1.32 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "t-dll.h"
|
# include "t-dll.h"
|
||||||
|
|
@ -452,6 +452,12 @@ extern "C" int ivl_scope_children(ivl_scope_t net,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" ivl_statement_t ivl_scope_def(ivl_scope_t net)
|
||||||
|
{
|
||||||
|
assert(net);
|
||||||
|
return net->def;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" unsigned ivl_scope_events(ivl_scope_t net)
|
extern "C" unsigned ivl_scope_events(ivl_scope_t net)
|
||||||
{
|
{
|
||||||
assert(net);
|
assert(net);
|
||||||
|
|
@ -608,6 +614,17 @@ extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" ivl_scope_t ivl_stmt_call(ivl_statement_t net)
|
||||||
|
{
|
||||||
|
switch (net->type_) {
|
||||||
|
case IVL_ST_UTASK:
|
||||||
|
return net->u_.utask_.def;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net)
|
extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
switch (net->type_) {
|
switch (net->type_) {
|
||||||
|
|
@ -812,6 +829,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll-api.cc,v $
|
* $Log: t-dll-api.cc,v $
|
||||||
|
* Revision 1.32 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.31 2001/04/02 00:28:35 steve
|
* Revision 1.31 2001/04/02 00:28:35 steve
|
||||||
* Support the scope expression node.
|
* Support the scope expression node.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: t-dll-proc.cc,v 1.19 2001/04/01 06:52:28 steve Exp $"
|
#ident "$Id: t-dll-proc.cc,v 1.20 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "target.h"
|
# include "target.h"
|
||||||
|
|
@ -74,6 +74,22 @@ bool dll_target::process(const NetProcTop*net)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dll_target::task_def(const NetScope*net)
|
||||||
|
{
|
||||||
|
ivl_scope_t scope = lookup_scope_(net);
|
||||||
|
const NetTaskDef*def = net->task_def();
|
||||||
|
|
||||||
|
assert(stmt_cur_ == 0);
|
||||||
|
stmt_cur_ = (struct ivl_statement_s*)calloc(1, sizeof*stmt_cur_);
|
||||||
|
assert(stmt_cur_);
|
||||||
|
def->proc()->emit_proc(this);
|
||||||
|
|
||||||
|
assert(stmt_cur_);
|
||||||
|
scope->def = stmt_cur_;
|
||||||
|
stmt_cur_ = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
void dll_target::proc_assign(const NetAssign*net)
|
void dll_target::proc_assign(const NetAssign*net)
|
||||||
|
|
@ -330,6 +346,15 @@ bool dll_target::proc_trigger(const NetEvTrig*net)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dll_target::proc_utask(const NetUTask*net)
|
||||||
|
{
|
||||||
|
assert(stmt_cur_);
|
||||||
|
assert(stmt_cur_->type_ == IVL_ST_NONE);
|
||||||
|
|
||||||
|
stmt_cur_->type_ = IVL_ST_UTASK;
|
||||||
|
stmt_cur_->u_.utask_.def = lookup_scope_(net->task());
|
||||||
|
}
|
||||||
|
|
||||||
bool dll_target::proc_wait(const NetEvWait*net)
|
bool dll_target::proc_wait(const NetEvWait*net)
|
||||||
{
|
{
|
||||||
assert(stmt_cur_);
|
assert(stmt_cur_);
|
||||||
|
|
@ -438,6 +463,9 @@ void dll_target::proc_while(const NetWhile*net)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll-proc.cc,v $
|
* $Log: t-dll-proc.cc,v $
|
||||||
|
* Revision 1.20 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.19 2001/04/01 06:52:28 steve
|
* Revision 1.19 2001/04/01 06:52:28 steve
|
||||||
* support the NetWhile statement.
|
* support the NetWhile statement.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
15
t-dll.h
15
t-dll.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: t-dll.h,v 1.31 2001/04/02 00:28:35 steve Exp $"
|
#ident "$Id: t-dll.h,v 1.32 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "target.h"
|
# include "target.h"
|
||||||
|
|
@ -84,9 +84,12 @@ struct dll_target : public target_t, public expr_scan_t {
|
||||||
bool proc_delay(const NetPDelay*);
|
bool proc_delay(const NetPDelay*);
|
||||||
void proc_stask(const NetSTask*);
|
void proc_stask(const NetSTask*);
|
||||||
bool proc_trigger(const NetEvTrig*);
|
bool proc_trigger(const NetEvTrig*);
|
||||||
|
void proc_utask(const NetUTask*);
|
||||||
bool proc_wait(const NetEvWait*);
|
bool proc_wait(const NetEvWait*);
|
||||||
void proc_while(const NetWhile*);
|
void proc_while(const NetWhile*);
|
||||||
|
|
||||||
|
void task_def(const NetScope*);
|
||||||
|
|
||||||
struct ivl_expr_s*expr_;
|
struct ivl_expr_s*expr_;
|
||||||
void expr_binary(const NetEBinary*);
|
void expr_binary(const NetEBinary*);
|
||||||
void expr_concat(const NetEConcat*);
|
void expr_concat(const NetEConcat*);
|
||||||
|
|
@ -304,6 +307,9 @@ struct ivl_scope_s {
|
||||||
|
|
||||||
unsigned nlpm_;
|
unsigned nlpm_;
|
||||||
ivl_lpm_t* lpm_;
|
ivl_lpm_t* lpm_;
|
||||||
|
|
||||||
|
/* Scopes that are tasks have a definition. */
|
||||||
|
ivl_statement_t def;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -385,6 +391,10 @@ struct ivl_statement_s {
|
||||||
ivl_event_t event_;
|
ivl_event_t event_;
|
||||||
} trig_;
|
} trig_;
|
||||||
|
|
||||||
|
struct { /* IVL_ST_UTASK */
|
||||||
|
ivl_scope_t def;
|
||||||
|
} utask_;
|
||||||
|
|
||||||
struct { /* IVL_ST_WAIT */
|
struct { /* IVL_ST_WAIT */
|
||||||
ivl_event_t event_;
|
ivl_event_t event_;
|
||||||
ivl_statement_t stmt_;
|
ivl_statement_t stmt_;
|
||||||
|
|
@ -399,6 +409,9 @@ struct ivl_statement_s {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: t-dll.h,v $
|
* $Log: t-dll.h,v $
|
||||||
|
* Revision 1.32 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.31 2001/04/02 00:28:35 steve
|
* Revision 1.31 2001/04/02 00:28:35 steve
|
||||||
* Support the scope expression node.
|
* Support the scope expression node.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
11
t-vvm.cc
11
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: t-vvm.cc,v 1.203 2001/03/27 03:31:06 steve Exp $"
|
#ident "$Id: t-vvm.cc,v 1.204 2001/04/02 02:28:12 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
@ -150,7 +150,7 @@ class target_vvm : public target_t {
|
||||||
virtual void event(const NetEvent*);
|
virtual void event(const NetEvent*);
|
||||||
virtual void signal(const NetNet*);
|
virtual void signal(const NetNet*);
|
||||||
virtual void memory(const NetMemory*);
|
virtual void memory(const NetMemory*);
|
||||||
virtual void task_def(const NetTaskDef*);
|
virtual void task_def(const NetScope*);
|
||||||
virtual void func_def(const NetFuncDef*);
|
virtual void func_def(const NetFuncDef*);
|
||||||
|
|
||||||
virtual void lpm_add_sub(const NetAddSub*);
|
virtual void lpm_add_sub(const NetAddSub*);
|
||||||
|
|
@ -1357,8 +1357,10 @@ void target_vvm::memory(const NetMemory*mem)
|
||||||
mem->count() << ");" << endl;
|
mem->count() << ");" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void target_vvm::task_def(const NetTaskDef*def)
|
void target_vvm::task_def(const NetScope*scope)
|
||||||
{
|
{
|
||||||
|
const NetTaskDef*def = scope->task_def();
|
||||||
|
|
||||||
thread_step_ = 0;
|
thread_step_ = 0;
|
||||||
const string name = mangle(def->name());
|
const string name = mangle(def->name());
|
||||||
const string save_thread_class = thread_class_;
|
const string save_thread_class = thread_class_;
|
||||||
|
|
@ -3636,6 +3638,9 @@ extern const struct target tgt_vvm = {
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* $Log: t-vvm.cc,v $
|
* $Log: t-vvm.cc,v $
|
||||||
|
* Revision 1.204 2001/04/02 02:28:12 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.203 2001/03/27 03:31:06 steve
|
* Revision 1.203 2001/03/27 03:31:06 steve
|
||||||
* Support error code from target_t::end_design method.
|
* Support error code from target_t::end_design method.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: target.cc,v 1.50 2001/03/27 03:31:06 steve Exp $"
|
#ident "$Id: target.cc,v 1.51 2001/04/02 02:28:13 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "target.h"
|
# include "target.h"
|
||||||
|
|
@ -49,7 +49,7 @@ void target_t::func_def(const NetFuncDef*)
|
||||||
"Unhandled function definition." << endl;
|
"Unhandled function definition." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void target_t::task_def(const NetTaskDef*)
|
void target_t::task_def(const NetScope*)
|
||||||
{
|
{
|
||||||
cerr << "target (" << typeid(*this).name() << "): "
|
cerr << "target (" << typeid(*this).name() << "): "
|
||||||
"Unhandled task definition." << endl;
|
"Unhandled task definition." << endl;
|
||||||
|
|
@ -389,6 +389,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: target.cc,v $
|
* $Log: target.cc,v $
|
||||||
|
* Revision 1.51 2001/04/02 02:28:13 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.50 2001/03/27 03:31:06 steve
|
* Revision 1.50 2001/03/27 03:31:06 steve
|
||||||
* Support error code from target_t::end_design method.
|
* Support error code from target_t::end_design method.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
7
target.h
7
target.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: target.h,v 1.49 2001/03/27 03:31:06 steve Exp $"
|
#ident "$Id: target.h,v 1.50 2001/04/02 02:28:13 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -69,7 +69,7 @@ struct target_t {
|
||||||
virtual void memory(const NetMemory*);
|
virtual void memory(const NetMemory*);
|
||||||
|
|
||||||
/* Output a defined task. */
|
/* Output a defined task. */
|
||||||
virtual void task_def(const NetTaskDef*);
|
virtual void task_def(const NetScope*);
|
||||||
virtual void func_def(const NetFuncDef*);
|
virtual void func_def(const NetFuncDef*);
|
||||||
|
|
||||||
/* LPM style components are handled here. */
|
/* LPM style components are handled here. */
|
||||||
|
|
@ -160,6 +160,9 @@ extern const struct target *target_table[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: target.h,v $
|
* $Log: target.h,v $
|
||||||
|
* Revision 1.50 2001/04/02 02:28:13 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.49 2001/03/27 03:31:06 steve
|
* Revision 1.49 2001/03/27 03:31:06 steve
|
||||||
* Support error code from target_t::end_design method.
|
* Support error code from target_t::end_design method.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: stub.c,v 1.34 2001/04/01 01:48:21 steve Exp $"
|
#ident "$Id: stub.c,v 1.35 2001/04/02 02:28:13 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -238,6 +238,10 @@ static void show_statement(ivl_statement_t net, unsigned ind)
|
||||||
fprintf(out, "%*s-> ...\n", ind, "");
|
fprintf(out, "%*s-> ...\n", ind, "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_ST_UTASK:
|
||||||
|
fprintf(out, "%*scall task ...\n", ind, "");
|
||||||
|
break;
|
||||||
|
|
||||||
case IVL_ST_WAIT: {
|
case IVL_ST_WAIT: {
|
||||||
ivl_event_t evnt = ivl_stmt_event(net);
|
ivl_event_t evnt = ivl_stmt_event(net);
|
||||||
fprintf(out, "%*s@(%s)\n", ind, "", ivl_event_name(evnt));
|
fprintf(out, "%*s@(%s)\n", ind, "", ivl_event_name(evnt));
|
||||||
|
|
@ -480,6 +484,9 @@ DECLARE_CYGWIN_DLL(DllMain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: stub.c,v $
|
* $Log: stub.c,v $
|
||||||
|
* Revision 1.35 2001/04/02 02:28:13 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.34 2001/04/01 01:48:21 steve
|
* Revision 1.34 2001/04/01 01:48:21 steve
|
||||||
* Redesign event information to support arbitrary edge combining.
|
* Redesign event information to support arbitrary edge combining.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvp_priv.h,v 1.6 2001/03/31 17:36:39 steve Exp $"
|
#ident "$Id: vvp_priv.h,v 1.7 2001/04/02 02:28:13 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "ivl_target.h"
|
# include "ivl_target.h"
|
||||||
|
|
@ -38,6 +38,8 @@ extern FILE* vvp_out;
|
||||||
*/
|
*/
|
||||||
extern int draw_process(ivl_process_t net, void*x);
|
extern int draw_process(ivl_process_t net, void*x);
|
||||||
|
|
||||||
|
extern int draw_task_definition(ivl_scope_t scope);
|
||||||
|
|
||||||
extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent);
|
extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -71,6 +73,9 @@ extern void clr_vector(struct vector_info vec);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_priv.h,v $
|
* $Log: vvp_priv.h,v $
|
||||||
|
* Revision 1.7 2001/04/02 02:28:13 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.6 2001/03/31 17:36:39 steve
|
* Revision 1.6 2001/03/31 17:36:39 steve
|
||||||
* Generate vvp code for case statements.
|
* Generate vvp code for case statements.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvp_process.c,v 1.18 2001/04/02 00:27:53 steve Exp $"
|
#ident "$Id: vvp_process.c,v 1.19 2001/04/02 02:28:13 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# include "vvp_priv.h"
|
||||||
|
|
@ -335,6 +335,15 @@ static int show_stmt_trigger(ivl_statement_t net)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int show_stmt_utask(ivl_statement_t net)
|
||||||
|
{
|
||||||
|
ivl_scope_t task = ivl_stmt_call(net);
|
||||||
|
|
||||||
|
fprintf(vvp_out, " %%fork TD_%s;\n", ivl_scope_name(task));
|
||||||
|
fprintf(vvp_out, " %%join;\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int show_stmt_wait(ivl_statement_t net)
|
static int show_stmt_wait(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
ivl_event_t ev = ivl_stmt_event(net);
|
ivl_event_t ev = ivl_stmt_event(net);
|
||||||
|
|
@ -496,6 +505,10 @@ static int show_statement(ivl_statement_t net)
|
||||||
rc += show_stmt_trigger(net);
|
rc += show_stmt_trigger(net);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_ST_UTASK:
|
||||||
|
rc += show_stmt_utask(net);
|
||||||
|
break;
|
||||||
|
|
||||||
case IVL_ST_WAIT:
|
case IVL_ST_WAIT:
|
||||||
rc += show_stmt_wait(net);
|
rc += show_stmt_wait(net);
|
||||||
break;
|
break;
|
||||||
|
|
@ -561,8 +574,27 @@ int draw_process(ivl_process_t net, void*x)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int draw_task_definition(ivl_scope_t scope)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
ivl_statement_t def = ivl_scope_def(scope);
|
||||||
|
|
||||||
|
fprintf(vvp_out, "TD_%s ;\n", ivl_scope_name(scope));
|
||||||
|
|
||||||
|
assert(def);
|
||||||
|
rc += show_statement(def);
|
||||||
|
|
||||||
|
fprintf(vvp_out, " %%end;\n");
|
||||||
|
|
||||||
|
thread_count += 1;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_process.c,v $
|
* $Log: vvp_process.c,v $
|
||||||
|
* Revision 1.19 2001/04/02 02:28:13 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.18 2001/04/02 00:27:53 steve
|
* Revision 1.18 2001/04/02 00:27:53 steve
|
||||||
* Scopes and numbers as vpi_call parameters.
|
* Scopes and numbers as vpi_call parameters.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vvp_scope.c,v 1.11 2001/04/01 21:34:48 steve Exp $"
|
#ident "$Id: vvp_scope.c,v 1.12 2001/04/02 02:28:13 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# include "vvp_priv.h"
|
||||||
|
|
@ -257,12 +257,19 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
|
||||||
draw_event_in_scope(event);
|
draw_event_in_scope(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ivl_scope_type(net) == IVL_SCT_TASK)
|
||||||
|
draw_task_definition(net);
|
||||||
|
|
||||||
|
|
||||||
ivl_scope_children(net, (ivl_scope_f*) draw_scope, net);
|
ivl_scope_children(net, (ivl_scope_f*) draw_scope, net);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_scope.c,v $
|
* $Log: vvp_scope.c,v $
|
||||||
|
* Revision 1.12 2001/04/02 02:28:13 steve
|
||||||
|
* Generate code for task calls.
|
||||||
|
*
|
||||||
* Revision 1.11 2001/04/01 21:34:48 steve
|
* Revision 1.11 2001/04/01 21:34:48 steve
|
||||||
* Recognize the BUF device.
|
* Recognize the BUF device.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* $Id: README.txt,v 1.11 2001/03/30 04:55:22 steve Exp $
|
* $Id: README.txt,v 1.12 2001/04/02 02:28:13 steve Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VVP SIMULATION ENGINE
|
VVP SIMULATION ENGINE
|
||||||
|
|
@ -242,12 +242,19 @@ A transient thread is created with a %fork instruction. When a
|
||||||
transient thread is created this way, the operand to the %fork gives
|
transient thread is created this way, the operand to the %fork gives
|
||||||
the starting address, and the new thread is said to be a child of the
|
the starting address, and the new thread is said to be a child of the
|
||||||
forking thread. The children of a thread are pushed onto a stack of
|
forking thread. The children of a thread are pushed onto a stack of
|
||||||
children.
|
children. A thread can have only one direct child.
|
||||||
|
|
||||||
A transient thread is reaped with a %join instruction. %join waits for
|
A transient thread is reaped with a %join instruction. %join waits for
|
||||||
the top thread in the stack of children to complete, then
|
the top thread in the stack of children to complete, then
|
||||||
continues. It is an error to %join when there are no children.
|
continues. It is an error to %join when there are no children.
|
||||||
|
|
||||||
|
As you can see, the transient thread in VVP is a cross between a
|
||||||
|
conventional thread and a function call. In fact, there is no %call
|
||||||
|
instruction in vvp, the job is accomplished with %fork/%join in the
|
||||||
|
caller and %end in the callee. The %fork, then is simply a
|
||||||
|
generalization of a function call, where the caller does not
|
||||||
|
necessarily wait for the callee.
|
||||||
|
|
||||||
TRUTH TABLES
|
TRUTH TABLES
|
||||||
|
|
||||||
The logic that a functor represents is expressed as a truth table. The
|
The logic that a functor represents is expressed as a truth table. The
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue