반응형

인코더

인코더의 기능은 디코더와 정확히 반대입니다. 인코더에는 n개의 입력 라인과 m개의 출력 라인이 있으며, 입력 라인과 출력 라인 사이의 관계는 n = 2m로 주어진다. 예를 들어 4:2 인코더를 고려해보자. 입력 라인의 수는 n = 4이고 출력 라인은 m = 2입니다. 4:2 인코더의 블록 다이어그램은 아래 그림과 같습니다.

 

 

In[3] In[2] In[1] In[0] Out_Y[1] Out_Y[0]
1 0 0 0 1 1
0 1 0 0 1 0
0 0 1 0 0 1
0 0 0 1 0 0

 

module encoder_4to2 ( input [3:0] data_in, output reg invalid_data, output reg [1:0] y_out);
always @*
begin
  case
( data_in )
    4'b0001 : { invalid_data, y_out } = 3'b000;
    4'b0010 : { invalid_data, y_out } = 3'b001;
    4'b0100 : { invalid_data, y_out } = 3'b010;
    4'b1000 : { invalid_data, y_out } = 3'b011;
    default : { invalid_data, y_out } = 3'b100;
  endcase
end
endmodule

 

우선 순위 인코더

우선 순위 인코더는 실제 응용 분야에서 사용되며 n개의 입력 라인과 m개의 출력 라인을 가지며 입력 라인과 출력 라인 간의 관계는 n = 2m로 주어집니다. 예를 들어 4:2 우선 순위 인코더를 고려해보면 입력 라인의 수는 n = 4이고 출력 라인은 m = 2입니다. 4:2 우선 순위 인코더의 블록 다이어그램은 다음 그림과 같습니다.

 

 

입력 In[3]이 가장 높은 우선 순위를 가지며 입력 in[0]이 가장 낮은 우선 순위를 갖습니다. 여기서 'X'는 상관 없음을 나타냅니다.

 

In[3] In[2] In[1] In[0] Out_Y[1] Out_Y[0]
1 X X X 1 1
0 1 X X 1 0
0 0 1 X 0 1
0 0 0 1 0 0

 

module encoder_4to2 ( input [3:0] data_in, output reg invalid_data, output reg [1:0] y_out );
always @*
begin
  if
( data_in[3])
    { invalid_data, y_out } = 3'b000;
  else if (data_in[2])
    { invalid_data, y_out } = 3'b001;
  else if (data_in[1])
    { invalid_data, y_out } = 3'b010;
  else if (data_in[0])
    { invalid_data, y_out } = 3'b011;
  else
    { invalid_data, y_out } = 3'b100;
end
endmodule

 

4:2 우선순위 인코더 테스트벤치

우선순위 테스트벤치와 시뮬레이션 파형은 다음과 같습니다.

 

module test_encoder_4to2;
// Inputs
reg [3:0] data_in;
// Outputs
wire invalid_data;
wire [1:0] y_out;

// Instantiate the Unit Under Test (UUT)
encoder_4to2 uut (
.data_in(data_in),
.invalid_data(invalid_data),
.y_out(y_out)
);

always #5 data_in[0] = ~data_in[0];
always #10 data_in[1] = ~data_in[1];
always #20 data_in[2] = ~data_in[2];
always #40 data_in[3] = ~data_in[3];

inial
begin
  // Inialize Inputs
  data_in = 0;

// Wait 100 ns for global reset to finish
#100;
end

endmodule

 

반응형
반응형

디코더와 인코더

대부분의 시스템 설계에서 디코더와 인코더의 사용을 경험합니다.

시스템 설계에서 대부분의 경우 디코더를 사용하여 메모리 또는 IO 장치 중 하나를 선택합니다.

 

디코더

디코더에는 n개의 선택 라인 또는 입력 라인과 m개의 출력 라인이 있으며 high 활성 또는 low 활성 출력을 생성하는 데 사용됩니다. 선택 라인과 출력 라인 사이의 관계는 m = 2n으로 주어진다. 한 번에 n개의 입력 라인의 논리 상태에 따라 출력 라인 중 하나가 하이 또는 로우가 됩니다.

 

다음 그림은 3:8 디코더를 나타냅니다. 그림과 같이 X2, X1, X0은 선택 입력이고 Y0 ~ Y7은 하이 활성 출력 라인입니다.

 

다음 표는 디코더의 진리표입니다. 하이 활성 출력 디코더의 경우 한 번에 출력 라인 중 하나가 하이 활성됩니다.

 

