-- PROJECT: D0 Run IIb Trigger L1 Calorimeter upgrade -- -- MODULE: Channel Link Receiver Test Card -- -- ELEMENT: ChalinkR_FPGA_test -- -- DESCRIPTION: Testbench for the Channel Link -- Receiver Tester. -- -- AUTHOR: D. Calvet calvet@hep.saclay.cea.fr and J.Marquet marquet@efrei.fr -- -- DATE AND HISTORY: -- June 2003 : created -- April 2004: added generation of FRAME, BX_COUNT and PARITY -- April 2004: changed LFSR_RESET so that it is independant of bus RESET -- This is to ensure that LFSR are always loaded and enabled when restarting -- a simulation. -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; library work; use work.utility_pkg.all; use work.constant_package.all; -------------------------------------------------------------------------------- entity ChalinkR_RS232_FPGA_test is constant H_WCLK_PERIOD : TIME := 500000000 ns / FREQ_REF; constant H_RX_CLK_PERIOD : TIME := 8 ns; constant H_REF_CLK_PERIOD : TIME := 5 ns; -- 100 MHz reference clock constant BAUD_RATE_SIMUL : integer := 307200; -- for behavioral simulation type natural_vector is array (natural range<>) of natural; constant LFSR_SEEDS : natural_vector(31 downto 0) := ( 0 => 16#0000#, 1 => 16#FFFE#, 2 => 16#012E#, 3 => 16#0C26#, 4 => 16#A128#, 5 => 16#16EA#, 6 => 16#2AB4#, 7 => 16#36BA#, 8 => 16#AA00#, 9 => 16#0332#, 10 => 16#1FFE#, 11 => 16#A002#, 12 => 16#1F0E#, 13 => 16#C002#, 14 => 16#7202#, 15 => 16#E412#, 16 => 16#7208#, 17 => 16#3208#, others => 0 ); end ChalinkR_RS232_FPGA_test; architecture behavior of ChalinkR_RS232_FPGA_test is -- -- Generic RS232 controller -- component acia generic ( TX_FIFO_SIZE : NATURAL := 4; RX_FIFO_SIZE : NATURAL := 4 ); port ( ----------------------------------------------------------------------- -- -- Miscellaneous signals -- RESET : in std_logic; -- RESET ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Local bus signals -- SPEED : in NATURAL; -- port speed TX_DATA : in std_logic_vector(7 downto 0); -- TX port TX_STROBE : in std_logic; -- TX strobe TX_READY : out std_logic; -- TX ready RX_DATA : out std_logic_vector(7 downto 0); -- RX port RX_STROBE : in std_logic; -- RX strobe RX_READY : out std_logic; -- RX ready ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- RS232 signals -- TX_OUT : out std_logic; -- TX serial output RX_IN : in std_logic -- RX serial input ----------------------------------------------------------------------- ); end component; -- -- 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; component ChalinkR_RS232_FPGA generic ( BAUD_RATE : integer := DEFAULT_BAUD_RATE ); port ( ----------------------------------------------------------------------- -- -- Miscellaneous signals -- RESET : in std_logic; -- Register RESET WCLK : in std_logic; --Write Clock ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- LED indicators -- LED_USER : out std_logic; -- LED indicator ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- RS232 interface -- TX_OUT : out std_logic; -- TX serial output RX_IN : in std_logic; -- RX serial input ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- 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_P : in std_logic; -- Bunch crossing clock input LVDS Positive SCLIF_CLK7_N : in std_logic; -- Bunch crossing clock input LVDS Negative SCLIF_BUSY_B_OUT_P : out std_logic; -- Busy signal (active low) upstream ADF -> SCL receiver LVDS Positive SCLIF_BUSY_B_OUT_N : out std_logic; -- Busy signal (active low) upstream ADF -> SCL receiver LVDS Negative SCLIF_CMDU_OUT_P : out std_logic; -- Command upstream ADF's -> SCL receiver LVDS Positive SCLIF_CMDU_OUT_N : out std_logic; -- Command upstream ADF's -> SCL receiver LVDS Negative SCLIF_CMDD_IN_P : in std_logic; -- Command downstream ADF's <- SCL receiver LVDS Positive SCLIF_CMDD_IN_N : in std_logic; -- Command downstream ADF's <- SCL receiver LVDS Negative SCLIF_ERR_B_OUT_P : out std_logic; -- Error signal (active low) upstream ADF -> SCL receiver LVDS Positive SCLIF_ERR_B_OUT_N : out std_logic; -- Error signal (active low) upstream ADF -> SCL receiver LVDS Negative SCLIF_STRIG_B_P : out std_logic; -- Self trigger ADF -> SCLIF LVDS Positive SCLIF_STRIG_B_N : out std_logic; -- Self trigger ADF -> SCLIF LVDS Negative SCLIF_SPARE_P : in std_logic; -- Spare wire LVDS Positive SCLIF_SPARE_N : in std_logic; -- Spare wire LVDS Negative ------------------------------------------------------------------------- -- 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 component; ----------------------------------------------------------------------- -- -- Miscellaneous signals -- signal RESET : std_logic := '0'; -- Register RESET signal RESET_B : std_logic ; ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- LED indicators -- signal LED_USER : std_logic; -- LED indicator ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Bus interface signals -- --signal WE : std_logic := '0'; -- Write Enable --signal CS_B : std_logic := '1'; -- Chip Select active low --signal ADDR : std_logic_vector(11 downto 0) := (others => '0'); -- Address bus --signal DATA : std_logic_vector(7 downto 0); -- Data bus signal WCLK : std_logic := '0'; -- Write Clock --signal DTACK_B : std_logic; -- Data acknowledge active low ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Clock signals -- signal CLK_BC_PLL : std_logic; -- BC clock ouptut for board level PLL signal CLK_BC_OUT : std_logic; -- BC clock ouptut for board level distribution signal CLK_BC_IN : std_logic := '1'; -- BC clock input from board level distribution signal CLK_BC4X_IN : std_logic := '1'; -- BCX4 clock input from board level distribution ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Channel Link Deserializer interface signals -- signal RX_CLK : std_logic := '1'; -- Received clock signal RX_CLK_B : std_logic; -- Received clock inverted signal RX_DATA : std_logic_vector(35 downto 0) := (others => '0'); -- Received data ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- SCL interface cable signals -- ----------------------------------------------------------------------- signal SCLIF_CLK7_P : std_logic := '1'; -- Bunch crossing clock input LVDS Positive signal SCLIF_CLK7_N : std_logic := '0'; -- Bunch crossing clock input LVDS Negative signal SCLIF_BUSY_B_OUT_P : std_logic; -- Busy signal (active low) upstream ADF -> SCL receiver LVDS Positive signal SCLIF_BUSY_B_OUT_N : std_logic; -- Busy signal (active low) upstream ADF -> SCL receiver LVDS Negative signal SCLIF_CMDU_OUT_P : std_logic; -- Command upstream ADF's -> SCL receiver LVDS Positive signal SCLIF_CMDU_OUT_N : std_logic; -- Command upstream ADF's -> SCL receiver LVDS Negative signal SCLIF_CMDD_IN_P : std_logic := '0'; -- Command downstream ADF's <- SCL receiver LVDS Positive signal SCLIF_CMDD_IN_N : std_logic := '1'; -- Command downstream ADF's <- SCL receiver LVDS Negative signal SCLIF_ERR_B_OUT_P : std_logic; -- Error signal (active low) upstream ADF -> SCL receiver LVDS Positive signal SCLIF_ERR_B_OUT_N : std_logic; -- Error signal (active low) upstream ADF -> SCL receiver LVDS Negative signal SCLIF_STRIG_B_P : std_logic; -- Self trigger ADF -> SCLIF LVDS Positive signal SCLIF_STRIG_B_N : std_logic; -- Self trigger ADF -> SCLIF LVDS Negative signal SCLIF_SPARE_P : std_logic := '0'; -- Spare wire LVDS Positive signal SCLIF_SPARE_N : std_logic := '1'; -- Spare wire LVDS Negative ----------------------------------------------------------------------- ------------------------------------------------------------------------- -- Debug Port -- signal DBG_IN : std_logic_vector(0 downto 0) := "0"; -- Debug port Input pads signal DBG_OUT : std_logic_vector(1 downto 0); -- Debug port Output pads ------------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Pins specific to debug implementation -- ----------------------------------------------------------------------- signal SCL_CLK : std_logic := '1'; -- (100 MHz clock from Evaluation Kit) ----------------------------------------------------------------------- ------------------------------------------------------------------------- -- LFSR Signals -- signal LFSR_RESET : std_logic := '0'; -- signal LFSR_SE : std_logic := '1'; -- signal LFSR_SEED_LD : std_logic := '0'; -- signal LFSR_SEED : std_logic_vector(511 downto 0) := (others => '0'); signal LFSR_OUT : std_logic_vector(511 downto 0); signal STATE_COUNT : natural := 0; ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- Serial BX_CNT, FRAME, FR_8_10, PARITY Signal -- signal BX_CNT : std_logic; -- Bit 32 of RX data signal FR_8_10 : std_logic; -- Bit 33 of RX data signal FRAME : std_logic; -- Bit 34 of RX data signal PARITY : std_logic; -- Bit 35 of RX data ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- BX counter and FRAME shift register -- signal BX_COUNTER : std_logic_vector(7 downto 0) := (others => '0'); signal SR_FRAME : std_logic_vector(7 downto 0) := (others => '0'); ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- VME bus signals -- -- There is no VME bus actually, but to use the same software bus interface, -- signal names are fixed. We also need to adapt the 16-bit data bus to 8-bit -- create ADDR<1..0>, etc --signal VME_SYSRESET_B : std_logic := '1'; --signal VME_AM : std_logic_vector(5 downto 0):=(others => '0'); --signal VME_ADDR : std_logic_vector(23 downto 1):=(others => '0'); --signal VME_ADDR_0 : std_logic:= '0'; -- re-created from VME_DS_B --signal VME_AS_B : std_logic:='1'; --signal VME_DS_B : std_logic_vector(1 downto 0):=(others => '1'); --signal VME_LWORD_B : std_logic:='1'; --signal VME_WRITE_B : std_logic:='1'; --signal VME_DATA : std_logic_vector(15 downto 0):= (others => 'Z'); -- Initial value MUST be Z for correct simulation with simulator driven by C program --signal VME_DTACK_B : std_logic; ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- ACIA Host bus signals -- signal HOST_RS232_SPEED : NATURAL:= 307200; -- Host RS232 port speed signal HOST_RS232_TX_DATA : std_logic_vector(7 downto 0); -- Host TX port signal HOST_RS232_TX_STROBE : std_logic; -- Host TX strobe signal HOST_RS232_TX_READY : std_logic := '1'; -- Host TX ready signal HOST_RS232_RX_DATA : std_logic_vector(7 downto 0):= "00001010"; -- Host RX port signal HOST_RS232_RX_STROBE : std_logic; -- Host RX strobe signal HOST_RS232_RX_READY : std_logic := '1'; -- Host RX ready ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- RS232 Host signals -- signal HOST_RS232_TX_OUT : std_logic:='1'; signal HOST_RS232_RX_IN : std_logic; ----------------------------------------------------------------------- signal RX_DATA_A : std_logic_vector(35 downto 0) := (others => '0'); -- Received data asynchronous begin -- -- Generic RS232 controller -- PC_ACIA: acia generic map( 4, 24 ) port map ( ----------------------------------------------------------------------- -- -- Miscellaneous signals -- RESET => RESET, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Local bus signals -- SPEED => HOST_RS232_SPEED, TX_DATA => HOST_RS232_TX_DATA, TX_STROBE => HOST_RS232_TX_STROBE, TX_READY => HOST_RS232_TX_READY, RX_DATA => HOST_RS232_RX_DATA, RX_STROBE => HOST_RS232_RX_STROBE, RX_READY => HOST_RS232_RX_READY, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- RS232 signals -- TX_OUT => HOST_RS232_TX_OUT, RX_IN => HOST_RS232_RX_IN ----------------------------------------------------------------------- ); -- -- The core FPGA -- FPGA : ChalinkR_RS232_FPGA generic map ( BAUD_RATE_SIMUL ) port map ( ----------------------------------------------------------------------- -- -- Miscellaneous signals -- RESET => RESET_B, WCLK => WCLK, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- LED indicators -- LED_USER => LED_USER, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- RS232 interface -- TX_OUT => HOST_RS232_RX_IN, RX_IN => HOST_RS232_TX_OUT, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Clock signals -- CLK_BC_PLL => CLK_BC_PLL, CLK_BC_OUT => CLK_BC_OUT, CLK_BC_IN => CLK_BC_IN, CLK_BC4X_IN => CLK_BC4X_IN, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Channel Link Deserializer interface signals -- RX_CLK => RX_CLK, RX_DATA => RX_DATA, ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- SCL interface cable signals -- ----------------------------------------------------------------------- SCLIF_CLK7_P => SCLIF_CLK7_P, SCLIF_CLK7_N => SCLIF_CLK7_N, SCLIF_BUSY_B_OUT_P => SCLIF_BUSY_B_OUT_P, SCLIF_BUSY_B_OUT_N => SCLIF_BUSY_B_OUT_N, SCLIF_CMDU_OUT_P => SCLIF_CMDU_OUT_P, SCLIF_CMDU_OUT_N => SCLIF_CMDU_OUT_N, SCLIF_CMDD_IN_P => SCLIF_CMDD_IN_P, SCLIF_CMDD_IN_N => SCLIF_CMDD_IN_N, SCLIF_ERR_B_OUT_P => SCLIF_ERR_B_OUT_P, SCLIF_ERR_B_OUT_N => SCLIF_ERR_B_OUT_N, SCLIF_STRIG_B_P => SCLIF_STRIG_B_P, SCLIF_STRIG_B_N => SCLIF_STRIG_B_N, SCLIF_SPARE_P => SCLIF_SPARE_P, SCLIF_SPARE_N => SCLIF_SPARE_N, ------------------------------------------------------------------------- -- Debug Port -- DBG_IN => DBG_IN, DBG_OUT => DBG_OUT, ------------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- Pins specific to debug implementation -- ----------------------------------------------------------------------- SCL_CLK => SCL_CLK ); -- -- Clocks and permanent signals -- WCLK <= not WCLK after H_WCLK_PERIOD; RX_CLK <= not RX_CLK after H_RX_CLK_PERIOD; RX_CLK_B <= not RX_CLK; SCL_CLK <= not SCL_CLK after H_REF_CLK_PERIOD; --DTACK_B <= 'H'; -- Pullup on DTACK_B -- -- Local bus signals made from their VME counterpart. -- RESET <= '0' after 0 ns, '1' after 50 ns, '0' after 100 ns; RESET_B <= not RESET; --RESET_ACIA <= not RESET; --RESET <= VME_SYSRESET_B; -- already inverted in ChalinkR_FPGA --VME_ADDR_0 <= ( ( VME_DS_B(1)) and (not VME_DS_B(0)) ); --ADDR <= VME_ADDR(11 downto 1) & VME_ADDR_0; --WE <= not VME_WRITE_B; --VME_DTACK_B <= DTACK_B; -- -- A process to create CS_B. -- We respond from address 0x000 to 0x3FF on A24 Program and Data accesses -- --CS_B_process: process(VME_AS_B, VME_ADDR(23 downto 12), VME_AM) --begin --if (VME_ADDR(23 downto 12)= "000000000000") and -- (VME_AM = "111010" or VME_AM = "111001") and -- (VME_AS_B = '0') --then -- CS_B <= '0'; --else -- CS_B <= '1'; --end if; --end process; -- -- A process to create CS_B. -- We respond from address 0x000 to 0x3FF on A24 Program and Data accesses -- --DATA_process: process(VME_WRITE_B, VME_ADDR_0, VME_DATA, DATA, CS_B) --begin --if CS_B = '1' then --DATA <= transport (others => 'Z') after 1 ns; --VME_DATA <= (others => 'Z'); --else --if (VME_ADDR_0 = '0') then --if VME_WRITE_B = '0' then --DATA <= transport VME_DATA(15 downto 8) after 1 ns; --else --VME_DATA(15 downto 8) <= DATA; --end if; --else --if VME_WRITE_B = '0' then --DATA <= transport VME_DATA(7 downto 0) after 1 ns; --else --VME_DATA(7 downto 0) <= DATA; --end if; --end if; --end if; --end process; -- -- The LFSR array to simulate received data -- LFSR_array : for i in 31 downto 0 generate A_LFSR : lfsr port map ( RESET => LFSR_RESET, CLK => RX_CLK_B, SE => LFSR_SE, LOAD_L => LFSR_SEED_LD, LOAD_H => LFSR_SEED_LD, SEED => LFSR_SEED(((16*(i+1))-1) downto (16*i)), Q => LFSR_OUT(((16*(i+1))-1) downto (16*i)) ); LFSR_SEED(((16*(i+1))-1) downto (16*i)) <= Natural_To_Std_Logic_Vector(LFSR_SEEDS(i), 16); RX_DATA_A(i) <= LFSR_OUT(16*i); end generate; LFSR_RESET <= '0' after 0 ns , '1' after (H_RX_CLK_PERIOD), '0' after (2*H_RX_CLK_PERIOD); LFSR_SE <= '0' after 0 ns , '1' after (400 * H_RX_CLK_PERIOD); LFSR_SEED_LD <= '0' after 0 ns , '1' after (10 * H_RX_CLK_PERIOD), '0' after (12 * H_RX_CLK_PERIOD); -- -- BX counter -- Count_BX : process (LFSR_RESET, RX_CLK_B) variable index : NATURAL := 0; variable bx_bit : std_logic; begin if LFSR_RESET = '1' then BX_COUNTER <= "00000001"; BX_CNT <= '1'; elsif RX_CLK_B'event and RX_CLK_B = '1' then if LFSR_SE = '1' then index := (index + 1) mod 8; if index = 7 then if BX_COUNTER /= 159 then BX_COUNTER <= BX_COUNTER + 1; else BX_COUNTER <= "00000001"; end if; end if; end if; BX_CNT <= BX_COUNTER(index); end if; end process; RX_DATA_A(32) <= BX_CNT; -- -- FR_8_10 generation -- FR_8_10 <= '0'; RX_DATA_A(33) <= FR_8_10; -- -- Frame generation logic -- Make_Frame : process (LFSR_RESET, RX_CLK_B) begin if LFSR_RESET = '1' then SR_FRAME <= "00000001"; elsif RX_CLK_B'event and RX_CLK_B = '1' then if LFSR_SE = '1' then SR_FRAME <= SR_FRAME(0) & SR_FRAME(7 downto 1); end if; end if; end process; FRAME <= SR_FRAME(0); RX_DATA_A(34) <= FRAME; -- -- Parity generation Logic -- Make_Parity : process (LFSR_RESET, RX_CLK_B) variable tmp : std_logic := '0'; begin if LFSR_RESET = '1' then PARITY <= '0'; elsif RX_CLK_B'event and RX_CLK_B = '1' then for i in 35 downto 0 loop if i = 35 then tmp := '0'; else tmp := tmp xor RX_DATA_A(i); end if; end loop; PARITY <= tmp; end if; end process; RX_DATA_A(35) <= PARITY; RX_DATA(35) <= PARITY; -- -- Make RX_DATA -- Synchronous logic is needed because PARITY calculation takes -- time and would generate glitches with asynchronous logic -- Make_Rx_data : process(LFSR_RESET, RX_CLK_B) begin if LFSR_RESET = '1' then RX_DATA(34 downto 0) <= (others => '0'); elsif RX_CLK_B'event and RX_CLK_B = '1' then RX_DATA(34 downto 0) <= RX_DATA_A(34 downto 0); end if; end process; -- -- Counting states of LFSR -- Cnt_State : process (LFSR_RESET, RX_CLK_B) begin if LFSR_RESET = '1' then STATE_COUNT <= 0; elsif RX_CLK_B'event and RX_CLK_B = '1' then if LFSR_SE = '1' then STATE_COUNT <= STATE_COUNT + 1; end if; end if; end process; end behavior;