/**************************************************************************** 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 "gsim.h" #define ARSHIFT_Z 0 #define ARSHIFT_S 1 #define ARSHIFT_I 2 #define ARSHIFT_DELAY_SZ 0 #define ARSHIFT_DELAY_IZ 1 #define ARSHIFT_WORD(A,i,wc,wshift,bshift) \ { unsigned n = 0; \ if (i+wshift < wc) \ n |= (A[i+wshift] >> bshift); \ if (i+wshift+1 < wc) \ n |= (A[i+wshift+1] << (SSWORDSIZE-bshift)); \ A[i] = n; } #define ARSHIFT_SETBITS(A,wc,wshift,bshift) \ { for (i = 0;i < wshift;i++) \ A[wc-i-1] = SSWORDMASK; \ if (bshift > 0) \ A[wc-1] |= ~((1 << (SSWORDSIZE-bshift))-1); } static void Arshift_processEvent(SGate*,EvQueue*,SEvent*); int shift_checkGate(SGate*); static SGateInfo arshift_info = { 0, "arshift",0x0, 3,{{"Z",GIO_OUT,0}, {"S",GIO_IN,0}, {"I",GIO_IN,0}}, {{"S-Z",bit(1),0}, {"I-Z",bit(2),0}, {0}}, Generic_copyGate, Arshift_processEvent, shift_checkGate, Nop_initGate, 0, 0, 0, Generic_propFrwdDelay, Generic_propBackDelay, Generic_delay, }; void init_arshift() { SGateInfo_register(&arshift_info,0); } static void Arshift_processEvent(SGate *g,EvQueue *Q,SEvent *E) { SPort *Z = g->g_ports.port[ARSHIFT_Z]; SState *S = SGate_allocPortState(g,ARSHIFT_S); SState *I = SGate_allocPortState(g,ARSHIFT_I); unsigned smask = (1<<(S->nbits & SSBITMASK))-1; SState *out = alloc_SState(); int delay; SState_reinit(out,Z->p_state.nbits); if ((S->flt[0]&smask)) { SState_unknown(out); } else { int wc = SSNUMWORDS(I->nbits); int hb = SSHIGHBIT(I->nbits); int in1 = ((I->one[wc-1] & (1 << hb)) != 0); int in0 = ((I->zero[wc-1] & (1 << hb)) != 0); int inZ = ((I->flt[wc-1] & (1 << hb)) != 0); SState_shift(out,I,-(S->one[0]&smask),in1,in0,inZ); } if (IsChangeOn(E,g,ARSHIFT_I)) delay = g->g_delayParms[ARSHIFT_DELAY_IZ]; else delay = g->g_delayParms[ARSHIFT_DELAY_SZ]; EvQueue_setPort(Q,Z,out,delay); free_SState(out); free_SState(I); free_SState(S); }