]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Mupix 8 Pixel Control. Works in Simulation.
authorTobias Weber <toweber86@gmail.com>
Fri, 10 Nov 2017 10:38:28 +0000 (11:38 +0100)
committerTobias Weber <toweber86@gmail.com>
Fri, 10 Nov 2017 10:38:28 +0000 (11:38 +0100)
mupix/Mupix8/sources/PixelControl.vhd

index 75b4aac275f7f53bbd383a9e9f8fd0dcab5653e9..c867925d91ea810e2f2caafcd38f79034ffa11c5 100644 (file)
@@ -6,6 +6,8 @@ library IEEE;
 use IEEE.STD_LOGIC_1164.all;
 use IEEE.numeric_std.all;
 
+use work.StdTypes.all;
+
 entity PixelControl is
   generic(
        fpga_clk_speed : integer := 1e8;
@@ -14,12 +16,8 @@ entity PixelControl is
   port (
     clk                  : in  std_logic; --clock
     reset                : in  std_logic; --reset
-    --mupix control
-    ctrl_din             : out std_logic; --serial data to mupix
-    ctrl_clk1            : out std_logic; --slow control clock 1
-    ctrl_clk2            : out std_logic; --slow control clock 2
-    ctrl_load            : out std_logic; --slow control load
-    ctrl_dout            :  in std_logic; --serial data from mupix
+    mupixslctrl          : out MupixSlowControl;
+    ctrl_dout            : in std_logic; --serial data from mupix
     --TRB slow control
     SLV_READ_IN          : in  std_logic;
     SLV_WRITE_IN         : in  std_logic;
@@ -33,12 +31,13 @@ end PixelControl;
 
 architecture Behavioral of PixelControl is
        
-       constant fifo_word_width : integer :=  32;
+       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 fifo_word_width - 1 := 0; --index to current bit in word from fifo
-       signal controlConfig : std_logic_vector(15 downto 0) := (others => '0');--configuration control
+       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
@@ -50,9 +49,9 @@ architecture Behavioral of PixelControl is
                        CLK     : in  std_logic;
                        RST     : in  std_logic;
                        WriteEn : in  std_logic;
-                       DataIn  : in  std_logic_vector(fifo_word_width - 1 downto 0);
+                       DataIn  : in  std_logic_vector(c_fifo_word_width - 1 downto 0);
                        ReadEn  : in  std_logic;
-                       DataOut : out std_logic_vector(fifo_word_width - 1 downto 0);
+                       DataOut : out std_logic_vector(c_fifo_word_width - 1 downto 0);
                        Empty   : out std_logic;
                        Full    : out std_logic
                );
@@ -72,46 +71,44 @@ architecture Behavioral of PixelControl is
        end component CRC;
 
        signal WriteEn : std_logic;
-       signal DataIn : std_logic_vector (fifo_word_width - 1 downto 0);
+       signal DataIn : std_logic_vector (c_fifo_word_width - 1 downto 0);
        signal ReadEn : std_logic;
-       signal DataOut : std_logic_vector (fifo_word_width - 1 downto 0);
+       signal DataOut : std_logic_vector (c_fifo_word_width - 1 downto 0);
        signal Empty : std_logic;
        signal Full : std_logic;
        
-       --clock enable signals
-       signal clk_enable : std_logic := '0';
-       constant clk_div_max : integer := fpga_clk_speed/spi_clk_speed - 1;
-       signal clk_div_counter : integer range 0 to clk_div_max := clk_div_max;
-       
        --send single configuration bit
-       type bit_send_fsm_type is (idle, sendbit1, sendbit2, sendbit3);
-       signal bit_send_fsm : bit_send_fsm_type := idle;
        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 config_fsm_type is (idle, config, readfifo, waitfifo, load);
-       signal config_fsm : config_fsm_type := idle;
+       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 : std_logic;
+       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 : std_logic;
+       signal reset_crc_from_mupix,  reset_crc_from_mupix_ext : std_logic;
        
        --control signals to mupix
-       signal mupix_ctrl_i, mupix_ctrl_reg : MupixSlowControl := MuPixSlowControlInit;
+       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 => fifo_word_width,
+                       DATA_WIDTH => c_fifo_word_width,
                        FIFO_DEPTH => 32
                )
                port map(
@@ -125,7 +122,6 @@ begin  -- Behavioral
                        Full    => Full
                );
        
