From 255922e5456b4043b3e0624a7aceb934d7472d4d Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 18 Apr 2013 17:35:12 -0700 Subject: [PATCH] vlog95: add support for emitting logic pull devices in a CA If a logical pull device is converted into a CA then it is an assignment with strength, so just emit the appropriate constant to get the correct functionality (e.g. 1'b1 for a pull up and 1'b0 for a pull down). Also add missing file/line information. --- elaborate.cc | 1 + tgt-vlog95/logic_lpm.c | 51 +++++++++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index 1f4857cb0..51fb41c14 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1440,6 +1440,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const if (need_bufz_for_input_port(prts)) { NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(), sig->vector_width(), true); + tmp->set_line(*this); des->add_node(tmp); connect(tmp->pin(1), sig->pin(0)); diff --git a/tgt-vlog95/logic_lpm.c b/tgt-vlog95/logic_lpm.c index 343834f00..8f9ea059d 100644 --- a/tgt-vlog95/logic_lpm.c +++ b/tgt-vlog95/logic_lpm.c @@ -507,6 +507,15 @@ void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD) } } +static void emit_pull_const(char value, unsigned width) +{ + unsigned idx; + fprintf(vlog_out, "%u'b", width); + for (idx = 0; idx < width; idx += 1) { + fprintf(vlog_out, "%c", value); + } +} + static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic) { unsigned inputs = ivl_logic_pins(nlogic) - 1; @@ -571,6 +580,14 @@ static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic) emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0); fprintf(vlog_out, ")"); break; + /* A pull up/down at this point has been turned into an assignment + * with strength so just emit the appropriate constant. */ + case IVL_LO_PULLDOWN: + emit_pull_const('0', ivl_logic_width(nlogic)); + break; + case IVL_LO_PULLUP: + emit_pull_const('1', ivl_logic_width(nlogic)); + break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown CA logic type " @@ -1853,18 +1870,21 @@ void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex) ivl_scope_t const_scope = ivl_const_scope(net_const); assert(! nlogic); assert(! sig); - fprintf(stderr, "Const: "); - if (scope != const_scope) fprintf(stderr, "(%s) ", - ivl_scope_name(const_scope)); + fprintf(stderr, "Const:"); + if (scope != const_scope) { + fprintf(stderr, " (%s)", ivl_scope_name(const_scope)); + } } else if (nlogic) { ivl_scope_t logic_scope = ivl_logic_scope(nlogic); + ivl_logic_t logic_type = ivl_logic_type(nlogic); assert(! sig); fprintf(stderr, "Logic: "); fprintf(stderr, "{%s:%d} ", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic)); - if (scope != logic_scope) fprintf(stderr, "(%s) ", - ivl_scope_name(logic_scope)); - switch (ivl_logic_type(nlogic)) { + if (scope != logic_scope) { + fprintf(stderr, "(%s) ", ivl_scope_name(logic_scope)); + } + switch (logic_type) { case IVL_LO_AND: fprintf(stderr, "and"); break; case IVL_LO_BUF: fprintf(stderr, "buf"); break; case IVL_LO_BUFIF0: fprintf(stderr, "bufif0"); break; @@ -1895,7 +1915,20 @@ void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex) case IVL_LO_XOR: fprintf(stderr, "xor"); break; default: fprintf(stderr, "<%d>", ivl_logic_type(nlogic)); } - fprintf(stderr, "(%u inputs)", ivl_logic_pins(nlogic) - 1); + /* The BUF and NOT gates can have multiple outputs and a + * single input. . */ + if ((logic_type == IVL_LO_BUF) || + (logic_type == IVL_LO_NOT)) { + unsigned outputs = ivl_logic_pins(nlogic) - 1; + if (outputs == 1) fprintf(stderr, "(1 output)"); + else fprintf(stderr, "(%u outputs)", outputs); + /* The rest of the gates have a single output and can + * have zero or more inputs. */ + } else { + unsigned inputs = ivl_logic_pins(nlogic) - 1; + if (inputs == 1) fprintf(stderr, "(1 input)"); + else fprintf(stderr, "(%u inputs)", inputs); + } } else if (sig) { ivl_scope_t sig_scope = ivl_signal_scope(sig); fprintf(stderr, "Signal: \""); @@ -1937,9 +1970,7 @@ void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex) case IVL_VT_CLASS: fprintf(stderr, " class"); break; } - } else { - fprintf(stderr, "Error: No/missing information!"); - } + } else fprintf(stderr, "Error: No/missing information!"); fprintf(stderr, " (%u)\n", ivl_nexus_ptr_pin(nex_ptr)); } }