~ruther/jesd204b-vhdl

6d8dae899548d0b864be14ee437f233269fe47b3 — František Boháček 1 year, 11 months ago c2a645a
feat: split samples to sample and control bits
M src/jesd204b_link_rx.vhd => src/jesd204b_link_rx.vhd +8 -6
@@ 57,11 57,12 @@ entity jesd204b_link_rx is
    co_nsynced : out std_logic;  -- Whether receiver is synced (active low)
    co_error   : out std_logic;

    di_data : in  lane_input_array(0 to L-1);  -- Data from transceivers
    do_samples          : out samples_array(0 to M - 1, 0 to S - 1);
    co_frame_state      : out frame_state;  -- Output samples
    co_correct_data     : out std_logic);  -- Whether samples are correct user
                                           -- data
    di_data         : in  lane_input_array(0 to L-1);  -- Data from transceivers
    do_samples      : out samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
    do_ctrl_bits    : out ctrl_bits_array(0 to M - 1, 0 to S - 1)(CS - 1 downto 0);
    co_frame_state  : out frame_state;  -- Output samples
    co_correct_data : out std_logic);   -- Whether samples are correct user
                                        -- data
end entity jesd204b_link_rx;

architecture a1 of jesd204b_link_rx is


@@ 244,6 245,7 @@ begin  -- architecture a1
      di_lanes_data   => transport_chars_array,
      ci_frame_states => transport_frame_state_array,
      co_frame_state  => co_frame_state,
      do_samples_data => do_samples);
      do_ctrl_bits    => do_ctrl_bits,
      do_samples      => do_samples);

end architecture a1;

M src/jesd204b_multipoint_link_rx.vhd => src/jesd204b_multipoint_link_rx.vhd +41 -39
@@ 7,40 7,41 @@ use work.transport_pkg.all;
entity jesd204b_multipoint_link_rx is

  generic (
    K_CHAR          : std_logic_vector(7 downto 0) := "10111100";  -- Sync character
    R_CHAR          : std_logic_vector(7 downto 0) := "00011100";  -- ILAS first
    K_CHAR            : std_logic_vector(7 downto 0) := "10111100";  -- Sync character
    R_CHAR            : std_logic_vector(7 downto 0) := "00011100";  -- ILAS first
                                        -- frame character
    A_CHAR          : std_logic_vector(7 downto 0) := "01111100";  -- Multiframe
    A_CHAR            : std_logic_vector(7 downto 0) := "01111100";  -- Multiframe
                                        -- alignment character
    Q_CHAR          : std_logic_vector(7 downto 0) := "10011100";  -- ILAS 2nd
    DATA_RATE       : integer;  -- DEVICE_CLK_FREQ*this is lane bit rate
    Q_CHAR            : std_logic_vector(7 downto 0) := "10011100";  -- ILAS 2nd
    DATA_RATE         : integer;  -- DEVICE_CLK_FREQ*this is lane bit rate
                                     -- frame 2nd character
    MULTIFRAME_RATE      : integer;     -- F * K, should be the same for every
    MULTIFRAME_RATE   : integer;        -- F * K, should be the same for every
                                        -- device
    ALIGN_BUFFER_SIZE : integer                      := 255;  -- Size of a
                                                              -- buffer that is
                                                              -- used for
                                                              -- aligning lanes
    RX_BUFFER_DELAY      : integer range 1 to 32        := 1;
    LINKS                : integer;     -- Count of links
    LANES                : integer;     -- Total nubmer of lanes
    CONVERTERS           : integer;     -- Total number of converters
    CONFIG               : link_config_array(0 to LINKS - 1);
    ERROR_CONFIG         : error_handling_config        := (2, 0, 5, 5, 5));
    RX_BUFFER_DELAY   : integer range 1 to 32        := 1;
    LINKS             : integer;        -- Count of links
    LANES             : integer;        -- Total nubmer of lanes
    CONVERTERS        : integer;        -- Total number of converters
    CONFIG            : link_config_array(0 to LINKS - 1);
    ERROR_CONFIG      : error_handling_config        := (2, 0, 5, 5, 5));

  port (
    ci_device_clk       : in  std_logic;
    ci_char_clk         : in  std_logic;
    ci_frame_clk        : in  std_logic;
    ci_sysref           : in  std_logic;
    ci_reset            : in  std_logic;
    ci_request_sync     : in  std_logic;
    co_nsynced          : out std_logic;
    co_error            : out std_logic;
    di_data : in  lane_input_array(0 to LANES - 1);
    do_samples          : out simple_samples_array(0 to LINKS - 1)(0 to CONFIG(0).M - 1, 0 to CONFIG(0).CS - 1);
    co_frame_state      : out frame_state_array(0 to LINKS - 1);
    co_correct_data     : out std_logic);
    ci_device_clk   : in  std_logic;
    ci_char_clk     : in  std_logic;
    ci_frame_clk    : in  std_logic;
    ci_sysref       : in  std_logic;
    ci_reset        : in  std_logic;
    ci_request_sync : in  std_logic;
    co_nsynced      : out std_logic;
    co_error        : out std_logic;
    di_data         : in  lane_input_array(0 to LANES - 1);
    do_samples      : out samples_array(0 to CONVERTERS - 1);
    do_ctrl_bits    : out ctrl_bits_array(0 to CONVERTERS - 1);
    co_frame_state  : out frame_state_array(0 to LINKS - 1);
    co_correct_data : out std_logic);

