Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

32-bit adder Carry Look-ahead

Hi,

I am new to Verilog and I am trying to implement a 32-bit adder Carry Look-ahead, but the output is incorrect. I included the simulation in ModelSim and my verilog code.

https://www.alteraforum.com/forum/attachment.php?attachmentid=10447

module adder(CarryIn, a, b, result, CarryOut);
    input  a, b;
    input CarryIn;
    output CarryOut;
    output  result;
    parameter delay = 50;
    
    wire  p, g;
    wire  c;
    
    buf# (delay) buf0(c, CarryIn);
    
    genvar i;
    generate
    for(i=0; i<32; i++)
        begin: CalculatePandG
            and# (delay) myAnd(g, a, b);
            or # (delay) myOr(p, a, b);
        end
    endgenerate
    
    carry_lookahead myCarryLookAhead(p, g, CarryIn, c, CarryOut);
    
    genvar j;
    generate
    for(j=0; j<32; j++)
        begin: JoinedAdder
            xor# (delay) Adderj(result, c, a, b);
        end
    endgenerate
endmodule
//CARRY-LOOKAHEAD
module carry_lookahead(p, g, CarryIn, c, CarryOut);
    input  p, g;
    input CarryIn;
    output  c;
    output CarryOut;
    
    buf# 50 buf0(c, CarryIn);
    
    genvar i;
    generate
    for(i=0; i<31; i++)
        begin: CarryLookAhead
            cal_carry myCarry(p, g, c, c);
        end
    endgenerate
    cal_carry myCarry31(p, g, c, CarryOut);
endmodule
module cal_carry(p, g, cin, cout);
    input p, g, cin;
    output cout;
    parameter delay = 50;
    
    wire temp;
    
    and# (delay) and0(temp, p, c);
    or # (delay) or0(cout, temp, g);
endmodule

Could someone help me to fix this problem?

Sorry for my bad English!

