Verilog

31条指令单周期cpu设计(Verilog)-(八)上代码→指令译码以及控制器

详解31条MIPS单周期CPU的指令译码器和控制器Verilog代码实现,包括指令译码逻辑、控制器真值表实现、以及与数据通路的连接方式。

说在前面

  • 开发环境:Vivado
  • 语言:Verilog
  • cpu框架:Mips
  • 控制器:组合逻辑

指令译码器

  • 我们需要根据一条32位的指令的结构确定是哪一条指令
  • 可以根据操作码(op)以及功能码(func),使用case语句确定(下述代码中case语句顺序与上表相同)
    `timescale 1ns / 1ns
    module instr_dec(
      input [31:0] instr_code,
      output reg [31:0] i
      );
      wire [11:0] t;
      assign t = {instr_code[31:26],instr_code[5:0]};
      always @ (*)
      begin
          casez(t)
              12'b000000100000 :i = 32'b00000000000000000000000000000001;
              12'b000000100001 :i = 32'b00000000000000000000000000000010;
              12'b000000100010 :i = 32'b00000000000000000000000000000100;
              12'b000000100011 :i = 32'b00000000000000000000000000001000;
              12'b000000100100 :i = 32'b00000000000000000000000000010000;
              12'b000000100101 :i = 32'b00000000000000000000000000100000;
              12'b000000100110 :i = 32'b00000000000000000000000001000000;
              12'b000000100111 :i = 32'b00000000000000000000000010000000;
              12'b000000101010 :i = 32'b00000000000000000000000100000000;
              12'b000000101011 :i = 32'b00000000000000000000001000000000;
              12'b000000000000 :i = 32'b00000000000000000000010000000000;
              12'b000000000010 :i = 32'b00000000000000000000100000000000;
              12'b000000000011 :i = 32'b00000000000000000001000000000000;
              12'b000000000100 :i = 32'b00000000000000000010000000000000;
              12'b000000000110 :i = 32'b00000000000000000100000000000000;
              12'b000000000111 :i = 32'b00000000000000001000000000000000;
              12'b000000001000 :i = 32'b00000000000000010000000000000000;
              12'b001000?????? :i = 32'b00000000000000100000000000000000;
              12'b001001?????? :i = 32'b00000000000001000000000000000000;
              12'b001100?????? :i = 32'b00000000000010000000000000000000;
              12'b001101?????? :i = 32'b00000000000100000000000000000000;
              12'b001110?????? :i = 32'b00000000001000000000000000000000;
              12'b100011?????? :i = 32'b00000000010000000000000000000000;
              12'b101011?????? :i = 32'b00000000100000000000000000000000;
              12'b000100?????? :i = 32'b00000001000000000000000000000000;
              12'b000101?????? :i = 32'b00000010000000000000000000000000;
              12'b001010?????? :i = 32'b00000100000000000000000000000000;
              12'b001011?????? :i = 32'b00001000000000000000000000000000;
              12'b001111?????? :i = 32'b00010000000000000000000000000000;
              12'b000010?????? :i = 32'b00100000000000000000000000000000;
              12'b000011?????? :i = 32'b01000000000000000000000000000000;
              default:          i = 32'bx;
          endcase
      end
      
    endmodule
    

控制器

  • 输入为指令译码器的输出
  • 输出为控制信号,依据指令操作时间表进行设计
  • 逻辑表达式
    PC_CLK = 1
    IM_R = 1
    Rsc4-0 = IM25-21
    Rtc4-0 = IM20-16
    M1 = ~(jr + j + jal)
    M2 = beq + bne
    M3 = jr
    M4 = sllv + srlv + srav
    M5 = addi + addiu + andi + ori + xori + lw + sw + slti + sltiu + lui
    M6 = jal
    M7 = lw
    M9 = ~(sll + srl + sra + sllv + srlv + srav)
    M10 = addi + addiu + andi + ori + xori + lw + sw + slti + sltiu + lui
    A0 = sub + subu + or + nor + slt + srl + srlv + ori + beq + bne + slti
    A1 = add + sub + xor + nor + slt + sltu + sll + sllv + addi + xori + lw + sw +beq +bne + slti +sltiu
    A2 = and + or + xor + nor + sll + srl + sra + sllv + srlv +srav + andi + ori + xori
    A3 = slt + sltu + sll + srl + sra +sllv + srlv + srav + slti + sltiu + lui
    RF_W = ~(jr + sw + beq + bne + j)
    RF_CLK = ~(jr + sw + beq + bne + j) clk
    DM_w = sw
    DM_r = lw
    DM_cs = lw +sw
    
    `timescale 1ns / 1ns
    module operation(
        input clk,
        input z,
        input [31:0] i,
        output PC_CLK,    
        output IM_R,     
        output M1,       
        output M2,        
        output M3,        
        output M4,        
        output M5,        
        output M6,       
        output M7,       
        output M9,      
        output M10,      
        output [3:0] ALUC,
        output RF_W,     
        output RF_CLK,   
        output DM_w,   
        output DM_r,     
        output DM_cs,
        output C_EXT16
        );
        assign PC_CLK = clk;
        assign IM_R = 1;
        assign M1 = ~(i[16] | i[29] | i[30]);
        assign M2 = ( i[24] & z) | (i[25] & ~z);
        assign M3 = i[16];
        assign M4 = i[13] | i[14] | i[15];
        assign M5 = i[17] | i[18] | i[19] | i[20] | i[21] | i[22] | i[23] | i[26] | i[27] | i[28];
        assign M6 = i[30];
        assign M7 = i[22];
        assign M9 = ~(i[10] | i[11] | i[12] | i[13] | i[14] | i[15]);
        assign M10 = i[17] | i[18] | i[19] | i[20] | i[21] | i[22] | i[23] | i[26] | i[27] | i[28];
        assign ALUC[0] = i[2] | i[3] | i[5] | i[7] | i[8] | i[11] | i[14] | i[20] | i[24] | i[25] | i[26];
        assign ALUC[1] = i[0] | i[2] | i[6] | i[7] | i[8] | i[9] | i[10] | i[13] | i[17] | i[21] | i[22] | i[23] | i[24] | i[25] | i[26] | i[27];
        assign ALUC[2] = i[4] | i[5] | i[6] | i[7] | i[10] | i[11] | i[12] | i[13] | i[14] | i[15] | i[19] | i[20] | i[21];
        assign ALUC[3] = i[8] | i[9] | i[10] | i[11] | i[12] | i[13] | i[14] | i[15] | i[26] | i[27] | i[28];
        assign RF_W = ~(i[16] | i[23] | i[24] | i[25] | i[29]);
        assign RF_CLK = ~clk;
        assign DM_w = i[23];
        assign DM_r = i[22];
        assign DM_cs = i[22] | i[23];
        assign C_EXT16 = ~(i[19] | i[20] | i[21]);
    endmodule