|
|
----------------------------------------------------------------------------------
|
|
|
-- 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
|
|
|
FIRST_DIVISION : INTEGER := 374;
|
|
|
NB_SECOND_DESYNC : INTEGER := 60
|
|
|
);
|
|
|
|
|
|
PORT (
|
|
|
clk25MHz : IN STD_LOGIC; --! Clock
|
|
|
clk24_576MHz : 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, 0),
|
|
|
1 => apb_iobar(paddr, pmask)
|
|
|
);
|
|
|
|
|
|
TYPE apb_lfr_time_management_Reg IS RECORD
|
|
|
ctrl : STD_LOGIC;
|
|
|
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 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;
|
|
|
|
|
|
SIGNAL time_new_49 : STD_LOGIC;
|
|
|
SIGNAL time_new : STD_LOGIC;
|
|
|
|
|
|
BEGIN
|
|
|
|
|
|
PROCESS(resetn, clk25MHz)
|
|
|
BEGIN
|
|
|
|
|
|
IF resetn = '0' THEN
|
|
|
Rdata <= (OTHERS => '0');
|
|
|
r.coarse_time_load <= x"80000000";
|
|
|
r.ctrl <= '0';
|
|
|
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;
|
|
|
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(0);
|
|
|
WHEN "000001" =>
|
|
|
r.coarse_time_load <= apbi.pwdata(31 DOWNTO 0);
|
|
|
coarsetime_reg_updated <= '1';
|
|
|
WHEN OTHERS =>
|
|
|
NULL;
|
|
|
END CASE;
|
|
|
ELSIF r.ctrl = '1' THEN
|
|
|
r.ctrl <= '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(0) <= r.ctrl;
|
|
|
Rdata(31 DOWNTO 1) <= (others => '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) <= (others => '0');
|
|
|
END CASE;
|
|
|
END IF;
|
|
|
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
apbo.prdata <= Rdata;
|
|
|
apbo.pconfig <= pconfig;
|
|
|
apbo.pindex <= pindex;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- IN
|
|
|
coarse_time <= r.coarse_time;
|
|
|
fine_time <= r.fine_time;
|
|
|
coarsetime_reg <= r.coarse_time_load;
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- OUT
|
|
|
r.coarse_time <= coarse_time_s;
|
|
|
r.fine_time <= fine_time_s;
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
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 => clk24_576MHz,
|
|
|
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 => clk24_576MHz,
|
|
|
rstn => resetn,
|
|
|
sin => coarsetime_reg_updated,
|
|
|
sout => new_coarsetime);
|
|
|
----------------------------------------------------------------------------
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
--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 => clk24_576MHz,
|
|
|
-- clk_out => clk25MHz,
|
|
|
-- rstn => resetn,
|
|
|
-- sin => coarse_time_new_49,
|
|
|
-- sout => coarse_time_new);
|
|
|
|
|
|
time_new_49 <= coarse_time_new_49 OR fine_time_new_49;
|
|
|
|
|
|
SYNC_VALID_BIT_4 : SYNC_VALID_BIT
|
|
|
GENERIC MAP (
|
|
|
NB_FF_OF_SYNC => 2)
|
|
|
PORT MAP (
|
|
|
clk_in => clk24_576MHz,
|
|
|
clk_out => clk25MHz,
|
|
|
rstn => resetn,
|
|
|
sin => time_new_49,
|
|
|
sout => 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 time_new = '1' THEN
|
|
|
fine_time_s <= fine_time_49;
|
|
|
coarse_time_s <= coarse_time_49;
|
|
|
END IF;
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- LFR_TIME_MANAGMENT
|
|
|
-----------------------------------------------------------------------------
|
|
|
lfr_time_management_1 : lfr_time_management
|
|
|
GENERIC MAP (
|
|
|
FIRST_DIVISION => FIRST_DIVISION,
|
|
|
NB_SECOND_DESYNC => NB_SECOND_DESYNC)
|
|
|
PORT MAP (
|
|
|
clk => clk24_576MHz,
|
|
|
rstn => resetn,
|
|
|
|
|
|
tick => new_timecode,
|
|
|
new_coarsetime => new_coarsetime,
|
|
|
coarsetime_reg => coarsetime_reg(31 DOWNTO 0),
|
|
|
|
|
|
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;
|
|
|
|