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 51library ieee ; 52use ieee.std_logic_1164.all ; 53use ieee.numeric_std.all ; 54 55--library osvvm ; 56--use osvvm.AlertLogPkg.all ; 57 58package ResolutionPkg is 59 constant MULTIPLE_DRIVER_SEVERITY : severity_level := ERROR ; 60 61-- 62-- Note that not all simulators support resolution functions of the form: 63-- subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ; 64-- 65-- Hence, types of the form are offered as a temporary workaround until they do: 66-- std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 67-- 68 69 -- resolved_max 70 -- return maximum value. 71 -- No initializations required on ports, default of type'left is ok 72 function resolved_max ( s : std_ulogic_vector) return std_ulogic ; 73 subtype std_logic_max is resolved_max std_ulogic ; 74 subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ; 75 type std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 76 77 subtype unsigned_max is (resolved_max) unresolved_unsigned ; 78 type unsigned_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 79 subtype signed_max is (resolved_max) unresolved_signed ; 80 type signed_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 81 82 function resolved_max ( s : bit_vector) return bit ; 83 subtype bit_max is resolved_max bit ; 84 subtype bit_vector_max is (resolved_max) bit_vector ; 85 type bit_vector_max_c is array (natural range <>) of bit_max ; -- for non VHDL-2008 86 87 function resolved_max ( s : integer_vector ) return integer ; 88 subtype integer_max is resolved_max integer ; 89 subtype integer_vector_max is (resolved_max) integer_vector ; 90 type integer_vector_max_c is array (natural range <>) of integer_max ; -- for non VHDL-2008 91 92 function resolved_max ( s : time_vector ) return time ; 93 subtype time_max is resolved_max time ; 94 subtype time_vector_max is (resolved_max) time_vector ; 95 type time_vector_max_c is array (natural range <>) of time_max ; -- for non VHDL-2008 96 97 function resolved_max ( s : real_vector ) return real ; 98 subtype real_max is resolved_max real ; 99 subtype real_vector_max is (resolved_max) real_vector ; 100 type real_vector_max_c is array (natural range <>) of real_max ; -- for non VHDL-2008 101 102 function resolved_max ( s : string) return character ; 103 subtype character_max is resolved_max character ; 104 subtype string_max is (resolved_max) string ; 105 type string_max_c is array (positive range <>) of character_max ; -- for non VHDL-2008 106 107 function resolved_max ( s : boolean_vector) return boolean ; 108 subtype boolean_max is resolved_max boolean ; 109 subtype boolean_vector_max is (resolved_max) boolean_vector ; 110 type boolean_vector_max_c is array (natural range <>) of boolean_max ; -- for non VHDL-2008 111 112 113 -- return sum of values that /= type'left 114 -- No initializations required on ports, default of type'left is ok 115 function resolved_sum ( s : integer_vector ) return integer ; 116 subtype integer_sum is resolved_sum integer ; 117 subtype integer_vector_sum is (resolved_sum) integer_vector ; 118 type integer_vector_sum_c is array (natural range <>) of integer_sum ; -- for non VHDL-2008 119 120 function resolved_sum ( s : time_vector ) return time ; 121 subtype time_sum is resolved_sum time ; 122 subtype time_vector_sum is (resolved_sum) time_vector ; 123 type time_vector_sum_c is array (natural range <>) of time_sum ; -- for non VHDL-2008 124 125 function resolved_sum ( s : real_vector ) return real ; 126 subtype real_sum is resolved_sum real ; 127 subtype real_vector_sum is (resolved_sum) real_vector ; 128 type real_vector_sum_c is array (natural range <>) of real_sum ; -- for non VHDL-2008 129 130 131 -- resolved_weak 132 -- Special just for std_ulogic 133 -- No initializations required on ports, default of type'left is ok 134 function resolved_weak (s : std_ulogic_vector) return std_ulogic ; -- no init, type'left 135 subtype std_logic_weak is resolved_weak std_ulogic ; 136 subtype std_logic_vector_weak is (resolved_weak) std_ulogic_vector ; 137 138 139 -- legacy stuff 140 -- requires ports to be initialized to 0 in the appropriate type. 141 function resolved ( s : integer_vector ) return integer ; 142 subtype resolved_integer is resolved integer ; 143 144 function resolved ( s : time_vector ) return time ; 145 subtype resolved_time is resolved time ; 146 147 function resolved ( s : real_vector ) return real ; 148 subtype resolved_real is resolved real ; 149 150 function resolved (s : string) return character ; -- same as resolved_max 151 subtype resolved_character is resolved character ; 152 -- subtype resolved_string is (resolved) string ; -- subtype will replace type later 153 type resolved_string is array (positive range <>) of resolved_character; -- will change to subtype -- assert but no init 154 155 function resolved ( s : boolean_vector) return boolean ; --same as resolved_max 156 subtype resolved_boolean is resolved boolean ; 157 158end package ResolutionPkg ; 159package body ResolutionPkg is 160 161 -- resolved_max 162 -- return maximum value. Assert FAILURE if more than 1 /= type'left 163 -- No initializations required on ports, default of type'left is ok 164 165 -- Optimized version is just the following: 166 -- ------------------------------------------------------------ 167 -- function resolved_max ( s : <array_type> ) return <element_type> is 168 -- ------------------------------------------------------------ 169 -- begin 170 -- return maximum(s) ; 171 -- end function resolved_max ; 172 173 ------------------------------------------------------------ 174 function resolved_max (s : std_ulogic_vector) return std_ulogic is 175 ------------------------------------------------------------ 176 begin 177 return maximum(s) ; 178 end function resolved_max ; 179 180 ------------------------------------------------------------ 181 function resolved_max ( s : bit_vector ) return bit is 182 ------------------------------------------------------------ 183 begin 184 return maximum(s) ; 185 end function resolved_max ; 186 187 ------------------------------------------------------------ 188 function resolved_max ( s : integer_vector ) return integer is 189 ------------------------------------------------------------ 190 begin 191 return maximum(s) ; 192 end function resolved_max ; 193 194 ------------------------------------------------------------ 195 function resolved_max ( s : time_vector ) return time is 196 ------------------------------------------------------------ 197 begin 198 return maximum(s) ; 199 end function resolved_max ; 200 201 ------------------------------------------------------------ 202 function resolved_max ( s : real_vector ) return real is 203 ------------------------------------------------------------ 204 begin 205 return maximum(s) ; 206 end function resolved_max ; 207 208 ------------------------------------------------------------ 209 function resolved_max ( s : string ) return character is 210 ------------------------------------------------------------ 211 begin 212 return maximum(s) ; 213 end function resolved_max ; 214 215 ------------------------------------------------------------ 216 function resolved_max ( s : boolean_vector) return boolean is 217 ------------------------------------------------------------ 218 begin 219 return maximum(s) ; 220 end function resolved_max ; 221 222 223 -- resolved_sum - appropriate for numeric types 224 -- return sum of values that /= type'left 225 -- No initializations required on ports, default of type'left is ok 226 ------------------------------------------------------------ 227 function resolved_sum ( s : integer_vector ) return integer is 228 ------------------------------------------------------------ 229 variable result : integer := 0 ; 230 begin 231 for i in s'RANGE loop 232 if s(i) /= integer'left then 233 result := s(i) + result; 234 end if ; 235 end loop ; 236 return result ; 237 end function resolved_sum ; 238 239 ------------------------------------------------------------ 240 function resolved_sum ( s : time_vector ) return time is 241 ------------------------------------------------------------ 242 variable result : time := 0 sec ; 243 begin 244 for i in s'RANGE loop 245 if s(i) /= time'left then 246 result := s(i) + result; 247 end if ; 248 end loop ; 249 return result ; 250 end function resolved_sum ; 251 252 ------------------------------------------------------------ 253 function resolved_sum ( s : real_vector ) return real is 254 ------------------------------------------------------------ 255 variable result : real := 0.0 ; 256 begin 257 for i in s'RANGE loop 258 if s(i) /= real'left then 259 result := s(i) + result; 260 end if ; 261 end loop ; 262 return result ; 263 end function resolved_sum ; 264 265 266 -- resolved_weak 267 -- Special just for std_ulogic 268 -- No initializations required on ports, default of type'left is ok 269 type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC; 270 271 constant weak_resolution_table : stdlogic_table := ( 272 -- Resolution order: Z < U < W < X < - < L < H < 0 < 1 273 -- --------------------------------------------------------- 274 -- | U X 0 1 Z W L H - | | 275 -- --------------------------------------------------------- 276 ('U', 'X', '0', '1', 'U', 'W', 'L', 'H', '-'), -- | U | 277 ('X', 'X', '0', '1', 'X', 'X', 'L', 'H', '-'), -- | X | 278 ('0', '0', '0', '1', '0', '0', '0', '0', '0'), -- | 0 | 279 ('1', '1', '1', '1', '1', '1', '1', '1', '1'), -- | 1 | 280 ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'), -- | Z | 281 ('W', 'X', '0', '1', 'W', 'W', 'L', 'H', '-'), -- | W | 282 ('L', 'L', '0', '1', 'L', 'L', 'L', 'H', 'L'), -- | L | 283 ('H', 'H', '0', '1', 'H', 'H', 'W', 'H', 'H'), -- | H | 284 ('-', '-', '0', '1', '-', '-', 'L', 'H', '-') -- | - | 285 ); 286 287 ------------------------------------------------------------ 288 function resolved_weak (s : std_ulogic_vector) return std_ulogic is 289 ------------------------------------------------------------ 290 variable result : std_ulogic := 'Z' ; 291 begin 292 for i in s'RANGE loop 293 result := weak_resolution_table(result, s(i)) ; 294 end loop ; 295 return result ; 296 end function resolved_weak ; 297 298 299 -- legacy stuff. 300 -- requires ports to be initialized to 0 in the appropriate type. 301 302 ------------------------------------------------------------ 303 function resolved ( s : integer_vector ) return integer is 304 -- requires interface to be initialized to 0 305 ------------------------------------------------------------ 306 variable result : integer := 0 ; 307 variable failed : boolean := FALSE ; 308 begin 309 for i in s'RANGE loop 310 if s(i) /= 0 then 311 failed := failed or (result /= 0) ; 312 result := maximum(s(i),result); 313 end if ; 314 end loop ; 315 assert not failed report "ResolutionPkg.resolved: multiple drivers on integer" severity MULTIPLE_DRIVER_SEVERITY ; 316 -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on integer") ; 317 return result ; 318 end function resolved ; 319 320 ------------------------------------------------------------ 321 function resolved ( s : time_vector ) return time is 322 -- requires interface to be initialized to 0 ns 323 ------------------------------------------------------------ 324 variable result : time := 0 ns ; 325 variable failed : boolean := FALSE ; 326 begin 327 for i in s'RANGE loop 328 if s(i) > 0 ns then 329 failed := failed or (result /= 0 ns) ; 330 result := maximum(s(i),result); 331 end if ; 332 end loop ; 333 assert not failed report "ResolutionPkg.resolved: multiple drivers on time" severity MULTIPLE_DRIVER_SEVERITY ; 334 -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on time") ; 335 return result ; 336 end function resolved ; 337 338 ------------------------------------------------------------ 339 function resolved ( s : real_vector ) return real is 340 -- requires interface to be initialized to 0.0 341 ------------------------------------------------------------ 342 variable result : real := 0.0 ; 343 variable failed : boolean := FALSE ; 344 begin 345 for i in s'RANGE loop 346 if s(i) /= 0.0 then 347 failed := failed or (result /= 0.0) ; 348 result := maximum(s(i),result); 349 end if ; 350 end loop ; 351 assert not failed report "ResolutionPkg.resolved: multiple drivers on real" severity MULTIPLE_DRIVER_SEVERITY ; 352 -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on real") ; 353 return result ; 354 end function resolved ; 355 356 ------------------------------------------------------------ 357 function resolved (s : string) return character is 358 -- same as resolved_max 359 ------------------------------------------------------------ 360 variable result : character := NUL ; 361 variable failed : boolean := FALSE ; 362 begin 363 for i in s'RANGE loop 364 if s(i) /= NUL then 365 failed := failed or (result /= NUL) ; 366 result := maximum(result, s(i)) ; 367 end if ; 368 end loop ; 369 assert not failed report "ResolutionPkg.resolved: multiple drivers on character" severity MULTIPLE_DRIVER_SEVERITY ; 370 -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on character") ; 371 return result ; 372 end function resolved ; 373 374 ------------------------------------------------------------ 375 function resolved ( s : boolean_vector) return boolean is 376 -- same as resolved_max 377 ------------------------------------------------------------ 378 variable result : boolean := FALSE ; 379 variable failed : boolean := FALSE ; 380 begin 381 for i in s'RANGE loop 382 if s(i) then 383 failed := failed or result ; 384 result := TRUE ; 385 end if ; 386 end loop ; 387 assert not failed report "ResolutionPkg.resolved: multiple drivers on boolean" severity MULTIPLE_DRIVER_SEVERITY ; 388 -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on boolean") ; 389 return result ; 390 end function resolved ; 391 392end package body ResolutionPkg ; 393