0
\$\begingroup\$

I am trying to make a very simple module in System Verilog that receives a short pulse as an input, and returns as an output a pulse which is twice wider. For example, if the input is a 1ns pulse, then I want the output to be 2ns pulse. A delayed output would be even better.

I thought of making a frequency divider, but that won't help here, since frequency divider works with clocks, which rise and fall all the time, in contrast to a pulse, which will rise only once.

Thank you!

\$\endgroup\$
  • 2
    \$\begingroup\$ Behavioral or for real? Also I am not yet sure what you mean with "A delayed output would be even better". \$\endgroup\$ – Oldfart Dec 21 '19 at 15:01
  • \$\begingroup\$ A very simple module won’t be able to do what you want with any degree of accuracy or repeatability. \$\endgroup\$ – Andy aka Dec 21 '19 at 15:45
1
\$\begingroup\$

As we have several people who say that it can't be done here is a behavioral solution :-) Note that in real hardware it can't be done this way.

module pulse_double(
   input      pulse,
   output reg double_pulse
   );

time time_rise,time_elapsed;

   always @(posedge pulse)
      time_rise = $time;

   always @(negedge pulse)
   begin
     time_elapsed = $time - time_rise;
     double_pulse <= 1'b1;
     double_pulse <= #(2*time_elapsed) 1'b0;
  end
endmodule


module pulse_double_test;
integer loop;
reg  pulse_in;
wire pulse_out;

   pulse_double pulse_double_inst(
    .pulse(pulse_in),
    .double_pulse(pulse_out)
   );

  initial
  begin
     for (loop=0; loop<10; loop=loop+1)
     begin
        pulse_in <= 1'b1;
        #(($random & 32'h07)+32'h02); // width between 2 and 9 
        pulse_in <= 1'b0;
        #20;
     end
  end
endmodule

With the waveform:

enter image description here

This is a simple solution which works for non-overlapping input/output pulses. If input pulses can overlap with the output you have to define what behavior is wanted and then adapt the code accordingly.

\$\endgroup\$
0
\$\begingroup\$

As oldfart correctly points out: This answer applies to verilog meant to actually define hardware only; for simulation models, see his answer!

For example, if the input is a 1ns pulse, then I want the output to be 2ns pulse

That's not among the abilities of verilog, as far as I can tell; since this is not a logical or clocked thing that you want, it's impossible to represent it in verilog.

However, let's rephrase:

If the input is a pulse that lasts for N clock cycles, then I want the output to be 2N clock cycles long.

Then it's really just counters: one increasing a "must still be emitted count" by one per clock cycle as long as the input is high. You'd add minimal logic: The output is high as long as the input is high OR the counter > 0. Also, for as long as the input is low, and counter > 0, decrease counter by 1.

Done! All you need is clock that is at least as fast as the shortest pulse you want to deal with. But that's kind of a given, since this really is digital logic, and not analog circuitry.

\$\endgroup\$
  • 1
    \$\begingroup\$ Marcus, the first is also not problem if the code is behavioral. That is why I asked "Behavioral or for real?" \$\endgroup\$ – Oldfart Dec 21 '19 at 15:56
  • \$\begingroup\$ @Oldfart you're right, and I added a bit of prologue :) \$\endgroup\$ – Marcus Müller Dec 21 '19 at 17:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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