반응형

 절차 블록 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

 

 

반응형
반응형

산술 회로

덧셈 및 뺄셈과 같은 산술 연산은 프로세서 논리 설계에 자주 사용됩니다. 모든 프로세서의 산술 및 논리 단위(ALU)는 더하기, 빼기, 증가 및 감소 연산을 수행하도록 설계되었습니다. 산술 설계는 원하는 성능을 달성하기 위해 합성 가능한 Verilog 코드로 설명되어야 합니다.

 

가산기

가산기는 두 이진수의 이진수 덧셈을 수행하는 데 사용됩니다. 가산기는 서명되거나 서명되지 않은 덧셈 연산에 사용됩니다.

 

반가산기

두 개의 입력 a_in, b_in을 갖고 단일 비트 출력 sum_out, carry_out을 생성하는 반가산기를 고려하십시오. 여기서 sum_out은 가산기 결과이고 carry_out은 캐리 출력입니다.

 

반가산기의 진리표

a_in b_in sum_out carry_out
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

 

module half_adder ( input a_in, b_in, output sum_out, carry_out );
assign sum_out = a_in ^ b_in;
assign carry_out = a_in & b_in;
endmodule

 

전가산기

전가산기는 덧셈을 수행하는 데 사용됩니다. 이진 입력을 a_in, b_in, c_in으로 간주하고 단일 비트 이진 출력을 sum_out, carry_out으로 간주합니다.

 

전가산기의 진리표

c_in a_in b_in sum_out carry_out
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

 

module full_adder ( input a_in, b_in, c_in, output sum_out, carry_out );
assign { carry_out, sum_out } = a_in + b_in + c_in;
endmodule

 

뺄셈기

뺄셈기는 두 이진수의 이진수 빼기를 수행하는 데 사용됩니다.

 

반감산기

입력이 _in, b_in이고 단일 출력 diff_out, rider_out을 생성하는 반감기를 고려하십시오. 여기서 diff_out은 차등 출력이고, borrow_out은 차입 출력입니다.

 

a_in b_in diff_out borrow_out
0 0 0 0
0 1 1 1
1 0 1 0
1 1 0 0

 

module half_subtractor ( input a_in, b_in, output diff_out, borrow_out );
assign diff_out = a_in ^ b_in;
assign borrow_out = (~a_in) & b_in;
endmodule

 

완전 감산기

전체 감산기는 빼기를 수행하는 데 사용됩니다. a_in, b_in, c_in으로 명명된 단일 비트 입력과 diff_out, borrow_out으로 단일 비트 이진 출력입니다.

 

c_in a_in b_in diff_out borrow_out
0 0 0 0 0
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
1 0 0 1 0
1 0 1 0 0
1 1 0 0 0
1 1 1 1 1

 

module full_subtractor ( input a_in, b_in, c_in, output diff_out, borrow_out );
assign { borrow_out, diff_out } = a_in- b_in - c_in;
endmodule

반응형
반응형

조합 논리는 논리 게이트로 구현되며 조합 논리에서 출력은 현재 입력의 함수입니다. 디자이너의 목표는 최소한의 논리 게이트 또는 논리 셀을 사용하여 논리를 구현하는 것입니다. 최소화 기법은 K-map, Boolean algebra, Shannon의 확장 정리입니다.

디자이너의 사고 과정은 디자인이 더 적은 논리 밀도로 더 나은 성능을 갖도록 해야 합니다. 면적 최소화 기술은 조합 논리 또는 부울 함수의 설계에서 중요한 역할을 합니다.

 

구성의 역할

조합 논리를 모델링하기 위해 할당 및 always @ 구문을 사용합니다. Always procedural 블록 내에서 if else로 구성하고 대부분의 경우 멀티플렉서 종류의 논리를 추론합니다.

 

if-else는 순차 구조이고 구문은 다음과 같습니다.

if (condition)

//blocking assignment executed if condition is true

else

// blocking assignment is executed if condition specified in if () is false

 

NOT 또는 논리 반전

NOT 논리는 반전 논리라고도 합니다.

합성 가능한 설계는 다음 예제와 같다.

 

module not_gate( input a_in, output reg y_out);
always@(a_in)
begin
  y_out = ~a_in;
end
endmodule

 

module not_gate( input a_in, output y_out);
assign y_out = ~a_in;
endmodule

 

NOT 게이트의 진리표

a_in y_out
0 1
1 0

 

 

OR 논리

OR 논리는 입력 중 하나가 논리 1일 때 논리 1로 출력을 생성합니다.

 

OR 게이트 진리표

a_in b_in y_out
0 0 0
0 1 1
1 0 1
1 1 1

 

module or_gate(input a_in, b_in , output reg y_out);
always@(a_in, b_in)
begin
  if ( a_in==0 && b_in ==0)
    y_out = 0;
  else
    y_out = 1;
end
endmodule

 

다음 그림은 OR 논리의 RTL 개략도이며, OR 논리 게이트의 입력 포트는 a_in, b_in, 출력 포트는 y_out입니다. 회로도에서 볼 수 있듯이 추론된 논리는 2:1 멀티플렉서 및 기타 연산자를 사용하여 논리를 추론합니다. 합성 결과는 EDA 도구에 따라 다르며 ASIC FPGA 설계의 경우 합성 결과가 다를 수 있습니다.

 

 

