P6 习题分析 
wtd指令:
记temp1为GRF[rs]的32种循环移位的和 如: 123 + 231 + 321
temp2为GRF[rt]的32种循环移位的和 
if (temp1 > temp2) 则 把1写入rd 
else if  (temp1 < temp2) 则 把 -1写入rd
else 把0写入rd
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 controller wire  wtd = (opcode_DEin == 6'b0  && func_DEin == 6'b000011 ) ? 1  : 0 ;RegWrite_DEin = (wtd || ...) ? 1  : 0 ; RegDst_DEin = (wtd || ...) ? 2'b01  : ...   wire  isWtd_DEin = (wtd) ? 1  : 0 ;hazardStall wire  wtd = (opcode_DEin == 6'b0  && func_DEin == 6'b000011 ) ? 1  : 0 ;Tuse_RS = (wtd || ...) ? 0  : ...     Tuse_RT = (wtd || ...) ? 0  : ...     Tnew_DEin = (wtd || ...) ? 1  : ...   cauculate(          input  wire  [31 :0 ] A,     output  wire  [31 :0 ] B ) reg  [31 :0 ] ans;reg  [31 :0 ] temp;integer  i;always @(*) begin     ans = 32'b0 ;     temp = A;     for  (i = 0 ; i < 32 ; i = i + 1 ) begin          temp = {temp[0 ], temp[31 :1 ]};          ans = ans + temp;     end  end mips writeBack_DEin = (isWtd_DEin == 1  && (rs_sum > rt_sum)) ? 32'b1  : (isWtd_DEin == 1  && (rs_sum < rt_sum)) ? (32'b0  - 32'b1 ) : (isWtd_DEin == 1  && (rs_sum = rt_sum)) ? 32'b0  : ... writeBack_EMin = (isWtd_DEout == 1  || ...) ? writeBack_DEout : ... 
 
