SystemC: 月球转运站

创世神创造了世界,还觉得不够,又做了一颗月球。
过了两天觉得地球不够圆,决定把存在月球的 pi拿回来。
於是再打个响指!

这时候就轮到猴子来操心了。
有了第一个基本模组,就会有第二个,那他们之间要怎麽互相交换资料呢?

b_transport

对应到 blocked transport,只要在 initiator socket 呼叫这个函式就可以进行传输。
但是在能运作之前,要先把基础建设建好。

moon_access_socket->b_transport(trans, delay);

initiator_socket

转运站的第一站,传输发起端。
负责发起 read/write 指令。
既然能要月球的 pi,就能把地球的派送回去。

tlm_utils::simple_initiator_socket<HELLO> moon_access_socket;

target_socket

转运站的终点站,传输响应端。
不管是 read/write ,到了之後都会有专人服务!

tlm_utils::simple_target_socket<MOON> moon_access_socket;

register

安排响应站的专职服务人员。
只要把对应的函式接上去就可以罗!

moon_access_socket.register_b_transport(this, &MOON::b_transport);

bind

有了传输发起端和传输响应端之後,
还要记得告诉公车司机要到哪边些收指令和开往哪边。

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

<<:  第一章 之三

>>:  #17. Image Carousel(原生JS版)

那些被忽略但很好用的 Web API / ImageCapture

疫情时代,视讯串流当头,用视讯镜头来做个线上摄影吧! 自从疫情爆发後,各行各业也开始进行居家办公,...

STM32开发笔记03---Bit-Banding

架构图 带位操作原理 以往我们在使用暂存器时,都是在操作该暂存器32bits(4bytes)的储存地...

Day04,弄几只API

正文 弄完资料库後,花了一点时间的写了这几只API。 主要的routing分成 API/[Contr...

Multiple objects (下)

大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...

【领域展开 21 式】 Menu 修炼持续进行中

继续大战 Menu day2 再怎样都要把 Sample 的页面浏览完成,才能知道要选哪些页面吧!徒...