호타리
2025. 7. 9. 16:50
2025.07.09
shift_register & FSM
btnU 를 누르면 1이 btnD를 누르면 0이 입력 되도록 구현
입력 되는 상황은 led6~led0로 left shift표시 되도록 하고 동일한 입력 2개(00 또는 11) 발견 시00이면 led15 on 11이면 led14를 on
그렇지 않은 경우는 led15 led14를 off로 처리
top.v
`timescale 1ns / 1ps
module pattern_detector_top (
input wire clk,
input wire rst, // 동기 리셋
input wire btnU, // 1 입력 버튼
input wire btnD, // 0 입력 버튼
output wire [15:0] led // led[6:0] = 입력 표시, led[7] = 패턴 감지
);
wire clean_btnU, clean_btnD;
wire pulse_btnU, pulse_btnD;
// 디바운싱
button_debouncer db_u (
.clk(clk),
.btn(btnU),
.debounced(clean_btnU)
);
button_debouncer db_d (
.clk(clk),
.btn(btnD),
.debounced(clean_btnD)
);
// 원샷
one_pulse op_u (
.clk(clk),
.btn_in(clean_btnU),
.pulse_out(pulse_btnU)
);
one_pulse op_d (
.clk(clk),
.btn_in(clean_btnD),
.pulse_out(pulse_btnD)
);
// FSM 동작
pattern_detector_fsm fsm (
.clk(clk),
.rst(rst),
.in1(pulse_btnU),
.in0(pulse_btnD),
.led(led)
);
endmodule
pattern_detector_fsm.v
`timescale 1ns / 1ps
module pattern_detector_fsm (
input wire clk,
input wire rst,
input wire in1, // btnU → 1
input wire in0, // btnD → 0
output reg [15:0] led // led[6:0]: 입력 표시, led[14]: 11 감지, led[15]: 00 감지
);
// 상태 정의
parameter S_IDLE = 2'b00;
parameter S_1ST = 2'b01;
reg [1:0] current_state, next_state;
reg prev_bit;
reg din_bit;
reg input_valid;
// 입력 디코딩
always @(*) begin
if (in1) begin
din_bit = 1'b1;
input_valid = 1'b1;
end else if (in0) begin
din_bit = 1'b0;
input_valid = 1'b1;
end else begin
input_valid = 1'b0;
end
end
// 입력 시프트 저장 레지스터 (입력값 자체 shift)
reg [6:0] input_shift;
// 상태 전이 및 출력 동작
always @(posedge clk or posedge rst) begin
if (rst) begin
current_state <= S_IDLE;
prev_bit <= 1'b0;
input_shift <= 7'b0000000;
led[15:14] <= 2'b00;
end else begin
current_state <= next_state;
if (input_valid) begin
// ⬅ 왼쪽으로 입력값 shift (0 또는 1 입력 반영)
input_shift <= {input_shift[5:0], din_bit};
// 이전 입력과 비교하여 패턴 감지
if (din_bit == 1'b0 && prev_bit == 1'b0) begin
led[15] <= 1'b1; // 00
led[14] <= 1'b0;
end else if (din_bit == 1'b1 && prev_bit == 1'b1) begin
led[15] <= 1'b0;
led[14] <= 1'b1; // 11
end else begin
led[15] <= 1'b0;
led[14] <= 1'b0; // 01 or 10
end
prev_bit <= din_bit;
end
end
end
// 상태 천이 및 출력 결합
always @(*) begin
next_state = current_state;
case (current_state)
S_IDLE: begin
if (input_valid)
next_state = S_1ST;
end
S_1ST: begin
next_state = S_1ST;
end
endcase
// 입력 시프트값 출력 연결
led[6:0] = input_shift;
// 나머지 led[13:7]는 0으로 유지
end
endmodule
one_pulse.v
`timescale 1ns / 1ps
module one_pulse (
input wire clk,
input wire btn_in,
output reg pulse_out
);
reg btn_delay;
always @(posedge clk) begin
btn_delay <= btn_in;
pulse_out <= btn_in & ~btn_delay;
end
endmodule
button_debouncer.v
`timescale 1ns / 1ps
module button_debouncer (
input wire clk,
input wire btn,
output reg debounced
);
reg [15:0] cnt;
reg btn_sync, btn_prev;
always @(posedge clk) begin
btn_sync <= btn;
if (btn_sync == btn_prev)
cnt <= cnt + 1;
else
cnt <= 0;
if (cnt == 16'hFFFF)
debounced <= btn_sync;
btn_prev <= btn_sync;
end
endmodule
결과 영상