From 39cf6bd16421c1de2692c65dab7a71da3d45113c Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 19 Sep 2000 04:15:27 +0000 Subject: [PATCH] Introduce the means to get statement types. --- ivl_target.h | 100 ++++++++++++++++++++++++++++++++++++++++-------- t-dll-api.cc | 70 +++++++++++++++++++++++++++++++-- t-dll-proc.cc | 22 ++++++++++- t-dll.h | 18 +++------ tgt-stub/stub.c | 79 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 251 insertions(+), 38 deletions(-) diff --git a/ivl_target.h b/ivl_target.h index 72c92ae2d..22a8f4228 100644 --- a/ivl_target.h +++ b/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.7 2000/09/18 01:24:32 steve Exp $" +#ident "$Id: ivl_target.h,v 1.8 2000/09/19 04:15:27 steve Exp $" #endif #ifdef __cplusplus @@ -40,7 +40,7 @@ _BEGIN_DECL * behavior. * * The interface is divided into two parts: the entry points within - * the core that are called by the module, and then entry points in + * the core that are called by the module, and the entry points in * the module that are called by the core. It is the latter that * causes the module to be invoked in the first place, but most of the * interesting information about the design is accessed through the @@ -70,6 +70,46 @@ typedef struct ivl_process_s *ivl_process_t; typedef struct ivl_scope_s *ivl_scope_t; typedef struct ivl_statement_s*ivl_statement_t; +/* + * These are types that are defined as enumerations. These have + * explicit values so that the binary API is a bit more resilient to + * changes and additions to the enumerations. + */ + +typedef enum ivl_logic_e { + IVL_LO_NONE = 0, + IVL_LO_AND, + IVL_LO_BUF, + IVL_LO_BUFIF0, + IVL_LO_BUFIF1, + IVL_LO_NAND, + IVL_LO_NOR, + IVL_LO_NOT, + IVL_LO_NOTIF0, + IVL_LO_NOTIF1, + IVL_LO_OR, + IVL_LO_XNOR, + IVL_LO_XOR +} ivl_logic_t; + +typedef enum ivl_process_type_e { + IVL_PR_INITIAL = 0, + IVL_PR_ALWAYS = 1 +} ivl_process_type_t; + +typedef enum ivl_statement_type_e { + IVL_ST_NONE = 0, + IVL_ST_NOOP = 1, + IVL_ST_ASSIGN, + IVL_ST_BLOCK, + IVL_ST_CONDIT, + IVL_ST_DELAY, + IVL_ST_DELAYX, + IVL_ST_STASK, + IVL_ST_WAIT, + IVL_ST_WHILE +} ivl_statement_type_t; + /* 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 @@ -88,16 +128,11 @@ extern const char* ivl_get_root_name(ivl_design_t net); /* LOGIC * These types and functions support manipulation of logic gates. The - * ivl_logit_t enumeration identifies the various kinds of gates that + * 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 various bits of information for a given logic - * device. + * provide access to the bits of information for a given logic device. */ -typedef enum ivl_logic_e { IVL_AND, IVL_BUF, IVL_BUFIF0, IVL_BUFIF1, - IVL_NAND, IVL_NOR, IVL_NOT, IVL_NOTIF0, - IVL_NOTIF1, IVL_OR, IVL_XNOR, IVL_XOR } ivl_logic_t; - extern ivl_logic_t ivl_get_logic_type(ivl_net_logic_t net); extern ivl_nexus_t ivl_get_logic_pin(ivl_net_logic_t net, unsigned pin); extern unsigned ivl_get_logic_pins(ivl_net_logic_t net); @@ -109,7 +144,6 @@ extern unsigned ivl_get_logic_pins(ivl_net_logic_t net); extern const char* ivl_get_nexus_name(ivl_nexus_t net); - extern unsigned ivl_get_signal_pins(ivl_net_signal_t net); @@ -122,21 +156,52 @@ extern unsigned ivl_get_signal_pins(ivl_net_signal_t net); * The ivl_get_process_type function gets the type of the process, * an "inital" or "always" statement. * - * The ivl_get_process_stmt functin gets the statement that forms the + * The ivl_get_process_stmt function gets the statement that forms the * process. See the statement related functions for how to manipulate * statements. */ -typedef enum ivl_process_type { - IVL_PR_INITIAL = 0, - IVL_PR_ALWAYS = 1 -} ivl_process_type_t; - extern ivl_process_type_t ivl_get_process_type(ivl_process_t net); extern ivl_statement_t ivl_get_process_stmt(ivl_process_t net); +/* + * These functions manage statements of various type. This includes + * all the different kinds of statements (as enumerated in + * ivl_statement_type_t) that might occur in behavioral code. + * + * The ivl_statement_type() function returns the type code for the + * statement. This is the major type, and implies which of the later + * functions are applicable to the statemnt. + */ +extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net); + +/* + * The following functions retrieve specific single values from the + * statement. These values are the bits of data and parameters that + * make up the statement. Many of these functions apply to more then + * one type of statement, so the comment in front of them tells which + * statement types can be passed to the function. + */ + + /* IVL_ST_BLOCK */ +extern unsigned ivl_stmt_block_count(ivl_statement_t net); + /* IVL_ST_BLOCK */ +extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i); + /* IVL_ST_CONDIT */ +extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net); +extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net); + /* IVL_ST_DELAY */ +extern unsigned long ivl_stmt_delay_val(ivl_statement_t net); + /* IVL_ST_DELAY, IVL_ST_WAIT, IVL_ST_WHILE */ +extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net); + /* TARGET MODULE ENTRY POINTS + * + * These are not functions in the API but functions that the target + * module supplies. They are presented as typedefs of functions (which + * are used internally) but the target module makes them work by + * exporting them. * * The module entry points generally take a cookie and possibly a name * as parameters. They use the cookie to get the required detailed @@ -236,6 +301,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * 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. * diff --git a/t-dll-api.cc b/t-dll-api.cc index 129215e15..0ae3567da 100644 --- a/t-dll-api.cc +++ b/t-dll-api.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-api.cc,v 1.1 2000/09/18 01:24:32 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.2 2000/09/19 04:15:27 steve Exp $" #endif # include "t-dll.h" @@ -38,12 +38,12 @@ extern "C" ivl_logic_t ivl_get_logic_type(ivl_net_logic_t net) { switch (net->dev_->type()) { case NetLogic::AND: - return IVL_AND; + return IVL_LO_AND; case NetLogic::OR: - return IVL_OR; + return IVL_LO_OR; } assert(0); - return IVL_AND; + return IVL_LO_NONE; } extern "C" unsigned ivl_get_logic_pins(ivl_net_logic_t net) @@ -78,8 +78,70 @@ extern "C" unsigned ivl_get_signal_pins(ivl_net_signal_t net) return sig->pin_count(); } +extern "C" ivl_statement_type_t ivl_statement_type(ivl_statement_t net) +{ + return net->type_; +} + +extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net) +{ + assert(net->type_ == IVL_ST_BLOCK); + return net->u_.block_.nstmt_; +} + +extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, + unsigned i) +{ + assert(net->type_ == IVL_ST_BLOCK); + assert(i < net->u_.block_.nstmt_); + return net->u_.block_.stmt_ + i; +} + +extern "C" ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net) +{ + assert(net->type_ == IVL_ST_CONDIT); + if (net->u_.condit_.stmt_[1].type_ == IVL_ST_NONE) + return 0; + else + return net->u_.condit_.stmt_ + 1; +} + +extern "C" ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net) +{ + assert(net->type_ == IVL_ST_CONDIT); + if (net->u_.condit_.stmt_[0].type_ == IVL_ST_NONE) + return 0; + else + return net->u_.condit_.stmt_ + 0; +} + +extern "C" unsigned long ivl_stmt_delay_val(ivl_statement_t net) +{ + assert(net->type_ == IVL_ST_DELAY); + return net->u_.delay_.delay_; +} + +extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) +{ + switch (net->type_) { + case IVL_ST_DELAY: + return net->u_.delay_.stmt_; + case IVL_ST_WAIT: + return net->u_.wait_.stmt_; + case IVL_ST_WHILE: + return net->u_.while_.stmt_; + default: + assert(0); + } + + return 0; +} + /* * $Log: t-dll-api.cc,v $ + * Revision 1.2 2000/09/19 04:15:27 steve + * Introduce the means to get statement types. + * * Revision 1.1 2000/09/18 01:24:32 steve * Get the structure for ivl_statement_t worked out. * diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 56ef56490..6240561f3 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-proc.cc,v 1.1 2000/09/18 01:24:32 steve Exp $" +#ident "$Id: t-dll-proc.cc,v 1.2 2000/09/19 04:15:27 steve Exp $" #endif # include "target.h" @@ -181,11 +181,27 @@ bool dll_target::proc_delay(const NetPDelay*net) ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = tmp; bool flag = net->emit_proc_recurse(this); + + /* If the recurse doesn't turn this new item into something, + then either it failed or there is no statement + there. Either way, draw a no-op into the statement. */ + if (stmt_cur_->type_ == IVL_ST_NONE) { + stmt_cur_->type_ = IVL_ST_NOOP; + } + stmt_cur_ = save_cur_; return flag; } +void dll_target::proc_stask(const NetSTask*net) +{ + assert(stmt_cur_); + assert(stmt_cur_->type_ == IVL_ST_NONE); + + stmt_cur_->type_ = IVL_ST_STASK; +} + bool dll_target::proc_wait(const NetEvWait*net) { assert(stmt_cur_); @@ -198,6 +214,7 @@ bool dll_target::proc_wait(const NetEvWait*net) ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = stmt_cur_->u_.wait_.stmt_; bool flag = net->emit_recurse(this); + stmt_cur_ = save_cur_; return flag; } @@ -225,6 +242,9 @@ void dll_target::proc_while(const NetWhile*net) /* * $Log: t-dll-proc.cc,v $ + * Revision 1.2 2000/09/19 04:15:27 steve + * Introduce the means to get statement types. + * * Revision 1.1 2000/09/18 01:24:32 steve * Get the structure for ivl_statement_t worked out. * diff --git a/t-dll.h b/t-dll.h index 6784ce2d4..ca75c1056 100644 --- a/t-dll.h +++ b/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.1 2000/09/18 01:24:32 steve Exp $" +#ident "$Id: t-dll.h,v 1.2 2000/09/19 04:15:27 steve Exp $" #endif # include "target.h" @@ -72,6 +72,7 @@ struct dll_target : public target_t { bool proc_block(const NetBlock*); void proc_condit(const NetCondit*); bool proc_delay(const NetPDelay*); + void proc_stask(const NetSTask*); bool proc_wait(const NetEvWait*); void proc_while(const NetWhile*); }; @@ -100,18 +101,6 @@ struct ivl_process_s { * is defined by the ivl_statement_type_t enumeration. Given the type, * certain information about the statement may be available. */ -typedef enum ivl_statement_type_e { - IVL_ST_NONE = 0, - IVL_ST_NOOP = 1, - IVL_ST_ASSIGN, - IVL_ST_BLOCK, - IVL_ST_CONDIT, - IVL_ST_DELAY, - IVL_ST_DELAYX, - IVL_ST_WAIT, - IVL_ST_WHILE -} ivl_statement_type_t; - struct ivl_statement_s { enum ivl_statement_type_e type_; union { @@ -148,6 +137,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.2 2000/09/19 04:15:27 steve + * Introduce the means to get statement types. + * * Revision 1.1 2000/09/18 01:24:32 steve * Get the structure for ivl_statement_t worked out. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 376713277..da1a283a7 100644 --- a/tgt-stub/stub.c +++ b/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.7 2000/09/18 01:24:32 steve Exp $" +#ident "$Id: stub.c,v 1.8 2000/09/19 04:15:27 steve Exp $" #endif /* @@ -78,11 +78,11 @@ int target_net_logic(const char*name, ivl_net_logic_t net) unsigned npins, idx; switch (ivl_get_logic_type(net)) { - case IVL_AND: + case IVL_LO_AND: fprintf(out, " and %s (%s", name, ivl_get_nexus_name(ivl_get_logic_pin(net, 0))); break; - case IVL_OR: + case IVL_LO_OR: fprintf(out, " or %s (%s", name, ivl_get_nexus_name(ivl_get_logic_pin(net, 0))); break; @@ -113,6 +113,73 @@ int target_net_signal(const char*name, ivl_net_signal_t net) return 0; } +static void show_statement(ivl_statement_t net, unsigned ind) +{ + const ivl_statement_type_t code = ivl_statement_type(net); + + switch (code) { + case IVL_ST_ASSIGN: + fprintf(out, "%*s? = ?;\n", ind, ""); + break; + + case IVL_ST_BLOCK: { + unsigned cnt = ivl_stmt_block_count(net); + unsigned idx; + fprintf(out, "%*sbegin\n", ind, ""); + for (idx = 0 ; idx < cnt ; idx += 1) { + ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); + show_statement(cur, ind+4); + } + fprintf(out, "%*send\n", ind, ""); + break; + } + + case IVL_ST_CONDIT: { + ivl_statement_t t = ivl_stmt_cond_true(net); + ivl_statement_t f = ivl_stmt_cond_false(net); + + fprintf(out, "%*sif (...)\n", ind, ""); + if (t) + show_statement(t, ind+4); + else + fprintf(out, "%*s;\n", ind+4, ""); + + if (f) { + fprintf(out, "%*selse\n", ind, ""); + show_statement(f, ind+4); + } + + break; + } + + case IVL_ST_DELAY: + fprintf(out, "%*s#%lu\n", ind, "", ivl_stmt_delay_val(net)); + show_statement(ivl_stmt_sub_stmt(net), ind+2); + break; + + case IVL_ST_NOOP: + fprintf(out, "%*s/* noop */;\n", ind, ""); + break; + + case IVL_ST_STASK: + fprintf(out, "%*s$?(...);\n", ind, ""); + break; + + case IVL_ST_WAIT: + fprintf(out, "%*s@(...)\n", ind, ""); + show_statement(ivl_stmt_sub_stmt(net), ind+2); + break; + + case IVL_ST_WHILE: + fprintf(out, "%*swhile ()\n", ind, ""); + show_statement(ivl_stmt_sub_stmt(net), ind+2); + break; + + default: + fprintf(out, "%*sunknown statement type (%u)\n", ind, "", code); + } +} + int target_process(ivl_process_t net) { switch (ivl_get_process_type(net)) { @@ -124,12 +191,16 @@ int target_process(ivl_process_t net) break; } - fprintf(out, " STUB: process\n"); + show_statement(ivl_get_process_stmt(net), 8); + return 0; } /* * $Log: stub.c,v $ + * 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. *