Search code examples
vhdlxilinxxilinx-ise

New DCM CLK instantiation error?


here's the code within the .xco file which was branched off my main vhdl file:

-- The following code must appear in the VHDL architecture header:
------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG
component DCM_18
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;

-- COMP_TAG_END ------ End COMPONENT Declaration ------------
-- The following code must appear in the VHDL architecture
-- body. Substitute your own instance name and net names.
------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG
your_instance_name : DCM_18
  port map
   (-- Clock in ports
    CLK_IN1 => CLK_IN1,
    -- Clock out ports
    CLK_OUT1 => CLK_OUT1);
-- INST_TAG_END ------ End INSTANTIATION Template ------------

the goal was to produce a 18.432 MHz clk from a 50 MHz clock. Here's the code I added to my main vhdl file:

clk: in std_logic;                         -- 50 MHz clock

signal test_clk: std_logic; -- new 18.432 MHz clock
-----------------------------------------------------


component DCM_18
port
(-- Clock in ports
    CLK_IN1           : in     std_logic;
    -- Clock out ports
    CLK_OUT1          : out    std_logic
);
end component;

-------------------------------------------------

new_CLK : DCM_18
 port map
 (-- Clock in ports                      
 CLK_IN1 => clk,
   -- Clock out ports
 CLK_OUT1 => test_clk
 );

However, I am recieving this error:

ERROR:Xst:2035 - Port has illegal connections. This port is connected to an input buffer and other components.

Any ideas?

EDIT: COMPLETE CODE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.math_real.all;

entity basic_uart is
  generic (
    DIVISOR: natural := 120 -- DIVISOR = 50,000,000 / (16 x BAUD_RATE)
    -- 9600 -> 120
     -- 19200 -> 60
  );
  port (
    clk: in std_logic;                         -- clock
    reset: in std_logic;                       -- reset

    -- Client interface
    rx_data: out std_logic_vector(7 downto 0); -- received byte
    rx_enable: out std_logic;                  -- validates received byte (1 system clock spike)
    tx_data: in std_logic_vector(7 downto 0);  -- byte to send
    tx_enable: in std_logic;                   -- validates byte to send if tx_ready is '1'
    tx_ready: out std_logic;                   -- if '1', we can send a new byte, otherwise we won't take it

    -- Physical interface
    rx: in std_logic;
    tx: out std_logic
  );
end basic_uart;

architecture Behavioral of basic_uart is

    component DCM_18
    port
    (-- Clock in ports
        CLK_IN1           : in     std_logic;
        -- Clock out ports
        CLK_OUT1          : out    std_logic
    );
    end component;

  constant COUNTER_BITS : natural := integer(ceil(log2(real(DIVISOR))));

  type fsm_state_t is (idle, active); -- common to both RX and TX FSM

  type rx_state_t is
  record
    fsm_state: fsm_state_t;                -- FSM state
    counter: std_logic_vector(3 downto 0); -- tick count
    bits: std_logic_vector(7 downto 0);    -- received bits
    nbits: std_logic_vector(3 downto 0);   -- number of received bits (includes start bit)
    enable: std_logic;                     -- signal we received a new byte
  end record;

  type tx_state_t is
  record
    fsm_state: fsm_state_t; -- FSM state
    counter: std_logic_vector(3 downto 0); -- tick count
    bits: std_logic_vector(8 downto 0); -- bits to emit, includes start bit
    nbits: std_logic_vector(3 downto 0); -- number of bits left to send
    ready: std_logic; -- signal we are accepting a new byte
  end record;

  signal rx_state,rx_state_next: rx_state_t;
  signal tx_state,tx_state_next: tx_state_t;

  signal sample, test_clk: std_logic; -- 1 clk spike at 16x baud rate
  signal sample_counter: std_logic_vector(COUNTER_BITS - 1 downto 0); -- should fit values in 0..DIVISOR-1

begin

