Show slave.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 "gstlm/gstlm/tlm.h"
#include "gstlm/protocol/generic.h"
#include "gstlm/userAPI/basicPorts.h"
using namespace tlm;
#include <iomanip>
#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
class slave : public sc_module, public tlm_b_if<GenericTransaction_P>
{
public:
GenericTargetPort target_port;
typedef GenericTargetPort::phaseHandle phaseHandle;
unsigned char MEM[100];
void react();
void b_transact(GenericTransaction_P);
//Constructor
SC_CTOR( slave ) :
target_port ("tport")
{
memcpy(MEM,"Response from slave", 20);
target_port.bind_b_if(*this);
SC_METHOD( react );
sensitive << target_port.default_event();
dont_initialize();
}
};
void slave::b_transact( GenericTransaction_P t)
{
SHOW_SC_TIME_(slave, "blocking: cmd " << t->get_mCmd());
switch (t->get_mCmd()) {
case Generic_MCMD_RD:
cout << " (read) take 10ns.\n";
t->set_sData(MasterDataType( & MEM[t->get_mAddr()] , 3 ));
wait(10, SC_NS);
break;
case Generic_MCMD_WR:
cout << " (write) take 15ns.\n";
wait(15, SC_NS);
/* dummy */
break;
}
}
void slave::react()
{
GenericTargetPort::accessHandle tah=target_port.get_transactionHandle();
GenericTargetPort::phaseHandle p=target_port.get_phase();
switch (p->state) {
case GenericPhase::RequestValid:
//AckRequest(t,p); // great, I'm ready!
if (tah->get_mCmd() == Generic_MCMD_RD) {
tah->set_sData( MasterDataType(&MEM[tah->get_mAddr()] ,1));
p->BurstNumber++;
if (p->BurstNumber < tah->get_mBurstLength())
target_port.SendData(tah,p,50,SC_NS);
else if (p->BurstNumber == tah->get_mBurstLength())
target_port.Response(tah,p,100,SC_NS);
else
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase burst number invalid" );
}
else if (tah->get_mCmd() == Generic_MCMD_WR) {
//dummy write
tah->get_mData();
p->BurstNumber++;
if (p->BurstNumber < tah->get_mBurstLength())
target_port.AckData(tah,p,50,SC_NS);
else if (p->BurstNumber == tah->get_mBurstLength())
target_port.AckResponse(tah,p,100,SC_NS);
else
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase burst number invalid" );
}
break;
case GenericPhase::DataAccepted:
if (tah->get_mCmd() == Generic_MCMD_RD) {
tah->set_sData( MasterDataType(&MEM[tah->get_mAddr()] ,1));
p->BurstNumber++;
if (p->BurstNumber < tah->get_mBurstLength())
target_port.SendData(tah,p,50,SC_NS);
else if (p->BurstNumber == tah->get_mBurstLength())
target_port.Response(tah,p,100,SC_NS);
else
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
}
else
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
break;
case GenericPhase::DataValid:
if (tah->get_mCmd() == Generic_MCMD_WR) {
//dummy write
tah->get_mData();
p->BurstNumber++;
if (p->BurstNumber < tah->get_mBurstLength())
target_port.AckData(tah,p,50,SC_NS);
else if (p->BurstNumber == tah->get_mBurstLength())
target_port.AckResponse(tah,p,100,SC_NS);
else
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
}
else
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
break;
case GenericPhase::ResponseAccepted:
// Always nice to know
break;
default:
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
break;
}
SHOW_SC_TIME(slave, "non_blocking: cmd " << tah->get_mCmd());
}
See more files for this project here