Electrical – Using a counter to count how many clock cycles a signal is high using Verilog

clockcounterfpgaliberoverilog

I want to use a counter to count how many clock cycles an input signal is high. The issue I am running into is that once the input signal returns back to zero, my counter resets which causes my output to also reset since my counter and output are set equal to one another.

In other words, you can see in my simulation that my output is set to 5 for only one clock cycle before it is reset back to zero. What I would like to happen is my output signal to remain equal to my last clock cycle until a new count is finished.

I've posted my code and simulation below.

///////////// HDL Code //////////////
module counter    (
out     ,  // Output of the counter
in_1  ,  // input signal
clk     ,  // clock Input
reset   ,     // reset Input
);

  output [7:0] out;
  input in_1, clk, reset;
     
  reg [7:0] out;
  reg [7:0] counter;
    
always @(posedge clk)
if (reset) 
  counter <= 8'b0;
else if (in_1) 
  counter <= counter + 1;
else if (in_1 == 8'b0) 
begin 
  out = counter; 
  counter = 8'b0;
end
endmodule 

///////////// Test bench Code //////////////

`timescale 1ns/100ps

module counter_tb;

//parameter SYSCLK_PERIOD = 20;// 50MHZ

reg clk_1;
reg in_11;
reg reset_1;

wire [7:0] out_1; 

initial
begin
    clk_1 = 1'b0;
    in_11 = 1'b0;
    reset_1 = 1'b1;
    
    #20;
    
    in_11 = 1'b1;
    reset_1 = 1'b0;
    
    #50;
    
    in_11 = 1'b0;
    
    #100;
    
    in_11 = 1'b1;
    
    #100;
    
    in_11 = 1'b0;
    
    #50;
    
    $stop;
end

//////////////////////////////////////////////////////////////////////
// Clock Driver
//////////////////////////////////////////////////////////////////////
always
    #5 clk_1 = ~clk_1;


//////////////////////////////////////////////////////////////////////
// Instantiate Unit Under Test:  counter
//////////////////////////////////////////////////////////////////////
counter counter_0 (
    // Inputs
    .in_1(in_11),
    .clk(clk_1),
    .reset(reset_1),

    // Outputs
    .out( out_1 ),

enter image description here

Best Answer

Don't mix <= and = in a single always block. Though I have never done this way yet, I can think of that on the 2nd active clock edge after in_1's deassertion, out is updated to the new counter which has been reset to zero one clock cycle before.

What you need is to latch the counter to out only when clk sees a deassertion on in_1. Design and figure out what circuit match your requirements, and then code.

Circuit first. This is not software program.