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. 참고 |
질문이나 지적 있으시면 댓글로 남겨주세요~
도움 되셨으면 하트 꾹!
'---------개인공부-------- > |verilog|' 카테고리의 다른 글
[verilog] 디지털 시계(배열, moore machine, parameter, always 문) (1) | 2020.01.01 |
---|---|
xilinx ise shortCut(verilog shortcut, 베릴로그 단축키, 자일링스 단축키) (0) | 2019.11.07 |
[verilog] 비동기 입력을 동기 입력으로 변환(asynchronous to synchronous) (0) | 2019.11.03 |
[verilog] counter(up, down, load, reset 구현) (0) | 2019.11.03 |
[verilog] decoder 3 to 8 (2) | 2019.10.12 |