산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> verilog

Verilog 사용자 정의 기본 요소(UDP) 마스터하기: 고급 로직 모델링

표준 Verilog 기본 요소(nand, not 등)가 복잡한 로직을 표현하기에 항상 쉽거나 충분하지 않을 수 있습니다. UDP 또는 사용자 정의 기본 요소(user-defined primitives)라고 하는 새로운 기본 요소들을 정의하여 조합 또는 순차 로직을 모델링할 수 있습니다.

모든 UDP는 정확히 하나의 출력을 가지며 0, 1, X 중 하나일 수 있고 Z는 절대 될 수 없습니다(지원 안 함). Z 값을 가진 입력은 X로 처리됩니다.

Verilog UDP 기호

Verilog 사용자 정의 기본 요소는 module 정의와 같은 레벨에 작성할 수 있지만, module과 endmodule 사이에는 절대 쓸 수 없습니다. 여러 입력 포트를 가질 수 있지만 항상 하나의 출력 포트만 가지며, 양방향 포트는 유효하지 않습니다. 모든 포트 신호는 스칼라여야 하므로 1비트 폭이어야 합니다.

하드웨어 동작은 기본 요소 상태 테이블로 기술되며, 입력의 다양한 가능한 조합과 해당 출력이 table과 endtable 안에 나열됩니다. 입력과 출력 신호 값은 다음 기호로 표시됩니다.

기호 설명
0 논리 0
1 논리 1
x 알 수 없음, 논리 0 또는 1일 수 있음. 순차 UDP의 입력/출력 또는 현재 상태에 사용 가능
? 논리 0, 1, 또는 x. UDP 출력에는 사용할 수 없음
- 변화 없음, UDP 출력에서만 허용
ab a에서 b로의 값 변화, a 또는 b는 0, 1, 또는 x
* ??와 동일, 입력 값의 모든 변화를 나타냄
r 01과 동일, 입력의 상승 에지
f 10과 동일, 입력의 하강 에지
p 입력의 잠재적 양의 에지: 0->1, 0->x, 또는 x->1
n 입력의 잠재적 하강 에지: 1->0, x->0, 1->x

조합 UDP 예제

// 출력은 포트 리스트에서 항상 첫 번째 신호여야 함
primitive mux (out, sel, a, b);
  output out;
  input sel, a, b;
  table
    // sel a b out
    0 1 ? : 1;
    0 0 ? : 0;
    1 ? 0 : 0;
    1 ? 1 : 1;
    x 0 0 : 0;
    x 1 1 : 1;
  endtable
endprimitive

?는 해당 신호가 0, 1, 또는 x일 수 있으며 최종 출력 결정에 영향을 주지 않음을 나타냅니다.

아래 테스트벤치 모듈은 UDP를 인스턴스화하고 입력 자극을 가합니다.

module tb;
  reg sel, a, b;
  reg [2:0] dly;
  wire out;
  integer i;
  // UDP 인스턴스화 - UDP는 포트 이름 연결로 인스턴스화할 수 없음에 유의
  mux u_mux ( out, sel, a, b);
  initial begin
    a <= 0; b <= 0;
    $monitor("[T=%0t] a=%0b b=%0b sel=%0b out=%0b", $time, a, b, sel, out);
    // a, b, sel을 서로 다른 랜덤 지연 후 구동
    for (i = 0; i < 10; i = i + 1) begin
      dly = $random; #(dly) a <= $random;
      dly = $random; #(dly) b <= $random;
      dly = $random; #(dly) sel <= $random;
    end
  end
endmodule

시뮬레이션 로그

xcelium> run
[T=0] a=0 b=0 sel=x out=0
[T=4] a=1 b=0 sel=x out=x
[T=5] a=1 b=1 sel=x out=1
[T=10] a=1 b=1 sel=1 out=1
[T=15] a=0 b=1 sel=1 out=1
[T=28] a=0 b=0 sel=1 out=0
[T=33] a=0 b=0 sel=0 out=0
[T=38] a=1 b=0 sel=0 out=1
[T=40] a=1 b=1 sel=0 out=1
[T=51] a=1 b=1 sel=1 out=1
[T=54] a=0 b=0 sel=1 out=0
[T=62] a=1 b=0 sel=1 out=0
[T=67] a=1 b=1 sel=1 out=1
[T=72] a=0 b=1 sel=1 out=1
[T=80] a=0 b=1 sel=0 out=0
[T=84] a=0 b=0 sel=0 out=0
[T=85] a=1 b=0 sel=0 out=1
xmsim: *W,RNQUIE: Simulation is complete.

