问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

GEM5的RISC-V架构实践:创建一个带cache的示例

创作时间:
作者:
@小白创作中心

GEM5的RISC-V架构实践:创建一个带cache的示例

引用
CSDN
1.
https://m.blog.csdn.net/sucool_lb/article/details/144375197

GEM5是一个功能强大的计算机系统模拟器,支持多种架构的CPU和各种硬件组件的模拟。RISC-V是一种开源指令集架构,近年来在嵌入式系统和高性能计算领域得到了广泛应用。本文将介绍如何使用GEM5创建一个带有缓存的RISC-V架构CPU SoC系统。

本节目标是创建一个带cache的示例RISCV CPU SoC系统,系统拓扑结构如下:

创建配置

需要创建两个脚本文件:

touch configs/tutorial/part1/caches.py
touch configs/tutorial/part1/two_level_riscv.py

two_level_riscv.py 内容

import m5
from m5.objects import *
m5.util.addToPath("../../")
from caches import *
from common import SimpleOpts

thispath = os.path.dirname(os.path.realpath(__file__))
default_binary = os.path.join(
    thispath,
    "../../../",
    "tests/test-progs/hello/bin/riscv/linux/hello",
)
SimpleOpts.add_option("binary", nargs="?", default=default_binary)
args = SimpleOpts.parse_args()

# 创建系统
system = System()

# 设置时钟电压域
system.clk_domain = SrcClockDomain()
system.clk_domain.clock = "1GHz"
system.clk_domain.voltage_domain = VoltageDomain()

system.mem_mode = "timing"  # 使用定时访问模式
system.mem_ranges = [AddrRange("8GiB")]  # 创建地址范围

# RISC-V CPU
system.cpu = RiscvTimingSimpleCPU()

# L1缓存
system.cpu.icache = L1ICache(args)
system.cpu.dcache = L1DCache(args)
system.cpu.icache.connectCPU(system.cpu)
system.cpu.dcache.connectCPU(system.cpu)

# L2总线
system.l2bus = L2XBar()
system.cpu.icache.connectBus(system.l2bus)
system.cpu.dcache.connectBus(system.l2bus)

# L2缓存
system.l2cache = L2Cache(args)
system.l2cache.connectCPUSideBus(system.l2bus)

# 主内存总线
system.membus = SystemXBar()

# 连接L2缓存到内存总线
system.l2cache.connectMemSideBus(system.membus)

# 中断控制器
system.cpu.createInterruptController()

# DDR3内存控制器
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports
system.system_port = system.membus.cpu_side_ports

# SE模式
# 二进制可执行文件
system.workload = SEWorkload.init_compatible(args.binary)

# 创建进程
process = Process()
process.cmd = [args.binary]
system.cpu.workload = process
system.cpu.createThreads()

# 模拟对象
root = Root(full_system=False, system=system)  # SE模式
m5.instantiate()

# 启动模拟
print(f"Beginning simulation!")
exit_event = m5.simulate()
print(f"Exiting @ tick {m5.curTick()} because {exit_event.getCause()}")

caches.py 内容

import m5
from m5.objects import Cache
# Add the common scripts to our path
m5.util.addToPath("../../")
from common import SimpleOpts

class L1Cache(Cache):
    """Simple L1 Cache with default values"""
    assoc = 2
    tag_latency = 2
    data_latency = 2
    response_latency = 2
    mshrs = 4
    tgts_per_mshr = 20

    def __init__(self, options=None):
        super().__init__()
        pass

    def connectBus(self, bus):
        """Connect this cache to a memory-side bus"""
        self.mem_side = bus.cpu_side_ports

    def connectCPU(self, cpu):
        """Connect this cache's port to a CPU-side port
        This must be defined in a subclass"""
        raise NotImplementedError

class L1ICache(L1Cache):
    """Simple L1 instruction cache with default values"""
    # Set the default size
    size = "16KiB"
    SimpleOpts.add_option(
        "--l1i_size", help=f"L1 instruction cache size. Default: {size}"
    )

    def __init__(self, opts=None):
        super().__init__(opts)
        if not opts or not opts.l1i_size:
            return
        self.size = opts.l1i_size

    def connectCPU(self, cpu):
        """Connect this cache's port to a CPU icache port"""
        self.cpu_side = cpu.icache_port

class L1DCache(L1Cache):
    """Simple L1 data cache with default values"""
    # Set the default size
    size = "64KiB"
    SimpleOpts.add_option(
        "--l1d_size", help=f"L1 data cache size. Default: {size}"
    )

    def __init__(self, opts=None):
        super().__init__(opts)
        if not opts or not opts.l1d_size:
            return
        self.size = opts.l1d_size

    def connectCPU(self, cpu):
        """Connect this cache's port to a CPU dcache port"""
        self.cpu_side = cpu.dcache_port

class L2Cache(Cache):
    """Simple L2 Cache with default values"""
    # Default parameters
    size = "256KiB"
    assoc = 8
    tag_latency = 20
    data_latency = 20
    response_latency = 20
    mshrs = 20
    tgts_per_mshr = 12
    SimpleOpts.add_option("--l2_size", help=f"L2 cache size. Default: {size}")

    def __init__(self, opts=None):
        super().__init__()
        if not opts or not opts.l2_size:
            return
        self.size = opts.l2_size

    def connectCPUSideBus(self, bus):
        self.cpu_side = bus.mem_side_ports

    def connectMemSideBus(self, bus):
        self.mem_side = bus.cpu_side_ports

运行脚本

./build/RISCV/gem5.opt configs/tutorial/part1/two_level_riscv.py

运行结果

gem5 Simulator System.  https://www.gem5.org
gem5 is copyrighted software; use the --copyright option for details.
gem5 version DEVELOP-FOR-24.1
gem5 compiled Dec 10 2024 10:32:58
gem5 started Dec 10 2024 22:28:57
gem5 executing on lubin-TK-E450, pid 209014
command line: ./build/RISCV/gem5.opt configs/tutorial/part1/two_level_riscv.py
Global frequency set at 1000000000000 ticks per second
src/arch/riscv/isa.cc:278: info: RVV enabled, VLEN = 256 bits, ELEN = 64 bits
src/base/statistics.hh:279: warn: One of the stats is a legacy stat. Legacy stat is a stat that does not belong to any statistics::Group. Legacy stat is deprecated.
system.remote_gdb: Listening for connections on port 7000
Beginning simulation!
src/sim/simulate.cc:199: info: Entering event queue @ 0.  Starting simulation...
src/sim/syscall_emul.hh:1121: warn: readlink() called on '/proc/self/exe' may yield unexpected results in various settings.
      Returning '/home/lubin/Source/RVgem5/tests/test-progs/hello/bin/riscv/linux/hello'
src/sim/mem_state.cc:448: info: Increasing stack size by one page.
Hello world!
Exiting @ tick 59206000 because exiting with last active thread context

本文详细介绍了如何使用GEM5创建一个带有缓存的RISC-V架构CPU SoC系统,包括系统配置、脚本编写和运行结果分析。这对于理解计算机体系结构和模拟器的使用具有重要参考价值。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号