new_CLK : DCM_18
  port map
   (-- Clock in ports
    --CLK_IN1 => clk,
     CLK_IN1 => clk,
    -- Clock out ports
    CLK_OUT1 => test_clk
    );

  -- sample signal at 16x baud rate, 1 CLK spikes
  sample_process: process (clk,reset) is
  begin
    if reset = '1' then
      sample_counter <= (others => '0');
      sample <= '0';
    elsif rising_edge(clk) then
      if sample_counter = DIVISOR - 1 then
        sample <= '1';
        sample_counter <= (others => '0');
      else
        sample <= '0';
        sample_counter <= sample_counter + 1;
      end if;
    end if;
  end process;

  -- RX, TX state registers update at each CLK, and RESET
  reg_process: process (clk,reset) is
  begin
    if reset = '1' then
      rx_state.fsm_state <= idle;
      rx_state.bits <= (others => '0');
      rx_state.nbits <= (others => '0');
      rx_state.enable <= '0';

      tx_state.fsm_state <= idle;
      tx_state.bits <= (others => '1');
      tx_state.nbits <= (others => '0');
      tx_state.ready <= '1';

    elsif rising_edge(clk) then
      rx_state <= rx_state_next;
      tx_state <= tx_state_next;

    end if;
  end process;

  -- RX FSM
  rx_process: process (rx_state,sample,rx) is
  begin
    case rx_state.fsm_state is

    when idle =>
      rx_state_next.counter <= (others => '0');
      rx_state_next.bits <= (others => '0');
      rx_state_next.nbits <= (others => '0');
      rx_state_next.enable <= '0';
      if rx = '0' then
        -- start a new byte
        rx_state_next.fsm_state <= active;
      else
        -- keep idle
        rx_state_next.fsm_state <= idle;
      end if;

    when active =>
      rx_state_next <= rx_state;
      if sample = '1' then
        if rx_state.counter = 8 then
          -- sample next RX bit (at the middle of the counter cycle)
          if rx_state.nbits = 9 then
            rx_state_next.fsm_state <= idle; -- back to idle state to wait for next start bit
            rx_state_next.enable <= rx; -- OK if stop bit is '1'
          else
            rx_state_next.bits <= rx & rx_state.bits(7 downto 1);
            rx_state_next.nbits <= rx_state.nbits + 1;
          end if;
        end if;

        rx_state_next.counter <= rx_state.counter + 1;
      end if;

    end case;
  end process;

  -- RX output
  rx_output: process (rx_state) is
  begin
    rx_enable <= rx_state.enable;
    rx_data <= rx_state.bits;
  end process;

  -- TX FSM
  tx_process: process (tx_state,sample,tx_enable,tx_data) is
  begin
    case tx_state.fsm_state is

    when idle =>
      if tx_enable = '1' then
        -- start a new bit
        tx_state_next.bits <= tx_data & '0';  -- data & start
        tx_state_next.nbits <= "0000" + 10; -- send 10 bits (includes '1' stop bit)
        tx_state_next.counter <= (others => '0');
        tx_state_next.fsm_state <= active;
        tx_state_next.ready <= '0';
      else
        -- keep idle
        tx_state_next.bits <= (others => '1');
        tx_state_next.nbits <= (others => '0');
        tx_state_next.counter <= (others => '0');
        tx_state_next.fsm_state <= idle;
        tx_state_next.ready <= '1';
      end if;

    when active =>
      tx_state_next <= tx_state;
      if sample = '1' then
        if tx_state.counter = 15 then
          -- send next bit
          if tx_state.nbits = 0 then
            -- turn idle
            tx_state_next.bits <= (others => '1');
            tx_state_next.nbits <= (others => '0');
            tx_state_next.counter <= (others => '0');
            tx_state_next.fsm_state <= idle;
            tx_state_next.ready <= '1';
          else
            tx_state_next.bits <= '1' & tx_state.bits(8 downto 1);
            tx_state_next.nbits <= tx_state.nbits - 1;
          end if;
        end if;
        tx_state_next.counter <= tx_state.counter + 1;
      end if;

    end case;
  end process;

  -- TX output
  tx_output: process (tx_state) is
  begin
    tx_ready <= tx_state.ready;
    tx <= tx_state.bits(0);
  end process;

end Behavioral;

EDIT: .XCO file code

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;

library unisim;
use unisim.vcomponents.all;

entity DCM_18 is
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end DCM_18;

architecture xilinx of DCM_18 is
  attribute CORE_GENERATION_INFO : string;
  attribute CORE_GENERATION_INFO of xilinx : architecture is "DCM_18,clk_wiz_v3_6,{component_name=DCM_18,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=PLL_BASE,num_out_clk=1,clkin1_period=20.000,clkin2_period=20.000,use_power_down=false,use_reset=false,use_locked=false,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=AUTO,manual_override=false}";
  -- Input clock buffering / unused connectors
  signal clkin1      : std_logic;
  -- Output clock buffering / unused connectors
  signal clkfbout         : std_logic;
  signal clkfbout_buf     : std_logic;
  signal clkout0          : std_logic;
  signal clkout1_unused   : std_logic;
  signal clkout2_unused   : std_logic;
  signal clkout3_unused   : std_logic;
  signal clkout4_unused   : std_logic;
  signal clkout5_unused   : std_logic;
  -- Unused status signals
  signal locked_unused    : std_logic;

