CPU设计实战 lab3 第四章实践任务一

第一个bug

debug_wb_pc = 0xxxxxxxxx

可看到信号为X,X是不定值,而这种错误往往是下面两种原因之一导致的:

  1. RTL里声明为reg型的变量从未被赋值

  2. RTL里存在多驱动的代码

首先,从第一种情况开始排查,由变量名debug_wb_pc可知该变量应该位于写回阶段里,打开WB_stage.v,查找变量debug_wb_pc,

发现:

 assign debug_wb_pc    = ws_pc;

可知debug_wb_pc的值由ws_pc得到,所以下一步就是查找wc_pc的值是从哪里得到的,发现:

 assign {ws_gr_we       ,  //69:69
         ws_dest        ,  //68:64
         ws_final_result,  //63:32
         ws_pc             //31:0
        } = ms_to_ws_bus_r;

ws_pc的值与ms_to_ws_bus_r有关,继续查找ms_to_ws_bus_r的值是从哪里得到的,发现:

 always @(posedge clk) begin
     if (reset) begin
         ws_valid <= 1'b0;
     end
     else if (ws_allowin) begin
         ws_valid <= ms_to_ws_valid;
     end
 ​
     if (ms_to_ws_valid && ws_allowin) begin
         ms_to_ws_bus_r = ms_to_ws_bus;
     end
 end

发现ms_to_ws_bus_r的值与ms_to_ws_bus有关,实际上这里有一个小bug,在always语句里应该使用非阻塞赋值,而这里使用的是阻塞赋值,将ms_to_ws_bus_r = ms_to_ws_bus;修改为ms_to_ws_bus_r <= ms_to_ws_bus;我原本以为这就是第一个bug,结果我运行仿真的时候发现还是报debug_wb_pc = 0xxxxxxxxx这个错,那说明真的的bug我还没找到,所以就继续以ms_to_ws_bus往下找,由名字ms_to_ws_bus可看出它与访存阶段和写回阶段有关,写回阶段没发现什么问题,所以去访存阶段里找,打开MEM_stage.v,发现:

 assign ms_to_ws_bus = {ms_gr_we       ,  //69:69
                        ms_dest        ,  //68:64
                        ms_final_result,  //63:32
                        ms_pc             //31:0
                       };

ms_to_ws_bus与ms_gr_we,ms_dest,ms_final_result,ms_pc 有关,接着继续找ms_gr_we,ms_dest,ms_final_result,ms_pc这些变量和谁有关,发现:

 assign {ms_res_from_mem,  //70:70
         ms_gr_we       ,  //69:69
         ms_dest        ,  //68:64
         ms_alu_result  ,  //63:32
         ms_pc             //31:0
        } = es_to_ms_bus_r;

与es_to_ms_bus_r有关,而:

 es_to_ms_bus_r <= es_to_ms_bus;

所以接下来要排查的变量便是es_to_ms_bus;到这里就可以发现接下来的步骤就和上面排查ms_to_ws_bus的步骤一样了。打开EXE.stage.v,可发现es_to_ms_bus与ds_to_es_bus_r有关,而ds_to_es_bus_r的值又与ds_to_es_bus相关,所以下一步就是打开ID_stage.v继续排查,步骤还是和上面一样,首先发现ds_to_es_bus与fs_to_ds_bus_r有关,到这里终于发现了问题:

 always @(posedge clk) begin
     if (fs_to_ds_valid && ds_allowin) begin
         fs_to_ds_bus_r <= fs_to_ds_bus;
     end
 end

发现在这个always中没有对ds_valid进行赋值,ds_valid是译码级的有效位,当他的值为1时表示该流水线上当前时钟周期存在有效的数据,值为0时表示该流水线上当前时钟周期为空。具体可看CPU设计实战P55页。

将代码修改为:

 always @(posedge clk) begin
    //第一个bug
     if(reset) begin
         ds_valid = 1'b0;
     end
     if(ds_allowin) begin
         ds_valid <= fs_to_ds_valid;
     end
     //
     if (fs_to_ds_valid && ds_allowin) begin
         fs_to_ds_bus_r <= fs_to_ds_bus;
     end
 end

解决第一个bug。

第二个bug

