zoukankan      html  css  js  c++  java
  • 自己动手写CPU之第八阶段(4)——转移指令实现过程2

    将陆续上传本人写的新书《自己动手写CPU》,今天是第36篇,我尽量每周四篇

    开展晒书评送书活动,在亚马逊、京东、当当三大图书站点上,发表《自己动手写CPU》书评的前十名读者,均可获赠《步步惊芯——软核处理器内部设计分析》一书,大家踊跃參与吧!活动时间:2014-9-11至2014-10-20


    8.4.3 改动运行阶段的EX 模块

          參考图8-6可知,EX模块须要添加一些接口,添加的接口描写叙述如表8-4所看到的。


          EX模块的代码主要改动例如以下,完整代码请參考本书附带光盘CodeChapter8文件夹下的ex.v文件。

    module ex(
    
      ......
    
      // 处于运行阶段的转移指令要保存的返回地址
      input wire[`RegBus]           link_address_i,
    
      // 当前运行阶段的指令是否位于延迟槽
      input wire                    is_in_delayslot_i,	
    	
      ...... 
    	
    );
    	
      ......
    
      always @ (*) begin
    
      ......
    	 
        case ( alusel_i ) 
          `EXE_RES_LOGIC:		begin
            wdata_o <= logicout;
          end
          `EXE_RES_SHIFT:		begin
            wdata_o <= shiftres;
          end	 	
          `EXE_RES_MOVE:		begin
            wdata_o <= moveres;
          end	 	
          `EXE_RES_ARITHMETIC:	begin
            wdata_o <= arithmeticres;
          end
          `EXE_RES_MUL:		begin
            wdata_o <= mulres[31:0];
          end	 	
          `EXE_RES_JUMP_BRANCH:	begin
            wdata_o <= link_address_i;
          end
          default:					begin
            wdata_o <= `ZeroWord;
          end
        endcase
    end	
    
    	......			
    
    endmodule
    

          假设alusel_o为EXE_RES_JUMP_BRANCH,那么就将返回地址link_address_i作为要写入目的寄存器的值赋给wdata_o。

          注意一点,此处并没有利用输入的信号is_in_delayslot_i,该信号表示当前处于运行阶段的指令是否是延迟槽指令,这个信号会在异常处理过程中使用到,本章临时不须要。

    8.4.4 改动OpenMIPS模块

          由于有一些模块加入了接口,所以须要改动顶层模块OpenMIPS,以将这些新添加的接口依照图8-6所看到的的关系连接起来。详细改动也非常easy,不在书中列出,读者能够參考本书附带光盘CodeChapter8文件夹下的openmips.v文件。

    8.5 測试转移指令的实现效果

          本节将通过两个測试程序验证转移指令是否实现正确,这两个測试程序分别验证跳转指令、分支指令。

    8.5.1 測试跳转指令

          測试代码例如以下,源文件是本书光盘CodeChapter8AsmTestTest1文件夹下的inst_rom.S文件。

    .org 0x0
    .set noat
    .set noreorder      # 加入这个伪操作,指示编译器不要对程序做出不论什么优化或是修改
    .set nomacro        
    .global _start
    _start:
       ori  $1,$0,0x0001   # (1)$1 = 0x1                
       j    0x20           #  转移到0x20处
       ori  $1,$0,0x0002   # (2)$1 = 0x2,这是延迟槽指令
       ori  $1,$0,0x1111
       ori  $1,$0,0x1100
    
       .org 0x20
       ori  $1,$0,0x0003   # (3)$1 = 0x3               
       jal  0x40           #  转移到0x40处,同一时候设置$31为0x2c
       div  $zero,$31,$1   # (4)此时$31 = 0x2c, $1 = 0x3,所以得到除法结果
                           #     HI = 0x2, LO = 0xe,这是延迟槽指令
    
       ori  $1,$0,0x0005   # (6)$1 = 0x5
       ori  $1,$0,0x0006   # (7)$1 = 0x6
       j    0x60           #  转移到0x60处
       nop
    
       .org 0x40
       jalr $2,$31          #  此时$31为0x2c,所以转移到0x2c,同一时候设置$2为0x48
       or   $1,$2,$0        # (5)$1 = 0x48,这是延迟槽指令
    
       ori  $1,$0,0x0009    # (10)$1 = 0x9
       ori  $1,$0,0x000a    # (11)$1 = 0xa
       j 0x80               #  转移到0x80处
       nop
    
       .org 0x60
       ori  $1,$0,0x0007    # (8)$1 = 0x7 
       jr   $2              #  此时$2为0x48,所以转移到0x48处
       ori  $1,$0,0x0008    # (9)$1 = 0x8,这是延迟槽指令
       ori  $1,$0,0x1111
       ori  $1,$0,0x1100
    
       .org 0x80
       nop
        
    _loop:
       j _loop
       nop
    


    8.5.2 測试分支指令

          測试代码例如以下,源文件是本书光盘CodeChapter8AsmTestTest2文件夹下的inst_rom.S文件。

    .org 0x0
       .set noat
       .set noreorder
       .set nomacro
       .global _start
    _start:
       ori  $3,$0,0x8000
       sll  $3,16               # 设置$3 = 0x80000000
       ori  $1,$0,0x0001        #(1)$1 = 0x1                
       b    s1                  # 转移到s1处
       ori  $1,$0,0x0002        #(2)$1 = 0x2,这是延迟槽指令
    1:
       ori  $1,$0,0x1111
       ori  $1,$0,0x1100
    
       .org 0x20
    s1:
       ori  $1,$0,0x0003        #(3)$1 = 0x3
       bal  s2                  # 转移到s2处,同一时候设置$31为0x2c
       div  $zero,$31,$1        #(4)此时$31 = 0x2c, $1 = 0x3,所以除法结果为
                                #    HI = 0x2, LO = 0xe,这是延迟槽指令
       ori  $1,$0,0x1100
       ori  $1,$0,0x1111
       bne  $1,$0,s3
       nop
       ori  $1,$0,0x1100
       ori  $1,$0,0x1111
    
       .org 0x50   
    s2:
       ori  $1,$0,0x0004      #(5)$1 = 0x4
       beq  $3,$3,s3          # $3等于$3,所以会发生转移,目的地址是s3
       or   $1,$31,$0         #(6)$1 = 0x2c,这是延迟槽指令
       ori  $1,$0,0x1111
       ori  $1,$0,0x1100
    2:
       ori  $1,$0,0x0007      #(9)$1 = 0x7
       ori  $1,$0,0x0008      #(10)$1 = 0x8
       bgtz $1,s4             # 此时$1为0x8,大于0,所以转移至标号s4处
       ori  $1,$0,0x0009      #(11)$1 = 0x9,这是延迟槽指令
       ori  $1,$0,0x1111
       ori  $1,$0,0x1100
    
       .org 0x80
    s3:
       ori  $1,$0,0x0005      #(7)$1 = 0x5            
       bgez $1,2b             # 此时$1为0x5,大于0,所以转移至前面的标号2处
       ori  $1,$0,0x0006      #(8)$1 = 0x6,这是延迟槽指令
       ori  $1,$0,0x1111
       ori  $1,$0,0x1100
    
       .org 0x100
    s4:
       ori  $1,$0,0x000a      #(12)$1 = 0xa              
       bgezal $3,s3           # 此时$3为0x80000000,小于0,所以不发生转移
       or   $1,$0,$31         #(13)$1 = 0x10c          
       ori  $1,$0,0x000b      #(14)$1 = 0xb
       ori  $1,$0,0x000c      #(15)$1 = 0xc
       ori  $1,$0,0x000d      #(16)$1 = 0xd
       ori  $1,$0,0x000e      #(17)$1 = 0xe
       bltz $3,s5             # 此时$3为0x80000000,小于0,所以发生转移,转移至s5处
       ori  $1,$0,0x000f      #(18)$1 = 0xf,这是延迟槽指令
       ori  $1,$0,0x1100
    
    
       .org 0x130
    s5:
       ori  $1,$0,0x0010      #(19)$1 = 0x10
       blez $1,2b             # 此时$1为0x10,大于0,所以不发生转移
       ori  $1,$0,0x0011      #(20)$1 = 0x11
       ori  $1,$0,0x0012      #(21)$1 = 0x12
       ori  $1,$0,0x0013      #(22)$1 = 0x13
       bltzal $3,s6           # 此时$3为0x80000000,小于0,所以发生转移,转移到s6处
       or   $1,$0,$31         #(23)$1 = 0x14c,这是延迟槽指令
       ori  $1,$0,0x1100
    
    
       .org 0x160
    s6:
       ori $1,$0,0x0014       #(24)$1 = 0x14
       nop
       
       
        
    _loop:
       j _loop
       nop
    

          上面的測试程序使用到了全部的分支指令,程序的凝视给出了寄存器$1的变化情况,及指令运行顺序,注意寄存器$1的变化是依照凝视中的序号顺序进行的。ModelSim仿真结果如图8-9所看到的,观察$1的变化可知OpenMIPS正确实现了分支指令。



    至此,转移指令也实现完成了,下一步将实现载入存储指令,敬请关注!

  • 相关阅读:
    NYOJ题目22 素数求和
    最大连续子序列&&MAX SUM
    Computer Transformation
    #转 二分查找
    吃巧克力
    公司年会
    亲和串
    开门人和关门人
    找新朋友
    big number
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4037514.html
Copyright © 2011-2022 走看看