Notice
                              
                          
                        
                          
                          
                            Recent Posts
                            
                        
                          
                          
                            Recent Comments
                            
                        
                          
                          
                            Link
                            
                        
                    | 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | 
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | 
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | 
| 26 | 27 | 28 | 29 | 30 | 31 | 
                            Tags
                            
                        
                          
                          - uart 통신
- FND
- Pspice
- half adder
- behavioral modeling
- verilog
- vivado
- structural modeling
- pwm
- BASYS3
- java
- dataflow modeling
- atmega 128a
- KEYPAD
- ring counter
- i2c 통신
- stop watch
- soc 설계
- prescaling
- gpio
- Edge Detector
- hc-sr04
- Recursion
- LED
- ATMEGA128A
- D Flip Flop
- Linked List
- DHT11
- Algorithm
- test bench
                            Archives
                            
                        
                          
                          - Today
- Total
거북이처럼 천천히
Verilog RTL 설계(7월 31일 - 2, PWM - 2) 본문
1. 다이오드가 연속적으로 켜져 있는 상태로 보이기 위해서는 10kHz Pulse wave를 줘야 한다.
- 다이오드가 사람 눈으로 보았을 때, 연속적으로 켜져 있는 상태로 보여주기 위해서는 10kHz 주파수를 갖는 Pulse wave를 인가하는 것이 좋다.
2. 그럼, 어떻게 PWM을 만들 것인가?
- Prescaling을 통해 원하는 Duty ratio를 갖는 Pulse wave를 만들 수 있다.
- 이를 예시와 함께 알아 보도록 하겠다.
 - 100usec 주기를 갖는 PWM을 Prescaling을 통해 만들어 보겠다.
 - Q) 왜 100usec 주기를 갖는 PWM을 만드는가?
 - A) 10000Hz 주파수를 갖는 Pulse wave의 주기는 100usec 주기를 갖기 때문에 10000Hz 주파수를 만들기
 위해서 100usec 주기를 갖는 PWM을 만들고자 한다.
3. Period가 100usec인 PWM 만들기
- 10ns인 Clcok Pulse를 100분주, 100분주하여 주기가 100usec인 PWM을 만들 것이다.
- Q) 왜 어째서 100분주를 두 번하여 100usec PWM을 만드는 것인가? 한 번에 10000분주해도 되지 않는가?
- A) 원하는 Duty ratio를 만들기 위해서, Duty ratio를 컨트롤하기 위해서 이다. 
 이는 코드를 설명한 후, 천천히 다시 설명하도록 하겠다.
3.1. 10ns인 CP를 100분주화 + 100분주화하여 100usec인 PWM을 만들기.
- LED의 밝기 단계를 100단계로 나누어 컨트롤 하기 위해 100분주하였다.
- 최종적으로 주파수가 10kHz인 Pulse wave를 만들기 위해서 또 다시 100분주 하였다.
< Source, Period = 100usec인 PWM의 duty ratio를 100단계로 나누어 컨트롤하는 모듈 >
// PWM 100 Step 
module Duty_ratio_100(
    input clk, reset_p,
    input [6:0] duty,
    output pwm );  
    
    // 10kHz 주파수를 갖는 Pulse Wave를 만들기 위해서 
    // Prescaling 하는 과정 == 100분주 Prescaler
    reg[6:0] cnt_freqX100;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) cnt_freqX100 = 0;
        else if(cnt_freqX100 >= 99) cnt_freqX100 = 0;
        else cnt_freqX100 = cnt_freqX100 + 1;
    end
    
    wire pulse_freqX100;
    assign pulse_freqX100 = (cnt_freqX100 < 50)? 0 : 1;
    
    wire pulse_freqX100_n_edge;
    edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(pulse_freqX100), .n_edge(pulse_freqX100_n_edge));
    
    
    // PWM의 Dity ratio를 단계별로 나누어 컨트롤 하기 위해서
    // 이번에는 led를 100단계로 밝기를 컨트롤하기 위해 
    // 100분주하는 것이다.
    reg[6:0] cnt_pwm;
    always @(posedge clk or posedge reset_p) begin
        if(reset_p) cnt_pwm = 0;
        else if(pulse_freqX100_n_edge) begin
            if(cnt_pwm >= 99) cnt_pwm = 0;
            else cnt_pwm = cnt_pwm + 1;
        end
    end
    
    // duty 만큼 활성화 하기 위해서는 
    // 작으면 1, 크면 0으로 설정
    assign pwm = (cnt_pwm < duty)? 1 : 0;
    
endmodule
// 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- LED의 밝기를 100단계로 나누어 컨트롤 하기 위해 100분주화 한다.
- 10ns Clock Pulse를 100분주화 하면 1usec 주기를 갖는 Pulse Wave를 갖게 되며, 이를 최종적으로 100usec pulse wave로 만들기 위해서 추가적으로 100분주화 하여 1usec pulse를 100usec pulse 로 만든다.
< Source, PWM의 duty ratio를 100단계로 나누어 LED 컨트롤하기 위한 Top module >
// PWM LED Control top module
module pwm_led_top_module (
    input clk, reset_p,
    input [6:0] duty,
    output pwm);
    
    Duty_ratio_100 pwm_duty_ratio_100(.clk(clk), .reset_p(reset_p), .duty(duty), .pwm(pwm));  
    
endmodule
< Simulation, Duty ratio = 50 >

< Simulation, Duty ratio = 80 >

< Simulation, Duty ratio = 10 >

'RTL Design > Verilog RTL 설계' 카테고리의 다른 글
| Verilog RTL 설계(7월 31일 - 4, PWM - 4) (0) | 2024.08.01 | 
|---|---|
| Verilog RTL 설계(7월 31일 - 3, PWM - 3) (0) | 2024.08.01 | 
| Verilog RTL 설계(7월 31일 - 1, PWM - 1) (0) | 2024.08.01 | 
| Verilog RTL 설계(7월 22일 - 3, 4X4 Matrix Keyboard - 3) (0) | 2024.07.25 | 
| Verilog RTL 설계(7월 25일 - 1, Slack) (0) | 2024.07.25 | 

 
                   
                  