⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwmavalonexample.v

📁 PWM generation,Altera standard function.
💻 V
字号:

/***************************************************************************/
/* File: pwm_avalon_interface.v                                            */
/* Description: Top level module. Instantiates pwm_task_logic and         */
/*    pwm_register_file modules and adds Avalon slave interface.           */
/***************************************************************************/

module pwm_avalon_interface
( clk,
resetn,
avalon_chip_select,
address,
write,
write_data,
read,
read_data,
pwm_out
);

//Parameter values to pass to pwm_register_file instance
parameter clock_divide_reg_init = 32'h0000_0000;
parameter duty_cycle_reg_init = 32'h0000_0000;

//Avalon_Slave_PWM Avalon I/O
input clk;          //System clock - tied to all blocks
input resetn;   //System reset - tied to all blocks
input avalon_chip_select; //Avalon Chip select
input [1:0]address;       //Avalon Address bus 
input write;    //Avalon Write signal
input [31:0]write_data;   //Avalon Write data bus
input read;              //Avalon Read signal

output [31:0]read_data;   //Avalon Read data bus

//Avalon_Slave_PWM Exported I/O
output pwm_out;        //PWM output signal

//Avalon_Slave_PWM Interal Nodes
wire [31:0] pwm_clock_divide; //Clock divide wire from register file to pwm task logic
wire [31:0] pwm_duty_cycle;    //Duty cycle value from register file to pwm task logic
wire        pwm_enable;        //PWM enable signal from register file to pwm task logic


//PWM Instance
pwm_task_logic task_logic
(
    .clk          (clk ),
    .pwm_enable       (pwm_enable),
    .resetn           (resetn),
    .clock_divide     (pwm_clock_divide),
    .duty_cycle       (pwm_duty_cycle),
    .pwm_out     (pwm_out)
);

//Register File instance
pwm_register_file #(clock_divide_reg_init, duty_cycle_reg_init) memory_element
( 
.clk              (clk),
.resetn            (resetn),
.chip_select       (avalon_chip_select),
.address           (address),
.write             (write),
.write_data        (write_data),
.read              (read),
.read_data         (read_data),
.pwm_clock_divide (pwm_clock_divide),
.pwm_duty_cycle (pwm_duty_cycle),
.pwm_enable        (pwm_enable)
);

endmodule

寄存器描述文件:

module pwm_register_file
( //Avalon Signals
clk,
resetn, 
chip_select,
address,
write,
write_data,
read,
read_data,

//PWM Output Signals
pwm_clock_divide,
pwm_duty_cycle,
pwm_enable
);

//Parameters
parameter clock_divide_reg_init = 32'h0000_0000;
parameter duty_cycle_reg_init   = 32'h0000_0000;

//Inputs

input clk;         //System Clock
input resetn;    //System Reset
input chip_select;   //Avalon Chip select signal
input [1:0] address;       //Avalon Address bus 
input write;    //Avalon Write signal
input [31:0] write_data; //Avalon Write data bus
input read;         //Avalon read signal

//Outputs
output [31:0] read_data;   //Avalon read data bus
output [31:0] pwm_clock_divide; //PWM clock divide drive signals
output [31:0] pwm_duty_cycle;   //PWM duty cycle drive signals
output        pwm_enable;       //PWM enable drive signals

//Signal Declarations 
  
reg [31:0] clock_divide_register; //Clock divider register
reg [31:0] duty_cycle_register; //Duty Cycle Register
reg        enable_register; //Enable Bit 
reg [31:0] read_data;    //Read_data bus

//Nodes used for address decoding
wire clock_divide_reg_selected, duty_cycle_reg_selected, enable_reg_selected;
//Nodes for determining if a valid write occurred to a specific address
wire write_to_clock_divide, write_to_duty_cycle, write_to_enable;
//Nodes for determining if a valid read occurred to a specific address
wire read_to_clock_divide, read_to_duty_cycle, read_to_enable;
//Nodes used to determine if a valid access has occurred
wire valid_write, valid_read;

//Start Main Code 

//address decode
assign clock_divide_reg_selected = !address[1] & !address[0]; //address 00
assign duty_cycle_reg_selected   = !address[1] & address[0]; //address 01
assign enable_reg_selected       = address[1] & !address[0]; //address 10

