• 自己写CPU第九阶段(5)——实现负载存储指令2(改变运行阶段)


    我们会继续上传新书《自己动手写CPU》。今天是第42篇。我尽量每周四篇,可是近期已经非常久没有实现这个目标了,一直都有事。不好意思哈。


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

    9.3.2 改动运行阶段

          1、改动EX模块

          在运行阶段的EX模块会计算载入存储的目的地址。參考图9-19可知,EX模块会添加部分接口,如表9-3所看到的。

         改动运行阶段的EX模块例如以下。

    完整代码位于本书附带光盘CodeChapter9_1文件夹下的ex.v文件。

    module ex(
    
      ......
    
      //新增输入接口inst_i,其值就是当前处于运行阶段的指令
      input wire[`RegBus]           inst_i,
    
      ......
    
      //以下新增的几个输出接口是为载入、存储指令准备的
      output wire[`AluOpBus]        aluop_o,
      output wire[`RegBus]          mem_addr_o,
      output wire[`RegBus]          reg2_o,
    
      ......
    );
    
      ......
    
      //aluop_o会传递到訪存阶段,届时将利用其确定载入、存储类型
      assign aluop_o = aluop_i;
    
      //mem_addr_o会传递到訪存阶段,是载入、存储指令相应的存储器地址,此处的reg1_i 
      //就是载入、存储指令中地址为base的通用寄存器的值。inst_i[15:0]就是指令中的
      //offset。通过mem_addr_o的计算。读者也能够明确为何要在译码阶段ID模块新增输
      //出接口inst_o
      assign mem_addr_o = reg1_i + {{16{inst_i[15]}},inst_i[15:0]};
    
      //reg2_i是存储指令要存储的数据,或者lwl、lwr指令要载入到的目的寄存器的原始值,
      //将该值通过reg2_o接口传递到訪存阶段
      assign reg2_o = reg2_i;
    
      ......


     

          2、改动EX/MEM模块

          參考图9-19可知,EX/MEM模块会添加部分接口,用于将EX模块新增的输出传递到訪存阶段,添加的接口描写叙述如表9-4所看到的。

          改动运行阶段的EX/MEM模块例如以下。仅仅是一个简单的传递操作。当流水线的运行阶段没有被暂停时。将来自运行阶段EX模块的输出传递到訪存阶段。完整代码请參考本书附带光盘CodeChapter9_1文件夹下的ex_mem.v文件。

    module ex_mem(
    
       ...... 	
    
       //为实现载入、存储指令而加入的输入接口
       input wire[`AluOpBus]        ex_aluop,
       input wire[`RegBus]          ex_mem_addr,
       input wire[`RegBus]          ex_reg2,
    
       ......
    
       //为实现载入、存储指令而加入的输出接口
       output reg[`AluOpBus]        mem_aluop,
       output reg[`RegBus]          mem_mem_addr,
       output reg[`RegBus]          mem_reg2,
    		
       ......
    );
    
    
       always @ (posedge clk) begin
         if(rst == `RstEnable) begin
            ......
            mem_aluop    <= `EXE_NOP_OP;
            mem_mem_addr <= `ZeroWord;
            mem_reg2     <= `ZeroWord;
         end else if(stall[3] == `Stop && stall[4] == `NoStop) begin
            ......
            mem_aluop    <= `EXE_NOP_OP;
            mem_mem_addr <= `ZeroWord;
            mem_reg2     <= `ZeroWord; 
         end else if(stall[3] == `NoStop) begin 
            ......
            mem_aluop    <= ex_aluop;
            mem_mem_addr <= ex_mem_addr;
            mem_reg2     <= ex_reg2;
         end else begin
            ......
         end
      end
    
    endmodule


    下一阶段将改变内存访问。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    Node.js基础学习一之Get请求
    Node.js学习准备篇
    如何在eclipse添加SVN菜单
    Java泛型的好处
    mybatis多数据源配置
    Python map() 函数
    python split()使用方法
    pythom os 模块
    深浅copy
    小数据池
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4604478.html
Copyright © 2020-2023  润新知