Add support for text macros with arguments.
[iverilog.git] / tgt-vvp / modpath.c
blobcfb79fa2999842e9c3793ba4a56cd3da0a1cc624
1 /*
2 * Copyright (c) 2007 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 # include "vvp_priv.h"
21 # include <string.h>
22 # include <stdlib.h>
23 # include <assert.h>
25 static ivl_signal_t find_path_source_port(ivl_delaypath_t path)
27 int idx;
28 ivl_nexus_t nex = ivl_path_source(path);
30 for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
31 ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
32 ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
33 if (sig == 0)
34 continue;
35 if (ivl_signal_port(sig) == IVL_SIP_NONE)
36 continue;
38 /* XXXX Should check that the scope is right. */
39 return sig;
42 return 0;
46 * Draw a .modpath record. The label is the label to use for this
47 * record. The driver is the label of the net that feeds into the
48 * modpath device. (Note that there is only 1 driver.) The path_sig is
49 * the signal that is the output of this modpath. From that signal we
50 * can find all the modpath source nodes to generate the complete
51 * modpath record.
53 static void draw_modpath_record(const char*label, const char*driver,
54 ivl_signal_t path_sig)
56 unsigned idx;
57 typedef const char*ccharp;
58 ccharp*src_drivers;
59 ccharp*con_drivers;
61 src_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp));
62 con_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp));
63 for (idx = 0 ; idx < ivl_signal_npath(path_sig) ; idx += 1) {
64 ivl_delaypath_t path = ivl_signal_path(path_sig, idx);
65 ivl_nexus_t src = ivl_path_source(path);
66 ivl_nexus_t con = ivl_path_condit(path);
68 src_drivers[idx] = draw_net_input(src);
70 if (con) con_drivers[idx] = draw_net_input(con);
71 else con_drivers[idx] = 0;
74 fprintf(vvp_out, " .scope S_%p;\n", ivl_path_scope(ivl_signal_path(path_sig,0)));
75 fprintf(vvp_out, "%s .modpath %s v%p_0", label, driver, path_sig);
77 for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) {
78 ivl_delaypath_t path = ivl_signal_path(path_sig, idx);
79 int ppos = ivl_path_source_posedge(path);
80 int pneg = ivl_path_source_negedge(path);
81 const char*edge = ppos? " +" : pneg ? " -" : "";
82 fprintf(vvp_out, ",\n %s%s", src_drivers[idx], edge);
83 fprintf(vvp_out,
84 " (%"PRIu64",%"PRIu64",%"PRIu64
85 ", %"PRIu64",%"PRIu64",%"PRIu64
86 ", %"PRIu64",%"PRIu64",%"PRIu64
87 ", %"PRIu64",%"PRIu64",%"PRIu64,
88 ivl_path_delay(path, IVL_PE_01),
89 ivl_path_delay(path, IVL_PE_10),
90 ivl_path_delay(path, IVL_PE_0z),
91 ivl_path_delay(path, IVL_PE_z1),
92 ivl_path_delay(path, IVL_PE_1z),
93 ivl_path_delay(path, IVL_PE_z0),
94 ivl_path_delay(path, IVL_PE_0x),
95 ivl_path_delay(path, IVL_PE_x1),
96 ivl_path_delay(path, IVL_PE_1x),
97 ivl_path_delay(path, IVL_PE_x0),
98 ivl_path_delay(path, IVL_PE_xz),
99 ivl_path_delay(path, IVL_PE_zx));
101 if (con_drivers[idx]) {
102 fprintf(vvp_out, " ? %s", con_drivers[idx]);
105 fprintf(vvp_out, ")");
107 ivl_signal_t src_sig = find_path_source_port(path);
108 fprintf(vvp_out, " v%p_0", src_sig);
111 fprintf(vvp_out, ";\n");
113 free(src_drivers);
114 free(con_drivers);
117 struct modpath_item {
118 ivl_signal_t path_sig;
119 char*drive_label;
120 struct modpath_item*next;
123 static struct modpath_item*modpath_list = 0;
125 void draw_modpath(ivl_signal_t path_sig, char*drive_label)
127 struct modpath_item*cur = calloc(1, sizeof(struct modpath_item));
128 cur->path_sig = path_sig;
129 cur->drive_label = drive_label;
130 cur->next = modpath_list;
131 modpath_list = cur;
134 void cleanup_modpath(void)
136 while (modpath_list) {
137 struct modpath_item*cur = modpath_list;
138 modpath_list = cur->next;
140 char modpath_label[64];
141 snprintf(modpath_label, sizeof modpath_label, "V_%p/m", cur->path_sig);
142 draw_modpath_record(modpath_label, cur->drive_label, cur->path_sig);
143 free(cur->drive_label);
144 free(cur);