카테고리 없음

CA ALU

이해와암기 사이 2023. 4. 23. 03:11

module RISCVALU( ALUctl, A, B, ALUOut, Zero);
    input [3:0] ALUctl;
    input [63:0] A,B;
    output reg [63:0] ALUOut;
    output Zero;
    
    assign Zero = (ALUOut ==0); // ALUOut 0 이면 제로 1 
    always @(ALUctl, A, B) begin 
        case (ALUctl)
            0: ALUOut <= A & B; // 0000 and
            1: ALUOut <= A | B; // 0001 or
            2: ALUOut <= A + B; // 0010 덧셈
            6: ALUOut <= A - B ; //0110 뺼샘 
            7: ALUOut <= A < B ? 1 : 0 ; // 0111 A가 B보다 작은지 체크 set less than
            12: ALUOut <= ~(A | B); // 1100 Nor 00일때 참 
            default : ALUOut <= 0;
        endcase
    end
endmodule

module ALU_32bit(
    input [31:0] a_in,
    input [31:0] b_in,
    input [3:0] op,
    output [31:0] result,
    output zero,
    output overflow
    );
    wire [30:0] co;
    wire set;
 
    ALU_1bit u0         (a_in[0], b_in[0], (op[2] & op[1]), op[3], op[2], set , op[1:0] , result[0], co[0]); 

