Pulse Width detection in verilog?

Guest
I'm working on a project that requires me to detect the frequency and duty cycle of the PWM signal


this is what i have so far but i have couple errors that i don't know how to fix:



module low_high_count(
input clk,
input pwm0_signal,
input reset_n,
output [31:0] frequency, //embsus GPIO outputs count
output [31:0] duty_cycle);

//inter variables
wire sysclk;
wire sysreset_n;
wire axi_timer_0_pwm0;
wire [31:0] axi_gpio_1_duty_cycle;
wire [31:0] axi_gpio_1_frequency;

//local variables used for calcuation
reg [31:0] hightime_count;
reg [31:0] lowtime_count;
reg [31:0] duty_cycle_calculation;
reg [31:0] frequency_calculation;
reg [31:0] period_calculation;

reg [31:0] old_frequency;
reg [31:0] old_duty_cycle;
assign old_frequency =0;
assign old_duty_cycle=0;

//connect the ports-wires ("wire" = "verilog input/output")
assign axi_timer_0_pwm0 = pwm0_signal;
assign sysclk=clk;
assign sysreset_n=reset_n;

assign axi_gpio_1_frequency = frequency;
assign axi_gpio_1_duty_cycle = duty_cycle;

//counts, starting at the first positive edge, the hight time
always @(posedge pwm0_signal )
if(!reset_n)
begin
hightime_count <= 32'd0 ; //resets positive clock count

end
else
begin
hightime_count <= hightime_count + 32'd1; //increment the count by 1

end


always @(negedge pwm0_signal)
if(!reset_n)
begin
lowtime_count <= 32'd0; //resets negative clock count
end
else
begin
lowtime_count <= lowtime_count + 32'd1; //increment the count by 1
end

//duty cycle and frequency calculation
assign period_calculation = (hightime_count + lowtime_count)/100000000;
assign frequency_calculation = (1/period_calculation);
assign duty_cycle_calculation = (hightime_count/(hightime_count + lowtime_count))*100;

assign old_frequency = frequency_calculation;
assign old_duty_cycle = duty_cycle_calculation;

assign frequency = frequency_calculation;
assign duty_cycle = duty_cycle_calculation;

endmodule


thank you so much

edgar
 
Hello,

there exists a group for verilog. YOu might get some answers concerning verilog there. But the principle is the same in VHDL, so this post should still help you. BTW your topic is somehow a FAQ, Google provides several sollutions to this problem.

module low_high_count(
input clk,
input pwm0_signal,
input reset_n,
output [31:0] frequency, //embsus GPIO outputs count
output [31:0] duty_cycle);

//counts, starting at the first positive edge, the hight time
always @(posedge pwm0_signal )

It is usually the wrong way to use the signal you like to measure as clock signal in a process.

What you like to do is to oversample the pwm signal with clk and measure how many cycles of clk the signal pwm is high after a rising edge.
Therefore you use best a two rank FF to bring the signal PWM stable in clock domain of signal "clk" (avoid problems with clock domain crossing), use a third ff for edge detection and measure the number of clock cycles the signal in clk-clock domain is set high.

In VHDL this would be:

signal pwm_clk : std_ulogic_vector(1 downto 0);
signal counter : integer range 0 to .....;

process (clk, reset)
if reset=ACTIVE then
pwm_clk <= (others=>'0');
counter <= 0;
elsif rising_edge(clk)
pwm_clk <= pwm_clk(1) & pwm0_signal;
if pwm_clk(2 downto 1) = "01" then
counter <= 0;
elsif pwm_clk(2)='1' then
counter <= counter+1;
end if;
end if;
 

Welcome to EDABoard.com

Sponsor

Back
Top