8 Replies Latest reply on May 21, 2011 1:48 AM by user_62720120

    Recognising time between two rising edges

    user_62720120

      Hi all,

         

      I need to wire up something using timers and counters with the following behaviour:

         

      * Output goes low if the input sees two rising edges occur 20us or less apart.

         

      * Output goes high on any other input edge.

         

       

         

      Can anyone suggest how I might do this?

         

      Many thanks in advance.

         

      Hugo Elias

        • 1. Re: Recognising time between two rising edges
          user_62720120

          Here's a waveform showing what I mean.

             

          Hugo

          • 2. Re: Recognising time between two rising edges
            udayan.umapathi
                  
            • This can be achieved using the Timer component. Use the UDB implementation of the timer component. Set the input clock to the component to be 12 Mhz. Configure the parameters as shown in the picture attached(Timer_20us_Capture,bmp). 
            •     
            • Input Clock of 12 Mhz with a period value of 240 gives rise to a period of 20us. At the end of period a pule is generated on the terminal count , TC terminal appearing at the timer output.
            •     
            • Set the Trigger and Capture mode parameters to Rising Edge. Connect the trigger and Capture terminal on the component input side to the input signal being monitored. Configuring the trigger mode for rising edge makes the timer component start its down count on the first rising edge appearing on trigger input terminal. The same rising edge is also tied to the Capture input terminal. Now if another edge occurs before 20us elapses, a capture event occurs and a pulse appears at the capture out terminal of timer. Since we know that the timer was started and the capture event occured before 20us this can be used to take necessary action(output goes low). This can be achieved by connecting an ISR to the capture terminal.
            •     
            • If the second rising edge does not occur in 20us, then the timer elapses and the terminal count pulses appears(exactly 20us after the first pulse appeared). An ISR component can be connected to the terminal count set the output high.In the ISR stop the timer and start using APIs and the process repeats.
            •    
               

            This is one of the way i can think about implementing this. It requires very little software overhead.

            • 3. Re: Recognising time between two rising edges
              user_62720120

              Thanks for the suggestion. Ideally, I'd like to do it entirely in hardware.  I can't figure out how to do it by adding descrete logic, so I'l learning Verilog.

                 

              Is there somewhere people can post their own created components so others can share them?

                 

              Hugo

              • 4. Re: Recognising time between two rising edges
                udayan.umapathi

                Currently we do not have any place where we are sharing components. However there are App Notes that describe some prominent components that has been created. Also note many of the components in the component catalog in PSoC Crestor are built using Verilog. We will consider your suggestion and see what best cypress can do about this.

                • 5. Re: Recognising time between two rising edges
                  user_62720120

                  OK, so I'm trying to write this in Verilog now. But, since it's my first ever Verilog code, I'm finding it quite confusing.  What I imagine would work is this, but it fails to compile:

                     

                   

                     

                  module DoubleEdge (
                      Counter,
                      Q,
                      C,
                      D,
                      R
                  );
                      output [4:0] Counter;    // Used for timing
                      output  Q;                      //
                      input   C;                       // Clock input
                      input   D;                       // The edges to detect
                      input   R;                       // Reset the module

                  //`#start body` -- edit after this line, do not edit this line

                      reg     [4:0] Counter;
                      reg        Q;
                      reg        T;
                   

                     

                  always @(posedge R)

                     

                  begin

                     

                      Counter <= 20;

                     

                      Q <= 1;

                     

                  end

                     

                   

                     

                  always @(posedge C)

                     

                  begin

                     

                      if (Counter) Counter <= Counter - 1;

                     

                  end

                     

                   

                     

                  always @(posedge D)

                     

                  begin

                     

                      if (Counter) Q <= 0;

                     

                      else Counter <= 20;

                     

                  end

                     

                   

                     

                  always @(negedge D)

                     

                  begin

                     

                      Q <= 1;

                     

                  end

                     
                     

                  endmodule
                   

                  • 6. Re: Recognising time between two rising edges
                    user_62720120

                    Here's another attempt, which still doesn't seem to work. The counter LEDs just go crazy.

                       

                     

                       

                    module DoubleEdge (
                        Counter,
                        Q,
                        C,
                        D,
                        R
                    );
                        output [4:0] Counter;
                        output  Q;
                        input   C;
                        input   D;
                        input   R;

                    //`#start body` -- edit after this line, do not edit this line

                        reg     [4:0] Counter;
                        reg        Q;
                        reg        T;
                       

                    always @(C)
                    begin

                        if (C) begin            // Clock rising edge
                       
                            if (D & !T) begin    // Data rising edge
                                if (Counter) Q <= 0;
                                Counter <= 20;
                            end else begin

                                if (R) Counter <= 20;
                            end
                           
                            if (!D & T) Q <= 1;       
                       
                        end    else begin                // Clock falling edge
                       
                            if (Counter) Counter <= Counter - 1;
                            T  <= D;
                        end
                       
                    end
                    endmodule

                    • 7. Re: Recognising time between two rising edges
                      udayan.umapathi

                      Let me understand your requrement completely. If after the first rising edge,  what if a falling edge comes. Should the output go high or should the edge be  ignored.

                      • 8. Re: Recognising time between two rising edges
                        user_62720120

                        After lots of trial and error, and with some help from the edaforum, I was able to write it in Verilog:

                           

                         

                           

                        [CODE]

                           

                        module CS_Detect (
                            CS,
                            CLK,
                            EDGES
                        );
                            output  CS;
                            input   CLK;
                            input   EDGES;

                        //`#start body` -- edit after this line, do not edit this line

                            reg [1:0] edges_reg;
                            reg [3:0] Counter;
                            reg CS;

                          
                        wire  pos_pulse =  edges_reg[0] & !edges_reg[1];
                        wire  neg_pulse = !edges_reg[0] &  edges_reg[1];

                        always @(posedge CLK)
                        begin

                            edges_reg[0] <= EDGES;
                            edges_reg[1] <= edges_reg[0];
                         
                            //edges_reg <= EDGES;
                            if (pos_pulse == 1) begin
                                Counter <= 15;
                            end else begin
                                if (Counter > 0) Counter <= Counter - 1;
                            end
                        end

                        always @(posedge CLK)
                        begin
                            if ((pos_pulse == 1) && (Counter > 0)) begin
                                CS <= 0;
                            end else begin
                                if (neg_pulse == 1) begin
                                    CS <= 1;
                                end
                            end
                        end

                        //`#end` -- edit above this line, do not edit this line
                        endmodule

                           

                        [/CODE]

                           

                         

                           

                        Many thanks

                           

                        Hugo