From 7b4e5ffc847fec31a354c4422d335ccd39f46d2f Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Thu, 7 May 2020 23:05:52 +0100 Subject: [PATCH] Update vlog95 target to handle buffers/tran_vps used to prevent port collapsing. (cherry picked from commit 40d2a49b90f6a977238f754d3427823917d688a4) --- tgt-vlog95/logic_lpm.c | 21 ++++++++++++--------- tgt-vlog95/misc.c | 19 ++++++++++++++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/tgt-vlog95/logic_lpm.c b/tgt-vlog95/logic_lpm.c index a7359feb0..6c78bfdab 100644 --- a/tgt-vlog95/logic_lpm.c +++ b/tgt-vlog95/logic_lpm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2018 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2011-2020 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -294,16 +294,17 @@ static unsigned is_local_nexus(ivl_scope_t scope, ivl_nexus_t nex) ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); if (! sig) continue; - /* Check to see if there is an output port driving into - * the local scope. */ + /* Check to see if there is an output or inout port + * driving into the local scope. */ if ((scope == ivl_scope_parent(ivl_signal_scope(sig))) && - (ivl_signal_port(sig) == IVL_SIP_OUTPUT)) { + ((ivl_signal_port(sig) == IVL_SIP_OUTPUT) || + (ivl_signal_port(sig) == IVL_SIP_INOUT))) { has_output_driver = 1; continue; } if (scope != ivl_signal_scope(sig)) continue; if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) || - (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) continue; + (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) continue; if (ivl_signal_local(sig)) { is_local = 1; } else { @@ -311,9 +312,10 @@ static unsigned is_local_nexus(ivl_scope_t scope, ivl_nexus_t nex) break; } } - /* We return is_local=true only if there is not an output driving - * into this scope. This is needed since some module outputs are - * combined with a concatenation. */ + /* We return is_local=true only if there is not an output or inout + * driving into this scope. This is needed since some module outputs + * are combined with a concatenation and some inouts are connected + * with a tran_VP. */ return is_local && !has_output_driver; } @@ -1707,7 +1709,8 @@ void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic) fprintf(vlog_out, "bufif1"); dly_count = 3; break; -// case IVL_LO_BUFT: + case IVL_LO_BUFT: + return; case IVL_LO_BUFZ: emit_bufz(scope, nlogic); return; diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index 7c8d32987..57be52a78 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2016 Cary R. (cygcary@yahoo.com) + * Copyright (C) 2011-2020 Cary R. (cygcary@yahoo.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -711,6 +711,8 @@ static unsigned is_local_input(ivl_scope_t scope, ivl_nexus_t nex) // HERE: Does this work correctly with an array reference created from @*? void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD) { + unsigned idx; + ivl_scope_t mod_scope; /* First look in the local scope for the nexus name. */ if (find_signal_in_nexus(scope, nex)) return; @@ -737,8 +739,19 @@ void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD) // multiples are found in a given scope. This all needs to be before // the constant code. - /* It is possible that the nexus does not have a name. For this - * case do not print an actual name. */ + /* It is possible that the nexus does not have a name. First check + if it drives another nexus through a transparent buffer. */ + for (idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) { + ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); + ivl_net_logic_t nlogic = ivl_nexus_ptr_log(nex_ptr); + if (nlogic && ivl_logic_type(nlogic) == IVL_LO_BUFT + && ivl_logic_pin(nlogic, 1) == nex) { + emit_name_of_nexus(scope, ivl_logic_pin(nlogic, 0), allow_UD); + return; + } + } + + /* If not, do not print an actual name. */ fprintf(vlog_out, "/* Empty */"); // dump_nexus_information(scope, nex); }