diff --git a/designs/Validation_LFR_TIME_MANAGEMENT/Makefile b/designs/Validation_LFR_TIME_MANAGEMENT/Makefile new file mode 100644 --- /dev/null +++ b/designs/Validation_LFR_TIME_MANAGEMENT/Makefile @@ -0,0 +1,151 @@ +VHDLIB=../.. +SCRIPTSDIR=$(VHDLIB)/scripts/ + +GRLIB := $(shell sh $(VHDLIB)/scripts/lpp_relpath.sh) +TOP=TB + +##VHDLSYNFILES= TB.vhd + +##LIBSKIP = core1553bbc core1553brm core1553brt gr1553 corePCIF \ +## tmtc openchip hynix ihp gleichmann micron usbhc + +##DIRSKIP = b1553 pcif leon2 leon2ft crypto satcan ddr usb ata i2c \ +## pci grusbhc haps slink ascs pwm coremp7 spi ac97 \ +## ./amba_lcd_16x2_ctrlr \ +## ./general_purpose/lpp_AMR \ +## ./general_purpose/lpp_balise \ +## ./general_purpose/lpp_delay \ +## ./dsp/lpp_fft \ +## ./lpp_bootloader \ +## ./lpp_cna \ +## ./lpp_demux \ +## ./lpp_matrix \ +## ./lpp_uart \ +## ./lpp_usb \ +## ./lpp_Header \ + +##FILESKIP =lpp_lfr_ms.vhd \x +## i2cmst.vhd \ +## APB_MULTI_DIODE.vhd \ +## APB_SIMPLE_DIODE.vhd \ +## Top_MatrixSpec.vhd \ +## APB_FFT.vhd + +##include $(GRLIB)/bin/Makefile +##include $(GRLIB)/software/leon3/Makefile + +CMD_VLIB=vlib +CMD_VMAP=vmap +CMD_VCOM=@vcom -quiet -93 -work + +################## project specific targets ########################## + +all: + @echo "make vsim" + @echo "make libs" + @echo "make clean" + @echo "make vcom_grlib vcom_lpp vcom_tb" + +run: + @vsim work.TB -do run.do + +vsim: libs vcom run + +libs: + @$(CMD_VLIB) modelsim + @$(CMD_VMAP) modelsim modelsim + @$(CMD_VLIB) modelsim/grlib + @$(CMD_VMAP) grlib modelsim/grlib + @$(CMD_VLIB) modelsim/work + @$(CMD_VMAP) work modelsim/work + @$(CMD_VLIB) modelsim/lpp + @$(CMD_VMAP) lpp modelsim/lpp + @echo "libs done" + + +clean: + @rm -Rf modelsim + @rm -Rf modelsim.ini + @rm -Rf *~ + @rm -Rf transcript + @rm -Rf wlft* + @rm -Rf *.wlf + @rm -Rf vish_stacktrace.vstf + @rm -Rf libs.do + +vcom: vcom_grlib vcom_lpp vcom_tb + +vcom_tb: + $(CMD_VCOM) work TB.vhd + @echo "vcom work done" + +vcom_grlib: + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/stdlib/version.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/stdlib/config_types.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/stdlib/config.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/stdlib/stdlib.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/stdlib/stdio.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/stdlib/testlib.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/ftlib/mtie_ftlib.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/util/util.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/sparc/sparc.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/sparc/sparc_disas.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/sparc/cpu_disas.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/modgen/multlib.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/modgen/leaves.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/amba.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/devices.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/defmst.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/apbctrl.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/ahbctrl.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/dma2ahb_pkg.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/dma2ahb.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/ahbmst.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/ahbmon.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/apbmon.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/ambamon.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/dma2ahb_tp.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/amba/amba_tp.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_pkg.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_ahb_mst_pkg.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_ahb_slv_pkg.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_util.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_ahb_mst.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_ahb_slv.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_ahbs.vhd + $(CMD_VCOM) grlib $(GRLIB)/lib/grlib/atf/at_ahb_ctrl.vhd + @echo "vcom grlib done" + +vcom_lpp: + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/lpp_amba/apb_devices_list.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/general_purpose.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/ADDRcntr.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/ALU.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/Adder.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/Clk_Divider2.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/Clk_divider.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MAC.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MAC_CONTROLER.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MAC_MUX.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MAC_MUX2.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MAC_REG.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MUX2.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/MUXN.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/Multiplier.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/REG.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/SYNC_FF.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/Shifter.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/TwoComplementer.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/Clock_Divider.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/lpp_front_to_level.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/lpp_front_detection.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/lpp_front_positive_detection.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/SYNC_VALID_BIT.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/RR_Arbiter_4.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/general_purpose/counter.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/lfr_time_management/lpp_lfr_time_management.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/lfr_time_management/apb_lfr_time_management.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/lfr_time_management/lfr_time_management.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/lfr_time_management/fine_time_counter.vhd + $(CMD_VCOM) lpp $(VHDLIB)/lib/lpp/lfr_time_management/coarse_time_counter.vhd + @echo "vcom lpp done" diff --git a/designs/Validation_LFR_TIME_MANAGEMENT/TB.vhd b/designs/Validation_LFR_TIME_MANAGEMENT/TB.vhd new file mode 100644 --- /dev/null +++ b/designs/Validation_LFR_TIME_MANAGEMENT/TB.vhd @@ -0,0 +1,254 @@ +------------------------------------------------------------------------------ +-- This file is a part of the LPP VHDL IP LIBRARY +-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Author : Jean-christophe Pellion +-- Mail : jean-christophe.pellion@lpp.polytechnique.fr +------------------------------------------------------------------------------- + +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.lpp_lfr_time_management.ALL; + +ENTITY TB IS + + PORT ( + SIM_OK : OUT STD_LOGIC + ); + +END TB; + + +ARCHITECTURE beh OF TB IS + + SIGNAL clk25MHz : STD_LOGIC := '0'; + SIGNAL clk24_576MHz : STD_LOGIC := '0'; + SIGNAL resetn : STD_LOGIC; + SIGNAL grspw_tick : STD_LOGIC; + SIGNAL apbi : apb_slv_in_type; + SIGNAL apbo : apb_slv_out_type; + SIGNAL coarse_time : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL fine_time : STD_LOGIC_VECTOR(15 DOWNTO 0); + + SIGNAL TB_string : STRING(1 TO 8):= "12345678"; + + SIGNAL coarse_time_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL fine_time_reg : STD_LOGIC_VECTOR(15 DOWNTO 0); + SIGNAL global_time : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL global_time_reg : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL tick_ongoing : STD_LOGIC; + + SIGNAL ASSERTION_1 : STD_LOGIC; + SIGNAL ASSERTION_2 : STD_LOGIC; + SIGNAL ASSERTION_3 : STD_LOGIC; + +BEGIN -- beh + + apb_lfr_time_management_1: apb_lfr_time_management + GENERIC MAP ( + pindex => 0, + paddr => 0, + pmask => 16#fff#, + FIRST_DIVISION => 20, + NB_SECOND_DESYNC => 4) + PORT MAP ( + clk25MHz => clk25MHz, + clk24_576MHz => clk24_576MHz, + resetn => resetn, + grspw_tick => grspw_tick, + apbi => apbi, + apbo => apbo, + coarse_time => coarse_time, + fine_time => fine_time); + + clk25MHz <= NOT clk25MHz AFTER 20000 ps; + clk24_576MHz <= NOT clk24_576MHz AFTER 20345 ps; + + + + + PROCESS + BEGIN -- PROCESS + WAIT UNTIL clk25MHz = '1'; + TB_string <= "RESET "; + + resetn <= '0'; + + apbi.psel(0) <= '0'; + apbi.pwrite <= '0'; + apbi.penable <= '0'; + apbi.paddr <= (OTHERS => '0'); + apbi.pwdata <= (OTHERS => '0'); + grspw_tick <= '0'; + WAIT UNTIL clk25MHz = '1'; + WAIT UNTIL clk25MHz = '1'; + resetn <= '1'; + WAIT FOR 60 ms; + --------------------------------------------------------------------------- + -- DESYNC TO SYNC + --------------------------------------------------------------------------- + WAIT UNTIL clk25MHz = '1'; + TB_string <= "TICK 1 "; + grspw_tick <= '1';------------------------------------------------------1 + WAIT UNTIL clk25MHz = '1'; + grspw_tick <= '0'; + WAIT FOR 53333 us; + WAIT UNTIL clk25MHz = '1'; + TB_string <= "TICK 2 "; + grspw_tick <= '1';------------------------------------------------------2 + WAIT UNTIL clk25MHz = '1'; + grspw_tick <= '0'; + WAIT FOR 56000 us; + WAIT UNTIL clk25MHz = '1'; + TB_string <= "TICK 3 "; + grspw_tick <= '1';------------------------------------------------------3 + WAIT UNTIL clk25MHz = '1'; + grspw_tick <= '0'; + WAIT FOR 200 ms; + WAIT UNTIL clk25MHz = '1'; + TB_string <= "CT new "; + -- WRITE NEW COARSE_TIME + apbi.psel(0) <= '1'; + apbi.pwrite <= '1'; + apbi.penable <= '1'; + apbi.paddr <= X"00000004"; + apbi.pwdata <= X"00001234"; + WAIT UNTIL clk25MHz = '1'; + apbi.psel(0) <= '0'; + apbi.pwrite <= '0'; + apbi.penable <= '0'; + apbi.paddr <= (OTHERS => '0'); + apbi.pwdata <= (OTHERS => '0'); + WAIT UNTIL clk25MHz = '1'; + + WAIT FOR 10 ms; + WAIT UNTIL clk25MHz = '1'; + TB_string <= "TICK 4 "; + grspw_tick <= '1';------------------------------------------------------3 + WAIT UNTIL clk25MHz = '1'; + grspw_tick <= '0'; + + + + + WAIT FOR 750 ms; + + REPORT "*** END simulation ***" SEVERITY failure; + WAIT; + + END PROCESS; + + + global_time <= coarse_time & fine_time; + + PROCESS (clk25MHz, resetn) + BEGIN -- PROCESS + IF resetn = '0' THEN -- asynchronous reset (active low) + coarse_time_reg <= (OTHERS => '0'); + fine_time_reg <= (OTHERS => '0'); + global_time_reg <= (OTHERS => '0'); + tick_ongoing <= '0'; + ELSIF clk25MHz'event AND clk25MHz = '1' THEN -- rising clock edge + global_time_reg <= global_time; + coarse_time_reg <= coarse_time; + fine_time_reg <= fine_time; + IF grspw_tick ='1' THEN + tick_ongoing <= '1'; + ELSIF tick_ongoing = '1' THEN + IF (fine_time_reg /= fine_time) OR (coarse_time_reg /= coarse_time) THEN + tick_ongoing <= '0'; + END IF; + END IF; + + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- ASSERTION 1 : + -- Coarse_time "changed" => FINE_TIME = 0 + -- False after a TRANSITION ! + ----------------------------------------------------------------------------- + PROCESS (clk25MHz, resetn) + BEGIN -- PROCESS + IF resetn = '0' THEN -- asynchronous reset (active low) + ASSERTION_1 <= '1'; + ELSIF clk25MHz'event AND clk25MHz = '1' THEN -- rising clock edge + IF coarse_time /= coarse_time_reg THEN + IF fine_time /= X"0000" THEN + IF fine_time /= X"0041" THEN + ASSERTION_1 <= '0'; + ELSE + ASSERTION_1 <= 'U'; + END IF; + ELSE + ASSERTION_1 <= '1'; + END IF; + END IF; + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- ASSERTION 2 : + -- tick => next(FINE_TIME) = 0 + ----------------------------------------------------------------------------- + PROCESS (clk25MHz, resetn) + BEGIN -- PROCESS + IF resetn = '0' THEN -- asynchronous reset (active low) + ASSERTION_2 <= '1'; + ELSIF clk25MHz'event AND clk25MHz = '1' THEN -- rising clock edge + IF tick_ongoing = '1' THEN + IF fine_time_reg /= fine_time OR coarse_time_reg /= coarse_time THEN + IF fine_time /= X"0000" THEN + ASSERTION_2 <= '0'; + END IF; + END IF; + END IF; + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- ASSERTION 3 : + -- next(TIME) > TIME + -- false if resynchro, or new coarse_time + ----------------------------------------------------------------------------- + PROCESS (clk25MHz, resetn) + BEGIN -- PROCESS + IF resetn = '0' THEN -- asynchronous reset (active low) + ASSERTION_3 <= '1'; + ELSIF clk25MHz'event AND clk25MHz = '1' THEN -- rising clock edge + ASSERTION_3 <= '1'; + IF global_time_reg(46 DOWNTO 0) > global_time(46 DOWNTO 0) THEN + IF global_time(47) = '0' AND global_time_reg(47) = '1' THEN + ASSERTION_3 <= 'U'; -- RESYNCHRO .... + ELSE + ASSERTION_3 <= '0'; + END IF; + END IF; + END IF; + END PROCESS; + + +END beh; + diff --git a/designs/Validation_LFR_TIME_MANAGEMENT/run.do b/designs/Validation_LFR_TIME_MANAGEMENT/run.do new file mode 100644 --- /dev/null +++ b/designs/Validation_LFR_TIME_MANAGEMENT/run.do @@ -0,0 +1,3 @@ +log -R * +do wave.do +run -all \ No newline at end of file diff --git a/designs/Validation_LFR_TIME_MANAGEMENT/wave.do b/designs/Validation_LFR_TIME_MANAGEMENT/wave.do new file mode 100644 --- /dev/null +++ b/designs/Validation_LFR_TIME_MANAGEMENT/wave.do @@ -0,0 +1,31 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate /tb/tb_string +add wave -noupdate /tb/assertion_1 +add wave -noupdate /tb/assertion_2 +add wave -noupdate /tb/assertion_3 +add wave -noupdate /tb/apb_lfr_time_management_1/lfr_time_management_1/state +add wave -noupdate -format Analog-Step -height 74 -max 66000.0 -radix hexadecimal /tb/apb_lfr_time_management_1/lfr_time_management_1/fine_time +add wave -noupdate /tb/apb_lfr_time_management_1/lfr_time_management_1/coarse_time_new +add wave -noupdate -radix hexadecimal /tb/apb_lfr_time_management_1/lfr_time_management_1/coarse_time +add wave -noupdate /tb/apb_lfr_time_management_1/grspw_tick +add wave -noupdate -group OUTPUT /tb/apb_lfr_time_management_1/fine_time +add wave -noupdate -group OUTPUT /tb/apb_lfr_time_management_1/coarse_time +add wave -noupdate /tb/apb_lfr_time_management_1/lfr_time_management_1/fine_time_new +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{FT 1} {15279095 ps} 1} {{FT 1 + 1s} {1000012719095 ps} 1} {{Cursor 3} {369333380000 ps} 0} {TRANSITION {169333245705 ps} 1} +configure wave -namecolwidth 512 +configure wave -valuecolwidth 139 +configure wave -justifyvalue left +configure wave -signalnamewidth 0 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits ps +update +WaveRestoreZoom {0 ps} {243152392641 ps} diff --git a/lib/lpp/general_purpose/counter.vhd b/lib/lpp/general_purpose/counter.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/general_purpose/counter.vhd @@ -0,0 +1,54 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.std_logic_arith.ALL; +USE IEEE.std_logic_unsigned.ALL; + +ENTITY counter IS + + GENERIC ( + CYCLIC : STD_LOGIC := '1'; + NB_BITS_COUNTER : INTEGER := 9 + ); + + PORT ( + clk : IN STD_LOGIC; + rstn : IN STD_LOGIC; + -- + RST_VALUE : IN STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0) := (OTHERS => '0'); + MAX_VALUE : IN STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0) := (OTHERS => '1'); + -- + set : IN STD_LOGIC; + set_value : IN STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0); + add1 : IN STD_LOGIC; + counter : OUT STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0) + ); + +END counter; + +ARCHITECTURE beh OF counter IS + SIGNAL counter_s : STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0); + +BEGIN -- beh + + PROCESS (clk, rstn) + BEGIN -- PROCESS + IF rstn = '0' THEN -- asynchronous reset (active low) + counter_s <= RST_VALUE; + ELSIF clk'event AND clk = '1' THEN -- rising clock edge + IF set = '1' THEN + counter_s <= set_value; + ELSIF add1 = '1' THEN + IF counter_s < MAX_VALUE THEN + counter_s <= counter_s + 1; + ELSE + IF CYCLIC = '1' THEN + counter_s <= (OTHERS => '0'); + END IF; + END IF; + END IF; + END IF; + END PROCESS; + + counter <= counter_s; + +END beh; diff --git a/lib/lpp/general_purpose/general_purpose.vhd b/lib/lpp/general_purpose/general_purpose.vhd --- a/lib/lpp/general_purpose/general_purpose.vhd +++ b/lib/lpp/general_purpose/general_purpose.vhd @@ -27,12 +27,26 @@ LIBRARY ieee; USE ieee.std_logic_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; PACKAGE general_purpose IS - + COMPONENT counter + GENERIC ( + CYCLIC : STD_LOGIC; + NB_BITS_COUNTER : INTEGER); + PORT ( + clk : IN STD_LOGIC; + rstn : IN STD_LOGIC; + RST_VALUE : IN STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0); + MAX_VALUE : IN STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0); + set : IN STD_LOGIC; + set_value : IN STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0); + add1 : IN STD_LOGIC; + counter : OUT STD_LOGIC_VECTOR(NB_BITS_COUNTER-1 DOWNTO 0)); + END COMPONENT; COMPONENT Clk_divider IS GENERIC(OSC_freqHz : INTEGER := 50000000; diff --git a/lib/lpp/general_purpose/vhdlsyn.txt b/lib/lpp/general_purpose/vhdlsyn.txt --- a/lib/lpp/general_purpose/vhdlsyn.txt +++ b/lib/lpp/general_purpose/vhdlsyn.txt @@ -22,3 +22,4 @@ lpp_front_detection.vhd lpp_front_positive_detection.vhd SYNC_VALID_BIT.vhd RR_Arbiter_4.vhd +counter.vhd diff --git a/lib/lpp/lfr_time_management/apb_lfr_time_management.vhd b/lib/lpp/lfr_time_management/apb_lfr_time_management.vhd --- a/lib/lpp/lfr_time_management/apb_lfr_time_management.vhd +++ b/lib/lpp/lfr_time_management/apb_lfr_time_management.vhd @@ -32,21 +32,23 @@ 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 - nb_wait_pediod : INTEGER := 375 + 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 - clk49_152MHz : IN STD_LOGIC; --! secondary 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 + 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 ); @@ -57,63 +59,44 @@ ARCHITECTURE Behavioral OF apb_lfr_time_ CONSTANT REVISION : INTEGER := 1; CONSTANT pconfig : apb_config_type := ( - 0 => ahb_device_reg (VENDOR_LPP, 14, 0, REVISION, pirq), + 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_VECTOR(31 DOWNTO 0); + 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 irq1 : STD_LOGIC; - SIGNAL irq2 : 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 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 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 - ----------------------------------------------------------------------------- - -- TODO - -- IRQ 1 & 2 - ----------------------------------------------------------------------------- - irq2 <= '0'; - irq1 <= '0'; - - - --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; PROCESS(resetn, clk25MHz) BEGIN @@ -121,7 +104,7 @@ BEGIN IF resetn = '0' THEN Rdata <= (OTHERS => '0'); r.coarse_time_load <= x"80000000"; - r.ctrl <= x"00000000"; + r.ctrl <= '0'; force_tick <= '0'; previous_force_tick <= '0'; soft_tick <= '0'; @@ -131,7 +114,7 @@ BEGIN ELSIF clk25MHz'EVENT AND clk25MHz = '1' THEN coarsetime_reg_updated <= '0'; - force_tick <= r.ctrl(0); + force_tick <= r.ctrl; previous_force_tick <= force_tick; IF (previous_force_tick = '0') AND (force_tick = '1') THEN soft_tick <= '1'; @@ -143,28 +126,28 @@ BEGIN 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); + r.ctrl <= apbi.pwdata(0); WHEN "000001" => - r.coarse_time_load <= apbi.pwdata(31 DOWNTO 0); + r.coarse_time_load <= apbi.pwdata(31 DOWNTO 0); coarsetime_reg_updated <= '1'; WHEN OTHERS => END CASE; - ELSIF r.ctrl(0) = '1' THEN - r.ctrl(0) <= '0'; + 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(31 DOWNTO 0) <= r.ctrl(31 DOWNTO 0); + Rdata(0) <= r.ctrl; 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); + Rdata(15 DOWNTO 0) <= r.fine_time(15 DOWNTO 0); WHEN OTHERS => Rdata(31 DOWNTO 0) <= x"00000000"; END CASE; @@ -173,25 +156,24 @@ BEGIN END IF; END PROCESS; - apbo.prdata <= Rdata; + apbo.prdata <= Rdata; apbo.pconfig <= pconfig; apbo.pindex <= pindex; - - coarse_time <= r.coarse_time; - fine_time <= r.fine_time; + + ----------------------------------------------------------------------------- + -- IN + coarse_time <= r.coarse_time; + fine_time <= r.fine_time; + coarsetime_reg <= r.coarse_time_load; ----------------------------------------------------------------------------- - coarsetime_reg <= r.coarse_time_load; + ----------------------------------------------------------------------------- + -- OUT 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 @@ -199,7 +181,7 @@ BEGIN NB_FF_OF_SYNC => 2) PORT MAP ( clk_in => clk25MHz, - clk_out => clk49_152MHz, + clk_out => clk24_576MHz, rstn => resetn, sin => tick, sout => new_timecode); @@ -209,57 +191,61 @@ BEGIN NB_FF_OF_SYNC => 2) PORT MAP ( clk_in => clk25MHz, - clk_out => clk49_152MHz, + clk_out => clk24_576MHz, rstn => resetn, sin => coarsetime_reg_updated, sout => new_coarsetime); + ---------------------------------------------------------------------------- - --SYNC_VALID_BIT_3 : SYNC_VALID_BIT + ----------------------------------------------------------------------------- + --SYNC_FF_1 : SYNC_FF -- GENERIC MAP ( -- NB_FF_OF_SYNC => 2) -- PORT MAP ( - -- clk_in => clk49_152MHz, + -- 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 => 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); + -- sin => coarse_time_new_49, + -- sout => coarse_time_new); - lpp_front_detection_1: lpp_front_detection - PORT MAP ( - clk => clk25MHz, - rstn => resetn, - sin => fine_time_new_temp, - sout => fine_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 => clk49_152MHz, - clk_out => clk25MHz, - rstn => resetn, - sin => coarse_time_new_49, - sout => coarse_time_new); + 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 fine_time_new = '1' THEN - fine_time_s <= fine_time_49; - END IF; - IF coarse_time_new = '1' THEN + IF time_new = '1' THEN + fine_time_s <= fine_time_49; coarse_time_s <= coarse_time_49; END IF; END IF; @@ -270,19 +256,19 @@ BEGIN ----------------------------------------------------------------------------- lfr_time_management_1 : lfr_time_management GENERIC MAP ( - nb_time_code_missing_limit => 60, - nb_wait_pediod => 375) + FIRST_DIVISION => FIRST_DIVISION, + NB_SECOND_DESYNC => NB_SECOND_DESYNC) PORT MAP ( - clk => clk49_152MHz, + clk => clk24_576MHz, rstn => resetn, - new_timecode => new_timecode, + tick => new_timecode, new_coarsetime => new_coarsetime, - coarsetime_reg => coarsetime_reg, + coarsetime_reg => coarsetime_reg(30 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; \ No newline at end of file +END Behavioral; diff --git a/lib/lpp/lfr_time_management/coarse_time_counter.vhd b/lib/lpp/lfr_time_management/coarse_time_counter.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lfr_time_management/coarse_time_counter.vhd @@ -0,0 +1,91 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +LIBRARY lpp; +USE lpp.general_purpose.ALL; + +ENTITY coarse_time_counter IS + GENERIC ( + NB_SECOND_DESYNC : INTEGER := 60); + + PORT ( + clk : IN STD_LOGIC; + rstn : IN STD_LOGIC; + + tick : IN STD_LOGIC; + set_TCU : IN STD_LOGIC; + set_TCU_value : IN STD_LOGIC_VECTOR(30 DOWNTO 0); + CT_add1 : IN STD_LOGIC; + fsm_desync : IN STD_LOGIC; + FT_max : IN STD_LOGIC; + + coarse_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + coarse_time_new : OUT STD_LOGIC + + ); + +END coarse_time_counter; + +ARCHITECTURE beh OF coarse_time_counter IS + + SIGNAL add1_bit31 : STD_LOGIC; + SIGNAL nb_second_counter : STD_LOGIC_VECTOR(5 DOWNTO 0); + SIGNAL coarse_time_new_counter : STD_LOGIC; + SIGNAL coarse_time_31 : STD_LOGIC; + SIGNAL coarse_time_31_reg : STD_LOGIC; + + --CONSTANT NB_SECOND_DESYNC : INTEGER := 4; -- TODO : 60 +BEGIN -- beh + + counter_1 : counter + GENERIC MAP ( + CYCLIC => '1', + NB_BITS_COUNTER => 31) + PORT MAP ( + clk => clk, + rstn => rstn, + RST_VALUE => (OTHERS => '0'), + MAX_VALUE => "111" & X"FFFFFFF" , + set => set_TCU, + set_value => set_TCU_value, + add1 => CT_add1, + counter => coarse_time(30 DOWNTO 0)); + + + add1_bit31 <= '1' WHEN fsm_desync = '1' AND FT_max = '1' ELSE '0'; + + counter_2 : counter + GENERIC MAP ( + CYCLIC => '0', + NB_BITS_COUNTER => 6) + PORT MAP ( + clk => clk, + rstn => rstn, + RST_VALUE => STD_LOGIC_VECTOR(to_unsigned(NB_SECOND_DESYNC, 6)), + MAX_VALUE => STD_LOGIC_VECTOR(to_unsigned(NB_SECOND_DESYNC, 6)), + set => tick, + set_value => (OTHERS => '0'), + add1 => add1_bit31, + counter => nb_second_counter); + + coarse_time_31 <= '1' WHEN nb_second_counter = STD_LOGIC_VECTOR(to_unsigned(NB_SECOND_DESYNC, 6)) ELSE '0'; + coarse_time(31) <= coarse_time_31; + coarse_time_new <= coarse_time_new_counter OR (coarse_time_31 XOR coarse_time_31_reg); + + PROCESS (clk, rstn) + BEGIN -- PROCESS + IF rstn = '0' THEN -- asynchronous reset (active low) + coarse_time_new_counter <= '0'; + coarse_time_31_reg <= '0'; + ELSIF clk'event AND clk = '1' THEN -- rising clock edge + coarse_time_31_reg <= coarse_time_31; + IF set_TCU = '1' OR CT_add1 = '1' THEN + coarse_time_new_counter <= '1'; + ELSE + coarse_time_new_counter <= '0'; + END IF; + END IF; + END PROCESS; + +END beh; diff --git a/lib/lpp/lfr_time_management/fine_time_counter.vhd b/lib/lpp/lfr_time_management/fine_time_counter.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lfr_time_management/fine_time_counter.vhd @@ -0,0 +1,93 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +LIBRARY lpp; +USE lpp.general_purpose.ALL; + +ENTITY fine_time_counter IS + + GENERIC ( + WAITING_TIME : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0040"; + FIRST_DIVISION : INTEGER := 374 + ); + + PORT ( + clk : IN STD_LOGIC; + rstn : IN STD_LOGIC; + -- + tick : IN STD_LOGIC; + fsm_transition : IN STD_LOGIC; + + FT_max : OUT STD_LOGIC; + FT_half : OUT STD_LOGIC; + FT_wait : OUT STD_LOGIC; + fine_time : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); + fine_time_new : OUT STD_LOGIC + ); + +END fine_time_counter; + +ARCHITECTURE beh OF fine_time_counter IS + + SIGNAL new_ft_counter : STD_LOGIC_VECTOR(8 DOWNTO 0); + SIGNAL new_ft : STD_LOGIC; + SIGNAL fine_time_counter : STD_LOGIC_VECTOR(15 DOWNTO 0); + +-- CONSTANT FIRST_DIVISION : INTEGER := 20; -- TODO : 374 + +BEGIN -- beh + + + + counter_1 : counter + GENERIC MAP ( + CYCLIC => '1', + NB_BITS_COUNTER => 9) + PORT MAP ( + clk => clk, + rstn => rstn, + RST_VALUE => (OTHERS => '0'), + MAX_VALUE => STD_LOGIC_VECTOR(to_unsigned(FIRST_DIVISION, 9)), + set => tick, + set_value => (OTHERS => '0'), + add1 => '1', + counter => new_ft_counter); + + new_ft <= '1' WHEN new_ft_counter = STD_LOGIC_VECTOR(to_unsigned(FIRST_DIVISION, 9)) ELSE '0'; + + counter_2 : counter + GENERIC MAP ( + CYCLIC => '1', + NB_BITS_COUNTER => 16) + PORT MAP ( + clk => clk, + rstn => rstn, + RST_VALUE => (OTHERS => '0'), + MAX_VALUE => X"FFFF", + set => tick, + set_value => (OTHERS => '0'), + add1 => new_ft, + counter => fine_time_counter); + + FT_max <= '1' WHEN new_ft = '1' AND fine_time_counter = X"FFFF" ELSE '0'; + FT_half <= '1' WHEN fine_time_counter > X"7FFF" ELSE '0'; + FT_wait <= '1' WHEN fine_time_counter > WAITING_TIME ELSE '0'; + + fine_time <= X"FFFF" WHEN fsm_transition = '1' ELSE fine_time_counter; + + PROCESS (clk, rstn) + BEGIN -- PROCESS + IF rstn = '0' THEN -- asynchronous reset (active low) + fine_time_new <= '0'; + ELSIF clk'EVENT AND clk = '1' THEN -- rising clock edge + IF (new_ft = '1' AND fsm_transition = '0') OR tick = '1' THEN + fine_time_new <= '1'; + ELSE + fine_time_new <= '0'; + END IF; + END IF; + END PROCESS; + +END beh; + diff --git a/lib/lpp/lfr_time_management/lfr_time_management.vhd b/lib/lpp/lfr_time_management/lfr_time_management.vhd --- a/lib/lpp/lfr_time_management/lfr_time_management.vhd +++ b/lib/lpp/lfr_time_management/lfr_time_management.vhd @@ -25,16 +25,16 @@ USE lpp.lpp_lfr_time_management.ALL; ENTITY lfr_time_management IS GENERIC ( - nb_time_code_missing_limit : INTEGER := 60; - nb_wait_pediod : INTEGER := 375 - ); + FIRST_DIVISION : INTEGER := 374; + NB_SECOND_DESYNC : INTEGER := 60); PORT ( clk : IN STD_LOGIC; rstn : IN STD_LOGIC; - new_timecode : IN STD_LOGIC; -- transition signal information + tick : IN STD_LOGIC; -- transition signal information + new_coarsetime : IN STD_LOGIC; -- transition signal information - coarsetime_reg : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + coarsetime_reg : IN STD_LOGIC_VECTOR(30 DOWNTO 0); fine_time : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); fine_time_new : OUT STD_LOGIC; @@ -45,68 +45,129 @@ END lfr_time_management; ARCHITECTURE Behavioral OF lfr_time_management IS - SIGNAL counter_clear : STD_LOGIC; - SIGNAL counter_full : STD_LOGIC; + SIGNAL FT_max : STD_LOGIC; + SIGNAL FT_half : STD_LOGIC; + SIGNAL FT_wait : STD_LOGIC; + + TYPE state_fsm_time_management IS (DESYNC, TRANSITION, SYNC); + SIGNAL state : state_fsm_time_management; - SIGNAL nb_time_code_missing : INTEGER; - SIGNAL coarse_time_s : INTEGER; + SIGNAL fsm_desync : STD_LOGIC; + SIGNAL fsm_transition : STD_LOGIC; - SIGNAL new_coarsetime_s : STD_LOGIC; - + SIGNAL set_TCU : STD_LOGIC; + SIGNAL CT_add1 : STD_LOGIC; + + SIGNAL new_coarsetime_reg : STD_LOGIC; + BEGIN - - lpp_counter_1 : lpp_counter - GENERIC MAP ( - nb_wait_period => nb_wait_pediod, - nb_bit_of_data => 16) - PORT MAP ( - clk => clk, - rstn => rstn, - clear => counter_clear, - full => counter_full, - data => fine_time, - new_data => fine_time_new); + ----------------------------------------------------------------------------- + -- + ----------------------------------------------------------------------------- PROCESS (clk, rstn) BEGIN -- PROCESS IF rstn = '0' THEN -- asynchronous reset (active low) - nb_time_code_missing <= 0; - counter_clear <= '0'; - coarse_time_s <= 0; - coarse_time_new <= '0'; - ELSIF clk'EVENT AND clk = '1' THEN -- rising clock edge + new_coarsetime_reg <= '0'; + ELSIF clk'event AND clk = '1' THEN -- rising clock edge IF new_coarsetime = '1' THEN - new_coarsetime_s <= '1'; - ELSIF new_timecode = '1' THEN - new_coarsetime_s <= '0'; - END IF; - - IF new_timecode = '1' THEN - coarse_time_new <= '1'; - IF new_coarsetime_s = '1' THEN - coarse_time_s <= to_integer(unsigned(coarsetime_reg)); - ELSE - coarse_time_s <= coarse_time_s + 1; - END IF; - nb_time_code_missing <= 0; - counter_clear <= '1'; - ELSE - coarse_time_new <= '0'; - counter_clear <= '0'; - IF counter_full = '1' THEN - coarse_time_new <= '1'; - coarse_time_s <= coarse_time_s + 1; - IF nb_time_code_missing = nb_time_code_missing_limit THEN - nb_time_code_missing <= nb_time_code_missing_limit; - ELSE - nb_time_code_missing <= nb_time_code_missing + 1; + new_coarsetime_reg <= '1'; + ELSIF tick = '1' THEN + new_coarsetime_reg <= '0'; + END IF; + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- FINE_TIME + ----------------------------------------------------------------------------- + fine_time_counter_1: fine_time_counter + GENERIC MAP ( + WAITING_TIME => X"0040", + FIRST_DIVISION => FIRST_DIVISION) + PORT MAP ( + clk => clk, + rstn => rstn, + tick => tick, + fsm_transition => fsm_transition, -- todo + FT_max => FT_max, + FT_half => FT_half, + FT_wait => FT_wait, + fine_time => fine_time, + fine_time_new => fine_time_new); + + ----------------------------------------------------------------------------- + -- COARSE_TIME + ----------------------------------------------------------------------------- + coarse_time_counter_1: coarse_time_counter + GENERIC MAP( + NB_SECOND_DESYNC => NB_SECOND_DESYNC ) + PORT MAP ( + clk => clk, + rstn => rstn, + tick => tick, + set_TCU => set_TCU, -- todo + set_TCU_value => coarsetime_reg, -- todo + CT_add1 => CT_add1, -- todo + fsm_desync => fsm_desync, -- todo + FT_max => FT_max, + coarse_time => coarse_time, + coarse_time_new => coarse_time_new); + + ----------------------------------------------------------------------------- + -- FSM + ----------------------------------------------------------------------------- + fsm_desync <= '1' WHEN state = DESYNC ELSE '0'; + fsm_transition <= '1' WHEN state = TRANSITION ELSE '0'; + + PROCESS (clk, rstn) + BEGIN -- PROCESS + IF rstn = '0' THEN -- asynchronous reset (active low) + state <= DESYNC; + ELSIF clk'event AND clk = '1' THEN -- rising clock edge + --CT_add1 <= '0'; + set_TCU <= '0'; + CASE state IS + WHEN DESYNC => + IF tick = '1' THEN + state <= SYNC; + set_TCU <= new_coarsetime_reg; + --IF new_coarsetime = '0' AND FT_half = '1' THEN + -- CT_add1 <= '1'; + --END IF; + --ELSIF FT_max = '1' THEN + -- CT_add1 <= '1'; END IF; - END IF; - END IF; + WHEN TRANSITION => + IF tick = '1' THEN + state <= SYNC; + set_TCU <= new_coarsetime_reg; + --IF new_coarsetime = '0' THEN + -- CT_add1 <= '1'; + --END IF; + ELSIF FT_wait = '1' THEN + --CT_add1 <= '1'; + state <= DESYNC; + END IF; + WHEN SYNC => + IF tick = '1' THEN + set_TCU <= new_coarsetime_reg; + --IF new_coarsetime = '0' THEN + -- CT_add1 <= '1'; + --END IF; + ELSIF FT_max = '1' THEN + state <= TRANSITION; + END IF; + WHEN OTHERS => NULL; + END CASE; END IF; END PROCESS; - coarse_time(30 DOWNTO 0) <= STD_LOGIC_VECTOR(to_unsigned(coarse_time_s,31)); - coarse_time(31) <= '1' WHEN nb_time_code_missing = nb_time_code_missing_limit ELSE '0'; - + + CT_add1 <= '1' WHEN state = SYNC AND tick = '1' AND new_coarsetime_reg = '0' ELSE + '1' WHEN state = DESYNC AND tick = '1' AND new_coarsetime_reg = '0' AND FT_half = '1' ELSE + '1' WHEN state = DESYNC AND tick = '0' AND FT_max = '1' ELSE + '1' WHEN state = TRANSITION AND tick = '1' AND new_coarsetime_reg = '0' ELSE + '1' WHEN state = TRANSITION AND tick = '0' AND FT_wait = '1' ELSE + '0'; END Behavioral; diff --git a/lib/lpp/lfr_time_management/lpp_counter.vhd b/lib/lpp/lfr_time_management/lpp_counter.vhd deleted file mode 100644 --- a/lib/lpp/lfr_time_management/lpp_counter.vhd +++ /dev/null @@ -1,65 +0,0 @@ -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -ENTITY lpp_counter IS - - GENERIC ( - nb_wait_period : INTEGER := 750; - nb_bit_of_data : INTEGER := 16 - ); - PORT ( - clk : IN STD_LOGIC; - rstn : IN STD_LOGIC; - clear : IN STD_LOGIC; - full : OUT STD_LOGIC; - data : OUT STD_LOGIC_VECTOR(nb_bit_of_data-1 DOWNTO 0); - new_data : OUT STD_LOGIC - ); - -END lpp_counter; - -ARCHITECTURE beh OF lpp_counter IS - - SIGNAL counter_wait : INTEGER; - SIGNAL counter_data : INTEGER; - - SIGNAL new_data_s : STD_LOGIC; -BEGIN -- beh - - PROCESS (clk, rstn) - BEGIN -- PROCESS - IF rstn = '0' THEN -- asynchronous reset (active low) - counter_wait <= 0; - counter_data <= 0; - full <= '0'; - new_data_s <= '0'; - ELSIF clk'event AND clk = '1' THEN -- rising clock edge - IF clear = '1' THEN - counter_wait <= 0; - counter_data <= 0; - full <= '0'; - new_data_s <= NOT new_data_s; - ELSE - IF counter_wait = nb_wait_period-1 THEN - counter_wait <= 0; - new_data_s <= NOT new_data_s; - IF counter_data = (2**nb_bit_of_data)-1 THEN - full <= '1'; - counter_data <= 0; - ELSE - full <= '0'; - counter_data <= counter_data +1; - END IF; - ELSE - full <= '0'; - counter_wait <= counter_wait +1; - END IF; - END IF; - END IF; - END PROCESS; - - data <= STD_LOGIC_VECTOR(to_unsigned(counter_data,nb_bit_of_data)); - new_data <= new_data_s; - -END beh; diff --git a/lib/lpp/lfr_time_management/lpp_lfr_time_management.vhd b/lib/lpp/lfr_time_management/lpp_lfr_time_management.vhd --- a/lib/lpp/lfr_time_management/lpp_lfr_time_management.vhd +++ b/lib/lpp/lfr_time_management/lpp_lfr_time_management.vhd @@ -31,15 +31,14 @@ PACKAGE lpp_lfr_time_management IS COMPONENT 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; - nb_wait_pediod : INTEGER := 375 - ); + 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; + NB_SECOND_DESYNC : INTEGER); PORT ( clk25MHz : IN STD_LOGIC; --! Clock - clk49_152MHz : IN STD_LOGIC; --! secondary 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 @@ -51,33 +50,52 @@ PACKAGE lpp_lfr_time_management IS COMPONENT lfr_time_management GENERIC ( - nb_time_code_missing_limit : INTEGER; - nb_wait_pediod : INTEGER := 375); + FIRST_DIVISION : INTEGER; + NB_SECOND_DESYNC : INTEGER); + PORT ( + clk : IN STD_LOGIC; + rstn : IN STD_LOGIC; + tick : IN STD_LOGIC; + new_coarsetime : IN STD_LOGIC; + coarsetime_reg : IN STD_LOGIC_VECTOR(30 DOWNTO 0); + fine_time : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); + fine_time_new : OUT STD_LOGIC; + coarse_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + coarse_time_new : OUT STD_LOGIC); + END COMPONENT; + + COMPONENT coarse_time_counter + GENERIC ( + NB_SECOND_DESYNC : INTEGER ); + PORT ( + clk : IN STD_LOGIC; + rstn : IN STD_LOGIC; + tick : IN STD_LOGIC; + set_TCU : IN STD_LOGIC; + set_TCU_value : IN STD_LOGIC_VECTOR(30 DOWNTO 0); + CT_add1 : IN STD_LOGIC; + fsm_desync : IN STD_LOGIC; + FT_max : IN STD_LOGIC; + coarse_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + coarse_time_new : OUT STD_LOGIC); + END COMPONENT; + + COMPONENT fine_time_counter + GENERIC ( + WAITING_TIME : STD_LOGIC_VECTOR(15 DOWNTO 0); + FIRST_DIVISION : INTEGER ); PORT ( clk : IN STD_LOGIC; rstn : IN STD_LOGIC; - new_timecode : IN STD_LOGIC; - new_coarsetime : IN STD_LOGIC; - coarsetime_reg : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + tick : IN STD_LOGIC; + fsm_transition : IN STD_LOGIC; + FT_max : OUT STD_LOGIC; + FT_half : OUT STD_LOGIC; + FT_wait : OUT STD_LOGIC; fine_time : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); - fine_time_new : OUT STD_LOGIC; - coarse_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); - coarse_time_new : OUT STD_LOGIC - ); + fine_time_new : OUT STD_LOGIC); END COMPONENT; - - COMPONENT lpp_counter - GENERIC ( - nb_wait_period : INTEGER; - nb_bit_of_data : INTEGER); - PORT ( - clk : IN STD_LOGIC; - rstn : IN STD_LOGIC; - clear : IN STD_LOGIC; - full : OUT STD_LOGIC; - data : OUT STD_LOGIC_VECTOR(nb_bit_of_data-1 DOWNTO 0); - new_data : OUT STD_LOGIC ); - END COMPONENT; - + + END lpp_lfr_time_management; diff --git a/lib/lpp/lfr_time_management/vhdlsyn.txt b/lib/lpp/lfr_time_management/vhdlsyn.txt --- a/lib/lpp/lfr_time_management/vhdlsyn.txt +++ b/lib/lpp/lfr_time_management/vhdlsyn.txt @@ -1,4 +1,5 @@ +lpp_lfr_time_management.vhd apb_lfr_time_management.vhd -lpp_counter.vhd lfr_time_management.vhd -lpp_lfr_time_management.vhd +fine_time_counter.vhd +coarse_time_counter.vhd