/**************************************************************************** Copyright (C) 1987-2005 by Jeffery P. Hansen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ****************************************************************************/ #include #include #include #include #include #include #include "gsim.h" static SState state; void init_process() { SState_init(&state,1); } /* Propogate the value on a net changed by event E */ void SNet_propogate(SNet *N,EvQueue *Q,SEvent *E) { int i; for (i = 0;i < N->n_ports.num;i++) { SPort *P = N->n_ports.port[i]; if (P->p_isDup || P->p_type->io == GIO_OUT || P->p_type->io == GIO_TRI) continue; (*P->p_gate->g_type->gi_processEvent)(P->p_gate,Q,E); } } /* Process a net event E */ void SNet_process(SNet *N,EvQueue *Q,SEvent *E) { if (!SState_eq(&N->n_state,&E->evnet.state)) { SState_copy(&N->n_oldState,&N->n_state); SState_copy(&N->n_state,&E->evnet.state); if (N->n_watchNames) { HashElem *hE; for (hE = Hash_first(N->n_watchNames);hE; hE = Hash_next(N->n_watchNames,hE)) { char *nname = SHashElem_key(hE); char buf[STRMAX],*p; p = buf; p += sprintf(p,"net %s ",nname); p += SState_getstr(&N->n_state,p); p += sprintf(p," @ %d",E->evnet.time); sendMsg("%s",buf); } } if (N->n_breaks) { HashElem *hE; for (hE = Hash_first(N->n_breaks);hE;hE = Hash_next(N->n_breaks,hE)) { SBreakpoint *B = (SBreakpoint *)HashElem_obj(hE); int eq = SState_eq(&N->n_state,B->bp_value); int match = 0; switch (B->bp_op) { case BPO_EQUAL : match = eq; break; case BPO_NEQ : match = !eq; break; } if (match) { Q->flags &= ~(EVF_RUN|EVF_POSCLOCK|EVF_NEGCLOCK); sendMsg("break %d",B->bp_id); } } } SNet_propogate(N,Q,E); } } /* Process a port event E */ void SPort_process(SPort *P,EvQueue *Q,SEvent *E) { SNet *N = P->p_net; int i; SState_copy(&P->p_state,&E->evport.state); /* Copy event state to port */ SState_reinit(&state,P->p_state.nbits); /* Resize scratch state to correct bit length */ SState_float(&state); /* Initialize scratch state to floating */ for (i = 0;i < N->n_ports.num;i++) { SPort *nP = N->n_ports.port[i]; int port_type = SPort_effectiveType(nP); if (port_type != GIO_OUT && port_type != GIO_TRI && port_type != GIO_INOUT) { continue; } SState_wire(&state,&state,&nP->p_state); } E->evclass = EV_NET; /* Transform event into net event */ E->evnet.net = N; /* set net event occurs on */ SState_copy(&E->evnet.state,&state); /* copy new state of net */ SNet_process(N,Q,E); /* process the net event */ }