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\$
  • \$\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\$ – Tom Carpenter Jan 7 '18 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\$ – Tom Carpenter Jan 7 '18 at 13:40
  • \$\begingroup\$ Are the signal edges assumed to be clean? (i.e. no bounce, spurious pulses, etc.) \$\endgroup\$ – Tom Carpenter Jan 7 '18 at 13:42
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\$
  • \$\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\$ – anhnha Jan 8 '18 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\$ – Tom Carpenter Jan 8 '18 at 7:43

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.