거북이처럼 천천히

10kHz인 PWM 설계 (Duty ratio stage 128단계) - (2) 본문

RTL Design/Verilog 연습

10kHz인 PWM 설계 (Duty ratio stage 128단계) - (2)

유로 청년 2024. 8. 11. 17:51

1. LED의 밝기를 128단계로 나누어 컨트롤 하기

  • LED을 계속 있되, LED의 밝기를 128단계로 나누어 컨트롤하기 위해 10kHz 주파스를 갖는 PWM을 만든 뒤, PWM의 duty ratio를 128단계로 나누어 컨트롤 할 수 있는 모듈을 설계하고자 한다.
  • 이를 위해 주기가 10ns인 Clock Pulse를 128분주화, 78분주화 하고자 한다.
  • 소스 코드에 대한 자세한 설명은 아래 게시글을 참고하길 바란다.
    https://jbhdeve.tistory.com/285
 

Verilog RTL 설계(7월 31일 - 4, PWM - 4)

1. Pulse wave의 duty ratio를 128단계로 나누어 컨트롤 하는 모듈을 설계한 뒤, LED를 통한 출력 Pulse wave의 duty ratio를 128단계로 나누어 컨트롤 하는 모듈 >// Duty ratio 128 step controlmodule PWM_prescaling_128_Contro

jbhdeve.tistory.com

 

 

 

2. PWM Control 모듈 소스 코드

< Source, Edge detector >

// Edge detector
module edge_detector (
    input clk, reset_p,
    input cp,
    output n_edge, p_edge );
    
    reg flip_flop_current, flip_flop_old;
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) begin
            flip_flop_current <= 0;
            flip_flop_old <= 0;
        end
        else begin
             flip_flop_current <= cp;
             flip_flop_old <= flip_flop_current;
        end
    end 
    
    assign p_edge = ({flip_flop_current, flip_flop_old} == 2'b10) ? 1 : 0;
    assign n_edge = ({flip_flop_current, flip_flop_old} == 2'b01) ? 1 : 0;
    
endmodule

 

 

 

< Source, 10kHz PWM의 Duty ratio를 128단계 컨트롤 모듈 >

module pwm_cntr(
    input clk, reset_p,
    input [6:0] duty,
    output pwm );
    
    // Declare parameter
    parameter clk_freq = 100_000_000;
    parameter pwm_freq = 10_000;
    parameter duty_stage = 128;
    
    // 10kHz PWM을 만들기 위해서는 몇 분주화를 해야 하는가?
    parameter temp = clk_freq / pwm_freq / duty_stage;
    parameter temp_half = temp / 2;
    
    // 10kHz를 만들기 위한 78.125분주화
    reg [6:0] cnt_temp;
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) cnt_temp = 0;
        else begin
            if(cnt_temp >= temp - 1) cnt_temp = 0;
            else cnt_temp = cnt_temp + 1; 
        end
    end 
    
    wire pwm_temp;
    assign pwm_temp = (cnt_temp) ? 0 : 1;
    
    // Get one cycle pulse of pwm_temp
    wire pwm_temp_nedge;
    edge_detector edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(pwm_temp), .n_edge(pwm_temp_nedge));
    
    // Duty ratio를 128단계로 나누어 컨트롤할 수 있는 PWM 생성
    // 이를 위해서 128분주화 실시.
    reg [6:0] cnt_duty;
    
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) cnt_duty = 00;
        else if(pwm_temp_nedge) cnt_duty = cnt_duty + 1;
    end
    
    assign pwm = (cnt_duty < duty) ? 1 : 0;
    
endmodule

 

 

 

3. 구현 영상