From 87177087c43ed2fa574a5f8ff755027d1e2d7d2e Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 23 Nov 2008 22:38:33 -0800 Subject: [PATCH] ivl_target.h access branch terminals Fill in the functions to add branch terminals, and add code in the stub to check that the terminals are present and reasonable. --- ivl.def | 4 ++++ ivl_target.h | 10 +++++++--- ivl_target_priv.h | 4 ++++ t-dll-api.cc | 12 ++++++++++++ tgt-stub/expression.c | 31 ++++++++++++++++++++++++++++++- tgt-stub/priv.h | 2 ++ tgt-stub/stub.c | 18 ++++++++++++++++++ 7 files changed, 77 insertions(+), 4 deletions(-) diff --git a/ivl.def b/ivl.def index 38c95ac20..d4a3a199c 100644 --- a/ivl.def +++ b/ivl.def @@ -1,5 +1,7 @@ EXPORTS +ivl_branch_terminal + ivl_design_const ivl_design_consts ivl_design_discipline @@ -112,6 +114,8 @@ ivl_lval_part_off ivl_lval_sig ivl_lval_width +ivl_nature_name + ivl_nexus_get_private ivl_nexus_name ivl_nexus_ptrs diff --git a/ivl_target.h b/ivl_target.h index f084b0540..a18163c2f 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -421,9 +421,11 @@ struct ivl_attribute_s { typedef const struct ivl_attribute_s*ivl_attribute_t; /* BRANCH -*/ -extern ivl_discipline_t ivl_branch_discipline(ivl_branch_t obj); -extern ivl_scope_t ivl_branch_scope(ivl_branch_t obj); + * Branches are analog constructs, a pair of terminals that is used in + * branch access functions. Terminal-1 is the reference node for the + * purposes of the access function that accesses it. + */ + /* extern ivl_scope_t ivl_branch_scope(ivl_branch_t obj); */ extern ivl_nexus_t ivl_branch_terminal(ivl_branch_t obj, int idx); /* DELAYPATH @@ -589,6 +591,8 @@ extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net); extern ivl_nature_t ivl_discipline_potential(ivl_discipline_t net); extern ivl_nature_t ivl_discipline_flow(ivl_discipline_t net); +extern const char* ivl_nature_name(ivl_nature_t net); + /* EVENTS * * Events are a unification of named events and implicit events diff --git a/ivl_target_priv.h b/ivl_target_priv.h index 8ef54a4f3..fd5c1338f 100644 --- a/ivl_target_priv.h +++ b/ivl_target_priv.h @@ -58,6 +58,10 @@ struct ivl_design_s { const class Design*self; }; +/* + * A branch is a pair of terminals. The elaborator assures that the + * terminals have compatible disciplines. + */ struct ivl_branch_s { ivl_nexus_t pins[2]; }; diff --git a/t-dll-api.cc b/t-dll-api.cc index d574de336..802584fc8 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -31,6 +31,13 @@ static StringHeap api_strings; /* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */ +extern "C" ivl_nexus_t ivl_branch_terminal(ivl_branch_t net, int idx) +{ + assert(idx >= 0); + assert( idx < 2); + return net->pins[idx]; +} + extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key) { return des->self->get_flag(key); @@ -1315,6 +1322,11 @@ extern "C" ivl_signal_t ivl_lval_sig(ivl_lval_t net) } } +extern "C" const char* ivl_nature_name(ivl_nature_t net) +{ + return net->name(); +} + /* * The nexus name is rarely needed. (Shouldn't be needed at all!) This * function will calculate the name if it is not already calculated. diff --git a/tgt-stub/expression.c b/tgt-stub/expression.c index 5a21a6a7a..0070b45e1 100644 --- a/tgt-stub/expression.c +++ b/tgt-stub/expression.c @@ -45,13 +45,42 @@ static void show_array_expression(ivl_expr_t net, unsigned ind) static void show_branch_access_expression(ivl_expr_t net, unsigned ind) { - fprintf(out, "%*s\n", ind, ""); + ivl_branch_t bra = ivl_expr_branch(net); + ivl_nature_t nature = ivl_expr_nature(net); + fprintf(out, "%*s\n", + ind, "", bra, ivl_nature_name(nature)); if (ivl_expr_value(net) != IVL_VT_REAL) { fprintf(out, "%*sERROR: Expecting type IVL_VT_REAL, got %s\n", ind, "", vt_type_string(net)); stub_errors += 1; } + + ivl_nexus_t ta = ivl_branch_terminal(bra, 0); + ivl_nexus_t tb = ivl_branch_terminal(bra, 1); + + ivl_discipline_t ta_disc = discipline_of_nexus(ta); + if (ta_disc == 0) { + fprintf(out, "%*sERROR: Source terminal of branch has no discipline\n", + ind, ""); + stub_errors += 1; + return; + } + + ivl_discipline_t tb_disc = discipline_of_nexus(tb); + if (ta_disc == 0) { + fprintf(out, "%*sERROR: Reference terminal of branch has no discipline\n", + ind, ""); + stub_errors += 1; + return; + } + + if (ta_disc != tb_disc) { + fprintf(out, "%*sERROR: Branch terminal disciplines mismatch: %s != %s\n", + ind, "", ivl_discipline_name(ta_disc), + ivl_discipline_name(tb_disc)); + stub_errors += 1; + } } static void show_binary_expression(ivl_expr_t net, unsigned ind) diff --git a/tgt-stub/priv.h b/tgt-stub/priv.h index 30f2eaf7d..f13e5b408 100644 --- a/tgt-stub/priv.h +++ b/tgt-stub/priv.h @@ -44,6 +44,8 @@ extern unsigned width_of_nexus(ivl_nexus_t nex); extern ivl_variable_type_t type_of_nexus(ivl_nexus_t nex); +extern ivl_discipline_t discipline_of_nexus(ivl_nexus_t nex); + /* * Show the details of the expression. */ diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 16184dc85..112ecda05 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -108,6 +108,24 @@ unsigned width_of_nexus(ivl_nexus_t nex) return 0; } +ivl_discipline_t discipline_of_nexus(ivl_nexus_t nex) +{ + unsigned idx; + + for (idx = 0 ; idx < ivl_nexus_ptrs(nex); idx += 1) { + ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); + ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); + + if (sig != 0) { + return ivl_signal_discipline(sig); + } + } + + /* ERROR: A nexus should have at least one signal to carry + properties like the data type. */ + return 0; +} + ivl_variable_type_t type_of_nexus(ivl_nexus_t net) { unsigned idx;