~ruther/jesd204b-vhdl

c2a645ad8c7aa448978c047271eb169bd1d87727 — František Boháček 1 year, 11 months ago e9ed12f
fix: remove asynchronous if from frame_alignment
2 files changed, 31 insertions(+), 29 deletions(-)

M src/data_link/frame_alignment.vhd
M testbench/data_link/frame_alignment_tb.vhd
M src/data_link/frame_alignment.vhd => src/data_link/frame_alignment.vhd +29 -27
@@ 55,8 55,6 @@ architecture a1 of frame_alignment is
  type alignment_state is (INIT, ALIGNED, MISALIGNED);
  signal reg_state : alignment_state := INIT;

  signal next_frame_state : frame_state;

  signal buffer_character : std_logic_vector(7 downto 0) := "00000000";
  signal buffer_raw_adjust_position : integer := 0;
  signal buffer_adjust_position : integer := 0;


@@ 80,6 78,10 @@ architecture a1 of frame_alignment is

  signal next_octet_index : integer range 0 to F := 0;
  signal next_adjusted_octet_index : integer range 0 to F := 0;

  constant frame_state_count : integer := 2;
  signal reg_frame_state_index : integer := 0;
  signal reg_frame_states : frame_state_array(0 to frame_state_count - 1);
begin  -- architecture a1
  data_buffer: entity work.ring_buffer
    generic map (


@@ 101,64 103,64 @@ begin  -- architecture a1
  begin  -- process next_frame
    if ci_reset = '0' then
      co_frame_state <= ('0', '0', '0', '0', '0', '0', '0', '0');
      reg_frame_state_index <= 0;
    elsif ci_frame_clk'event and ci_frame_clk = '1' then  -- rising clock edge
      co_frame_state <= next_frame_state;
      co_frame_state <= reg_frame_states(reg_frame_state_index);
      reg_frame_state_index <= (reg_frame_state_index + 1) mod frame_state_count;
    end if;
  end process next_frame;

  set_next: process (ci_char_clk, ci_frame_clk, ci_reset) is
  begin  -- process set_next
    if ci_reset = '1' and ci_frame_clk'event and ci_frame_clk = '1' then
      if reg_state /= INIT then
        next_frame_state <= ('1', '0', '0', '0', '0', '0', '0', '0');
      end if;
    end if;

    if ci_reset = '0' then              -- asynchronous reset (active
      reg_state <= INIT;
      reg_last_frame_data <= (others => '0');
      next_frame_state <= ('0', '0', '0', '0', '0', '0', '0', '0');
      buffer_align_to <= -1;
      reg_frame_states <= (others => ('0', '0', '0', '0', '0', '0', '0', '0'));
    elsif ci_char_clk'event and ci_char_clk = '1' then  -- rising clock edge
      -- set last_frame_data if this is the last frame and not /F/ or /A/
      if next_is_last_octet = '1' and not (is_f = '1' or is_a = '1') then
        reg_last_frame_data <= di_char.d8b;
      end if;
      for i in 0 to frame_state_count - 1 loop
        if i = reg_frame_state_index then
          if di_char.kout = '1' and not (is_a = '1' or is_f = '1') then
            reg_frame_states(i).invalid_characters <= '1';
          end if;
          if di_char.disparity_error = '1' then
            reg_frame_states(i).disparity_error <= '1';
          end if;
          if di_char.missing_error then
            reg_frame_states(i).not_in_table_error <= '1';
          end if;
          if di_char.user_data = '0' then
            reg_frame_states(i).user_data <= '0';
          end if;
          if (reg_state = ALIGNED and is_wrong_char = '1') or reg_state = MISALIGNED then
            reg_frame_states(i).wrong_alignment <= '1';
          end if;
        else
          reg_frame_states(i) <= ('1', '0', '0', '0', '0', '0', '0', '0');
        end if;
      end loop;  -- i

      if ci_request_sync = '1' then
        reg_state <= INIT;
        next_frame_state <= ('0', '0', '0', '0', '0', '0', '0', '0');
      elsif reg_state = INIT then
      next_frame_state <= ('0', '0', '0', '0', '0', '0', '0', '0');
        -- if a or f, align to it and move to aligned
        if is_a = '1' or is_f = '1' then
          -- align to current character.
          buffer_align_to <= next_octet_index;
          next_frame_state <= ('1', '0', '0', '0', '0', '0', '0', '0');
          reg_state <= ALIGNED;
        end if;
      else
        if di_char.kout = '1' and not (is_a = '1' or is_f = '1') then
          next_frame_state.invalid_characters <= '1';
        end if;
        if di_char.disparity_error = '1' then
          next_frame_state.disparity_error <= '1';
        end if;
        if di_char.missing_error then
          next_frame_state.not_in_table_error <= '1';
        end if;
        if di_char.user_data = '0' then
          next_frame_state.user_data <= '0';
        end if;
        if reg_state = ALIGNED then
          if is_wrong_char = '1' then
            next_frame_state.wrong_alignment <= '1';
            reg_state <= MISALIGNED;
            reg_correct_sync_chars <= 1;
            reg_known_sync_char_position <= next_octet_index;
          end if;
        elsif reg_state = MISALIGNED then
          next_frame_state.wrong_alignment <= '1';
          if is_wrong_char = '1' then
            if reg_known_sync_char_position = next_octet_index then
              reg_correct_sync_chars <= reg_correct_sync_chars + 1;

M testbench/data_link/frame_alignment_tb.vhd => testbench/data_link/frame_alignment_tb.vhd +2 -2
@@ 31,9 31,9 @@ architecture a1 of frame_alignment_tb is
    ('0', '0', ('1', '0', '0', "10111100", '0'), '0', '0'),
    ('0', '0', ('0', '0', '0', "11000001", '1'), '0', '0'),  -- frame begins
    ('0', '0', ('0', '0', '0', "11000010", '1'), '0', '0'),
    ('0', '0', ('0', '0', '0', "11000011", '1'), '0', '0'),
    ('0', '0', ('0', '1', '0', "11000011", '1'), '0', '0'),
    ('0', '0', ('0', '0', '0', "11000100", '1'), '0', '0'),
    ('0', '0', ('1', '0', '0', "11111100", '1'), '0', '0'),  -- frame ends
    ('0', '0', ('1', '0', '0', "11111100", '1'), '1', '0'),  -- frame ends
    ('0', '0', ('0', '0', '0', "00000001", '1'), '1', '0'),
    ('0', '0', ('1', '0', '0', "00000010", '1'), '1', '0'),
    ('0', '0', ('0', '0', '0', "00000011", '1'), '1', '0'),

Do not follow this link