--******************************************************************************
--* @short Board Control Logic for GMT Logic Board. (Inside ROP Chip)
--*
--* Board Control performs the following functions:
--*
--* @li Direct programming of all the FPGAs on board
--* @li reading of status registers
--* @li reading of DCM_locked registers
--* @li writing of dummy registers
--* @li writing of reset and reset_DCM registers
--* @li writing of command register to set READY/BUSY status from SW
--*
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv3.cern.ch>
--* @version $Revision: 1.9 $
--* @date $Date: 2006/04/10 09:39:59 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
-- pragma translate_off
library UNISIM;
use UNISIM.VCOMPONENTS.all;
-- pragma translate_on
use IEEE.NUMERIC_STD.all;
use work.VMEMux.all;
use work.ROPVMEAddrMap.all;
entity ROPBoardControl is
port (
-- STATUS Signals of FPGAs for VME
dcm_locked_ROP : in std_logic;
dcm_locked_INF : in std_logic;
dcm_locked_INC : in std_logic;
dcm_locked_IND : in std_logic;
dcm_locked_INB : in std_logic;
dcm_locked_AUF : in std_logic;
dcm_locked_LFF : in std_logic;
dcm_locked_LFB : in std_logic;
dcm_locked_AUB : in std_logic;
dcm_locked_SRT : in std_logic;
-- Dummy signals (as spares)
dummy_ROP : out std_logic;
dummy_INF : out std_logic;
dummy_INC : out std_logic;
dummy_IND : out std_logic;
dummy_INB : out std_logic;
dummy_AUF : out std_logic;
dummy_LFF : out std_logic;
dummy_LFB : out std_logic;
dummy_AUB : out std_logic;
dummy_SRT : out std_logic;
-- STATUS Signals of FPGAs for TCS
status_ROP : in std_logic_vector(1 downto 0);
status_INF : in std_logic_vector(1 downto 0);
status_INC : in std_logic_vector(1 downto 0);
status_IND : in std_logic_vector(1 downto 0);
status_INB : in std_logic_vector(1 downto 0);
status_AUF : in std_logic_vector(1 downto 0);
status_LFF : in std_logic_vector(1 downto 0);
status_LFB : in std_logic_vector(1 downto 0);
status_AUB : in std_logic_vector(1 downto 0);
status_SRT : in std_logic_vector(1 downto 0);
STAT_GMT : out std_logic_vector(3 downto 0);
reset_ROP : out std_logic;
reset_INF : out std_logic;
reset_INC : out std_logic;
reset_IND : out std_logic;
reset_INB : out std_logic;
reset_AUF : out std_logic;
reset_LFB : out std_logic;
reset_LFF : out std_logic;
reset_AUB : out std_logic;
reset_SRT : out std_logic;
reset_dcm_ROP : out std_logic;
reset_dcm_INF : out std_logic;
reset_dcm_INC : out std_logic;
reset_dcm_IND : out std_logic;
reset_dcm_INB : out std_logic;
reset_dcm_AUF : out std_logic;
reset_dcm_LFB : out std_logic;
reset_dcm_LFF : out std_logic;
reset_dcm_AUB : out std_logic;
reset_dcm_SRT : out std_logic;
-- Direct Configuration of FPGA chips via VME - not of Proms
v_nprog_INF : out std_logic; -- normal output
v_cclk_INF : out std_logic; -- tri state output
v_din_INF : out std_logic; -- tri state output
v_ninit_INF : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_INF : in std_logic;
v_nprog_INC : out std_logic; -- normal output
v_cclk_INC : out std_logic; -- tri state output
v_din_INC : out std_logic; -- tri state output
v_ninit_INC : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_INC : in std_logic;
v_nprog_IND : out std_logic; -- normal output
v_cclk_IND : out std_logic; -- tri state output
v_din_IND : out std_logic; -- tri state output
v_ninit_IND : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_IND : in std_logic;
v_nprog_INB : out std_logic; -- normal output
v_cclk_INB : out std_logic; -- tri state output
v_din_INB : out std_logic; -- tri state output
v_ninit_INB : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_INB : in std_logic;
v_nprog_AUF : out std_logic; -- normal output
v_cclk_AUF : out std_logic; -- tri state output
v_din_AUF : out std_logic; -- tri state output
v_ninit_AUF : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_AUF : in std_logic;
v_nprog_LFF : out std_logic; -- normal output
v_cclk_LFF : out std_logic; -- tri state output
v_din_LFF : out std_logic; -- tri state output
v_ninit_LFF : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_LFF : in std_logic;
v_nprog_LFB : out std_logic; -- normal output
v_cclk_LFB : out std_logic; -- tri state output
v_din_LFB : out std_logic; -- tri state output
v_ninit_LFB : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_LFB : in std_logic;
v_nprog_AUB : out std_logic; -- normal output
v_cclk_AUB : out std_logic; -- tri state output
v_din_AUB : out std_logic; -- tri state output
v_ninit_AUB : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_AUB : in std_logic;
v_nprog_SRT : out std_logic; -- normal output
v_cclk_SRT : out std_logic; -- tri state output
v_din_SRT : out std_logic; -- tri state output
v_ninit_SRT : inout std_logic; -- BIDIRECTIONAL with tristate output
v_done_SRT : in std_logic;
-- VME port
vme_addr : in std_logic_vector;
vme_data : in std_logic_vector;
vme_en : in std_logic;
vme_wr : in std_logic;
vme_data_out : out std_logic_vector(15 downto 0);
vme_en_out : out std_logic;
-- Clock and control
clk : in std_logic;
reset : in std_logic;
-- added by Tobias Noebauer: BCres from backplane to forward to AUF and AUB
BCres : in std_logic
);
end;
architecture behavioral of ROPBoardControl is
attribute syn_useioff : boolean;
attribute syn_useioff of behavioral : architecture is true;
-- status registers
signal done_status : std_logic_vector(15 downto 0);
signal dcm_locked_status : std_logic_vector(15 downto 0);
signal status0 : std_logic_vector(15 downto 0);
signal status1 : std_logic_vector(15 downto 0);
signal dummy_cmd : std_logic_vector(15 downto 0);
signal init_status : std_logic_vector(15 downto 0);
-- command registers
signal prog_enable : std_logic_vector(15 downto 0);
signal nprog_cmd : std_logic_vector(15 downto 0);
signal init_cmd : std_logic_vector(15 downto 0);
signal reset_cmd : std_logic_vector(15 downto 0);
signal reset_dcm_cmd : std_logic_vector(15 downto 0);
signal command_cmd : std_logic_vector(15 downto 0);
signal ready_from_SW, busy_from_SW : std_logic;
signal stat_gmt_i : std_logic_vector(3 downto 0);
-- VME Mux
signal vme_data_out_i : TVMEData_vec (0 to 11);
signal vme_en_out_i : TVMEEnable_vec (0 to 11);
begin
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- FPGA programming via VME
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- programming:
-- ============
-- nprog is used to start programming
-- rising edge on prog_b of the FPGA starts configuration
-- the FPGA then drives init_b low while it clears the configuration
-- configuration can be delayed by driving init_b low extrenally.
-- configuration mode pins are sampled when when init_b transitions to high
-- afterwards, configuration via clock and data starts
-----------------------------------------------------------------------------
--* program enable command register
-----------------------------------------------------------------------------
prog_enable_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => ROP_prog_enable_addr)
port map (
data => prog_enable, reset => reset,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(0),
vme_en_out => vme_en_out_i(0),
vme_clk => clk);
-----------------------------------------------------------------------------
--* nprog command register
-----------------------------------------------------------------------------
nprog_reg: entity work.VMEReg
generic map (
init_val => "1111111111111111",
my_vme_base_address => ROP_nprog_addr)
port map (
data => nprog_cmd, reset => reset,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(1),
vme_en_out => vme_en_out_i(1),
vme_clk => clk);
v_nprog_SRT <= nprog_cmd(9); v_nprog_AUB <= nprog_cmd(8);
v_nprog_LFB <= nprog_cmd(7); v_nprog_LFF <= nprog_cmd(6);
v_nprog_AUF <= nprog_cmd(5); v_nprog_INB <= nprog_cmd(4);
v_nprog_IND <= nprog_cmd(3); v_nprog_INC <= nprog_cmd(2);
v_nprog_INF <= nprog_cmd(1);
-----------------------------------------------------------------------------
--* init command register
-----------------------------------------------------------------------------
init_cmd_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => ROP_init_cmd_addr)
port map (
data => init_cmd, reset => reset,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(2),
vme_en_out => vme_en_out_i(2),
vme_clk => clk);
-- NOTE: writing a 1 to the register forces init to low
v_ninit_INF <= '0' when init_cmd(1) = '1' else 'Z';
v_ninit_INC <= '0' when init_cmd(2) = '1' else 'Z';
v_ninit_IND <= '0' when init_cmd(3) = '1' else 'Z';
v_ninit_INB <= '0' when init_cmd(4) = '1' else 'Z';
v_ninit_AUF <= '0' when init_cmd(5) = '1' else 'Z';
v_ninit_LFF <= '0' when init_cmd(6) = '1' else 'Z';
v_ninit_LFB <= '0' when init_cmd(7) = '1' else 'Z';
v_ninit_AUB <= '0' when init_cmd(8) = '1' else 'Z';
v_ninit_SRT <= '0' when init_cmd(9) = '1' else 'Z';
-----------------------------------------------------------------------------
--* init status status register
-----------------------------------------------------------------------------
init_status <= not ("111111" & v_ninit_SRT & v_ninit_AUB &
v_ninit_LFB & v_ninit_LFF & v_ninit_AUF & v_ninit_INB &
v_ninit_IND & v_ninit_INC & v_ninit_INF & '1');
init_status_reg: entity work.VMEStatusReg
generic map (my_vme_base_address => ROP_init_status_raddr)
port map (
data => init_status,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(3),
vme_en_out => vme_en_out_i(3),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* programming done status register
-----------------------------------------------------------------------------
done_status <= "000000" & v_done_SRT & v_done_AUB &
v_done_LFB & v_done_LFF & v_done_AUF & v_done_INB &
v_done_IND & v_done_INC & v_done_INF & '0';
done_reg: entity work.VMEStatusReg
generic map (my_vme_base_address => ROP_done_raddr)
port map (
data => done_status,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(4),
vme_en_out => vme_en_out_i(4),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* din registers. generate a clock pulse when written. only bit 0 is used.
-----------------------------------------------------------------------------
prg_INF: entity work.ROPProgPulseRegister generic map ( address => ROP_din_INF_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(1), clk => clk, din => v_din_INF, cclk => v_cclk_INF);
prg_INC: entity work.ROPProgPulseRegister generic map ( address => ROP_din_INC_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(2), clk => clk, din => v_din_INC, cclk => v_cclk_INC);
prg_IND: entity work.ROPProgPulseRegister generic map ( address => ROP_din_IND_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(3), clk => clk, din => v_din_IND, cclk => v_cclk_IND);
prg_INB: entity work.ROPProgPulseRegister generic map ( address => ROP_din_INB_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(4), clk => clk, din => v_din_INB, cclk => v_cclk_INB);
prg_AUF: entity work.ROPProgPulseRegister generic map ( address => ROP_din_AUF_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(5), clk => clk, din => v_din_AUF, cclk => v_cclk_AUF);
prg_LFF: entity work.ROPProgPulseRegister generic map ( address => ROP_din_LFF_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(6), clk => clk, din => v_din_LFF, cclk => v_cclk_LFF);
prg_LFB: entity work.ROPProgPulseRegister generic map ( address => ROP_din_LFB_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(7), clk => clk, din => v_din_LFB, cclk => v_cclk_LFB);
prg_AUB: entity work.ROPProgPulseRegister generic map ( address => ROP_din_AUB_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(8), clk => clk, din => v_din_AUB, cclk => v_cclk_AUB);
prg_SRT: entity work.ROPProgPulseRegister generic map ( address => ROP_din_SRT_addr )
port map (vme_addr => vme_addr, vme_data0 => vme_data(0), vme_en => vme_en, vme_wr => vme_wr,
enable => prog_enable(9), clk => clk, din => v_din_SRT, cclk => v_cclk_SRT);
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- other status and command registers
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----------------------------------------------------------------------------
--* DCM locked register
-----------------------------------------------------------------------------
dcm_locked_status <= "000000" & dcm_locked_SRT & dcm_locked_AUB &
dcm_locked_LFB & dcm_locked_LFF & dcm_locked_AUF & dcm_locked_INB &
dcm_locked_IND & dcm_locked_INC & dcm_locked_INF & dcm_locked_ROP;
dcm_locked_reg: entity work.VMEStatusReg
generic map (my_vme_base_address => ROP_dcm_locked_raddr)
port map (
data => dcm_locked_status,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(5),
vme_en_out => vme_en_out_i(5),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* Status registers
-----------------------------------------------------------------------------
status0 <= "000000" & status_SRT(0) & status_AUB(0) &
status_LFB(0) & status_LFF(0) & status_AUF(0) & status_INB(0) &
status_IND(0) & status_INC(0) & status_INF(0) & status_ROP(0);
status1 <= "000000" & status_SRT(1) & status_AUB(1) &
status_LFB(1) & status_LFF(1) & status_AUF(1) & status_INB(1) &
status_IND(1) & status_INC(1) & status_INF(1) & status_ROP(1);
status0_reg: entity work.VMEStatusReg
generic map (my_vme_base_address => ROP_status0_raddr)
port map (
data => status0,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(6),
vme_en_out => vme_en_out_i(6),
vme_clk => clk,
reset => reset);
status1_reg: entity work.VMEStatusReg
generic map (my_vme_base_address => ROP_status1_raddr)
port map (
data => status0,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(7),
vme_en_out => vme_en_out_i(7),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* dummy command register
--* if bit 10 set: send BCres to AUF instead of value of bit 5
--* if bit 11 set: send BCres to AUB instead of value of bit 8
-----------------------------------------------------------------------------
dummy_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => ROP_dummy_cmd_addr)
port map (
data => dummy_cmd,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(8),
vme_en_out => vme_en_out_i(8),
vme_clk => clk,
reset => reset);
-- added by Tobias Noebauer: if bit 10 (11) of ROP_dummy_cmd_addr is set,
-- send 'real' BCres to AUF (AUB) instead of value of bit 5 (8)
dummy_AUF <= BCres when dummy_cmd(10) = '1' else dummy_cmd(5);
dummy_AUB <= BCres when dummy_cmd(11) = '1' else dummy_cmd(8);
dummy_SRT <= dummy_cmd(9);
-- removed by TN: dummy_AUB <= dummy_cmd(8);
dummy_LFB <= dummy_cmd(7);
dummy_LFF <= dummy_cmd(6);
-- removed by TN: dummy_AUF <= dummy_cmd(5);
dummy_INB <= dummy_cmd(4);
dummy_IND <= dummy_cmd(3);
dummy_INC <= dummy_cmd(2);
dummy_INF <= dummy_cmd(1);
dummy_ROP <= dummy_cmd(0);
-----------------------------------------------------------------------------
--* reset command register
-----------------------------------------------------------------------------
reset_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => ROP_reset_addr)
port map (
data => reset_cmd,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(9),
vme_en_out => vme_en_out_i(9),
vme_clk => clk,
reset => reset);
reset_SRT <= reset_cmd(9); reset_AUB <= reset_cmd(8);
reset_LFB <= reset_cmd(7); reset_LFF <= reset_cmd(6);
reset_AUF <= reset_cmd(5); reset_INB <= reset_cmd(4);
reset_IND <= reset_cmd(3); reset_INC <= reset_cmd(2);
reset_INF <= reset_cmd(1); reset_ROP <= reset_cmd(0);
-----------------------------------------------------------------------------
--* reset_dcm command register
-----------------------------------------------------------------------------
reset_dcm_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => ROP_reset_dcm_addr)
port map (
data => reset_dcm_cmd,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(10),
vme_en_out => vme_en_out_i(10),
vme_clk => clk,
reset => reset);
reset_dcm_SRT <= reset_dcm_cmd(9); reset_dcm_AUB <= reset_dcm_cmd(8);
reset_dcm_LFB <= reset_dcm_cmd(7); reset_dcm_LFF <= reset_dcm_cmd(6);
reset_dcm_AUF <= reset_dcm_cmd(5); reset_dcm_INB <= reset_dcm_cmd(4);
reset_dcm_IND <= reset_dcm_cmd(3); reset_dcm_INC <= reset_dcm_cmd(2);
reset_dcm_INF <= reset_dcm_cmd(1); reset_dcm_ROP <= reset_dcm_cmd(0);
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Combined GMT Status output
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----------------------------------------------------------------------------
--* command register
-----------------------------------------------------------------------------
command_reg: entity work.VMEReg
generic map (
init_val => "0000000000000000",
my_vme_base_address => ROP_command_addr)
port map (
data => command_cmd,
vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(11),
vme_en_out => vme_en_out_i(11),
vme_clk => clk,
reset => reset);
ready_from_SW <= command_cmd(0);
busy_from_SW <= command_cmd(1);
-----------------------------------------------------------------------------
--* combine status of chips to GMT status
-----------------------------------------------------------------------------
status_combination: entity work.ROPCombineStatus
port map (
dcm_locked_ROP => dcm_locked_ROP, status_ROP => status_ROP,
dcm_locked_INF => dcm_locked_INF, status_INF => status_INF,
dcm_locked_INC => dcm_locked_INC, status_INC => status_INC,
dcm_locked_IND => dcm_locked_IND, status_IND => status_IND,
dcm_locked_INB => dcm_locked_INB, status_INB => status_INB,
dcm_locked_AUF => dcm_locked_AUF, status_AUF => status_AUF,
dcm_locked_LFF => dcm_locked_LFF, status_LFF => status_LFF,
dcm_locked_LFB => dcm_locked_LFB, status_LFB => status_LFB,
dcm_locked_AUB => dcm_locked_AUB, status_AUB => status_AUB,
dcm_locked_SRT => dcm_locked_SRT, status_SRT => status_SRT,
STAT_GMT => stat_gmt_i,
busy_from_SW => busy_from_SW,
ready_from_SW => ready_from_SW,
clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* register GMT status
-----------------------------------------------------------------------------
register_status: process (clk) is
begin
if clk'event and clk = '1' then -- rising clock edge
STAT_GMT <= stat_gmt_i;
end if;
end process register_status;
-- multiplex vme_data_output
mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out, vme_en_out);
end architecture behavioral;