From 6d4fad2cb725799d2c7834cd0918e4036905f24e Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Sun, 14 Aug 2022 21:55:05 +0200 Subject: testsuite/synth: add a test for #2177 --- testsuite/synth/issue2177/clock_functions_pack.vhd | 178 +++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 testsuite/synth/issue2177/clock_functions_pack.vhd (limited to 'testsuite/synth/issue2177/clock_functions_pack.vhd') diff --git a/testsuite/synth/issue2177/clock_functions_pack.vhd b/testsuite/synth/issue2177/clock_functions_pack.vhd new file mode 100644 index 000000000..76ba013f6 --- /dev/null +++ b/testsuite/synth/issue2177/clock_functions_pack.vhd @@ -0,0 +1,178 @@ +---------------------------------------------------------------------- +-- Typedefs and functions for clocks +-- www.fpgaarcade.com +-- All rights reserved. +-- +-- admin@fpgaarcade.com +-- +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this +-- file, You can obtain one at https://mozilla.org/MPL/2.0/. +---------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +package clock_functions_pack is + + ----------------------------------------------------------------------------- + -- Transparent handling of clock enables + -- + -- Basic type def + type r_clk is record + base : std_logic; + val : std_logic; + rise : std_logic; + fall : std_logic; + end record; + constant z_clk : r_clk := ( + base => '0', + val => '0', + rise => '0', + fall => '0'); + + -- Overloaded functions for synchronous process template + function rising_edge(signal clk : r_clk) return boolean; + function falling_edge(signal clk : r_clk) return boolean; + + -- Overloaded functions for boolean arithmetic on clocks + function "not" (clk : r_clk) return r_clk; + -- + function "and" (clk1, clk2 : r_clk) return r_clk; + function "and" (clk1 : r_clk; op2 : std_logic) return r_clk; + function "and" (op1 : std_logic; clk2 : r_clk) return std_logic; + -- + function "nand" (clk1, clk2 : r_clk) return r_clk; + function "nand" (clk1 : r_clk; op2 : std_logic) return r_clk; + function "nand" (op1 : std_logic; clk2 : r_clk) return std_logic; + -- + function "or" (clk1, clk2 : r_clk) return r_clk; + function "or" (clk1 : r_clk; op2 : std_logic) return r_clk; + function "or" (op1 : std_logic; clk2 : r_clk) return std_logic; + -- + function "nor" (clk1, clk2 : r_clk) return r_clk; + function "nor" (clk1 : r_clk; op2 : std_logic) return r_clk; + function "nor" (op1 : std_logic; clk2 : r_clk) return std_logic; + -- + function "=" (clk1 : r_clk; op2 : std_logic) return boolean; + +end; + +package body clock_functions_pack is + + function rising_edge(signal clk : r_clk) return boolean is + begin + return rising_edge(clk.base) and clk.rise = '1'; + end; + + function falling_edge(signal clk : r_clk) return boolean is + begin + return rising_edge(clk.base) and clk.fall = '1'; + end; + + function "not" (clk : r_clk) return r_clk is + begin + return (base => clk.base, + val => not clk.val, + rise => clk.fall, + fall => clk.rise); + end; + + function "and" (clk1, clk2 : r_clk) return r_clk is + begin + return (base => clk1.base, + val => clk1.val and clk2.val, + rise => (clk1.rise and clk2.val and not clk2.fall) or + (clk2.rise and clk1.val and not clk1.fall), + fall => (clk1.fall and clk2.val) or + (clk2.fall and clk1.val)); + end; + + function "and" (clk1 : r_clk; op2 : std_logic) return r_clk is + begin + return (base => clk1.base, + val => clk1.val and op2, + rise => clk1.rise and op2, + fall => clk1.fall and op2); + end; + + function "and" (op1 : std_logic; clk2 : r_clk) return std_logic is + begin + return op1 and clk2.val; + end; + + function "nand" (clk1, clk2 : r_clk) return r_clk is + begin + return (base => clk1.base, + val => clk1.val nand clk2.val, + rise => (clk1.fall and clk2.val) or + (clk2.fall and clk1.val), + fall => (clk1.rise and clk2.val and not clk2.fall) or + (clk2.rise and clk1.val and not clk1.fall)); + end; + + function "nand" (clk1 : r_clk; op2 : std_logic) return r_clk is + begin + return (base => clk1.base, + val => clk1.val nand op2, + rise => clk1.fall and op2, + fall => clk1.rise and op2); + end; + + function "nand" (op1 : std_logic; clk2 : r_clk) return std_logic is + begin + return op1 nand clk2.val; + end; + + function "or" (clk1, clk2 : r_clk) return r_clk is + begin + return (base => clk1.base, + val => clk1.val or clk2.val, + rise => (clk1.rise and not clk2.val) or + (clk2.rise and not clk1.val), + fall => (clk1.fall and not clk2.val and not clk2.rise) or + (clk2.fall and not clk1.val and not clk1.rise)); + end; + + function "or" (clk1 : r_clk; op2 : std_logic) return r_clk is + begin + return (base => clk1.base, + val => clk1.val or op2, + rise => clk1.rise and not op2, + fall => clk1.fall and not op2); + end; + + function "or" (op1 : std_logic; clk2 : r_clk) return std_logic is + begin + return op1 or clk2.val; + end; + + function "nor" (clk1, clk2 : r_clk) return r_clk is + begin + return (base => clk1.base, + val => clk1.val nor clk2.val, + rise => (clk1.fall and not clk2.val and not clk2.rise) or + (clk2.fall and not clk1.val and not clk1.rise), + fall => (clk1.rise and not clk2.val) or + (clk2.rise and not clk1.val)); + end; + + function "nor" (clk1 : r_clk; op2 : std_logic) return r_clk is + begin + return (base => clk1.base, + val => clk1.val nor op2, + rise => clk1.fall and not op2, + fall => clk1.rise and not op2); + end; + + function "nor" (op1 : std_logic; clk2 : r_clk) return std_logic is + begin + return op1 nor clk2.val; + end; + + function "=" (clk1 : r_clk; op2 : std_logic) return boolean is + begin + return clk1.val = op2; + end; + +end; -- cgit v1.2.3