//determine if a vaild transaction was initiated 
assign valid_write = chip_select & write;  
assign valid_read = chip_select & read;

//determine if a write occurred to a specific address
assign write_to_clock_divide = valid_write & clock_divide_reg_selected;
assign write_to_duty_cycle   = valid_write & duty_cycle_reg_selected;
assign write_to_enable       = valid_write & enable_reg_selected;

//determine if a read occurred to a specific address
assign read_to_clock_divide = valid_read & clock_divide_reg_selected;
assign read_to_duty_cycle   = valid_read & duty_cycle_reg_selected;
assign read_to_enable       = valid_read & enable_reg_selected;

//Write to clock_divide Register
always@(posedge clk or negedge resetn)
begin
if(~resetn)begin //Async Reset
   clock_divide_register <= clock_divide_reg_init; //32'h0000_0000;
end
else begin 
   if(write_to_clock_divide) begin
    clock_divide_register <= write_data; 
   end
   else begin
    clock_divide_register <= clock_divide_register; 
   end
  
end
end 

//Write to duty_cycle Register
always@(posedge clk or negedge resetn)
begin
if(~resetn)begin //Async Reset
   duty_cycle_register <= duty_cycle_reg_init; //32'h0000_0000;
end
else begin 
   if(write_to_duty_cycle) begin
    duty_cycle_register <= write_data; 
   end
   else begin
    duty_cycle_register <= duty_cycle_register; 
   end
end
end 

//Write to enable register
always@(posedge clk or negedge resetn)
begin
if(~resetn)begin //Async Reset
   enable_register <= 1'b0;
end
else begin
   if(write_to_enable)begin
    enable_register <= write_data[0];
   end
   else begin
    enable_register <= enable_register;
   end
end
end

//Read Data Bus Mux
always@(read_to_clock_divide or read_to_duty_cycle or read_to_enable or clock_divide_register or duty_cycle_register or enable_register)
begin
if(read_to_clock_divide) begin
   read_data = clock_divide_register;
end
else if(read_to_duty_cycle) begin
   read_data = duty_cycle_register;
end
else if(read_to_enable) begin
   read_data = {31'd0,enable_register};
end
else begin
   read_data = 32'h0000_0000;
end
end

//assign register values to register file outputs to the PWM
assign pwm_clock_divide = clock_divide_register;
assign pwm_duty_cycle = duty_cycle_register;
assign pwm_enable = enable_register;

endmodule

PWM生成逻辑描述文件:

/***************************************************************************/
/* File: pwm_task_logic.v                                                  */
/* Description: This module contains the core of the pwm functionality.    */
/*    The clock_divide and duty_cycle inputs are used in conjunction with */
/*    a counter to determine how long the pwm output stays high and low.   */
/*    The output is 1 bit.                                                 */
/***************************************************************************/

module pwm_task_logic
(
clk,
pwm_enable,
resetn, 
clock_divide,
duty_cycle,
pwm_out
);

//Inputs
input clk;     //Input Clock to be divided
input [31:0] clock_divide; //Clock Divide value
input [31:0] duty_cycle; //Duty Cycle vale
input pwm_enable;    //Enable signal
input resetn;    //Reset

//Outputs
output pwm_out;    //PWM output

//Signal Declarations 
reg [31:0] counter;   //PWM Internal Counter
reg pwm_out;    //PWM output

//Start Main Code 
always @(posedge clk or negedge resetn)         //PWM Counter Process
begin
if (~resetn)begin
   counter <= 0;
end
else if(pwm_enable)begin
   if (counter >= clock_divide)begin
    counter <= 0;
   end
   else begin 
    counter <= counter + 1;
   end
end
else begin
   counter <= counter;   
end
end

always @(posedge clk or negedge resetn)      //PWM Comparitor
begin
if (~resetn)begin
   pwm_out <= 0;
end
else if(pwm_enable)begin
   if (counter >= duty_cycle)begin
    pwm_out <= 1'b1;
   end
   else begin
    if (counter == 0)
     pwm_out <= 0;
    else
     pwm_out <= pwm_out;
    end
   end
else begin
   pwm_out <= 1'b0;
end
end


endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -