10월 13일
Tri Buffer
이미지 출처
https://www.electronics-tutorials.ws/logic/logic_9.html
Digital Buffer and the Tri-state Buffer Tutorial
Digital Electronics Tutorial about the Digital Buffer and the Tri-state Buffer also known as a non-inverting digital buffer used in digital logic circuits
www.electronics-tutorials.ws
enable | X | buffer Y | not Buffer Y |
0 | X | Z | Z |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
출력이 세 가지임. 그래서 three state buffer, tri buffer.
어제 과제로 대입하면 decoder와 fnd 사이에 들어가는데 off일 때 아예 값이 없도록 하는 식으로 적용됨.
module TriBuffer(
input [3:0] i_x,
input i_En,
output [3:0] o_y
);
//assign o_y = (i_En == 1'b1) ? 4'bzzzz : i_x;
assign o_y = (i_En == 1'b1) ? 4'b1111 : i_x;
endmodule
여기서 z는 high impedence를 말함. 근데 오류 나서 다시 바꿈.
DecoderFndDigit fnd_decoder(
.i_select(w_fndCounter),
.o_digitPosition(w_digit)
);
wire [3:0] w_digit;
TriBuffer triBuffer(
.i_x(w_digit),
.i_En(i_onOff),
.o_y(o_digit)
);
원래는 decoder에서 바로 output으로 o_digit이 나갔는데 tri buffer를 추가한 것.
-------------
FSM(Finite State Machine;유한상태기계)
1. 상태 변경
2. 이벤트 처리
3. 상태에 따른 동작
system verilog에서는 enum 선언이 지원되지만 original? verilog에서는 지원되지 않아 다르게 선언해야 하는데, parameter 구문을 통해서 선언한다.
verilog에서 1 0이라고 하면, 기본적으로 10진수로 보고 32 bit 크기로 해석한다. 따라서 정확하게 따지려면 1'b0, 1'b1과 같이 선언하는 게 좋다.
module FSM_Light(
input i_clk,
input i_reset,
input i_onOff_switch,
output o_light
);
//define 기능
parameter S_LED_ON = 1'b0,
S_LED_OFF = 1'b1;
reg curState, nextState;
reg r_light;
assign o_light = r_light;
//상태 변경 적용
always @(posedge i_clk or posedge i_reset) begin
if(i_reset) begin
curState <= S_LED_OFF;
end
else curState <= nextState;
end
//이벤트 처리
always @(curState or i_onOff_switch) begin
case(curState)
S_LED_OFF : begin
if(i_onOff_switch == 1'b1) nextState = S_LED_ON;
else nextState <= S_LED_OFF;
end
S_LED_ON : begin
if(i_onOff_switch == 1'b0) nextState = S_LED_OFF;
else nextState <= S_LED_ON;
end
endcase
end
//상태에 따른 동작
always @(curState) begin
case (curState)
S_LED_OFF : r_light <= 1'b0;
S_LED_ON : r_light <= 1'b1;
endcase
end
endmodule
module FSM_Light(
input i_clk,
input i_reset,
input [1:0] i_onOff_switch,
output [1:0] o_light
);
parameter S_LED_00 = 2'b00, S_LED_01 = 2'b01,
S_LED_02 = 2'b10;
reg [1:0] curState, nextState;
reg [1:0] r_light;
assign o_light = r_light;
always @(posedge i_clk or posedge i_reset) begin
if(i_reset) begin
curState <= S_LED_00;
end
else curState <= nextState;
end
always @(curState or i_onOff_switch) begin
case(curState)
S_LED_00 : begin
if(i_onOff_switch == 2'b01) nextState = S_LED_01;
else if(i_onOff_switch == 2'b10) nextState = S_LED_02;
else nextState <= S_LED_00;
end
S_LED_01 : begin
if(i_onOff_switch == 2'b10) nextState = S_LED_02;
else if(i_onOff_switch == 2'b00) nextState = S_LED_00;
else if(i_onOff_switch == 2'b11) nextState = S_LED_00;
else nextState <= S_LED_01;
end
S_LED_02 : begin
if(i_onOff_switch == 2'b00) nextState = S_LED_00;
else if(i_onOff_switch == 2'b11) nextState = S_LED_00;
else if(i_onOff_switch == 2'b01) nextState = S_LED_01;
else nextState <= S_LED_02;
end
default : nextState <= S_LED_00;
endcase
end
always @(curState) begin
case (curState)
S_LED_00 : r_light <= 2'b00;
S_LED_01 : r_light <= 2'b01;
S_LED_02 : r_light <= 2'b10;
default : r_light <= 2'b00;
endcase
end
endmodule
if 내부에 else가 있는 이유. case에서 경우의 수를 다 입력하지 않으면 원치 않는 latch가 발생했던 것처럼 if 역시 그러하다. 그런 부분을 고려해서 다 입력.
always 괄호 안을 sensitivity list라고 하는데 포함되면 클럭과 비동기화로 작동(비동기식 작동 방식)하고, 포함되지 않으면 클럭과 동기화(클럭 동기화 작동 방식)로 작동.
module button(
input i_clk, i_reset, i_button,
output o_state
);
parameter PUSHED = 1'b1, RELEASED = 1'b0, true = 1'b1, false = 1'b0;
reg prevState, r_state, nextState;
assign o_state = r_state;
always @(posedge i_clk or posedge i_reset) begin
if (i_reset) begin
r_state <= RELEASED;
end
else begin
if(i_button == PUSHED && prevState == RELEASED) begin
prevState <= PUSHED;
r_state <= false;
end
else if(i_button == RELEASED && prevState == PUSHED) begin
prevState <= RELEASED;
r_state <= true;
end
else begin
r_state <= false;
end
end
end
endmodule
module FSM_Light(
input i_clk,
input i_reset, i_button, i_reverse_btn,
output [1:0] o_light
);
parameter S_LED_00 = 2'b00, S_LED_01 = 2'b01,
S_LED_02 = 2'b10, S_LED_03 = 2'b11;
reg [1:0] curState, nextState;
reg [1:0] r_light;
assign o_light = r_light;
always @(posedge i_clk or posedge i_reset) begin
if(i_reset) begin
curState <= S_LED_00;
end
else curState <= nextState;
end
always @(curState or i_button or i_reverse_btn) begin
case(curState)
S_LED_00 : begin
if(i_button) nextState <= S_LED_01;
else if(i_reverse_btn) nextState <= S_LED_03;
else nextState <= S_LED_00;
end
S_LED_01 : begin
if(i_button) nextState <= S_LED_02;
else if(i_reverse_btn) nextState <= S_LED_00;
else nextState <= S_LED_01;
end
S_LED_02 : begin
if(i_button) nextState <= S_LED_03;
else if(i_reverse_btn) nextState <= S_LED_01;
else nextState <= S_LED_02;
end
S_LED_03 : begin
if(i_button) nextState <= S_LED_00;
else if(i_reverse_btn) nextState <= S_LED_02;
else nextState <= S_LED_03;
end
endcase
end
always @(curState) begin
case (curState)
S_LED_00 : r_light <= 2'b00;
S_LED_01 : r_light <= 2'b01;
S_LED_02 : r_light <= 2'b10;
S_LED_03 : r_light <= 2'b11;
endcase
end
endmodule
module top_fsm_light(
input i_clk, i_reset, i_button, i_reverse_btn,
output [1:0] o_light
);
wire w_button, w_button2;
FSM_Light fsm_light(
.i_clk(i_clk),
.i_reset(i_reset),
.i_button(w_button),
.i_reverse_btn(w_button2),
.o_light(o_light)
);
button btn_controller(
.i_clk(i_clk),
.i_reset(i_reset),
.i_button(i_button),
.o_state(w_button)
);
button reverse_btn_controller(
.i_clk(i_clk),
.i_reset(i_reset),
.i_button(i_reverse_btn),
.o_state(w_button2)
);
endmodule
chattering 방지를 위한 디바운스(debounce) 구간 설정
module button(
input i_clk, i_reset, i_button,
output o_state
);
parameter PUSHED = 1'b1, RELEASED = 1'b0, TRUE = 1'b1, FALSE = 1'b0;
parameter DEBOUNCE = 500_000; // 10ms
reg prevState, r_state, nextState;
reg [31:0] r_counter = 0;
assign o_state = r_state;
always @(posedge i_clk or posedge i_reset) begin
if (i_reset) begin
r_state <= RELEASED;
prevState <= RELEASED;
r_counter <= 0;
end
else begin
if(i_button == PUSHED && prevState == RELEASED && r_counter < DEBOUNCE) begin
r_state <= FALSE;
r_counter <= r_counter + 1;
end
else if(i_button == PUSHED && prevState == RELEASED && r_counter == DEBOUNCE) begin
prevState <= PUSHED;
r_state <= FALSE;
r_counter <= 0;
end
else if(i_button == RELEASED && prevState == PUSHED && r_counter < DEBOUNCE) begin
r_counter <= r_counter + 1;
r_state <= FALSE;
end
else if(i_button == RELEASED && prevState == PUSHED && r_counter == DEBOUNCE) begin
prevState <= RELEASED;
r_state <= TRUE;
r_counter <= 0;
end
else begin
r_state <= FALSE;
end
end
end
endmodule
-----------
Light 밝기 조절하는 chip 설계
button 3개 off, light up, light down
그동안 이렇게 밝기를 조절할 때 PWM을 이용했다.
음... Led 주기는 임의로 설정. 1kHz로..?
1kHz 클럭을 다시 1000번 세면서 PWM 설정을 주려고 한다. up 버튼은 S4에서는 유지되며 off 버튼은 state 무관 S0으로 간다.
-1000번 세면서 비교기는 300,600,800,999로 기준 변경.
https://github.com/316415/FSM_LightStand_PWM.git
GitHub - 316415/FSM_LightStand_PWM: LED brightness control.
LED brightness control. Contribute to 316415/FSM_LightStand_PWM development by creating an account on GitHub.
github.com
https://youtube.com/shorts/Qo-kExtJVFI?feature=share

vscode 단축키 특정 키워드 누르고 crtl+d
나중에 설명? "비동기식 적용"