[ 2067 ns] Error!!! reference: PC = 0xbfc00000, wb_rf_wnum = 0x08, wb_rf_wdata = 0xffffffff mycpu : PC = 0xbfc00000, wb_rf_wnum = 0x08, wb_rf_wdata = 0xxxxxxxxX

由报错信息可知wb_rf_wdata的值应该为0xffffffff,而现在却是0xxxxxxxxX,而出现X的常见原因在第一个bug里已说明,下面要做的就是找到bug位于哪里,由变量名wb_rf_wdata可知,该变量应该在访存阶段,打开WB.stage.v,找到wb_rf_wdata变量发现:

 assign debug_wb_rf_wdata = ws_final_result;

继续查找wc_final_result与什么有关:

 assign {ws_gr_we       ,  //69:69
         ws_dest        ,  //68:64
         ws_final_result,  //63:32
         ws_pc             //31:0
        } = ms_to_ws_bus_r;

发现wc_final_result是由ms_to_ws_bus_r赋值的,由ms_to_ws_bus_r继续找下去,发现:

  ms_to_ws_bus_r <= ms_to_ws_bus;

所以接下来找ms_to_ws_bus和什么相关,打开MEM_stage.v查找ms_to_ws_bus发现:

 assign ms_to_ws_bus = {ms_gr_we       ,  //69:69
                        ms_dest        ,  //68:64
                        ms_final_result,  //63:32
                        ms_pc             //31:0
                       };

由此可知,ws_final_result的值是由ms_final_result传递过去的,接下来查找ms_final_result发现:

 assign ms_final_result = ms_res_from_mem ? mem_result
                                          : ms_alu_result;

这时候就找到问题所在了,查看该波形发现ms_res_from_mem的值为Z,这便是导致出错的其中一个原因,但是这并不是最根本的原因,根本原因是找到ms_res_from_mem的值为什么是Z。而信号为Z这种错误往往是由下面两个原因导致的:

  1. RTL里声明为wire型的变量从未被赋值。

  2. 模块调用的信号未连接导致信号悬空。

接下来就是排查ms_res_from_mem出现Z的原因,发现:

 assign {ms_res_from_mem,  //70:70
         ms_gr_we       ,  //69:69
         ms_dest        ,  //68:64
         ms_alu_result  ,  //63:32
         ms_pc             //31:0
        } = es_to_ms_bus_r;

所以接下来查找es_to_ms_bus_r和什么有关,发现es_to_ms_bus_r的值是由es_to_ms_bus赋值得到的,所以接下来排查es_to_ms_bus,打开MEM_stage.v,查找es_to_ms_bus发现:

 assign es_to_ms_bus = {es_res_from_mem,  //70:70
                        es_gr_we       ,  //69:69
                        es_dest        ,  //68:64
                        es_alu_result  ,  //63:32
                        es_pc             //31:0
                       };

ms_res_from_mem的值由es_res_from_mem得到,紧接着发现:

 assign es_res_from_mem = es_load_op;

查找es_load_op发现:

 assign {es_alu_op      ,  //135:124
         es_load_op     ,  //123:123   
         es_src1_is_sa  ,  //122:122
         es_src1_is_pc  ,  //121:121
         es_src2_is_imm ,  //120:120
         es_src2_is_8   ,  //119:119
         es_gr_we       ,  //118:118
         es_mem_we      ,  //117:117
         es_dest        ,  //116:112
         es_imm         ,  //111:96
         es_rs_value    ,  //95 :64
         es_rt_value    ,  //63 :32
         es_pc             //31 :0
        } = ds_to_es_bus_r;

发现es_load_op与ds_to_es_bus_r有关,而ds_to_es_bus_r的值又与ds_to_es_bus有关,接下来排查ds_to_es_bus,打开ID_stage.v,查找ds_to_es_bus,发现:

 assign ds_to_es_bus = {alu_op      ,  //135:124
                        load_op     ,  //123:123
                        src1_is_sa  ,  //122:122
                        src1_is_pc  ,  //121:121
                        src2_is_imm ,  //120:120
                        src2_is_8   ,  //119:119
                        gr_we       ,  //118:118
                        mem_we      ,  //117:117
                        dest        ,  //116:112
                        imm         ,  //111:96
                        rs_value    ,  //95 :64
                        rt_value    ,  //63 :32
                        ds_pc          //31 :0
                       };

