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 :)