新的 DCM CLK 实例化错误?
New DCM CLK instantiation error?
这是从我的主 vhdl 文件分支出来的 .xco 文件中的代码:
-- 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 ------------
目标是从 50 MHz 时钟产生 18.432 MHz 时钟。这是我添加到主 vhdl 文件中的代码:
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
);
但是,我收到了这个错误:
ERROR:Xst:2035 - Port has illegal connections. This port is
connected to an input buffer and other components.
有什么想法吗?
编辑:完整代码
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;
编辑:.XCO 文件代码
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;
编辑(新 CLK 实例化):从 50 MHz CLK
创建 18.4 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
出现此错误:
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.
问题是coregen会为source clock实例化一个global clock buffer,如果这个pin路由到一个global clock buffer,就不能也直接路由到其他地方了。
我的建议是不要将 coregen 用于一些简单的事情,例如实例化 DCM 块。如果您只是简单地实例化 DCM,您可以将源时钟连接到它 并将 连接到其他逻辑,工具将自动在正确的位置插入一个全局时钟缓冲区以允许它工作。
你似乎在使用ISE,所以去Edit > Language Templates
,然后select VHDL > Device Primitive Instantiation
,展开相关设备,然后select Clock Components
,并为您的 DCM 找到一个模板。您可以将源时钟直接连接到此实例。
我认为这种方法的优点是:
- 阅读您代码的任何人都可以直接看到各种参数(乘法器、除法器等),而不是必须打开 coregen。
- 您可以根据泛型或常量指定参数,这样更容易改变输出频率。
- 您不必担心在何处插入了哪些时钟缓冲区;在大多数情况下,没有必要手动实例化它们。
如果您在为 DCM 实例化设置各种泛型时遇到困难,请查看文档,它通常非常好。例如,此处的 Spartan 6 文档:http://www.xilinx.com/support/documentation/user_guides/ug382.pdf 第 98 页起。或者,您可以从 .xco
文件复制实例并将其用作起点。
您的输入引脚被命名为 clk
并路由到 DCM_18
组件,通过 CoreGen 创建。 DCM_18 模块使用 PLL_ADV 生成时钟。
如您所见,DCM_18 模块实例化了一个 IBUFG,通过一个特殊的(支持时钟的)输入缓冲器将您的时钟信号从外部引脚 clk
路由到一个时钟网络,这就是直接到 PLL_ADV.
PLL_ADV 输出 clkout0 通过 BUFG 路由,以将新时钟信号馈送到时钟网络,您设计中的每个触发器都可以使用它。
所以回到你的顶层模块,新时钟是通过 test_clk
提供的。你应该用这个时钟做你的人字拖。
使用clk
是错误的,因为你无法在引脚(IPAD)和输入缓冲区(IBUF(G))之间获取信号。
这是从我的主 vhdl 文件分支出来的 .xco 文件中的代码:
-- 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 ------------
目标是从 50 MHz 时钟产生 18.432 MHz 时钟。这是我添加到主 vhdl 文件中的代码:
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
);
但是,我收到了这个错误:
ERROR:Xst:2035 - Port has illegal connections. This port is connected to an input buffer and other components.
有什么想法吗?
编辑:完整代码
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;
编辑:.XCO 文件代码
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;
编辑(新 CLK 实例化):从 50 MHz CLK
创建 18.4 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
出现此错误:
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.
问题是coregen会为source clock实例化一个global clock buffer,如果这个pin路由到一个global clock buffer,就不能也直接路由到其他地方了。
我的建议是不要将 coregen 用于一些简单的事情,例如实例化 DCM 块。如果您只是简单地实例化 DCM,您可以将源时钟连接到它 并将 连接到其他逻辑,工具将自动在正确的位置插入一个全局时钟缓冲区以允许它工作。
你似乎在使用ISE,所以去Edit > Language Templates
,然后select VHDL > Device Primitive Instantiation
,展开相关设备,然后select Clock Components
,并为您的 DCM 找到一个模板。您可以将源时钟直接连接到此实例。
我认为这种方法的优点是:
- 阅读您代码的任何人都可以直接看到各种参数(乘法器、除法器等),而不是必须打开 coregen。
- 您可以根据泛型或常量指定参数,这样更容易改变输出频率。
- 您不必担心在何处插入了哪些时钟缓冲区;在大多数情况下,没有必要手动实例化它们。
如果您在为 DCM 实例化设置各种泛型时遇到困难,请查看文档,它通常非常好。例如,此处的 Spartan 6 文档:http://www.xilinx.com/support/documentation/user_guides/ug382.pdf 第 98 页起。或者,您可以从 .xco
文件复制实例并将其用作起点。
您的输入引脚被命名为 clk
并路由到 DCM_18
组件,通过 CoreGen 创建。 DCM_18 模块使用 PLL_ADV 生成时钟。
如您所见,DCM_18 模块实例化了一个 IBUFG,通过一个特殊的(支持时钟的)输入缓冲器将您的时钟信号从外部引脚 clk
路由到一个时钟网络,这就是直接到 PLL_ADV.
PLL_ADV 输出 clkout0 通过 BUFG 路由,以将新时钟信号馈送到时钟网络,您设计中的每个触发器都可以使用它。
所以回到你的顶层模块,新时钟是通过 test_clk
提供的。你应该用这个时钟做你的人字拖。
使用clk
是错误的,因为你无法在引脚(IPAD)和输入缓冲区(IBUF(G))之间获取信号。