当前位置: 首页 > news >正文

深入浅出SystemC TLM — 以PCIe为例介绍虚拟原型的作用

0. “更早的”芯片验证的意义

        在传统的芯片设计流程中,软件开发人员需要等待物理芯片(硅片)从工厂流片回来,才能开始驱动、操作系统和应用软件的开发。这导致了数月的项目延迟,并形成了“硬件等软件,软件等硬件”的互锁瓶颈。

        虚拟原型 技术正是为了打破这一瓶颈而生。它通过在芯片生产之前,就用软件模型构建出整个硬件系统的“虚拟样机”,使得软件开发和硬件设计可以并行进行。而 SystemC TLM 就是构建高效、快速虚拟原型的关键技术。

1. SystemC TLM 的设计目的与核心理念

1.1 设计目的

        SystemC TLM的核心目的只有一个:为了实现硬件模型的早期软件开发和高性能仿真。

        它不是为了验证硬件的时序和电路细节(那是RTL仿真的工作),而是为了在硬件尚未就绪时,提供一个功能正确、运行速度极快的软件仿真环境,用于:固件和驱动开发、操作系统移植与启动、架构探索与性能分析,以及系统级验证

1.2 核心理念:事务级建模

TLM 的核心思想是 “通信与计算分离”

1.2.1. RTL级建模的内涵

        关心通信的每一个细节,比如时钟周期、信号线、握手协议、每一个比特的传输。仿真速度极慢。

1.2.2. 事务级建模的内涵

        不关心通信的具体实现过程,只关心组件之间交换的数据内容(即“事务”)

        例如,一个CPU要往内存地址0x1000写入数据0x1234RTL 会模拟地址总线的建立、写使能信号拉高、数据总线赋值、等待应答信号等数十个时钟周期。TLM 则只需一次函数调用:initiator_socket->write(0x1000, 0x1234)。这个函数调用就代表了一次完整的“写入事务”。

这种抽象极大地提升了仿真速度,通常比RTL仿真快100到10000倍

2. TLM的原理与核心结构

2.1 SystemC基础

       SystemC 是一个 C++ 库,它提供了描述硬件并发性、时钟和模块的类。一个 SystemC 模型通常由多个模块(sc_module) 组成,模块之间通过端口(sc_port) 和接口(sc_interface) 进行通信。

2.2 TLM-2.0的核心结构

       TLM-2.0是实际上的工业标准,它定义了一套标准的接口和通用载荷,使得不同IP供应商提供的模型可以无缝地集成在一起。主要包括:

1. 套接字

       发起者套接字(initiator_socket)是由发起事务的模块使用,主动调用传输函数。

       目标套接字(target_socket)则是响应事务的模块使用,绑定一个回调函数来处理收到的事务。

2. 通用载荷

       tlm_generic_payload 是 TLM-2.0 的灵魂,它是一个标准化的数据结构,用于封装一次内存映射总线事务的所有信息。其主要成员包括:

              command: 读(TLM_READ_COMMAND)或写(TLM_WRITE_COMMAND)。

              address: 交易的起始地址。

              data_ptr: 指向数据缓冲区的指针。

              data_length: 数据的长度。

              response_status: 返回的响应状态(如TLM_OK_RESPONSETLM_ADDRESS_ERROR_RESPONSE)。

3. 传输接口

       核心接口是 tlm_fw_transport_if 和 tlm_bw_transport_if

       前向路径是发起者调用 b_transport(gp, delay) 将载荷发送给目标。

       后向路径是用于时序标注的逆向调用,在基础模式下可暂不深入。

4. 松散定时与近似定时模型

       LT模式

              最常用、最快的模式。它不模拟总线上的精确时序,只保证逻辑正确性。b_transport调用是阻塞的,一次调用完成整个交易。这是软件开发的理想选择。

       AT模式

              在LT的基础上增加了时序标注,可以模拟更精确的总线竞争、流水线等行为,用于架构性能分析,速度比LT慢。

3. 构建一个简化的PCIe TLM模型

       让我们用一个极其简化 的PCIe Root Complex(RC)与 Endpoint(EP)通信的例子,来串联上述概念。