-       --TODO: CRC checking logic
        crc_in : entity work.CRC
                generic map(detect_enable_edge => true)
                port map(
@@ -136,7 +132,7 @@ begin  -- Behavioral
                        crc_out => crc_out_crc_to_mupix
                );
                
-       reset_crc_to_mupix <= reset or controlConfig(2);        
+       reset_crc_to_mupix <= reset or reset_crc_to_mupix_ext;  
                
        crc_out : entity work.CRC
                generic map(detect_enable_edge => true)
@@ -148,108 +144,94 @@ begin  -- Behavioral
                        crc_out => crc_out_crc_from_mupix
                );
        
-       reset_crc_from_mupix <= reset or controlConfig(3);
-       
-       spi_clk_div_proc : process (clk) is
-       begin
-               if rising_edge(clk) then
-                       if reset = '1' then
-                               clk_enable <= '0';
-                               clk_div_counter <= clk_div_max;
-                       else
-                               if clk_div_counter = 0 then
-                                       clk_div_counter <= clk_div_max;
-                                       clk_enable <= '1';
-                               else    
-                                       clk_div_counter <= clk_div_counter - 1;
-                                       clk_enable <= '0';
-                               end if;
-                       end if;
-               end if;
-       end process spi_clk_div_proc;
+       reset_crc_from_mupix <= reset or reset_crc_from_mupix_ext;
        
        
-       sendpixbit_proc : process (clk) is
+       sendpix_bits : process(clk) is
        begin
                if rising_edge(clk) then
                        if reset = '1' then
-                               mupix_ctrl_i.ck_c <= '0';
-                               mupix_ctrl_i.ck_d <= '0';
-                               mupix_ctrl_i.sin <= '0';
-                               sending <= '0';
-                               bit_send_fsm <= idle;
-                               bitcounter <= (others => '0');
-                               bitcouner_word <= fifo_word_width - 1;
+                               send_bits_fsm     <= idle;
+                               mupix_ctrl_i.clk1 <= '0';
+                               mupix_ctrl_i.clk2 <= '0';
+                               mupix_ctrl_i.sin  <= '0';
+                               sending           <= '0';
                        else
-                               if clk_enable = '1' then
-                                       mupix_ctrl_i.ck_c <= '0';
-                                       mupix_ctrl_i.ck_d <= '0';
-                                       mupix_ctrl_i.sin <= '0';
-                                       enable_crc_to_mupix <= '0';
-                                       enable_crc_from_mupix <= '0';
-                                       data_in_crc_from_mupix <= '0';
-                                       data_in_crc_to_mupix <= '0';
-                                       case bit_send_fsm is 
-                                               when idle =>
-                                                       bitcouner_word <= fifo_word_width - 1;
-                                                       if start_send = '1' then
-                                                               bit_send_fsm <= sendbit1;
-                                                               sending <= '1';
-                                                       else
-                                                               bit_send_fsm <= idle;
-                                                               sending <= '0';
-                                                       end if;
-                                               when sendbit1 =>
-                                                       mupix_ctrl_i.sin <= DataOut(bitcouner_word);
-                                                       sending <= '1';
-                                                       bit_send_fsm <= sendbit2;
-                                               when sendbit2 => --rising clock edge
-                                                       mupix_ctrl_i.sin <= DataOut(bitcouner_word);
-                                                       if controlConfig(0) = '1' then
-                                                               mupix_ctrl_i.ck_d <= '1';
-                                                       else
-                                                               mupix_ctrl_i.ck_c <= '1';
-                                                       end if;
-                                                       enable_crc_to_mupix <= '1';
-                                                       data_in_crc_to_mupix <= DataOut(bitcouner_word);
-                                                       bit_send_fsm <= sendbit3;
-                                                       sending <= '1';
-                                               when sendbit3 =>
-                                                       sending <= '1';
-                                                       mupix_ctrl_i.sin <= DataOut(bitcouner_word);
-                                                       enable_crc_from_mupix <= '1';
-                                                       if controlConfig(0) = '1' then
-                                                               data_in_crc_from_mupix <= sout_d_from_mupix;
-                                                       else
-                                                               data_in_crc_from_mupix <= sout_c_from_mupix;
-                                                       end if;
-                                                       bitcouner_word <= bitcouner_word - 1;
-                                                       bitcounter <= bitcounter + 1;
+                               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
-                                                               bit_send_fsm <= idle;
+                                                               send_bits_fsm          <= done;
                                                        else
