library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity user_logic_pma_controller is generic ( nXcvrs : integer := 1; nChannels : integer := 4 ); port ( reconfig_busy : in std_logic; mgmt_clk_clk : in std_logic := '0'; mgmt_rst_reset : in std_logic := '0'; reconfig_mgmt_address : out std_logic_vector(6 downto 0) := (others => '0'); reconfig_mgmt_read : out std_logic := '0'; reconfig_mgmt_readdata : in std_logic_vector(31 downto 0); reconfig_mgmt_waitrequest : in std_logic; reconfig_mgmt_write : out std_logic := '0'; reconfig_mgmt_writedata : out std_logic_vector(31 downto 0) := (others => '0'); pma_write : in std_logic := '0'; vme_setting : in std_logic_vector(31 downto 0) := (others => '0'); pma_status : out std_logic_vector(31 downto 0) := (others => '0') ); end entity user_logic_pma_controller; architecture behavioral of user_logic_pma_controller is -- flow controls type reconfig_mgmt_fsm_type is (idle,cfg_channel,cfg_offset,cfg_data,cfg_write,cfg_waitforwrite,cfg_read,cfg_waitforread); signal reconfig_mgmt_fsm : reconfig_mgmt_fsm_type := idle; signal waiting : std_logic := '0'; signal xcvr : integer range 0 to nXcvrs; signal channel : integer range 0 to nChannels; -- mapping signals signal last_word : std_logic_vector(31 downto 0) := (others => '0'); signal pma_offset : std_logic_vector(31 downto 0) := (others => '0'); signal pma_data : std_logic_vector(31 downto 0) := (others => '0'); begin pma_offset(7 downto 0) <= vme_setting(15 downto 8); pma_data (7 downto 0) <= vme_setting( 7 downto 0); -- concurrent signal assignments proc_sync : process (mgmt_clk_clk) is begin if (rising_edge(mgmt_clk_clk)) then if (mgmt_rst_reset = '1') then reconfig_mgmt_address <= "0000000"; reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '0'; reconfig_mgmt_writedata <= x"00000000"; reconfig_mgmt_fsm <= idle; xcvr <= xcvr; channel <= 0; pma_status <= X"01234567"; waiting <= '0'; elsif (reconfig_mgmt_waitrequest = '1' or reconfig_busy = '1') then waiting <= '0'; reconfig_mgmt_read <= '0'; else case reconfig_mgmt_fsm is when idle => waiting <= '0'; reconfig_mgmt_address <= "0000000"; reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '0'; reconfig_mgmt_writedata <= (others => '0'); if pma_write = '1' and last_word /= vme_setting then last_word <= vme_setting; reconfig_mgmt_fsm <= cfg_channel; else last_word <= last_word; reconfig_mgmt_fsm <= idle; end if; xcvr <= 0; channel <= 0; when cfg_channel => pma_status <= X"01111110"; waiting <= '0'; reconfig_mgmt_address <= "0001000"; -- 0x08 reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '1'; -- karol had 2*nChannels*xcvr ... why the *2*!? reconfig_mgmt_writedata <= std_logic_vector(to_unsigned(2*nChannels*xcvr+channel, reconfig_mgmt_writedata'length)); xcvr <= xcvr; channel <= channel; reconfig_mgmt_fsm <= cfg_offset; when cfg_offset => pma_status <= X"02222220"; reconfig_mgmt_address <= "0001011"; -- 0x0B reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '1'; reconfig_mgmt_writedata <= pma_offset; xcvr <= xcvr; channel <= channel; reconfig_mgmt_fsm <= cfg_data; when cfg_data => pma_status <= X"03333330"; waiting <= '0'; reconfig_mgmt_address <= "0001100"; -- 0x0C reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '1'; reconfig_mgmt_writedata <= pma_data; xcvr <= xcvr; channel <= channel; reconfig_mgmt_fsm <= cfg_write; when cfg_write => pma_status <= X"04444440"; reconfig_mgmt_address <= "0001010"; -- 0x0A reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '1'; reconfig_mgmt_writedata <= X"00000001"; xcvr <= xcvr; channel <= channel; reconfig_mgmt_fsm <= cfg_waitforwrite; waiting <= '1'; when cfg_waitforwrite => pma_status <= X"05555550"; if waiting = '1' then -- wait here, in limbo. reconfig_mgmt_fsm <= cfg_waitforwrite; elsif channel + 1 = nChannels and xcvr + 1 = nXcvrs then -- done reconfig_mgmt_fsm <= cfg_read; -- to check elsif channel + 1 = nChannels then -- next transceiver reconfig_mgmt_fsm <= cfg_channel; channel <= 0; xcvr <= xcvr + 1; else -- next channel reconfig_mgmt_fsm <= cfg_channel; channel <= channel + 1; end if; when cfg_read => pma_status <= X"06666660"; reconfig_mgmt_fsm <= cfg_waitforread; reconfig_mgmt_address <= "0001010"; -- 0x0A reconfig_mgmt_read <= '0'; reconfig_mgmt_write <= '1'; reconfig_mgmt_writedata <= X"00000002"; xcvr <= xcvr; channel <= channel; reconfig_mgmt_fsm <= cfg_waitforread; waiting <= '1'; when cfg_waitforread => if waiting = '1' then -- wait here, in limbo. pma_status <= X"07777770"; reconfig_mgmt_fsm <= cfg_waitforread; else pma_status <= reconfig_mgmt_readdata; reconfig_mgmt_read <= '1'; reconfig_mgmt_write <= '0'; reconfig_mgmt_fsm <= idle; end if; end case; end if; end if; end process proc_sync; end architecture behavioral;