작성
·
51
·
수정됨
0
대학교 프로젝트 러닝머신 모듈을 구현하려고 하는데요. 스위치,LCD, LED, 7-seg 등을 사용할 건데 스위치를 눌렀을 때 제대로 작동을 하지 않습니다. 대략적으로 스위치 기능만 요약드리자면
1 2 3
4 5 6
7 8 9 라고 할 때
1번- 스위치 모드 변경(LCD에 출력되는 값 변경)
2번-slope 증가
3번-speed 저장
4번-speed 감소
5번- 러닝머신을 작동시키고 작동되는 상태에서 다시 누르면 러닝머신이 일시정지
6번- speed 증가
7번- 저장된 speed로 변경
8번- slope 감소
9번- 러닝머신 종료 및 값 리셋
전체적인 스위치 모듈 코드는 다음과 같습니다.
`timescale 1ns / 1ps
module Switch_Handler(
input osc, // 시스템 클럭
input reset, // 리셋 신호
input SW_INPUT0, // 스위치 행 입력
input SW_INPUT1,
input SW_INPUT2,
output reg SW_COMMON0, // 스위치 열 출력
output reg SW_COMMON1,
output reg SW_COMMON2,
output reg [15:0] speed, // 속도 제어
output reg [15:0] slope, // 경사 제어
output reg active, // 활성 상태
output reg paused, // 일시정지 상태
output reg switch_mode, // 모드 전환 신호
output reg reset_distance // 거리 리셋 신호
);
// 내부 변수
reg [2:0] sw_column = 0; // 현재 활성화된 스위치 열
reg [2:0] sw_state = 0; // 스위치 행 입력 저장
reg [31:0] cnt_sw = 0;
reg tick = 0;
reg [15:0] speed_reg;
// Tick generation (5000 clock cycles for debounce/scan interval)
always @(posedge osc) begin
if (cnt_sw >= 5000) begin
tick <= 1;
cnt_sw <= 0;
end else begin
tick <= 0;
cnt_sw <= cnt_sw + 1;
end
end
// Column scanning logic
always @(posedge tick or posedge reset) begin
if (reset) begin
sw_column <= 3'd0;
end else if (sw_column == 4) begin
sw_column <= 3'd1;
end else begin
sw_column <= sw_column + 1'b1;
end
end
always @(posedge osc or posedge reset) begin
if (reset) begin
SW_COMMON0 <= 1'b0;
SW_COMMON1 <= 1'b0;
SW_COMMON2 <= 1'b0;
end else begin
case (sw_column)
1: begin
SW_COMMON0 <= 1'b0;
SW_COMMON1 <= 1'b1;
SW_COMMON2 <= 1'b1;
end
2: begin
SW_COMMON0 <= 1'b1;
SW_COMMON1 <= 1'b0;
SW_COMMON2 <= 1'b1;
end
3: begin
SW_COMMON0 <= 1'b1;
SW_COMMON1 <= 1'b1;
SW_COMMON2 <= 1'b0;
end
default: begin
SW_COMMON0 <= 1'b0;
SW_COMMON1 <= 1'b0;
SW_COMMON2 <= 1'b0;
end
endcase
end
end
// Capture switch state
always @(posedge osc or posedge reset) begin
if (reset) begin
sw_state <= 3'd0;
end else begin
sw_state <= {SW_INPUT2, SW_INPUT1, SW_INPUT0};
end
end
initial begin
speed = 0;
speed_reg = 0;
slope = 0;
paused = 0;
active = 0;
switch_mode = 0;
end
always @(posedge osc or posedge reset) begin
if (reset) begin
active <= 0;
paused <= 0;
speed <= 0;
slope <= 0;
speed_reg <= 0;
end else begin
case (sw_column)
1:
begin
case (sw_state)
3'b110: if(active == 1) switch_mode <= ~switch_mode;
3'b101: if(active == 1 && slope < 15) slope <= slope + 1;
3'b011: if(active == 1 && speed > 0)speed_reg <= speed;
default: ;
endcase
end
2:
begin
case (sw_state)
3'b110:if(active == 1 && paused && speed > 1) speed <= speed - 1;
3'b101:
begin
if (!active) begin
active <= 1;
speed <= 1;
end
else if(active == 1) paused <= ~paused;
end
3'b011:
if(active == 1 && !paused && speed < 20) speed <= speed + 1;
default: ;
endcase
end
3:
begin
case(sw_state)
3'b110:
if(active == 1 && !paused) speed <= speed_reg;
3'b101:
begin
if(active == 1 && !paused && slope > 0) slope <= slope - 1;
end
3'b011: begin if(active == 1) begin
active <= 0;
speed <=0;
slope <=0;
speed_reg <=0;
paused <=0;
end
end
endcase
end
endcase
end
end
endmodule
제발 도와주세요 ㅠㅠ
답변