Library of reusable VHDL components
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.

392 lines
16 KiB

  1. --
  2. -- File Name: ResolutionPkg.vhd
  3. -- Design Unit Name: ResolutionPkg
  4. -- Revision: STANDARD VERSION
  5. --
  6. -- Maintainer: Jim Lewis email: jim@SynthWorks.com
  7. -- Contributor(s):
  8. -- Jim Lewis email: jim@SynthWorks.com
  9. --
  10. -- Package Defines
  11. -- resolved resolution functions for integer, real, and time
  12. -- types resolved_integer, resolved_real, resolved_time
  13. --
  14. -- Developed for:
  15. -- SynthWorks Design Inc.
  16. -- VHDL Training Classes
  17. -- 11898 SW 128th Ave. Tigard, Or 97223
  18. -- http://www.SynthWorks.com
  19. --
  20. -- Revision History:
  21. -- Date Version Description
  22. -- 09/2006: 0.1 Initial revision
  23. -- Numerous revisions for VHDL Testbenches and Verification
  24. -- 02/2009: 1.0 VHDL-2008 STANDARD VERSION
  25. -- 05/2015 2015.05 Added Alerts
  26. -- -- Replaced Alerts with asserts as alerts are illegal in pure functions
  27. -- 11/2016 2016.11 Removed Asserts as they are not working as intended.
  28. -- See ResolutionPkg_debug as it uses Alerts to correctly detect errors
  29. --
  30. --
  31. -- Copyright (c) 2005 - 2016 by SynthWorks Design Inc. All rights reserved.
  32. --
  33. -- Verbatim copies of this source file may be used and
  34. -- distributed without restriction.
  35. --
  36. -- This source file may be modified and distributed under
  37. -- the terms of the ARTISTIC License as published by
  38. -- The Perl Foundation; either version 2.0 of the License,
  39. -- or (at your option) any later version.
  40. --
  41. -- This source is distributed in the hope that it will be
  42. -- useful, but WITHOUT ANY WARRANTY; without even the implied
  43. -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  44. -- PURPOSE. See the Artistic License for details.
  45. --
  46. -- You should have received a copy of the license with this source.
  47. -- If not download it from,
  48. -- http://www.perlfoundation.org/artistic_license_2_0
  49. --
  50. library ieee ;
  51. use ieee.std_logic_1164.all ;
  52. use ieee.numeric_std.all ;
  53. library osvvm ;
  54. use osvvm.AlertLogPkg.all ;
  55. package ResolutionPkg is
  56. constant MULTIPLE_DRIVER_SEVERITY : severity_level := ERROR ;
  57. --
  58. -- Note that not all simulators support resolution functions of the form:
  59. -- subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ;
  60. --
  61. -- Hence, types of the form are offered as a temporary workaround until they do:
  62. -- std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008
  63. --
  64. -- resolved_max
  65. -- return maximum value.
  66. -- No initializations required on ports, default of type'left is ok
  67. function resolved_max ( s : std_ulogic_vector) return std_ulogic ;
  68. subtype std_logic_max is resolved_max std_ulogic ;
  69. subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ;
  70. type std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008
  71. subtype unsigned_max is (resolved_max) unresolved_unsigned ;
  72. type unsigned_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008
  73. subtype signed_max is (resolved_max) unresolved_signed ;
  74. type signed_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008
  75. function resolved_max ( s : bit_vector) return bit ;
  76. subtype bit_max is resolved_max bit ;
  77. subtype bit_vector_max is (resolved_max) bit_vector ;
  78. type bit_vector_max_c is array (natural range <>) of bit_max ; -- for non VHDL-2008
  79. function resolved_max ( s : integer_vector ) return integer ;
  80. subtype integer_max is resolved_max integer ;
  81. subtype integer_vector_max is (resolved_max) integer_vector ;
  82. type integer_vector_max_c is array (natural range <>) of integer_max ; -- for non VHDL-2008
  83. function resolved_max ( s : time_vector ) return time ;
  84. subtype time_max is resolved_max time ;
  85. subtype time_vector_max is (resolved_max) time_vector ;
  86. type time_vector_max_c is array (natural range <>) of time_max ; -- for non VHDL-2008
  87. function resolved_max ( s : real_vector ) return real ;
  88. subtype real_max is resolved_max real ;
  89. subtype real_vector_max is (resolved_max) real_vector ;
  90. type real_vector_max_c is array (natural range <>) of real_max ; -- for non VHDL-2008
  91. function resolved_max ( s : string) return character ;
  92. subtype character_max is resolved_max character ;
  93. subtype string_max is (resolved_max) string ;
  94. type string_max_c is array (positive range <>) of character_max ; -- for non VHDL-2008
  95. function resolved_max ( s : boolean_vector) return boolean ;
  96. subtype boolean_max is resolved_max boolean ;
  97. subtype boolean_vector_max is (resolved_max) boolean_vector ;
  98. type boolean_vector_max_c is array (natural range <>) of boolean_max ; -- for non VHDL-2008
  99. -- return sum of values that /= type'left
  100. -- No initializations required on ports, default of type'left is ok
  101. function resolved_sum ( s : integer_vector ) return integer ;
  102. subtype integer_sum is resolved_sum integer ;
  103. subtype integer_vector_sum is (resolved_sum) integer_vector ;
  104. type integer_vector_sum_c is array (natural range <>) of integer_sum ; -- for non VHDL-2008
  105. function resolved_sum ( s : time_vector ) return time ;
  106. subtype time_sum is resolved_sum time ;
  107. subtype time_vector_sum is (resolved_sum) time_vector ;
  108. type time_vector_sum_c is array (natural range <>) of time_sum ; -- for non VHDL-2008
  109. function resolved_sum ( s : real_vector ) return real ;
  110. subtype real_sum is resolved_sum real ;
  111. subtype real_vector_sum is (resolved_sum) real_vector ;
  112. type real_vector_sum_c is array (natural range <>) of real_sum ; -- for non VHDL-2008
  113. -- resolved_weak
  114. -- Special just for std_ulogic
  115. -- No initializations required on ports, default of type'left is ok
  116. function resolved_weak (s : std_ulogic_vector) return std_ulogic ; -- no init, type'left
  117. subtype std_logic_weak is resolved_weak std_ulogic ;
  118. subtype std_logic_vector_weak is (resolved_weak) std_ulogic_vector ;
  119. -- legacy stuff
  120. -- requires ports to be initialized to 0 in the appropriate type.
  121. function resolved ( s : integer_vector ) return integer ;
  122. subtype resolved_integer is resolved integer ;
  123. function resolved ( s : time_vector ) return time ;
  124. subtype resolved_time is resolved time ;
  125. function resolved ( s : real_vector ) return real ;
  126. subtype resolved_real is resolved real ;
  127. function resolved (s : string) return character ; -- same as resolved_max
  128. subtype resolved_character is resolved character ;
  129. -- subtype resolved_string is (resolved) string ; -- subtype will replace type later
  130. type resolved_string is array (positive range <>) of resolved_character; -- will change to subtype -- assert but no init
  131. function resolved ( s : boolean_vector) return boolean ; --same as resolved_max
  132. subtype resolved_boolean is resolved boolean ;
  133. end package ResolutionPkg ;
  134. package body ResolutionPkg is
  135. -- resolved_max
  136. -- return maximum value. Assert FAILURE if more than 1 /= type'left
  137. -- No initializations required on ports, default of type'left is ok
  138. -- Optimized version is just the following:
  139. -- ------------------------------------------------------------
  140. -- function resolved_max ( s : <array_type> ) return <element_type> is
  141. -- ------------------------------------------------------------
  142. -- begin
  143. -- return maximum(s) ;
  144. -- end function resolved_max ;
  145. ------------------------------------------------------------
  146. function resolved_max (s : std_ulogic_vector) return std_ulogic is
  147. ------------------------------------------------------------
  148. begin
  149. return maximum(s) ;
  150. end function resolved_max ;
  151. ------------------------------------------------------------
  152. function resolved_max ( s : bit_vector ) return bit is
  153. ------------------------------------------------------------
  154. begin
  155. return maximum(s) ;
  156. end function resolved_max ;
  157. ------------------------------------------------------------
  158. function resolved_max ( s : integer_vector ) return integer is
  159. ------------------------------------------------------------
  160. begin
  161. return maximum(s) ;
  162. end function resolved_max ;
  163. ------------------------------------------------------------
  164. function resolved_max ( s : time_vector ) return time is
  165. ------------------------------------------------------------
  166. begin
  167. return maximum(s) ;
  168. end function resolved_max ;
  169. ------------------------------------------------------------
  170. function resolved_max ( s : real_vector ) return real is
  171. ------------------------------------------------------------
  172. begin
  173. return maximum(s) ;
  174. end function resolved_max ;
  175. ------------------------------------------------------------
  176. function resolved_max ( s : string ) return character is
  177. ------------------------------------------------------------
  178. begin
  179. return maximum(s) ;
  180. end function resolved_max ;
  181. ------------------------------------------------------------
  182. function resolved_max ( s : boolean_vector) return boolean is
  183. ------------------------------------------------------------
  184. begin
  185. return maximum(s) ;
  186. end function resolved_max ;
  187. -- resolved_sum - appropriate for numeric types
  188. -- return sum of values that /= type'left
  189. -- No initializations required on ports, default of type'left is ok
  190. ------------------------------------------------------------
  191. function resolved_sum ( s : integer_vector ) return integer is
  192. ------------------------------------------------------------
  193. variable result : integer := 0 ;
  194. begin
  195. for i in s'RANGE loop
  196. if s(i) /= integer'left then
  197. result := s(i) + result;
  198. end if ;
  199. end loop ;
  200. return result ;
  201. end function resolved_sum ;
  202. ------------------------------------------------------------
  203. function resolved_sum ( s : time_vector ) return time is
  204. ------------------------------------------------------------
  205. variable result : time := 0 sec ;
  206. begin
  207. for i in s'RANGE loop
  208. if s(i) /= time'left then
  209. result := s(i) + result;
  210. end if ;
  211. end loop ;
  212. return result ;
  213. end function resolved_sum ;
  214. ------------------------------------------------------------
  215. function resolved_sum ( s : real_vector ) return real is
  216. ------------------------------------------------------------
  217. variable result : real := 0.0 ;
  218. begin
  219. for i in s'RANGE loop
  220. if s(i) /= real'left then
  221. result := s(i) + result;
  222. end if ;
  223. end loop ;
  224. return result ;
  225. end function resolved_sum ;
  226. -- resolved_weak
  227. -- Special just for std_ulogic
  228. -- No initializations required on ports, default of type'left is ok
  229. type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;
  230. constant weak_resolution_table : stdlogic_table := (
  231. -- Resolution order: Z < U < W < X < - < L < H < 0 < 1
  232. -- ---------------------------------------------------------
  233. -- | U X 0 1 Z W L H - | |
  234. -- ---------------------------------------------------------
  235. ('U', 'X', '0', '1', 'U', 'W', 'L', 'H', '-'), -- | U |
  236. ('X', 'X', '0', '1', 'X', 'X', 'L', 'H', '-'), -- | X |
  237. ('0', '0', '0', '1', '0', '0', '0', '0', '0'), -- | 0 |
  238. ('1', '1', '1', '1', '1', '1', '1', '1', '1'), -- | 1 |
  239. ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'), -- | Z |
  240. ('W', 'X', '0', '1', 'W', 'W', 'L', 'H', '-'), -- | W |
  241. ('L', 'L', '0', '1', 'L', 'L', 'L', 'H', 'L'), -- | L |
  242. ('H', 'H', '0', '1', 'H', 'H', 'W', 'H', 'H'), -- | H |
  243. ('-', '-', '0', '1', '-', '-', 'L', 'H', '-') -- | - |
  244. );
  245. ------------------------------------------------------------
  246. function resolved_weak (s : std_ulogic_vector) return std_ulogic is
  247. ------------------------------------------------------------
  248. variable result : std_ulogic := 'Z' ;
  249. begin
  250. for i in s'RANGE loop
  251. result := weak_resolution_table(result, s(i)) ;
  252. end loop ;
  253. return result ;
  254. end function resolved_weak ;
  255. -- legacy stuff.
  256. -- requires ports to be initialized to 0 in the appropriate type.
  257. ------------------------------------------------------------
  258. function resolved ( s : integer_vector ) return integer is
  259. -- requires interface to be initialized to 0
  260. ------------------------------------------------------------
  261. variable result : integer := 0 ;
  262. variable failed : boolean := FALSE ;
  263. begin
  264. for i in s'RANGE loop
  265. if s(i) /= 0 then
  266. failed := failed or (result /= 0) ;
  267. result := maximum(s(i),result);
  268. end if ;
  269. end loop ;
  270. assert not failed report "ResolutionPkg.resolved: multiple drivers on integer" severity MULTIPLE_DRIVER_SEVERITY ;
  271. -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on integer") ;
  272. return result ;
  273. end function resolved ;
  274. ------------------------------------------------------------
  275. function resolved ( s : time_vector ) return time is
  276. -- requires interface to be initialized to 0 ns
  277. ------------------------------------------------------------
  278. variable result : time := 0 ns ;
  279. variable failed : boolean := FALSE ;
  280. begin
  281. for i in s'RANGE loop
  282. if s(i) > 0 ns then
  283. failed := failed or (result /= 0 ns) ;
  284. result := maximum(s(i),result);
  285. end if ;
  286. end loop ;
  287. assert not failed report "ResolutionPkg.resolved: multiple drivers on time" severity MULTIPLE_DRIVER_SEVERITY ;
  288. -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on time") ;
  289. return result ;
  290. end function resolved ;
  291. ------------------------------------------------------------
  292. function resolved ( s : real_vector ) return real is
  293. -- requires interface to be initialized to 0.0
  294. ------------------------------------------------------------
  295. variable result : real := 0.0 ;
  296. variable failed : boolean := FALSE ;
  297. begin
  298. for i in s'RANGE loop
  299. if s(i) /= 0.0 then
  300. failed := failed or (result /= 0.0) ;
  301. result := maximum(s(i),result);
  302. end if ;
  303. end loop ;
  304. assert not failed report "ResolutionPkg.resolved: multiple drivers on real" severity MULTIPLE_DRIVER_SEVERITY ;
  305. -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on real") ;
  306. return result ;
  307. end function resolved ;
  308. ------------------------------------------------------------
  309. function resolved (s : string) return character is
  310. -- same as resolved_max
  311. ------------------------------------------------------------
  312. variable result : character := NUL ;
  313. variable failed : boolean := FALSE ;
  314. begin
  315. for i in s'RANGE loop
  316. if s(i) /= NUL then
  317. failed := failed or (result /= NUL) ;
  318. result := maximum(result, s(i)) ;
  319. end if ;
  320. end loop ;
  321. assert not failed report "ResolutionPkg.resolved: multiple drivers on character" severity MULTIPLE_DRIVER_SEVERITY ;
  322. -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on character") ;
  323. return result ;
  324. end function resolved ;
  325. ------------------------------------------------------------
  326. function resolved ( s : boolean_vector) return boolean is
  327. -- same as resolved_max
  328. ------------------------------------------------------------
  329. variable result : boolean := FALSE ;
  330. variable failed : boolean := FALSE ;
  331. begin
  332. for i in s'RANGE loop
  333. if s(i) then
  334. failed := failed or result ;
  335. result := TRUE ;
  336. end if ;
  337. end loop ;
  338. assert not failed report "ResolutionPkg.resolved: multiple drivers on boolean" severity MULTIPLE_DRIVER_SEVERITY ;
  339. -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on boolean") ;
  340. return result ;
  341. end function resolved ;
  342. end package body ResolutionPkg ;