Show sillysort.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
#define MEMSIZE 10000
#define VERBOSE
#include <systemc.h>
#include "gstlm/gstlm/tlm.h"
#include "gstlm/protocol/generic.h"
#include "gstlm/userAPI/basicPorts.h"
using namespace tlm;
/**
* A simple bus master that plays with the protocol.
*/
class sillysort : public sc_module
{
public:
GenericMasterPort init_port;
typedef GenericMasterPort::accessHandle transactionHandle;
typedef GenericMasterPort::phaseHandle phaseHandle;
unsigned char mem[MEMSIZE];
void sillysort::sendPV(transactionHandle );
sc_event ft;
MAddr tadd;
void run();
void react();
void test_wr();
void test_rd();
public:
//Constructor
SC_HAS_PROCESS(sillysort);
/**
* Sillysort constructor.
* @param name_ The module name.
* @param targetAddress The target memory address.
* @param data Initial memory content
*/
sillysort(sc_module_name name_, MAddr targetAddress, const char* data = NULL) :
sc_module(name_),init_port("iport") {
tadd=targetAddress;
// init memory
bzero((char*)mem, MEMSIZE);
if (data != NULL)
strcpy((char *)(mem),data);
cout<<"Hello my name is "<<name()<<" and my port's id is "<<init_port.get_master_port_number()<<endl<<flush;
// This master has two threads, one which uses the blocking transaction
// interface, and the other uses the non-blocking interface
SC_THREAD(run);
SC_METHOD(react);
sensitive(init_port.default_event());
dont_initialize();
}
};
void sillysort::run()
{
// send a blocking PV write ... /////////////////////////////////////////////
// set things up at the slave
transactionHandle t1 = init_port.create_transaction();
t1->set_mCmd(Generic_MCMD_WR);
t1->set_mAddr(tadd);
t1->set_mData(MasterDataType(&mem[0],strlen((char *)mem)+1));
t1->set_mBurstLength(strlen((char *)mem)+1);
GSTRACE("run: PV-writing \"" << (char *)mem << "\" to slave");
sendPV(t1);
GSTRACE("run: finished PV-writing to slave");
unsigned char swaps;
do {
// send a blocking PV read ////////////////////////////////////////////////
transactionHandle t1 = init_port.create_transaction();
t1->set_mCmd(Generic_MCMD_RD);
t1->set_mAddr(tadd);
t1->set_mBurstLength(strlen((char *)mem)+1);
t1->set_mData(MasterDataType(&mem[0],strlen((char *)mem)+1));
GSTRACE("run: PV-read from slave");
sendPV(t1);
GSTRACE("run: PV got \"" << (char *)mem << "\" from slave");
// now do a PVT write /////////////////////////////////////////////////////
swaps=0;
t1 = init_port.create_transaction();
t1->set_mCmd(Generic_MCMD_WR);
t1->set_mAddr(tadd);
t1->set_mBurstLength(strlen((char *)mem)+1);
t1->set_mData(MasterDataType(&mem[0],strlen((char *)mem)+1));
// we can do a blocking PVT call like this...
init_port.Request.block(t1);
GSTRACE("run: slave accepted request.");
for (unsigned int i=0; i<strlen((char *)mem)-1; i++) {
if (mem[i]>mem[i+1]) {
unsigned char t=mem[i];
mem[i]=mem[i+1];
mem[i+1]=t;
swaps++;
}
}
// and we can do a non-blocking PVT call like this...
init_port.SendData(t1, init_port.get_phase());
wait(ft); // wait until react() was informed that the slave accepted the data
GSTRACE("run: slave accepted data.");
} while (swaps);
}
void sillysort::sendPV(transactionHandle t)
{
init_port.Transact(t);
}
void sillysort::react()
{
GenericMasterPort::accessHandle tah=init_port.get_transactionHandle();
GenericMasterPort::phaseHandle phase=init_port.get_phase();
GSTRACE("react started");
switch (phase.state) {
case GenericPhase::RequestValid: // someone sends a request to us
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Listen mate, I'm the one giving the orders round here!" );
break;
case GenericPhase::RequestAccepted: // someone acknowledges a request from us
if (tah->get_mCmd() == Generic_MCMD_WR) {
GSTRACE("react: Slave Accepted, sending data.");
//init_port.SendData(tah,phase);
} else {
GSTRACE("react: Slave Accepted, waiting to receive data.");
// init_port.Repass(tah,phase);
}
break;
case GenericPhase::DataValid: // someone sends data to us
GSTRACE("react: got data \"" << (char *)mem << "\" from slave [address="<<tah->get_mAddr()<<"]");
init_port.AckData(tah, phase);
break;
case GenericPhase::DataAccepted: // someone has accepted our data
GSTRACE("react: got data-ACK from slave [address="<<tah->get_mAddr()<<"]");
ft.notify();
break;
case GenericPhase::ResponseValid: // someone sends a response to us
GSTRACE("react: got response \"" << (char *)mem << "\" from slave [address="<<tah->get_mAddr()<<"]");
init_port.AckResponse(tah,phase);
ft.notify();
break;
case GenericPhase::ResponseAccepted: // someone has accepted our response (uhoh, I thought we were a master?!)
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Only master should accept responses" );
break;
default: // only will come here if someone uses a user-specific phase we do not know
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
}
}
See more files for this project here