/**************************************************************************** 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. ****************************************************************************/ #ifndef __thyme_h #define __thyme_h /* State symbol codes */ #define SYM_NUL1 0 #define SYM_ZERO 1 #define SYM_ONE 2 #define SYM_NUL2 3 #define SYM_FLOAT 4 #define SYM_LOW 5 #define SYM_HIGH 6 #define SYM_UNKNOWN 7 /* Event classes */ #define EV_UNKNOWN 0 /* An unknown event type */ #define EV_NET 1 /* A net changed value */ #define EV_PORT 2 /* A port changed value */ #define EV_GATE 3 /* A gate event occured */ #define EV_CONTROL 4 /* A control event occured */ /* Control event types */ #define EVC_STOP 0 /* Halt the queue */ /* Event queue flags */ #define EVF_RUN 0x1 /* Event queue is free running */ #define EVF_POSCLOCK 0x2 /* Wait for a clock posedge transition */ #define EVF_NEGCLOCK 0x4 /* Wait for a clock negedge transition */ #define EVF_HASCLOCK 0x8 /* The circuit contains at least one clock */ #define EVF_PERSRUN 0x10 /* Presistent run mode (run flag will be set when a switch is set) */ #define EVF_NOCMD 0x20 /* Do not process commands */ #define NO_TIME -1 /* A non-time value */ /* Breakpoint opcodes */ #define BPO_EQUAL 0 #define BPO_NEQ 1 /* Get the net affected by an event */ #define getEvNet(E) (((E)->evclass == EV_NET) ? (E)->evnet.net : (E)->evport.port->p_net) /* Test if event E is a change on port number n of g */ #define IsChangeOn(E,g,n) (getEvNet(E) == (g)->g_ports.port[(n)]->p_net) typedef int simTime; /* Simulation time */ /* Logic values 0 1 x z L H ------------------------- zero 1 0 1 0 1 0 one 0 1 1 0 0 1 flt 0 0 1 1 1 1 */ struct sstate { int status; short nbits; /* Number of bits in state */ short nalloc; /* Number of words allocated */ unsigned *zero; unsigned *one; unsigned *flt; }; struct sstate_fl { SState state; /* Actual state data */ struct sstate_fl *next; /* Next pointer for free list */ }; struct breakpoint { int bp_id; /* ID # of breakpoint */ char *bp_text; /* Text of breakpoint */ SNet *bp_net; /* Net breakpoint is on */ SState *bp_value; /* Target value */ int bp_op; /* Operation */ }; struct base_sevent { int evclass; /* Type of event */ simTime time; /* Time of event */ SEvent *next; /* Next event in bucket */ SState state; /* New state of net */ int status; }; struct net_sevent { int evclass; /* Type of event */ simTime time; /* Time of event */ SEvent *next; /* Next event in bucket */ SState state; /* New state of net */ int status; SNet *net; /* Net which changed */ }; struct port_sevent { int evclass; /* Type of event */ simTime time; /* Time of event */ SEvent *next; /* Next event in bucket */ SState state; /* New state of net */ int status; SPort *port; /* Net which changed */ }; struct gate_sevent { int evclass; /* Type of event */ simTime time; /* Time of event */ SEvent *next; /* Next event in bucket */ SState state; /* New state of net */ int status; SGate *gate; /* Gate on which event occurred */ int type; /* Event code for gate */ void *gdata; /* Optional data to send with event */ }; struct ctl_sevent { int evclass; /* Type of event */ simTime time; /* Time of event */ SEvent *next; /* Next event in bucket */ SState state; /* New state of net */ int status; int type; /* Control code */ void *data; /* Control data */ }; union sevent { int evclass; struct base_sevent evbase; struct net_sevent evnet; struct port_sevent evport; struct gate_sevent evgate; struct ctl_sevent evctl; }; struct evqueue { SModule *mod; /* Expanded module being simulated */ unsigned flags; /* Event queue flags */ int clockHold; /* Cycles to wait after clock posedge */ int clockCount; /* Number of clock cycles to step */ SGate *triggerClock; /* Clock to trigger on (null if any clock) */ int curStep; /* Current time step */ int numPending; /* Number of pending events */ SEvent *wheel_head[THYMEWHEEL_SIZE]; /* Event queues for each step (for dequeue) */ SEvent *wheel_tail[THYMEWHEEL_SIZE]; /* Event queues for each step (for enqueue) */ SEvent *wheel_overflow; /* Overflow events ouside regular time window */ NHash bptable; /* Table of breakpoints */ }; #define EvQueue_pending(Q) (Q)->numPending #define EvQueue_curPending(Q) ((Q)->wheel_head[((Q)->curStep & THYMEWHEEL_MASK)] != 0) void EvQueue_init(EvQueue *Q,SModule *M); void EvQueue_mainEventLoop(EvQueue *Q); SEvent *EvQueue_dequeue(EvQueue*); void EvQueue_process(EvQueue*,SEvent*); void EvQueue_execute(EvQueue*,char*); void EvQueue_enqueue(EvQueue*,SEvent*); /* Generic event enqueue */ void EvQueue_setNet(EvQueue*,SNet*,SState*,int); /* Enqueue a net value change event */ void EvQueue_setPort(EvQueue*,SPort*,SState*,int); /* Enqueue a port value change event */ void EvQueue_qGateEv(EvQueue*,SGate*,int,void*,int); /* Enqueue a gate event */ void EvQueue_control(EvQueue*,int,void*,int); /* Enqueue a queue control event */ void EvQueue_addBreak(EvQueue*,int,char*); /* Add a breakpoint */ void EvQueue_delBreak(EvQueue*,int); /* Delete a breakpoint */ void EvQueue_check(EvQueue*); SEvent *new_SEvent(); void delete_SEvent(SEvent*,int); void SState_init(SState *S,int nbits); void SState_uninit(SState *S); void SState_reinit(SState *S,int nbits); void SState_zero(SState *S); void SState_one(SState *S); void SState_unknown(SState *S); void SState_float(SState *S); void SState_print(SState *S,FILE *f); void SState_convert(SState *S,char *A); void SState_not(SState *R,SState *A); void SState_buf(SState *R,SState *A); void SState_copy(SState *R,SState *A); void SState_or(SState *R,SState *A,SState *B,int); void SState_and(SState *R,SState *A,SState *B,int); void SState_xor(SState *R,SState *A,SState *B,int); void SState_copyRange(SState *R,int rl,SState *A,int ah,int al); void SState_expandExtend(SState *R,int nbits); int SState_getBitSym(SState*,int); int SState_convertToInt(SState*,unsigned*); int SState_convertFromInt(SState*,unsigned); int SState_isLogic(SState*); int SState_getstr(SState *S,char *p); void SState_wire(SState *R,SState *A,SState *B); void SState_bufif(SState *R,SState *I,SState *E); void SState_nmos(SState *R,SState *I,SState *G); void SState_pmos(SState *R,SState *I,SState *G); int SState_isValue(SState *S); void SState_shift(SState *R,SState *I,int shift,int in1,int in0,int inZ); void SState_roll(SState *R,SState *I,int shift); int SState_eq(SState*,SState*); SState *alloc_SState(); void free_SState(SState*); #endif