다중 입력 OR 게이트의 경우 비트 연산자( | )를 사용할 수 있습니다.

 

module or_gate(input [7:0] a_in, b_in , output [7:0] y_out);
assign y_out = a_in | b_in;
endmodule

 

 

NOR 논리

NOR 논리는 OR 논리의 반전입니다.

NOR 논리의 진리표

a_in b_in y_out
0 0 1
0 1 0
1 0 0
1 1 0

 

module nor_gate(input a_in, b_in , output reg y_out);
always@(a_in, b_in)
begin
  if ( a_in==0 && b_in ==0)
    y_out = 1;
  else
    y_out = 0;
end
endmodule

 

NOR 논리 게이트의 입력 포트는 a_in, b_in, 출력 포트는 y_out입니다. 그림과 같이 추론된 논리는 등호 연산자와 AND 게이트를 사용하여 NOR 게이트를 구현합니다.

 

 

다중 입력 OR 게이트의 경우 비트 연산자 OR( | )의 비트 NOT(~)을 사용할 수 있습니다.

 

module nor_gate(input [7:0] a_in, b_in , output [7:0] y_out);
assign y_out = ~(a_in | b_in);
endmodule

 

 

AND 논리

AND 논리는 입력 a_in, b_in이 모두 논리 1일 때 논리 1로 출력을 생성합니다.

 

AND 논리의 진리표

a_in b_in y_out
0 0 0
0 1 0
1 0 0
1 1 1

 

module and_gate(input a_in, b_in , output reg y_out);
always@(a_in, b_in)
begin
  if
( a_in==1 && b_in ==1)
    y_out = 1;
  else
    y_out = 0;
end
endmodule

 

낸드 로직

NAND AND 논리의 반전입니다.

 

NAND 논리의 진리표

a_in b_in y_out
0 0 1
0 1 1
1 0 1
1 1 0

 

module nand_gate(input a_in, b_in , output reg y_out);
always@(a_in, b_in)
begin
  if
( a_in==1 && b_in ==1)
    y_out = 0;
  else
    y_out = 1;
end
endmodule

 

NAND 로직의 RTL 회로도는 다음 그림과 같으며, NAND 로직 게이트의 입력 포트는 a_in, b_in으로 명명되고 출력은 y_out으로 명명됩니다. 추론된 논리는 멀티플렉서를 사용하여 AND NOT을 생성합니다.

 

 

다중 입력 NAND 게이트는 할당 구성을 사용하고 비트 NOT(~) 및 비트 AND(&) 연산자가 있는 표현식을 사용하여 코딩되며 다음 예제와 같습니다.

 

module nand_gate(input [7:0] a_in, b_in , output [7:0] y_out);
assign y_out = ~(a_in & b_in);
endmodule

 

 

2입력 XOR 논리

두 개의 입력 XOR을 배타적 논리합(exclusive OR logic)이라고 하며 두 입력이 같지 않을 때 논리 1로 출력을 생성합니다.

 

XOR 논리의 진리표

a_in b_in y_out
0 0 0
0 1 1
1 0 1
1 1 0

 

module xor_gate(input a_in, b_in , output reg y_out);
always@(a_in, b_in)
begin
  if
( a_in != b_in )
    y_out = 1;
  else
    y_out = 0;
end
endmodule

 

다중 입력 XOR 게이트에 대한 RTL은 비트 단위 연산자를 사용하여 코딩됩니다.

 

module xor_gate ( input [7:0] a_in, b_in , output [7:0] y_out );
assign y_out = (a_in ^ b_in);
endmodule

 

2입력 XNOR 논리

두 개의 입력 XNOR를 배타적 NOR 논리라고 하며 두 개의 입력이 같을 때 논리 1로 출력을 생성합니다. XNOR XOR 논리의 반전입니다.

 

module xnor_gate(input a_in, b_in , output reg y_out);
always@(a_in, b_in)
begin
  if
( a_in == b_in )
    y_out = 1;
  else
    y_out = 0;
end
endmodule

 

라이브러리에서 XNOR 게이트를 사용할 수 없는 경우 AND-OR-invert를 사용하거나 최소 수의 NAND 또는 NOR 게이트를 사용하여 XNOR 논리를 실현할 수 있습니다.

 

다중 입력 XNOR에 대한 RTL은 다음 예제와 같습니다.

module xnor_gate(input [7:0] a_in, b_in , output [7:0] y_out);
assign y_out = (a_in ~^ b_in);
endmodule

 

tri-state 논리

Tristate에는 논리 0, 논리 1 및 고임피던스 z의 세 가지 논리 상태가 있습니다.

 

tri-state 버퍼 논리의 진리표

Enable data_in data_out
1 0000 0000
1 1111 1111
0 xxxx zzzz

 

module tri_state_logic ( input [3:0] data_in, input enable, output reg [3:0] data_out );

always@(data_in, enable)
begin
  if
(enable)
    data_out = data_in;
  else
    data_out= 4'bZZZZ;
end
endmodule

반응형

+ Recent posts