-- -- Buffer Controller Chip -- Controller -- -- Matt Warren -- UCL -- -- Provides all the BCC functions (that aren't command decoder) -- -- -- Log: -- 2009-Jan-07 - This file is born -- 2009-Jan-12 - Updated for 4 channel readout -- 2009-Jan-13 - Version 0.01 as sent to Dave Nelson -- 2009-Jan-20 - Complete rework - Version 0.1 sent to Dave Nelson -- 2009-Jan-21 - Tidied, removed rst -- - Version 0.2 -- 2009-Jan-26 - Improved sensitivty lists for synth (why?) -- - Version 0.3 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity bcc_control is port( abcn_dclk_o : out std_logic; abcn_bco_o : out std_logic; abcn_mode80_o : out std_logic; abcn_com_o : out std_logic; abcn_resetb_o : out std_logic; abcn_l1_o : out std_logic; local_com_i : in std_logic; local_l1_i : in std_logic; local_resetb_i : in std_logic; data0_i : in std_logic; data1_i : in std_logic; data2_i : in std_logic; data3_i : in std_logic; local_data_o : out std_logic; config_reg_i : in std_logic_vector (15 downto 0); comdest_i : in std_logic_vector (1 downto 0); rst : in std_logic; clk_locked_i : in std_logic; clk : in std_logic; clk2x : in std_logic ); -- Declarations end bcc_control; -- architecture rtl of bcc_control is signal dclk : std_logic; signal sclk : std_logic; signal aclk : std_logic; signal data_sel : std_logic; signal std_data : std_logic; signal quad_data : std_logic; signal col0_data : std_logic; signal col1_data : std_logic; signal data0_q : std_logic; signal data1_q : std_logic; signal data2_q : std_logic; signal data3_q : std_logic; signal com_com : std_logic; signal com_l1 : std_logic; signal com_resetb : std_logic; signal col1_top_sel : std_logic; signal col0_top_sel : std_logic; signal aclk_en : std_logic; signal abcn_dclk_en : std_logic; signal abcn_bco_en : std_logic; signal abcn_dclk_inv : std_logic; signal abcn_bco_inv : std_logic; signal aclk_inv : std_logic; signal sclk_inv : std_logic; signal mode80_sel : std_logic; signal quadmode : std_logic; signal linkmode : std_logic_vector(1 downto 0); signal quadmode_selector : std_logic_vector(1 downto 0); begin col1_top_sel <= config_reg_i(12); col0_top_sel <= config_reg_i(11); abcn_dclk_en <= config_reg_i(10) and clk_locked_i; abcn_bco_en <= config_reg_i( 9) and clk_locked_i; aclk_en <= config_reg_i( 8); abcn_dclk_inv <= config_reg_i( 7); abcn_bco_inv <= config_reg_i( 6); aclk_inv <= config_reg_i( 5); sclk_inv <= config_reg_i( 4); mode80_sel <= config_reg_i( 3); quadmode <= config_reg_i( 2); linkmode <= config_reg_i(1 downto 0); abcn_bco_o <= (clk xor abcn_bco_inv) and abcn_bco_en; abcn_dclk_o <= (dclk xor abcn_dclk_inv) and abcn_dclk_en; abcn_mode80_o <= mode80_sel; -- dclk selector dclk <= clk when (mode80_sel = '0') else clk2x; -- Signals TO asics section ------------------------------------------------------------------- -- destination addressed signals com_com <= local_com_i when comdest_i = "00" else '0'; com_l1 <= local_com_i when comdest_i = "01" else '0'; com_resetb <= not(local_com_i) when comdest_i = "10" else '1'; -- clock signals out to asics -- note: aclk_en is really just to keep aclk pd the same as bco aclk <= (clk xor aclk_inv) and aclk_en; prc_abcn_sigs_clk : process (aclk) -- com_com, local_l1_i, com_l1, rst, local_resetb_i, com_reset) begin if rising_edge(aclk) then if (rst = '1') then abcn_com_o <= '0'; abcn_l1_o <= '0'; abcn_resetb_o <= '1'; else abcn_com_o <= com_com; abcn_l1_o <= local_l1_i or com_l1; abcn_resetb_o <= not(rst) and local_resetb_i and com_resetb; end if; end if; end process; -- Data readout FROM asics section -------------------------------------------------------------- sclk <= dclk xor sclk_inv; -- Clock data in prc_clock_data_in : process (sclk, data0_i,data1_i,data2_i,data3_i) begin if rising_edge(sclk) then if (rst = '1') then data0_q <= '0'; data1_q <= '0'; data2_q <= '0'; data3_q <= '0'; else data0_q <= data0_i; data1_q <= data1_i; data2_q <= data2_i; data3_q <= data3_i; end if; end if; end process; -- select redundant links col0_data <= data2_q when (col0_top_sel = '1') else data0_q; col1_data <= data3_q when (col1_top_sel = '1') else data1_q; -- Standard Mode prc_data_linkmode : process (linkmode, dclk) begin case linkmode is when "00" => data_sel <= dclk; when "01" => data_sel <= '0'; when "10" => data_sel <= '1'; when "11" => data_sel <= '1'; when others => null; end case; end process; std_data <= col1_data when (data_sel = '0') else col0_data; -- Quad Mode quadmode_selector <= (clk & clk2x); prc_quadmode : process (quadmode_selector, data0_q, data1_q, data2_q, data3_q) begin case quadmode_selector is when "00" => quad_data <= data0_q; when "01" => quad_data <= data1_q; when "10" => quad_data <= data2_q; when "11" => quad_data <= data3_q; when others => null; end case; end process; local_data_o <= quad_data when (quadmode = '1') else std_data; end architecture rtl;