apb_lfr_time_management.vhd
174 lines
| 6.6 KiB
| text/x-vhdl
|
VhdlLexer
paul
|
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: | ||||
-- | ||||
---------------------------------------------------------------------------------- | ||||
pellion
|
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; | ||||
USE lpp.apb_devices_list.ALL; | ||||
USE lpp.lpp_lfr_time_management.ALL; | ||||
paul
|
r153 | |||
pellion
|
r165 | ENTITY apb_lfr_time_management IS | ||
paul
|
r153 | |||
pellion
|
r165 | 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 | ||||
otherclk : INTEGER := 49152000; --! other clock in Hz | ||||
finetimeclk : INTEGER := 65536 --! divided clock used for the fine time counter | ||||
); | ||||
paul
|
r153 | |||
pellion
|
r165 | 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 | ||||
); | ||||
paul
|
r153 | |||
pellion
|
r165 | END apb_lfr_time_management; | ||
paul
|
r153 | |||
pellion
|
r165 | ARCHITECTURE Behavioral OF apb_lfr_time_management IS | ||
CONSTANT REVISION : INTEGER := 1; | ||||
paul
|
r153 | |||
--! 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; | ||||
pellion
|
r165 | CONSTANT pconfig : apb_config_type := ( | ||
paul
|
r153 | --! 0 => ahb_device_reg (VENDOR_LPP, LPP_ROTARY, 0, REVISION, 0), | ||
pellion
|
r165 | 0 => ahb_device_reg (19, 14, 0, REVISION, pirq), | ||
1 => apb_iobar(paddr, pmask)); | ||||
paul
|
r153 | |||
pellion
|
r165 | 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; | ||||
paul
|
r153 | |||
pellion
|
r165 | 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; | ||||
paul
|
r153 | |||
pellion
|
r165 | BEGIN | ||
paul
|
r153 | |||
pellion
|
r165 | lfrtimemanagement0 : lfr_time_management | ||
GENERIC MAP(masterclk => masterclk, timeclk => otherclk, finetimeclk => finetimeclk) | ||||
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 => apbo.pirq(pirq), irq2 => apbo.pirq(pirq+1)); | ||||
paul
|
r153 | |||
pellion
|
r165 | PROCESS(resetn, clk25MHz, reset_next_commutation) | ||
BEGIN | ||||
paul
|
r153 | |||
pellion
|
r165 | IF resetn = '0' THEN | ||
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'; | ||||
paul
|
r153 | |||
pellion
|
r165 | ELSIF reset_next_commutation = '1' THEN | ||
r.next_commutation <= x"ffffffff"; | ||||
paul
|
r153 | |||
pellion
|
r165 | ELSIF clk25MHz'EVENT AND clk25MHz = '1' THEN | ||
paul
|
r153 | |||
pellion
|
r165 | 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; | ||||
paul
|
r153 | --APB Write OP | ||
pellion
|
r165 | 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; | ||||
paul
|
r153 | |||
--APB READ OP | ||||
pellion
|
r165 | 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; | ||||
paul
|
r153 | |||
pellion
|
r165 | END IF; | ||
apbo.pconfig <= pconfig; | ||||
END PROCESS; | ||||
paul
|
r153 | |||
pellion
|
r165 | apbo.prdata <= Rdata WHEN apbi.penable = '1'; | ||
coarse_time <= r.coarse_time; | ||||
fine_time <= r.fine_time; | ||||
paul
|
r153 | |||
pellion
|
r165 | END Behavioral; | ||