--
-- timing_io.vhd
--
-- Timing Control and Test Generation
--
--
-- Version 1.0 30/1/06 A.McCormick (Alpha Data)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
library work;
use work.common_interface.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity timing_io is
port (
clk : in std_logic;
rst : in std_logic;
system_in : in std_logic_vector(system_width-1 downto 0);
system_out : out std_logic_vector(system_width-1 downto 0);
ten_mhz_clk : in std_logic;
tbus_bplane :inout std_logic_vector(10 downto 1);
tbus_header :inout std_logic_vector(10 downto 1);
tbus_master :in std_logic_vector(10 downto 1);
ten_mhz_clk_out : out std_logic;
cycle_start_out : out std_logic;
cycle_stop_out : out std_logic;
cal_start_out : out std_logic;
cal_stop_out : out std_logic;
injection_out : out std_logic;
hchange_out : out std_logic;
fref_out : out std_logic);
end timing_io;
architecture rtl of timing_io is
signal ten_mhz_reg : std_logic_vector(2 downto 0);
signal timing_mux : std_logic_vector(7 downto 0);
signal timing_assert : std_logic_vector(7 downto 0);
signal timing_reg : std_logic_vector(31 downto 0);
signal timing_mux10 : std_logic_vector(7 downto 0);
signal timing_assert10 : std_logic_vector(7 downto 0);
--signal ten_mhz_shift : std_logic_vector(24 downto 0) := "1111110000001111111000000"; -- generate poor 10MHz clock
signal ten_mhz_clk_bg : std_logic;
signal fref_counter : std_logic_vector(15 downto 0);
signal fref_limit : std_logic_vector(15 downto 0);
signal fref_int : std_logic;
signal ten_mhz_int : std_logic;
signal eighty_mhz_int : std_logic;
signal ten_mhz_counter : std_logic_vector(2 downto 0) := "000";
signal cycle_start_in : std_logic;
signal cycle_stop_in : std_logic;
signal cal_start_in : std_logic;
signal cal_stop_in : std_logic;
signal injection_in : std_logic;
signal hchange_in : std_logic;
signal fref_in : std_logic;
signal cycle_start_o : std_logic;
signal cycle_stop_o : std_logic;
signal cal_start_o : std_logic;
signal cal_stop_o : std_logic;
signal injection_o : std_logic;
signal hchange_o : std_logic;
signal fref_o : std_logic;
signal cycle_start_bp : std_logic;
signal cycle_stop_bp : std_logic;
signal cal_start_bp : std_logic;
signal cal_stop_bp : std_logic;
signal injection_bp : std_logic;
signal hchange_bp : std_logic;
signal fref_bp : std_logic;
signal cycle_start_hd : std_logic;
signal cycle_stop_hd : std_logic;
signal cal_start_hd : std_logic;
signal cal_stop_hd : std_logic;
signal injection_hd : std_logic;
signal hchange_hd : std_logic;
signal fref_hd : std_logic;
signal master_bplane,master_header,slave_bplane,slave_header,use_bplane : std_logic;
begin -- rtl
cycle_start_in <= tbus_master(2);
cycle_stop_in <= tbus_master(3);
cal_start_in <= tbus_master(4);
cal_stop_in <= tbus_master(5);
injection_in <= tbus_master(6);
hchange_in <= tbus_master(7);
fref_in <= tbus_master(8);
dcm0: dcm
generic map (
clkfx_divide => 25,
clkfx_multiply => 16,
clk_feedback => "NONE")
port map (
clkin => clk,
clkfx => eighty_mhz_int,
rst => rst,
psclk => '0',
psen => '0',
psincdec => '0');
div_80Mhz_clk: process (eighty_mhz_int)
begin -- process div_80Mhz_clk
if eighty_mhz_int'event and eighty_mhz_int = '1' then -- rising clock edge
ten_mhz_counter <= ten_mhz_counter+1;
ten_mhz_int <= ten_mhz_counter(2);
end if;
end process div_80Mhz_clk;
clk_buf0 : BUFGMUX
port map (
S => timing_reg(8),
I0 => ten_mhz_clk,
I1 => ten_mhz_int,
O => ten_mhz_clk_bg);
-- Sample 10MHz clock to find safe time to change test signals
sample_10mhz: process (clk, rst)
begin -- process sample_10mhz
if rst = '1' then -- asynchronous reset
ten_mhz_reg <= (others => '0');
--ten_mhz_shift <= "1111110000001111111000000"; -- generate poor 10MHz clock
-- from 125
timing_mux <= (others => '0');
timing_assert <= (others => '0');
fref_counter <= (others => '0');
fref_limit <= (others => '0');
master_bplane <= '0';
master_header <= '0';
slave_bplane <= '1';
slave_header <= '1';
use_bplane <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
ten_mhz_reg <= ten_mhz_reg(1 downto 0) & ten_mhz_clk_bg;
--ten_mhz_shift <= ten_mhz_shift(23 downto 0) & ten_mhz_shift(24);
-- Register Data to be converted to 10MHz, 2 clock cycles (16ns)
-- after rising edge of 10MHz CLK
if ten_mhz_reg(2) = '0' and ten_mhz_reg(1) = '1' then
timing_mux <= timing_reg(15 downto 8);
timing_assert <= timing_reg(7 downto 0);
end if;
fref_limit <= "0000" & timing_reg(27 downto 16);
if OR_reduce(fref_counter) = '0' then
fref_counter <= fref_limit;
fref_int <= not fref_int;
else
fref_counter <= fref_counter-1;
end if;
master_bplane <= timing_reg(28);
master_header <= timing_reg(29);
use_bplane <= timing_reg(30);
slave_bplane <= not master_bplane;
slave_header <= not master_header;
end if;
end process sample_10mhz;
-- Register timing signals and multiplex with test signals
reg_timing: process (ten_mhz_clk_bg)
begin -- process reg_timing
if ten_mhz_clk_bg'event and ten_mhz_clk_bg = '1' then -- rising clock edge
timing_mux10 <= timing_mux;
timing_assert10 <= timing_assert;
if timing_mux10(1) = '1' then
cycle_start_o <= timing_assert10(1);
else
cycle_start_o <= cycle_start_in;
end if;
if timing_mux10(2) = '1' then
cycle_stop_o <= timing_assert10(2);
else
cycle_stop_o <= cycle_stop_in;
end if;
if timing_mux10(3) = '1' then
cal_start_o <= timing_assert10(3);
else
cal_start_o <= cal_start_in;
end if;
if timing_mux10(4) = '1' then
cal_stop_o <= timing_assert10(4);
else
cal_stop_o <= cal_stop_in;
end if;
if timing_mux10(6) = '1' then
hchange_o <= timing_assert10(6);
else
hchange_o <= hchange_in;
end if;
end if;
end process reg_timing;
-- Injection and FREF not synced to 10MHz
injection_o <= injection_in when timing_mux10(5) = '0' else timing_assert10(5);
fref_o <= fref_in when timing_mux10(7) = '0' else fref_int;
creg0 : readable_control_register
generic map (
width => 32, addr => 2)
port map (
clk => clk, rst => rst, system_in => system_in, system_out => system_out,
control_data => timing_reg, control_wstb => open);
ten_mhz_clk_out <= ten_mhz_clk_bg;
iob_bp1: IOBUF
port map (
I => ten_mhz_clk_bg,
IO => tbus_bplane(1),
O => open,
T => slave_bplane);
iob_bp2: IOBUF
port map (
I => cycle_start_o,
IO => tbus_bplane(2),
O => cycle_start_bp,
T => slave_bplane);
iob_bp3: IOBUF
port map (
I => cycle_stop_o,
IO => tbus_bplane(3),
O => cycle_stop_bp,
T => slave_bplane);
iob_bp4: IOBUF
port map (
I => cal_start_o,
IO => tbus_bplane(4),
O => cal_start_bp,
T => slave_bplane);
iob_bp5: IOBUF
port map (
I => cal_stop_o,
IO => tbus_bplane(5),
O => cal_stop_bp,
T => slave_bplane);
iob_bp6: IOBUF
port map (
I => injection_o,
IO => tbus_bplane(6),
O => injection_bp,
T => slave_bplane);
iob_bp7: IOBUF
port map (
I => hchange_o,
IO => tbus_bplane(7),
O => hchange_bp,
T => slave_bplane);
iob_bp8: IOBUF
port map (
I => fref_o,
IO => tbus_bplane(8),
O => fref_bp,
T => slave_bplane);
iob_hd1: IOBUF
port map (
I => ten_mhz_clk_bg,
IO => tbus_header(1),
O => open,
T => slave_header);
iob_hd2: IOBUF
port map (
I => cycle_start_o,
IO => tbus_header(2),
O => cycle_start_hd,
T => slave_header);
iob_hd3: IOBUF
port map (
I => cycle_stop_o,
IO => tbus_header(3),
O => cycle_stop_hd,
T => slave_header);
iob_hd4: IOBUF
port map (
I => cal_start_o,
IO => tbus_header(4),
O => cal_start_hd,
T => slave_header);
iob_hd5: IOBUF
port map (
I => cal_stop_o,
IO => tbus_header(5),
O => cal_stop_hd,
T => slave_header);
iob_hd6: IOBUF
port map (
I => injection_o,
IO => tbus_header(6),
O => injection_hd,
T => slave_header);
iob_hd7: IOBUF
port map (
I => hchange_o,
IO => tbus_header(7),
O => hchange_hd,
T => slave_header);
iob_hd8: IOBUF
port map (
I => fref_o,
IO => tbus_header(8),
O => fref_hd,
T => slave_header);
-- Select BPLANE or HEADER as INPUT
cycle_start_out <= cycle_start_bp when use_bplane = '1' else cycle_start_hd;
cycle_stop_out <= cycle_stop_bp when use_bplane = '1' else cycle_stop_hd;
cal_start_out <= cal_start_bp when use_bplane = '1' else cal_start_hd;
cal_stop_out <= cal_stop_bp when use_bplane = '1' else cal_stop_hd;
injection_out <= injection_bp when use_bplane = '1' else injection_hd;
hchange_out <= hchange_bp when use_bplane = '1' else hchange_hd;
fref_out <= fref_bp when use_bplane = '1' else fref_hd;
end rtl;