From 6406f6eb1502dfda0b0c928a4fc4589f0cb9e6c8 Mon Sep 17 00:00:00 2001 From: Reinier van der Walle <walle@astron.nl> Date: Wed, 19 Jul 2017 10:12:47 +0000 Subject: [PATCH] Initial commit of dp_xonoff_reg_timeout, amodified version of dp_xonoff_reg to allow a timeout. Also modified mms_dp_xonoff to be able to use the timeout function by setting the g_timeout_time generic --- libraries/base/dp/hdllib.cfg | 2 + .../dp/src/vhdl/dp_xonoff_reg_timeout.vhd | 158 ++++++++++++++++++ libraries/base/dp/src/vhdl/mms_dp_xonoff.vhd | 68 +++++--- .../dp/tb/vhdl/tb_dp_xonoff_reg_timeout.vhd | 125 ++++++++++++++ 4 files changed, 333 insertions(+), 20 deletions(-) create mode 100644 libraries/base/dp/src/vhdl/dp_xonoff_reg_timeout.vhd create mode 100644 libraries/base/dp/tb/vhdl/tb_dp_xonoff_reg_timeout.vhd diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index c6dc1c195a..d9b58f17da 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -17,6 +17,7 @@ synth_files = src/vhdl/dp_frame_busy_arr.vhd src/vhdl/dp_xonoff.vhd src/vhdl/dp_xonoff_reg.vhd + src/vhdl/dp_xonoff_reg_timeout.vhd src/vhdl/mms_dp_xonoff.vhd src/vhdl/dp_flush.vhd src/vhdl/dp_latency_increase.vhd @@ -210,6 +211,7 @@ test_bench_files = tb/vhdl/tb_dp_shiftram.vhd tb/vhdl/tb_dp_xonoff.vhd tb/vhdl/tb_mms_dp_xonoff.vhd + tb/vhdl/tb_dp_xonoff_reg_timeout.vhd tb/vhdl/tb_dp_sync_insert.vhd tb/vhdl/tb_dp_folder.vhd tb/vhdl/tb_dp_switch.vhd diff --git a/libraries/base/dp/src/vhdl/dp_xonoff_reg_timeout.vhd b/libraries/base/dp/src/vhdl/dp_xonoff_reg_timeout.vhd new file mode 100644 index 0000000000..8ba17d2991 --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_xonoff_reg_timeout.vhd @@ -0,0 +1,158 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2013 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- 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, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Provide MM slave register for dp_xonoff with timeout +-- Description: +-- +-- Read/write register for stream enable/disable, disables <g_default_value> seconds after last enable write +-- +-- 31 24 23 16 15 8 7 0 wi +-- |-----------------|-----------------|-----------------|-----------------| +-- | |X| 0 +-- |-----------------------------------------------------------------------| +-- +-- +-- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + +ENTITY dp_xonoff_reg_timeout IS + GENERIC ( + g_default_value : STD_LOGIC := '1'; + g_mm_timeout : NATURAL := 10; -- 10 Seconds, Max = 42 + g_sim : BOOLEAN := FALSE -- When True, use micro seconds instead of seconds + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + st_rst : IN STD_LOGIC; + st_clk : IN STD_LOGIC; + + -- Memory Mapped Slave in mm_clk domain + sla_in : IN t_mem_mosi; + sla_out : OUT t_mem_miso; + + -- MM registers in st_clk domain + xonoff_reg : OUT STD_LOGIC_VECTOR(0 DOWNTO 0) + ); +END dp_xonoff_reg_timeout; + + +ARCHITECTURE str OF dp_xonoff_reg_timeout IS + + CONSTANT c_mm_reg : t_c_mem := (latency => 1, + adr_w => 1, + dat_w => c_word_w, + nof_dat => 1, + init_sl => g_default_value); + CONSTANT c_mm_max_counter : NATURAL := sel_a_b(g_sim, g_mm_timeout * 50, g_mm_timeout * (50*10**6)); -- @50MHz + + + SIGNAL mm_xonoff_reg : STD_LOGIC_VECTOR(0 DOWNTO 0); + SIGNAL mm_xonoff_reg_out : STD_LOGIC_VECTOR(0 DOWNTO 0); + SIGNAL counter : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL cnt_clr : STD_LOGIC := '0'; + SIGNAL cnt_en : STD_LOGIC := '1'; + + + +BEGIN + + p_mm_reg : PROCESS (mm_rst, mm_clk) + BEGIN + IF mm_rst = '1' THEN + -- Read access + sla_out <= c_mem_miso_rst; + -- Write access, register values + mm_xonoff_reg(0) <= g_default_value; + + ELSIF rising_edge(mm_clk) THEN + -- Read access defaults + sla_out.rdval <= '0'; + cnt_clr <= '0'; + -- Check if timeout is reached + IF TO_UINT(counter) >= c_mm_max_counter THEN + cnt_en <= '0'; + mm_xonoff_reg_out(0) <= '0'; + ELSE + mm_xonoff_reg_out <= mm_xonoff_reg; + END IF; + + -- Write access: set register value + IF sla_in.wr = '1' THEN + CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + WHEN 0 => + mm_xonoff_reg(0) <= sla_in.wrdata(0); + IF sla_in.wrdata(0) = '1' THEN + cnt_clr <= '1'; + cnt_en <= '1'; + END IF; + + WHEN OTHERS => NULL; -- not used MM addresses + END CASE; + + -- Read access: get register value + ELSIF sla_in.rd = '1' THEN + sla_out <= c_mem_miso_rst; -- set unused rddata bits to '0' when read + sla_out.rdval <= '1'; -- c_mm_reg.latency = 1 + CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS + -- Read Block Sync + WHEN 0 => + sla_out.rddata(0) <= mm_xonoff_reg(0); + + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END PROCESS; + + + + u_counter : ENTITY common_lib.common_counter + GENERIC MAP ( + g_latency => 0 + ) + PORT MAP ( + rst => mm_rst, + clk => mm_clk, + cnt_clr => cnt_clr, + cnt_en => cnt_en, + count => counter + ); + + u_reg_cross_domain : ENTITY common_lib.common_reg_cross_domain + PORT MAP ( + in_rst => mm_rst, + in_clk => mm_clk, + + in_dat => mm_xonoff_reg_out, + + out_rst => st_rst, + out_clk => st_clk, + + out_dat => xonoff_reg + ); + +END str; diff --git a/libraries/base/dp/src/vhdl/mms_dp_xonoff.vhd b/libraries/base/dp/src/vhdl/mms_dp_xonoff.vhd index f75d56a371..c413ec5a69 100644 --- a/libraries/base/dp/src/vhdl/mms_dp_xonoff.vhd +++ b/libraries/base/dp/src/vhdl/mms_dp_xonoff.vhd @@ -31,7 +31,9 @@ ENTITY mms_dp_xonoff IS g_nof_streams : NATURAL := 1; g_combine_streams : BOOLEAN := FALSE; g_bypass : BOOLEAN := FALSE; - g_default_value : STD_LOGIC := '1' + g_default_value : STD_LOGIC := '1'; + g_timeout_time : NATURAL := 0; + g_sim : BOOLEAN := FALSE ); PORT ( -- Memory-mapped clock domain @@ -82,25 +84,51 @@ BEGIN ); gen_reg : FOR i IN 0 TO c_nof_ctrl_streams-1 GENERATE - u_reg : ENTITY work.dp_xonoff_reg - GENERIC MAP( - g_default_value => g_default_value - ) - PORT MAP ( - -- Clocks and reset - mm_rst => mm_rst, - mm_clk => mm_clk, - st_rst => dp_rst, - st_clk => dp_clk, - - -- Memory Mapped Slave in mm_clk domain - sla_in => reg_mosi_arr(i), - sla_out => reg_miso_arr(i), - - -- MM registers in dp_clk domain - -- . control - xonoff_reg => xonoff_reg(i DOWNTO i) - ); + gen_no_timeout : IF g_timeout_time = 0 GENERATE + u_reg : ENTITY work.dp_xonoff_reg + GENERIC MAP( + g_default_value => g_default_value + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + st_rst => dp_rst, + st_clk => dp_clk, + + -- Memory Mapped Slave in mm_clk domain + sla_in => reg_mosi_arr(i), + sla_out => reg_miso_arr(i), + + -- MM registers in dp_clk domain + -- . control + xonoff_reg => xonoff_reg(i DOWNTO i) + ); + END GENERATE; + + gen_with_timeout : IF g_timeout_time > 0 GENERATE + u_reg : ENTITY work.dp_xonoff_reg_timeout + GENERIC MAP( + g_default_value => g_default_value, + g_mm_timeout => g_timeout_time, + g_sim => g_sim + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + st_rst => dp_rst, + st_clk => dp_clk, + + -- Memory Mapped Slave in mm_clk domain + sla_in => reg_mosi_arr(i), + sla_out => reg_miso_arr(i), + + -- MM registers in dp_clk domain + -- . control + xonoff_reg => xonoff_reg(i DOWNTO i) + ); + END GENERATE; END GENERATE; xonoff_reg_i <= xonoff_reg WHEN g_combine_streams = FALSE ELSE (OTHERS => xonoff_reg(0)); diff --git a/libraries/base/dp/tb/vhdl/tb_dp_xonoff_reg_timeout.vhd b/libraries/base/dp/tb/vhdl/tb_dp_xonoff_reg_timeout.vhd new file mode 100644 index 0000000000..f59127d7b8 --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_dp_xonoff_reg_timeout.vhd @@ -0,0 +1,125 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2010 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- 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, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + + +-- +-- Usage: +-- > as 10 +-- > run -all + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + + + +ENTITY tb_dp_xonoff_reg_timeout IS +END tb_dp_xonoff_reg_timeout; + + +ARCHITECTURE tb OF tb_dp_xonoff_reg_timeout IS + + CONSTANT clk_period : TIME := 20 ns; -- 50 MHz + CONSTANT st_clk_period : TIME := 5000 ps; -- 200 MHz + + + -- Minimum nof clk cycles between eop and sop + CONSTANT c_500ns_latency : NATURAL := 500/20; + CONSTANT c_timeout_2us : NATURAL := 2000/20; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL clk : STD_LOGIC := '1'; + SIGNAL st_clk : STD_LOGIC := '1'; + SIGNAL rst : STD_LOGIC; + + SIGNAL sla_in_mosi : t_mem_mosi := c_mem_mosi_rst; + SIGNAL sla_out_miso : t_mem_miso := c_mem_miso_rst; + + SIGNAL xonoff_reg : STD_LOGIC_VECTOR(0 DOWNTO 0); + +BEGIN + + clk <= NOT clk OR tb_end AFTER clk_period/2; + st_clk <= NOT st_clk OR tb_end AFTER st_clk_period/2; + rst <= '1', '0' AFTER 3*clk_period; + + p_stimuli : PROCESS + BEGIN + + WAIT UNTIL rst='0'; + FOR I IN 0 TO c_500ns_latency-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; + + ---------------------------------------------------------------------------- + -- First + ---------------------------------------------------------------------------- + sla_in_mosi.wrdata(0) <= '1'; + sla_in_mosi.wr <= '1'; + WAIT UNTIL rising_edge(clk); + sla_in_mosi.wrdata(0) <= '0'; + sla_in_mosi.wr <= '0'; + FOR I IN 0 TO c_500ns_latency-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; + ASSERT xonoff_reg(0)='1' REPORT "xonoff_reg was not set correctly" SEVERITY ERROR; + + sla_in_mosi.wrdata(0) <= '1'; + sla_in_mosi.wr <= '1'; + WAIT UNTIL rising_edge(clk); + sla_in_mosi.wrdata(0) <= '0'; + sla_in_mosi.wr <= '0'; + FOR I IN 0 TO c_timeout_2us-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; + ASSERT xonoff_reg(0)='0' REPORT "Timeout did not work" SEVERITY ERROR; + + sla_in_mosi.wrdata(0) <= '1'; + sla_in_mosi.wr <= '1'; + WAIT UNTIL rising_edge(clk); + sla_in_mosi.wrdata(0) <= '0'; + sla_in_mosi.wr <= '0'; + FOR I IN 0 TO c_500ns_latency-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; + ASSERT xonoff_reg(0)='1' REPORT "xonoff_reg was not set correctly after recovering from timeout" SEVERITY ERROR; + tb_end <= '1'; + ASSERT FALSE REPORT "Simulation tb_dp_xonoff_reg_timeout finished." SEVERITY NOTE; + WAIT; + END PROCESS; + + + + + u_dut : ENTITY work.dp_xonoff_reg_timeout + GENERIC MAP ( + g_mm_timeout => 1, + g_sim => TRUE + ) + PORT MAP ( + mm_rst => rst, + mm_clk => clk, + st_rst => rst, + st_clk => st_clk, + + sla_in => sla_in_mosi, + sla_out => sla_out_miso, + + xonoff_reg => xonoff_reg + ); + +END tb; -- GitLab