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
- DHT11
- prescaling
- LED
- i2c 통신
- soc 설계
- test bench
- Recursion
- Linked List
- ATMEGA128A
- BASYS3
- pwm
- uart 통신
- atmega 128a
- KEYPAD
- FND
- Algorithm
- Pspice
- ring counter
- verilog
- D Flip Flop
- gpio
- structural modeling
- hc-sr04
- Edge Detector
- half adder
- stop watch
- dataflow modeling
- vivado
- java
- behavioral modeling
Archives
- Today
- Total
거북이처럼 천천히
Verilog RTL 설계(7월 31일 - 4, PWM - 4) 본문
1. Pulse wave의 duty ratio를 128단계로 나누어 컨트롤 하는 모듈을 설계한 뒤, LED를 통한 출력
< Source, Pulse wave의 duty ratio를 128단계로 나누어 컨트롤 하는 모듈 >
// Duty ratio 128 step control
module PWM_prescaling_128_Control_LED(
input clk, reset_p,
input [6:0] duty,
output pwm );
parameter sys_clk = 100_000_000;
parameter step_duty = 128;
parameter pwm_freq = 10_000;
parameter temp = sys_clk / step_duty / pwm_freq;
parameter temp_half = temp / 2;
integer cnt_sysclk;
always @(posedge clk or posedge reset_p) begin
if(reset_p) cnt_sysclk = 0;
else begin
if(cnt_sysclk >= temp -1) cnt_sysclk = 0;
else cnt_sysclk = cnt_sysclk + 1;
end
end
wire clk_div_temp;
assign clk_div_temp = (cnt_sysclk < temp_half) ? 0 : 1;
wire clk_div_temp_n_edge;
edge_detector edge_detector_0(.clk(clk), .reset_p(reset_p), .cp(clk_div_temp), .n_edge(clk_div_temp_n_edge));
// 128 Prescaling
reg [6:0] clk_pwm_duty;
always @(posedge clk or posedge reset_p) begin
if(reset_p) clk_pwm_duty = 0;
else if(clk_div_temp_n_edge) clk_pwm_duty = clk_pwm_duty + 1;
end
assign pwm = (clk_pwm_duty < 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
- Clock Pulse Wave를 duty ratio를 128단계로 나누어 컨트롤하기 위해 128분주화 하면 새로운 Pulse wave를 얻을 수 있으며, 이 새로운 Pulse wave는 100000000Hz / 128 = 781250Hz를 갖는다.
- 하지만, LED를 연속적으로 불이 켜지도록 만들기 위해서는 최소한 10kHz Pulse여야 한다.
- 따라서 781250Hz Pulse를 몇 분주해야 10kHz Pulse wave가 나올 수 있는지에 대해서 생각해볼 필요가 있다.
- 781250Hz Pulse를 781250Hz / 10kHz = 78.125 = 78 분주를 하게 되면 10kHz Pulse wave를 얻을 수 있다.
- 따라서 CP를 128분주 + 78분주를 통해 10kHz Pulse를 얻을 수 있으며, 해당 Pulse의 duty ratio를 128단계를 나누 었기 때문에 128단계로 LED의 밝기를 조절할 수 있다.
- duty 변수와 Basys3의 switch를 연결하여 switch를 통해 duty 값을 전달하면 해당 duty 값 만큼 LED의 밝기가 나와 Basys3의 switch를 통해 LED의 밝기를 조절할 수 있다.
< Source, Top Module >
module PWM_LED_0(
input clk, reset_p,
input [6:0] switch,
output pwm_led);
PWM_prescaling_128_Control_LED PWM_LED(.clk(clk), .reset_p(reset_p), .duty(switch), .pwm(pwm_led) );
endmodule
- Basys3의 7개 Switch를 통해 10kHz, Pulse Wave의 Duty ratio를 컨트롤 하게 된다.
< LED 밝기 동작 확인 >
2. Pulse wave의 duty ratio를 128단계로 나누어 컨트롤 하는 모듈을 설계한 뒤, LED를 통한 출력
하는데, 추가적으로 시간에 지남에 따라 LED 밝기를 점차 증가되도록 설계
< Source, Top Module >
module PWM_LED_0(
input clk, reset_p,
output pwm_led);
reg [31:0] cnt_sysclk;
always @(posedge clk) cnt_sysclk = cnt_sysclk + 1;
PWM_prescaling_128_Control_LED PWM_LED(.clk(clk), .reset_p(reset_p), .duty(cnt_sysclk[30:25]), .pwm(pwm_led) );
endmodule
- 10ns Clock Pulse마다 Counting되는 Counter를 이용하여 32bit 중에서 7bit를 묶어 duty 값으로 전달한다.
- cnt_sysclk은 10ns 마다 1씩 카운트 되기 때문에 LSB 영역은 빠르게 값이 변화할 것이다.
- 하지만, MSB 영역쪽은 상대적으로 천천히 변화할 것이기 때문에 이를 활용하여 LSB 쪽에 가까운 7bit를 묶어 전달한다면 LED의 밝기는 빠르게 변화할 것이다.
- 그러나, MSB 영역쪽에서 7bit를 묶어 전달한다면 값이 천천히 변화하기 때문에 상대적으로 LED의 밝기는 천천히 변화할 것이다.
- 위 경우에는 30번째 bit ~ 25번째 bit를 duty 값으로 주었기 때문에 LED의 밝기는 2^31 * 10ns = 21.474초 동안 점차 밝아 지다가 다시 어두워 질 것이다.
- LSB에서 MSB쪽으로 1bit씩 갈수록 LED의 밝기가 점차 밝아지는 속도는 2배 느려지며, 밝아지는 시간은 2배 늘어난다.
< LED 밝기 동작 확인 >
'RTL Design > Verilog RTL 설계' 카테고리의 다른 글
Verilog RTL 설계(7월 19일 - 1, Cooking Timer - 1) (0) | 2024.08.08 |
---|---|
Verilog RTL 설계(8월 1일 - 1, PWM - 5) (0) | 2024.08.02 |
Verilog RTL 설계(7월 31일 - 3, PWM - 3) (0) | 2024.08.01 |
Verilog RTL 설계(7월 31일 - 2, PWM - 2) (0) | 2024.08.01 |
Verilog RTL 설계(7월 31일 - 1, PWM - 1) (0) | 2024.08.01 |