diff --git a/Makefile b/Makefile index 208b0147b97b9d22425f4e61f288a30d0c716534..0a1aca45b4a9c971c21f92631d6a2183bd992420 100644 --- a/Makefile +++ b/Makefile @@ -20,8 +20,7 @@ tcl/sources.tcl: ############################################################################### # Compute interface from rdl files -# TODO: generic rule from variables -hdl/combpm_protocol_electron_ctrl.vhd: rdl/combpm_protocol_electron_ctrl.rdl +hdl/%.vhd:rdl/%.rdl hectare --axi-vhdl $@ $< ############################################################################### diff --git a/hdl/combpm_protocol_electron.vhd b/hdl/combpm_protocol_electron.vhd index 273bbb8c05c024efaf1d7db3e96e7226965c2755..32c3c05901a828d1c0207bbf62241a9f891d1b10 100644 --- a/hdl/combpm_protocol_electron.vhd +++ b/hdl/combpm_protocol_electron.vhd @@ -7,11 +7,13 @@ entity combpm_protocol_electron is port( rst_n : in std_logic; clk : in std_logic; + pps : in std_logic; + + mc_time : in std_logic_vector(39 downto 0); -- GT interface gt_datarx : in std_logic_vector(15 downto 0); - gt_rxresetdone : in std_logic; - gt_rxbyteisaligned : in std_logic; + gt_interfaceready : in std_logic; -- AXIS interface m_axi_tid : out std_logic_vector(0 downto 0); @@ -26,7 +28,13 @@ entity combpm_protocol_electron is -- Status and control interface soft_reset : in std_logic; - frame_counter : out std_logic_vector(15 downto 0); + frame_seq_cnt : out std_logic_vector(15 downto 0); + frame_valid_cnt : out std_logic_vector(15 downto 0); + frame_invalid_cnt : out std_logic_vector(15 downto 0); + frame_valid_rate : out std_logic_vector(15 downto 0); + frame_invalid_rate : out std_logic_vector(15 downto 0); + cnt_seq_mismatch : out std_logic; + seq_discontinuity : out std_logic; frame_error : out std_logic ); end entity combpm_protocol_electron; @@ -71,10 +79,14 @@ architecture rtl of combpm_protocol_electron is signal crc_cnt : unsigned(3 downto 0); signal d : std_logic_vector(15 downto 0); - signal frame_counter_r : unsigned(15 downto 0); - signal gt_rxcommadeten_s : std_logic; + signal last_seq : std_logic_vector(15 downto 0); - signal itf_ready : std_logic; + signal last_cnt_seq_r : unsigned(15 downto 0); + signal cnt_frame_seq_r : unsigned(15 downto 0); + signal cnt_valid_r : unsigned(15 downto 0); + signal cnt_invalid_r : unsigned(15 downto 0); + signal rate_valid_r : unsigned(15 downto 0); + signal rate_invalid_r : unsigned(15 downto 0); begin @@ -119,8 +131,8 @@ begin '0'; -- Any and all flag - flag_all <= flag_sop and flag_eop and flag_dummy and flag_rsvd and flag_crc and itf_ready; - flag_any <= flag_sop or flag_eop or flag_crc; + flag_all <= flag_sop and flag_eop and flag_dummy and flag_rsvd and flag_crc and gt_interfaceready; + flag_any <= (flag_sop or flag_eop or flag_crc) and gt_interfaceready; ---------------------------- -- FRAME FIELD EXTRACTION -- @@ -244,8 +256,8 @@ begin -- Make AXIS packet m_axi_tdata(31 downto 0) <= packet_ypos; m_axi_tdata(63 downto 32) <= packet_xpos; - m_axi_tdata(95 downto 64) <= x"0000" & packet_timestamp; - m_axi_tdata(111 downto 96) <= (others => '0'); + m_axi_tdata(103 downto 64) <= mc_time; + m_axi_tdata(111 downto 104) <= packet_timestamp(7 downto 0); m_axi_tdata(127 downto 112) <= "000000" & packet_bpmid; -- AXIS ancillary data @@ -268,22 +280,82 @@ begin ------------------------ -- CONTROL AND STATUS -- ------------------------ - frame_error <= flag_any xor flag_all; - frame_counter <= std_logic_vector(frame_counter_r); - itf_ready <= gt_rxresetdone and gt_rxbyteisaligned; + frame_error <= flag_all xor flag_any; + frame_valid_cnt <= std_logic_vector(cnt_valid_r); + frame_invalid_cnt <= std_logic_vector(cnt_invalid_r); + frame_seq_cnt <= std_logic_vector(last_cnt_seq_r); -- frame counter p_framecnt:process(clk, rst_n) begin if rst_n = '0' then - frame_counter_r <= (others => '0'); + cnt_frame_seq_r <= (others => '0'); + cnt_valid_r <= (others => '0'); + cnt_invalid_r <= (others => '0'); + rate_valid_r <= (others => '0'); + rate_invalid_r <= (others => '0'); elsif rising_edge(clk) then + if soft_reset = '1' then - frame_counter_r <= (others => '0'); + cnt_frame_seq_r <= (others => '0'); + cnt_valid_r <= (others => '0'); + cnt_invalid_r <= (others => '0'); + rate_valid_r <= (others => '0'); + rate_invalid_r <= (others => '0'); else + -- Valid frame counter if flag_all = '1' then - frame_counter_r <= frame_counter_r+1; + cnt_valid_r <= cnt_valid_r+1; + end if; + + -- Invalid frame counter + if (flag_all xor flag_any) = '1' then + cnt_invalid_r <= cnt_invalid_r+1; end if; + + -- Rate counter + if pps = '1' then + frame_valid_rate <= std_logic_vector(rate_valid_r); + frame_invalid_rate <= std_logic_vector(rate_invalid_r); + rate_valid_r <= (others => '0'); + rate_invalid_r <= (others => '0'); + else + -- Valid frame rate counter + if flag_all = '1' then + rate_valid_r <= rate_valid_r+1; + end if; + + -- Invalid frame rate counter + if (flag_all xor flag_any) = '1' then + rate_invalid_r <= rate_invalid_r+1; + end if; + end if; + + -- Sequence detection + cnt_seq_mismatch <= '0'; -- Supercharged in logic below + seq_discontinuity <= '0'; -- Supercharged in logic below + if flag_all = '1' then + if last_seq = packet_timestamp then + -- Same sequence + cnt_frame_seq_r <= cnt_frame_seq_r+1; + else + -- New sequence + cnt_frame_seq_r <= (others => '0'); + last_seq <= packet_timestamp; + last_cnt_seq_r <= cnt_frame_seq_r; + + -- Check sequence increment + if unsigned(packet_timestamp) - unsigned(last_seq) /= 1 then + seq_discontinuity <= '1'; + end if; + + -- Check number of frame in sequence + if last_cnt_seq_r /= cnt_frame_seq_r then + cnt_seq_mismatch <= '1'; + end if; + end if; + end if; + end if; end if; end process p_framecnt; diff --git a/hdl/top_combpm_electron.vhd b/hdl/top_combpm_electron.vhd index 30789d71fe0d767b9c3125efe33b810033b5c129..fe7b8adef5763326ea79a65bcaa3884780515869 100644 --- a/hdl/top_combpm_electron.vhd +++ b/hdl/top_combpm_electron.vhd @@ -15,7 +15,9 @@ entity top_combpm_electron is rst_n : in std_logic; -- Asynchronous reset free_100_clk : in std_logic; -- Freerunning clock for GT + pps : in std_logic; -- A pulse per second signal, sync to clk domain clk : out std_logic; -- main clock (AXIS and AXI-MM) + mc_time : in std_logic_vector(39 downto 0); -- Transceiver QPLL interface qpll_out_clk : in std_logic; -- QPLL clock for transceivers @@ -162,10 +164,17 @@ architecture struct of top_combpm_electron is signal sync_reset : std_logic; signal usrclk : std_logic; signal rst : std_logic; - signal frame_counter : std_logic_vector(15 downto 0); - signal frame_error : std_logic; signal soft_reset : std_logic; + signal frame_seq_cnt : std_logic_vector(15 downto 0); + signal frame_valid_cnt : std_logic_vector(15 downto 0); + signal frame_invalid_cnt : std_logic_vector(15 downto 0); + signal frame_valid_rate : std_logic_vector(15 downto 0); + signal frame_invalid_rate : std_logic_vector(15 downto 0); + signal cnt_seq_mismatch : std_logic; + signal seq_discontinuity : std_logic; + signal frame_error : std_logic; + signal gt_datarx : std_logic_vector(15 downto 0); signal gt_powergood : std_logic; signal gt_rxclkactive : std_logic; @@ -178,6 +187,8 @@ architecture struct of top_combpm_electron is signal gt_rxresetdatapath : std_logic; signal gt_rxresetplldatapath : std_logic; + signal interface_ready : std_logic; + begin @@ -211,6 +222,8 @@ begin -- SFP direct connexion sfp_tx_disable <= '1'; + -- Interface Ready signal combinatorial + interface_ready <= gt_powergood and gt_rxresetdone and gt_rxbyteisaligned and qpll_lock; ---------------------- -- AXI-MM INTERFACE -- @@ -233,10 +246,16 @@ begin gt_rxcommadeten_o => gt_rxcommadeten, gt_rxrstdatapath_o => gt_rxresetdatapath, gt_rxrstplldatapath_o => gt_rxresetplldatapath, - protocol_framecnt_i => frame_counter, - protocol_frameerror_i => frame_error, protocol_softreset_o => soft_reset, + protocol_frameerror_i => frame_error, + protocol_seqframecnterror_i => cnt_seq_mismatch, + protocol_seqframediscont_i => seq_discontinuity, + framecnt_validframecnt_i => frame_valid_cnt, + framecnt_invalidframecnt_i => frame_invalid_cnt, + framerate_validframerate_i => frame_valid_rate, + framerate_invalidframerate_i => frame_invalid_rate, + clk => usrclk, reset => sync_reset, S_AXI_AWADDR => S_AXI_AWADDR, @@ -267,9 +286,9 @@ begin port map( rst_n => sync_resetn, clk => usrclk, + pps => pps, gt_datarx => gt_datarx, - gt_rxresetdone => gt_rxresetdone, - gt_rxbyteisaligned => gt_rxbyteisaligned, + gt_interfaceready => interface_ready, m_axi_tid => m_axis_tid, m_axi_tdest => m_axis_tdest, @@ -281,10 +300,16 @@ begin m_axi_tvalid => m_axis_tvalid, m_axi_tready => m_axis_tready, + mc_time => mc_time, soft_reset => soft_reset, - frame_counter => frame_counter, + frame_seq_cnt => frame_seq_cnt, + frame_valid_cnt => frame_valid_cnt, + frame_invalid_cnt => frame_invalid_cnt, + frame_valid_rate => frame_valid_rate, + frame_invalid_rate => frame_invalid_rate, + cnt_seq_mismatch => cnt_seq_mismatch, + seq_discontinuity => seq_discontinuity, frame_error => frame_error - ); --------------- diff --git a/rdl/combpm_protocol_electron_ctrl.rdl b/rdl/combpm_ctrl.rdl similarity index 70% rename from rdl/combpm_protocol_electron_ctrl.rdl rename to rdl/combpm_ctrl.rdl index 559c0b5ee70ae504a9e9f177a40cd9903c46912b..98745d9cc596d4f899bf6752c8ddda3a584dc06c 100644 --- a/rdl/combpm_protocol_electron_ctrl.rdl +++ b/rdl/combpm_ctrl.rdl @@ -96,24 +96,55 @@ addrmap combpm_ctrl { reg { name="Protocol status and control"; - field { - desc="Frame counter"; - hw=w; - sw=r; - } FRAMECNT[16]; - field { desc="Frame error"; - hw=w; - sw=r; + hw=w;sw=r; } FRAMEERROR; + field { + desc="Sequence frame count mismatch"; + hw=w;sw=r; + } SEQFRAMECNTERROR; + + field { + desc="Sequence frame discontinuity"; + hw=w;sw=r; + } SEQFRAMEDISCONT; + field { desc="Soft reset"; - hw=r; - sw=rw; + hw=r;sw=rw; } SOFTRESET; } PROTOCOL; + reg { + name="Protocol frame counters"; + + field { + desc="Valid frame counter"; + hw=w;sw=r; + } VALIDFRAMECNT[16]; + + field { + desc="Invalid frame counter"; + hw=w;sw=r; + } INVALIDFRAMECNT[16]; + } FRAMECNT; + + reg { + name="Protocol frame rate"; + + field { + desc="Valid frame rate"; + hw=w;sw=r; + } VALIDFRAMERATE[16]; + + field { + desc="Invalid frame rate"; + hw=w;sw=r; + } INVALIDFRAMERATE[16]; + } FRAMERATE; + + };