diff --git a/boards/uniboard2b/designs/unb2b_minimal/quartus/qsys_unb2b_minimal.qsys b/boards/uniboard2b/designs/unb2b_minimal/quartus/qsys_unb2b_minimal.qsys index dd4df7f0e7d6fe053ba6e65666bf8128aa983aa0..fa55630a3f4ea6599badd3466dd0bc36e2a091ab 100644 --- a/boards/uniboard2b/designs/unb2b_minimal/quartus/qsys_unb2b_minimal.qsys +++ b/boards/uniboard2b/designs/unb2b_minimal/quartus/qsys_unb2b_minimal.qsys @@ -78,7 +78,7 @@ { datum baseAddress { - value = "952"; + value = "960"; type = "String"; } } @@ -120,7 +120,7 @@ } datum sopceditor_expanded { - value = "0"; + value = "1"; type = "boolean"; } } @@ -128,7 +128,7 @@ { datum baseAddress { - value = "944"; + value = "912"; type = "String"; } } @@ -202,7 +202,7 @@ { datum baseAddress { - value = "936"; + value = "952"; type = "String"; } } @@ -223,7 +223,7 @@ { datum baseAddress { - value = "928"; + value = "944"; type = "String"; } } @@ -273,7 +273,7 @@ } datum sopceditor_expanded { - value = "1"; + value = "0"; type = "boolean"; } } @@ -302,7 +302,7 @@ { datum baseAddress { - value = "920"; + value = "936"; type = "String"; } } @@ -323,7 +323,7 @@ { datum baseAddress { - value = "912"; + value = "928"; type = "String"; } } @@ -4067,7 +4067,7 @@ <consumedSystemInfos> <entry> <key>ADDRESS_MAP</key> - <value><address-map><slave name='pio_system_info.mem' start='0x0' end='0x80' datawidth='32' /><slave name='avs_eth_0.mms_reg' start='0x80' end='0xC0' datawidth='32' /><slave name='reg_fpga_voltage_sens.mem' start='0xC0' end='0x100' datawidth='32' /><slave name='reg_unb_pmbus.mem' start='0x100' end='0x200' datawidth='32' /><slave name='reg_unb_sens.mem' start='0x200' end='0x300' datawidth='32' /><slave name='timer_0.s1' start='0x300' end='0x320' datawidth='16' /><slave name='reg_fpga_temp_sens.mem' start='0x320' end='0x340' datawidth='32' /><slave name='reg_epcs.mem' start='0x340' end='0x360' datawidth='32' /><slave name='reg_remu.mem' start='0x360' end='0x380' datawidth='32' /><slave name='pio_wdi.s1' start='0x380' end='0x390' datawidth='32' /><slave name='reg_mmdp_data.mem' start='0x390' end='0x398' datawidth='32' /><slave name='reg_mmdp_ctrl.mem' start='0x398' end='0x3A0' datawidth='32' /><slave name='reg_dpmm_data.mem' start='0x3A0' end='0x3A8' datawidth='32' /><slave name='reg_dpmm_ctrl.mem' start='0x3A8' end='0x3B0' datawidth='32' /><slave name='pio_pps.mem' start='0x3B0' end='0x3B8' datawidth='32' /><slave name='jtag_uart_0.avalon_jtag_slave' start='0x3B8' end='0x3C0' datawidth='32' /><slave name='avs_eth_0.mms_tse' start='0x1000' end='0x2000' datawidth='32' /><slave name='avs_eth_0.mms_ram' start='0x2000' end='0x3000' datawidth='32' /><slave name='reg_wdi.mem' start='0x3000' end='0x3008' datawidth='32' /><slave name='ram_scrap.mem' start='0x3800' end='0x4000' datawidth='32' /><slave name='cpu_0.debug_mem_slave' start='0x4000' end='0x4800' datawidth='32' /><slave name='rom_system_info.mem' start='0x10000' end='0x18000' datawidth='32' /><slave name='onchip_memory2_0.s1' start='0x20000' end='0x40000' datawidth='32' /></address-map></value> + <value><address-map><slave name='pio_system_info.mem' start='0x0' end='0x80' datawidth='32' /><slave name='avs_eth_0.mms_reg' start='0x80' end='0xC0' datawidth='32' /><slave name='reg_fpga_voltage_sens.mem' start='0xC0' end='0x100' datawidth='32' /><slave name='reg_unb_pmbus.mem' start='0x100' end='0x200' datawidth='32' /><slave name='reg_unb_sens.mem' start='0x200' end='0x300' datawidth='32' /><slave name='timer_0.s1' start='0x300' end='0x320' datawidth='16' /><slave name='reg_fpga_temp_sens.mem' start='0x320' end='0x340' datawidth='32' /><slave name='reg_epcs.mem' start='0x340' end='0x360' datawidth='32' /><slave name='reg_remu.mem' start='0x360' end='0x380' datawidth='32' /><slave name='pio_wdi.s1' start='0x380' end='0x390' datawidth='32' /><slave name='pio_pps.mem' start='0x390' end='0x3A0' datawidth='32' /><slave name='reg_mmdp_data.mem' start='0x3A0' end='0x3A8' datawidth='32' /><slave name='reg_mmdp_ctrl.mem' start='0x3A8' end='0x3B0' datawidth='32' /><slave name='reg_dpmm_data.mem' start='0x3B0' end='0x3B8' datawidth='32' /><slave name='reg_dpmm_ctrl.mem' start='0x3B8' end='0x3C0' datawidth='32' /><slave name='jtag_uart_0.avalon_jtag_slave' start='0x3C0' end='0x3C8' datawidth='32' /><slave name='avs_eth_0.mms_tse' start='0x1000' end='0x2000' datawidth='32' /><slave name='avs_eth_0.mms_ram' start='0x2000' end='0x3000' datawidth='32' /><slave name='reg_wdi.mem' start='0x3000' end='0x3008' datawidth='32' /><slave name='ram_scrap.mem' start='0x3800' end='0x4000' datawidth='32' /><slave name='cpu_0.debug_mem_slave' start='0x4000' end='0x4800' datawidth='32' /><slave name='rom_system_info.mem' start='0x10000' end='0x18000' datawidth='32' /><slave name='onchip_memory2_0.s1' start='0x20000' end='0x40000' datawidth='32' /></address-map></value> </entry> <entry> <key>ADDRESS_WIDTH</key> @@ -5478,7 +5478,7 @@ <name>coe_address_export</name> <role>export</role> <direction>Output</direction> - <width>1</width> + <width>2</width> <lowerBound>0</lowerBound> <vhdlType>STD_LOGIC_VECTOR</vhdlType> </port> @@ -5542,7 +5542,7 @@ <name>avs_mem_address</name> <role>address</role> <direction>Input</direction> - <width>1</width> + <width>2</width> <lowerBound>0</lowerBound> <vhdlType>STD_LOGIC_VECTOR</vhdlType> </port> @@ -5611,7 +5611,7 @@ </entry> <entry> <key>addressSpan</key> - <value>8</value> + <value>16</value> </entry> <entry> <key>addressUnits</key> @@ -6017,11 +6017,11 @@ <suppliedSystemInfos> <entry> <key>ADDRESS_MAP</key> - <value><address-map><slave name='mem' start='0x0' end='0x8' datawidth='32' /></address-map></value> + <value><address-map><slave name='mem' start='0x0' end='0x10' datawidth='32' /></address-map></value> </entry> <entry> <key>ADDRESS_WIDTH</key> - <value>3</value> + <value>4</value> </entry> <entry> <key>MAX_SLAVE_DATA_WIDTH</key> @@ -15269,11 +15269,11 @@ <suppliedSystemInfos> <entry> <key>ADDRESS_MAP</key> - <value><address-map><slave name='mem' start='0x0' end='0x2000' datawidth='32' /></address-map></value> + <value><address-map><slave name='mem' start='0x0' end='0x8000' datawidth='32' /></address-map></value> </entry> <entry> <key>ADDRESS_WIDTH</key> - <value>13</value> + <value>15</value> </entry> <entry> <key>MAX_SLAVE_DATA_WIDTH</key> @@ -16058,7 +16058,7 @@ version="18.0" start="cpu_0.data_master" end="jtag_uart_0.avalon_jtag_slave"> - <parameter name="baseAddress" value="0x03b8" /> + <parameter name="baseAddress" value="0x03c0" /> </connection> <connection kind="avalon" @@ -16093,7 +16093,7 @@ version="18.0" start="cpu_0.data_master" end="pio_pps.mem"> - <parameter name="baseAddress" value="0x03b0" /> + <parameter name="baseAddress" value="0x0390" /> </connection> <connection kind="avalon" @@ -16121,28 +16121,28 @@ version="18.0" start="cpu_0.data_master" end="reg_dpmm_ctrl.mem"> - <parameter name="baseAddress" value="0x03a8" /> + <parameter name="baseAddress" value="0x03b8" /> </connection> <connection kind="avalon" version="18.0" start="cpu_0.data_master" end="reg_dpmm_data.mem"> - <parameter name="baseAddress" value="0x03a0" /> + <parameter name="baseAddress" value="0x03b0" /> </connection> <connection kind="avalon" version="18.0" start="cpu_0.data_master" end="reg_mmdp_ctrl.mem"> - <parameter name="baseAddress" value="0x0398" /> + <parameter name="baseAddress" value="0x03a8" /> </connection> <connection kind="avalon" version="18.0" start="cpu_0.data_master" end="reg_mmdp_data.mem"> - <parameter name="baseAddress" value="0x0390" /> + <parameter name="baseAddress" value="0x03a0" /> </connection> <connection kind="avalon" diff --git a/boards/uniboard2b/designs/unb2b_minimal/src/vhdl/qsys_unb2b_minimal_pkg.vhd b/boards/uniboard2b/designs/unb2b_minimal/src/vhdl/qsys_unb2b_minimal_pkg.vhd index bf055078658ba689bfd1404f05e8a7f4d0539c62..fdaca584e15cf4cfcae57e3fb3fad11d4988668b 100644 --- a/boards/uniboard2b/designs/unb2b_minimal/src/vhdl/qsys_unb2b_minimal_pkg.vhd +++ b/boards/uniboard2b/designs/unb2b_minimal/src/vhdl/qsys_unb2b_minimal_pkg.vhd @@ -50,7 +50,7 @@ PACKAGE qsys_unb2b_minimal_pkg IS avs_eth_0_tse_write_export : out std_logic; -- export avs_eth_0_tse_writedata_export : out std_logic_vector(31 downto 0); -- export clk_clk : in std_logic := 'X'; -- clk - pio_pps_address_export : out std_logic_vector(0 downto 0); -- export + pio_pps_address_export : out std_logic_vector(1 downto 0); -- export pio_pps_clk_export : out std_logic; -- export pio_pps_read_export : out std_logic; -- export pio_pps_readdata_export : in std_logic_vector(31 downto 0) := (others => 'X'); -- export diff --git a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2b_board_peripherals_pkg.vhd b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2b_board_peripherals_pkg.vhd index 68a57ffd73a5cdb997b3d3f8dfcf9990f64a5aad..47d0e1390b2e2ce81898ee294cf60bf51078c686 100644 --- a/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2b_board_peripherals_pkg.vhd +++ b/boards/uniboard2b/libraries/unb2b_board/src/vhdl/unb2b_board_peripherals_pkg.vhd @@ -165,7 +165,7 @@ PACKAGE unb2b_board_peripherals_pkg IS reg_unb_pmbus_adr_w : NATURAL; -- = 6 END RECORD; - CONSTANT c_unb2b_board_peripherals_mm_reg_default : t_c_unb2b_board_peripherals_mm_reg := (TRUE, 10, 4, 10, 5, 13, 1, 1, 6, 1, 1, 1, 1, 1, 3, 3, 3, 16, 4, 6, 2, 2, 1, 4, 3, 6, 13, 12, 2, 32, 8, 2, 8, 10, 16, 1024, 14, 5, 3, 11, 2, 3, 5, 16, 11, 3, 1, 3, 4, 6); + CONSTANT c_unb2b_board_peripherals_mm_reg_default : t_c_unb2b_board_peripherals_mm_reg := (TRUE, 10, 4, 10, 5, 13, 1, 2, 6, 1, 1, 1, 1, 1, 3, 3, 3, 16, 4, 6, 2, 2, 1, 4, 3, 6, 13, 12, 2, 32, 8, 2, 8, 10, 16, 1024, 14, 5, 3, 11, 2, 3, 5, 16, 11, 3, 1, 3, 4, 6); END unb2b_board_peripherals_pkg; diff --git a/libraries/base/common/src/vhdl/common_interval_monitor.vhd b/libraries/base/common/src/vhdl/common_interval_monitor.vhd index 6bfdba86062b8e11cadb8c044876eafccc7310ff..03342546aa7430be58d7e93e4dbfae9266fd1573 100644 --- a/libraries/base/common/src/vhdl/common_interval_monitor.vhd +++ b/libraries/base/common/src/vhdl/common_interval_monitor.vhd @@ -41,14 +41,15 @@ ENTITY common_interval_monitor IS in_val : IN STD_LOGIC := '1'; in_evt : IN STD_LOGIC; -- MM - interval_cnt : OUT STD_LOGIC_VECTOR(g_interval_cnt_w-1 DOWNTO 0) + interval_cnt : OUT STD_LOGIC_VECTOR(g_interval_cnt_w-1 DOWNTO 0); + clk_cnt : OUT STD_LOGIC_VECTOR(g_interval_cnt_w-1 DOWNTO 0) ); END common_interval_monitor; ARCHITECTURE rtl OF common_interval_monitor IS - SIGNAL clk_cnt : STD_LOGIC_VECTOR(interval_cnt'RANGE); + SIGNAL i_clk_cnt : STD_LOGIC_VECTOR(interval_cnt'RANGE); SIGNAL nxt_clk_cnt : STD_LOGIC_VECTOR(interval_cnt'RANGE); SIGNAL i_interval_cnt : STD_LOGIC_VECTOR(interval_cnt'RANGE); SIGNAL nxt_interval_cnt : STD_LOGIC_VECTOR(interval_cnt'RANGE); @@ -56,34 +57,35 @@ ARCHITECTURE rtl OF common_interval_monitor IS BEGIN interval_cnt <= i_interval_cnt; + clk_cnt <= i_clk_cnt; p_clk: PROCESS(clk, rst) BEGIN IF rst='1' THEN - clk_cnt <= (OTHERS=>'1'); + i_clk_cnt <= (OTHERS=>'1'); i_interval_cnt <= (OTHERS=>'1'); ELSIF rising_edge(clk) THEN - clk_cnt <= nxt_clk_cnt; + i_clk_cnt <= nxt_clk_cnt; i_interval_cnt <= nxt_interval_cnt; END IF; END PROCESS; - p_counter : PROCESS(clk_cnt, i_interval_cnt, in_evt, in_val) + p_counter : PROCESS(i_clk_cnt, i_interval_cnt, in_evt, in_val) BEGIN - nxt_clk_cnt <= clk_cnt; + nxt_clk_cnt <= i_clk_cnt; nxt_interval_cnt <= i_interval_cnt; IF in_evt='1' THEN - -- If there is an in_evt pulse, then capture the clk_cnt into interval_cnt and restart clk_cnt + -- If there is an in_evt pulse, then capture the i_clk_cnt into interval_cnt and restart i_clk_cnt nxt_clk_cnt <= (OTHERS=>'0'); - nxt_interval_cnt <= INCR_UVEC(clk_cnt, 1); - ELSIF SIGNED(clk_cnt)=-1 THEN - -- If there occur no in_evt pulses, then clk_cnt will eventually stop at maximum (= -1) + nxt_interval_cnt <= INCR_UVEC(i_clk_cnt, 1); + ELSIF SIGNED(i_clk_cnt)=-1 THEN + -- If there occur no in_evt pulses, then i_clk_cnt will eventually stop at maximum (= -1) nxt_clk_cnt <= (OTHERS=>'1'); nxt_interval_cnt <= (OTHERS=>'1'); ELSIF in_val='1' THEN -- Increment for valid clk cycles - nxt_clk_cnt <= INCR_UVEC(clk_cnt, 1); + nxt_clk_cnt <= INCR_UVEC(i_clk_cnt, 1); END IF; END PROCESS; diff --git a/libraries/io/ppsh/ppsh.peripheral.yaml b/libraries/io/ppsh/ppsh.peripheral.yaml index c6af948356d4b093cc19e9d5eace4ccf7571eb51..f3b7cd60ae05e8705cd514d890b861324aea573c 100644 --- a/libraries/io/ppsh/ppsh.peripheral.yaml +++ b/libraries/io/ppsh/ppsh.peripheral.yaml @@ -25,6 +25,9 @@ peripherals: - - field_name : control address_offset: 0x4 field_description: " ppsh control " + - - field_name : offset + address_offset: 0x8 + field_description: " ppsh offset count " slave_discription: " " peripheral_description: | @@ -38,5 +41,7 @@ peripherals: |toggle[31], stable[30] xxx capture_cnt = [29:0]| 0 | |-----------------------------------------------------------------------|----| |edge[31], xxx expected_cnt = [29:0]| 1 | + |-----------------------------------------------------------------------|----| + | xxx offset_cnt = [29:0]| 2 | +----------------------------------------------------------------------------+" diff --git a/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd b/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd index 407223ebefa07cf14118ebb415bf87e17cbf06af..b9a44ad727df7423db06f33781fcbfddcd027c2d 100644 --- a/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd +++ b/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd @@ -65,6 +65,7 @@ ARCHITECTURE str OF mms_ppsh IS SIGNAL st_pps_toggle : STD_LOGIC; SIGNAL st_pps_stable : STD_LOGIC; SIGNAL st_capture_cnt : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); -- counts the number of clk clock cycles between subsequent pps_ext pulses + SIGNAL st_offset_cnt : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); -- counts the number of clk clock cycles between now and last pps_ext pulse SIGNAL st_pps_stable_ack : STD_LOGIC; @@ -96,6 +97,7 @@ BEGIN pps_toggle => st_pps_toggle, pps_stable => st_pps_stable, capture_cnt => st_capture_cnt, + offset_cnt => st_offset_cnt, pps_stable_ack => st_pps_stable_ack, capture_edge => st_capture_edge, expected_cnt => st_expected_cnt @@ -126,6 +128,7 @@ BEGIN st_pps_stable => st_pps_stable, st_pps_stable_ack => st_pps_stable_ack, st_capture_cnt => st_capture_cnt, + st_offset_cnt => st_offset_cnt, st_capture_edge => st_capture_edge, st_expected_cnt => st_expected_cnt ); diff --git a/libraries/io/ppsh/src/vhdl/ppsh.vhd b/libraries/io/ppsh/src/vhdl/ppsh.vhd index 9a6332cdd961f9006dc1aa9d7dd1b95f7c0342d6..eb9dc3991bc07bdc52047bc83ff0b70ca0e0e026 100644 --- a/libraries/io/ppsh/src/vhdl/ppsh.vhd +++ b/libraries/io/ppsh/src/vhdl/ppsh.vhd @@ -68,6 +68,7 @@ ENTITY ppsh IS pps_toggle : OUT STD_LOGIC; -- pps toggle level signal in clk domain (i.e. 0.5 Hz square wave) pps_stable : OUT STD_LOGIC; -- pps stable signal in clk domain capture_cnt : OUT STD_LOGIC_VECTOR(ceil_log2(g_clk_freq)-1 DOWNTO 0); -- counts the number of clk clock cycles between subsequent pps_ext pulses + offset_cnt : OUT STD_LOGIC_VECTOR(ceil_log2(g_clk_freq)-1 DOWNTO 0); -- counts the number of clk clock cycles between now and last pps_ext pulse pps_stable_ack : IN STD_LOGIC := '0'; -- pps stable acknowledge in clk domain capture_edge : IN STD_LOGIC := '0'; -- when '0' then clock pps_ext on rising edge of clk, else use falling edge of clk expected_cnt : IN STD_LOGIC_VECTOR(ceil_log2(g_clk_freq)-1 DOWNTO 0) := (OTHERS=> '1') -- expected number of clk clock cycles between subsequent pps_ext pulses @@ -102,7 +103,7 @@ ARCHITECTURE rtl OF ppsh IS BEGIN capture_cnt <= i_capture_cnt; - pps_toggle <= i_pps_toggle; + pps_toggle <= i_pps_toggle; pps_ext_delayed(0) <= pps_ext; -- no input delay support @@ -171,7 +172,8 @@ BEGIN in_val => '1', in_evt => pps_ext_revt, -- MM - interval_cnt => i_capture_cnt + interval_cnt => i_capture_cnt, + clk_cnt => offset_cnt ); -- Output the pps_sys with extra pipelining to ease timing of pps_sys fan out diff --git a/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd b/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd index 51efde2ff71ddcd645f5445a3b39a4e1197137a7..31789f7f36f640e0344ecb210d18011c69bda76c 100644 --- a/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd +++ b/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd @@ -31,6 +31,23 @@ -- |-----------------------------------------------------------------------| -- |edge[31], xxx expected_cnt = [n:0]| 1 -- |-----------------------------------------------------------------------| +-- | xxx offset_cnt = [n:0]| 2 +-- |-----------------------------------------------------------------------| + + +-- Info from L2SDP-78 ticket. +-- Add a new offset_cnt field to the PPSH register that reports the current capture_cnt value at the moment that this MM read access occurs. +-- The offset_cnt reports the time since last PPSH in units of the dp_clk, so 5 ns (at 200MHz). The host can use this offset_cnt value to +-- determine the alignment between its local Time of Day and the PPS in the FPGA. +-- +-- The offset_cnt needs to be supported in the pi_ppsh.py and util_ppsh.py. Please also use the option --rep to quickly repeat the reading +-- of the PPSH registers. This is useful to show that the offset_cnt increases and then restarts after every new PPS. The PPS in the FPGA is +-- also represented by the pps_toggle field in the PPSH registers. +-- +-- The PPSH is part of unb2_minimal. To fit the PPSH register the span in QSYS and in the mmm file needs to be increased from 2 words to 4 words. +-- +-- Also prepare unb2c_minimal by updating the PPSH register span there. + LIBRARY IEEE, common_lib; USE IEEE.STD_LOGIC_1164.ALL; @@ -57,6 +74,7 @@ ENTITY ppsh_reg IS st_pps_toggle : IN STD_LOGIC; st_pps_stable : IN STD_LOGIC; st_capture_cnt : IN STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); -- counts the number of clk clock cycles between subsequent pps_ext pulses + st_offset_cnt : IN STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); -- counts the number of clk clock cycles between now and last pps_ext pulse st_pps_stable_ack : OUT STD_LOGIC; @@ -70,9 +88,9 @@ ARCHITECTURE rtl OF ppsh_reg IS -- Define the actual size of the MM slave register CONSTANT c_mm_reg : t_c_mem := (latency => 1, - adr_w => ceil_log2(2), + adr_w => ceil_log2(4), dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers - nof_dat => 2, + nof_dat => 4, init_sl => '0'); -- Register access control signal in mm_clk domain @@ -85,6 +103,7 @@ ARCHITECTURE rtl OF ppsh_reg IS SIGNAL mm_capture_cnt : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); SIGNAL mm_expected_cnt : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); + SIGNAL mm_offset_cnt : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0); BEGIN @@ -139,6 +158,9 @@ BEGIN -- Read back PPSH control sla_out.rddata(31) <= mm_capture_edge; sla_out.rddata(29 DOWNTO 0) <= RESIZE_UVEC(mm_expected_cnt, 30); + WHEN 2 => + -- Read PPSH offset count + sla_out.rddata(29 DOWNTO 0) <= RESIZE_UVEC(mm_offset_cnt, 30); WHEN OTHERS => NULL; -- not used MM addresses END CASE; END IF; @@ -166,6 +188,7 @@ BEGIN mm_pps_toggle <= st_pps_toggle; mm_pps_stable <= st_pps_stable; mm_capture_cnt <= st_capture_cnt; + mm_offset_cnt <= st_offset_cnt; st_pps_stable_ack <= mm_pps_stable_ack; @@ -209,6 +232,18 @@ BEGIN out_new => OPEN ); + u_offset_cnt : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_rst => st_rst, + in_clk => st_clk, + in_dat => st_offset_cnt, + in_done => OPEN, + out_rst => mm_rst, + out_clk => mm_clk, + out_dat => mm_offset_cnt, + out_new => OPEN + ); + -- MM --> ST u_pps_stable_ack : ENTITY common_lib.common_spulse PORT MAP ( diff --git a/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd b/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd index e6894f64e14e00b7fed5826306882d7aeae971fe..39e21de98a90bb33568d11fbeed94e304dc52444 100644 --- a/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd +++ b/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd @@ -35,37 +35,39 @@ ARCHITECTURE tb OF tb_mms_ppsh IS CONSTANT c_clk_freq : NATURAL := 1000; -- clock frequency in Hz CONSTANT c_clk_period : TIME := 1000000 us / c_clk_freq; CONSTANT c_pps_period : NATURAL := c_clk_freq; -- 1 s takes c_clk_freq clk cycles - + SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL rst : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1'; - + -- DUT SIGNAL pps_ext : STD_LOGIC; SIGNAL pps_sys : STD_LOGIC; - + SIGNAL reg_mosi : t_mem_mosi := c_mem_mosi_rst; SIGNAL reg_miso : t_mem_miso; - + -- Verify SIGNAL bsn : NATURAL; SIGNAL pps_toggle : STD_LOGIC; SIGNAL pps_stable : STD_LOGIC; SIGNAL capture_cnt : NATURAL; - + SIGNAL offset_cnt : NATURAL; + SIGNAL last_offset_cnt : NATURAL; + BEGIN -- Usage: -- > as 10 -- > run -all -- p_verify assert when unexpected capture_cnt and pps_stable are read via MM - + ----------------------------------------------------------------------------- -- Stimuli ----------------------------------------------------------------------------- rst <= '1', '0' AFTER 7*c_clk_period; clk <= NOT clk OR tb_end AFTER c_clk_period/2; - + p_pps_ext : PROCESS VARIABLE v_pps_period : NATURAL := c_pps_period; BEGIN @@ -85,42 +87,53 @@ BEGIN proc_common_wait_some_cycles(clk, 1); pps_ext <= '0'; END LOOP; - + WAIT; END PROCESS; - + p_mm_stimuli : PROCESS VARIABLE v_word : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); BEGIN proc_common_wait_until_low(clk, rst); -- Wait until reset has finished proc_common_wait_some_cycles(clk, 10); -- Wait an additional amount of cycles - + v_word := '0' & TO_UVEC(c_pps_period, 31); -- capture_edge = '0' = at rising edge -- expected_cnt = c_pps_period = 1000 proc_mem_mm_bus_wr(1, v_word, clk, reg_mosi); - + + -- Simulate reading PPS status every 10 PPS periods proc_common_wait_some_cycles(clk, 10); FOR I IN 0 TO 9 LOOP proc_common_wait_some_cycles(clk, c_pps_period*10); - + proc_mem_mm_bus_rd(0, clk, reg_mosi); - proc_common_wait_some_cycles(clk, 1); + proc_common_wait_some_cycles(clk, 1); pps_toggle <= reg_miso.rddata(31); pps_stable <= reg_miso.rddata(30); capture_cnt <= TO_UINT(reg_miso.rddata(ceil_log2(c_clk_freq)-1 DOWNTO 0)); END LOOP; - + + -- Simulate reading PPS offset counter every 0.1 PPS periods + proc_common_wait_some_cycles(clk, 10); + FOR I IN 0 TO 4 LOOP + proc_common_wait_some_cycles(clk, c_pps_period/10); + last_offset_cnt <= offset_cnt; + proc_mem_mm_bus_rd(2, clk, reg_mosi); + proc_common_wait_some_cycles(clk, 1); + offset_cnt <= TO_UINT(reg_miso.rddata(ceil_log2(c_clk_freq)-1 DOWNTO 0)); + END LOOP; + proc_common_wait_some_cycles(clk, 100); tb_end <= '1'; WAIT; END PROCESS; - + p_verify : PROCESS BEGIN proc_common_wait_until_low(clk, rst); -- Wait until reset has finished proc_common_wait_some_cycles(clk, 10); -- Wait an additional amount of cycles - + proc_common_wait_some_cycles(clk, c_pps_period/2); -- Verification offset -- 1 proc_common_wait_some_cycles(clk, c_pps_period*10); @@ -158,14 +171,20 @@ BEGIN proc_common_wait_some_cycles(clk, c_pps_period*10); ASSERT pps_stable='1' REPORT "9) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "9) Wrong capture_cnt" SEVERITY ERROR; + -- 10 + proc_common_wait_some_cycles(clk, c_pps_period/10); + ASSERT offset_cnt=last_offset_cnt REPORT "10) Wrong offset_cnt" SEVERITY ERROR; + -- 11 + proc_common_wait_some_cycles(clk, c_pps_period/10); + ASSERT offset_cnt=last_offset_cnt REPORT "11) Wrong offset_cnt" SEVERITY ERROR; WAIT; END PROCESS; - - + + ----------------------------------------------------------------------------- -- DUT: PPSH ----------------------------------------------------------------------------- - + dut : ENTITY work.mms_ppsh GENERIC MAP ( g_st_clk_freq => c_clk_freq @@ -177,11 +196,11 @@ BEGIN st_rst => rst, st_clk => clk, pps_ext => pps_ext, - + -- Memory-mapped clock domain reg_mosi => reg_mosi, reg_miso => reg_miso, - + -- Streaming clock domain pps_sys => pps_sys ); diff --git a/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd b/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd index d3d492961a1ecef4311e535f6e467dd8312e9a85..4887a8489d1df8bb0245cf12ddb2f6c75c31dbca 100644 --- a/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd +++ b/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd @@ -33,7 +33,7 @@ ARCHITECTURE tb OF tb_ppsh IS CONSTANT c_clk_period : TIME := 1000000 us / c_clk_freq; CONSTANT c_pps_default_period : NATURAL := c_clk_freq; -- 1 s takes c_clk_freq clk cycles CONSTANT c_pps_skew : TIME := 7*c_clk_period/10; - + -- The state name tells what kind of test is being done TYPE t_state_enum IS ( s_idle, @@ -49,31 +49,32 @@ ARCHITECTURE tb OF tb_ppsh IS SIGNAL rst : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1'; SIGNAL pps : STD_LOGIC; - + -- DUT SIGNAL pps_ext : STD_LOGIC; SIGNAL pps_sys : STD_LOGIC; SIGNAL pps_toggle : STD_LOGIC; SIGNAL capture_edge : STD_LOGIC; SIGNAL capture_cnt : STD_LOGIC_VECTOR(ceil_log2(c_clk_freq)-1 DOWNTO 0); - + SIGNAL offset_cnt : STD_LOGIC_VECTOR(ceil_log2(c_clk_freq)-1 DOWNTO 0); + -- Verify - + BEGIN -- Usage: 'run -all', observe unsigned capture_cnt, there should occur no -- REPORT errors. - + ----------------------------------------------------------------------------- -- Stimuli ----------------------------------------------------------------------------- rst <= '1', '0' AFTER 7*c_clk_period; clk <= NOT clk OR tb_end AFTER c_clk_period/2; - + -- Verify that using the falling capture edge indeed does change timing by -- using a c_pps_skew that is > 0.5 c_clk_period and < c_clk_period capture_edge <= '0', '1' AFTER 5000 ms, '0' AFTER 7000 ms; - + -- Verify the capture_cnt p_pps_default_period : PROCESS BEGIN @@ -131,7 +132,7 @@ BEGIN END LOOP; -- Missing PPS pulses tb_state <= s_missing_pps; - + -- End tb_state <= s_end; WAIT FOR c_pps_default_period*c_clk_period; @@ -139,14 +140,14 @@ BEGIN WAIT; END PROCESS; - -- Apply some PPS to CLK skew + -- Apply some PPS to CLK skew pps_ext <= TRANSPORT pps AFTER c_pps_skew; - - + + ----------------------------------------------------------------------------- -- DUT: PPSH ----------------------------------------------------------------------------- - + dut : ENTITY work.ppsh GENERIC MAP ( g_clk_freq => c_clk_freq @@ -160,13 +161,14 @@ BEGIN pps_toggle => pps_toggle, -- MM control capture_edge => capture_edge, - capture_cnt => capture_cnt + capture_cnt => capture_cnt, + offset_cnt => offset_cnt ); ----------------------------------------------------------------------------- -- Verify capture_cnt ----------------------------------------------------------------------------- - + -- Simple verify scheme that matches the stimuli from p_pps_default_period p_verify : PROCESS(clk) BEGIN @@ -179,69 +181,83 @@ BEGIN UNSIGNED(capture_cnt)/=2**capture_cnt'LENGTH-1 THEN REPORT "PPSH : Unexpected capture count value." SEVERITY ERROR; END IF; - + -- Verify influence of PPS capture edge selection IF (NOW > 6000 ms) AND (NOW <= 6000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq+1 THEN REPORT "PPSH : Unexpected capture count value at 6 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 7000 ms) AND (NOW <= 7000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 7 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 8000 ms) AND (NOW <= 8000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq-1 THEN REPORT "PPSH : Unexpected capture count value at 8 s." SEVERITY ERROR; END IF; END IF; - + -- Verify external PPS period fluctuations at specific stimuli moments IF (NOW > 10000 ms) AND (NOW <= 10000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 10 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 22000 ms) AND (NOW <= 22000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq-1 THEN REPORT "PPSH : Unexpected capture count value at 22 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 25000 ms) AND (NOW <= 25000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 25 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 28000 ms) AND (NOW <= 28000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq+1 THEN REPORT "PPSH : Unexpected capture count value at 28 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 30000 ms) AND (NOW <= 30000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 30 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 35000 ms) AND (NOW <= 35000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=2**capture_cnt'LENGTH-1 THEN REPORT "PPSH : Unexpected capture count value at 35 s." SEVERITY ERROR; END IF; END IF; - + IF (NOW > 49000 ms) AND (NOW <= 49000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=2**capture_cnt'LENGTH-1 THEN REPORT "PPSH : Unexpected capture count value at 49 s." SEVERITY ERROR; END IF; END IF; + + -- check if offset_cnt is counting + IF (NOW > 7500 ms) AND (NOW <= 7500 ms + c_clk_period) THEN + IF UNSIGNED(offset_cnt)/=475 THEN + REPORT "PPSH : Unexpected offset count value at 5.5 s." SEVERITY ERROR; + END IF; + END IF; + + IF (NOW > 7700 ms) AND (NOW <= 7700 ms + c_clk_period) THEN + IF UNSIGNED(offset_cnt)/=675 THEN + REPORT "PPSH : Unexpected offset count value at 5.5 s." SEVERITY ERROR; + END IF; + END IF; + END IF; END PROCESS; - + END tb;