mohi@608
Member level 4
- Joined
- Apr 4, 2012
- Messages
- 69
- Helped
- 1
- Reputation
- 2
- Reaction score
- 1
- Trophy points
- 1,288
- Activity points
- 1,719
this is a simple example for a counter :
HTML:
// TLM counter
// compiler: Visual C++ 2008 Express Edition
//
#include <stdio.h>
#include <systemc.h>
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
using namespace tlm;
using namespace tlm_utils;
//
// C++ counter
//
unsigned int counter(unsigned int cnt)
{
return (cnt+1);
}
//
// SystemC counter module
//
class counter_module : public sc_module
{
SC_HAS_PROCESS(counter_module);
virtual void increment_request_transport(tlm_generic_payload& tx, sc_time& dt);
public:
simple_target_socket<counter_module> increment_socket;
private:
unsigned int cnt;
public:
counter_module(sc_module_name nm) : sc_module(nm),
increment_socket("increment_socket")
{
increment_socket.register_b_transport(this, &counter_module::increment_request_transport);
cnt=0;
}
const char* hdl_name() const { return "counter_module"; }
};
//
// Transport Handler
//
void counter_module::increment_request_transport(tlm_generic_payload& tx, sc_time& dt)
{
if(tx.get_command() == TLM_READ_COMMAND)
{
cnt = counter(cnt);
tx.set_data_length(4);
unsigned char rv[5];
rv[0] = cnt & 0xFF;
rv[1] = (cnt>>8) & 0xFF;
rv[2] = (cnt>>16) & 0xFF;
rv[3] = (cnt>>24) & 0xFF;
//cout << " cnt = " << (int)rv[0] << " " << (int)rv[1] << " " << (int)rv[2] << " " << (int)rv[3] << endl;
tx.set_data_ptr(rv);
tx.set_response_status(TLM_OK_RESPONSE);
}
else if(tx.get_command() == TLM_WRITE_COMMAND) // Reset actually
{
cnt = 0;
unsigned char rv[5];
rv[0] = cnt & 0xFF;
rv[1] = (cnt>>8) & 0xFF;
rv[2] = (cnt>>16) & 0xFF;
rv[3] = (cnt>>24) & 0xFF;
tx.set_data_length(4);
tx.set_data_ptr(rv);//conversion from int to char iccurs
tx.set_response_status(TLM_OK_RESPONSE);
}
else
tx.set_response_status(TLM_ADDRESS_ERROR_RESPONSE);
}
//
// Stimulus generator
//
class stimulus: public sc_module
{
SC_HAS_PROCESS(stimulus);
public:
simple_initiator_socket<counter_module> read_increment;
tlm_generic_payload tx;
void run();
void reset_counter();
unsigned int read_counter();
stimulus(sc_module_name nm) :
sc_module(nm),
read_increment("read_increment")
{
SC_THREAD(run);
}
const char* hdl_name() const { return "stimulus"; }
};
//
// Stimulus main process
//
void stimulus::run()
{
reset_counter();
wait(1, SC_NS);
for(int i=1; i<22; i++)
{
cout << "Counter = " << read_counter() << " at cycle " << i << endl;
wait(1, SC_NS);
}
reset_counter();
wait(1, SC_NS);
for(int i=23; i<100; i++)
{
cout << "Counter = " << read_counter() << " at cycle " << i << endl;
wait(1, SC_NS);
}
sc_stop();
}
//
// Reset counter request
//
void stimulus::reset_counter()
{
tx.set_address(0);
unsigned char value[5] = {0,0,0,0,0};
tx.set_data_ptr(value);
tx.set_data_length(1);
tx.set_command(TLM_WRITE_COMMAND);
sc_time to(SC_ZERO_TIME);
read_increment->b_transport(tx, to);
wait(1, SC_NS);
}
//
// Read counter (increment occurs before reading)
//
unsigned int stimulus::read_counter()
{
unsigned int data;
tx.set_address(0);
tx.set_data_length(1);
sc_time to(SC_ZERO_TIME);
tx.set_command(TLM_READ_COMMAND);
read_increment->b_transport(tx, to);
data = *reinterpret_cast<unsigned int*>(tx.get_data_ptr());
wait(20, SC_NS);
return data;
}
//
// Top-level module
//
int sc_main (int argc, char *argv[])
{
counter_module counter_module_dut("counter_module_dut");
stimulus stimulus_dut ("stimulus_dut");
stimulus_dut.read_increment(counter_module_dut.increment_socket);
sc_start();
return 0;
}