end entity jesd204b_multipoint_link_rx;



@@ 118,10 119,10 @@ begin  -- architecture a1
  links_rx : for i in 0 to LINKS - 1 generate
    link : entity work.jesd204b_link_rx
      generic map (
        K_CHAR       => K_CHAR,
        R_CHAR       => R_CHAR,
        A_CHAR       => A_CHAR,
        Q_CHAR       => Q_CHAR,
        K_CHAR            => K_CHAR,
        R_CHAR            => R_CHAR,
        A_CHAR            => A_CHAR,
        Q_CHAR            => Q_CHAR,
        ERROR_CONFIG      => ERROR_CONFIG,
        ALIGN_BUFFER_SIZE => ALIGN_BUFFER_SIZE,
        RX_BUFFER_DELAY   => RX_BUFFER_DELAY,


@@ 143,17 144,18 @@ begin  -- architecture a1
        Nn                => CONFIG(i).Nn,
        ADJDIR            => CONFIG(i).ADJDIR)
    port map (
      ci_char_clk         => ci_char_clk,
      ci_frame_clk        => ci_frame_clk,
      ci_multiframe_clk   => multiframe_clk,
      ci_reset            => ci_reset,
      ci_request_sync     => ci_request_sync,
      co_nsynced          => links_nsynced(i),
      co_error            => links_error(i),
      di_data => di_data(sumCummulativeLanes(i) to sumCummulativeLanes(i) + CONFIG(i).L - 1),
      do_samples          => do_samples(i),  -- do_samples(sumCummulativeConverters(i) to sumCummulativeConverters(i) + CONFIG(i).M - 1),
      co_frame_state      => co_frame_state(i),
      co_correct_data     => links_correct_data(i));
      ci_char_clk       => ci_char_clk,
      ci_frame_clk      => ci_frame_clk,
      ci_multiframe_clk => multiframe_clk,
      ci_reset          => ci_reset,
      ci_request_sync   => ci_request_sync,
      co_nsynced        => links_nsynced(i),
      co_error          => links_error(i),
      di_data           => di_data(sumCummulativeLanes(i) to sumCummulativeLanes(i) + CONFIG(i).L - 1),
      do_ctrl_bits      => do_ctrl_bits(sumCummulativeConverters(i) to sumCummulativeConverters(i) + CONFIG(i).M - 1),
      do_samples        => do_samples(sumCummulativeConverters(i) to sumCummulativeConverters(i) + CONFIG(i).M - 1),
      co_frame_state    => co_frame_state(i),
      co_correct_data   => links_correct_data(i));
  end generate links_rx;

end architecture a1;

M src/transport/transport_layer.vhd => src/transport/transport_layer.vhd +23 -23
@@ 29,21 29,18 @@ entity transport_layer is
    di_lanes_data   : in  lane_character_array(0 to L-1)(F*8-1 downto 0);  -- Data from the lanes
    ci_frame_states : in  frame_state_array(0 to L-1);
    co_frame_state  : out frame_state;
    do_samples_data : out samples_array(0 to M - 1, 0 to S - 1));  -- The
                                        -- output samples
    do_samples      : out samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
    do_ctrl_bits    : out ctrl_bits_array(0 to M - 1, 0 to S - 1)(CS - 1 downto 0));
