Useful VHDL Functions

代码
1 -----------------------------------------------------
2  --Generated by Utility gen_entity.pl by Aviral Mittal
3  -----------------------------------------------------
4 --Following is a pkg file, defining some commonly used vhdl functions.
5 -- Version 2.0
6 --
7 --
8 --------------------------------------------------------------------------------
9 -- Changes wrt prev release.
10 -- 2.0 : new functions added
11 -- sext : Sign Extend
12 -- bit_reverse : Reverse the order of bits of a vector
13 -- shln : shift left by 'n' bits
14 -- ccitt_crc_16 : CRC
15 -- Date : 28 Oct 2009
16 --
17 --
18 -- 1.0 a new function addition called tc i.e twos compliment.
19 -- Date of Release 18 Jan 2006
20 --------------------------------------------------------------------------------
21 --$Author: amittal $
22 --------------------------------------------------------------------------------
23 --$Date: Fri May 1 20:23:09 2009 $
24 --------------------------------------------------------------------------------
25 --$Revision: 1.5 $
26 --------------------------------------------------------------------------------
27 --$Log: fun_pkg.vhdl.rca $
28 --
29 -- Revision: 1.5 Fri May 1 20:23:09 2009 amittal
30 -- made shln synthesizeable
31 --
32 -- Revision: 1.4 Fri Jan 30 13:58:41 2009 amittal
33 -- corrected ccitt_crc_16 function
34 --
35 -- Revision: 1.2 Fri Jul 11 11:14:01 2008 amittal
36 -- Added Shift functions
37 --------------------------------------------------------------------------------
38 --$Revision: 1.5 $
39 --------------------------------------------------------------------------------
40 --$KeysEnd$
41 --------------------------------------------------------------------------------
42 --------------------------------------------------------------------------------
43 LIBRARY IEEE;
44 USE IEEE.STD_LOGIC_1164.ALL;
45 PACKAGE fun_pkg IS
46 FUNCTION NextGray(G1:std_logic_vector) return std_logic_vector;
47 --this function implements a length independent gray counter.
48 --No arithmatic operators are used.
49 FUNCTION bin2gray(B1:std_logic_vector) return std_logic_vector;
50 --this function converts a binary count to gray count
51 FUNCTION gray2bin(G1:std_logic_vector) return std_logic_vector;
52 --this function converts a gray count to binary count
53 FUNCTION crr(s1:std_logic_vector;index:integer) return std_logic_vector;
54 --crr=CircularRotateRight
55 --this function Circular Rotates Right 's1' by 'index'
56 FUNCTION crl(s1:std_logic_vector;index:integer) return std_logic_vector;
57 --crl=CircularRotateLeft
58 --this function Circular Rotates Right 's1' by 'index'
59 FUNCTION incr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector;
60 --This function increments an std_logic_vector type by '1', without
61 --using any arithmatic
62 FUNCTION dcr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector;
63 --This function decrements an std_logic_vector type by '1', without
64 --using any arithmatic
65 FUNCTION all_ones(s1:std_logic_vector) return std_logic;
66 --This function returns if the input vector has all ones and no zeros
67 FUNCTION all_zeros(s1:std_logic_vector) return std_logic;
68 --This function returns if the input vector has all zeros and no ones
69 FUNCTION mux1(a0:std_logic;a1:std_logic;sel:std_logic) return std_logic;
70 --one bit mux, handy to be used in combinational assignmets
71 FUNCTION mux_vec(a0:std_logic_vector;a1:std_logic_vector;sel:std_logic) return std_logic_vector;
72 --multi bit mux, handy to be used in combinational assignmets
73 FUNCTION if_eq(s1:std_logic_vector;s2:std_logic_vector) return std_logic;
74 --returns a '1' iff s1=s2(s1 and s2 MUST be of equal no of bits
75 FUNCTION inv_if_one(s1:std_logic_vector;en:std_logic) return std_logic_vector;
76 --retruns a 1's compilment of s1, if en is '1' otherwise s1 as such is returned
77 FUNCTION inv(s1:std_logic_vector) return std_logic_vector;
78 --retruns a 1's compilment of s1 i.e invert of s1;
79 FUNCTION myabs(s1:std_logic_vector) return std_logic_vector;
80 --this function returns an absolute value of a vector
81 FUNCTION twos_comp(s1:std_logic_vector) return std_logic_vector;
82 --returns a twos compliment of s1
83 --To make things more clear: It returns s1 itself if s1(s1'high) = '0'. Since
84 --if s1(s1'high) i.e msb of s1 is '0', then the input no is +ive and hence
85 --no processing is done on s1. On the other hand, if s1(s1'high) is -ive
86 --then each bit in s1 is inverted and then s1 is inremented by '1'
87 FUNCTION tc(s1:std_logic_vector) return std_logic_vector;
88 --returns a twos compliment of a s1.
89 --No matter if the input is -ive or +ive. It will return a
90 --twos compliment of the input vector.
91 --IE if the input number is -ive, output will be +ive number
92 --if the input number is +ive, the output will be a -ive number
93 --
94 FUNCTION sshr(s1:std_logic_vector) return std_logic_vector;
95 -- Signed Shift right
96 -- performes shift right i.e >> i.e / 2, msb = 0, suitable for signed;
97 FUNCTION zshr(s1:std_logic_vector) return std_logic_vector;
98 -- UnSigned Shift right
99 -- performes shift right i.e >> i.e / 2, msb = 0, suitable for unsigned;
100 FUNCTION shl(s1:std_logic_vector) return std_logic_vector;
101 -- performes shift left i.e << i.e x 2, lsb = 0;
102 FUNCTION csshr(s1:std_logic_vector;s2:std_logic) return std_logic_vector;
103 -- Conditional Signed Shift right, if s2= 1, shift, otherwise return original
104 -- performes shift right i.e >> i.e / 2, msb = 0, suitable for signed;
105 FUNCTION czshr(s1:std_logic_vector;s2:std_logic) return std_logic_vector;
106 -- Conditional UnSigned Shift right;shift when s2 = '1'
107 -- performes shift right i.e >> i.e / 2, msb = 0, suitable for unsigned;
108 FUNCTION zshrn(s1:std_logic_vector;n:integer) return std_logic_vector;
109 -- UnSigned Shift right by n bits
110 -- performes shift right i.e >> i.e / 2, msb = 0, suitable for unsigned;
111 FUNCTION sshrn(s1:std_logic_vector;nn:integer) return std_logic_vector;
112 -- Signed Shift right by n bits
113 -- performes shift right i.e >> i.e / 2, msb = 0, suitable for signed;
114 FUNCTION sext(s1:std_logic_vector;nn:integer) return std_logic_vector;
115 -- sign extend an std_logic_vector by nn bits
116 -- Example s1 = 10101010, nn = 3, return = 11110101010
117 FUNCTION shln(s1:std_logic_vector;nn:integer) return std_logic_vector;
118 -- shift left by nn bits, add nn 0s to LSBs
119 -- Example s1 = 11111101, nn = 3, return = 11101000
120 FUNCTION ccitt_crc_16(s1:std_logic_vector;ser_in:std_logic) return std_logic_vector;
121 --Calculates the next CRC value as per ccitt_crc_16
122 --X^16 + X^12 + X^5 + 1
123 FUNCTION bit_reverse(s1:std_logic_vector) return std_logic_vector;
124 --It reverses the bits of std_logic_vector
125 --ie LSB becomes MSB and vice-versa
126 --Example 01100000 becomes 00000110
127 END fun_pkg;
128 PACKAGE body fun_pkg IS
129 --Function Declaration Section
130 FUNCTION bin2gray(B1:std_logic_vector) return std_logic_vector is
131 VARIABLE G1 : std_logic_vector(B1'high downto B1'low) ;
132 BEGIN
133 G1(G1'high):=B1(B1'high);
134 for i in B1'high-1 downto B1'low loop
135 G1(i) := B1(i+1) XOR B1(i);
136 end loop;
137 return G1;
138 end bin2gray; -- end function
139 FUNCTION gray2bin(G1:std_logic_vector) return std_logic_vector is
140 VARIABLE B1 : std_logic_vector(G1'high downto G1'low) ;
141 BEGIN
142 B1(G1'high):=G1(B1'high);
143 for i in G1'high-1 downto G1'low loop
144 B1(i) := B1(i+1) XOR G1(i);
145 end loop;
146 return B1;
147 end gray2bin; -- end function
148 FUNCTION crr(s1:std_logic_vector;index:integer) return std_logic_vector is
149 --crr=CircularRotateRight
150 --this function Circular Rotates Right 's1' by 'index'
151 variable z : std_logic_vector(s1'high downto s1'low);
152 begin
153 --pragma translate_off
154 --pragma coverage_off
155 if(index >= s1'length) then
156 assert false
157 report "crr: rotate index is greater than variable length can't rotate" severity error;
158 end if;
159 if(index < 0) then
160 assert false
161 report "crr: rotate index is negative,can't rotate" severity error;
162 end if;
163 --pragma coverage_on
164 --pragma translate_on
165 if(index = 0) then
166 z:=s1;
167 else
168 for jj in 1 to s1'high loop
169 z:= s1(jj-1 downto 0) & s1(s1'high downto jj);
170 if(jj = index) then
171 exit;
172 end if;
173 end loop;
174 end if;
175 return z;
176 end crr; -- end function
177 function crl(s1:std_logic_vector;index:integer) return std_logic_vector is
178 --crl=CircularRotateLeft
179 --this function Circular Rotates Right 's1' by 'index'
180 variable z : std_logic_vector(s1'high downto s1'low);
181 begin
182 --pragma translate_off
183 --pragma coverage_off
184 if(index >= s1'length) then
185 assert false
186 report "crl: rotate index is greater than variable length can't rotate" severity error;
187 end if;
188 if(index < 0) then
189 assert false
190 report "crl: rotate index is negative,can't rotate" severity error;
191 end if;
192 --pragma coverage_on
193 --pragma translate_on
194 if(index = 0) then
195 z:=s1;
196 else
197 for jj in 1 to s1'high loop
198 z:= s1(s1'high-jj downto 0) & s1(s1'high downto s1'high-jj+1);
199 if(jj = index) then
200 exit;
201 end if;
202 end loop;
203 end if;
204 return z;
205 end crl; -- end function
206
207
208
209 FUNCTION incr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector is
210 --this function increments a std_logic_vector type by '1'
211 VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
212 VARIABLE tb : std_logic_vector(s1'high downto s1'low);
213 BEGIN
214 tb(s1'low) := en;
215 V := s1;
216 for i in (V'low + 1) to V'high loop
217 tb(i) := V(i - 1) and tb(i -1);
218 end loop;
219 for i in V'low to V'high loop
220 if(tb(i) = '1') then
221 V(i) := not(V(i));
222 end if;
223 end loop;
224 return V;
225 end incr_vec; -- end function
226 FUNCTION dcr_vec(s1:std_logic_vector;en:std_logic) return std_logic_vector is
227 --this function decrements a std_logic_vector type by '1'
228 VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
229 VARIABLE tb : std_logic_vector(s1'high downto s1'low);
230 BEGIN
231 tb(s1'low) := not(en);
232 V := s1;
233 for i in (V'low + 1) to V'high loop
234 tb(i) := V(i - 1) or tb(i -1);
235 end loop;
236 for i in V'low to V'high loop
237 if(tb(i) = '0') then
238 V(i) := not(V(i));
239 end if;
240 end loop;
241 return V;
242 end dcr_vec; -- end function
243 FUNCTION all_ones(s1:std_logic_vector) return std_logic is
244 --this function tells if all bits of a vector are '1'
245 --return value Z is '1', then vector has all 1 bits
246 --VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
247 VARIABLE Z : std_logic;
248 BEGIN
249 Z := s1(s1'low);
250 FOR i IN (s1'low+1) to s1'high LOOP
251 Z := Z AND s1(i);
252 END LOOP;
253 RETURN Z;
254 END all_ones; -- end function
255 FUNCTION all_zeros(s1:std_logic_vector) return std_logic is
256 --this function tells if all bits of a vector are '0'
257 --return value Z if '1', then vector has all 0 bits
258 --VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
259 VARIABLE Z : std_logic;
260 BEGIN
261 Z := '0';
262 FOR i IN (s1'low) to s1'high LOOP
263 Z := Z OR s1(i);
264 END LOOP;
265 RETURN not(Z);
266 END all_zeros; -- end function
267 FUNCTION mux1(a0:std_logic;a1:std_logic;sel:std_logic) return std_logic is
268 --a 1 bit mux, handy to be used combinational assignments.
269 --output = a0, if sel = 0,
270 --output = a1,if sel = 1.
271 VARIABLE Z: std_logic;
272 BEGIN
273 IF(sel = '0') THEN
274 Z := a0;
275 ELSE
276 Z := a1;
277 END IF;
278 RETURN Z;
279 END mux1; -- end function
280 FUNCTION mux_vec(a0:std_logic_vector;a1:std_logic_vector;sel:std_logic)
281 return std_logic_vector is
282 --a vectored mux, handy to be used combinational assignments.
283 --output = a0, if sel = 0,
284 --output = a1,if sel = 1.
285 VARIABLE Z: std_logic_vector(a0'high downto a0'low);
286 BEGIN
287 IF(sel = '0') THEN
288 Z := a0;
289 ELSE
290 Z := a1;
291 END IF;
292 RETURN Z;
293 END mux_vec; -- end function
294 FUNCTION if_eq(s1:std_logic_vector;s2:std_logic_vector) return std_logic is
295 --this function returns a value of '1' if the passed
296 --input1 vector is equal to the input2 value
297 --Usage:
298 -- mybit = if_eq(sig1,const1);
299 -- where sig1 and const1 are equal in widths
300 -- This function works only with 'constant' types
301 -- The function must be passed a 'constant' type
302 -- for its variable 'const1', otherwise potential problems may
303 -- arise
304 VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
305 VARIABLE Z : std_logic;
306 BEGIN
307 FOR i IN (s1'high) downto (s1'low) LOOP
308 V(i) := s1(i) XOR s2(i);
309 END LOOP;
310 Z := all_zeros(V);
311 RETURN Z;
312 END if_eq; -- end function
313 FUNCTION inv_if_one(s1:std_logic_vector;en:std_logic) return std_logic_vector is
314 --this function inverts all the bits of a vector if
315 --'en' is '1'.
316 VARIABLE Z : std_logic_vector(s1'high downto s1'low);
317 BEGIN
318 FOR i IN (s1'low) to s1'high LOOP
319 Z(i) := en XOR s1(i);
320 END LOOP;
321 RETURN Z;
322 END inv_if_one; -- end function
323 FUNCTION inv(s1:std_logic_vector) return std_logic_vector is
324 --this function inverts all the bits of input vector
325 VARIABLE Z : std_logic_vector(s1'high downto s1'low);
326 BEGIN
327 FOR i IN (s1'low) to s1'high LOOP
328 Z(i) := NOT(s1(i));
329 END LOOP;
330 RETURN Z;
331 END inv; -- end function
332 FUNCTION twos_comp(s1:std_logic_vector) return std_logic_vector is
333 VARIABLE Z : std_logic_vector(s1'high downto s1'low);
334 --Finds twos compliment of an std_logic_vector type.
335 --will do nothing to +ive numbers.(which have their msb='0'
336 BEGIN
337 Z := inv_if_one(s1,s1(s1'high));
338 Z := incr_vec(Z,s1(s1'high));
339 RETURN Z;
340 END twos_comp; -- end function
341 FUNCTION tc(s1:std_logic_vector) return std_logic_vector is
342 VARIABLE Z : std_logic_vector(s1'high downto s1'low);
343 --Finds twos compliment of an std_logic_vector type.
344 --No matter input is -ive or +ive, it will always return
345 --output = NOT(input) + 1;
346 BEGIN
347 Z := inv(s1);
348 Z := incr_vec(Z,'1');
349 RETURN Z;
350 END tc; -- end function
351 FUNCTION myabs(s1:std_logic_vector) return std_logic_vector is
352 --this function returns an absolute value of a vector
353 --This is same as the function 'twos_comp' above
354 VARIABLE V : std_logic_vector(s1'high downto s1'low) ;
355 BEGIN
356 for i in V'low to V'high loop
357 V(i) := s1(i) XOR s1(s1'high);
358 end loop;
359 V := incr_vec(V,s1(s1'high));
360 return V;
361 end myabs; -- end function
362 FUNCTION NextGray(G1:std_logic_vector) return std_logic_vector is
363 VARIABLE G2 : std_logic_vector(G1'high downto G1'low) ;
364 VARIABLE B1 : std_logic_vector(G1'high downto G1'low) ;
365 VARIABLE tb : std_logic_vector(G1'high downto G1'low);
366 BEGIN
367 if(G1'length <= 2) then
368 assert false
369 report "NextGray: Min Vector Length in Function is 3" severity error;
370 end if;
371 if(all_zeros(not(G1(G1'high)) & G1(G1'high-1 downto G1'low)) = '1') then
372 G2 := (others => '0');
373 return G2;
374 end if;
375 B1 := gray2bin(G1);
376 tb(G1'low) := not(B1(B1'low));
377 tb(G1'low + 1) := G1(G1'low) and B1(B1'low);
378 for i in (G1'low + 2) to G1'high loop
379 tb(i) := all_zeros( not(G1(i-1)) & G1(i-2 downto G1'low) & not(B1(B1'low)) );
380 end loop;
381 G2:=G1;
382 for i in G1'low to G1'high loop
383 if(tb(i) = '1') then
384 G2(i) := not(G2(i));
385 end if;
386 end loop;
387 return G2;
388 end NextGray; -- end function
389 FUNCTION sshr(s1:std_logic_vector) return std_logic_vector is
390 variable r : std_logic_vector(s1'high downto s1'low);
391 begin
392 r(r'high) := s1(s1'high);
393 r(r'high -1 downto 0) := s1(s1'high downto 1);
394 return r;
395 end sshr;
396 FUNCTION csshr(s1:std_logic_vector;s2:std_logic) return std_logic_vector is
397 variable r : std_logic_vector(s1'high downto s1'low);
398 begin
399 if(s2 = '1') then
400 r(r'high) := s1(s1'high);
401 r(r'high -1 downto 0) := s1(s1'high downto 1);
402 else
403 r := s1;
404 end if;
405 return r;
406 end csshr;
407 FUNCTION zshr(s1:std_logic_vector) return std_logic_vector is
408 variable r : std_logic_vector(s1'high downto s1'low);
409 begin
410 r(r'high) := '0';
411 r(r'high -1 downto 0) := s1(s1'high downto 1);
412 return r;
413 end zshr;
414 FUNCTION czshr(s1:std_logic_vector;s2:std_logic) return std_logic_vector is
415 variable r : std_logic_vector(s1'high downto s1'low);
416 begin
417 if(s2 = '1') then
418 r(r'high) := '0';
419 r(r'high -1 downto 0) := s1(s1'high downto 1);
420 else
421 r := s1;
422 end if;
423 return r;
424 end czshr;
425 --------------------------------------------------------------------------------
426 --IMP NOTE: the following function zshrn is not synthesizeable at the moment
427 --------------------------------------------------------------------------------
428 FUNCTION zshrn(s1:std_logic_vector;n:integer) return std_logic_vector is
429 --------------------------------------------------------------------------------
430 variable r : std_logic_vector(s1'high downto s1'low);
431 begin
432 --pragma translate_off
433 --pragma coverage_off
434 if(n < 0) then
435 assert false
436 report "zshrn: shift index is negative,can't rotate" severity error;
437 end if;
438 --pragma translate_on
439 --pragma coverage_on
440 r := s1;
441 if(n = 0) then
442 return r;
443 end if;
444 r(r'high downto r'high-(n-1)) := (others => '0');
445 r(r'high -n downto 0) := s1(s1'high downto n);
446 return r;
447 end zshrn;
448 FUNCTION sshrn(s1:std_logic_vector;nn:integer) return std_logic_vector is
449 variable rr : std_logic_vector(s1'high downto s1'low);
450 begin
451 --pragma translate_off
452 --pragma coverage_off
453 if(nn < 0) then
454 assert false
455 report "sshrn: shift index is negative,can't rotate" severity error;
456 end if;
457 --pragma translate_on
458 --pragma coverage_on
459 if(nn = 0) then
460 rr := s1;
461 else
462 rr := (others => s1(s1'high));
463 for ii in s1'high downto 0 loop
464 rr(ii-nn) := s1(ii);
465 if(ii = nn) then
466 exit;
467 end if;
468 end loop;
469 end if;
470 return rr;
471 end sshrn;
472 FUNCTION shl(s1:std_logic_vector) return std_logic_vector is
473 variable r : std_logic_vector(s1'high downto s1'low);
474 begin
475 r(r'low) := '0';
476 r(r'high downto 1) := s1(s1'high-1 downto 0);
477 return r;
478 end shl;
479 FUNCTION ccitt_crc_16(s1:std_logic_vector;ser_in:std_logic) return std_logic_vector is
480 --Calculates the next CRC value as per ccitt_crc_16
481 --X^16 + X^12 + X^5 + 1
482 variable r : std_logic_vector(s1'high downto s1'low);
483 begin
484 r(15) := s1(14);
485 r(14) := s1(13);
486 r(13) := s1(12);
487 r(12) := s1(11) xor s1(15) xor ser_in;
488 r(11) := s1(10);
489 r(10) := s1(9);
490 r(9) := s1(8);
491 r(8) := s1(7);
492 r(7) := s1(6);
493 r(6) := s1(5);
494 r(5) := s1(4) xor s1(15) xor ser_in;
495 r(4) := s1(3);
496 r(3) := s1(2);
497 r(2) := s1(1);
498 r(1) := s1(0);
499 r(0) := s1(15) xor ser_in;
500 return r;
501 end ccitt_crc_16;
502 FUNCTION sext(s1:std_logic_vector;nn:integer) return std_logic_vector is
503 variable rr : std_logic_vector(s1'high+nn downto s1'low);
504 begin
505 if(nn < 0) then
506 assert false
507 report "sext: index nn is negative,can't sign extend" severity error;
508 end if;
509 rr(s1'high downto s1'low) := s1;
510 for ii in s1'high+nn downto s1'high+1 loop
511 rr(ii) := s1(s1'high);
512 end loop;
513 return rr;
514 END sext;
515 FUNCTION shln(s1:std_logic_vector;nn:integer) return std_logic_vector is
516 -- shift left by nn bits, add nn 0s to LSBs
517 -- Example s1 = 11111101, nn = 3, return = 11101000
518 --It is in effect unsigned multiplication by 2^nn
519 variable rr : std_logic_vector(s1'high downto s1'low);
520 begin
521 if(nn < 0) then
522 assert false
523 report "shln: shift index nn is negative,can't shift" severity error;
524 end if;
525 if(nn = 0) then
526 rr := s1;
527 else
528 rr := (others => '0');
529 for ii in s1'high downto s1'low+1 loop
530 rr(ii) := s1(ii-nn);
531 if(ii = nn) then
532 exit;
533 end if;
534 end loop;
535 end if;
536 return rr;
537 end shln;
538 FUNCTION bit_reverse(s1:std_logic_vector) return std_logic_vector is
539 variable rr : std_logic_vector(s1'high downto s1'low);
540 begin
541 for ii in s1'high downto s1'low loop
542 rr(ii) := s1(s1'high-ii);
543 end loop;
544 return rr;
545 end bit_reverse;
546 --Function Declaration Section Ends
547 END fun_pkg;

 


 

posted @ 2011-01-25 22:54  IAmAProgrammer  阅读(405)  评论(0编辑  收藏  举报