btd指令:
d = (GRF[rt] + GRF[rs])& 32’hfffffffe 
d << 1
无条件跳转到pc + 4 + ( d[29:0]  || 00 ) + offset
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 controller wire  btd = (opcode_DEin == 6'b111110 ) ? 1  : 0 ;Branch_DEin = (btd || ...) ? 1  : 0 ; EXTOp = (btd || ...) ? 2'b01  : ...     isBtd_DEin = (btd) ? 1  : 0 ; hazardStall wire  btd = (opcode_DEin == 6'b111110 ) ? 1  : 0 ;Tuse_RS = (btd || ...) ? 1  : 0 ;        Tuse_RT = (btd || ...) ? 1  : 0 ;        Tnew_DEin = (btd || ...) ? `minTnew;   cmp assign  zero_DEin = (isBtd) ? 1  : 0 ;mips wire  [31 :0 ] d = ((A1_DEin + A2_DEin)& 32'hfffffffe ) << 1 ;wire  [31 :0 ] distance = {d[29 :0 ], 2'b0 };assign  shift = (isBtd_DEin == 1 ) ? (distance + immExt_DEin); 
 
lwz指令:
和lw一样读出WD,把它的低5位与GRF[rt]的低5位进行异或,其值为X
找到小于等于X的最大质数,记为Y
把WD写入GRF[Y]
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 wire  stall_E = (isLwz_DEout == 1  && (rs_DEin == 质数 || rt_DEin == 质数)) ? 1  : 0 ;wire  stall_M = (isLwz_EMout == 1  && (RegAddr_MWin == rs_DEin || RegAddr_MWin == rt_DEin)) ? 1  : 0 ;wire  [4 :0 ] xor_ans = WD[4 :0 ] ^ A2[4 :0 ];wire  [4 :0 ] max_z = (xor_ans >= 31 ) ? 31  :(xor_ans >= 29 ) ? 29  : (xor_ans >= 23 ) ? 23  : (xor_ans >= 19 ) ? 19  : (xor_ans >= 17 ) ? 17  : (xor_ans >= 13 ) ? 13  : (xor_ans >= 11 ) ? 11  : (xor_ans >= 7 )  ? 7   : (xor_ans >= 5 )  ? 5   : (xor_ans >= 3 )  ? 3   : (xor_ans >= 2 )  ? 2   :  1 ; assign  RegAddr_MWin = (isLwz_EMout == 1 ) ? max_z : ...
 
lwc指令:
读出WD,WD是偶数则写入rt寄存器 , WD是奇数则写入31号寄存器
 
1 2 3 4 5 6 controller  assign  RegDst = (lwc|| ...) ? 2'b00  :           mips assign  stall_E = (isLwc_E == 1  &s& (rs_D == 31  || rt_D == 31 )) ? 1  : 0 ;assign  stall_M = (isLwc_M == 1  && RegAddr_M == 31  && (rs_D == 31  || rt_D == 31 )) ? 1  : 0 ; 
 
fmultu指令:
R型指令。具体操作为进行一个需要在乘除模块计算3个周期的计算指令,操作细节如下:
首先,对 GPR[rs] 和 GPR[rt] 进行64位无符号乘法,结果记为 prod。
若 prod 高32位为0,则把 prod[63:32] 保存到 HI 寄存器中,把 prod[31:0] 保存到 LO 寄存器中。
否则,我们找到 prod 中最高位1的出现位置 highbit_1 与 prod 中最低位0的出现位置 lowbit_0 (可以证明,这种情况下 prod 中必定存在至少一个1和一个0) 。之后,记 reverse_bit 为 highbit_1-lowbit_0 的绝对值,可以证明 reverse_bit 必定在 0∼63 内。最后,把 prod[reverse_bit] 进行翻转(0变成1,1变成0),将结果的高32位保存到 HI 寄存器中,将结果的低32位保存到 LO 寄存器中。
 
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 assign  start_DEin = (fmultu) ? 1  : 0 ;assign  isFmultu_DEin = (fmultu) ? 1  : 0 ;mult  reg  [63 :0 ] prod;reg  [5 :0 ] highbit_1;reg  [5 :0 ] lowbit_0;reg  [5 :0 ] reverse_bit;integer  i;always @(*) begin     if  (isFmultu_DEout == 1 ) begin          hold_unsign = {{1'b0 }, A} * {{1'b0 }, B};         prod = hold_unsign[63 :0 ];         if  (prod[63 :32 ] == 32'b0 ) begin              hi_hold = prod[63 :32 ];             lo_hold = prod[31 :0 ];         end          else  begin              for  (i = 63 ; i >= 0 ; i = i - 1 ) begin                  if  (prod[i] == 1 ) begin                      highbit_1 = i;                     break ;                 end              end              for  (i = 0 ; i < 64 ; i = i + 1 ) begin                  if  (prod[i] == 0 ) begin                      lowbit_0 = i;                     break ;                 end              end              reverse_bit = (highbit_1 - lowbit_0 > 0 ) ? highbit_1 - lowbit_0 : lowbit_0 - highbit_1;             prod[reverse_bit] = !prod[reverse_bit];             hi_hold = prod[63 :32 ];             lo_hold = prod[31 :0 ];         end      end  end always @(posedge  clk) begin     if  (isFmultu_DEout == 1 ) begin          pause <= 3 ;     end  end 
 
sbc指令:
把GRF[rs]分成31-24,23-16,15-8,7-0四个部分,统计每个部分1的个数。如果GRF[rt]是奇数,则将这四个部分按照升序排序组成一个新的数字,写入rd寄存器;如果GRF[rt]是偶数,则将这四个部分按照降序排序组成一个新的数字写入rd寄存器。(排序是稳定排序)
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 module  sort(    input  wire  [31 :0 ] A,     input  wire  way,                       output  wire  [31 :0 ] B );     reg  [7 :0 ] A[4 ];     reg  [4 :0 ] Num[4 ];     reg  [7 :0 ] holdA;     reg  [4 :0 ] holdN;     reg  [31 :0 ] B1;     reg  [31 :0 ] B2;     integer  i;     integer  j;          always @(*) begin          A[3 ] = A[31 :24 ];         A[2 ] = A[23 :16 ];         A[1 ] = A[15 :8 ];         A[0 ] = A[7 :0 ];         Num[3 ] = A[3 ][0 ] + A[3 ][1 ] + A[3 ][2 ] + A[3 ][3 ] + A[3 ][4 ] + A[3 ][5 ] + A[3 ][6 ] + A[3 ][7 ];         Num[2 ] = A[2 ][0 ] + A[2 ][1 ] + A[2 ][2 ] + A[2 ][3 ] + A[2 ][4 ] + A[2 ][5 ] + A[2 ][6 ] + A[2 ][7 ];         Num[1 ] = A[1 ][0 ] + A[1 ][1 ] + A[1 ][2 ] + A[1 ][3 ] + A[1 ][4 ] + A[1 ][5 ] + A[1 ][6 ] + A[1 ][7 ];         Num[0 ] = A[0 ][0 ] + A[0 ][1 ] + A[0 ][2 ] + A[0 ][3 ] + A[0 ][4 ] + A[0 ][5 ] + A[0 ][6 ] + A[0 ][7 ];                  for  (i = 3 ; i > 0 ; i = i - 1 ) begin              for  (j = 3 ; j > 3  - i; j = j - 1 ) begin                  if  (Num[j] < Num[j - 1 ]) begin                      holdN = Num[j];                     holdA = A[j];                     Num[j] = Num[j - 1 ];                     A[j] = A[j - 1 ];                     Num[j - 1 ] = holdN;                     A[j - 1 ] = holdA;                 end              end          end          B1 = {A[3 ], A[2 ], A[1 ], A[0 ]};                      for  (i = 3 ; i > 0 ; i = i - 1 ) begin              for  (j = 3 ; j > 3  - i; j = j - 1 ) begin                  if  (Num[j] > Num[j - 1 ]) begin                      holdN = Num[j];                     holdA = A[j];                     Num[j] = Num[j - 1 ];                     A[j] = A[j - 1 ];                     Num[j - 1 ] = holdN;                     A[j - 1 ] = holdA;                 end              end          end          B2 = {A[3 ], A[2 ], A[1 ], A[0 ]};                      assign  B = (way == 1 ) ? B1 : B2;     end  
 
lwm指令:
按照lw的方式从内存中读出的数记作WD,把WD写入WD - GRF[rt]号寄存器。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 controller  wire  lwm = (opcode_DEin == 6'b111110 ) ? 1  : 0 ;RegWrite_DEin = (lwm || ...) ? 1  : 0 ; MemRead_DEin = (lwm || ...) ? 1  : 0 ; MemtoReg_DEin = (lwm || ...) ? 1  : 0 ; word_DEin = (lwm || ...) ? 1  : 0 ; EXTOp = (lwm || ...) ? 2'b01  : ...     isLwm_DEin = (lwm) ? 1  : 0 ; HazardStall wire  lwm = (opcode_DEin == 6'b111110 ) ? 1  : 0 ;Tuse_RS = (lwm || ...) ? 1  : ...; Tuse_RT = (lwm || ...) ? 2  : ...; Tnew_DEin = (lwm || ...) ? 3  : ...; mips stall_E = (isLwm_DEout === 1 ) ? 1  : 0 ; stall_M = (isLwm_EMout === 1  && RegAddr_MWin !== 5'b0  &&(RegAddr_MWin === rs_DEin || RegAddr_WMin === rt_DEin)) ? 1  : 0 ; wire  [31 :0 ] lwm_sub = WD - A2_MWin;RegAddr_MWin = (isLwm_EMout === 1 ) ? lwm_sub[4 :0 ] : RegAddr_EMout;