end entity transport_layer;

architecture a1 of transport_layer is
  signal samples_data : samples_array
    (0 to M - 1, 0 to S - 1)
    (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0));
  signal prev_samples_data : samples_array
    (0 to M - 1, 0 to S - 1)
    (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0));
  signal next_samples_data : samples_array
  (0 to M - 1, 0 to S - 1)
    (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0));
  signal reg_error         : std_logic;  -- if err, repeat last samples.
  signal samples             : samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
  signal prev_samples        : samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
  signal next_samples        : samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
  signal ctrl_bits           : ctrl_bits_array(0 to M - 1, 0 to S - 1)(CS - 1 downto 0);
  signal prev_ctrl_bits      : ctrl_bits_array(0 to M - 1, 0 to S - 1)(CS - 1 downto 0);
  signal next_ctrl_bits      : ctrl_bits_array(0 to M - 1, 0 to S - 1)(CS - 1 downto 0);
  signal reg_error           : std_logic;  -- if err, repeat last samples.
  signal current_frame_state : frame_state;

  signal reg_buffered_data : std_logic_vector(L*F*8-1 downto 0) := (others => '0');


@@ 67,11 64,13 @@ begin  -- architecture a1
      reg_error <= '0';
      reg_buffered_data <= (others => '0');
    elsif ci_frame_clk'event and ci_frame_clk = '1' then  -- rising clock edge
      do_samples_data <= next_samples_data;
      do_samples <= next_samples;
      do_ctrl_bits <= next_ctrl_bits;
      co_frame_state <= current_frame_state;

      if any_error = '0' then
        prev_samples_data <= samples_data;
        prev_samples <= samples;
        prev_ctrl_bits <= ctrl_bits;
      end if;

      for i in 0 to L-1 loop


@@ 104,20 103,21 @@ begin  -- architecture a1
               current_frame_state.disparity_error = '1' or
               current_frame_state.not_in_table_error = '1' or
               current_frame_state.wrong_alignment = '1' else '0';
  next_samples_data <= samples_data when any_error = '0' else prev_samples_data;
  next_samples <= samples when any_error = '0' else prev_samples;
  next_ctrl_bits <= ctrl_bits when any_error = '0' else prev_ctrl_bits;

  -- for one or multiple lanes if CF = 0
  -- (no control words)
  -- (control chars are right after sample)
  multi_lane_no_cf: if CF = 0 generate
    converters: for ci in 0 to M - 1 generate
      samples: for si in 0 to S - 1 generate
        samples_data(ci, si).data <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn downto L*F*8 - 1 - ci*Nn*S - si*Nn - N + 1);
      assign_samples: for si in 0 to S - 1 generate
        samples(ci, si) <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn downto L*F*8 - 1 - ci*Nn*S - si*Nn - N + 1);

        control_bits: if CS > 0 generate
          samples_data(ci, si).ctrl_bits <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn - N downto L*F*8 - 1 - ci*Nn*S - si*Nn - N - CS + 1);
          ctrl_bits(ci, si) <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn - N downto L*F*8 - 1 - ci*Nn*S - si*Nn - N - CS + 1);
        end generate control_bits;
      end generate samples;
      end generate assign_samples;
    end generate converters;
  end generate multi_lane_no_cf;



@@ 126,13 126,13 @@ begin  -- architecture a1
  multi_lane_cf: if CF > 0 generate
    cf_groups: for cfi in 0 to CF-1 generate
      converters: for ci in 0 to M/CF-1 generate
        samples: for si in 0 to S - 1 generate
          samples_data(ci + cfi*M/CF, si).data <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn downto L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn - N + 1);
        assign_samples: for si in 0 to S - 1 generate
          samples(ci + cfi*M/CF, si) <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn downto L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn - N + 1);

          control_bits: if CS > 0 generate
            samples_data(ci + cfi*M/CF, si).ctrl_bits <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*S*Nn - ci*S*CS - si*CS downto L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*Nn*S - ci*S*CS - si*CS - CS + 1);
            ctrl_bits(ci + cfi*M/CF, si) <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*S*Nn - ci*S*CS - si*CS downto L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*Nn*S - ci*S*CS - si*CS - CS + 1);
          end generate control_bits;
        end generate samples;
        end generate assign_samples;
      end generate converters;
    end generate cf_groups;
  end generate multi_lane_cf;

