// PWM Frequency Signal Output According to Duty Ratio
module pwm_Nstep (
input clk, reset_p,
input [31:0] duty, // PWM Duty Rate, CCR Capture Compare Register
output reg pwm // PWM Duty Applied Pulse
);
parameter sys_clk_freq = 100_000_000; // System Clock Frequency
parameter pwm_freq = 10_000; // PWM Frequency
parameter duty_step_N = 200; // Duty Step, ARR Auto Reload Register
parameter temp = sys_clk_freq / pwm_freq / duty_step_N / 2; // Half of Cycle
integer cnt_sysclk; // System Clock Count
reg pwm_freqXn; // PWM Frequency
always @(posedge clk, posedge reset_p) begin
if (reset_p) begin
cnt_sysclk <= 0; // System Clock Count Reset
pwm_freqXn <= 0; // PWM Frequency Reset
end
else begin
if (cnt_sysclk >= temp - 1) begin // when Half of Cycle
cnt_sysclk <= 0; // System Clock Count Reset
pwm_freqXn <= ~pwm_freqXn; // PWM Frequency Generation
end
else cnt_sysclk <= cnt_sysclk + 1; // Count System Clock
end
end
// Edge Detection of PWM Frequency
wire pwm_freqXn_nedge; // PWM Frequency Negative Edge
edge_detector_pos pwm_freqXn_ed (.clk(clk), .reset_p(reset_p),
.cp(pwm_freqXn), .n_edge(pwm_freqXn_nedge));
integer cnt_duty; // PWM Frequency Count
always @(posedge clk, posedge reset_p) begin
if (reset_p) begin
cnt_duty <= 0; // PWM Frequency Count Reset
pwm <= 0; // Pulse Reset
end
else if (pwm_freqXn_nedge) begin
if (cnt_duty >= duty_step_N) cnt_duty = 0; // Count to End of Duty
else cnt_duty <= cnt_duty + 1; // Count PWM Frequency
if (cnt_duty < duty) pwm <= 1; // Pulse High Until Duty
else pwm <= 0; // Pulse Low After Duty
end
end
endmodule