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)
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"
25 static ivl_signal_t
find_path_source_port(ivl_delaypath_t path
)
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
);
35 if (ivl_signal_port(sig
) == IVL_SIP_NONE
)
38 /* XXXX Should check that the scope is right. */
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
53 static void draw_modpath_record(const char*label
, const char*driver
,
54 ivl_signal_t path_sig
)
57 typedef const char*ccharp
;
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
);
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");
117 struct modpath_item
{
118 ivl_signal_t path_sig
;
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
;
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
);