From 9be0c49cf576fca9f27d9f8524161ebc92ea0aa8 Mon Sep 17 00:00:00 2001 From: Tobias Weber Date: Tue, 17 Jul 2018 17:23:16 +0200 Subject: [PATCH] Link gets synchronized on all four channels. Unpacker delivers data which still needs to be checked. Data Width Conversion gives strange results if receiving clock is slower than trbnet clock. --- mupix/Mupix8/sources/MuPixDataLink_new.vhd | 2 +- .../sources/Simulation/LinkSimulation.vhd | 30 ++-- .../sources/Simulation/Mupix8StateMachine.vhd | 148 ++++++++++++++---- 3 files changed, 131 insertions(+), 49 deletions(-) diff --git a/mupix/Mupix8/sources/MuPixDataLink_new.vhd b/mupix/Mupix8/sources/MuPixDataLink_new.vhd index cbdaafa..22a71cc 100644 --- a/mupix/Mupix8/sources/MuPixDataLink_new.vhd +++ b/mupix/Mupix8/sources/MuPixDataLink_new.vhd @@ -635,7 +635,7 @@ begin & link_sync_flag_i(serdes_channel_select); when x"016b" => slv_ack_out <= '1'; - slv_data_out(3 downto 0) <= link_sync_flag_i and not rx_dataerror_sync; + slv_data_out(7 downto 0) <= unpacker_valid_i & (link_sync_flag_i and not rx_dataerror_sync); when others => slv_unknown_addr_out <= '1'; end case; diff --git a/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd b/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd index 9f1ec34..05d2502 100644 --- a/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd +++ b/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd @@ -34,8 +34,8 @@ architecture rtl of LinkSimulation is port ( clk : in std_logic; reset : in std_logic; - start : in std_logic; words : in std_logic_vector(4 downto 0); + slowdown : in std_logic_vector(15 downto 0); wr_en : out std_logic; data_out : out std_logic_vector(9 downto 0)); end component MupixStateMachine; @@ -67,16 +67,16 @@ architecture rtl of LinkSimulation is attribute ODDRAPPS : string; attribute ODDRAPPS of simlink_oddr : label is "SCLK_ALIGNED"; - signal sim_clk_i : std_logic; - signal data_clk_i : std_logic; - signal data_out_i, data_out_reg : std_logic_vector(1 downto 0); - signal fifo_rden_i : std_logic; - signal fifo_empty_i : std_logic; - signal fifo_data_out : std_logic_vector(9 downto 0); - signal fifo_wren_i : std_logic; - signal fifo_data_in : std_logic_vector(9 downto 0); - signal start_i : std_logic := '0'; - signal words_i : std_logic_vector(4 downto 0) := (others => '0'); + signal sim_clk_i : std_logic; + signal data_clk_i : std_logic; + signal data_out_i, data_out_reg : std_logic_vector(1 downto 0); + signal fifo_rden_i : std_logic; + signal fifo_empty_i : std_logic; + signal fifo_data_out : std_logic_vector(9 downto 0); + signal fifo_wren_i : std_logic; + signal fifo_data_in : std_logic_vector(9 downto 0); + signal words_i : std_logic_vector(4 downto 0) := "00100"; + signal slowdown_i : std_logic_vector(15 downto 0) := x"FF0A"; begin -- architecture rtl @@ -91,8 +91,8 @@ begin -- architecture rtl port map ( clk => data_clk_i, reset => reset, - start => start_i, words => words_i, + slowdown => slowdown_i, wr_en => fifo_wren_i, data_out => fifo_data_in); @@ -121,9 +121,9 @@ begin -- architecture rtl rden => fifo_rden_i, dataout => data_out_i); - data_output_pipe: process (sim_clk_i) is + data_output_pipe : process (sim_clk_i) is begin -- process data_output_pipe - if rising_edge(sim_clk_i) then -- rising clock edge + if rising_edge(sim_clk_i) then -- rising clock edge if reset = '1' then -- synchronous reset (active high) data_out_reg <= (others => '0'); else @@ -131,7 +131,7 @@ begin -- architecture rtl end if; end if; end process data_output_pipe; - + simlink_oddr : ODDRXD1 port map ( SCLK => sim_clk_i, diff --git a/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd b/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd index 103ebfe..4ad1edd 100644 --- a/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd +++ b/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd @@ -12,8 +12,8 @@ entity MupixStateMachine is port ( clk : in std_logic; -- clk input reset : in std_logic; -- reset input - start : in std_logic; -- start data transmission words : in std_logic_vector(4 downto 0); -- number of words to transmit + slowdown : in std_logic_vector(15 downto 0); -- slow down state machine wr_en : out std_logic; -- fifo enable output data_out : out std_logic_vector(9 downto 0)); -- 8b10b encoded data to fifo end entity MupixStateMachine; @@ -29,20 +29,26 @@ architecture rtl of MupixStateMachine is output : out std_logic_vector(9 downto 0)); end component enc_8b10b; - type mupix8_state_type is (sync, loadcol, readcol); - signal mupix8_state : mupix8_state_type := sync; - signal cnt4 : integer range 0 to 4 := 0; - signal start_edge_i : std_logic_vector(1 downto 0) := (others => '0'); + type link_type is array (0 to 3) of std_logic_vector(7 downto 0); + constant link_i : link_type := (x"AA", x"BB", x"CC", x"DD"); + signal link_cnt_i : unsigned(1 downto 0) := (others => '0'); + + type mupix8_state_type is (sync, pd1, pd2, loadcol1, loadcol2, loadpix1, loadpix2, readcol1, readcol2); + signal mupix8_state : mupix8_state_type := sync; + signal cnt4 : integer range 0 to 4 := 0; + signal start_i : std_logic := '0'; signal mupix_data_i : std_logic_vector(7 downto 0) := (others => '0'); signal encoded_data_i : std_logic_vector(9 downto 0) := (others => '0'); - signal data_encoded_falling : std_logic_vector(9 downto 0) := (others => '0'); + signal data_encoded_falling : std_logic_vector(9 downto 0) := (others => '0'); signal komma_en_i : std_logic := '0'; - signal column, row : unsigned(7 downto 0) := (others => '0'); - signal timestamp : unsigned(7 downto 0) := (others => '0'); - signal tot : unsigned(7 downto 0) := (others => '0'); - signal word_cnt_i : unsigned(4 downto 0) := (others => '0'); + signal binary_counter : unsigned(23 downto 0) := (others => '0'); + signal column, row : unsigned(7 downto 0) := (others => '0'); + signal timestamp : unsigned(7 downto 0) := (others => '0'); + signal tot : unsigned(7 downto 0) := (others => '0'); + signal word_cnt_i : unsigned(4 downto 0) := (others => '0'); + signal slowdown_cnt_i : unsigned(15 downto 0) := (others => '0'); begin -- architecture rtl @@ -79,18 +85,26 @@ begin -- architecture rtl -- delay write enable after reset for 8b10b encoder write_proc : process (clk) is - variable wait_after_reset : integer range 0 to 3 := 0; + variable wait_after_reset : integer range 0 to 3 := 0; + variable wait_before_start : integer range 0 to 31 := 0; begin -- process write_proc if rising_edge(clk) then if reset = '1' then - wait_after_reset := 0; - wr_en <= '0'; + wait_after_reset := 0; + wr_en <= '0'; + start_i <= '0'; + wait_before_start := 0; else if wait_after_reset = 3 then - wr_en <= '1'; + wr_en <= '1'; else wait_after_reset := wait_after_reset + 1; end if; + if wait_before_start = 31 then + start_i <= '1'; + else + wait_before_start := wait_before_start + 1; + end if; end if; end if; end process write_proc; @@ -100,11 +114,13 @@ begin -- architecture rtl begin -- process timestamp_gen if rising_edge(clk) then -- rising clock edge if reset = '1' then -- synchronous reset (active high) - timestamp <= (others => '0'); - tot <= (others => '0'); + timestamp <= (others => '0'); + tot <= (others => '0'); + binary_counter <= (others => '0'); else - timestamp <= timestamp + 1; - tot <= tot + 3; + timestamp <= timestamp + 1; + tot <= tot + 3; + binary_counter <= binary_counter + 1; end if; end if; end process timestamp_gen; @@ -119,7 +135,6 @@ begin -- architecture rtl column <= (others => '0'); row <= (others => '0'); cnt4 <= 0; - start_edge_i <= (others => '0'); else komma_en_i <= '1'; mupix_data_i <= k28_5; @@ -129,30 +144,97 @@ begin -- architecture rtl column <= (others => '0'); row <= (others => '0'); word_cnt_i <= (others => '0'); - if start = '1' then - mupix8_state <= loadcol; + if start_i = '1' then + mupix8_state <= pd1; + end if; + when pd1 => -- pd1, pd2, loadcol1 give same output to encoder, here + -- for completness of mupix state machine + if cnt4 < 3 then + cnt4 <= cnt4 + 1; + mupix8_state <= pd1; + else + cnt4 <= 0; + mupix8_state <= pd2; + end if; + when pd2 => + if cnt4 < 3 then + cnt4 <= cnt4 + 1; + mupix8_state <= pd2; + else + cnt4 <= 0; + mupix8_state <= loadcol1; + end if; + when loadcol1 => + if cnt4 < 3 then + cnt4 <= cnt4 + 1; + mupix8_state <= loadcol1; + else + cnt4 <= 0; + link_cnt_i <= link_cnt_i + 1; + mupix8_state <= loadcol2; mupix_data_i <= k28_0; end if; - when loadcol => + when loadcol2 => cnt4 <= cnt4 + 1; if cnt4 = 0 then komma_en_i <= '0'; - mupix_data_i <= x"AA"; + mupix_data_i <= link_i(to_integer(link_cnt_i)); elsif cnt4 = 1 then mupix_data_i <= k28_0; elsif cnt4 = 2 then - mupix_data_i <= x"AA"; + mupix_data_i <= link_i(to_integer(link_cnt_i)); komma_en_i <= '0'; else - mupix8_state <= readcol; + mupix8_state <= loadpix1; cnt4 <= 0; - mupix_data_i <= std_logic_vector(tot); - komma_en_i <= '0'; + mupix_data_i <= k28_5; + end if; + when loadpix1 => + if cnt4 < 3 then + cnt4 <= cnt4 + 1; + mupix8_state <= loadpix1; + else + cnt4 <= 0; + if slowdown_cnt_i = unsigned(slowdown) - 1 then + slowdown_cnt_i <= (others => '0'); + mupix8_state <= loadpix2; + komma_en_i <= '0'; + mupix_data_i <= std_logic_vector(binary_counter(23 downto 16)); + else + slowdown_cnt_i <= slowdown_cnt_i + 1; + mupix8_state <= loadpix1; + end if; end if; - when readcol => + when loadpix2 => cnt4 <= cnt4 + 1; if cnt4 = 0 then + komma_en_i <= '0'; + mupix_data_i <= std_logic_vector(binary_counter(15 downto 8)); + elsif cnt4 = 1 then + komma_en_i <= '0'; + mupix_data_i <= std_logic_vector(binary_counter(7 downto 0)); + elsif cnt4 = 2 then + komma_en_i <= '0'; mupix_data_i <= std_logic_vector(timestamp); + else + mupix8_state <= readcol1; + mupix_data_i <= k28_5; + cnt4 <= 0; + end if; + when readcol1 => + if cnt4 < 3 then + cnt4 <= cnt4 + 1; + mupix8_state <= readcol1; + else + cnt4 <= 0; + mupix8_state <= readcol2; + mupix_data_i <= std_logic_vector(timestamp); + komma_en_i <= '0'; + end if; + when readcol2 => + cnt4 <= cnt4 + 1; + if cnt4 = 0 then + mupix_data_i <= std_logic_vector(tot); komma_en_i <= '0'; elsif cnt4 = 1 then mupix_data_i <= std_logic_vector(column); @@ -164,13 +246,13 @@ begin -- architecture rtl word_cnt_i <= word_cnt_i + 1; column <= column + 2; row <= row + 3; - if word_cnt_i = x"03" then - mupix8_state <= sync; + if word_cnt_i = unsigned(words) then + mupix8_state <= pd1; + cnt4 <= 0; + word_cnt_i <= (others => '0'); else - mupix8_state <= readcol; + mupix8_state <= readcol1; cnt4 <= 0; - mupix_data_i <= std_logic_vector(tot); - komma_en_i <= '0'; end if; end if; end case; -- 2.43.0