Skip to content
Snippets Groups Projects
Commit 332665f6 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Merge branch 'L2SDP-78' into 'master'

Resolve L2SDP-78

Closes L2SDP-78

See merge request desp/hdl!26
parents 8725aca0 4f2b39fb
No related branches found
No related tags found
2 merge requests!28Master,!26Resolve L2SDP-78
......@@ -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>&lt;address-map&gt;&lt;slave name='pio_system_info.mem' start='0x0' end='0x80' datawidth='32' /&gt;&lt;slave name='avs_eth_0.mms_reg' start='0x80' end='0xC0' datawidth='32' /&gt;&lt;slave name='reg_fpga_voltage_sens.mem' start='0xC0' end='0x100' datawidth='32' /&gt;&lt;slave name='reg_unb_pmbus.mem' start='0x100' end='0x200' datawidth='32' /&gt;&lt;slave name='reg_unb_sens.mem' start='0x200' end='0x300' datawidth='32' /&gt;&lt;slave name='timer_0.s1' start='0x300' end='0x320' datawidth='16' /&gt;&lt;slave name='reg_fpga_temp_sens.mem' start='0x320' end='0x340' datawidth='32' /&gt;&lt;slave name='reg_epcs.mem' start='0x340' end='0x360' datawidth='32' /&gt;&lt;slave name='reg_remu.mem' start='0x360' end='0x380' datawidth='32' /&gt;&lt;slave name='pio_wdi.s1' start='0x380' end='0x390' datawidth='32' /&gt;&lt;slave name='reg_mmdp_data.mem' start='0x390' end='0x398' datawidth='32' /&gt;&lt;slave name='reg_mmdp_ctrl.mem' start='0x398' end='0x3A0' datawidth='32' /&gt;&lt;slave name='reg_dpmm_data.mem' start='0x3A0' end='0x3A8' datawidth='32' /&gt;&lt;slave name='reg_dpmm_ctrl.mem' start='0x3A8' end='0x3B0' datawidth='32' /&gt;&lt;slave name='pio_pps.mem' start='0x3B0' end='0x3B8' datawidth='32' /&gt;&lt;slave name='jtag_uart_0.avalon_jtag_slave' start='0x3B8' end='0x3C0' datawidth='32' /&gt;&lt;slave name='avs_eth_0.mms_tse' start='0x1000' end='0x2000' datawidth='32' /&gt;&lt;slave name='avs_eth_0.mms_ram' start='0x2000' end='0x3000' datawidth='32' /&gt;&lt;slave name='reg_wdi.mem' start='0x3000' end='0x3008' datawidth='32' /&gt;&lt;slave name='ram_scrap.mem' start='0x3800' end='0x4000' datawidth='32' /&gt;&lt;slave name='cpu_0.debug_mem_slave' start='0x4000' end='0x4800' datawidth='32' /&gt;&lt;slave name='rom_system_info.mem' start='0x10000' end='0x18000' datawidth='32' /&gt;&lt;slave name='onchip_memory2_0.s1' start='0x20000' end='0x40000' datawidth='32' /&gt;&lt;/address-map&gt;</value>
<value>&lt;address-map&gt;&lt;slave name='pio_system_info.mem' start='0x0' end='0x80' datawidth='32' /&gt;&lt;slave name='avs_eth_0.mms_reg' start='0x80' end='0xC0' datawidth='32' /&gt;&lt;slave name='reg_fpga_voltage_sens.mem' start='0xC0' end='0x100' datawidth='32' /&gt;&lt;slave name='reg_unb_pmbus.mem' start='0x100' end='0x200' datawidth='32' /&gt;&lt;slave name='reg_unb_sens.mem' start='0x200' end='0x300' datawidth='32' /&gt;&lt;slave name='timer_0.s1' start='0x300' end='0x320' datawidth='16' /&gt;&lt;slave name='reg_fpga_temp_sens.mem' start='0x320' end='0x340' datawidth='32' /&gt;&lt;slave name='reg_epcs.mem' start='0x340' end='0x360' datawidth='32' /&gt;&lt;slave name='reg_remu.mem' start='0x360' end='0x380' datawidth='32' /&gt;&lt;slave name='pio_wdi.s1' start='0x380' end='0x390' datawidth='32' /&gt;&lt;slave name='pio_pps.mem' start='0x390' end='0x3A0' datawidth='32' /&gt;&lt;slave name='reg_mmdp_data.mem' start='0x3A0' end='0x3A8' datawidth='32' /&gt;&lt;slave name='reg_mmdp_ctrl.mem' start='0x3A8' end='0x3B0' datawidth='32' /&gt;&lt;slave name='reg_dpmm_data.mem' start='0x3B0' end='0x3B8' datawidth='32' /&gt;&lt;slave name='reg_dpmm_ctrl.mem' start='0x3B8' end='0x3C0' datawidth='32' /&gt;&lt;slave name='jtag_uart_0.avalon_jtag_slave' start='0x3C0' end='0x3C8' datawidth='32' /&gt;&lt;slave name='avs_eth_0.mms_tse' start='0x1000' end='0x2000' datawidth='32' /&gt;&lt;slave name='avs_eth_0.mms_ram' start='0x2000' end='0x3000' datawidth='32' /&gt;&lt;slave name='reg_wdi.mem' start='0x3000' end='0x3008' datawidth='32' /&gt;&lt;slave name='ram_scrap.mem' start='0x3800' end='0x4000' datawidth='32' /&gt;&lt;slave name='cpu_0.debug_mem_slave' start='0x4000' end='0x4800' datawidth='32' /&gt;&lt;slave name='rom_system_info.mem' start='0x10000' end='0x18000' datawidth='32' /&gt;&lt;slave name='onchip_memory2_0.s1' start='0x20000' end='0x40000' datawidth='32' /&gt;&lt;/address-map&gt;</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>&lt;address-map&gt;&lt;slave name='mem' start='0x0' end='0x8' datawidth='32' /&gt;&lt;/address-map&gt;</value>
<value>&lt;address-map&gt;&lt;slave name='mem' start='0x0' end='0x10' datawidth='32' /&gt;&lt;/address-map&gt;</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>&lt;address-map&gt;&lt;slave name='mem' start='0x0' end='0x2000' datawidth='32' /&gt;&lt;/address-map&gt;</value>
<value>&lt;address-map&gt;&lt;slave name='mem' start='0x0' end='0x8000' datawidth='32' /&gt;&lt;/address-map&gt;</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"
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 |
+----------------------------------------------------------------------------+"
......@@ -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
);
......
......@@ -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
......
......@@ -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 (
......
......@@ -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
);
......
......@@ -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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment