~ruther/jesd204b-vhdl

1103c72652ca7d2a3647fb3ac0709a7f57b3787a — František Boháček 2 years ago 3f3f62d
feat(link): add error handler entity for managing data link errors (lane misalignment, frame misalignment, not in table error, disparity error, unexpected character error)
M src/data_link/data_link_layer.vhd => src/data_link/data_link_layer.vhd +37 -12
@@ 22,6 22,9 @@ entity data_link_layer is
    co_lane_ready : out std_logic;      -- Received /A/, waiting for lane sync
    ci_lane_start : in std_logic;       -- Start sending data from lane buffer

    -- errors
    ci_error_config : in error_handling_config;

    -- input, output
    co_synced : out std_logic;
    di_10b : in std_logic_vector(9 downto 0);


@@ 33,21 36,25 @@ architecture a1 of data_link_layer is

  signal decoder_do_char : character_vector;

  signal lane_alignment_ci_realign : std_logic := '0';
  signal lane_alignment_co_aligned : std_logic;
  signal lane_alignment_co_error : std_logic;
  signal lane_alignment_co_ready : std_logic;
  signal lane_alignment_do_char : character_vector;
  signal lane_alignment_co_correct_sync_chars : integer;

  signal frame_alignment_ci_request_sync : std_logic;
  signal frame_alignment_ci_enable_realign : std_logic := '0';
  signal frame_alignment_ci_realign : std_logic := '0';
  signal frame_alignment_co_aligned : std_logic;
  signal frame_alignment_co_error : std_logic;
  signal frame_alignment_do_char : frame_character;
  signal frame_alignment_co_correct_sync_chars : integer;

  signal link_controller_co_synced : std_logic;
  signal link_controller_co_state : link_state;
  signal link_controller_do_config : link_config;
  signal link_controller_ci_resync : std_logic := '0';
  signal link_controller_ci_resync : std_logic;

begin  -- architecture a1
  do_lane_config <= link_controller_do_config;
  co_lane_ready <= lane_alignment_co_ready;


@@ 61,6 68,23 @@ begin  -- architecture a1
  --          |            |                         |        |
  --  FRAME ALIGNMENT <= LANE ALIGNMENT <= 8b10b DECODER <= CHAR ALIGNMENT

  -- error handling
  error_handling : entity work.error_handler
    port map (
      ci_char_clk                      => ci_char_clk,
      ci_reset                         => ci_reset,
      ci_state                         => link_controller_co_state,
      ci_F                             => ci_F,
      di_char                          => decoder_do_char,
      ci_config                        => ci_error_config,
      ci_lane_alignment_error          => lane_alignment_co_error,
      ci_frame_alignment_error         => frame_alignment_co_error,
      ci_lane_alignment_correct_count  => lane_alignment_co_correct_sync_chars,
      ci_frame_alignment_correct_count => frame_alignment_co_correct_sync_chars,
      co_frame_alignment_realign       => frame_alignment_ci_realign,
      co_lane_alignment_realign        => lane_alignment_ci_realign,
      co_request_sync                  => link_controller_ci_resync);

  -- link controller
  link_controller : entity work.link_controller
    port map (


@@ 110,15 134,16 @@ begin  -- architecture a1
  -- frame alignment
  frame_alignment : entity work.frame_alignment
    port map (
      ci_char_clk       => ci_char_clk,
      ci_reset          => ci_reset,
      ci_scrambled      => ci_scrambled,
      ci_F              => ci_F,
      ci_K              => ci_K,
      ci_request_sync   => frame_alignment_ci_request_sync,
      ci_enable_realign => frame_alignment_ci_enable_realign,
      co_aligned        => frame_alignment_co_aligned,
      co_misaligned     => frame_alignment_co_error,
      di_char           => lane_alignment_do_char);
      ci_char_clk           => ci_char_clk,
      ci_reset              => ci_reset,
      ci_scrambled          => ci_scrambled,
      ci_F                  => ci_F,
      ci_K                  => ci_K,
      co_correct_sync_chars => frame_alignment_co_correct_sync_chars,
      ci_request_sync       => frame_alignment_ci_request_sync,
      ci_realign            => frame_alignment_ci_realign,
      co_aligned            => frame_alignment_co_aligned,
      co_error              => frame_alignment_co_error,
      di_char               => lane_alignment_do_char);

end architecture a1;

