1

I am working on an assignment and am a little lost and don't really know how to get started. I need to implement the following flags in a 32Bit ALU:

• Z ("Zero"): Set to 1 ("True") if the result of the operation is zero

• N ("Negative"): Set to 1 ("True") if the first bit of the result is 1, which indicates a negative number

• O ("Overflow"): Set to 1 ("True") to indicate that the operation overflowed the bus width.

Additionally, a comparison function that compares input a to input b and then set one of three flags:

• LT if input a is less than input b

• GT if input a is greater than input b

• EQ if input a is equal to input b

I need to modify this ALU to include the three flags and comparison outputs then change the test bench to test for all of these modifications.

This was all the information I received for this assignment and there is no textbook or any other resources really. It's an online class, and I cannot get a response from my instructor. So I am a little confused as to how to get started. I am still a total newbie when it comes to digital logic so please bear with me. I just need some help understanding how these flags and comparison works. If any one can explain this a little better to me as far as how they work and what they do, and possibly how I would implement them into the ALU and testbench, I would really appreciate it.

I don't expect anyone to do my assignment, I really just need help understanding it.

ALU

module alu32 (a, b, out, sel);      
    input [31:0] a, b;    
    input [3:0] sel;   
    output [31:0] out,
    reg [31:0] out;  

    //Code starts here 
    always @(a, b, sel)   
    begin     
        case (sel)       
            //Arithmetic Functions       
            0  : out <= a + b;       
            1  : out <= a - b;       
            2  : out <= b - a;       
            3  : out <= a * b;       
            4  : out <= a / b;       
            5  : out <= b % a;       
            //Bit-wise Logic Functions       
            6  : out <= ~a; //Not       
            7  : out <= a & b; //And       
            8  : out <= a | b; //Or       
            9  : out <= a ^ b; //XOR       
            10 : out <= a ^~ b; //XNOR       
            //Logic Functions       
            11 : out <= !a;       
            12 : out <= a && b;       
            13 : out <= a || b;       
            default: out <= a + b;     
        endcase
    end  
endmodule 

ALU Testbench

module alu32_tb();  
    reg [31:0] a, b; 
    reg [3:0] sel; 
    wire [31:0] out; 

initial begin

$monitor("sel=%d a=%d b=%d out=%d", sel,a,b,out);   
    //Fundamental tests - all a+b   
    #0 sel=4'd0; a = 8'd0; b = 8'd0;    
    #1 sel=4'd0; a = 8'd0; b = 8'd25;   
    #1 sel=4'd0; a = 8'd37; b = 8'd0;   
    #1 sel=4'd0; a = 8'd45; b = 8'd75;  
    //Arithmetic   
    #1 sel=4'd1; a = 8'd120; b = 8'd25; //a-b   
    #1 sel=4'd2; a = 8'd30; b = 8'd120; //b-a   
    #1 sel=4'd3; a = 8'd75; b = 8'd3; //a*b   
    #1 sel=4'd4; a = 8'd75; b = 8'd3; //a/b   
    #1 sel=4'd5; a = 8'd74; b = 8'd3; //a%b  
    //Bit-wise Logic Functions   
    #1 sel=4'd6; a = 8'd31; //Not   
    #1 sel=4'd7; a = 8'd31; b = 8'd31; //And   
    #1 sel=4'd8; a = 8'd30; b = 8'd1; //Or   
    #1 sel=4'd9; a = 8'd30; b = 8'd1; //XOR   
    #1 sel=4'd10; a = 8'd30; b = 8'd1; //XNOR  
    //Logic Functions   
    #1 sel=4'd11; a = 8'd25; //Not   
    #1 sel=4'd12; a = 8'd30; b = 8'd0; //And   
    #1 sel=4'd13; a = 8'd0; b = 8'd30; //Or      
    #1 $finish; 
end  

