This article is based on the verilog implementation of the ALU design part in "Computer Composition and Design Hardware/Software Interface RISC-V Edition Original Book 5th Edition" (David A. Patterson_John L. Hennis)
1. Hardware structure
The 64-bit ALU design adapted to the RISC-V architecture in the book is used to mainly complete logical operations such as AND, OR, NOR, basic arithmetic operations such as addition and subtraction, as well as the implementation of the less than or equal to set slt instruction and the conditional jump instruction bne instruction.
1.1-bit ALU structure
1) Non-most significant bit 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) Most significant bit ALU
The design of the overflow detection unit is as follows:
Overflow detection is used when performing addition and subtraction operations. There are only 4 situations in which overflow will occur:
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-bit serial ALU structure
The structure in the figure above given in the book cannot achieve slt less than comparison setting when subtraction overflows, but the simulation results found that: when subtraction overflows, the corresponding result is the inversion of the Set bit of ALU63, so it only needs to be set in the Set bit of ALU63 and This can be achieved by passing the Overflow bit XOR to the less bit input of ALU0.
//----------------------------------------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 control signal
ALU_Operation={Ainvert,Bnegate,Operation[1:0]}
4. Final code implementation
`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
// Additional Comments:
//
//
//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
//-----------------------------------------------------------------------------------------------
2. Simulation test
The simulation test code is as follows: When performing specific simulation, you only need to replace the corresponding content in the initial block
`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
// Additional Comments:
//
//
//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. Arithmetic operations
The arithmetic operation verification of unsigned numbers and signed numbers is roughly the same. The only difference is the judgment of the overflow flag. The following only verifies signed numbers.
1) Addition ALU_Operation=4'b0010
a. Positive + positive
000586ab00459259H+000584abe69f24b4H
=1555443885642329+1553248727016628
=3108692612658957
=000b0b56e6e4e70dH
initial
begin
ALU_DA=64'h000586ab00459259;
ALU_DB=64'h000584abe69f24b4;
ALU_Operation=4'b0010;
end
b. Positive + negative
000586ab00459259H+fffa7b541960db4cH
=1555443885642329+(-1553248727016628)
=2195158625701
=0001ff19a66da5H
initial
begin
ALU_DA=64'h000586ab00459259;
ALU_DB=64'hfffa7b541960db4c;
ALU_Operation=4'b0010;
end
c. Negative + Negative
fffa7954ffba6da7H+fffa7b541960db4cH
=-1555443885642329+(-1553248727016628)
=-3108692612658957
=000b0b56e6e4e70dH
initial
begin
ALU_DA=64'hfffa7954ffba6da7;
ALU_DB=64'hfffa7b541960db4c;
ALU_Operation=4'b0010;
end
2) Subtraction ALU_Operation=4'b0110
a. Positive-positive
05984621abef6f5eH-06985a2f2b2ee9e6H
=403149277082120030-475228919322044902
=-72079642239924872
=feffebf280c08578H
b. Negative-negative
fa67b9de541090a2H-f967a5d0d4d1161aH
=-403149277082120030-(-475228919322044902)
=72079642239924872
=0100140d7f3f7a88H
c.Positive-negative
05984621abef6f5eH-f967a5d0d4d1161aH
=403149277082120030-(-475228919322044902)
=878378196404164932
=c30a050d71e5944H
d. Negative-Positive
fa67b9de541090a2H-06985a2f2b2ee9e6H
=(-403149277082120030)-475228919322044902
=-878378196404164932
=f3cf5faf28e1a6bcH
3) Overflow test
a. Positive + positive
7ffffffffffffffH+0000000000000009H, the result will definitely be greater than 2^64-1, and overflow occurs at
Overflow position 1
b. Negative + Negative
8000000000000001H+ffffffffffffffff7H, the result will definitely be less than -2^64, overflow occurs at
Overflow position 1
c.Positive-negative
7ffffffffffffffH-fffffffffffffff7H, the result will definitely be greater than 2^64-1, overflow occurs at
Overflow position 1
d. Negative-Positive
8000000000000001H-0000000000000009H, the result will definitely be less than -2^64, overflow occurs at
Overflow position 1
2. Logical operations
initial
begin
ALU_DA=64'h8452ba5cafe8cca8;
ALU_DB=64'h2baef5fa56abafba;
ALU_Operation=4'b0000;
end
1) With ALU_Operation=4'b0000
2) or ALU_Operation=4'b0001
3) Or non-ALU_Operation=4'b1100
3. Less than comparison setting ALU_Operation=4'b0111
1) Judgment when subtraction does not overflow
0452ba5cafe8cca8 H < 7baef5fa56abafba H,result = 64‘b 1
7452ba5cafe8cca8 H > 0baef5fa56abafba H,result = 64‘b 0
2) Judgment when subtraction overflows
7fffffffffffffff H > 8000000000000009 H,result = 64‘b 0
8000000000000009 H < 7fffffffffffffff H,result = 64‘b 1
At this point, the simulation test ends.