1 #ifndef __NOXIMBUFFER_H__ 2 #define __NOXIMBUFFER_H__ 3 4 #include <cassert> 5 #include <queue> 6 #include "DataStructs.h" 7 using namespace std;
class Buffer { ................. }; #endif
public:ide
1 Buffer(); //构造函数 2 3 virtual ~ Buffer() {//虚析构函数解决因delete基类指针致使的资源泄漏 4 }
1 Buffer::Buffer() 2 { 3 SetMaxBufferSize(GlobalParams::buffer_depth); 4 max_occupancy = 0; 5 hold_time = 0.0; 6 last_event = 0.0; 7 hold_time_sum = 0.0; 8 previous_occupancy = 0; 9 mean_occupancy = 0.0; 10 true_buffer = true; 11 full_cycles_counter = 0; 12 last_front_flit_seq = NOT_VALID; 13 deadlock_detected = false; 14 }
1 void SetMaxBufferSize(const unsigned int bms); // Set buffer max size (in flits) 2 3 unsigned int GetMaxBufferSize() const; // Get max buffer size 4 5 unsigned int getCurrentFreeSlots() const; // free buffer slots 6 7 bool IsFull() const; // Returns true if buffer is full 8 9 bool IsEmpty() const; // Returns true if buffer is empty 10 11 virtual void Drop(const Flit & flit) const; // Called by Push() when buffer is full 12 13 virtual void Empty() const; // Called by Pop() when buffer is empty 14 15 void Push(const Flit & flit); // Push a flit. Calls Drop method if buffer is full 16 17 Flit Pop(); // Pop a flit 18 19 Flit Front() const; // Return a copy of the first flit in the buffer 20 21 unsigned int Size() const; 22 23 void ShowStats(std::ostream & out); 24 25 void Disable(); 26 27 void Print(); 28 29 bool deadlockFree(); 30 void deadlockCheck(); 31 32 void setLabel(string); 33 string getLabel() const;
1 void Buffer::SetMaxBufferSize(const unsigned int bms) 2 { 3 assert(bms > 0); 4 5 max_buffer_size = bms; 6 }
1 unsigned int Buffer::GetMaxBufferSize() const 2 { 3 return max_buffer_size; 4 }
1 unsigned int Buffer::getCurrentFreeSlots() const 2 { 3 return (GetMaxBufferSize() - Size()); 4 }
1 unsigned int Buffer::Size() const 2 { 3 return buffer.size(); 4 }
1 bool Buffer::IsFull() const 2 { 3 return buffer.size() == max_buffer_size; 4 } 5 6 bool Buffer::IsEmpty() const 7 { 8 return buffer.size() == 0; 9 } 10 11 void Buffer::Drop(const Flit & flit) const 12 { 13 assert(false); 14 } 15 16 void Buffer::Empty() const 17 { 18 assert(false); 19 }
1 void Buffer::Push(const Flit & flit) 2 { 3 SaveOccupancyAndTime(); 4 5 if (IsFull()) 6 Drop(flit); 7 else 8 buffer.push(flit); 9 10 UpdateMeanOccupancy(); 11 12 if (max_occupancy < buffer.size()) 13 max_occupancy = buffer.size(); 14 }
1 Flit Buffer::Pop() 2 { 3 Flit f; 4 5 SaveOccupancyAndTime(); 6 7 if (IsEmpty()) 8 Empty(); 9 else { 10 f = buffer.front(); 11 buffer.pop(); 12 } 13 14 UpdateMeanOccupancy(); 15 16 return f; 17 }
1 Flit Buffer::Front() const 2 { 3 Flit f; 4 5 if (IsEmpty()) 6 Empty(); 7 else 8 f = buffer.front(); 9 10 return f; 11 }
1 void Buffer::SaveOccupancyAndTime() 2 { 3 previous_occupancy = buffer.size(); 4 hold_time = (sc_time_stamp().to_double() / GlobalParams::clock_period_ps) - last_event; 5 last_event = sc_time_stamp().to_double() / GlobalParams::clock_period_ps; 6 }
1 void Buffer::UpdateMeanOccupancy() 2 { 3 double current_time = sc_time_stamp().to_double() / GlobalParams::clock_period_ps; 4 if (current_time - GlobalParams::reset_time < GlobalParams::stats_warm_up_time) 5 return; 6 7 mean_occupancy = mean_occupancy * (hold_time_sum/(hold_time_sum+hold_time)) + (1.0/(hold_time_sum+hold_time)) * hold_time * buffer.size(); 8 hold_time_sum += hold_time; 9 }
1 void Buffer::ShowStats(std::ostream & out) 2 { 3 if (true_buffer) 4 out << "\t" << mean_occupancy << "\t" << max_occupancy; 5 else 6 out << "\t\t"; 7 }
1 void Buffer::setLabel(string l) 2 { 3 //cout << "\n BUFFER LABEL: " << l << endl; 4 label = l; 5 } 6 7 string Buffer::getLabel() const 8 { 9 return label; 10 } 11 12 void Buffer::Print() 13 { 14 queue<Flit> m = buffer; 15 16 string bstr = ""; 17 18 char t[] = "HBT"; 19 20 cout << label << " | "; 21 while (!(m.empty())) 22 { 23 Flit f = m.front(); 24 m.pop(); 25 cout << bstr << t[f.flit_type] << f.sequence_no << "(" << f.dst_id << ") | "; 26 } 27 cout << endl; 28 }
1 void Buffer::deadlockCheck() 2 { 3 // TOOD: add as parameter 4 int check_threshold = 50000; 5 6 if (IsEmpty()) return; 7 8 Flit f = buffer.front(); 9 int seq = f.sequence_no; 10 11 if (last_front_flit_seq == seq) 12 { 13 full_cycles_counter++; 14 } 15 else 16 { 17 if (deadlock_detected) 18 { 19 cout << " WRONG DEADLOCK detection, please increase the check_threshold " << endl; 20 assert(false); 21 } 22 last_front_flit_seq = seq; 23 full_cycles_counter=0; 24 } 25 26 if (full_cycles_counter>check_threshold && !deadlock_detected) 27 { 28 double current_time = sc_time_stamp().to_double() / GlobalParams::clock_period_ps; 29 cout << "WARNING: DEADLOCK DETECTED at cycle " << current_time << " in buffer: " << getLabel() << endl; 30 deadlock_detected = true; 31 } 32 }
1 bool Buffer::deadlockFree() 2 { 3 if (IsEmpty()) return true; 4 5 Flit f = buffer.front(); 6 7 int seq = f.sequence_no; 8 9 if (last_front_flit_seq==seq) 10 { 11 full_cycles_counter++; 12 } 13 else 14 { 15 last_front_flit_seq = seq; 16 full_cycles_counter=0; 17 } 18 if (full_cycles_counter>50000) 19 { 20 return false; 21 } 22 return true; 23 }
1 void Buffer::Disable() 2 { 3 true_buffer = false; 4 }
private:函数
1 bool true_buffer; 2 bool deadlock_detected; 3 4 int full_cycles_counter; 5 int last_front_flit_seq; 6 7 string label; 8 9 unsigned int max_buffer_size; 10 11 queue < Flit > buffer; 12 13 unsigned int max_occupancy; 14 double hold_time, last_event, hold_time_sum; 15 double mean_occupancy; 16 int previous_occupancy; 17 18 void SaveOccupancyAndTime(); 19 void UpdateMeanOccupancy();