9

Design requires a signal to be activated at specific circumstance on rising edge of the clock, and deactivated at another circumstance on falling edge of clock. Here's what I think:

always@(posedge CLK) begin
  signal1 <= 1'b0; // reset flag
  if(circumstance1) signal1 <=1'b1; // raise flag if circumstance occurs
end

always@(negedge CLK) begin
  signal2 <= 1'b1; // reset flag (actually set alternate to signal1)
  if(circumstance2) signal2 <=1'b0; // raise flag if circumstance occurs
end

always@(posedge signal1 or negedge signal2) begin
  if(signal1) outsignal <= 1'b0;   // activate outsignal
  else outsignal <= 1'n1;   // deactivate outsignal
end

Will that work? Are there better alternatives (doubling clock and catching single edge is not an option here).

Edit after Russell's reply. Russell, I think you propose the following:

wire nCLK = ~CLK;

always@(posedge CLK or posedge nCLK or negedge nRESET) begin
    if(!nRESET) outsignal <= 1'b0;
    else if(nCLK) outsignal <= 1'b1;
         else outsignal <= 1'b0;
end

did I understand you properly?

Anonymous
  • 561
  • 3
  • 7
  • 24

2 Answers2

6

You need so called "Dual Edge Flip-Flop" (DEFF). Although some vendors offer DEFFs as primitives on their CPLD/FPGA, most products haven't them. In this case you need to implement DEFF yourself. Unfortunately, the code in your post always@(posedge CLK or posedge nCLK or negedge nRESET) won't work because standard flip-flops have not more than two inputs with single edge events. So the solution must use standard flip-flops with additional combinational circuits. The circuit in the picture solves this. It guarantees glitchless operation since output XOR element has no more than single input transition on each state change.

DEFF schematics

Here is verified and used in our projects Verilog code that implements this DEFF:

module DEFF (
  input clock, reset, in,
  output out
);

  reg trig1, trig2;

  assign out = trig1^trig2;

  always @(posedge clock, posedge reset) begin
    if (reset)  trig1 <= 0;
    else  trig1 <= in^trig2;
  end

  always @(negedge clock, posedge reset) begin
    if (reset)  trig2 <= 0;
    else  trig2 <= in^trig1;
  end
endmodule
Serge Goncharov
  • 488
  • 1
  • 6
  • 13
  • 1
    Someone told me that `In an FPGA these blocks might not be arranged as neatly as that diagram is showing. Delays from LUT and routing might create an output signal that contains glitches.`. What do you think ? – kevin998x Feb 24 '21 at 03:59
  • 2
    The code above is tested by me and used in Altera FPGA in different projects. There are two kinds of problems are possible: metastability issues, when data input is changed simultaneously with clock signal, and timing, when the path is too long or clock frequency is too high. But both of these potential problems are NOT specific to this module and may arise in other circuits too. I didn't test this in Xilinx or other FPGAs, may be other compilers produce mess in some circumstances. There are no double transitions in any component, so there won't be glitches with adequate speed. – Serge Goncharov Feb 25 '21 at 12:57
  • What do you think about [this circuit from a US patent](https://i.imgur.com/ZnBuofE.png) ? – kevin998x Feb 25 '21 at 13:50
  • Is this your own diagram? If so, may I use it with your permission on Wikipedia. – Raleigh L. Dec 22 '22 at 08:33
  • @RaleighL. No, this diagram is not mine. I don't remember where did I get this link from, but it is quite easy to reproduce it using any graphic editor. – Serge Goncharov Dec 30 '22 at 16:23
3

Is this an off-chip signal? If so, Xilinx and other chip vendors offer primitives that can help you with this. If you wire up an ODDR2 primitive you might have better luck. Invert the clock. Drive the normal clock into C0 and they inverted clock into C1. Then use your logic to set the D0 and D1 inputs.

The way you wrote above is not a very robust solution.

Try using fabric primitives to accomplish this task.

Russell
  • 3,384
  • 4
  • 31
  • 45
  • Yes, it is external signal. No, not DDR. I need to acheve specific timing with several output signals which is (timing) tied to both edges. – Anonymous Oct 26 '13 at 17:43
  • 5
    What you're describing *is* double data-rate, or DDR, signalling - even if it isn't being used to communicate with DDR memory. –  Oct 27 '13 at 05:43
  • What vendor and part are you using? You need to explicitly define a DDR primitive. – Russell Oct 27 '13 at 15:09
  • Circuit is not allowed to have any hiccups in the signal transitions. I do not think muxed DDR circuit will be suitable. I am considering to source another higher freq clock to detect posedge and negedge of CLK in single always block (and it will resolve the issue with multiple drivers) – Anonymous Oct 27 '13 at 17:19