반응형

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

 

 

반응형
반응형

 절차 블록 initial

절차 블록 initial은 합성할 수 없는 구성이며 0 시뮬레이션 시간에 한 번만 실행됩니다.

주로 초기화에 사용됩니다. 여기에 구문이 표시됩니다.

 

initial
begin
// assignments with delays
end

 

테스트 벤치는 initial 절차 블록을 사용하며, 목표는 테스트 중인 설계를 구동할 수 있는 초기값들을 생성해주는 것입니다. begin-end 내에서 지연 간 할당을 블록킹하는 경우 이러한 모든 할당이 순차적으로 실행됩니다.

 

시뮬레이션 개념: 기본 테스트벤치

대부분의 실제 시나리오에서 테스트벤치를 사용하여 설계의 기능적 정확성을 확인합니다. 기본 테스트 벤치는 드라이버와 DUT가 있는 다이어그램을 사용하여 시각화할 수 있습니다.

 

다음 그림과 같이 테스트벤치에는 드라이버와 DUT가 있다. 드라이버는 신호의 자극을 생성하고 DUT 입력을 구동하는 데 사용됩니다. 목표는 출력 신호를 확인하여 설계의 기능적 정확성을 이해하고 확인하는 것입니다.

 

 

다음 예제의 테스트벤치는 합성할 수 없는 구성을 사용하여 코딩되었습니다. 목적은 신호 a_in, b_in, control_in을 구동하고 result_out, carry_out에서 출력을 확인하는 것입니다.

 

module test_add_sub;
reg [3:0] a_in, b_in;
reg
control_in;
wire [3:0] result_out;
wire carry_out;

four_bit_subtractor UUT (

.a_in(a_in),
.b_in(b_in),
.control_in(control_in),
.result_out(result_out),
.carry_out(carry_out) );

initial
begin
  a_in = 4'b0000;
  b_in = 4'b0000;
  control_in =0;
  #10;
  a_in = 4'b1000;
  b_in = 4'b0010;
  control_in =0;
  #10;

a_in = 4'b1000;
b_in = 4'b0110;
#10;
a_in = 4'b1000;
b_in = 4'b0111;
control_in =1;
#50;
a_in = 4'b1000;
b_in = 4'b1111;
control_in =1;
#10;
a_in = 4'b0111;
b_in = 4'b0111;
control_in =0;
#10;
a_in = 4'b0111;
b_in = 4'b0111;
control_in =1;
end

endmodule

 

타임 스탬프 t = 20ns, control_in = 0에 대한 시뮬레이션 파형에서 볼 수 있듯이 1000, 0110을 더하여 result_out 1110으로, carry_out = 0을 얻습니다. 타임 스탬프 t = 30ns에서 control_in = 1, 1000 0111을 빼서 result_out = 0001, carry_out = 0이 됩니다. 다른 타임스탬프의 경우 result_out, carry_out을 관찰할 수 있습니다.

 

 

비교기와 패리티 검출기

대부분의 실제 시나리오에서 비교기는 두 이진수의 동등성을 비교하는 데 사용됩니다. 패리티 감지기는 주어진 이진수에 대한 짝수 또는 홀수 패리티를 계산하는 데 사용됩니다. 설계 엔지니어가 이에 대해 더 잘 이해하는 것이 매우 중요합니다.

 

이진 비교기

이들은 두 이진수를 비교하는 데 사용됩니다. 논의된 바와 같이, 이전 Verilog 4가지 상태를 지원하며 로직 0, 로직 1, x, 하이임피던스 z입니다. Verilog는 논리적 등호 연산자(==)와 부등 연산자(!=)를 지원하며 두 숫자를 비교하는 데 사용됩니다. 이러한 연산자는 합성 가능한 RTL 설계에 사용됩니다.

 

a_in b_in a_greater_b a_equal_b a_less_b
0 0 0 1 0
0 1 0 0 1
1 0 1 0 0
1 1 0 1 0

 

