OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [hibi/] [3.0/] [tb/] [sad_tb/] [packet.hh] - Rev 145

Compare with Previous | Blame | View Log

/*
 * Author: Lasse Lehtonen
 *
 * Packet that's sent through hibi
 *
 * $Id: packet.hh 2010 2011-10-07 08:16:05Z ege $
 *
 */

#ifndef SAD_HIBI_PACKET_HH
#define SAD_HIBI_PACKET_HH


#include "constants.hh"

#include <sstream>
using namespace std;

#include <systemc>
using namespace sc_core;
using namespace sc_dt;



class Packet
{
public:

   //* Constructor
   Packet(unsigned int words, sc_bv<addr_width_c> source,
          sc_bv<addr_width_c> destination, HibiCommand command,
          unsigned int data1 = 0, unsigned int data2 = 0,
          unsigned int data3 = 0)
      : _words(words),
        _receivedWords(0),
        _source(source),
        _destination(destination),
        _command(command),
        _data(static_cast<sc_bv<data_width_c> >(0)),
        _id(Packet::packet_id),
        _respSize(0)
   {
      
      // Packet contents depend on the command: 
      // write, exclusive lock/release, read, config
      if(_command == DATA_WR ||
         _command == MSG_WR ||
         _command == DATA_WRNP ||
         _command == MSG_WRNP ||
         _command == EXCL_WR )
      {
         _data = static_cast<sc_bv<data_width_c> >(Packet::packet_id);   
      }
      else if(_command == EXCL_LOCK ||
              _command == EXCL_RELEASE )
      {
         _words = 1;
         _data = static_cast<sc_bv<data_width_c> >(Packet::packet_id);
      }
      else if(_command == EXCL_RD ||
              _command == DATA_RD ||
              _command == MSG_RD ||
              _command == DATA_RDL ||
              _command == MSG_RDL)
      {
         _data = _source;
         _id = _source;
         _respSize = data1;
      }
      else if(_command == CFG_WR)
      {
         // data1 = cfg page, data2 = cfg slot, data3 = the data
         // Sent addr must contain dst id, cfg page, and cfg param index
         unsigned int pagesize = 2;
         unsigned int pagewidth = 1;
         unsigned int timeslots = n_time_slots_c == 0 ? 1 : n_time_slots_c;
         while(pagesize < 9 + timeslots*3)
         {
            pagesize *= 2;
            pagewidth++;
         }
         int totpages = 2;
         unsigned int totpageswidth = 1;
         while(totpages < n_cfg_pages_c)
         {
            totpages *= 2;
            totpageswidth++;
         }
         _data = data3; 
         _destination.range(addr_width_c-1, addr_width_c-id_width_c) =
            destination.range(id_width_c-1, 0);
         _destination.range(totpageswidth+pagewidth-1, pagewidth) = data1;
         _destination.range(pagewidth-1, 0) = data2;
         
      }
      else if(_command == CFG_RD)
      {
         // data1 = cfg page, data2 = cfg index
         // Sent addr must contain dst id, cfg page, and cfg param index
         unsigned int pagesize = 2;
         unsigned int pagewidth = 1;
         unsigned int timeslots = n_time_slots_c == 0 ? 1 : n_time_slots_c;
         while(pagesize < 9 + timeslots*3)
         {
            pagesize *= 2;
            pagewidth++;
         }
         int totpages = 2;
         unsigned int totpageswidth = 1;
         while(totpages < n_cfg_pages_c)
         {
            totpages *= 2;
            totpageswidth++;
         }
         _data = _source;
         _destination.range(addr_width_c-1, addr_width_c-id_width_c) =
            destination.range(id_width_c-1, 0);
         _destination.range(totpageswidth+pagewidth-1, pagewidth) = data1;
         _destination.range(pagewidth-1, 0) = data2;
      }
      else
      {
         cout << "Unsupported command" << endl;
      }

      Packet::packet_id++;
   }

   //* Destructor
   ~Packet()
   {
      
   }

   //* Returns hibi command as a bit vector
   const sc_bv<comm_width_c>& getCommand() const
   { return commands_c[_command]; }

   //* Returns hibi command as enumeration
   const HibiCommand& getHibiCommand() const
   { return _command; }

   //* Returns destination address as a bit vector
   const sc_bv<addr_width_c>& getDstAddress() const
   { return _destination; }

   //* Returns source address as a bit vector
   const sc_bv<addr_width_c>& getSrcAddress() const
   { return _source; }

   //* Returns destination Id
   unsigned int getDstId() const
   { 
      return _destination.range(addr_width_c-1, addr_width_c-id_width_c).
         to_uint(); 
   }

   //* Returns the data to send
   const sc_bv<data_width_c>& getData() const
   { return _data; }

   //* Returns packet's ID
   const sc_uint<16>& getId() const
   { return _id; }
   
   //* Returns packet's size in words
   const unsigned int& getSize() const
   { return _words; }

   //* Returns the number of received words
   const unsigned int& getReceived() const
   { return _receivedWords; }

   //* Returns packet's size in words
   const unsigned int& getResponseSize() const
   { return _respSize; }

   //* Increments received word counter
   void receiveWord()
   {      
      if(++_receivedWords > _words)
      {
         ostringstream oss;
         oss << "Received too many words for packet with id: " << _id;
         SC_REPORT_FATAL(oss.str().c_str(),"");
      }
   }

   //* True if packet has received all words already
   bool complete()
   { return _receivedWords >= _words ? true : false; }

private:

   // This helps creating unique id for all packets
   static sc_uint<16> packet_id;
   
   // Other params for a packet. All commands do 
   // not need all these
   unsigned int        _words;         // num of data_words
   unsigned int        _receivedWords; // obsolete???
   sc_bv<addr_width_c> _source;        // return addr in read rq
   sc_bv<addr_width_c> _destination;   // where to send
   HibiCommand         _command;
   sc_bv<data_width_c> _data;          // remains same during burst
   sc_uint<16>         _id;            // uniques
   unsigned int        _respSize;      // #words reutrned in reads

};

// Initializing static class member 
sc_uint<16> Packet::packet_id = 100;

#endif

// Local Variables:
// mode: c++
// c-file-style: "ellemtel"
// c-basic-offset: 3
// End:

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.