1
\$\begingroup\$

I am trying to write Verilog code which will measure the width of a pulse and then send a return pulse which has the same width. So far, I have created a counter which counts the number of periods that the input signal is high. I can then take the last number from this counter and multiply it by the clock time period to get the time that the input pulse was high.

The issue I am running into is how to store the count from the previous pulse, generate the return pulse and start measuring the next pulse so that its return pulse can be generated. I know I need to incorporate some type of delay but I am not sure how long the delay should be.

Here is the code and simulation result I have so far.

///////////// 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 ),

endmodule 

enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ Why are you comparing the one bit \$in_1\$ with an 8 bit zero? \$\endgroup\$
    – copper.hat
    Commented Aug 27, 2020 at 2:42
  • \$\begingroup\$ I am a little unclear on what exactly you want. Perhaps you could add an additional one bit output that indicates when out has a new value? \$\endgroup\$
    – copper.hat
    Commented Aug 27, 2020 at 2:47
  • \$\begingroup\$ You need to define the parameters of your inputs. Tell us about input pulses that overlap with output pulses. Can you get 100 pulses of one clock cycle while you are trying to produce an output pulse of 500 clock cycles? What is the limit here? \$\endgroup\$ Commented Aug 27, 2020 at 12:08

1 Answer 1

0
\$\begingroup\$

You don't need to measure the output pulse, you just have to set it high for the same number of clock cycles.

One way to do this would be to have two separate counters, an input counter and an output counter. The input counter could count up from 0 as you are already doing. Whenever you are done measuring the input count, you could then use that to set the initial value of the output counter. Then every clock cycle, have the output counter count down, stopping at 0. Set the output signal high whenever the output counter value is nonzero.

You could also possibly use the same counter for both input and output (count up while measuring input, then count down for output), but it will probably be a little trickier to handle all the corner cases properly.

By the way, when you say "I can then take the last number from this counter and multiply it by the clock time period to get the time," I just want to make sure you mean just for a debug output. You don't need to do this multiplication within the design itself.

\$\endgroup\$
5
  • \$\begingroup\$ I see what you are saying and I like your idea but how would this work if say the first pulse is 1000 seconds long and the second pulse is 100 seconds long? In that case as the second counter is counting down from 1000 the first counter has already counted up to 100 and is now going to interrupt the second counter. Also, yes the multiplying the counter by the clock time period is just for debugging. \$\endgroup\$
    – yer
    Commented Aug 26, 2020 at 22:55
  • \$\begingroup\$ You could handle that case, but you'll need another counter to do it. Are you sure that you need to handle it? Do you need to handle more than one extra pulse? How many? \$\endgroup\$
    – Justin
    Commented Aug 27, 2020 at 14:08
  • \$\begingroup\$ I could have almost continuous successive pulses. \$\endgroup\$
    – yer
    Commented Aug 27, 2020 at 19:50
  • \$\begingroup\$ @yer - In the case where you have a long pulse followed by many short pulses, do you want the short pulse outputs to be delayed until the long pulse is completed? \$\endgroup\$
    – Justin
    Commented Aug 27, 2020 at 20:59
  • \$\begingroup\$ @yer - You may need to use a system where you have a large output counter and a buffer of turn-on and turn-off count values with start/stop index pointers. It will be more complex. You still need to determine hard limits though. What is the longest input pulse in # of clock cycles? You cannot say "any," but you can say "100 billion." How many additional pulses do you need to remember to save while outputting the delayed pulse. Again, you can't say "any number," but you can say "100." You can't really say "100 billion" for this one though, since it will take way too much memory. \$\endgroup\$
    – Justin
    Commented Aug 27, 2020 at 21:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.