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
#include <systemc.h>
#include "gstlm/gstlm/tlm.h"
#include "gstlm/protocol/generic.h"
#include "gstlm/userAPI/basicPorts.h"
#include <time.h>
using namespace tlm;
//#define SPEEDTEST
#include <iomanip>
#ifndef SPEEDTEST
#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
#else
#define SHOW_SC_TIME_(module,msg) // nothing
#define SHOW_SC_TIME(module,msg) // nothing
#endif
SC_MODULE (sillysort)
{
GenericMasterPort init_port;
typedef GenericMasterPort::accessHandle transactionHandle;
typedef GenericMasterPort::phaseHandle phaseHandle;
unsigned char mem[MEMSIZE];
void sillysort::sendPV(transactionHandle );
void sillysort::sendPVT(transactionHandle );
sc_event ft;
int pending;
void run();
void run2();
void react();
//Constructor
SC_CTOR( sillysort ) : init_port("iport") {
strcpy((char *)(mem),"As molt...");
pending=0;
SC_THREAD( run );
// SC_THREAD( run2 );
SC_METHOD( react );
sensitive << init_port.default_event();
dont_initialize();
}
};
// This master has two threads, one which uses the blocking transaction
// interface, and the other uses the non-blocking interface
void sillysort::run()
{
clock_t start=clock();
unsigned long long pvts=0;
unsigned long long pvs=0;
#ifdef SPEEDTEST
for (int i=0;i<1000;i++)
{
#endif
// set things up at the slave
strcpy((char *)(mem),"As molt...");
transactionHandle t1 = init_port.create_transaction();
t1->set_mCmd(Generic_MCMD_WR);
t1->set_mAddr(0x0);
t1->set_mData(MasterDataType(&mem[0],strlen((char *)mem)+1));
t1->set_mBurstLength(strlen((char *)mem)+1);
SHOW_SC_TIME(sillysort, "run: start writing \"" << (char *)mem << "\" to slave");
init_port.Transact(t1);
pvs++;
SHOW_SC_TIME(sillysort, "run: finished writing to slave");
int swaps;
do {
while (pending) {
wait(ft);
}
// wait(); // sync point
// get the data to our local cache, then run
transactionHandle t1 = init_port.create_transaction();
t1->set_mCmd(Generic_MCMD_RD);
t1->set_mAddr(0x0);
t1->set_mBurstLength(strlen((char *)mem)+1);
t1->set_mData(MasterDataType(&mem[0],strlen((char *)mem)+1));
SHOW_SC_TIME(sillysort, "run: PV read from slave");
init_port.Transact(t1);
pvs++;
SHOW_SC_TIME(sillysort, "run: PV got \"" << (char *)mem << "\" from slave");
swaps=0;
for (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;
transactionHandle t1 = init_port.create_transaction();
t1->set_mCmd(Generic_MCMD_WR);
t1->set_mAddr(i);
t1->set_mBurstLength(2);
t1->set_mData(MasterDataType(&mem[i],2));
SHOW_SC_TIME(sillysort, "run: start writing \"" << (char *)mem << "\" (bytes "<<i<<" to "<<i+1<<") to slave");
sendPVT(t1);
pvts++;
swaps++;
}
}
} while (swaps);
#ifdef SPEEDTEST
}
clock_t end=clock();
cout << "start:"<<start<<" end:"<<end<<" elapsed(s):"<<(float)(end-start)/CLOCKS_PER_SEC<<endl;
cout << "pvt transactions:"<<pvts<<" pv transactions:"<<pvs<<endl;
cout << "pvts/second:"<<(float)pvts/((float)(end-start)/CLOCKS_PER_SEC)<<endl;
#endif
}
void sillysort::sendPV(transactionHandle t)
{
init_port.Transact(t);
}
void sillysort::sendPVT(transactionHandle t)
{
pending++;
init_port.Request.block(t);
SHOW_SC_TIME(sillysort, "run: Slave Accepted.");
}
void sillysort::react()
{
GenericMasterPort::accessHandle tah=init_port.get_transactionHandle();
GenericMasterPort::phaseHandle phase=init_port.get_phase();
switch (phase.state) {
case GenericPhase::RequestValid:
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Listen mate, I'm the one giving the orders round here!" );
break;
case GenericPhase::RequestAccepted:
if (tah->get_mCmd() == Generic_MCMD_WR) {
SHOW_SC_TIME(sillysort, "run: Slave Accepted, sending data.");
init_port.SendData(tah,phase);
} else {
SHOW_SC_TIME(sillysort, "run: Slave Accepted, waiting to receive data.");
init_port.Repass(tah,phase);
}
break;
case GenericPhase::DataValid:
SHOW_SC_TIME(sillysort, "run2: (burst) got data \"" << (char *)mem << "\" from slave.");
init_port.AckData(tah,phase);
break;
case GenericPhase::DataAccepted:
// ok send the next burst
if (phase.BurstNumber < tah->get_mBurstLength()) {
SHOW_SC_TIME(sillysort, "run2: Sending data to slave." << phase.BurstNumber);
init_port.SendData(tah,phase);
} else if (phase.BurstNumber > tah->get_mBurstLength()) {
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Fell of the end of the burst?" );
}
break;
case GenericPhase::ResponseValid:
SHOW_SC_TIME(sillysort, "run2: (burst done) got data \"" << (char *)mem << "\" from slave.");
init_port.AckResponse(tah,phase);
pending--;
ft.notify();
break;
case GenericPhase::ResponseAccepted:
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Only master should accept responses" );
break;
default:
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Phase not recognized" );
}
}
See more files for this project here