CPU设计实战 第六章(上)

本章在第五章基础上,继续在流水线中添加转移指令和访存指令。

转移指令的添加

本章一共添加8条转移指令,其中6条(BGEZ、GBTZ、BLEZ、BLTZ、BLTZAL、BGEZAL)分支指令,2条(J、JALR)跳转指令。八条指令的功能及指令格式如下:

1. BGEZ
BGEZ指令格式

2. BGTZ
在这里插入图片描述
在这里插入图片描述
3. BLEZ
在这里插入图片描述
4. BLTZ
在这里插入图片描述
5. BLTZAL
在这里插入图片描述
6. BGEZAL
在这里插入图片描述
7. J
在这里插入图片描述
8.JALR
在这里插入图片描述
在这里插入图片描述
转移指令的功能有两个要素:一是决定是否跳转,二是跳转地址的计算。根据对上述8条转移指令的分析,可知转移指令的跳转目标的计算方式有三种,一是转移延迟槽指令PC加上转移指令中的立即数左移两位做有符号扩展的值、二是转移延迟槽指令的PC的高4位与转移指令中的立即数左移两位后进行拼接的值、三是rs号寄存器的值。还要特别注意BGEZAL、BLTZAL和JALR指令需要将PC+8(转移延迟槽之后的指令PC,即返回地址)分别写入到$31和rd号寄存器。
综上,我们需要在译码阶段新增转移指令,在现有的处理框架之下去实现新的跳转控制信号、跳转目标以及是否需要向通用寄存器写入返回地址。对于6条分支指令,我们可以参照BEQ、BNE指令在译码阶段使用rs_eq_rt(rs==rt)进行转移条件判断的形式,增加rs_gez(rs>=0)、rs_gtz(rs>0)、rs_lez(rs<=0)、rs_ltz(rs<0)四个信号,并对跳转条件是否成立(br_taken)、跳转目标(br_target)进行相应修改。
ID_stage.v

wire        inst_bgez;
wire        inst_bgtz;
wire        inst_blez;
wire        inst_bltz;
wire        inst_j;
wire        inst_bltzal;
wire        inst_bgezal;
wire        inst_jalr;
assign inst_bgez   = op_d[6'h01] & rt_d[5'h01];
assign inst_bgtz   = op_d[6'h07] & rt_d[5'h00];
assign inst_blez   = op_d[6'h06] & rt_d[5'h00];
assign inst_bltz   = op_d[6'h01] & rt_d[5'h00];
assign inst_j      = op_d[6'h02];
assign inst_bltzal = op_d[6'h01] & rt_d[5'h10];
assign inst_bgezal = op_d[6'h01] & rt_d[5'h11];
assign inst_jalr   = op_d[6'h00] & func_d[6'h09] & rt_d[5'h00]& sa_d[5'h00];
wire        rs_gez;
wire        rs_gtz;
wire        rs_lez;
wire        rs_ltz;
assign inst_no_dest =inst_beq | inst_bne | inst_jr | inst_sw |inst_bgez 
                     |inst_bgtz |inst_blez |inst_bltz |  inst_j ;
assign alu_op[ 0] = inst_addu | inst_addiu | inst_lw | inst_sw | inst_jal 
                   | inst_add | inst_addi|inst_bltzal | inst_bgezal 
                   |inst_jalr;
assign src1_is_pc   = inst_jal | inst_bltzal | inst_bgezal | inst_jalr;
assign src2_is_8    = inst_jal | inst_bltzal | inst_bgezal | inst_jalr;
assign dst_is_r31   = inst_jal | inst_bltzal | inst_bgezal;//将跳转指令后第二条指令的pc值返回到$31号寄存器,即pc+8 -> $31                           
assign gr_we        = ~inst_sw & ~inst_beq & ~inst_bne & ~inst_jr & ~inst_j
                       & ~inst_mthi & ~inst_mtlo & ~inst_mult & ~inst_multu 
                       & ~inst_div & ~inst_divu & ~inst_bgez & ~inst_bgtz 
                       & ~inst_blez & ~inst_bltz;
assign rs_gez = (rs_value[31] == 1'b0 || rs_value == 32'd0);//rs>=0
assign rs_gtz = (rs_value[31] == 1'b0 && rs_value != 32'd0);//rs>0
assign rs_lez = (rs_value[31] == 1'b1 || rs_value == 32'd0);//rs<=0
assign rs_ltz = (rs_value[31] == 1'b1 && rs_value != 32'd0);//rs<0  
assign br_taken = (   inst_beq  &&  rs_eq_rt
                   || inst_bne  && !rs_eq_rt
                   || inst_bgez && rs_gez 
                   || inst_bgtz && rs_gtz
                   || inst_blez && rs_lez
                   || inst_bltz && rs_ltz
                   || inst_bltzal && rs_ltz
                   || inst_bgezal && rs_gez
                   || inst_jal
                   || inst_jr
                   || inst_j
                   || inst_jalr
                  ) && ds_valid; 
assign br_target = (inst_beq || inst_bne || inst_bgez || inst_bgtz ||
                    inst_blez|| inst_bltz || inst_bltzal || inst_bgezal) ? 
                    (fs_pc + {{14{imm[15]}}, imm[15:0], 2'b0}) :
                   (inst_jr || inst_jalr) ? rs_value : 
                    {fs_pc[31:28], jidx[25:0], 2'b0};                                       

至此转移指令添加完成,关于访存指令的添加将在下一篇中介绍。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值