手把手教你学VDK(3.3)--使用 TLM (Transaction-Level Modeling) 创建硬件模型

目录

使用 TLM (Transaction-Level Modeling) 创建硬件模型

1. TLM 基本概念

1.1 什么是 TLM?

1.2 TLM 层次

1.3 TLM 标准

2. 安装 SystemC 和 TLM 库

2.1 下载 SystemC

2.2 解压和安装

2.3 编译和安装

2.4 设置环境变量

3. 创建 TLM 模型

3.1 创建项目目录结构

3.2 编写 TLM 模型

3.2.1 创建一个 TLM 存储器模块

3.2.2 创建一个 TLM 发起者模块

3.3 创建顶层模块

3.4 编写测试平台

4. 编写 Makefile

5. 编译和运行仿真

5.1 编译源代码

5.2 运行仿真

6. 查看仿真结果

6.1 使用波形查看器

7. 调试和优化

7.1 使用调试工具

7.2 性能分析

总结


使用 TLM (Transaction-Level Modeling) 创建硬件模型

TLM(Transaction-Level Modeling)是一种高层次的硬件建模方法,主要用于系统级仿真和验证。TLM 允许开发者以事务的形式描述硬件组件之间的交互,从而简化了复杂系统的建模和仿真。本教程将详细讲解如何使用 TLM 创建硬件模型。

1. TLM 基本概念
1.1 什么是 TLM?

TLM 是一种建模方法,它使用事务(transaction)来表示数据包或操作请求。事务可以跨越多个时钟周期,因此 TLM 模型通常运行得比传统的 RTL 模型更快。TLM 主要用于系统级仿真和早期软件开发。

1.2 TLM 层次

TLM 分为多个层次,每个层次有不同的抽象级别:

  • TLM 0:最低层次,接近于 RTL,每个操作都在一个时钟周期内完成。
  • TLM 1:中等层次,使用同步事务,所有操作在一个事务周期内完成。
  • TLM 2:最高层次,使用异步事务,支持非阻塞调用和多线程操作。
1.3 TLM 标准
  • TLM 1.0:早期标准,主要支持同步事务。
  • TLM 2.0:现代标准,支持异步事务和多线程操作,更灵活和高效。
2. 安装 SystemC 和 TLM 库

确保你已经安装了 SystemC 和 TLM 库。以下是安装步骤:

2.1 下载 SystemC

从官方网站下载 SystemC 的最新版本:

2.2 解压和安装

解压下载的文件并安装 SystemC:

 

Sh

深色版本

wget https://accellera.org/images/downloads/standards/systemc/systemc-2.3.3.tar.gz
tar -xzf systemc-2.3.3.tar.gz
cd systemc-2.3.3
2.3 编译和安装

编译和安装 SystemC:

 

Sh

深色版本

mkdir build
cd build
cmake ..
make
sudo make install
2.4 设置环境变量

编辑 ~/.bashrc 文件,添加 SystemC 的路径:

 

Sh

深色版本

export SYSTEMC_HOME=/usr/local/systemc-2.3.3
export PATH=$PATH:$SYSTEMC_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SYSTEMC_HOME/lib-linux

应用环境变量:

 

Sh

深色版本

source ~/.bashrc
3. 创建 TLM 模型
3.1 创建项目目录结构

创建一个项目目录结构,组织你的源代码和仿真文件。例如:

 

Sh

深色版本

mkdir -p project/src/hardware
mkdir -p project/src/software
mkdir -p project/sim
mkdir -p project/build
3.2 编写 TLM 模型
3.2.1 创建一个 TLM 存储器模块

project/src/hardware 目录下创建一个 TLM 存储器模块文件 tlm_memory.cpp

 

Cpp

深色版本

#include <systemc>
#include <tlm>

using namespace sc_core;
using namespace tlm;

SC_MODULE(TLMMemory) {
    tlm::tlm_target_socket<> target_socket;

    TLMMemory(sc_module_name name) : target_socket("target_socket") {
        target_socket.register_b_transport(this, &TLMMemory::b_transport);
    }

    void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
        tlm::tlm_command cmd = trans.get_command();
        sc_dt::uint64 addr = trans.get_address();
        unsigned char* payload = trans.get_data_ptr();
        unsigned int len = trans.get_data_length();

        if (cmd == tlm::TLM_READ_COMMAND) {
            // 读操作
            for (unsigned int i = 0; i < len; ++i) {
                payload[i] = memory[addr + i];
            }
        } else if (cmd == tlm::TLM_WRITE_COMMAND) {
            // 写操作
            for (unsigned int i = 0; i < len; ++i) {
                memory[addr + i] = payload[i];
            }
        }

        trans.set_response_status(tlm::TLM_OK_RESPONSE);
    }

private:
    std::vector<uint8_t> memory(1024, 0); // 1KB 存储器
};
3.2.2 创建一个 TLM 发起者模块

project/src/hardware 目录下创建一个 TLM 发起者模块文件 tlm_initiator.cpp

 

Cpp

深色版本

#include <systemc>
#include <tlm>

