00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "libraryitem.h"
00011 #include "logic.h"
00012 #include "magnitudecomparator.h"
00013 #include "variant.h"
00014
00015 #include <cmath>
00016 #include <klocale.h>
00017
00018 Item* MagnitudeComparator::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00019 {
00020 return new MagnitudeComparator( (ICNDocument*)itemDocument, newItem, id );
00021 }
00022
00023 LibraryItem* MagnitudeComparator::libraryItem()
00024 {
00025 return new LibraryItem(
00026 QString("ec/magnitudecomparator"),
00027 i18n("Magnitude Comparator"),
00028 i18n("Integrated Circuits"),
00029 "ic1.png",
00030 LibraryItem::lit_component,
00031 MagnitudeComparator::construct
00032 );
00033 }
00034
00035 MagnitudeComparator::MagnitudeComparator( ICNDocument *icnDocument, bool newItem, const char *id )
00036 : Component( icnDocument, newItem, id ? id : "magnitudecomparator" )
00037 {
00038 m_name = i18n("Magnitude Comparator");
00039
00040 m_desc = i18n("Compares two binary numbers and generates output to indicate which binary number has the greater magnitude. It has 3 cascading inputs:"
00041 "<ul><li>I: A > B</li>"
00042 "<li>I: A < B</li>"
00043 "<li>I: A = B</li></ul>"
00044 "and 3 outputs:"
00045 "<ul><li>O: A > B</li>"
00046 "<li>O: A < B</li>"
00047 "<li>O: A = B</li></ul>");
00048
00049 createProperty( "numInput", Variant::Type::Int );
00050 property("numInput")->setCaption( i18n("Number Inputs") );
00051 property("numInput")->setMinValue(1);
00052 property("numInput")->setMaxValue(8);
00053 property("numInput")->setValue(4);
00054
00055 m_oldABLogicCount = 0;
00056 cascadingInputs = 3;
00057 outputs = 3;
00058
00059 firstTime = true;
00060 }
00061
00062 MagnitudeComparator::~MagnitudeComparator()
00063 {
00064 }
00065
00066
00067 void MagnitudeComparator::dataChanged()
00068 {
00069 initPins();
00070 }
00071
00072
00073 void MagnitudeComparator::inStateChanged()
00074 {
00075 int i;
00076
00077 for ( i = 0; i < 3; i++ )
00078 m_output[i]->setHigh(false);
00079
00080
00081 for ( i = m_oldABLogicCount-1; i >= 0; i-- ) {
00082 if (m_aLogic[i]->isHigh() && !m_bLogic[i]->isHigh())
00083 {
00084 m_output[0]->setHigh(true);
00085 return;
00086 }
00087 else if ( !m_aLogic[i]->isHigh() && m_bLogic[i]->isHigh() ) {
00088 m_output[1]->setHigh(true);
00089 return;
00090 }
00091 }
00092
00093 if ( m_cLogic[2]->isHigh() )
00094 m_output[2]->setHigh(true);
00095 else if ( m_cLogic[0]->isHigh() )
00096 if ( !m_cLogic[1]->isHigh() )
00097 m_output[0]->setHigh(true);
00098 else
00099 ;
00100 else if ( m_cLogic[1]->isHigh() )
00101 m_output[1]->setHigh(true);
00102 else {
00103 m_output[0]->setHigh(true);
00104 m_output[1]->setHigh(true);
00105 }
00106 }
00107
00108
00109 void MagnitudeComparator::initPins()
00110 {
00111 const double numInputs = dataInt("numInput");
00112 int newABLogicCount = (int)numInputs;
00113
00114 if ( newABLogicCount == m_oldABLogicCount )
00115 return;
00116
00117 QStringList leftPins;
00118 int space = 3 - newABLogicCount;
00119 for ( int i = 0; i < space; i++ )
00120 leftPins << "";
00121 for ( int i = 0; i < newABLogicCount; i++ )
00122 leftPins << QString("A%1").arg( QString::number(i) );
00123 for ( int i = 0; i < newABLogicCount; i++ )
00124 leftPins << QString("B%1").arg( QString::number(i) );
00125 for ( int i = 0; i < space; i++ )
00126 leftPins << "";
00127
00128 QStringList rightPins;
00129 space = -space;
00130 for ( int i = 0; i < space; i++ )
00131 rightPins << "";
00132 QString inNames[] = { "I: A>B", "I: A<B", "I: A=B" };
00133 rightPins << inNames[2] << inNames[1] << inNames[0];
00134 QString outNames[] = { "O: A>B", "O: A<B", "O: A=B" };
00135 rightPins << outNames[2] << outNames[1] << outNames[0];
00136 for ( int i = 0; i < space; i++ )
00137 rightPins << "";
00138
00139 QStringList pins = leftPins + rightPins;
00140
00141 initDIPSymbol( pins, 88 );
00142 initDIP(pins);
00143
00144 ECNode *node;
00145
00146 if (firstTime) {
00147 m_cLogic.resize(3);
00148 for ( int i = 0; i < cascadingInputs; i++ )
00149 {
00150 node = ecNodeWithID( inNames[i] );
00151 m_cLogic.insert( i, createLogicIn(node) );
00152 m_cLogic[i]->setCallback( this, (CallbackPtr)(&MagnitudeComparator::inStateChanged));
00153 }
00154
00155 m_output.resize(3);
00156 for ( int i = 0; i < outputs; i++ )
00157 {
00158 node = ecNodeWithID( outNames[i] );
00159 m_output.insert( i, createLogicOut(node,false) );
00160 }
00161 firstTime = false;
00162 }
00163
00164 if ( newABLogicCount > m_oldABLogicCount )
00165 {
00166 m_aLogic.resize(newABLogicCount);
00167 for ( int i=m_oldABLogicCount; i<newABLogicCount; ++i )
00168 {
00169 node = ecNodeWithID("A"+QString::number(i));
00170 m_aLogic.insert( i, createLogicIn(node) );
00171 m_aLogic[i]->setCallback( this, (CallbackPtr)(&MagnitudeComparator::inStateChanged) );
00172 }
00173
00174 m_bLogic.resize(newABLogicCount);
00175 for ( int i=m_oldABLogicCount; i<newABLogicCount; ++i )
00176 {
00177 node = ecNodeWithID("B"+QString::number(i));
00178 m_bLogic.insert( i, createLogicIn(node) );
00179 m_bLogic[i]->setCallback( this, (CallbackPtr)(&MagnitudeComparator::inStateChanged) );
00180 }
00181 }
00182 else
00183 {
00184 for ( int i=newABLogicCount; i<m_oldABLogicCount; ++i )
00185 {
00186 QString id = "A"+QString::number(i);
00187 removeDisplayText(id);
00188 removeElement( m_aLogic[i], false );
00189 removeNode(id);
00190 }
00191 m_aLogic.resize(newABLogicCount);
00192 for ( int i=newABLogicCount; i<m_oldABLogicCount; ++i )
00193 {
00194 QString id = "B"+QString::number(i);
00195 removeDisplayText(id);
00196 removeElement( m_bLogic[i], false );
00197 removeNode(id);
00198 }
00199 m_bLogic.resize(newABLogicCount);
00200 }
00201
00202 m_oldABLogicCount = newABLogicCount;
00203 inStateChanged();
00204 }
00205
00206