1-------------------------------------------------------------------------------- 2--! @file 3--! @brief A bunch of useful functions for (non)synthesizable VHDL 4-------------------------------------------------------------------------------- 5library ieee; 6 use ieee.std_logic_1164.all; 7 use ieee.numeric_std.all; 8 use ieee.math_real.all; 9library std; 10 use std.textio.all; 11 12package er_pack is 13 -- constants used inside function 'rt' 14 constant simres : time := 1 ps; -- simulation resolution (time) 15 constant resreal : real := 1.0e-12; -- simulation resolution (real) 16 17 ---------------------------------------------------------------------------- 18 -- Types, Subtypes, and constants 19 ---------------------------------------------------------------------------- 20 type integer_vector is array (integer range <>) of integer; 21 type natural_vector is array (integer range <>) of natural; 22 type real_vector is array (integer range <>) of real; 23 ---------------------------------------------------------------------------- 24 25 ---------------------------------------------------------------------------- 26 -- synthesis off 27 function print_nibble(arg : std_logic_vector(3 downto 0)) return character; 28 function print_message(arg : string) return boolean; 29 -- synthesis on 30 31 ---------------------------------------------------------------------------- 32 -- print function 33 ---------------------------------------------------------------------------- 34 -- synthesis off 35 function slv2string (arg : in std_logic_vector) return string; 36 -- synthesis on 37 38 ---------------------------------------------------------------------------- 39 --! Return a vector of all ones. 40 --! @param arg The number of bits in the output vector. 41 --! @returns A vector of all ones. 42 ---------------------------------------------------------------------------- 43 function ones (arg : natural) return std_logic_vector; 44 45 ---------------------------------------------------------------------------- 46 --! Return a vector of all zeros. 47 --! @param arg The number of bits in the output vector. 48 --! @returns A vector of all zeros. 49 ---------------------------------------------------------------------------- 50 function zeros(arg : natural) return std_logic_vector; 51 52 ---------------------------------------------------------------------------- 53 --! Return the maximum (max positive) 2's complement value that can be 54 --! expressed in the given number of bits. This is defined as {0,1,...,1}. 55 --! @param arg The number of bits in the output vector. 56 --! @returns The maximum 2's complement value. 57 ---------------------------------------------------------------------------- 58 function max (arg : natural) return std_logic_vector; 59 60 ---------------------------------------------------------------------------- 61 --! Return the minimum (max negative) 2's complement value that can be 62 --! expressed in the given number of bits. This is defined as {1,0,...,0}. 63 --! @param arg The number of bits in the output vector. 64 --! @returns The minimum 2's complement value. 65 ---------------------------------------------------------------------------- 66 function min (arg : natural) return std_logic_vector; 67 68 ---------------------------------------------------------------------------- 69 --! Return the maximum value of two input values. 70 --! @param a The first input value 71 --! @param b The second input value 72 --! @returns The maximum value of a and b 73 ---------------------------------------------------------------------------- 74 function max(a:natural; b:natural) return natural; 75 76 ---------------------------------------------------------------------------- 77 --! Return the minimum value of two input values. 78 --! @param a The first input value 79 --! @param b The second input value 80 --! @returns The minimum value of a and b 81 ---------------------------------------------------------------------------- 82 function min(a:natural; b:natural) return natural; 83 84 ---------------------------------------------------------------------------- 85 --! Return the next multiple of the given variable 86 --! @param arg The input value 87 --! @param mult The multiple 88 --! @returns arg rounded up to the next multiple of mult 89 ---------------------------------------------------------------------------- 90 function next_multiple (arg : natural; mult : natural) return natural; 91 92 ---------------------------------------------------------------------------- 93 --! Log function 94 --! This might be the single most useful function in all of VHDL. It simply 95 --! returns the log of a value 96 --! @param base The base to use for the log. 97 --! @param arg The value to log. 98 --! @returns The log (arg) 99 ---------------------------------------------------------------------------- 100 function log (base : positive; arg : positive) return natural; 101 102 ---------------------------------------------------------------------------- 103 --! Log2 function 104 --! This might be the single most useful function in all of VHDL. It simply 105 --! returns the log2 of a value 106 --! @param arg The value to log. 107 --! @returns The log2 (arg) 108 ---------------------------------------------------------------------------- 109 function log2 (arg : positive) return natural; 110 111 ---------------------------------------------------------------------------- 112 --! Number of Bits function 113 --! Return the number of bits necessary to hold a particular values. This 114 --! is the log2 function rounded up 115 --! @param arg The value to store 116 --! @returns The number of bits necessary to hold arg 117 ---------------------------------------------------------------------------- 118 function num_bits (arg : positive) return natural; 119 120 ---------------------------------------------------------------------------- 121 --! delay via register 122 --! This function should take place in a clocked process, but is an easy 123 --! way to delay a signal 124 --! @param reg The shift register that is doing the delaying 125 --! @param sig The signal that is being delayed. This is put in the low 126 --! address of the signal. 127 --! @returns This will return the shifted (delayed) vector 128 ---------------------------------------------------------------------------- 129 function delay ( 130 reg : natural_vector; 131 sig : natural) return natural_vector; 132 133 ---------------------------------------------------------------------------- 134 --! delay via register 135 --! This function should take place in a clocked process, but is an easy 136 --! way to delay a signal 137 --! @param reg The shift register that is doing the delaying 138 --! @param sig The signal that is being delayed. This is put in the low 139 --! address of the signal. 140 --! @returns This will return the shifted (delayed) vector 141 ---------------------------------------------------------------------------- 142 function delay ( 143 reg : integer_vector; 144 sig : integer) return integer_vector; 145 146 ---------------------------------------------------------------------------- 147 --! delay via register 148 --! This function should take place in a clocked process, but is an easy 149 --! way to delay a signal 150 --! @param reg The shift register that is doing the delaying 151 --! @param sig The signal that is being delayed. This is put in the low 152 --! address of the signal. 153 --! @returns This will return the shifted (delayed) vector 154 ---------------------------------------------------------------------------- 155 function delay ( 156 reg : std_logic_vector; 157 sig : std_logic) return std_logic_vector; 158 159 ---------------------------------------------------------------------------- 160 --! Return a std_logic that is the result of a rising edge detector. There 161 --! will need to be an input register with at least two values in it, since 162 --! different indexes are used to derive the output. 163 --! @param reg The input shift/Delay register 164 --! @param idx (Optional) The index of the input reg register to start the 165 --! the detection. The default value is the highest most index. 166 --! @return not reg(idx) and reg(idx-1); 167 ---------------------------------------------------------------------------- 168 function rising_edge (reg : std_logic_vector; idx : integer) return std_logic; 169 function rising_edge (reg : std_logic_vector) return std_logic; 170 171 ---------------------------------------------------------------------------- 172 --! Return a std_logic that is the result of a falling edge detector. There 173 --! will need to be an input register with at least two values in it, since 174 --! different indexes are used to derive the output. 175 --! @param reg The input shift/Delay register 176 --! @param idx (Optional) The index of the input reg register to start the 177 --! the detection. The default value is the highest most index. 178 --! @return reg(idx) and not reg(idx-1); 179 ---------------------------------------------------------------------------- 180 function falling_edge (reg : std_logic_vector; idx : integer) return std_logic; 181 function falling_edge (reg : std_logic_vector) return std_logic; 182 183 ---------------------------------------------------------------------------- 184 --! Return a std_logic that is the result of an edge detector. There will 185 --! need to be an input register with at least two values in it, since 186 --! different indexes are used to derive the output. 187 --! @param reg The input shift/Delay register 188 --! @param idx (Optional) The index of the input reg register to start the 189 --! the detection. The default value is the highest most index. 190 --! @return reg(idx) xor reg(idx-1); 191 ---------------------------------------------------------------------------- 192 function edge (reg : std_logic_vector) return std_logic; 193 function edge (reg : std_logic_vector; idx : integer) return std_logic; 194 195 ---------------------------------------------------------------------------- 196 --! Flip a register. This will put the high bits in the low positions, 197 --! producing a mirror image of the bits. It will preserve the range of the 198 --! input vector. 199 --! @param ret The input register. 200 --! @return The flipped version of the input register. 201 ---------------------------------------------------------------------------- 202 function flip (reg : std_logic_vector) return std_logic_vector; 203 204 ---------------------------------------------------------------------------- 205 --! Convert a real number to a std_logic_vector with a given number of bits. 206 --! The input real should be a value between 1.0 and -1.0. Any value 207 --! outside of this range will saturate the output vector. 208 --! @param l The real number 209 --! @param b The number of bits for the std_logic_vector 210 ---------------------------------------------------------------------------- 211 function to_slv(l:real; b:natural) return std_logic_vector; 212 213 ---------------------------------------------------------------------------- 214 -- Convert a time to a real representation for the number of seconds 215 -- @param t The time to convert 216 -- @return The real time (in seconds) 217 ---------------------------------------------------------------------------- 218 function rt(t : time) return real; 219 220 ---------------------------------------------------------------------------- 221 --! Divide two times. Return a real 222 --! @param l The numerator 223 --! @param r The denominator 224 --! @returns The result of the divide in a real number 225 ---------------------------------------------------------------------------- 226 function "/" (l, r : time) return real; 227 228 ---------------------------------------------------------------------------- 229 --! Priority decoder 230 --! Return the lowest index that is set high. 231 --! @param reg the register to decode 232 --! @returns The index of the highest bit set. If the whole register is 233 --! zero, then it returns an out-of-bound integer 234 ---------------------------------------------------------------------------- 235 function priority_decode(reg : std_logic_vector) return integer; 236 237 ---------------------------------------------------------------------------- 238 --! Saturate an unsigned value to the given number of bits. 239 --! @param val The unsigned value 240 --! @param bits The number of bits 241 --! @returns If the input value is greater than the requested number of bits 242 --! can hold, it will return 2^bits-1. All other cases will return the 243 --! original number. 244 ---------------------------------------------------------------------------- 245 function saturate(val : unsigned; bits : natural) return unsigned; 246 function usat(val : std_logic_vector; bits : natural ) return std_logic_vector; 247 248 ---------------------------------------------------------------------------- 249 --! Saturate a signed value to the given number of bits. 250 --! @param val The signed value 251 --! @param bits The number of bits 252 --! @returns If the absolute value of the input value is greater than 253 --! 2^(bits-1)-1, then return the appriate signed version of 2^(bits-1)-1. 254 --! All other cases will return the original number. 255 ---------------------------------------------------------------------------- 256 function saturate(val : signed; bits : natural) return signed; 257 function ssat(val : std_logic_vector; bits : natural ) return std_logic_vector; 258 259 ---------------------------------------------------------------------------- 260 --! numeric_std helper functions 261 --! (un)signed shift left/right 262 ---------------------------------------------------------------------------- 263 --! unsigned shift left 264 function usl (val : std_logic_vector; bits : natural) return std_logic_vector; 265 --! unsigned shift right 266 function usr (val : std_logic_vector; bits : natural) return std_logic_vector; 267 --! signed shift left 268 function ssl (val : std_logic_vector; bits : natural) return std_logic_vector; 269 --! signed shift right 270 function ssr (val : std_logic_vector; bits : natural) return std_logic_vector; 271 272end package er_pack; 273 274-------------------------------------------------------------------------------- 275-------------------------------------------------------------------------------- 276-- Package body 277-------------------------------------------------------------------------------- 278-------------------------------------------------------------------------------- 279package body er_pack is 280 ---------------------------------------------------------------------------- 281 -- synthesis off 282 function print_nibble(arg : std_logic_vector(3 downto 0)) 283 return character is 284 variable ret : character; 285 variable num : natural; 286 -- status variables 287 variable is_x : boolean; 288 variable is_u : boolean; 289 variable is_dash : boolean; 290 variable is_z : boolean; 291 variable is_w : boolean; 292 begin 293 for idx in arg'range loop 294 -- take care of the special cases 295 case arg(idx) is 296 when 'X' => is_x := true; 297 when 'U' => is_u := true; 298 when '-' => is_dash := true; 299 when 'Z' => is_z := true; 300 when 'W' => is_w := true; 301 when others => NULL; 302 end case; 303 end loop; 304 305 -- Print it 306 if is_x then ret := 'X'; 307 elsif is_u then ret := 'U'; 308 elsif is_dash then ret := '-'; 309 elsif is_z then ret := 'Z'; 310 elsif is_w then ret := 'W'; 311 else 312 num := to_integer(unsigned(arg)); 313 case num is 314 when 15 => ret := 'F'; 315 when 14 => ret := 'E'; 316 when 13 => ret := 'D'; 317 when 12 => ret := 'C'; 318 when 11 => ret := 'B'; 319 when 10 => ret := 'A'; 320 when 9 => ret := '9'; 321 when 8 => ret := '8'; 322 when 7 => ret := '7'; 323 when 6 => ret := '6'; 324 when 5 => ret := '5'; 325 when 4 => ret := '4'; 326 when 3 => ret := '3'; 327 when 2 => ret := '2'; 328 when 1 => ret := '1'; 329 when 0 => ret := '0'; 330 when others => ret := 'J'; 331 end case; 332 end if; 333 334 -- we're done 335 return ret; 336 end function print_nibble; 337 338 --! Just print a string. It's not hard, but it takes more than one line 339 --! without the function 340 function print_message(arg : string) return boolean is 341 variable out_line : line; 342 begin 343 write(out_line, arg); 344 writeline(output, out_line); 345 return true; 346 end function print_message; 347 348 -- print function 349 function slv2string (arg : in std_logic_vector) return string is 350 variable ret : string (1 to arg'length/4+1); 351 variable jdx : integer; 352 variable tmp_nibble : std_logic_vector(3 downto 0); 353 variable kdx : natural := 1; 354 begin 355 -- Try to get a useful hex value 356 jdx := 0; 357 kdx := ret'high; 358 for idx in arg'reverse_range loop 359 -- fill the next value of the nibble 360 tmp_nibble(jdx) := arg(idx); 361 362 -- correct jdx and print accordingly 363 if jdx = 3 then 364 -- reset the jdx value 365 jdx := 0; 366 ret(kdx) := print_nibble(tmp_nibble); 367 368 -- correct kdx 369 kdx := kdx - 1; 370 else 371 -- decrement jdx 372 jdx := jdx + 1; 373 end if; 374 375 end loop; 376 377 -- edge cases 378 if jdx /= 0 then 379 tmp_nibble(3 downto jdx) := (others => '0'); 380 ret(kdx) := print_nibble(tmp_nibble); 381 return ret; 382 end if; 383 384 -- if we got here, then we have an exact number of nibbles. Give back 385 -- all but one character. 386 return ret(2 to ret'high); 387 end function slv2string; 388 -- synthesis on 389 390 ---------------------------------------------------------------------------- 391 function ones (arg : natural) return std_logic_vector is 392 variable ret : std_logic_vector(arg-1 downto 0) := (others => '1'); 393 begin 394 return ret; 395 end function ones; 396 ---------------------------------------------------------------------------- 397 function zeros(arg : natural) return std_logic_vector is 398 variable ret : std_logic_vector(arg-1 downto 0) := (others => '0'); 399 begin 400 return ret; 401 end function zeros; 402 ---------------------------------------------------------------------------- 403 function max (arg : natural) return std_logic_vector is 404 variable ret : std_logic_vector(arg-1 downto 0) := '0' & ones(arg-1); 405 begin 406 return ret; 407 end function max; 408 ---------------------------------------------------------------------------- 409 function min (arg : natural) return std_logic_vector is 410 variable ret : std_logic_vector(arg-1 downto 0) := '1' & zeros(arg-1); 411 begin 412 return ret; 413 end function min; 414 ---------------------------------------------------------------------------- 415 function max(a:natural; b:natural) return natural is 416 begin 417 if a > b then 418 return a; 419 end if; 420 return b; 421 end function max; 422 ---------------------------------------------------------------------------- 423 function min(a:natural; b:natural) return natural is 424 begin 425 if a < b then 426 return a; 427 end if; 428 return b; 429 end function min; 430 ---------------------------------------------------------------------------- 431 function next_multiple (arg : natural; mult : natural) 432 return natural is 433 begin 434 return (arg / mult) * mult; 435 end function next_multiple; 436 437 ---------------------------------------------------------------------------- 438 function log (base : positive; arg : positive) return natural is 439 variable div : positive := arg; 440 variable ret : natural := 0; 441 begin 442 while div > 1 loop 443 div := div / base; 444 ret := ret + 1; 445 end loop; 446 return ret; 447 end function log; 448 449 ---------------------------------------------------------------------------- 450 function log2 (arg : positive) return natural is 451 begin 452 return log(2, arg); 453 end function log2; 454 455 ---------------------------------------------------------------------------- 456 function num_bits (arg : positive) return natural is 457 variable ret : natural := log2(arg); 458 begin 459 if 2**ret /= arg then 460 ret := ret + 1; 461 end if; 462 return ret; 463 end function num_bits; 464 465 ---------------------------------------------------------------------------- 466 function delay ( 467 reg : integer_vector; 468 sig : integer) 469 return integer_vector is 470 variable ret : integer_vector(reg'range); 471 begin 472 if ret'ascending then 473 ret := sig & reg(reg'low to reg'high-1); 474 else 475 ret := reg(reg'high-1 downto reg'low) & sig; 476 end if; 477 return ret; 478 end function; 479 480 function delay ( 481 reg : natural_vector; 482 sig : natural) 483 return natural_vector is 484 variable ret : natural_vector(reg'range); 485 begin 486 if ret'ascending then 487 ret := sig & reg(reg'low to reg'high-1); 488 else 489 ret := reg(reg'high-1 downto reg'low) & sig; 490 end if; 491 return ret; 492 end function; 493 494 function delay ( 495 reg : std_logic_vector; 496 sig : std_logic) 497 return std_logic_vector is 498 variable ret : std_logic_vector(reg'range); 499 begin 500 if ret'ascending then 501 ret := sig & reg(reg'low to reg'high-1); 502 else 503 ret := reg(reg'high-1 downto reg'low) & sig; 504 end if; 505 return ret; 506 end function; 507 508 ---------------------------------------------------------------------------- 509 function rising_edge ( 510 reg : std_logic_vector) 511 return std_logic is 512 variable idx : integer := reg'high; 513 begin 514 return rising_edge(reg, idx); 515 end function; 516 ---------------------------------------------------------------------------- 517 function rising_edge ( 518 reg : std_logic_vector; 519 idx : integer) 520 return std_logic is 521 begin 522 -- Check the input for validity 523 assert reg'length >= 2 524 report "input vector not long enough" severity error; 525 assert idx <= reg'high and idx > reg'low 526 report "input vector not long enough" severity error; 527 528 -- now just return the answer 529 return not reg(idx) and reg(idx-1); 530 end function; 531 ---------------------------------------------------------------------------- 532 function falling_edge ( 533 reg : std_logic_vector) 534 return std_logic is 535 variable idx : integer := reg'high; 536 begin 537 return falling_edge(reg, idx); 538 end function falling_edge; 539 ---------------------------------------------------------------------------- 540 function falling_edge ( 541 reg : std_logic_vector; 542 idx : integer) 543 return std_logic is 544 begin 545 -- Check the input for validity 546 assert reg'length >= 2 547 report "input vector not long enough" severity error; 548 assert idx <= reg'high and idx > reg'low 549 report "input vector not long enough" severity error; 550 551 -- now just return the answer 552 return reg(idx) and not reg(idx-1); 553 end function falling_edge; 554 ---------------------------------------------------------------------------- 555 function edge ( 556 reg : std_logic_vector) 557 return std_logic is 558 variable idx : integer := reg'high; 559 begin 560 return edge(reg, idx); 561 end function edge; 562 ---------------------------------------------------------------------------- 563 function edge ( 564 reg : std_logic_vector; 565 idx : integer) 566 return std_logic is 567 begin 568 -- Check the input for validity 569 assert reg'length >= 2 570 report "input vector not long enough" severity error; 571 assert idx <= reg'high and idx > reg'low 572 report "input vector not long enough" severity error; 573 574 -- now just return the answer 575 return reg(idx) xor reg(idx-1); 576 end function edge; 577 ---------------------------------------------------------------------------- 578 function flip (reg : std_logic_vector) return std_logic_vector is 579 variable ret : std_logic_vector(reg'range); 580 variable idx : integer := reg'high; 581 variable jdx : integer := reg'low; 582 begin 583 while jdx < idx loop 584 -- Populate ret with the reg bits backwards 585 ret(idx) := reg(jdx); 586 ret(jdx) := reg(idx); 587 588 -- update the counters 589 idx := idx + 1; 590 jdx := jdx + 1; 591 end loop; 592 593 -- return the flipped register 594 return ret; 595 end function flip; 596 597 ---------------------------------------------------------------------------- 598 function to_slv(l:real; b:natural) return std_logic_vector is 599 variable slv : std_logic_vector(b-1 downto 0); 600 variable temp_r : real; 601 variable temp_i : integer; 602 begin 603 -- Check the bounds and saturate when necessary 604 if l <= -1.0 then 605 slv := min(b); 606 elsif l >= 1.0 then 607 slv := max(b); 608 else 609 -- Compute the answer 610 temp_r := l * real(2**(b-1)-1); -- Scale the real to not overflow 611 temp_i := integer(round(temp_r)); -- round it and turn it into an integer 612 slv := std_logic_vector(to_signed(temp_i, b)); -- Turn it to an slv 613 end if; 614 615 -- Now just return it 616 return slv; 617 end function to_slv; 618 619 ---------------------------------------------------------------------------- 620 function rt(t : time) return real is 621 variable nat_time : natural := t / simres; 622 variable real_time : real := real(nat_time); 623 begin 624 return real_time * resreal; 625 end; 626 627 ---------------------------------------------------------------------------- 628 function "/" (l, r : time) return real is 629 variable real_l : real := rt(l); 630 variable real_r : real := rt(r); 631 begin 632 return real_l / real_r; 633 end function "/"; 634 635 ---------------------------------------------------------------------------- 636 function priority_decode(reg : std_logic_vector) return integer is 637 variable ret : integer; 638 begin 639 -- Start with the default value 640 if reg'ascending then 641 ret := reg'right + 1; 642 else 643 ret := reg'right - 1; 644 end if; 645 646 -- now determine which one is lit 647 for idx in reg'reverse_range loop 648 if reg(idx) = '1' then 649 ret := idx; 650 end if; 651 end loop; 652 653 -- return it 654 return ret; 655 end function priority_decode; 656 657 ---------------------------------------------------------------------------- 658 function saturate(val : unsigned; bits : natural) return unsigned is 659 variable max_val : unsigned(bits-1 downto 0) := unsigned(ones(bits)); 660 begin 661 -- Check the value over the max 662 if val > max_val then 663 return resize(max_val, val'length); 664 end if; 665 666 -- If we got here, we just return the value 667 return val; 668 end function saturate; 669 670 -- The std_logic_vector version 671 function usat(val : std_logic_vector; bits : natural ) return std_logic_vector is 672 begin 673 return std_logic_vector(saturate(unsigned(val), bits)); 674 end function usat; 675 676 ---------------------------------------------------------------------------- 677 function saturate(val : signed; bits : natural) return signed is 678 variable max_val : signed(bits-1 downto 0) := '0' & signed(ones (bits-2)) & '1'; 679 variable min_val : signed(bits-1 downto 0) := '1' & signed(zeros(bits-2)) & '1'; 680 begin 681 -- Check the value over the max 682 if val > max_val then 683 return resize(max_val, val'length); 684 elsif val < min_val then 685 return resize(min_val, val'length); 686 end if; 687 688 -- If we got here, we just return the value 689 return val; 690 end function saturate; 691 692 -- The std_logic_vector version 693 function ssat(val : std_logic_vector; bits : natural ) return std_logic_vector is 694 begin 695 return std_logic_vector(saturate(signed(val), bits)); 696 end function ssat; 697 698 ---------------------------------------------------------------------------- 699 -- numeric_std helper functions 700 ---------------------------------------------------------------------------- 701 function usl (val : std_logic_vector; bits : natural) return std_logic_vector is 702 begin 703 return std_logic_vector(shift_left(unsigned(val), bits)); 704 end function usl; 705 function usr (val : std_logic_vector; bits : natural) return std_logic_vector is 706 begin 707 return std_logic_vector(shift_right(unsigned(val), bits)); 708 end function usr; 709 function ssl (val : std_logic_vector; bits : natural) return std_logic_vector is 710 begin 711 return std_logic_vector(shift_left(signed(val), bits)); 712 end function ssl; 713 function ssr (val : std_logic_vector; bits : natural) return std_logic_vector is 714 begin 715 return std_logic_vector(shift_right(signed(val), bits)); 716 end function ssr; 717end package body; 718 719 720