与上面的ds_to_es_bus_r对照发现es_load_op的值由load_op得到,接下来查找load_op,发现load_op只进行了定义:

 wire        load_op;

却未对load_op赋值,这就是导致前面信号出现Z的原因,接下来我们要给load_op赋值,而给load_op赋什么值呢?我们需要看load_op用于什么指令,因为load_op用在ds_to_es_bus,所以我们向执行阶段找,回到MEM_stage.v,查找ds_to_es_bus发现ds_to_es_bus_r用到了ds_to_es_bus的值,继续查看ds_to_es_bus_r发现:

 assign {es_alu_op      ,  //135:124
         es_load_op     ,  //123:123
         es_src1_is_sa  ,  //122:122
         es_src1_is_pc  ,  //121:121
         es_src2_is_imm ,  //120:120
         es_src2_is_8   ,  //119:119
         es_gr_we       ,  //118:118
         es_mem_we      ,  //117:117
         es_dest        ,  //116:112
         es_imm         ,  //111:96
         es_rs_value    ,  //95 :64
         es_rt_value    ,  //63 :32
         es_pc             //31 :0
        } = ds_to_es_bus_r;

其中包括es_load_op,在前面的分析中我们知道es_load_op和load_op的值一样,所以接下来我们排查es_load_op发现:

 assign es_res_from_mem = es_load_op;

发现与es_res_from_mem有关,从这可以看出load_op指令是一条与访存有关的指令。(实际上该结论在我们前面排查的时候应该就已经得到了)而lab3一共实现了19条指令,这19条指令里只有两条和访存有关,①LW(取字),②SW(存字)。这里很明显访存是取字,所以我们知道了load_op在这里应该执行的是LW指令,所以回到ID_stage.v添加代码给load_op赋值:

 assign load_op = inst_lw;

至此第二个bug解决。

第三个bug

[ 2067 ns] Error!!! reference: PC = 0xbfc00000, wb_rf_wnum = 0x08, wb_rf_wdata = 0xffffffff mycpu : PC = 0xbfc00000, wb_rf_wnum = 0x08, wb_rf_wdata = 0xfffffffe

从报错可以看出是wb_rf_wdata的值应该是0xffffffff而此时是0xfffffffe,下面要做的就是找到bug位于哪里,由变量名wb_rf_wdata可知,该变量应该在访存阶段,打开WB.stage.v,找到wb_rf_wdata变量发现:

 assign debug_wb_rf_wdata = ws_final_result;

继续查找wc_final_result与什么有关:

 assign {ws_gr_we       ,  //69:69
         ws_dest        ,  //68:64
         ws_final_result,  //63:32
         ws_pc             //31:0
        } = ms_to_ws_bus_r;

发现wc_final_result是由ms_to_ws_bus_r赋值的,由ms_to_ws_bus_r继续找下去,发现:

  ms_to_ws_bus_r <= ms_to_ws_bus;

所以接下来找ms_to_ws_bus和什么相关,打开MEM_stage.v查找ms_to_ws_bus发现:

 assign ms_to_ws_bus = {ms_gr_we       ,  //69:69
                        ms_dest        ,  //68:64
                        ms_final_result,  //63:32
                        ms_pc             //31:0
                       };

由此可知,ws_final_result的值是由ms_final_result传递过去的,接下来查找ms_final_result发现:

 assign ms_final_result = ms_res_from_mem ? mem_result
                                          : ms_alu_result;

ms_final_result的值由该问号表达式决定,通过查看波形发现ms_res_from_mem的值为0,所以ms_final_result=ms_alu_result,ms_alu_result的值出错就是导致错误的原因,下面继续追ms_alu_result发现:

 assign {ms_res_from_mem,  //70:70
         ms_gr_we       ,  //69:69
         ms_dest        ,  //68:64
         ms_alu_result  ,  //63:32
         ms_pc             //31:0
        } = es_to_ms_bus_r;

ms_alu_result与es_to_ms_bus_r有关,而es_to_ms_bus_r又与es_to_ms_bus有关,接下来打开EXE_stage.v,查找es_to_ms_bus发现:

 assign es_to_ms_bus = {es_res_from_mem,  //70:70
                        es_gr_we       ,  //69:69
                        es_dest        ,  //68:64
                        es_alu_result  ,  //63:32
                        es_pc             //31:0
                       };

