算术逻辑单元 (Arithmetic Logic Unit, ALU)是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分,由"And Gate" 和"Or Gate"构成的算术逻辑单元,主要功能是进行二进制的算术运算,如加减乘(不包括整数除法)。基本上,在所有现代CPU体系结构中,二进制都以补数的形式来表示。此算术逻辑单元能构完成带进位的八位数的加减运算和四位数的乘法和除法的运算。本文介绍带进位的ALU设计,用VerilogHDL语言编写,并可以在FPGA上实现。
module ALU(ALU_O,ALU_C,C_in,op,AC_in,GR_in);
output ALU_C; //进位位输出
output [7:0] ALU_O;
input C_in; //进位位输入
input [4:0] op; //操作方式选择码
input [7:0] AC_in;
input [7:0] GR_in;
reg [7:0] ALU_O;
reg ALU_C;
always @(C_in or op or AC_in or GR_in)
begin
case (op)
5'b00011: begin {ALU_C,ALU_O}={C_in,AC_in};end
5'b00100:
begin {ALU_C,ALU_O}={C_in,GR_in};end //如果操作译码为5’b00100则完成RI->AC直移
5'b00111:
begin {ALU_C,ALU_O}=AC_in+GR_in;end //如果操作译码为了5‘b00111则进行八位数相加
5'b01000:
begin {ALU_C,ALU_O}=AC_in-GR_in;end //如果操作编码为了5‘b01000则八位数相减
5'b01011:
begin {ALU_C,ALU_O}=AC_in+GR_in+C_in;end //如果操作译码为了5‘b01011则进行带进位八位数相加
5'b01100:
begin {ALU_C,ALU_O}=AC_in-GR_in-C_in;end //如果操作译码为了5‘b01100则进行带借位八位数相减
5'b01111:
begin {ALU_C,ALU_O}={C_in,~GR_in};end//如果操作编码为5’b01111则进行取反操作
5'b10000:
begin {ALU_O,ALU_C}={C_in,GR_in};end //如果操作码为5’b10000则完成SHCR AC,RI
5'b10001:
begin {ALU_C,ALU_O}={GR_in,C_in};end //如果操作码为5’b10001则完成SHCL AC,RI
5'b11100:
begin {ALU_C,ALU_O}={C_in,mul(AC_in[3:0],GR_in[3:0])};end
//如果操作译码为5’b11100则完成四位数相乘
5'b11101:
begin {ALU_C,ALU_O}={C_in,div(AC_in[7:0],GR_in[7:0])};end //如果操作译码为5’b11101则完成四位数相除
default:begin {ALU_C,ALU_O}={C_in,ALU_O};end
endcase
end
function [7:0] mul;// 四位数移位相乘函数
input [3:0]AC_in;
input [3:0]GR_in;
reg [7:0]R;
reg [7:0]temp;
reg [7:0]temp2;
begin
R=0;
temp=0;
temp2=AC_in;
if(GR_in[0]==1)
begin
temp=temp2;
R=temp2;
temp2=temp;
end
if(GR_in[1]==1)
begin
temp=temp2;
R=R+(temp2<<1);
temp2=temp;
end
if(GR_in[2]==1)
begin
temp=temp2;
R=R+(temp2<<2);
temp2=temp;
end
if(GR_in[3]==1)
begin
temp=temp2;
R=R+(temp2<<3);
temp2=temp;
end
mul=R;
end
endfunction
function [7:0]div; //八位数相除的函数
input [7:0]AC_in;
input [7:0]GR_in;
reg [7:0]R_out;
reg [7:0]temp;
reg [7:0]temp2;
reg [7:0]temp3;
reg [7:0]next;
reg [7:0]temp4;
begin
R_out=8'b0;
temp=AC_in;
next=8'b0;
temp3=8'b0;
temp2=GR_in;
temp4=AC_in;
if(AC_in>7;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[7]=1'b1;
temp=temp4-(temp2<<7);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp>>6;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[6]=1'b1;
temp=temp4-(temp2<<6);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp>>5;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[5]=1'b1;
temp=temp4-(temp2<<5);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp>>4;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[4]=1'b1;
temp=temp4-(temp2<<4);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp>>3;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[3]=1'b1;
temp=temp4-(temp2<<3);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp>>2;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[2]=1'b1;
temp=temp4-(temp2<<2);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp>>1;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[1]=1'b1;
temp=temp4-(temp2<<1);
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
next=temp;
temp=temp;
if(temp>=GR_in)
begin
temp3=temp2;
R_out[0]=1'b1;
temp=temp4-temp2;
temp2=temp3;
next=temp;
temp4=temp;
end
temp=next;
div=R_out;
end
end
endfunction
endmodule