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 |
Tags
- vivado
- hc-sr04
- BASYS3
- java
- test bench
- Recursion
- behavioral modeling
- pwm
- stop watch
- FND
- i2c 통신
- gpio
- D Flip Flop
- dataflow modeling
- Edge Detector
- soc 설계
- prescaling
- Linked List
- structural modeling
- DHT11
- half adder
- verilog
- Algorithm
- ring counter
- ATMEGA128A
- Pspice
- atmega 128a
- KEYPAD
- uart 통신
- LED
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 |