M src/transport/transport_pkg.vhd => src/transport/transport_pkg.vhd +3 -10
@@ 5,12 5,6 @@ use work.data_link_pkg.all;
-- Package for transport layer types
package transport_pkg is

  -- Output sample with control bits
  type sample is record
    data      : std_logic_vector;
    ctrl_bits : std_logic_vector;
  end record sample;

  type frame_state is record           -- An errors passed from data_link to transport
    user_data            : std_logic;   -- All characters are user_data
    invalid_characters   : std_logic;   -- Any of the charachers should not be


@@ 28,13 22,12 @@ package transport_pkg is
                                        -- instead of new frame
  end record frame_state;

  type ctrl_bits_array is array (natural range <>, natural range <>) of std_logic_vector;
  type samples_array is array (natural range <>, natural range <>) of std_logic_vector;

  type frame_state_array is array (natural range <>) of frame_state;

  -- Array of frame characters (characters in one frame)
  type lane_character_array is array (natural range <>) of std_logic_vector;

  -- Array of samples in one frame by converter and by sample (used with oversampling)
  type samples_array is array (natural range <>, natural range <>) of sample;
  type simple_samples_array is array (natural range <>) of samples_array;

end package transport_pkg;

M testbench/jesd204b_rx_data_tb.vhd => testbench/jesd204b_rx_data_tb.vhd +13 -12
@@ 141,8 141,8 @@ architecture a1 of jesd204b_rx_data_tb is

  signal co_nsynced : std_logic;
  signal co_error : std_logic;
  signal do_samples : samples_array (M-1 downto 0, S-1 downto 0)
    (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0));
  signal do_samples : samples_array (M-1 downto 0, S-1 downto 0)(N-1 downto 0);
  signal do_ctrl_bits : ctrl_bits_array (M-1 downto 0, S-1 downto 0)(CS-1 downto 0);
  signal co_correct_data : std_logic;

begin  -- architecture a1


@@ 158,16 158,17 @@ begin  -- architecture a1
      N  => N,
      Nn => Nn)
    port map (
      ci_char_clk         => char_clk,
      ci_frame_clk        => frame_clk,
      ci_multiframe_clk   => '0',
      ci_reset            => reset,
      ci_request_sync     => '0',
      di_data => di_data,
      co_nsynced          => co_nsynced,
      co_error            => co_error,
      do_samples          => do_samples,
      co_correct_data     => co_correct_data);
      ci_char_clk       => char_clk,
      ci_frame_clk      => frame_clk,
      ci_multiframe_clk => '0',
      ci_reset          => reset,
      ci_request_sync   => '0',
      di_data           => di_data,
      co_nsynced        => co_nsynced,
      co_error          => co_error,
      do_samples        => do_samples,
      do_ctrl_bits      => do_ctrl_bits,
      co_correct_data   => co_correct_data);

  encoders: for i in 0 to L-1 generate
    encoder: entity work.an8b10b_encoder

M testbench/jesd204b_rx_ils_tb.vhd => testbench/jesd204b_rx_ils_tb.vhd +13 -12
@@ 137,8 137,8 @@ architecture a1 of jesd204b_rx_ils_tb is

  signal co_nsynced : std_logic;
  signal co_error : std_logic;
  signal do_samples : samples_array (M-1 downto 0, S-1 downto 0)
    (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0));
  signal do_samples : samples_array (M-1 downto 0, S-1 downto 0)(N-1 downto 0);
  signal do_ctrl_bits : ctrl_bits_array (M-1 downto 0, S-1 downto 0)(CS-1 downto 0);
  signal co_correct_data : std_logic;

begin  -- architecture a1


@@ 154,16 154,17 @@ begin  -- architecture a1
      N  => N,
      Nn => Nn)
    port map (
      ci_char_clk         => char_clk,
      ci_frame_clk        => frame_clk,
      ci_multiframe_clk   => '0',
      ci_reset            => reset,
      ci_request_sync     => '0',
      di_data => di_data,
      co_nsynced          => co_nsynced,
      co_error            => co_error,
      do_samples          => do_samples,
      co_correct_data     => co_correct_data);
      ci_char_clk       => char_clk,
      ci_frame_clk      => frame_clk,
      ci_multiframe_clk => '0',
      ci_reset          => reset,
      ci_request_sync   => '0',
      di_data           => di_data,
      co_nsynced        => co_nsynced,
      co_error          => co_error,
      do_samples        => do_samples,
      do_ctrl_bits      => do_ctrl_bits,
      co_correct_data   => co_correct_data);

  encoders: for i in 0 to L-1 generate
    encoder: entity work.an8b10b_encoder

