UVM & RTL/Verilog HDL

[20] Verilog HDL 조합회로 구현 (ENCODER, DECODER)

Return 2022. 3. 5. 18:55

★ 인코더 

 n : m 2진 인코더는 n-비트의 입력을 m비트의 출력으로 변환 시키는 회로이다. (n=2**m) 4:2 이진 인코더의 진리표는 다음과 같으며, 입력에는 단지 하나의 1만 포함되어야 한다. 

인코더회로는 if조건문, case문, for 반복문 등 여러 가지 방법으로 모델링될 수 있다. case문을 사용한 모델링은 if조건문보다 논리적인 이해가 명확하다. for 반복문은 입력의 비트 수가 큰 경우 또는 입출력 비트 수를 파라미터화하여 모델링하는 경우에 사용될 수 있다.

module enc_4to2(a,y);

    // 1. case문 사용.
    input [3:0] a;
    output reg [1:0] y;

    always @(*) begin
        case(a)
            4'b0001 : y=2'b00;
            4'b0010 : y=2'b01;
            4'b0100 : y=2'b10;
            4'b1000 : y=2'b11;
            default y=2'bx;
        endcase
    end

    // 2. if문 사용.
    input [3:0] a;
    output reg[1:0] y;
    always@(*)begin
        if(a==4'b0001) y=2'b00;
        else if(a==4'b0010) y=2'b01;
        else if(a==4'b0100) y=2'b10;
        else if(a==4'b1000) y=2'b11;
        else y=2'bx;
    end

    // 3. for문 사용.
    input [3:0] a;
    output reg [1:0] y;
    integer n;
    reg [3:0] temp;

    always@(*)begin
        temp = 4'b0001;
        y=2'bx;
        for(m=0;n<4;n=n+1)begin
            if(a==temp)
                y=n;
            temp = temp <<1;
        end
    end

endmodule

▣ TESTBENCH

module tb_enc_4to2;
    reg [3:0] a;
    wire y;

    enc_4to2 u0(a,y);

    initial begin
        a=4'b0001;
        #20 a=4'b0010;
        #20 a=4'b0100;
        #20 a=4'b1000;
        #20;
    end
endmodule

4TO2 ENCODER TESTBENCH SIMULATION

★ 우선순위 인코더 

 case문은 나열된 case항목들을 순서대로 조건과 비교하여 판단하며, 따라서 첫 번째 case항목이 나머지 case항목에 비해 묵시적으로 높은 우선순위를 갖는다.  if조건문에서도 첫 번째 조건이 나머지 다른 조건들에 비해 높은 우선순위를 갖는다. if와 case조건문 모두 상호 배타적이면 멀티플렉서로 합성되고, 그렇지 않은 경우에는 우선순위 구조로 합성된다. 

 

 다음 표는 우선순위 인코더(priority encoder)의 진리표이다. 출력 y의 값을 결정하는데 있어서 입력의 MSB인 a[3]이 가장 높은 우선순위를 갖는다. 신호 valid는 입력 a에 최소한 1비트 이상의 1이 포함되어 있는 경우에만 1이되어 출력 y의 유효성을 나타낸다. 

 다음 코드의 모델링은 이러한 우선순위를 활용해 if,casex문을 활용한 모델링이다. 3번째 방법은 for반복문을 활용한 모델링이며, for반복문 내부에서 입력a의 각 비트가 순차적으로 판단되어 출력 y의 값이 결정된다. 출력y의 default값은 for 반복문 밖에서 정의되어야 하는 것에 유의한다. for 반복문은 입력 또는 출력의 비트 수가 증가해도 소스코드의 길이가 늘지 않아 간결한 코딩이 가능하다는 장점을 갖는다. 

module pri_enc_4to2(a,y,valid);

    //1. case문 사용
    input [3:0] a;
    output reg [1:0] y;
    output reg valid;

    always@(*)begin
        valid =1;
        case(a)
            4'b1xxx : y=2'b11;
            4'b01xx : y=2'b10;
            4'b001x : y=2'b01;
            4'b0001 : y=2'b00;
            default : begin
                y=2'bx;
                valid=0;
            end
        endcase
    end

    // 2. if문 사용 
    input [3:0] a;
    output reg [1:0] y;
    output reg valid;

    always@(*)begin
        valid 1;
        if(a==4'b1xxx) y=2'b11;
        else if(a==4'b01xx) y=2'b10;
        else if(a==4'b001x) y=2'b01;
        else if(a==4'b0001) y=2'b00;
        else begin
            valid =0;
            y=2'bx;
        end
    end

    // 3. for문 사용 
    input [3:0] a;
    output reg[1:0]y;
    output reg valid;
    integer n;

    always@(*) begin
        valid=0;
        y=2'bx;
        for(n=3;n>=0;n=n-1) begin :LOOP
            if(a[n]) begin
                valid =1;
                y = n;
                disable LOOP;
            end
        end
endmodule

▣ TESTBENCH

module tb_pri_enc_4to2;
    reg [3:0] a;
    wire valid;
    wire [1:0] y;

    pri_enc_4to2 u0(a,y,valid);

    initial begin 
        a = 4'b0001;
        #20 a = 4'b0010;
        #20 a = 4'b0100;
        #20 a = 2'b1000;
        #20;
    end
endmodule

4TO2 PRIORITY ENCODER TESTBENCH SIMULATION

★ 디코더 

 n : m 이진 인코더로 인코딩된 데이터는 m:n 이진 디코더에 의해 원래의 데이터로 복원될 수 있으며, m :n 이진 디코더는 m비트의 입력을 받아 n(2**m)비트의 출력을 만든다. 2:4이진 디코더는 다음과 같은 진리표를 가지며 if, case조건문 , for반복문 등을 사용하여 모델링될 수 있다. 비트 수가 클 경우 for문을 활용하는것이 좋다. 

module dec_2to4 (a,y);
    input [1:0] a;
    output reg [3:0] y;

    // 1. case문 사용.
    always @(*) begin
        case(a)
            2'b00 : y=4'b0001;
            2'b01 : y=4'b0010;
            2'b10 : y=4'b0100;
            2'b11 : y=4'b1000;
            default : y=4'bx;
        endcase
    end

    // 2. if 조건문 사용 
    always @(*) begin
        if(a==2'b00) y=4'b0001;
        else if(a==2'b01) y=4'b0010;
        else if(a==2'b10) y=4'b0100;
        else if(a==2'b11) y=4'b1000;
        else y=4'bx;
    end

    // 3. for문 사용 
    integer n;
    always @(*) begin
        for(n=0;n<3;n=n+1) begin
            if(a==n)
                y[n] = 1'b1;
            else
                y[n] = 1'b0;
        end
    end

endmodule

▣ TESTBENCH

module tb_dec_2to4;
    reg [1:0] a;
    reg [3:0] y;

    dec_2to4 u0(a,y);

    always begin
        a= 2'b00;
        #20 a= 2'b01;
        #20 a= 2'b10;
        #20 a= 2'b11;
        #20;
    end
endmodule

2TO4 DECODER TESTBENCH SIMULATION

 디코더의 입력과 출력 비트 수를 각각 m비트 n비트로 파라미터화하여 모델링한 후, 모듈 인스턴스에서 파라미터 값의 변경을 통해 원하는 비트 수의 디코더를 구현할 수 있다.

module dec_param(en,a,y);
    parameter in_width =3 , out_width =6;
    input en;
    input [in_width-1:0] a;
    output reg [out_width-1:0] y;
    integer n;

    always @(*) begin
        if(!en) y=0;
        else
            if(a>out_width-1)
                for(n=0;n<=out_width;n=n+1)
                    y[n] = 1'bx;
            else
                for(n=0;n<out_width;n=n+1)
                    if(a==n) y[n] = 1'b1;
                    else y[n] = 1'b0;
    end
endmodule

▣ TESTBENCH

module tb_dec_param;
    reg en;
    reg [2:0] a;
    wire [5:0] y;
    integer n;

    dec_param u0(en,a,y);

    always begin
        en=1;
        for(n=0;n<8;n=n+1)begin
            #20 a=n;
        end

        en=0;
        for(n=0;n<8;n=n+1)begin
            #20 a=n;
        end
    end
endmodule

3TO6 ENABLE DECODER TESTBENCH SIMULATION
초기값 할당