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
- soc 설계
- BASYS3
- uart 통신
- Pspice
- half adder
- ATMEGA128A
- gpio
- Algorithm
- Linked List
- Edge Detector
- D Flip Flop
- verilog
- FND
- pwm
- vivado
- hc-sr04
- behavioral modeling
- DHT11
- i2c 통신
- KEYPAD
- structural modeling
- ring counter
- dataflow modeling
- LED
- prescaling
- java
- Recursion
- stop watch
- test bench
- atmega 128a
Archives
- Today
- Total
거북이처럼 천천히
10kHz인 PWM 설계 (Duty ratio stage 128단계) - (4) 본문
1. Parameter를 통해 다용도로 사용 가능한 PWM 컨트롤 모듈 설계
- PWM는 LED 뿐만 아니라 모터 제어에도 사용하며, LED는 10kHz, 모터는 100Hz 주파수를 갖는 PWM을 목표로 설계한다.
- 이를 위해 parameter를 사용하여 다용도로 사용 가능한 PWM Control Module를 설계하도록 하겠다.
- 아래 소스 코드에 대한 자세한 설명은 아래 게시글을 참고하길 바란다.
https://jbhdeve.tistory.com/286
2. Parameter를 통해 다용도로 사용 가능한 PWM Control Module
< 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 <= flip_flop_current;
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, 다용도로 설계된 PWM Control Module >
- Parameter 값으로 system clock, 만들고자 하는 PWM의 주파수, Duty ratio의 단계를 받게 된다.
// Control PWM
module pwm_cntr #(
parameter sys_clk = 100_000_00,
parameter pwm_freq = 10_000,
parameter duty_step = 128,
parameter temp = sys_clk / pwm_freq / duty_step,
parameter temp_half = temp / 2 )
(
input clk, reset_p,
input [31:0] duty,
output pwm
);
// 10kHz PWM 을 만들기 위한 분주화 작업
// 10kHz PWM 을 만들기 위해 78분주화
integer 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 temp_pwm;
assign temp_pwm = (cnt_temp < temp_half) ? 0 : 1;
// Get one Cycle Pulse of temp_pwm
wire temp_pwm_nedge;
edge_detector edge_detector_0 (.clk(clk), .reset_p(reset_p), .cp(temp_pwm), .n_edge(temp_pwm_nedge));
// PWM의 duty ratio를 control하기 위한 분주화 작업
integer cnt_duty;
always @(posedge clk or posedge reset_p) begin
if(reset_p) cnt_duty = 0;
else if(temp_pwm_nedge) begin
if(cnt_duty >= duty_step - 1) cnt_duty = 0;
else cnt_duty = cnt_duty + 1;
end
end
assign pwm = (cnt_duty < duty) ? 1 : 0;
endmodule
< Source, RGB LED control module >
// Top module of PWM
module top_module_pwm (
input clk, reset_p,
output [2:0] pwm );
// Clock Pulse의 Counter
reg [31:0] counter;
always @(posedge clk or posedge reset_p) begin
if(reset_p) counter = 0;
else counter = counter + 1;
end
// Control PWM
pwm_cntr #(.duty_step(97)) pwm_cntr_red (.clk(clk), .reset_p(reset_p), .duty(counter[31:26]), .pwm(pwm[0]));
pwm_cntr #(.duty_step(93)) pwm_cntr_green (.clk(clk), .reset_p(reset_p), .duty(counter[29:24]), .pwm(pwm[1]));
pwm_cntr #(.duty_step(89)) pwm_cntr_blue (.clk(clk), .reset_p(reset_p), .duty(counter[27:22]), .pwm(pwm[2]));
endmodule
3. 구현 영상
- Red LED는 42.9496초를 주기로 밝았다 꺼졌다를 반복하게 된다.
- Green LED는 10.7374초 주기로 밝았다 꺼졌다를 반복하게 된다.
- Blue LED는 2.6843초 주기로 밝았다 꺼졌다를 반복하게 된다.
- RGB 색상이 서로 다른 주기를 갖고, 밝기가 변화하기 때문에 이로 인해 다양한 색상이 LED로 표현이 가능하다.
'RTL Design > Verilog 연습' 카테고리의 다른 글
10kHz인 PWM 설계 (Duty ratio stage 128단계) - (3) (0) | 2024.08.11 |
---|---|
10kHz인 PWM 설계 (Duty ratio stage 128단계) - (2) (0) | 2024.08.11 |
10kHz인 PWM 설계 (Duty ratio stage 128단계) - (1) (0) | 2024.08.11 |
DHT11 - 1 (0) | 2024.08.11 |
10kHz인 PWM 설계 (Duty ratio stage 100단계) - (1) (0) | 2024.08.11 |