]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
saving some unfinished work
authorTobias Weber <toweber86@gmail.com>
Wed, 27 Jun 2018 09:10:08 +0000 (17:10 +0800)
committerTobias Weber <toweber86@gmail.com>
Wed, 27 Jun 2018 09:10:08 +0000 (17:10 +0800)
mupix/Mupix8/sources/GrayCounter2.vhd [new file with mode: 0644]
mupix/Mupix8/sources/MuPixDataLink_new.vhd [new file with mode: 0644]
mupix/Mupix8/tb/GraycounterTest.vhd [new file with mode: 0644]

diff --git a/mupix/Mupix8/sources/GrayCounter2.vhd b/mupix/Mupix8/sources/GrayCounter2.vhd
new file mode 100644 (file)
index 0000000..a700293
--- /dev/null
@@ -0,0 +1,53 @@
+----------------------------------------------------
+-- Gray counter by converting binary number
+-- Tobias Weber 27.06.2018
+-- Ruhr University Bochum
+----------------------------------------------------
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity Graycounter is
+  generic (
+    COUNTWIDTH : integer := 8
+    );
+  port (
+    clk     : in  std_logic;            -- clock
+    reset   : in  std_logic;            -- reset
+    inc_en  : in  std_logic;            -- increment counter enable
+    counter : out std_logic_vector(COUNTWIDTH - 1 downto 0)  -- counter
+    );
+end Graycounter;
+
+architecture rtl of Graycounter is
+
+  signal binary_counter : unsigned(COUNTWIDTH - 1 downto 0) := (others => '0');
+  signal gray_counter : std_logic_vector(COUNTWIDTH - 1 downto 0) := (others => '0');
+
+begin
+
+  binary_cnt: process(clk)
+  begin
+    if rising_edge(clk) then
+      if (reset = '1') then
+        binary_counter <= (others => '0');
+        counter        <= (others => '0');
+      else
+        if inc_en = '1' then
+          binary_counter <= binary_counter + 1;
+        end if;
+        counter <= gray_counter;
+      end if;
+    end if;
+  end process binary_cnt;
+
+  graycode: process (binary_counter) is
+  begin  -- process graycode
+    gray_counter <= std_logic_vector(binary_counter xor ('0' & binary_counter(COUNTWIDTH - 1 downto 1)));  
+  end process graycode;
+  
+
+end rtl;
diff --git a/mupix/Mupix8/sources/MuPixDataLink_new.vhd b/mupix/Mupix8/sources/MuPixDataLink_new.vhd
new file mode 100644 (file)
index 0000000..b46066a
--- /dev/null
@@ -0,0 +1,354 @@
+------------------------------------------------------------------
+-- Mupix data 10b8b readout with internal FIFO 
+--T. Weber, Ruhr Universität Bochum
+------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.StdTypes.all;
+use work.Constants.all;
+
+entity MupixDataLinkWithUnpacker is
+  generic (
+    useRecoveredClock : integer range 0 to 1 := c_Yes);
+  port(
+    sysclk               : in  std_logic;  --trb system clock (typically 100 MHz) 
+    dataclk              : in  std_logic;  --mupix link clock from FPGA PLL(50 - 150 MHz)
+    rst                  : in  std_logic;  --synchronous reset
+    clear                : in  std_logic;  --asynchronous reset
+    --lattice serdes
+    mupix_data           : in  std_logic_vector(7 downto 0);  --lvds pairs of 4 incoming data channels
+    --fifo signals
+    fifo_rden            : in  std_logic_vector(c_links - 1 downto 0);  -- read enable to FIFOs
+    fifo_empty           : out std_logic_vector(c_links - 1 downto 0);  -- input FIFO empty flags
+    fifo_full            : out std_logic_vector(c_links - 1 downto 0);  -- input FIFO full flags
+    fifo_data            : out std_logic_vector(c_links*c_mupixhitsize - 1 downto 0);  -- input data from FIFOs
+    --misc
+    channel_status_led   : out std_logic_vector(c_links - 1 downto 0);
+    --TRB slow control channel
+    SLV_READ_IN          : in  std_logic;
+    SLV_WRITE_IN         : in  std_logic;
+    SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
+    SLV_DATA_IN          : in  std_logic_vector(31 downto 0);
+    SLV_ADDR_IN          : in  std_logic_vector(15 downto 0);
+    SLV_ACK_OUT          : out std_logic;
+    SLV_NO_MORE_DATA_OUT : out std_logic;
+    SLV_UNKNOWN_ADDR_OUT : out std_logic);
+end entity MupixDataLinkWithUnpacker;
+
+architecture rtl of MupixDataLinkWithUnpacker is
+
+  signal clkrx : std_logic_vector(3 downto 0);
+
+  component InputSynchronizer
+    generic(depth : integer := 2;
+            width : integer := 1);
+    port(
+      clk         : in  std_logic;
+      rst         : in  std_logic;
+      input       : in  std_logic_vector(width - 1 downto 0);
+      sync_output : out std_logic_vector(width - 1 downto 0));
+  end component InputSynchronizer;
+
+  component serdes_fifo
+    port (
+      Data    : in  std_logic_vector(39 downto 0);
+      WrClock : in  std_logic;
+      RdClock : in  std_logic;
+      WrEn    : in  std_logic;
+      RdEn    : in  std_logic;
+      Reset   : in  std_logic;
+      RPReset : in  std_logic;
+      Q       : out std_logic_vector(39 downto 0);
+      RCNT    : out std_logic_vector(10 downto 0);
+      Empty   : out std_logic;
+      Full    : out std_logic);
+  end component serdes_fifo;
+
+  component mupix_serdes_new
+    generic (USER_CONFIG_FILE : string := "mupix_serdes_new.txt");
+    port (
+------------------
+-- CH0 --
+      hdinp_ch0, hdinn_ch0 : in  std_logic;  -- input serial link from mupix
+      rxiclk_ch0           : in  std_logic;  -- rx clock for fifo bridge (should be sysclock or recovered clock?)
+      rx_full_clk_ch0      : out std_logic;  -- full receive clock from serdes
+      rx_half_clk_ch0      : out std_logic;  -- half receive clock from serdes
+      fpga_rxrefclk_ch0    : in  std_logic;  -- reference clock from fpga fabric
+      rxdata_ch0           : out std_logic_vector (7 downto 0);  -- received data
+      rx_k_ch0             : out std_logic;  -- control charactor indicator
+      rx_disp_err_ch0      : out std_logic;  -- indicate disparity error
+      rx_cv_err_ch0        : out std_logic;  -- error in data 
+      word_align_en_ch0_c  : in  std_logic;  -- enable word alignment (pulse high)
+      rx_pwrup_ch0_c       : in  std_logic;  -- power up receive channel
+      rx_los_low_ch0_s     : out std_logic;  -- signal lost
+      rx_cdr_lol_ch0_s     : out std_logic;  -- clock recovery failure
+      rx_div2_mode_ch0_c   : in  std_logic;  -- enable clock div mode
+-- CH1 --
+      hdinp_ch1, hdinn_ch1 : in  std_logic;
+      rxiclk_ch1           : in  std_logic;
+      rx_full_clk_ch1      : out std_logic;
+      rx_half_clk_ch1      : out std_logic;
+      fpga_rxrefclk_ch1    : in  std_logic;
+      rxdata_ch1           : out std_logic_vector (7 downto 0);
+      rx_k_ch1             : out std_logic;
+      rx_disp_err_ch1      : out std_logic;
+      rx_cv_err_ch1        : out std_logic;
+      word_align_en_ch1_c  : in  std_logic;
+      rx_pwrup_ch1_c       : in  std_logic;
+      rx_los_low_ch1_s     : out std_logic;
+      rx_cdr_lol_ch1_s     : out std_logic;
+      rx_div2_mode_ch1_c   : in  std_logic;
+-- CH2 --
+      hdinp_ch2, hdinn_ch2 : in  std_logic;
+      rxiclk_ch2           : in  std_logic;
+      rx_full_clk_ch2      : out std_logic;
+      rx_half_clk_ch2      : out std_logic;
+      fpga_rxrefclk_ch2    : in  std_logic;
+      rxdata_ch2           : out std_logic_vector (7 downto 0);
+      rx_k_ch2             : out std_logic;
+      rx_disp_err_ch2      : out std_logic;
+      rx_cv_err_ch2        : out std_logic;
+      word_align_en_ch2_c  : in  std_logic;
+      rx_pwrup_ch2_c       : in  std_logic;
+      rx_los_low_ch2_s     : out std_logic;
+      rx_cdr_lol_ch2_s     : out std_logic;
+      rx_div2_mode_ch2_c   : in  std_logic;
+-- CH3 --
+      hdinp_ch3, hdinn_ch3 : in  std_logic;
+      rxiclk_ch3           : in  std_logic;
+      rx_full_clk_ch3      : out std_logic;
+      rx_half_clk_ch3      : out std_logic;
+      fpga_rxrefclk_ch3    : in  std_logic;
+      rxdata_ch3           : out std_logic_vector (7 downto 0);
+      rx_k_ch3             : out std_logic;
+      rx_disp_err_ch3      : out std_logic;
+      rx_cv_err_ch3        : out std_logic;
+      word_align_en_ch3_c  : in  std_logic;
+      rx_pwrup_ch3_c       : in  std_logic;
+      rx_los_low_ch3_s     : out std_logic;
+      rx_cdr_lol_ch3_s     : out std_logic;
+      rx_div2_mode_ch3_c   : in  std_logic;
+---- Miscillaneous ports
+      fpga_txrefclk        : in  std_logic;  -- tx reference clock
+      tx_sync_qd_c         : in  std_logic;  -- serializer reset
+      refclk2fpga          : out std_logic;  -- reference clock to fpga core
+      rst_n                : in  std_logic;  -- reset all
+      serdes_rst_qd_c      : in  std_logic);  -- reset serdes, but nor pcs
+  end component mupix_serdes_new;
+
+  component MupixUnpacker
+    generic(
+      g_hitsize     : integer := 40;
+      g_countersize : integer := 32
+      );
+    port(
+      clk            : in  std_logic;
+      reset          : in  std_logic;
+      data_in        : in  std_logic_vector(7 downto 0);
+      komma          : in  std_logic;
+      valid          : in  std_logic;
+      hit_out        : out std_logic_vector(g_hitsize - 1 downto 0);
+      hit_enable     : out std_logic;
+      coarsecounter  : out std_logic_vector(g_countersize - 1 downto 0);
+      counter_enable : out std_logic;
+      link_flag      : out std_logic;
+      errorcounter   : out std_logic_vector(31 downto 0));
+  end component MupixUnpacker;
+
+  component LinkSynchronizer
+    generic (
+      clk_speed : integer := 8);
+    port (
+      clk_in            : in  std_logic;
+      reset_in          : in  std_logic;
+      comma_in          : in  std_logic;
+      cverr_in          : in  std_logic;
+      link_sync_out     : out std_logic;
+      link_sync_flag    : out std_logic;
+      comma_counter_out : out std_logic_vector(15 downto 0));
+  end component LinkSynchronizer;
+
+  constant ch_powerup_i : std_logic_vector(3 downto 0) := "1111";  -- change to powerdown unused channels
+  constant ch_divmode_i : std_logic_vector(3 downto 0) := "0000";  -- use half rx clock speed
+
+  -- serdes signals (declare for all channels possibly used)
+  signal rx_full_clock_i : std_logic_vector(3 downto 0);  -- recovered receive clock
+  signal rx_data_i       : std_logic_vector(4*8 - 1 downto 0);  -- receive data
+  signal rx_komma_i      : std_logic_vector(3 downto 0);  -- komma words
+  signal rx_disp_err_i   : std_logic_vector(3 downto 0);  -- disparity error indicator
+  signal rx_dataerror_i  : std_logic_vector(3 downto 0);  -- error in rx data
+  signal align_en_i      : std_logic_vector(3 downto 0);  -- regain word alignment to rx data
+  signal rx_sig_lost_i   : std_logic_vector(3 downto 0);  -- rx signal lost
+  signal rx_cdr_i        : std_logic_vector(3 downto 0);  -- clock recovery failure
+
+  -- synced signals
+  signal rx_cdr_sync      : std_logic_vector(3 downto 0);
+  signal rx_sig_lost_sync : std_logic_vector(3 downto 0);
+
+  -- fifo signals
+  signal fifo_data_oi   : std_logic_vector(c_links*c_mupixhitsize - 1 downto 0);
+  signal fifo_data_ii   : std_logic_vector(c_links*c_mupixhitsize - 1 downto 0);
+  signal fifo_empty_i   : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+  signal fifo_full_i    : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+  signal fifo_wren_i    : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+  signal fifo_rden_i    : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+  constant fifo_depth   : integer                                := 10;  -- fifo depth (change when regenerating FIFO IP core)
+  signal fifo_readcnt_i : std_logic_vector((c_links - 1)*fifo_depth - 1 downto 0);
+
+  -- status and error counters
+  signal serdes_channel_select  : integer range 0 to 3    := 0;
+  signal disp_error_counter     : t_counter_array(0 to 3) := (others => (others => '0'));
+  signal data_error_counter     : t_counter_array(0 to 3) := (others => (others => '0'));
+  signal unpacker_error_counter : t_counter_array(0 to 3) := (others => (others => '0'));
+
+  -- link synchronizer signals
+  signal link_sync_out_i  : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+  signal link_sync_flag_i : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+  signal komma_counter    : t_counter_array(0 to 3)                := (others => (others => '0'));
+
+  -- unpacker signals
+  signal unpacker_valid_i : std_logic_vector(c_links - 1 downto 0) := (others => '0');
+
+begin
+
+  gen_receive_clock_rec : if useRecoveredClock = c_Yes generate
+    clkrx <= rx_full_clock_i;
+  end generate;
+
+  gen_receive_clock_norec : if useRecoveredClock = c_No generate
+    clkrx <= sysclk & sysclk & sysclk & sysclk;
+  end generate;
+
+  -- not sure about correct clock distribution
+  mupix_serdes_new : entity work.mupix_serdes_new
+    generic map (
+      USER_CONFIG_FILE => "mupix_serdes_new.txt")
+    port map (
+      hdinp_ch0           => mupix_data(0),
+      hdinn_ch0           => mupix_data(1),
+      rxiclk_ch0          => clkrx(0),
+      rx_full_clk_ch0     => rx_full_clock_i(0),
+      rx_half_clk_ch0     => open,
+      fpga_rxrefclk_ch0   => dataclk,
+      rxdata_ch0          => rx_data_i(1*8 - 1 downto 0*8),
+      rx_k_ch0            => rx_komma_i(0),
+      rx_disp_err_ch0     => rx_disp_err_i(0),
+      rx_cv_err_ch0       => rx_dataerror_i(0),
+      word_align_en_ch0_c => align_en_i(0),
+      rx_pwrup_ch0_c      => ch_powerup_i(0),
+      rx_los_low_ch0_s    => rx_sig_lost_i(0),
+      rx_cdr_lol_ch0_s    => rx_cdr_i(0),
+      rx_div2_mode_ch0_c  => ch_divmode_i(0),
+      hdinp_ch1           => mupix_data(2),
+      hdinn_ch1           => mupix_data(3),
+      rxiclk_ch1          => clkrx(1),
+      rx_full_clk_ch1     => rx_full_clock_i(1),
+      rx_half_clk_ch1     => open,
+      fpga_rxrefclk_ch1   => dataclk,
+      rxdata_ch1          => rx_data_i(2*8 - 1 downto 1*8),
+      rx_k_ch1            => rx_komma_i(1),
+      rx_disp_err_ch1     => rx_disp_err_i(1),
+      rx_cv_err_ch1       => rx_dataerror_i(1),
+      word_align_en_ch1_c => align_en_i(1),
+      rx_pwrup_ch1_c      => ch_powerup_i(1),
+      rx_los_low_ch1_s    => rx_sig_lost_i(1),
+      rx_cdr_lol_ch1_s    => rx_cdr_i(1),
+      rx_div2_mode_ch1_c  => ch_divmode_i(1),
+      hdinp_ch2           => mupix_data(4),
+      hdinn_ch2           => mupix_data(5),
+      rxiclk_ch2          => clkrx(2),
+      rx_full_clk_ch2     => rx_full_clock_i(2),
+      rx_half_clk_ch2     => open,
+      fpga_rxrefclk_ch2   => dataclk,
+      rxdata_ch2          => rx_data_i(3*8 - 1 downto 2*8),
+      rx_k_ch2            => rx_komma_i(2),
+      rx_disp_err_ch2     => rx_disp_err_i(2),
+      rx_cv_err_ch2       => rx_dataerror_i(2),
+      word_align_en_ch2_c => align_en_i(2),
+      rx_pwrup_ch2_c      => ch_powerup_i(2),
+      rx_los_low_ch2_s    => rx_sig_lost_i(2),
+      rx_cdr_lol_ch2_s    => rx_cdr_i(2),
+      rx_div2_mode_ch2_c  => ch_divmode_i(2),
+      hdinp_ch3           => mupix_data(6),
+      hdinn_ch3           => mupix_data(7),
+      rxiclk_ch3          => clkrx(3),
+      rx_full_clk_ch3     => rx_full_clock_i(3),
+      rx_half_clk_ch3     => open,
+      fpga_rxrefclk_ch3   => dataclk,
+      rxdata_ch3          => rx_data_i(4*8 - 1 downto 3*8),
+      rx_k_ch3            => rx_komma_i(3),
+      rx_disp_err_ch3     => rx_disp_err_i(3),
+      rx_cv_err_ch3       => rx_dataerror_i(3),
+      word_align_en_ch3_c => align_en_i(3),
+      rx_pwrup_ch3_c      => ch_powerup_i(3),
+      rx_los_low_ch3_s    => rx_sig_lost_i(3),
+      rx_cdr_lol_ch3_s    => rx_cdr_i(3),
+      rx_div2_mode_ch3_c  => ch_divmode_i(2),
+      fpga_txrefclk       => dataclk,
+      tx_sync_qd_c        => '0',
+      refclk2fpga         => open,
+      rst_n               => '1',
+      serdes_rst_qd_c     => clear);
+
+  generate_synchronizer : for j in 0 to c_links - 1 generate
+    entity work.LinkSynchronizer
+      generic map (
+        clk_speed => 8)
+      port map (
+        clk_in            => clkrx,
+        reset_in          => rst,
+        comma_in          => rx_komma_i(j),
+        cverr_in          => rx_dataerror_i(j),
+        link_sync_out     => link_sync_out_i(j),
+        link_sync_flag    => link_sync_flag_i(j),
+        comma_counter_out => komma_counter(j));
+  end generate generate_synchronizer;
+
+  unpacker_valid_i <= not rx_dataerror_i;
+
+  generate_unpacker : for j in 0 to c_links - 1 generate
+    entity work.MupixUnpacker
+      generic map (
+        g_hitsize     => c_mupixhitsize,
+        g_countersize => 31)
+      port map (
+        clk            => clkrx,
+        reset          => rst,
+        data_in        => rx_data_i((j + 1)*8 - 1 downto j*8),
+        komma          => rx_komma_i(j),
+        valid          => unpacker_valid_i(j),
+        hit_out        => fifo_data_ii((j + 1)*c_mupixhitsize downto j*c_mupixhitsize),
+        hit_enable     => fifo_wren_i(j),
+        coarsecounter  => open,
+        counter_enable => open,
+        link_flag      => open,
+        errorcounter   => unpacker_error_counter(j));
+  end generate generate_fifo;
+
+  generate_fifo : for j in 0 to c_links - 1 generate
+    entity work.serdes_fifo
+      port map (
+        Data    => fifo_data_ii((j + 1)*c_mupixhitsize downto j*c_mupixhitsize),
+        WrClock => clkrx(j),
+        RdClock => sysclk,
+        WrEn    => fifo_wren_i(j),
+        RdEn    => fifo_rden_i(j),
+        Reset   => rst,
+        RPReset => rst,
+        Q       => fifo_data_oi((j + 1)*c_mupixhitsize downto j*c_mupixhitsize),
+        RCNT    => fifo_readcnt_i((j + 1)*fifo_depth - 1 downto j*fifo_depth),
+        Empty   => fifo_empty_i(j),
+        Full    => fifo_full_i(j));
+  end generate generate_fifo;
+
+  sync_los_low : InputSynchronizer
+    generic map(depth => 2, width => 4)
+    port map(clk      => sysclk, rst => rst, input => rx_sig_lost_i, sync_output => rx_sig_lost_sync);
+
+  sync_cdr_lol : InputSynchronizer
+    generic map(depth => 2, width => 4)
+    port map(clk      => sysclk, rst => rst, input => rx_cdr_i, sync_output => rx_cdr_sync);
+
+end architecture;
diff --git a/mupix/Mupix8/tb/GraycounterTest.vhd b/mupix/Mupix8/tb/GraycounterTest.vhd
new file mode 100644 (file)
index 0000000..561a6d9
--- /dev/null
@@ -0,0 +1,98 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity GraycounterTest is
+end entity GraycounterTest;
+
+architecture sim of GraycounterTest is
+
+  constant clk_period : time    := 10 ns;
+  constant COUNTWIDTH : integer := 3;
+
+  signal clk     : std_logic;
+  signal reset   : std_logic := '0';
+  signal inc_en  : std_logic := '0';
+  signal counter : std_logic_vector(COUNTWIDTH - 1 downto 0);
+  signal bypass  : std_logic := '0';
+  signal binary_out : std_logic_vector(COUNTWIDTH - 1 downto 0);
+
+  component Graycounter is
+    generic (
+      COUNTWIDTH : integer);
+    port (
+      clk     : in  std_logic;
+      reset   : in  std_logic;
+      inc_en  : in  std_logic;
+      counter : out std_logic_vector(COUNTWIDTH-1 downto 0));
+  end component Graycounter;
+
+  component gray_to_binary is
+    generic (
+      NBITS : integer);
+    port (
+      clk     : in  std_logic;
+      reset   : in  std_logic;
+      bypass  : in  std_logic;
+      gray_in : in  std_logic_vector (NBITS - 1 downto 0);
+      bin_out : out std_logic_vector (NBITS - 1 downto 0));
+  end component gray_to_binary;
+  
+begin  -- architecture sim
+
+  Graycounter_1 : entity work.Graycounter
+    generic map (
+      COUNTWIDTH => COUNTWIDTH)
+    port map (
+      clk     => clk,
+      reset   => reset,
+      inc_en  => inc_en,
+      counter => counter);
+
+  gray_to_binary_1: entity work.gray_to_binary
+    generic map (
+      NBITS => COUNTWIDTH)
+    port map (
+      clk     => clk,
+      reset   => reset,
+      bypass  => bypass,
+      gray_in => counter,
+      bin_out => binary_out);
+
+  clock_gen : process is
+  begin
+    clk <= '1';
+    wait for clk_period/2;
+    clk <= '0';
+    wait for clk_period/2;
+  end process clock_gen;
+
+  sim : process is
+  begin  -- process sim
+    wait for 100 ns;
+    inc_en <= '1';
+    -- normal couting
+    wait for 4*clk_period;
+    inc_en <= '0';
+    wait for 10*clk_period;
+    inc_en <= '1';
+    wait for 6*clk_period;
+    inc_en <= '0';
+    -- reacting to reset
+    wait for clk_period;
+    reset  <= '1';
+    wait for clk_period;
+    reset  <= '0';
+    wait for 2*clk_period;
+    inc_en <= '1';
+    wait for 4*clk_period;
+    inc_en <= '0';
+    wait for 5*clk_period;
+    inc_en <= '1';
+    wait for 15*clk_period;
+    inc_en <= '0';
+    wait;
+  end process sim;
+
+
+end architecture sim;