⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syst_graph.cpp

📁 《无线通信系统仿真——c++使用模型》这本书的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
//  File = syst_graph.cpp
//

#include <stdlib.h>
#include <fstream>
#include "syst_graph.h"
#include "globals.h"
#include "sigplot.h"
//#include "sig_mgr.h"
//#include "cntl_mgr.h"
//#include "actsysgp.h"
//#include "cmsg.h"
//#include "reinit.h"

#ifdef _DEBUG
  extern ofstream *DebugFile;
#endif

extern SignalPlotter SigPlot;
//extern Reinitializer Reinit;
extern int PassNumber;
extern int EnclaveNumber;
extern int EnclaveOffset[10];
extern PracSimModel *ActiveModel;

//============================================
// constructor

SystemGraph::SystemGraph()
{
  Sdg_Vert_Descr = new std::vector<sdg_sig_desc_type*>;
  Sdg_Edge_Descr = new std::vector<sdg_edge_desc_type*>;
  Samp_Intvl = new std::vector<double>;
  Block_Size = new std::vector<int>;
  Syst_Lev_Models = new std::vector<PracSimModel*>;
  Sig_Dep_Graph = new DirectedGraph;
  Num_Regular_Sigs = 0;
  return;
}
//============================================
// destructor

SystemGraph::~SystemGraph()
{
}
//============================================