系统架构

   CPU(Initiator),发起读写请求。

   PCIe Root Complex(Interconnect),负责地址路由,将CPU的请求转发到正确的Endpoint。

   PCIe Endpoint(Target),例如一个NVMe SSD控制器,它内部有一个存储数据的缓冲区。

3.1 定义PCIe Endpoint(目标模块)

#include <systemc>
#include <tlm.h>
#include <tlm_utils/simple_target_socket.h>class pcie_endpoint : public sc_core::sc_module {
public:// 1. 声明一个目标套接字tlm_utils::simple_target_socket<pcie_endpoint> target_socket;pcie_endpoint(sc_core::sc_module_name name) : sc_module(name) {// 2. 将套接字的传输回调函数绑定到本类的b_transport方法target_socket.register_b_transport(this, &pcie_endpoint::b_transport);// 初始化一个简单的内存空间,模拟SSD的缓冲区memset(memory, 0, sizeof(memory));}private:// 3. 实现b_transport方法,处理来自发起者的交易virtual void b_transport(tlm::tlm_generic_payload& gp, sc_core::sc_time& delay) {// 解析通用载荷tlm::tlm_command cmd = gp.get_command();sc_dt::uint64    addr = gp.get_address();unsigned char*   ptr = gp.get_data_ptr();unsigned int     len = gp.get_data_length();if (cmd == tlm::TLM_WRITE_COMMAND) {// 写操作:将数据从ptr拷贝到memory的对应地址std::cout << "EP: WRITE to addr 0x" << std::hex << addr << ", data=0x";for (int i = 0; i < len; i++) {memory[addr + i] = ptr[i];std::cout << std::hex << (int)ptr[i];}std::cout << " at time " << sc_core::sc_time_stamp() << std::endl;gp.set_response_status(tlm::TLM_OK_RESPONSE);} else if (cmd == tlm::TLM_READ_COMMAND) {// 读操作:将数据从memory的对应地址拷贝到ptrstd::cout << "EP: READ from addr 0x" << std::hex << addr << ", data=0x";for (int i = 0; i < len; i++) {ptr[i] = memory[addr + i];std::cout << std::hex << (int)ptr[i];}std::cout << " at time " << sc_core::sc_time_stamp() << std::endl;gp.set_response_status(tlm::TLM_OK_RESPONSE);} else {gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);}}unsigned char memory[1024]; // EP的本地内存/寄存器空间
};

3.2 定义CPU(发起者模块)

#include <tlm_utils/simple_initiator_socket.h>class cpu : public sc_core::sc_module {
public:// 1. 声明一个发起者套接字tlm_utils::simple_initiator_socket<cpu> initiator_socket;cpu(sc_core::sc_module_name name) : sc_module(name) {// 在SystemC线程中发起交易SC_THREAD(run);}void run() {// 等待系统稳定wait(10, sc_core::SC_NS);// 2. 准备通用载荷tlm::tlm_generic_payload gp;sc_core::sc_time delay = sc_core::SC_ZERO_TIME;unsigned char data[4] = {0xDE, 0xAD, 0xBE, 0xEF};// 模拟一次写操作gp.set_command(tlm::TLM_WRITE_COMMAND);gp.set_address(0x100); // 写入到EP的0x100地址gp.set_data_ptr(data);gp.set_data_length(4);std::cout << "CPU: Initiating WRITE transaction..." << std::endl;// 3. 发起交易!initiator_socket->b_transport(gp, delay);// 检查响应if (gp.is_response_error()) {std::cout << "CPU: Transaction failed!" << std::endl;}wait(10, sc_core::SC_NS);// 模拟一次读操作memset(data, 0, 4); // 清空数据缓冲区gp.set_command(tlm::TLM_READ_COMMAND);gp.set_address(0x100); // 从EP的0x100地址读取std::cout << "CPU: Initiating READ transaction..." << std::endl;// 4. 再次发起交易!initiator_socket->b_transport(gp, delay);if (!gp.is_response_error()) {std::cout << "CPU: Read back data: 0x";for (int i = 0; i < 4; i++) {std::cout << std::hex << (int)data[i];}std::cout << std::endl;}}
};

3.3 顶层系统集成

