5
\$\begingroup\$

I have a clock coming from a pin (GMI_CLK). It passes through a PLL and a new clock with 4 times the frequency is generated (Sys_CLK). Now I need a pulse each time a rising edge of the original clock is detected (Sys_valid). enter image description here

This works perfect in the simulation. It has been coded as followed, but both ways generate errors during synthesis:

make_clkvalid: process(sys_clk)
    variable GMI_CLK_alt : std_logic;
begin
    if rising_edge(sys_clk) then
        if GMI_CLK = '1' and GMI_CLK_alt = '0' then
            Sys_valid <= '1';
        else
            Sys_valid <= '0';
        end if;

        GMI_CLK_alt := GMI_CLK;

    end if;
end process make_clkvalid;

[Synth 8-5535] port has illegal connections. It is illegal to have a port connected to an input buffer and other components. The following are the port connections : Input Buffer: Port I of instance clkin1_ibufg(IBUF) in module Other Components: Port I1 of instance i_43(LUT2) in module GMI_IO Port I1 of instance i_42(LUT2) in module GMI_IO Port D of instance GMI_CLK_alt_reg__0(FD) in module GMI_IO Port D of instance GMI_CLK_alt_reg(FD_1) in module GMI_IO


or like this:

make_clkvalid: process(GMI_CLK, Sys_clk)
begin
    if rising_edge(GMI_CLK) then
        Sys_valid <= '1';
    elsif falling_edge(Sys_clk) then 
        Sys_valid <= '0';
    end if;
end process make_clkvalid;

[Synth 8-27] else clause after check for clock not supported [GMI_IO.vhd":183]


How can I implement it for synthesis?

\$\endgroup\$
2
  • \$\begingroup\$ You will need to include more code to diagnose the first error, which is not directly related to the code you posted. \$\endgroup\$
    – scary_jeff
    Dec 8, 2015 at 13:07
  • 1
    \$\begingroup\$ OK, I think I know why you got the first message. Hopefully my updated answer solves it for you. \$\endgroup\$
    – scary_jeff
    Dec 8, 2015 at 13:50

1 Answer 1

6
\$\begingroup\$

Your second implementation fails because of what is a common mistake. The code pattern:

if rising_edge(clk_a) then
    signal_a <= '1';
elsif falling_edge(clk_b) then 
    signal_a <= '0';
end if;

Cannot be realised in hardware, because it describes a 1-bit register with two different clock inputs. Such a register does not exist in the FPGA fabric; the closest is a DDR output register which may be present, but even this is intended to be used with a clock and its inverse, not two totally separate clocks.

The first attempt looks more sensible. If you could include the error message that it generates, I will update my answer.


Now that you added the error message, I can see that this has nothing to do with the code snippet you posted. Although the relevant code has not been provided, I think the error here is that you have your GMI clock input connected to an IBUFG, and also to the logic in this module.

The most likely cause of this is that you have created your PLL code using CoreGen. CoreGen will needlessly place a global clock buffer between a clock input pin and a PLL/DCM instance. The result is that when you connect this same pin to something else (i.e. your edge detection circuit), the design cannot be routed because of the structure of the FPGA.

To solve this, all you have to do is remove the BUFG instantiation from the .VHD file that CoreGen created, and then connect what was the input to the BUFG, to the input of the PLL/DCM instance. Synthesis will insert a clock buffer in the appropriate place to allow your design to work.

Per the comment by @TomCarpenter, if the above solves your problem, there is an option in CoreGen to set the input buffer to "None". This avoids modifying the CoreGen output, which could catch someone out later on.

Even better would be to not use CoreGen for something as simple as instantiating a PLL; If you go to Edit > Language Templates > VHDL > Device Primitive Instantiation > Spartan 6 (or whatever) > Clock Components in ISE (it's under Window > Language Templates > etc in Vivado), you can find simple templates for instantiating your PLL, without the hassle / problems of CoreGen (such as the problem that you have seen).

\$\endgroup\$
4
  • \$\begingroup\$ I'm pretty sure the CoreGen for the PLL has options for what the outputs connect to, the default is I believe BUFG. It should be possible to change this to remove the BUFG rather than editing the HDL directly. \$\endgroup\$ Dec 8, 2015 at 14:34
  • \$\begingroup\$ @TomCarpenter I've never run the CoreGen in question, but the issue is that it, at least by default, it inserts a BUFG on the input signal to the PLL. \$\endgroup\$
    – scary_jeff
    Dec 8, 2015 at 15:36
  • 2
    \$\begingroup\$ Just checked, you can select both the input and output buffer types. For inputs the options are: "single-ended input", "differential input", "global buffer (BUFG)", and "No buffer". The final option should remove the BUFG instance. \$\endgroup\$ Dec 8, 2015 at 15:43
  • \$\begingroup\$ Good to know for the next time. Now it works with the template. \$\endgroup\$
    – Botnic
    Dec 8, 2015 at 15:47

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.