-                                                               bit_send_fsm <= sendbit1;
+                                                               send_bits_fsm          <= sendbit1;
+                                                               bitcouner_word         <= bitcouner_word -1;
                                                        end if;
-                                       end case;
-                               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 sendpixbit_proc;
+       end process sendpix_bits;
+       
                
        
-       configure_proc : process (clk) is
+       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.ld_c <= '0';
-                               config_fsm <= idle;
+                               mupix_ctrl_i.load <= '0';
+                               config_fsm        <= idle;
                                hold_load_counter := 0;
                        else
-                               mupix_ctrl_i.ld_c <= '0';
-                               ReadEn <= '0';
-                               start_send <= '0';
-                               case config_fsm is  
+                               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
@@ -259,43 +241,33 @@ begin  -- Behavioral
                                                end if;
                                        when readfifo =>
                                                if Empty = '0' then
-                                                       ReadEn <= '1';
-                                                       config_fsm <= waitfifo;
-                                               else
-                                                       ReadEn <= '0';
-                                                       config_fsm <= readfifo;
-                                               end if;
-                                       when waitfifo =>
-                                               config_fsm <= config;
-                                               if sending = '0' then
+                                                       ReadEn     <= '1';
                                                        start_send <= '1';
                                                        config_fsm <= waitfifo;
                                                else
-                                                       start_send <= '0';
-                                                       config_fsm <= config;
+                                                       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
+                                                       if bitcounter < bitstosend then -- everything send or read other fifo word
                                                                config_fsm <= readfifo;
                                                        else
-                                                               if controlConfig(1) = '0' then
-                                                                       config_fsm <= load;
-                                                               else
-                                                                       config_fsm <= idle;
-                                                               end if;
+                                                               config_fsm <= load;
                                                        end if;
-                                               end if; 
-                                       when load =>
+                                               end if;
+                                       when load =>        -- load from shift register
                                                hold_load_counter := hold_load_counter + 1;
-                                               mupix_ctrl_i.ld_c <= '1';
+                                               mupix_ctrl_i.load <= '1';
+                                               config_fsm        <= load;
                                                if hold_load_counter = 7 then
-                                                       mupix_ctrl_i.ld_c <= '0';
-                                                       config_fsm <= idle;
-                                               else
-                                                       config_fsm <= load;
+                                                       mupix_ctrl_i.load <= '0';
+                                                       reset_bitcounter  <= '1';
+                                                       config_fsm        <= idle;
                                                end if;
                                end case;
                        end if;
@@ -307,71 +279,101 @@ begin  -- Behavioral
   --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: configure chip dacs/pixel dacs, 
-  --                 bit 1: readback bit 32-16 number of config bits 
-  --                 bit 2: reset outgoing CRC sum
-  --                 bit 3: reset incoming CRC sum
+  --x0083: configure 
+  --                            bit 0: sin
+  --                 bit 1: clk1
+  --                 bit 2: clk2
+  --                 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
   -----------------------------------------------------------------------------
-  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'; 
-      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" =>
-               controlConfig <= SLV_DATA_IN(15 downto 0);
-               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 <= std_logic_vector(bitstosend) & controlConfig;
-            SLV_ACK_OUT  <= '1';
-          when others =>
-            SLV_UNKNOWN_ADDR_OUT <= '1';
-        end case;
-      end if;
-    end if;
-  end process SLV_BUS;
+  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';
 
-  crc_correct <= '1' when crc_out_crc_from_mupix = crc_out_crc_to_mupix else '0';
-       
-  output_pipe : process (clk) is
-  begin
-       if rising_edge(clk) then
-               if reset = '1' then
-                       mupix_ctrl_reg <= MuPixSlowControlInit;
-               else
-                       mupix_ctrl_reg <= mupix_ctrl_i;
-               end if;
-       end if;
-  end process output_pipe;
-  
-  --matching to outputs        
-  mupix_ctrl <= mupix_ctrl_reg;
+                       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);
+                                               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(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;
 
 end Behavioral;