-
Notifications
You must be signed in to change notification settings - Fork 0
/
firebee_utils_pkg.vhd
170 lines (153 loc) · 7.04 KB
/
firebee_utils_pkg.vhd
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
----------------------------------------------------------------------
---- ----
---- This file is part of the 'Firebee' project. ----
---- http://acp.atari.org ----
---- ----
---- Description: ----
---- This package contains utility functions, procedures and constants
---- for the Firebee project.
----
---- Author(s): ----
---- - Markus Froeschle, [email protected]
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2015 Markus Froeschle
---- ----
---- This source file 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 2 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, write to the Free ----
---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ----
---- Boston, MA 02110-1301, USA. ----
---- ----
----------------------------------------------------------------------
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package firebee_utils_pkg is
function f_addr_cmp_l(signal addr : std_logic_vector; constant addr_const : std_logic_vector) return std_logic;
function f_addr_cmp_w(signal addr : std_logic_vector; constant addr_const : std_logic_vector) return std_logic;
function f_addr_cmp_b(signal addr : std_logic_vector; constant addr_const : std_logic_vector) return std_logic;
function f_addr_cmp_mask(signal addr : std_logic_vector; constant addr_const : std_logic_vector; constant num_ignore : integer) return std_logic;
function max(left : integer; right : integer) return integer;
function min(left : integer; right : integer) return integer;
component synchronizer IS
PORT
(
-- Input ports
source_signal : in std_logic;
target_clock : in std_logic;
target_signal : out std_logic
);
end component synchronizer;
-- size constants for the TSIZE vector
type tsize_t is (SIZE_LONG, SIZE_WORD, SIZE_BYTE, SIZE_LINE, SIZE_TRISTATE);
attribute enum_encoding : string;
attribute enum_encoding of tsize_t: type is "00 10 01 11 ZZ";
-- constant SIZE_LONG : std_logic_vector(1 downto 0) := "00";
-- constant SIZE_WORD : std_logic_vector(1 downto 0) := "10";
-- constant SIZE_BYTE : std_logic_vector(1 downto 0) := "01";
-- constant SIZE_LINE : std_logic_vector(1 downto 0) := "11";
end firebee_utils_pkg;
package body firebee_utils_pkg is
-- returns the smaller of two integers
function min(left : integer; right : integer) return integer is
begin
if left < right then
return left;
else
return right;
end if;
end function min;
-- returns the larger of two integers
function max(left : integer; right : integer) return integer is
begin
if left > right then
return left;
else
return right;
end if;
end function max;
-- returns the number of bits needed to represent n
function log2ceil(n : natural) return natural is
variable n_bit : unsigned(31 downto 0);
begin -- log2ceil
if n = 0 then
return 0;
end if;
n_bit := to_unsigned(n-1,32);
for i in 31 downto 0 loop
if n_bit(i) = '1' then
return i + 1;
end if;
end loop; -- i
return 1;
end log2ceil;
-- this is for arbitrary sized address compares. It compares from the highest bit of addr_const to the lowest - num_ignore
-- bit, thus allowing any size of comparision.
function f_addr_cmp_mask(signal addr : std_logic_vector;
constant addr_const : std_logic_vector;
constant num_ignore : integer
) return std_logic is
variable ret : std_logic := '1';
variable hi : integer;
variable lo : integer;
begin
hi := min(addr_const'high, addr'high);
lo := max(addr_const'low, addr'low);
-- report("faddr_cmp_mask(): hi = " & to_string(hi) & " lo = " & to_string(lo) & " log2ceil(num_ignore) = " & to_string(log2ceil(num_ignore)));
l_loop: for i in hi downto lo + log2ceil(num_ignore) - 1 loop
if addr(i) /= addr_const(i) then
-- synthesis translate_off
-- report("f_addr_cmp_mask(): addr = " & to_hstring(unsigned(addr)) & " differs from addr_const = " & to_hstring(unsigned(addr_const)) &
-- " at bit = " & integer'image(i));
-- report("addr(" & integer'image(i) & ") (" & to_string(addr) & ") = " & to_string(addr(i)) &
-- " addr_const(" & integer'image(i) & ") ( " & to_string(addr_const) & ") = " & to_string(addr_const(i)));
-- synthesis translate_on
ret := '0';
exit l_loop;
else
-- pragma synthesis off
-- report("f_addr_cmp_mask(): addr = " & to_hstring(unsigned(addr)) & " equals to addr_const = " & to_hstring(unsigned(addr_const)) &
-- " at bit = " & integer'image(i));
-- report("addr(" & integer'image(i) & ") (" & to_string(addr) & ") = " & to_string(addr(i)) &
-- " addr_const(" & integer'image(i) & ") ( " & to_string(addr_const) & ") = " & to_string(addr_const(i)));
-- pragma synthesis on
end if;
end loop;
-- pragma synthesis off
report("f_addr_cmp_mask(" & to_hstring(unsigned(addr)) & ", " & to_hstring(unsigned(addr_const)) & "): return " & to_string(ret));
-- pragma synthesis on
return ret;
end function f_addr_cmp_mask;
function f_addr_cmp_l(signal addr : std_logic_vector;
constant addr_const : std_logic_vector
) return std_logic is
begin
return f_addr_cmp_mask(addr, addr_const, 2);
end function f_addr_cmp_l;
function f_addr_cmp_w(signal addr : std_logic_vector;
constant addr_const : std_logic_vector
) return std_logic is
begin
return f_addr_cmp_mask(addr, addr_const, 1);
end function f_addr_cmp_w;
function f_addr_cmp_b(signal addr : std_logic_vector;
constant addr_const : std_logic_vector
) return std_logic is
begin
return f_addr_cmp_mask(addr, addr_const, 0);
end function f_addr_cmp_b;
end package body firebee_utils_pkg;