Based on MIPS Instruction Structure

Main Module


module Alu(
    input [31:0] a, // operand 1
    input [31:0] b, // operand 2
    input [3:0] aluc, // control port
    output [31:0] r, // result
    // Flags
    output zero,
    output carry,
    output negative,
    output overflow
    );
// operation definition
parameter DIGIT = 32;
// parameter ENABLE = 1, DISABLE = 0;
parameter ADDU = 4'b0000, ADD = 4'b0010, SUBU = 4'b0001;
parameter SUB  = 4'b0011, AND = 4'b0100, OR   = 4'b0101;
parameter XOR  = 4'b0110, NOR = 4'b0111, LUI  = 4'b100x;
parameter SLTU = 4'b1010, SLT = 4'b1011, SRA  = 4'b1100;
parameter SLL  = 4'b1110, SLR = 4'b1111, SRL  = 4'b1101;
// ---
// output wire
wire [DIGIT-1:0] Addu;
wire [DIGIT-1:0] Add;
wire [DIGIT-1:0] Subu;
wire [DIGIT-1:0] Sub;
// ---
wire [DIGIT-1:0] And;
wire [DIGIT-1:0] Or;
wire [DIGIT-1:0] Xor;
wire [DIGIT-1:0] Nor;
// ---
wire [DIGIT-1:0] Lui;
wire [DIGIT-1:0] Sltu;
wire [DIGIT-1:0] Slt;
// ---
wire [DIGIT-1:0] Sra;
wire [DIGIT-1:0] Sll;
wire [DIGIT-1:0] Srl;
wire [DIGIT-1:0] Slr; // slr instruction is unnecessary...
// ---
// Flags
wire addu_z, addu_c, addu_n, addu_o;
wire add_z, add_c, add_n, add_o;
wire subu_z, subu_c, subu_n, subu_o;
wire sub_z, sub_c, sub_n, sub_o;
// ---
wire and_z, and_c, and_n, and_o;
wire or_z, or_c, or_n, or_o;
wire xor_z, xor_c, xor_n, xor_o;
wire nor_z, nor_c, nor_n, nor_o;
// ---
wire lui_z, lui_c, lui_n, lui_o;
wire sltu_z, sltu_c, sltu_n, sltu_o;
wire slt_z, slt_c, slt_n, slt_o;
// ---
wire sra_z, sra_c, sra_n, sra_o;
wire sll_z, sll_c, sll_n, sll_o;
wire srl_z, srl_c, srl_n, srl_o;
wire slr_z, slr_c, slr_n, slr_o;

// Module instantation
AddSub m_addu(.in_a(a), .in_b(b), .aluc(ADDU), .out(Addu),
                  .zero(addu_z), .carry(addu_c), .negative(addu_n), .overflow(addu_o));
AddSub m_add(.in_a(a), .in_b(b), .aluc(ADD), .out(Add),
                  .zero(add_z), .carry(add_c), .negative(add_n), .overflow(add_o));
AddSub m_subu(.in_a(a), .in_b(b), .aluc(SUBU), .out(Subu),
                  .zero(subu_z), .carry(subu_c), .negative(subu_n), .overflow(subu_o));
AddSub m_sub(.in_a(a), .in_b(b), .aluc(SUB), .out(Sub),
                  .zero(sub_z), .carry(sub_c), .negative(sub_n), .overflow(sub_o));
LogicOpr m_and(.in_a(a), .in_b(b), .aluc(AND), .out(And),
                     .zero(and_z), .carry(and_c), .negative(and_n), .overflow(and_o));
LogicOpr m_or(.in_a(a), .in_b(b), .aluc(OR), .out(Or),
                    .zero(or_z), .carry(or_c), .negative(or_n), .overflow(or_o));
LogicOpr m_xor(.in_a(a), .in_b(b), .aluc(XOR), .out(Xor),
                     .zero(xor_z), .carry(xor_c), .negative(xor_n), .overflow(xor_o));
