Generate vvp code for case statements.

This commit is contained in:
steve 2001-03-31 17:36:38 +00:00
parent 2f1d258acb
commit b3a3b888d8
8 changed files with 262 additions and 12 deletions

View File

@ -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.39 2001/03/30 05:49:52 steve Exp $"
#ident "$Id: ivl_target.h,v 1.40 2001/03/31 17:36:38 steve Exp $"
#endif
#ifdef __cplusplus
@ -247,6 +247,9 @@ typedef enum ivl_statement_type_e {
IVL_ST_NOOP = 1,
IVL_ST_ASSIGN,
IVL_ST_BLOCK,
IVL_ST_CASE,
IVL_ST_CASEX,
IVL_ST_CASEZ,
IVL_ST_CONDIT,
IVL_ST_DELAY,
IVL_ST_DELAYX,
@ -676,7 +679,13 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
/* IVL_ST_BLOCK, IVL_ST_FORK */
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
/* IVL_ST_CONDIT */
/* IVL_ST_CASE */
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
/* IVL_ST_CASE */
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
/* IVL_ST_CASE */
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
/* IVL_ST_CONDIT, IVL_ST_CASE */
extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net);
/* IVL_ST_CONDIT */
extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net);
@ -721,6 +730,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.40 2001/03/31 17:36:38 steve
* Generate vvp code for case statements.
*
* Revision 1.39 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*

View File

@ -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.27 2001/03/30 05:49:52 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.28 2001/03/31 17:36:38 steve Exp $"
#endif
# include "t-dll.h"
@ -580,10 +580,64 @@ extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net,
}
}
extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_CASE:
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
return net->u_.case_.ncase;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_CASE:
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
assert(idx < net->u_.case_.ncase);
return net->u_.case_.case_ex[idx];
default:
assert(0);
return 0;
}
}
extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_CASE:
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
assert(idx < net->u_.case_.ncase);
return net->u_.case_.case_st + idx;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net)
{
assert(net && (net->type_ == IVL_ST_CONDIT));
return net->u_.condit_.cond_;
switch (net->type_) {
case IVL_ST_CONDIT:
return net->u_.condit_.cond_;
case IVL_ST_CASE:
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
return net->u_.case_.cond;
default:
assert(0);
return 0;
}
}
extern "C" ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net)
@ -727,6 +781,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.28 2001/03/31 17:36:38 steve
* Generate vvp code for case statements.
*
* Revision 1.27 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*

View File

