1
/***************************************************************************
2
* Copyright (C) 2012 by santiago González *
3
* santigoro@gmail.com *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 3 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program; if not, see <http://www.gnu.org/licenses/>. *
18
***************************************************************************/
20
#include "e-shiftreg.h"
21
#include "simulator.h"
23
eShiftReg::eShiftReg( QString id, int latchClk, int serOut )
26
// input0: DS serial data input
27
// input1: MR master reset (active LOW)
37
if( latchClk > 0 ) createLatchClockPin();
38
if( serOut > 0 ) createSerOutPin();
42
eShiftReg::~eShiftReg()
44
delete m_latchClockPin;
48
void eShiftReg::initialize()
57
if( m_serOutPin ) // Set Serial Out Pin
59
m_serOutPin->setOut( false );
60
m_serOutPin->stampOutput();
62
eLogicDevice::initialize();
65
void eShiftReg::stamp()
67
eNode* enode = m_input[1]->getEpin()->getEnode(); // m_input[1] = Reset pin
68
if( enode ) enode->voltChangedCallback( this );
72
enode = m_latchClockPin->getEpin()->getEnode();
73
if( enode ) enode->voltChangedCallback( this );
75
eLogicDevice::stamp();
78
void eShiftReg::voltChanged()
80
eLogicDevice::updateOutEnabled();
82
bool clkRising = (eLogicDevice::getClockState() == Clock_Rising);// Get Clk to don't miss any clock changes
83
double volt = m_input[1]->getEpin()->getVolt();// Reset pin volt.
84
bool reset = eLogicDevice::getInputState( 1 );// m_input[1] = Reset
85
bool addEvent = false;
87
if( reset != m_reset )
92
m_shiftReg.reset(); // Reset shift register
93
if( m_serOutPin ) m_resSerOut = true;// Reset Serial Out Pin
96
m_changed = true; // Shift Register changed
98
else if( clkRising && !reset ) // Clock rising edge
101
for( int i=7; i>0; --i )m_shiftReg[i] = m_shiftReg[i-1];
103
if( m_serOutPin ) m_setSerOut = true; // Set Serial Out Pin
105
// Read data input pin & put in reg bit0
106
volt = m_input[0]->getEpin()->getVolt(); // Reset pin volt.
107
m_shiftReg[0] = (volt > m_inputHighV); // input0: data input
109
m_changed = true; // Shift Register changed
113
if( m_latchClockPin ) // find Latch Clock rising edge
115
bool lastLcClock = m_latchClock;
117
double volt = m_latchClockPin->getVolt(); // Clock pin volt.
119
if ( volt > m_inputHighV ) m_latchClock = true;
120
else if( volt < m_inputLowV ) m_latchClock = false;
122
if( m_latchClock && !lastLcClock && m_changed )
124
for( int i=0; i<8; ++i ) // Store Shift-reg in Output Latch
126
bool data = m_shiftReg[i];
132
}else if( m_changed )
137
if( addEvent ) Simulator::self()->addEvent( m_propDelay, this );
140
void eShiftReg::runEvent()
144
if( m_latchClockPin )
145
for( int i=0; i<8; ++i ) setOut( i, m_latch[i] );
147
for( int i=0; i<8; ++i ) setOut( i, m_shiftReg[i] );
151
m_serOutPin->setOut( false );
152
m_serOutPin->stampOutput();
157
m_serOutPin->setOut( m_shiftReg[7] );
158
m_serOutPin->stampOutput();
163
void eShiftReg::createLatchClockPin()
165
ePin* epin = new ePin( m_elmId+"latchClockPin", 0 );
166
m_latchClockPin = new eSource( m_elmId+"eSourceLatchClock", epin );
167
m_latchClockPin->setImp( m_inputImp );
170
void eShiftReg::createSerOutPin()
172
ePin* epin = new ePin( m_elmId+"serOutPin", 0 );
173
m_serOutPin = new eSource( m_elmId+"eSourceSerOutPin", epin );
174
m_serOutPin->setVoltHigh( m_outHighV );
175
m_serOutPin->setImp( m_outImp );
178
void eShiftReg::setResetInv( bool inv )
181
m_input[1]->setInverted( inv );