begin


  -- Input buffering
  --------------------------------------
  clkin1_buf : IBUFG
  port map
   (O => clkin1,
    I => CLK_IN1);


  -- Clocking primitive
  --------------------------------------
  -- Instantiation of the PLL primitive
  --    * Unused inputs are tied off
  --    * Unused outputs are labeled unused

  pll_base_inst : PLL_BASE
  generic map
   (BANDWIDTH            => "OPTIMIZED",
    CLK_FEEDBACK         => "CLKFBOUT",
    COMPENSATION         => "SYSTEM_SYNCHRONOUS",
    DIVCLK_DIVIDE        => 1,
    CLKFBOUT_MULT        => 14,
    CLKFBOUT_PHASE       => 0.000,
    CLKOUT0_DIVIDE       => 38,
    CLKOUT0_PHASE        => 0.000,
    CLKOUT0_DUTY_CYCLE   => 0.500,
    CLKIN_PERIOD         => 20.000,
    REF_JITTER           => 0.010)
  port map
    -- Output clocks
   (CLKFBOUT            => clkfbout,
    CLKOUT0             => clkout0,
    CLKOUT1             => clkout1_unused,
    CLKOUT2             => clkout2_unused,
    CLKOUT3             => clkout3_unused,
    CLKOUT4             => clkout4_unused,
    CLKOUT5             => clkout5_unused,
    LOCKED              => locked_unused,
    RST                 => '0',
    -- Input clock control
    CLKFBIN             => clkfbout_buf,
    CLKIN               => clkin1);

  -- Output buffering
  -------------------------------------
  clkf_buf : BUFG
  port map
   (O => clkfbout_buf,
    I => clkfbout);


  clkout1_buf : BUFG
  port map
   (O   => CLK_OUT1,
    I   => clkout0);



end xilinx;

EDIT (NEW CLK instantiation): creating a 18.4 MHz CLK from a 50 MHz CLK

-- <-----Cut code below this line and paste into the architecture body---->

   -- DCM_CLKGEN: Frequency Aligned Digital Clock Manager
   --             Spartan-6
   -- Xilinx HDL Language Template, version 14.7

   DCM_CLKGEN_inst : DCM_CLKGEN
   generic map (
      CLKFXDV_DIVIDE => 2,       -- CLKFXDV divide value (2, 4, 8, 16, 32)
      CLKFX_DIVIDE => 38,         -- Divide value - D - (1-256)
      CLKFX_MD_MAX => 0.0,       -- Specify maximum M/D ratio for timing anlysis
      CLKFX_MULTIPLY => 14,       -- Multiply value - M - (2-256)
      CLKIN_PERIOD => 20.0,       -- Input clock period specified in nS
      SPREAD_SPECTRUM => "NONE", -- Spread Spectrum mode "NONE", "CENTER_LOW_SPREAD", "CENTER_HIGH_SPREAD",
                                 -- "VIDEO_LINK_M0", "VIDEO_LINK_M1" or "VIDEO_LINK_M2" 
      STARTUP_WAIT => FALSE      -- Delay config DONE until DCM_CLKGEN LOCKED (TRUE/FALSE)
   )
   port map (
      CLKFX => new_CLK,         -- 1-bit output: Generated clock output
      CLKFX180 => OPEN,   -- 1-bit output: Generated clock output 180 degree out of phase from CLKFX.
      CLKFXDV => OPEN,     -- 1-bit output: Divided clock output
      LOCKED => OPEN,       -- 1-bit output: Locked output
      PROGDONE => OPEN,   -- 1-bit output: Active high output to indicate the successful re-programming
      STATUS => OPEN,       -- 2-bit output: DCM_CLKGEN status
      CLKIN => CLK,         -- 1-bit input: Input clock
      FREEZEDCM => OPEN, -- 1-bit input: Prevents frequency adjustments to input clock
      PROGCLK => OPEN,     -- 1-bit input: Clock input for M/D reconfiguration
      PROGDATA => OPEN,   -- 1-bit input: Serial data input for M/D reconfiguration
      PROGEN => OPEN,       -- 1-bit input: Active high program enable
      RST => OPEN              -- 1-bit input: Reset input pin
   );

   -- End of DCM_CLKGEN_inst instantiation

Got this error:

ERROR:Pack:198 - NCD was not produced. All logic was removed from the design. This is usually due to having no input or output PAD connections in the design and no nets or symbols marked as 'SAVE'. You can either add PADs or 'SAVE' attributes to the design, or run 'map -u' to disable logic trimming in the mapper.


Solution

  • Your input pin is named clk and routed to the DCM_18 component, created via CoreGen. The DCM_18 module uses a PLL_ADV to generate your clock.

    As you can see, the DCM_18 module instantiates a IBUFG to route your clock signal from extern pin clk through a special (clock capable) input buffer and into a clock net, that goes straight to the PLL_ADV.

    The PLL_ADV output clkout0 is routed through a BUFG, to feed the new clock signal into a clock network, that can be used by every flip flop in your design.

    So back in your top-level module, the new clock is provided via test_clk. You should use this clock for your flip flops.

    Using clk is a fault, because you can't grab a signal between the pin (IPAD) and the input buffer (IBUF(G)).