apb_lfr_time_management.vhd
208 lines
| 7.1 KiB
| text/x-vhdl
|
VhdlLexer
|
r153 | ---------------------------------------------------------------------------------- | ||
-- 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: | ||||
-- | ||||
---------------------------------------------------------------------------------- | ||||
|
r165 | 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; | ||||
|
r176 | 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, 0, 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; | ||||