-- PROJECT: D0 Run IIb Trigger L1 Calorimeter upgrade -- -- MODULE: Channel Link Receiver Test Card -- -- ELEMENT: ChalinkR -- -- DESCRIPTION: Channel Link Receiver Tester. -- This is designed to fit in a Virtex II -- evaluation kit (Memec Design) that has a XC2V1000 FG256 -- chip on it. A custom mezzanine card equipped with a 48-bit -- Channel Link deserializer is plugged ontop of the kit. -- The ChalinkR_FPGA component adds all the I/O pads to the -- ChalinkR component. -- -- AUTHOR: D. Calvet calvet@hep.saclay.cea.fr -- -- DATE AND HISTORY: -- June 2003 : created -- March 2004: added logic to capture the address where data is being written -- upon a trigger. This helps to locate the word that caused a trigger. -- March 2004: Permanently Enable port B of RAMs. These were -- changed dynamically by the address decoding logic, but set to the wrong state. -- April 2004: added logic to generate local signals for FRAME and BX_COUNT -- bit pattern comparison is now be made on the 36-bit received -- -- April 2004: fixed De-multiplexing for we_ram signal: this was determined -- by the state of some address lines instead of the PAGE selection bits. -- Note that only data in page 0 to 3 can be written. Page 4 is the 9th bit -- of the 4 block RAMS; it cannot be written independently of the 8 other bits. -- -- August 2004: integrated frequency meter (B. Trincaz) -- -- September 2004: replaced single flip-flop on signal single_shot by 2 -- cascaded flip-flops. The number of word received was not always successfully -- captured by the logic. The bus signals are synchronous with the 24 MHz on-board -- clock while the received word counter is synchronous with RX_CLOCK (typ. 60 MHz). -- It is suspected that meta-stability was causing the loss of the capture pulse -- from time to time. -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; library unisim; use unisim.all; library work; use work.utility_pkg.all; -------------------------------------------------------------------------------- -- -- Channel Link Tester Logic -- ENTITY ChalinkR is port ( ----------------------------------------------------------------------- -- -- Miscellaneous signals -- RESET : in std_logic; -- Register RESET ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- LED indicators -- LED_USER : out std_logic; -- LED indicator ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Bus interface signals -- WE : in std_logic; -- Write Enable CS_B : in std_logic; -- Chip Select active low ADDR : in std_logic_vector(11 downto 0); -- Address bus DATA_IN : in std_logic_vector(7 downto 0); -- Data bus Input DATA_OUT : out std_logic_vector(7 downto 0); -- Data bus Output DATA_Z : out std_logic; -- Control High Z Data Bus WCLK : in std_logic; -- Write Clock DTACK_B : out std_logic; -- Data acknowledge active low ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Clock signals -- CLK_BC_PLL : out std_logic; -- BC clock ouptut for board level PLL CLK_BC_OUT : out std_logic; -- BC clock ouptut for board level distribution CLK_BC_IN : in std_logic; -- BC clock input from board level distribution CLK_BC4X_IN : in std_logic; -- BCX4 clock input from board level distribution ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Channel Link Deserializer interface signals -- RX_CLK : in std_logic; -- Received clock RX_DATA : in std_logic_vector(35 downto 0); -- Received data ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- SCL interface cable signals -- ----------------------------------------------------------------------- SCLIF_CLK7 : in std_logic; -- Bunch crossing clock input SCLIF_BUSY_B_OUT : out std_logic; -- Busy signal (active low) upstream ADF -> SCL receiver SCLIF_CMDU_OUT : out std_logic; -- Command upstream ADF's -> SCL receiver SCLIF_CMDD_IN : in std_logic; -- Command downstream ADF's <- SCL receiver SCLIF_ERR_B_OUT : out std_logic; -- Error signal (active low) upstream ADF -> SCL receiver SCLIF_STRIG_B : out std_logic; -- Self trigger ADF -> SCLIF SCLIF_SPARE : in std_logic; -- Spare wire ------------------------------------------------------------------------- -- Debug Port -- DBG_IN : in std_logic_vector(0 downto 0); -- Debug port Input pads DBG_OUT : out std_logic_vector(1 downto 0); -- Debug port Output pads ------------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Pins specific to debug implementation -- ----------------------------------------------------------------------- SCL_CLK : in std_logic -- (100 MHz clock from Evaluation Kit) ); END ChalinkR; architecture structure of ChalinkR is -- -- 16-bit LFSR -- component lfsr port ( RESET : in std_logic; -- Asynchronous RESET CLK : in std_logic; -- Clock SE : in std_logic; -- Synchronous Shift Enable LOAD_L : in std_logic; -- Load Lower byte of Seed LOAD_H : in std_logic; -- Load Higher byte of Seed SEED : in std_logic_vector(15 downto 0); -- Seed Q : out std_logic_vector(15 downto 0) -- Output ); end component; -- -- N bit register based on D-flip-flops with Write Enable and Asynch preset -- component cha_reg generic( REG_WIDTH : NATURAL := 16 ); port ( PRESET : IN std_logic; -- Register PRESET CLK : IN std_logic; -- Clock PRE : IN std_logic_vector((REG_WIDTH-1) downto 0); -- Preset values DAI : IN std_logic_vector((REG_WIDTH-1) downto 0); -- Data Input bus WE : IN std_logic; -- Write Enable register Q : OUT std_logic_VECTOR((REG_WIDTH-1) downto 0) -- Content of register ); END component; -- -- Frequency_meter -- component freq port( RESET : in std_logic; -- RESET CLK_REF : in std_logic; -- HORLOGE CLK_X : in std_logic; -- SIGNAL DONT LA FREQUENCE VARIE F_OUT : out std_logic_vector(15 downto 0); -- SIGNAL DE SORTIE CODE SUR 16 BITS HOLD_B : in std_logic -- SIGNAL PERMETTANT LA LECTURE SUR LE BUS ); end component; -- -- N bit saturating counter with Asynchronous RESET -- and synchronous count enable -- component cnt_sat generic( LENG : INTEGER := 8 ); port ( RESET : in std_logic; -- Asynchronous RESET CE : in std_logic; -- Count Enable CLK : in std_logic; -- Clock Q : out std_logic_vector((LENG-1) downto 0) -- Output ); end component; -- -- General Control State Machine -- component gen_ctrl port ( RESET : in std_logic; -- Reset MODE : in std_logic; -- Mode of Tester STOP_CTRL : in std_logic; -- Control mode for stop CLK : in std_logic; -- Clock CAPTURE_COUNT : in std_logic_vector(11 downto 0); -- Number of words to capture after trigger ARM_TRIGGER : in std_logic; -- Pulse to arm trigger TRIGGER : in std_logic; -- Pulse to trigger ABORT_RUN : in std_logic; -- Pulse to abort run ERR_DETECTED : in std_logic; -- Receive Bit Error detected RAM_ADDR : out std_logic_vector(10 downto 0); -- RAM address STATE_RESET : out std_logic; -- Internal state STATE_ARMED : out std_logic; -- Internal state STATE_RUNNING : out std_logic; -- Internal state STATE_STOPPED : out std_logic -- Internal state ); end component; -- -- Trigger -- component trigger generic ( SIZE : NATURAL := 8 ); port ( ----------------------------------------------------------------------- RESET : in std_logic; -- Reset CLK : in std_logic; -- Clock ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Inputs -- DATA : in std_logic_vector((SIZE-1) downto 0); -- Data MATCH : in std_logic_vector((SIZE-1) downto 0); -- Match MASK : in std_logic_vector((SIZE-1) downto 0); -- Mask FORCE : in std_logic; -- To force a match ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Output -- TRIG : out std_logic -- Indicates a match ----------------------------------------------------------------------- ); END component; -- -- Module: SelectRAM_A9_B9 -- -- Description: VHDL instantiation template -- Block SelectRAM -- Dual Port A:2048 x 9 bits & B:2048 x 9 bits -- -- Device: VIRTEX-II Family ------------------------------------------------------------------------------------------- component RAMB16_S9_S9 -- pragma translate_off generic ( -- "Read during Write" attribute for functional simulation WRITE_MODE_A : string := "WRITE_FIRST" ; -- WRITE_FIRST(default)/ READ_FIRST/ NO_CHANGE WRITE_MODE_B : string := "WRITE_FIRST"; -- WRITE_FIRST(default)/ READ_FIRST/ NO_CHANGE INIT_A : bit_vector := "000000000"; -- changed by DC from X"000" so that it is exactly 9 bits SRVAL_A : bit_vector := "000000000"; -- changed by DC from X"000" so that it is exactly 9 bits INIT_B : bit_vector := "000000000"; -- changed by DC from X"000" so that it is exactly 9 bits SRVAL_B : bit_vector := "000000000"; -- changed by DC from X"000" so that it is exactly 9 bits -- RAM initialization ("0" by default) for functional simulation: see example INIT_00 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_01 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_02 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_03 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_04 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_05 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_06 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_07 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_08 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_09 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_0A : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_0B : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_0C : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_0D : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_0E : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_0F : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_10 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_11 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_12 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_13 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_14 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_15 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_16 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_17 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_18 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_19 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_1A : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_1B : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_1C : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_1D : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_1E : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_1F : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_20 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_21 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_22 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_23 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_24 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_25 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_26 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_27 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_28 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_29 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_2A : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_2B : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_2C : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_2D : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_2E : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_2F : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_30 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_31 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_32 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_33 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_34 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_35 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_36 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_37 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_38 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_39 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_3A : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_3B : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_3C : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_3D : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_3E : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INIT_3F : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_00 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_01 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_02 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_03 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_04 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_05 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_06 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; INITP_07 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000" ); -- pragma translate_on port ( DIA : in std_logic_vector (7 downto 0); DIPA : in std_logic_vector (0 downto 0); ADDRA : in std_logic_vector (10 downto 0); ENA : in std_logic; WEA : in std_logic; SSRA : in std_logic; CLKA : in std_logic; DOA : out std_logic_vector (7 downto 0); DOPA : out std_logic_vector (0 downto 0); -- DIB : in std_logic_vector (7 downto 0); DIPB : in std_logic_vector (0 downto 0); ADDRB : in std_logic_vector (10 downto 0); ENB : in std_logic; WEB : in std_logic; SSRB : in std_logic; CLKB : in std_logic; DOB : out std_logic_vector (7 downto 0); DOPB : out std_logic_vector (0 downto 0) ); end component; signal wa_cs_b : std_logic; signal rx_in : std_logic_vector(31 downto 0); -- Received data signal rx_bc : std_logic; -- received Beam Crossing count signal rx_fr : std_logic; -- received FRAME signal signal rx_fr_8_10 : std_logic; -- received FR_8_10 signal signal rx_par : std_logic; -- received parity signal rx_data_l : std_logic_vector(35 downto 0); -- Received data latched signal rx_data_l_d : std_logic_vector(35 downto 0); -- Received data latched delayed 1 signal rx_data_l_dd : std_logic_vector(35 downto 0); -- Received data latched delayed 2 signal exp_par : std_logic; -- expected parity -- First 1/4 RAM signal ram_ll_dipa : std_logic_vector(0 downto 0); -- RAM LL data input parity A signal ram_ll_addra : std_logic_vector(10 downto 0); -- RAM LL address A signal ram_ll_ena : std_logic; -- RAM LL Enable A signal ram_ll_wea : std_logic; -- RAM LL Write Enable A signal ram_ll_ssra : std_logic; -- RAM LL SSRA signal ram_ll_doa : std_logic_vector(7 downto 0); -- RAM LL data ouptut A signal ram_ll_dopa : std_logic_vector(0 downto 0); -- RAM LL data parity output A signal ram_ll_dib : std_logic_vector(7 downto 0); -- RAM LL data input B signal ram_ll_dipb : std_logic_vector(0 downto 0); -- RAM LL data input parity B signal ram_ll_addrb : std_logic_vector(10 downto 0); -- RAM LL address B signal ram_ll_enb : std_logic; -- RAM LL Enable B signal ram_ll_web : std_logic; -- RAM LL Write Enable B signal ram_ll_ssrb : std_logic; -- RAM LL SSRB signal ram_ll_dob : std_logic_vector(7 downto 0); -- RAM LL data ouptut B signal ram_ll_dopb : std_logic_vector(0 downto 0); -- RAM LL data parity output B -- Second 1/4 RAM signal ram_lh_dipa : std_logic_vector(0 downto 0); -- RAM LH data input parity A signal ram_lh_addra : std_logic_vector(10 downto 0); -- RAM LH address A signal ram_lh_ena : std_logic; -- RAM LH Enable A signal ram_lh_wea : std_logic; -- RAM LH Write Enable A signal ram_lh_ssra : std_logic; -- RAM LH SSRA signal ram_lh_doa : std_logic_vector(7 downto 0); -- RAM LH data ouptut A signal ram_lh_dopa : std_logic_vector(0 downto 0); -- RAM LH data parity output A signal ram_lh_dib : std_logic_vector(7 downto 0); -- RAM LH data input B signal ram_lh_dipb : std_logic_vector(0 downto 0); -- RAM LH data input parity B signal ram_lh_addrb : std_logic_vector(10 downto 0); -- RAM LH address B signal ram_lh_enb : std_logic; -- RAM LH Enable B signal ram_lh_web : std_logic; -- RAM LH Write Enable B signal ram_lh_ssrb : std_logic; -- RAM LH SSRB signal ram_lh_dob : std_logic_vector(7 downto 0); -- RAM LH data ouptut B signal ram_lh_dopb : std_logic_vector(0 downto 0); -- RAM LH data parity output B -- Third 1/4 RAM signal ram_hl_dipa : std_logic_vector(0 downto 0); -- RAM HL data input parity A signal ram_hl_addra : std_logic_vector(10 downto 0); -- RAM HL address A signal ram_hl_ena : std_logic; -- RAM HL Enable A signal ram_hl_wea : std_logic; -- RAM HL Write Enable A signal ram_hl_ssra : std_logic; -- RAM HL SSRA signal ram_hl_doa : std_logic_vector(7 downto 0); -- RAM HL data ouptut A signal ram_hl_dopa : std_logic_vector(0 downto 0); -- RAM HL data parity output A signal ram_hl_dib : std_logic_vector(7 downto 0); -- RAM HL data input B signal ram_hl_dipb : std_logic_vector(0 downto 0); -- RAM HL data input parity B signal ram_hl_addrb : std_logic_vector(10 downto 0); -- RAM HL address B signal ram_hl_enb : std_logic; -- RAM HL Enable B signal ram_hl_web : std_logic; -- RAM HL Write Enable B signal ram_hl_ssrb : std_logic; -- RAM HL SSRB signal ram_hl_dob : std_logic_vector(7 downto 0); -- RAM HL data ouptut B signal ram_hl_dopb : std_logic_vector(0 downto 0); -- RAM HL data parity output B -- Fourth 1/4 RAM signal ram_hh_dipa : std_logic_vector(0 downto 0); -- RAM HH data input parity A signal ram_hh_addra : std_logic_vector(10 downto 0); -- RAM HH address A signal ram_hh_ena : std_logic; -- RAM HH Enable A signal ram_hh_wea : std_logic; -- RAM HH Write Enable A signal ram_hh_ssra : std_logic; -- RAM HH SSRA signal ram_hh_doa : std_logic_vector(7 downto 0); -- RAM HH data ouptut A signal ram_hh_dopa : std_logic_vector(0 downto 0); -- RAM HH data parity output A signal ram_hh_dib : std_logic_vector(7 downto 0); -- RAM HH data input B signal ram_hh_dipb : std_logic_vector(0 downto 0); -- RAM HH data input parity B signal ram_hh_addrb : std_logic_vector(10 downto 0); -- RAM HH address B signal ram_hh_enb : std_logic; -- RAM HH Enable B signal ram_hh_web : std_logic; -- RAM HH Write Enable B signal ram_hh_ssrb : std_logic; -- RAM HH SSRB signal ram_hh_dob : std_logic_vector(7 downto 0); -- RAM HH data ouptut B signal ram_hh_dopb : std_logic_vector(0 downto 0); -- RAM HH data parity output B signal reg_data_out : std_logic_vector(7 downto 0); -- Data output of all registers signal ram_data_out : std_logic_vector(7 downto 0); -- Data output of all RAMs signal we_reg : std_logic; -- WE for registers signal we_ram : std_logic; -- WE for RAMs signal reset_s_h : std_logic; -- Soft or Hard RESET signal ram_wr_addr : std_logic_vector(10 downto 0); -- RAM write address counter -- -- Internal state of tester -- signal sta_reset : std_logic; -- State RESET signal sta_armed : std_logic; -- State ARMED signal sta_running : std_logic; -- State RUNNING signal sta_stopped : std_logic; -- State STOPPED -- -- Register bits -- signal bit_mode : std_logic; -- Mode signal bit_stop_ctrl : std_logic; -- Stop on error control bit signal bits_page : std_logic_vector(2 downto 0); -- Memory Page selection signal bit_soft_reset : std_logic; -- Soft RESET signal bit_arm_trig : std_logic; -- Arm trigger signal bit_force_trig : std_logic; -- Force trigger signal bit_abort : std_logic; -- Abort run signal word_to_cap : std_logic_vector(11 downto 0); -- number of words to capture -- -- Registers -- signal reg_A : std_logic_vector(7 downto 0); -- Mode and Page register signal reg_A_preset : std_logic_vector(7 downto 0); -- Value on Preset signal reg_A_we : std_logic; -- Write enable signal reg_B : std_logic_vector(3 downto 0); -- Trigger control register signal reg_B_preset : std_logic_vector(3 downto 0); -- Value on Preset signal reg_B_we : std_logic; -- Write enable signal reg_C : std_logic_vector(7 downto 0); -- Word to Capture Count (Low) register signal reg_C_preset : std_logic_vector(7 downto 0); -- Value on Preset signal reg_C_we : std_logic; -- Write enable signal reg_D : std_logic_vector(7 downto 0); -- Word to Capture Count (High) register signal reg_D_preset : std_logic_vector(7 downto 0); -- Value on Preset signal reg_D_we : std_logic; -- Write enable signal reg_CD_we : std_logic; -- Write Enable for register C or D signal reg_CD : std_logic_vector(7 downto 0); -- Register C or D content on bus -- -- Trigger pattern and mask -- signal trigger_pat_we : std_logic; -- write enable for one trigger pattern byte among all signal trig_pattern : std_logic_vector(39 downto 0); -- trigger pattern data signal trig_pattern_bus: std_logic_vector(7 downto 0); -- trigger pattern data on output bus signal trig_pattern_pre: std_logic_vector(39 downto 0); -- trigger pattern preset data signal trig_pattern_we : std_logic_vector(4 downto 0); -- trigger pattern write enable signal trigger_msk_we : std_logic; -- write enable for one trigger mask byte among all signal trig_mask : std_logic_vector(39 downto 0); -- trigger mask data signal trig_mask_bus : std_logic_vector(7 downto 0); -- trigger mask data on output bus signal trig_mask_pre : std_logic_vector(39 downto 0); -- trigger mask preset data signal trig_mask_we : std_logic_vector(4 downto 0); -- trigger mask write enable signal trig_data : std_logic_vector(36 downto 0); -- trigger data: external input + 36 bit received data -- -- LFSR seeds and control -- signal lfsr_load : std_logic; -- Load signal for one LFSRs among all signal lfsr_seed : std_logic_vector(15 downto 0); -- 16 bit LFSR Seed signal lfsr_seed_bus : std_logic_vector(7 downto 0); -- LFSR Seed byte from data bus signal lfsr_out : std_logic_vector(511 downto 0); -- 32 x 16 bit LFSR output signal lfsr_out_bus : std_logic_vector(7 downto 0); -- LFSR output on bus signal lfsr_seed_l_ld : std_logic_vector(31 downto 0); -- LFSR seed load enable for lower byte signal lfsr_seed_h_ld : std_logic_vector(31 downto 0); -- LFSR seed load enable for higher byte signal lfsr_se : std_logic; -- LFSR shift Enable -- -- Bit Error counters -- signal cnt_err : std_logic_vector(287 downto 0); -- 36 x 8 bit counter signal cnt_err_bus : std_logic_vector(7 downto 0); -- error counter on output bus signal err_detected : std_logic_vector(35 downto 0); -- error detected signal bit_ref : std_logic_vector(35 downto 0); -- expected bit pattern signal err_detected_ored: std_logic; -- or of all bits of err_detected -- -- Received word counter -- signal cnt_rcv : std_logic_vector(47 downto 0); -- 48 bit counter signal cnt_rcv_latched : std_logic_vector(47 downto 0); -- 48 bit counter latched signal cnt_rcv_bus : std_logic_vector(7 downto 0); -- counter on output bus signal get_cnt_rcv : std_logic; signal single_shot : std_logic; signal single_shot_d : std_logic; -- -- Trigger -- signal trig : std_logic; -- trigger -- -- LED signals -- signal led_fast_blink : std_logic_vector(23 downto 0); -- RX_CLK divided by 2**24 gives 3.5 Hz from 60 MHz Rx clock signal led_slow_blink : std_logic_vector(24 downto 0); -- RX_CLK divided by 2**25 gives 0.7 Hz from 24 MHz clock -- -- Trigger position address -- signal trig_pos_addr : std_logic_vector(10 downto 0); -- RAM address (2K word = 11 bit) where trigger occured -- -- FRAME signals -- signal sr_frame : std_logic_vector(7 downto 0); -- 8 bit shift register to make a local FRAME signal signal exp_frame : std_logic; -- expected FRAME signal -- -- BX Counter related signals -- signal bx_dser : std_logic_vector(7 downto 0); -- 8 bit shift register to de-serialize BX counter signal signal bx_cnt_loc : std_logic_vector(10 downto 0); -- BX count local signal bx_cnt_loc_8b : std_logic_vector(7 downto 0); -- BX count local 8 upper bits signal bx_cnt_loc_sr : std_logic_vector(7 downto 0); -- BX count local serialized signal exp_bx_cnt : std_logic; -- Expected BX_CNT signal -- -- Signals for Frequencemeter -- signal frequency : std_logic_vector(15 downto 0); signal hold_b : std_logic; signal reading : std_logic; signal data_msb : std_logic; begin -- -- Capture RX_DATA bus -- Capture_RX_DATA : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then rx_in <= (others => '0'); rx_bc <= '0'; rx_fr <= '0'; rx_fr_8_10 <= '0'; rx_par <= '0'; elsif RX_CLK'event and RX_CLK = '1' then rx_in <= RX_DATA(31 downto 0); rx_bc <= RX_DATA(32); rx_fr_8_10 <= RX_DATA(33); rx_fr <= RX_DATA(34); rx_par <= RX_DATA(35); end if; end process; rx_data_l <= rx_par & rx_fr & rx_fr_8_10 & rx_bc & rx_in; -- -- Delay received data -- Delay_RX_DATA: process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then rx_data_l_d <= (others => '0'); rx_data_l_dd <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then rx_data_l_dd <= rx_data_l_d; rx_data_l_d <= rx_data_l; end if; end process; -- -- SCLIF signals -- unused at present -- SCLIF_BUSY_B_OUT <= '1'; SCLIF_CMDU_OUT <= '0'; SCLIF_ERR_B_OUT <= '1'; SCLIF_STRIG_B <= '1'; -- -- Clock Generation -- CLK_BC_PLL <= SCLIF_CLK7; CLK_BC_OUT <= SCLIF_CLK7; -- -- Debug Port -- --DBG_OUT(0) <= DBG_IN(0); --DBG_OUT(0) <= ram_ll_web or ram_lh_web or ram_hl_web or ram_hh_web; --DBG_OUT(1) <= SCLIF_CMDD_IN and SCLIF_SPARE and SCL_CLK and CLK_BC4X_IN and CLK_BC_IN; --DBG_OUT(1) <= CS_B; DBG_OUT(0) <= rx_data_l_d(34); DBG_OUT(1) <= data_msb; -- -- Soft or Hard reset -- reset_s_h <= RESET or bit_soft_reset; -- -- First 1/4 of the memory of the tester -- Holds channel 0 to 7 and 1 control bit -- Tester_RAM_LL: RAMB16_S9_S9 -- pragma translate_off -- pragma translate_on port map ( DIA => rx_in(7 downto 0), DIPA => ram_ll_dipa, ADDRA => ram_ll_addra, ENA => ram_ll_ena, WEA => ram_ll_wea, SSRA => ram_ll_ssra, CLKA => RX_CLK, DOA => ram_ll_doa, DOPA => ram_ll_dopa, -- DIB => ram_ll_dib, DIPB => ram_ll_dipb, ADDRB => ram_ll_addrb, ENB => ram_ll_enb, WEB => ram_ll_web, SSRB => ram_ll_ssrb, CLKB => WCLK, DOB => ram_ll_dob, DOPB => ram_ll_dopb ); ram_ll_dipa(0) <= rx_bc; ram_ll_ssra <= '0'; ram_ll_ssrb <= '0'; ram_ll_dib <= DATA_IN; ram_ll_dipb <= "0"; -- cannot write to this bit only ram_ll_addrb <= ADDR(10 downto 0); -- -- Second 1/4 of the memory of the tester -- Holds channel 15 to 8 and 1 control bit -- Tester_RAM_LH: RAMB16_S9_S9 -- pragma translate_off -- pragma translate_on port map ( DIA => rx_in(15 downto 8), DIPA => ram_lh_dipa, ADDRA => ram_lh_addra, ENA => ram_lh_ena, WEA => ram_lh_wea, SSRA => ram_lh_ssra, CLKA => RX_CLK, DOA => ram_lh_doa, DOPA => ram_lh_dopa, -- DIB => ram_lh_dib, DIPB => ram_lh_dipb, ADDRB => ram_lh_addrb, ENB => ram_lh_enb, WEB => ram_lh_web, SSRB => ram_lh_ssrb, CLKB => WCLK, DOB => ram_lh_dob, DOPB => ram_lh_dopb ); ram_lh_dipa(0) <= rx_fr_8_10; ram_lh_ssra <= '0'; ram_lh_ssrb <= '0'; ram_lh_dib <= DATA_IN; ram_lh_dipb <= "0"; -- cannot write to this bit only ram_lh_addrb <= ADDR(10 downto 0); -- -- Third 1/4 of the memory of the tester -- Holds channel 23 to 16 and 1 control bit -- Tester_RAM_HL: RAMB16_S9_S9 -- pragma translate_off -- pragma translate_on port map ( DIA => rx_in(23 downto 16), DIPA => ram_hl_dipa, ADDRA => ram_hl_addra, ENA => ram_hl_ena, WEA => ram_hl_wea, SSRA => ram_hl_ssra, CLKA => RX_CLK, DOA => ram_hl_doa, DOPA => ram_hl_dopa, -- DIB => ram_hl_dib, DIPB => ram_hl_dipb, ADDRB => ram_hl_addrb, ENB => ram_hl_enb, WEB => ram_hl_web, SSRB => ram_hl_ssrb, CLKB => WCLK, DOB => ram_hl_dob, DOPB => ram_hl_dopb ); ram_hl_dipa(0) <= rx_fr; ram_hl_ssra <= '0'; ram_hl_ssrb <= '0'; ram_hl_dib <= DATA_IN; ram_hl_dipb <= "0"; -- cannot write to this bit only ram_hl_addrb <= ADDR(10 downto 0); -- -- Fourth 1/4 of the memory of the tester -- Holds channel 31 to 24 and 1 control bit -- Tester_RAM_HH: RAMB16_S9_S9 -- pragma translate_off -- pragma translate_on port map ( DIA => rx_in(31 downto 24), DIPA => ram_hh_dipa, ADDRA => ram_hh_addra, ENA => ram_hh_ena, WEA => ram_hh_wea, SSRA => ram_hh_ssra, CLKA => RX_CLK, DOA => ram_hh_doa, DOPA => ram_hh_dopa, -- DIB => ram_hh_dib, DIPB => ram_hh_dipb, ADDRB => ram_hh_addrb, ENB => ram_hh_enb, WEB => ram_hh_web, SSRB => ram_hh_ssrb, CLKB => WCLK, DOB => ram_hh_dob, DOPB => ram_hh_dopb ); ram_hh_dipa(0) <= rx_par; ram_hh_ssra <= '0'; ram_hh_ssrb <= '0'; ram_hh_dib <= DATA_IN; ram_hh_dipb <= "0"; -- cannot write to this bit only ram_hh_addrb <= ADDR(10 downto 0); -- -- Last stage of data output multiplexing -- Sets register content or tester RAM data depending on ADDR(11) -- Mux_Data_Out : process(ADDR(11), reg_data_out, ram_data_out) begin if ADDR(11) = '0' then DATA_OUT <= reg_data_out; else DATA_OUT <= ram_data_out; end if; end process; -- -- -- Logic_Data_Z : process(CS_B, WE) begin if CS_B = '0' and WE = '1' then DATA_Z <= '1'; else DATA_Z <= '0'; end if; end process; -- -- Multiplexing stage for data output of all RAMs -- Mux_RAM_Data_Out : process( CS_B, bits_page, ram_ll_dob, ram_ll_dopb, ram_lh_dob, ram_lh_dopb, ram_hl_dob, ram_hl_dopb, ram_hh_dob, ram_hh_dopb ) begin if CS_B = '0' then case bits_page is when "000" => ram_data_out <= ram_ll_dob; when "001" => ram_data_out <= ram_lh_dob; when "010" => ram_data_out <= ram_hl_dob; when "011" => ram_data_out <= ram_hh_dob; when "100" => ram_data_out <= "0000" & ram_hh_dopb(0 downto 0) & ram_hl_dopb(0 downto 0) & ram_lh_dopb(0 downto 0) & ram_ll_dopb(0 downto 0); when "101" => ram_data_out <= (others => '0'); -- unused when "110" => ram_data_out <= (others => '0'); -- unused when "111" => ram_data_out <= (others => '0'); -- unused when others => ram_data_out <= (others => '0'); end case; else ram_data_out <= (others => '0'); end if; end process; -- -- Multiplexing stage for data output of all registers -- Mux_reg_Data_Out : process( ADDR(10 downto 8), reg_A, reg_B, sta_reset, sta_armed, sta_running, sta_stopped, reg_CD, trig_pattern_bus, trig_mask_bus, lfsr_out_bus, cnt_err_bus, cnt_rcv_bus ) begin case ADDR(10 downto 8) is when "000" => reg_data_out <= reg_A; when "001" => reg_data_out <= sta_stopped & sta_running & sta_armed & sta_reset & reg_B; when "010" => reg_data_out <= reg_CD; when "011" => reg_data_out <= lfsr_out_bus; when "100" => reg_data_out <= cnt_err_bus; when "101" => reg_data_out <= trig_pattern_bus; when "110" => reg_data_out <= trig_mask_bus; when "111" => reg_data_out <= cnt_rcv_bus; when others => reg_data_out <= (others => '0'); end case; end process; -- -- Multiplexing stage for data output to bus of received word counter -- and Trigger position address word Mux_cnt_rcv_bus : process( ADDR(2 downto 0), cnt_rcv_latched, trig_pos_addr ) begin case ADDR(2 downto 0) is when "000" => cnt_rcv_bus <= cnt_rcv_latched(7 downto 0); when "001" => cnt_rcv_bus <= cnt_rcv_latched(15 downto 8); when "010" => cnt_rcv_bus <= cnt_rcv_latched(23 downto 16); when "011" => cnt_rcv_bus <= cnt_rcv_latched(31 downto 24); when "100" => cnt_rcv_bus <= cnt_rcv_latched(39 downto 32); when "101" => cnt_rcv_bus <= cnt_rcv_latched(47 downto 40); when "110" => cnt_rcv_bus <= trig_pos_addr(7 downto 0); when "111" => cnt_rcv_bus <= "00000" & trig_pos_addr(10 downto 8); when others => cnt_rcv_bus <= (others => '0'); end case; end process; -- -- Logic to capture the received word counter so that it is stable when read -- Logic_Single_Shot : process ( reset_s_h, RX_CLK) begin if reset_s_h = '1' then get_cnt_rcv <= '0'; single_shot_d <= '0'; single_shot <= '0'; elsif RX_CLK'event and RX_CLK = '1' then if CS_B = '0' and ADDR(11 downto 8) = "0111" and ADDR(2 downto 0) = "000" then get_cnt_rcv <= not single_shot_d; single_shot <= '1'; else single_shot <= '0'; end if; single_shot_d <= single_shot; end if; end process; -- -- Logic to capture the received word counter so that it is stable when read -- Capture_cnt_rcv : process ( reset_s_h, RX_CLK) begin if reset_s_h = '1' then cnt_rcv_latched <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then if get_cnt_rcv = '1' then cnt_rcv_latched <= cnt_rcv; end if; end if; end process; -- -- Multiplexing stage for data output to bus of trigger pattern -- Mux_trig_pattern_bus : process( ADDR(2 downto 0), trig_pattern ) begin case ADDR(2 downto 0) is when "000" => trig_pattern_bus <= trig_pattern(7 downto 0); when "001" => trig_pattern_bus <= trig_pattern(15 downto 8); when "010" => trig_pattern_bus <= trig_pattern(23 downto 16); when "011" => trig_pattern_bus <= trig_pattern(31 downto 24); when "100" => trig_pattern_bus <= trig_pattern(39 downto 32); -- 3 higher bit unused when "101" => trig_pattern_bus <= (others => '0'); when "110" => trig_pattern_bus <= (others => '0'); when "111" => trig_pattern_bus <= (others => '0'); when others => trig_pattern_bus <= (others => '0'); end case; end process; -- -- Multiplexing stage for data output to bus of trigger mask -- and frequency measured -- Mux_trig_mask_bus : process( ADDR(2 downto 0), trig_mask, frequency) begin case ADDR(2 downto 0) is when "000" => trig_mask_bus <= trig_mask(7 downto 0); when "001" => trig_mask_bus <= trig_mask(15 downto 8); when "010" => trig_mask_bus <= trig_mask(23 downto 16); when "011" => trig_mask_bus <= trig_mask(31 downto 24); when "100" => trig_mask_bus <= trig_mask(39 downto 32); -- 3 higher bit unused when "101" => trig_mask_bus <= (others => '0'); when "110" => trig_mask_bus <= frequency(7 downto 0); when "111" => trig_mask_bus <= frequency(15 downto 8); when others => trig_mask_bus <= (others => '0'); end case; end process; -- -- Multiplexing stage for output to bus of error counters -- Mux_cnt_err_bus : process( ADDR(5 downto 0), cnt_err ) variable cnt_value : std_logic_vector(7 downto 0); begin for i in 36 downto 0 loop if i= 36 then cnt_value := (others => '0'); else if Std_Logic_Vector_To_Natural(ADDR(5 downto 0)) = i then cnt_value := cnt_err(((8*(i+1))-1) downto (8*i)); end if; end if; end loop; cnt_err_bus <= cnt_value; end process; -- -- Multiplexing stage for output to bus of LFSR state -- Mux_lfsr_out_bus : process( ADDR(5 downto 0), lfsr_out ) variable lfsr_value : std_logic_vector(7 downto 0); begin for i in 64 downto 0 loop if i= 64 then lfsr_value := (others => '0'); else if Std_Logic_Vector_To_Natural(ADDR(5 downto 0)) = i then lfsr_value := lfsr_out(((8*(i+1))-1) downto (8*i)); end if; end if; end loop; lfsr_out_bus <= lfsr_value; end process; -- -- Multiplexing stage for data output to bus of desired number of words to capture -- Mux_reg_CD : process( ADDR(0), reg_C, reg_D ) begin if ADDR(0) = '0' then reg_CD <= reg_C; else reg_CD <= reg_D; end if; end process; -- -- First stage of de-multiplexing for WE signal -- Demux_WE : process(ADDR(11), WE) begin if ADDR(11) = '0' then we_reg <= WE; we_ram <= '0'; else we_reg <= '0'; we_ram <= WE; end if; end process; -- -- De-multiplexing for we_ram signal -- Demux_we_ram : process(CS_B, ADDR(11), bits_page, we_ram) begin if CS_B = '0' and ADDR(11) = '1' then case bits_page is when "000" => ram_ll_web <= we_ram; ram_lh_web <= '0'; ram_hl_web <= '0'; ram_hh_web <= '0'; when "001" => ram_ll_web <= '0'; ram_lh_web <= we_ram; ram_hl_web <= '0'; ram_hh_web <= '0'; when "010" => ram_ll_web <= '0'; ram_lh_web <= '0'; ram_hl_web <= we_ram; ram_hh_web <= '0'; when "011" => ram_ll_web <= '0'; ram_lh_web <= '0'; ram_hl_web <= '0'; ram_hh_web <= we_ram; when others => ram_ll_web <= '0'; ram_lh_web <= '0'; ram_hl_web <= '0'; ram_hh_web <= '0'; end case; else ram_ll_web <= '0'; ram_lh_web <= '0'; ram_hl_web <= '0'; ram_hh_web <= '0'; end if; end process; --ram_ll_web <= '0'; --ram_lh_web <= '0'; --ram_hl_web <= '0'; --ram_hh_web <= '0'; -- -- Permanently Enable port B of RAMs -- ram_ll_enb <= '1'; ram_lh_enb <= '1'; ram_hl_enb <= '1'; ram_hh_enb <= '1'; -- -- De-multiplexing for we_reg signal -- Demux_we_reg : process(CS_B, ADDR(10 downto 8), we_reg) begin if CS_B = '0' then case ADDR(10 downto 8) is when "000" => reg_A_we <= we_reg; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; when "001" => reg_A_we <= '0'; reg_B_we <= we_reg; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; when "010" => reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= we_reg; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; when "011" => reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= we_reg; trigger_pat_we <= '0'; trigger_msk_we <= '0'; when "100" => -- Error Counters are Read Only reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; when "101" => reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= we_reg; trigger_msk_we <= '0'; when "110" => reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= we_reg; when "111" => -- Received word counter is Read Only reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; when others => reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; end case; else reg_A_we <= '0'; reg_B_we <= '0'; reg_CD_we <= '0'; lfsr_load <= '0'; trigger_pat_we <= '0'; trigger_msk_we <= '0'; end if; end process; -- -- De-multiplexing stage for reg_CD_we signal -- Demux_reg_CD_we : process(ADDR(0), reg_CD_we) begin if ADDR(0) = '0' then reg_C_we <= reg_CD_we; reg_D_we <= '0'; else reg_C_we <= '0'; reg_D_we <= reg_CD_we; end if; end process; -- -- De-multiplexing for lfsr_load signal -- Demux_lfsr_load : process(CS_B, WE, ADDR(5 downto 0), lfsr_load) begin if CS_B = '0' and WE = '1' then for i in 31 downto 0 loop if i = Std_Logic_Vector_To_Natural(ADDR(5 downto 1)) then if ADDR(0) = '0' then lfsr_seed_l_ld(i) <= lfsr_load; lfsr_seed_h_ld(i) <= '0'; else lfsr_seed_l_ld(i) <= '0'; lfsr_seed_h_ld(i) <= lfsr_load; end if; else lfsr_seed_l_ld(i) <= '0'; lfsr_seed_h_ld(i) <= '0'; end if; end loop; else lfsr_seed_l_ld <= (others => '0'); lfsr_seed_h_ld <= (others => '0'); end if; end process; -- -- De-multiplexing for trigger_pat_we signal -- Demux_trigger_pat_we : process(CS_B, ADDR(2 downto 0), trigger_pat_we) begin if CS_B = '0' then case ADDR(2 downto 0) is when "000" => trig_pattern_we(0) <= trigger_pat_we; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; when "001" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= trigger_pat_we; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; when "010" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= trigger_pat_we; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; when "011" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= trigger_pat_we; trig_pattern_we(4) <= '0'; when "100" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= trigger_pat_we; when "101" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; when "110" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; when "111" => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; when others => trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; end case; else trig_pattern_we(0) <= '0'; trig_pattern_we(1) <= '0'; trig_pattern_we(2) <= '0'; trig_pattern_we(3) <= '0'; trig_pattern_we(4) <= '0'; end if; end process; -- -- De-multiplexing for trigger_msk_we signal -- Demux_trigger_msk_we : process(CS_B, ADDR(2 downto 0), trigger_msk_we) begin if CS_B = '0' then case ADDR(2 downto 0) is when "000" => trig_mask_we(0) <= trigger_msk_we; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; when "001" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= trigger_msk_we; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; when "010" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= trigger_msk_we; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; when "011" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= trigger_msk_we; trig_mask_we(4) <= '0'; when "100" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= trigger_msk_we; when "101" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; when "110" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; when "111" => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; when others => trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; end case; else trig_mask_we(0) <= '0'; trig_mask_we(1) <= '0'; trig_mask_we(2) <= '0'; trig_mask_we(3) <= '0'; trig_mask_we(4) <= '0'; end if; end process; -- -- Data Acknowledge logic -- Logic_Dtack_b : process(RESET, WCLK) begin if RESET = '1' then DTACK_B <= '1'; elsif WCLK'event and WCLK = '1' then DTACK_B <= wa_cs_b; end if; end process; wa_cs_b <= CS_B or RESET; -- -- Register A -- Register_A : cha_reg generic map( 8 ) port map ( PRESET => RESET, CLK => WCLK, PRE => reg_A_preset, DAI => DATA_IN, WE => reg_A_we, Q => reg_A ); reg_A_preset <= (others => '0'); bit_mode <= reg_A(0); -- Mode bit_stop_ctrl <= reg_A(1); -- Stop on error control bit bits_page <= reg_A(6 downto 4); -- Memory Page selection -- -- Register B -- Register_B : cha_reg generic map( 4 ) port map ( PRESET => RESET, CLK => WCLK, PRE => reg_B_preset, DAI => DATA_IN(3 downto 0), WE => reg_B_we, Q => reg_B ); reg_B_preset <= (others => '0'); bit_soft_reset <= reg_B(0); -- Soft RESET bit_arm_trig <= reg_B(1); -- Arm trigger bit_force_trig <= reg_B(2); -- Force trigger bit_abort <= reg_B(3); -- Abort run -- -- Register C -- Register_C : cha_reg generic map( 8 ) port map ( PRESET => RESET, CLK => WCLK, PRE => reg_C_preset, DAI => DATA_IN, WE => reg_C_we, Q => reg_C ); reg_C_preset <= (others => '0'); word_to_cap(7 downto 0) <= reg_C; -- -- Register D -- Register_D : cha_reg generic map( 8 ) port map ( PRESET => RESET, CLK => WCLK, PRE => reg_D_preset, DAI => DATA_IN, WE => reg_D_we, Q => reg_D ); reg_D_preset <= "00000100"; word_to_cap(11 downto 8) <= reg_D(3 downto 0); -- -- Registers for trigger word -- Registers_trig_word : for i in 4 downto 0 generate A_Register_trig_word : cha_reg generic map ( 8 ) port map ( PRESET => RESET, CLK => WCLK, PRE => trig_pattern_pre(((8*(i+1))-1) downto (8*i)), DAI => DATA_IN, WE => trig_pattern_we(i), Q => trig_pattern(((8*(i+1))-1) downto (8*i)) ); end generate; trig_pattern_pre <= (others => '0'); -- -- Registers for trigger mask -- Registers_trig_mask : for i in 4 downto 0 generate A_Register_trig_mask : cha_reg generic map ( 8 ) port map ( PRESET => RESET, CLK => WCLK, PRE => trig_mask_pre(((8*(i+1))-1) downto (8*i)), DAI => DATA_IN, WE => trig_mask_we(i), Q => trig_mask(((8*(i+1))-1) downto (8*i)) ); end generate; trig_mask_pre <= (others => '1'); -- -- The LFSR array -- LFSR_array : for i in 31 downto 0 generate A_LFSR : lfsr port map ( RESET => RESET, CLK => RX_CLK, SE => lfsr_se, LOAD_L => lfsr_seed_l_ld(i), LOAD_H => lfsr_seed_h_ld(i), SEED => lfsr_seed, Q => lfsr_out(((16*(i+1))-1) downto (16*i)) ); end generate; lfsr_se <= sta_running; lfsr_seed <= DATA_IN & DATA_IN; -- -- Logic to generate FRAME signal -- Make_Frame : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then sr_frame <= "00000001"; elsif RX_CLK'event and RX_CLK = '1' then if lfsr_se = '1' then sr_frame <= sr_frame(0) & sr_frame(7 downto 1); end if; end if; end process; exp_frame <= sr_frame(0); -- -- Connect all A address bus of RAMs to address counter -- ram_ll_addra <= ram_wr_addr; ram_lh_addra <= ram_wr_addr; ram_hl_addra <= ram_wr_addr; ram_hh_addra <= ram_wr_addr; ram_ll_ena <= sta_armed or sta_running; ram_lh_ena <= sta_armed or sta_running; ram_hl_ena <= sta_armed or sta_running; ram_hh_ena <= sta_armed or sta_running; ram_ll_wea <= sta_armed or sta_running; ram_lh_wea <= sta_armed or sta_running; ram_hl_wea <= sta_armed or sta_running; ram_hh_wea <= sta_armed or sta_running; -- -- The received word counter -- Rcv_word_Cnt : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then cnt_rcv <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then if sta_running = '1' or (sta_armed = '1' and trig = '1') then cnt_rcv <= cnt_rcv + 1; end if; end if; end process; -- -- General Control State Machine -- General_Control: gen_ctrl port map ( RESET => reset_s_h, MODE => bit_mode, STOP_CTRL => bit_stop_ctrl, CLK => RX_CLK, CAPTURE_COUNT => word_to_cap, ARM_TRIGGER => bit_arm_trig, TRIGGER => trig, ABORT_RUN => bit_abort, ERR_DETECTED => err_detected_ored, RAM_ADDR => ram_wr_addr, STATE_RESET => sta_reset, STATE_ARMED => sta_armed, STATE_RUNNING => sta_running, STATE_STOPPED => sta_stopped ); -- -- Trigger -- A_trigger: trigger generic map ( 37 ) port map ( ----------------------------------------------------------------------- RESET => reset_s_h, CLK => RX_CLK, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Inputs -- DATA => trig_data, MATCH => trig_pattern(36 downto 0), MASK => trig_mask(36 downto 0), FORCE => bit_force_trig, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Output -- TRIG => trig ----------------------------------------------------------------------- ); trig_data <= SCLIF_SPARE & rx_data_l; -- -- Array of error counters -- Error_Counters: for i in 35 downto 0 generate An_Error_Counter : cnt_sat generic map ( 8 ) port map ( RESET => reset_s_h, CE => err_detected(i), CLK => RX_CLK, Q => cnt_err(((8*(i+1))-1) downto (8*i)) ); end generate; -- -- Logic to detect bit errors -- Detect_Bit_Errors : process (bit_mode, sta_running, RX_CLK) begin if bit_mode = '0' or sta_running = '0' then err_detected <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then err_detected <= (bit_ref xor rx_data_l_dd); end if; end process; -- -- Make the expected parity -- Check_Parity: process(reset_s_h, RX_CLK) variable tmp_par : std_logic := '0'; begin if reset_s_h = '1' then exp_par <= '0'; tmp_par := '0'; elsif RX_CLK'event and RX_CLK = '1' then for i in 35 downto 0 loop if i = 35 then tmp_par := '0'; else tmp_par := tmp_par xor rx_data_l_d(i); end if; end loop; exp_par <= tmp_par; end if; end process; -- -- OR of all error detected -- OR_Detect_Bit_Errors : process(err_detected) variable tmp_err_detected_ored : std_logic; begin for i in 36 downto 0 loop if i = 36 then tmp_err_detected_ored := '0'; else if err_detected(i) = '1' then tmp_err_detected_ored := '1'; end if; end if; end loop; err_detected_ored <= tmp_err_detected_ored; end process; -- -- Extract LSB of all LFSR outputs -- Expect_Pattern : for i in 31 downto 0 generate bit_ref(i) <= lfsr_out(16*i); end generate; bit_ref(32) <= exp_bx_cnt; -- BX_COUNT bit_ref(33) <= '0'; -- FR_8_10 bit_ref(34) <= exp_frame; -- FRAME bit_ref(35) <= exp_par; -- PARITY -- -- The Fast Blink LED counter -- Fast_Blink_Cnt : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then led_fast_blink <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then led_fast_blink <= led_fast_blink + 1; end if; end process; -- -- The Slow Blink LED counter -- Slow_Blink_Cnt : process(reset_s_h, WCLK) begin if reset_s_h = '1' then led_slow_blink <= (others => '0'); elsif WCLK'event and WCLK = '1' then led_slow_blink <= led_slow_blink + 1; end if; end process; -- -- LED control logic -- The LED is active LOW on the Virtex II eval Kit LED_USER <= not ( sta_armed or (led_fast_blink(22) and sta_running) or (led_slow_blink(24) and sta_stopped) ); -- -- Capture the address where data is written when a Trigger occurs -- Capture_Trig_Pos: process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then trig_pos_addr <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then if sta_armed = '1' and trig = '0' then trig_pos_addr <= ram_wr_addr; end if; end if; end process; -- -- De-serialize BX Counter -- Get_BX_Count : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then bx_dser <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then bx_dser <= rx_bc & bx_dser(7 downto 1); end if; end process; -- -- Make local BX Counter -- Local_BX_Count : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then bx_cnt_loc <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then if rx_fr = '1' and sta_running = '0' then bx_cnt_loc <= (bx_dser + 1) & "000"; else if bx_cnt_loc = (159 * 8 + 7) then bx_cnt_loc <= "00000001000"; else bx_cnt_loc <= bx_cnt_loc + 1; end if; end if; end if; end process; bx_cnt_loc_8b <= bx_cnt_loc(10 downto 3); -- -- Serialize BX count local to compare with that received -- Serial_Bx_Cnt_loc : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then bx_cnt_loc_sr <= (others => '0'); elsif RX_CLK'event and RX_CLK = '1' then if bx_cnt_loc(2 downto 0) = "000" then bx_cnt_loc_sr <= bx_cnt_loc_8b; else bx_cnt_loc_sr <= '0' & bx_cnt_loc_sr(7 downto 1); end if; end if; end process; exp_bx_cnt <= bx_cnt_loc_sr(0) and '1'; -- enable BX counter checking -- -- A Frequency meter -- --frequency <= "1111101000000000"; -- hardwired 64000 kHz so far fre : freq port map ( RESET => RESET, CLK_REF => SCL_CLK, CLK_X => RX_CLK, F_OUT => frequency, HOLD_B => hold_b ); -- -- A process to hold the measurement of the frequency meter -- from the start of read of the least significant byte until -- the end of read of the most significant byte -- Hold_Frequency : process(reset_s_h, WCLK) begin if reset_s_h = '1' then hold_b <='1'; reading <='0'; elsif WCLK'event and WCLK='1' then if (ADDR = "011000000110" and WE = '0' and CS_B = '0') then hold_b <='0'; reading <='0'; end if; if ADDR = "011000000111" and WE = '0' then if CS_B = '0' then reading <='1'; end if; if CS_B = '1' and reading = '1' then hold_b <='1'; reading <='0'; end if; end if; end if; end process; -- Detect MSB of de-ser data Desr_MSB : process(reset_s_h, RX_CLK) begin if reset_s_h = '1' then data_msb <= '0'; elsif RX_CLK'event and RX_CLK = '1' then data_msb <= rx_data_l_d(34) and rx_data_l_dd(2); end if; end process; end;