Remove restriction on size of constants
[iverilog.git] / emit.cc
blob3d00ad6064d1dca21b5b9c9d7a317941eebd8ddf
1 /*
2 * Copyright (c) 1998-2005 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: emit.cc,v 1.89 2007/01/16 05:44:15 steve Exp $"
21 #endif
23 # include "config.h"
25 # include <iostream>
28 * The emit function is called to generate the output required of the
29 * target.
31 # include "target.h"
32 # include "netlist.h"
33 # include <typeinfo>
34 # include <cassert>
36 bool NetNode::emit_node(struct target_t*tgt) const
38 cerr << "EMIT: Gate type? " << typeid(*this).name() << endl;
39 return false;
42 bool NetLogic::emit_node(struct target_t*tgt) const
44 tgt->logic(this);
45 return true;
48 bool NetUDP::emit_node(struct target_t*tgt) const
50 tgt->udp(this);
51 return true;
54 bool NetAddSub::emit_node(struct target_t*tgt) const
56 tgt->lpm_add_sub(this);
57 return true;
60 bool NetArrayDq::emit_node(struct target_t*tgt) const
62 return tgt->lpm_array_dq(this);
65 bool NetCaseCmp::emit_node(struct target_t*tgt) const
67 tgt->net_case_cmp(this);
68 return true;
71 bool NetCLShift::emit_node(struct target_t*tgt) const
73 tgt->lpm_clshift(this);
74 return true;
77 bool NetCompare::emit_node(struct target_t*tgt) const
79 tgt->lpm_compare(this);
80 return true;
83 bool NetConcat::emit_node(struct target_t*tgt) const
85 return tgt->concat(this);
88 bool NetConst::emit_node(struct target_t*tgt) const
90 return tgt->net_const(this);
93 bool NetDivide::emit_node(struct target_t*tgt) const
95 tgt->lpm_divide(this);
96 return true;
99 bool NetFF::emit_node(struct target_t*tgt) const
101 tgt->lpm_ff(this);
102 return true;
105 bool NetLiteral::emit_node(struct target_t*tgt) const
107 return tgt->net_literal(this);
110 bool NetModulo::emit_node(struct target_t*tgt) const
112 tgt->lpm_modulo(this);
113 return true;
116 bool NetMult::emit_node(struct target_t*tgt) const
118 tgt->lpm_mult(this);
119 return true;
122 bool NetMux::emit_node(struct target_t*tgt) const
124 tgt->lpm_mux(this);
125 return true;
128 bool NetPartSelect::emit_node(struct target_t*tgt) const
130 return tgt->part_select(this);
133 bool NetReplicate::emit_node(struct target_t*tgt) const
135 return tgt->replicate(this);
138 bool NetSignExtend::emit_node(struct target_t*tgt) const
140 return tgt->sign_extend(this);
143 bool NetUReduce::emit_node(struct target_t*tgt) const
145 return tgt->ureduce(this);
148 bool NetSysFunc::emit_node(struct target_t*tgt) const
150 return tgt->net_sysfunction(this);
153 bool NetUserFunc::emit_node(struct target_t*tgt) const
155 return tgt->net_function(this);
158 bool NetBUFZ::emit_node(struct target_t*tgt) const
160 return tgt->bufz(this);
163 bool NetProcTop::emit(struct target_t*tgt) const
165 return tgt->process(this);
168 bool NetProc::emit_proc(struct target_t*tgt) const
170 cerr << "EMIT: Proc type? " << typeid(*this).name() << endl;
171 return false;
174 bool NetAssign::emit_proc(struct target_t*tgt) const
176 tgt->proc_assign(this);
177 return true;
180 bool NetAssignNB::emit_proc(struct target_t*tgt) const
182 tgt->proc_assign_nb(this);
183 return true;
186 bool NetBlock::emit_proc(struct target_t*tgt) const
188 return tgt->proc_block(this);
191 bool NetCase::emit_proc(struct target_t*tgt) const
193 tgt->proc_case(this);
194 return true;
197 bool NetCAssign::emit_proc(struct target_t*tgt) const
199 return tgt->proc_cassign(this);
202 bool NetCondit::emit_proc(struct target_t*tgt) const
204 return tgt->proc_condit(this);
207 bool NetDeassign::emit_proc(struct target_t*tgt) const
209 return tgt->proc_deassign(this);
212 bool NetDisable::emit_proc(struct target_t*tgt) const
214 return tgt->proc_disable(this);
217 bool NetForce::emit_proc(struct target_t*tgt) const
219 return tgt->proc_force(this);
222 bool NetForever::emit_proc(struct target_t*tgt) const
224 tgt->proc_forever(this);
225 return true;
228 bool NetPDelay::emit_proc(struct target_t*tgt) const
230 return tgt->proc_delay(this);
233 bool NetPDelay::emit_proc_recurse(struct target_t*tgt) const
235 if (statement_) return statement_->emit_proc(tgt);
236 return true;
239 bool NetRelease::emit_proc(struct target_t*tgt) const
241 return tgt->proc_release(this);
244 bool NetRepeat::emit_proc(struct target_t*tgt) const
246 tgt->proc_repeat(this);
247 return true;
250 bool NetSTask::emit_proc(struct target_t*tgt) const
252 tgt->proc_stask(this);
253 return true;
256 bool NetUTask::emit_proc(struct target_t*tgt) const
258 tgt->proc_utask(this);
259 return true;
262 bool NetWhile::emit_proc(struct target_t*tgt) const
264 tgt->proc_while(this);
265 return true;
268 void NetBlock::emit_recurse(struct target_t*tgt) const
270 if (last_ == 0)
271 return;
273 NetProc*cur = last_;
274 do {
275 cur = cur->next_;
276 cur->emit_proc(tgt);
277 } while (cur != last_);
280 bool NetCondit::emit_recurse_if(struct target_t*tgt) const
282 if (if_)
283 return if_->emit_proc(tgt);
284 else
285 return true;
288 bool NetCondit::emit_recurse_else(struct target_t*tgt) const
290 if (else_)
291 return else_->emit_proc(tgt);
292 else
293 return true;
296 bool NetEvProbe::emit_node(struct target_t*tgt) const
298 tgt->net_probe(this);
299 return true;
302 bool NetEvTrig::emit_proc(struct target_t*tgt) const
304 return tgt->proc_trigger(this);
307 bool NetEvWait::emit_proc(struct target_t*tgt) const
309 return tgt->proc_wait(this);
312 bool NetEvWait::emit_recurse(struct target_t*tgt) const
314 if (!statement_) return true;
315 return statement_->emit_proc(tgt);
318 void NetForever::emit_recurse(struct target_t*tgt) const
320 if (statement_)
321 statement_->emit_proc(tgt);
324 void NetRepeat::emit_recurse(struct target_t*tgt) const
326 if (statement_)
327 statement_->emit_proc(tgt);
330 void NetScope::emit_scope(struct target_t*tgt) const
332 tgt->scope(this);
334 for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
335 tgt->event(cur);
337 for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
338 cur->emit_scope(tgt);
340 if (signals_) {
341 NetNet*cur = signals_->sig_next_;
342 do {
343 tgt->signal(cur);
344 cur = cur->sig_next_;
345 } while (cur != signals_->sig_next_);
347 /* Run the signals again, but this time to connect the
348 delay paths. This is done as a second pass because
349 the paths reference other signals that may be later
350 in the list. We can do it here becase delay paths are
351 always connected within the scope. */
352 cur = signals_->sig_next_;
353 do {
354 tgt->signal_paths(cur);
355 cur = cur->sig_next_;
356 } while (cur != signals_->sig_next_);
361 bool NetScope::emit_defs(struct target_t*tgt) const
363 bool flag = true;
365 switch (type_) {
366 case MODULE:
367 for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
368 flag &= cur->emit_defs(tgt);
369 break;
371 case FUNC:
372 flag &= tgt->func_def(this);
373 break;
374 case TASK:
375 tgt->task_def(this);
376 break;
377 default: /* BEGIN_END and FORK_JOIN, do nothing */
378 break;
381 return flag;
384 void NetWhile::emit_proc_recurse(struct target_t*tgt) const
386 proc_->emit_proc(tgt);
389 int Design::emit(struct target_t*tgt) const
391 int rc = 0;
393 if (tgt->start_design(this) == false)
394 return -2;
396 // enumerate the scopes
397 for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
398 scope != root_scopes_.end(); scope++)
399 (*scope)->emit_scope(tgt);
402 // emit nodes
403 bool nodes_rc = true;
404 if (nodes_) {
405 NetNode*cur = nodes_->node_next_;
406 do {
407 nodes_rc = nodes_rc && cur->emit_node(tgt);
408 cur = cur->node_next_;
409 } while (cur != nodes_->node_next_);
413 // emit task and function definitions
414 bool tasks_rc = true;
415 for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
416 scope != root_scopes_.end(); scope++)
417 tasks_rc &= (*scope)->emit_defs(tgt);
420 // emit the processes
421 bool proc_rc = true;
422 for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
423 proc_rc &= idx->emit(tgt);
425 rc = tgt->end_design(this);
427 if (nodes_rc == false)
428 return -1;
429 if (tasks_rc == false)
430 return -2;
431 if (proc_rc == false)
432 return -3;
434 return rc;
437 void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
439 tgt->expr_binary(this);
442 void NetEConcat::expr_scan(struct expr_scan_t*tgt) const
444 tgt->expr_concat(this);
447 void NetEConst::expr_scan(struct expr_scan_t*tgt) const
449 tgt->expr_const(this);
452 void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const
454 tgt->expr_param(this);
457 void NetECReal::expr_scan(struct expr_scan_t*tgt) const
459 tgt->expr_creal(this);
462 void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
464 tgt->expr_rparam(this);
467 void NetEParam::expr_scan(struct expr_scan_t*tgt) const
469 cerr << get_line() << ":internal error: unexpected NetEParam."
470 << endl;
473 void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
475 tgt->expr_event(this);
478 void NetEScope::expr_scan(struct expr_scan_t*tgt) const
480 tgt->expr_scope(this);
483 void NetESelect::expr_scan(struct expr_scan_t*tgt) const
485 tgt->expr_select(this);
488 void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
490 tgt->expr_sfunc(this);
493 void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const
495 tgt->expr_ufunc(this);
498 void NetESignal::expr_scan(struct expr_scan_t*tgt) const
500 tgt->expr_signal(this);
503 void NetETernary::expr_scan(struct expr_scan_t*tgt) const
505 tgt->expr_ternary(this);
508 void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
510 tgt->expr_unary(this);
513 int emit(const Design*des, const char*type)
515 for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
516 const struct target*tgt = target_table[idx];
517 if (strcmp(tgt->name, type) == 0)
518 return des->emit(tgt->meth);
522 cerr << "error: Code generator type " << type
523 << " not found." << endl;
524 return -1;
529 * $Log: emit.cc,v $
530 * Revision 1.89 2007/01/16 05:44:15 steve
531 * Major rework of array handling. Memories are replaced with the
532 * more general concept of arrays. The NetMemory and NetEMemory
533 * classes are removed from the ivl core program, and the IVL_LPM_RAM
534 * lpm type is removed from the ivl_target API.
536 * Revision 1.88 2006/11/10 05:44:44 steve
537 * Process delay paths in second path over signals.
539 * Revision 1.87 2006/06/18 04:15:50 steve
540 * Add support for system functions in continuous assignments.
542 * Revision 1.86 2005/07/11 16:56:50 steve
543 * Remove NetVariable and ivl_variable_t structures.
545 * Revision 1.85 2005/07/07 16:22:49 steve
546 * Generalize signals to carry types.
548 * Revision 1.84 2005/05/24 01:44:27 steve
549 * Do sign extension of structuran nets.
551 * Revision 1.83 2005/02/08 00:12:36 steve
552 * Add the NetRepeat node, and code generator support.
554 * Revision 1.82 2005/02/03 04:56:20 steve
555 * laborate reduction gates into LPM_RED_ nodes.
557 * Revision 1.81 2005/01/24 05:28:30 steve
558 * Remove the NetEBitSel and combine all bit/part select
559 * behavior into the NetESelect node and IVL_EX_SELECT
560 * ivl_target expression type.
562 * Revision 1.80 2005/01/22 01:06:55 steve
563 * Change case compare from logic to an LPM node.
565 * Revision 1.79 2004/12/29 23:55:43 steve
566 * Unify elaboration of l-values for all proceedural assignments,
567 * including assing, cassign and force.
569 * Generate NetConcat devices for gate outputs that feed into a
570 * vector results. Use this to hande gate arrays. Also let gate
571 * arrays handle vectors of gates when the outputs allow for it.
573 * Revision 1.78 2004/12/11 02:31:26 steve
574 * Rework of internals to carry vectors through nexus instead
575 * of single bits. Make the ivl, tgt-vvp and vvp initial changes
576 * down this path.
578 * Revision 1.77 2004/10/04 01:10:53 steve
579 * Clean up spurious trailing white space.
581 * Revision 1.76 2004/05/31 23:34:37 steve
582 * Rewire/generalize parsing an elaboration of
583 * function return values to allow for better
584 * speed and more type support.
586 * Revision 1.75 2003/09/13 01:30:07 steve
587 * Missing case warnings.
589 * Revision 1.74 2003/05/30 02:55:32 steve
590 * Support parameters in real expressions and
591 * as real expressions, and fix multiply and
592 * divide with real results.
594 * Revision 1.73 2003/04/22 04:48:29 steve
595 * Support event names as expressions elements.
597 * Revision 1.72 2003/03/10 23:40:53 steve
598 * Keep parameter constants for the ivl_target API.
600 * Revision 1.71 2003/01/26 21:15:58 steve
601 * Rework expression parsing and elaboration to
602 * accommodate real/realtime values and expressions.