M testbench/jesd204b_rx_kchars_tb.vhd => testbench/jesd204b_rx_kchars_tb.vhd +14 -12
@@ 77,8 77,8 @@ architecture a1 of jesd204b_rx_kchars_tb is

  signal co_nsynced : std_logic;
  signal co_error : std_logic;
  signal do_samples : samples_array (M-1 downto 0, S-1 downto 0)
    (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0));
  signal do_samples : samples_array (M-1 downto 0, S-1 downto 0)(N-1 downto 0);
  signal do_ctrl_bits : ctrl_bits_array (M-1 downto 0, S-1 downto 0)(CS-1 downto 0);
  signal co_correct_data : std_logic;

begin  -- architecture a1


@@ 94,16 94,18 @@ begin  -- architecture a1
      N  => N,
      Nn => Nn)
    port map (
      ci_char_clk         => char_clk,
      ci_frame_clk        => frame_clk,
      ci_multiframe_clk   => '0',
      ci_reset            => reset,
      ci_request_sync     => '0',
      di_data => di_data,
      co_nsynced          => co_nsynced,
      co_error            => co_error,
      do_samples          => do_samples,
      co_correct_data     => co_correct_data);
      ci_char_clk       => char_clk,
      ci_frame_clk      => frame_clk,
      ci_multiframe_clk => '0',
      ci_reset          => reset,
      ci_request_sync   => '0',
      di_data           => di_data,
      co_nsynced        => co_nsynced,
      co_error          => co_error,
      do_samples        => do_samples,
      do_ctrl_bits      => do_ctrl_bits,
      co_correct_data   => co_correct_data);


  char_clk <= not char_clk after char_clk_period/2;
  frame_clk <= not frame_clk after frame_clk_period/2;

M testbench/transport/transport_layer_fc_tb.vhd => testbench/transport/transport_layer_fc_tb.vhd +58 -23
@@ 18,16 18,18 @@ architecture a1 of transport_layer_fc_tb is
  constant Nn           : integer := 4;
  constant CLK_PERIOD   : time    := 5 ns;

  constant DUMMY_S : sample := ("0000", "0");
  constant DUMMY_S : std_logic_vector(N - 1 downto 0)            := "0000";
  constant DUMMY_C : std_logic_vector(CONTROL_SIZE - 1 downto 0) := "0";
  type test_vector is record
    di_lanes_data : lane_character_array (0 to L - 1) (F*8-1 downto 0);
    di_lanes_data   : lane_character_array (0 to L - 1) (F*8-1 downto 0);
    ci_frame_states : frame_state_array (0 to L - 1);
    expected_result : integer;
  end record test_vector;

  type result_vector is record
    do_samples_data : samples_array (0 to M - 1, 0 to S - 1)(data(M - 1 downto 0), ctrl_bits(CONTROL_SIZE - 1 downto 0));
    co_frame_state : frame_state;
    do_samples_data   : samples_array (0 to M - 1, 0 to S - 1);
    do_ctrl_bits_data : ctrl_bits_array (0 to M - 1, 0 to S - 1);
    co_frame_state    : frame_state;
  end record result_vector;

  constant dummy_frame_state : frame_state := ('0', '0', '0', '0', '0', '0', '0', '0');


@@ 47,30 49,63 @@ architecture a1 of transport_layer_fc_tb is
  (
    (
      (
        (("1011", "1"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S),
        (("0100", "0"), others => DUMMY_S)
        ("1011", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("0001", others => DUMMY_S),
        ("0100", others => DUMMY_S)
      ),
      (
        ("1", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("1", others => DUMMY_C),
        ("0", others => DUMMY_C)
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("0001", "1"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S)
        ("0001", others => DUMMY_S),
        ("0001", others => DUMMY_S),
        ("0001", others => DUMMY_S),
        ("0001", others => DUMMY_S)
      ),
      (
        ("1", others => DUMMY_C),
        ("1", others => DUMMY_C),
        ("1", others => DUMMY_C),
        ("1", others => DUMMY_C)
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S)
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S)
      ),
      (
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C)
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S)
      ),
      (
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C)
      ),
      ('1', '1', '0', '0', '0', '1', '0', '1')
    )
  );



