cpu之ALU

来源:互联网 发布:js修改class的值 编辑:程序博客网 时间:2024/05/21 14:56
`include "defines.v"module ALU(input wire[31:0] SrcA,input wire[31:0] SrcB,input wire[5:0] ALUCtra,input wire[5:0] ALUCtrb,output reg Zero,output reg Execute_sucess,output reg [31:0] ALURes);//以下是为了进行算术运算wire[5:0] aluop; assign aluop=ALUCtrb;wire ov_sum;//保存溢出情况wire SrcA_lt_SrcB;//判断前者是否小于后者wire [31:0] SrcB_mux;//保存第二个数的补码wire [31:0] SrcA_not;//保存第一个数取反后的值wire [31:0] result_sum;//保存加法的结果wire[31:0] opdata1_mult;//乘法的两个操作数wire[31:0] opdata2_mult;wire[63:0] hilo_temp;wire [31:0] hilo_temp_half;//取得乘法操作的操作数,如果是有符号乘法且操作数是负数,那么取反加一assign opdata1_mult = ((aluop == `Mul)  && (SrcA[31] == 1'b1)) ? (~SrcA + 1) : SrcA;  assign opdata2_mult = ((aluop == `Mul)&& (SrcB[31] == 1'b1)) ? (~SrcB + 1) : SrcB;  assign hilo_temp = opdata1_mult * opdata2_mult;    assign hilo_temp_half = (~hilo_temp + 1);assign SrcB_mux=((aluop==`Sub)||                 (aluop==`Subu)||                 (aluop==`Slt))?(~SrcB)+1:SrcB;                 //求补码                 assign result_sum=SrcA+SrcB_mux;assign ov_sum = ((!SrcA[31] && !SrcB_mux[31]) && result_sum[31]) ||((SrcA[31] && SrcB_mux[31]) && (!result_sum[31]));  assign SrcA_lt_SrcB = ((aluop == `Slt)) ? ((SrcA[31] && !SrcB[31]) ||  (!SrcA[31] && !SrcB[31] && result_sum[31])||                   (SrcA[31] && SrcB[31] && result_sum[31]))                   :(SrcA < SrcB);                   always @(SrcA,SrcB,ALUCtra,ALUCtrb) begin //**************case (ALUCtra) `lb : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`lbu : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`lh : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`lhu : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`lw : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`lwl : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`lwr : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`sb : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`sh : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`sw : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`swl : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`swr : beginALURes <= SrcA+SrcB;Execute_sucess <= 1'b1;Zero <= 1'b0;end`SPECIAL : begincase (ALUCtrb)`And : begin  ALURes <= SrcA&SrcB;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Or : begin  ALURes <= SrcA|SrcB;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Xor : begin  ALURes <= SrcA^SrcB;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Nor : begin  ALURes <= ~(SrcA|SrcB);  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Sll : begin  ALURes <= SrcA<<(SrcB[10:6]);  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Srl : begin  ALURes <= SrcA>>(SrcB[10:6]);  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Sra : begin  ALURes <= ({32{SrcA[31]}}<<(6'd32-{1'b0,SrcB[10:6]}))                |SrcA>>(SrcB[10:6]);                Execute_sucess <= 1'b1;                Zero <= 1'b0;  end    `Sllv : begin  ALURes <= SrcB<<(SrcA[4:0]);  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Srlv : begin  ALURes <= SrcB>>(SrcA[4:0]);  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Srav : begin  ALURes <= ({32{SrcB[31]}}<<(6'd32-{1'b0,SrcA[4:0]}))                |SrcB>>(SrcA[4:0]);                Execute_sucess <= 1'b1;                Zero <= 1'b0;  end    `Movn : begin  if (SrcB==32'h0) begin  ALURes<=32'h0;//将写入的数据变为32'h0                //并将写入的寄存器变为寄存器0  Execute_sucess <= 1'b0;//这是为了防止数据相关的出现  Zero <= 1'b0;  end else begin  ALURes <= SrcA;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end  end    `Movz : begin  if (SrcB!=32'h0) begin  ALURes<=32'h0;//将写入的数据变为32'h0                //并将写入的寄存器变为寄存器0  Execute_sucess <= 1'b0;//这是为了防止数据相关的出现  Zero <= 1'b0;  end else begin  ALURes <= SrcA;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end  end    `Add : begin  //这个指令需要判断是否成功  if (ov_sum==1'b1) begin  ALURes <= 32'h0;  Execute_sucess <= 1'b0;//运行不成功  Zero <= 1'b0;  end else begin  ALURes <= result_sum;  Execute_sucess <= 1'b1;//运行成功  Zero <= 1'b0;  end  end    `Addu : begin  ALURes <= result_sum;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Sub : begin  //这个指令需要判断是否成功  if (ov_sum==1'b1) begin  ALURes <= 32'h0;  Execute_sucess <= 1'b0;//运行不成功  Zero <= 1'b0;  end else begin  ALURes <= result_sum;  Execute_sucess <= 1'b1;//运行成功  Zero <= 1'b0;  end  end    `Subu : begin  ALURes <= result_sum;  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Slt : begin  if (SrcA_lt_SrcB==1'b1) begin  ALURes <= 32'h1;  end else begin  ALURes <= 32'h0;  end  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end    `Sltu : begin  if (SrcA_lt_SrcB==1'b1) begin  ALURes <= 32'h1;  end else begin  ALURes <= 32'h0;  end  Execute_sucess <= 1'b1;  Zero <= 1'b0;  end  endcaseend`Andi : beginALURes <= SrcA&({16'b0,SrcB[15:0]});Execute_sucess <= 1'b1;Zero <= 1'b0;end`Xori : beginALURes <= SrcA^({16'b0,SrcB[15:0]});Execute_sucess <= 1'b1;Zero <= 1'b0;end`Lui : beginALURes <= {SrcB,16'b0};Execute_sucess <= 1'b1;Zero <= 1'b0;end`Ori : beginALURes <= SrcA|({16'b0,SrcB[15:0]});Execute_sucess <= 1'b1;Zero <= 1'b0;end`SPECIAL2: begincase (ALUCtrb)`Mul :beginif(SrcA[31] ^ SrcB[31] == 1'b1) beginALURes <= hilo_temp_half;Execute_sucess <= 1'b1;      Zero <= 1'b0;  end else begin  ALURes <=hilo_temp[31:0];  Execute_sucess <= 1'b1;      Zero <= 1'b0;  endendendcase end`Addi : begin//这个指令需要判断是否成功  if (ov_sum==1'b1) begin  ALURes <= 32'h0;  Execute_sucess <= 1'b0;//运行不成功  Zero <= 1'b0;  end else begin  ALURes <= result_sum;  Execute_sucess <= 1'b1;//运行成功  Zero <= 1'b0;  endend`Addiu : begin  ALURes <= result_sum;  Execute_sucess <= 1'b1;  Zero <= 1'b0;end`Slti : begin if (SrcA_lt_SrcB==1'b1) begin  ALURes <= 32'h1; end else begin  ALURes <= 32'h0; end  Execute_sucess <= 1'b1;Zero <= 1'b0;end  `Sltiu : begin  if (SrcA_lt_SrcB==1'b1) begin  ALURes <= 32'h1;  end else begin  ALURes <= 32'h0;  end  Execute_sucess <= 1'b1;Zero <= 1'b0;end`Beq : beginif (SrcA==SrcB) beginExecute_sucess <= 1'b1;Zero <= 1'b1;end else beginExecute_sucess <= 1'b0;Zero <= 1'b0;endend`Bgtz : beginif (SrcA>SrcB) beginExecute_sucess <= 1'b1;Zero <= 1'b1;end else beginExecute_sucess <= 1'b0;Zero <= 1'b0;endend`Blez : beginif (SrcA<=SrcB) beginExecute_sucess <= 1'b1;Zero <= 1'b1;end else beginExecute_sucess <= 1'b0;Zero <= 1'b0;endend`Bne : beginif (SrcA!=SrcB) beginExecute_sucess <= 1'b1;Zero <= 1'b1;end else beginExecute_sucess <= 1'b0;Zero <= 1'b0;endenddefault:ALURes<=32'h0;endcaseendendmodule