728x90

 0. [verilog] - Moore Machine


0 또는 1이 랜덤하게 입력되는 상황에서 '1011' 의 패턴이 발견 될 때마다 1을 출력하고 그 외에는 0을 출력하는 시스템을 Moore 머신으로 디자인하시오.


 1. 풀이


그림으로 구현 과정을 이해하기 편할 것이라 생각해 다이어그램을 만들어보았습니다.

아래는 각 state가 되는 num의 값들 입니다.

STATE

num

STATE_0(s1) (xxx0)

0000, 0100, 1000, 1100

STATE_1(s2) (xxx1)

0001, 0011, 0111, 1001, 1111

STATE_2(s3) (xx10)

0010, 0110, 1010, 1110

STATE_3(s4) (x101)

0101, 1101

STATE_4(s5) (1011)

1011


지금 보니 다이어그램에 S5에서 S3로 a:0/b:1 의 입력이 들어온 경우 넘어가는 화살표를 만들어주었어야 했는데, 실수로 빠뜨렸습니다.


이러한 구현을 이제 verilog로 구현을 하면 되는데, 저는 총 4개의 always문을 활용해 구현을 하였습니다.

2개의 always문은 조합회로로 state변경과 output 변경의 역할을 각각 수행하고 있습니다.

현재 state와 input의 값을 통해 next_state를 결정지어주는 역할을 state변경 always 문에서 수행하고 있습니다.

output변경 always문은 간단하게 case문에서 state에 따라 output과 연결된 변수의 값을 변경하는 것으로 구현이 완료되었습니다.


남은 2가지 always문 중 1개는 비동기 입력을 동기 입력으로 변환해주는 기능을 수행합니다.

비동기 입력을 동기 입력으로 전환하는 것은 이전에도 만들어본 것이었는데, 이전과 다른 부분은 2bit를 비동기로 입력받아야 하는 것이었습니다. 따라서 동시 입력, 동시 무입력은 그냥 무시하게 만들었고, 두 버튼 중 1개만 눌린 경우 동기 입력으로 변환시키게 코드를 작성하였습니다.


마지막 하나 남은 always문은 순차 회로로 간단하게 state를 현재 저장되어있는 next_state로 바꾸어주는 역할을 하고있습니다.


이렇게 4개로 분할된 각각의 always문을 활용해 어느정도 규모있는 설계를 수행해 볼 수 있었습니다.


이러한 과정을 활용하면 state가 더 많아지는 설계에서도 오류 없는 설계를 할 수 있을 것으로 예상됩니다.



 2. 소스코드


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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module my_applicaton(clk,A,B,out,num,state);
input clk,A,B;
output reg out;
//현재 숫자를 led로 표시하기 위해 output으로 선언하였다.
output reg [3:0] num;
output reg [2:0] state;
 
localparam STATE_0 = 3'd0,
              STATE_1 = 3'd1,
              STATE_2 = 3'd2,
              STATE_3 = 3'd3,
              STATE_4 = 3'd4;
              
reg [2:0] next_state;
 
reg check_change;
 
//다음상태를 결정하는 조합회로 블록
always @(*) begin
    next_state = state;
    if(check_change) begin
        case (state)
            STATE_0 : begin
                if(num[0] == 1) next_state = STATE_1;
            end
            STATE_1 : begin
                if(num[0] == 0) next_state = STATE_2;
            end
            STATE_2 : begin
                if(num[0] == 1) next_state = STATE_3;
                else next_state = STATE_0;
            end
            STATE_3 : begin
                if(num[0] == 1) next_state = STATE_4;
                else next_state = STATE_2;
            end
            STATE_4 : begin
                if(num[0] == 0) next_state = STATE_2;
                else next_state = STATE_1;
            end
            default : next_state = STATE_0;
        endcase
    end
end
 
 
//현재상태를 저장하는 순차회로 블록
always @ (posedge clk) begin
    state <= next_state;
end
 
reg delay_A,delay_B,data_A,data_B;
 
//숫자의 입력을 negedge clk에 받아온다.
always @ (negedge clk) begin
    delay_A <= ~A; data_A <= A&delay_A;
    delay_B <= ~B; data_B <= B&delay_B;
    check_change = 1'b0;
    if(data_A^data_B) begin
        if(data_A) num <= {num[2:0] , 1'b1};
        else num <= {num[2:0] , 1'b0};
        check_change = 1'b1;
    end
end
 
//출력값을 결정하는 조합회로 블록
always @(*) begin
    case (state)
        STATE_0 : begin
            out = 0;
        end
        STATE_1 : begin
            out = 0;
        end
        STATE_2 : begin
            out = 0;
        end
        STATE_3 : begin
            out = 0;
        end
        STATE_4 : begin
            out = 1;
        end
        default : out = 0;
    endcase
end
 
endmodule
cs


 3. 참고




질문이나 지적 있으시면 댓글로 남겨주세요~

도움 되셨으면 하트 꾹!


+ Recent posts