Lösung des ESY6/A Praktikums "signal_processing".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

float.vhd 6.0KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. package float is
  5. constant SIGN : std_logic_vector( 31 downto 31 ) := ( others => '0' );
  6. constant EXP : std_logic_vector( 30 downto 23 ) := ( others => '0' );
  7. constant MANTISSA : std_logic_vector( 22 downto 0 ) := ( others => '0' );
  8. function find_leftmost( arg : unsigned; value : std_ulogic ) return integer;
  9. function count_leading_digits( arg : unsigned; value : std_ulogic ) return integer;
  10. function to_float( arg : std_logic_vector ) return std_logic_vector;
  11. function to_fixed( arg : std_logic_vector ) return std_logic_vector;
  12. end package float;
  13. package body float is
  14. function find_leftmost( arg : unsigned; value : std_ulogic ) return integer is
  15. begin
  16. for i in arg'left downto arg'right loop
  17. if ( arg( i ) = value ) then
  18. return i;
  19. end if;
  20. end loop;
  21. return -1;
  22. end function find_leftmost;
  23. function count_leading_digits( arg : unsigned; value : std_ulogic ) return integer is
  24. variable left_most_value : integer range -1 to arg'high;
  25. variable leading_values : integer range 0 to arg'high;
  26. begin
  27. left_most_value := find_leftmost( arg, not value );
  28. leading_values := 0;
  29. if ( left_most_value /= -1 ) then
  30. leading_values := arg'high - left_most_value;
  31. end if;
  32. return leading_values;
  33. end function count_leading_digits;
  34. function to_float( arg : std_logic_vector ) return std_logic_vector is
  35. variable y : std_logic_vector( 31 downto 0 );
  36. variable s : std_logic;
  37. variable e : unsigned( 7 downto 0 );
  38. variable m : unsigned( 22 downto 0 );
  39. variable value : unsigned( 30 downto 0 );
  40. variable leading_sign_digits : integer range 0 to value'high;
  41. variable reminding : integer range 0 to value'high;
  42. begin
  43. s := arg( 31 );
  44. if ( s = '0' ) then
  45. value := unsigned( arg( 30 downto 0 ) );
  46. else
  47. value := not unsigned( arg( 30 downto 0 ) );
  48. value := value +1;
  49. end if;
  50. leading_sign_digits := count_leading_digits( value, '0' );
  51. reminding := value'high - leading_sign_digits;
  52. e := to_unsigned( 126 - leading_sign_digits, e'length );
  53. if ( reminding > m'length ) then
  54. m := value( reminding - 1 downto reminding - m'length );
  55. elsif ( reminding > 1 ) then
  56. m := ( others => '0' );
  57. m( m'high downto m'high - reminding + 1 ) := value( reminding - 1 downto 0 );
  58. else
  59. m := ( others => '0' );
  60. end if;
  61. if (arg = x"00000000") then
  62. y := (others => '0');
  63. else
  64. y := s & std_logic_vector( e ) & std_logic_vector( m );
  65. end if;
  66. return y;
  67. end function to_float;
  68. function to_fixed( arg : std_logic_vector ) return std_logic_vector is
  69. variable y : unsigned( 31 downto 0 );
  70. variable s : std_logic;
  71. variable e : unsigned( 7 downto 0 );
  72. variable m_index_max : integer range -127 to 128;
  73. begin
  74. s := arg( 31 );
  75. e := unsigned(arg(30 downto 23));
  76. m_index_max := to_integer(signed(30-(126-e)));
  77. if (arg = x"00000000") then
  78. y := (others => '0');
  79. else
  80. y := (others => '0');
  81. case m_index_max is
  82. when 30 => y(30 downto 7):= '1' & unsigned( arg(22 downto 0) );
  83. when 29 => y(29 downto 6):= '1' & unsigned( arg(22 downto 0) );
  84. when 28 => y(28 downto 5):= '1' & unsigned( arg(22 downto 0) );
  85. when 27 => y(27 downto 4):= '1' & unsigned( arg(22 downto 0) );
  86. when 26 => y(26 downto 3):= '1' & unsigned( arg(22 downto 0) );
  87. when 25 => y(25 downto 2):= '1' & unsigned( arg(22 downto 0) );
  88. when 24 => y(24 downto 1):= '1' & unsigned( arg(22 downto 0) );
  89. when 23 => y(23 downto 0):= '1' & unsigned( arg(22 downto 0) );
  90. when 22 => y(22 downto 0):= '1' & unsigned( arg(22 downto 1) );
  91. when 21 => y(21 downto 0):= '1' & unsigned( arg(22 downto 2) );
  92. when 20 => y(20 downto 0):= '1' & unsigned( arg(22 downto 3) );
  93. when 19 => y(19 downto 0):= '1' & unsigned( arg(22 downto 4) );
  94. when 18 => y(18 downto 0):= '1' & unsigned( arg(22 downto 5) );
  95. when 17 => y(17 downto 0):= '1' & unsigned( arg(22 downto 6) );
  96. when 16 => y(16 downto 0):= '1' & unsigned( arg(22 downto 7) );
  97. when 15 => y(15 downto 0):= '1' & unsigned( arg(22 downto 8) );
  98. when 14 => y(14 downto 0):= '1' & unsigned( arg(22 downto 9) );
  99. when 13 => y(13 downto 0):= '1' & unsigned( arg(22 downto 10) );
  100. when 12 => y(12 downto 0):= '1' & unsigned( arg(22 downto 11) );
  101. when 11 => y(11 downto 0):= '1' & unsigned( arg(22 downto 12) );
  102. when 10 => y(10 downto 0):= '1' & unsigned( arg(22 downto 13) );
  103. when 9 => y(9 downto 0):= '1' & unsigned( arg(22 downto 14) );
  104. when 8 => y(8 downto 0):= '1' & unsigned( arg(22 downto 15) );
  105. when 7 => y(7 downto 0):= '1' & unsigned( arg(22 downto 16) );
  106. when 6 => y(6 downto 0):= '1' & unsigned( arg(22 downto 17) );
  107. when 5 => y(5 downto 0):= '1' & unsigned( arg(22 downto 18) );
  108. when 4 => y(4 downto 0):= '1' & unsigned( arg(22 downto 19) );
  109. when 3 => y(3 downto 0):= '1' & unsigned( arg(22 downto 20) );
  110. when 2 => y(2 downto 0):= '1' & unsigned( arg(22 downto 21) );
  111. when 1 => y(1 downto 0):= '1' & unsigned( arg(22 downto 22) );
  112. when 0 => y(0):= '1';
  113. when others => null;
  114. end case;
  115. if ( s = '1' ) then
  116. y := not(y);
  117. y:= y + x"00000001";
  118. end if;
  119. end if;
  120. return std_logic_vector( y );
  121. end function to_fixed;
  122. end package body float;