00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "flipflop.h"
00012 #include "icndocument.h"
00013 #include "logic.h"
00014 #include "libraryitem.h"
00015 #include "node.h"
00016 #include "simulator.h"
00017
00018 #include <kiconloader.h>
00019 #include <klocale.h>
00020 #include <qpainter.h>
00021
00022
00023
00024 Item* ECDFlipFlop::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00025 {
00026 return new ECDFlipFlop( (ICNDocument*)itemDocument, newItem, id );
00027 }
00028
00029 LibraryItem* ECDFlipFlop::libraryItem()
00030 {
00031 return new LibraryItem(
00032 "ec/d_flipflop",
00033 i18n("D Flip-Flop"),
00034 i18n("Integrated Circuits"),
00035 "ic3.png",
00036 LibraryItem::lit_component,
00037 ECDFlipFlop::construct );
00038 }
00039
00040 ECDFlipFlop::ECDFlipFlop( ICNDocument *icnDocument, bool newItem, const char *id )
00041 : Component( icnDocument, newItem, (id) ? id : "d_flipflop" )
00042 {
00043 m_name = i18n("D-Type Flip-Flop");
00044 m_desc = i18n("The output state is set from the input state when the clock is pulsed.");
00045
00046 setSize( -32, -24, 64, 48 );
00047
00048 init2PinLeft( -8, 8 );
00049 init2PinRight( -8, 8 );
00050
00051 m_prevD[0] = m_prevD[1] = false;
00052 m_whichPrevD = 0;
00053 m_prevDSimTime = 0;
00054 m_pSimulator = Simulator::self();
00055
00056 m_bPrevClock = false;
00057 m_pD = createLogicIn( m_pNNode[0] );
00058 m_pClock = createLogicIn( m_pNNode[1] );
00059 m_pQ = createLogicOut( m_pPNode[0], false );
00060 m_pQBar = createLogicOut( m_pPNode[1], false );
00061
00062 setp = createLogicIn( createPin( 0, -32, 90, "set" ) );
00063 rstp = createLogicIn( createPin( 0, 32, 270, "rst" ) );
00064
00065 addDisplayText( "D", QRect( -32, -16, 20, 16 ), "D" );
00066 addDisplayText( ">", QRect( -32, 0, 20, 16 ), ">" );
00067 addDisplayText( "Q", QRect( 12, -16, 20, 16 ), "Q" );
00068 addDisplayText( "Q'", QRect( 12, 0, 20, 16 ), "Q'" );
00069 addDisplayText( "Set", QRect( -16, -20, 32, 16 ), "Set" );
00070 addDisplayText( "Rst", QRect( -16, 4, 32, 16 ), "Rst" );
00071
00072 m_pD->setCallback( this, (CallbackPtr)(&ECDFlipFlop::inputChanged) );
00073 m_pClock->setCallback( this, (CallbackPtr)(&ECDFlipFlop::clockChanged) );
00074 setp->setCallback( this, (CallbackPtr)(&ECDFlipFlop::asyncChanged) );
00075 rstp->setCallback( this, (CallbackPtr)(&ECDFlipFlop::asyncChanged) );
00076
00077 inStateChanged(false);
00078 }
00079
00080 ECDFlipFlop::~ECDFlipFlop()
00081 {
00082 }
00083
00084 void ECDFlipFlop::asyncChanged(bool)
00085 {
00086 bool set = setp->isHigh();
00087 bool rst = rstp->isHigh();
00088 if(set || rst)
00089 {
00090 m_pQ->setHigh(set);
00091 m_pQBar->setHigh(rst);
00092 }
00093 }
00094
00095 void ECDFlipFlop::inputChanged( bool newState )
00096 {
00097 unsigned long long simTime = m_pSimulator->time();
00098 if ( (simTime == m_prevDSimTime) && (newState == m_prevD[m_whichPrevD]) )
00099 return;
00100
00101 m_prevDSimTime = simTime;
00102 m_whichPrevD = 1-m_whichPrevD;
00103 m_prevD[m_whichPrevD] = newState;
00104 }
00105
00106 void ECDFlipFlop::clockChanged( bool newState )
00107 {
00108 bool set = setp->isHigh();
00109 bool rst = rstp->isHigh();
00110
00111 bool fallingEdge = m_bPrevClock && !newState;
00112 m_bPrevClock = newState;
00113
00114 if( set || rst ) return;
00115
00116 if (fallingEdge)
00117 {
00118 unsigned long long simTime = m_pSimulator->time();
00119 bool d = ( simTime == m_prevDSimTime ) ? m_prevD[1-m_whichPrevD] : m_prevD[m_whichPrevD];
00120
00121 m_pQ->setHigh(d);
00122 m_pQBar->setHigh(!d);
00123 }
00124 }
00125
00126 void ECDFlipFlop::inStateChanged(bool)
00127 {
00128
00129 m_pQ->setHigh(false);
00130 m_pQBar->setHigh(true);
00131 }
00132
00133
00134
00135
00136 Item* ECJKFlipFlop::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00137 {
00138 return new ECJKFlipFlop( (ICNDocument*)itemDocument, newItem, id );
00139 }
00140
00141 LibraryItem* ECJKFlipFlop::libraryItem()
00142 {
00143 return new LibraryItem(
00144 QString::QString("ec/jk_flipflop"),
00145 i18n("JK Flip-Flop"),
00146 i18n("Integrated Circuits"),
00147 "ic3.png",
00148 LibraryItem::lit_component,
00149 ECJKFlipFlop::construct );
00150 }
00151
00152 ECJKFlipFlop::ECJKFlipFlop( ICNDocument *icnDocument, bool newItem, const char *id )
00153 : Component( icnDocument, newItem, (id) ? id : "jk_flipflop" )
00154 {
00155 m_name = i18n("JK-Type Flip-Flop");
00156 m_desc = i18n("The output state is set according to J and K when the clock is pulsed.");
00157
00158 setSize( -32, -32, 64, 64 );
00159
00160 init3PinLeft( -16, 0, 16 );
00161 init2PinRight( -16, 16 );
00162
00163 m_pJ = createLogicIn( m_pNNode[0] );
00164 m_pClock = createLogicIn( m_pNNode[1] );
00165 m_pK = createLogicIn( m_pNNode[2] );
00166
00167 m_pQ = createLogicOut( m_pPNode[0], false );
00168 m_pQBar = createLogicOut( m_pPNode[1], false );
00169
00170 setp = createLogicIn( createPin( 0, -40, 90, "set" ) );
00171 rstp = createLogicIn( createPin( 0, 40, 270, "rst" ) );
00172
00173 addDisplayText( "J", QRect( -32, -24, 20, 16 ), "J" );
00174 addDisplayText( ">", QRect( -32, -8, 20, 16 ), ">" );
00175 addDisplayText( "K", QRect( -32, 8, 20, 16 ), "K" );
00176 addDisplayText( "Q", QRect( 12, -24, 20, 16 ), "Q" );
00177 addDisplayText( "Q'", QRect( 12, 8, 20, 16 ), "Q'" );
00178 addDisplayText( "Set", QRect( -16, -28, 32, 16 ), "Set" );
00179 addDisplayText( "Rst", QRect( -16, 12, 32, 16 ), "Rst" );
00180
00181 m_pClock->setCallback( this, (CallbackPtr)(&ECJKFlipFlop::clockChanged) );
00182 setp->setCallback( this, (CallbackPtr)(&ECJKFlipFlop::asyncChanged) );
00183 rstp->setCallback( this, (CallbackPtr)(&ECJKFlipFlop::asyncChanged) );
00184
00185 inStateChanged(false);
00186 }
00187
00188 ECJKFlipFlop::~ECJKFlipFlop()
00189 {
00190 }
00191
00192 void ECJKFlipFlop::clockChanged(bool newvalue)
00193 {
00194 bool j = m_pJ->isHigh();
00195 bool k = m_pK->isHigh();
00196 bool set = setp->isHigh();
00197 bool rst = rstp->isHigh();
00198
00199 if( set || rst ) return;
00200
00201
00202 if (!newvalue && (j || k)) {
00203 if ( j && k ) {
00204 m_pQ->setHigh(!prev_state);
00205 m_pQBar->setHigh(prev_state);
00206 prev_state = !prev_state;
00207 } else {
00208
00209 m_pQ->setHigh(j);
00210 m_pQBar->setHigh(k);
00211 prev_state = j;
00212 }
00213 }
00214 }
00215
00216 void ECJKFlipFlop::asyncChanged(bool)
00217 {
00218 bool set = setp->isHigh();
00219 bool rst = rstp->isHigh();
00220
00221 if (set || rst) {
00222 m_pQ->setHigh(set);
00223 m_pQBar->setHigh(rst);
00224 prev_state = set;
00225 }
00226 }
00227
00228 void ECJKFlipFlop::inStateChanged(bool)
00229 {
00230 m_pQBar->setHigh(true);
00231 m_pQ->setHigh(false);
00232 prev_state = false;
00233 }
00234
00235
00236
00237
00238 Item* ECSRFlipFlop::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00239 {
00240 return new ECSRFlipFlop( (ICNDocument*)itemDocument, newItem, id );
00241 }
00242
00243 LibraryItem* ECSRFlipFlop::libraryItem()
00244 {
00245 return new LibraryItem(
00246 QString::QString("ec/sr_flipflop"),
00247 i18n("SR Flip-Flop"),
00248 i18n("Integrated Circuits"),
00249 "ic3.png",
00250 LibraryItem::lit_component,
00251 ECSRFlipFlop::construct );
00252 }
00253
00254 ECSRFlipFlop::ECSRFlipFlop( ICNDocument *icnDocument, bool newItem, const char *id )
00255 : Component( icnDocument, newItem, (id) ? id : "sr_flipflop" )
00256 {
00257 m_name = i18n("SR Flip-Flop");
00258 m_desc = i18n("The output is made high by holding <i>set</i> high, and low by holding <i>reset</i> high.");
00259
00260 setSize( -24, -24, 48, 48 );
00261
00262 init2PinLeft( -8, 8 );
00263 init2PinRight( -8, 8 );
00264
00265 m_pS = createLogicIn( m_pNNode[0] );
00266 m_pR = createLogicIn( m_pNNode[1] );
00267 m_pQ = createLogicOut( m_pPNode[0], true );
00268 m_pQBar = createLogicOut( m_pPNode[1], false );
00269
00270 old_q1 = true;
00271 old_q2 = false;
00272 m_pQ->setHigh(old_q1);
00273 m_pQBar->setHigh(old_q2);
00274
00275 addDisplayText( "S", QRect( -24, -16, 20, 16 ), "S" );
00276 addDisplayText( "R", QRect( -24, 0, 20, 16 ), "R" );
00277 addDisplayText( "Q", QRect( 4, -16, 20, 16 ), "Q" );
00278 addDisplayText( "Q'", QRect( 4, 0, 20, 16 ), "Q'" );
00279
00280 m_pS->setCallback( this, (CallbackPtr)(&ECSRFlipFlop::inStateChanged) );
00281 m_pR->setCallback( this, (CallbackPtr)(&ECSRFlipFlop::inStateChanged) );
00282 m_pQ->setCallback( this, (CallbackPtr)(&ECSRFlipFlop::inStateChanged) );
00283 m_pQBar->setCallback( this, (CallbackPtr)(&ECSRFlipFlop::inStateChanged) );
00284 }
00285
00286 ECSRFlipFlop::~ECSRFlipFlop()
00287 {
00288 }
00289
00290 void ECSRFlipFlop::inStateChanged(bool)
00291 {
00292
00293 bool new_q1 = false;
00294 bool new_q2 = false;
00295
00296 bool s = m_pS->isHigh();
00297 bool r = m_pR->isHigh();
00298 bool q1 = m_pQ->isHigh();
00299 bool q2 = m_pQBar->isHigh();
00300
00301
00302 if (!q1) new_q2 = true;
00303 if (!q2) new_q1 = true;
00304
00305 if ( q1 && q2 )
00306 {
00307 if ( s && !r )
00308 {
00309 new_q1 = true;
00310 new_q2 = false;
00311 }
00312 else if ( !s && r )
00313 {
00314 new_q1 = false;
00315 new_q2 = true;
00316 }
00317 else if ( s && r )
00318 {
00319 new_q1 = old_q1;
00320 new_q2 = old_q2;
00321 }
00322 else if ( !s && !r )
00323 {
00324 new_q1 = false;
00325 new_q2 = false;
00326 }
00327 }
00328 else if ( q1 && !q2 )
00329 {
00330
00331 if ( r && !s ) new_q2 = true;
00332 else new_q2 = false;
00333 }
00334 else if ( !q1 && q2 )
00335 {
00336
00337 if ( s && !r ) new_q1 = true;
00338 else new_q1 = false;
00339 }
00340
00341 old_q1 = new_q1;
00342 old_q2 = new_q2;
00343
00344 m_pQ->setHigh(new_q1);
00345 m_pQBar->setHigh(new_q2);
00346 }
00347