diff --git a/packages/CoveragePkg.vhd b/CoveragePkg.vhd similarity index 87% rename from packages/CoveragePkg.vhd rename to CoveragePkg.vhd index 6a8c848..f54dbd0 100644 --- a/packages/CoveragePkg.vhd +++ b/CoveragePkg.vhd @@ -1,7 +1,7 @@ -- -- File Name: CoveragePkg.vhd -- Design Unit Name: CoveragePkg --- Revision: STANDARD VERSION, revision 2013.05 +-- Revision: STANDARD VERSION, revision 2014.01 -- -- Maintainer: Jim Lewis email: jim@synthworks.com -- Contributor(s): @@ -22,75 +22,63 @@ -- Latest standard version available at: -- http://www.SynthWorks.com/downloads -- --- Revision History: +-- Revision History: See also CoveragePkg_release_notes.pdf -- Date Version Description -- 06/2010: 0.1 Initial revision -- 09/2010 Release in SynthWorks' VHDL Testbenches and Verification classes -- 02/2011: 1.0 Requires VHDL-2008 types integer_vector and boolean_vecctor -- Changed CoverBinType to facilitage long term support of cross coverage -- 02/2011: 1.1 Added GetMinCov, GetMaxCov, CountCovHoles, GetCovHole --- 04/2011: 2.0 Added CovPType --- 06/2011: 2.1 Removed Signal Based Coverage --- 07/2011: 2.2 Added Weight, AtLeast, randomization with percentage thresholds +-- 04/2011: 2.0 Added protected type based data structure: CovPType +-- 06/2011: 2.1 Removed signal based coverage modeling +-- 07/2011: 2.2 Added randomization with coverage goals (AtLeast), weight, and percentage thresholds +-- Revised RandCovPoint, RandCovBinVal, AddBins, AddCross, GenBin, Added SetWeightMode -- Randomization with weights/weight modes -- Cleaned up parameter naming --- 11/2011: 2.2a Made ALL_RANGE and constants in ZERO_BIN and ONE_BIN have a 1 index +-- 11/2011: 2.2a Changed constants ALL_RANGE, ZERO_BIN, and ONE_BIN to have a 1 index -- rather than 0 to match the range of BinVal -- 12/2011: 2.2b Fixed minor inconsistencies on interface declarations. --- Library RandomPkg is assumed to be in the same library as CoveragePkg +-- Package RandomPkg is assumed to be in the same library as CoveragePkg -- 01/2012: 2.3 Added Function GetBin from Jerry K. -- Made write for RangeArrayType visible -- 01/2012: 2.4 --- Added bin merging and deletion for overlapping bins +-- Revised AddBins and AddCross to handle merging and deletion for overlapping bins +-- Note merging is an experimental feature. -- Renamed RandCovHole to RandCovBinVal - maintained old version calls new -- Renamed GetCovHole to GetHoleBinVal - maintained old version calls new -- 04/2013: 2013.04 --- Added control for merging and deletion. --- Note: Merging will change in a future revision. --- Merging is off by default. Use function SetMerging to turn it on. +-- Revised AddBins and AddCross s.t. bin merging is off by default. +-- Added SetMerging to enable/disable merging. +-- Note: Merging is an experimental feature and still evolving. +-- Revised AddBins and AddCross to check for changes in BinVal size (different size bin). -- Added RandCovPoint for integer. --- Thresholding is now enabled or disabled by an internal variable. --- Enable or disable using SetThresholding. Off by default. --- Revised RandCovPoint and RandCovBinVal to use thresholding. --- Thresholding is also turned on by SetCovThreshold(Percent). --- Added coverage target multiplier as a multiplier to all AtLeast values. --- Multiplier is CovTarget/100. It is 100% by default. --- Change it with SetCovTarget. Removed the default value from --- the PercentCov parameter of all methods (RandCovPoint, --- RandCovBinVal, IsCovered, CountCovHoles, GetHoleBinVal, and --- WriteCovHoles). Replaced the default value with an --- overloaded function that uses coverage target instead. --- Added ILLEGAL_FAILURE mode to illegal bin control. --- When set, if an illegal bin is encountered, a severity --- failure will be generated. +-- Added SetThresholding and SetCovThreshold(Percent) to enable/disable(default) thresholding. +-- Revised RandCovPoint and RandCovBinVal to use new mechanism. +-- Added SetCovTarget to increase/decrease coverage goals for longer/shorter simulation runs. +-- Made CovTarget the default percentage goal (via overloading) for methods RandCovPoint, +-- RandCovBinVal, IsCovered, CountCovHoles, GetHoleBinVal, and WriteCovHoles +-- Revised SetIllegalMode and ICover to support ILLEGAL_FAILURE (severity FAILURE on illegal bin). -- Added manual bin iteration support. -- BinIndex: GetNumBins, GetMinIndex, GetMaxIndex -- BinVal: GetBinVal(BinIndex), GetMinBinVal, GetMaxBinVal -- Point: GetPoint (BinIndex), GetMinPoint, GetMaxPoint --- Added FileOpenWriteBin and FileCloseWriteBin --- Opens default file for WriteBin, WriteCovHoles, and DumpBin +-- Added GetCov to return the current percent done of the entire coverage model. +-- Added FileOpenWriteBin and FileCloseWriteBin to specify default file for WriteBin, WriteCovHoles, and DumpBin -- Added CompareBins to facilitate comparing two coverage models. --- Added error checking to methods. --- Uninitialized model checks to WriteBin, WriteCovHoles, and WriteCovDb. --- Check AddBins or AddCross do not change the current BinVal size. +-- Revised WriteBin, WriteCovHoles, and WriteCovDb to check for uninitialized model. +-- Revised WriteBins and WriteCovHoles to only print weight if the selected WeightMode uses the weight. -- Added IsInitialized to check if a coverage model is initialized. -- Added GetBinInfo and GetBinValLength to get bin information --- WriteBins and WriteCovHoles only print weight if the selected WeightMode uses the weight. --- Changed WriteCovDb default for File_Open_Kind to WRITE_MODE --- Generally only one WriteCovDb is needed per coverage model. --- Updated WriteCovDb and ReadCovDb for new internal control/state variables --- in the order of ThresholdingEnable, CovTarget, and MergingEnable. --- To manually edit old file, add FALSE, 100.0, FALSE to end of first line --- Removed IgnoreBin with AtLeast and Weight parameters. --- These are zero for ignore bins. --- Working on consistency of naming. The following have changed: +-- Changed WriteCovDb default for File_Open_Kind to WRITE_MODE +-- Revised WriteCovDb and ReadCovDb for new internal control/state variables +-- Removed IgnoreBin with AtLeast and Weight parameters. These are zero for ignore bins. +-- Revised method naming for consistency. The following have changed: -- New Name Old Name Why -- CovBinErrCnt GetErrorCount Consistency between packages -- GetMinCount GetMinCov[return integer] Naming clarity -- GetMaxCount GetMaxCov[return integer] Naming clarity -- SetName SetItemName SetName now does multi-line messages --- --- The following methods with an AtLeast parameter are deprecated, +-- Deprecated usage of the AtLeast parameter (integer) with the following methods: -- RandCovPoint, RandCovBinVal, IsCovered, CountCovHoles, -- GetHoleBinVal, and WriteCovHoles. -- 5/2013 2013.05 @@ -98,8 +86,16 @@ -- Removed extra variable declaration in functions GetHoleBinval, -- RandCovBinVal, RandCovHole, GetHoleBinVal -- Using work.RandomPkg.NULL_RANGE_TYPE to remove NULL range warnings --- --- +-- 1/2014 2014.01 +-- Revised ReadCovDb to support merging of coverage models +-- Revised RandCovPoint and RandCovBinVal to log the bin index in the LastIndex variable +-- Revised ICover to look in bin referenced by LastIndex first +-- Added GetLastIndex and GetLastBinVal +-- Revised AddBins and AddCross bin merging to allow arbitrary CountBin overlap (facilitated by LastIndex) +-- Note: Merging is an experimental feature and still evolving. +-- Split SetName into SetMessage (headers) and SetName (printing illegal bins) +-- Added methods GetItemCount and GetTotalCovGoal +-- Revised GetCov to use CovTarget and overloaded to use a PercentCov parameter. -- -- Development Notes: -- The coverage procedures are named ICover to avoid conflicts with @@ -148,8 +144,9 @@ use std.textio.all ; -- library ieee_proposed ; -- remove with VHDL-2008 -- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008 -use work.RandomPkg.all ; use work.RandomBasePkg.all ; +use work.RandomPkg.all ; +use work.MessagePkg.all ; package CoveragePkg is @@ -164,7 +161,7 @@ package CoveragePkg is constant ALL_RANGE : RangeArrayType := (1=>(Integer'left, Integer'right)) ; procedure write ( file f : text ; BinVal : RangeArrayType ) ; - + procedure write ( variable buf : inout line ; constant BinVal : in RangeArrayType) ; -- CovBinBaseType.action values. -- Note that coverage counting depends on these values @@ -314,7 +311,9 @@ package CoveragePkg is procedure SetIllegalMode (A : IllegalModeType) ; procedure SetWeightMode (A : WeightModeType; Scale : real := 1.0) ; procedure SetName (NameIn : String) ; + procedure SetMessage (MessageIn : String) ; procedure DeallocateName ; -- clear name + procedure DeallocateMessage ; -- clear message procedure SetThresholding(A : boolean := TRUE ) ; -- 2.5 procedure SetCovThreshold (Percent : real) ; procedure SetCovTarget (Percent : real) ; -- 2.5 @@ -364,6 +363,7 @@ package CoveragePkg is procedure Deallocate ; + procedure ICoverLast ; procedure ICover( CovPoint : integer) ; procedure ICover( CovPoint : integer_vector) ; @@ -381,16 +381,22 @@ package CoveragePkg is impure function CountCovHoles return integer ; impure function IsCovered return boolean ; impure function IsCovered ( PercentCov : real ) return boolean ; + impure function GetCov ( PercentCov : real ) return real ; impure function GetCov return real ; -- PercentCov of entire model/all bins + impure function GetItemCount return integer ; + impure function GetTotalCovGoal ( PercentCov : real ) return integer ; + impure function GetTotalCovGoal return integer ; + impure function GetLastIndex return integer ; -- Return BinVal impure function GetBinVal ( BinIndex : integer ) return RangeArrayType ; + impure function GetLastBinVal return RangeArrayType ; impure function RandCovBinVal ( PercentCov : real ) return RangeArrayType ; impure function RandCovBinVal return RangeArrayType ; impure function GetMinBinVal return RangeArrayType ; impure function GetMaxBinVal return RangeArrayType ; - impure function GetHoleBinVal ( ReqHoleNum : integer ; CovTargetPercent : real ) return RangeArrayType ; - impure function GetHoleBinVal ( CovTargetPercent : real ) return RangeArrayType ; + impure function GetHoleBinVal ( ReqHoleNum : integer ; PercentCov : real ) return RangeArrayType ; + impure function GetHoleBinVal ( PercentCov : real ) return RangeArrayType ; impure function GetHoleBinVal ( ReqHoleNum : integer := 1 ) return RangeArrayType ; -- Return Points @@ -430,7 +436,7 @@ package CoveragePkg is procedure WriteCovHoles ( FileName : string; PercentCov : real ; OpenKind : File_Open_Kind := APPEND_MODE ) ; procedure DumpBin ; -- Development only - procedure ReadCovDb (FileName : string) ; + procedure ReadCovDb (FileName : string; Merge : boolean := FALSE) ; procedure WriteCovDb (FileName : string; OpenKind : File_Open_Kind := WRITE_MODE ) ; impure function GetErrorCount return integer ; @@ -727,16 +733,19 @@ package body CoveragePkg is ------------------------------------------------------------ - procedure write ( file f : text ; CovPoint : integer_vector ) is + procedure write ( + variable buf : inout line ; + CovPoint : integer_vector + ) is -- package local. called by ICover ------------------------------------------------------------ alias iCovPoint : integer_vector(1 to CovPoint'length) is CovPoint ; begin - write(f, "(" & integer'image(iCovPoint(1)) ) ; + write(buf, "(" & integer'image(iCovPoint(1)) ) ; for i in 2 to iCovPoint'right loop - write(f, "," & integer'image(iCovPoint(i)) ) ; + write(buf, "," & integer'image(iCovPoint(i)) ) ; end loop ; - write(f, ")") ; + swrite(buf, ")") ; end procedure write ; @@ -758,10 +767,49 @@ package body CoveragePkg is end procedure write ; + ------------------------------------------------------------ + procedure write ( + -- called by WriteBin and WriteCovHoles + ------------------------------------------------------------ + variable buf : inout line ; + constant BinVal : in RangeArrayType + ) is + ------------------------------------------------------------ + begin + for i in BinVal'range loop + if BinVal(i).min = BinVal(i).max then + write(buf, "(" & integer'image(BinVal(i).min) & ") " ) ; + elsif (BinVal(i).min = integer'left) and (BinVal(i).max = integer'right) then + swrite(buf, "(ALL) " ) ; + else + write(buf, "(" & integer'image(BinVal(i).min) & " to " & + integer'image(BinVal(i).max) & ") " ) ; + end if ; + end loop ; + end procedure write ; + + + ------------------------------------------------------------ + procedure WriteBinVal ( + -- package local for now + ------------------------------------------------------------ + variable buf : inout line ; + constant BinVal : in RangeArrayType + ) is + begin + for i in BinVal'range loop + write(buf, BinVal(i).min) ; + write(buf, ' ') ; + write(buf, BinVal(i).max) ; + write(buf, ' ') ; + end loop ; + end procedure WriteBinVal ; + + ------------------------------------------------------------ -- package local function failed (InValid : boolean ; Message : string := " ") return boolean is - -- Move to TbUtilPkg and make visible? + -- Move to TextUtilPkg and make visible? ------------------------------------------------------------ begin if InValid then @@ -833,22 +881,6 @@ package body CoveragePkg is end procedure read ; - ------------------------------------------------------------ - procedure write ( - -- package local for now - ------------------------------------------------------------ - variable buf : inout line ; - constant BinVal : in RangeArrayType - ) is - begin - for i in BinVal'range loop - write(buf, BinVal(i).min) ; - write(buf, ' ') ; - write(buf, BinVal(i).max) ; - write(buf, ' ') ; - end loop ; - end procedure write ; - -- ------------------------------------------------------------ function BinLengths ( @@ -1122,13 +1154,8 @@ package body CoveragePkg is type CovPType is protected body -- Name Data Structure - type LineListType ; - type LineListPtrType is access LineListType ; - type LineListType is record - Name : Line ; - NextPtr : LineListPtrType ; - end record LineListType ; - + variable Message : MessagePType ; + -- CoverageBin Data Structures type RangeArrayPtrType is access RangeArrayType ; @@ -1148,13 +1175,13 @@ package body CoveragePkg is variable NumBins : integer := 0 ; variable BinValLength : integer := 1 ; variable OrderCount : integer := 0 ; -- for statistics + variable ItemCount : integer := 0 ; -- Count of randomizations + variable LastIndex : integer := 1 ; -- Index of last randomization -- Internal Modes and Names variable IllegalMode : IllegalModeType := ILLEGAL_ON ; variable WeightMode : WeightModeType := AT_LEAST ; variable WeightScale : real := 1.0 ; - variable NameHeadPtr : LineListPtrType := NULL ; - variable NameTailPtr : LineListPtrType := NULL ; variable ThresholdingEnable : boolean := FALSE ; -- thresholding disabled by default variable CovThreshold : real := 45.0 ; @@ -1218,12 +1245,14 @@ package body CoveragePkg is ------------------------------------------------------------ procedure SetWeightMode (A : WeightModeType; Scale : real := 1.0) is ------------------------------------------------------------ + variable buf : line ; begin WeightMode := A ; WeightScale := Scale ; if (WeightMode = REMAIN_EXP) and (WeightScale > 2.0) then - write(OUTPUT, "%%WARNING: WeightScale > 2.0 and large Counts can cause RandCovPoint to fail due to integer values out of range" & LF) ; + swrite(buf, "%%WARNING: WeightScale > 2.0 and large Counts can cause RandCovPoint to fail due to integer values out of range") ; + writeline(OUTPUT, buf) ; end if ; if (WeightScale < 1.0) and (WeightMode = REMAIN_WEIGHT or WeightMode = REMAIN_SCALED) then report "WeightScale must be > 1.0 when WeightMode = REMAIN_WEIGHT or WeightMode = REMAIN_SCALED" @@ -1239,77 +1268,62 @@ package body CoveragePkg is ------------------------------------------------------------ procedure SetName (NameIn : String) is ------------------------------------------------------------ - variable NamePtr : line ; begin - NamePtr := new string'(NameIn) ; - if NameHeadPtr = NULL then - NameHeadPtr := new LineListType'(NamePtr, NULL) ; - NameTailPtr := NameHeadPtr ; - if not RvSeedInit then - RV.InitSeed(NameIn) ; - RvSeedInit := TRUE ; - end if ; - else - NameTailPtr.NextPtr := new LineListType'(NamePtr, NULL) ; - NameTailPtr := NameTailPtr.NextPtr ; + Message.SetName(NameIn) ; + if not RvSeedInit then -- Init seed if not initialized + RV.InitSeed(NameIn) ; + RvSeedInit := TRUE ; + end if ; + end procedure SetName ; + + ------------------------------------------------------------ + procedure SetMessage (MessageIn : String) is + ------------------------------------------------------------ + begin + Message.SetMessage(MessageIn) ; + if not RvSeedInit then -- Init seed if not initialized + RV.InitSeed(MessageIn) ; + RvSeedInit := TRUE ; end if ; - end procedure SetName ; + end procedure SetMessage ; ------------------------------------------------------------ -- pt local for now -- file formal parameter not allowed with a public method procedure WriteBinName ( file f : text ; S : string ; Prefix : string := "%%" ) is ------------------------------------------------------------ - variable CurPtr : LineListPtrType ; + variable MessageCount : integer ; variable buf : line ; begin - if NameHeadPtr = NULL then + MessageCount := Message.GetMessageCount ; + if MessageCount = 0 then if Prefix'length + S'length > 0 then write(buf, Prefix & S) ; writeline(f, buf) ; -- write(f, Prefix & S & LF); end if ; else - write(buf, Prefix & S & NameHeadPtr.Name.all) ; + write(buf, Prefix & S & Message.GetMessage(1)) ; writeline(f, buf) ; - -- write(f, Prefix & S & NameHeadPtr.Name.all & LF) ; - CurPtr := NameHeadPtr.NextPtr ; - while CurPtr /= NULL loop - write(buf, Prefix & CurPtr.Name.all) ; + for i in 2 to MessageCount loop + write(buf, Prefix & Message.GetMessage(i)) ; writeline(f, buf) ; - -- write(f, Prefix & CurPtr.Name.all & LF) ; - CurPtr := CurPtr.NextPtr ; end loop ; end if ; end procedure WriteBinName ; ------------------------------------------------------------ - procedure DeallocateName is + procedure DeallocateMessage is ------------------------------------------------------------ - variable CurPtr : LineListPtrType ; begin - while NameHeadPtr /= NULL loop - CurPtr := NameHeadPtr ; - NameHeadPtr := NameHeadPtr.NextPtr ; - deallocate( CurPtr.Name) ; - deallocate( CurPtr ) ; - end loop ; - NameTailPtr := NULL ; -- contents deallocated above - end procedure DeallocateName ; + Message.DeallocateMessage ; + end procedure DeallocateMessage ; ------------------------------------------------------------ - -- pt local - impure function NumberOfNames return integer is + procedure DeallocateName is ------------------------------------------------------------ - variable CurPtr : LineListPtrType ; - variable Count : integer := 0 ; begin - CurPtr := NameHeadPtr ; - while CurPtr /= NULL loop - Count := Count + 1 ; - CurPtr := CurPtr.NextPtr ; - end loop ; - return Count ; - end function NumberOfNames ; + Message.DeallocateName ; + end procedure DeallocateName ; ------------------------------------------------------------ procedure SetThresholding (A : boolean := TRUE ) is @@ -1465,7 +1479,7 @@ package body CoveragePkg is begin Position := NumBins + 1 ; FoundInside := FALSE ; - FindLoop : for i in 1 to NumBins loop + FindLoop : for i in NumBins downto 1 loop -- skip this CovBin if CovPoint is not in it next FindLoop when not inside(BinVal, CovBinPtr(i).BinVal.all) ; Position := i ; @@ -1474,8 +1488,50 @@ package body CoveragePkg is end loop ; end procedure FindBinInside ; + ------------------------------------------------------------ + -- pt local + -- Inserts values into a new bin. + -- Called by InsertBin + procedure InsertNewBin( + BinVal : RangeArrayType ; + Action : integer ; + Count : integer ; + AtLeast : integer ; + Weight : integer ; + PercentCov : real := 0.0 + ) is + begin + NumBins := NumBins + 1 ; + CovBinPtr.all(NumBins).BinVal := new RangeArrayType'(BinVal) ; + CovBinPtr.all(NumBins).Action := Action ; + CovBinPtr.all(NumBins).Count := Count ; + CovBinPtr.all(NumBins).AtLeast := AtLeast ; + CovBinPtr.all(NumBins).Weight := Weight ; + CovBinPtr.all(NumBins).PercentCov := PercentCov ; + CovBinPtr.all(NumBins).OrderCount := 0 ; --- Metrics for evaluating randomization order Temp + end procedure InsertNewBin ; - ------------------------------------------------------------ + + ------------------------------------------------------------ + -- pt local + -- Inserts values into a new bin. + -- Called by InsertBin + procedure MergeBin ( + Position : Natural ; + Count : integer ; + AtLeast : integer ; + Weight : integer + ) is + begin + CovBinPtr.all(Position).Count := CovBinPtr.all(Position).Count + Count ; + CovBinPtr.all(Position).AtLeast := CovBinPtr.all(Position).AtLeast + AtLeast ; + CovBinPtr.all(Position).Weight := CovBinPtr.all(Position).Weight + Weight ; + CovBinPtr.all(Position).PercentCov := + real(CovBinPtr.all(Position).Count)*100.0/maximum(real(CovBinPtr.all(Position).AtLeast), 1.0) ; + end procedure MergeBin ; + + + ------------------------------------------------------------ -- pt local -- All insertion comes here -- Enforces the general insertion use model: @@ -1494,50 +1550,46 @@ package body CoveragePkg is variable Position : integer ; variable FoundInside : boolean ; begin - FindBinInside(BinVal, Position, FoundInside) ; - if not MergingEnable or CountMode = COUNT_ALL or not FoundInside then - -- Usage: general insertion - NumBins := NumBins + 1 ; - CovBinPtr.all(NumBins).BinVal := new RangeArrayType'(BinVal) ; - CovBinPtr.all(NumBins).Action := Action ; - CovBinPtr.all(NumBins).Count := Count ; - CovBinPtr.all(NumBins).AtLeast := AtLeast ; - CovBinPtr.all(NumBins).Weight := Weight ; - CovBinPtr.all(NumBins).PercentCov := PercentCov ; - CovBinPtr.all(NumBins).OrderCount := 0 ; --- Metrics for evaluating randomization order Temp - elsif Action = COV_COUNT then - if CovBinPtr.all(Position).Action = COV_COUNT then - if CovBinPtr.all(Position).BinVal.all = BinVal then - -- Usage: When count bins are equal, merge them. - CovBinPtr.all(Position).AtLeast := CovBinPtr.all(Position).AtLeast + AtLeast ; - CovBinPtr.all(Position).Weight := CovBinPtr.all(Position).Weight + Weight ; - CovBinPtr.all(Position).Count := CovBinPtr.all(Position).Count + Count ; - CovBinPtr.all(Position).PercentCov := - real(CovBinPtr.all(Position).Count)*100.0/maximum(real(CovBinPtr.all(Position).AtLeast), 1.0) ; + if not MergingEnable then + InsertNewBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; + + else -- handle merging +-- future optimization, FindBinInside only checks against Ignore and Illegal bins + FindBinInside(BinVal, Position, FoundInside) ; + + if not FoundInside then + InsertNewBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; + + elsif Action = COV_COUNT then +-- when check only ignore and illegal bins, only action is to drop + if CovBinPtr.all(Position).Action /= COV_COUNT then + null ; -- drop count bin when it is inside a Illegal or Ignore bin + + elsif CovBinPtr.all(Position).BinVal.all = BinVal then + -- Bins match, so merge the count values + MergeBin (Position, Count, AtLeast, Weight) ; else - -- Usage: Count bin inside a previous count bin is an error, unless COUNT_ALL - -- ?? Can we run into this algorithmically? - if so can add variable to allow it - -- if CountMode /= COUNT_ALL then -- this check is redundant - report "InsertBin (AddBins/AddCross): inserted count bin is a subset of prior count bin" severity failure ; - -- end if ; - end if; - else - -- Usage: Drop count bin when in either ignore or illegal bin - -- Facilitates capture of count bins - null ; -- quietly drop the bin + -- Bins overlap, but do not match, insert new bin + InsertNewBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; + end if; + + elsif Action = COV_IGNORE then +-- when check only ignore and illegal bins, only action is to report error + if CovBinPtr.all(Position).Action = COV_COUNT then + InsertNewBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; + else + report "InsertBin (AddBins/AddCross): ignore bin dropped. It is a subset of prior bin" severity error ; + end if; + + elsif Action = COV_ILLEGAL then +-- when check only ignore and illegal bins, only action is to report error + if CovBinPtr.all(Position).Action = COV_COUNT then + InsertNewBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; + else + report "InsertBin (AddBins/AddCross): illegal bin dropped. It is a subset of prior bin" severity error ; + end if; end if ; - elsif ACTION = COV_IGNORE then - -- Usage: Most likely an error. - -- Potential: fine grain entry of catch-all ignore bins - -- However, ignore bins are non-signaling, so fine grain entry not useful - report "InsertBin (AddBins/AddCross): inserted ignore bin dropped. It is a subset of prior bin" severity error ; - -- null ; -- quietly drop the bin - elsif ACTION = COV_ILLEGAL then - -- Usage: fine grain entry of catch-all illegal bins, - -- Illegal bins are signaling. Drop the ones with overlap. - report "InsertBin (AddBins/AddCross): inserted illegal bin dropped. It is a subset of prior bin" severity error ; - -- null ; -- quietly drop the bin - end if ; + end if ; -- merging enabled end procedure InsertBin ; @@ -1668,7 +1720,7 @@ package body CoveragePkg is deallocate(CovBinPtr(i).BinVal) ; end loop ; deallocate(CovBinPtr) ; - DeallocateName ; + Message.Deallocate ; -- Restore internal variables to their default values NumBins := 0 ; OrderCount := 0 ; @@ -1686,42 +1738,68 @@ package body CoveragePkg is ------------------------------------------------------------ - procedure ICover ( CovPoint : integer) is + -- Local + procedure ICoverIndex( Index : integer ; CovPoint : integer_vector ) is ------------------------------------------------------------ + variable buf : line ; begin - ICover((1=> CovPoint)) ; - end procedure ICover ; + -- Update Count, PercentCov + CovBinPtr(Index).Count := CovBinPtr(Index).Count + CovBinPtr(Index).action ; + CovBinPtr(Index).PercentCov := real(CovBinPtr(Index).Count)*100.0/maximum(real(CovBinPtr(Index).AtLeast), 1.0) ; + -- OrderCount handling - Statistics + OrderCount := OrderCount + 1 ; + CovBinPtr(Index).OrderCount := OrderCount + CovBinPtr(Index).OrderCount ; + if CovBinPtr(Index).action = COV_ILLEGAL and IllegalMode /= ILLEGAL_OFF then + write(buf, "%% " & Message.GetName & " Illegal Value: " ) ; + if CovPoint = NULL_INTV then + swrite(buf, "LastIndex Value") ; + else + write(buf, CovPoint) ; + end if ; + write(buf, " is in an illegal Bin. " & "Time: " & time'image(now)) ; + writeline(OUTPUT, buf) ; + if IllegalMode = ILLEGAL_FAILURE then + report Message.GetName & " Illegal Value" severity failure ; + end if ; + end if ; + end procedure ICoverIndex ; ------------------------------------------------------------ - procedure ICover( CovPoint : integer_vector) is + procedure ICoverLast is ------------------------------------------------------------ begin - CovLoop : for i in 1 to NumBins loop - -- skip this CovBin if CovPoint is not in it - next CovLoop when not inside(CovPoint, CovBinPtr(i).BinVal.all) ; + ICoverIndex(LastIndex, NULL_INTV) ; + end procedure ICoverLast ; - -- found CovPoint in this CovBin, run this code and exit. - CovBinPtr(i).Count := CovBinPtr(i).Count + CovBinPtr(i).action ; - -- place holder for actions to do to weight vector - CovBinPtr(i).PercentCov := real(CovBinPtr(i).Count)*100.0/maximum(real(CovBinPtr(i).AtLeast), 1.0) ; + ------------------------------------------------------------ + procedure ICover ( CovPoint : integer) is + ------------------------------------------------------------ + begin + ICover((1=> CovPoint)) ; + end procedure ICover ; - -- OrderCount handling - OrderCount := OrderCount + 1 ; - CovBinPtr(i).OrderCount := OrderCount + CovBinPtr(i).OrderCount ; - if CovBinPtr(i).action = COV_ILLEGAL and IllegalMode /= ILLEGAL_OFF then - write(OUTPUT, "%%Illegal Value: " ) ; - write(OUTPUT, CovPoint) ; - write(OUTPUT, " is in an illegal Bin. " & "Time: " & time'image(now) & LF) ; - if IllegalMode = ILLEGAL_FAILURE then - report "Illegal Value" severity failure ; - end if ; - end if ; - exit CovLoop when CountMode = COUNT_FIRST ; -- only find first one - end loop CovLoop ; - end procedure ICover ; + ------------------------------------------------------------ + procedure ICover( CovPoint : integer_vector) is + ------------------------------------------------------------ + variable Found : boolean := FALSE ; + begin + if CountMode = COUNT_FIRST and inside(CovPoint, CovBinPtr(LastIndex).BinVal.all) then + ICoverIndex(LastIndex, CovPoint) ; + Found := TRUE ; + end if; + if not Found then + CovLoop : for i in 1 to NumBins loop + -- skip this CovBin if CovPoint is not in it + next CovLoop when not inside(CovPoint, CovBinPtr(i).BinVal.all) ; + -- Mark Covered + ICoverIndex(i, CovPoint) ; + exit CovLoop when CountMode = COUNT_FIRST ; -- only find first one + end loop CovLoop ; + end if ; + end procedure ICover ; ------------------------------------------------------------ @@ -1882,19 +1960,20 @@ package body CoveragePkg is end function IsCovered ; - ------------------------------------------------------------ - impure function GetCov return real is ------------------------------------------------------------ - variable TotalCovGoal, TotalCovCount : integer := 0 ; + impure function GetCov ( PercentCov : real ) return real is + ------------------------------------------------------------ + variable TotalCovGoal, TotalCovCount, ScaledCovGoal : integer := 0 ; begin BinLoop : for i in 1 to NumBins loop if CovBinPtr(i).action = COV_COUNT then - TotalCovGoal := TotalCovGoal + CovBinPtr(i).AtLeast ; - if CovBinPtr(i).Count <= CovBinPtr(i).AtLeast then + ScaledCovGoal := integer(ceil(PercentCov * real(CovBinPtr(i).AtLeast)/100.0)) ; + TotalCovGoal := TotalCovGoal + ScaledCovGoal ; + if CovBinPtr(i).Count <= ScaledCovGoal then TotalCovCount := TotalCovCount + CovBinPtr(i).Count ; else -- do not count the extra values that exceed their cov goal - TotalCovCount := TotalCovCount + CovBinPtr(i).AtLeast ; + TotalCovCount := TotalCovCount + ScaledCovGoal ; end if ; end if ; end loop BinLoop ; @@ -1903,30 +1982,80 @@ package body CoveragePkg is ------------------------------------------------------------ - impure function GetHoleBinVal ( ReqHoleNum : integer ; CovTargetPercent : real ) return RangeArrayType is + impure function GetCov return real is + ------------------------------------------------------------ + variable TotalCovGoal, TotalCovCount : integer := 0 ; + begin + return GetCov( CovTarget ) ; + end function GetCov ; + + + ------------------------------------------------------------ + impure function GetItemCount return integer is + ------------------------------------------------------------ + begin + return ItemCount ; + end function GetItemCount ; + + + ------------------------------------------------------------ + impure function GetTotalCovGoal ( PercentCov : real ) return integer is + ------------------------------------------------------------ + variable TotalCovGoal, ScaledCovGoal : integer := 0 ; + begin + BinLoop : for i in 1 to NumBins loop + if CovBinPtr(i).action = COV_COUNT then + ScaledCovGoal := integer(ceil(PercentCov * real(CovBinPtr(i).AtLeast)/100.0)) ; + TotalCovGoal := TotalCovGoal + ScaledCovGoal ; + end if ; + end loop BinLoop ; + return TotalCovGoal ; + end function GetTotalCovGoal ; + + + ------------------------------------------------------------ + impure function GetTotalCovGoal return integer is + ------------------------------------------------------------ + begin + return GetTotalCovGoal(CovTarget) ; + end function GetTotalCovGoal ; + + + ------------------------------------------------------------ + impure function GetLastIndex return integer is + ------------------------------------------------------------ + begin + return LastIndex ; + end function GetLastIndex ; + + + ------------------------------------------------------------ + impure function GetHoleBinVal ( ReqHoleNum : integer ; PercentCov : real ) return RangeArrayType is ------------------------------------------------------------ variable HoleCount : integer := 0 ; + variable buf : line ; begin CovLoop : for i in 1 to NumBins loop - if CovBinPtr(i).action = COV_COUNT and CovBinPtr(i).PercentCov < CovTargetPercent then + if CovBinPtr(i).action = COV_COUNT and CovBinPtr(i).PercentCov < PercentCov then HoleCount := HoleCount + 1 ; if HoleCount = ReqHoleNum then return CovBinPtr(i).BinVal.all ; end if ; end if ; end loop CovLoop ; - write(OUTPUT, "%%Error GetHoleBinVal did not find hole. " & + write(buf, "%%Error GetHoleBinVal did not find hole. " & "HoleCount = " & integer'image(HoleCount) & "ReqHoleNum = " & integer'image(ReqHoleNum) & LF) ; + writeline(OUTPUT, buf) ; return CovBinPtr(NumBins).BinVal.all ; end function GetHoleBinVal ; ------------------------------------------------------------ - impure function GetHoleBinVal ( CovTargetPercent : real ) return RangeArrayType is + impure function GetHoleBinVal ( PercentCov : real ) return RangeArrayType is ------------------------------------------------------------ begin - return GetHoleBinVal(1, CovTargetPercent) ; + return GetHoleBinVal(1, PercentCov) ; end function GetHoleBinVal ; @@ -1989,6 +2118,7 @@ package body CoveragePkg is variable MaxCovPercent : real ; variable MinCovPercent : real ; begin + ItemCount := ItemCount + 1 ; MinCovPercent := GetMinCov ; if ThresholdingEnable then MaxCovPercent := MinCovPercent + CovThreshold ; @@ -2017,7 +2147,8 @@ package body CoveragePkg is -- DistInt returns integer range 0 to Numbins-1 -- Caution: DistInt can fail when sum(WeightVec) > 2**31 -- See notes in CalcWeight for REMAIN_EXP - return 1 + RV.DistInt( WeightVec ) ; -- return range 1 to NumBins + LastIndex := 1 + RV.DistInt( WeightVec ) ; -- return range 1 to NumBins + return LastIndex ; end function RandHoleIndex ; @@ -2029,6 +2160,14 @@ package body CoveragePkg is end function GetBinVal ; + ------------------------------------------------------------ + impure function GetLastBinVal return RangeArrayType is + ------------------------------------------------------------ + begin + return CovBinPtr( LastIndex ).BinVal.all ; + end function GetLastBinVal ; + + ------------------------------------------------------------ impure function RandCovBinVal ( PercentCov : real ) return RangeArrayType is ------------------------------------------------------------ @@ -2135,7 +2274,7 @@ package body CoveragePkg is begin return ToRandPoint(GetBinVal(BinIndex)) ; end function GetPoint ; - + ------------------------------------------------------------ impure function GetMinPoint return integer is @@ -2326,31 +2465,34 @@ package body CoveragePkg is -- pt local for now -- file formal parameter not allowed with method procedure WriteBin ( file f : text ) is ------------------------------------------------------------ + variable buf : line ; begin WriteBinName(f, "WriteBin: ") ; if NumBins < 1 then - Write(f, "%%FATAL, Coverage Model is empty. Nothing to print." & LF ) ; + swrite(buf, "%%FATAL, Coverage Model is empty. Nothing to print.") ; + writeline(f, buf) ; report "Coverage model is empty. Nothing to print." severity failure ; end if ; for i in 1 to NumBins loop -- CovBinPtr.all'range if CovBinPtr(i).count < 0 then - write(f, "%%Illegal Bin:") ; - write(f, CovBinPtr(i).BinVal.all) ; - write(f, " Count = " & integer'image(-CovBinPtr(i).count)) ; - write(f, "" & LF) ; + swrite(buf, "%%Illegal Bin:") ; + write(buf, CovBinPtr(i).BinVal.all) ; + write(buf, " Count = " & integer'image(-CovBinPtr(i).count)) ; + write(buf, "" & LF) ; elsif CovBinPtr(i).action = COV_COUNT then - write(f, "%% Bin:") ; - write(f, CovBinPtr(i).BinVal.all) ; - write(f, " Count = " & integer'image(CovBinPtr(i).count)) ; - write(f, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; + swrite(buf, "%% Bin:") ; + write(buf, CovBinPtr(i).BinVal.all) ; + write(buf, " Count = " & integer'image(CovBinPtr(i).count)) ; + write(buf, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; if WeightMode = WEIGHT or WeightMode = REMAIN_WEIGHT then -- Print Weight only when it is used - write(f, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; + write(buf, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; end if ; - write(f, "" & LF) ; + writeline(f, buf) ; end if ; end loop ; - write(f, "" & LF) ; + swrite(buf, "") ; + writeline(f, buf) ; end procedure WriteBin ; @@ -2380,31 +2522,33 @@ package body CoveragePkg is -- pt local for now -- file formal parameter not allowed with method procedure DumpBin ( file f : text ) is ------------------------------------------------------------ + variable buf : line ; begin WriteBinName(f, "DumpBin: ") ; -- if NumBins < 1 then -- Write(f, "%%FATAL, Coverage Model is empty. Nothing to print." & LF ) ; -- end if ; for i in 1 to NumBins loop -- CovBinPtr.all'range - write(f, "%% Bin:") ; - write(f, CovBinPtr(i).BinVal.all) ; + swrite(buf, "%% Bin:") ; + write(buf, CovBinPtr(i).BinVal.all) ; case CovBinPtr(i).action is - when COV_COUNT => write(f, " Count = ") ; - when COV_IGNORE => write(f, " Ignore = ") ; - when COV_ILLEGAL => write(f, " Illegal = ") ; - when others => write(f, " BOGUS BOGUS BOGUS = ") ; + when COV_COUNT => swrite(buf, " Count = ") ; + when COV_IGNORE => swrite(buf, " Ignore = ") ; + when COV_ILLEGAL => swrite(buf, " Illegal = ") ; + when others => swrite(buf, " BOGUS BOGUS BOGUS = ") ; end case ; - write(f, integer'image(CovBinPtr(i).count)) ; + write(buf, CovBinPtr(i).count) ; -- write(f, " Count = " & integer'image(CovBinPtr(i).count)) ; - write(f, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; - write(f, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; - write(f, " OrderCount = " & integer'image(CovBinPtr(i).OrderCount)) ; + write(buf, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; + write(buf, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; + write(buf, " OrderCount = " & integer'image(CovBinPtr(i).OrderCount)) ; if CovBinPtr(i).count > 0 then - write(f, " Normalized OrderCount = " & integer'image(CovBinPtr(i).OrderCount/CovBinPtr(i).count)) ; + write(buf, " Normalized OrderCount = " & integer'image(CovBinPtr(i).OrderCount/CovBinPtr(i).count)) ; end if ; - write(f, "" & LF) ; + writeline(f, buf) ; end loop ; - write(f, "" & LF) ; + swrite(buf, "") ; + writeline(f,buf) ; end procedure DumpBin ; @@ -2424,26 +2568,29 @@ package body CoveragePkg is -- pt local procedure WriteCovHoles ( file f : text; PercentCov : real := 100.0 ) is ------------------------------------------------------------ + variable buf : line ; begin WriteBinName(f, "WriteCovHoles: ") ; if NumBins < 1 then - Write(f, "%%FATAL, Coverage Model is empty. Nothing to print." & LF ) ; + swrite(buf, "%%FATAL, Coverage Model is empty. Nothing to print.") ; + writeline(f, buf) ; report "Coverage model is empty. Nothing to print." severity failure ; end if ; CovLoop : for i in 1 to NumBins loop if CovBinPtr(i).action = COV_COUNT and CovBinPtr(i).PercentCov < PercentCov then - write(f, "%% Bin:") ; - write(f, CovBinPtr(i).BinVal.all) ; - write(f, " Count = " & integer'image(CovBinPtr(i).Count)) ; - write(f, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; + swrite(buf, "%% Bin:") ; + write(buf, CovBinPtr(i).BinVal.all) ; + write(buf, " Count = " & integer'image(CovBinPtr(i).Count)) ; + write(buf, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; if WeightMode = WEIGHT or WeightMode = REMAIN_WEIGHT then -- Print Weight only when it is used - write(f, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; + write(buf, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; end if ; - write(f, "" & LF) ; + writeline(f, buf) ; end if ; end loop CovLoop ; - write(f, "" & LF) ; + swrite(buf, "") ; + writeline(f, buf) ; end procedure WriteCovHoles ; @@ -2493,15 +2640,18 @@ package body CoveragePkg is -- pt local impure function FindBin ( ------------------------------------------------------------ + Merge : boolean ; BinVal : RangeArrayType ; Action : integer ) return integer is begin - for i in 1 to NumBins loop - if BinVal = CovBinPtr(i).BinVal.all and Action = CovBinPtr(i).Action then - return i ; - end if; - end loop ; + if Merge then + for i in 1 to NumBins loop + if BinVal = CovBinPtr(i).BinVal.all and Action = CovBinPtr(i).Action then + return i ; + end if; + end loop ; + end if ; return 0 ; end function FindBin ; @@ -2521,12 +2671,25 @@ package body CoveragePkg is variable iWeightScale : real ; variable iCovThreshold : real ; variable iCountMode : integer ; - variable iNumberOfNames : integer ; + variable iNumberOfMessages : integer ; variable iThresholdingEnable : boolean ; variable iCovTarget : real ; variable iMergingEnable : boolean ; begin + ReadLoop0 : while not EndFile(CovDbFile) loop + ReadLine(CovDbFile, buf) ; + EmptyOrCommentLine(buf, Empty) ; + next when Empty ; + + if buf.all /= "CoveragePkg_Not_Named" then + Message.SetName(buf.all) ; + end if ; + + exit ReadLoop0 ; + end loop ReadLoop0 ; + + ReadLoop1 : while not EndFile(CovDbFile) loop ReadLine(CovDbFile, buf) ; EmptyOrCommentLine(buf, Empty) ; @@ -2579,12 +2742,13 @@ package body CoveragePkg is EmptyOrCommentLine(buf, Empty) ; next when Empty ; - read(buf, iNumberOfNames, ReadValid) ; - exit ReadLoop2 when failed(not ReadValid, "ReadCovDb: Failed while reading NumberOfNames") ; + read(buf, iNumberOfMessages, ReadValid) ; + exit ReadLoop2 when failed(not ReadValid, "ReadCovDb: Failed while reading NumberOfMessages") ; - for i in 1 to iNumberOfNames loop + for i in 1 to iNumberOfMessages loop + exit ReadLoop2 when failed(EndFile(CovDbFile), "ReadCovDb: End of File while reading Messages") ; ReadLine(CovDbFile, buf) ; - SetName(buf.all) ; + SetMessage(buf.all) ; end loop ; exit ReadLoop2 ; @@ -2627,12 +2791,13 @@ package body CoveragePkg is ------------------------------------------------------------ -- pt local - procedure ReadCovDb ( + procedure ReadCovDbDataBase ( ------------------------------------------------------------ File CovDbFile : text ; constant NumRangeItems : in integer ; constant NumLines : in integer ; - variable Good : out boolean + constant Merge : in boolean ; + variable Good : out boolean ) is variable buf : line ; variable Empty : boolean ; @@ -2666,22 +2831,21 @@ package body CoveragePkg is read(buf, BinVal, ReadValid) ; exit ReadLoop when failed(not ReadValid, "ReadCovDb: Failed while reading BinVal") ; - index := FindBin(BinVal, Action) ; - if index > 0 then -- found it. --- Should count add to current count? - CovBinPtr(index).Count := Count ; + index := FindBin(Merge, BinVal, Action) ; + if index > 0 then -- merge it + CovBinPtr(index).Count := CovBinPtr(index).Count + Count ; + CovBinPtr(index).PercentCov := real(CovBinPtr(index).Count)*100.0/maximum(real(CovBinPtr(index).AtLeast), 1.0) ; else - InsertBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; - end if ; + InsertNewBin(BinVal, Action, Count, AtLeast, Weight, PercentCov) ; + end if ; end loop ReadLoop ; Good := ReadValid ; - end ReadCovDb ; + end ReadCovDbDataBase ; ------------------------------------------------------------ -- pt local - procedure ReadCovDb ( File CovDbFile : text ) is - -- procedure ReadCovDb (FileName : string) is + procedure ReadCovDb (File CovDbFile : text; Merge : boolean := FALSE) is ------------------------------------------------------------ -- Format: Action Count min1 max1 min2 max2 -- file CovDbFile : text open READ_MODE is FileName ; @@ -2689,6 +2853,10 @@ package body CoveragePkg is variable NumLines : integer ; variable ReadValid : boolean ; begin + if not Merge then + Deallocate ; -- remove any old bins + end if ; + ReadLoop : loop -- Read coverage private variables to the file ReadCovVars(CovDbFile, ReadValid) ; @@ -2699,19 +2867,19 @@ package body CoveragePkg is exit when not ReadValid ; -- Read the file - ReadCovDb(CovDbFile, NumRangeItems, NumLines, ReadValid) ; + ReadCovDbDataBase(CovDbFile, NumRangeItems, NumLines, Merge, ReadValid) ; exit ; end loop ReadLoop ; end ReadCovDb ; ------------------------------------------------------------ - procedure ReadCovDb (FileName : string) is + procedure ReadCovDb (FileName : string; Merge : boolean := FALSE) is ------------------------------------------------------------ -- Format: Action Count min1 max1 min2 max2 file CovDbFile : text open READ_MODE is FileName ; begin - ReadCovDb(CovDbFile) ; + ReadCovDb(CovDbFile, Merge) ; end procedure ReadCovDb ; @@ -2722,6 +2890,13 @@ package body CoveragePkg is variable buf : line ; begin -- write coverage private variables to the file + if Message.GetName /= "" then + write(buf, Message.GetName) ; + else + swrite(buf, "CoveragePkg_Not_Named") ; + end if ; + writeline(CovDbFile, buf) ; + write(buf, RV.GetSeed ) ; write(buf, ' ') ; write(buf, CovThreshold) ; @@ -2741,7 +2916,7 @@ package body CoveragePkg is write(buf, MergingEnable) ; -- boolean write(buf, ' ') ; writeline(CovDbFile, buf) ; - write(buf, NumberOfNames ) ; + write(buf, Message.GetMessageCount ) ; writeline(CovDbFile, buf) ; WriteBinName(CovDbFile, "", "") ; end procedure WriteCovVars ; @@ -2775,7 +2950,7 @@ package body CoveragePkg is write(buf, ' ') ; write(buf, CovBinPtr(LineCount).PercentCov) ; write(buf, ' ') ; - write(buf, CovBinPtr(LineCount).BinVal.all) ; + WriteBinVal(buf, CovBinPtr(LineCount).BinVal.all) ; writeline(CovDbFile, buf) ; end loop WriteLoop ; end procedure WriteCovDb ; @@ -2997,11 +3172,11 @@ package body CoveragePkg is -- ------------------------------------------------------------ ------------------------------------------------------------ - -- Deprecated. Replaced by SetName with multi-line support + -- Deprecated. Replaced by SetMessage with multi-line support procedure SetItemName (ItemNameIn : String) is ------------------------------------------------------------ begin - SetName(ItemNameIn) ; + SetMessage(ItemNameIn) ; end procedure SetItemName ; @@ -3092,6 +3267,7 @@ package body CoveragePkg is variable WeightVec : integer_vector(0 to NumBins-1) ; -- Prep for change to DistInt variable MinCount, AdjAtLeast, MaxAtLeast : integer ; begin + ItemCount := ItemCount + 1 ; MinCount := GetMinCov ; -- iAtLeast := integer(ceil(CovTarget * real(AtLeast)/100.0)) ; if ThresholdingEnable then @@ -3123,7 +3299,8 @@ package body CoveragePkg is end if ; end loop CovLoop ; -- DistInt returns integer range 0 to Numbins-1 - return 1 + RV.DistInt( WeightVec ) ; -- return range 1 to NumBins + LastIndex := 1 + RV.DistInt( WeightVec ) ; -- return range 1 to NumBins + return LastIndex ; end function RandHoleIndex ; ------------------------------------------------------------ @@ -3165,6 +3342,7 @@ package body CoveragePkg is impure function GetHoleBinVal ( ReqHoleNum : integer ; AtLeast : integer ) return RangeArrayType is ------------------------------------------------------------ variable HoleCount : integer := 0 ; + variable buf : line ; begin CovLoop : for i in 1 to NumBins loop -- if CovBinPtr(i).action = COV_COUNT and CovBinPtr(i).Count < minimum(AtLeast, CovBinPtr(i).AtLeast) then @@ -3175,9 +3353,10 @@ package body CoveragePkg is end if ; end if ; end loop CovLoop ; - write(OUTPUT, "%%Error GetHoleBinVal did not find hole. " & + write(buf, "%%Error GetHoleBinVal did not find hole. " & "HoleCount = " & integer'image(HoleCount) & "ReqHoleNum = " & integer'image(ReqHoleNum) & LF) ; + writeline(OUTPUT, buf) ; return CovBinPtr(NumBins).BinVal.all ; end function GetHoleBinVal ; @@ -3196,28 +3375,31 @@ package body CoveragePkg is procedure WriteCovHoles ( file f : text; AtLeast : integer ) is ------------------------------------------------------------ -- variable minAtLeast : integer ; + variable buf : line ; begin WriteBinName(f, "WriteCovHoles: ") ; if NumBins < 1 then - Write(f, "%%FATAL, Coverage Model is empty. Nothing to print." & LF ) ; + swrite(buf, "%%FATAL, Coverage Model is empty. Nothing to print.") ; + writeline(f, buf) ; report "Coverage model is empty. Nothing to print." severity failure ; end if ; CovLoop : for i in 1 to NumBins loop -- minAtLeast := minimum(AtLeast,CovBinPtr(i).AtLeast) ; -- if CovBinPtr(i).action = COV_COUNT and CovBinPtr(i).Count < minAtLeast then if CovBinPtr(i).action = COV_COUNT and CovBinPtr(i).Count < AtLeast then - write(f, "%% Bin:") ; - write(f, CovBinPtr(i).BinVal.all) ; - write(f, " Count = " & integer'image(CovBinPtr(i).Count)) ; - write(f, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; + swrite(buf, "%% Bin:") ; + write(buf, CovBinPtr(i).BinVal.all) ; + write(buf, " Count = " & integer'image(CovBinPtr(i).Count)) ; + write(buf, " AtLeast = " & integer'image(CovBinPtr(i).AtLeast)) ; if WeightMode = WEIGHT or WeightMode = REMAIN_WEIGHT then -- Print Weight only when it is used - write(f, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; - end if; - write(f, "" & LF) ; + write(buf, " Weight = " & integer'image(CovBinPtr(i).Weight)) ; + end if ; + writeline(f, buf) ; end if ; end loop CovLoop ; - write(f, "" & LF) ; + swrite(buf, "") ; + writeline(f, buf) ; end procedure WriteCovHoles ; @@ -3264,12 +3446,14 @@ package body CoveragePkg is variable NumBins1, NumBins2 : integer ; variable BinInfo1, BinInfo2 : CovBinBaseType ; variable BinVal1, BinVal2 : RangeArrayType(1 to Bin1.GetBinValLength) ; + variable buf : line ; begin NumBins1 := Bin1.GetNumBins ; NumBins2 := Bin2.GetNumBins ; if (NumBins1 /= NumBins2) then - write(OUTPUT, "Bins have different lengths" & LF) ; + write(buf, "Bins have different lengths" & LF) ; + writeline(OUTPUT, buf) ; ErrorCount := ErrorCount + 1 ; return ; end if ; @@ -3281,21 +3465,22 @@ package body CoveragePkg is BinVal2 := Bin2.GetBinVal(i) ; if BinInfo1 /= BinInfo2 or BinVal1 /= BinVal2 then ErrorCount := ErrorCount + 1 ; - write(OUTPUT, "%% Bin:" & integer'image(i) & " miscompare." & LF) ; - write(OUTPUT, "%% Bin1: ") ; - write(OUTPUT, BinVal1) ; - write(OUTPUT, " Action = " & integer'image(BinInfo1.action)) ; - write(OUTPUT, " Count = " & integer'image(BinInfo1.count)) ; - write(OUTPUT, " AtLeast = " & integer'image(BinInfo1.AtLeast)) ; - write(OUTPUT, " Weight = " & integer'image(BinInfo1.Weight)) ; - write(OUTPUT, ""& LF) ; - write(OUTPUT, "%% Bin2: ") ; - write(OUTPUT, BinVal2) ; - write(OUTPUT, " Action = " & integer'image(BinInfo2.action)) ; - write(OUTPUT, " Count = " & integer'image(BinInfo2.count)) ; - write(OUTPUT, " AtLeast = " & integer'image(BinInfo2.AtLeast)) ; - write(OUTPUT, " Weight = " & integer'image(BinInfo2.Weight)) ; - write(OUTPUT, ""& LF) ; + write(buf, "%% Bin:" & integer'image(i) & " miscompare." & LF) ; + writeline(OUTPUT, buf) ; + swrite(buf, "%% Bin1: ") ; + write(buf, BinVal1) ; + write(buf, " Action = " & integer'image(BinInfo1.action)) ; + write(buf, " Count = " & integer'image(BinInfo1.count)) ; + write(buf, " AtLeast = " & integer'image(BinInfo1.AtLeast)) ; + write(buf, " Weight = " & integer'image(BinInfo1.Weight)) ; + writeline(OUTPUT, buf) ; + swrite(buf, "%% Bin2: ") ; + write(buf, BinVal2) ; + write(buf, " Action = " & integer'image(BinInfo2.action)) ; + write(buf, " Count = " & integer'image(BinInfo2.count)) ; + write(buf, " AtLeast = " & integer'image(BinInfo2.AtLeast)) ; + write(buf, " Weight = " & integer'image(BinInfo2.Weight)) ; + writeline(OUTPUT, buf) ; end if ; end loop ; end procedure CompareBins ; diff --git a/CoveragePkg_release_notes.pdf b/CoveragePkg_release_notes.pdf new file mode 100644 index 0000000..7ec2e68 Binary files /dev/null and b/CoveragePkg_release_notes.pdf differ diff --git a/CoveragePkg_user_guide.pdf b/CoveragePkg_user_guide.pdf new file mode 100644 index 0000000..8fafe50 Binary files /dev/null and b/CoveragePkg_user_guide.pdf differ diff --git a/MessagePkg.vhd b/MessagePkg.vhd new file mode 100644 index 0000000..eb6eec6 --- /dev/null +++ b/MessagePkg.vhd @@ -0,0 +1,204 @@ +-- +-- File Name: MessagePkg.vhd +-- Design Unit Name: MessagePkg +-- Revision: STANDARD VERSION, revision 2014.01 +-- +-- Maintainer: Jim Lewis email: jim@synthworks.com +-- Contributor(s): +-- Jim Lewis SynthWorks +-- +-- +-- Package Defines +-- Data structure for name and message handling. +-- +-- Developed for: +-- SynthWorks Design Inc. +-- VHDL Training Classes +-- 11898 SW 128th Ave. Tigard, Or 97223 +-- http://www.SynthWorks.com +-- +-- Latest standard version available at: +-- http://www.SynthWorks.com/downloads +-- +-- Revision History: +-- Date Version Description +-- 06/2010: 0.1 Initial revision +-- +-- +-- Copyright (c) 2010 - 2013 by SynthWorks Design Inc. All rights reserved. +-- +-- Verbatim copies of this source file may be used and +-- distributed without restriction. +-- +-- This source file is free software; you can redistribute it +-- and/or modify it under the terms of the ARTISTIC License +-- as published by The Perl Foundation; either version 2.0 of +-- the License, or (at your option) any later version. +-- +-- This source is distributed in the hope that it will be +-- useful, but WITHOUT ANY WARRANTY; without even the implied +-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-- PURPOSE. See the Artistic License for details. +-- +-- You should have received a copy of the license with this source. +-- If not download it from, +-- http://www.perlfoundation.org/artistic_license_2_0 +-- + +library ieee ; +use ieee.std_logic_1164.all ; +use ieee.numeric_std.all ; +use ieee.math_real.all ; +use std.textio.all ; + +package MessagePkg is + + type MessagePType is protected + + procedure SetName (NameIn : String) ; + impure function GetName return string ; + impure function IsSetName return boolean ; + + procedure SetMessage (MessageIn : String) ; + impure function GetMessage (ItemNumber : integer) return string ; + impure function GetMessageCount return integer ; + + procedure DeallocateName ; -- clear name + procedure DeallocateMessage ; -- clear message + procedure Deallocate ; -- clear all + + end protected MessagePType ; + +end package MessagePkg ; +package body MessagePkg is + + -- Local Data Structure Types + type LineArrayType is array (natural range <>) of line ; + type LineArrayPtrType is access LineArrayType ; + + ------------------------------------------------------------ + -- Local. Get first word from a string + function GetWord (Message : string) return string is + ------------------------------------------------------------ + alias aMessage : string( 1 to Message'length) is Message ; + begin + for i in aMessage'range loop + if aMessage(i) = ' ' or aMessage(i) = HT then + return aMessage(1 to i-1) ; + end if ; + end loop ; + return aMessage ; + end function GetWord ; + + + type MessagePType is protected body + + variable NamePtr : line := new string'("") ; + variable MessageCount : integer := 0 ; + constant INITIAL_ITEM_COUNT : integer := 25 ; + variable MaxMessageCount : integer := INITIAL_ITEM_COUNT ; + variable MessagePtr : LineArrayPtrType := new LineArrayType(1 to INITIAL_ITEM_COUNT) ; + + ------------------------------------------------------------ + procedure SetName (NameIn : String) is + ------------------------------------------------------------ + begin + deallocate(NamePtr) ; + NamePtr := new string'(NameIn) ; + end procedure SetName ; + + ------------------------------------------------------------ + impure function GetName return string is + ------------------------------------------------------------ + begin + if NamePtr.all /= "" or MessagePtr(1) = NULL then + return NamePtr.all ; + else + return GetWord( MessagePtr(1).all ) ; + end if ; + end function GetName ; + + ------------------------------------------------------------ + impure function IsSetName return boolean is + ------------------------------------------------------------ + begin + return NamePtr.all /= "" ; + end function IsSetName ; + + ------------------------------------------------------------ + procedure SetMessage (MessageIn : String) is + ------------------------------------------------------------ + variable NamePtr : line ; + variable OldMaxMessageCount : integer ; + variable OldMessagePtr : LineArrayPtrType ; + begin + MessageCount := MessageCount + 1 ; + if MessageCount > MaxMessageCount then + OldMaxMessageCount := MaxMessageCount ; + MaxMessageCount := OldMaxMessageCount * 2 ; + OldMessagePtr := MessagePtr ; + MessagePtr := new LineArrayType(1 to MaxMessageCount) ; + for i in 1 to OldMaxMessageCount loop + MessagePtr(i) := OldMessagePtr(i) ; + end loop ; + Deallocate( OldMessagePtr ) ; + end if ; + MessagePtr(MessageCount) := new string'(MessageIn) ; + end procedure SetMessage ; + + ------------------------------------------------------------ + impure function GetMessage (ItemNumber : integer) return string is + ------------------------------------------------------------ + begin + if MessageCount > 0 then + if ItemNumber >= 1 and ItemNumber <= MessageCount then + return MessagePtr(ItemNumber).all ; + else + report LF & "%% MessagePkg:MessagePType.GetMessage input value out of range" severity failure ; + return "" ; -- error if this happens + end if ; + else + return NamePtr.all ; + end if ; + end function GetMessage ; + + ------------------------------------------------------------ + impure function GetMessageCount return integer is + ------------------------------------------------------------ + begin + return MessageCount ; + end function GetMessageCount ; + + ------------------------------------------------------------ + procedure DeallocateName is -- clear name + ------------------------------------------------------------ + begin + deallocate(NamePtr) ; + NamePtr := new string'("") ; + end procedure DeallocateName ; + + ------------------------------------------------------------ + procedure DeallocateMessage is -- clear message + ------------------------------------------------------------ + variable CurPtr : LineArrayPtrType ; + begin + for i in 1 to MessageCount loop + deallocate( MessagePtr(i) ) ; + end loop ; + MessageCount := 0 ; + -- Do NOT Do this: deallocate( MessagePtr ) ; + end procedure DeallocateMessage ; + + ------------------------------------------------------------ + procedure Deallocate is -- clear all + ------------------------------------------------------------ + begin + DeallocateName ; + DeallocateMessage ; + end procedure Deallocate ; + + end protected body MessagePType ; + +end package body MessagePkg ; + + diff --git a/README.md b/README.md index 16261f6..60e0c51 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,31 @@ -# Unofficial "Open Source VHDL Verification Methodology" Repository +# "Open Source VHDL Verification Methodology" -This is an unofficial repository of [Open Source VHDL Verification Methodology][osvvm] (OS-VVM) provided for Git submodule linking. +This is an **unofficial** repository of "Open Source VHDL Verification Methodology" provided for **git submodule linking**. + +------ +[**Open Source VHDL Verification Methodology (OS-VVM)**][osvvm] is an intelligent testbench methodology that allows mixing of “Intelligent Coverage” (coverage driven randomization) with directed, algorithmic, file based, and constrained random test approaches. The methodology can be adopted in part or in whole as needed. With OSVVM you can add advanced verification methodologies to your current testbench without having to learn a new language or throw out your existing testbench or testbench models. + +**Source:** [http://www.osvvm.org/][osvvm] +**License:** [Artistic License 2.0][PAL2.0] +**Copyright:** Copyright © 2012-2015 by [SynthWorks Design Inc.](http://www.synthworks.com/) ## Release History + - 22.01.2014 - 2014.01 Complete OS-VVM package containing VHDL sources and documentation. - 25.05.2013 - 2013.05 Complete OS-VVM package containing VHDL sources, documentation and sample designs1. 1 This repository does not contain the OS-VVM user guide and the example designs provided by [Aldec][aldec], due to the unknow license state of these files. - [osvvm]: http://www.osvvm.org/ - [aldec]: http://www.aldec.com/ +------ + +*These files are uploaded by Patrick Lehmann.* + + [osvvm]: http://www.osvvm.org/ + [aldec]: http://www.aldec.com/ + [PAL2.0]: http://www.perlfoundation.org/artistic_license_2_0 + + + + + diff --git a/packages/RandomBasePkg.vhd b/RandomBasePkg.vhd similarity index 100% rename from packages/RandomBasePkg.vhd rename to RandomBasePkg.vhd diff --git a/packages/RandomPkg.vhd b/RandomPkg.vhd similarity index 52% rename from packages/RandomPkg.vhd rename to RandomPkg.vhd index 23297c1..e0f2a85 100644 --- a/packages/RandomPkg.vhd +++ b/RandomPkg.vhd @@ -1,35 +1,35 @@ -- --- File Name: RandomPkg.vhd --- Design Unit Name: RandomPkg --- Revision: STANDARD VERSION, revision 2013.05 +-- File Name : RandomPkg.vhd +-- Design Unit Name : RandomPkg +-- Revision : STANDARD VERSION, revision 2014.01 -- --- Maintainer: Jim Lewis email: jim@synthworks.com --- Contributor(s): --- Jim Lewis email: jim@synthworks.com +-- Maintainer : Jim Lewis email : jim@synthworks.com +-- Contributor(s) : +-- Jim Lewis email : jim@synthworks.com -- * -- --- * In writing procedures normal, poisson, the following sources were referenced: +-- * In writing procedures normal, poisson, the following sources were referenced : -- Wikipedia -- package rnd2 written by John Breen and Ken Christensen -- package RNG written by Gnanasekaran Swaminathan -- -- --- Description: +-- Description : -- RandomPType, a protected type, defined to hold randomization RandomSeeds and -- function methods to facilitate randomization with uniform and weighted -- distributions -- --- Developed for: +-- Developed for : -- SynthWorks Design Inc. -- VHDL Training Classes -- 11898 SW 128th Ave. Tigard, Or 97223 --- http://www.SynthWorks.com +-- http ://www.SynthWorks.com -- --- Revision History: +-- Revision History : -- Date Version Description --- 12/2006: 0.1 Initial revision +-- 12/2006 : 0.1 Initial revision -- Numerous revisions for VHDL Testbenches and Verification --- 02/2009: 1.0 First Public Released Version +-- 02/2009 : 1.0 First Public Released Version -- 02/25/2009 1.1 Replaced reference to std_2008 with a reference to -- ieee_proposed.standard_additions.all ; -- 06/2010 1.2 Added Normal and Poisson distributions @@ -47,25 +47,27 @@ -- 5/2013 - Removed extra variable declaration in functions RandInt and RandReal -- 5/2013 2013.05 Big vector randomization added overloading RandUnsigned, RandSlv, and RandSigned -- Added NULL_RANGE_TYPE to minimize null range warnings +-- 1/2014 2014.01 Added RandTime, RandReal(set), RandIntV, RandRealV, RandTimeV +-- Made sort, revsort from SortListPkg_int visible via aliases -- --- Copyright (c) 2006 - 2013 by SynthWorks Design Inc. All rights reserved. +-- Copyright (c) 2006 - 2014 by SynthWorks Design Inc. All rights reserved. -- -- Verbatim copies of this source file may be used and -- distributed without restriction. -- --- This source file is free software; you can redistribute it +-- This source file is free software ; you can redistribute it -- and/or modify it under the terms of the ARTISTIC License --- as published by The Perl Foundation; either version 2.0 of +-- as published by The Perl Foundation ; either version 2.0 of -- the License, or (at your option) any later version. -- -- This source is distributed in the hope that it will be --- useful, but WITHOUT ANY WARRANTY; without even the implied +-- useful, but WITHOUT ANY WARRANTY ; without even the implied -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -- PURPOSE. See the Artistic License for details. -- -- You should have received a copy of the license with this source. -- If not download it from, --- http://www.perlfoundation.org/artistic_license_2_0 +-- http ://www.perlfoundation.org/artistic_license_2_0 -- use work.RandomBasePkg.all ; @@ -79,10 +81,10 @@ use ieee.numeric_std.all ; use ieee.numeric_std_unsigned.all ; use ieee.math_real.all ; --- comment out following 3 lines with VHDL-2008. Leave in for VHDL-2002 --- library ieee_proposed ; -- remove with VHDL-2008 --- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008 --- use ieee_proposed.standard_textio_additions.all ; -- remove with VHDL-2008 +-- comment out following 3 lines with VHDL-2008. Leave in for VHDL-2002 +-- library ieee_proposed ; -- remove with VHDL-2008 +-- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008 +-- use ieee_proposed.standard_textio_additions.all ; -- remove with VHDL-2008 package RandomPkg is @@ -90,15 +92,19 @@ package RandomPkg is -- For now they are defined in the package RandomBasePkg.vhd -- package RandomGenericPkg is -- generic ( - -- type RandomSeedType ; -- base type for randomization - -- procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ; + -- type RandomSeedType ; -- base type for randomization + -- procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ; -- function GenRandSeed(IV : integer_vector) return RandomSeedType ; -- function GenRandSeed(I : integer) return RandomSeedType ; -- function GenRandSeed(S : string) return RandomSeedType ; -- ) ; + -- make things from SortListPkg_int visible + alias sort is work.SortListPkg_int.sort[integer_vector return integer_vector] ; + alias revsort is work.SortListPkg_int.revsort[integer_vector return integer_vector] ; + -- note NULL_RANGE_TYPE should probably be in std.standard - subtype NULL_RANGE_TYPE is integer range 0 downto 1 ; + subtype NULL_RANGE_TYPE is integer range 0 downto 1 ; constant NULL_INTV : integer_vector (NULL_RANGE_TYPE) := (others => 0) ; -- Supports DistValInt functionality @@ -115,32 +121,32 @@ package RandomPkg is type RandomParmType is record Distribution : RandomDistType ; - Mean : Real ; -- also used as probability of success - StdDeviation : Real ; -- also used as number of trials for binomial + Mean : Real ; -- also used as probability of success + StdDeviation : Real ; -- also used as number of trials for binomial end record ; -- RandomParm IO - function to_string(A : RandomDistType) return string ; - procedure write(variable L: inout line ; A : RandomDistType ) ; - procedure read(variable L: inout line ; A : out RandomDistType ; good : out boolean ) ; - procedure read(variable L: inout line ; A : out RandomDistType ) ; - function to_string(A : RandomParmType) return string ; - procedure write(variable L: inout line ; A : RandomParmType ) ; - procedure read(variable L: inout line ; A : out RandomParmType ; good : out boolean ) ; - procedure read(variable L: inout line ; A : out RandomParmType ) ; + function to_string(A : RandomDistType) return string ; + procedure write(variable L : inout line ; A : RandomDistType ) ; + procedure read(variable L : inout line ; A : out RandomDistType ; good : out boolean ) ; + procedure read(variable L : inout line ; A : out RandomDistType ) ; + function to_string(A : RandomParmType) return string ; + procedure write(variable L : inout line ; A : RandomParmType ) ; + procedure read(variable L : inout line ; A : out RandomParmType ; good : out boolean ) ; + procedure read(variable L : inout line ; A : out RandomParmType ) ; type RandomPType is protected -- Seed Manipulation -- Known ambiguity between InitSeed with string and integer_vector - -- Recommendation, use: RV.InitSeed(RV'instance_path) ; - -- For integer_vector use either: RV.InitSeed(IV => (1,5)) ; - -- or: RV.InitSeed(integer_vector'(1,5)) ; + -- Recommendation, use : RV.InitSeed(RV'instance_path) ; + -- For integer_vector use either : RV.InitSeed(IV => (1,5)) ; + -- or : RV.InitSeed(integer_vector'(1,5)) ; procedure InitSeed (S : string ) ; procedure InitSeed (I : integer ) ; procedure InitSeed (IV : integer_vector ) ; - -- SetSeed & GetSeed: Used to save and restore seed values + -- SetSeed & GetSeed : Used to save and restore seed values procedure SetSeed (RandomSeedIn : RandomSeedType ) ; impure function GetSeed return RandomSeedType ; -- SeedRandom = SetSeed & GetSeed for SV compatibility @@ -166,26 +172,26 @@ package RandomPkg is -- alias SetRandomMode is SetRandomParm [RandomDistType, Real, Real] ; -- Base Randomization Distributions - -- Uniform: Generate a random number with a Uniform distribution + -- Uniform : Generate a random number with a Uniform distribution impure function Uniform (Min, Max : in real) return real ; impure function Uniform (Min, Max : integer) return integer ; - impure function Uniform (Min, Max : integer ; Exclude: integer_vector) return integer ; + impure function Uniform (Min, Max : integer ; Exclude : integer_vector) return integer ; -- FavorSmall -- Generate random numbers with a greater number of small -- values than large values impure function FavorSmall (Min, Max : real) return real ; impure function FavorSmall (Min, Max : integer) return integer ; - impure function FavorSmall (Min, Max : integer ; Exclude: integer_vector) return integer ; + impure function FavorSmall (Min, Max : integer ; Exclude : integer_vector) return integer ; -- FavorBig -- Generate random numbers with a greater number of large -- values than small values impure function FavorBig (Min, Max : real) return real ; impure function FavorBig (Min, Max : integer) return integer ; - impure function FavorBig (Min, Max : integer ; Exclude: integer_vector) return integer ; + impure function FavorBig (Min, Max : integer ; Exclude : integer_vector) return integer ; - -- Normal: Generate a random number with a normal distribution + -- Normal : Generate a random number with a normal distribution impure function Normal (Mean, StdDeviation : real) return real ; -- Normal + RandomVal >= Min and RandomVal < Max impure function Normal (Mean, StdDeviation, Min, Max : real) return real ; @@ -197,7 +203,7 @@ package RandomPkg is Exclude : integer_vector := NULL_INTV ) return integer ; - -- Poisson: Generate a random number with a poisson distribution + -- Poisson : Generate a random number with a poisson distribution -- Discrete distribution = only generates integral values impure function Poisson (Mean : real) return real ; -- Poisson + RandomVal >= Min and RandomVal < Max @@ -210,32 +216,61 @@ package RandomPkg is ) return integer ; - -- real randomization with a range - impure function RandReal(Min, Max: Real) return real ; - - -- integer randomization with a range + -- randomization with a range impure function RandInt (Min, Max : integer) return integer ; + impure function RandReal(Min, Max : Real) return real ; + impure function RandTime (Min, Max : time ; Unit : time := ns) return time ; impure function RandSlv (Min, Max, Size : natural) return std_logic_vector ; impure function RandUnsigned (Min, Max, Size : natural) return Unsigned ; - impure function RandSigned (Min, Max : integer; Size : natural ) return Signed ; + impure function RandSigned (Min, Max : integer ; Size : natural ) return Signed ; + impure function RandIntV (Min, Max : integer ; Size : natural) return integer_vector ; + impure function RandIntV (Min, Max : integer ; Unique : natural ; Size : natural) return integer_vector ; + impure function RandRealV (Min, Max : real ; Size : natural) return real_vector ; + impure function RandTimeV (Min, Max : time ; Size : natural ; Unit : time := ns) return time_vector ; + impure function RandTimeV (Min, Max : time ; Unique : natural ; Size : natural ; Unit : time := ns) return time_vector ; + + + -- randomization with a range and exclude vector + impure function RandInt (Min, Max : integer ; Exclude : integer_vector ) return integer ; + impure function RandTime (Min, Max : time ; Exclude : time_vector ; Unit : time := ns) return time ; + impure function RandSlv (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return std_logic_vector ; + impure function RandUnsigned (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return Unsigned ; + impure function RandSigned (Min, Max : integer ; Exclude : integer_vector ; Size : natural ) return Signed ; + impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Size : natural) return integer_vector ; + impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector ; + impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Size : natural ; Unit : in time := ns) return time_vector ; + impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Unique : natural ; Size : natural ; Unit : in time := ns) return time_vector ; - -- integer randomization with a range and exclude vector - impure function RandInt (Min, Max : integer; Exclude: integer_vector ) return integer ; - impure function RandSlv (Min, Max : natural; Exclude: integer_vector; Size : natural ) return std_logic_vector ; - impure function RandUnsigned (Min, Max : natural; Exclude: integer_vector ; Size : natural ) return Unsigned ; - impure function RandSigned (Min, Max : integer; Exclude: integer_vector ; Size : natural ) return Signed ; -- Randomly select a value within a set of values impure function RandInt ( A : integer_vector ) return integer ; - impure function RandSlv (A : integer_vector ; Size : natural) return std_logic_vector ; - impure function RandUnsigned (A : integer_vector ; Size : natural) return Unsigned ; - impure function RandSigned (A : integer_vector ; Size : natural ) return Signed ; + impure function RandReal ( A : real_vector ) return real ; + impure function RandTime (A : time_vector) return time ; + impure function RandSlv (A : integer_vector ; Size : natural) return std_logic_vector ; + impure function RandUnsigned (A : integer_vector ; Size : natural) return Unsigned ; + impure function RandSigned (A : integer_vector ; Size : natural ) return Signed ; + impure function RandIntV (A : integer_vector ; Size : natural) return integer_vector ; + impure function RandIntV (A : integer_vector ; Unique : natural ; Size : natural) return integer_vector ; + impure function RandRealV (A : real_vector ; Size : natural) return real_vector ; + impure function RandRealV (A : real_vector ; Unique : natural ; Size : natural) return real_vector ; + impure function RandTimeV (A : time_vector ; Size : natural) return time_vector ; + impure function RandTimeV (A : time_vector ; Unique : natural ; Size : natural) return time_vector ; + -- Randomly select a value within a set of values with exclude values (so can skip last or last n) - impure function RandInt ( A : integer_vector; Exclude: integer_vector ) return integer ; - impure function RandSlv (A : integer_vector; Exclude: integer_vector; Size : natural) return std_logic_vector ; - impure function RandUnsigned (A : integer_vector; Exclude: integer_vector ; Size : natural) return Unsigned ; - impure function RandSigned (A : integer_vector; Exclude: integer_vector ; Size : natural ) return Signed ; + impure function RandInt ( A, Exclude : integer_vector ) return integer ; + impure function RandReal ( A, Exclude : real_vector ) return real ; + impure function RandTime (A, Exclude : time_vector) return time ; + impure function RandSlv (A, Exclude : integer_vector ; Size : natural) return std_logic_vector ; + impure function RandUnsigned (A, Exclude : integer_vector ; Size : natural) return Unsigned ; + impure function RandSigned (A, Exclude : integer_vector ; Size : natural ) return Signed ; + impure function RandIntV (A, Exclude : integer_vector ; Size : natural) return integer_vector ; + impure function RandIntV (A, Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector ; + impure function RandRealV (A, Exclude : real_vector ; Size : natural) return real_vector ; + impure function RandRealV (A, Exclude : real_vector ; Unique : natural ; Size : natural) return real_vector ; + impure function RandTimeV (A, Exclude : time_vector ; Size : natural) return time_vector ; + impure function RandTimeV (A, Exclude : time_vector ; Unique : natural ; Size : natural) return time_vector ; + -- Randomly select between 0 and N-1 based on the specified weight. -- where N = number values in weight array @@ -244,11 +279,13 @@ package RandomPkg is impure function DistUnsigned ( Weight : integer_vector ; Size : natural ) return unsigned ; impure function DistSigned ( Weight : integer_vector ; Size : natural ) return signed ; + -- Distribution with just weights and with exclude values - impure function DistInt ( Weight : integer_vector; Exclude: integer_vector ) return integer ; - impure function DistSlv ( Weight : integer_vector; Exclude: integer_vector; Size : natural ) return std_logic_vector ; - impure function DistUnsigned ( Weight : integer_vector; Exclude: integer_vector; Size : natural ) return unsigned ; - impure function DistSigned ( Weight : integer_vector; Exclude: integer_vector; Size : natural ) return signed ; + impure function DistInt ( Weight : integer_vector ; Exclude : integer_vector ) return integer ; + impure function DistSlv ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return std_logic_vector ; + impure function DistUnsigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return unsigned ; + impure function DistSigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return signed ; + -- Distribution with weight and value impure function DistValInt ( A : DistType ) return integer ; @@ -256,13 +293,15 @@ package RandomPkg is impure function DistValUnsigned ( A : DistType ; Size : natural) return unsigned ; impure function DistValSigned ( A : DistType ; Size : natural) return signed ; + -- Distribution with weight and value and with exclude values - impure function DistValInt ( A : DistType; Exclude: integer_vector ) return integer ; - impure function DistValSlv ( A : DistType; Exclude: integer_vector; Size : natural) return std_logic_vector ; - impure function DistValUnsigned ( A : DistType; Exclude: integer_vector; Size : natural) return unsigned ; - impure function DistValSigned ( A : DistType; Exclude: integer_vector; Size : natural) return signed ; + impure function DistValInt ( A : DistType ; Exclude : integer_vector ) return integer ; + impure function DistValSlv ( A : DistType ; Exclude : integer_vector ; Size : natural) return std_logic_vector ; + impure function DistValUnsigned ( A : DistType ; Exclude : integer_vector ; Size : natural) return unsigned ; + impure function DistValSigned ( A : DistType ; Exclude : integer_vector ; Size : natural) return signed ; - -- Large vector handling. + + -- Large vector handling. impure function RandUnsigned (Size : natural) return unsigned ; impure function RandSlv (Size : natural) return std_logic_vector ; impure function RandSigned (Size : natural) return signed ; @@ -273,14 +312,14 @@ package RandomPkg is impure function RandSlv (Min, Max : std_logic_vector) return std_logic_vector ; impure function RandSigned (Min, Max : signed) return signed ; - + -- Convenience Functions - impure function RandReal return real ; -- 0.0 to 1.0 - impure function RandReal(Max: Real) return real ; -- 0.0 to Max + impure function RandReal return real ; -- 0.0 to 1.0 + impure function RandReal(Max : Real) return real ; -- 0.0 to Max impure function RandInt (Max : integer) return integer ; impure function RandSlv (Max, Size : natural) return std_logic_vector ; impure function RandUnsigned (Max, Size : natural) return Unsigned ; - impure function RandSigned (Max : integer; Size : natural ) return Signed ; + impure function RandSigned (Max : integer ; Size : natural ) return Signed ; end protected RandomPType ; @@ -307,7 +346,7 @@ package body RandomPkg is return A * ValRange + Min ; end function Scale ; - function Scale (A : real ; Min, Max : integer) return integer is + function Scale (A : real ; Min, Max : integer) return integer is variable ValRange : real ; variable rMin, rMax : real ; begin @@ -330,6 +369,87 @@ package body RandomPkg is return sqrt(A) ; end FavorBig ; + -- local. + function to_time_vector (A : integer_vector ; Unit : time) return time_vector is + variable result : time_vector(A'range) ; + begin + for i in A'range loop + result(i) := A(i) * Unit ; + end loop ; + return result ; + end function to_time_vector ; + + -- local + function to_integer_vector (A : time_vector ; Unit : time) return integer_vector is + variable result : integer_vector(A'range) ; + begin + for i in A'range loop + result(i) := A(i) / Unit ; + end loop ; + return result ; + end function to_integer_vector ; + + -- Local. Remove the exclude list from the list - integer_vector + procedure RemoveExclude(A, Exclude : integer_vector ; variable NewA : out integer_vector ; variable NewALength : inout natural ) is + alias norm_NewA : integer_vector(1 to NewA'length) is NewA ; + begin + NewALength := 0 ; + for i in A'range loop + if not inside(A(i), Exclude) then + NewALength := NewALength + 1 ; + norm_NewA(NewALength) := A(i) ; + end if ; + end loop ; + end procedure RemoveExclude ; + + -- Local. Inside - real_vector + function inside(A : real ; Exclude : real_vector) return boolean is + begin + for i in Exclude'range loop + if A = Exclude(i) then + return TRUE ; + end if ; + end loop ; + return FALSE ; + end function inside ; + + -- Local. Remove the exclude list from the list - real_vector + procedure RemoveExclude(A, Exclude : real_vector ; variable NewA : out real_vector ; variable NewALength : inout natural ) is + alias norm_NewA : real_vector(1 to NewA'length) is NewA ; + begin + NewALength := 0 ; + for i in A'range loop + if not inside(A(i), Exclude) then + NewALength := NewALength + 1 ; + norm_NewA(NewALength) := A(i) ; + end if ; + end loop ; + end procedure RemoveExclude ; + + -- Local. Inside - time_vector + function inside(A : time ; Exclude : time_vector) return boolean is + begin + for i in Exclude'range loop + if A = Exclude(i) then + return TRUE ; + end if ; + end loop ; + return FALSE ; + end function inside ; + + -- Local. Remove the exclude list from the list - time_vector + procedure RemoveExclude(A, Exclude : time_vector ; variable NewA : out time_vector ; variable NewALength : inout natural ) is + alias norm_NewA : time_vector(1 to NewA'length) is NewA ; + begin + NewALength := 0 ; + for i in A'range loop + if not inside(A(i), Exclude) then + NewALength := NewALength + 1 ; + norm_NewA(NewALength) := A(i) ; + end if ; + end loop ; + end procedure RemoveExclude ; + ----------------------------------------------------------------- -- RandomParmType IO @@ -342,18 +462,18 @@ package body RandomPkg is ----------------------------------------------------------------- - procedure write(variable L: inout line ; A : RandomDistType ) is + procedure write(variable L : inout line ; A : RandomDistType ) is begin write(L, to_string(A)) ; end procedure write ; ----------------------------------------------------------------- - procedure read(variable L: inout line ; A : out RandomDistType ; good : out boolean ) is + procedure read(variable L : inout line ; A : out RandomDistType ; good : out boolean ) is variable strval : string(1 to 40) ; variable len : natural ; begin - -- procedure SREAD (L: inout LINE; VALUE: out STRING; STRLEN: out NATURAL); + -- procedure SREAD (L : inout LINE ; VALUE : out STRING ; STRLEN : out NATURAL) ; sread(L, strval, len) ; A := RandomDistType'value(strval(1 to len)) ; good := len > 0 ; @@ -361,7 +481,7 @@ package body RandomPkg is ----------------------------------------------------------------- - procedure read(variable L: inout line ; A : out RandomDistType ) is + procedure read(variable L : inout line ; A : out RandomDistType ) is variable good : boolean ; begin read(L, A, good) ; @@ -378,20 +498,20 @@ package body RandomPkg is ----------------------------------------------------------------- - procedure write(variable L: inout line ; A : RandomParmType ) is + procedure write(variable L : inout line ; A : RandomParmType ) is begin write(L, to_string(A)) ; end procedure write ; ----------------------------------------------------------------- - procedure read(variable L: inout line ; A : out RandomParmType ; good : out boolean ) is + procedure read(variable L : inout line ; A : out RandomParmType ; good : out boolean ) is variable strval : string(1 to 40) ; variable len : natural ; variable igood : boolean ; begin loop - -- procedure SREAD (L: inout LINE; VALUE: out STRING; STRLEN: out NATURAL); + -- procedure SREAD (L : inout LINE ; VALUE : out STRING ; STRLEN : out NATURAL) ; sread(L, strval, len) ; A.Distribution := RandomDistType'value(strval(1 to len)) ; igood := len > 0 ; @@ -408,7 +528,7 @@ package body RandomPkg is ----------------------------------------------------------------- - procedure read(variable L: inout line ; A : out RandomParmType ) is + procedure read(variable L : inout line ; A : out RandomParmType ) is variable good : boolean ; begin read(L, A, good) ; @@ -464,7 +584,7 @@ package body RandomPkg is -- -- randomization mode -- - variable RandomParm : RandomParmType ; -- left most values ok for init + variable RandomParm : RandomParmType ; -- left most values ok for init procedure SetRandomParm (RandomParmIn : RandomParmType) is begin @@ -496,20 +616,20 @@ package body RandomPkg is -- For compatibility with previous version procedure SetRandomMode (RandomDistIn : RandomDistType) is begin - SetRandomParm(RandomDistIn); + SetRandomParm(RandomDistIn) ; end procedure SetRandomMode ; - + -- -- Base Randomization Distributions -- -- - -- Uniform: Generate a random number with a Uniform distribution + -- Uniform : Generate a random number with a Uniform distribution -- impure function Uniform (Min, Max : in real) return real is variable rRandomVal : real ; begin - assert (Max >= Min) report "%%RandomPkg Uniform: Max < Min" severity FAILURE ; + assert (Max >= Min) report "%%RandomPkg Uniform : Max < Min" severity FAILURE ; Uniform(rRandomVal, RandomSeed) ; return scale(rRandomVal, Min, Max) ; end function Uniform ; @@ -517,12 +637,12 @@ package body RandomPkg is impure function Uniform (Min, Max : integer) return integer is variable rRandomVal : real ; begin - assert (Max >= Min) report "%%RandomPkg Uniform: Max < Min" severity FAILURE ; + assert (Max >= Min) report "%%RandomPkg Uniform : Max < Min" severity FAILURE ; Uniform(rRandomVal, RandomSeed) ; return scale(rRandomVal, Min, Max) ; end function Uniform ; - impure function Uniform (Min, Max : integer ; Exclude: integer_vector) return integer is + impure function Uniform (Min, Max : integer ; Exclude : integer_vector) return integer is variable iRandomVal : integer ; variable ExcludeList : SortListPType ; variable count : integer ; @@ -548,20 +668,20 @@ package body RandomPkg is impure function FavorSmall (Min, Max : real) return real is variable rRandomVal : real ; begin - assert (Max >= Min) report "%%RandomPkg FavorSmall: Max < Min" severity FAILURE ; + assert (Max >= Min) report "%%RandomPkg FavorSmall : Max < Min" severity FAILURE ; Uniform(rRandomVal, RandomSeed) ; - return scale(FavorSmall(rRandomVal), Min, Max) ; -- real + return scale(FavorSmall(rRandomVal), Min, Max) ; -- real end function FavorSmall ; impure function FavorSmall (Min, Max : integer) return integer is variable rRandomVal : real ; begin - assert (Max >= Min) report "%%RandomPkg FavorSmall: Max < Min" severity FAILURE ; + assert (Max >= Min) report "%%RandomPkg FavorSmall : Max < Min" severity FAILURE ; Uniform(rRandomVal, RandomSeed) ; - return scale(FavorSmall(rRandomVal), Min, Max) ; -- integer + return scale(FavorSmall(rRandomVal), Min, Max) ; -- integer end function FavorSmall ; - impure function FavorSmall (Min, Max : integer ; Exclude: integer_vector) return integer is + impure function FavorSmall (Min, Max : integer ; Exclude : integer_vector) return integer is variable iRandomVal : integer ; variable ExcludeList : SortListPType ; variable count : integer ; @@ -578,7 +698,7 @@ package body RandomPkg is return iRandomVal ; end function FavorSmall ; - + -- -- FavorBig -- Generate random numbers with a greater number of large @@ -587,7 +707,7 @@ package body RandomPkg is impure function FavorBig (Min, Max : real) return real is variable rRandomVal : real ; begin - assert (Max >= Min) report "%%RandomPkg FavorBig: Max < Min" severity FAILURE ; + assert (Max >= Min) report "%%RandomPkg FavorBig : Max < Min" severity FAILURE ; Uniform(rRandomVal, RandomSeed) ; return scale(FavorBig(rRandomVal), Min, Max) ; -- real end function FavorBig ; @@ -595,12 +715,12 @@ package body RandomPkg is impure function FavorBig (Min, Max : integer) return integer is variable rRandomVal : real ; begin - assert (Max >= Min) report "%%RandomPkg FavorBig: Max < Min" severity FAILURE ; + assert (Max >= Min) report "%%RandomPkg FavorBig : Max < Min" severity FAILURE ; Uniform(rRandomVal, RandomSeed) ; return scale(FavorBig(rRandomVal), Min, Max) ; -- integer end function FavorBig ; - impure function FavorBig (Min, Max : integer ; Exclude: integer_vector) return integer is + impure function FavorBig (Min, Max : integer ; Exclude : integer_vector) return integer is variable iRandomVal : integer ; variable ExcludeList : SortListPType ; variable count : integer ; @@ -622,11 +742,11 @@ package body RandomPkg is -- Normal -- Generate a random number with a normal distribution -- - -- Use Box Muller, per Wikipedia: - -- http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform + -- Use Box Muller, per Wikipedia : + -- http ://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform -- - -- Use polar method, per Wikipedia: - -- http://en.wikipedia.org/wiki/Marsaglia_polar_method + -- Use polar method, per Wikipedia : + -- http ://en.wikipedia.org/wiki/Marsaglia_polar_method -- impure function Normal (Mean, StdDeviation : real) return real is variable x01, y01 : real ; @@ -650,7 +770,7 @@ package body RandomPkg is -- loop -- Uniform (x01, RandomSeed) ; -- Uniform (y01, RandomSeed) ; - -- x := 2.0 * x01 - 1.0 ; -- scale to -1 to 1 + -- x := 2.0 * x01 - 1.0 ; -- scale to -1 to 1 -- y := 2.0 * y01 - 1.0 ; -- s := x*x + y*y ; -- exit when s < 1.0 and s > 0.0 ; @@ -669,14 +789,14 @@ package body RandomPkg is variable rRandomVal : real ; begin if Max < Min then - report "%%RandomPkg Normal: Max < Min" severity FAILURE ; + report "%%RandomPkg Normal : Max < Min" severity FAILURE ; else loop rRandomVal := Normal (Mean, StdDeviation) ; exit when rRandomVal >= Min and rRandomVal <= Max ; end loop ; - end if ; - return rRandomVal ; + end if ; + return rRandomVal ; end function Normal ; -- Normal + RandomVal >= Min and RandomVal <= Max @@ -690,14 +810,14 @@ package body RandomPkg is variable iRandomVal : integer ; begin if Max < Min then - report "%%RandomPkg Normal: Max < Min" severity FAILURE ; + report "%%RandomPkg Normal : Max < Min" severity FAILURE ; else loop iRandomVal := integer(round( Normal(Mean, StdDeviation) )) ; exit when iRandomVal >= Min and iRandomVal <= Max and not inside(iRandomVal, Exclude) ; end loop ; - end if ; + end if ; return iRandomVal ; end function Normal ; @@ -707,44 +827,44 @@ package body RandomPkg is -- Generate a random number with a poisson distribution -- Discrete distribution = only generates integral values -- - -- Use knuth method, per Wikipedia: - -- http://en.wikipedia.org/wiki/Poisson_distribution + -- Use knuth method, per Wikipedia : + -- http ://en.wikipedia.org/wiki/Poisson_distribution -- impure function Poisson (Mean : real) return real is - variable Product : Real := 1.0; - variable Bound : Real := 0.0; + variable Product : Real := 1.0 ; + variable Bound : Real := 0.0 ; variable UniformRand : Real := 0.0 ; variable PoissonRand : Real := 0.0 ; begin - Bound := exp(-1.0 * Mean); + Bound := exp(-1.0 * Mean) ; Product := 1.0 ; -- add this check to set parameters? if Mean <= 0.0 or Bound <= 0.0 then - report "Poisson: Mean < 0 or too large. Mean = " & real'image(Mean) severity failure ; + report "Poisson : Mean < 0 or too large. Mean = " & real'image(Mean) severity failure ; return -1.0 ; end if ; while (Product >= Bound) loop - PoissonRand := PoissonRand + 1.0; + PoissonRand := PoissonRand + 1.0 ; Uniform(UniformRand, RandomSeed) ; - Product := Product * UniformRand; - end loop; + Product := Product * UniformRand ; + end loop ; return PoissonRand ; - end function Poisson ; -- no range + end function Poisson ; -- no range -- Poisson + RandomVal >= Min and RandomVal < Max impure function Poisson (Mean, Min, Max : real) return real is variable rRandomVal : real ; begin if Max < Min then - report "%%RandomPkg Poisson: Max < Min" severity FAILURE ; + report "%%RandomPkg Poisson : Max < Min" severity FAILURE ; else loop rRandomVal := Poisson (Mean) ; exit when rRandomVal >= Min and rRandomVal <= Max ; end loop ; - end if ; + end if ; return rRandomVal ; end function Poisson ; @@ -757,23 +877,23 @@ package body RandomPkg is variable iRandomVal : integer ; begin if Max < Min then - report "%%RandomPkg Poisson: Max < Min" severity FAILURE ; + report "%%RandomPkg Poisson : Max < Min" severity FAILURE ; else loop iRandomVal := integer(round( Poisson (Mean) )) ; exit when iRandomVal >= Min and iRandomVal <= Max and not inside(iRandomVal, Exclude) ; end loop ; - end if ; + end if ; return iRandomVal ; end function Poisson ; - + -- - -- real randomization with a range + -- integer randomization with a range -- Distribution determined by RandomParm -- - impure function RandReal(Min, Max: Real) return real is + impure function RandInt (Min, Max : integer) return integer is begin case RandomParm.Distribution is when NONE | UNIFORM => return Uniform(Min, Max) ; @@ -782,17 +902,16 @@ package body RandomPkg is when NORMAL => return Normal(RandomParm.Mean, RandomParm.StdDeviation, Min, Max) ; when POISSON => return Poisson(RandomParm.Mean, Min, Max) ; when others => - report "RandomPkg: distribution not implemented" severity failure ; - return real(integer'low) ; + report "RandomPkg : distribution not implemented" severity failure ; + return integer'low ; end case ; - end function RandReal ; - + end function RandInt ; -- - -- integer randomization with a range + -- real randomization with a range -- Distribution determined by RandomParm -- - impure function RandInt (Min, Max : integer) return integer is + impure function RandReal(Min, Max : Real) return real is begin case RandomParm.Distribution is when NONE | UNIFORM => return Uniform(Min, Max) ; @@ -801,10 +920,18 @@ package body RandomPkg is when NORMAL => return Normal(RandomParm.Mean, RandomParm.StdDeviation, Min, Max) ; when POISSON => return Poisson(RandomParm.Mean, Min, Max) ; when others => - report "RandomPkg: distribution not implemented" severity failure ; - return integer'low ; + report "RandomPkg : distribution not implemented" severity failure ; + return real(integer'low) ; end case ; - end function RandInt ; + end function RandReal ; + + impure function RandTime (Min, Max : time ; Unit :time := ns) return time is + variable IntVal : integer ; + begin + -- if Max - Min > 2**31 result will be out of range + IntVal := RandInt(0, (Max - Min)/Unit) ; + Return Min + Unit*IntVal ; + end function RandTime ; impure function RandSlv (Min, Max, Size : natural) return std_logic_vector is begin @@ -816,17 +943,66 @@ package body RandomPkg is return to_unsigned(RandInt(Min, Max), Size) ; end function RandUnsigned ; - impure function RandSigned (Min, Max : integer; Size : natural ) return Signed is + impure function RandSigned (Min, Max : integer ; Size : natural ) return Signed is begin return to_signed(RandInt(Min, Max), Size) ; end function RandSigned ; + impure function RandIntV (Min, Max : integer ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandInt(Min, Max) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandIntV (Min, Max : integer ; Unique : natural ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + variable iUnique : natural ; + begin + -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size) + iUnique := Unique ; + if Max-Min+1 < Unique then + report "RandIntV / RandRealV / RandTimeV: Unique > number of values available" severity failure ; + iUnique := Max-Min+1 ; + end if ; + for i in result'range loop + result(i) := RandInt(Min, Max, result(maximum(1, 1 + i - iUnique) to Size)) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandRealV (Min, Max : real ; Size : natural) return real_vector is + variable result : real_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandReal(Min, Max) ; + end loop ; + return result ; + end function RandRealV ; + + impure function RandTimeV (Min, Max : time ; Size : natural ; Unit : time := ns) return time_vector is + variable result : time_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandTime(Min, Max, Unit) ; + end loop ; + return result ; + end function RandTimeV ; + + impure function RandTimeV (Min, Max : time ; Unique : natural ; Size : natural ; Unit : time := ns) return time_vector is + begin + -- if Unique = 0, it is more efficient to call RandTimeV(Min, Max, Size) + return to_time_vector(RandIntV(Min/Unit, Max/Unit, Unique, Size), Unit) ; + end function RandTimeV ; + -- -- integer randomization with a range and exclude vector -- Distribution determined by RandomParm -- - impure function RandInt (Min, Max : integer; Exclude: integer_vector ) return integer is + impure function RandInt (Min, Max : integer ; Exclude : integer_vector ) return integer is begin case RandomParm.Distribution is when NONE | UNIFORM => return Uniform(Min, Max, Exclude) ; @@ -835,26 +1011,65 @@ package body RandomPkg is when NORMAL => return Normal(RandomParm.Mean, RandomParm.StdDeviation, Min, Max, Exclude) ; when POISSON => return Poisson(RandomParm.Mean, Min, Max, Exclude) ; when others => - report "RandomPkg: distribution not implemented" severity failure ; + report "RandomPkg : distribution not implemented" severity failure ; return integer'low ; end case ; end function RandInt ; - impure function RandSlv (Min, Max : natural; Exclude: integer_vector; Size : natural ) return std_logic_vector is + impure function RandTime (Min, Max : time ; Exclude : time_vector ; Unit : time := ns) return time is + variable IntVal : integer ; + begin + -- if Min or Max > 2**31 value will be out of range + return RandInt(Min/Unit, Max/Unit, to_integer_vector(Exclude, Unit)) * Unit ; + end function RandTime ; + + impure function RandSlv (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return std_logic_vector is begin return std_logic_vector(to_unsigned(RandInt(Min, Max, Exclude), Size)) ; end function RandSlv ; - impure function RandUnsigned (Min, Max : natural; Exclude: integer_vector; Size : natural ) return Unsigned is + impure function RandUnsigned (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return Unsigned is begin return to_unsigned(RandInt(Min, Max, Exclude), Size) ; end function RandUnsigned ; - impure function RandSigned (Min, Max : integer; Exclude: integer_vector; Size : natural ) return Signed is + impure function RandSigned (Min, Max : integer ; Exclude : integer_vector ; Size : natural ) return Signed is begin return to_signed(RandInt(Min, Max, Exclude), Size) ; end function RandSigned ; + impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandInt(Min, Max, Exclude) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector is + variable ResultPlus : integer_vector(1 to Size + Exclude'length) ; + begin + -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size) + ResultPlus(Size+1 to ResultPlus'right) := Exclude ; + for i in 1 to Size loop + ResultPlus(i) := RandInt(Min, Max, ResultPlus(maximum(1, 1 + i - Unique) to ResultPlus'right)) ; + end loop ; + return ResultPlus(1 to Size) ; + end function RandIntV ; + + impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Size : natural ; Unit : in time := ns) return time_vector is + begin + return to_time_vector( RandIntV(Min/Unit, Max/Unit, to_integer_vector(Exclude, Unit), Size), Unit ) ; + end function RandTimeV ; + + impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Unique : natural ; Size : natural ; Unit : in time := ns) return time_vector is + begin + -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size) + return to_time_vector( RandIntV(Min/Unit, Max/Unit, to_integer_vector(Exclude, Unit), Unique, Size), Unit ) ; + end function RandTimeV ; + + -- -- Randomly select a value within a set of values @@ -866,59 +1081,261 @@ package body RandomPkg is return A_norm( RandInt(1, A'length) ) ; end function RandInt ; - impure function RandSlv (A : integer_vector ; Size : natural) return std_logic_vector is + impure function RandReal ( A : real_vector ) return real is + alias A_norm : real_vector(1 to A'length) is A ; + begin + return A_norm( RandInt(1, A'length) ) ; + end function RandReal ; + + impure function RandTime ( A : time_vector ) return time is + alias A_norm : time_vector(1 to A'length) is A ; + begin + return A_norm( RandInt(1, A'length) ) ; + end function RandTime ; + + impure function RandSlv (A : integer_vector ; Size : natural) return std_logic_vector is begin return std_logic_vector(to_unsigned(RandInt(A), Size)) ; end function RandSlv ; - impure function RandUnsigned (A : integer_vector ; Size : natural) return Unsigned is + impure function RandUnsigned (A : integer_vector ; Size : natural) return Unsigned is begin return to_unsigned(RandInt(A), Size) ; end function RandUnsigned ; - impure function RandSigned (A : integer_vector ; Size : natural ) return Signed is + impure function RandSigned (A : integer_vector ; Size : natural ) return Signed is begin return to_signed(RandInt(A), Size) ; end function RandSigned ; + impure function RandIntV (A : integer_vector ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandInt(A) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandIntV (A : integer_vector ; Unique : natural ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + variable iUnique : natural ; + begin + -- if Unique = 0, it is more efficient to call RandIntV(A, Size) + -- require A'length >= Unique + iUnique := Unique ; + if A'length < Unique then + report "RandIntV: Unique > length of set of values" severity failure ; + iUnique := A'length ; + end if ; + for i in result'range loop + result(i) := RandInt(A, result(maximum(1, 1 + i - iUnique) to Size)) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandRealV (A : real_vector ; Size : natural) return real_vector is + variable result : real_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandReal(A) ; + end loop ; + return result ; + end function RandRealV ; + + impure function RandRealV (A : real_vector ; Unique : natural ; Size : natural) return real_vector is + alias A_norm : real_vector(1 to A'length) is A ; + variable result : real_vector(1 to Size) ; + variable IntResult : integer_vector(result'range) ; + begin + -- randomly generate indices + IntResult := RandIntV(1, A'length, Unique, Size) ; + -- translate indicies into result values + for i in result'range loop + result(i) := A_norm(IntResult(i)) ; + end loop ; + return result ; + end function RandRealV ; + + impure function RandTimeV (A : time_vector ; Size : natural) return time_vector is + variable result : time_vector(1 to Size) ; + begin + for i in result'range loop + result(i) := RandTime(A) ; + end loop ; + return result ; + end function RandTimeV ; + + impure function RandTimeV (A : time_vector ; Unique : natural ; Size : natural) return time_vector is + alias A_norm : time_vector(1 to A'length) is A ; + variable result : time_vector(1 to Size) ; + variable IntResult : integer_vector(result'range) ; + begin + -- randomly generate indices + IntResult := RandIntV(1, A'length, Unique, Size) ; + -- translate indicies into result values + for i in result'range loop + result(i) := A_norm(IntResult(i)) ; + end loop ; + return result ; + end function RandTimeV ; + -- -- Randomly select a value within a set of values with exclude values (so can skip last or last n) -- Distribution determined by RandomParm -- - impure function RandInt ( A : integer_vector; Exclude: integer_vector ) return integer is - alias A_norm : integer_vector(1 to A'length) is A ; - variable ExcludeIndexList : SortListPType ; - variable iVal : integer ; - begin - -- convert exclude list into indices of A_norm to exclude - -- necessary to preserve ordering of the distribution (such as NORMAL) - for i in A_norm'range loop - if inside(A_norm(i), Exclude) then - ExcludeIndexList.add(i) ; - end if ; - end loop ; - -- Randomize an index into A_Norm with exclude index list - iVal := RandInt(1, A'length, ExcludeIndexList.to_array (EraseList => TRUE)) ; - -- return the value at the randomized index - return A_norm(iVal) ; + + impure function RandInt ( A, Exclude : integer_vector ) return integer is + variable NewA : integer_vector(1 to A'length) ; + variable NewALength : natural ; + begin + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Randomize Index + return NewA(RandInt(1, NewALength)) ; end function RandInt ; - impure function RandSlv (A : integer_vector; Exclude: integer_vector; Size : natural) return std_logic_vector is + impure function RandReal ( A, Exclude : real_vector ) return real is + variable NewA : real_vector(1 to A'length) ; + variable NewALength : natural ; + begin + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Randomize Index + return NewA(RandInt(1, NewALength)) ; + end function RandReal ; + + impure function RandTime ( A, Exclude : time_vector ) return time is + variable NewA : time_vector(1 to A'length) ; + variable NewALength : natural ; + begin + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Randomize Index + return NewA(RandInt(1, NewALength)) ; + end function RandTime ; + + impure function RandSlv (A, Exclude : integer_vector ; Size : natural) return std_logic_vector is begin return std_logic_vector(to_unsigned(RandInt(A, Exclude), Size)) ; end function RandSlv ; - impure function RandUnsigned (A : integer_vector; Exclude: integer_vector; Size : natural) return Unsigned is + impure function RandUnsigned (A, Exclude : integer_vector ; Size : natural) return Unsigned is begin return to_unsigned(RandInt(A, Exclude), Size) ; end function RandUnsigned ; - impure function RandSigned (A : integer_vector; Exclude: integer_vector; Size : natural ) return Signed is + impure function RandSigned (A, Exclude : integer_vector ; Size : natural ) return Signed is begin return to_signed(RandInt(A, Exclude), Size) ; end function RandSigned ; + impure function RandIntV (A, Exclude : integer_vector ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + variable NewA : integer_vector(1 to A'length) ; + variable NewALength : natural ; + begin + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Randomize Index + for i in result'range loop + result(i) := NewA(RandInt(1, NewALength)) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandIntV (A, Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector is + variable result : integer_vector(1 to Size) ; + variable NewA : integer_vector(1 to A'length) ; + variable NewALength, iUnique : natural ; + begin + -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size) + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Require NewALength >= Unique + iUnique := Unique ; + if NewALength < Unique then + report "RandIntV: Unique > Length of Set A - Exclude" severity failure ; + iUnique := NewALength ; + end if ; + -- Randomize using exclude list of Unique # of newly generated values + for i in result'range loop + result(i) := RandInt(NewA(1 to NewALength), result(maximum(1, 1 + i - iUnique) to Size)) ; + end loop ; + return result ; + end function RandIntV ; + + impure function RandRealV (A, Exclude : real_vector ; Size : natural) return real_vector is + variable result : real_vector(1 to Size) ; + variable NewA : real_vector(1 to A'length) ; + variable NewALength : natural ; + begin + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Randomize Index + for i in result'range loop + result(i) := NewA(RandInt(1, NewALength)) ; + end loop ; + return result ; + end function RandRealV ; + + impure function RandRealV (A, Exclude : real_vector ; Unique : natural ; Size : natural) return real_vector is + variable result : real_vector(1 to Size) ; + variable NewA : real_vector(1 to A'length) ; + variable NewALength, iUnique : natural ; + begin + -- if Unique = 0, it is more efficient to call RandRealV(Min, Max, Size) + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Require NewALength >= Unique + iUnique := Unique ; + if NewALength < Unique then + report "RandRealV: Unique > Length of Set A - Exclude" severity failure ; + iUnique := NewALength ; + end if ; + -- Randomize using exclude list of Unique # of newly generated values + for i in result'range loop + result(i) := RandReal(NewA(1 to NewALength), result(maximum(1, 1 + i - iUnique) to Size)) ; + end loop ; + return result ; + end function RandRealV ; + + impure function RandTimeV (A, Exclude : time_vector ; Size : natural) return time_vector is + variable result : time_vector(1 to Size) ; + variable NewA : time_vector(1 to A'length) ; + variable NewALength : natural ; + begin + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Randomize Index + for i in result'range loop + result(i) := NewA(RandInt(1, NewALength)) ; + end loop ; + return result ; + end function RandTimeV ; + + impure function RandTimeV (A, Exclude : time_vector ; Unique : natural ; Size : natural) return time_vector is + variable result : time_vector(1 to Size) ; + variable NewA : time_vector(1 to A'length) ; + variable NewALength, iUnique : natural ; + begin + -- if Unique = 0, it is more efficient to call RandRealV(Min, Max, Size) + -- Remove Exclude from A + RemoveExclude(A, Exclude, NewA, NewALength) ; + -- Require NewALength >= Unique + iUnique := Unique ; + if NewALength < Unique then + report "RandTimeV: Unique > Length of Set A - Exclude" severity failure ; + iUnique := NewALength ; + end if ; + -- Randomize using exclude list of Unique # of newly generated values + for i in result'range loop + result(i) := RandTime(NewA(1 to NewALength), result(maximum(1, 1 + i - iUnique) to Size)) ; + end loop ; + return result ; + end function RandTimeV ; + -- -- Basic Discrete Distributions @@ -932,25 +1349,25 @@ package body RandomPkg is DistArray := Weight ; sum := 0 ; for i in DistArray'range loop - DistArray(i) := DistArray(i) + sum ; + DistArray(i) := DistArray(i) + sum ; if DistArray(i) < sum then - report "DistInt failed: negative weight or sum > 31 bits" - severity failure ; + report "DistInt failed : negative weight or sum > 31 bits" + severity failure ; return DistArray'low ; -- allows debugging vs integer'left, out of range - end if ; + end if ; sum := DistArray(i) ; end loop ; - if sum >= 1 then + if sum >= 1 then iRandomVal := Uniform(1, sum) ; for i in DistArray'range loop if iRandomVal <= DistArray(i) then return i ; - end if; + end if ; end loop ; - report "DistInt: randomization failed" severity failure ; + report "DistInt : randomization failed" severity failure ; else - report "DistInt: No randomizatoin weights" severity failure ; - end if ; + report "DistInt : No randomizatoin weights" severity failure ; + end if ; return DistArray'low ; -- allows debugging vs integer'left, out of range end function DistInt ; @@ -969,12 +1386,12 @@ package body RandomPkg is return to_signed(DistInt(Weight), Size) ; end function DistSigned ; - + -- -- Basic Distributions with exclude values (so can skip last or last n) -- Always uses Uniform via DistInt -- - impure function DistInt ( Weight : integer_vector; Exclude: integer_vector ) return integer is + impure function DistInt ( Weight : integer_vector ; Exclude : integer_vector ) return integer is variable DistArray : integer_vector(weight'range) ; variable ExcludeTemp : integer ; begin @@ -988,17 +1405,17 @@ package body RandomPkg is return DistInt(DistArray) ; end function DistInt ; - impure function DistSlv ( Weight : integer_vector; Exclude: integer_vector; Size : natural ) return std_logic_vector is + impure function DistSlv ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return std_logic_vector is begin return std_logic_vector(to_unsigned(DistInt(Weight, Exclude), Size)) ; end function DistSlv ; - impure function DistUnsigned ( Weight : integer_vector; Exclude: integer_vector; Size : natural ) return unsigned is + impure function DistUnsigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return unsigned is begin return to_unsigned(DistInt(Weight, Exclude), Size) ; end function DistUnsigned ; - impure function DistSigned ( Weight : integer_vector; Exclude: integer_vector; Size : natural ) return signed is + impure function DistSigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return signed is begin return to_signed(DistInt(Weight, Exclude), Size) ; end function DistSigned ; @@ -1010,7 +1427,7 @@ package body RandomPkg is -- impure function DistValInt ( A : DistType ) return integer is variable DistArray : integer_vector(0 to A'length -1) ; - alias DistRecArray : DistType(DistArray'range) is A; + alias DistRecArray : DistType(DistArray'range) is A ; begin for i in DistArray'range loop DistArray(i) := DistRecArray(i).Weight ; @@ -1038,54 +1455,54 @@ package body RandomPkg is -- Distribution for sparse values with exclude values (so can skip last or last n) -- Always uses Uniform via DistInt -- - impure function DistValInt ( A : DistType; Exclude: integer_vector ) return integer is + impure function DistValInt ( A : DistType ; Exclude : integer_vector ) return integer is variable DistArray : integer_vector(0 to A'length -1) ; - alias DistRecArray : DistType(DistArray'range) is A; + alias DistRecArray : DistType(DistArray'range) is A ; begin for i in DistRecArray'range loop if inside(DistRecArray(i).Value, exclude) then - DistArray(i) := 0 ; -- exclude + DistArray(i) := 0 ; -- exclude else DistArray(i) := DistRecArray(i).Weight ; - end if; + end if ; end loop ; return DistRecArray(DistInt(DistArray)).Value ; end function DistValInt ; - impure function DistValSlv ( A : DistType; Exclude: integer_vector; Size : natural ) return std_logic_vector is + impure function DistValSlv ( A : DistType ; Exclude : integer_vector ; Size : natural ) return std_logic_vector is begin return std_logic_vector(to_unsigned(DistValInt(A, Exclude), Size)) ; end function DistValSlv ; - impure function DistValUnsigned ( A : DistType; Exclude: integer_vector; Size : natural ) return unsigned is + impure function DistValUnsigned ( A : DistType ; Exclude : integer_vector ; Size : natural ) return unsigned is begin return to_unsigned(DistValInt(A, Exclude), Size) ; end function DistValUnsigned ; - impure function DistValSigned ( A : DistType; Exclude: integer_vector; Size : natural ) return signed is + impure function DistValSigned ( A : DistType ; Exclude : integer_vector ; Size : natural ) return signed is begin return to_signed(DistValInt(A, Exclude), Size) ; end function DistValSigned ; -- - -- Large vector handling. + -- Large vector handling. -- impure function RandUnsigned (Size : natural) return unsigned is constant NumLoops : integer := integer(ceil(real(Size)/30.0)) ; constant Remain : integer := (Size - 1) mod 30 + 1 ; -- range 1 to 30 - variable RandVal : unsigned(1 to Size) ; + variable RandVal : unsigned(1 to Size) ; begin - if size = 0 then + if size = 0 then return NULL_UV ; -- Null array - end if ; + end if ; for i in 0 to NumLoops-2 loop RandVal(1 + 30*i to 30 + 30*i) := to_unsigned(RandInt(0, 2**30-1), 30) ; end loop ; - RandVal(1+30*(NumLoops-1) to Remain + 30*(NumLoops-1)) := to_unsigned(RandInt(0, 2**Remain-1), Remain) ; - return RandVal ; + RandVal(1+30*(NumLoops-1) to Remain + 30*(NumLoops-1)) := to_unsigned(RandInt(0, 2**Remain-1), Remain) ; + return RandVal ; end function RandUnsigned ; - + impure function RandSlv (Size : natural) return std_logic_vector is begin return std_logic_vector(RandUnsigned(Size)) ; @@ -1095,98 +1512,98 @@ package body RandomPkg is begin return signed(RandUnsigned(Size)) ; end function RandSigned ; - - + + impure function RandUnsigned (Max : unsigned) return unsigned is alias normMax : unsigned (Max'length downto 1) is Max ; variable Result : unsigned(Max'range) := (others => '0') ; - alias normResult : unsigned(normMax'range) is Result ; + alias normResult : unsigned(normMax'range) is Result ; variable Size : integer ; begin -- Size = -1 if not found or Max'length = 0 - Size := find_leftmost(normMax, '1') ; + Size := find_leftmost(normMax, '1') ; - if Size > 0 then - loop - normResult(Size downto 1) := RandUnsigned(Size) ; - exit when normResult <= Max ; - end loop ; + if Size > 0 then + loop + normResult(Size downto 1) := RandUnsigned(Size) ; + exit when normResult <= Max ; + end loop ; return Result ; -- = normResult with range same as Max - else - return resize("0", Max'length) ; - end if ; - end function RandUnsigned ; + else + return resize("0", Max'length) ; + end if ; + end function RandUnsigned ; -- Working version that scales the value -- impure function RandUnsigned (Max : unsigned) return unsigned is -- constant MaxVal : unsigned(Max'length+3 downto 1) := (others => '1') ; -- begin - -- if max'length > 0 then + -- if max'length > 0 then -- -- "Max'length+3" creates 3 guard bits -- return resize( RandUnsigned(Max'length+3) * ('0'&Max+1) / ('0'&MaxVal+1), Max'length) ; - -- else + -- else -- return NULL_UV ; -- Null Array - -- end if ; - -- end function RandUnsigned ; - + -- end if ; + -- end function RandUnsigned ; + impure function RandSlv (Max : std_logic_vector) return std_logic_vector is begin return std_logic_vector(RandUnsigned( unsigned(Max))) ; - end function RandSlv ; + end function RandSlv ; impure function RandSigned (Max : signed) return signed is begin if max'length > 0 then - assert (Max >= 0) report "%%RandomPkg RandSigned: Max < 0" severity FAILURE ; + assert (Max >= 0) report "%%RandomPkg RandSigned : Max < 0" severity FAILURE ; return signed(RandUnsigned( unsigned(Max))) ; else return NULL_SV ; -- Null Array - end if ; - end function RandSigned ; - - + end if ; + end function RandSigned ; + + impure function RandUnsigned (Min, Max : unsigned) return unsigned is - constant LEN : integer := maximum(Max'length, Min'length) ; + constant LEN : integer := maximum(Max'length, Min'length) ; begin - if LEN > 0 and Min <= Max then + if LEN > 0 and Min <= Max then return RandUnsigned(Max-Min) + Min ; - else - if Len > 0 then - report "%%RandomPkg RandUnsigned: Max < Min" severity FAILURE ; - end if ; - return NULL_UV ; - end if; - end function RandUnsigned ; + else + if Len > 0 then + report "%%RandomPkg RandUnsigned : Max < Min" severity FAILURE ; + end if ; + return NULL_UV ; + end if ; + end function RandUnsigned ; + - impure function RandSlv (Min, Max : std_logic_vector) return std_logic_vector is - constant LEN : integer := maximum(Max'length, Min'length) ; + constant LEN : integer := maximum(Max'length, Min'length) ; begin - if LEN > 0 and Min <= Max then + if LEN > 0 and Min <= Max then return RandSlv(Max-Min) + Min ; else - if Len > 0 then - report "%%RandomPkg RandSlv: Max < Min" severity FAILURE ; - end if ; - return NULL_SlV ; - end if ; - end function RandSlv ; - - + if Len > 0 then + report "%%RandomPkg RandSlv : Max < Min" severity FAILURE ; + end if ; + return NULL_SlV ; + end if ; + end function RandSlv ; + + impure function RandSigned (Min, Max : signed) return signed is - constant LEN : integer := maximum(Max'length, Min'length) ; + constant LEN : integer := maximum(Max'length, Min'length) ; begin - if LEN > 0 and Min <= Max then + if LEN > 0 and Min <= Max then return resize(RandSigned(resize(Max,LEN+1) - resize(Min,LEN+1)) + Min, LEN) ; else - if Len > 0 then - report "%%RandomPkg RandSigned: Max < Min" severity FAILURE ; - end if ; - return NULL_SV ; - end if ; - end function RandSigned ; + if Len > 0 then + report "%%RandomPkg RandSigned : Max < Min" severity FAILURE ; + end if ; + return NULL_SV ; + end if ; + end function RandSigned ; + - -- -- Convenience Functions. Resolve into calls into the other functions -- @@ -1195,10 +1612,10 @@ package body RandomPkg is return RandReal(0.0, 1.0) ; end function RandReal ; - impure function RandReal(Max: Real) return real is -- 0.0 to Max + impure function RandReal(Max : Real) return real is -- 0.0 to Max begin return RandReal(0.0, Max) ; - -- assert Max >= 0.0 report "RandReal: Range Error" severity FAILURE ; + -- assert Max >= 0.0 report "RandReal : Range Error" severity FAILURE ; -- return RandReal * Max ; end function RandReal ; @@ -1218,7 +1635,7 @@ package body RandomPkg is end function RandUnsigned ; - impure function RandSigned (Max : integer; Size : natural ) return Signed is + impure function RandSigned (Max : integer ; Size : natural ) return Signed is begin -- chose 0 to Max rather than -Max to +Max to be same as RandUnsigned, either seems logical return to_signed(RandInt(0, Max), Size) ; diff --git a/RandomPkg_user_guide.pdf b/RandomPkg_user_guide.pdf new file mode 100644 index 0000000..81239fc Binary files /dev/null and b/RandomPkg_user_guide.pdf differ diff --git a/packages/SortListPkg_int.vhd b/SortListPkg_int.vhd similarity index 85% rename from packages/SortListPkg_int.vhd rename to SortListPkg_int.vhd index 185affc..5d62fa2 100644 --- a/packages/SortListPkg_int.vhd +++ b/SortListPkg_int.vhd @@ -1,7 +1,7 @@ -- -- File Name: SortListPkg_int.vhd -- Design Unit Name: SortListPkg_int --- Revision: STANDARD VERSION, revision 2013.05 +-- Revision: STANDARD VERSION, revision 2014.01 -- -- Maintainer: Jim Lewis email: jim@synthworks.com -- Contributor(s): @@ -30,10 +30,11 @@ -- 4/2013 2013.04 No Changes -- 5/2013 2013.05 No changes of substance. -- Deleted extra variable declaration in procedure remove +-- 1/2014 2014.01 Added RevSort. Added AllowDuplicate paramter to Add procedure -- -- -- --- Copyright (c) 2008 - 2013 by SynthWorks Design Inc. All rights reserved. +-- Copyright (c) 2008 - 2014 by SynthWorks Design Inc. All rights reserved. -- -- Verbatim copies of this source file may be used and -- distributed without restriction. @@ -74,9 +75,10 @@ package SortListPkg_int is function inside (constant E : ElementType; constant A : in ArrayofElementType) return boolean ; impure function sort (constant A : in ArrayofElementType) return ArrayofElementType ; + impure function revsort (constant A : in ArrayofElementType) return ArrayofElementType ; type SortListPType is protected - procedure add ( constant A : in ElementType ) ; + procedure add ( constant A : in ElementType ; constant AllowDuplicate : Boolean := FALSE ) ; procedure add ( constant A : in ArrayofElementType ) ; procedure add ( constant A : in ArrayofElementType ; Min, Max : integer ) ; procedure add ( variable A : inout SortListPType ) ; @@ -95,6 +97,7 @@ package SortListPkg_int is procedure remove ( variable A : inout SortListPType ) ; impure function to_array (constant EraseList : boolean := FALSE) return ArrayofElementType ; + impure function to_rev_array (constant EraseList : boolean := FALSE) return ArrayofElementType ; end protected SortListPType ; end SortListPkg_int ; @@ -124,32 +127,38 @@ package body SortListPkg_int is variable HeadPointer : ListPointerType := NULL ; -- variable TailPointer : ListPointerType := NULL ; - procedure add ( constant A : in ElementType ) is + procedure add ( constant A : in ElementType ; constant AllowDuplicate : Boolean := FALSE ) is variable CurPtr, tempPtr : ListPointerType ; begin if HeadPointer = NULL then HeadPointer := new ListType'(A, NULL) ; - elsif A = HeadPointer.A then -- ignore duplicates - return ; - + if AllowDuplicate then + tempPtr := HeadPointer ; + HeadPointer := new ListType'(A, tempPtr) ; + end if ; elsif A < HeadPointer.A then tempPtr := HeadPointer ; HeadPointer := new ListType'(A, tempPtr) ; - else CurPtr := HeadPointer ; - loop - exit when CurPtr.NextPtr = NULL ; - exit when A < CurPtr.NextPtr.A ; - if A = CurPtr.NextPtr.A then return ; end if; -- exit + AddLoop : loop + exit AddLoop when CurPtr.NextPtr = NULL ; + exit AddLoop when A < CurPtr.NextPtr.A ; + if A = CurPtr.NextPtr.A then + if AllowDuplicate then + exit AddLoop ; -- insert + else + return ; -- return without insert + end if; + end if ; CurPtr := CurPtr.NextPtr ; - end loop ; + end loop AddLoop ; tempPtr := CurPtr.NextPtr ; CurPtr.NextPtr := new ListType'(A, tempPtr) ; end if ; end procedure add ; - + procedure add ( constant A : in ArrayofElementType ) is begin for i in A'range loop @@ -364,15 +373,37 @@ package body SortListPkg_int is return result ; end function to_array ; - end protected body SortListPType ; + impure function to_rev_array (constant EraseList : boolean := FALSE) return ArrayofElementType is + variable result : ArrayofElementType(Count downto 1) ; + begin + for i in 1 to Count loop + result(i) := Get(i) ; + end loop ; + if EraseList then + erase ; + end if ; + return result ; + end function to_rev_array ; + + end protected body SortListPType ; impure function sort (constant A : in ArrayofElementType) return ArrayofElementType is variable Result : SortListPType ; begin - Result.Add(A) ; + for i in A'range loop + Result.Add(A(i), TRUE) ; + end loop ; return Result.to_array(EraseList => TRUE) ; end function sort ; + impure function revsort (constant A : in ArrayofElementType) return ArrayofElementType is + variable Result : SortListPType ; + begin + for i in A'range loop + Result.Add(A(i), TRUE) ; + end loop ; + return Result.to_rev_array(EraseList => TRUE) ; + end function revsort ; end SortListPkg_int ; diff --git a/doc/CoveragePkg_release_notes.pdf b/doc/CoveragePkg_release_notes.pdf deleted file mode 100644 index 526a591..0000000 Binary files a/doc/CoveragePkg_release_notes.pdf and /dev/null differ diff --git a/doc/CoveragePkg_user_guide.pdf b/doc/CoveragePkg_user_guide.pdf deleted file mode 100644 index cdff949..0000000 Binary files a/doc/CoveragePkg_user_guide.pdf and /dev/null differ diff --git a/doc/RandomPkg_user_guide.pdf b/doc/RandomPkg_user_guide.pdf deleted file mode 100644 index 5179c88..0000000 Binary files a/doc/RandomPkg_user_guide.pdf and /dev/null differ