0
\$\begingroup\$

I would like to write a verilog code to generate RTL level for signal B as in the figure. It has been a long time since I wrote verilog at school so I am quite rusty at this. Let's say I have two signals A, B as in the picture and I need to generate the signal C with the description below.

The rising edge of signal C is determined as follows:

  1. At the falling edge of signal A if rising edge of signal B is occured before falling edge of signal A.
  2. At the rising edge of signal B if rising edge of signal B is occured after falling edge of signal A.
    (you may want to look at the picture to understand the rule easier)

The duty cycle of signal C is equal to duty cycle of signal A.

I am stuck at the part to compare whether the rising edge of signal B is occured BEFORE or AFTER falling edge of signal A. Hope someone could help me on this.

enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ What are the pulse-widths of the signals? (ns? us?) And what sort of resolution to do need? (exact or is clock sampled ok). \$\endgroup\$ Commented Jan 7, 2018 at 13:39
  • \$\begingroup\$ "The duty cycle of signal C is equal to duty cycle of signal A." - that doesn't appear to be what is shown in your diagram. \$\endgroup\$ Commented Jan 7, 2018 at 13:40
  • \$\begingroup\$ Are the signal edges assumed to be clean? (i.e. no bounce, spurious pulses, etc.) \$\endgroup\$ Commented Jan 7, 2018 at 13:42

1 Answer 1

1
\$\begingroup\$

There isn't quite enough information in your question as to the best way to approach this. However I will make two assumptions:

  1. The signals are conditioned (i.e. no spurious pulses or noisy edges)
  2. You are able to sample the signals with a fast clock to make them synchronous. This means you can simply check the signals at discrete time points rather than asynchronously.

Given these assumptions, the approach I would use is to detect the edges of the signals using a simple synchronous edge detector. You can then use a state machine to determine the order of events.

//First we sample the signals with fast clock and perform edge detection.
//This gives us a series of discrete time points to work with
reg aDly, bDly;
reg aFall, bRise;
always @ (posedge fastClock) begin
    aDly <= a;
    bDly <= b;
    aFall <=  aDly && !a; //Falling edge of a when aDly high and a low.
    bRise <= !bDly &&  b; //Rising edge of b when bDly low and b high.
end

reg someEvent; //Set this high when c needs to fall.

//Now we do the logic for C with a state machine.
localparam IDLE_STATE   = 2'b00;
localparam AFIRST_STATE = 2'b01;
localparam BFIRST_STATE = 2'b10;

reg [1:0] stateMachine;
reg       c;

always @ (posedge fastClock or posedge reset) begin
    if (reset) begin
        stateMachine <= IDLE_STATE;
        c            <= 1'b0;
    end else begin
        case (stateMachine) begin
            IDLE_STATE: begin //Wait for the start of an event sequence.
                //If the start of a sequnece
                if (bRise && aFall) begin
                    //If both happen at the same time
                    c               <= 1'b1;            //C goes high immediately.
                end else if (aFall) begin
                    //If falling edge of a comes first
                    c               <= 1'b0;            //C stays low.
                    stateMachine    <= AFIRST_STATE;    //And go on to wait for b rising.
                end else if (bRise) begin
                    //If rising edge of b comes first
                    c               <= 1'b0;            //C stays low.
                    stateMachine    <= BFIRST_STATE;    //And go on to wait for a falling.
                end else if (someEvent) begin
                    //Work out when C should go low - I can't tell this from your description
                    c               <= 1'b0;            //C goes low.
                end
            end
            AFIRST_STATE: begin //Wait for rising edge of b
                if (bRise) begin
                    //Once rising edge of b occurs,
                    c               <= 1'b1;            //C goes high.
                    stateMachine    <= IDLE_STATE ;     //Return to idle.
                end
            end
            BFIRST_STATE: begin //Wait for falling edge of a
                if (aFall) begin
                    //Once rising edge of b occurs,
                    c               <= 1'b1;            //C goes high.
                    stateMachine    <= IDLE_STATE ;     //Return to idle.
                end
            end
        endcase
    end
end

You will need to work out what logic to use to determine when C should go low. I can't tell this from your question.

If you want a fixed width, you could use a counter which is triggered when C goes high.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks. To make the problem easier, let change the condition C goes low when signal B goes low. That doesn't make fixed width but it is OK now. \$\endgroup\$ Commented Jan 8, 2018 at 6:46
  • \$\begingroup\$ @anhnha in which case add a falling edge detector for the B signal (bFall) and use that signal as 'someEvent'. \$\endgroup\$ Commented Jan 8, 2018 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.