void SystemGraph::MergeCurrModelGraph( ModelGraph* curr_mod_graph )
{
   std::vector<int> merged_verts;
   int num_cmg_verts;
   int cmg_vert_num;
   int sdg_sig_num;
   obj_id_type sdg_sig_id, cmg_sig_id;
   SignalKinds_type cmg_vert_kind;
   bool node_not_found;
   double cmg_samp_intvl;
   int cmg_block_size;

   //------------------------------------------------------------
   // First section of code merges the vertices from the current
   // model graph (CMG) into the system dependency graph (SDG)
   //
   //  Check each signal from CSG to see if it's already in SDG

   num_cmg_verts = curr_mod_graph->GetNumVerts();

   //-----------------------------------------------------
   //  This loop checks each signal from CMG to see if it's 
   //  already in SDG

   for(  cmg_vert_num = 0; 
         cmg_vert_num < num_cmg_verts;
         cmg_vert_num++) {
      cmg_vert_kind = curr_mod_graph->GetVertexKind(cmg_vert_num);
      cmg_sig_id = curr_mod_graph->GetVertexId(cmg_vert_num);

      node_not_found = true;
      int num_sdg_verts = Sig_Dep_Graph->GetNumVerts();

      for( sdg_sig_num = 0; 
           (sdg_sig_num < num_sdg_verts) & node_not_found; 
           sdg_sig_num++) {

         sdg_sig_id = Sig_Dep_Graph->GetVertexId(sdg_sig_num);

         if( sdg_sig_id == cmg_sig_id ) {
            //---------------------------------------
            // this CMSG signal is already in SDG, so add its
            // index (in SDG) to list of merged signals

            merged_verts.push_back(sdg_sig_num);

            //----------------------------------------
            // If sampling rate is undefined for signal in SDG,
            // copy value from CMG signal (which may or may not be 
            // defined).  If sampling rate is defined for signal in SDG,
            // check to see if there is a different value defined in
            // CMG.  If there is, a fatal error condition exists.

            cmg_samp_intvl = curr_mod_graph->GetSampIntvl(cmg_vert_num);

            if(((Sdg_Vert_Descr->at(sdg_sig_num))->samp_intvl) == 0.0) {
               ((Sdg_Vert_Descr->at(sdg_sig_num))->samp_intvl) = cmg_samp_intvl;
            }
            else {
               if( (cmg_samp_intvl != 0.0) &&
                   (cmg_samp_intvl != 
                   ((Sdg_Vert_Descr->at(sdg_sig_num))->samp_intvl)) ) {

                  // -- ERROR --
                  *DebugFile << "Fatal error -- "
                             << "incomsistent sampling rate for signal "
                             << ((GenericSignal*)sdg_sig_id)->GetName() << endl;
                  exit(1);
               }
            }

            //---------------------------------------------------
            //  If block size is undefined for signal in SDG,
            //  copy value from CMG signal (which may or may not be
            //  defined.  If block size is defined for signal in SDG,
            //  check to see if there is a different value in CMG.
            //  If there is, a fatal error condition exists.

            cmg_block_size = curr_mod_graph->GetBlockSize(cmg_vert_num);
            if( ((Sdg_Vert_Descr->at(sdg_sig_num))->block_size) == 0 ) {
               ((Sdg_Vert_Descr->at(sdg_sig_num))->block_size) = cmg_block_size;
            }
            else {
               if( (cmg_block_size != 0 ) &&
                   (cmg_block_size != 
                   ((Sdg_Vert_Descr->at(sdg_sig_num))->block_size) )) {
               // -- ERROR --
               *DebugFile << "Fatal error -- "
                          << "inconsistent block size for signal "
                          << ((GenericSignal*)sdg_sig_id)->GetName() << endl;
               exit(1);
               }
            }
            // no need to check remaining SDG signals for this CMSG signal
            node_not_found = false;

         } // end of if( sdg_sig_id == cmg_sig_id )
      } // end of loop over sdg_sig_num

      //-----------------------------------------------------
      // If loop above completed without a match, we need
      // to add CMG vertex to SDG

      if( node_not_found ) {

         // maybe...we should use the sig_desc_type structure
         // in the CMG, then this would become a simple
         // structure to structure copy
         sdg_sig_desc_type* new_sig_desc = new sdg_sig_desc_type;
         new_sig_desc->signal_id = 
                     curr_mod_graph->GetSignalId(cmg_vert_num);
         new_sig_desc->block_size = 
                     curr_mod_graph->GetBlockSize(cmg_vert_num);
         new_sig_desc->samp_intvl = 
                     curr_mod_graph->GetSampIntvl(cmg_vert_num);
         new_sig_desc->kind_of_signal = 
                     curr_mod_graph->GetVertexKind(cmg_vert_num);

         if(new_sig_desc->kind_of_signal == SK_REGULAR_SIGNAL) Num_Regular_Sigs++;
         Sdg_Vert_Descr->push_back(new_sig_desc);
         sdg_sig_num = Sig_Dep_Graph->AddVertex(cmg_sig_id);
         merged_verts.push_back(sdg_sig_num);
      }
   } // end of loop over cmg_vert_num


   //----------------------------------------------------------
   //  at this point we are done adding vertices, and now begin
   //  to add edges between these vertices as specified in the CMG
   //
   //  new edges in the SDG can only connect to vertices that were
   //  just added or which matched vertices in the CMG

   int sdg_fm_idx, sdg_to_idx;
   int cmg_edge_num;
   int existing_edge;
   bool conn_is_feedback;
   obj_id_type cmg_edge_id;

   int num_merged_verts;
	   num_merged_verts = int(merged_verts.size());
   for(  int cmg_fm_idx = 0; 
         cmg_fm_idx < num_merged_verts; 
         cmg_fm_idx++)  {

      sdg_fm_idx = merged_verts.at(cmg_fm_idx);
      conn_is_feedback = curr_mod_graph->ConnIsFeedback(cmg_fm_idx);

      for( int cmg_to_idx = 0; 
           cmg_to_idx < num_merged_verts; 
           cmg_to_idx++) {

         sdg_to_idx = merged_verts.at(cmg_to_idx);
         cmg_edge_num = curr_mod_graph->GetEdgeNum(cmg_fm_idx, cmg_to_idx);

         if(cmg_edge_num >= 0) {
            //---------------------------------
            // CMG contains an edge from vertex 'cmg_fm_idx'
            // to vertex 'cmg_to_idx'
            // See if ASG-SDG already contains an edge between
            // the corresponding vertices.

            existing_edge = 
                  Sig_Dep_Graph->GetEdgeNum(sdg_fm_idx, sdg_to_idx);

            if(existing_edge >= 0 ) {
               double cmg_resamp = curr_mod_graph->GetResampRate(cmg_edge_num);
              // double sdg_resamp = Sig_Dep_Graph->GetResampRate(existing_edge);
               double sdg_resamp = (Sdg_Edge_Descr->at(existing_edge))->resamp_rate;;

               if(cmg_resamp != sdg_resamp)
               {
                  // parallel edge exists in ASG-SDG -- not sure how to
                  // handle -- see old listing for handling of edges
                  // due to subordinate models
                  *DebugFile << "parallel edge error" << endl;
                  *DebugFile << "existing_edge = " << existing_edge << endl;
                  *DebugFile << "cmg_fm_idx = " << cmg_fm_idx << endl;
                  *DebugFile << "cmg_to_idx = " << cmg_to_idx << endl;
                  exit(1);
               }
            }
            //-----------------------------------------
            // OK to add edge
      
            cmg_edge_id = curr_mod_graph->GetEdgeId(cmg_edge_num);
            Sig_Dep_Graph->AddEdge( cmg_edge_id, 
                                    sdg_fm_idx, 
                                    sdg_to_idx);

            sdg_edge_desc_type* new_edge_desc = new sdg_edge_desc_type;
            new_edge_desc->model_id = (PracSimModel*)cmg_edge_id;
            new_edge_desc->resamp_rate = 
                     curr_mod_graph->GetResampRate(cmg_edge_num);
            new_edge_desc->is_const_intvl = 
                     curr_mod_graph->GetIsConstIntvl(cmg_edge_num);
            new_edge_desc->delta_delay =
                     curr_mod_graph->GetDelay(cmg_edge_num);
            Sdg_Edge_Descr->push_back(new_edge_desc);

         } // end of if(cmg_edge_num)

      } // end of loop over cmg_to_idx

   } // end of loop over cmg_fm_idx
   return;
}
//========================================================
void SystemGraph::DumpSDGraph(void)
{
   int sig_num, sig_num2, edge_num;
   GenericSignal *sig_id;
   PracSimModel *model_id;
   int num_nodes = Sig_Dep_Graph->GetNumVerts();
   int num_edges = Sig_Dep_Graph->GetNumEdges();

   *DebugFile << "\nIn SystemGraph::DumpSDGraph" << endl;
   *DebugFile << "Num_SDG_Nodes = " << num_nodes << endl;
   *DebugFile << "Vertices:" << endl;

   *DebugFile << "index, Sdg_Vtx_Id, Signal Name, Samp Intvl, "
              << "Block Size" << endl;

   for( sig_num = 0; sig_num < num_nodes; sig_num++) {
      sig_id = (Sdg_Vert_Descr->at(sig_num))->signal_id;
      *DebugFile << sig_num << ")  "
                 << sig_id << "  "
                 << sig_id->GetName() << "  "
                 << (Sdg_Vert_Descr->at(sig_num))->samp_intvl << "  "
                 << (Sdg_Vert_Descr->at(sig_num))->block_size << endl;
   }

   *DebugFile << "\nEdges:" << endl;
   *DebugFile << "index, SDG edge model, Model Name, Resamp Rate, "
              << "Delay" << endl;
   for( edge_num = 0; edge_num < num_edges; edge_num ++) {
      model_id = (Sdg_Edge_Descr->at(edge_num))->model_id;
      *DebugFile << edge_num << ")  "
                 << model_id << "  "
                 << model_id->GetModelName() << ":" 
                 << model_id->GetInstanceName() << "  "
                 << (Sdg_Edge_Descr->at(edge_num))->resamp_rate << "  "
                 << (Sdg_Edge_Descr->at(edge_num))->delta_delay << endl;
   }

   *DebugFile << "\nAdjacency Matrix:" << endl;
   for( sig_num = 0; sig_num < num_nodes; sig_num++) {
      for( sig_num2 = 0; sig_num2 < num_nodes; sig_num2++) {
         edge_num = Sig_Dep_Graph->GetEdgeNum(sig_num, sig_num2);

         if( edge_num >= 0 ) {
        *DebugFile << "Edge " << edge_num
                   << " connects from vertex " << sig_num
                   << " to vertex " << sig_num2 << endl;
         }
      }
   }
}
//===================================================================

