Forum Discussion
Altera_Forum
Honored Contributor
17 years agoSOPC PWM Module
Hi, I would like to add some PWM outputs to my NIOS system. I could not find a module in the SOPC builder and hardly anything on the web. It is somehow unbelievable that not many users need PWM...
Altera_Forum
Honored Contributor
17 years agoI make a simple pwm module (only 1 output).
is in use in a cyclone III, without problems. 3 modules: ************************ pwm.v ************************ //modulo generador PWM //toni salguero //inicio: 15 de junio de 2009 module pwm( rst_n, clk, //bus avalon av_cs, av_rd, av_wr, av_datain, av_dataout, av_addr, //señal de salida PWM pwm_out ); input rst_n; input clk; //bus avalon input av_cs; input av_rd; input av_wr; input [1:0]av_addr; input [31:0]av_datain; output [31:0]av_dataout; //señal de salida PWM output pwm_out; wire pwm_enable; wire [15:0]pwm_divisor; wire [7:0] pwm_width; pwm_avalon_slave_if pwmif (rst_n, clk, av_cs, av_rd, av_wr, av_addr, av_datain, av_dataout, pwm_enable, pwm_divisor, pwm_width); pwm_control pwmc (rst_n, clk, pwm_enable, pwm_divisor, pwm_width, pwm_out); endmodule ************************ pwm_control.v ************************ //modulo de control del pwm //toni salguero //inicio: 15 de junio de 2009 module pwm_control( rst_n, clk, pwm_enable, pwm_divisor, pwm_width, pwm_out ); input rst_n; input clk; input pwm_enable; input [15:0]pwm_divisor; input [7:0]pwm_width; output pwm_out; wire pwm_clk; reg [7:0]contador; reg [15:0]clk_div; //generador del clock del modulo always @ (posedge clk or negedge rst_n) begin if(~rst_n) begin clk_div <= 0; end else if(pwm_enable) begin clk_div <= clk_div+1; if(clk_div == pwm_divisor) begin clk_div <= 0; end end end assign pwm_clk = (clk_div == 0 ) ? 1'b1 : 1'b0; //señal de salida always @ (posedge clk or negedge rst_n) if(~rst_n) begin contador <= 0; end else if(pwm_enable) begin if(pwm_clk) contador <= contador+1; end else contador <= 0; assign pwm_out = (contador <= pwm_width) ? 1'b1: 1'b0; endmodule ************************ pwm_avalon_slave_if.v ************************ //interficie con el bus avalon //toni salguero //inicio: 15 de junio de 2009 module pwm_avalon_slave_if( rst_n, clk, chipselect, read_n, write_n, address, writedata, readdata, pwm_enable, pwm_divisor, pwm_width ); input rst_n; input clk; input chipselect; input read_n; input write_n; input [1:0]address; input [31:0]writedata; output [31:0]readdata; output pwm_enable; output [15:0]pwm_divisor; output [7:0]pwm_width; reg delayed_cs; reg pwm_enable; reg [15:0]pwm_divisor; reg [7:0]pwm_width; wire cs; //retardo de cs always @ (posedge clk or negedge rst_n) if(~rst_n) delayed_cs <= 0; else delayed_cs <= chipselect; assign cs = chipselect & ~delayed_cs; //carga datos en el registro de control always @ (posedge clk or negedge rst_n) if (~rst_n) begin pwm_enable <= 0; pwm_divisor <= 0; pwm_width <= 0; end else if (cs & ~write_n & (address == 0)) begin pwm_width <= writedata[7:0]; end else if (cs & ~write_n & (address == 1)) begin pwm_enable <= writedata[31]; pwm_divisor <= writedata[15:0]; end //lectura de los datos //datos de salida assign readdata = 32'b0 | {32{(~read_n & chipselect & (address == 0))}} & {24'b0, pwm_width} | {32{(~read_n & chipselect & (address == 1))}} & {pwm_enable, 15'b0, pwm_divisor}; endmodule Toni Salguero