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)
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 #ident "$Id: emit.cc,v 1.89 2007/01/16 05:44:15 steve Exp $"
28 * The emit function is called to generate the output required of the
36 bool NetNode::emit_node(struct target_t
*tgt
) const
38 cerr
<< "EMIT: Gate type? " << typeid(*this).name() << endl
;
42 bool NetLogic::emit_node(struct target_t
*tgt
) const
48 bool NetUDP::emit_node(struct target_t
*tgt
) const
54 bool NetAddSub::emit_node(struct target_t
*tgt
) const
56 tgt
->lpm_add_sub(this);
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);
71 bool NetCLShift::emit_node(struct target_t
*tgt
) const
73 tgt
->lpm_clshift(this);
77 bool NetCompare::emit_node(struct target_t
*tgt
) const
79 tgt
->lpm_compare(this);
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);
99 bool NetFF::emit_node(struct target_t
*tgt
) const
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);
116 bool NetMult::emit_node(struct target_t
*tgt
) const
122 bool NetMux::emit_node(struct target_t
*tgt
) const
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
;
174 bool NetAssign::emit_proc(struct target_t
*tgt
) const
176 tgt
->proc_assign(this);
180 bool NetAssignNB::emit_proc(struct target_t
*tgt
) const
182 tgt
->proc_assign_nb(this);
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);
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);
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
);
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);
250 bool NetSTask::emit_proc(struct target_t
*tgt
) const
252 tgt
->proc_stask(this);
256 bool NetUTask::emit_proc(struct target_t
*tgt
) const
258 tgt
->proc_utask(this);
262 bool NetWhile::emit_proc(struct target_t
*tgt
) const
264 tgt
->proc_while(this);
268 void NetBlock::emit_recurse(struct target_t
*tgt
) const
277 } while (cur
!= last_
);
280 bool NetCondit::emit_recurse_if(struct target_t
*tgt
) const
283 return if_
->emit_proc(tgt
);
288 bool NetCondit::emit_recurse_else(struct target_t
*tgt
) const
291 return else_
->emit_proc(tgt
);
296 bool NetEvProbe::emit_node(struct target_t
*tgt
) const
298 tgt
->net_probe(this);
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
321 statement_
->emit_proc(tgt
);
324 void NetRepeat::emit_recurse(struct target_t
*tgt
) const
327 statement_
->emit_proc(tgt
);
330 void NetScope::emit_scope(struct target_t
*tgt
) const
334 for (NetEvent
*cur
= events_
; cur
; cur
= cur
->snext_
)
337 for (NetScope
*cur
= sub_
; cur
; cur
= cur
->sib_
)
338 cur
->emit_scope(tgt
);
341 NetNet
*cur
= signals_
->sig_next_
;
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_
;
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
367 for (NetScope
*cur
= sub_
; cur
; cur
= cur
->sib_
)
368 flag
&= cur
->emit_defs(tgt
);
372 flag
&= tgt
->func_def(this);
377 default: /* BEGIN_END and FORK_JOIN, do nothing */
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
393 if (tgt
->start_design(this) == false)
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
);
403 bool nodes_rc
= true;
405 NetNode
*cur
= nodes_
->node_next_
;
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
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)
429 if (tasks_rc
== false)
431 if (proc_rc
== false)
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."
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
;
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
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.