Code Search for Developers
 
 
  

simplememory.h from GreenSocs at Krugle


Show simplememory.h syntax highlighted

// LICENSETEXT
// 
//   Copyright (C) 2005,2006 :
//   GreenSocs Ltd
// 	(http://www.greensocs.com/),
// 
//   email: info@greensocs.com
// 
//     This program is free software; you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation; either version 2 of the License, or
//     (at your option) any later version.
// 
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with this program; if not, write to the Free Software
//     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
// 
// ENDLICENSETEXT

#include <systemc.h>
#include <list>
using std::list;

#include "gstlm/tlm.h"
#include "protocol/generic.h"
#include "userAPI/basicPorts.h"

using namespace tlm;


#include <iomanip>

#ifndef SHOW_SC_TIME
//#define SHOW_SC_TIME_(module,msg) cout << "time " << std::setw(3) << sc_simulation_time() << ": " \
//                                       << std::setw(6) << #module << ": " << msg
//#define SHOW_SC_TIME(module,msg)  SHOW_SC_TIME_(module,msg) << endl


#define SHOW_SC_TIME_(module,msg) // nothing
#define SHOW_SC_TIME(module,msg)  // nothing
#endif

#define CYCLES(x) 3*x, SC_NS

class simplememory : public sc_module, public tlm_b_if<GenericTransaction_P>
{
public:
  GenericTargetPort target_port;
  typedef GenericTargetPort::phaseHandle phaseHandle;
  
  unsigned char MEM[MEMSIZE];

  std::list<std::pair<GenericTargetPort::accessHandle,  GenericTargetPort::phaseHandle > > waiting;
  bool inWrite;
  

  void react();
  void simplememory::PVTProcess(  GenericTargetPort::accessHandle,  GenericTargetPort::phaseHandle);
  

  void b_transact(GenericTransaction_P);

  int IPmodel( GenericTargetPort::accessHandle t);
  
  

  //Constructor
  SC_CTOR( simplememory ) :
    target_port ("tport")
  {
    target_port.bind_b_if(*this);

    inWrite=false;
    
    SC_METHOD( react );
    sensitive << target_port.default_event();
    dont_initialize();
  }
};


void simplememory::b_transact( GenericTransaction_P t)
{
  (void) IPmodel(t); // we dont care about timing
}


void simplememory::react()
{
  GenericTargetPort::accessHandle tah=target_port.get_transactionHandle();
  GenericTargetPort::phaseHandle p=target_port.get_phase();
  PVTProcess(tah,p);
}

/* This method plays out the protocol. We can do this how we like, so long as we
 * stick to the generic protocol. We can hard wire in some number, ask the IP
 * block, be random, whatever. These numbers determin which "real" bus protocol
 * we are essencially modelling */
void simplememory::PVTProcess(  GenericTargetPort::accessHandle tah,  GenericTargetPort::phaseHandle p)
{
  
  switch (p.state) {

    case GenericPhase::RequestValid:
      if (inWrite) {
        //keep writes in order !!!
        SHOW_SC_TIME(simplememory, "PVT : can't process this write for now ");
        waiting.push_back(std::pair<GenericTargetPort::accessHandle,  GenericTargetPort::phaseHandle > (tah,p));

      } else {
        target_port.FinishBlocking(tah,p,CYCLES(2) );  // great, I'm ready!
      
        if (tah->get_mCmd() == Generic_MCMD_RD) {
          SHOW_SC_TIME(simplememory, "PVT : Accepted Read (in 10) sending master data in 50");
                                  // because we can, copy it all on beat one but
                                  // it takes some time, get the IP model to
                                  // tell us
          target_port.SendData(tah,p,CYCLES(IPmodel(tah)));
        } else {
          SHOW_SC_TIME(simplememory, "PVT : Accepted write (in 10) waiting for Data ");
          inWrite=true;
        }
      }
      break;
      
    case GenericPhase::DataAccepted:
      if (p.BurstNumber >= tah->get_mBurstLength()) {
        target_port.Response(tah,p,CYCLES(2));
      } // 
        // we could have said "else" here, if the protocol we are trying to
        // model sends the last item in the respose
      target_port.SendData(tah,p,CYCLES(1));
      break;
      
    case GenericPhase::DataValid:
      SHOW_SC_TIME(simplememory, "PVT : Got Data Ack ");
      if (p.BurstNumber >= tah->get_mBurstLength()) {
        SHOW_SC_TIME(simplememory, "PVT : Response send");
        // it takes some time after the data has all come in for it to be
        // consumed, get the IP model to tell us.
        target_port.Response(tah,p,CYCLES(IPmodel(tah)));
      } 
      target_port.AckData(tah,p,CYCLES(1));
      break;
      
    case GenericPhase::ResponseAccepted:
      SHOW_SC_TIME(simplememory, "PVT :  " << tah->get_mCmd());
      if (tah->get_mCmd() == Generic_MCMD_WR) {
        inWrite=false;
      }
      if (!inWrite) {
        if (!waiting.empty()) {
          SHOW_SC_TIME(simplememory, "PVT : RE-AWAKE pending write  ");
          std::pair<GenericTargetPort::accessHandle,  GenericTargetPort::phaseHandle > pair= waiting.front();
          waiting.pop_front();
          PVTProcess(pair.first,pair.second);
        }
      }
      
      // Always nice to know
      break;
      
    default:
      SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
      break;
  }
  
  
}
  


/* Here is what the user should end up writing
   a very simple model,
   to work in a 'co-war' like environment, where the model writer thinks about
   timing up front, then this model can return a timing number, or a strucutre
   of timing numbers if required */

int simplememory::IPmodel( GenericTargetPort::accessHandle t)
{
  SHOW_SC_TIME_(simplememory, "blocking: cmd " << t->get_mCmd());

  switch (t->get_mCmd()) {

  case Generic_MCMD_RD:
//    cout << " (read)\n";
    t->set_sData(MasterDataType( & MEM[t->get_mAddr()] ,t->get_mBurstLength() ));
    return 10;
    break;

  case Generic_MCMD_WR:
//    cout << " (write)\n";
    t->get_mData(MasterDataType( & MEM[t->get_mAddr()] ,t->get_mBurstLength() ));
    return 20;
    break;
  }

}






See more files for this project here

GreenSocs

To develop SystemC infrustructure, basic IP, patches and add on library code for eventual standerdization.\r\nThe GreenSocs project is made up of a number of contributions (sub projects). Please visit www.greensocs.com for more information.

Project homepage: http://sourceforge.net/projects/greensocs
Programming language(s): C,C++,Java,Perl,XML
License: other

  Makefile
  example_simple.cpp
  sillysort.h
  simplememory.h