aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth/issue2177/clock_functions_pack.vhd
blob: 76ba013f6838de0f8e42019a126c46fe3754dc07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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;