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

Explained delta-cycles in VHDL simulation.

parent ed30ebb1
Branches
No related tags found
1 merge request!6Master
...@@ -193,6 +193,7 @@ test_bench_files = ...@@ -193,6 +193,7 @@ test_bench_files =
tb/vhdl/tb_requantize.vhd tb/vhdl/tb_requantize.vhd
tb/vhdl/tb_resize.vhd tb/vhdl/tb_resize.vhd
tb/vhdl/tb_round.vhd tb/vhdl/tb_round.vhd
tb/vhdl/tb_delta_cycle_demo.vhd
tb/vhdl/tb_tb_common_add_sub.vhd tb/vhdl/tb_tb_common_add_sub.vhd
tb/vhdl/tb_tb_common_adder_tree.vhd tb/vhdl/tb_tb_common_adder_tree.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Author: E. Kooistra
-- Purpose: Demonstrate harmful effect of delta-cycle difference between a
-- clock and a copied clock and how to solve this.
-- Description:
-- 1) The problem:
-- The assignment of clk2 <= clk1 causes that in simulation clk2 differs from
-- clk1 by one delta cycle and that results in that in simulation d1 /= d2,
-- while on hardware d1 = d2, because the delta cycle on the clk2 does not
-- impact synthesis, because in hardware clk1 and clk2 are the same clock
-- tree. The clk1 is typically a clock that comes from an PLL in the design,
-- so it is generated in the FPGA.
--
-- 2) The solution
-- a)If an assignment like clk2 <= clk1 is done, then make sure that this is
-- the only place where clk1 is used.
--
-- b)For a clk1 that is needed within a certain component and also outside
-- that component there are two solutions:
-- 1) Assign clk2_out <= clk1, where clk2_out is an OUT port on that
-- component. The component then also needs a clk2 IN port and then both
-- clk2_out OUT and clk2 IN are mapped to the same clk2 signal. The clk2
-- signal has the same delta cycle phase inside the component and outside
-- the component, because going through the component IO hierarchy does
-- not cause extra delta-cycles delays. The PORT MAP of the instanciated
-- component then has:
--
-- PORT MAP (
-- ...
-- clk2_out => clk2
-- clk2 => clk2
-- ---
-- );
--
-- and both internally in the component and externally only clk2 is used
-- for clocking logic.
-- 2) Balance the delta-cycle delays, so assign clk2_out <= clk1 for the
-- OUT port and assign clk2_int <= clk1 for internal usage inside this
-- component. Both clk2_out and clk2_int have the same delta-cycle
-- phase, so logic can be clocked at either clock without affecting the
-- timing in simulation.
--
-- Conclusion:
-- Scheme 2b1 is used in ctrl_unb*_board.vhd and in the io_ddr.vhd. However
-- scheme 2b2 is preferred, because it avoids that clk1 has to traverse up
-- and back down the hierarchy of one or more components in an FPGA design,
-- to reach a common single high level that can source the clk1 back down
-- to every where it is used..
--
-- Note that it is not allowed in VHDL to use (read) an OUT port. To read
-- an OUT port it is necessary to use an auxiliary signal, e.g. i_xout for
-- OUT xout and then do x_out <= i_x_out and i_xout can be used internally.
-- This scheme cannot be used for clk2 OUT, because then clk2 <= i_clk2
-- would again cause the delta-cycle delay difference between i_clk2 and
-- clk2 that needs to be avoided. Therefore the solution 2b is needed if a
-- clk2 that is created inside a component (e.g. by an PLL) is also used
-- outside this component.
--
-- Usage:
--
-- Modelsim> as 5
-- Modelsim> run -a
-- Observe in Wave Window that d1 /= d2.
--
-------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY tb_delta_cycle_demo IS
END tb_delta_cycle_demo;
ARCHITECTURE tb OF tb_delta_cycle_demo IS
CONSTANT clk_period : TIME := 10 ns;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL clk1 : STD_LOGIC := '1';
SIGNAL clk2 : STD_LOGIC := '1';
SIGNAL data : STD_LOGIC := '0';
SIGNAL d1 : STD_LOGIC;
SIGNAL d2 : STD_LOGIC;
BEGIN
-- Stimuli
clk1 <= NOT clk1 OR tb_end AFTER clk_period/2;
clk2 <= clk1;
p_data : PROCESS
BEGIN
data <= '0';
FOR I IN 0 TO 2 LOOP WAIT UNTIL rising_edge(clk1); END LOOP;
data <= '1';
FOR I IN 0 TO 2 LOOP WAIT UNTIL rising_edge(clk1); END LOOP;
END PROCESS;
p_clk1 : PROCESS (clk1)
BEGIN
IF rising_edge(clk1) THEN
d1 <= data;
END IF;
END PROCESS;
p_clk2 : PROCESS (clk2)
BEGIN
IF rising_edge(clk2) THEN
d2 <= data;
END IF;
END PROCESS;
tb_end <= '0', '1' AFTER 1 us;
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment