# verilog实现适应RISC-V的ALU

1 篇文章 0 订阅

## 一、硬件结构

#### 1.1位ALU结构

##### 1）非最高有效位ALU

//------------------------------适应RISC-V的1位ALU（非最高位ALU）---------------------------------
module ALU_1bit(
input a,
input b,
input less,
input Ainvert,
input Binvert,
input CarryIn,
input [1:0] Operation,
output reg Result,
output CarryOut
);

wire a_n,b_n;
assign a_n=(Ainvert==0)?a:~a;
assign b_n=(Binvert==0)?b:~b;
assign CarryOut=(a_n&b_n)|(a_n&CarryIn)|(b_n&CarryIn);

always@(*)
begin
case (Operation)
2'b00:Result=a_n & b_n;
2'b01:Result=a_n | b_n;
2'b10:Result=a_n^b_n^CarryIn;
2'b11:Result=less;
endcase
end
endmodule
//-----------------------------------------------------------------------------------------------

##### 2）最高有效位ALU

Overflow=a^Set&((~a^b)^Binvert)

//--------------------------------适应RISC-V的1位ALU（最高位ALU）---------------------------------
module ALU_Hbit(
input a,
input b,
input less,
input Ainvert,
input Binvert,
input CarryIn,
input [1:0] Operation,
output reg Result,
output Set,
output Overflow
);

wire a_n,b_n;
assign a_n=(Ainvert==0)?a:~a;
assign b_n=(Binvert==0)?b:~b;
assign Set=a_n^b_n^CarryIn;

always@(*)
begin
case (Operation)
2'b00:Result=a_n & b_n;
2'b01:Result=a_n | b_n;
2'b10:Result=Set;
2'b11:Result=less;
default:Result=0;
endcase
end

//Overflow 溢出检测逻辑
assign Overflow=a^Set&((~a^b)^Binvert);

endmodule
//-----------------------------------------------------------------------------------------------

#### 2.64位串行ALU结构

