1
\$\begingroup\$

I'm used to writing the following process that will react on the rising edge of the CLK (script 1):

X: PROCESS(CLK)
BEGIN
    IF RISING_EDGE(CLK) THEN OUTPUT <= CLK AND VAR;
    ELSE NULL;
    END IF;
END PROCESS X;

Now I need the process to react on both rising and falling edges of CLK, so according to the device datasheet I wrote this (script 2):

X: PROCESS(CLK)
   BEGIN
        IF (CLK'EVENT) THEN OUTPUT <= CLK AND VAR;
        ELSE NULL;
        END IF;
END PROCESS X;

Both cases fit and can be programmed on the device. But it seems like the second case does not really work: the OUTPUT does not change.

I need the OUTPUT to be updated on both edges of the CLK. Would it be functionally equivalent to script 2 if I rewrite the process as the following (script 3)? In other words, do I have to put IF condition, or the process reacts on the rising/falling edge of the CLK regardless?

X: PROCESS(CLK)
   BEGIN
      OUTPUT <= CLK AND VAR;
END PROCESS X;

EDIT: With script 2 I get the warning that the signal VAR is missing from the sensitivity list. However, I need the OUTPUT to change only with CLK, but be dependent on VAR value.

With Script 4 (below), which I would expect to be equivalent to script 2, the warning is different: WARNING:Xst:2110 - Clock of register OUTPUT seems to be also used in the data or control logic of that element.

X: PROCESS(CLK)
   BEGIN
       IF (CLK'EVENT) THEN
           IF CLK = '1' THEN OUTPUT <= ('1' AND VAR);
           ELSE OUTPUT <= '0';
           END IF;
       ELSE NULL;
       END IF;
END PROCESS X;

Here's the fitter report with relevant vars(NICLK is for OUTPUT and SampEn is for VAR):

enter image description here

\$\endgroup\$
10
  • 1
    \$\begingroup\$ The problem with VHDL is the synthesis algorithm might only be able to recognise specific sequences of commands when it comes to defining clocks, single flip-flops and some other structures. The IDE's documentation could help. This is also manufacturer specific. \$\endgroup\$
    – Evan
    Jul 17, 2014 at 1:42
  • \$\begingroup\$ I use Xilinx ISE webpack and a CoolRunner. The manual on page 2 for the family provides VHDL example for dual-edged trigger. I wrote the script 2 according to the example. So, the IDE, the CPLD, and the documentation is of Xilinx. And it used to work before. Could I change something in some settings that would make it not to work? I believe, I did not change anything in the source. \$\endgroup\$
    – Nazar
    Jul 17, 2014 at 14:39
  • \$\begingroup\$ Have you checked the synthesis results? \$\endgroup\$
    – Philippe
    Jul 17, 2014 at 17:09
  • \$\begingroup\$ @Philippe what should I look for in the synthesis results? \$\endgroup\$
    – Nazar
    Jul 17, 2014 at 18:03
  • \$\begingroup\$ "With Script 4 (below)...". The VHDL parlance is process statement, while yes technically it can contain a script "noun - Computing an automated series of instructions carried out in a specific order", a process statement can also have a sensitivity list, a process declarative part and begin and end reserved words surrounding a process statement part. It's the process statement part that can contain a 'script' (or just a single sequential statement). \$\endgroup\$
    – user8352
    Jul 17, 2014 at 19:37

2 Answers 2

2
\$\begingroup\$

A concurrent signal assignment statement of the form:

OUTPUT <= CLK AND VAR;

Has an equivalent process (how it's simulated) of the form:

process
begin
   OUTPUT <= CLK AND VAR;
   wait on CLK, VAR;  -- wait on 'sensitivity list'
end process;

With the wait statement the equivalent of putting both right hand side signals in a sensitivity list.

The second process is already sensitive to CLK events, the if CLK'EVENT is redundant. I'd suggest that your synthesis tool should likely have generated a warning and may have not produced an assignment to OUTPUT, something examining synthesis warnings, any produced net list or generated schematic might indicate. Otherwise the second and third processes are equivalent.

You're likely to get warning for both the second and third process statements that VAR is missing from the sensitivity list, which is likely ignored for synthesis purposes. The effect of this is not have closure between simulation results pre- and post-synthesis.

Note that what you've defined is a gated clock and having VAR in the sensitivity list won't matter unless VAR transitions before the rising edge of CLK or after the falling edge of CLK, in which case it could move the OUTPUT clock edge (if OUTPUT'EVENT and OUTPUT = '1', if rising_edge(OUTPUT), or the same for the falling edge).

And if VAR could screw up your resulting 'clock' edge you have a problem that should be addressed anyway.

(And of course someone is bound to chime in that a sensitivity list can use the reserved word all to signify all right hand side signals in VHDL-2008).

addendum

The questioner has indicated he's trying to gate clocks, and from added information to his question shows this is using Xilinx tools.

Xilinx recommends against gating clocks this way [1], the most obvious reason is that clock skew becomes dependent on routing to and from a LUT as well as the the LUT delay itself. You could imagine trying to balance delays in all your clocks. With clocks generated from a higher clock rate you could for instance disable a clock with a clear or reset. The idea here is match delays on gated and non gated clocks as an FPGA implementation issue above and beyond all the measures you'd take to cross clock boundaries otherwise.

Xilinx supports gated clocks in series 7 FPGAs and ZYNQ devices using dedicated clock enables through the use of the paid version of ISE (Vivaldo), something called intelligent clock gating, where you don't gate your clocks, you let the tools do it for you.

You could also note the period constraint is lost passing through an non-sequential element manually gating clocks.


[1] White Paper: HDL Coding Practices to Accelerate Design Performance, around Figure 11. Starting on Page 10, Clock Enable and Gated Clocks.

\$\endgroup\$
9
  • \$\begingroup\$ I am using ISE WebPack and a CoolRunnerII CPLD. The OUTPUT is intended to be a duplicate of the CLK, but it should be 'on' only when VAR is high (the period of hi/low for VAR is much grater than for CLK). Thus, VAR serves as a switch to turn on the OUTPUT clock. You are right about everything you stated above. But this thing worked before. But now it does not. The process 2 was written according to p.2 of the manual. VAR is not synchronized with CLK. How should I rewrite the process to achieve the described function? \$\endgroup\$
    – Nazar
    Jul 17, 2014 at 14:08
  • \$\begingroup\$ Here's the warning: 'WARNING:Xst:819 - "D:/Projects/Xilinx/S11639/main.vhd" line 246: One or more signals are missing in the process sensitivity list. To enable synthesis of FPGA/CPLD hardware, XST will assume that all necessary signals are present in the sensitivity list. Please note that the result of the synthesis may differ from the initial design specification. The missing signals are: <VAR> '. But I do not need VAR to be on the sensitivity list. It happens asynchronously with CLK. \$\endgroup\$
    – Nazar
    Jul 17, 2014 at 14:46
  • \$\begingroup\$ Gating a clock with an asynchronous signal can be a recipe for a disaster unless you can guarantee it doesn't change state (you're using it to turn off circuitry). And if you are using it that way, it doesn't hurt to have it in the sensitivity list, it will just never occur. If it ever changes you need to consider the effects of violating the clock minimum pulse width or changes in edge position. You could synchronize the signal to the clock with two successive collocated flip flops run off the clock while having a reset hold over of the same duration. \$\endgroup\$
    – user8352
    Jul 17, 2014 at 19:19
  • \$\begingroup\$ Not having VAR in the sensitivity list is one of those things that can cause a difference between simulation and synthesis results. Your simulation can run fine, you can still get abnormalities on the gated clock in silicon. You've treated VAR like it is synchronous to the clock, just as if you had passed it through two flip flops to filter out metastability events. \$\endgroup\$
    – user8352
    Jul 17, 2014 at 19:57
  • \$\begingroup\$ Still can not understand it. Again, the goal is to duplicate the CLK in the OUTPUT. Thus, OUTPUT is the same as CLK, except it is not active when VAR is low. Because VAR is not synchronized with CLK, I can not simply write OUTPUT <= CLK AND VAR (outside the process), because the OUTPUT duty cycle will not be 50/50% at VAR transitions. So, I need the OUTPUT only change on CLK events, but be ANDed with VAR. Could you, please, give me an example on how to implement it? \$\endgroup\$
    – Nazar
    Jul 17, 2014 at 20:11
0
\$\begingroup\$

The common way to do clock gating for an output clock is to use a DDR output buffer, with the data_h signal connected to the gate signal and data_l connected to '0', and the clock connected normally.

The main reason for that is that the LEs do not really have adequate circuitry for this task. The FFs in the LEs can only update on the rising edge of a clock, and the LUTs cannot hold state without a latch, which has some stability issues.

Internally, you could create the signal you want from within a LUT if you have a shifted clock (e.g. 90 degrees), but the output would need to be shunted over to a clock network to be useful, and it would be too jittery to be a good clock.

So if you need a gated clock internally, you'd transmit the "enable" signal along with the clock, and synthesis would feed those into the "enable" input of the affected FFs.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.