Kogge Stone Adder를 만들었는데 이상하게 계속 오류가 난다.

 

Radix-4 Booth Multiplier를 만들때 써야 하는데 이렇게 오류가 많이 나는 덧셈기는 절대 못 쓸 물건이다.

그래서 한번 고쳐보기로 했다.

 

Carry Look-Ahead Tree에서 오류

그려놓은 Block Diagram

 

최초 버전에서는 코드 치는 번거로움을 최대한 줄이고자 generate-for 문을 이용했다.

첫번째 인덱스에서만 0, Cin 을 집어넣어주고 그 뒤로는 이전 단계에서 온 P, G를 1, 2, 4, 8 전에 있는것과 섞어주는거다.

 

이 방법은 CLA Tree Stage 2 까지는 얼추 맞아 떨어지는 것처럼 보인다.

하지만 위에 Block Diagram을 다시 보자. 그리고 Stage 3의 코드를 가져와보자.

// CLA tree stage 3 (13 cells)
generate
    for ( idx = 0; idx < 13; idx = idx + 1 ) begin : cla_tree_stage_3
        if ( idx == 4 ) begin // if first cell of the stage
            black_cell _black_cell2(.pout(pg_tree_p_st_3[idx]),  .gout(pg_tree_g_st_3[idx]),
                             .p(pg_tree_p_st_2[idx + 2]), .g(pg_tree_g_st_2[idx + 2]),
                             .p_1(p_terms[idx-4]),        .g_1(g_terms[idx-4]));   
        end
        else begin
            black_cell _black_cell2(.pout(pg_tree_p_st_3[idx]),  .gout(pg_tree_g_st_3[idx]),
                             .p(pg_tree_p_st_2[idx + 2]), .g(pg_tree_g_st_2[idx + 2]),
                             .p_1(pg_tree_p_st_2[idx]),   .g_1(pg_tree_g_st_2[idx]));
        end
    end
endgenerate

사실 idx == 4 에서부터 벌써 오류가 보이지만 일단 이걸 차치하더라도 뭔가 잘못 되었음을 느낄 수 있을 것이다.

Stage 3에서의 Black Cell 연산에 들어가는 P, G는 Stage 2에서 온 것 뿐만이 아닌 Stage 1에서 온 것까지 포함된다.

Stage 4에서도 마찬가지이다.

 

따라서 나는 generate-for 문을 전부 들어내고 일일이 다 연결해 주어야 했다..

위에 나온 Stage 3의 경우 이렇게 변경되었다.

black_cell _black_cell3_0(.pout(p_st_3[0]),   .gout(g_st_3[0]),   .p(p_st_2[2]),   .g(g_st_2[2]),   .p_1(1'b0),         .g_1(cin) );
black_cell _black_cell3_1(.pout(p_st_3[1]),   .gout(g_st_3[1]),   .p(p_st_2[3]),   .g(g_st_2[3]),   .p_1(p_st_1[0]),    .g_1(g_st_1[0]) );
black_cell _black_cell3_2(.pout(p_st_3[2]),   .gout(g_st_3[2]),   .p(p_st_2[4]),   .g(g_st_2[4]),   .p_1(p_st_2[0]),    .g_1(g_st_2[0]) );
black_cell _black_cell3_3(.pout(p_st_3[3]),   .gout(g_st_3[3]),   .p(p_st_2[5]),   .g(g_st_2[5]),   .p_1(p_st_2[1]),    .g_1(g_st_2[1]) );
black_cell _black_cell3_4(.pout(p_st_3[4]),   .gout(g_st_3[4]),   .p(p_st_2[6]),   .g(g_st_2[6]),   .p_1(p_st_2[2]),    .g_1(g_st_2[2]) );
black_cell _black_cell3_5(.pout(p_st_3[5]),   .gout(g_st_3[5]),   .p(p_st_2[7]),   .g(g_st_2[7]),   .p_1(p_st_2[3]),    .g_1(g_st_2[3]) );
black_cell _black_cell3_6(.pout(p_st_3[6]),   .gout(g_st_3[6]),   .p(p_st_2[8]),   .g(g_st_2[8]),   .p_1(p_st_2[4]),    .g_1(g_st_2[4]) );
black_cell _black_cell3_7(.pout(p_st_3[7]),   .gout(g_st_3[7]),   .p(p_st_2[9]),   .g(g_st_2[9]),   .p_1(p_st_2[5]),    .g_1(g_st_2[5]) );
black_cell _black_cell3_8(.pout(p_st_3[8]),   .gout(g_st_3[8]),   .p(p_st_2[10]),  .g(g_st_2[10]),  .p_1(p_st_2[6]),    .g_1(g_st_2[6]) );
black_cell _black_cell3_9(.pout(p_st_3[9]),   .gout(g_st_3[9]),   .p(p_st_2[11]),  .g(g_st_2[11]),  .p_1(p_st_2[7]),    .g_1(g_st_2[7]) );
black_cell _black_cell3_a(.pout(p_st_3[10]),  .gout(g_st_3[10]),  .p(p_st_2[12]),  .g(g_st_2[12]),  .p_1(p_st_2[8]),    .g_1(g_st_2[8]) );
black_cell _black_cell3_b(.pout(p_st_3[11]),  .gout(g_st_3[11]),  .p(p_st_2[13]),  .g(g_st_2[13]),  .p_1(p_st_2[9]),    .g_1(g_st_2[9]) );
black_cell _black_cell3_c(.pout(p_st_3[12]),  .gout(g_st_3[12]),  .p(p_st_2[14]),  .g(g_st_2[14]),  .p_1(p_st_2[10]),   .g_1(g_st_2[10]) );

이 뭔 뻘짓인가 싶지만 별 수 없다. 내 머리가 딸려서 for 문을 쓰면 코드가 더 더러워진다.

 

 

Black Cell에서의 오류

module black_cell(pout, gout, p, g, p_1, g_1);
    input     p, g, p_1, g_1;
    output    pout, gout;

    assign pout = g | (p & g_1);
    assign gout = p & p_1;
endmodule

이건 고치기 전의 Black Cell 코드이다.

Pout, Gout이 뒤집혀 있었다.

 

이러니까 아무리 탑 모듈에서 고쳐대도 오류가 사라지지 않았던 것이다. (심지어 RTL 시뮬레이션에서도.)

module black_cell(pout, gout, p, g, p_1, g_1);
    input     p, g, p_1, g_1;
    output    pout, gout;

    assign pout = p & p_1;
    assign gout = g | (p & g_1);
endmodule

이렇게 고치니 오류가 싹 사라진게 씁슬할 따름.