@@ 80,9 115,8 @@ architecture a1 of transport_layer_fc_tb is
  signal di_lanes_data : lane_character_array (0 to L - 1)(F*8-1 downto 0);
  signal ci_frame_states : frame_state_array (0 to L - 1);

  signal do_samples_data : samples_array
    (0 to M - 1, 0 to S - 1)
    (data(N - 1 downto 0), ctrl_bits(CONTROL_SIZE - 1 downto 0));
  signal do_samples     : samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
  signal do_ctrl_bits   : ctrl_bits_array(0 to M - 1, 0 to S - 1)(CONTROL_SIZE - 1 downto 0);
  signal co_frame_state : frame_state;

  signal test_data_index : integer := 0;


@@ 102,8 136,9 @@ begin  -- architecture a1
      ci_frame_clk    => ci_frame_clk,
      di_lanes_data   => di_lanes_data,
      ci_frame_states => ci_frame_states,
      co_frame_state => co_frame_state,
      do_samples_data => do_samples_data);
      co_frame_state  => co_frame_state,
      do_ctrl_bits    => do_ctrl_bits,
      do_samples      => do_samples);

  ci_frame_clk <= not ci_frame_clk after CLK_PERIOD/2;
  ci_reset <= '1' after CLK_PERIOD*2;


@@ 128,8 163,8 @@ begin  -- architecture a1
          assert co_frame_state = result_vectors(prev_test_vec.expected_result).co_frame_state report "The frame state does not match, index: " & integer'image(prev_test_vec.expected_result) severity error;
          for ci in 0 to M - 1 loop
            for si in 0 to S - 1 loop
              assert do_samples_data(ci, si).data = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).data report "The samples data do not match, expected: " & vec2str(result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).data) & ", got: " & vec2str(dummy) & ", index: " & integer'image(i-1) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_samples_data(ci, si).ctrl_bits = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).ctrl_bits report "The samples control bits do not match, index: " & integer'image(prev_test_vec.expected_result) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_samples(ci, si) = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si) report "The samples data do not match, expected: " & vec2str(result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si)) & ", got: " & vec2str(dummy) & ", index: " & integer'image(i-1) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_ctrl_bits(ci, si) = result_vectors(prev_test_vec.expected_result).do_ctrl_bits_data(ci, si) report "The samples control bits do not match, index: " & integer'image(prev_test_vec.expected_result) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
            end loop;  -- s
          end loop;  -- c
        end if;

M testbench/transport/transport_layer_multi_cf_tb.vhd => testbench/transport/transport_layer_multi_cf_tb.vhd +40 -21
@@ 25,8 25,9 @@ architecture a1 of transport_layer_multi_fc_tb is
  end record test_vector;

  type result_vector is record
    do_samples_data : samples_array (0 to M - 1, 0 to S - 1)(data(M - 1 downto 0), ctrl_bits(CONTROL_SIZE - 1 downto 0));
    co_frame_state : frame_state;
    do_samples_data   : samples_array (0 to M - 1, 0 to S - 1);
    do_ctrl_bits_data : ctrl_bits_array (0 to M - 1, 0 to S - 1);
    co_frame_state    : frame_state;
  end record result_vector;

  type test_vector_array is array (natural range<>) of test_vector;


@@ 44,28 45,46 @@ architecture a1 of transport_layer_multi_fc_tb is
  (
    (
      (
        (("0001", "01"), ("0101", "01")),
        (("0010", "10"), ("0110", "10")),
        (("0011", "11"), ("0111", "11")),
        (("0100", "00"), ("1000", "00"))
        ("0001", "0101"),
        ("0010", "0110"),
        ("0011", "0111"),
        ("0100", "1000")
      ),
      (
        ("01", "01"),
        ("10", "10"),
        ("11", "11"),
        ("00", "00")
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("0011", "00"), ("1111", "10")),
        (("1100", "11"), ("0101", "01")),
        (("0000", "00"), ("1010", "10")),
        (("1111", "11"), ("0000", "01"))
        ("0011", "1111"),
        ("1100", "0101"),
        ("0000", "1010"),
        ("1111", "0000")
      ),
      (
        ("00", "10"),
        ("11", "01"),
        ("00", "10"),
        ("11", "01")
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("0001", "01"), ("0101", "01")),
        (("0010", "10"), ("0110", "10")),
        (("0011", "11"), ("0111", "11")),
        (("0100", "00"), ("1000", "00"))
        ("0001", "0101"),
        ("0010", "0110"),
        ("0011", "0111"),
        ("0100", "1000")
      ),
      (
        ("01", "01"),
        ("10", "10"),
        ("11", "11"),
        ("00", "00")
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    )


