Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

SOPC 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 outputs on their microprozessors.

Pls give me advise how to proceed.

Thanks,

Wolfgang

P.S.: I only post this message in the IP Discussion, because the NIOS forum is obiously down.

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I 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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    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. ..

    Pls give me advise how to proceed.

    --- Quote End ---

    You should read close topic (http://www.alteraforum.com/forum/showthread.php?t=5892). There is link to literature there. And I attached component with PWM outputs to SOPC (systemavalon_slave_pwm.zip)