------------------------------------------------------------------------------ -- Adapted from Xilinx(c) coregen/cg_iserdes_tdc_8b -- ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use ieee.std_logic_misc.all; use ieee.numeric_std.all; library unisim; use unisim.vcomponents.all; entity iserdes2_tdc_8b is --generic --(-- width of the data for the system --sys_w : integer := 1; -- width of the data for the device --dev_w : integer := 8); port ( clk_io_i : in std_logic; strb_i : in std_logic; -- From the system into the device --DATA_IN_FROM_PINS serdata_i : in std_logic; --_vector(sys_w-1 downto 0); --DATA_IN_TO_DEVICE pardata_o : out std_logic_vector(7 downto 0); --dev_w-1 downto 0); pardata_no : out std_logic_vector(7 downto 0); --dev_w-1 downto 0); -- Clock and reset signals --CLK_IN : in std_logic; -- Fast clock from PLL/MMCM CLK_DIV_IN : in std_logic; -- Slow clock from PLL/MMCM --LOCKED_IN : in std_logic; --LOCKED_OUT : out std_logic; IO_RESET : in std_logic); -- Reset signal for IO circuit end iserdes2_tdc_8b; architecture rtl of iserdes2_tdc_8b is --attribute CORE_GENERATION_INFO : string; --attribute CORE_GENERATION_INFO of xilinx : architecture is "cg_iserdes_tdc_8b,selectio_wiz_v4_1,{component_name=cg_iserdes_tdc_8b,bus_dir=INPUTS,bus_sig_type=SINGLE,bus_io_std=LVTTL,use_serialization=true,use_phase_detector=false,serialization_factor=8,enable_bitslip=false,enable_train=false,system_data_width=1,bus_in_delay=NONE,bus_out_delay=NONE,clk_sig_type=SINGLE,clk_io_std=LVTTL,clk_buf=BUFPLL,active_edge=RISING,clk_delay=NONE,v6_bus_in_delay=NONE,v6_bus_out_delay=NONE,v6_clk_buf=BUFIO,v6_active_edge=NOT_APP,v6_ddr_alignment=SAME_EDGE_PIPELINED,v6_oddr_alignment=SAME_EDGE,ddr_alignment=C0,v6_interface_type=NETWORKING,interface_type=RETIMED,v6_bus_in_tap=0,v6_bus_out_tap=0,v6_clk_io_std=LVCMOS18,v6_clk_sig_type=SINGLE}"; constant clock_enable : std_logic := '1'; signal unused : std_logic; signal clk_in_int_buf : std_logic; signal clk_div_in_int : std_logic; -- After the buffer signal data_in_from_pins_int : std_logic; --_vector(sys_w-1 downto 0); -- Between the delay and serdes signal data_in_from_pins_delay : std_logic; --_vector(sys_w-1 downto 0); --constant num_serial_bits : integer := dev_w/sys_w; --type serdarr is array (0 to 7) of std_logic; --_vector(sys_w-1 downto 0); -- Array to use intermediately from the serdes to the internal -- devices. bus "0" is the leftmost bus -- * fills in starting with 0 signal iserdes_q : std_logic_vector(7 downto 0) := x"00"; --signal serdesstrobe : std_logic; signal icascade : std_logic; --_vector(sys_w-1 downto 0); begin -- Create the clock logic --bufpll_inst : BUFPLL -- generic map ( -- DIVIDE => 8) -- port map ( -- IOCLK => clk_in_int_buf, -- LOCK => LOCKED_OUT, -- SERDESSTROBE => serdesstrobe, -- GCLK => CLK_DIV_IN, -- GCLK pin must be driven by BUFG -- LOCKED => LOCKED_IN, -- PLLIN => CLK_IN); -- We have multiple bits- step over every bit, instantiating the required elements --pins: for pin_count in 0 to sys_w-1 generate --begin -- Instantiate the buffers ---------------------------------- -- Instantiate a buffer for every bit of the data bus -- ibuf_inst : IBUF -- generic map ( -- IOSTANDARD => "LVTTL") -- port map ( -- I => DATA_IN_FROM_PINS (pin_count), -- O => data_in_from_pins_int(pin_count)); -- Pass through the delay ----------------------------------- --data_in_from_pins_delay(pin_count) <= data_in_from_pins_int(pin_count); -- Instantiate the serdes primitive ---------------------------------- -- declare the iserdes iserdes2_master : ISERDES2 generic map ( BITSLIP_ENABLE => false, DATA_RATE => "SDR", DATA_WIDTH => 8, INTERFACE_TYPE => "RETIMED", SERDES_MODE => "MASTER") port map ( Q1 => iserdes_q(3), --(pin_count), Q2 => iserdes_q(2), --(pin_count), Q3 => iserdes_q(1), --(pin_count), Q4 => iserdes_q(0), --(pin_count), SHIFTOUT => icascade, --(pin_count), INCDEC => open, VALID => open, BITSLIP => '0', CE0 => clock_enable, -- 1-bit Clock enable input CLK0 => clk_io_i, --clk_in_int_buf, -- 1-bit IO Clock network input. Optionally Invertible. This is the primary clock -- input used when the clock doubler circuit is not engaged (see DATA_RATE -- attribute). CLK1 => '0', CLKDIV => CLK_DIV_IN, D => serdata_i, --data_in_from_pins_delay(pin_count), -- 1-bit Input signal from IOB. IOCE => strb_i, -- 1-bit Data strobe signal derived from BUFIO CE. Strobes data capture for -- NETWORKING and NETWORKING_PIPELINES alignment modes. RST => IO_RESET, -- 1-bit Asynchronous reset only. SHIFTIN => '0', -- unused connections FABRICOUT => open, CFB0 => open, CFB1 => open, DFB => open); iserdes2_slave : ISERDES2 generic map ( BITSLIP_ENABLE => false, DATA_RATE => "SDR", DATA_WIDTH => 8, INTERFACE_TYPE => "RETIMED", SERDES_MODE => "SLAVE") port map ( Q1 => iserdes_q(7), --(pin_count), Q2 => iserdes_q(6), --(pin_count), Q3 => iserdes_q(5), --(pin_count), Q4 => iserdes_q(4), --(pin_count), SHIFTOUT => open, INCDEC => open, VALID => open, BITSLIP => '0', CE0 => clock_enable, -- 1-bit Clock enable input CLK0 => clk_io_i, --clk_in_int_buf, -- 1-bit IO Clock network input. Optionally Invertible. This is the primary clock -- input used when the clock doubler circuit is not engaged (see DATA_RATE -- attribute). CLK1 => '0', CLKDIV => CLK_DIV_IN, D => '0', -- 1-bit Input signal from IOB. IOCE => strb_i, -- 1-bit Data strobe signal derived from BUFIO CE. Strobes data capture for -- NETWORKING and NETWORKING_PIPELINES alignment modes. RST => IO_RESET, -- 1-bit Asynchronous reset only. SHIFTIN => icascade, --(pin_count), -- unused connections FABRICOUT => open, CFB0 => open, CFB1 => open, DFB => open); -- Concatenate the serdes outputs together. Keep the timesliced -- bits together, and placing the earliest bits on the right -- ie, if data comes in 0, 1, 2, 3, 4, 5, 6, 7, ... -- the output will be 3210, 7654, ... ------------------------------------------------------------- --in_slices: for slice_count in 0 to num_serial_bits-1 generate begin -- This places the first data in time on the right --DATA_IN_TO_DEVICE(slice_count) <= -- iserdes_q(num_serial_bits-slice_count-1)(0); -- To place the first data in time on the left, use the -- following code, instead -- DATA_IN_TO_DEVICE(slice_count) <= -- iserdes_q(slice_count); --end generate in_slices; pardata_o <= iserdes_q; pardata_no <= not iserdes_q; --end generate pins; end rtl;