00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "demultiplexer.h"
00012
00013 #include "logic.h"
00014 #include "libraryitem.h"
00015
00016 #include <kiconloader.h>
00017 #include <klocale.h>
00018
00019 #include <cmath>
00020
00021 Item* Demultiplexer::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00022 {
00023 return new Demultiplexer( (ICNDocument*)itemDocument, newItem, id );
00024 }
00025
00026 LibraryItem* Demultiplexer::libraryItem()
00027 {
00028 return new LibraryItem(
00029 "ec/demultiplexer",
00030 i18n("Demultiplexer"),
00031 i18n("Integrated Circuits"),
00032 "ic1.png",
00033 LibraryItem::lit_component,
00034 Demultiplexer::construct
00035 );
00036 }
00037
00038 Demultiplexer::Demultiplexer( ICNDocument *icnDocument, bool newItem, const char *id )
00039 : Component( icnDocument, newItem, id ? id : "demultiplexer" )
00040 {
00041 m_name = i18n("Demultiplexer");
00042 m_desc = i18n("Seperates the input data stream into components. The value of the input is passed to the \"X\" output selected by the binary number given by the \"A\" inputs.");
00043
00044 m_input = 0;
00045
00046 createProperty( "addressSize", Variant::Type::Int );
00047 property("addressSize")->setCaption( i18n("Address Size") );
00048 property("addressSize")->setMinValue(1);
00049 property("addressSize")->setMaxValue(8);
00050 property("addressSize")->setValue(1);
00051
00052
00053 createProperty( "numInput", Variant::Type::Int );
00054 property("numInput")->setMinValue(-1);
00055 property("numInput")->setValue(-1);
00056 property("numInput")->setHidden(true);
00057 }
00058
00059 Demultiplexer::~Demultiplexer()
00060 {
00061 }
00062
00063
00064 void Demultiplexer::dataChanged()
00065 {
00066 if ( hasProperty("numInput") && dataInt("numInput") != -1 )
00067 {
00068 int addressSize = int( std::ceil( std::log( (double)dataInt("numInput") ) / std::log(2.0) ) );
00069 property("numInput")->setValue(-1);
00070
00071 if ( addressSize < 1 )
00072 addressSize = 1;
00073 else if ( addressSize > 8 )
00074 addressSize = 8;
00075
00076
00077 property("addressSize")->setValue(addressSize);
00078 return;
00079 }
00080
00081 if ( hasProperty("numInput") )
00082 {
00083 m_variantData["numInput"]->deleteLater();
00084 m_variantData.remove("numInput");
00085 }
00086
00087 initPins( unsigned(dataInt("addressSize")) );
00088 }
00089
00090
00091 void Demultiplexer::inStateChanged( bool )
00092 {
00093 unsigned long long pos = 0;
00094 for ( unsigned i = 0; i < m_aLogic.size(); ++i )
00095 {
00096 if ( m_aLogic[i]->isHigh() )
00097 pos += 1 << i;
00098 }
00099 for ( unsigned i = 0; i < m_xLogic.size(); ++i )
00100 m_xLogic[i]->setHigh( (pos == i) && m_input->isHigh() );
00101 }
00102
00103
00104 void Demultiplexer::initPins( unsigned newAddressSize )
00105 {
00106 unsigned oldAddressSize = m_aLogic.size();
00107 unsigned long long oldXLogicCount = m_xLogic.size();
00108 unsigned long long newXLogicCount = 1 << newAddressSize;
00109
00110 if ( newXLogicCount == oldXLogicCount )
00111 return;
00112
00113 QStringList pins;
00114
00115 for ( unsigned i=0; i<newAddressSize; ++i )
00116 pins += "A"+QString::number(i);
00117 for ( unsigned i=newAddressSize; i<(newXLogicCount+(newXLogicCount%2))/2; ++i )
00118 pins += "";
00119 pins += "X";
00120 for ( unsigned i=(newXLogicCount+(newXLogicCount%2))/2+1; i<newXLogicCount; ++i )
00121 pins += "";
00122 for ( int i=newXLogicCount-1; i>=0; --i )
00123 pins += "X"+QString::number(i);
00124
00125 initDIPSymbol( pins, 64 );
00126 initDIP(pins);
00127
00128 ECNode *node;
00129
00130 if (!m_input)
00131 {
00132 node = ecNodeWithID("X");
00133 m_input = createLogicIn(node);
00134 m_input->setCallback( this, (CallbackPtr)(&Demultiplexer::inStateChanged) );
00135 }
00136
00137 if ( newXLogicCount > oldXLogicCount )
00138 {
00139 m_xLogic.resize(newXLogicCount);
00140 for ( unsigned i = oldXLogicCount; i < newXLogicCount; ++i )
00141 {
00142 node = ecNodeWithID("X"+QString::number(i));
00143 m_xLogic.insert( i, createLogicOut(node,false) );
00144 }
00145
00146 m_aLogic.resize(newAddressSize);
00147 for ( unsigned i = oldAddressSize; i < newAddressSize; ++i )
00148 {
00149 node = ecNodeWithID("A"+QString::number(i));
00150 m_aLogic.insert( i, createLogicIn(node) );
00151 m_aLogic[i]->setCallback( this, (CallbackPtr)(&Demultiplexer::inStateChanged) );
00152 }
00153 }
00154 else
00155 {
00156 for ( unsigned i = newXLogicCount; i < oldXLogicCount; ++i )
00157 {
00158 QString id = "X"+QString::number(i);
00159 removeDisplayText(id);
00160 removeElement( m_xLogic[i], false );
00161 removeNode(id);
00162 }
00163 m_xLogic.resize(newXLogicCount);
00164
00165 for ( unsigned i = newAddressSize; i < oldAddressSize; ++i )
00166 {
00167 QString id = "A"+QString::number(i);
00168 removeDisplayText(id);
00169 removeElement( m_aLogic[i], false );
00170 removeNode(id);
00171 }
00172 m_aLogic.resize(newAddressSize);
00173 }
00174 }
00175