2008-05-28 05:06:58 +02:00
|
|
|
/*
|
2020-05-31 21:36:01 +02:00
|
|
|
* Copyright (c) 2008-2020 Stephen Williams (steve@icarus.com)
|
2008-05-28 05:06:58 +02:00
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-08-29 03:41:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-05-28 05:06:58 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include "vvp_priv.h"
|
|
|
|
|
# include <assert.h>
|
|
|
|
|
# include <stdlib.h>
|
|
|
|
|
# include <string.h>
|
|
|
|
|
|
2008-06-02 06:08:31 +02:00
|
|
|
static void draw_tran_island(ivl_island_t island)
|
|
|
|
|
{
|
|
|
|
|
fprintf(vvp_out, "I%p .island tran;\n", island);
|
|
|
|
|
ivl_island_flag_set(island, 0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-28 05:06:58 +02:00
|
|
|
void draw_switch_in_scope(ivl_switch_t sw)
|
|
|
|
|
{
|
2008-09-30 03:06:47 +02:00
|
|
|
ivl_island_t island;
|
|
|
|
|
ivl_nexus_t nex_a, nex_b, enable;
|
|
|
|
|
const char*str_a, *str_b, *str_e;
|
|
|
|
|
|
2010-07-13 01:04:22 +02:00
|
|
|
ivl_expr_t rise_exp = ivl_switch_delay(sw, 0);
|
|
|
|
|
ivl_expr_t fall_exp = ivl_switch_delay(sw, 1);
|
2010-07-20 06:14:29 +02:00
|
|
|
ivl_expr_t decay_exp= ivl_switch_delay(sw, 2);
|
2010-07-13 01:04:22 +02:00
|
|
|
|
2008-09-30 03:06:47 +02:00
|
|
|
island = ivl_switch_island(sw);
|
2008-06-02 06:08:31 +02:00
|
|
|
if (ivl_island_flag_test(island, 0) == 0)
|
|
|
|
|
draw_tran_island(island);
|
|
|
|
|
|
2008-09-30 03:06:47 +02:00
|
|
|
nex_a = ivl_switch_a(sw);
|
2008-06-02 06:08:31 +02:00
|
|
|
assert(nex_a);
|
2009-10-12 01:51:06 +02:00
|
|
|
str_a = draw_island_net_input(island, nex_a);
|
2008-06-02 06:08:31 +02:00
|
|
|
|
2008-09-30 03:06:47 +02:00
|
|
|
nex_b = ivl_switch_b(sw);
|
2008-06-02 06:08:31 +02:00
|
|
|
assert(nex_b);
|
2009-10-12 01:51:06 +02:00
|
|
|
str_b = draw_island_net_input(island, nex_b);
|
2008-06-02 06:08:31 +02:00
|
|
|
|
2008-09-30 03:06:47 +02:00
|
|
|
enable = ivl_switch_enable(sw);
|
|
|
|
|
str_e = 0;
|
2010-07-20 06:14:29 +02:00
|
|
|
char str_e_buf[4 + 2*sizeof(void*)];
|
|
|
|
|
|
|
|
|
|
if (enable && rise_exp) {
|
|
|
|
|
/* If the enable has a delay, then generate a .delay
|
|
|
|
|
node to delay the input by the specified amount. Do
|
|
|
|
|
the delay outside of the island so that the island
|
|
|
|
|
processing doesn't have to deal with it. */
|
|
|
|
|
const char*raw = draw_net_input(enable);
|
|
|
|
|
|
2016-04-02 20:49:38 +02:00
|
|
|
draw_delay(sw, 1, raw, rise_exp, fall_exp, decay_exp);
|
|
|
|
|
|
2012-03-10 00:04:52 +01:00
|
|
|
snprintf(str_e_buf, sizeof str_e_buf, "p%p", sw);
|
|
|
|
|
str_e = str_e_buf;
|
|
|
|
|
|
2016-04-02 20:49:38 +02:00
|
|
|
fprintf(vvp_out, "%s .import I%p, L_%p;\n", str_e, island, sw);
|
2010-07-20 06:14:29 +02:00
|
|
|
|
|
|
|
|
} else if (enable) {
|
|
|
|
|
str_e = draw_island_net_input(island, enable);
|
|
|
|
|
}
|
2008-06-02 06:08:31 +02:00
|
|
|
|
|
|
|
|
switch (ivl_switch_type(sw)) {
|
2018-02-23 23:30:32 +01:00
|
|
|
case IVL_SW_RTRAN:
|
|
|
|
|
fprintf(vvp_out, " .rtran");
|
|
|
|
|
break;
|
|
|
|
|
case IVL_SW_RTRANIF0:
|
|
|
|
|
fprintf(vvp_out, " .rtranif0");
|
|
|
|
|
break;
|
|
|
|
|
case IVL_SW_RTRANIF1:
|
|
|
|
|
fprintf(vvp_out, " .rtranif1");
|
|
|
|
|
break;
|
2008-06-02 06:08:31 +02:00
|
|
|
case IVL_SW_TRAN:
|
2008-06-03 20:16:25 +02:00
|
|
|
fprintf(vvp_out, " .tran");
|
2008-06-02 06:08:31 +02:00
|
|
|
break;
|
|
|
|
|
case IVL_SW_TRANIF0:
|
2008-06-03 20:16:25 +02:00
|
|
|
fprintf(vvp_out, " .tranif0");
|
2008-06-02 06:08:31 +02:00
|
|
|
break;
|
|
|
|
|
case IVL_SW_TRANIF1:
|
2008-06-03 20:16:25 +02:00
|
|
|
fprintf(vvp_out, " .tranif1");
|
2008-06-02 06:08:31 +02:00
|
|
|
break;
|
2008-06-03 20:16:25 +02:00
|
|
|
case IVL_SW_TRAN_VP:
|
|
|
|
|
fprintf(vvp_out, " .tranvp %u %u %u,",
|
|
|
|
|
ivl_switch_width(sw), ivl_switch_part(sw), ivl_switch_offset(sw));
|
|
|
|
|
break;
|
|
|
|
|
|
2008-06-02 06:08:31 +02:00
|
|
|
default:
|
2020-05-31 21:36:01 +02:00
|
|
|
fprintf(stderr, "%s:%u: vvp.tgt error: unrecognised switch type.\n",
|
2010-07-13 01:04:22 +02:00
|
|
|
ivl_switch_file(sw), ivl_switch_lineno(sw));
|
2008-06-02 06:08:31 +02:00
|
|
|
vvp_errors += 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(vvp_out, " I%p, %s %s", island, str_a, str_b);
|
2010-07-20 06:14:29 +02:00
|
|
|
if (enable) {
|
2008-06-02 06:08:31 +02:00
|
|
|
fprintf(vvp_out, ", %s", str_e);
|
2010-07-20 06:14:29 +02:00
|
|
|
}
|
2008-06-02 06:08:31 +02:00
|
|
|
fprintf(vvp_out, ";\n");
|
2008-05-28 05:06:58 +02:00
|
|
|
}
|