@@ 77,9 96,8 @@ architecture a1 of transport_layer_multi_fc_tb is
  signal di_lanes_data : lane_character_array (0 to L - 1)(F*8-1 downto 0);
  signal ci_frame_states : frame_state_array (0 to L - 1);

  signal do_samples_data : samples_array
    (0 to M - 1, 0 to S - 1)
    (data(N - 1 downto 0), ctrl_bits(CONTROL_SIZE - 1 downto 0));
  signal do_samples     : samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
  signal do_ctrl_bits   : ctrl_bits_array(0 to M - 1, 0 to S - 1)(CONTROL_SIZE - 1 downto 0);
  signal co_frame_state : frame_state;

  signal test_data_index : integer := 0;


@@ 100,8 118,9 @@ begin  -- architecture a1
      ci_frame_clk    => ci_frame_clk,
      di_lanes_data   => di_lanes_data,
      ci_frame_states => ci_frame_states,
      co_frame_state => co_frame_state,
      do_samples_data => do_samples_data);
      co_frame_state  => co_frame_state,
      do_ctrl_bits    => do_ctrl_bits,
      do_samples      => do_samples);

  ci_frame_clk <= not ci_frame_clk after CLK_PERIOD/2;
  ci_reset <= '1' after CLK_PERIOD*2;


@@ 126,8 145,8 @@ begin  -- architecture a1
          assert co_frame_state = result_vectors(prev_test_vec.expected_result).co_frame_state report "The frame state does not match, index: " & integer'image(prev_test_vec.expected_result) severity error;
          for ci in 0 to M - 1 loop
            for si in 0 to S - 1 loop
              assert do_samples_data(ci, si).data = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).data report "The samples data do not match, expected: " & vec2str(result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).data) & ", got: " & vec2str(dummy) & ", index: " & integer'image(i-1) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_samples_data(ci, si).ctrl_bits = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).ctrl_bits report "The samples control bits do not match, index: " & integer'image(prev_test_vec.expected_result) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_samples(ci, si) = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si) report "The samples data do not match, expected: " & vec2str(result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si)) & ", got: " & vec2str(dummy) & ", index: " & integer'image(i-1) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_ctrl_bits(ci, si) = result_vectors(prev_test_vec.expected_result).do_ctrl_bits_data(ci, si) report "The samples control bits do not match, index: " & integer'image(prev_test_vec.expected_result) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
            end loop;  -- s
          end loop;  -- c
        end if;

M testbench/transport/transport_layer_simp_tb.vhd => testbench/transport/transport_layer_simp_tb.vhd +54 -29
@@ 13,21 13,23 @@ architecture a1 of transport_layer_simp_tb is
  constant S            : integer := 1;  -- Count of samples
  constant L            : integer := 1;  -- Count of lanes
  constant F            : integer := 4;  -- Count of octets in a frame per lane
  constant CF            : integer := 0;  -- Count of control word bits
  constant CF            : integer := 0;  -- Count of control words
  constant N : integer := 4;            -- Sample size
  constant Nn : integer := 8;
  constant CLK_PERIOD : time := 1 ns;

  constant DUMMY_S : sample := ("0000", "0");
  constant DUMMY_S : std_logic_vector(N - 1 downto 0)            := "0000";
  constant DUMMY_C : std_logic_vector(CONTROL_SIZE - 1 downto 0) := "0";
  type test_vector is record
    di_lanes_data : lane_character_array (0 to L - 1) (F*8-1 downto 0);
    di_lanes_data   : lane_character_array (0 to L - 1) (F*8-1 downto 0);
    ci_frame_states : frame_state_array (0 to L - 1);
    expected_result : integer;
  end record test_vector;

  type result_vector is record
    do_samples_data : samples_array (0 to M - 1, 0 to S - 1)(data(M - 1 downto 0), ctrl_bits(CONTROL_SIZE - 1 downto 0));
    co_frame_state : frame_state;
    do_samples_data   : samples_array (0 to M - 1, 0 to S - 1);
    do_ctrl_bits_data : ctrl_bits_array (0 to M - 1, 0 to S - 1);
    co_frame_state    : frame_state;
  end record result_vector;

  constant dummy_frame_state : frame_state := ('0', '0', '0', '0', '0', '0', '0', '0');


