2

我在 Visual Studio 2008(64 位)中通过在开头设置断点调试了以下代码do_test1do_test2令我惊讶的是,代码在函数的同一线程中sc_main运行。

我没有在Linux环境中调试。但是,通过搜索源代码,我发现它"pthread.h"被包含在一些 SystemC 库源代码中。

问题1:在Windows中,会SC_THREAD创建一个真正的线程吗?或者它总是在同一个线程中sc_main?如果是这种情况,我可以说SC_THREAD是创建一个“假”线程吗?

问题2:在Linux中,既然"pthread.h"被包含,会不会SC_THREAD创建一个新线程?

问题 3:在 Windows 和 Linux 中,我是否遗漏了一些设置来启用真正的线程?

=========================================

以下代码来自该网站:

http://www.asic-world.com/systemc/systemc_time4.html#Example_:_sc_event

    #include <systemc.h>

    SC_MODULE (events) {
      sc_in<bool> clock;

      sc_event  e1;
      sc_event  e2;

      void do_test1() {

        while (true) {
          // Wait for posedge of clock
          wait();
          cout << "@" << sc_time_stamp() <<" Starting test"<<endl;
          // Wait for posedge of clock
          wait();
          cout << "@" << sc_time_stamp() <<" Triggering e1"<<endl;
          // Trigger event e1
          e1.notify(5,SC_NS);
          // Wait for posedge of clock
          wait();
          // Wait for event e2
          wait(e2);
          cout << "@" << sc_time_stamp() <<" Got Trigger e2"<<endl;
          // Wait for posedge of clock
          wait();
          cout<<"Terminating Simulation"<<endl;
          sc_stop(); // sc_stop triggers end of simulation
        }
      }

      void do_test2() {
        while (true) {
          // Wait for event e2
          wait(e1);
          cout << "@" << sc_time_stamp() <<" Got Trigger e1"<<endl;
          // Wait for 3 posedge of clock
          wait(3);
          cout << "@" << sc_time_stamp() <<" Triggering e2"<<endl;
          // Trigger event e2
          e2.notify();
        }
      }

      SC_CTOR(events) {
        SC_CTHREAD(do_test1,clock.pos());
        SC_CTHREAD(do_test2,clock.pos());
      }
    }; 

    int sc_main (int argc, char* argv[]) {
      sc_clock clock ("my_clock",1,0.5);
      events  object("events");
        object.clock (clock); 
      sc_start();  // Run the simulation till sc_stop is encountered
      return 0;// Terminate simulation
    }
4

2 回答 2

14

简短的回答:

线程库,无论是用户级线程(上下文切换更轻、更快)还是内核级线程,都不用于提供真正的并发性。相反,它们用于实现SC_THREAD进程的协程语义。

长答案:

SystemC 有 3 种类型的进程(即并发单元),其中最重要的只有两种:

  1. SC_METHODs 是方法(类似于alwaysVerilog 中的语句),当被事件触发时,它们会在零时间内完整执行。它们不能用于wait等待时间间隔或事件发生。
  2. SC_THREADs 是只执行一次的方法(如initialVerilog 中的语句),但它们可以wait用来等待特定事件或时间段,并且可以使用循环来模拟always 语句(因此SC_THREAD可以消耗时间)。

从实现的角度来看,s 没有问题,SC_METHOD因为它们就像在 SystemC 内核中注册的方法一样,在触发时会被调用。然而,对于SC_THREADs,虽然它们被定义为成员函数,但它们的行为却不像普通的例程。它们被称为协程

允许多个入口点在某些位置暂停和恢复执行的子例程。

SystemC 内核没有为系统级或 RTL 模型提供真正的并发性。它仅通过流程构造提供模拟并发。因此,在编写高级模型时,您不必使用同步原语(例如,锁或信号量)来保护不同进程共享的数据,因为在任何时候,只有一个进程正在执行并且它不能被SystemC 内核(只有在当前执行的进程放弃控制权时才会切换到准备执行的下一个进程。仍然可以使用同步,但 SystemC 提倡使用通道中的消息传递用于进程之间的通信。这是一个优势,因为它降低了复杂性。但是,也有缺点。SystemC 模型按顺序执行(非并行化),因此它们不利用多核架构来加速仿真。这是一个需要仿真性能的热门研究领域。

无论如何,SystemC 内核因此实现了协作调度,其中每个都SC_THREAD自愿放弃控制(通过使用wait)以允许其他SC_THREAD进程执行。如果您在一个永不放弃控制的过程中有一个无限循环SC_THREAD,那么整个模拟将卡在那里并且模拟时间不会提前。s也是如此SC_METHOD,它必须返回以便 SystemC 内核重新获得控制权。

为了使用协程实现这种协作调度策略,使用线程库(例如,pthreads 或 SystemC 源代码中包含的 QuickThread)来使SC_THREAD's(作为线程启动)能够挂起自己并使内核能够恢复他们以后。阅读本文以了解更多信息。

于 2013-09-07T06:35:47.723 回答
3

没有&是的。这取决于您的 SystemC 库配置。

您可以将 SystemC 配置为使用 pthread 或 Windows 本机线程。因此,当您编译并运行您的 SystemC 设计时,它会创建真正的线程。但是,默认情况下,在 UNIX 环境中,它不会默认使用 pthread,因为系统调用很昂贵。无论您如何将 SystemC 配置为使用 pthread 或 Window 本机线程,SystemC 都只能一一运行线程。因为它一次只运行一个线程,所以使用它的用户级线程比其他线程更快,因为不涉及系统调用。

为什么 SystemC 不会一次运行所有调度线程?这是另一个问题。

于 2013-09-06T03:15:13.593 回答