LogicOpr m_nor(.in_a(a), .in_b(b), .aluc(NOR), .out(Nor),
                     .zero(nor_z), .carry(nor_c), .negative(nor_n), .overflow(nor_o));
Shifter32 m_sll(.in_a(a), .in_b(b), .aluc(SLL), .out(Sll),
                     .zero(sll_z), .carry(sll_c), .negative(sll_n), .overflow(sll_o));
Shifter32 m_slr(.in_a(a), .in_b(b), .aluc(SLR), .out(Slr),
                     .zero(slr_z), .carry(slr_c), .negative(slr_n), .overflow(slr_o));
Shifter32 m_srl(.in_a(a), .in_b(b), .aluc(SRL), .out(Srl),
                     .zero(srl_z), .carry(srl_c), .negative(srl_n), .overflow(srl_o));
Shifter32 m_sra(.in_a(a), .in_b(b), .aluc(SRA), .out(Sra),
                     .zero(sra_z), .carry(sra_c), .negative(sra_n), .overflow(sra_o));
Others m_lui(.in_a(a), .in_b(b), .aluc(LUI), .out(Lui),
                     .zero(lui_z), .carry(lui_c), .negative(lui_n), .overflow(lui_o));
Others m_slt(.in_a(a), .in_b(b), .aluc(SLT), .out(Slt),
                     .zero(slt_z), .carry(slt_c), .negative(slt_n), .overflow(slt_o));
Others m_sltu(.in_a(a), .in_b(b), .aluc(SLTU), .out(Sltu),
                     .zero(sltu_z), .carry(sltu_c), .negative(sltu_n), .overflow(sltu_o));
// select the result to output
Selector m_result(.aluc(aluc), .r_add(Add), .r_addu(Addu), .r_sub(Sub), .r_subu(Subu),
                        .r_lui(Lui), .r_slt(Slt), .r_sltu(Sltu), .r_and(And), .r_or(Or),
                        .r_xor(Xor), .r_nor(Nor), .r_sll(Sll),   .r_slr(Slr), .r_srl(Srl), .r_sra(Sra),
                        // Flags
                        .out(r), .zero(zero), .carry(carry), .negative(negative), .overflow(overflow),
                        .addu_z(addu_z), .addu_c(addu_c), .addu_n(addu_n), .addu_o(addu_o),
                        .add_z(add_z), .add_c(add_c), .add_n(add_n), .add_o(add_o),
                        .subu_z(subu_z), .subu_c(subu_c), .subu_n(subu_n), .subu_o(subu_o),
                        .sub_z(sub_z), .sub_c(sub_c), .sub_n(sub_n), .sub_o(sub_o),
                        // ---
                        .and_z(and_z), .and_c(and_c), .and_n(and_n), .and_o(and_o),
                        .or_z(or_z), .or_c(or_c), .or_n(or_n), .or_o(or_o),
                        .xor_z(xor_z), .xor_c(xor_c), .xor_n(xor_n), .xor_o(xor_o),
                        .nor_z(nor_z), .nor_c(nor_c), .nor_n(nor_n), .nor_o(nor_o),
                        // ---
                        .lui_z(lui_z), .lui_c(lui_c), .lui_n(lui_n), .lui_o(lui_o),
                        .sltu_z(sltu_z), .sltu_c(sltu_c), .sltu_n(sltu_n), .sltu_o(sltu_o),
                        .slt_z(slt_z), .slt_c(slt_c), .slt_n(slt_n), .slt_o(slt_o),
                        // ---
                        .sra_z(sra_z), .sra_c(sra_c), .sra_n(sra_n), .sra_o(sra_o),
                        .sll_z(sll_z), .sll_c(sll_c), .sll_n(sll_n), .sll_o(sll_o),
                        .srl_z(srl_z), .srl_c(srl_c), .srl_n(srl_n), .srl_o(srl_o),
                        .slr_z(slr_z), .slr_c(slr_c), .slr_n(slr_n), .slr_o(slr_o));
endmodule

Add&Sub Module


/* Unsigned Adder */
module AddSub(
    input [31:0] in_a, // operand 1
    input [31:0] in_b, // operand 2
    input [3:0] aluc, // operand 3
    output reg [31:0] out,
    // Flag
    output reg zero,
    output reg carry,
    output reg negative,
    output reg overflow
    );
parameter DIGIT = 32;
parameter ENABLE = 1;
parameter DISABLE = 0;
parameter ADDU = 4'b0000, ADD = 4'b0010, SUBU = 4'b0001, SUB  = 4'b0011;

initial begin
    out = 32'h0000_0000;
    zero = DISABLE;
    carry = DISABLE;
    negative = DISABLE;
    overflow = DISABLE;
end
always @ (*) begin

    case(aluc)
    ADDU: begin // Unsigned add
        out = in_a + in_b;
        // flag judgement
        if(in_a[DIGIT-1] == 0 && in_b[DIGIT-1] == 0)
            carry = DISABLE;
        else begin
            if(out[DIGIT-1] == 0)
                carry = ENABLE;
            else
                carry = DISABLE;
        end
    end
    SUBU: begin // Unsigned sub
        out = in_a - in_b;
        // flag judgement
        if((in_a[DIGIT-1] == 0 && in_b[DIGIT-1] == 1))
            carry = ENABLE;
        else if(in_a[DIGIT-1] == 1 && in_b[DIGIT-1] == 0)
            carry = DISABLE;
        else if(out[DIGIT-1] == 1)
            carry = ENABLE;
        else
            carry = DISABLE;
    end
    ADD: begin // Signed add
        out = in_a + in_b;
        // flag judgement
        if((out[DIGIT-1] != in_a[DIGIT-1]) && (in_a[DIGIT-1] == in_b[DIGIT-1]))
            overflow = ENABLE;
        else
            overflow = DISABLE;
    end
    SUB: begin // Signed sub
        out = in_a + (~in_b + 1);
        // flag judgement
        if((in_a[DIGIT-1] != in_b[DIGIT-1]) && (out[DIGIT-1] != in_a[DIGIT-1]))
            overflow = ENABLE;
        else
            overflow = DISABLE;
    end
    endcase
    if(out == 0) // zero flag
        zero = ENABLE;
    else
        zero = DISABLE;
    if(out[DIGIT-1] == 1) // negative flag
        negative = ENABLE;
    else
        negative = DISABLE;
end

endmodule

Logic Operation Module


module LogicOpr(
    input [31:0] in_a, // operand 1
    input [31:0] in_b, // operand 2
    input [3:0] aluc, // operand 3
    output reg [31:0] out,
    // Flag
    output reg zero,
    output reg carry,
    output reg negative,
    output reg overflow
    );
parameter DIGIT = 32;
parameter AND = 4'b0100, OR   = 4'b0101, XOR  = 4'b0110, NOR = 4'b0111;
parameter ENABLE = 1;
parameter DISABLE = 0;
// initialize
initial begin
    out = 32'h0000_0000;
    zero = DISABLE;
    carry = DISABLE;
    negative = DISABLE;
    overflow = DISABLE;
end
always @ (*) begin
    case(aluc)
    AND:
        out = in_a & in_b;
    OR:
        out = in_a | in_b;
    XOR:
        out = in_a ^ in_b;
    NOR:
        out = ~(in_a | in_b);
    endcase
    if(out == 0)
        zero = ENABLE;
    else
        zero = DISABLE;
    if(out[31] == 1)
        negative = ENABLE;
    else
        negative = DISABLE;
end

endmodule

32-bit Shifter Module


module Shifter32(
    input [31:0] in_a,
    input [31:0] in_b,
    input [3:0]aluc,
    output reg [31:0] out,
    // Flags
    output reg zero,
    output reg carry,
    output reg negative,
    output reg overflow
     );
parameter DIGIT = 32;
parameter ENABLE = 1;
parameter DISABLE = 0;
parameter SRA  = 4'b1100, SRL  = 4'b1101;
// initialize
initial begin
    out = 32'h0000_0000;
    zero = DISABLE;
    carry = DISABLE;
    negative = DISABLE;
    overflow = DISABLE;
end
always @ (*) begin
    case(aluc)
    SRA: begin // sra
        out = in_b >>> (in_a - 1);
        carry = out[0];
        out = in_b >>> 1;
    end
    SRL: begin // srl
        out = in_b >> (in_a - 1);
        carry = out[0];
        out = in_b >> 1;
    end
    default: begin // slr,sll
        out = in_b << (in_a - 1);
        carry = out[DIGIT-1];
        out = out << 1;
    end
    endcase
    if(out == 0) // zero flag
        zero = ENABLE;
    else
        zero = DISABLE;
    if(out[DIGIT-1] == 1) // negative flag
        negative = ENABLE;
    else
        negative = DISABLE;

end

endmodule

Others' Module


module Others(
    input [31:0] in_a, // operand 1
    input [31:0] in_b, // operand 2
    input [3:0] aluc, // control port
    output reg [31:0] out, // result
    // Flags
    output reg zero,
    output reg carry,
    output reg negative,
    output reg overflow
    );
parameter DIGIT = 32;
parameter SLTU = 4'b1010, SLT = 4'b1011;
parameter ENABLE = 1;
parameter DISABLE = 0;
// initialize
initial begin
    out = 32'h0000_0000;
    zero = DISABLE;
    carry = DISABLE;
    negative = DISABLE;
    overflow = DISABLE;
end
always @ (*) begin
    case(aluc)
    SLTU: begin
        out = (in_a < in_b) ? 1 : 0;
    end
    SLT: begin
        if(in_a[31] == 0 && in_b[31] == 0)
            out = (in_a < in_b) ? 1 : 0;
        else if(in_a[31] == 1 && in_b[31] == 0)
            out = 1;
        else if(in_a[31] == 0 && in_b[31] == 1)
            out = 0;
        else
            out = ((~in_b+1) < (~in_a+1)) ? 1 : 0;
    end
    default: begin // lui
        out = {in_b[15:0], 16'b0};
    end
    endcase
    if(out == 0) // zero flag
        zero = ENABLE;
    else
        zero = DISABLE;
    if(out[DIGIT-1] == 1) // negative flag
        negative = ENABLE;
    else
        negative = DISABLE;
end

endmodule

Selector Moudle


module Selector(
    input [3:0] aluc,
    input [31:0] r_add,
    input [31:0] r_addu,
    input [31:0] r_sub,
    input [31:0] r_subu,
    input [31:0] r_and,
    input [31:0] r_or,
    input [31:0] r_xor,
    input [31:0] r_nor,
    input [31:0] r_sll,
    input [31:0] r_slr,
    input [31:0] r_srl,
    input [31:0] r_sra,
    input [31:0] r_lui,
    input [31:0] r_slt,
    input [31:0] r_sltu,
    // Flags
    input addu_z, addu_c, addu_n, addu_o,
    input add_z, add_c, add_n, add_o,
    input subu_z, subu_c, subu_n, subu_o,
    input sub_z, sub_c, sub_n, sub_o,
    // ---
    input and_z, and_c, and_n, and_o,
    input or_z, or_c, or_n, or_o,
    input xor_z, xor_c, xor_n, xor_o,
    input nor_z, nor_c, nor_n, nor_o,
    // ---
    input lui_z, lui_c, lui_n, lui_o,
    input sltu_z, sltu_c, sltu_n, sltu_o,
    input slt_z, slt_c, slt_n, slt_o,
    // ---
    input sra_z, sra_c, sra_n, sra_o,
    input sll_z, sll_c, sll_n, sll_o,
    input srl_z, srl_c, srl_n, srl_o,
    input slr_z, slr_c, slr_n, slr_o,
    output reg [31:0] out,
    output reg zero, negative, carry, overflow
    );
// operation definition
parameter DIGIT = 32;
parameter ENABLE = 1, DISABLE = 0;
parameter ADDU = 4'b0000, ADD = 4'b0010, SUBU = 4'b0001;
parameter SUB  = 4'b0011, AND = 4'b0100, OR   = 4'b0101;
parameter XOR  = 4'b0110, NOR = 4'b0111, LUI_1  = 4'b1001, LUI_2 = 4'b1000;
parameter SLTU = 4'b1010, SLT = 4'b1011, SRA  = 4'b1100;
parameter SLL  = 4'b1110, SLR = 4'b1111, SRL  = 4'b1101;
initial begin
    out = 32'h0000_0000;
    zero = DISABLE;
    carry = DISABLE;
    negative = DISABLE;
    overflow = DISABLE;
end
always @ (*) begin
    case(aluc)
    ADDU: begin
        out = r_addu;
        zero = addu_z;
        carry = addu_c;
        negative = addu_n;
        overflow = addu_o;
    end
    ADD: begin
        out = r_add;
        zero = add_z;
        carry = add_c;
        negative = add_n;
        overflow = add_o;
    end
    SUBU: begin
        out = r_subu;
        zero = subu_z;
        carry = subu_c;
        negative = subu_n;
        overflow = subu_o;
    end
    SUB: begin
        out = r_sub;
        zero = sub_z;
        carry = sub_c;
        negative = sub_n;
        overflow = sub_o;
    end
    AND: begin
        out = r_and;
        zero = and_z;
        carry = and_c;
        negative = and_n;
        overflow = and_o;
    end
    OR: begin
        out = r_or;
        zero = or_z;
        carry = or_c;
        negative = or_n;
        overflow = or_o;
    end
    XOR: begin
        out = r_xor;
        zero = xor_z;
        carry = xor_c;
        negative = xor_n;
        overflow = xor_o;
    end
    NOR: begin
        out = r_nor;
        zero = nor_z;
        carry = nor_c;
        negative = nor_n;
        overflow = nor_o;
    end
    LUI_1: begin
        out = r_lui;
        zero = lui_z;
        carry = lui_c;
        negative = lui_n;
        overflow = lui_o;
    end
    LUI_2: begin
        out = r_lui;
        zero = lui_z;
        carry = lui_c;
        negative = lui_n;
        overflow = lui_o;
    end
    SLT: begin
        out = r_slt;
        zero = slt_z;
        carry = slt_c;
        negative = slt_n;
        overflow = slt_o;
    end
    SLTU: begin
        out = r_sltu;
        zero = sltu_z;
        carry = sltu_c;
        negative = sltu_n;
        overflow = sltu_o;
    end
    SLL: begin
        out = r_sll;
        zero = sll_z;
        carry = sll_c;
        negative = sll_n;
        overflow = sll_o;
    end
    SLR: begin
        out = r_slr;
        zero = slr_z;
        carry = slr_c;
        negative = slr_n;
        overflow = slr_o;
    end
    SRL: begin
        out = r_srl;
        zero = srl_z;
        carry = srl_c;
        negative = srl_n;
        overflow = srl_o;
    end
    SRA: begin
        out = r_sra;
        zero = sra_z;
        carry = sra_c;
        negative = sra_n;
        overflow = sra_o;
    end
    endcase
end

endmodule

Test bench


module alu_tb;

    // Inputs
    reg [31:0] a;
    reg [31:0] b;
    reg [3:0] aluc;

    // Outputs
    wire [31:0] r;
    wire zero;
    wire carry;
    wire negative;
    wire overflow;

    // Instantiate the Unit Under Test (UUT)
    Alu uut (
        .a(a),
        .b(b),
        .aluc(aluc),
        .r(r),
        .zero(zero),
        .carry(carry),
        .negative(negative),
        .overflow(overflow)
    );

    initial begin
        // Initialize Inputs
        a = 0;
        b = 0;
        aluc = 0;

      #20;
        a = 32'hf000_0000;
        b = 32'hffff_ffff;
        aluc = 4'b0000; // addu
        // Add stimulus here
        #20; // 40
        aluc = 4'b0010; // add
        #20; // 60
        aluc = 4'b0001; // subu
        #20; // 80
        aluc = 4'b0011; // sub
        #20; // 100
        aluc = 4'b0100; // and
        #20; // 120
        aluc = 4'b0101; // or
        #20; // 140
        aluc = 4'b0110; // xor
        #20; // 160
        aluc = 4'b0111; // nor
        #20; // 180
        aluc = 4'b1001; // lui
        #20; // 200
        aluc = 4'b1000; // lui
        #20; // 220
        aluc = 4'b1011; // slt
        #20; // 240
        aluc = 4'b1010; // sltu
        #20; // 260
//      aluc = 4'b1100; // sra
        #20;
//      aluc = 4'b1110; // sll
        #20;
//      aluc = 4'b1111; // slr
        #20;
//      aluc = 4'b1101; // srl

        // Wait 100 ns for global reset to finish
        #100;
    end

endmodule

32-bit ALU [Verilog]的更多相关文章

  1. jchdl - RTL实例 - MOS6502 ALU (Verilog)

    https://mp.weixin.qq.com/s/jLUz757FQZjMEYzYb2AIww   MOS6502是简单,但是曾经相当流行的一款CPU.网上有很多模拟程序可供学习使用.这里使用一个 ...

  2. Verilog MIPS32 CPU(三)-- ALU

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  3. Verilog MIPS32 CPU(八)-- 控制器

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  4. Verilog MIPS32 CPU(六)-- MDU

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  5. Verilog MIPS32 CPU(七)-- DIV、DIVU

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  6. Verilog MIPS32 CPU(五)-- CP0

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  7. Verilog MIPS32 CPU(四)-- RAM

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  8. Verilog MIPS32 CPU(二)-- Regfiles

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

  9. Verilog MIPS32 CPU(一)-- PC寄存器

    Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...

随机推荐

  1. html4基础知识梳理

    基础的html知识,只放Xmind的截图. 第一部分: 第二部分: 某些标签的使用示例及注意事项,在印象笔记里.

  2. git node(&npm)安装

    1.git 下载地址:https://git-scm.com/download/win 2.node 下载地址:https://nodejs.org/en/download/ 安装node会自带npm ...

  3. .Net框架2.0和4.0版本对比

    .Net版本 2.0 SP2 4.0 操作系统 Windows 2000 SP4以上 Windows XP SP3以上 安装包大小 NetFx20SP2_x86.exe 23.8 MBNetFx20S ...

  4. 如何去定义一个jquery插件

    扩展jquery的时候.最核心的方法是以下两种: $.extend(object) 可以理解为jquery添加一个静态方法 $.fn.extend(object) 可以理解为jquery实例添加一个方 ...

  5. Android 创建自己的Camera App

    在sdk中找到/sdk/docs/guide/topics/media/camera.html#custom-camera,里面有详细的api参考 在清单文件中添加相应的权限: <uses-pe ...

  6. android apk静默安装

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/47803149 之前有很多朋友都问过我,在Android系统中怎样才能实现静默安装呢 ...

  7. 【代码笔记】iOS-使图片两边不拉伸,中间拉伸

    代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. // ...

  8. [读书笔记] Head First 设计模式

    OO基础 抽象 封装 多态 继承 OO原则 原则 描述 封装变化 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混合在一起. 把会变化的部分取出来并“封装”起来,好让其他部分不 ...

  9. location of the android sdk has not been setup in the preferences

    点eclipse的android virtual device manager提示错误:error:location of the android sdk has not been setup in ...

  10. WPF 使用Caliburn.Micro 多线程打开窗口

    我们都知道在WPF里面用多线程打开一个窗口很简单.如下 public void ClickMe(object sender) { Thread newWindowThread = new Thread ...