apb_lfr_time_management.vhd
286 lines
| 8.4 KiB
| text/x-vhdl
|
VhdlLexer
pellion
|
r186 | ---------------------------------------------------------------------------------- | ||
-- 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; | ||||
pellion
|
r176 | USE lpp.apb_devices_list.ALL; | ||
pellion
|
r227 | USE lpp.general_purpose.ALL; | ||
pellion
|
r176 | USE lpp.lpp_lfr_time_management.ALL; | ||
ENTITY apb_lfr_time_management IS | ||||
GENERIC( | ||||
pellion
|
r227 | 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 | ||||
pellion
|
r176 | ); | ||
PORT ( | ||||
pellion
|
r227 | 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 | ||||
pellion
|
r176 | ); | ||
END apb_lfr_time_management; | ||||
ARCHITECTURE Behavioral OF apb_lfr_time_management IS | ||||
CONSTANT REVISION : INTEGER := 1; | ||||
CONSTANT pconfig : apb_config_type := ( | ||||
pellion
|
r186 | 0 => ahb_device_reg (VENDOR_LPP, 14, 0, REVISION, pirq), | ||
pellion
|
r227 | 1 => apb_iobar(paddr, pmask) | ||
); | ||||
pellion
|
r176 | |||
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); | ||||
pellion
|
r227 | fine_time : STD_LOGIC_VECTOR(15 DOWNTO 0); | ||
pellion
|
r176 | END RECORD; | ||
pellion
|
r227 | 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; | ||||
pellion
|
r176 | SIGNAL irq1 : STD_LOGIC; | ||
SIGNAL irq2 : STD_LOGIC; | ||||
pellion
|
r227 | SIGNAL coarsetime_reg_updated : STD_LOGIC; | ||
SIGNAL coarsetime_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); | ||||
pellion
|
r176 | |||
pellion
|
r227 | 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'; | ||||
pellion
|
r176 | |||
pellion
|
r227 | |||
--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; | ||||
pellion
|
r176 | |||
pellion
|
r227 | PROCESS(resetn, clk25MHz) | ||
pellion
|
r176 | BEGIN | ||
IF resetn = '0' THEN | ||||
pellion
|
r227 | Rdata <= (OTHERS => '0'); | ||
pellion
|
r176 | r.coarse_time_load <= x"80000000"; | ||
r.ctrl <= x"00000000"; | ||||
force_tick <= '0'; | ||||
previous_force_tick <= '0'; | ||||
soft_tick <= '0'; | ||||
pellion
|
r227 | coarsetime_reg_updated <= '0'; | ||
pellion
|
r176 | |||
ELSIF clk25MHz'EVENT AND clk25MHz = '1' THEN | ||||
pellion
|
r227 | coarsetime_reg_updated <= '0'; | ||
pellion
|
r176 | |||
pellion
|
r227 | force_tick <= r.ctrl(0); | ||
pellion
|
r176 | 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); | ||||
pellion
|
r227 | coarsetime_reg_updated <= '1'; | ||
pellion
|
r176 | 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" => | ||||
pellion
|
r227 | Rdata(31 DOWNTO 0) <= r.ctrl(31 DOWNTO 0); | ||
pellion
|
r176 | WHEN "000001" => | ||
pellion
|
r227 | Rdata(31 DOWNTO 0) <= r.coarse_time_load(31 DOWNTO 0); | ||
pellion
|
r176 | WHEN "000010" => | ||
pellion
|
r227 | Rdata(31 DOWNTO 0) <= r.coarse_time(31 DOWNTO 0); | ||
pellion
|
r176 | WHEN "000011" => | ||
pellion
|
r227 | Rdata(31 DOWNTO 16) <= (OTHERS => '0'); | ||
Rdata(15 DOWNTO 0) <= r.fine_time(15 DOWNTO 0); | ||||
pellion
|
r176 | WHEN OTHERS => | ||
Rdata(31 DOWNTO 0) <= x"00000000"; | ||||
END CASE; | ||||
END IF; | ||||
END IF; | ||||
END PROCESS; | ||||
pellion
|
r227 | apbo.prdata <= Rdata; | ||
apbo.pconfig <= pconfig; | ||||
apbo.pindex <= pindex; | ||||
pellion
|
r176 | coarse_time <= r.coarse_time; | ||
fine_time <= r.fine_time; | ||||
pellion
|
r227 | ----------------------------------------------------------------------------- | ||
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); | ||||
pellion
|
r176 | |||
pellion
|
r190 | END Behavioral; | ||