From 82228a6372e8dbd0f7eb124f9a2b915d832ad63d Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Fri, 23 May 2014 16:00:13 +0200 Subject: [PATCH] CBMNet before refactoring to slave-only version --- cbmnet/code/cbmnet_phy_ecp3.vhd | 121 ++++++--- cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd | 2 +- cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd | 2 +- cbmnet/code/cbmnet_phy_pkg.vhd | 15 +- cbmnet/code/cbmnet_phy_rx_gear.vhd | 24 +- cbmnet/code/cbmnet_phy_tx_gear.vhd | 19 +- cbmnet/compile_periph_frankfurt.pl | 82 +++--- cbmnet/cores/cbmnet_sfp1.ipx | 14 +- cbmnet/cores/cbmnet_sfp1.lpc | 4 +- cbmnet/test/info.pl | 137 ++++++++++ cbmnet/test/osci_clk_phase.py | 83 ++++++ cbmnet/test/phase.py | 83 ++++++ cbmnet/test/toggle | 4 +- cbmnet/trb3_periph_cbmnet.p2t | 9 +- cbmnet/trb3_periph_cbmnet.p3t | 5 + cbmnet/trb3_periph_cbmnet.vhd | 252 +++++++++---------- cbmnet/trb3_periph_cbmnet_constraints.lpf | 21 +- 17 files changed, 634 insertions(+), 243 deletions(-) mode change 100644 => 100755 cbmnet/code/cbmnet_phy_ecp3.vhd create mode 100755 cbmnet/test/info.pl create mode 100644 cbmnet/test/osci_clk_phase.py create mode 100755 cbmnet/test/phase.py mode change 100644 => 100755 cbmnet/trb3_periph_cbmnet.p2t create mode 100644 cbmnet/trb3_periph_cbmnet.p3t mode change 100644 => 100755 cbmnet/trb3_periph_cbmnet.vhd diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd old mode 100644 new mode 100755 index 50256bb..6e1b699 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -52,9 +52,9 @@ entity cbmnet_phy_ecp3 is LED_OK_OUT : out std_logic; -- Status and control port - STAT_OP : out std_logic_vector (15 downto 0) := (others => '0'); - CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); - DEBUG_OUT : out std_logic_vector (127 downto 0) := (others => '0') + STAT_OP : out std_logic_vector ( 15 downto 0) := (others => '0'); + CTRL_OP : in std_logic_vector ( 15 downto 0) := (others => '0'); + DEBUG_OUT : out std_logic_vector (255 downto 0) := (others => '0') ); end entity; @@ -63,6 +63,11 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is attribute HGROUP : string; -- for whole architecture attribute HGROUP of cbmnet_phy_ecp3_arch : architecture is "cbmnet_phy_group"; + + attribute syn_hier: string; + attribute syn_hier of cbmnet_phy_ecp3_arch : architecture is "hard"; + + attribute syn_sharing : string; attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off"; @@ -112,7 +117,7 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is signal sci_qd_i : std_logic; signal sci_reg_i : std_logic; signal sci_addr_i : std_logic_vector(8 downto 0); - signal sci_data_in_i : std_logic_vector(7 downto 0); + signal sci_data_in_i : std_logic_vector(7 downto 0) := (others => '0'); signal sci_data_out_i : std_logic_vector(7 downto 0); signal sci_read_i : std_logic; signal sci_write_i : std_logic; @@ -150,13 +155,18 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is signal rx_data_i : std_logic_vector(17 downto 0); -- in the front end this signal is identical to rx_data_from_gear_i -- otherwise a clock domain crossing from rclk_125_i to clk_125_local is - -- necessary. this signal will no exhibit a deterministic latency !!!!!! - -- (however, this is no problem, as the clock master will no receive DLMs) + -- necessary. this signal will not exhibit a deterministic latency !!!!!! + -- (however, this is no problem, as the clock master will not receive DLMs) + + signal rx_data_debug_i : std_logic_vector(17 downto 0); signal tx_data_i : std_logic_vector(17 downto 0); -- 16(+2) bit word generated fed to gear signal tx_gear_reset_i : std_logic; + signal tx_gear_allow_relock_i : std_logic; + - signal rx_gear_debug_i : std_logic_vector(15 downto 0); + signal rx_gear_debug_i : std_logic_vector(31 downto 0) := (others => '0'); + signal tx_gear_debug_i : std_logic_vector(31 downto 0) := (others => '0'); -- CBMNet Ready Managers signal rm_rx_ready_i : std_logic; @@ -179,6 +189,9 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is -- Stats signal stat_reconnect_counter_i : unsigned(15 downto 0); -- counts the number of RX-serdes resets since last external reset + signal stat_last_reconnect_duration_i : unsigned(31 downto 0); + + signal stat_wa_int_i : std_logic_vector(15 downto 0) := (others => '0'); signal tx_data_debug_i : std_logic_vector(17 downto 0); signal tx_data_debug_state_i : std_logic; @@ -186,11 +199,9 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is signal low_level_rx_see_dlm0 : std_logic; signal low_level_tx_see_dlm0 : std_logic; signal low_level_tx_see_dlm0_125 : std_logic; - - begin clk_125_local <= CLK; - CLK_RX_HALF_OUT <= rclk_125_i; + CLK_RX_HALF_OUT <= rclk_125_i when IS_SYNC_SLAVE = c_YES or 1=1 else clk_tx_half_i; CLK_RX_FULL_OUT <= rclk_250_i; SD_TXDIS_OUT <= '0'; @@ -303,7 +314,7 @@ begin RX_PCS_RST_CH_C => rx_pcs_rst_i, STATE_OUT => rx_rst_fsm_state_i ); - byte_alignment_to_fsm_i <= (not barrel_shifter_misaligned_i); + byte_alignment_to_fsm_i <= (not barrel_shifter_misaligned_i) or CTRL_OP(3); word_alignment_to_fsm_i <= not (gear_to_fsm_rst_i or AND_ALL(rx_error_delay)); rx_error_delay <= rx_error_delay(rx_error_delay'high - 1 downto 0) & rx_dec_error_i when rising_edge(clk_125_local); @@ -334,7 +345,10 @@ begin end if; end process; - THE_RX_GEAR: CBMNET_PHY_RX_GEAR port map ( + THE_RX_GEAR: CBMNET_PHY_RX_GEAR + generic map ( + IS_SYNC_SLAVE => IS_SYNC_SLAVE + ) port map ( -- SERDES PORT CLK_250_IN => rclk_250_i, -- in std_logic; PCS_READY_IN => rx_rst_fsm_ready_i, -- in std_logic; @@ -350,6 +364,22 @@ begin DEBUG_OUT => rx_gear_debug_i ); + process is + variable state_v : std_logic; + begin + wait until rising_edge(rclk_250_i); + + if state_v = '0' then + rx_data_debug_i(7 downto 0) <= rx_data_from_serdes_i(7 downto 0); + rx_data_debug_i(16) <= rx_data_from_serdes_i(8); + else + rx_data_debug_i(15 downto 8) <= rx_data_from_serdes_i(7 downto 0); + rx_data_debug_i(17) <= rx_data_from_serdes_i(8); + end if; + + state_v := not state_v; + end process; + rx_data_i <= rx_data_from_gear_i when rising_edge(clk_125_local) or (IS_SYNC_SLAVE = c_YES); THE_TX_GEAR: CBMNET_PHY_TX_GEAR @@ -360,12 +390,14 @@ begin CLK_125_OUT => clk_tx_half_i, RESET_IN => tx_gear_reset_i, -- in std_logic; + ALLOW_RELOCK_IN => tx_gear_allow_relock_i, -- in std_logic DATA_IN => tx_data_i, -- in std_logic_vector(17 downto 0) DATA_OUT => tx_data_to_serdes_i -- out std_logic_vector(8 downto 0); ); tx_gear_reset_i <= not tx_rst_fsm_ready_i; + tx_gear_allow_relock_i <= ((not tx_rst_fsm_ready_i) and not CTRL_OP(1)) or CTRL_OP(2); process is begin @@ -458,11 +490,9 @@ begin -- upon retrival the barrel shifter is checked and - if necessary - a serdes reset is issued PROC_SCI_CTRL: process variable cnt : integer range 0 to 4 := 0; - variable lsm_status_buf : std_logic; begin wait until rising_edge(clk_125_local); - barrel_shifter_misaligned_i <= '0'; - + case sci_state is when IDLE => sci_ch_i <= x"0"; @@ -481,10 +511,6 @@ begin cnt := 0; sci_state <= IDLE; - if lsm_status_buf = '1' and wa_position_i(3 downto 0) /= x"0" then - barrel_shifter_misaligned_i <= '1'; - end if; - else sci_state <= GET_WA_WAIT; sci_addr_i <= '0' & x"22"; @@ -505,10 +531,17 @@ begin cnt := cnt + 1; end case; - - lsm_status_buf := lsm_status_i; end process; - + + process is begin + wait until rising_edge(clk_125_local); + barrel_shifter_misaligned_i <= '0'; + if lsm_status_i = '1' and wa_position_i(3 downto 0) /= x"0" then + barrel_shifter_misaligned_i <= '1'; + end if; + end process; + + -- RX/TX leds are on as soon as the correspondent pll is locked and data -- other than the idle word is transmitted PROC_LEDS: process is @@ -566,10 +599,18 @@ begin if rst_n_i = '0' then stat_reconnect_counter_i <= (others => '0'); + stat_last_reconnect_duration_i <= (others => '0'); + stat_wa_int_i <= (others => '0'); else if rx_serdes_rst_i = '1' and last_rx_serdes_rst_i = '0' then stat_reconnect_counter_i <= stat_reconnect_counter_i + TO_UNSIGNED(1,1); end if; + + if serdes_ready_i = '0' then + stat_last_reconnect_duration_i <= stat_last_reconnect_duration_i + TO_UNSIGNED(1,1); + end if; + + stat_wa_int_i <= stat_wa_int_i or wa_position_i; end if; last_rx_serdes_rst_i := rx_serdes_rst_i; @@ -624,36 +665,44 @@ begin low_level_tx_see_dlm0_125 <= '1'; end if; end process; - - DEBUG_OUT(19 downto 0) <= "00" & tx_data_i; + +-- DEBUG_OUT_BEGIN + DEBUG_OUT(19 downto 0) <= "00" & tx_data_i(17 downto 0); + DEBUG_OUT(23 downto 20) <= "0" & tx_pll_lol_i & rx_los_low_i & rx_cdr_lol_i; + DEBUG_OUT(27 downto 24) <= gear_to_fsm_rst_i & barrel_shifter_misaligned_i & SD_PRSNT_N_IN & SD_LOS_IN; DEBUG_OUT(31 downto 28) <= rst_qd_i & rx_serdes_rst_i & tx_pcs_rst_i & rx_pcs_rst_i; - DEBUG_OUT(51 downto 32) <= "00" & rx_data_i; - DEBUG_OUT(59 downto 52) <= rx_rst_fsm_state_i & tx_rst_fsm_state_i; + DEBUG_OUT( 51 downto 32) <= "00" & rx_data_i(17 downto 0); + DEBUG_OUT( 59 downto 52) <= rx_rst_fsm_state_i(3 downto 0) & tx_rst_fsm_state_i(3 downto 0); - DEBUG_OUT(63 downto 60) <= serdes_ready_i & rm_rx_ready_i & rm_tx_ready_i & rm_tx_almost_ready_i; + DEBUG_OUT( 63 downto 60) <= serdes_ready_i & rm_rx_ready_i & rm_tx_ready_i & rm_tx_almost_ready_i; - DEBUG_OUT(71 downto 64) <= rx_gear_debug_i(7 downto 0); + DEBUG_OUT( 79 downto 64) <= rx_gear_debug_i(15 downto 0); + DEBUG_OUT( 95 downto 80) <= tx_gear_debug_i(15 downto 0); - DEBUG_OUT(99 downto 96) <= rm_rx_almost_ready_i & rm_rx_see_ready0_i & rm_rx_saw_ready1_i & rm_rx_valid_char_i; + DEBUG_OUT( 99 downto 96) <= rm_rx_almost_ready_i & rm_rx_see_ready0_i & rm_rx_saw_ready1_i & rm_rx_valid_char_i; DEBUG_OUT(103 downto 100) <= wa_position_i(3 downto 0); DEBUG_OUT(107 downto 104) <= "00" & rm_rx_to_gear_reset_i & gear_to_rm_rst_i; - DEBUG_OUT(127 downto 108) <= "00" & tx_data_debug_i; --STD_LOGIC_VECTOR(stat_reconnect_counter_i); + DEBUG_OUT(127 downto 108) <= "00" & tx_data_debug_i(17 downto 0); + DEBUG_OUT(147 downto 128) <= "00" & rx_data_debug_i(17 downto 0) when rising_edge(clk_125_local); + DEBUG_OUT(179 downto 148) <= stat_last_reconnect_duration_i(31 downto 0); + DEBUG_OUT(195 downto 180) <= stat_reconnect_counter_i(15 downto 0); + DEBUG_OUT(211 downto 196) <= stat_wa_int_i(15 downto 0); + --DEBUG_OUT(255 downto 170) <= (others => '0'); +-- DEBUG_OUT_END + -- STAT_OP REGISTER STAT_OP(6 downto 0) <= tx_data_to_serdes_i(6 downto 0); - - STAT_OP( 7) <= low_level_tx_see_dlm0_125; + STAT_OP( 7) <= low_level_rx_see_dlm0; STAT_OP( 8) <= clk_125_local; STAT_OP( 9) <= rclk_250_i; STAT_OP(10) <= rclk_125_i; STAT_OP(11) <= clk_tx_full_i; STAT_OP(12) <= clk_tx_half_i; - - STAT_OP(13) <= low_level_rx_see_dlm0; - STAT_OP(14) <= low_level_tx_see_dlm0; + STAT_OP(13) <= low_level_tx_see_dlm0; end generate; -end architecture; +end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd index 3f5ec86..de4ffc9 100644 --- a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd @@ -107,7 +107,7 @@ begin end process; - proc_fsm_trans: process(cs, tx_pll_lol_qd_s_int, rx_los_low_int, rx_lol_los_int, timer2) + proc_fsm_trans: process(cs, tx_pll_lol_qd_s_int, rx_los_low_int, rx_lol_los_int, timer2, proper_word_align_i, proper_byte_align_i, rx_lol_los_int, rm_reset_i) begin -- reset_timer1 <= '0'; reset_timer2 <= '0'; diff --git a/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd b/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd index d690727..2245a9b 100644 --- a/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd @@ -121,7 +121,7 @@ begin tx_pcs_rst_ch_c_int <= '1'; RST_QD_C_int <= '1'; reset_timer1 <= '1'; - ns <= WAIT_FOR_TIMER1; + ns <= WAIT_FOR_TIMER1; when WAIT_FOR_TIMER1 => STATE_OUT <= x"2"; diff --git a/cbmnet/code/cbmnet_phy_pkg.vhd b/cbmnet/code/cbmnet_phy_pkg.vhd index 98db4cc..c3ee736 100644 --- a/cbmnet/code/cbmnet_phy_pkg.vhd +++ b/cbmnet/code/cbmnet_phy_pkg.vhd @@ -49,7 +49,7 @@ package cbmnet_phy_pkg is -- Status and control port STAT_OP : out std_logic_vector (15 downto 0); CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); - DEBUG_OUT : out std_logic_vector (127 downto 0) := (others => '0') + DEBUG_OUT : out std_logic_vector (255 downto 0) := (others => '0') ); end component; @@ -57,6 +57,9 @@ package cbmnet_phy_pkg is -- INTERNAL ----------------------------------------------------------------------------------------------------------------------- component CBMNET_PHY_RX_GEAR is + generic( + IS_SYNC_SLAVE : integer := c_NO --select slave mode + ); port ( -- SERDES PORT CLK_250_IN : in std_logic; @@ -71,7 +74,7 @@ package cbmnet_phy_pkg is DATA_OUT : out std_logic_vector(17 downto 0); -- DEBUG - DEBUG_OUT : out std_logic_vector(15 downto 0) := (others => '0') + DEBUG_OUT : out std_logic_vector(31 downto 0) := (others => '0') ); end component; @@ -85,10 +88,12 @@ package cbmnet_phy_pkg is CLK_125_OUT : out std_logic; RESET_IN : in std_logic; - + ALLOW_RELOCK_IN : in std_logic; + DATA_IN : in std_logic_vector(17 downto 0); - - DATA_OUT : out std_logic_vector(8 downto 0) + DATA_OUT : out std_logic_vector(8 downto 0); + + DEBUG_OUT : out std_logic_vector(31 downto 0) ); end component; diff --git a/cbmnet/code/cbmnet_phy_rx_gear.vhd b/cbmnet/code/cbmnet_phy_rx_gear.vhd index 051c57d..7c9d848 100644 --- a/cbmnet/code/cbmnet_phy_rx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_rx_gear.vhd @@ -3,13 +3,16 @@ LIBRARY IEEE; USE IEEE.numeric_std.all; library work; --- use work.trb_net_std.all; + use work.trb_net_std.all; -- use work.trb_net_components.all; -- use work.med_sync_define.all; use work.cbmnet_interface_pkg.all; use work.cbmnet_phy_pkg.all; entity CBMNET_PHY_RX_GEAR is + generic( + IS_SYNC_SLAVE : integer := c_NO --select slave mode + ); port ( -- SERDES PORT CLK_250_IN : in std_logic; @@ -24,7 +27,7 @@ entity CBMNET_PHY_RX_GEAR is DATA_OUT : out std_logic_vector(17 downto 0); -- DEBUG - DEBUG_OUT : out std_logic_vector(15 downto 0) := (others => '0') + DEBUG_OUT : out std_logic_vector(31 downto 0) := (others => '0') ); end entity; @@ -93,7 +96,7 @@ begin elsif indi_misalignment_i = '1' then -- in this state we should already have a stable and correct lock. - -- if we, however detect a missalignment, something is terribly wrong. + -- if we, however, detect a missalignment, something is terribly wrong. -- in this case, will perform a resychronisation fsm_i <= FSM_RESET; @@ -108,21 +111,26 @@ begin end if; end process; --- Timeout (approx. 1ms) +-- Timeout (approx. 2ms) proc_timeout: process is - variable timer_v : unsigned(17 downto 0); + variable timer_v : unsigned(19 downto 0) := (others => '0'); + variable idx : integer := 18; begin wait until rising_edge(clk_125_i); + if IS_SYNC_SLAVE = 0 then + idx := timer_v'high; + end if; + if reset_timer_i = '1' then timer_v := TO_UNSIGNED(0, timer_v'length); - elsif timer_v(timer_v'high) = '0' then + elsif timer_v(idx) = '0' then timer_v := timer_v + TO_UNSIGNED(1,1); end if; - timeout_i <= timer_v(timer_v'high); + timeout_i <= timer_v(idx); end process; -- Implement the 2:1 gearing and clock down-sampling @@ -152,6 +160,8 @@ begin DEBUG_OUT(3 downto 0) <= STD_LOGIC_VECTOR(fsm_state_i); DEBUG_OUT(4) <= delay_clock_i; + DEBUG_OUT(5) <= indi_alignment_i; + DEBUG_OUT(6) <= indi_misalignment_i; -- Detect Indications for correct or wrong alignment indi_alignment_i <= '1' when data_out_buf_i(17 downto 16) = "01" and data_out_buf_i(15 downto 8) = x"00" and diff --git a/cbmnet/code/cbmnet_phy_tx_gear.vhd b/cbmnet/code/cbmnet_phy_tx_gear.vhd index dae2a76..9969670 100644 --- a/cbmnet/code/cbmnet_phy_tx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_tx_gear.vhd @@ -20,10 +20,12 @@ entity CBMNET_PHY_TX_GEAR is CLK_125_OUT : out std_logic; RESET_IN : in std_logic; + ALLOW_RELOCK_IN : in std_logic; DATA_IN : in std_logic_vector(17 downto 0); + DATA_OUT : out std_logic_vector(8 downto 0); - DATA_OUT : out std_logic_vector(8 downto 0) + DEBUG_OUT : out std_logic_vector(31 downto 0) ); end entity; @@ -38,11 +40,15 @@ architecture CBMNET_PHY_TX_GEAR_ARCH of CBMNET_PHY_TX_GEAR is signal clk_125_xfer_buf_i : std_logic := '0'; signal clk_125_xfer_del_i : std_logic := '0'; - + signal delay_counter_i : unsigned(15 downto 0); begin process is begin wait until rising_edge(CLK_250_IN); + if RESET_IN='1' then + delay_counter_i <= TO_UNSIGNED(0,16); + end if; + clk_125_xfer_buf_i <= clk_125_xfer_i; clk_125_xfer_del_i <= clk_125_xfer_buf_i; CLK_125_OUT <= '0'; @@ -55,8 +61,9 @@ begin low_data_i <= data_in_buf125_i(16) & data_in_buf125_i( 7 downto 0); fsm_i <= FSM_LOW; - if clk_125_xfer_buf_i /= clk_125_xfer_del_i then + if clk_125_xfer_buf_i /= clk_125_xfer_del_i and ALLOW_RELOCK_IN = '1' then fsm_i <= FSM_HIGH; + delay_counter_i <= delay_counter_i + 1; end if; @@ -64,7 +71,7 @@ begin DATA_OUT <= low_data_i; fsm_i <= FSM_HIGH; end case; - end process; + end process; process is begin wait until rising_edge(CLK_125_IN); @@ -72,4 +79,6 @@ begin data_in_buf125_i <= DATA_IN; clk_125_xfer_i <= not clk_125_xfer_i; end process; -end architecture CBMNET_PHY_TX_GEAR_ARCH; + + DEBUG_OUT <= x"0000" & STD_LOGIC_VECTOR( delay_counter_i ); +end architecture CBMNET_PHY_TX_GEAR_ARCH; \ No newline at end of file diff --git a/cbmnet/compile_periph_frankfurt.pl b/cbmnet/compile_periph_frankfurt.pl index 855151a..a2a3248 100755 --- a/cbmnet/compile_periph_frankfurt.pl +++ b/cbmnet/compile_periph_frankfurt.pl @@ -2,6 +2,10 @@ use Data::Dumper; use warnings; use strict; +use Term::ANSIColor; +use File::stat; +use POSIX; + my $build_master = 1; @@ -10,28 +14,24 @@ my $build_slave = 1; my $mode = $ARGV[0]; $mode = 's' unless defined $mode; -$build_master = 0 if $mode eq 's'; +$build_master = 0 if $mode eq 's'; $build_slave = 0 if $mode eq 'm' or $mode eq 'w'; print "Will build:\n"; print " -> Slave\n" if $build_slave; print " -> Master\n" if $build_master; -print "\n\n"; - local $| = 1; -if ($mode eq 'w') { - print "Wait for slave process\n"; - while(-e 'workdir') { - sleep 3; - print ('.'); - } -} - if ($build_master and $build_slave) { - system "xterm -e './compile_periph_frankfurt.pl s; read' &"; - sleep 5; - system "xterm -e './compile_periph_frankfurt.pl w; read' &"; + if (fork()) { + system "xterm -geometry 200x25 -e './compile_periph_frankfurt.pl s;'"; + exit; + } + if (fork()) { + system "xterm -geometry 200x25 -e './compile_periph_frankfurt.pl m;'"; + exit; + } wait; + exit (-e 'workdir_master/trb3_periph_cbmnet.bit') && (-e 'workdir_slave/trb3_periph_cbmnet.bit') ? 1 : 0; } @@ -40,26 +40,39 @@ if ($build_master and $build_slave) { my $TOPNAME = "trb3_periph_cbmnet"; #Name of top-level entity my $BasePath = "../base/"; #path to "base" directory my $CbmNetPath = "../../cbmnet"; -my $lattice_path = '/d/jspc29/lattice/diamond/2.01'; -my $synplify_path = '/d/jspc29/lattice/synplify/F-2012.03-SP1/'; my $lm_license_file_for_synplify = "27000\@lxcad01.gsi.de"; my $lm_license_file_for_par = "1702\@hadeb05.gsi.de"; + +my $lattice_path = '/d/jspc29/lattice/diamond/2.2_x64/'; +#my $synplify_path = '/d/jspc29/lattice/synplify/F-2012.03-SP1/'; +my $synplify_path = '/d/jspc29/lattice/synplify/G-2012.09-SP1/'; + +#my $lattice_path = '/d/jspc29/lattice/diamond/3.0_x64'; +#my $synplify_path = '/d/jspc29/lattice/synplify/I-2013.09-SP1/'; ################################################################################### -my $workdir = "workdir_" . ($build_slave ? 'slave' : 'master'); +my $btype = ($build_slave ? 'slave' : 'master'); -symlink($CbmNetPath, 'cbmnet') unless (-e 'cbmnet'); -unless(-e $workdir) { - mkdir $workdir; - chdir $workdir; - system '../../base/linkdesignfiles.sh'; - symlink '../cores/cbmnet_sfp1.txt', 'cbmnet_sfp1.txt'; - chdir '..'; +if (-e "../cbmnet_build_$btype/workdir/trb3_periph_cbmnet.bit") { + my $cd = stat("../cbmnet_build_$btype/workdir/trb3_periph_cbmnet.bit")->ctime; + system "mv ../cbmnet_build_$btype /tmp/cbmnet_build_" . $btype . "_" . POSIX::strftime("%Y%m%d_%H%M%S", localtime $cd); +} else { + system "rm -rf ../cbmnet_build_$btype"; } -unlink 'workdir'; -symlink $workdir, 'workdir'; + +system "cp -ar . ../cbmnet_build_$btype"; +mkdir "../cbmnet_build_$btype/workdir"; +symlink "../cbmnet_build_$btype/workdir", "workdir_$btype"; +chdir "../cbmnet_build_$btype"; + +symlink($CbmNetPath, 'cbmnet') unless (-e 'cbmnet'); + +chdir "workdir"; +system '../../base/linkdesignfiles.sh'; +symlink '../cores/cbmnet_sfp1.txt', 'cbmnet_sfp1.txt'; +chdir '..'; use FileHandle; @@ -74,8 +87,8 @@ my $PACKAGE="FPBGA672"; my $SPEEDGRADE="8"; #create full lpf file -system("cp $BasePath/$TOPNAME.lpf $workdir/$TOPNAME.lpf"); -system("cat ".$TOPNAME."_constraints.lpf >> $workdir/$TOPNAME.lpf"); +system("cp $BasePath/$TOPNAME.lpf workdir/$TOPNAME.lpf"); +system("cat ".$TOPNAME."_constraints.lpf >> workdir/$TOPNAME.lpf"); #set -e #set -o errexit @@ -97,7 +110,8 @@ package version is constant VERSION_NUMBER_TIME : integer := $t; constant CBM_FEE_MODE_C : integer := $build_slave; - + constant INCLUDE_TRBNET_C : integer := 1; + end package version; EOF $fh->close; @@ -108,9 +122,8 @@ my $r = ""; my $c="$synplify_path/bin/synplify_premier_dp -batch $TOPNAME.prj"; $r=execute($c, "do_not_exit" ); -system 'rm -f workdir'; +chdir "workdir"; -chdir $workdir; $fh = new FileHandle("<$TOPNAME".".srr"); my @a = <$fh>; $fh -> close; @@ -143,14 +156,17 @@ execute($c); my $tpmap = $TOPNAME . "_map" ; +execute('env'); + $c=qq|$lattice_path/ispfpga/bin/lin/map -retime -split_node -a $FAMILYNAME -p $DEVICENAME -t $PACKAGE -s $SPEEDGRADE "$TOPNAME.ngd" -o "$tpmap.ncd" -mp "$TOPNAME.mrp" "$TOPNAME.lpf"|; execute($c); system("rm $TOPNAME.ncd"); -$c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|; +#$c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|; #$c=qq|$lattice_path/ispfpga/bin/lin/par -f "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.dir" "$TOPNAME.prf"|; +$c=qq|$lattice_path/bin/lin/mpartrce -p "../$TOPNAME.p2t" -f "../$TOPNAME.p3t" -tf "$TOPNAME.pt" "|.$TOPNAME.qq|_map.ncd" "$TOPNAME.ncd"|; execute($c); #Make Bitfile @@ -179,7 +195,9 @@ sub execute { my ($c, $op) = @_; #print "option: $op \n"; $op = "" if(!$op); + print color 'blue bold'; print "\n\ncommand to execute: $c \n"; + print color 'reset'; $r=system($c); if($r) { print "$!"; diff --git a/cbmnet/cores/cbmnet_sfp1.ipx b/cbmnet/cores/cbmnet_sfp1.ipx index ddf2037..c966b6d 100644 --- a/cbmnet/cores/cbmnet_sfp1.ipx +++ b/cbmnet/cores/cbmnet_sfp1.ipx @@ -1,11 +1,11 @@ - + - - - - - - + + + + + + diff --git a/cbmnet/cores/cbmnet_sfp1.lpc b/cbmnet/cores/cbmnet_sfp1.lpc index e784386..9084ed6 100644 --- a/cbmnet/cores/cbmnet_sfp1.lpc +++ b/cbmnet/cores/cbmnet_sfp1.lpc @@ -16,8 +16,8 @@ CoreRevision=8.1 ModuleName=cbmnet_sfp1 SourceFormat=VHDL ParameterFileVersion=1.0 -Date=10/05/2013 -Time=12:37:58 +Date=02/19/2014 +Time=18:17:20 [Parameters] Verilog=0 diff --git a/cbmnet/test/info.pl b/cbmnet/test/info.pl new file mode 100755 index 0000000..17c8943 --- /dev/null +++ b/cbmnet/test/info.pl @@ -0,0 +1,137 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Data::Dumper; +use File::Basename; +use List::Util qw(first max reduce); +use POSIX qw/ceil/; + +use Term::ANSIColor; +use bigint; + + +sub readFile { + open FILE, "<", shift; + my @lines = ; + + my $begin = first { $lines[$_] =~ /-- DEBUG_OUT_BEGIN/ } 0..$#lines; + my $end = first { $lines[$_] =~ /-- DEBUG_OUT_END/ } 0..$#lines; + + close FILE; + + return @lines[$begin+1 .. $end-1]; +} + +sub interpretLine { + my $line = shift; + return () unless ($line =~ m/DEBUG_OUT\s*\(\s*(\d+)\s*downto\s*(\d+)\s*\)\s*<=\s*([^;]+);/); + my $globFrom = $2; + my $globTo = $1; + my @exprs = reverse (split /\s*&\s*/, $3); + + my @defs = (); + my $index = $globFrom; + + for my $expr (@exprs) { + $expr =~ s/when.*$//; + + return () if ($expr =~ m/\(others/) ; + + if ($expr =~ m/"([01]+)"/) { + $index += length $1; + } else { + my $len = 1; + if ($expr =~ m/\(\s*(\d+)\s*downto\s*(\d+)\s*\)/) { + $len = 1 + $1 - $2; + } + push @defs, [$expr, $index, $len]; + $index += $len; + } + } + + my $expLen = $globTo - $globFrom + 1; + my $totLen = $index - $globFrom; + + print "width mismatch (expected $expLen, got $totLen): $line" if $expLen != $totLen; + + return @defs; +} + +sub readRegs { + my $endpoint = shift; + my $length = shift; + my $firstReg = 0xa008; + my $res = `trbcmd rm $endpoint $firstReg $length 0`; + + my $reg = 0; + my $i = 0; + for my $line (split /\n/, $res) { + if ($line =~ m/^0x....\s+0x(.{8})/) { + $reg += hex($1) << (32 * $i++) ; + } + } + + return $reg; +} + +sub paddListL { + my $maxLen = max (map {length $_} @_); + return map { ' ' x ($maxLen - length $_) . $_ } @_; +} + +sub paddListR { + my $maxLen = max (map {length $_} @_); + return map { $_ . ' ' x ($maxLen - length $_) } @_; +} + +my @lines = readFile( dirname(__FILE__) . "/../code/cbmnet_phy_ecp3.vhd" ); +my @defs = (); + +for my $line (@lines) { + @defs = (@defs, interpretLine $line); +} + +@defs = sort {(lc $a->[0]) cmp (lc $b->[0])} @defs; +my @names = paddListR (map {$_->[0]} @defs); + + + +my @old_results; +while (1) { + my @results = (); + + for my $i (0 .. 1) { + my $reg = readRegs 0x8000 + $i, 8; + my @slices = (); + for my $def (@defs) { + my $idx = $def->[1]; + my $len = $def->[2]; + push @slices, sprintf($len == 1 ? "%x" : "0x%0" . (ceil($len / 4.0)) . "x", ($reg >> $idx) & ((1 << $len) - 1)); + } + + push @results, [paddListL @slices]; + } + + for my $idx (0..$#names) { + my $line = $names[$idx] . " | "; + + for my $i (0..$#results) { + if ($#old_results > 0 and $results[$i]->[$idx] ne $old_results[$i]->[$idx]) { + $line .= (color 'bold') . $results[$i]->[$idx] . (color 'reset'); + } else { + $line .= $results[$i]->[$idx]; + } + + $line .= " | " if ($i < $#old_results); + } + + + print "$line\n"; + } + + @old_results = @results; + + + sleep 1; + print chr(27) . "[1;1H" ; +} \ No newline at end of file diff --git a/cbmnet/test/osci_clk_phase.py b/cbmnet/test/osci_clk_phase.py new file mode 100644 index 0000000..fd4a5f8 --- /dev/null +++ b/cbmnet/test/osci_clk_phase.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python2.7 +import numpy as np +import pylab as plt +import scipy as sp +import scipy.signal as sps +import scipy.ndimage.filters as spf +import sys + +def extractChannels(frame): + defs = [[255, 251, 15], [15, 251, 15], [255,3,255], [15, 251, 255]] + + channels = [] + for de in defs: + fc = frame.copy() + for col in range(3): + d = de[col] + if d < 128: + fc[...,col] = fc[...,col] < (100) + else: + fc[...,col] = fc[...,col] > (150) + + channels.append(255 * fc[...,0] * fc[...,1] * fc[...,2]) + + return [spf.gaussian_filter(ch, 3) for ch in channels] + +def getYValues(ch): + return np.argmax(ch, axis=0) + +def getLocMax(func): + data = func.copy() + m = np.max(data) + data = data * (data > 0.8*m) + data = np.convolve(data, sps.gaussian(31, 5), mode='same') + + wx = 100 + x = 0 + while(x < data.shape[0]): + sub = data[x:x+wx] + idx = np.argmax(sub) + sub[:], sub[idx] = 0, sub[idx] + x += np.max([1, idx]) + + nz = np.nonzero(data) + return nz[0] + +def computePhases(fn, geo): + img = plt.imread(fn) + img = (255.0 * img / np.max(img)).astype('uint8') + frame = img[geo[0]:geo[1],geo[2]:geo[3],:] + + chs = extractChannels(frame) + lms = [] + pers = np.zeros( 4 ) + for i, ch in zip(range(4), chs): + data = getYValues(ch) + lm = getLocMax(data) + assert(len(lm) > 1) + lms.append(lm) + pers[i] = (np.average(lm[1:] - lm[:-1])) + + period = np.average(pers) + assert((((pers - period) / period) ** 2 < 1e-3).all()) + + phases = np.array([np.average( lm - period * np.array(range(len(lm))) ) / period for lm in lms ]) + phases -= phases[0] + phases[phases < 0] += 1 + phases -= phases.astype(int) + + return phases + +fn = sys.argv[1] +val = computePhases(fn, [48,366,75,874]) +if len(val) == 4: + print "ok, phase: ", val +else: + print "fail" + + + + + + + diff --git a/cbmnet/test/phase.py b/cbmnet/test/phase.py new file mode 100755 index 0000000..fd4a5f8 --- /dev/null +++ b/cbmnet/test/phase.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python2.7 +import numpy as np +import pylab as plt +import scipy as sp +import scipy.signal as sps +import scipy.ndimage.filters as spf +import sys + +def extractChannels(frame): + defs = [[255, 251, 15], [15, 251, 15], [255,3,255], [15, 251, 255]] + + channels = [] + for de in defs: + fc = frame.copy() + for col in range(3): + d = de[col] + if d < 128: + fc[...,col] = fc[...,col] < (100) + else: + fc[...,col] = fc[...,col] > (150) + + channels.append(255 * fc[...,0] * fc[...,1] * fc[...,2]) + + return [spf.gaussian_filter(ch, 3) for ch in channels] + +def getYValues(ch): + return np.argmax(ch, axis=0) + +def getLocMax(func): + data = func.copy() + m = np.max(data) + data = data * (data > 0.8*m) + data = np.convolve(data, sps.gaussian(31, 5), mode='same') + + wx = 100 + x = 0 + while(x < data.shape[0]): + sub = data[x:x+wx] + idx = np.argmax(sub) + sub[:], sub[idx] = 0, sub[idx] + x += np.max([1, idx]) + + nz = np.nonzero(data) + return nz[0] + +def computePhases(fn, geo): + img = plt.imread(fn) + img = (255.0 * img / np.max(img)).astype('uint8') + frame = img[geo[0]:geo[1],geo[2]:geo[3],:] + + chs = extractChannels(frame) + lms = [] + pers = np.zeros( 4 ) + for i, ch in zip(range(4), chs): + data = getYValues(ch) + lm = getLocMax(data) + assert(len(lm) > 1) + lms.append(lm) + pers[i] = (np.average(lm[1:] - lm[:-1])) + + period = np.average(pers) + assert((((pers - period) / period) ** 2 < 1e-3).all()) + + phases = np.array([np.average( lm - period * np.array(range(len(lm))) ) / period for lm in lms ]) + phases -= phases[0] + phases[phases < 0] += 1 + phases -= phases.astype(int) + + return phases + +fn = sys.argv[1] +val = computePhases(fn, [48,366,75,874]) +if len(val) == 4: + print "ok, phase: ", val +else: + print "fail" + + + + + + + diff --git a/cbmnet/test/toggle b/cbmnet/test/toggle index a69aa77..b5cf770 100755 --- a/cbmnet/test/toggle +++ b/cbmnet/test/toggle @@ -1,4 +1,6 @@ #!/usr/bin/env bash trbcmd setbit $1 0xa001 $2 -trbcmd clearbit $1 0xa001 $2 \ No newline at end of file +sleep 1 +trbcmd clearbit $1 0xa001 $2 +trbcmd r $1 0xa0001 diff --git a/cbmnet/trb3_periph_cbmnet.p2t b/cbmnet/trb3_periph_cbmnet.p2t old mode 100644 new mode 100755 index 4cac4c4..42de4f4 --- a/cbmnet/trb3_periph_cbmnet.p2t +++ b/cbmnet/trb3_periph_cbmnet.p2t @@ -1,12 +1,13 @@ +#-t is seed -w -i 15 -l 5 --n 1 +#-n 1 -y --s 12 --t 10 +#-s 12 +-t 3 -c 1 --e 2 +#-e 2 #-m nodelist.txt # -w # -i 6 diff --git a/cbmnet/trb3_periph_cbmnet.p3t b/cbmnet/trb3_periph_cbmnet.p3t new file mode 100644 index 0000000..be01654 --- /dev/null +++ b/cbmnet/trb3_periph_cbmnet.p3t @@ -0,0 +1,5 @@ +-rem +-distrce +-log "trb3_periph_cbmnet.log" +-o "trb3_periph_cbmnet.csv" +-pr "trb3_periph_cbmnet.prf" diff --git a/cbmnet/trb3_periph_cbmnet.vhd b/cbmnet/trb3_periph_cbmnet.vhd old mode 100644 new mode 100755 index f44df53..8553a49 --- a/cbmnet/trb3_periph_cbmnet.vhd +++ b/cbmnet/trb3_periph_cbmnet.vhd @@ -14,8 +14,9 @@ use work.cbmnet_phy_pkg.all; entity trb3_periph_cbmnet is generic ( - CBM_FEE_MODE : integer := CBM_FEE_MODE_C -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received + CBM_FEE_MODE : integer := CBM_FEE_MODE_C; -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received -- in Master mode, logic will run on internal clock and regularly send dlms + INCLUDE_TRBNET : integer := INCLUDE_TRBNET_C ); port( --Clocks @@ -72,7 +73,8 @@ entity trb3_periph_cbmnet is SUPPL : in std_logic; --terminated diff pair, PCLK, Pads --Test Connectors - TEST_LINE : out std_logic_vector(15 downto 0); + TEST_LINE : out std_logic_vector(15 downto 0); + --TEST_LVDS_LINE : out std_logic_vector(1 downto 0); -- PCS Core TODO: Suppose this is necessary only for simulation SD_RXD_N_IN : in std_logic; @@ -109,7 +111,6 @@ entity trb3_periph_cbmnet is attribute syn_keep : boolean; attribute syn_keep of CLK_GPLL_LEFT, CLK_GPLL_RIGHT, CLK_PCLK_LEFT, CLK_PCLK_RIGHT, TRIGGER_LEFT, TRIGGER_RIGHT : signal is true; - attribute syn_keep : boolean; attribute syn_preserve : boolean; end entity; @@ -139,7 +140,7 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is --Media Interface - signal med_stat_op : std_logic_vector (1*16-1 downto 0); + signal med_stat_op : std_logic_vector (1*16-1 downto 0) := (others => '0'); signal med_ctrl_op : std_logic_vector (1*16-1 downto 0); signal med_stat_debug : std_logic_vector (1*64-1 downto 0); signal med_ctrl_debug : std_logic_vector (1*64-1 downto 0); @@ -279,7 +280,7 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is signal phy_stat_op, phy_ctrl_op : std_logic_vector(15 downto 0) := (others => '0'); signal phy_stat_debug, phy_ctrl_debug : std_logic_vector(63 downto 0) := (others => '0'); - signal phy_debug_i : std_logic_vector (127 downto 0) := (others => '0'); + signal phy_debug_i : std_logic_vector (255 downto 0) := (others => '0'); -- Link Tester signal link_tester_ctrl_en :std_logic; @@ -299,9 +300,18 @@ architecture trb3_periph_arch of trb3_periph_cbmnet is signal dummy : std_logic; + type SEND_FSM_T is (IDLE, WAITc, SEND); + signal send_fsm_i : SEND_FSM_T; + signal send_wait_counter_i : unsigned(18 downto 0); + signal send_pack_counter_i : unsigned( 4 downto 0); + + signal dlm_counter_i : unsigned(31 downto 0); + begin clk_125_i <= CLK_GPLL_LEFT; + assert(INCLUDE_TRBNET = c_YES); + --------------------------------------------------------------------------- -- CBMNet and PHY --------------------------------------------------------------------------- @@ -347,12 +357,29 @@ begin DEBUG_OUT => phy_debug_i ); + SFP_RATESEL <= (others => '1'); - TEST_LINE(14 downto 0) <= phy_stat_op(14 downto 0); - TEST_LINE(15) <= cbm_dlm2send_va when CBM_FEE_MODE = c_YES else cbm_dlm_rec_va; + TEST_LINE(13 downto 0) <= phy_stat_op(13 downto 0); + TEST_LINE(15 downto 14) <= cbm_dlm2send_va & cbm_dlm_rec_va; + -- FPGA5_COMM(7 downto 4) <= "00" & rclk_125_i & clk_125_i; + + --TEST_LINE(15) <= cbm_dlm2send_va when CBM_FEE_MODE = c_YES else cbm_dlm_rec_va; + process is + variable counter_v : unsigned(20 downto 0); + begin + wait until rising_edge(rclk_125_i); + counter_v := counter_v + to_unsigned(1,1); + cbm_dlm2send_va <= '0'; + if counter_v = 0 then + cbm_dlm2send_va <= '1'; + end if; + end process; + + +-- cbm_data2link <= "00" & x"dead"; THE_CBM_ENDPOINT: lp_top generic map ( NUM_LANES => NUM_LANES, @@ -400,125 +427,69 @@ begin ); cbm_res_n <= not rreset_i; + + + PROC_DATA_SEND: process begin + wait until rising_edge(rclk_125_i); + + send_wait_counter_i <= send_wait_counter_i + TO_UNSIGNED(1,1); + + if cbm_data2send_stop = "0" then + send_pack_counter_i <= send_pack_counter_i + TO_UNSIGNED(1,1); + end if; ---------------------------------------------------------------------------- --- CBMNet Link Tester ---------------------------------------------------------------------------- - GEN_LINK_TESTER_BE: if CBM_FEE_MODE = c_NO generate --- THE_LINK_TESTER: link_tester_be --- generic map ( --- MIN_CTRL_PACKET_SIZE => 12, -- : integer := 12; --- MAX_CTRL_PACKET_SIZE => 60, -- : integer := 60; --- --- DATAWIDTH => 16, -- : integer := 16; --- SINGLE_DEST => 1, -- : integer := 1; --- DATA_PADDING => 0, -- : integer := 0; --- CTRL_PADDING => 16#A5A5# -- : integer := 16#A5A5#; --- ) --- port map ( --- clk => rclk_125_i, -- in std_logic; --- res_n => cbm_res_n, -- in std_logic; --- link_active => cbm_link_active, -- in std_logic; --- --- ctrl_en => link_tester_ctrl_en, -- in std_logic; //enable ctrl packet generation --- dlm_en => link_tester_dlm_en, -- in std_logic; //enable dlm generation --- force_rec_data_stop => link_tester_data_stop, -- in std_logic; //force data flow to stop --- force_rec_ctrl_stop => link_tester_ctrl_stop, -- in std_logic; //force ctrl flow to stop --- --- ctrl2send_stop => cbm_ctrl2send_stop, -- in std_logic; --- ctrl2send_start => cbm_ctrl2send_start, -- out std_logic; --- ctrl2send_end => cbm_ctrl2send_end, -- out std_logic; --- ctrl2send => cbm_ctrl2send, -- out std_logic_vector(15 downto 0); --- --- dlm2send_valid => cbm_dlm2send_va, -- out std_logic; --- dlm2send => cbm_dlm2send, -- out std_logic_vector(3 downto 0); --- --- dlm_rec => cbm_dlm_rec_type, -- in std_logic_vector(3 downto 0); --- dlm_rec_valid => cbm_dlm_rec_va, -- in std_logic; --- --- data_rec_start => cbm_data_rec_start(0), -- in std_logic; --- data_rec_end => cbm_data_rec_end(0), -- in std_logic; --- data_rec => cbm_data_rec, -- in std_logic_vector(DATAWIDTH-1 downto 0); --- data_rec_stop => cbm_data_rec_stop(0), -- out std_logic; --- --- ctrl_rec_start => cbm_ctrl_rec_start, -- in std_logic; --- ctrl_rec_end => cbm_ctrl_rec_end, -- in std_logic; --- ctrl_rec => cbm_ctrl_rec, -- in std_logic_vector(15 downto 0); --- ctrl_rec_stop => cbm_ctrl_rec_stop, -- out std_logic; --- --- data_valid => link_tester_data_valid, -- out std_logic; --- ctrl_valid => link_tester_ctrl_valid, -- out std_logic; --- dlm_valid => link_tester_dlm_valid -- out std_logic --- ); - end generate; - - GEN_LINK_TESTER_FE: if CBM_FEE_MODE = c_YES generate - THE_LINK_TESTER: link_tester_fe - generic map ( - MIN_PACKET_SIZE => 8, -- : integer := 8; - MAX_PACKET_SIZE => 64, -- : integer := 64; - PACKET_GRAN => 2, -- : integer := 2; - MIN_CTRL_PACKET_SIZE => 12, -- : integer := 12; - MAX_CTRL_PACKET_SIZE => 60, -- : integer := 60; + cbm_data2send <= (others => '0'); + cbm_data2send(send_pack_counter_i'HIGH downto 0) <= STD_LOGIC_VECTOR(send_pack_counter_i); + cbm_data2send(send_pack_counter_i'HIGH + 9 downto 9) <= STD_LOGIC_VECTOR(send_pack_counter_i); + + cbm_data2send_start <= "0"; + cbm_data2send_end <= "0"; + + case(send_fsm_i) is + when IDLE => + if cbm_link_active='1' and cbm_data2send_stop = "0" then + send_fsm_i <= WAITc; + send_wait_counter_i <= (others => '0'); + end if; + + when WAITc => + if send_wait_counter_i(send_pack_counter_i'HIGH) = '1' then + send_fsm_i <= SEND; + cbm_data2send_start <= "1"; + end if; + + when SEND => + if send_wait_counter_i(send_pack_counter_i'HIGH) = '1' then + cbm_data2send_end <= "1"; + send_fsm_i <= IDLE; + end if; + end case; + + if reset_i = '1' then + send_fsm_i <= IDLE; + end if; + end process; - CTRL_PADDING => 16#A5A5#, -- : integer := 16#A5A5#; - - OWN_ADDR => "1000000000000000", -- : std_logic_vector(15 downto 0) := "1000000000000000"; - DEST_ADDR => "1000000000000000", -- : std_logic_vector(15 downto 0) := "0000000000000000"; + PROC_DLM_COUNTER: process is + variable dlm_type_v : integer range 15 downto 0; + begin + wait until rising_edge(rclk_125_i); + + if reset_i = '1' then + dlm_counter_i <= (others => '0'); + elsif cbm_dlm_rec_va = '1' then + dlm_type_v := to_integer(unsigned(cbm_dlm_rec_type)); + for i in 0 to 15 loop + if dlm_type_v = i then + dlm_counter_i(1+i*2 downto i*2) <= dlm_counter_i(1+i*2 downto i*2) + TO_UNSIGNED(1,1); + end if; + end loop; + end if; + end process; - PACKET_MODE => 1 -- : integer := 1 --if enabled generates another packet size order to test further corner cases - ) - port map ( - clk => rclk_125_i, -- in std_logic; - res_n => cbm_res_n, -- in std_logic; - link_active => cbm_link_active, -- in std_logic; - - data_en => link_tester_data_en, -- in std_logic; //enable data packet generation - ctrl_en => link_tester_ctrl_en, -- in std_logic; //enable ctrl packet generation - force_rec_ctrl_stop => link_tester_ctrl_stop, -- in std_logic; //force ctrl flow to stop - - ctrl2send_stop => cbm_ctrl2send_stop, -- in std_logic; - ctrl2send_start => cbm_ctrl2send_start, -- out std_logic; - ctrl2send_end => cbm_ctrl2send_end, -- out std_logic; - ctrl2send => cbm_ctrl2send, -- out std_logic_vector(15 downto 0); - - data2send_stop => cbm_data2send_stop(0), -- in std_logic; - data2send_start => cbm_data2send_start(0), -- out std_logic; - data2send_end => cbm_data2send_end(0), -- out std_logic; - data2send => cbm_data2send, -- out std_logic_vector(15 downto 0); - - dlm2send_valid => cbm_dlm2send_va, -- out std_logic; - dlm2send => cbm_dlm2send, -- out std_logic_vector(3 downto 0); - - dlm_rec => cbm_dlm_rec_type, -- in std_logic_vector(3 downto 0); - dlm_rec_valid => cbm_dlm_rec_va, -- in std_logic; - - data_rec_start => cbm_data_rec_start(0), -- in std_logic; - data_rec_end => cbm_data_rec_end(0), -- in std_logic; - data_rec => cbm_data_rec, -- in std_logic_vector(15 downto 0); - data_rec_stop => cbm_data_rec_stop(0), -- out std_logic; - - ctrl_rec_start => cbm_ctrl_rec_start, -- in std_logic; - ctrl_rec_end => cbm_ctrl_rec_end, -- in std_logic; - ctrl_rec => cbm_ctrl_rec, -- in std_logic_vector(15 downto 0); - ctrl_rec_stop => cbm_ctrl_rec_stop -- out std_logic - ); - end generate; - link_tester_stat <= ( - 0 => link_tester_data_valid, - 1 => link_tester_ctrl_valid, - 2 => link_tester_dlm_valid, - others => '0' - ); - link_tester_data_en <= link_tester_ctrl(0); - link_tester_ctrl_en <= link_tester_ctrl(1); - link_tester_dlm_en <= link_tester_ctrl(2); - link_tester_data_stop <= link_tester_ctrl(4); - link_tester_ctrl_stop <= link_tester_ctrl(5); - PROC_REGIO_DEBUG: process is variable address : integer range 0 to 255; begin @@ -537,13 +508,20 @@ begin when 16#4# => debug_data_out <= phy_ctrl_debug(31 downto 0); when 16#5# => debug_data_out <= phy_ctrl_debug(63 downto 32); when 16#6# => debug_data_out <= STD_LOGIC_VECTOR(TO_UNSIGNED(CBM_FEE_MODE, 32)); + when 16#8# => debug_data_out <= phy_debug_i(31+32*0 downto 32*0); when 16#9# => debug_data_out <= phy_debug_i(31+32*1 downto 32*1); when 16#a# => debug_data_out <= phy_debug_i(31+32*2 downto 32*2); when 16#b# => debug_data_out <= phy_debug_i(31+32*3 downto 32*3); - - when 16#c# => debug_data_out <= link_tester_stat; - when 16#d# => debug_data_out <= link_tester_ctrl; + when 16#c# => debug_data_out <= phy_debug_i(31+32*4 downto 32*4); + when 16#d# => debug_data_out <= phy_debug_i(31+32*5 downto 32*5); + when 16#e# => debug_data_out <= phy_debug_i(31+32*6 downto 32*6); + when 16#f# => debug_data_out <= phy_debug_i(31+32*7 downto 32*7); + + when 16#10# => debug_data_out <= link_tester_stat; + when 16#11# => debug_data_out <= link_tester_ctrl; + + when 16#12# => debug_data_out <= dlm_counter_i; when others => debug_ack <= '0'; end case; @@ -554,12 +532,15 @@ begin when 16#4# => phy_ctrl_debug(31 downto 0) <= debug_data_in; when 16#5# => phy_ctrl_debug(63 downto 32) <= debug_data_in; - when 16#d# => link_tester_ctrl <= debug_data_in; + when 16#11# => link_tester_ctrl <= debug_data_in; when others => debug_ack <= '0'; end case; end if; end process; - + + + + --------------------------------------------------------------------------- -- Reset Generation --------------------------------------------------------------------------- @@ -598,7 +579,7 @@ begin pll_lock <= pll_lock1; -- and pll_lock2; - +-- GEN_TRBNET: if INCLUDE_TRBNET = c_YES generate --------------------------------------------------------------------------- -- The TrbNet media interface (to other FPGA) --------------------------------------------------------------------------- @@ -898,12 +879,15 @@ begin LED_RED <= not time_counter(26); LED_YELLOW <= not med_stat_op(11); ---------------------------------------------------------------------------- --- Test Circuits ---------------------------------------------------------------------------- - process - begin - wait until rising_edge(clk_100_i); - time_counter <= time_counter + 1; - end process; +-- end generate; + + +------ DUMMY to check integrity of TEST_LINE connection +-- process is +-- variable test_line_v : std_logic_vector(15 downto 0) := x"0001"; +-- begin +-- wait until rising_edge(rclk_125_i); +-- test_line_v := test_line_v(14 downto 0) & test_line_v(15); +-- TEST_LINE <= test_line_v; +-- end process; end architecture; \ No newline at end of file diff --git a/cbmnet/trb3_periph_cbmnet_constraints.lpf b/cbmnet/trb3_periph_cbmnet_constraints.lpf index feee12b..381c50a 100644 --- a/cbmnet/trb3_periph_cbmnet_constraints.lpf +++ b/cbmnet/trb3_periph_cbmnet_constraints.lpf @@ -8,8 +8,9 @@ SYSCONFIG MCCLK_FREQ = 20; - FREQUENCY PORT CLK_PCLK_RIGHT 200 MHz; - FREQUENCY PORT CLK_PCLK_LEFT 200 MHz; +# FREQUENCY PORT CLK_PCLK_RIGHT 200 MHz; +# FREQUENCY PORT CLK_PCLK_LEFT 200 MHz; + FREQUENCY PORT CLK_GPLL_RIGHT 200 MHz; FREQUENCY PORT CLK_GPLL_LEFT 125 MHz; @@ -17,13 +18,13 @@ FREQUENCY NET "THE_CBM_PHY/RCLK_250_I" 250 MHz; #Change the next two lines to the clk_fast signal of the ADC - USE PRIMARY2EDGE NET "THE_MAIN_PLL/PLLInst_0"; - USE PRIMARY NET "THE_MAIN_PLL/PLLInst_0"; - USE PRIMARY NET "CLK_PCLK_LEFT"; - USE PRIMARY NET "CLK_PCLK_LEFT_c"; +# USE PRIMARY2EDGE NET "THE_MAIN_PLL/PLLInst_0"; +# USE PRIMARY NET "THE_MAIN_PLL/PLLInst_0"; +# USE PRIMARY NET "CLK_PCLK_LEFT"; +# USE PRIMARY NET "CLK_PCLK_LEFT_c"; - USE PRIMARY NET "THE_CBM_PHY/RCLK_250_I"; - USE SECONDARY NET "THE_CBM_PHY/CLK_TX_FULL_I"; +# USE PRIMARY NET "THE_CBM_PHY/RCLK_250_I"; +# USE SECONDARY NET "THE_CBM_PHY/CLK_TX_FULL_I"; ################################################################# # Reset Nets @@ -38,6 +39,10 @@ LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200_THE_SERDES/PCSD_INST" SITE "PCS REGION "MEDIA_UPLINK" "R102C95D" 13 25; LOCATE UGROUP "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLINK" ; +LOCATE COMP "THE_CBM_PHY/THE_SERDES/PCSD_INST" SITE "PCSB" ; +REGION "CBM_PHY" "R102C49D" 13 25; +LOCATE UGROUP "THE_CBM_PHY/cbmnet_phy_group" REGION "CBM_PHY"; + ################################################################# # Relax some of the timing constraints -- 2.43.0