Verilog 수학 함수는 상수 표현식 대신 사용할 수 있으며 정수와 실수 연산을 모두 지원합니다. 정수 수학 함수 $clog2 함수는 주어진 인자의 log2의 올림(ceiling) 값을 반환합니다. 이는 주로 주어진 크기의 메모리를 어드레싱하는 데 필요한 최소 비트 폭을 계산하는 데 사용됩니다. 예를 들어, 설계에 7개의 병렬 가산기가 있으면 7을 모두 표현하는 데 필요한 최소 비트 수는 7의 $clog2인 3이 됩니다. module des #(parameter NUM_UNITS = 7) // 이 시스템 함수를 사용하여
디스플레이 시스템 태스크는 주로 시뮬레이션 흐름을 로그 파일로 추적하고 디버깅을 빠르게 돕기 위해 정보 및 디버그 메시지를 표시하는 데 사용됩니다. 다양한 디스플레이 태스크 그룹과 값 출력 형식이 있습니다. Display/Write 태스크 문법 $display와 $write 모두 인자 리스트에 나타나는 순서대로 인자들을 표시합니다. $display(<list_of_arguments>); $write(<list_of_arguments>); $write는 문자열 끝에 줄바꿈 문자 \n을 추가하지 않지만, $
클럭은 서로 다른 블록들이 서로 동기화될 수 있게 하므로 디지털 회로 구축의 기초입니다. 클럭의 속성 디지털 클럭의 핵심 속성은 주파수(frequency)(클럭 주기 결정), 듀티 사이클(duty cycle), 다른 클럭과의 관계에서 클럭 위상(phase)입니다. 클럭 주기 주파수는 특정 시간 동안 몇 사이클이 있는지를 나타냅니다. 따라서 클럭 주기는 1 사이클을 완료하는 데 걸리는 시간입니다. 클럭 듀티 사이클 클럭이 하이 상태인 시간이 주기 대비 몇 퍼센트인지 정의합니다. 클럭 위상 한 클럭 주기를 360도 원으로
Verilog 설계와 테스트벤치는 일반적으로 always 또는 initial 블록, 연속 할당, 기타 절차적 문장으로 구성된 많은 코드 라인을 가지며, 이들은 시뮬레이션 과정에서 서로 다른 시간에 활성화됩니다. Verilog 모델에서 신호 값의 모든 변경은 업데이트 이벤트(update event)로 간주됩니다. 그리고 이러한 업데이트 이벤트에 민감한 always와 assign 블록 같은 프로세스들은 임의의 순서로 평가되며 이를 평가 이벤트(evaluation event)라고 합니다. 이러한 이벤트들이 서로 다른 시간에 발생할 수
Verilog 시뮬레이션은 시간이 어떻게 정의되는지에 의존합니다. 시뮬레이터는 #1이 시간 측면에서 무엇을 의미하는지 알아야 하기 때문입니다. `timescale 컴파일러 지시자는 뒤따르는 모듈들의 시간 단위와 정밀도를 지정합니다. 문법 `timescale <time_unit>/<time_precision> // 예제 `timescale 1ns/1ps `timescale 10us/100ns `timescale 10ns/1ns time_unit은 지연과 시뮬레이션 시간의 측정 단위이며, time_precisi
Verilog는 하드웨어 기술 언어이며, 설계자가 RTL 설계를 시뮬레이션하여 로직 게이트로 변환할 수 있어야 한다는 요구사항은 없습니다. 그렇다면 왜 시뮬레이션을 해야 할까요? 시뮬레이션은 설계에 서로 다른 시간에 다양한 입력 자극을 가하여 RTL 코드가 의도한 대로 동작하는지 확인하는 기법입니다. 본질적으로 시뮬레이션은 설계의 견고성을 검증하는 잘 정립된 기법입니다. 또한 제작된 칩이 실제 세계에서 어떻게 사용되고 다양한 입력에 어떻게 반응할지와 유사합니다. 예를 들어, 위 설계는 클럭과 신호 입력을 가진 양의 에지 검출
표준 Verilog 기본 요소(nand, not 등)가 복잡한 로직을 표현하기에 항상 쉽거나 충분하지 않을 수 있습니다. UDP 또는 사용자 정의 기본 요소(user-defined primitives)라고 하는 새로운 기본 요소들을 정의하여 조합 또는 순차 로직을 모델링할 수 있습니다. 모든 UDP는 정확히 하나의 출력을 가지며 0, 1, X 중 하나일 수 있고 Z는 절대 될 수 없습니다(지원 안 함). Z 값을 가진 입력은 X로 처리됩니다. Verilog UDP 기호 Verilog 사용자 정의 기본 요소는 module 정의와
Verilog는 트랜지스터 레벨 모델링도 지원하지만, 회로 복잡성이 증가하면서 설계자들이 스위치 레벨 모델링보다는 더 높은 추상화 수준으로 이동해야 했기 때문에 요즘은 설계자들이 거의 사용하지 않습니다. NMOS/PMOS module des (input d, ctrl, output outn, outp); nmos (outn, d, ctrl); pmos (outp, d, ctrl); endmodule module tb; reg d, ctrl; wire outn, outp; des u0 (.d(d), .ctrl(
디지털 소자는 이진 엔티티로 0과 1 두 값만 가질 수 있습니다. 그러나 0에서 1로, 1에서 0으로의 전이에는 과도기 지연이 있으며, 각 게이트 소자도 입력을 출력으로 전파하는 데 지연이 있습니다. 예를 들어, 2입력 AND 게이트는 두 입력이 모두 1이 되면 출력을 1로 전환하고, 입력 중 하나가 0이 되면 다시 0으로 전환해야 합니다. 이러한 게이트와 핀-투-핀 지연은 Verilog에서 논리 기본 요소를 인스턴스화할 때 지정할 수 있습니다. 상승, 하강, 턴오프 지연 게이트 출력이 어떤 값에서 1로 변경되는 데 걸리는 시간
이전 글에서 주요 내장 기본 요소들을 다루었고, 간단한 and, nor, not 게이트를 사용한 실전 예제를 보는 것이 좋겠습니다. 기본 요소의 출력 포트와 연결하기 위해 모듈 출력은 wire 타입이어야 합니다. 예제 #1: 2x1 멀티플렉서 module mux_2x1 ( input a, b, sel, output out ); wire sel_n; wire out_0; not (sel_n, sel); and (out_0, a, sel); and (out_1, b, sel_n); or (out, ou
대부분의 디지털 설계는 RTL 같은 높은 추상화 수준에서 수행되지만, 때로는 and, or 같은 조합 소자를 사용하여 더 낮은 수준에서 작고 결정적인 회로를 구축하는 것이 직관적일 수 있습니다. 이 수준에서의 모델링은 일반적으로 게이트 레벨 모델링이라고 불리며, 게이트를 포함하고 하드웨어 회로도와 Verilog 코드 간에 일대일 대응 관계가 있습니다. Verilog는 기본 요소(primitives)로 알려진 몇 가지 기본 논리 게이트를 지원하는데, 이들은 이미 미리 정의되어 있어 모듈처럼 인스턴스화할 수 있습니다. And/Or/
대부분의 프로그래밍 언어에는 범위(scope)라는 특성이 있어, 코드의 특정 섹션이 변수와 메서드에 대해 가시성을 정의합니다. 범위는 같은 네임스페이스 내 다른 객체 이름 간의 충돌을 피하기 위한 네임스페이스를 정의합니다. Verilog는 모듈, 함수, 태스크, 명명된 블록, generate 블록에 대해 새로운 범위를 정의합니다. module tb; reg signal; // 같은 범위에서 이미 존재하는 이름으로 다른 변수 선언 불가 reg signal; // 에러 // 하지만 signal 이름은 태스크 안에서 재
Verilog 지연 문장은 할당 연산자의 좌변(LHS) 또는 우변(RHS) 어느 쪽에든 지연을 지정할 수 있습니다. 블록 간 지연 (Inter-assignment Delays) // 지연이 왼쪽 항에 지정됨 #<delay> <LHS> = <RHS> 블록 간 지연 문장은 할당 연산자의 LHS에 지연 값이 있습니다. 이는 문장 자체가 지연이 만료된 후에 실행됨을 나타내며, 지연 제어의 가장 일반적인 형태입니다. module tb; reg a, b, c, q; initial begin
Verilog에는 두 가지 타이밍 제어 유형이 있습니다: 지연(delay)과 이벤트(event) 표현식. 지연 제어는 시뮬레이터가 문을 만나고 실제로 실행하는 사이에 지연을 추가하는 방법일 뿐입니다. 이벤트 표현식은 넷이나 변수의 값 변경(암시적 이벤트)이나 다른 프로시저에서 트리거되는 명시적 명명 이벤트 같은 시뮬레이션 이벤트 발생까지 문을 지연시킵니다. 시뮬레이션 시간은 다음 방법들로 진행될 수 있습니다. 내부 지연을 가지도록 모델링된 게이트와 넷도 시뮬레이션 시간을 진행시킵니다. 지연 제어 (Delay Control) 지
Verilog는 컴파일러에게 코드를 특정 방식으로 처리하도록 지시하는 몇 가지 컴파일러 지시자를 지원합니다. 예를 들어, 코드의 일부가 특정 기능의 구현을 나타내는데, 해당 기능이 사용되지 않으면 코드를 설계에 포함하지 않는 방법이 필요합니다. 이는 조건부 컴파일로 해결할 수 있습니다. 설계자는 코드를 컴파일러 지시자로 감싸서, 주어진 플래그가 설정되었을 때 컴파일러가 코드를 포함하거나 제외하도록 할 수 있습니다. 문법 조건부 컴파일은 Verilog `ifdef와 `ifndef 키워드로 달성할 수 있습니다. 이 키워드들은 설계
파라미터는 모듈을 다른 사양으로 재사용할 수 있게 하는 Verilog 구조입니다. 예를 들어, 4비트 가산기는 비트 수 값을 받아들이도록 파라미터화할 수 있고, 모듈 인스턴스화 시 새로운 파라미터 값을 전달할 수 있습니다. 이렇게 N비트 가산기가 4비트, 8비트, 16비트 가산기가 될 수 있습니다. 이는 함수 호출 시 전달되는 함수 인자와 비슷합니다. parameter MSB = 7; // MSB는 값 7을 가진 파라미터 parameter REAL = 4.5; // REAL은 실수를 가짐 parameter FI
function은 입력에 대한 처리 후 단일 값을 반환하는 반면, task는 더 범용적이며 여러 결과 값을 계산하여 output과 inout 타입 인자로 반환할 수 있습니다. 태스크는 @, posedge 등 시뮬레이션 시간을 소비하는 요소를 포함할 수 있습니다. 문법 태스크는 포트 리스트의 인자 집합이 필요하지 않을 수 있으며, 이 경우 비워둘 수 있습니다. // 스타일 1 task [name]; input [port_list]; inout [port_list]; output [port_list]; begin
RTL 내에서 반복되는 코드 조각을 여러 번 호출해야 할 때가 많습니다. 이들은 주로 시뮬레이션 시간을 소비하지 않으며, 다양한 데이터 값으로 복잡한 계산을 수행해야 할 수 있습니다. 이런 경우 function을 선언하고 반복되는 코드를 함수 안에 넣어 결과를 반환하게 하면 됩니다. 이제 함수 호출만 하고 계산할 데이터만 전달하면 되므로 RTL 코드 양이 획기적으로 줄어듭니다. 이는 C 언어의 함수와 매우 유사합니다. 함수의 목적은 표현식에서 사용될 값을 반환하는 것입니다. 함수 정의는 항상 function 키워드로 시작하며 반환
case 문은 주어진 표현식이 리스트의 다른 표현식 중 하나와 일치하는지 검사하고 그에 따라 분기합니다. 일반적으로 멀티플렉서를 구현하는 데 사용됩니다. 조건이 많으면 if-else 구조는 적합하지 않으며, 멀티플렉서 대신 우선순위 인코더로 합성될 수 있습니다. 문법 Verilog case 문은 case 키워드로 시작하고 endcase 키워드로 끝납니다. 괄호 안의 표현식은 정확히 한 번 평가되며, 작성된 순서대로 대안 리스트와 비교되어 일치하는 대안의 문장들이 실행됩니다. 여러 문장 블록은 begin과 end로 묶어야 합니다.
for 루프는 소프트웨어에서 가장 널리 사용되는 루프지만, Verilog에서는 주로 하드웨어 로직을 복제(replicate)하는 데 사용됩니다. for 루프의 핵심은 주어진 조건이 참인 동안 루프 내의 문장 집합을 반복하는 것입니다. 이는 while 루프와 매우 유사하지만, 반복자가 있고 조건이 이 반복자의 값에 의존하는 문맥에서 더 많이 사용됩니다. 문법 for (<초기_조건>; <조건>; <단계_할당>) begin // 문장들 end for 키워드는 이 루프 유형을 지정하며 세 부분으로 구
verilog