zoukankan      html  css  js  c++  java
  • OR1200指令Cache使用举例

    下面内容摘自《步步惊芯——软核处理器内部设计分析》一书

    12.4 ICache中的特殊寄存器

          通过ICache的接口可知其具有特殊寄存器,而且是不可读的特殊寄存器,OR1200处理器中ICache实现的特殊寄存器如表12.1所看到的。


          可见仅仅实现了一个特殊寄存器——ICBIR(InstructionCache Block Invalidate Register),即指令缓存块无效寄存器,且是不可读寄存器。一般而言,特殊寄存器的地址是16位,高5位存放的是组号,低11位存放的是特殊寄存器在组中的索引。可是从表12.1中发现ICBIR的索引是随意的,这是因为第4组中仅仅实现了这一个特殊寄存器。所以仅仅要特殊寄存器地址的高5位是0x4,那么一定是ICBIR。这样就不是必需限定一个索引,此外,从图12.5能够发现ICache没有spr_addr接口,原因相同。

    ICBIR格式如表12.2所看到的。


          假设向ICBIR中写入一个地址,设为Addr。那么将使得ICache文件夹表中第Addr[12:4]个line的V为0,表示该line无效,实际实现就是将IC_TAG中第Addr[12:4]项的V设置为0。

    12.5 ICache使用情景

          同第10章分析MMU的方法一样。本章也是採用情景分析法。通过对使用ICache的各种情景的分析以实现对ICache模块剖析。

    使用ICache的情景有例如以下几种:

          (1)l.mtspr指令写ICBIR

          (2)指令取指阶段ICache失靶

          (3)指令取指阶段ICache命中

          (4)指令取指阶段。目的指令所在的内存页禁止缓存

          上述四种情景中。情景(1)在流水线的运行阶段使用到了ICache,情景(2)、(3)、(4)在流水线的取指阶段使用到了ICache。

    本章在兴许部分将给出一个演示样例程序,当中涉及到了ICache的所有使用情景。然后结合该演示样例程序分析在上述几种情景下ICache的工作过程,从而理解ICache的代码与原理。

    12.6 分析用例

          本节将给出一个演示样例程序。当中涉及到了ICache的所有使用情景。该程序执行在第11章建立的简单SOPC上。代码例如以下:

           .section .text,"ax"  
           .global _start
           .org 0x100       
    #######################           第1步            #########################
    _start:
          #初始化r0-r3,都清零。同一时候能够观察此时l.addi指令运行须要的时钟周期数
          l.movhi r0,0x0                
          l.addi r1,r0,0x0
          l.addi r2,r0,0x0
          l.addi r3,r0,0x0
    
    #######################           第2步            #########################
    _IC_Init:                           
          # ICache初始化,将IC_TAG中512个表项的V都设置为0,表示无效,设置方法就
          # 是向ICBIR寄存器中依次写入0x0、0x10、0x20……0x2000
          l.mtspr r0,r1,0x2000          #ICBIR寄存器的组内索引能够随意。仅仅要地址
                                        #的高5位是0x4就可以,此处取0x2000
                                        
          l.sfeqi r1,0x2000             #当r1等于0x2000时表示已经设置完成IC_TAG中
                                        #所有512个表项
                                        
          l.bnf _IC_Init                #假设r1不等于0x2000,表示还没有设置完成,
                                        #继续循环
                                        
          l.addi r1,r1,0x10             #延迟槽指令,r1加0x10
          l.movhi r1,0x0                #ICache初始化完成后。将r1清零,由于后面还要
                                        #使用r1
    
    #######################           第3步            ########################
          l.ori r3,r0,0x1             #r3等于0x1
          l.mtspr r0,r3,0x1200        #向地址0x1200的SPR写入0x1,0x1200相应的SPR
                                      #是ITLBW0MR0,所以此处就是设置ITLBW0MR0,对
                                      #应MR表的第0项放置0x1,
                                      #当中VPN为0。Valid为1
    
          l.ori r3,r0,0x00C0          #r3等于0x00C0
          l.mtspr r0,r3,0x1280        #向地址0x1280的SPR写入0x00C0,0x1280相应的SPR
                                      #就是ITLBW0TR0,所以此处就是设置ITLBW0TR0,对
                                      #应TR表的第0项放置0x00C0。当中PPN为0x0。
                                      #sxe为1,uxe为1,ci为0
                                      
          #上述设置使得有效地址0x0-0x1fff被翻译为物理地址0x0-0x1fff,两者相等
    
    ########################           第4步            ########################
          l.ori r3,r0,0x8051          #r3等于0x8051
          l.mtspr r0,r3,0x11          #设置SR寄存器为0x8051,即SR[IME]、SR[ICE]都为1。
                                      #使能IMMU、ICache
          l.nop
    
    ########################           第5步            ########################
    _loop:                            
          #此时ICache已经使能,第一次运行以下的循环。读取第1条指令时会发生ICache
          #失靶,于是读入第一条指令所在的内存块。共16个字节。含4条指令。这样运行第
          #2条、第3条、第4条指令时就会ICache命中,同一时候在后面的循环中都会ICache
          #命中
          l.addi r1,r1,0x1            #每次循环r1加1
          l.sfeqi r1,0x10             #推断是否循环了16次
          l.bnf _loop                 #假设循环了16次,则退出循环
          l.addi r2,r2,0x1            #r2记录总循环次数
    
    #########################           第6步            #########################
          l.addi r1,r0,0x0            #r1清零
          
          l.ori r3,r0,0x00C2
          l.mtspr r0,r3,0x1280        #向地址0x1280的SPR写入0x00C2。0x1280相应的SPR
                                      #就是ITLBW0TR0,所以此处就是设置ITLBW0TR0,对
                                      #应TR表的第0项放置0x00C2,当中PPN为0x0,sxe为1。
                                      #uxe为1,ci为1,表示0x0-0x1fff相应的内存页禁止
                                      #缓存
          
          l.j _loop                   #此时0x0-0x1fff相应的内存页禁止缓存,再次运行
                                      #第5步中的循环,观察此时的运行效果
    

          上述程序能够分为6步。每一步的主要工作例如以下:

          第1步:初始化寄存器r0-r3,都清零。

          第2步:初始化ICache。由于ICache中IC_TAG的实现主体就是单口RAM。在系统启动的时候。RAM中的内容是不确定的。所以须要初始化ICache,初始化的方法就是依次设置IC_TAG中每一个表项的V为0。表示该表项无效。指令l.mtspr向特殊寄存器ICBIR中依次写入0x0、0x10、0x20……0x2000。就会依次设置IC_TAG中每一个表项的V为0,參考之前对ICBIR的介绍。

          第3步:设置ITLB的第一个表项,使得有效地址0x0-0x1fff被翻译为0x0-0x1fff,实际就是有效地址等于物理地址,演示样例程序代码非常短,从地址0x100開始,不会超过0x1fff,所以在演示样例程序执行的时候,IMMU地址翻译的结果就是物理地址与有效地址相等。IMMU所发挥的作用在第6步中会有所体现。

          第4步:设置SR寄存器。使能IMMU、ICache。

          第5步:这是一个仅仅有4条指令的循环体,而且通过计算可知循环体中4条指令地址各自是0x140、0x144、0x148、0x14C,所以这4条指令位于同一个内存块。

    第一次运行循环体。读取循环体中第1条指令时。会发生ICache失靶异常,于是会读入这四条指令(由于位于同一个内存块)到ICache。此时ICache中数据部分如图12.9所看到的。这样在运行循环体中第2、3、4条指令时就会ICache命中。而且在接下来的循环中都会ICache命中。从而循环体中每条指令运行仅仅须要一个时钟周期,循环一共运行16次,然后退出。


          第6步:再次设置ITLB的第一个表项,使得该页的属性标志位CI为1,即禁止缓存,然后再转移到第5步中的循环体运行。观察此时循环体的运行,预期效果应该是尽管此时所需指令在ICache中。可是因为设置了禁止缓存,所以还是会从RAM中取指,与没有ICache时一样,指令运行须要多个时钟周期。

          在第6步转移到第5步的循环体之前会将r1清零,所以循环体中r1会又一次从0x1加到0x10。可是r2会接着之前的值递增,也就是r2记录的是总的循环次数。

    这样当r2等于0x0-0x10时,应该是第一次运行循环体,此时CI为0,当r2为其余值时。表示不是第一次运行循环体,此时应该已经设置CI为1,在观察ModelSim仿真波形的时候能够依据r2的值推断此时是第几次运行循环体,同一时候能够知道此时CI是否为1。

          在Ubuntu中新建文件Example.S,内容就是上述代码。拷贝ram.ld、Makefile、Bin2Mem.exe到Example.S所在文件夹,当中的Makefile选择在10章中改动过后的Makefile,也就是不会使用OR1KSim进行模拟。此时再打开终端。调整路径到上述文件所在文件夹。输入“make all”得到能够在ModelSim仿真中使用的存储器初始化文件mem.data。

    简单SOPC就使用该文件初始化RAM。为了便于知道仿真波形中if_insn、id_insn、ex_insn等信号相应的指令,以下列出指令与其相应的二进制,分为三列,各自是指令地址、指令、指令相应的二进制。

    ##############################           第1步            #####################
           指令地址             指令                      指令相应的二进制
    _start:
            0x100              l.movhi r0,0x0                0x18000000
            0x104              l.addi r1,r0,0x0              0x9c200000
            0x108              l.addi r2,r0,0x0              0x9c400000
            0x10C              l.addi r3,r0,0x0              0x9c600000
    ##############################           第2步            #####################
           指令地址             指令                      指令相应的二进制
    _IC_Init:                          
            0x110              l.mtspr r0,r1,0x2000          0xc0800800
            0x114              l.sfeqi r1,0x2000             0xbc012000
            0x118              l.bnf _IC_Init                0x0ffffffe
            0x11C              l.addi r1,r1,0x10             0x9c210010
            0x120              l.movhi r1,0x0                0x18200000
    ##############################           第3步            #####################
           指令地址             指令                      指令相应的二进制
            0x124              l.ori r3,r0,0x1               0xa8600001
            0x128              l.mtspr r0,r3,0x1200          0xc0401a00
            0x12C              l.ori r3,r0,0x00C0            0xa86000c0
            0x130              l.mtspr r0,r3,0x1280          0xc0401a80
    ##############################           第4步            #####################
           指令地址             指令                      指令相应的二进制
            0x134              l.ori r3,r0,0x8051            0xa8608051
            0x138              l.mtspr r0,r3,0x11            0xc0001811
            0x13C              l.nop                         0x15000000
    ##############################           第5步            #####################
           指令地址             指令                      指令相应的二进制
    _loop:                          
            0x140              l.addi r1,r1,0x1              0x9c210001
            0x144              l.sfeqi r1,0x10               0xbc010010
            0x148              l.bnf _loop                   0x0ffffffe
            0x14C              l.addi r2,r2,0x1              0x9c420001
    ##############################           第6步            #####################
           指令地址             指令                      指令相应的二进制
            0x150              l.addi r1,r0,0x0              0x9c200000
            0x154              l.ori r3,r0,0x00C2            0xa86000c2
            0x158              l.mtspr r0,r3,0x1280          0xc0401a80
            0x15C              l.j _loop                     0x03fffff9
    

          ModelSim仿真波形如图12.10-12.14所看到的。从仿真结果可知ICache的效果是符合预期的。本书光盘的Chapter12文件夹下包含ModelSim仿真project。Chapter12/Code文件夹下包含演示样例程序源码。

          本章接下来将借助该程序具体分析ICache在各种使用情景下的工作过程。














  • 相关阅读:
    HTML技巧篇:如何让单行文本以及多行文本溢出时显示省略号(…)
    SpringMVC中响应json数据(异步传送)
    如何用Spring框架的<form:form>标签实现REST风格的增删改查操作
    如何使用REST请求风格
    Spring插件的安装与卸载---笔记
    元素 "context:component-scan" 的前缀 "context" 未绑定的解决方案
    简单的文件上传的下载(动态web项目)
    用简单的反射优化代码(动态web项目)
    json数据与Gson工具类的使用
    JSON简介
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7008641.html
Copyright © 2011-2022 走看看