alu32 myalu (.a(a), .b(b), .out(out), .sel(sel));  
endmodule  
Scruffy Nerfherder
  • 189
  • 1
  • 4
  • 15
  • 1
    I think, you may start from adding one or two flags as additional alu32 arguments (are they input, output, or input+output?) and then implementing the flag for one or two alu functions. For example, zero flag for a+b may be defined as result of logic function (a+b) == 0; overflow flag for multiply (a*b) will be set if a*b is greater than 2^32... – osgx Dec 06 '15 at 05:24
  • The instructions we were given did not specify whether they were input, output, or input + output. I sent my instructor an e-mail asking for more information days ago but haven't received a response. We didn't get much information at all on this assignment. Thanks for your response though, that does help. I will start by adding a zero flag to the arguments and see if I can implement that into one of the functions. Then move on to the overflow flag. – Scruffy Nerfherder Dec 06 '15 at 05:44
  • 1
    Scruffy Nerfherder, Do you know the concept of flags *(e.g. http://en.wikibooks.org/wiki/Microprocessor_Design/ALU_Flags or http://en.wikipedia.org/wiki/Zero_flag)? Usually they are set by most arithmetic operations; and sometimes they may be used to do branches, or to be used in some very special commands like "add with carry" (x86 adc). So, if you have no "add with carry", the flags should be ... ? – osgx Dec 06 '15 at 05:47
  • 1
    From what I gather they should be outputs.. – Scruffy Nerfherder Dec 06 '15 at 05:58

1 Answers1

3

You can add these flag outputs to the design. Like the following. Simply connect them in testbench.

// In design:
output zero;
output overflow;
output negative;

// In testbench:
wire zero,overflow,negative;
alu32 myalu (.a(a), .b(b), .out(out), .sel(sel), .zero(zero), .overflow(overflow),.negative(negative));  

For logic part, you can do it with continuous assignments. You may need to add some logic for using these flags only during certain values of sel.

Z ("Zero"): Set to 1 ("True") if the result of the operation is zero

So, we can have condition like all the bits of out must be zero. This can be done in many other ways.

// Bit wise OR-ing on out
assign zero = ~(|out);

O ("Overflow"): Set to 1 ("True") to indicate that the operation overflowed the bus width.

According to this description and the code shown, you simply want carry flag here.That is, a signed extension of addition operation. Refer to this page on WikiPedia for overflow condition.

But, Overflow condition is not the same as the carry bit. Overflow represents data loss while carry represents a bit used for calculation in next stage.

So, doing something like following may be useful:

// Extend the result for capturing carry bit
// Simply use this bit if you want result > bus width
{carry,out} <= a+b;
// overflow in signed arithmetic:
assign overflow = ({carry,out[31]} == 2'b01);

N ("Negative"): Set to 1 ("True") if the first bit of the result is 1, which indicates a negative number

Again this is simply the MSB of the out register. But, the underflow condition is entirely a different thing.

// Depending on sel, subtraction must be performed here
assign negative = (out[31] == 1 && (sel == 1 || sel == 2));

Also, simple condition like assign lt = (a<b) ? 1 : 0; and others can detect the input LT, GT and EQ conditions.

Refer the answer here for the overflow/underflow flag understanding. Overflow-Carry link may also be useful.

Refer Carryout-Overflow, ALU in Verilog and ALU PDF for further information about ALU implementation.

Community
  • 1
  • 1
sharvil111
  • 4,301
  • 1
  • 14
  • 29
  • Okay thank you so much! This was definitely a huge help. But, as for the overflow flag you listed `{carry,out} <= a+b;` and `assign overflow = ({carry,out[31]} == 2'b01);` so would I need to add a `carry` attribute as well? Would that be an input/output? – Scruffy Nerfherder Dec 06 '15 at 21:15
  • That would be an output, one bit. For example: When you add `2'b10` with another `2'b10` on a two bit machine, the result is `3'b100` out of which, the MSB `1` is a carry bit and remaining `00` is displayed as sum bits. So, declare an output carry bit as `output carry; reg carry;`. Respective connections are to be made in testbench. – sharvil111 Dec 07 '15 at 02:11
  • sharvil111, what is basic way of detecting overflow in multiply alu operation? I think that verilog `a*b` with a and b of 32 bits will give only 32 bits of result, is it correct? – osgx Dec 08 '15 at 16:28
  • 1
    @osgx Just guessing about multiplication. When `a*b` is performed for **32 bits**, the maximum result is **64 bits**. So the result must be stored in a 64 bit wide variable and plus one *sign* bit, resulting in a final of **65 bits**. Referring to the answer [here](http://stackoverflow.com/questions/24586842/signed-multiplication-overflow-detection-in-verilog), if that much wide register is not used then it is difficult to detect overflow. – sharvil111 Dec 09 '15 at 03:47