You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.8 KiB
176 lines
4.8 KiB
/***************************************************************************
|
|
* Copyright (C) 2004-2005 by David Saxton *
|
|
* david@bluehaze.org *
|
|
* *
|
|
* 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 "demultiplexer.h"
|
|
|
|
#include "logic.h"
|
|
#include "libraryitem.h"
|
|
|
|
#include <kiconloader.h>
|
|
#include <tdelocale.h>
|
|
|
|
#include <cmath>
|
|
|
|
Item* Demultiplexer::construct( ItemDocument *itemDocument, bool newItem, const char *id )
|
|
{
|
|
return new Demultiplexer( (ICNDocument*)itemDocument, newItem, id );
|
|
}
|
|
|
|
LibraryItem* Demultiplexer::libraryItem()
|
|
{
|
|
return new LibraryItem(
|
|
"ec/demultiplexer",
|
|
i18n("Demultiplexer"),
|
|
i18n("Integrated Circuits"),
|
|
"ic1.png",
|
|
LibraryItem::lit_component,
|
|
Demultiplexer::construct
|
|
);
|
|
}
|
|
|
|
Demultiplexer::Demultiplexer( ICNDocument *icnDocument, bool newItem, const char *id )
|
|
: Component( icnDocument, newItem, id ? id : "demultiplexer" )
|
|
{
|
|
m_name = i18n("Demultiplexer");
|
|
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.");
|
|
|
|
m_input = 0l;
|
|
|
|
createProperty( "addressSize", Variant::Type::Int );
|
|
property("addressSize")->setCaption( i18n("Address Size") );
|
|
property("addressSize")->setMinValue(1);
|
|
property("addressSize")->setMaxValue(8);
|
|
property("addressSize")->setValue(1);
|
|
|
|
// For backwards compatibility
|
|
createProperty( "numInput", Variant::Type::Int );
|
|
property("numInput")->setMinValue(-1);
|
|
property("numInput")->setValue(-1);
|
|
property("numInput")->setHidden(true);
|
|
}
|
|
|
|
Demultiplexer::~Demultiplexer()
|
|
{
|
|
}
|
|
|
|
|
|
void Demultiplexer::dataChanged()
|
|
{
|
|
if ( hasProperty("numInput") && dataInt("numInput") != -1 )
|
|
{
|
|
int addressSize = int( std::ceil( std::log( (double)dataInt("numInput") ) / std::log(2.0) ) );
|
|
property("numInput")->setValue(-1);
|
|
|
|
if ( addressSize < 1 )
|
|
addressSize = 1;
|
|
else if ( addressSize > 8 )
|
|
addressSize = 8;
|
|
|
|
// This function will get called again when we set the value of numInput
|
|
property("addressSize")->setValue(addressSize);
|
|
return;
|
|
}
|
|
|
|
if ( hasProperty("numInput") )
|
|
{
|
|
m_variantData["numInput"]->deleteLater();
|
|
m_variantData.remove("numInput");
|
|
}
|
|
|
|
initPins( unsigned(dataInt("addressSize")) );
|
|
}
|
|
|
|
|
|
void Demultiplexer::inStateChanged( bool /*state*/ )
|
|
{
|
|
unsigned long long pos = 0;
|
|
for ( unsigned i = 0; i < m_aLogic.size(); ++i )
|
|
{
|
|
if ( m_aLogic[i]->isHigh() )
|
|
pos += 1 << i;
|
|
}
|
|
for ( unsigned i = 0; i < m_xLogic.size(); ++i )
|
|
m_xLogic[i]->setHigh( (pos == i) && m_input->isHigh() );
|
|
}
|
|
|
|
|
|
void Demultiplexer::initPins( unsigned newAddressSize )
|
|
{
|
|
unsigned oldAddressSize = m_aLogic.size();
|
|
unsigned long long oldXLogicCount = m_xLogic.size();
|
|
unsigned long long newXLogicCount = 1 << newAddressSize;
|
|
|
|
if ( newXLogicCount == oldXLogicCount )
|
|
return;
|
|
|
|
TQStringList pins;
|
|
|
|
for ( unsigned i=0; i<newAddressSize; ++i )
|
|
pins += "A"+TQString::number(i);
|
|
for ( unsigned i=newAddressSize; i<(newXLogicCount+(newXLogicCount%2))/2; ++i )
|
|
pins += "";
|
|
pins += "X";
|
|
for ( unsigned i=(newXLogicCount+(newXLogicCount%2))/2+1; i<newXLogicCount; ++i )
|
|
pins += "";
|
|
for ( int i=newXLogicCount-1; i>=0; --i )
|
|
pins += "X"+TQString::number(i);
|
|
|
|
initDIPSymbol( pins, 64 );
|
|
initDIP(pins);
|
|
|
|
ECNode *node;
|
|
|
|
if (!m_input)
|
|
{
|
|
node = ecNodeWithID("X");
|
|
m_input = createLogicIn(node);
|
|
m_input->setCallback( this, (CallbackPtr)(&Demultiplexer::inStateChanged) );
|
|
}
|
|
|
|
if ( newXLogicCount > oldXLogicCount )
|
|
{
|
|
m_xLogic.resize(newXLogicCount);
|
|
for ( unsigned i = oldXLogicCount; i < newXLogicCount; ++i )
|
|
{
|
|
node = ecNodeWithID("X"+TQString::number(i));
|
|
m_xLogic.insert( i, createLogicOut(node,false) );
|
|
}
|
|
|
|
m_aLogic.resize(newAddressSize);
|
|
for ( unsigned i = oldAddressSize; i < newAddressSize; ++i )
|
|
{
|
|
node = ecNodeWithID("A"+TQString::number(i));
|
|
m_aLogic.insert( i, createLogicIn(node) );
|
|
m_aLogic[i]->setCallback( this, (CallbackPtr)(&Demultiplexer::inStateChanged) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( unsigned i = newXLogicCount; i < oldXLogicCount; ++i )
|
|
{
|
|
TQString id = "X"+TQString::number(i);
|
|
removeDisplayText(id);
|
|
removeElement( m_xLogic[i], false );
|
|
removeNode(id);
|
|
}
|
|
m_xLogic.resize(newXLogicCount);
|
|
|
|
for ( unsigned i = newAddressSize; i < oldAddressSize; ++i )
|
|
{
|
|
TQString id = "A"+TQString::number(i);
|
|
removeDisplayText(id);
|
|
removeElement( m_aLogic[i], false );
|
|
removeNode(id);
|
|
}
|
|
m_aLogic.resize(newAddressSize);
|
|
}
|
|
}
|
|
|