본문 바로가기

임베디드 시스템반도체 개발자 과정 by 서울기술교육센터/후기

78일차

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을 이용했다.

기준보다 작으면 1, 크면 0

 

 

 음... Led 주기는 임의로 설정. 1kHz로..?

 1kHz 클럭을 다시 1000번 세면서 PWM 설정을 주려고 한다. up 버튼은 S4에서는 유지되며 off 버튼은 state 무관 S0으로 간다.

-1000번 세면서 비교기는 300,600,800,999로 기준 변경.

1000번 세는 카운터

 

 

 

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

나중에 설명? "비동기식 적용"

'임베디드 시스템반도체 개발자 과정 by 서울기술교육센터 > 후기' 카테고리의 다른 글

80일차  (0) 2022.10.17
79일차  (0) 2022.10.14
77일차  (0) 2022.10.12
76일차  (0) 2022.10.11
75일차  (0) 2022.10.07