所以 ms_alu_result的值由es_alu_result得到,接下来排查es_alu_result发现:

 alu u_alu(
     .alu_op     (es_alu_op    ),
     .alu_src1   (es_alu_src2  ), //调用错误
     .alu_src2   (es_alu_src2  ),
     .alu_result (es_alu_result)
     );

这这里终于发现了错误:.alu_src1传参错误,应该传入es_alu_src1才对,修改代码如下:

 alu u_alu(
     .alu_op     (es_alu_op    ),
     .alu_src1   (es_alu_src1  ),
     .alu_src2   (es_alu_src2  ),
     .alu_result (es_alu_result)
     );

至此第三个bug解决。

第四个bug

[ 2107 ns] Error!!! reference: PC = 0xbfc0038c, wb_rf_wnum = 0x04, wb_rf_wdata = 0xbfb00000 mycpu : PC = 0xbfc00010, wb_rf_wnum = 0x08, wb_rf_wdata = 0x80000000

看到这个报错后,发现是PC的值出错,PC此时的值应该是0xbfc0038c,但是实际PC的值确是0xbfc00010,运行仿真后,查看各阶段的PC:

在PC=0xbfc00010以前,发现均是按顺序执行PC=PC+4,未发现什么异常,而结果却显示此时正确的PC值应该是0xbfc0038c,所以想到可能是PC值为0xbfc00010前面的指令中包含有跳转指令但实际却未执行跳转指令导致的,要想知道这个需要打开CPU_CDE\soft\func_lab3\obj目录下的test.s(该文件是生成的反汇编文件)文件,打开后可看到指令的执行过程,查找0xbfc00010前的指令,结果发现在PC=0xbfc00008时,应该执行跳转指令且可看到跳转的地址刚好是正确的PC地址,现在我们找到了错误的原因,接下来就是解决为什么在PC=0xbfc00008时没有发生跳转。

由于取指阶段使用来取出指令的,所以我们先看取指阶段,打开IF_stage.v,找和pc有关的变量,首先是fs_pc,发现:

 fs_pc <= nextpc;

发现去与nextpc有关,接着找nextpc的和什么相关,发现:

 assign nextpc       = br_taken ? br_target : seq_pc; 
 assign seq_pc       = fs_pc + 3'h4;

可看到当br_taken为0时nextpc=seq_pc,而seq_pc=fs_pc+3'h4,即当br_taken为0时顺序执行,当br_taken值为1时,nextpc =br_target,此时将执行跳转。通过查看波形可看到,在fs_pc=bfc00008时,br_taken的值为0,这便是错误的原因,此时应该执行跳转指令,br_taken的值应该为1才对。下面就分析为什么br_taken的值出现错误。

首先,发现:

 assign {br_taken,br_target} = br_bus;

br_taken的值与br_bus有关,接下来寻找br_bus和什么有关,打开ID_stage.v,查找br_bus,发现在译码阶段:

 assign br_bus       = {br_taken,br_target};