//----------------------------------------64位串行ALU--------------------------------------------
module ALU_RISC_V(
input [63:0]    ALU_DA,
input [63:0]    ALU_DB,
input [3:0]     ALU_Operation,
output          Zero,
output          Overflow,
output [63:0]   Result
);
genvar i;
wire CarryOut[62:0],less0,Set;
assign less0=Overflow^Set;
ALU_1bit alu0(
.a(ALU_DA[0]),
.b(ALU_DB[0]),
.less(less0),
.Ainvert(ALU_Operation[3]),
.Binvert(ALU_Operation[2]),
.CarryIn(ALU_Operation[2]),
.Operation(ALU_Operation[1:0]),
.Result(Result[0]),
.CarryOut(CarryOut[0])
);
generate
for(i=1;i<63;i=i+1)
begin:ALU_62bit
ALU_1bit alu(
.a(ALU_DA[i]),
.b(ALU_DB[i]),
.less(1'b0),
.Ainvert(ALU_Operation[3]),
.Binvert(ALU_Operation[2]),
.CarryIn(CarryOut[i-1]),
.Operation(ALU_Operation[1:0]),
.Result(Result[i]),
.CarryOut(CarryOut[i])
);
end
endgenerate
ALU_Hbit alu63(
.a(ALU_DA[63]),
.b(ALU_DB[63]),
.less(1'b0),
.Ainvert(ALU_Operation[3]),
.Binvert(ALU_Operation[2]),
.CarryIn(CarryOut[62]),
.Operation(ALU_Operation[1:0]),
.Result(Result[63]),
.Set(Set),
.Overflow(Overflow)
);
assign Zero=~|Result;
endmodule
//-----------------------------------------------------------------------------------------------


#### 3.ALU_Operation控制信号

ALU_Operation={Ainvert,Bnegate,Operation[1:0]}

#### 4.最终代码实现

timescale 1ns / 1ps
//
// Company: NJUEE
// Engineer: xixi
//
// Create Date: 2023/09/08 20:22:22
// Design Name:
// Module Name: ALU_RISC_V
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
//
//

//ALU_Operation ：{Ainvert,Bnegate,Operation[1:0]}
//0000 与
//0001 或
//0010 加
//0110 减
//0111 小于比较置位
//1100 或非

//----------------------------------------64位串行ALU--------------------------------------------
module ALU_RISC_V(
input [63:0]    ALU_DA,
input [63:0]    ALU_DB,
input [3:0]     ALU_Operation,
output          Zero,
output          Overflow,
output [63:0]   Result
);
genvar i;
wire CarryOut[62:0],less0,Set;
assign less0=Overflow^Set;
ALU_1bit alu0(
.a(ALU_DA[0]),
.b(ALU_DB[0]),
.less(less0),
.Ainvert(ALU_Operation[3]),
.Binvert(ALU_Operation[2]),
.CarryIn(ALU_Operation[2]),
.Operation(ALU_Operation[1:0]),
.Result(Result[0]),
.CarryOut(CarryOut[0])
);
generate
for(i=1;i<63;i=i+1)
begin:ALU_62bit
ALU_1bit alu(
.a(ALU_DA[i]),
.b(ALU_DB[i]),
.less(1'b0),
.Ainvert(ALU_Operation[3]),
.Binvert(ALU_Operation[2]),
.CarryIn(CarryOut[i-1]),
.Operation(ALU_Operation[1:0]),
.Result(Result[i]),
.CarryOut(CarryOut[i])
);
end
endgenerate
ALU_Hbit alu63(
.a(ALU_DA[63]),
.b(ALU_DB[63]),
.less(1'b0),
.Ainvert(ALU_Operation[3]),
.Binvert(ALU_Operation[2]),
.CarryIn(CarryOut[62]),
.Operation(ALU_Operation[1:0]),
.Result(Result[63]),
.Set(Set),
.Overflow(Overflow)
);
assign Zero=~|Result;
endmodule
//-----------------------------------------------------------------------------------------------

//------------------------------适应RISC-V的1位ALU（非最高位ALU）---------------------------------
module ALU_1bit(
input a,
input b,
input less,
input Ainvert,
input Binvert,
input CarryIn,
input [1:0] Operation,
output reg Result,
output CarryOut
);

wire a_n,b_n;
assign a_n=(Ainvert==0)?a:~a;
assign b_n=(Binvert==0)?b:~b;
assign CarryOut=(a_n&b_n)|(a_n&CarryIn)|(b_n&CarryIn);

always@(*)
begin
case (Operation)
2'b00:Result=a_n & b_n;
2'b01:Result=a_n | b_n;
2'b10:Result=a_n^b_n^CarryIn;
2'b11:Result=less;
endcase
end
endmodule
//-----------------------------------------------------------------------------------------------

//--------------------------------适应RISC-V的1位ALU（最高位ALU）---------------------------------
module ALU_Hbit(
input a,
input b,
input less,
input Ainvert,
input Binvert,
input CarryIn,
input [1:0] Operation,
output reg Result,
output Set,
output Overflow
);

wire a_n,b_n;
assign a_n=(Ainvert==0)?a:~a;
assign b_n=(Binvert==0)?b:~b;
assign Set=a_n^b_n^CarryIn;

always@(*)
begin
case (Operation)
2'b00:Result=a_n & b_n;
2'b01:Result=a_n | b_n;
2'b10:Result=Set;
2'b11:Result=less;
default:Result=0;
endcase
end

//Overflow 溢出检测逻辑
assign Overflow=a^Set&((~a^b)^Binvert);

endmodule
//-----------------------------------------------------------------------------------------------

## 二、仿真测试

timescale 1ns / 1ps
//
// Company: NJUEE
// Engineer: xixi
//
// Create Date: 2023/09/08 20:43:54
// Design Name:
// Module Name: tb_ALU_RISC_V
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
//
//
//ALU_Operation ：{Ainvert,Bnegate,Operation[1:0]}
//0000 与
//0001 或
//0010 加
//0110 减
//0111 小于比较置位
//1100 或非

module tb_ALU_RISC_V(
);
reg[63:0]    ALU_DA;
reg[63:0]    ALU_DB;
reg[3:0]     ALU_Operation;
wire          Zero;
wire          Overflow;
wire [63:0]   Result;

initial
begin
ALU_DA=64'h8000000000000009;
ALU_DB=64'h7fffffffffffffff;
ALU_Operation=4'b0111;
end

ALU_RISC_V alu(
.ALU_DA(ALU_DA),
.ALU_DB(ALU_DB),
.ALU_Operation(ALU_Operation),
.Zero(Zero),
.Overflow(Overflow),
.Result(Result)
);
endmodule


#### 1.算术运算

##### 1）加法         ALU_Operation=4'b0010
###### a.正+正

000586ab00459259H+000584abe69f24b4H
=1555443885642329+1553248727016628
=3108692612658957
=000b0b56e6e4e70dH

initial
begin
ALU_DA=64'h000586ab00459259;
ALU_DB=64'h000584abe69f24b4;
ALU_Operation=4'b0010;
end
###### b.正+负

000586ab00459259H+fffa7b541960db4cH
=1555443885642329+（-1553248727016628）
=2195158625701
=0001ff19a66da5H

initial
begin
ALU_DA=64'h000586ab00459259;
ALU_DB=64'hfffa7b541960db4c;
ALU_Operation=4'b0010;
end
###### c.负+负

fffa7954ffba6da7H+fffa7b541960db4cH
=-1555443885642329+（-1553248727016628）
=-3108692612658957
=000b0b56e6e4e70dH

initial
begin
ALU_DA=64'hfffa7954ffba6da7;
ALU_DB=64'hfffa7b541960db4c;
ALU_Operation=4'b0010;
end

##### 2）减法         ALU_Operation=4'b0110
###### a.正-正

05984621abef6f5eH-06985a2f2b2ee9e6H
=403149277082120030-475228919322044902
=-72079642239924872
=feffebf280c08578H

###### b.负-负

fa67b9de541090a2H-f967a5d0d4d1161aH
=-403149277082120030-(-475228919322044902)
=72079642239924872
=0100140d7f3f7a88H

###### c.正-负

05984621abef6f5eH-f967a5d0d4d1161aH
=403149277082120030-(-475228919322044902)
=878378196404164932
=c30a050d71e5944H

###### d.负-正

fa67b9de541090a2H-06985a2f2b2ee9e6H
=(-403149277082120030)-475228919322044902
=-878378196404164932
=f3cf5faf28e1a6bcH

##### 3）溢出测试
###### a.正+正

7fffffffffffffffH+0000000000000009H，结果一定会大于2^64-1，发生溢出
Overflow位置1

###### b.负+负

8000000000000001H+fffffffffffffff7H，结果一定会小于-2^64，发生溢出
Overflow位置1

###### c.正-负

7fffffffffffffffH-fffffffffffffff7H，结果一定会大于2^64-1，发生溢出
Overflow位置1

###### d.负-正

8000000000000001H-0000000000000009H，结果一定会小于-2^64，发生溢出
Overflow位置1

#### 2.逻辑运算

initial
begin
ALU_DA=64'h8452ba5cafe8cca8;
ALU_DB=64'h2baef5fa56abafba;
ALU_Operation=4'b0000;
end

#### 3.小于比较置位         ALU_Operation=4'b0111

##### 1）减法无溢出时的判断

0452ba5cafe8cca8 H < 7baef5fa56abafba H，result = 64‘b 1

7452ba5cafe8cca8 H > 0baef5fa56abafba H，result = 64‘b 0

##### 2）减法溢出时的判断

7fffffffffffffff H > 8000000000000009 H，result = 64‘b 0

8000000000000009 H < 7fffffffffffffff H，result = 64‘b 1

• 2
点赞
• 14
收藏
觉得还不错? 一键收藏
• 2
评论
11-06 3317
08-08 1万+
01-14 1839
05-30 1024
08-13 7153
06-25 6053
06-18 1454
07-30 764
05-31 1003

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