signalsverilogfpgaclockpulse

Generating a pulse with fast and slow clock in Verilog


I'm preparing a program in Verilog. I have a problem with implementing a short pulse that will occur every time on a rising edge of slow clock and disappear on the rising edge of the fast clock.

Below I paste the code I wrote, which gives me such a pulse, but unfortunately it appears only once on the first edge and never occurs again.

reg cnt_write_bit1, cnt_write_bit2; 
initial cnt_write_bit1 = 0;
initial cnt_write_bit2 = 0;
reg cnt_write_fifo;
initial cnt_write_fifo = 0; 

always @ (posedge clk_1kHz)
begin : WRITE_FIFO
    if (cnt_write_fifo)
    begin
        cnt_write_bit1 <= 0;
    end
    else
    begin
        cnt_write_bit1 <= 1;
    end
end

always @ (posedge clk_50MHz)
begin : STOP_WRITE_FIFO
    if (cnt_write_fifo)
    begin
        cnt_write_bit2 <= 0;
    end
    else //if (!cnt_write_bit1)
    begin
        cnt_write_bit2 <= 1;
    end
end

always @ (cnt_write_bit1, cnt_write_bit2)
begin 
    if (cnt_write_bit1 && cnt_write_bit2)
    begin 
        cnt_write_fifo <= 1;
    end
    else if (!cnt_write_bit2)
    begin
        cnt_write_fifo <= 0;
    end
end

On the simulation it looks like this:

The pulse on the "cnt_write_fifo" signal should be repeatable on every rising edge of slow clock, but unfortunately it is not.

I will be grateful for any help.


Solution

  • If as you say the clocks are a-synchronous you can't do what you want.
    Let's say at some point in time the two rising clock edges are 1ps apart, (slow clock leading) you then would need to generate a signal which is high for 1ps. Apart from the difficulties of achieving that, what would you do with it?

    I suggest you change your 'specification' into something like:

    "There is a signal generated from a slow clock. If there is a rising edge I want to have a pulse of 1 clock cycle long on a non-related faster clock. There is allowed a maximum of X fast clock pulses delay between the signal changing on the slow clock generating a pulse on the fast clock (X>=2)".

    Sorry major edit: I had my brain not switched on!
    Transfer the signal from the slow clock to the fast clock using synchronizes. Then in the fast clock domain find the rising edge:

    //
    // Transfer a signal from a slow clock to a fast clock
    // Also detect the rising edge in the fast clock domain
    //
    module signal_transfer 
    (
    
      input      slow_clock, 
      input      slow_signal,
    
      input      reset_n,     // reset for fast clock domain
      input      fast_clock,
      output reg fast_signal,
      output     fast_rising
      );
    
    reg signal_meta,signal_delay;
    
    
       always @(posedge fast_clock or negedge reset_n)
       begin
          if (!reset_n)
          begin
             signal_meta  <= 1'b0;
             fast_signal  <= 1'b0;
             signal_delay <= 1'b0;
          end
          else
          begin
             signal_meta  <= slow_signal;
             fast_signal  <= signal_meta;
             signal_delay <= fast_signal;
          end
       end
    
       assign fast_rising = fast_signal & !signal_delay;
    
    endmodule