diff options
Diffstat (limited to 'src/electronics/components/magnitudecomparator.cpp')
-rw-r--r-- | src/electronics/components/magnitudecomparator.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/electronics/components/magnitudecomparator.cpp b/src/electronics/components/magnitudecomparator.cpp new file mode 100644 index 0000000..2659122 --- /dev/null +++ b/src/electronics/components/magnitudecomparator.cpp @@ -0,0 +1,206 @@ +/*************************************************************************** + * Copyright (C) 2005 by Fredy Yanardi * + * * + * 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. * + ***************************************************************************/ + +#include "libraryitem.h" +#include "logic.h" +#include "magnitudecomparator.h" +#include "variant.h" + +#include <cmath> +#include <klocale.h> + +Item* MagnitudeComparator::construct( ItemDocument *itemDocument, bool newItem, const char *id ) +{ + return new MagnitudeComparator( (ICNDocument*)itemDocument, newItem, id ); +} + +LibraryItem* MagnitudeComparator::libraryItem() +{ + return new LibraryItem( + QString("ec/magnitudecomparator"), + i18n("Magnitude Comparator"), + i18n("Integrated Circuits"), + "ic1.png", + LibraryItem::lit_component, + MagnitudeComparator::construct + ); +} + +MagnitudeComparator::MagnitudeComparator( ICNDocument *icnDocument, bool newItem, const char *id ) + : Component( icnDocument, newItem, id ? id : "magnitudecomparator" ) +{ + m_name = i18n("Magnitude Comparator"); +// m_desc = i18n("Compares to two binary number and generates input to indicate which binary number has greater magnitude. It has 3 cascading inputs: I0 for I<SUB>A > B</SUB>, I1 for I<SUB>A < B</SUB>, and I2 for I<SUB>A = B</SUB> and 3 outputs: O0 for O<SUB>A > B</SUB>, O1 for O<SUB>A < B</SUB>, and O2 for O<SUB>A = B</SUB>"); + m_desc = i18n("Compares two binary numbers and generates output to indicate which binary number has the greater magnitude. It has 3 cascading inputs:" + "<ul><li>I: A > B</li>" + "<li>I: A < B</li>" + "<li>I: A = B</li></ul>" + "and 3 outputs:" + "<ul><li>O: A > B</li>" + "<li>O: A < B</li>" + "<li>O: A = B</li></ul>"); + + createProperty( "numInput", Variant::Type::Int ); + property("numInput")->setCaption( i18n("Number Inputs") ); + property("numInput")->setMinValue(1); + property("numInput")->setMaxValue(8); + property("numInput")->setValue(4); + + m_oldABLogicCount = 0; + cascadingInputs = 3; + outputs = 3; + + firstTime = true; +} + +MagnitudeComparator::~MagnitudeComparator() +{ +} + + +void MagnitudeComparator::dataChanged() +{ + initPins(); +} + + +void MagnitudeComparator::inStateChanged() +{ + int i; + + for ( i = 0; i < 3; i++ ) + m_output[i]->setHigh(false); + +// for ( i = dataInt("numInput")-1; i >= 0; i-- ) { + for ( i = m_oldABLogicCount-1; i >= 0; i-- ) { + if (m_aLogic[i]->isHigh() && !m_bLogic[i]->isHigh()) + { + m_output[0]->setHigh(true); + return; + } + else if ( !m_aLogic[i]->isHigh() && m_bLogic[i]->isHigh() ) { + m_output[1]->setHigh(true); + return; + } + } + + if ( m_cLogic[2]->isHigh() ) + m_output[2]->setHigh(true); + else if ( m_cLogic[0]->isHigh() ) + if ( !m_cLogic[1]->isHigh() ) + m_output[0]->setHigh(true); + else + ; + else if ( m_cLogic[1]->isHigh() ) + m_output[1]->setHigh(true); + else { + m_output[0]->setHigh(true); + m_output[1]->setHigh(true); + } +} + + +void MagnitudeComparator::initPins() +{ + const double numInputs = dataInt("numInput"); + int newABLogicCount = (int)numInputs; + + if ( newABLogicCount == m_oldABLogicCount ) + return; + + QStringList leftPins; + int space = 3 - newABLogicCount; + for ( int i = 0; i < space; i++ ) + leftPins << ""; + for ( int i = 0; i < newABLogicCount; i++ ) + leftPins << QString("A%1").arg( QString::number(i) ); + for ( int i = 0; i < newABLogicCount; i++ ) + leftPins << QString("B%1").arg( QString::number(i) ); + for ( int i = 0; i < space; i++ ) + leftPins << ""; + + QStringList rightPins; + space = -space; + for ( int i = 0; i < space; i++ ) + rightPins << ""; + QString inNames[] = { "I: A>B", "I: A<B", "I: A=B" }; + rightPins << inNames[2] << inNames[1] << inNames[0]; + QString outNames[] = { "O: A>B", "O: A<B", "O: A=B" }; + rightPins << outNames[2] << outNames[1] << outNames[0]; + for ( int i = 0; i < space; i++ ) + rightPins << ""; + + QStringList pins = leftPins + rightPins; + + initDIPSymbol( pins, 88 ); + initDIP(pins); + + ECNode *node; + + if (firstTime) { + m_cLogic.resize(3); + for ( int i = 0; i < cascadingInputs; i++ ) + { + node = ecNodeWithID( inNames[i] ); + m_cLogic.insert( i, createLogicIn(node) ); + m_cLogic[i]->setCallback( this, (CallbackPtr)(&MagnitudeComparator::inStateChanged)); + } + + m_output.resize(3); + for ( int i = 0; i < outputs; i++ ) + { + node = ecNodeWithID( outNames[i] ); + m_output.insert( i, createLogicOut(node,false) ); + } + firstTime = false; + } + + if ( newABLogicCount > m_oldABLogicCount ) + { + m_aLogic.resize(newABLogicCount); + for ( int i=m_oldABLogicCount; i<newABLogicCount; ++i ) + { + node = ecNodeWithID("A"+QString::number(i)); + m_aLogic.insert( i, createLogicIn(node) ); + m_aLogic[i]->setCallback( this, (CallbackPtr)(&MagnitudeComparator::inStateChanged) ); + } + + m_bLogic.resize(newABLogicCount); + for ( int i=m_oldABLogicCount; i<newABLogicCount; ++i ) + { + node = ecNodeWithID("B"+QString::number(i)); + m_bLogic.insert( i, createLogicIn(node) ); + m_bLogic[i]->setCallback( this, (CallbackPtr)(&MagnitudeComparator::inStateChanged) ); + } + } + else + { + for ( int i=newABLogicCount; i<m_oldABLogicCount; ++i ) + { + QString id = "A"+QString::number(i); + removeDisplayText(id); + removeElement( m_aLogic[i], false ); + removeNode(id); + } + m_aLogic.resize(newABLogicCount); + for ( int i=newABLogicCount; i<m_oldABLogicCount; ++i ) + { + QString id = "B"+QString::number(i); + removeDisplayText(id); + removeElement( m_bLogic[i], false ); + removeNode(id); + } + m_bLogic.resize(newABLogicCount); + } + + m_oldABLogicCount = newABLogicCount; + inStateChanged(); +} + + |