// op=xx11 result[0]에 set이 입력됨 // op x11x 일때 c_in 1이 들어감
    ALU_1bit u1         (a_in[1], b_in[1], co[0], op[3], op[2], 1'b0, op[1:0] , result[1], co[1]); // set에 result[1~31]에는 0    
    ALU_1bit u2         (a_in[2], b_in[2], co[1], op[3], op[2], 1'b0, op[1:0] , result[2], co[2]);
    ALU_1bit u3         (a_in[3], b_in[3], co[2], op[3], op[2], 1'b0, op[1:0] , result[3], co[3]);
    ALU_1bit u4         (a_in[4], b_in[4], co[3], op[3], op[2], 1'b0, op[1:0] , result[4], co[4]);
    ALU_1bit u5         (a_in[5], b_in[5], co[4], op[3], op[2], 1'b0, op[1:0] , result[5], co[5]);
    ALU_1bit u6         (a_in[6], b_in[6], co[5], op[3], op[2], 1'b0, op[1:0] , result[6], co[6]);
    ALU_1bit u7         (a_in[7], b_in[7], co[6], op[3], op[2], 1'b0, op[1:0] , result[7], co[7]);
    ALU_1bit u8         (a_in[8], b_in[8], co[7], op[3], op[2], 1'b0, op[1:0] , result[8], co[8]);
    ALU_1bit u9         (a_in[9], b_in[9], co[8], op[3], op[2], 1'b0, op[1:0] , result[9], co[9]);
    ALU_1bit u10         (a_in[10], b_in[10], co[9], op[3], op[2], 1'b0, op[1:0] , result[10], co[10]);
    ALU_1bit u11         (a_in[11], b_in[11], co[10], op[3], op[2], 1'b0, op[1:0] , result[11], co[11]);
    ALU_1bit u12         (a_in[12], b_in[12], co[11], op[3], op[2], 1'b0, op[1:0] , result[12], co[12]);
    ALU_1bit u13         (a_in[13], b_in[13], co[12], op[3], op[2], 1'b0, op[1:0] , result[13], co[13]);
    ALU_1bit u14         (a_in[14], b_in[14], co[13], op[3], op[2], 1'b0, op[1:0] , result[14], co[14]);
    ALU_1bit u15         (a_in[15], b_in[15], co[14], op[3], op[2], 1'b0, op[1:0] , result[15], co[15]);
    ALU_1bit u16         (a_in[16], b_in[16], co[15], op[3], op[2], 1'b0, op[1:0] , result[16], co[16]);
    ALU_1bit u17         (a_in[17], b_in[17], co[16], op[3], op[2], 1'b0, op[1:0] , result[17], co[17]);
    ALU_1bit u18         (a_in[18], b_in[18], co[17], op[3], op[2], 1'b0, op[1:0] , result[18], co[18]);
    ALU_1bit u19         (a_in[19], b_in[19], co[18], op[3], op[2], 1'b0, op[1:0] , result[19], co[19]);
    ALU_1bit u20         (a_in[20], b_in[20], co[19], op[3], op[2], 1'b0, op[1:0] , result[20], co[20]);
    ALU_1bit u21         (a_in[21], b_in[21], co[20], op[3], op[2], 1'b0, op[1:0] , result[21], co[21]);
    ALU_1bit u22         (a_in[22], b_in[22], co[21], op[3], op[2], 1'b0, op[1:0] , result[22], co[22]);
    ALU_1bit u23         (a_in[23], b_in[23], co[22], op[3], op[2], 1'b0, op[1:0] , result[23], co[23]);
    ALU_1bit u24         (a_in[24], b_in[24], co[23], op[3], op[2], 1'b0, op[1:0] , result[24], co[24]);
    ALU_1bit u25         (a_in[25], b_in[25], co[24], op[3], op[2], 1'b0, op[1:0] , result[25], co[25]);
    ALU_1bit u26         (a_in[26], b_in[26], co[25], op[3], op[2], 1'b0, op[1:0] , result[26], co[26]);
    ALU_1bit u27         (a_in[27], b_in[27], co[26], op[3], op[2], 1'b0, op[1:0] , result[27], co[27]);
    ALU_1bit u28         (a_in[28], b_in[28], co[27], op[3], op[2], 1'b0, op[1:0] , result[28], co[28]);
    ALU_1bit u29         (a_in[29], b_in[29], co[28], op[3], op[2], 1'b0, op[1:0] , result[29], co[29]);
    ALU_1bit u30         (a_in[30], b_in[30], co[29], op[3], op[2], 1'b0, op[1:0] , result[30], co[30]);
    ALU_1bit_overflow u31(a_in[31], b_in[31], co[30], op[3], op[2], 1'b0, op[1:0] , result[31], set , overflow);
   
    assign zero = ~|(result) ; // NOR result 모든 비트가 0이면 zero 참
 
endmodule

module ALU_1bit(
    input a_in,
    input b_in,
    input carry_in,
    input invert_a,
    input invert_b,
    input less,
    input [1:0] op, // 00 AND 명령 , 01 OR 명령 , 10 ADD 명령, 11 slt 명령, 00 NOR 명령 
    output result, 
    output carry_out
    );
    
    wire a_out, b_out;
    wire and_out,or_out,sum;
    
    fulladder_1bit_structuarl add( .a(a_out) , .b(b_out) , .carry_in(carry_in) , .sum(sum) , .carry_out(carry_out) );
    mux_operation m2( op, and_out, or_out , sum, less, result);
    // MUX에서 연산 결과중 하나를 op를 보고  선택해야함 
    
    and( and_out, a_out , b_out );
    or( or_out, a_out, b_out);
    xor( a_out, a_in, invert_a ); // invert A 명령 , invert_a 이 1이면 A가 1이면 0 A가 0이면 1
    xor( b_out, b_in, invert_b ); // invert B 명령 , invert_b 이 1이면 B가 1이면 0 B가 0이면 1
    // invert 명령이 정해지면 a_out, b_out 값이 정해짐 
    
endmodule

module mux_operation(
    input [1:0] op,
    input and_out,
    input or_out,
    input sum,
    input less,
    output result
    );
    
    assign result =  (op==2'b00) ? and_out :
                     (op==2'b01) ? or_out :
                     (op==2'b10) ? sum :
                     (op==2'b11) ? less : 1'b0; // result[63:1] 까지는 모두 0이 들어감 result[0]에는 A+B'+1=A-B 의 MSB가 할당됌

endmodule

module ALU_1bit_overflow(
    input ai, // a_in
    input bi, //b_in
    input ci, // carry_in
    input aiv, // a_invert
    input biv, // b_invert
    input less,
    input [1:0] op,
    output re, // result
    output set, // less than
    output of // overflow
    );
    wire ao,bo,co;
    wire o1,o2,o3;
    
    fulladder_1bit_structuarl add( ao, bo, ci, o3, co); // o3에는 sum , co에는 carry_out 나옴 
    
    mux_operation m2(op, o1, o2, o3, less, re); // o1=and_out , o2=or_out, o3=sum, less=less, re=result
    
    and( o1 , ao, bo);
    or( o2 ,ao, bo);
    xor(ao, ai, aiv );
    xor(bo, bi, biv );
    assign set = o3; // A+B'+1 =A-B 했는데 MSB가 1이면 slt 0이면 sgt
    assign of = (ci^co) ; // overflow truthtable . a와 b의 부호가 같을때 ci과 co 가 다르면 overflow   
    
endmodule

module fulladder_1bit_structuarl(
    input a,
    input b,
    input carry_in,
    output sum,
    output carry_out
    );
    wire s1,carry_case1,carry_case2;

    xor G1(s1,a,b); // s1 =  a , b 둘중 하나만 1이면
    xor G2(sum,s1,carry_in); // sum = s1 , carry_in 둘중 하나만 1이면 
    and G3(carry_case1,a,b); // a,b가 둘다 1이면 carry case1
    and G4(carry_case2,s1,carry_in); // a,b 둘중 하나만 1이면서 carry_in도 1이면 carry case2
    xor G5(carry_out,carry_case2,carry_case1); // carry_case 둘중 하나만 1이면 carry_out

endmodule