forked from open-logic/open-logic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
olo_base_pkg_logic.vhd
279 lines (241 loc) · 11.2 KB
/
olo_base_pkg_logic.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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
------------------------------------------------------------------------------
-- Copyright (c) 2018 by Paul Scherrer Institute, Switzerland
-- Copyright (c) 2024 by Oliver Bründler
-- All rights reserved.
-- Authors: Oliver Bruendler
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- Description
------------------------------------------------------------------------------
-- Package containing logic functions.
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.olo_base_pkg_math.all;
------------------------------------------------------------------------------
-- Package Header
------------------------------------------------------------------------------
package olo_base_pkg_logic is
function zerosVector(size : in natural) return std_logic_vector;
function onesVector(size : in natural) return std_logic_vector;
function shiftLeft( arg : in std_logic_vector;
bits : in integer;
fill : in std_logic := '0')
return std_logic_vector;
function shiftRight( arg : in std_logic_vector;
bits : in integer;
fill : in std_logic := '0')
return std_logic_vector;
function binaryToGray(binary : in std_logic_vector) return std_logic_vector;
function grayToBinary(gray : in std_logic_vector) return std_logic_vector;
-- Parallel Prefix Computation of the OR function
-- Input --> Output
-- 0100 --> 0111
-- 0101 --> 0111
-- 0011 --> 0011
-- 0010 --> 0011
function ppcOr(inp : in std_logic_vector) return std_logic_vector;
function reduceOr(vec : in std_logic_vector) return std_logic;
function reduceAnd(vec : in std_logic_vector) return std_logic;
function reduceXor(vec : in std_logic_vector) return std_logic;
function to01X(inp : in std_logic) return std_logic;
function to01X(inp : in std_logic_vector) return std_logic_vector;
function to01(inp : in std_logic) return std_logic;
function to01(inp : in std_logic_vector) return std_logic_vector;
function invertBitOrder(inp : in std_logic_vector) return std_logic_vector;
-- LFSR / CRC / PRBS Polynomials
-- 1 for the x^n positions used
constant Polynomial_Prbs2_c : std_logic_vector( 1 downto 0) := "11";
constant Polynomial_Prbs3_c : std_logic_vector( 2 downto 0) := "110";
constant Polynomial_Prbs4_c : std_logic_vector( 3 downto 0) := "1100";
constant Polynomial_Prbs5_c : std_logic_vector( 4 downto 0) := "10100";
constant Polynomial_Prbs6_c : std_logic_vector( 5 downto 0) := "110000";
constant Polynomial_Prbs7_c : std_logic_vector( 6 downto 0) := "1100000";
constant Polynomial_Prbs8_c : std_logic_vector( 7 downto 0) := "10111000";
constant Polynomial_Prbs9_c : std_logic_vector( 8 downto 0) := "100010000";
constant Polynomial_Prbs10_c : std_logic_vector( 9 downto 0) := "1001000000";
constant Polynomial_Prbs11_c : std_logic_vector(10 downto 0) := "10100000000";
constant Polynomial_Prbs12_c : std_logic_vector(11 downto 0) := "100000101001";
constant Polynomial_Prbs13_c : std_logic_vector(12 downto 0) := "1000000001101";
constant Polynomial_Prbs14_c : std_logic_vector(13 downto 0) := "10000000010101";
constant Polynomial_Prbs15_c : std_logic_vector(14 downto 0) := "110000000000000";
constant Polynomial_Prbs16_c : std_logic_vector(15 downto 0) := "1101000000001000";
constant Polynomial_Prbs17_c : std_logic_vector(16 downto 0) := "10010000000000000";
constant Polynomial_Prbs18_c : std_logic_vector(17 downto 0) := "100000010000000000";
constant Polynomial_Prbs19_c : std_logic_vector(18 downto 0) := "1000000000000100011";
constant Polynomial_Prbs20_c : std_logic_vector(19 downto 0) := "10010000000000000000";
constant Polynomial_Prbs21_c : std_logic_vector(20 downto 0) := "101000000000000000000";
constant Polynomial_Prbs22_c : std_logic_vector(21 downto 0) := "1100000000000000000000";
constant Polynomial_Prbs23_c : std_logic_vector(22 downto 0) := "10000100000000000000000";
constant Polynomial_Prbs24_c : std_logic_vector(23 downto 0) := "111000010000000000000000";
constant Polynomial_Prbs25_c : std_logic_vector(24 downto 0) := "1001000000000000000000000";
constant Polynomial_Prbs26_c : std_logic_vector(25 downto 0) := "10000000000000000000100011";
constant Polynomial_Prbs27_c : std_logic_vector(26 downto 0) := "100000000000000000000010011";
constant Polynomial_Prbs28_c : std_logic_vector(27 downto 0) := "1001000000000000000000000000";
constant Polynomial_Prbs29_c : std_logic_vector(28 downto 0) := "10100000000000000000000000000";
constant Polynomial_Prbs30_c : std_logic_vector(29 downto 0) := "100000000000000000000000101001";
constant Polynomial_Prbs31_c : std_logic_vector(30 downto 0) := "1001000000000000000000000000000";
constant Polynomial_Prbs32_c : std_logic_vector(31 downto 0) := "10000000001000000000000000000011";
end olo_base_pkg_logic;
------------------------------------------------------------------------------
-- Package Body
------------------------------------------------------------------------------
package body olo_base_pkg_logic is
-- *** ZerosVector ***
function zerosVector(size : in natural) return std_logic_vector is
constant c : std_logic_vector(size - 1 downto 0) := (others => '0');
begin
return c;
end function;
-- *** OnesVector ***
function onesVector(size : in natural) return std_logic_vector is
constant c : std_logic_vector(size - 1 downto 0) := (others => '1');
begin
return c;
end function;
-- *** ShiftLeft ***
function shiftLeft( arg : in std_logic_vector;
bits : in integer;
fill : in std_logic := '0')
return std_logic_vector is
constant argDt : std_logic_vector(arg'high downto arg'low) := arg;
variable v : std_logic_vector(argDt'range);
begin
if bits < 0 then
return shiftRight(argDt, -bits, fill);
else
v(v'left downto bits) := argDt(argDt'left - bits downto argDt'right);
v(bits - 1 downto v'right) := (others => fill);
return v;
end if;
end function;
-- *** ShiftRight ***
function shiftRight( arg : in std_logic_vector;
bits : in integer;
fill : in std_logic := '0')
return std_logic_vector is
constant argDt : std_logic_vector(arg'high downto arg'low) := arg;
variable v : std_logic_vector(argDt'range);
begin
if bits < 0 then
return shiftLeft(argDt, -bits, fill);
else
v(v'left - bits downto v'right) := argDt(argDt'left downto bits);
v(v'left downto v'left - bits + 1) := (others => fill);
return v;
end if;
end function;
-- *** BinaryToGray ***
function binaryToGray(binary : in std_logic_vector) return std_logic_vector is
variable Gray_v : std_logic_vector(binary'range);
begin
Gray_v := binary xor ('0' & binary(binary'high downto binary'low + 1));
return Gray_v;
end function;
-- *** GrayToBinary ***
function grayToBinary(gray : in std_logic_vector) return std_logic_vector is
variable Binary_v : std_logic_vector(gray'range);
begin
Binary_v(Binary_v'high) := gray(gray'high);
for b in gray'high - 1 downto gray'low loop
Binary_v(b) := gray(b) xor Binary_v(b + 1);
end loop;
return Binary_v;
end function;
-- *** PpcOr ***
function ppcOr(inp : in std_logic_vector) return std_logic_vector is
constant Stages_c : integer := log2ceil(inp'length);
constant Pwr2Width_c : integer := 2**Stages_c;
type StageOut_t is array (natural range <>) of std_logic_vector(Pwr2Width_c - 1 downto 0);
variable StageOut_v : StageOut_t(0 to Stages_c);
variable BinCnt_v : unsigned(Pwr2Width_c - 1 downto 0);
begin
StageOut_v(0) := (others => '0');
StageOut_v(0)(inp'length - 1 downto 0) := inp;
for stage in 0 to Stages_c - 1 loop
BinCnt_v := (others => '0');
for idx in 0 to Pwr2Width_c - 1 loop
if BinCnt_v(stage) = '0' then
StageOut_v(stage + 1)(idx) := StageOut_v(stage)(idx) or StageOut_v(stage)((idx / (2**stage) + 1) * 2**stage);
else
StageOut_v(stage + 1)(idx) := StageOut_v(stage)(idx);
end if;
BinCnt_v := BinCnt_v + 1;
end loop;
end loop;
return StageOut_v(Stages_c)(inp'length - 1 downto 0);
end function;
function reduceOr(vec : in std_logic_vector) return std_logic is
variable tmp : std_logic;
begin
tmp := '0';
for i in vec'low to vec'high loop
tmp := tmp or vec(i);
end loop;
return tmp;
end function;
function reduceAnd(vec : in std_logic_vector) return std_logic is
variable tmp : std_logic;
begin
tmp := '1';
for i in vec'low to vec'high loop
tmp := tmp and vec(i);
end loop;
return tmp;
end function;
function reduceXor(vec : in std_logic_vector) return std_logic is
variable tmp : std_logic;
begin
tmp := '0';
for i in vec'low to vec'high loop
tmp := tmp xor vec(i);
end loop;
return tmp;
end function;
function to01X(inp : in std_logic) return std_logic is
begin
case inp is
when '0' | 'L' => return '0';
when '1' | 'H' => return '1';
when others => return 'X';
end case;
end function;
function to01X(inp : in std_logic_vector) return std_logic_vector is
variable tmp : std_logic_vector(inp'range);
begin
for i in inp'low to inp'high loop
tmp(i) := to01X(inp(i));
end loop;
return tmp;
end function;
function to01(inp : in std_logic) return std_logic is
begin
case inp is
when '0' | 'L' => return '0';
when '1' | 'H' => return '1';
when others => return '0';
end case;
end function;
function to01(inp : in std_logic_vector) return std_logic_vector is
variable tmp : std_logic_vector(inp'range);
begin
for i in inp'low to inp'high loop
tmp(i) := to01(inp(i));
end loop;
return tmp;
end function;
function invertBitOrder(inp : in std_logic_vector) return std_logic_vector is
variable inp_v : std_logic_vector(inp'length-1 downto 0);
variable tmp : std_logic_vector(inp_v'range);
begin
inp_v := inp;
for i in 0 to inp_v'high loop
tmp(tmp'high - i) := inp_v(i);
end loop;
return tmp;
end function;
end package body;