創世神創造了世界,還覺得不夠,又做了一顆月球。
過了兩天覺得地球不夠圓,決定把存在月球的 pi拿回來。
於是再打個響指!
這時候就輪到猴子來操心了。
有了第一個基本模組,就會有第二個,那他們之間要怎麼互相交換資料呢?
對應到 blocked transport,只要在 initiator socket 呼叫這個函式就可以進行傳輸。
但是在能運作之前,要先把基礎建設建好。
moon_access_socket->b_transport(trans, delay);
轉運站的第一站,傳輸發起端。
負責發起 read/write 指令。
既然能要月球的 pi,就能把地球的派送回去。
tlm_utils::simple_initiator_socket<HELLO> moon_access_socket;
轉運站的終點站,傳輸響應端。
不管是 read/write ,到了之後都會有專人服務!
tlm_utils::simple_target_socket<MOON> moon_access_socket;
安排響應站的專職服務人員。
只要把對應的函式接上去就可以囉!
moon_access_socket.register_b_transport(this, &MOON::b_transport);
有了傳輸發起端和傳輸響應端之後,
還要記得告訴公車司機要到哪邊些收指令和開往哪邊。
hello.moon_access_socket.bind(moon.moon_access_socket);
這次把 dataMemory 從 hello 搬到 moon囉!
//main.cpp
#include <vector>
#include "systemc.h"
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
class HELLO : public sc_module{
public:
HELLO(sc_module_name name) : sc_module(name){
SC_HAS_PROCESS(HELLO);
SC_THREAD(hello_thread);
}
tlm_utils::simple_initiator_socket<HELLO> moon_access_socket;
private:
sc_core::sc_time delay = sc_core::sc_time(1, sc_core::SC_NS);
uint32_t pc = 0;
void hello_thread(void)
{
for(int i = 0; i < 30; i++)
{
step();
wait(delay);
}
}
void step()
{
char data;
sc_dt::uint64 addr = pc;
int size = 1;
tlm::tlm_generic_payload trans;
trans.set_command(tlm::TLM_READ_COMMAND);
trans.set_data_ptr(reinterpret_cast<unsigned char*>(&data));
trans.set_data_length(size);
trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
trans.set_address(addr);
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
moon_access_socket->b_transport(trans, delay);
std::cout << "time " << sc_core::sc_time_stamp() << ":" << "hello received!!" << data << std::endl;
pc++;
}
};
class MOON : public sc_module{
public:
MOON(sc_module_name name) : sc_module(name){
moon_access_socket.register_b_transport(this, &MOON::b_transport);
}
tlm_utils::simple_target_socket<MOON> moon_access_socket;
private:
std::vector<char> dataMemory{'M', 'o', 'o', 'n', '!',
',', ' ', '3', '.', '1',
'4', '1', '5', '9', '2',
'6', '5', '3', '5', '8',
'9', '7', '9', '3', '2',
'3', '8', '4', '6', '2'};
void b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay){
delay = sc_core::SC_ZERO_TIME;
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address();
unsigned char *ptr = trans.get_data_ptr();
unsigned int len = trans.get_data_length();
if(adr < dataMemory.size())
{
*(char*)ptr = dataMemory[adr];
std::cout << "time " << sc_core::sc_time_stamp() << ":" << "moon response!!" << dataMemory[adr] << std::endl;
trans.set_response_status(tlm::TLM_OK_RESPONSE);
}
else
{
trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
std::cout << "error an address " << adr << "!!" << std::endl;
}
}
};
int sc_main(int argc,char** argv){
HELLO hello("hello");
MOON moon("moon");
hello.moon_access_socket.bind(moon.moon_access_socket);
sc_core::sc_start();
return 0;
}
這次將sc_start()
改成sc_start(sc_core::sc_time(11, sc_core::SC_NS))
,
跑了 11ns 當作示範。
$ make run
./hello
SystemC 2.3.3-Accellera --- Sep 17 2021 22:09:07
Copyright (c) 1996-2018 by all Contributors,
ALL RIGHTS RESERVED
time 0 s:moon response!!M
time 0 s:hello received!!M
time 1 ns:moon response!!o
time 1 ns:hello received!!o
time 2 ns:moon response!!o
time 2 ns:hello received!!o
time 3 ns:moon response!!n
time 3 ns:hello received!!n
time 4 ns:moon response!!!
time 4 ns:hello received!!!
time 5 ns:moon response!!,
time 5 ns:hello received!!,
time 6 ns:moon response!!
time 6 ns:hello received!!
time 7 ns:moon response!!3
time 7 ns:hello received!!3
time 8 ns:moon response!!.
time 8 ns:hello received!!.
time 9 ns:moon response!!1
time 9 ns:hello received!!1
time 10 ns:moon response!!4
time 10 ns:hello received!!4