这是.xco文件中的代码,它是从我的主vhdl文件分支出来的:
-- 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 clk。这是我添加到主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
);
然而,我收到了这个错误:
错误:Xst:2035 - 端口有非法连接。这个端口是 连接到输入缓冲区和其他组件。
有什么想法吗?
编辑:完整代码
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
出现此错误:
错误:包装:198 - 未生成NCD。所有的逻辑都被删除了 设计。这通常是由于没有输入或输出PAD 设计中的连接,没有标记为“保存”的网络或符号。 您可以将PAD或“SAVE”属性添加到设计中,也可以运行 'map -u'禁用映射器中的逻辑修整。
答案 0 :(得分:1)
问题是coregen将为源时钟实例化一个全局时钟缓冲区,如果该引脚被路由到全局时钟缓冲区,它也不能直接路由到其他地方。
我的建议是不要将coregen用于简单的实例化DCM块。如果您只是实例化DCM,则可以将源时钟连接到和到其他逻辑,工具将自动在正确的位置插入全局时钟缓冲区以使其正常工作。
您似乎正在使用ISE,因此请转到Edit > Language Templates
,然后选择VHDL > Device Primitive Instantiation
,展开相关设备,然后选择Clock Components
,并找到DCM的模板。您可以将源时钟直接连接到此实例。
我认为这种方法的优点是:
如果您在设置DCM实例化的各种泛型时遇到问题,请查看文档,这通常非常好。例如,此处的Spartan 6文档:http://www.xilinx.com/support/documentation/user_guides/ug382.pdf第98页开始。或者,您可以从.xco
文件复制实例化,并将其作为起点。
答案 1 :(得分:1)
您的输入引脚名为clk
,并路由到通过CoreGen创建的DCM_18
组件。 DCM_18模块使用PLL_ADV生成时钟。
如您所见,DCM_18模块实例化IBUFG,以便将时钟信号从外部引脚clk
通过一个特殊的(支持时钟的)输入缓冲器传送到时钟网,然后直接连接到PLL_ADV。 / p>
PLL_ADV输出clkout0通过BUFG路由,将新时钟信号馈入时钟网络,可供设计中的每个触发器使用。
回到顶层模块,新时钟通过test_clk
提供。你应该把这个时钟用作你的拖鞋。
使用clk
是一个错误,因为您无法在引脚(IPAD)和输入缓冲区(IBUF(G))之间获取信号。