X2 X1 X0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
0 0 0 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0 0
0 1 1 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0 0 0
1 0 1 0 0 1 0 0 0 0 0
1 1 0 0 1 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0

 

다음 그림은 하이 활성 인에이블 입력 en을 갖는 3:8 디코더의 상징적 표현입니다. 표시된 진리표는 활성 하이 활성화 en = 1을 갖는 디코더에 대해 양호합니다. en = 0일 때 디코더는 비활성화되고 출력 Y = 8'b0000_0000입니다.

 

 

다음은 3:8 디코더의 코딩 예제입니다.

 

//Verilog RTL for 3 to 8 decoder
module decoder_3to8 (X,en,Y) ;
input [2:0] X;
input en;
output [7:0] Y;
reg [7:0] Y;

// Functionality of design
always @ (X or en)
begin
  if (en)
    case(X)
      3'b000 : Y= 8'b0000_0001;
      3'b001 : Y= 8'b0000_0010;
      3'b010 : Y= 8'b0000_0100;
      3'b011 : Y= 8'b0000_1000;
      3'b100 : Y= 8'b0001_0000;
      3'b101 : Y= 8'b0010_0000;
      3'b110 : Y= 8'b0100_0000;
      3'b111 : Y= 8'b1000_0000;
    endcase
  else
    Y=8'b0000_0000;
  end
endmodule

 

case 구성을 사용하는 1 라인에서 2 디코더로

1 라인 대 2 또는 (1:2) 디코더에는 하나의 선택 입력 Sel과 두 개의 출력 라인 Out_Y0 Out_Y1이 있습니다.

입력 sel_in, 하이 활성화 입력 enable_in 및 출력 y_out[0], y_out[1]이 있는 1:2 디코더 입니다.

 

Sel Out_Y1 Out_Y0
0 0 1
1 1 0

 

module decoder_1to2 ( input sel_in, input enable_in, output reg [1:0] y_out );
always @*
begin
  if
(enable_in)
    case ( sel_in )
      1'b0 : y_out = 2'b01;
      1'b1 : y_out = 2'b10;
    endcase
  else
    y_out = 2'b00;
  end
endmodule

 

1 Line to 2 Decoder 사용 사례

1 라인 대 2 또는 1:2 디코더에는 1개의 선택 입력 Sel, 인에이블 입력 En 2개의 출력 라인 Out_Y0 Out_Y1이 있습니다.

 

En Sel Out_Y1 Out_Y0
1 0 0 1
1 1 1 0
0 X 0 0

 

//Verilog RTL for 1 Line to 2 Line decoder with active high enable input
module one_two_decoder_with_enable ( Sel, En, Out_Y1, Out_Y0);
input Sel;
input En;
output Out_Y1;
output Out_Y0;
reg Out_Y1;
reg Out_Y0;

always @ (Sel or En)
begin
  if (En)
    case (Sel)
      1'b0 : {Out_Y1, Out_Y0} = 2'b01;
      1'b1 : {Out_Y1, Out_Y0} = 2'b10;
    endcase
  else
    {Out_Y1, Out_Y0} = 2'b00;
  end
endmodule

 

2 Line to 4 Decoder with Enable 사용 사례

2 라인 대 4 또는 (2:4) 디코더에는 2개의 선택 입력 sel_in[1], sel_in[0], enable 입력 enable_in 4개의 출력 라인 y_out[3], y_out[2], y_out[1] y_out이 있습니다.

 

enable_in Sel_in[1] sel_in[0] y_out[3] y_out[2] y_out[1] y_out[0]
1 0 0 0 0 0 1
1 0 1 0 0 1 0
1 1 0 0 1 0 0
1 1 1 1 0 0 0
0 X X 0 0 0 0

 

module decoder_2to4 ( input [1:0] sel_in, input enable_in, output reg [3:0] y_out );
always @*
begin
  if
(enable_in)
    case ( sel_in )
      2'b00 : y_out = 4'b0001;
      2'b01 : y_out = 4'b0010;
      2'b10 : y_out = 4'b0100;
      2'b11 : y_out = 4'b1000;
    endcase
  else
    y_out = 2'b0000;
  end
endmodule

 

로우 활성화가 있는 2라인-4 디코더 사용

2 라인 대 4 또는 (2:4) 디코더에는 2개의 선택 입력 Sel[1], Sel[0], 로우 활성화 입력 En_bar 4개의 활성 로우 출력 라인 Out_Y[3], Out_Y[2], Out_Y[1], Out_Y[0]이 있습니다.

 

