fpga-lab-2/HDL/avalon_pwm.v

89 lines
1.5 KiB
Verilog

module avalon_pwm
(
clk, wr_data, cs, wr_n, addr, clr_n, rd_data, pwm_out
);
input clk;
input [31:0] wr_data;
input cs;
input wr_n;
input addr;
input clr_n;
output [31:0] rd_data;
output [7:0] pwm_out;
/////////////////////////////////////////////////////////////////////
// Registers and wires
reg [31:0] div;
reg [31:0] duty;
reg [31:0] counter;
reg off;
reg [31:0] rd_data;
wire div_en, duty_en;
/////////////////////////////////////////////////////////////////////
// Avalon slave interface
//chip select and address decoder
assign div_en = cs & !wr_n & !addr ;
assign duty_en = cs & !wr_n & addr ;
//register write
always @(posedge clk or negedge clr_n)
begin
if (clr_n == 0)
begin
div <= 0;
duty <= 0;
end
else
begin
if (div_en) div <= wr_data;
if (duty_en) duty <= wr_data;
end
end
//register read
always @(*)
begin
if (addr == 0)
rd_data = div;
else
rd_data = duty;
end
/////////////////////////////////////////////////////////////////////
// PWM logic
//PWM counter
always @(posedge clk or negedge clr_n)
begin
if (clr_n == 0)
counter <= 0;
else
if (counter >= div)
counter <= 0;
else
counter <= counter + 1;
end
//PWM compare
always @(posedge clk or negedge clr_n)
begin
if (clr_n == 0)
off <= 0;
else
if (counter >= duty)
off <= 1;
else
if (counter == 0)
off <= 0;
else
off <= off;
end
assign pwm_out = {8{!off}};
endmodule