|
|
----------------------------------------------------------------------------------
|
|
|
-- 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.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
|
|
|
masterclk : INTEGER := 25000000; --! master clock in Hz
|
|
|
timeclk : INTEGER := 49152000; --! other clock in Hz
|
|
|
finetimeclk : INTEGER := 65536 --! divided clock used for the fine time counter
|
|
|
);
|
|
|
|
|
|
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(31 DOWNTO 0) --! fine time
|
|
|
);
|
|
|
|
|
|
END apb_lfr_time_management;
|
|
|
|
|
|
ARCHITECTURE Behavioral OF apb_lfr_time_management IS
|
|
|
|
|
|
CONSTANT REVISION : INTEGER := 1;
|
|
|
|
|
|
--! the following types are defined in the grlib amba package
|
|
|
--! subtype amba_config_word is std_logic_vector(31 downto 0);
|
|
|
--! type apb_config_type is array (0 to NAPBCFG-1) of amba_config_word;
|
|
|
CONSTANT pconfig : apb_config_type := (
|
|
|
--! 0 => ahb_device_reg (VENDOR_LPP, LPP_ROTARY, 0, REVISION, 0),
|
|
|
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(31 DOWNTO 0);
|
|
|
next_commutation : STD_LOGIC_VECTOR(31 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 reset_next_commutation : STD_LOGIC;
|
|
|
|
|
|
SIGNAL irq1 : STD_LOGIC;
|
|
|
SIGNAL irq2 : STD_LOGIC;
|
|
|
|
|
|
BEGIN
|
|
|
|
|
|
lfrtimemanagement0 : lfr_time_management
|
|
|
GENERIC MAP(
|
|
|
masterclk => masterclk,
|
|
|
timeclk => timeclk,
|
|
|
finetimeclk => finetimeclk,
|
|
|
nb_clk_div_ticks => 1)
|
|
|
PORT MAP(
|
|
|
master_clock => clk25MHz,
|
|
|
time_clock => clk49_152MHz,
|
|
|
resetn => resetn,
|
|
|
grspw_tick => grspw_tick,
|
|
|
soft_tick => soft_tick,
|
|
|
coarse_time_load => r.coarse_time_load,
|
|
|
coarse_time => r.coarse_time,
|
|
|
fine_time => r.fine_time,
|
|
|
next_commutation => r.next_commutation,
|
|
|
-- reset_next_commutation => reset_next_commutation,
|
|
|
irq1 => irq1,--apbo.pirq(pirq),
|
|
|
irq2 => irq2);--apbo.pirq(pirq+1));
|
|
|
|
|
|
--apbo.pirq <= (OTHERS => '0');
|
|
|
|
|
|
all_irq_gen: FOR I IN 15 DOWNTO 0 GENERATE
|
|
|
irq1_gen: IF I = pirq GENERATE
|
|
|
apbo.pirq(I) <= irq1;
|
|
|
END GENERATE irq1_gen;
|
|
|
irq2_gen: IF I = pirq+1 GENERATE
|
|
|
apbo.pirq(I) <= 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;
|
|
|
|
|
|
--all_irq_sig: FOR I IN 31 DOWNTO 0 GENERATE
|
|
|
--END GENERATE all_irq_sig;
|
|
|
|
|
|
PROCESS(resetn, clk25MHz)--, reset_next_commutation)
|
|
|
BEGIN
|
|
|
|
|
|
IF resetn = '0' THEN
|
|
|
Rdata <= (OTHERS => '0');
|
|
|
r.coarse_time_load <= x"80000000";
|
|
|
r.ctrl <= x"00000000";
|
|
|
r.next_commutation <= x"ffffffff";
|
|
|
force_tick <= '0';
|
|
|
previous_force_tick <= '0';
|
|
|
soft_tick <= '0';
|
|
|
|
|
|
--ELSIF reset_next_commutation = '1' THEN
|
|
|
-- r.next_commutation <= x"ffffffff";
|
|
|
|
|
|
ELSIF clk25MHz'EVENT AND clk25MHz = '1' THEN
|
|
|
|
|
|
previous_force_tick <= force_tick;
|
|
|
force_tick <= r.ctrl(0);
|
|
|
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);
|
|
|
WHEN "000100" =>
|
|
|
r.next_commutation <= apbi.pwdata(31 DOWNTO 0);
|
|
|
WHEN OTHERS =>
|
|
|
r.coarse_time_load <= x"00000000";
|
|
|
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 24) <= r.ctrl(31 DOWNTO 24);
|
|
|
Rdata(23 DOWNTO 16) <= r.ctrl(23 DOWNTO 16);
|
|
|
Rdata(15 DOWNTO 8) <= r.ctrl(15 DOWNTO 8);
|
|
|
Rdata(7 DOWNTO 0) <= r.ctrl(7 DOWNTO 0);
|
|
|
WHEN "000001" =>
|
|
|
Rdata(31 DOWNTO 24) <= r.coarse_time_load(31 DOWNTO 24);
|
|
|
Rdata(23 DOWNTO 16) <= r.coarse_time_load(23 DOWNTO 16);
|
|
|
Rdata(15 DOWNTO 8) <= r.coarse_time_load(15 DOWNTO 8);
|
|
|
Rdata(7 DOWNTO 0) <= r.coarse_time_load(7 DOWNTO 0);
|
|
|
WHEN "000010" =>
|
|
|
Rdata(31 DOWNTO 24) <= r.coarse_time(31 DOWNTO 24);
|
|
|
Rdata(23 DOWNTO 16) <= r.coarse_time(23 DOWNTO 16);
|
|
|
Rdata(15 DOWNTO 8) <= r.coarse_time(15 DOWNTO 8);
|
|
|
Rdata(7 DOWNTO 0) <= r.coarse_time(7 DOWNTO 0);
|
|
|
WHEN "000011" =>
|
|
|
Rdata(31 DOWNTO 24) <= r.fine_time(31 DOWNTO 24);
|
|
|
Rdata(23 DOWNTO 16) <= r.fine_time(23 DOWNTO 16);
|
|
|
Rdata(15 DOWNTO 8) <= r.fine_time(15 DOWNTO 8);
|
|
|
Rdata(7 DOWNTO 0) <= r.fine_time(7 DOWNTO 0);
|
|
|
WHEN "000100" =>
|
|
|
Rdata(31 DOWNTO 24) <= r.next_commutation(31 DOWNTO 24);
|
|
|
Rdata(23 DOWNTO 16) <= r.next_commutation(23 DOWNTO 16);
|
|
|
Rdata(15 DOWNTO 8) <= r.next_commutation(15 DOWNTO 8);
|
|
|
Rdata(7 DOWNTO 0) <= r.next_commutation(7 DOWNTO 0);
|
|
|
WHEN OTHERS =>
|
|
|
Rdata(31 DOWNTO 0) <= x"00000000";
|
|
|
END CASE;
|
|
|
END IF;
|
|
|
|
|
|
END IF;
|
|
|
END PROCESS;
|
|
|
|
|
|
apbo.prdata <= Rdata ;--WHEN apbi.penable = '1';
|
|
|
coarse_time <= r.coarse_time;
|
|
|
fine_time <= r.fine_time;
|
|
|
apbo.pconfig <= pconfig;
|
|
|
apbo.pindex <= pindex;
|
|
|
|
|
|
END Behavioral;
|
|
|
|