gem5——向简单脚本中添加缓存

本文介绍了如何在gem5模拟器中添加缓存,包括创建L1Cache和L2Cache类,连接CPU和总线,并通过实例化脚本simple2.py展示具体配置过程。详细讲解了端口选择的依据,如L2bus的cpu_side_ports连接L1DataCache的mem_side_ports。最后,通过运行脚本展示了成功输出。
摘要由CSDN通过智能技术生成

    本文章是我学习如何向一个简单的gem5脚本添加缓存时的代码和注释,可与https://blog.csdn.net/luzi0206/article/details/117629255?spm=1001.2014.3001.5501对照阅读。

     我是根据http://www.gem5.org/documentation/learning_gem5/part1/cache_config/进行学习的。

       下图为体系结构框图:

      首先创建与添加的缓存的类,代码为caches.py:

#导入SimObject中caches的类。位于src/mem/Cache/Cache.py中。
from m5.objects import Cache

#对BaseCache进行扩展,建立新的类:L1Cache(1级缓存)、L2Cache(2级缓存)。
class L1Cache(Cache):
    #对Cache进行扩展
    assoc = 2
    tag_latency = 2
    data_latency = 2
    response_latency = 2
    mshrs = 4
    tgts_per_mshr = 20
    #添加两个函数将缓存与CPU和总线连接
    def connectCPU(self,cpu):
        #连接至CPU。在后续子类L1ICache和L1DCache中,因为端口不同,需要单独定义。
        raise NotImplementedError

    def connectBus(self,bus):
        #连接至总线
        self.mem_side = bus.cpu_side_ports


class L2Cache(Cache):
    size = '256kB'
    assoc = 8
    tag_latency = 20
    data_latency = 20
    response_latency = 20
    mshrs = 20
    tgts_per_mshr = 12

    def connectCPUSideBus(self,bus):
        #连接至CPU端
        self.cpu_side = bus.mem_side_ports

    def connectMemSideBus(self,bus):
        #连接至总线端
        self.mem_side = bus.cpu_side_ports
        

#建立L1Cache的2个子类。
class L1ICache(L1Cache):
    size = '16kB'

    def connectCPU(self, cpu):
        #为指令缓存定义单独的ConnectCPU函数,
        self.cpu_side = cpu.icache_port

class L1DCache(L1Cache):
    size = '64kB'

    def connectCPU(self, cpu):
        #为数据缓存定义单独的ConnectCPU函数,
        self.cpu_side = cpu.dcache_port

    然后创建gem5的脚本,代码为simple2.py:

#导入m5和SimObjects
import m5
from m5.objects import *
#导入编写的caches.py中的caches
from caches import *


#创建要模拟的系统
system = System()
#设置系统时钟。1、建立时钟域,2、设置时钟频率,3、为时钟域指定电压域
system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()

#设置系统模拟内存(计时模式),设置内存范围
system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]

#创建CPU(基于时间),
system.cpu = TimingSimpleCPU()
#创建L1Cache
system.cpu.icache = L1ICache()
system.cpu.dcache = L1DCache()
#将L1Cache连接至CPU端口,这里是通过L1ICache和L1DCache类中的函数实现的。
system.cpu.icache.connectCPU(system.cpu)
system.cpu.dcache.connectCPU(system.cpu)

#创建系统范围内存总线
system.membus = SystemXBar()

#将CPU上的缓存端口连接到内存总线上。由于没有建立缓存cache,所以将icache和dcache直接连接到menbus
#因为一级缓存连接到了二级缓存上,这里删除以前的这条连线(将缓存端口直接连接到内存总线上)
#system.cpu.icache_port = system.membus.cpu_side_ports
#system.cpu.dcache_port = system.membus.cpu_side_ports

#创建二级总线(不能直接将一级缓存连接到二级缓存),并连接一级缓存和二级缓存
system.l2bus = L2XBar()
system.cpu.icache.connectBus(system.l2bus)
system.cpu.dcache.connectBus(system.l2bus)

#创建二级缓存,连接二级缓存到二级总线和内存总线
system.l2cache = L2Cache()
system.l2cache.connectCPUSideBus(system.l2bus)
system.l2cache.connectMemSideBus(system.membus)

#连接CPU的其他端口以确保系统可以正常工作,例如I/O控制器。
system.cpu.createInterruptController()
#将系统的一个特殊端口连接到menbus,这个端口只允许系统读写内存。
system.system_port = system.membus.cpu_side_ports

#x86的特定要求,将PIO和中断端口连接到内存总线
if m5.defines.buildEnv['TARGET_ISA'] == "x86":
    system.cpu.interrupts[0].pio = system.membus.mem_side_ports
    system.cpu.interrupts[0].int_requestor = system.membus.cpu_side_ports
    system.cpu.interrupts[0].int_responder = system.membus.mem_side_ports

#创建一个内存控制器,并将其连接到内存总线。这里使用的是DDR3控制器,负责内存的范围。
system.mem_ctrl = MemCtrl()
system.mem_ctrl.port = system.membus.mem_side_ports
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]

#---------设置CPU执行的进程--------------------#
#这里使用syscall仿真模式
#1、设置可执行文件,2、创建进程,设置进程执行的可执行文件,
# 3、将进程设置为CPU的工作负载,4、在CPU上创建进程(或者说创建执行环境)
binary = 'tests/test-progs/hello/bin/x86/linux/hello'

#对于gem5 v21及更高版本,加入下面一行。
system.workload = SEWorkload.init_compatible(binary)

process = Process()
process.cmd = [binary]
system.cpu.workload = process
system.cpu.createThreads()

#---------实例化系统并执行-------------#
#创建根对象,并实例化模拟
root = Root(full_system = False,system = system)
m5.instantiate()

#开始模拟。这里的print不是语句而是作为一个函数被调用。
print("Beginning simulation")
exit_event = m5.simulate()

#模拟结束后对系统进行检测
print('Exiting @ tick {} because {}'
    .format(m5.curTick(),exit_event.getCause()))

    测试:

build/X86/gem5.opt configs/simple2.py 

    结果:

Beginning simulation
info: Entering event queue @ 0.  Starting simulation...
Hello world!
Exiting @ tick 56435000 because exiting with last active thread context

        在连接时需要考虑端口的选择问题(原本的代码是

memobject1.master = memobject2.slave

这里将端口名改为mem_side_ports、cpu_side_ports)。依据的体系结构来进行选择的,例如L2bus连接L1DataCachel时,因为L1DataCachel相对于L2bus位于CPU侧,所以L1DataCache需要连接L2bus的cpu_side_ports端口,而L2bus相对于L1DataCachel位于menbus侧,所以L2bus需要连接L1DataCachel的的mem_side_ports端口,即CPU侧的mem_side_ports端口需要连接menbus侧的cpu_side_ports端口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值