Search code examples
verilogsystem-verilogfpga

Create a pulse of a given signal


I have a signal sig. This may remain high for multiple clock cycles. I want to create a pulse of it that should toggle for as many clock cycles for which the signal was high.

That is every time my signal sig goes from low to high, I will get a pulse of it. The challenging thing is if the signal is high for multiple clk, how will I create a pulse of it? Even though my signal is high for three consecutive clock cycles, my pulse should toggle three times (from 0 to 1 and 1 to 0).

module PULSE_GEN  (input clk,  input sig,input en,output wire pulse);

reg r1,r2,r3;
        always @(posedge clk) begin
           if(en)
           begin
             r1 =sig;
             r2 = r1 ^ sig; 
             r3 = r1 & r2;
           end
           else
             r3 = 1'b0;
        end 

assign pulse =  r3; 

endmodule

However, I am not able to generate the pulse. The waveform in the order shows pulse, en, sig and clk. pulse is always low.

enter image description here

I created a drawing of a desired waveform:

enter image description here

As the image shows ,sig is higher for multiple clock cycles.The requirement is that the pulse should become high on the posedge of clk and should become low on next posedge of the clk. And Again becomes high on next posedge as sig was high. This should happen only when en condition is high(which is basically Time advance).If en is low ,pulse should be low.


Solution

  • The fact that you require pulse to rise with sig means you need to use Mealy style state machine; where the output is a function of its present state and current input. Mealy is fast, but is more susceptible to glitches and other limitation. I recommend searching: Mealy vs Moore. I also recommend searching about Verilog blocking vs non-blocking

    Your required behavior can be achieved with the below. I omitted the en as your question looks like homework. I will leave it to you to figure out.

    assign pulse = !present_state && sig;
    always @(posedge clk) begin
      present_state <= pulse && sig;
    end
    

    enter image description here