module pwm_basic
#(parameter R = 8)(
input clk,
input reset_n,
input [R – 1:0] duty,
output pwm_out
);
// Up Counter
reg [R - 1:0] Q_reg, Q_next;
always @(posedge clk, negedge reset_n)
begin
if (~reset_n)
Q_reg <= 'b0;
else
Q_reg <= Q_next;
end
// Next state logic
always @(*)
begin
Q_next = Q_reg + 1;
end
// Output logic
assign pwm_out = (Q_reg < duty);
endmodule
This is our previous design let us see how we can enhance it
First we will code the input timer module
module timer_input
#(parameter BITS = 4)(
input clk,
input reset_n,
input enable,
input [BITS – 1:0] FINAL_VALUE,
// output [BITS – 1:0] Q,
output done
);
reg [BITS - 1:0] Q_reg, Q_next;
always @(posedge clk, negedge reset_n)
begin
if (~reset_n)
Q_reg <= 'b0;
else if(enable)
Q_reg <= Q_next;
else
Q_reg <= Q_reg;
end
// Next state logic
assign done = Q_reg == FINAL_VALUE;
always @(*)
Q_next = done? 'b0: Q_reg + 1;
endmodule
This is a synchronous reset block triggered on the positive edge of the clock and the negative edge of the reset signal.
begin if (~reset_n) Q_reg <= 'b0;
If the reset signal is active (low), the counter is reset to zero.
else if(enable) Q_reg <= Q_next;
If the enable signal is active, the current state of the counter (Q_next
) is loaded into Q_reg
.
else Q_reg <= Q_reg;
Otherwise, the counter remains in its current state.
assign done = Q_reg == FINAL_VALUE;
The done
output is asserted when the counter reaches the FINAL_VALUE
.
always @(*) Q_next = done? 'b0: Q_reg + 1;
This is the next state logic. It increments the counter (Q_reg
) by 1 unless the done
signal is asserted, in which case the counter resets to 0.
Now we will connect timer module with counter , Let us see how
module pwm_improved
#(parameter R = 8, TIMER_BITS = 15)
(
input clk,
input reset_n,
input [R:0] duty, // Control the Duty Cylce,this is the modified duty cycle
input [TIMER_BITS - 1:0] FINAL_VALUE, // Control the switching frequency
output pwm_out
);
// Up Counter
reg [R - 1:0] Q_reg, Q_next;
wire tick;
always @(posedge clk, negedge reset_n)
begin
if (~reset_n)
Q_reg <= 'b0;
else
Q_reg <= Q_next;
end
// Next state logic
always @(*)
begin
Q_next = Q_reg + 1;
end
// Output logic
assign pwm_out = (Q_reg < duty);
// Prescalar Timer
timer_input #(.BITS(TIMER_BITS)) timer0 (
.clk(clk),
.reset_n(reset_n),
.enable(1'b1),
.FINAL_VALUE(FINAL_VALUE),
.done(tick)
);
endmodule
Now let us connect timer output to up counter
module pwm_improved
#(parameter R = 8, TIMER_BITS = 15)(
input clk,
input reset_n,
input [R:0] duty, // Control the Duty Cylce
input [TIMER_BITS – 1:0] FINAL_VALUE, // Control the switching frequency
output pwm_out
);
reg [R - 1:0] Q_reg, Q_next;
reg d_reg, d_next;
wire tick;
// Up Counter
always @(posedge clk, negedge reset_n)
begin
if (~reset_n)
begin
Q_reg <= 'b0;
end
else if (tick)
begin
Q_reg <= Q_next; ///this is how we connect the timer output i.e tick with counter,when we get new output from timer the counter is updated
end
else
begin
Q_reg <= Q_reg;
end
end
// Next state logic
always @(Q_reg, duty)
begin
Q_next = Q_reg + 1;
d_next = (Q_reg < duty);
end
// Prescalar Timer
timer_input #(.BITS(TIMER_BITS)) timer0 (
.clk(clk),
.reset_n(reset_n),
.enable(1'b1),
.FINAL_VALUE(FINAL_VALUE),
.done(tick)
);
endmodule
Let us see now , How we will integrate flip flop with our circuit
module pwm_improved
#(parameter R = 8, TIMER_BITS = 15)(
input clk,
input reset_n,
input [R:0] duty, // Control the Duty Cylce
input [TIMER_BITS – 1:0] FINAL_VALUE, // Control the switching frequency
output pwm_out
);
reg [R - 1:0] Q_reg, Q_next;
reg d_reg, d_next;
wire tick;
// Up Counter
always @(posedge clk, negedge reset_n)
begin
if (~reset_n)
begin
Q_reg <= 'b0;
d_reg <= 1'b0;
end
else if (tick)
begin
Q_reg <= Q_next;
d_reg <= d_next; //THIS is to integrate flip flop with our design
end
else
begin
Q_reg <= Q_reg;
d_reg <= d_reg;
end
end
// Next state logic
always @(Q_reg, duty)
begin
Q_next = Q_reg + 1;
d_next = (Q_reg < duty);
end
assign pwm_out = d_reg; ///final output is the output of flip flop
// Prescalar Timer
timer_input #(.BITS(TIMER_BITS)) timer0 (
.clk(clk),
.reset_n(reset_n),
.enable(1'b1),
.FINAL_VALUE(FINAL_VALUE),
.done(tick)
);
endmodule
Testbench is similar to basic PWM design
Leave a comment