Clock Forwarding Won’t Work

fpgaspartanvhdlxilinx

I am trying to forward a global clock signal to an output pin. I am using a Spartan SP601 evaluation board, LX16CSG324. Refer to the end of this segment of code. I am using a 2.5 V LVDS differential 200 MHz oscillator. I first run the differential clock signals through IBUFGDS and BUFG. Then, I feed the clock signal and the inverted clock signal into ODDR2, with hohoho being a user I/O pin.

I have also provided the relevant parts of my user constraints file. The final output from pin hohoho is constantly about 133 mV. Have I missed anything? Is there anything that I'm doing incorrectly? Is LVDS_25 the correct I/O standard to use for my clock? Whenever I look in Spartan 6 manuals, they list all the differential I/O standards together, but don't seem to say anything about how to determine which one to use.

library IEEE;
library UNISIM;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use UNISIM.vcomponents.all;

entity final_trigger is
     generic ( ports : natural := 3);
    Port (    reset : in  STD_LOGIC;
              I,IB : in STD_LOGIC;  
              myag_l,byag_l,opo_lq: out STD_LOGIC;
              rx : in STD_LOGIC;
              tx : out STD_LOGIC;
              hohoho : out STD_LOGIC
           );
end final_trigger;

architecture struc_arch of final_trigger is
    signal clk,O: std_logic;
    signal clk_inv: std_logic;
    signal tx_full,rx_empty: std_logic;
    signal en: std_logic;
    signal disable: std_logic_vector(ports-1 downto 0);
    signal counter: unsigned(25 downto 0);
    signal d_big,d_mini,d_opo: std_logic_vector(25 downto 0);
    signal w_big,w_mini,w_opo: std_logic_vector(25 downto 0);
    signal period_change: std_logic_vector(25 downto 0);
    signal in_data, out_data: std_logic_vector(7 downto 0);
begin
serial: entity work.uart(str_arch)
    port map(clk=>clk,reset=>reset,rd_uart=>en,wr_uart=>en,rx=>rx,w_data=>out_data,tx_full=>tx_full,rx_empty=>rx_empty,r_data=>in_data,tx=>tx);
pulse: entity work.trigger(struc_arch)
    generic map(ports=>ports)
    port map(clk=>clk,rst=>reset,d_big=>d_big,d_mini=>d_mini,d_opo=>d_opo,w_big=>w_big,w_mini=>w_mini,w_opo=>w_opo,
                period_change=>period_change,disable=>disable,myag_l=>myag_l,myag_q=>open,byag_l=>byag_l,byag_q=>open,
                opo_lq=>opo_lq);
inc: entity work.var_delay_incrementor(fsmd_arch)
    generic map(ports=>ports)
    port map(clk=>clk,reset=>reset,update=>en,in_data=>in_data,out_data=>out_data,d_big=>d_big,d_mini=>d_mini,d_opo=>d_opo,w_big=>w_big,w_mini=>w_mini,w_opo=>w_opo,period_change=>period_change,disable=>disable);
enable: entity work.enable(fsm_arch)
    port map(clk=>clk,reset=>reset,rx_empty=>rx_empty,en=>en);
IBUFGDS_inst : IBUFGDS
generic map (
   DIFF_TERM => FALSE, -- Differential Termination 
   IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
   IOSTANDARD => "DEFAULT")
port map (
   O => O,  -- Clock buffer output
   I => I,  -- Diff_p clock buffer input (connect directly to top-level port)
   IB => IB -- Diff_n clock buffer input (connect directly to top-level port)
);
BUFG_inst : BUFG
port map (
   O => clk, -- 1-bit output: Clock buffer output
   I => O  -- 1-bit input: Clock buffer input
);
ODDR2_inst : ODDR2
generic map(
    DDR_ALIGNMENT => "NONE", --Sets output alignment to "NONE", "C0", "C1"
    INIT => '0', --Sets initial state of the Q output to '0' or '1'
    SRTYPE => "SYNC") -- Specifies "SYNC" or "ASYNC" set/reset
port map (
    Q => hohoho, -- 1-bit output data
    C0 => clk, -- 1-bit clock input
    C1 => clk_inv, -- 1-bit clock input
    CE => '1', -- 1-bit clock enable input
    D0 => '1', -- 1-bit data input (associated with C0)
    D1 => '0', -- 1-bit data input (associated with C1)
    R => '0', -- 1-bit reset input
    S => '0' -- 1-bit set input
);

clk_inv <= not clk;
end struc_arch;

User Constraints File

## OUTPUT PINS ##
NET "byag_l" LOC = "F15"; ## 2 on J13
NET "myag_l" LOC = "B4"; ## 4 on J13
NET "opo_lq" LOC = "F13"; ## 6 on J13
NET "hohoho" LOC = "P12"; ## 8 on J13
## CLOCK ##
NET "I" LOC = "K15" | IOSTANDARD="LVDS_25"; ## 6 on U5 EG2121CA, 4 of U20 SI500D (DNP)
NET "IB" LOC = "K16" | IOSTANDARD="LVDS_25"; ## 5 on U5 EG2121CA, 5 of U20 SI500D (DNP)
NET "I" TNM_NET = "clk";
TIMESPEC "TS_clk" = PERIOD "clk" 5 ns HIGH 50%;

Best Answer

I think you need an OBUF on the end of your ODDR. The ODDR cannot drive a pin directly. No doubt there is a warning in there somewhere, but hidden amongst thousands of trivial warnings :)