M src/data_link/data_link_pkg.vhd => src/data_link/data_link_pkg.vhd +16 -0
@@ 53,4 53,20 @@ package data_link_pkg is
    CHKSUM    : integer range 0 to 255;
  end record link_config;

  type error_handling_config is record
    lane_alignment_realign_after  : integer;  -- realign after correctly
                                              -- received X alignment
                                              -- characters (0 to disable)
    frame_alignment_realign_after : integer;  -- realign after correctly
                                              -- received X alignment
                                              -- characters (0 to disable)
    tolerate_missing_in_frame     : integer;  -- How many missing errors to
                                              -- tolerate in a frame (0 to disable)
    tolerate_disparity_in_frame   : integer;  -- How many disparity errors to
                                              -- tolerate in a frame (0 to disable)
    tolerate_unexpected_characters_in_frame : integer;  -- How many unexpected
                                                        -- characters to
                                                        -- tolerate in a frame
  end record error_handling_config;

end package data_link_pkg;

A src/data_link/error_handler.vhd => src/data_link/error_handler.vhd +82 -0
@@ 0,0 1,82 @@
library ieee;
use ieee.std_logic_1164.all;
use work.data_link_pkg.all;

entity error_handler is
  port (
    ci_char_clk                      : in  std_logic;
    ci_reset                         : in  std_logic;
    ci_state                         : in link_state;

    ci_F : in integer range 0 to 256;

    di_char                          : in  character_vector;

    ci_config                        : in  error_handling_config;
    ci_lane_alignment_error          : in  std_logic;
    ci_lane_alignment_correct_count  : in  integer;
    ci_frame_alignment_error         : in  std_logic;
    ci_frame_alignment_correct_count : in  integer;

    co_frame_alignment_realign       : out std_logic;
    co_lane_alignment_realign        : out std_logic;
    co_request_sync                  : out std_logic);
end entity error_handler;

architecture a1 of error_handler is
  signal active : std_logic;

  signal reg_index : integer range 0 to 256 := 0;
  signal reg_request_sync : std_logic;
  signal reg_missing_count : integer range 0 to 256 := 0;
  signal reg_disparity_count : integer range 0 to 256 := 0;
  signal reg_unexpected_count : integer range 0 to 256 := 0;

  signal next_index : integer range 0 to 256 := 0;
  signal next_request_sync : std_logic;
  signal next_missing_count : integer range 0 to 256 := 0;
  signal next_disparity_count : integer range 0 to 256 := 0;
  signal next_unexpected_count : integer range 0 to 256 := 0;
begin  -- architecture a1
  set_next: process (ci_char_clk, ci_reset) is
  begin  -- process set_next
    if ci_reset = '0' then              -- asynchronous reset (active low)
      reg_index <= 0;
      reg_request_sync <= '0';
      reg_missing_count <= 0;
      reg_disparity_count <= 0;
      reg_unexpected_count <= 0;
    elsif ci_char_clk'event and ci_char_clk = '1' then  -- rising clock edge
      reg_index <= next_index;
      reg_request_sync <= next_request_sync;
      reg_missing_count <= next_missing_count;
      reg_disparity_count <= next_disparity_count;
      reg_unexpected_count <= next_unexpected_count;
    end if;
  end process set_next;

  co_request_sync <= reg_request_sync;
  active <= '1' when di_char.user_data = '1' and ci_state /= INIT else '0';
  next_index <= 0 when active = '0' else
                (reg_index + 1) mod ci_F;

  next_request_sync <= '0' when active = '0' else
                       '1' when reg_request_sync = '1' else
                       '1' when ci_lane_alignment_correct_count >= ci_config.lane_alignment_realign_after else
                       '1' when ci_frame_alignment_correct_count >= ci_config.frame_alignment_realign_after else
                       '1' when reg_missing_count > ci_config.tolerate_missing_in_frame else
                       '1' when reg_disparity_count > ci_config.tolerate_disparity_in_frame else
                       '1' when reg_unexpected_count > ci_config.tolerate_unexpected_characters_in_frame else
                       '0';

  next_missing_count <= 0 when next_index = 0 else
                        next_missing_count when di_char.missing_error = '0' else
                        next_missing_count + 1;
  next_disparity_count <= 0 when next_index = 0 else
                        next_disparity_count when di_char.disparity_error = '0' else
                        next_disparity_count + 1;
  next_unexpected_count <= 0 when next_index = 0 else
                          next_unexpected_count when ci_state = DATA and di_char.kout = '1' and not (di_char.d8b = "11111100" or di_char.d8b = "01111100") else
                          next_unexpected_count + 1;

end architecture a1;

Do not follow this link