From a4bf76e9b4408f1d25e706b868f21d809c89abb2 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Thu, 20 Jul 2017 14:25:12 +0000 Subject: [PATCH] Added common_toggle_align.vhd with tb. --- libraries/base/common/hdllib.cfg | 2 + .../common/src/vhdl/common_toggle_align.vhd | 109 +++++++++++++ .../common/tb/vhdl/tb_common_toggle_align.vhd | 144 ++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 libraries/base/common/src/vhdl/common_toggle_align.vhd create mode 100644 libraries/base/common/tb/vhdl/tb_common_toggle_align.vhd diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg index 364afa6f1f..ea74660cd7 100644 --- a/libraries/base/common/hdllib.cfg +++ b/libraries/base/common/hdllib.cfg @@ -56,6 +56,7 @@ synth_files = src/vhdl/common_evt.vhd src/vhdl/common_flank_to_pulse.vhd src/vhdl/common_toggle.vhd + src/vhdl/common_toggle_align.vhd src/vhdl/common_switch.vhd src/vhdl/common_request.vhd src/vhdl/common_counter.vhd @@ -181,6 +182,7 @@ test_bench_files = tb/vhdl/tb_common_spulse.vhd tb/vhdl/tb_common_switch.vhd tb/vhdl/tb_common_toggle.vhd + tb/vhdl/tb_common_toggle_align.vhd tb/vhdl/tb_common_transpose.vhd tb/vhdl/tb_common_transpose_symbol.vhd tb/vhdl/tb_common_zip.vhd diff --git a/libraries/base/common/src/vhdl/common_toggle_align.vhd b/libraries/base/common/src/vhdl/common_toggle_align.vhd new file mode 100644 index 0000000000..54e66471a5 --- /dev/null +++ b/libraries/base/common/src/vhdl/common_toggle_align.vhd @@ -0,0 +1,109 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2017 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra, 20 jul 2017, Created +-- Purpose: Align output to the toggling input and maintain this toggling +-- Description: +-- The in_toggle has a toggle period of g_nof_clk_per_period clk cycles. +-- +-- - When in_align = '1' then the out_toggle follows the in_toggle. +-- - When in_align = '0' then the out_toggle maintains the current toggling +-- independent of in_toggle +-- +-- This compenent can be used to in_align to a certain input phase that is +-- defined by the toggling in_toggle and then maintain this input phase +-- even when in_toggle stops toggling or change phase for some reason. + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + +ENTITY common_toggle_align IS + GENERIC ( + g_pipeline : NATURAL := 1; -- 0 for combinatorial to have out_toggle in phase with in_toggle, > 0 for pipelined out_toggle + g_nof_clk_per_period : NATURAL := 4 -- must be even and >= 2 + ); + PORT ( + rst : IN STD_LOGIC := '0'; + clk : IN STD_LOGIC; + in_align : IN STD_LOGIC; + in_toggle : IN STD_LOGIC; + out_toggle : OUT STD_LOGIC + ); +END; + +ARCHITECTURE rtl OF common_toggle_align IS + + SIGNAL prev_in_toggle : STD_LOGIC; + SIGNAL in_toggle_revt : STD_LOGIC; + + SIGNAL cnt_clr : STD_LOGIC; + SIGNAL cnt : NATURAL RANGE 0 TO g_nof_clk_per_period-1; + SIGNAL nxt_cnt : NATURAL; + + SIGNAL nxt_out_toggle : STD_LOGIC; + +BEGIN + + p_reg : PROCESS(rst, clk) + BEGIN + IF rst='1' THEN + cnt <= 0; + ELSIF rising_edge(clk) THEN + cnt <= nxt_cnt; + prev_in_toggle <= in_toggle; + END IF; + END PROCESS; + + -- detect rising edge of in_toggle period + in_toggle_revt <= '1' WHEN prev_in_toggle='0' AND in_toggle='1' ELSE '0'; + + cnt_clr <= in_align AND in_toggle_revt; + + nxt_cnt <= 0 WHEN cnt_clr='1' OR cnt=g_nof_clk_per_period-1 ELSE cnt+1; + + -- align to input toggle or maintain output toggle + p_out_toggle : PROCESS (in_align, nxt_cnt) + BEGIN + IF in_align='1' THEN + -- align to incomming in_toggle + nxt_out_toggle <= in_toggle; + ELSE + -- maintain phase and period of incomming in_toggle that it was aligned to + IF nxt_cnt<g_nof_clk_per_period/2 THEN + nxt_out_toggle <= '1'; + ELSE + nxt_out_toggle <= '0'; + END IF; + END IF; + END PROCESS; + + u_common_pipeline_sl : ENTITY work.common_pipeline_sl + GENERIC MAP ( + g_pipeline => g_pipeline + ) + PORT MAP ( + rst => rst, + clk => clk, + in_dat => nxt_out_toggle, + out_dat => out_toggle + ); + +END rtl; diff --git a/libraries/base/common/tb/vhdl/tb_common_toggle_align.vhd b/libraries/base/common/tb/vhdl/tb_common_toggle_align.vhd new file mode 100644 index 0000000000..50a885d245 --- /dev/null +++ b/libraries/base/common/tb/vhdl/tb_common_toggle_align.vhd @@ -0,0 +1,144 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2017 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra, 20 jul 2017, Created +-- Purpose: Test bench for common_toggle_align.vhd +-- Usage: +-- > as 10 +-- > run -all +-- Observe out_toggle in Wave Window in relation to in_toggle and align + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE work.common_pkg.ALL; +USE work.tb_common_pkg.ALL; + +ENTITY tb_common_toggle_align IS +END tb_common_toggle_align; + +ARCHITECTURE tb OF tb_common_toggle_align IS + + CONSTANT clk_period : TIME := 10 ns; + + CONSTANT c_interval : NATURAL := 10; + CONSTANT c_pipeline : NATURAL := 0; + CONSTANT c_toggle_period : NATURAL := 4; + CONSTANT c_half_period : NATURAL := c_toggle_period/2; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL rst : STD_LOGIC; + SIGNAL clk : STD_LOGIC := '0'; + SIGNAL in_align : STD_LOGIC; + SIGNAL in_toggle : STD_LOGIC; + SIGNAL out_toggle : STD_LOGIC; + +BEGIN + + clk <= NOT clk OR tb_end AFTER clk_period/2; + rst <= '1', '0' AFTER 7 * clk_period; + + p_in_stimuli : PROCESS + BEGIN + in_align <= '1'; + in_toggle <= '0'; + proc_common_wait_until_low(clk, rst); + proc_common_wait_some_cycles(clk, 10); + + --------------------------------------------------------------------------- + -- align + --------------------------------------------------------------------------- + + in_align <= '1'; + + -- start toggling + FOR I IN 0 TO c_interval-1 LOOP + in_toggle <= NOT in_toggle; + proc_common_wait_some_cycles(clk, c_half_period); + END LOOP; + -- introduce a glitch in the toggling and check that out_toggle remains aligned + proc_common_wait_some_cycles(clk, 1); + FOR I IN 0 TO c_interval-1 LOOP + in_toggle <= NOT in_toggle; + proc_common_wait_some_cycles(clk, c_half_period); + END LOOP; + + --------------------------------------------------------------------------- + -- maintain + --------------------------------------------------------------------------- + in_align <= '0'; + + -- continue toggling + FOR I IN 0 TO c_interval-1 LOOP + in_toggle <= NOT in_toggle; + proc_common_wait_some_cycles(clk, c_half_period); + END LOOP; + -- introduce a glitch in the toggling and check that out_toggle ignores the glitch + proc_common_wait_some_cycles(clk, 1); + FOR I IN 0 TO c_interval-1 LOOP + in_toggle <= NOT in_toggle; + proc_common_wait_some_cycles(clk, c_half_period); + END LOOP; + + --------------------------------------------------------------------------- + -- align again + --------------------------------------------------------------------------- + + in_align <= '1'; + + -- continue toggling and check that out_toggle aligns again + FOR I IN 0 TO c_interval-1 LOOP + in_toggle <= NOT in_toggle; + proc_common_wait_some_cycles(clk, c_half_period); + END LOOP; + + --------------------------------------------------------------------------- + -- stop in_toggle + --------------------------------------------------------------------------- + proc_common_wait_some_cycles(clk, c_half_period*c_interval); + + --------------------------------------------------------------------------- + -- maintain after in_toggle has stopped + --------------------------------------------------------------------------- + in_align <= '0'; + proc_common_wait_some_cycles(clk, c_half_period*c_interval); + + --------------------------------------------------------------------------- + -- end + --------------------------------------------------------------------------- + proc_common_wait_some_cycles(clk, 10); + tb_end <= '1'; + WAIT; + END PROCESS; + + u_toggle : ENTITY work.common_toggle_align + GENERIC MAP ( + g_pipeline => c_pipeline, + g_nof_clk_per_period => c_toggle_period + ) + PORT MAP ( + rst => rst, + clk => clk, + in_align => in_align, + in_toggle => in_toggle, + out_toggle => out_toggle + ); + +END tb; -- GitLab