En_bar Sel[1] Sel[0] Out_Y[3] Out_Y[2] Out_Y[1] Out_Y[0]
0 0 0 1 1 1 0
0 0 1 1 1 0 1
0 1 0 1 0 1 1
0 1 1 0 1 1 1
1 X X 1 1 1 1

 

//Verilog RTL for 2 Line to 4 Line decoder with active low enable input and active low output lines
module Two_to_Four_decoder(Sel,En_bar, Out_Y);
input [1:0] Sel;
input En_bar;
output [3:0] Out_Y;
reg [3:0] Out_Y;

always @ (Sel or En_bar)
begin
  if (~En_bar)
    case (Sel)
      2'b00 : Out_Y = 4'b1110;
      2'b01 : Out_Y = 4'b1101;
      2'b10 : Out_Y = 4'b1011;
      2'b11 : Out_Y = 4'b0111;
    endcase
  else
    Out_Y = 4'b1111;
  end
endmodule

 

//Verilog RTL for 2 Line to 4 Line decoder with active low enable input and for active low output lines
module Two_to_Four_decoder(Sel,En_bar, Out_Y);
input [1:0] Sel;

input En_bar;

output [3:0] Out_Y;

 

assign Out_Y[3] = (~En_bar) && (~Sel[1]) && (~Sel[0]);
assign Out_Y[2] = (~En_bar) && (~Sel[1]) && (Sel[0]);
assign Out_Y[1] = (~En_bar) && (Sel[1]) && (~Sel[0]);
assign Out_Y[0] = (~En_bar) && (Sel[1]) && (Sel[0]);
endmodule

 

연속 할당을 사용하는 2-4 디코더

디코더의 기능도 연속 할당 구성을 사용하여 설명할 수 있습니다. 다중 할당 구문인 이유는 병렬로 실행되고 병렬 출력 로직으로 유추합니다.

 

module decoder_2to4 ( input [1:0] sel_in, input enable_in, output [3:0] y_out );
assign y_out[0] = enable_in & (~sel_in[1])&(~sel_in[0]);
assign y_out[1] = enable_in & (~sel_in[1])&(sel_in[0]);
assign y_out[2] = enable_in & (sel_in[1])&(~sel_in[0]);
assign y_out[3] = enable_in & (sel_in[1])&(sel_in[0]);
endmodule

 

시프트 연산자를 사용한 디코더

2:4 디코더에 대한 RTL 설계를 구현하는 더 나은 기술은 시프트 연산자를 사용하는 것입니다.

 

module decoder_2to4 ( input [1:0] sel_in, input enable_in, output reg [3:0] y_out );
always @*
begin
  if
