SystemC:Channel 📅 2026/7/15 3:59:16 在SystemC中通道是实现模块间通信的核心机制。它的设计哲学是将模块的功能实现与模块间的通信方式彻底分离使得系统在从高层抽象到底层RTL的逐步细化过程中只需要更换或修改通道而无需改动模块本身的功能代码极大地提升了模型的可重用性和灵活性。通道可以理解为一个“通信的容器”它封装了所有通信协议和同步逻辑的具体实现。1 分类1.1 原生通道 (Primitive Channel)定义最基础的通道不包含其他模块或进程也不能访问其他通道。用途提供最基本的通信和同步机制。常见类型sc_signal用于实现RTL风格的计算-提交compute-commit范式。它拥有“当前值”和“下一个值”任何写入操作都只修改下一个值并在仿真内核的更新阶段update phase统一提交为当前值。这保证了在同一个delta-cycle内所有进程对同一信号的读取结果是一致的避免了零延迟竞争。sc_fifo提供具有固定深度的先进先出FIFO通道用于数据缓冲。sc_mutex、sc_semaphore用于进程间的互斥和同步。所有原生通道都继承自基类 sc_prim_channel它们必须继承并实现一个或多个 SystemC 接口类。1.2 层次化通道 (Hierarchical Channel)定义它本身就是一个sc_module因此内部可以包含进程、端口、子模块以及其他通道。用途用于实现复杂的通信协议例如总线模型或TLMTransaction-Level Modeling事务级建模中的通用通道。一个典型的例子是AHB或AXI总线模型它内部包含了仲裁器、译码器等逻辑外部模块通过其提供的接口方法来发起总线事务。2 原生通道2.1 sc_mutexsc_mutex 是SystemC提供的一个用于互斥访问共享资源的原生通道。它确保了同一时刻只有一个进程能够进入临界区执行代码从而保护共享数据不被并发修改导致错误。sc_mutex 类实现了 sc_mutex_if 接口类。这个类包含了几种访问方法包括阻塞和非阻塞风格。阻塞方法只能在 SC_THREAD 进程中使用。互斥量维护一个锁定状态locked/unlocked进程通过两个操作来控制对共享资源的访问操作方法行为锁定Lock/获取lock()如果互斥量未锁定立即锁定并返回如果已被锁定进程被阻塞直到互斥量被释放尝试锁定Trylocktrylock()如果互斥量未锁定立即锁定并返回true如果已被锁定立即返回false不阻塞解锁Unlock/释放unlock()释放互斥量唤醒一个因等待该互斥量而被阻塞的进程classsc_mutex:publicsc_interface{public:// 构造函数sc_mutex();// 锁定互斥量阻塞式intlock();// 尝试锁定互斥量非阻塞inttrylock();// 解锁互斥量intunlock();// 获取当前锁定状态仅用于调试intget_lock()const;};说明lock() - 阻塞式获取如果互斥量未锁定立即锁定返回0成功如果互斥量已锁定进程被挂起直到拥有者调用unlock()释放它trylock() - 非阻塞式尝试如果互斥量未锁定立即锁定返回0成功如果互斥量已锁定不阻塞返回-1失败unlock() - 释放释放互斥量如果有进程因lock()阻塞唤醒最早被阻塞的一个只有当前拥有该互斥量的进程才能调用unlock()get_lock() - 查看锁定状态1锁定0未锁定主要用于调试sc_mutex 在电子设计中的一个应用是对共享总线进行仲裁。在没有仲裁器设计的情况下可以使用 sc_mutex 快速管理总线资源直到仲裁器设计完成。sc_mutex 也可以作为实现总线模型的类的一部分如下所示classbus:publicsc_module{sc_mutex bus_access;…voidwrite(intaddr,intdata){bus_access.lock();// perform writebus_access.unlock();}…};sc_mutex 的一个缺点是没有事件来通知 sc_mutex 何时被释放。这个缺点意味着你需要基于其他事件或基于时间的延迟反复使用 trylock() 来访问共享资源。2.2 sc_semaphoresc_semaphore 是SystemC提供的一个用于进程间同步与互斥的原生通道。它本质上是一个计数信号量Counting Semaphore用于控制多个进程对共享资源的访问。对于某些资源你可能想要对它们建模多个副本或所有者。为了管理这种类型的资源SystemC 提供了 sc_semaphore 类。sc_semaphore 类继承并实现了 sc_semaphore_if 接口。在创建 sc_semaphore 对象时需要指定可用的数量。从某种意义上说互斥锁只是计数为一的信号量。对 sc_semaphore 的访问包括等待可用资源然后在使用完资源后发布完成通知。信号量维护一个整数值计数值代表当前可用的资源数量。进程可以通过两种操作来使用它操作方法行为获取Wait/取走wait()如果计数值 0将计数值减1并立即返回如果计数值 0进程被阻塞直到计数值 0释放Post/归还post()将计数值加1并唤醒一个因等待该信号量而被阻塞的进程如果有的话与互斥量sc_mutex的区别特性sc_semaphoresc_mutex计数可以有多个计数值 1始终为1二值信号量所有者无所有者概念任何进程都可以post有所有者只有获取它的进程才能释放适用场景控制多个同类资源的访问保护共享资源的互斥访问典型用途连接池、缓冲池、生产者-消费者临界区保护sc_semaphore的接口classsc_semaphore:publicsc_interface{public:// 构造函数初始计数值默认为1explicitsc_semaphore(intinit_value1);// 获取信号量如果不可用则阻塞intwait();// 尝试获取信号量非阻塞成功返回0失败返回-1inttrywait();// 释放信号量intpost();// 获取当前计数值intget_value()const;};说明wait() - 阻塞式获取如果计数值 0计数值减1立即返回0成功如果计数值 0进程被挂起直到有post()操作唤醒它trywait() - 非阻塞式尝试获取如果计数值 0计数值减1返回0成功如果计数值 0不阻塞直接返回-1失败post() - 释放计数值加1如果有进程因wait()阻塞唤醒其中最早被阻塞的一个get_value() - 查看当前计数值仅用于调试2.3 sc_fifosc_fifo 是SystemC提供的一个有界先进先出FIFO数据缓冲通道用于在进程间传递数据。它内部维护一个固定大小的环形缓冲区遵循先进先出的原则是生产者-消费者模式的典型实现工具。操作方法行为写入Writewrite()如果FIFO未满将数据写入队列尾部并立即返回如果FIFO已满进程被阻塞直到有空间可用(被read()释放)读取Readread()如果FIFO非空从队列头部读取数据并立即返回如果FIFO为空进程被阻塞直到有数据写入非阻塞写入nb_write()如果FIFO未满写入数据并返回true如果已满立即返回false不阻塞非阻塞读取nb_read()如果FIFO非空读取数据并返回true如果为空立即返回false不阻塞窥探Peekpeek()读取队首数据但不移除如果FIFO为空则阻塞非阻塞窥探nb_peek()读取队首数据但不移除如果为空则立即返回false查询当前数据个数num_available()返回FIFO中有效数据的数量查询空闲空间num_free()返回FIFO中还能写入多少个数据templateclassTclasssc_fifo:publicsc_interface{public:// 构造函数指定FIFO深度默认16explicitsc_fifo(intsize_16);// 阻塞式操作 voidwrite(constT);voidread(T);Tread();// 非阻塞式操作 boolnb_write(constT);boolnb_read(T);// 窥探操作读取但不移除 voidpeek(T)const;Tpeek()const;boolnb_peek(T)const;// 状态查询 intnum_available()const;// 当前数据数量intnum_free()const;// 当前空闲空间boolempty()const;// 是否为空boolfull()const;// 是否为满// 重置 voidreset();// 清空FIFO};