~ruther/jesd204b-vhdl

a6e4dd85d3ac9bc447062b9566793e97262e76c9 — František Boháček 1 year, 10 months ago ff129f4
feat: add possibility to specify order of input to LSB (only MSB was supported)
M src/data_link/an8b10b_decoder.vhd => src/data_link/an8b10b_decoder.vhd +20 -4
@@ 16,6 16,9 @@ use ieee.numeric_std.all;
use work.data_link_pkg.all;

entity an8b10b_decoder is
  generic (
    REVERSE : std_logic := '1' -- Whether to expect characters reversed
  );
  port (
    ci_char_clk : in  std_logic;        -- The character clock
    ci_reset    : in  std_logic;        -- The reset (asynchronous active low)


@@ 77,6 80,10 @@ architecture a1 of an8b10b_decoder is
  signal data_4b_int_neg : integer range 0 to 15 := 0;
  signal data_6b_int_neg : integer range 0 to 63 := 0;

  signal di_10b_reversed : std_logic_vector(9 downto 0);

  signal di_10b_actual : std_logic_vector(9 downto 0);

  function IsMissingCharacter(
    cdata_4b_int : integer range 0 to 15;
    cdata_6b_int : integer range 0 to 63


@@ 171,6 178,8 @@ architecture a1 of an8b10b_decoder is
  end function IsDisparityCorrect;

begin  -- architecture a1
  di_10b_reversed <= di_10b(0) & di_10b(1) & di_10b(2) & di_10b(3) & di_10b(4) & di_10b(5) & di_10b(6) & di_10b(7) & di_10b(8) & di_10b(9);

  -- purpose: Set next states
  -- type   : sequential
  -- inputs : ci_char_clk, ci_reset


@@ 196,8 205,15 @@ begin  -- architecture a1
      reg_rd <= next_rd;
    end if;
  end process set_next;
  data_4b <= di_10b(3 downto 0);
  data_6b <= di_10b(9 downto 4);

  WITHOUT_REVERSE: if REVERSE = '0' generate
    di_10b_actual <= di_10b;
  end generate;
  REVERSED: if REVERSE = '1' generate
    di_10b_actual <= di_10b_reversed;
  end generate;
  data_4b <= di_10b_actual(3 downto 0);
  data_6b <= di_10b_actual(9 downto 4);
  data_4b_int <= to_integer(unsigned(data_4b));
  data_6b_int <= to_integer(unsigned(data_6b));
  data_4b_int_neg <= to_integer(unsigned(not data_4b));


@@ 208,11 224,11 @@ begin  -- architecture a1
  -- will output 1 ... it's basically an odd parity)
  -- synchronize in case of disparity error (can be either at the beginning of
  -- communication or the last character was loaded incorrectly)
  change_rd <= (not xor_reduce(di_10b) or next_disparity_error) and not (not xor_reduce(di_10b) and next_disparity_error);
  change_rd <= (not xor_reduce(di_10b_actual) or next_disparity_error) and not (not xor_reduce(di_10b_actual) and next_disparity_error);
  next_rd <= (not reg_rd and change_rd) or (reg_rd and not change_rd);

  -- control characters
  next_kout <= IsControlCharacter(di_10b);
  next_kout <= IsControlCharacter(di_10b_actual);

  -- errors
  next_missing_error <= IsMissingCharacter(data_4b_int, data_6b_int) and not next_kout;

M src/data_link/char_alignment.vhd => src/data_link/char_alignment.vhd +15 -4
@@ 17,7 17,10 @@ use ieee.std_logic_1164.all;
entity char_alignment is

  generic (
    K_CHAR : std_logic_vector(9 downto 0) := "0011111010"  -- The character used for synchronization (positive RD)
    K_CHAR : std_logic_vector(9 downto 0) := "0011111010";  -- The character used for synchronization (positive RD)
    REVERSE : std_logic := '1'  -- Whether to expect the K character in
                                -- reverse, most probably will be reversed in a
                                -- real FPGA situation
    );
  port (
    ci_char_clk: in std_logic;          -- The character clock


@@ 30,6 33,7 @@ entity char_alignment is
end entity char_alignment;

architecture a1 of char_alignment is
  constant K_CHAR_REVERSED : std_logic_vector(9 downto 0) := K_CHAR(0) & K_CHAR(1) & K_CHAR(2) & K_CHAR(3) & K_CHAR(4) & K_CHAR(5) & K_CHAR(6) & K_CHAR(7) & K_CHAR(8) & K_CHAR(9);
  signal next_cache_10b : std_logic_vector(19 downto 0) := (others => '0');  -- The next value of cache_10b
  signal next_do_10b : std_logic_vector(9 downto 0) := (others => '0');  -- The next value of do_10b
  signal next_co_aligned : std_logic := '0';


@@ 79,9 83,16 @@ begin  -- architecture a1
      if ci_synced = '0' then
        -- Try to find /K/ (K_CHAR) in either RD (either K_CHAR or not K_CHAR).
        for i in 0 to 9 loop
          if reg_cache_10b(i+9 downto i) = K_CHAR or reg_cache_10b(i+9 downto i) = not K_CHAR then
            reg_found_sync_char <= '1';
            reg_alignment_index <= i;
          if REVERSE = '1' then
            if reg_cache_10b(i+9 downto i) = K_CHAR_REVERSED or reg_cache_10b(i+9 downto i) = not K_CHAR_REVERSED then
              reg_found_sync_char <= '1';
              reg_alignment_index <= i;
            end if;
          else
            if reg_cache_10b(i+9 downto i) = K_CHAR or reg_cache_10b(i+9 downto i) = not K_CHAR then
              reg_found_sync_char <= '1';
              reg_alignment_index <= i;
            end if;
          end if;
        end loop;  -- i
      end if;

M src/data_link/data_link_layer.vhd => src/data_link/data_link_layer.vhd +7 -0
@@ 27,6 27,7 @@ entity data_link_layer is
                                        -- multiframe start
    A_CHAR       : std_logic_vector(7 downto 0) := "01111100";  -- multiframe end
    Q_CHAR       : std_logic_vector(7 downto 0) := "10011100";  -- 2nd ILAS frame
    REVERSE      : std_logic := '0'; -- Whether to expect 10b characters reversed
                                        -- 2nd character
    ALIGN_BUFFER_SIZE : integer                      := 255;  -- Size of a
                                                              -- buffer that is


@@ 145,6 146,9 @@ begin  -- architecture a1

  -- char alignment
  char_alignment: entity work.char_alignment
    generic map (
      REVERSE => REVERSE
    )
    port map (
      ci_char_clk => ci_char_clk,
      ci_reset    => ci_reset,


@@ 154,6 158,9 @@ begin  -- architecture a1

  -- 8b10b decoder
  an8b10b_decoder: entity work.an8b10b_decoder
    generic map (
      REVERSE => REVERSE
    )
    port map (
      ci_char_clk => ci_char_clk,
      ci_reset    => ci_reset,

M src/jesd204b_link_rx.vhd => src/jesd204b_link_rx.vhd +3 -0
@@ 22,6 22,8 @@ entity jesd204b_link_rx is
                                        -- alignment character
    Q_CHAR       : std_logic_vector(7 downto 0) := "10011100";  -- ILAS 2nd
                                        -- frame 2nd character
    REVERSE_LANE_INPUT : std_logic := '0'; -- Whether to reverse data going in
                                           -- the lane
    ADJCNT            : integer range 0 to 15        := 0;
    ADJDIR            : std_logic                    := '0';
    BID               : integer range 0 to 15        := 0;


@@ 194,6 196,7 @@ begin  -- architecture a1
  data_links : for i in 0 to L-1 generate
    data_link_layer : entity work.data_link_layer
      generic map (
        REVERSE => REVERSE_LANE_INPUT,
        ALIGN_BUFFER_SIZE => ALIGN_BUFFER_SIZE,
        K_CHAR       => K_CHAR,
        R_CHAR       => R_CHAR,

Do not follow this link