Pass local scope precision from compiler to vvp/etc.
[iverilog.git] / vvp / words.cc
blob0cff6da08ad9d9455dc32a8e78cf2f72abaf9d90
1 /*
2 * Copyright (c) 2003-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
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: words.cc,v 1.9 2007/04/10 01:26:16 steve Exp $"
21 #endif
23 # include "compile.h"
24 # include "vpi_priv.h"
25 # include "array.h"
26 # include "schedule.h"
27 # include <stdio.h>
28 # include <stdlib.h>
29 # include <string.h>
30 # include <iostream>
31 #ifdef HAVE_MALLOC_H
32 # include <malloc.h>
33 #endif
34 # include <assert.h>
36 static void __compile_var_real(char*label, char*name,
37 vvp_array_t array, unsigned long array_addr,
38 int msb, int lsb)
40 vvp_fun_signal_real*fun = new vvp_fun_signal_real;
41 vvp_net_t*net = new vvp_net_t;
42 net->fun = fun;
43 define_functor_symbol(label, net);
45 vpiHandle obj = vpip_make_real_var(name, net);
47 compile_vpi_symbol(label, obj);
49 if (name) {
50 assert(!array);
51 vpip_attach_to_current_scope(obj);
52 schedule_init_vector(vvp_net_ptr_t(net,0), fun->real_value());
54 if (array) {
55 assert(!name);
56 array_attach_word(array, array_addr, obj);
58 free(label);
59 if (name) free(name);
62 void compile_var_real(char*label, char*name, int msb, int lsb)
64 __compile_var_real(label, name, 0, 0, msb, lsb);
67 void compile_varw_real(char*label, vvp_array_t array,
68 unsigned long addr,
69 int msb, int lsb)
71 __compile_var_real(label, 0, array, addr, msb, lsb);
75 * A variable is a special functor, so we allocate that functor and
76 * write the label into the symbol table.
78 static void __compile_var(char*label, char*name,
79 vvp_array_t array, unsigned long array_addr,
80 int msb, int lsb, char signed_flag)
82 unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
84 vvp_fun_signal*vsig = new vvp_fun_signal(wid);
85 vvp_net_t*node = new vvp_net_t;
87 node->fun = vsig;
88 define_functor_symbol(label, node);
90 /* Make the vpiHandle for the reg. */
91 vpiHandle obj = (signed_flag > 1) ?
92 vpip_make_int(name, msb, lsb, node) :
93 vpip_make_reg(name, msb, lsb, signed_flag!=0, node);
94 compile_vpi_symbol(label, obj);
95 // If the signal has a name, then it goes into the current
96 // scope as a signal.
97 if (name) {
98 assert(!array);
99 vpip_attach_to_current_scope(obj);
100 schedule_init_vector(vvp_net_ptr_t(node,0), vsig->vec4_value());
102 // If this is an array word, then it does not have a name, and
103 // it is attached to the addressed array.
104 if (array) {
105 assert(!name);
106 array_attach_word(array, array_addr, obj);
108 free(label);
109 if (name) free(name);
112 void compile_variable(char*label, char*name,
113 int msb, int lsb, char signed_flag)
115 __compile_var(label, name, 0, 0, msb, lsb, signed_flag);
119 * In this case, the variable it intended to be attached to the array
120 * as a word. The array_addr is the *canonical* address of the word in
121 * the array.
123 * This function is actually used by the compile_array function,
124 * instead of directly by the parser.
126 void compile_variablew(char*label, vvp_array_t array, unsigned long array_addr,
127 int msb, int lsb, char signed_flag)
129 __compile_var(label, 0, array, array_addr, msb, lsb, signed_flag);
133 * Here we handle .net records from the vvp source:
135 * <label> .net <name>, <msb>, <lsb>, <input> ;
136 * <label> .net/s <name>, <msb>, <lsb>, <input> ;
137 * <label> .net8 <name>, <msb>, <lsb>, <input> ;
138 * <label> .net8/s <name>, <msb>, <lsb>, <input> ;
140 * Create a VPI handle to represent it, and fill that handle in with
141 * references into the net.
143 static void __compile_net(char*label, char*name,
144 char*array_label, unsigned long array_addr,
145 int msb, int lsb,
146 bool signed_flag, bool net8_flag,
147 unsigned argc, struct symb_s*argv)
149 unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1;
151 vvp_net_t*node = new vvp_net_t;
153 vvp_array_t array = array_label? array_find(array_label) : 0;
154 assert(array_label? array!=0 : true);
156 vvp_fun_signal_base*vsig = net8_flag
157 ? dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal8(wid))
158 : dynamic_cast<vvp_fun_signal_base*>(new vvp_fun_signal(wid,BIT4_Z));
159 node->fun = vsig;
161 /* Add the label into the functor symbol table. */
162 define_functor_symbol(label, node);
164 assert(argc == 1);
166 /* Connect the source to my input. */
167 inputs_connect(node, 1, argv);
169 /* Make the vpiHandle for the reg. */
170 vpiHandle obj = vpip_make_net(name, msb, lsb, signed_flag, node);
171 /* This attaches the label to the vpiHandle */
172 compile_vpi_symbol(label, obj);
173 /* If this is an array word, then attach it to the
174 array. Otherwise, attach it to the current scope. */
175 if (array)
176 array_attach_word(array, array_addr, obj);
177 else
178 vpip_attach_to_current_scope(obj);
180 free(label);
181 if (name) free(name);
182 if (array_label) free(array_label);
183 free(argv);
186 void compile_net(char*label, char*name,
187 int msb, int lsb,
188 bool signed_flag, bool net8_flag,
189 unsigned argc, struct symb_s*argv)
191 __compile_net(label, name, 0, 0,
192 msb, lsb, signed_flag, net8_flag,
193 argc, argv);
196 void compile_netw(char*label, char*array_label, unsigned long array_addr,
197 int msb, int lsb,
198 bool signed_flag, bool net8_flag,
199 unsigned argc, struct symb_s*argv)
201 __compile_net(label, 0, array_label, array_addr,
202 msb, lsb, signed_flag, net8_flag,
203 argc, argv);
206 void compile_net_real(char*label, char*name, int msb, int lsb,
207 unsigned argc, struct symb_s*argv)
209 vvp_net_t*net = new vvp_net_t;
211 vvp_fun_signal_real*fun = new vvp_fun_signal_real;
212 net->fun = fun;
214 /* Add the label into the functor symbol table. */
215 define_functor_symbol(label, net);
217 assert(argc == 1);
219 /* Connect the source to my input. */
220 inputs_connect(net, 1, argv);
222 /* Make the vpiHandle for the reg. */
223 vpiHandle obj = vpip_make_real_var(name, net);
224 compile_vpi_symbol(label, obj);
225 vpip_attach_to_current_scope(obj);
227 free(label);
228 free(name);
229 free(argv);
232 void compile_alias(char*label, char*name, int msb, int lsb, bool signed_flag,
233 unsigned argc, struct symb_s*argv)
235 assert(argc == 1);
237 vvp_net_t*node = vvp_net_lookup(argv[0].text);
239 /* Add the label into the functor symbol table. */
240 define_functor_symbol(label, node);
243 /* Make the vpiHandle for the reg. */
244 vpiHandle obj = vpip_make_net(name, msb, lsb, signed_flag, node);
245 compile_vpi_symbol(label, obj);
246 vpip_attach_to_current_scope(obj);
248 free(label);
249 free(name);
250 free(argv[0].text);
251 free(argv);
254 void compile_alias_real(char*label, char*name, int msb, int lsb,
255 unsigned argc, struct symb_s*argv)
257 assert(argc == 1);
259 vvp_net_t*node = vvp_net_lookup(argv[0].text);
261 /* Add the label into the functor symbol table. */
262 define_functor_symbol(label, node);
265 /* Make the vpiHandle for the reg. */
266 vpiHandle obj = vpip_make_real_var(name, node);
267 compile_vpi_symbol(label, obj);
268 vpip_attach_to_current_scope(obj);
270 free(label);
271 free(name);
272 free(argv[0].text);
273 free(argv);