@@ 49,37 51,61 @@ architecture a1 of transport_layer_simp_tb is
  (
    (
      (
        (("1011", "1"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S),
        (("0100", "0"), others => DUMMY_S)
        ("1011", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("0001", others => DUMMY_S),
        ("0100", others => DUMMY_S)
      ),
      (
        ("1", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("1", others => DUMMY_C),
        ("0", others => DUMMY_C)
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("0001", "1"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S),
        (("0001", "1"), others => DUMMY_S)
        ("0001", others => DUMMY_S),
        ("0001", others => DUMMY_S),
        ("0001", others => DUMMY_S),
        ("0001", others => DUMMY_S)
      ),
      (
        ("1", others => DUMMY_C),
        ("1", others => DUMMY_C),
        ("1", others => DUMMY_C),
        ("1", others => DUMMY_C)
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S)
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S)
      ),
      (
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C)
      ),
      ('1', '0', '0', '0', '0', '0', '0', '0')
    ),
    (
      (
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S),
        (("1110", "0"), others => DUMMY_S)
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S),
        ("1110", others => DUMMY_S)
      ),
      (
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C),
        ("0", others => DUMMY_C)
      ),
      ('1', '1', '0', '0', '0', '1', '0', '1')
    )


@@ 91,9 117,8 @@ architecture a1 of transport_layer_simp_tb is
  signal di_lanes_data : lane_character_array (0 to L - 1)(F*8-1 downto 0);
  signal ci_frame_states : frame_state_array (0 to L - 1);

  signal do_samples_data : samples_array
    (0 to M - 1, 0 to S - 1)
    (data(N - 1 downto 0), ctrl_bits(CONTROL_SIZE - 1 downto 0));
  signal do_samples     : samples_array(0 to M - 1, 0 to S - 1)(N - 1 downto 0);
  signal do_ctrl_bits   : ctrl_bits_array(0 to M - 1, 0 to S - 1)(CONTROL_SIZE - 1 downto 0);
  signal co_frame_state : frame_state;

  signal test_data_index : integer := 0;


@@ 113,13 138,13 @@ begin  -- architecture a1
      ci_frame_clk    => ci_frame_clk,
      di_lanes_data   => di_lanes_data,
      ci_frame_states => ci_frame_states,
      co_frame_state => co_frame_state,
      do_samples_data => do_samples_data);
      co_frame_state  => co_frame_state,
      do_ctrl_bits    => do_ctrl_bits,
      do_samples      => do_samples);

  ci_frame_clk <= not ci_frame_clk after CLK_PERIOD/2;
  ci_reset <= '1' after CLK_PERIOD*2;


  test: process is
    variable test_vec : test_vector;
    variable prev_test_vec : test_vector;


@@ 140,8 165,8 @@ begin  -- architecture a1
          assert co_frame_state = result_vectors(prev_test_vec.expected_result).co_frame_state report "The frame state does not match, index: " & integer'image(prev_test_vec.expected_result) severity error;
          for ci in 0 to M - 1 loop
            for si in 0 to S - 1 loop
              assert do_samples_data(ci, si).data = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).data report "The samples data do not match, expected: " & vec2str(result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).data) & ", got: " & vec2str(dummy) & ", index: " & integer'image(i-1) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_samples_data(ci, si).ctrl_bits = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si).ctrl_bits report "The samples control bits do not match, index: " & integer'image(prev_test_vec.expected_result) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_samples(ci, si) = result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si) report "The samples data do not match, expected: " & vec2str(result_vectors(prev_test_vec.expected_result).do_samples_data(ci, si)) & ", got: " & vec2str(dummy) & ", index: " & integer'image(i-1) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
              assert do_ctrl_bits(ci, si) = result_vectors(prev_test_vec.expected_result).do_ctrl_bits_data(ci, si) report "The samples control bits do not match, index: " & integer'image(prev_test_vec.expected_result) & ", ci: " & integer'image(ci) & ", si: " & integer'image(si) severity error;
            end loop;  -- s
          end loop;  -- c
        end if;

Do not follow this link