순차 UDP 예제

순차 로직은 레벨 민감 또는 에지 민감일 수 있으므로 두 종류의 순차 UDP가 있습니다. 출력 포트는 UDP 정의 내에서 reg 타입으로 선언되어야 하며, 선택적으로 initial 문으로 초기화할 수 있습니다.

순차 UDP는 입력과 출력 필드 사이에 추가 필드를 가지며, :로 구분되어 현재 상태를 나타냅니다.

레벨 민감 UDP

primitive d_latch (q, clk, d);
  output q;
  input clk, d;
  reg q;
  table
    // clk d q q+
    1 1 : ? : 1;
    1 0 : ? : 0;
    0 ? : ? : -;
  endtable
endprimitive

위 테이블에서 마지막 행의 하이픈 -은 q+에 값 변화가 없음을 나타냅니다.

module tb;
  reg clk, d;
  reg [1:0] dly;
  wire q;
  integer i;
  d_latch u_latch (q, clk, d);
  always #10 clk = ~clk;
  initial begin
    clk = 0;
    $monitor ("[T=%0t] clk=%0b d=%0b q=%0b", $time, clk, d, q);
    #10; // X 효과 보기 위해
    for (i = 0; i < 50; i = i+1) begin
      dly = $random; #(dly) d <= $random;
    end
    #20 $finish;
  end
endmodule

시뮬레이션 로그

xcelium> run
[T=0] clk=0 d=x q=x
[T=10] clk=1 d=1 q=1
[T=13] clk=1 d=0 q=0
[T=14] clk=1 d=1 q=1
[T=17] clk=1 d=0 q=0
[T=20] clk=0 d=1 q=0
[T=28] clk=0 d=0 q=0
[T=30] clk=1 d=1 q=1
[T=38] clk=1 d=0 q=0
[T=39] clk=1 d=1 q=1
[T=40] clk=0 d=1 q=1
[T=42] clk=0 d=0 q=1
[T=47] clk=0 d=1 q=1
[T=50] clk=1 d=0 q=0
[T=55] clk=1 d=1 q=1
[T=59] clk=1 d=0 q=0
[T=60] clk=0 d=0 q=0
[T=61] clk=0 d=1 q=0
[T=64] clk=0 d=0 q=0
[T=67] clk=0 d=1 q=0
[T=70] clk=1 d=0 q=0
[T=73] clk=1 d=1 q=1
[T=74] clk=1 d=0 q=0
[T=77] clk=1 d=1 q=1
[T=79] clk=1 d=0 q=0
[T=80] clk=0 d=0 q=0
[T=84] clk=0 d=1 q=0
[T=86] clk=0 d=0 q=0
[T=87] clk=0 d=1 q=0
[T=90] clk=1 d=1 q=1
[T=91] clk=1 d=0 q=0
[T=100] clk=0 d=0 q=0
[T=110] clk=1 d=0 q=0
Simulation complete via $finish(1) at time 111 NS + 0

에지 민감 UDP

D 플립플롭을 Verilog 사용자 정의 기본 요소로 모델링한 예제입니다. 클럭의 상승 에지는 01 또는 0?로 지정됩니다.

primitive d_flop (q, clk, d);
  output q;
  input clk, d;
  reg q;
  table
    // clk d q q+
    // clk 상승 에지(01)에서 출력 얻기
    0 : ? : 0;
    (01) 1 : ? : 1;
    (0?) 1 : 1 : 1;
    (0?) 0 : 0 : 0;
    // clk 하강 에지 무시
    (?0) ? : ? : -;
    // 안정된 clk에서 데이터 변화 무시
    ? (??): ? : -;
  endtable