using namespace sc_core;
using namespace tlm;

SC_MODULE(TLMInitiator) {
    tlm::tlm_initiator_socket<> initiator_socket;

    TLMInitiator(sc_module_name name) : initiator_socket("initiator_socket") {
        SC_THREAD(run);
    }

    void run() {
        tlm::tlm_generic_payload trans;
        unsigned char buffer[4];

        // 写操作
        trans.set_command(tlm::TLM_WRITE_COMMAND);
        trans.set_address(0x100);
        trans.set_data_ptr(buffer);
        trans.set_data_length(4);
        buffer[0] = 0x12;
        buffer[1] = 0x34;
        buffer[2] = 0x56;
        buffer[3] = 0x78;
        initiator_socket->b_transport(trans, sc_time(10, SC_NS));

        // 读操作
        trans.set_command(tlm::TLM_READ_COMMAND);
        trans.set_address(0x100);
        trans.set_data_ptr(buffer);
        trans.set_data_length(4);
        initiator_socket->b_transport(trans, sc_time(10, SC_NS));

        std::cout << "Read data: ";
        for (int i = 0; i < 4; ++i) {
            std::cout << std::hex << (int)buffer[i] << " ";
        }
        std::cout << std::endl;
    }
};
3.3 创建顶层模块

project/src 目录下创建一个顶层模块文件 system_top.cpp,集成 TLM 模块:

 

Cpp

深色版本

#include <systemc>
#include <tlm>

using namespace sc_core;
using namespace tlm;

#include "hardware/tlm_memory.cpp"
#include "hardware/tlm_initiator.cpp"

SC_MODULE(SystemTop) {
    TLMMemory memory;
    TLMInitiator initiator;

    tlm::tlm_target_socket<> target_socket;
    tlm::tlm_initiator_socket<> initiator_socket;

    SC_CTOR(SystemTop) : memory("memory"), initiator("initiator") {
        initiator_socket.bind(initiator.initiator_socket);
        memory.target_socket.bind(initiator_socket);

        // 记录波形
        sc_trace_file *tf = sc_create_vcd_trace_file("wave");
        sc_trace(tf, sc_time_stamp(), "time");
    }

    ~SystemTop() {
        sc_close_vcd_trace_file(tf);
    }
};
3.4 编写测试平台

project/src 目录下创建一个测试平台文件 testbench.cpp,用于驱动顶层模块:

 

Cpp

深色版本

#include <systemc>
using namespace sc_core;

#include "system_top.cpp"

void test() {
    SystemTop top("top");

    // 运行仿真
    sc_start(100, SC_NS);
}

int sc_main(int argc, char* argv[]) {
    test();
    return 0;
}
4. 编写 Makefile

project 目录下创建一个 Makefile,用于编译和链接源代码:

 

Makefile

深色版本

# Makefile
CC = g++
SYSTEMC_HOME = /usr/local/systemc-2.3.3
SYSTEMC_LIB = $(SYSTEMC_HOME)/lib-linux
SYSTEMC_INCLUDE = $(SYSTEMC_HOME)/include

CFLAGS = -I$(SYSTEMC_INCLUDE) -Wall -g
LDFLAGS = -L$(SYSTEMC_LIB) -lsystemc -lm -lrt

SRCS = $(wildcard src/hardware/*.cpp) $(wildcard src/*.cpp)
OBJS = $(SRCS:.cpp=.o)
TARGET = sim/system_top

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $^

%.o: %.cpp
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(OBJS) $(TARGET)
5. 编译和运行仿真
5.1 编译源代码

在终端中运行以下命令编译源代码:

 

Sh

深色版本

cd project
make
5.2 运行仿真

创建一个脚本文件(例如 run_sim.sh),用于运行仿真:

 

Sh

深色版本

#!/bin/bash
./sim/system_top

确保脚本文件具有可执行权限:

 

Sh

深色版本

chmod +x sim/run_sim.sh

运行仿真:

 

Sh

深色版本

./sim/run_sim.sh
6. 查看仿真结果
6.1 使用波形查看器

使用波形查看器(如GTKWave)查看仿真结果:

 

Sh

深色版本

gtkwave wave.vcd
7. 调试和优化
7.1 使用调试工具

使用调试工具(如GDB)进行调试:

 

Sh

深色版本

gdb ./sim/system_top

在GDB中设置断点、单步执行和查看变量:

 

Sh

深色版本

(gdb) break TLMMemory::b_transport
(gdb) run
(gdb) step
(gdb) print addr
7.2 性能分析

使用SystemC提供的性能分析工具,评估仿真过程中的性能指标,如CPU利用率、内存占用等。根据分析结果优化代码和硬件模型。

总结

通过以上步骤,你已经学会了如何使用 TLM 创建和仿真一个简单的硬件模型。从安装 SystemC 和 TLM 库、创建项目目录结构、编写 TLM 模型和顶层模块、编写测试平台、编译和运行仿真,到查看仿真结果和调试优化,每个步骤都至关重要。希望这些内容能帮助你更好地理解和应用 TLM 技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值