module binary_comparator (

input [3:0] a_in , b_in,
output reg a_greter_b, a_equal_b, a_less_

always @ *
begin
  if
(a_in ==b_in)
  begin
    a_greter_b = 0;
    a_equal_b = 1;
    a_less_b =0;
  end
  else if
(a_in > b_in)
  begin
    a_greter_b = 1;
    a_equal_b = 0;
    a_less_b =0;
  end
  else

begin
a_greter_b = 0;
a_equal_b = 0;
a_less_b =1;

end

end
endmodule

 

중첩된 if…else 구조를 사용하기 때문에 출력에서 멀티플렉서 트리로 우선 순위 논리를 유추하고 비효율적인 설계입니다.

 

패리티 감지기

패리티 감지기는 이진수 문자열의 짝수 또는 홀수 패리티를 감지하는 데 사용됩니다. 1이 짝수이면 출력이 로직 0이고 홀수이면 출력이 로직 1입니다.

 

Condition Description
Odd 1s Assign output as logical 1
Even 1s Assign output as logical zero

 

module even_parity_detector ( input [7:0] data_in, output parity_out);
assign parity_out = ^ data_in;
endmodule

 

코드 변환기

이름 자체에서 알 수 있듯이 코드 변환기는 코드를 한 숫자 체계 표현에서 다른 숫자 체계로 변환하는 데 사용됩니다. 실제 시나리오에서는 이진에서 gray, gray에서 이진 변환기가 사용됩니다.

 

이진-그레이 코드 변환기

이진수 시스템의 기수는 2이며, 다중 비트 이진수의 경우 하나 또는 두 개 이상의 비트가 두 개의 연속 숫자에서 변경됩니다. 그레이 코드에서는 두 개의 연속 그레이 코드에서 한 번에 한 비트만 변경됩니다.

 

4-bit binary 4-bit gray
0000 0000
0001 0001
0010 0011
0011 0010
0100 0110
0101 0111
0110 0101
0111 0100
1000 1100
1001 1101
1010 1111
1011 1110
1100 1010
1101 1011
1110 1001
1111 1000

 

module binary_to_gray ( input [3:0] binary_in, output [3:0] gray_out );
assign gray_out [3] = binary_in[3];
assign gray_out [2] = binary_in[3] ^ binary_in[2];
assign gray_out [1] = binary_in[2] ^ binary_in[1];
assign gray_out [0] = binary_in[1] ^ binary_in[0];
endmodule

 

그레이를 이진 코드로 변환하는 변환기

4비트 그레이-2진 코드 변환기의 진리표

4-bit gray 4-bit binary
0000 0000
0001 0001
0011 0010
0010 0011
0110 0100
0111 0101
0101 0110
0100 0111
1100 1000
1101 1001
1111 1010
1110 1011
1010 1100
1011 1101
1001 1110
1000 1111

 

module binary_to_gray ( input [3:0] gray_in, output [3:0] binary_out );
assign binary_out[3] = gray_in[3];
assign binary_out [2] = gray_in[3] ^ gray_in[2];
assign binary_out [1] = ( gray_in[3] ^ gray_in[2] ) ^ gray_in[1] ;
assign binary_out [0] = ( gray_in[3] ^ gray_in[2] ^ gray_in[0] ) ^gray_in[0];
endmodule

 

사양에서 디자인에 대해 생각하자

y_out을 각각 a_in != b_in a_in = b_in에 대한 XOR(a_in, b_in) XNOR(a_in, b_in)로 얻기 위한 RTL은 합성은 다음 처럼 코딩됩니다.

 

Condition Output Description
a_in = b_in y_out = a_in ~^ b_in If both inputs are at same logic level, then output
should be XNOR (a_in, b_in)
a_in != b_in y_out = a_in ^ b_in If both inputs are at different logic level, then output should be XOR (a_in, b_in)

 

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

반응형
반응형

절차 블록은 always @*

조합 설계 중에 대부분의 경우 always 절차 블록이 많은 수의 감지신호 입력을 가질 수 있습니다. 감지신호 목록이 있는 always 절차 블록은 조합 설계를 모델링하는 데 가장 적합합니다.

 

8개의 감지신호 입력에 always 절차적 블록은 다음처럼 표현할 수 있습니다.

always @ (a_in, b_in, c_in, d_in, e_in, f_in, g_in, h_in)

 

감지신호 목록에서 입력 중 하나를 놓치면 시뮬레이션 및 합성 불일치가 발생합니다. 시뮬레이션 및 합성 불일치를 피하기 위해 RTL 설계 중 더 나은 전략은 필요한 모든 입력을 감지할 수 있는always 절차 블록을 갖는 것입니다.

 

always @*를 사용할 수 있습니다. 여기서 *는 시뮬레이터에 제공되는 정보로 감지신호 목록의 모든 입력을 포함할 수 있습니다. 이 방법은 RTL 코딩의 효율적인 방법입니다.

 

다중 비트 가산기와 감산기

다중 비트 가산기 및 감산기는 프로세서의 산술 단위 설계에 사용됩니다.

 

4비트 전가산기

일반적으로 많은 실용적인 디자인은 다중 비트 가산기와 감산기를 사용합니다. 기본 구성 요소를 전가산기로 사용하여 더하기 작업을 수행하는 것이 산업 관행입니다.

 

예를 들어 설계자가 4비트 가산기를 구현하려면 4개의 전가산기가 필요합니다.

다음 예처럼 2개의 4비트 2진수 a_in, b_in의 덧셈을 수행하면 결과는 출력 포트 4비트 sum_out에서 사용할 수 있습니다. 캐리 입력은 c_in이고 캐리 출력은 carry_out입니다.

 

다음 예는 4비트 가산기에 대해 코딩된 RTL의 합성 결과이며, 4비트 가산기의 입력 포트는 a_in, b_in, c_in, 출력 포트는 sum_out, carry_out으로 명명하였습니다.

 

module four_bit_adder ( input [3:0] a_in, b_in, input c_in, output [3:0] sum_out, output carry_out);
assign { carry_out, sum_out } = a_in + b_in + c_in;
endmodule

 

 

4비트 완전 감산기

다음은 4비트 감산기의 실시예이며, 2개의 4비트 이진수 a_in, b_in에 대해 감산이 수행됩니다. 결과는 4비트 빼기이며 출력 포트 diff_out를 사용하였습니다. 빌림수 입력은 c_in이고 빌림수 출력은 borrow_out입니다.

 

module four_bit_subtractor ( input [3:0] a_in, b_in, input c_in, output [3:0] diff_out, output borrow_out );
assign { borrow_out, diff_out } = a_in - b_in - c_in;
endmodule

 

4비트 가산기와 감산기

덧셈과 뺄셈 연산의 설계는 가산기만 사용하여 수행할 수 있습니다. 뺄셈은 2의 보수 덧셈을 사용하여 수행할 수 있습니다.

 

RTL은 합성 가능한 구조를 사용하여 4비트 가산기 및 감산기를 구현하도록 코딩됩니다. control_in = 1이면 덧셈을 수행하고 control_in = 0인 경우 빼기를 수행합니다.

 

4비트 가산기/감산기의 입력 포트는 a_in, b_in, c_in으로 명명하고 제어 포트의 이름은 control_in, 출력의 이름은 result_out, carry_out로 하였습니다.

 

Operation Description Expression
Addition Unsigned addition of A, B A + B + 0
Subtraction Unsigned subtraction of A, B A - B = A + ~B + 1

 

module four_bit_adder_subtractor (

input [3:0] a_in, b_in,

input c_in,

input control_in,

output reg [3:0] result_out,
output reg carry_out );

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

endmodule

 

 

리소스 최적화

위의 예에서 코딩된 RTL 디자인을 주의 깊게 관찰하면 더하기 및 빼기를 수행하는 데 더 많은 리소스를 사용한다는 결론을 내릴 수 있습니다. 로직은 한 번에 두 가지 작업을 모두 수행하고 출력 선택 시 로직은 멀티플렉서 선택 입력(control_in)에 따라 작업 중 하나를 선택하는 데 사용됩니다. 설계가 비효율적이며 최적화가 필요합니다.

 

가산기만 사용한 최적화

리소스를 최적화하기 위해 2의 보수 덧셈을 사용하여 빼기를 구현해 보겠습니다.

다음 표에 표시된 작업에 대한 RTL if..else 구문을 사용하여 코딩되고 다음 예제에 나와 있습니다.

 

Operation control_in Expression
Addition 0 A + B + 0
Subtraction 1 A - B = A + ~B + 1

 

 

RTL을 코딩하는 데 사용되는 전략은 로직을 최적화하는 데 유용하며 설계는 데이터 경로의 가산기만 사용합니다. 그러나 멀티플렉서의 체인이 작업 중 하나의 결과를 선택하기 위해 출력에서 사용되기 때문에 여전히 문제가 있습니다.

 

module four_bit_adder_subtractor (

input [3:0] a_in, b_in,
input control_in,
output reg [3:0] result_out,
output reg carry_out );


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

 

 

로직을 더 좋게 조정하여 최적화

데이터 경로 및 제어 경로 최적화를 위해 공통 자원을 가산기로 사용하고 공통 표현식을 사용하여 더하기 및 빼기를 수행합니다.

 

합성 결과를 보면 추론된 로직은 2개의 가산기와 멀티플렉서만을 사용하였습니다. 출력 단계에서 가산기를 추론하고 최적화된 데이터와 제어 경로를 갖습니다.

 

 

Operation control_in Variable
input
Common
expression
Addition 0 b_in A + control_in
Subtraction 1 ~b_in A + control_in

 

module four_bit_adder_subtractor (

input [3:0] a_in, b_in,
input control_in,
output [3:0] result_out,
output carry_out );
reg [4:0] temp_result;

assign { carry_out, result_out } = a_in + temp_result ;

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

endmodule

 

 

반응형

+ Recent posts