| |
PWM controller based on Verilog:
//-----------------------------32 bits pwm controller------------------------//
//the width is negative
module pwm(clk,write_data,cs,write_n,addr,clr_n,read_data,pwm_out);
//----------------------define the inout put-------------------------//
input clk,cs,clr_n;
input addr;
input write_n;
output pwm_out;
output [31:0] read_data;
input [31:0] write_data;
//--------------------define regs and wires--------------------------//
reg [31:0] period;
reg [31:0] pulse_width;
reg [31:0] counter;
reg off;
reg [31:0] read_data;
wire period_en, pulse_width_en; //enable to write
//-------------------------------------------------------------------//
//define the content of period and pulse_width
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0)
begin
period<=32'h 00000000;
pulse_width<=32'h 00000000;
end
else
begin
if (period_en)//write in preiod data
period<=write_data[31:0];
else
period<=period;
if (pulse_width_en)//write in width data
pulse_width<=write_data[31:0];
else
pulse_width<=pulse_width;
end
end
//------------------------------------------------------------------//
//visit the regs
always @(addr or period or pulse_width)
begin
if (addr == 0)
read_data=period;
else
read_data=pulse_width;
end
//-------------------------------------------------------------------//
//the logic to generate pwm
//the period of pwm
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0)
counter<=0;
else
begin
if (counter>=period-1)
counter<=0;
else
counter<=counter+1;
end
end
//-----------------------------------------------------//
//ajust the width of pwm
always @(posedge clk or negedge clr_n)
begin
if (clr_n==0)
off<=0;
else
if (counter>=pulse_width)
off <= 1;
else
if (counter==0)
off<=0;
else
off<=off;
end
assign period_en = cs & !write_n & !addr;
assign pulse_width_en = cs & !write_n & addr;
//PWM output
assign pwm_out=!off;
endmodule