---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 11:17:05 07/02/2012 -- Design Name: -- Module Name: apb_lfr_time_management - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; LIBRARY grlib; USE grlib.amba.ALL; USE grlib.stdlib.ALL; USE grlib.devices.ALL; LIBRARY lpp; USE lpp.apb_devices_list.ALL; USE lpp.general_purpose.ALL; USE lpp.lpp_lfr_time_management.ALL; ENTITY apb_lfr_time_management IS GENERIC( pindex : INTEGER := 0; --! APB slave index paddr : INTEGER := 0; --! ADDR field of the APB BAR pmask : INTEGER := 16#fff#; --! MASK field of the APB BAR pirq : INTEGER := 0 --! 2 consecutive IRQ lines are used ); PORT ( clk25MHz : IN STD_LOGIC; --! Clock clk49_152MHz : IN STD_LOGIC; --! secondary clock resetn : IN STD_LOGIC; --! Reset grspw_tick : IN STD_LOGIC; --! grspw signal asserted when a valid time-code is received apbi : IN apb_slv_in_type; --! APB slave input signals apbo : OUT apb_slv_out_type; --! APB slave output signals coarse_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); --! coarse time fine_time : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) --! fine time ); END apb_lfr_time_management; ARCHITECTURE Behavioral OF apb_lfr_time_management IS CONSTANT REVISION : INTEGER := 1; CONSTANT pconfig : apb_config_type := ( 0 => ahb_device_reg (VENDOR_LPP, 14, 0, REVISION, pirq), 1 => apb_iobar(paddr, pmask) ); TYPE apb_lfr_time_management_Reg IS RECORD ctrl : STD_LOGIC_VECTOR(31 DOWNTO 0); coarse_time_load : STD_LOGIC_VECTOR(31 DOWNTO 0); coarse_time : STD_LOGIC_VECTOR(31 DOWNTO 0); fine_time : STD_LOGIC_VECTOR(15 DOWNTO 0); END RECORD; SIGNAL r : apb_lfr_time_management_Reg; SIGNAL Rdata : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL force_tick : STD_LOGIC; SIGNAL previous_force_tick : STD_LOGIC; SIGNAL soft_tick : STD_LOGIC; SIGNAL irq1 : STD_LOGIC; SIGNAL irq2 : STD_LOGIC; SIGNAL coarsetime_reg_updated : STD_LOGIC; SIGNAL coarsetime_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL coarse_time_new : STD_LOGIC; SIGNAL coarse_time_new_49 : STD_LOGIC; SIGNAL coarse_time_49 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL coarse_time_s : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL fine_time_new : STD_LOGIC; SIGNAL fine_time_new_temp : STD_LOGIC; SIGNAL fine_time_new_49 : STD_LOGIC; SIGNAL fine_time_49 : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL fine_time_s : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL tick : STD_LOGIC; SIGNAL new_timecode : STD_LOGIC; SIGNAL new_coarsetime : STD_LOGIC; BEGIN ----------------------------------------------------------------------------- -- TODO -- IRQ 1 & 2 ----------------------------------------------------------------------------- irq2 <= '0'; irq1 <= '0'; --all_irq_gen : FOR I IN 15 DOWNTO 0 GENERATE --irq1_gen : IF I = pirq GENERATE apbo.pirq(pirq) <= irq1; --END GENERATE irq1_gen; --irq2_gen : IF I = pirq+1 GENERATE apbo.pirq(pirq+1) <= irq2; -- END GENERATE irq2_gen; -- others_irq : IF (I < pirq) OR (I > (pirq + 1)) GENERATE -- apbo.pirq(I) <= '0'; -- END GENERATE others_irq; --END GENERATE all_irq_gen; PROCESS(resetn, clk25MHz) BEGIN IF resetn = '0' THEN Rdata <= (OTHERS => '0'); r.coarse_time_load <= x"80000000"; r.ctrl <= x"00000000"; force_tick <= '0'; previous_force_tick <= '0'; soft_tick <= '0'; coarsetime_reg_updated <= '0'; ELSIF clk25MHz'EVENT AND clk25MHz = '1' THEN coarsetime_reg_updated <= '0'; force_tick <= r.ctrl(0); previous_force_tick <= force_tick; IF (previous_force_tick = '0') AND (force_tick = '1') THEN soft_tick <= '1'; ELSE soft_tick <= '0'; END IF; --APB Write OP IF (apbi.psel(pindex) AND apbi.penable AND apbi.pwrite) = '1' THEN CASE apbi.paddr(7 DOWNTO 2) IS WHEN "000000" => r.ctrl <= apbi.pwdata(31 DOWNTO 0); WHEN "000001" => r.coarse_time_load <= apbi.pwdata(31 DOWNTO 0); coarsetime_reg_updated <= '1'; WHEN OTHERS => END CASE; ELSIF r.ctrl(0) = '1' THEN r.ctrl(0) <= '0'; END IF; --APB READ OP IF (apbi.psel(pindex) AND (NOT apbi.pwrite)) = '1' THEN CASE apbi.paddr(7 DOWNTO 2) IS WHEN "000000" => Rdata(31 DOWNTO 0) <= r.ctrl(31 DOWNTO 0); WHEN "000001" => Rdata(31 DOWNTO 0) <= r.coarse_time_load(31 DOWNTO 0); WHEN "000010" => Rdata(31 DOWNTO 0) <= r.coarse_time(31 DOWNTO 0); WHEN "000011" => Rdata(31 DOWNTO 16) <= (OTHERS => '0'); Rdata(15 DOWNTO 0) <= r.fine_time(15 DOWNTO 0); WHEN OTHERS => Rdata(31 DOWNTO 0) <= x"00000000"; END CASE; END IF; END IF; END PROCESS; apbo.prdata <= Rdata; apbo.pconfig <= pconfig; apbo.pindex <= pindex; coarse_time <= r.coarse_time; fine_time <= r.fine_time; ----------------------------------------------------------------------------- coarsetime_reg <= r.coarse_time_load; r.coarse_time <= coarse_time_s; r.fine_time <= fine_time_s; ----------------------------------------------------------------------------- -- IN coarsetime_reg_updated -- IN coarsetime_reg -- OUT coarse_time_s -- ok -- OUT fine_time_s -- ok ----------------------------------------------------------------------------- tick <= grspw_tick OR soft_tick; SYNC_VALID_BIT_1 : SYNC_VALID_BIT GENERIC MAP ( NB_FF_OF_SYNC => 2) PORT MAP ( clk_in => clk25MHz, clk_out => clk49_152MHz, rstn => resetn, sin => tick, sout => new_timecode); SYNC_VALID_BIT_2 : SYNC_VALID_BIT GENERIC MAP ( NB_FF_OF_SYNC => 2) PORT MAP ( clk_in => clk25MHz, clk_out => clk49_152MHz, rstn => resetn, sin => coarsetime_reg_updated, sout => new_coarsetime); --SYNC_VALID_BIT_3 : SYNC_VALID_BIT -- GENERIC MAP ( -- NB_FF_OF_SYNC => 2) -- PORT MAP ( -- clk_in => clk49_152MHz, -- clk_out => clk25MHz, -- rstn => resetn, -- sin => 9, -- sout => ); SYNC_FF_1: SYNC_FF GENERIC MAP ( NB_FF_OF_SYNC => 2) PORT MAP ( clk => clk25MHz, rstn => resetn, A => fine_time_new_49, A_sync => fine_time_new_temp); lpp_front_detection_1: lpp_front_detection PORT MAP ( clk => clk25MHz, rstn => resetn, sin => fine_time_new_temp, sout => fine_time_new); SYNC_VALID_BIT_4 : SYNC_VALID_BIT GENERIC MAP ( NB_FF_OF_SYNC => 2) PORT MAP ( clk_in => clk49_152MHz, clk_out => clk25MHz, rstn => resetn, sin => coarse_time_new_49, sout => coarse_time_new); PROCESS (clk25MHz, resetn) BEGIN -- PROCESS IF resetn = '0' THEN -- asynchronous reset (active low) fine_time_s <= (OTHERS => '0'); coarse_time_s <= (OTHERS => '0'); ELSIF clk25MHz'EVENT AND clk25MHz = '1' THEN -- rising clock edge IF fine_time_new = '1' THEN fine_time_s <= fine_time_49; END IF; IF coarse_time_new = '1' THEN coarse_time_s <= coarse_time_49; END IF; END IF; END PROCESS; ----------------------------------------------------------------------------- -- LFR_TIME_MANAGMENT ----------------------------------------------------------------------------- lfr_time_management_1 : lfr_time_management GENERIC MAP ( nb_time_code_missing_limit => 60) PORT MAP ( clk => clk49_152MHz, rstn => resetn, new_timecode => new_timecode, new_coarsetime => new_coarsetime, coarsetime_reg => coarsetime_reg, fine_time => fine_time_49, fine_time_new => fine_time_new_49, coarse_time => coarse_time_49, coarse_time_new => coarse_time_new_49); END Behavioral;