data/full_repos/permissive/157101210/alu.v
data/verilator_xmls/37bfacbe-b9ac-4c25-bf23-ddd091e41228.xml
module ALU(
	input[31:0] operandA,
	input[31:0] operandB,
	input[5:0] opcode,
	input[5:0] funct,
	output zero,
	output[31:0] res,
	output overflow,
	output carryout
);
	wire[31:0] initialResult;
	wire[31:0] initialFinal;
	reg isInitial;
	wire[31:0] sltResult;
	wire[31:0] sltFinal;
	reg isSLT;
	wire isSubtract;
	wire[32:0] carryOut;

	or carryOr(carryOut[0], isSubtract, isSubtract);
	
	generate
        genvar i;
        for (i=0; i<32; i=i+1)

        begin
            ALUBitSlice aluBitSlice (
                .carryOut (carryOut[i+1]),
                .res (initialResult[i]),
                .a (operandA[i]),
                .b (operandB[i]),
                .carryIn (carryOut[i]),
                .isSubtract (isSubtract),
                .opcode (opcode),
                .funct (funct)
            );
        end
    endgenerate

	always @(opcode or funct) begin
		case (opcode)
			`LW_OP:   begin isInitial=1; isSLT=0; end
			`SW_OP:   begin isInitial=1; isSLT=0; end
			`J_OP:    begin isInitial=1; isSLT=0; end
			`JAL_OP:  begin isInitial=1; isSLT=0; end
			`BEQ_OP:  begin isInitial=1; isSLT=0; end
			`BNE_OP:  begin isInitial=1; isSLT=0; end
			`XORI_OP: begin isInitial=1; isSLT=0; end
			`ADDI_OP: begin isInitial=1; isSLT=0; end

			`RTYPE_OP: begin
				case (funct)
					`JR_FUNCT:  begin isInitial=1; isSLT=0; end
					`ADD_FUNCT: begin isInitial=1; isSLT=0; end
					`SUB_FUNCT: begin isInitial=1; isSLT=0; end
					`SLT_FUNCT: begin isInitial=0; isSLT=1; end
					default: $display("Error in ALU: Invalid funct. OPCODE: %b", opcode);
				endcase
			end

			default: $display("Error in ALU: Invalid opcode");
		endcase
	end


    wire overflowInv;
    wire isSLTinv;
    wire SLTval;

    wire bInv;
    not(bInv, operandB[31]);

    wire aCheck;
    wire bCheck;
    wire abCheck;

    and(aCheck, operandA[31], initialResult[31], isSLT);
    and(bCheck, bInv, initialResult[31], isSLT);
    and(abCheck, operandA[31], bInv, isSLT);

    or(SLTval, aCheck, bCheck, abCheck);


    not(isSLTinv, isSLT);


    generate
        genvar j;
        for (j=1; j<32; j=j+1)
        begin
            and(res[j], initialResult[j], isSLTinv);
        end
    endgenerate

    wire sltCheck;
    and(sltCheck, initialResult[0], isSLTinv);
    or(res[0], sltCheck, SLTval);

	didOverflow overflowCalc (
		.overflow (overflow),
		.a (operandA[31]),
		.b (operandB[31]),
		.s (initialResult[31]),
		.sub (isSubtract)
	);

	isZero zeroCalc(
        .zeroBit (res),
        .out (zero)
    );

    or orCarryout(carryout, carryOut[32], carryOut[32]);

endmodule
module ALU(
	input[31:0] operandA,
	input[31:0] operandB,
	input[5:0] opcode,
	input[5:0] funct,
	output zero,
	output[31:0] res,
	output overflow,
	output carryout
);

	wire[31:0] initialResult;
	wire[31:0] initialFinal;
	reg isInitial;
	wire[31:0] sltResult;
	wire[31:0] sltFinal;
	reg isSLT;
	wire isSubtract;
	wire[32:0] carryOut;

	or carryOr(carryOut[0], isSubtract, isSubtract);
	
	generate
        genvar i;
        for (i=0; i<32; i=i+1)

        begin
            ALUBitSlice aluBitSlice (
                .carryOut (carryOut[i+1]),
                .res (initialResult[i]),
                .a (operandA[i]),
                .b (operandB[i]),
                .carryIn (carryOut[i]),
                .isSubtract (isSubtract),
                .opcode (opcode),
                .funct (funct)
            );
        end
    endgenerate

	always @(opcode or funct) begin
		case (opcode)
			`LW_OP:   begin isInitial=1; isSLT=0; end
			`SW_OP:   begin isInitial=1; isSLT=0; end
			`J_OP:    begin isInitial=1; isSLT=0; end
			`JAL_OP:  begin isInitial=1; isSLT=0; end
			`BEQ_OP:  begin isInitial=1; isSLT=0; end
			`BNE_OP:  begin isInitial=1; isSLT=0; end
			`XORI_OP: begin isInitial=1; isSLT=0; end
			`ADDI_OP: begin isInitial=1; isSLT=0; end

			`RTYPE_OP: begin
				case (funct)
					`JR_FUNCT:  begin isInitial=1; isSLT=0; end
					`ADD_FUNCT: begin isInitial=1; isSLT=0; end
					`SUB_FUNCT: begin isInitial=1; isSLT=0; end
					`SLT_FUNCT: begin isInitial=0; isSLT=1; end
					default: $display("Error in ALU: Invalid funct. OPCODE: %b", opcode);
				endcase
			end

			default: $display("Error in ALU: Invalid opcode");
		endcase
	end


    wire overflowInv;
    wire isSLTinv;
    wire SLTval;

    wire bInv;
    not(bInv, operandB[31]);

    wire aCheck;
    wire bCheck;
    wire abCheck;

    and(aCheck, operandA[31], initialResult[31], isSLT);
    and(bCheck, bInv, initialResult[31], isSLT);
    and(abCheck, operandA[31], bInv, isSLT);

    or(SLTval, aCheck, bCheck, abCheck);


    not(isSLTinv, isSLT);


    generate
        genvar j;
        for (j=1; j<32; j=j+1)
        begin
            and(res[j], initialResult[j], isSLTinv);
        end
    endgenerate

    wire sltCheck;
    and(sltCheck, initialResult[0], isSLTinv);
    or(res[0], sltCheck, SLTval);

	didOverflow overflowCalc (
		.overflow (overflow),
		.a (operandA[31]),
		.b (operandB[31]),
		.s (initialResult[31]),
		.sub (isSubtract)
	);

	isZero zeroCalc(
        .zeroBit (res),
        .out (zero)
    );

    or orCarryout(carryout, carryOut[32], carryOut[32]);

endmodule