(~enable_in)
    y_out = 4'b0000;
  else
    y_out = ( 4'b0001 << sel_in);
  end
endmodule

 

2:4 디코더의 테스트벤치

2:4 디코더의 테스트벤치와 시뮬레이션 결과를 보여주고 있습니다.

 

 

module test_decoder;
// Inputs
reg [1:0] sel_in;
reg enable_in;
// Outputs
wire [3:0] y_out;

// Instantiate the Unit Under Test (UUT)
decoder_2to4 uut ( .sel_in(sel_in), .enable_in(enable_in), .y_out(y_out));

always #10 sel_in[0] = ~sel_in[0];
always #20 sel_in[1] = ~sel_in[1];

initial
begin
  // Initialize Inputs
  sel_in = 0;
  enable_in = 0;
  // Wait 100 ns and then force enable_in =1
  #100;
  enable_in =1 ;

// Wait 250 ns and then force enable_in =0
#250
enable_in =0;

end
endmodule

 

2:4 디코더를 사용하여 4라인에서 16 디코더로

4 라인 대 16 또는 (4:16) 디코더에는 4개의 선택 입력 sel_in[3]: sel_in[0], 활성 로우 인에이블 입력 enable_in이 있으며 4개의 2:4 디코더를 사용하여 설계되었습니다. 2:4 디코더에는 4개의 활성 로우 출력 라인 y_out[3], y_out[2], y_out[1] y-out[0]이 있습니다. 출력에 16개의 2:1 멀티플렉서가 있습니다.

 

module decoder_4to16 ( input [3:0] sel_in, input enable_in, output reg [15:0] y_out );
reg [3:0] tmp_enable;


always@*
  if (~enable_in)
    tmp_enable = 4'b0000;
  else
    tmp_enable = ( 4'b0001 << sel_in[3:2]);

always@*
if (~tmp_enable[0])
  y_out[3:0] = 4'b0000;
else
  y_out [3:0] = ( 4'b0001 << sel_in[1:0]);

 

always@*
if (~tmp_enable[1])
  y_out[7:4] = 4'b0000;
else

y_out [7:4] = ( 4'b0001 << sel_in[1:0]);

always@*
if (~tmp_enable[2])
  y_out[11:8] = 4'b0000;
else
  y_out [11:8] = ( 4'b0001 << sel_in[1:0]);

 

always@*
if (~tmp_enable[3])
  y_out[15:12] = 4'b0000;
else
  y_out [15:12] = ( 4'b0001 << sel_in[1:0]);

endmodule

 

4:16 디코더용 테스트벤치

4:16 디코더에 대한 테스트벤치와 시뮬레이션 결과는 다음과 같습니다.

 

 

module test_decoder_4to16;
// Inputs
reg [3:0] sel_in;
reg enable_in;
// Outputs
wire [15:0] y_out;

// Instantiate the Unit Under Test (UUT)
decoder_4to16 uut (
.sel_in(sel_in),
.enable_in(enable_in),
.y_out(y_out)
);


always #5 sel_in[0] = ~sel_in[0];
always #10 sel_in[1] = ~sel_in[1];
always #20 sel_in[2] = ~sel_in[2];
always #40 sel_in[3] = ~sel_in[3];

initial
begin
  // Initialize Inputs
  sel_in = 0;
  enable_in = 0;

// Wait 100 ns and then force enable_in =1

#100;

enable_in =1 ;
// Wait 250 ns and then force enable_in =0
#250
enable_in =0;

end
endmodule

반응형
반응형

4:1 MUX 사용 사례 구성

4:1 MUX case-endcase 구조를 사용하여 설명됩니다.

표시된 것처럼 case-endcase 구성은 병렬 논리를 추론하는 데 사용됩니다.

 

module mux_4to1 ( input [3:0] d_in, input [1:0] sel_in, output reg y_out);
always @*
begin
  case
( sel_in )
    2'b00 : y_out = d_in[0];
    2'b01 : y_out = d_in[1];
    2'b10 : y_out = d_in[2];
    2'b11 : y_out = d_in[3];
  endcase
end
endmodule

 

 

2:1 MUX를 사용하는 4:1 Mux

4:1 MUX 2:1 MUX를 사용하여 구현할 수 있습니다.

4:1 MUX 3개의 2:1 멀티플렉서를 사용하여 구현됩니다.

 

 

module mux_4to1 ( input [3:0] d_in, input [1:0] sel_in, output y_out );

reg tmp_1, tmp_2;

always @*

begin
case
( sel_in[0] )
1'b0 : begin
  tmp_1 = d_in[0];
  tmp_2 = d_in[2];
end
1'b1 : begin
  tmp_1 = d_in[1];
  tmp_2 = d_in[3];
end
endcase

end

assign y_out = (sel_in[1]) ? tmp_2 : tmp_1;

endmodule

 

멀티플렉서를 사용하여 조합 논리 설계

이제 합성 가능한 구조를 사용하여 다음 표에 표시된 단일 비트 가산기와 감산기를 구현해 보겠습니다.

if…else 구성의 사용으로 인해 추론된 논리는 출력에서 멀티플렉서 체인을 사용합니다.

 

Control input Operation Description
0 a_in + b_in Perform addition of (a_in, b_in)
1 a_in - b_in Perform subtraction of (a_in, b_in)

 

module add_sub ( input a_in, b_in, control_in, output reg result_out, carry_out );

always @ *
if (control_in)
  { carry_out, result_out } = a_in + b_in;
else
  { carry_out, result_out } = a_in + (~b_in) + 1;

endmodule

 

RTL 조정을 사용한 최적화 전략

위의 예제의 최적화 전략은 한 번에 하나의 연산만 수행하고 최소 리소스를 사용합니다.

 

module add_sub ( input a_in, b_in, control_in, output reg result_out, carry_out );
reg tmp_1;


always @*
{ carry_out, result_out } = a_in + tmp_1 + control_in ;

always @ *
if (control_in)
  tmp_1 = ~b_in;
else
  tmp_1 = b_in;

endmodule

반응형
반응형

범용 로직으로서의 멀티플렉서

대부분의 응용 프로그램에서 멀티플렉서를 사용합니다. 멀티플렉서 또는 MUX Boolean 함수 또는 논리 게이트를 구현하는 데 사용되며 범용 로직이라고 합니다. 멀티플렉서의 주요 응용 프로그램은 입력 중 하나를 선택하는 스위치라고 생각하면 됩니다.

 

멀티플렉서

멀티플렉서는 많은 입력 중 하나를 선택하는 데 사용됩니다. 멀티플렉서는 범용 로직이라고도 하며 실제로 사용되는 용어는 MUX입니다. 적절한 멀티플렉서를 사용하여 모든 조합 논리 기능을 실현할 수 있습니다.

 

멀티플렉서는 ASIC FPGA 기반 설계에서 선택 로직으로 사용됩니다.

 

멀티플렉서는 가산기에 비해 더 적은 면적을 차지하며, 대부분의 경우 MUX는 가산기 및 감산기와 같은 산술 구성 요소를 구현하는 데 사용됩니다.

 

다음 그림은 n:1 MUX의 블록도를 나타내고 있으며 n개의 입력 라인, m개의 선택 라인, 하나의 출력 라인으로 구성됩니다. 입력 라인은 i[0], i[1] … i[n - 1]로 표시됩니다. s[0], s[1], … s[m - 1]로 라인을 선택하고 y로 라인을 출력합니다.

 

멀티플렉서는 n개의 입력 라인, m개의 선택 라인 및 단일 출력 라인을 가지고 있습니다. 입력 라인과 선택 라인 사이의 관계는 n = 2m로 표시됩니다.

예를 들어, 4:1 MUX 입력 라인은 4개이므로 m = log2n, 2와 동일한 라인을 선택합니다.

 

 

범용 로직으로서의 멀티플렉서

모든 조합 논리 기능이 MUX를 사용하여 실현될 수 있으므로 범용 논리로 취급됩니다.

 

2:1 먹스

2:1 MUX에는 2개의 입력 라인이 있습니다. 하나는 선택 라인이고 다른 하나는 출력 라인입니다. sel_in 입력이 논리 0일 때 출력 y_out a_in으로 할당되고 출력은 논리 1과 동일한 sel_in에 대해 b_in으로 할당됩니다.

 

2:1 MUX 및 게이트 레벨 설계의 진리표

sel_in y_out
O a_in
1 b_in

 

module mux_2to1 ( input a_in, b_in, sel_in, output y_out );
assign y_out = (sel_in) ? b_in : a_in ;
endmodule

 

 

MUX를 범용 로직을 사용하는 이유는 이해하기 쉽고 구조가 간단하기 때문입니다. 다음 그림은 2:1 MUX를 사용하여 2개의 입력 XOR 논리 게이트를 구현하는 방법을 이해하는 데 유용합니다. XOR 논리 게이트에 두 개의 입력 a, b 및 출력 y가 있다고 가정합니다.

 

 

if...else case 구문

2:1 MUX를 코딩할 수 있는 다양한 방법이 있습니다.

if-else를 사용하거나 case… endcase를 사용하여 코딩할 수 있습니다.

 

다음 예는 if-else를 사용하여 합성 가능한 디자인과 case문을 사용하여 합성 가능한 디자인을 설명합니다.

 

module mux_2to1( input a_in, b_in, sel_in, output reg y_out );
always@*
begin
  if
(sel_in)
    y_out = b_in;
  else
    y_out = a_in;
  end
endmodule

 

module mux_2to1 ( input a_in, b_in, sel_in, output reg y_out );
always@*
begin
  case
(sel_in)
    1'b0 : y_out = a_in;
    1'b1 : y_out = b_in;
  endcase
end
endmodule

 

if...else를 사용하는 4:1 MUX

4:1 MUX에는 4개의 입력 라인과 단일 출력 라인이 있습니다. 4:1 MUX에는 두 개의 선택 라인이 있으며 한 번에 하나의 입력을 선택하는 데 사용됩니다.

 

4:1 MUX의 진리표

sel_in[1] sel_in[0] y_out
0 0 d_in[0]
0 1 d_in[1]
1 0 d_in[2]
1 1 d_in[3]

 

module mux_4to1 ( input [3:0] d_in, input [1:0] sel_in, output reg y_out );
always @*
begin
  if
(sel_in ==2'b00)
    y_out = d_in[0];
  else if (sel_in ==2'b01)
    y_out = d_in[1];
  else if (sel_in ==2'b10)
    y_out = d_in[2];
  else
    y_out = d_in[3];
  end
endmodule

 

 

반응형

+ Recent posts