0
\$\begingroup\$

My question here is with reference to this question previously asked. Currently, I am able to generate delays for each signal as desired.

Next, I want to generate different delays for alternate vsync rising edges. Example:

  • If it is the first rising edge of vsync, then generate delay equal to 4 clock cycles on output (i.e., vsync_o).
  • If it is the second rising edge of vsync, then generate delay equal to 2 clk cycles on output (i.e., vsync_o).

So the delays I want on the output should alternate between 4 clock cycles and 2 clock cycles.

I am not able to figure out how to do this. I am currently initializing a counter which does not reset (so I can compute the number of vsync pulses).....but this will ultimately saturate. Is there a better method or am I missing something?

I have written the following code. Will this lead to any problems which can be avoided otherwise?

`timescale 1ns / 1ps

module Sync_Delay( clk_27,  vsync,   hsync,          
                            vsync_o, hsync_o );

 input clk_27;

 input wire vsync;
 input wire hsync;

 output reg vsync_o;
 output reg hsync_o;

 reg[20:0] v_bits;
 reg[2:0] h_bits;

 reg cnt = 0;

 always @ (posedge vsync)
 begin
     cnt = !cnt;
 end

 always @ (posedge clk_27)
    begin
    if (cnt == 0)
       begin
       vsync_o <= vsync;
       hsync_o <= hsync;
       end
    else
       begin
       vsync_o <= v_bits[20];
       v_bits <= {v_bits[19:0], vsync};
       hsync_o <= h_bits[2];
       h_bits <= {h_bits[1:0], hsync};
       end
 end
endmodule

I notice a difference in pulse width between the input and output signal, which is not desirable.

\$\endgroup\$
  • \$\begingroup\$ You only need a one-bit counter for vsync to tell you whether it's an "even" or "odd" count. Just allow it to roll over. \$\endgroup\$ – pjc50 Jun 16 '16 at 12:38
1
\$\begingroup\$

From the other question, you already have a way of delaying the signal by between 1 and 4 clock cycles:

reg[3:0] bits;

always @ (posedge clk_27)
begin
    vsync_o <= bits[3]; //this was in the original code but actually makes it 5 cycles! But whatever.
    bits <= {bits[2:0], vsync};
end

So you can easily modify that to have two signals coming out, one with 4 cycles delay and the other with 2 cycles delay (hint: if bit 3 is 4 cycles of delay, which bi is 2 cycles).

Now you have two signals - one with 4 cycles of delay, and one with two cycles of delay. All that is needed then is a way to select which one is which. The word "select" implies you need a multiplixer - 2:1 in fact (two signals in, one out).

That means you also need something to drive the select line. Given it is 2:1, this is just a 1 bit control signal which you need to toggle every time there is a pulse. What do you know that can toggle? A flip-flop. To you need a flip-flop that toggles every time there is a pulse on Vsync.

The next question is, how do you detect a pulse on Vsync? Well, you see if there is a rising edge (or falling edge, or both). For that you need a rising edge detector. The structure is essentially:

reg delay;
always @ (posedge clock) begin
    delay <= in;
end
wire risingedge = delay && !in;
wire fallingedge = !delay && in;
wire bothedges = delay != in;

So you need the signal, plus the signal delayed by one clock cycle. You have vsync, and your bits register has the signal delayed by one clock cycle, so you already have all the signals you need to build an edge detector.

reg whichDelay;
always @ (posedge clock or posedge reset) beign
    if (reset) begin
        whichDelay <= 1'b1; //Start with a delay of 2 because on the first rising edge we will toggle.
    end else if (vsync && !bits[0]) begin
        whichDelay <= !whichDelay; //Toggle on each vsync input
    end
end

assign vsync_o = whichDelay ? bits[1] : bits[3];

And there you have it.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the detailed explanation. I will take a while to understand your answer. In the meanwhile, I have edited my question. Kindly provide a feedback. (Please note that this is the first time I'm coding using Verilog) \$\endgroup\$ – Saania Jun 17 '16 at 8:03
0
\$\begingroup\$

Yes there is a better method. You must write your VHDL in gate level. Use a 2:1 mux to route your signal through two different delay element.

Concurrently use a counter to keep track of first and second rise of vsync. It should output its signal to the selector pin of the mux.

\$\endgroup\$

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.