class top : public sc_core::sc_module {
public:cpu cpu_inst;pcie_endpoint pcie_ep_inst;top(sc_core::sc_module_name name) : sc_module(name), cpu_inst("cpu"), pcie_ep_inst("pcie_ssd_endpoint") {// 最关键的一步:将CPU的发起者套接字连接到EP的目标套接字cpu_inst.initiator_socket.bind(pcie_ep_inst.target_socket);}
};int sc_main(int argc, char* argv[]) {top top_inst("top_level");std::cout << "Starting PCIe TLM Simulation..." << std::endl;sc_core::sc_start(); // 启动SystemC内核std::cout << "Simulation Finished." << std::endl;return 0;
}

3.4 运行结果

        运行此仿真,将会看到类似以下的输出:

Starting PCIe TLM Simulation...
CPU: Initiating WRITE transaction...
EP: WRITE to addr 0x100, data=0xdeadbeef at time 10 ns
CPU: Initiating READ transaction...
EP: READ from addr 0x100, data=0xdeadbeef at time 20 ns
CPU: Read back data: 0xdeadbeef
Simulation Finished.

3.5. 最佳实践建议

  1. 分层建模,即从最简单的LT模型开始,用于最早的软件启动。如果需要性能分析,再逐步引入AT模型。

  2. 使用标准套接字和载荷,这样可以确保 IP 的可重用性和互操作性。

  3. 内存映射,需要在互联模块(如 Root Complex)中实现一个地址解码器,将来自 CPU 的地址路由到不同的目标设备(如 GPU、NIC、SSD)。

  4. 与虚拟平台集成,可以将这个 PCIe EP 模型集成进 QEMU 或 Virtual Platform 中,作为硬件设备模型,让一个未经修改的 Linux 内核能够直接将其识别为一个 PCIe 设备并加载驱动。

3.6. 结论

这个PCIe的例子中,我们清晰地看到了 SystemC TLM 的强大之处:

       目的明确,TLM 就是为软件开发提速;原理高效,通过 TLM 事务级抽象,牺牲模型不必要的时间细节,换取极致的仿真速度;结构清晰,由套接字、通用载荷、接口回调构成了简洁而强大的框架;应用广泛,TLM 是现代芯片设计“左移”流程中不可或缺的一环。

        虽然这里示例极度简化,但它揭示了构建复杂 SoC 虚拟原型的核心模式。在实际项目中,会遇到多发起者、多目标、DMA、中断等复杂场景,但它们都是在这些基础概念之上构建起来的。

http://www.dtcms.com/a/509153.html

相关文章:

  • 网站配色分析上海知名的网站建设公司
  • HarmonyOS线程模型与性能优化实战
  • 苏州市规划建设局网站阳江房产网58同城
  • ubuntu系统中对于硬盘占用的分析
  • 推荐专业做网站公司wordpress在后台去掉链接
  • easyui做门户网站百度seo快速见效方法
  • html5手机资讯网站模板网络营销解决方案
  • 做商城网站的项目背景网店营业执照
  • stanley工具网站开发什么叫动漫设计与制作
  • Datawhale25年10月组队学习:math for AI+Task3线性代数(下)
  • 2014网站建设如何做一个论坛网站
  • 网站建设重点是什么it服务商
  • 【连接器专题】案例:在充电线端应用PTC时为什么内模要用PP类材料
  • 安徽建设相关网站seo经理
  • 【随笔】2026年陕西会举办哪几场马拉松
  • 推广网站seo设计网站公司 都赞湖南岚鸿案例10
  • 网站建设书 模板下载爱用系统的设计理念
  • 会qt怎么做网站衡水网站建设浩森宇特
  • 信阳制作网站ihanships免费模板素材网站
  • 江浦做网站百度seo新规则
  • 网站推广自己可以做吗如何建一个营销网站
  • 淘宝实时优惠券网站怎么做的网站情况建设说明
  • 电子科技网站模板买完域名接下来怎么弄
  • C语言动态数组
  • Linux小课堂: 系统监控与进程管理之深入解析 w、ps 与 top 命令
  • 一文解析软件项目管理:从核心概念到实战要点
  • 选择合适的电机试验平台的要点
  • 栅格系统做的网站怎么做手机app软件
  • 75.颜色分类
  • vue3知识点-setup返回值OptionsAPI以及其语法糖汇总