@ -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.16 2001/03/30 23:24:02 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.17 2001/03/31 17:36:39 steve Exp $"
#endif
# include "target.h"
@ -177,6 +177,54 @@ bool dll_target::proc_block(const NetBlock*net)
return flag;
}
void dll_target::proc_case(const NetCase*net)
{
assert(stmt_cur_);
assert(stmt_cur_->type_ == IVL_ST_NONE);
switch (net->type()) {
case NetCase::EQ:
stmt_cur_->type_ = IVL_ST_CASE;
break;
case NetCase::EQX:
stmt_cur_->type_ = IVL_ST_CASEX;
break;
case NetCase::EQZ:
stmt_cur_->type_ = IVL_ST_CASEZ;
break;
}
assert(stmt_cur_->type_ != IVL_ST_NONE);
assert(expr_ == 0);
net->expr()->expr_scan(this);
stmt_cur_->u_.case_.cond = expr_;
expr_ = 0;
unsigned ncase = net->nitems();
stmt_cur_->u_.case_.ncase = ncase;
stmt_cur_->u_.case_.case_ex = new ivl_expr_t[ncase];
stmt_cur_->u_.case_.case_st = new struct ivl_statement_s[ncase];
ivl_statement_t save_cur = stmt_cur_;
for (unsigned idx = 0 ; idx < ncase ; idx += 1) {
const NetExpr*ex = net->expr(idx);
if (ex) {
net->expr(idx)->expr_scan(this);
save_cur->u_.case_.case_ex[idx] = expr_;
expr_ = 0;
} else {
save_cur->u_.case_.case_ex[idx] = 0;
}
stmt_cur_ = save_cur->u_.case_.case_st + idx;
net->stat(idx)->emit_proc(this);
}
stmt_cur_ = save_cur;
}
void dll_target::proc_condit(const NetCondit*net)
{
assert(stmt_cur_);
@ -364,6 +412,9 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.17 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.16 2001/03/30 23:24:02 steve
* Make empty event sub-expression a noop.
*

13
t-dll.h
View File

@ -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.27 2001/03/30 05:49:52 steve Exp $"
#ident "$Id: t-dll.h,v 1.28 2001/03/31 17:36:39 steve Exp $"
#endif
# include "target.h"
@ -79,6 +79,7 @@ struct dll_target : public target_t, public expr_scan_t {
struct ivl_statement_s*stmt_cur_;
void proc_assign(const NetAssign*);
bool proc_block(const NetBlock*);
void proc_case(const NetCase*);
void proc_condit(const NetCondit*);
bool proc_delay(const NetPDelay*);
void proc_stask(const NetSTask*);
@ -346,6 +347,13 @@ struct ivl_statement_s {
unsigned nstmt_;
} block_;
struct { /* IVL_ST_CASE, IVL_ST_CASEX, IVL_ST_CASEZ */
ivl_expr_t cond;
unsigned ncase;
ivl_expr_t*case_ex;
struct ivl_statement_s*case_st;
} case_;
struct { /* IVL_ST_CONDIT */
/* This is the condition expression */
ivl_expr_t cond_;
@ -387,6 +395,9 @@ struct ivl_statement_s {
/*
* $Log: t-dll.h,v $
* Revision 1.28 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.27 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*

View File

@ -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.32 2001/03/30 05:49:52 steve Exp $"
#ident "$Id: stub.c,v 1.33 2001/03/31 17:36:39 steve Exp $"
#endif
/*
@ -164,6 +164,29 @@ static void show_statement(ivl_statement_t net, unsigned ind)
break;
}
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
case IVL_ST_CASE: {
unsigned cnt = ivl_stmt_case_count(net);
unsigned idx;
fprintf(out, "%*scase (...) <%u cases>\n", ind, "", cnt);
show_expression(ivl_stmt_cond_expr(net), ind+4);
for (idx = 0 ; idx < cnt ; idx += 1) {
ivl_expr_t ex = ivl_stmt_case_expr(net, idx);
ivl_statement_t st = ivl_stmt_case_stmt(net, idx);
if (ex == 0)
fprintf(out, "%*sdefault\n", ind+4, "");
else
show_expression(ex, ind+4);
show_statement(st, ind+4);
}
fprintf(out, "%*sendcase\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);
@ -460,6 +483,9 @@ DECLARE_CYGWIN_DLL(DllMain);
/*
* $Log: stub.c,v $
* Revision 1.33 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.32 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: eval_expr.c,v 1.6 2001/03/31 02:00:44 steve Exp $"
#ident "$Id: eval_expr.c,v 1.7 2001/03/31 17:36:39 steve Exp $"
#endif
# include "vvp_priv.h"
@ -48,7 +48,7 @@ static inline void clr_bit(unsigned addr)
allocation_map[addr] &= ~(1 << bit);
}
static inline void clr_vector(struct vector_info vec)
void clr_vector(struct vector_info vec)
{
unsigned idx;
for (idx = 0 ; idx < vec.wid ; idx += 1)
@ -400,6 +400,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
/*
* $Log: eval_expr.c,v $
* Revision 1.7 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.6 2001/03/31 02:00:44 steve
* Generate code for + and concat expressions.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvp_priv.h,v 1.5 2001/03/27 06:27:41 steve Exp $"
#ident "$Id: vvp_priv.h,v 1.6 2001/03/31 17:36:39 steve Exp $"
#endif
# include "ivl_target.h"
@ -52,6 +52,12 @@ extern void draw_nexus_input(ivl_nexus_t nex);
/*
* The draw_eval_expr function writes out the code to evaluate a
* behavioral expression.
*
* Expression results are placed into a vector allocated in the bit
* space of the thread. The vector_info structure represents that
* allocation. When the caller is done with the bits, it must release
* the vector with clr_vector so that the code generator can reuse
* those bits.
*/
struct vector_info {
unsigned short base;
@ -59,9 +65,15 @@ struct vector_info {
};
extern struct vector_info draw_eval_expr(ivl_expr_t exp);
extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w);
extern void clr_vector(struct vector_info vec);
/*
* $Log: vvp_priv.h,v $
* Revision 1.6 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.5 2001/03/27 06:27:41 steve
* Generate code for simple @ statements.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvp_process.c,v 1.12 2001/03/30 05:49:53 steve Exp $"
#ident "$Id: vvp_process.c,v 1.13 2001/03/31 17:36:39 steve Exp $"
#endif
# include "vvp_priv.h"
@ -133,6 +133,77 @@ static int show_stmt_assign(ivl_statement_t net)
return 0;
}
static int show_stmt_case(ivl_statement_t net)
{
ivl_expr_t exp = ivl_stmt_cond_expr(net);
struct vector_info cond = draw_eval_expr(exp);
unsigned count = ivl_stmt_case_count(net);
unsigned local_base = local_count;
unsigned idx, default_case;
local_count += count + 1;
/* First draw the branch table. All the non-default cases
generate a branch out of here, to the code that implements
the case. The default will fall through all the tests. */
default_case = count;
for (idx = 0 ; idx < count ; idx += 1) {
ivl_expr_t cex = ivl_stmt_case_expr(net, idx);
struct vector_info cvec;
if (cex == 0) {
default_case = idx;
continue;
}
cvec = draw_eval_expr_wid(cex, cond.wid);
fprintf(vvp_out, " %%cmp/u %u, %u, %u;\n", cond.base,
cvec.base, cond.wid);
fprintf(vvp_out, " %%jmp/1 T_%d.%d, 6;\n",
thread_count, local_base+idx);
/* Done with the case expression */
clr_vector(cvec);
}
/* Done with the condition expression */
clr_vector(cond);
/* Emit code for the default case. */
if (default_case < count) {
ivl_statement_t cst = ivl_stmt_case_stmt(net, default_case);
show_statement(cst);
}
/* Jump to the out of the case. */
fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count,
local_base+count);
for (idx = 0 ; idx < count ; idx += 1) {
ivl_statement_t cst = ivl_stmt_case_stmt(net, idx);
if (idx == default_case)
continue;
fprintf(vvp_out, "T_%d.%d\n", thread_count, local_base+idx);
show_statement(cst);
fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count,
local_base+count);
}
/* The out of the case. */
fprintf(vvp_out, "T_%d.%d\n", thread_count, local_base+count);
return 0;
}
static int show_stmt_condit(ivl_statement_t net)
{
int rc = 0;
@ -307,6 +378,10 @@ static int show_statement(ivl_statement_t net)
break;
}
case IVL_ST_CASE:
rc += show_stmt_case(net);
break;
case IVL_ST_CONDIT:
rc += show_stmt_condit(net);
break;
@ -394,6 +469,9 @@ int draw_process(ivl_process_t net, void*x)
/*
* $Log: vvp_process.c,v $
* Revision 1.13 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.12 2001/03/30 05:49:53 steve
* Generate code for fork/join statements.
*