From a6e4dd85d3ac9bc447062b9566793e97262e76c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Tue, 23 May 2023 21:39:59 +0200 Subject: [PATCH] feat: add possibility to specify order of input to LSB (only MSB was supported) --- src/data_link/an8b10b_decoder.vhd | 24 ++++++++++++++++++++---- src/data_link/char_alignment.vhd | 19 +++++++++++++++---- src/data_link/data_link_layer.vhd | 7 +++++++ src/jesd204b_link_rx.vhd | 3 +++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/data_link/an8b10b_decoder.vhd b/src/data_link/an8b10b_decoder.vhd index 8aaaa83..7694328 100644 --- a/src/data_link/an8b10b_decoder.vhd +++ b/src/data_link/an8b10b_decoder.vhd @@ -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; diff --git a/src/data_link/char_alignment.vhd b/src/data_link/char_alignment.vhd index 69faaea..3683729 100644 --- a/src/data_link/char_alignment.vhd +++ b/src/data_link/char_alignment.vhd @@ -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; diff --git a/src/data_link/data_link_layer.vhd b/src/data_link/data_link_layer.vhd index a7433ac..0b3c3e7 100644 --- a/src/data_link/data_link_layer.vhd +++ b/src/data_link/data_link_layer.vhd @@ -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, diff --git a/src/jesd204b_link_rx.vhd b/src/jesd204b_link_rx.vhd index 6fb240a..a9e20f1 100644 --- a/src/jesd204b_link_rx.vhd +++ b/src/jesd204b_link_rx.vhd @@ -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, -- 2.48.1