00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033
00034 #include "Sim/Pipeline/PipelineLatch.h"
00035 #include "Sim/Dumper/Dumper.h"
00036
00037 using namespace std;
00038 using namespace Onikiri;
00039
00040 bool PipelineLatch::FindAndEraseFromLatch( List* latch, OpIterator op )
00041 {
00042 iterator target =
00043 std::find( latch->begin(), latch->end(), op );
00044
00045 if( target != latch->end() ){
00046 latch->erase( target );
00047 return true;
00048 }
00049 else{
00050 return false;
00051 }
00052 }
00053
00054 void PipelineLatch::DumpStallBegin()
00055 {
00056 if( m_enableDumpStall && !m_latchOutIsStalled ){
00057 for( iterator i = m_latchOut.begin(); i != m_latchOut.end(); ++i ){
00058 g_dumper.DumpStallBegin( *i );
00059 }
00060 m_latchOutIsStalled = true;
00061 }
00062 }
00063
00064 void PipelineLatch::DumpStallEnd()
00065 {
00066 if( m_enableDumpStall && m_latchOutIsStalled ){
00067 for( iterator i = m_latchOut.begin(); i != m_latchOut.end(); ++i ){
00068 g_dumper.DumpStallEnd( *i );
00069 }
00070 m_latchOutIsStalled = false;
00071 }
00072 }
00073
00074
00075 void PipelineLatch::UpdateLatch()
00076 {
00077 typedef List::iterator iterator;
00078 for( iterator i = m_latchIn.begin(); i != m_latchIn.end(); ){
00079 m_latchOut.push_back( *i );
00080 i = m_latchIn.erase( i );
00081 }
00082 }
00083
00084
00085 PipelineLatch::PipelineLatch( const char* name ) :
00086 BaseType( name ),
00087 m_enableDumpStall( true ),
00088 m_latchOutIsStalled( false )
00089 {
00090 }
00091
00092 void PipelineLatch::Receive( OpIterator op )
00093 {
00094 ASSERT(
00095 !IsStalledThisCycle(),
00096 "The latch is written on a stalled cycle."
00097 );
00098 m_latchIn.push_back( op );
00099 }
00100
00101
00102
00103 void PipelineLatch::End()
00104 {
00105 ASSERT(
00106 !( !IsStalledThisCycle() && m_latchOut.size() > 0 ),
00107 "Outputs are not picked on an un-stalled cycle."
00108 );
00109
00110 ASSERT(
00111 !( m_latchIn.size() > 0 && m_latchOut.size() > 0 ),
00112 "Data on the pipeline latch is overwritten by a upper pipeline. "
00113 "The data has not processed for pipeline stall."
00114 );
00115
00116 UpdateLatch();
00117 BaseType::End();
00118 }
00119
00120 void PipelineLatch::Transition()
00121 {
00122 BaseType::Transition();
00123 if( IsStalledThisCycle() ){
00124
00125 DumpStallBegin();
00126 }
00127 }
00128
00129
00130 void PipelineLatch::BeginStall()
00131 {
00132 BaseType::BeginStall();
00133 DumpStallBegin();
00134 }
00135
00136 void PipelineLatch::EndStall()
00137 {
00138 BaseType::EndStall();
00139 DumpStallEnd();
00140 };
00141
00142 void PipelineLatch::Delete( OpIterator op )
00143 {
00144 if( FindAndEraseFromLatch( &m_latchIn, op ) ){
00145 return;
00146 }
00147 if( FindAndEraseFromLatch( &m_latchOut, op ) ){
00148 return;
00149 }
00150 }
00151
00152 void PipelineLatch::EnableDumpStall( bool enable )
00153 {
00154 m_enableDumpStall = enable;
00155 }