void SystemGraph::ResolveSignalParms(void)
{
  int sig_num, unsorted_sig_num, base_sig_num, edge_num;
  int num_base_sigs_used = 0;
  bool base_sig_not_found;
  double samp_rate;
  int block_size;
  GenericSignal *sig_id;
  bool is_forward;

  int num_nodes = Sig_Dep_Graph->GetNumVerts();
  bool *used_as_base = new bool[num_nodes];

  for( sig_num = 0; sig_num < num_nodes; sig_num++)
    {
    used_as_base[sig_num] = false;
    }
  this->TopoSortSDG();

  while(num_base_sigs_used < Num_Regular_Sigs)
    {
    //---------------------------------------------------------------
    // find base signal

    base_sig_not_found = true;
    for(unsorted_sig_num = 0; unsorted_sig_num < num_nodes; unsorted_sig_num++)
      {
      sig_num = Sorted_Sig_Nodes[unsorted_sig_num];

      sig_id = (Sdg_Vert_Descr->at(sig_num))->signal_id;
      samp_rate = (Sdg_Vert_Descr->at(sig_num))->samp_intvl;
      if(samp_rate <= 0.0)
        {
        #ifdef _DEBUG
        *DebugFile << sig_id->GetName()
                  << " rejected because samp rate <= 0 ( "
                  << samp_rate << " )" << endl;
        #endif
        continue;
        }

      block_size = (Sdg_Vert_Descr->at(sig_num))->block_size;
      if(block_size <= 0.0)
        {
        #ifdef _DEBUG
        *DebugFile << sig_id->GetName()
                  << " rejected because block size <= 0 ( "
                  << block_size << " )" << endl;
        #endif
        continue;
        }

      if(used_as_base[sig_num])
        {
        #ifdef _DEBUG
        *DebugFile << sig_id->GetName()
                  << " rejected because already used as base"
                  << endl;
        #endif
        continue;
        }
      //
      // if execution gets to here, we have found a useable base signal
      //
      base_sig_num = sig_num;
      used_as_base[base_sig_num] = true;
      num_base_sigs_used++;
      base_sig_not_found = false;
      break;
      } // end of loop over unsorted_sig_num

    if(base_sig_not_found)
      {
      (*DebugFile) << "Unable to find suitable base signal" << endl;
      #ifdef _DEBUG
        *DebugFile << "The following signals have not"
                  << " been used as base signals:" << endl;
        for(unsorted_sig_num = 0; unsorted_sig_num < num_nodes; unsorted_sig_num++)
          {
          sig_num = Sorted_Sig_Nodes[unsorted_sig_num];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -