Verilog, help with an ALU for a newbie

Discussion in 'Programmer's Corner' started by toffee_pie, Oct 31, 2009.

  1. toffee_pie

    Thread Starter Active Member

    Oct 31, 2009
    162
    7
    hi all,

    I am trying to implement a 16 bit ALU, and thus far have this much written.

    I want to get some of the basic arithmitic compiling successfully before I move onto more difficuklt taskks.

    I am having problems getting my head around how I deal with the 2s compliment signed output, 16 bits wide.

    I need to have an extra bit in the output? do I need extra regs for the bit ?

    this is what I have done so far.



    .

    / VERILOG CODE


    // 'timescale 10ns

    module ALU (c,resetb,clk,a,b,op, ov);


    output signed [s + 15:0] c; // 2's compliment signed 16 bit output word

    output ov; // The result of addition or subtraction is
    // supposed to fit
    // within the significant bits used to represent the numbers.
    // If ‘n’ bits are used to represent signed numbers
    // in 2’s complement
    // scheme, then the result must be in the range
    // –2n-1 to 2n-1-1.
    // If the result does not fit in this range, then an arithmetic
    // overflow has occurred, this used for signed operations.


    input clk,resetb; // system clock @ 100Mhz , synchronous
    // system reset active low
    input [2:0] op; // assigns ALU one of its 8 operand Instruction
    input [15:0] a,b; // unsigned 16 bit input operands to ALU

    // internal nodes

    wire [15:0] a,b;
    reg signed [15:0] c; // output reg
    reg signed overflow;


    parameter WIDTH = 'd16;

    parameter ADD_AB = 3'b000; // addition -> c = a + b
    parameter SUB_AB = 3'b001; // subtraction -> c = a - b
    parameter MUL_AB = 3'b010; // multiplication -> c = a * b
    parameter AND_AB = 3'b011; // and -> c = a & b
    parameter OR_AB = 3'b100; // or -> c = a | b
    parameter XOR_AB = 3'b101; // xor -> c = a ^ b
    parameter SHIFT_LEFT_A = 3'b110; // shift left -> c = a >> 1
    parameter SHIFT_RIGHT_A = 3'b111; // shift right -> c = b >> 1



    always @ (a or b or op) begin

    // Lets do Arithmetic operations

    begin

    if (op[2:1] == 2'b00) begin

    case (op[2:0])

    3'b000:c = a + b ; // addition
    3'b001:c = a - b ; // subtraction
    //3'b010:c = a * b ; //
    default:c = 16'bx;

    endcase

    //overflow = c[15]^c[14];

    end


    // Lets do Logical operations

    else if (op[2:1] == 2'b01) begin

    case (op[2:0])

    3'b011:c = a & b ; // logical and
    3'b100:c = a | b ; // logical or
    3'b111:c = a ^ b; // logical exor
    default:c = 16'bx;


    endcase

    endmodule
     
  2. Ursa Major

    New Member

    Jul 8, 2010
    1
    0
    `timescale 1ns / 1ps
    ////////////////////////////////////////////////////////////////////////////////
    //
    ////////////////////////////////////////////////////////////////////////////////
    module tb_alu_v;
    // Inputs
    reg rstb;
    reg clk;
    reg [15:0] a;
    reg [15:0] b;
    reg [7:0] op;
    // Outputs
    wire [15:0] c;
    wire ov;

    parameter ADD_AB = 8'b00000001; // addition -> c = a + b
    parameter SUB_AB = 8'b00000010; // subtraction -> c = a - b
    parameter MUL_AB = 8'b00000100; // multiplication -> c = a * b
    parameter AND_AB = 8'b00001000; // and -> c = a & b
    parameter OR_AB = 8'b00010000; // or -> c = a | b
    parameter XOR_AB = 8'b00100000; // xor -> c = a ^ b
    parameter SHIFT_LEFT_A = 8'b01000000; // shift left -> c = a >> 1
    parameter SHIFT_RIGHT_A = 8'b10000000; // shift right -> c = b >> 1
    // Instantiate the Unit Under Test (UUT)
    alu uut (
    .c(c),
    .rstb(rstb),
    .clk(clk),
    .a(a),
    .b(b),
    .op(op),
    .ov(ov)
    );
    initial begin
    // Initialize Inputs
    rstb = 0;
    clk = 0;
    a = 0;
    b = 0;
    op = 0;
    // Wait 100 ns for global reset to finish
    #100;

    // Add stimulus here
    #5
    a = 8;
    b = 3;
    op = ADD_AB;
    #5
    a = 8;
    b = 3;
    op = SUB_AB;
    #5
    a = 8;
    b = 3;
    op = MUL_AB;
    #5
    a = 8;
    op = SHIFT_LEFT_A;
    #5
    a = 8;
    op = SHIFT_RIGHT_A;
    #5
    a = 8;
    b = 3;
    op = XOR_AB;
    #5
    a = 8;
    b = 3;
    op = AND_AB;
    #5
    a = 8;
    b = 3;
    op = OR_AB;

    end

    always
    #2 clk = ~clk;

    endmodule

    /////////////////////////////////////////////////
    `timescale 1ns / 1ps
    //****************************************************
    // 16 bit arithmetic logic unit
    //
    // parameter:
    // CLK.......system clock
    // RESET.....System Reset
    // A.........A input
    // B.........B input
    // OP........operation to perform
    // Y.........8 bit result output
    // C.........carry status
    // OV.........overflow status
    // N.........sign status
    // Z.........zero status
    //
    //****************************************************
    module alu(c,rstb,clk,a,b,op,ov);
    parameter s = 0; // dummy variable
    output signed[s+15:0] c;
    input rstb,clk; // system clock @ 100Mhz , synchronous
    // system reset active low
    input [15:0]a,b; // unsigned 16 bit input operands to ALU
    //input [2:0]op;
    input [7:0]op;

    output ov; // The result of addition or subtraction is supposed to fit
    // within the significant bits used to represent the numbers.
    // If ‘n’ bits are used to represent signed numbers
    // in 2’s complement
    // scheme, then the result must be in the range
    // –2n-1 to 2n-1-1.
    // If the result does not fit in this range, then an arithmetic
    // overflow has occurred, this used for signed operations.

    //input clk, resetb; input [2:0] op; // assigns ALU one of its 8 operand Instruction
    // internal nodes
    wire [15:0] a,b;
    reg signed [15:0] c; // output reg
    reg signed overflow;

    parameter WIDTH = 'd16;
    /*
    parameter ADD_AB = 3'b000; // addition -> c = a + b
    parameter SUB_AB = 3'b001; // subtraction -> c = a - b
    parameter MUL_AB = 3'b010; // multiplication -> c = a * b
    parameter AND_AB = 3'b011; // and -> c = a & b
    parameter OR_AB = 3'b100; // or -> c = a | b
    parameter XOR_AB = 3'b101; // xor -> c = a ^ b
    parameter SHIFT_LEFT_A = 3'b110; // shift left -> c = a >> 1
    parameter SHIFT_RIGHT_A = 3'b111; // shift right -> c = b >> 1
    */
    parameter ADD_AB = 8'b00000001; // addition -> c = a + b
    parameter SUB_AB = 8'b00000010; // subtraction -> c = a - b
    parameter MUL_AB = 8'b00000100; // multiplication -> c = a * b
    parameter AND_AB = 8'b00001000; // and -> c = a & b
    parameter OR_AB = 8'b00010000; // or -> c = a | b
    parameter XOR_AB = 8'b00100000; // xor -> c = a ^ b
    parameter SHIFT_LEFT_A = 8'b01000000; // shift left -> c = a >> 1
    parameter SHIFT_RIGHT_A = 8'b10000000; // shift right -> c = b >> 1
    /*
    always @ (a or b or op)
    // Lets do Arithmetic operations
    begin
    if (op[2:1] == 2'b00)
    begin
    case (op[2:0])
    3'b000:c = a + b ; // addition
    3'b001:c = a - b ; // subtraction
    3'b010:c = a * b ; //
    default:c = 16'bx;
    endcase
    //overflow = c[15]^c[14];
    end
    // Lets do Logical operations
    else if (op[2:1] == 2'b01)
    begin
    case (op[2:0])
    3'b011:c = a & b ; // logical and
    3'b100:c = a | b ; // logical or
    3'b111:c = a ^ b; // logical exor
    default:c = 16'bx;
    endcase
    end
    end
    */
    always @ (a or b or op)
    // Lets do Arithmetic operations
    begin
    case (op)
    ADD_AB :
    begin
    $display("ADD");
    c = a + b ; // addition
    end
    SUB_AB :
    begin
    $display("SUBTRACT");
    c = a - b ; // subtraction
    end
    MUL_AB :
    begin
    $display("MUL");
    c = a * b ; //
    end
    AND_AB :
    begin
    $display("AND");
    c = a & b ; // logical and
    end
    OR_AB :c = a | b; // logical or
    XOR_AB :c = a ^ b; // logical exor
    SHIFT_LEFT_A :
    begin
    $display("SHL");
    c = a >> 1; // shift left -> c = a >> 1
    end
    SHIFT_RIGHT_A :
    begin
    $display("SHR");
    c = a << 1 ;
    end
    default:c = 16'bx;
    endcase
    end

    endmodule
     
Loading...