RTL设计(1)- ALU

ALU简介

算术逻辑单元(Arithmetic&Logical Unit)是能实现多组算术运算和逻辑运算的组合逻辑电路,简称ALU。它是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分,由门电路构成的算术逻辑单元,主要功能是进行二位元的算术运算,如加减乘(不包括整数除法)。基本上,在所有现代CPU体系结构中,二进制都以补码的形式来表示。

大部分ALU都可以完成以下运算∶
整数算术运算(加、减,有时还包括乘和除,不过成本较高)
位逻辑运算(与、或、非、异或)
移位运算(左移、右移)

如果在ALU中集成复杂运算,可以在内部采用流水线的方式实现。

ALU实例

以下展示一个简单的ALU模块的实例。

alu.v

`timescale 1ns / 1ps

// Company: 
// Engineer: 
// 
// Create Date: 2020/12/07
// Author Name: Sniper
// Module Name: alu
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 


module alu
#(
    parameter DATA_WIDTH = 32
)
(
    input [DATA_WIDTH-1:0] a,		//operand of ALU
    input [DATA_WIDTH-1:0] b,		//operand of ALU
    input cin,              		//carry in at the LSB
    input [3:0] operate,			//operate select
    output reg [DATA_WIDTH-1:0] r,	//result of ALU
    output reg cout					//carry produced by ALU operation
);

localparam ADD = 4'b0000;//r=a+b+cin
localparam SUB = 4'b0001;//r=a-b
localparam AND = 4'b0010;//r=a&b
localparam OR  = 4'b0011;//r=a|b
localparam NOT = 4'b0100;//r=~a
localparam XOR = 4'b0101;//r=a^b
localparam COMPRAE = 4'b0110;//r=a>b?1:0
localparam SHIFT_L = 4'b0111;//r=a<<b
localparam SHIFT_R = 4'b1000;//r=a>>b


//function for calculation
function [DATA_WIDTH:0] calculate;
    input [DATA_WIDTH-1:0] a;
    input [DATA_WIDTH-1:0] b;
    input cin;
    input [3:0] oper;

    begin
        case(oper)
            ADD: calculate = a+b+cin;
            SUB: calculate = {
    
    1'b0, a-b};
            AND: calculate = {
    
    1'b0, a&b};
            OR : calculate = {
    
    1'b0, a|b};
            NOT: calculate = {
    
    1'b0, ~a};
            XOR: calculate = {
    
    1'b0, a^b};
            COMPRAE: calculate = {
    
    1'b0, a>b?1:0};
            SHIFT_L: calculate = {
    
    1'b0, a<<b};
            SHIFT_R: calculate = {
    
    1'b0, a>>b};

            default: calculate = 0;
        endcase
    end
endfunction

//calculate
always@(*)
begin
    {
    
    cout, r[DATA_WIDTH-1:0]} = calculate(a, b, cin, operate);
end



endmodule

tb_alu.v

`timescale 1ns / 1ps

// Company:
// Engineer:
//
// Create Date: 2020/12/07
// Author Name: Sniper
// Module Name: tb_alu
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//


module tb_alu;

//parameter
parameter DATA_WIDTH = 32;


reg clk;

//input
reg [DATA_WIDTH-1:0] a;
reg [DATA_WIDTH-1:0] b;
reg cin;
reg [3:0] operate;


//output
wire [DATA_WIDTH-1:0] r;
wire cout;



initial
begin
    clk = 0;
    a[DATA_WIDTH-1:0] = 0;
    b[DATA_WIDTH-1:0] = 0;
    cin = 0;
    operate[3:0] = 0;

	#100;
    @(posedge clk);
    a <= 32'hffff_ffff;
    b <= 2;
    cin <= 1;
    operate <= 0;

    @(posedge clk);
    a <= 100;
    b <= 2;
    cin <= 1;
    operate <= 0;

    forever
    begin
        @(posedge clk);
        operate <= operate + 1;
    end


end

//clock
always #5 clk = ~clk;



//DUT
alu 
#(
    .DATA_WIDTH(DATA_WIDTH)
)
DUT
(
    .a(a),
    .b(b),
    .cin(cin),
    .operate(operate),
    .r(r),
    .cout(cout)
);

initial
begin
  $dumpfile("tb_alu.vcd");
  $dumpvars(0,tb_alu);
end

initial #1000 $finish;

endmodule

运行结果

vcs -R alu.v tb_alu.v

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/meng1506789/article/details/110819276
alu