而br_taken,和br_target的值又和下面的变量有关:

 assign br_taken = (   inst_beq  &&  rs_eq_rt
                    || inst_bne  && !rs_eq_rt
                    || inst_jal
                    || inst_jr
                   ) && ds_valid;
 assign br_target = (inst_beq || inst_bne) ? (fs_pc + {{14{imm[15]}}, imm[15:0], 2'b0}) :
                    (inst_jr)              ? rs_value :
                   /*inst_jal*/              {fs_pc[31:28], jidx[25:0], 2'b0};

查看波形可知此时br_taken的值为1,在当前阶段时正确的,可传给br_bus后就出错了,这时发现br_bus好像并没有接受到br_taken的值,因为此时assign br_bus = {br_taken,br_target};应该是拼接后的结果,可看到br_bus只与br_target的值相同,细心观察后发现,br_bus的位宽设置错了,应该是33位,而这里却只有32位,这便是出错的原因,br_bus根本没用接收到br_taken的值。

 查找定义br_bus的位置,发现:

   output [`BR_BUS_WD       -1:0] br_bus

打开mycpu.h

 `ifndef MYCPU_H
     `define MYCPU_H
 ​
     `define BR_BUS_WD       32
     `define FS_TO_DS_BUS_WD 64
     `define DS_TO_ES_BUS_WD 136
     `define ES_TO_MS_BUS_WD 71
     `define MS_TO_WS_BUS_WD 70
     `define WS_TO_RF_BUS_WD 38
 `endif

果然发现BR_BUS_WD为32,而它应该是33,修改代码如下:

 `ifndef MYCPU_H
     `define MYCPU_H
 ​
     `define BR_BUS_WD       33
     `define FS_TO_DS_BUS_WD 64
     `define DS_TO_ES_BUS_WD 136
     `define ES_TO_MS_BUS_WD 71
     `define MS_TO_WS_BUS_WD 70
     `define WS_TO_RF_BUS_WD 38
 `endif

至此第四个bug解决。

第五个bug

----[ 716985 ns] Number 8'd09 Functional Test Point PASS!!!

FATAL_ERROR: Vivado Simulator kernel has discovered an exceptional condition from which it cannot recover. Process will terminate. For technical support on this issue, please open a WebCase with this project attached at Support. Time: 717915 ns Iteration: 1 Process: /tb_top/soc_lite/data_ram/inst/native_mem_module.blk_mem_gen_v8_4_4_inst/NetRegassign3314_721 File: H:/CPU/CPU_CDE/mycpu_verify/run_vivado/mycpu_prj1/mycpu_prj1.ip_user_files/ipstatic/simulation/blk_mem_gen_v8_4.v

这个报错很奇怪,实际上也算不上是报错,只不过是运行着的时候一直卡死在Number 8'd09 Functional Test Point PASS!!!,卡的时间长了就出现了FATAL_ERROR。CPU设计实战P119页介绍了出现cpu卡死的情况该怎么去调,结合课本的内容、查看反汇编代码、以及比对golden_trace.txt。找了大半天都没发现问题出在哪里,最后去求助了学长,发现问题出现在alu.v中,里面出现了环路导致CPU卡死。具体原因如下:

 assign or_result  = alu_src1 | alu_src2 | alu_result;
 assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
                   | ({32{op_slt       }} & slt_result)
                   | ({32{op_sltu      }} & sltu_result)
                   | ({32{op_and       }} & and_result)
                   | ({32{op_nor       }} & nor_result)
                   | ({32{op_or        }} & or_result)
                   | ({32{op_xor       }} & xor_result)
                   | ({32{op_lui       }} & lui_result)
                   | ({32{op_sll       }} & sll_result)
                   | ({32{op_srl|op_sra}} & sr_result);

alu_result的结果由or_result赋值,而or_result的结果却又由alu_result赋值,就这样产生了环路,导致结果出错,修改代码如下:

 assign or_result  = alu_src1 | alu_src2;
 assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
                   | ({32{op_slt       }} & slt_result)
                   | ({32{op_sltu      }} & sltu_result)
                   | ({32{op_and       }} & and_result)
                   | ({32{op_nor       }} & nor_result)
                   | ({32{op_or        }} & or_result)
                   | ({32{op_xor       }} & xor_result)
                   | ({32{op_lui       }} & lui_result)
                   | ({32{op_sll       }} & sll_result)
                   | ({32{op_srl|op_sra}} & sr_result);

至此第五个bug解决(还是不太清楚怎么调试出来的)。

第六个bug

[ 888537 ns] Error!!! reference: PC = 0xbfc88c90, wb_rf_wnum = 0x02, wb_rf_wdata = 0xadff20c0 mycpu : PC = 0xbfc88c90, wb_rf_wnum = 0x02, wb_rf_wdata = 0x2dff20c0

从报错信息上来看,PC值是对的,但是wb_rf_wdata的值是错的,从报错可以看出是wb_rf_wdata的值应该是0xadff20c0而此时是0x2dff20c0,下面要做的就是找到bug位于哪里,由变量名wb_rf_wdata可知,该变量应该在访存阶段,打开WB.stage.v,找到wb_rf_wdata变量发现:

 assign debug_wb_rf_wdata = ws_final_result;

继续查找wc_final_result与什么有关:

 assign {ws_gr_we       ,  //69:69
         ws_dest        ,  //68:64
         ws_final_result,  //63:32
         ws_pc             //31:0
        } = ms_to_ws_bus_r;

发现wc_final_result是由ms_to_ws_bus_r赋值的,由ms_to_ws_bus_r继续找下去,发现:

  ms_to_ws_bus_r <= ms_to_ws_bus;

所以接下来找ms_to_ws_bus和什么相关,打开MEM_stage.v查找ms_to_ws_bus发现:

 assign ms_to_ws_bus = {ms_gr_we       ,  //69:69
                        ms_dest        ,  //68:64
                        ms_final_result,  //63:32
                        ms_pc             //31:0
                       };

由此可知,ws_final_result的值是由ms_final_result传递过去的,接下来查找ms_final_result发现:

 assign ms_final_result = ms_res_from_mem ? mem_result
                                          : ms_alu_result;

ms_final_result的值由该问号表达式决定,通过查看波形发现ms_res_from_mem的值为0,所以ms_final_result=ms_alu_result,ms_alu_result的值出错就是导致错误的原因,下面继续追ms_alu_result发现:

 assign {ms_res_from_mem,  //70:70
         ms_gr_we       ,  //69:69
         ms_dest        ,  //68:64
         ms_alu_result  ,  //63:32
         ms_pc             //31:0
        } = es_to_ms_bus_r;

ms_alu_result与es_to_ms_bus_r有关,而es_to_ms_bus_r又与es_to_ms_bus有关,接下来打开EXE_stage.v,查找es_to_ms_bus发现:

 assign es_to_ms_bus = {es_res_from_mem,  //70:70
                        es_gr_we       ,  //69:69
                        es_dest        ,  //68:64
                        es_alu_result  ,  //63:32
                        es_pc             //31:0
                       };

所以 ms_alu_result的值由es_alu_result得到,接下来排查es_alu_result发现:

 alu u_alu(
     .alu_op     (es_alu_op    ),
     .alu_src1   (es_alu_src1 ), 
     .alu_src2   (es_alu_src2  ),
     .alu_result (es_alu_result)
     );

通过波形查看es_alu_result的值发现,此时es_alu_result的值为0x2dff20c0,因为.alu_result是output变量,所以判断是ALU内部出现了错误,我们先查看一下PC=0xbfc88c90执行的是什么操作,打开test.s查看反汇编代码,搜索xbfc88c90,发现:

 bfc88c90:   00081002    srl v0,t0,0x0

所以执行的是SRL逻辑右移操作,接下来打开alu.v排查SRL相关代码,首先看到控制信号op_srl,通过波形查看到op_srl此时的值确实是1,接着继续查找发现:

 assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
                   | ({32{op_slt       }} & slt_result)
                   | ({32{op_sltu      }} & sltu_result)
                   | ({32{op_and       }} & and_result)
                   | ({32{op_nor       }} & nor_result)
                   | ({32{op_or        }} & or_result)
                   | ({32{op_xor       }} & xor_result)
                   | ({32{op_lui       }} & lui_result)
                   | ({32{op_sll       }} & sll_result)
                   | ({32{op_srl|op_sra}} & sr_result); // op_srl表示逻辑右移,op_sra表示算术右移 

可看到当op_srl的值为1的时候,alu_result=sr_result,接下来查看sr_result的值和什么有关,发现:

 // SRL, SRA result
 assign sr64_result = {{32{op_sra & alu_src2[31]}}, alu_src2[31:0]} >> alu_src1[4:0];
 assign sr_result   = sr64_result[30:0];

看到这里,通过波形查看sr64_result的值,发现是0xadff20c0(10101101111111110010000011000000),而sr_result的值是0x2dff20c0(00101101111111110010000011000000)只有一位的差别,这下就明白了,错误的原因就是sr64_result[30:0]这里位宽写错了,应该是32位,而这里只有31位,修改代码如下:

 // SRL, SRA result
 assign sr64_result = {{32{op_sra & alu_src2[31]}}, alu_src2[31:0]} >> alu_src1[4:0];
 assign sr_result   = sr64_result[31:0];

值得一提的是这里通过利用op_sra & alu_src2[31]巧妙的将逻辑右移和算术右移的结果都用sr_result来表示,当op_sra为0时表示执行的是SRL(逻辑右移),右移后左边补32个0,sr64_result[31:0]就是逻辑右移的结果。当op_sra为1时,表示执行的是SRA(算术右移),右移后左边补32个符号位(正数补0,负数补1),此时sr64_result[31:0]就是算术右移的结果。

至此第六个bug解决,第四章实践任务一的所有bug全部解决。

此时测试已通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值