[Embedded System Lab] Chapter 1 - Basic Grammar & Debugging

"Basic Grammar & Debugging"

[Objective]

제공된 "Mystery Module"의 내부 Logic을 분석하고, Simulation 작성을 통해 해당 동작을 확인하며 Verilog 기초 이해하기

[Module Description]

Mystery Module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
`timescale 1ns / 1ps
module mystery_module(
    input wire clk,
    input wire rst,
    output reg [7:0] out
);
    reg [7:0] a, b;
    reg p, q;
    
    always @ (posedge clk or posedge rst) begin
        if (rst) begin
            out <= 2;
            a <= 3;
            q <= 0;
        end else if (!q) begin
            b <= 2;
            p <= 1;
            q <= 1;
        end else if (b * b > a) begin
            out <= p ? a : out;
            a <= a + 1;
            q <= 0;
        end else begin
            p <= (a % b == 0) ? 0 : p;
            b <= b + 1;
        end
    end
endmodule
cs

· always 구문은 clk 신호가 상승 Edge 또는 rst 신호가 상승 Edge인 경우에 다음을 실행
① rst = High(1)인 경우
    → out = 2, a = 3, q = 0 값을 저장
② rst = Low(0) & q = Low(0)인 경우
    → b = 2, p = 1, q = 1 값을 저장
③ rst = Low(0) & q = Hight(1) & b² > a인 경우
    → p = 1이면 out = a / p = 0이면 out = out & a = a + 1, q = 0 값을 저장
④ rst = Low(0) & q = Hight(1) & b² ≤ a인 경우
    → a를 b로 나눈 나머지가 0이면 p = 0 / a를 b로 나눈 나머지가 0이 아니면 p = p & b = b + 1

** reg : always 구문 안에서 값을 할당 받음
** wire : 외부에서 들어오는 신호로써, 단순히 신호를 전달만 하는 역할

Testbench Module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
`timescale 1ns / 1ps
module tb;
    reg clk;                        // 1-bit clk 신호
    reg rst;                        // 1-bit rst 신호
    wire [7:0] out;                 // 8-bit out 데이터
 
    // clock 생성
    initial begin
        clk <= 0;                   // clk = 0으로 초기화
        forever #5 clk <= ~clk;     // 5ns마다 반전 = 주기 10ns
    end
    
    // 동작
    initial begin
        rst <= 0;                   // rst = 0으로 초기화
        #12.5 rst <= 1;             // 12.5ns 이후 rst = 1
        #10 rst <= 0;               // (12.5+10)ns 이후 rst = 0
        #1000 $finish;              // (12.5+10+1000)ns 이후 종료
    end
 
    // Instantiation를 통한 Module Port 연결
    mystery_module mystery_module_inst (
        .clk(clk),                  // clk 연결
        .rst(rst),                  // rst 연결
        .out(out)                   // out 연결
    );
endmodule
cs

· clk
① 0ns에 clk에 0을 저장하여 clk 신호 초기화
② 5ns마다 clk를 반전시켜 주기가 10ns인 clock 생성

· Simulation 동작 과정
① 0ns에 rst에 0을 저장하여 rst 신호 초기화
② 최소 한 clock이 지난 12.5ns에 rst 값을 1로 변경
③ 22.5ns에 rst 값을 다시 0으로 변경
④ 1022.5ns에 Simulation 종료

[Waveform]

· a, b, p, q는 Mystery Module 내부 신호라서 Simulation 실행 시 Waveform에 자동으로 나타나지 않음
→ 위와 같이 a, b, p, q 신호를 추가하여 Waveform에서 확인


· clk
tb Module에서 설정한대로 0ns에 0이며, 5ns마다 반전되어 10ns의 주기를 갖는 것을 확인 가능

· rst
tb Module에서 설정한대로 12.5ns에 High가 되고, 10ns 이후인 22.5ns에 Low가 되는 것을 확인 가능

· out
1) rst 신호가 12.5ns에 High가 되는 순간 상승 Edge에 의해 always 구문이 실행
    → rst = 1이므로 조건 ①을 만족하여 out = 2, a = 3, q = 0 값 저장
2) 15ns에 clk 신호가 High가 되는 순간 상승 Edge이므로 always 구문을 실행하지만, 여전히 rst 신호가 1이므로 결과는 유지
3) rst 신호가 22.5ns에 Low가 되고, 25ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → rst = 0, q = 0이므로 조건 ②를 만족하여 b = 2, p = 1, q = 1 값 저장
4) 35ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → a = 3, b = 2이므로 조건 ③을 만족하며, p = 1이므로 out = a (3), a = 4, q = 0 값 저장
5) 45ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → q = 0이므로 조건 ②를 만족하여 b = 2, p = 1, q = 1 값 저장
6) 55ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → a = 4, b = 2이므로 조건 ④를 만족하며, a를 b로 나눈 나머지가 0이므로 p = 0, b = 3 값 저장
7) 65ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → a = 4, b = 3이므로 조건 ③을 만족하며, p = 0이므로 out = out (3)으로 유지, a = 5, q = 0 값 저장
8) 75ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → q = 0이므로 조건 ②를 만족하여 b = 2, p = 1, q = 1 값 저장
9) 85ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → a = 5, b = 2이므로 조건 ④를 만족하며, a를 b로 나눈 나머지가 0이 아니므로 p = p (1)로 유지, b = 3 값 저장
10) 95ns에 clk 신호가 상승 Edge이므로 always 구문이 실행
    → a = 5, b = 3이므로 조건 ③을 만족하며, p = 1이므로 out = a (5), a = 6, q = 0 값 저장
11) 이후 clk 신호가 상승 Edge일 때마다 always 구문이 실행
    → a % b == 0인 경우가 없었다면 p는 계속 1이 되고, 이 상태로 제곱근을 넘어서면 해당 숫자를 out으로 출력하는 소수 판별 Logic
    → Fig.5.에서 볼 수 있듯이 이 Logic은 설정한대로 1022.5ns에 종료

[Discussion]

· Non-Blocking(<=)을 사용하여 값이 동시에 업데이트 될 수 있도록 Sequential Logic으로 구현
· Blocking(=)을 사용 시 값이 순차적으로 업데이트 되는 Combinational Logic으로 구현 됨
→ 이번 실험에서는 동작에 크게 영향을 주지 않으므로 어느 Logic을 사용해도 상관 X

· 0ns에 clk, rst 신호만 초기화를 하고 나머지는 초기화 X
→ 처음으로 값을 할당 받기 전까지 Simulator가 해당 신호의 값을 모르기 때문에 Unknown 상태인 X 출력

Mystery Module에서 소수 판별 시 제곱근을 기준으로 양쪽이 대칭이므로 전부 계산하지 않고 제곱근까지만 확인
Ex. a = 36 → 1 x 36 / 2 x 18 / 3 x 12 / 4 x 9 / 6 x 6 (제곱근) / 9 x 4 (대칭) / …

소수가 맞다면 out으로 출력 후 q = 0으로 만들고, 이로 인해 조건 ②에서 b = 2로 초기화되어 다시 2부터 나누면서 a가 소수인지 확인

[Reference]

· Verilog_Basics_1 (Embedded System Lab : Chapter1) - William J. Song

댓글

이 블로그의 인기 게시물

[Mini-NPU RTL] NN Reference Model

[Mini-NPU RTL] TPU (Study Paper)