Thanks in advance.

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have already solved my problem, but I truly thank you for your reply! :)

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    hie v1t0ry,

    sure, no problem.

    could i suggest that you:

    a) upload your fixed code here? if it's not confidential, then it would be really helpful as well for other forum members if they happen to have the same problem and stumble across your code? =)

    b) also, if not confidential, upload a copy of the fixed / working code in the Share Materials section of the forum?

    http://www.alteraforum.com/forum/forumdisplay.php?f=16

    just my 2 cents, to help each other out!

    take care and have a nice day!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This is my Verilog code of MIPS 32-bit ALU, which is able to perform 4 functions including addition, subtraction, exclusive-OR, and set-on-less-than.

    I use the adder to perform both addition and subtraction.

    Hope it is useful for amateurs like me! :)

    
    `timescale 1 ps / 100 fs
    // DA Cau Truc May Tinh - Lab 2 - ALU
    // Ngo Dat - 11DT3
    //32-BIT ALU
    module alu(Output, Carryout, Zero, Overflow, Negative, BusA, BusB, ALUControl);
    	output  Output;
    	output Carryout, Zero, Overflow, Negative;
    	input  BusA, BusB;
    	input  ALUControl;
    	wire  c, Less, add_out, xor_out, Less_out, p, g, BusBinv;
    	wire CarryIn;
    	parameter delay = 50;
    	
    	assign Less = 31'd0;
    	
    	buf# (delay) buf0(CarryIn, ALUControl);
    	
    	genvar k;
    	generate
    	for(k=0; k<32; k++)
    		begin: CalculatePandG
    			xor# (delay) myXor(BusBinv, BusB, ALUControl);
    			and# (delay) myAnd(g, BusA, BusBinv);
    			or # (delay) myOr(p, BusA, BusBinv);
    		end
    	endgenerate
    	
    	carry_lookahead myCarryLookAhead(p, g, CarryIn, c, Carryout);
    	
    	genvar i;
    	generate
    	for(i=0; i<32; i=i+1)
    		begin: JoinedALUs
    			alu_1bit myALU(add_out, xor_out, Less_out, BusA, BusB, c, Less, ALUControl);
    		end
    	endgenerate
    	
    	buf# (delay) buf1(Negative, add_out);
    	xor# (delay) xor0(Overflow, c, Carryout);
    	xor# (delay) xor1(Less, Overflow, Negative);
    	Zero_module myZero(Zero, Output);
    	mux32x4_32 myMUX(Output, add_out, xor_out, add_out, Less_out, ALUControl, ALUControl);	
    endmodule
    //1-BIT ALU
    module alu_1bit(add_out, xor_out, Less_out, a, b, CarryIn, Less, ALUControl);
    	output add_out, xor_out, Less_out;
    	input a, b, CarryIn, Less;
    	input  ALUControl;
    	parameter delay = 50;
    	wire bin, btemp;
    	
    	not# (delay) not0(bin, b);
    	m2_1 myMUX0(btemp, ALUControl, b, bin);
    	xor# (delay) myAdder(add_out, a, btemp, CarryIn);
    	xor# (delay) xor0(xor_out, a, b);
    	buf# (delay) buf0(Less_out, Less);	
    endmodule
    //CARRY-LOOKAHEAD
    module carry_lookahead(p, g, CarryIn, c, CarryOut);
    	input  p, g;
    	input CarryIn;
    	output  c;
    	output CarryOut;
    	
    	buf# 50 buf0(c, CarryIn);
    	
    	genvar i;
    	generate
    	for(i=0; i<31; i++)
    		begin: CarryLookAhead
    			cal_carry myCarry(p, g, c, c);
    		end
    	endgenerate
    	cal_carry myCarry31(p, g, c, CarryOut);
    endmodule
    module cal_carry(p, g, cin, cout);
    	input p, g, cin;
    	output cout;
    	parameter delay = 50;	
    	wire temp;
    	
    	and# (delay) and0(temp, p, cin);
    	or # (delay) or0(cout, temp, g);
    endmodule
    //2-1 MULTIPLEXOR
    module m2_1(data, sel, y0, y1);
    	output data;
    	input sel, y0, y1;
    	wire nsel, a, b;
    	parameter delay = 50;
    	not# (delay) not0(nsel, sel);
    	and# (delay) and0(a, nsel, y0);
    	and# (delay) and1(b, sel,  y1);
    	or # (delay) or0(data, a, b);
    endmodule 
    //4-1 MULTIPLEXOR  
    module m4_1(data, sel1, sel0, y0, y1, y2, y3);
    	output data;	
    	input sel1, sel0, y0, y1, y2, y3;	
    	wire out0, out1;
    	m2_1 myMultiplexer0(out0, sel0, y0, y1);
    	m2_1 myMultiplexer1(out1, sel0, y2, y3);
    	m2_1 myMultiplexer2(data, sel1, out0, out1);
    endmodule
    //32x4 TO 32 MULTIPLEXOR
    module mux32x4_32(Output, Add, Xor, Subtract, SLT, control_1,control_0);
    	output  Output;
    	input  Add, Xor, Subtract, SLT;
    	input control_1, control_0;
    	
    	genvar i;
    	generate
    	for(i=0; i<32; i=i+1)
    		 begin : mux32x4_32
    		 m4_1 myMux(Output, control_1, control_0, Add, Xor, Subtract, SLT); 
    		 end
    	endgenerate
    	
    endmodule
    //ZERO FLAG
    module Zero_module(Output,Input);
    	output Output;
    	input  Input;
    	wire temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
    	parameter delay = 50;
    	
    	or# (delay) or0(temp0, Input, Input, Input,Input);
    	or# (delay) or1(temp1, Input, Input, Input,Input);
    	or# (delay) or2(temp2, Input, Input, Input,Input);
    	or# (delay) or3(temp3, Input, Input, Input,Input);
    	or# (delay) or4(temp4, Input, Input, Input,Input);
    	or# (delay) or5(temp5, Input, Input, Input,Input);
    	or# (delay) or6(temp6, Input, Input, Input,Input);
    	or# (delay) or7(temp7, Input, Input, Input,Input);
    	or# (delay) or8(temp8, temp0, temp1, temp2, temp3);
    	or# (delay) or9(temp9, temp4, temp5, temp6, temp7);
    	nor# (delay) nor0(Output, temp8, temp9);
    endmodule
    // Test bench for ALU file
    module ALUStimulus();
    	parameter ClockDelay = 100000;
    	reg  BusA, BusB;
    	reg  ALUControl;
    	wire  Output;
    	wire Zero, Overflow, Carryout, Negative;
    	integer i;
    	// If your register file module is not named "alu" then you will
    	// have to change the following line in order to create an instance of
    	// your register file.  Also you must make sure that the port declarations
    	// match up with the module instance in this stimulus file.
    	alu alu1(.Output, .Carryout, .Zero, .Overflow, .Negative, .BusA, .BusB, .ALUControl);
    	initial begin
    		// Addition unit testing 
    		ALUControl=00; 
    		BusA=32'h00000DEF; BusB=32'h00000ABC;# (ClockDelay); // Should output 000018AB
    		BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 00001339
    		BusA=32'h7FFFFFFF; BusB=32'h00000001;# (ClockDelay); // Should output 80000000, overflow, negative
    		
    		// Xor unit testing 
    		ALUControl=01; 
    		BusA=32'h00000DEF; BusB=32'h00000ABC;# (ClockDelay); // Should output 00000753	
    		BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 00001331
    		BusA=32'h80000000; BusB=32'h00000001;# (ClockDelay); // Should output 80000001
    		
    		// Subtraction unit testing 
    		ALUControl=10; 
    		BusA=32'h00000DEF; BusB=32'h00000ABC;# (ClockDelay); // Should output 00000333	
    		BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 0000112F
    		BusA=32'h80000000; BusB=32'h00000001;# (ClockDelay); // Should output 7FFFFFFF, overflow
    		
    		// Set Less Than unit testing 
    		ALUControl=11; 
    		BusA=32'h00000000; BusB=32'h00000DEF;# (ClockDelay); // Should output 00000001
    		BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 00000000
    	end
    endmodule
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Some advice, if you want synthesizable logic I recommend avoiding delays in your RTL. That code will simulate fine but if you compile it for an FPGA you might end up surprised by the way it behaves in actual hardware.