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. 구현 영상