]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
readback of mupix 8 shift register.
authorTobias Weber <toweber86@gmail.com>
Tue, 10 Jul 2018 12:58:46 +0000 (14:58 +0200)
committerTobias Weber <toweber86@gmail.com>
Tue, 10 Jul 2018 12:58:46 +0000 (14:58 +0200)
mupix/Mupix8/sources/PixelControl.vhd
mupix/Mupix8/tb/PixCtrlTest.vhd

index 36db86c8650512f193eacf530cd569e0bce24b07..47a21f9b5708a66c12361bb9922b96ebca4346f6 100644 (file)
@@ -10,14 +10,15 @@ use work.StdTypes.all;
 
 entity PixelControl is
   generic(
-       fpga_clk_speed : integer := 1e8;
-       spi_clk_speed : integer := 1e4
-  );
+    fpga_clk_speed : integer := 1e8;
+    spi_clk_speed  : integer := 1e4;
+    config_bits    : integer := 8096
+    );
   port (
-    clk                  : in  std_logic; --clock
-    reset                : in  std_logic; --reset
+    clk                  : in  std_logic;  --clock
+    reset                : in  std_logic;  --reset
     mupixslctrl          : out MupixSlowControl;
-    ctrl_dout            : in std_logic; --serial data from mupix
+    ctrl_dout            : in  std_logic;  --serial data from mupix
     --TRB slow control
     SLV_READ_IN          : in  std_logic;
     SLV_WRITE_IN         : in  std_logic;
@@ -30,352 +31,450 @@ entity PixelControl is
 end PixelControl;
 
 architecture Behavioral of PixelControl is
-       
-       constant c_fifo_word_width : integer :=  32;
-       constant c_clk_div_max : integer := fpga_clk_speed/spi_clk_speed - 1;
-       signal clk_div_cnt : integer range 0 to c_clk_div_max - 1 := 0;
-       
-       signal bitcounter : unsigned(15 downto 0) := (others => '0');--number of transmitted configuration bits
-       signal bitstosend : unsigned(15 downto 0) := (others => '0');--number of bits which need to be send
-       signal bitcouner_word : integer range 0 to c_fifo_word_width - 1 := c_fifo_word_width - 1; --index to current bit in word from fifo
-       
-       --fifos storage of configuration bits
-       component STD_FIFO
-               generic(
-                       DATA_WIDTH : positive := 8;
-                       FIFO_DEPTH : positive := 256
-               );
-               port(
-                       CLK     : in  std_logic;
-                       RST     : in  std_logic;
-                       WriteEn : in  std_logic;
-                       DataIn  : in  std_logic_vector(c_fifo_word_width - 1 downto 0);
-                       ReadEn  : in  std_logic;
-                       DataOut : out std_logic_vector(c_fifo_word_width - 1 downto 0);
-                       Empty   : out std_logic;
-                       Full    : out std_logic
-               );
-       end component STD_FIFO;
-       
-       component CRC
-               generic(
-                       detect_enable_edge : boolean := false
-               );
-               port(
-                       clk     : in  std_logic;
-                       rst     : in  std_logic;
-                       enable  : in  std_logic;
-                       data_in : in  std_logic;
-                       crc_out : out std_logic_vector(4 downto 0)
-               );
-       end component CRC;
-
-       signal WriteEn : std_logic;
-       signal DataIn : std_logic_vector (c_fifo_word_width - 1 downto 0);
-       signal ReadEn : std_logic;
-       signal DataOut : std_logic_vector (c_fifo_word_width - 1 downto 0);
-       signal Empty : std_logic;
-       signal Full : std_logic;
-       
-       --send single configuration bit
-       signal start_send, sending : std_logic; 
-       signal reset_bitcounter : std_logic;
-       type t_send_bits_fsm is (idle, sendbit1, sendbit2, done);
-       signal send_bits_fsm : t_send_bits_fsm := idle; 
-       
-
-       --configuration state machine
-       type t_config_fsm is (idle, config, readfifo, waitfifo, load);
-       signal config_fsm : t_config_fsm := idle;
-       
-       --check sum for data integrity
-       signal crc_correct : std_logic;
-       signal enable_crc_to_mupix : std_logic;
-       signal data_in_crc_to_mupix : std_logic;
-       signal crc_out_crc_to_mupix : std_logic_vector(4 downto 0);
-       signal reset_crc_to_mupix,  reset_crc_to_mupix_ext: std_logic;
-       signal enable_crc_from_mupix : std_logic;
-       signal data_in_crc_from_mupix : std_logic;
-       signal crc_out_crc_from_mupix : std_logic_vector(4 downto 0);
-       signal reset_crc_from_mupix,  reset_crc_from_mupix_ext : std_logic;
-       
-       --control signals to mupix
-       signal mupix_ctrcl_select : std_logic;
-       signal mupix_ctrl_i, mupix_ctrl_ext, mupix_ctrl_sel, mupix_ctrl_reg : MupixSlowControl := c_mupix_slctrl_init;
-       
-       
+
+  constant c_fifo_word_width : integer                              := 32;
+  constant c_clk_div_max     : integer                              := fpga_clk_speed/spi_clk_speed - 1;
+  signal clk_div_cnt         : integer range 0 to c_clk_div_max - 1 := 0;
+
+  signal bitcounter     : unsigned(15 downto 0)                    := (others => '0');  --number of transmitted configuration bits
+  signal bitstosend     : unsigned(15 downto 0)                    := (others => '0');  --number of bits which need to be send
+  signal bitcouner_word : integer range 0 to c_fifo_word_width - 1 := c_fifo_word_width - 1;  --index to current bit in word from fifo
+
+  --fifos storage of configuration bits
+  component STD_FIFO
+    generic(
+      DATA_WIDTH : positive := 8;
+      FIFO_DEPTH : positive := 256
+      );
+    port(
+      CLK     : in  std_logic;
+      RST     : in  std_logic;
+      WriteEn : in  std_logic;
+      DataIn  : in  std_logic_vector(c_fifo_word_width - 1 downto 0);
+      ReadEn  : in  std_logic;
+      DataOut : out std_logic_vector(c_fifo_word_width - 1 downto 0);
+      Empty   : out std_logic;
+      Full    : out std_logic
+      );
+  end component STD_FIFO;
+
+  component CRC
+    generic(
+      detect_enable_edge : boolean := false
+      );
+    port(
+      clk     : in  std_logic;
+      rst     : in  std_logic;
+      enable  : in  std_logic;
+      data_in : in  std_logic;
+      crc_out : out std_logic_vector(4 downto 0)
+      );
+  end component CRC;
+
+  component BlockMemory is
+    generic (
+      DataWidth    : integer;
+      AddressWidth : integer);
+    port (
+      clk    : in  std_logic;
+      reset  : in  std_logic;
+      WrEn   : in  std_logic;
+      WrAddr : in  std_logic_vector(AddressWidth - 1 downto 0);
+      Din    : in  std_logic_vector(DataWidth - 1 downto 0);
+      ReAddr : in  std_logic_vector(AddressWidth - 1 downto 0);
+      Dout   : out std_logic_vector(DataWidth - 1 downto 0));
+  end component BlockMemory;
+
+  signal WriteEn : std_logic;
+  signal DataIn  : std_logic_vector (c_fifo_word_width - 1 downto 0);
+  signal ReadEn  : std_logic;
+  signal DataOut : std_logic_vector (c_fifo_word_width - 1 downto 0);
+  signal Empty   : std_logic;
+  signal Full    : std_logic;
+
+  --send single configuration bit
+  signal start_send, sending : std_logic;
+  signal reset_bitcounter    : std_logic;
+  type t_send_bits_fsm is (idle, sendbit1, sendbit2, done);
+  signal send_bits_fsm       : t_send_bits_fsm := idle;
+
+
+  --configuration state machine
+  type t_config_fsm is (idle, config, readfifo, waitfifo, load);
+  signal config_fsm : t_config_fsm := idle;
+
+  --readback of configuration data
+  constant c_config_words_max                : integer                                            := config_bits/32 + 1;
+  constant c_ram_address_width               : integer                                            := f_log2(c_config_words_max);
+  signal data_from_mupix_i                   : std_logic                                          := '0';
+  signal readback_wr_addr, readback_rd_addr  : std_logic_vector(c_ram_address_width - 1 downto 0) := (others => '0');
+  signal readback_wr_addr_new                : std_logic_vector(c_ram_address_width - 1 downto 0) := (others => '0');
+  signal readback_data_in, readback_data_out : std_logic_vector(31 downto 0)                      := (others => '0');
+  signal readback_mem_wren_i                 : std_logic                                          := '0';
+  signal reset_readback_i                    : std_logic                                          := '0';
+  signal readback_cnt_i                      : integer range 0 to 32                              := 0;
+  signal readback_shift_reg                  : std_logic_vector(31 downto 0)                      := (others => '0');
+  signal mupix_clk1_edge                     : std_logic_vector(1 downto 0)                       := (others => '0');
+  signal mupix_load_edge                     : std_logic_vector(1 downto 0)                       := (others => '0');
+
+
+  --check sum for data integrity
+  signal crc_correct                                    : std_logic;
+  signal enable_crc_to_mupix                            : std_logic;
+  signal data_in_crc_to_mupix                           : std_logic;
+  signal crc_out_crc_to_mupix                           : std_logic_vector(4 downto 0);
+  signal reset_crc_to_mupix, reset_crc_to_mupix_ext     : std_logic;
+  signal enable_crc_from_mupix                          : std_logic;
+  signal crc_out_crc_from_mupix                         : std_logic_vector(4 downto 0);
+  signal reset_crc_from_mupix, reset_crc_from_mupix_ext : std_logic;
+
+  --control signals to mupix
+  signal mupix_ctrcl_select                                           : std_logic;
+  signal mupix_ctrl_i, mupix_ctrl_ext, mupix_ctrl_sel, mupix_ctrl_reg : MupixSlowControl := c_mupix_slctrl_init;
+
+
 begin  -- Behavioral
-       
-       fifo_1 : entity work.STD_FIFO
-               generic map(
-                       DATA_WIDTH => c_fifo_word_width,
-                       FIFO_DEPTH => 32
-               )
-               port map(
-                       CLK     => CLK,
-                       RST     => reset,
-                       WriteEn => WriteEn,
-                       DataIn  => DataIn,
-                       ReadEn  => ReadEn,
-                       DataOut => DataOut,
-                       Empty   => Empty,
-                       Full    => Full
-               );
-       
-       crc_in : entity work.CRC
-               generic map(detect_enable_edge => true)
-               port map(
-                       clk     => clk,
-                       rst     => reset_crc_to_mupix,
-                       enable  => enable_crc_to_mupix,
-                       data_in => data_in_crc_to_mupix,
-                       crc_out => crc_out_crc_to_mupix
-               );
-               
-       reset_crc_to_mupix <= reset or reset_crc_to_mupix_ext;  
-               
-       crc_out : entity work.CRC
-               generic map(detect_enable_edge => true)
-               port map(
-                       clk     => clk,
-                       rst     => reset_crc_from_mupix,
-                       enable  => enable_crc_from_mupix,
-                       data_in => data_in_crc_from_mupix,
-                       crc_out => crc_out_crc_from_mupix
-               );
-       
-       reset_crc_from_mupix <= reset or reset_crc_from_mupix_ext;
-       
-       
-       sendpix_bits : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if reset = '1' then
-                               send_bits_fsm     <= idle;
-                               mupix_ctrl_i.clk1 <= '0';
-                               mupix_ctrl_i.clk2 <= '0';
-                               mupix_ctrl_i.sin  <= '0';
-                               sending           <= '0';
-                       else
-                               case send_bits_fsm is
-                                       when idle =>
-                                               bitcouner_word    <= 31;
-                                               sending           <= '0';
-                                               clk_div_cnt       <= 0;
-                                               send_bits_fsm     <= idle;
-                                               mupix_ctrl_i.clk1 <= '0';
-                                               mupix_ctrl_i.clk2 <= '0';
-                                               mupix_ctrl_i.sin  <= '0';
-                                               if start_send = '1' then
-                                                       sending          <= '1';
-                                                       send_bits_fsm    <= sendbit1;
-                                               end if;
-                                               if reset_bitcounter = '1' then
-                                                       bitcounter <= (others => '0');
-                                               end if;
-                                       when sendbit1 =>
-                                               clk_div_cnt            <= clk_div_cnt + 1;
-                                               send_bits_fsm          <= sendbit1;
-                                               mupix_ctrl_i.sin <= DataOut(bitcouner_word);
-                                               enable_crc_from_mupix  <= '0';
-                                               enable_crc_to_mupix    <= '0';
-                                               data_in_crc_from_mupix <= '0';
-                                               data_in_crc_to_mupix   <= ctrl_dout;
-                                               if clk_div_cnt = (c_clk_div_max - 1)/2 then
-                                                       send_bits_fsm     <= sendbit2;
-                                                       mupix_ctrl_i.clk1 <= '1'; -- clocking
-                                                       mupix_ctrl_i.clk2 <= '0';
-                                                       data_in_crc_from_mupix <= ctrl_dout; --CRC checksum
-                                                       data_in_crc_to_mupix   <= DataOut(bitcouner_word);
-                                                       enable_crc_from_mupix  <= '1';
-                                                       enable_crc_to_mupix    <= '1';
-                                                       bitcounter             <= bitcounter + 1;
-                                               end if;
-                                       when sendbit2 =>
-                                               clk_div_cnt            <= clk_div_cnt + 1;
-                                               send_bits_fsm          <= sendbit2;
-                                               if clk_div_cnt = c_clk_div_max - 1 then
-                                                       mupix_ctrl_i.clk1 <= '0';
-                                                       mupix_ctrl_i.clk2 <= '1';
-                                                       clk_div_cnt       <= 0;
-                                                       if bitcouner_word = 0 or bitcounter = bitstosend then
-                                                               send_bits_fsm          <= done;
-                                                       else
-                                                               send_bits_fsm          <= sendbit1;
-                                                               bitcouner_word         <= bitcouner_word -1;
-                                                       end if;
-                                               end if;
-                                       when done => -- 
-                                               clk_div_cnt            <= clk_div_cnt + 1;
-                                               send_bits_fsm          <= done;
-                                               if clk_div_cnt = (c_clk_div_max - 1)/2 then
-                                                       send_bits_fsm          <= idle; -- just hold clk2 high long enough before going back to idle
-                                               end if;
-                               end case;
-                       end if;
-               end if;
-       end process sendpix_bits;
-       
-               
-       
-       configure_proc : process(clk) is
-               variable hold_load_counter : integer range 0 to 7;
-       begin
-               if rising_edge(clk) then
-                       if reset = '1' then
-                               mupix_ctrl_i.load <= '0';
-                               config_fsm        <= idle;
-                               hold_load_counter := 0;
-                       else
-                               mupix_ctrl_i.load <= '0';
-                               ReadEn            <= '0';
-                               start_send        <= '0';
-                               reset_bitcounter  <= '0';
-                               case config_fsm is
-                                       when idle =>
-                                               hold_load_counter := 0;
-                                               if Empty = '0' then
-                                                       config_fsm <= readfifo;
-                                               else
-                                                       config_fsm <= idle;
-                                               end if;
-                                       when readfifo =>
-                                               if Empty = '0' then
-                                                       ReadEn     <= '1';
-                                                       start_send <= '1';
-                                                       config_fsm <= waitfifo;
-                                               else
-                                                       ReadEn     <= '0';
-                                                       config_fsm <= readfifo; -- wait on next config word in fifo
-                                               end if;
-                                       when waitfifo =>    -- wait for fifo word to be valid
-                                               config_fsm <= config;
-                                       when config =>
-                                               if sending = '1' then
-                                                       config_fsm <= config;
-                                               else
-                                                       if bitcounter < bitstosend then -- everything send or read other fifo word
-                                                               config_fsm <= readfifo;
-                                                       else
-                                                               config_fsm <= load;
-                                                       end if;
-                                               end if;
-                                       when load =>        -- load from shift register
-                                               hold_load_counter := hold_load_counter + 1;
-                                               mupix_ctrl_i.load <= '1';
-                                               config_fsm        <= load;
-                                               if hold_load_counter = 7 then
-                                                       mupix_ctrl_i.load <= '0';
-                                                       reset_bitcounter  <= '1';
-                                                       config_fsm        <= idle;
-                                               end if;
-                               end case;
-                       end if;
-               end if;
-       end process configure_proc;
-       
-       
+
+  fifo_1 : entity work.STD_FIFO
+    generic map(
+      DATA_WIDTH => c_fifo_word_width,
+      FIFO_DEPTH => 32
+      )
+    port map(
+      CLK     => CLK,
+      RST     => reset,
+      WriteEn => WriteEn,
+      DataIn  => DataIn,
+      ReadEn  => ReadEn,
+      DataOut => DataOut,
+      Empty   => Empty,
+      Full    => Full
+      );
+
+  crc_in : entity work.CRC
+    generic map(detect_enable_edge => false)
+    port map(
+      clk     => clk,
+      rst     => reset_crc_to_mupix,
+      enable  => enable_crc_to_mupix,
+      data_in => data_in_crc_to_mupix,
+      crc_out => crc_out_crc_to_mupix
+      );
+
+  reset_crc_to_mupix <= reset or reset_crc_to_mupix_ext;
+
+  crc_out : entity work.CRC
+    generic map(detect_enable_edge => false)
+    port map(
+      clk     => clk,
+      rst     => reset_crc_from_mupix,
+      enable  => enable_crc_from_mupix,
+      data_in => data_from_mupix_i,
+      crc_out => crc_out_crc_from_mupix
+      );
+
+  reset_crc_from_mupix <= reset or reset_crc_from_mupix_ext;
+
+  BlockMemory_1 : entity work.BlockMemory
+    generic map (
+      DataWidth    => 32,
+      AddressWidth => c_ram_address_width)
+    port map (
+      clk    => clk,
+      reset  => reset,
+      WrEn   => readback_mem_wren_i,
+      WrAddr => readback_wr_addr,
+      Din    => readback_data_in,
+      ReAddr => readback_rd_addr,
+      Dout   => readback_data_out);
+
+
+  -- purpose: readback of configuration from dout of mupix and storing in bram
+  readback_proc : process (clk) is
+  begin  -- process readback_proc
+    if rising_edge(clk) then            -- rising clock edge
+      if reset = '1' or reset_readback_i = '1' then
+        mupix_clk1_edge       <= (others => '0');
+        mupix_load_edge       <= (others => '0');
+        readback_cnt_i        <= 0;
+        readback_wr_addr      <= (others => '0');
+        readback_data_in      <= (others => '0');
+        readback_mem_wren_i   <= '0';
+        readback_shift_reg    <= (others => '0');
+        enable_crc_from_mupix <= '0';
+        enable_crc_to_mupix   <= '0';
+        data_from_mupix_i     <= '0';
+        data_in_crc_to_mupix  <= '0';
+        readback_wr_addr_new  <= (others => '0');
+      else
+        enable_crc_from_mupix <= '0';
+        enable_crc_to_mupix   <= '0';
+        data_from_mupix_i     <= '0';
+        data_in_crc_to_mupix  <= '0';
+        readback_mem_wren_i   <= '0';
+        mupix_clk1_edge       <= mupix_clk1_edge(0) & mupix_ctrl_reg.clk1;
+        mupix_load_edge       <= mupix_load_edge(0) & mupix_ctrl_reg.load;
+        if mupix_clk1_edge = "01" then  -- use rising edge of clk1 as sampling point for mupix_dout and crc sums
+          readback_shift_reg    <= readback_shift_reg(30 downto 0) & ctrl_dout;
+          readback_cnt_i        <= readback_cnt_i + 1;
+          data_from_mupix_i     <= ctrl_dout;  --CRC checksum
+          enable_crc_from_mupix <= '1';
+          data_in_crc_to_mupix  <= mupix_ctrl_reg.sin;
+          enable_crc_to_mupix   <= '1';
+          readback_wr_addr      <= readback_wr_addr_new;
+        end if;
+        if readback_cnt_i = 32 or mupix_load_edge = "01" then
+          readback_cnt_i       <= 0;
+          readback_mem_wren_i  <= '1';
+          readback_data_in     <= readback_shift_reg;
+          if to_integer(unsigned(readback_wr_addr_new)) < c_config_words_max - 1 then
+            readback_wr_addr_new <= std_logic_vector(unsigned(readback_wr_addr_new) + 1);
+          else
+            readback_wr_addr_new <= (others => '0');
+          end if;
+        end if;
+      end if;
+    end if;
+  end process readback_proc;
+
+
+  sendpix_bits : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if reset = '1' then
+        send_bits_fsm     <= idle;
+        mupix_ctrl_i.clk1 <= '0';
+        mupix_ctrl_i.clk2 <= '0';
+        mupix_ctrl_i.sin  <= '0';
+        sending           <= '0';
+      else
+        case send_bits_fsm is
+          when idle =>
+            bitcouner_word    <= 31;
+            sending           <= '0';
+            clk_div_cnt       <= 0;
+            send_bits_fsm     <= idle;
+            mupix_ctrl_i.clk1 <= '0';
+            mupix_ctrl_i.clk2 <= '0';
+            mupix_ctrl_i.sin  <= '0';
+            if start_send = '1' then
+              sending       <= '1';
+              send_bits_fsm <= sendbit1;
+            end if;
+            if reset_bitcounter = '1' then
+              bitcounter <= (others => '0');
+            end if;
+          when sendbit1 =>
+            clk_div_cnt      <= clk_div_cnt + 1;
+            send_bits_fsm    <= sendbit1;
+            mupix_ctrl_i.sin <= DataOut(bitcouner_word);
+            if clk_div_cnt = (c_clk_div_max - 1)/2 then
+              send_bits_fsm     <= sendbit2;
+              mupix_ctrl_i.clk1 <= '1';  -- clocking
+              mupix_ctrl_i.clk2 <= '0';
+              bitcounter        <= bitcounter + 1;
+            end if;
+          when sendbit2 =>
+            clk_div_cnt   <= clk_div_cnt + 1;
+            send_bits_fsm <= sendbit2;
+            if clk_div_cnt = c_clk_div_max - 1 then
+              mupix_ctrl_i.clk1 <= '0';
+              mupix_ctrl_i.clk2 <= '1';
+              clk_div_cnt       <= 0;
+              if bitcouner_word = 0 or bitcounter = bitstosend then
+                send_bits_fsm <= done;
+              else
+                send_bits_fsm  <= sendbit1;
+                bitcouner_word <= bitcouner_word -1;
+              end if;
+            end if;
+          when done =>                  -- 
+            clk_div_cnt   <= clk_div_cnt + 1;
+            send_bits_fsm <= done;
+            if clk_div_cnt = (c_clk_div_max - 1)/2 then
+              send_bits_fsm <= idle;  -- just hold clk2 high long enough before going back to idle
+            end if;
+        end case;
+      end if;
+    end if;
+  end process sendpix_bits;
+
+
+
+  configure_proc : process(clk) is
+    variable hold_load_counter : integer range 0 to 7;
+  begin
+    if rising_edge(clk) then
+      if reset = '1' then
+        mupix_ctrl_i.load <= '0';
+        config_fsm        <= idle;
+        hold_load_counter := 0;
+      else
+        mupix_ctrl_i.load <= '0';
+        ReadEn            <= '0';
+        start_send        <= '0';
+        reset_bitcounter  <= '0';
+        case config_fsm is
+          when idle =>
+            hold_load_counter := 0;
+            if Empty = '0' then
+              config_fsm <= readfifo;
+            else
+              config_fsm <= idle;
+            end if;
+          when readfifo =>
+            if Empty = '0' then
+              ReadEn     <= '1';
+              start_send <= '1';
+              config_fsm <= waitfifo;
+            else
+              ReadEn     <= '0';
+              config_fsm <= readfifo;   -- wait on next config word in fifo
+            end if;
+          when waitfifo =>              -- wait for fifo word to be valid
+            config_fsm <= config;
+          when config =>
+            if sending = '1' then
+              config_fsm <= config;
+            else
+              if bitcounter < bitstosend then  -- everything send or read other fifo word
+                config_fsm <= readfifo;
+              else
+                config_fsm <= load;
+              end if;
+            end if;
+          when load =>                  -- load from shift register
+            hold_load_counter := hold_load_counter + 1;
+            mupix_ctrl_i.load <= '1';
+            config_fsm        <= load;
+            if hold_load_counter = 7 then
+              mupix_ctrl_i.load <= '0';
+              reset_bitcounter  <= '1';
+              config_fsm        <= idle;
+            end if;
+        end case;
+      end if;
+    end if;
+  end process configure_proc;
+
+
   -----------------------------------------------------------------------------
   --x0080: input to fifo (write)/current fifo output (read)
   --x0081: current CRC check sum (read only)
   --x0082: data fifo is full (read only)
   --x0083: configure 
-  --                            bit 0: sin
+  --                 bit 0: sin
   --                 bit 1: clk1
   --                 bit 2: clk2
-  --                 bit 3: load       
-  --                            bit 4: select FPGA programming or software programming 
+  --                 bit 3: load        
+  --                 bit 4: select FPGA programming or software programming 
   --                 bit 5: reset outgoing CRC sum
   --                 bit 6: reset incoming CRC sum
   --                 bit 31-16: number of total bits for configuration
+  --x0084: reset readback process
+  --x0085: set readback address/data from readback memory
   -----------------------------------------------------------------------------
   SLV_BUS : process(clk)
-       begin                               -- process SLV_BUS
-               if rising_edge(clk) then
-                       SLV_DATA_OUT         <= (others => '0');
-                       SLV_UNKNOWN_ADDR_OUT <= '0';
-                       SLV_NO_MORE_DATA_OUT <= '0';
-                       SLV_ACK_OUT          <= '0';
-
-                       DataIn                   <= (others => '0');
-                       WriteEn                  <= '0';
-                       reset_crc_to_mupix_ext   <= '0';
-                       reset_crc_from_mupix_ext <= '0';
-
-                       if SLV_WRITE_IN = '1' then
-                               case SLV_ADDR_IN is
-                                       when x"0080" =>
-                                               DataIn      <= SLV_DATA_IN;
-                                               WriteEn     <= '1';
-                                               SLV_ACK_OUT <= '1';
-                                       when x"0083" =>
-                                               mupix_ctrl_ext.sin       <= SLV_DATA_IN(0);
-                                               mupix_ctrl_ext.clk1      <= SLV_DATA_IN(1);
-                                               mupix_ctrl_ext.clk2      <= SLV_DATA_IN(2);
-                                               mupix_ctrl_ext.load      <= SLV_DATA_IN(3);
-                                               mupix_ctrcl_select       <= SLV_DATA_IN(4);
-                                               reset_crc_to_mupix_ext   <= SLV_DATA_IN(5);
-                                               reset_crc_from_mupix_ext <= SLV_DATA_IN(6);
-                                               mupix_ctrl_ext.rb        <= SLV_DATA_IN(7);
-                                               bitstosend               <= unsigned(SLV_DATA_IN(31 downto 16));
-                                               SLV_ACK_OUT              <= '1';
-                                       when others =>
-                                               SLV_UNKNOWN_ADDR_OUT <= '1';
-                               end case;
-
-                       elsif SLV_READ_IN = '1' then
-                               case SLV_ADDR_IN is
-                                       when x"0080" =>
-                                               SLV_DATA_OUT <= DataOut;
-                                               SLV_ACK_OUT  <= '1';
-                                       when x"0081" =>
-                                               SLV_DATA_OUT(10 downto 0) <= crc_out_crc_from_mupix & crc_out_crc_to_mupix & crc_correct;
-                                               SLV_ACK_OUT               <= '1';
-                                       when x"0082" =>
-                                               SLV_DATA_OUT(1 downto 0) <= Empty & Full;
-                                               SLV_ACK_OUT              <= '1';
-                                       when x"0083" =>
-                                               SLV_DATA_OUT(0)            <= mupix_ctrl_ext.sin;
-                                               SLV_DATA_OUT(1)            <= mupix_ctrl_ext.clk1;
-                                               SLV_DATA_OUT(2)            <= mupix_ctrl_ext.clk2;
-                                               SLV_DATA_OUT(3)            <= mupix_ctrl_ext.load;
-                                               SLV_DATA_OUT(4)            <= mupix_ctrcl_select;
-                                               SLV_DATA_OUT(5)            <= reset_crc_to_mupix_ext;
-                                               SLV_DATA_OUT(6)            <= reset_crc_from_mupix_ext;
-                                               SLV_DATA_OUT(7)            <= mupix_ctrl_ext.rb;
-                                               SLV_DATA_OUT(31 downto 16) <= std_logic_vector(bitstosend);
-                                               SLV_ACK_OUT                <= '1';
-                                       when others =>
-                                               SLV_UNKNOWN_ADDR_OUT <= '1';
-                               end case;
-                       end if;
-               end if;
-       end process SLV_BUS;
-
-       crc_correct <= '1' when crc_out_crc_from_mupix = crc_out_crc_to_mupix else '0';
-
-       slow_control_mux : process(mupix_ctrcl_select, mupix_ctrl_ext, mupix_ctrl_i) is
-       begin
-               if mupix_ctrcl_select = '1' then
-                       mupix_ctrl_sel <= mupix_ctrl_ext;
-               else
-                       mupix_ctrl_sel <= mupix_ctrl_i;
-               end if;
-       end process slow_control_mux;
-
-       output_pipe : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if reset = '1' then
-                               mupix_ctrl_reg <= c_mupix_slctrl_init;
-                       else
-                               mupix_ctrl_reg <= mupix_ctrl_sel;
-                       end if;
-               end if;
-       end process output_pipe;
-
-       --matching to outputs   
-       mupixslctrl    <= mupix_ctrl_reg;
+  begin  -- process SLV_BUS
+    if rising_edge(clk) then
+      SLV_DATA_OUT         <= (others => '0');
+      SLV_UNKNOWN_ADDR_OUT <= '0';
+      SLV_NO_MORE_DATA_OUT <= '0';
+      SLV_ACK_OUT          <= '0';
+
+      DataIn                   <= (others => '0');
+      WriteEn                  <= '0';
+      reset_crc_to_mupix_ext   <= '0';
+      reset_crc_from_mupix_ext <= '0';
+      reset_readback_i         <= '0';
+      slv_data_out             <= (others => '0');
+      if SLV_WRITE_IN = '1' then
+        case SLV_ADDR_IN is
+          when x"0080" =>
+            DataIn      <= SLV_DATA_IN;
+            WriteEn     <= '1';
+            SLV_ACK_OUT <= '1';
+          when x"0083" =>
+            mupix_ctrl_ext.sin       <= SLV_DATA_IN(0);
+            mupix_ctrl_ext.clk1      <= SLV_DATA_IN(1);
+            mupix_ctrl_ext.clk2      <= SLV_DATA_IN(2);
+            mupix_ctrl_ext.load      <= SLV_DATA_IN(3);
+            mupix_ctrcl_select       <= SLV_DATA_IN(4);
+            reset_crc_to_mupix_ext   <= SLV_DATA_IN(5);
+            reset_crc_from_mupix_ext <= SLV_DATA_IN(6);
+            mupix_ctrl_ext.rb        <= SLV_DATA_IN(7);
+            bitstosend               <= unsigned(SLV_DATA_IN(31 downto 16));
+            SLV_ACK_OUT              <= '1';
+          when x"0084" =>
+            slv_ack_out      <= '1';
+            reset_readback_i <= '1';
+          when x"0085" =>
+            slv_ack_out      <= '1';
+            if to_integer(unsigned(slv_data_in)) < c_config_words_max then
+              readback_rd_addr <= slv_data_in(c_ram_address_width - 1 downto 0);
+            else
+              readback_rd_addr <= (others => '0');
+            end if;
+          when others =>
+            SLV_UNKNOWN_ADDR_OUT <= '1';
+        end case;
+
+      elsif SLV_READ_IN = '1' then
+        case SLV_ADDR_IN is
+          when x"0080" =>
+            SLV_DATA_OUT <= DataOut;
+            SLV_ACK_OUT  <= '1';
+          when x"0081" =>
+            SLV_DATA_OUT(10 downto 0) <= crc_out_crc_from_mupix & crc_out_crc_to_mupix & crc_correct;
+            SLV_ACK_OUT               <= '1';
+          when x"0082" =>
+            SLV_DATA_OUT(1 downto 0) <= Empty & Full;
+            SLV_ACK_OUT              <= '1';
+          when x"0083" =>
+            SLV_DATA_OUT(0)            <= mupix_ctrl_ext.sin;
+            SLV_DATA_OUT(1)            <= mupix_ctrl_ext.clk1;
+            SLV_DATA_OUT(2)            <= mupix_ctrl_ext.clk2;
+            SLV_DATA_OUT(3)            <= mupix_ctrl_ext.load;
+            SLV_DATA_OUT(4)            <= mupix_ctrcl_select;
+            SLV_DATA_OUT(5)            <= reset_crc_to_mupix_ext;
+            SLV_DATA_OUT(6)            <= reset_crc_from_mupix_ext;
+            SLV_DATA_OUT(7)            <= mupix_ctrl_ext.rb;
+            SLV_DATA_OUT(31 downto 16) <= std_logic_vector(bitstosend);
+            SLV_ACK_OUT                <= '1';
+          when x"0085" =>
+            slv_ack_out  <= '1';
+            slv_data_out <= readback_data_out;
+          when others =>
+            SLV_UNKNOWN_ADDR_OUT <= '1';
+        end case;
+      end if;
+    end if;
+  end process SLV_BUS;
+
+  crc_correct <= '1' when crc_out_crc_from_mupix = crc_out_crc_to_mupix else '0';
+
+  slow_control_mux : process(mupix_ctrcl_select, mupix_ctrl_ext, mupix_ctrl_i) is
+  begin
+    if mupix_ctrcl_select = '1' then
+      mupix_ctrl_sel <= mupix_ctrl_ext;
+    else
+      mupix_ctrl_sel <= mupix_ctrl_i;
+    end if;
+  end process slow_control_mux;
+
+  output_pipe : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if reset = '1' then
+        mupix_ctrl_reg <= c_mupix_slctrl_init;
+      else
+        mupix_ctrl_reg <= mupix_ctrl_sel;
+      end if;
+    end if;
+  end process output_pipe;
+
+  --matching to outputs 
+  mupixslctrl <= mupix_ctrl_reg;
 
 end Behavioral;
 
index d97f944e1f921847c1f482db9ba669a238a419cf..825f7dc0841cf9ff9e89c1246ba67162da92a6bf 100644 (file)
@@ -10,121 +10,199 @@ entity PixCtrlTest is
 end entity PixCtrlTest;
 
 architecture simulation of PixCtrlTest is
-       
-       component PixelControl
-               generic(
-                       fpga_clk_speed : integer := 1e8;
-                       spi_clk_speed  : integer := 1e4
-               );
-               port(
-                       clk                  : in  std_logic; --clock
-                       reset                : in  std_logic; --reset
-                       mupixslctrl          : out MupixSlowControl;
-                       ctrl_dout            : in  std_logic; --serial data from mupix
-                       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 component PixelControl;
-       
-       component MupixShiftReg
-               generic(
-                       pixeldac_shift_length : integer := 64
-               );
-               port(
-                       clk1 : in  std_logic;
-                       clk2 : in  std_logic;
-                       sin  : in  std_logic;
-                       sout : out std_logic);
-       end component MupixShiftReg;
-       
-       signal clk : std_logic;
-       signal reset : std_logic := '0';
-       signal sout : std_logic := '0';
-       signal mupix_ctrl : MupixSlowControl;
-       signal SLV_READ_IN : std_logic := '0';
-       signal SLV_WRITE_IN : std_logic := '0';
-       signal SLV_DATA_OUT : std_logic_vector(31 downto 0);
-       signal SLV_DATA_IN : std_logic_vector(31 downto 0) := (others => '0');
-       signal SLV_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0');
-       signal SLV_ACK_OUT : std_logic;
-       signal SLV_NO_MORE_DATA_OUT : std_logic;
-       signal SLV_UNKNOWN_ADDR_OUT : std_logic;
-       
-       constant clk_period : time := 10 ns;
-       constant c_shiftregister_length : integer := 80;
-       constant c_time_per_word : time := 32*clk_period*1e8/1e7;
-       
+
+  component PixelControl
+    generic(
+      fpga_clk_speed : integer := 1e8;
+      spi_clk_speed  : integer := 1e4;
+      config_bits    : integer := 3200
+      );
+    port(
+      clk                  : in  std_logic;  --clock
+      reset                : in  std_logic;  --reset
+      mupixslctrl          : out MupixSlowControl;
+      ctrl_dout            : in  std_logic;  --serial data from mupix
+      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 component PixelControl;
+
+  component MupixShiftReg
+    generic(
+      pixeldac_shift_length : integer := 64
+      );
+    port(
+      clk1 : in  std_logic;
+      clk2 : in  std_logic;
+      sin  : in  std_logic;
+      sout : out std_logic);
+  end component MupixShiftReg;
+
+  signal clk                  : std_logic;
+  signal reset                : std_logic                     := '0';
+  signal sout                 : std_logic                     := '0';
+  signal mupix_ctrl           : MupixSlowControl;
+  signal SLV_READ_IN          : std_logic                     := '0';
+  signal SLV_WRITE_IN         : std_logic                     := '0';
+  signal SLV_DATA_OUT         : std_logic_vector(31 downto 0);
+  signal SLV_DATA_IN          : std_logic_vector(31 downto 0) := (others => '0');
+  signal SLV_ADDR_IN          : std_logic_vector(15 downto 0) := (others => '0');
+  signal SLV_ACK_OUT          : std_logic;
+  signal SLV_NO_MORE_DATA_OUT : std_logic;
+  signal SLV_UNKNOWN_ADDR_OUT : std_logic;
+
+  constant clk_period             : time                                                  := 10 ns;
+  constant c_shiftregister_length : integer                                               := 80;
+  constant c_time_per_word        : time                                                  := 32*clk_period*1e8/1e7;
+  constant c_testdata             : std_logic_vector(c_shiftregister_length - 1 downto 0) := x"AAAAAAAABBBBBBBBCCCC";
+
+  -- send load signal to mupix using external slow control
+  procedure MupixLoad(
+    signal slv_write_in : out std_logic;
+    signal slv_data_in  : out std_logic_vector(31 downto 0);
+    signal slv_addr_in  : out std_logic_vector(15 downto 0);
+    constant clk_period : in  time := 10 ns) is
+  begin
+    TRBRegisterWrite(slv_write_in, slv_data_in, slv_addr_in, x"00000018", x"0083");
+    wait for 5*clk_period;
+    TRBRegisterWrite(slv_write_in, slv_data_in, slv_addr_in, x"00000000", x"0083");
+  end procedure MupixLoad;
+
+  -- reset of crc checksums and readback
+  procedure MupixReset (
+    signal slv_write_in : out std_logic;
+    signal slv_data_in  : out std_logic_vector(31 downto 0);
+    signal slv_addr_in  : out std_logic_vector(15 downto 0);
+    constant clk_period : in  time := 10 ns) is
+  begin
+    TRBRegisterWrite(slv_write_in, slv_data_in, slv_addr_in, x"0000000f", x"0084");
+    TRBRegisterWrite(slv_write_in, slv_data_in, slv_addr_in, x"00000060", x"0083");
+  end procedure MupixReset;
+  
+  -- purpose: write bit to mupix 8
+  procedure WriteMupixSlow (
+    signal slv_write_in : out std_logic;
+    signal slv_data_in  : out std_logic_vector(31 downto 0);
+    signal slv_addr_in  : out std_logic_vector(15 downto 0);
+    constant sin        : in  std_logic;
+    constant clk_period : in  time := 10 ns) is
+  begin  -- procedure WriteMupixSlow
+    slv_write_in            <= '1';
+    slv_addr_in             <= x"0083";
+    slv_data_in(4 downto 0) <= "1000" & sin;
+    wait for clk_period;
+    slv_write_in            <= '0';
+    wait for 100 ns;
+    slv_write_in            <= '1';
+    slv_addr_in             <= x"0083";
+    slv_data_in(4 downto 0) <= "1001" & sin;
+    wait for clk_period;
+    slv_write_in            <= '0';
+    wait for 100 ns;
+    slv_write_in            <= '1';
+    slv_addr_in             <= x"0083";
+    slv_data_in(4 downto 0) <= "1010" & sin;
+    wait for clk_period;
+    slv_write_in            <= '0';
+    wait for 100 ns;
+    slv_write_in            <= '1';
+    slv_addr_in             <= x"0083";
+    slv_data_in(4 downto 0) <= "1000" & "0";
+    wait for clk_period;
+    slv_write_in            <= '0';
+    slv_data_in             <= (others => '0');
+    slv_addr_in             <= (others => '0');
+    wait for clk_period;
+  end procedure WriteMupixSlow;
+
 begin
-       
-       dut : entity work.PixelControl
-               generic map(
-                       fpga_clk_speed => 1e8,
-                       spi_clk_speed  => 1e7
-               )
-               port map(
-                       clk                  => clk,
-                       reset                => reset,
-                       ctrl_dout            => sout,
-                       mupixslctrl          => mupix_ctrl,
-                       SLV_READ_IN          => SLV_READ_IN,
-                       SLV_WRITE_IN         => SLV_WRITE_IN,
-                       SLV_DATA_OUT         => SLV_DATA_OUT,
-                       SLV_DATA_IN          => SLV_DATA_IN,
-                       SLV_ADDR_IN          => SLV_ADDR_IN,
-                       SLV_ACK_OUT          => SLV_ACK_OUT,
-                       SLV_NO_MORE_DATA_OUT => SLV_NO_MORE_DATA_OUT,
-                       SLV_UNKNOWN_ADDR_OUT => SLV_UNKNOWN_ADDR_OUT
-               );
-               
-               mupix : entity work.MupixShiftReg
-                       generic map(
-                               pixeldac_shift_length => c_shiftregister_length
-                       )
-                       port map(
-                               clk1 => mupix_ctrl.clk1,
-                               clk2 => mupix_ctrl.clk2,
-                               sin  => mupix_ctrl.sin,
-                               sout => sout
-                       );
-               
-       clk_gen : process is
-       begin
-               clk <= '1';
-               wait for clk_period/2;
-               clk <= '0';
-               wait for clk_period/2;
-       end process clk_gen;
-       
-       stimulus_gen : process is
-       begin
-               wait for 100 ns;
-               --test control through trb slow control
---             TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000011",x"0083");
---             TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000013",x"0083");
---             TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000014",x"0083");
---             TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000000",x"0083");
-               --test programming with data from FIFO via FPGA state machine
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0000", x"0083");
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA",x"0080");
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB",x"0080");
-               wait for 3*c_time_per_word;
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCC0000",x"0080");
-               --test of crc checksum computation
-               wait for 1.5*c_time_per_word;
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0060", x"0083");
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0000", x"0083");
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA",x"0080");
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB",x"0080");
-               TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCC0000",x"0080");
-               
-               wait;
-       end process stimulus_gen;
-       
-       
+
+  dut : entity work.PixelControl
+    generic map(
+      fpga_clk_speed => 1e8,
+      spi_clk_speed  => 1e7,
+      config_bits    => 80
+      )
+    port map(
+      clk                  => clk,
+      reset                => reset,
+      ctrl_dout            => sout,
+      mupixslctrl          => mupix_ctrl,
+      SLV_READ_IN          => SLV_READ_IN,
+      SLV_WRITE_IN         => SLV_WRITE_IN,
+      SLV_DATA_OUT         => SLV_DATA_OUT,
+      SLV_DATA_IN          => SLV_DATA_IN,
+      SLV_ADDR_IN          => SLV_ADDR_IN,
+      SLV_ACK_OUT          => SLV_ACK_OUT,
+      SLV_NO_MORE_DATA_OUT => SLV_NO_MORE_DATA_OUT,
+      SLV_UNKNOWN_ADDR_OUT => SLV_UNKNOWN_ADDR_OUT
+      );
+
+  mupix : entity work.MupixShiftReg
+    generic map(
+      pixeldac_shift_length => c_shiftregister_length
+      )
+    port map(
+      clk1 => mupix_ctrl.clk1,
+      clk2 => mupix_ctrl.clk2,
+      sin  => mupix_ctrl.sin,
+      sout => sout
+      );
+
+  clk_gen : process is
+  begin
+    clk <= '1';
+    wait for clk_period/2;
+    clk <= '0';
+    wait for clk_period/2;
+  end process clk_gen;
+
+  stimulus_gen : process is
+  begin
+    wait for 100 ns;
+    --test control through trb slow control
+    --first pass 
+    for i in c_shiftregister_length - 1 downto 0 loop
+      WriteMupixSlow(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, c_testdata(i));
+    end loop;
+    MupixLoad(slv_write_in, slv_data_in, slv_addr_in);
+    wait for 100 ns;
+    MupixReset(slv_write_in, slv_data_in, slv_addr_in);
+    wait for 1 us;
+    --second pass to test checksum and readback
+    for i in c_shiftregister_length - 1 downto 0 loop
+      WriteMupixSlow(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, c_testdata(i));
+    end loop;  -- send load and reset the readback
+    MupixLoad(slv_write_in, slv_data_in, slv_addr_in);
+    wait for 100 ns;
+    MupixReset(slv_write_in, slv_data_in, slv_addr_in);
+    wait for 1 us;
+    --read from readback memeory
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000002", x"0085");
+    TRBRegisterRead(SLV_READ_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000000", x"0085");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000005", x"0085");
+    --test programming with data from FIFO via FPGA state machine
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0000", x"0083");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA", x"0080");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB", x"0080");
+    wait for 3*c_time_per_word;
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCC0000", x"0080");
+    --test of crc checksum computation
+    wait for 1.5*c_time_per_word;
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0060", x"0083");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0000", x"0083");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA", x"0080");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB", x"0080");
+    TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCC0000", x"0080");
+
+    wait;
+  end process stimulus_gen;
+
+
 end architecture simulation;