endprimitive

테스트벤치에서 UDP를 인스턴스화하고 랜덤 클럭 수 후 랜덤 d 입력 값으로 구동합니다.

module tb;
  reg clk, d;
  reg [1:0] dly;
  wire q;
  integer i;
  d_flop u_flop (q, clk, d);
  always #10 clk = ~clk;
  initial begin
    clk = 0;
    $monitor ("[T=%0t] clk=%0b d=%0b q=%0b", $time, clk, d, q);
    #10; // X 효과 보기 위해
    for (i = 0; i < 20; i = i+1) begin
      dly = $random; repeat(dly) @(posedge clk); d <= $random;
    end
    #20 $finish;
  end
endmodule

이미지에서 볼 수 있듯이 출력 q가 입력 d를 1클럭 지연 후 따르며, 이는 D 플립플롭의 원하는 동작입니다.

시뮬레이션 로그

xcelium> run
[T=0] clk=0 d=x q=x
[T=10] clk=1 d=1 q=x
[T=20] clk=0 d=1 q=x
[T=30] clk=1 d=1 q=1
[T=40] clk=0 d=1 q=1
[T=50] clk=1 d=1 q=1
[T=60] clk=0 d=1 q=1
[T=70] clk=1 d=0 q=1
[T=80] clk=0 d=0 q=1
[T=90] clk=1 d=1 q=0
[T=100] clk=0 d=1 q=0
[T=110] clk=1 d=1 q=1
[T=120] clk=0 d=1 q=1
[T=130] clk=1 d=1 q=1
[T=140] clk=0 d=1 q=1
[T=150] clk=1 d=0 q=1
[T=160] clk=0 d=0 q=1
[T=170] clk=1 d=0 q=0
[T=180] clk=0 d=0 q=0
[T=190] clk=1 d=0 q=0
[T=200] clk=0 d=0 q=0
[T=210] clk=1 d=1 q=0
[T=220] clk=0 d=1 q=0
[T=230] clk=1 d=1 q=1
[T=240] clk=0 d=1 q=1
[T=250] clk=1 d=1 q=1
[T=260] clk=0 d=1 q=1
[T=270] clk=1 d=1 q=1
[T=280] clk=0 d=1 q=1
[T=290] clk=1 d=1 q=1
[T=300] clk=0 d=1 q=1
[T=310] clk=1 d=1 q=1
[T=320] clk=0 d=1 q=1
[T=330] clk=1 d=1 q=1
[T=340] clk=0 d=1 q=1
[T=350] clk=1 d=1 q=1
[T=360] clk=0 d=1 q=1
[T=370] clk=1 d=0 q=1
[T=380] clk=0 d=0 q=1
[T=390] clk=1 d=0 q=0
[T=400] clk=0 d=0 q=0
[T=410] clk=1 d=1 q=0
[T=420] clk=0 d=1 q=0
[T=430] clk=1 d=1 q=1
[T=440] clk=0 d=1 q=1
[T=450] clk=1 d=1 q=1
[T=460] clk=0 d=1 q=1
[T=470] clk=1 d=1 q=1
[T=480] clk=0 d=1 q=1
Simulation complete via $finish(1) at time 490 NS + 0

verilog

  1. 버릴로그(Verilog) 입문: 디지털 회로 설계를 위한 하드웨어 기술 언어
  2. Verilog 결합(Concatenation) & 복제(Replication) 연산자 실전 가이드
  3. Verilog 할당문 이해: 유형, 문법, 모범 사례
  4. Verilog 차단 vs 비차단 할당: 핵심 차이점 완벽 이해
  5. Verilog 함수 마스터하기: 효율적인 RTL 설계를 위한 활용법
  6. Verilog 태스크 이해: 함수와의 차이점, 문법, 활용법
  7. Verilog 클럭 생성기: 설계 및 구현 가이드
  8. Verilog 수학 함수 마스터하기: 효율적인 하드웨어 설계를 위한 활용
  9. Verilog $timeformat 마스터하기: 정밀도 및 표시 제어
  10. 모든 범위에서 Verilog Timescale 이해 및 출력하기