-- -- ABC130 COM decoder -- Decodes the com stream to find BCRs ECRs etc -- These are used to control internal trigger dependent systems -- -- Matt Warren 2014 -- -- 2014-04-28 - Born from the ashes of trig_decoder library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity com_decoder is port( com_i : in std_logic; -- ABC130 a13_fcfr_o : out std_logic; a13_sysr_o : out std_logic; a13_bcr_o : out std_logic; a13_ecr_o : out std_logic; a13_softr_o : out std_logic; -- Infra strobe40_i : in std_logic; rst : in std_logic; clk : in std_logic ); -- Declarations end com_decoder; architecture rtl of com_decoder is signal sr_com : std_logic_vector(15 downto 0); signal bcnt : integer range 0 to 63; signal bcnt_clr : std_logic; signal a13_fcfr : std_logic; signal a13_sysr : std_logic; signal a13_bcr : std_logic; signal a13_ecr : std_logic; signal a13_softr : std_logic; type states is (WaitShort, WaitLong, Idle); signal state, nstate : states; begin prc_sr : process (clk) begin if rising_edge(clk) then if (rst = '1') then sr_com <= (others => '0'); else if (strobe40_i = '0') then sr_com <= sr_com(14 downto 0) & com_i; end if; end if; end if; end process; -- State Machine ---------------------------------------------------------------- prc_sm_sync : process (clk) begin if rising_edge(clk) then if (rst = '1') then state <= Idle; else --if (strobe40_i = '0') then state <= nstate; end if; end if; end process; -- ABC130 decodes ------------------------------------------ -- COM Short -- 1010 0000 FCF Reset -- 1010 0011 SYS Reset -- 1010 0101 BC Reset -- 1010 0110 L0ID Preset -- 1010 1001 Soft Reset -- 1010 1010 SEU registers Reset -- COM Long -- 1011 1101 + 50b HCC payload -- 1011 1110 + 50b ABC payload prc_sm_async : process (state, sr_com, bcnt) begin -- defaults bcnt_clr <= '0'; case state is when Idle => nstate <= Idle; bcnt_clr <= '1'; -- short/fast commands a13_fcfr <= '0'; a13_sysr <= '0'; a13_bcr <= '0'; a13_ecr <= '0'; a13_softr <= '0'; case (sr_com(7 downto 0)) is -- short when "10100000" => a13_fcfr <= '1'; nstate <= WaitShort; when "10100011" => a13_sysr <= '1'; nstate <= WaitShort; when "10100101" => a13_bcr <= '1'; nstate <= WaitShort; when "10100110" => a13_ecr <= '1'; nstate <= WaitShort; when "10101001" => a13_softr <= '1'; nstate <= WaitShort; -- long when "10111101" => nstate <= WaitLong; when "10111110" => nstate <= WaitLong; when others => null; end case; when WaitShort => nstate <= WaitShort; if (bcnt = 6) then nstate <= Idle; end if; when WaitLong => nstate <= WaitLong; if (bcnt = 56) then nstate <= Idle; end if; end case; end process; prc_bit_counter : process (clk) begin if rising_edge(clk) then if (rst = '1') then bcnt <= 0; elsif (strobe40_i = '0') then if (bcnt_clr = '1') or (bcnt = 63) then bcnt <= 0; else bcnt <= bcnt + 1; end if; end if; end if; end process; prc_clk_out : process(clk) begin if rising_edge(clk) then if (strobe40_i = '0') then -- ABC130 a13_fcfr_o <= a13_fcfr; a13_sysr_o <= a13_sysr; a13_bcr_o <= a13_bcr; a13_ecr_o <= a13_ecr; a13_softr_o <= a13_softr; end if; end if; end process; end rtl;