You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fixed_generic_pkg-body.vhdl 211KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360
  1. -- -----------------------------------------------------------------
  2. --
  3. -- Copyright 2019 IEEE P1076 WG Authors
  4. --
  5. -- See the LICENSE file distributed with this work for copyright and
  6. -- licensing information and the AUTHORS file.
  7. --
  8. -- This file to you under the Apache License, Version 2.0 (the "License").
  9. -- You may obtain a copy of the License at
  10. --
  11. -- http://www.apache.org/licenses/LICENSE-2.0
  12. --
  13. -- Unless required by applicable law or agreed to in writing, software
  14. -- distributed under the License is distributed on an "AS IS" BASIS,
  15. -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  16. -- implied. See the License for the specific language governing
  17. -- permissions and limitations under the License.
  18. --
  19. -- Title : Fixed-point package (Generic package body)
  20. -- :
  21. -- Library : This package shall be compiled into a library
  22. -- : symbolically named IEEE.
  23. -- :
  24. -- Developers: Accellera VHDL-TC and IEEE P1076 Working Group
  25. -- :
  26. -- Purpose : This packages defines basic binary fixed point arithmetic
  27. -- : arithmetic functions
  28. -- :
  29. -- Note : This package may be modified to include additional data
  30. -- : required by tools, but it must in no way change the
  31. -- : external interfaces or simulation behavior of the
  32. -- : description. It is permissible to add comments and/or
  33. -- : attributes to the package declarations, but not to change
  34. -- : or delete any original lines of the package declaration.
  35. -- : The package body may be changed only in accordance with
  36. -- : the terms of Clause 16 of this standard.
  37. -- :
  38. -- --------------------------------------------------------------------
  39. -- $Revision: 1220 $
  40. -- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
  41. -- --------------------------------------------------------------------
  42. library IEEE;
  43. use IEEE.MATH_REAL.all;
  44. package body fixed_generic_pkg is
  45. -- Author David Bishop (dbishop@vhdl.org)
  46. -- Other contributers: Jim Lewis, Yannick Grugni, Ryan W. Hilton
  47. -- null array constants
  48. constant NAUF : UNRESOLVED_ufixed (0 downto 1) := (others => '0');
  49. constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');
  50. constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
  51. -- This differed constant will tell you if the package body is synthesizable
  52. -- or implemented as real numbers, set to "true" if synthesizable.
  53. constant fixedsynth_or_real : BOOLEAN := true;
  54. -- Special version of "minimum" to do some boundary checking without errors
  55. function mins (l, r : INTEGER)
  56. return INTEGER is
  57. begin -- function mins
  58. if (l = INTEGER'low or r = INTEGER'low) then
  59. return 0; -- error condition, silent
  60. end if;
  61. return minimum (l, r);
  62. end function mins;
  63. -- Special version of "minimum" to do some boundary checking with errors
  64. function mine (l, r : INTEGER)
  65. return INTEGER is
  66. begin -- function mine
  67. if (l = INTEGER'low or r = INTEGER'low) then
  68. report fixed_generic_pkg'instance_name
  69. & " Unbounded number passed, was a literal used?"
  70. severity error;
  71. return 0;
  72. end if;
  73. return minimum (l, r);
  74. end function mine;
  75. -- The following functions are used only internally. Every function
  76. -- calls "cleanvec" either directly or indirectly.
  77. -- purpose: Fixes "downto" problem and resolves meta states
  78. function cleanvec (
  79. arg : UNRESOLVED_sfixed) -- input
  80. return UNRESOLVED_sfixed
  81. is
  82. begin -- function cleanvec
  83. assert not (arg'ascending and (arg'low /= INTEGER'low))
  84. report fixed_generic_pkg'instance_name
  85. & " Vector passed using a ""to"" range, expected is ""downto"""
  86. severity error;
  87. return arg;
  88. end function cleanvec;
  89. -- purpose: Fixes "downto" problem and resolves meta states
  90. function cleanvec (
  91. arg : UNRESOLVED_ufixed) -- input
  92. return UNRESOLVED_ufixed
  93. is
  94. begin -- function cleanvec
  95. assert not (arg'ascending and (arg'low /= INTEGER'low))
  96. report fixed_generic_pkg'instance_name
  97. & " Vector passed using a ""to"" range, expected is ""downto"""
  98. severity error;
  99. return arg;
  100. end function cleanvec;
  101. -- Type convert a "unsigned" into a "ufixed", used internally
  102. function to_fixed (
  103. arg : UNRESOLVED_UNSIGNED; -- shifted vector
  104. constant left_index : INTEGER;
  105. constant right_index : INTEGER)
  106. return UNRESOLVED_ufixed
  107. is
  108. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  109. begin -- function to_fixed
  110. result := UNRESOLVED_ufixed(arg);
  111. return result;
  112. end function to_fixed;
  113. -- Type convert a "signed" into an "sfixed", used internally
  114. function to_fixed (
  115. arg : UNRESOLVED_SIGNED; -- shifted vector
  116. constant left_index : INTEGER;
  117. constant right_index : INTEGER)
  118. return UNRESOLVED_sfixed
  119. is
  120. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  121. begin -- function to_fixed
  122. result := UNRESOLVED_sfixed(arg);
  123. return result;
  124. end function to_fixed;
  125. -- Type convert a "ufixed" into an "unsigned", used internally
  126. function to_uns (
  127. arg : UNRESOLVED_ufixed) -- fp vector
  128. return UNRESOLVED_UNSIGNED
  129. is
  130. subtype t is UNRESOLVED_UNSIGNED(arg'high - arg'low downto 0);
  131. variable slv : t;
  132. begin -- function to_uns
  133. slv := t(arg);
  134. return slv;
  135. end function to_uns;
  136. -- Type convert an "sfixed" into a "signed", used internally
  137. function to_s (
  138. arg : UNRESOLVED_sfixed) -- fp vector
  139. return UNRESOLVED_SIGNED
  140. is
  141. subtype t is UNRESOLVED_SIGNED(arg'high - arg'low downto 0);
  142. variable slv : t;
  143. begin -- function to_s
  144. slv := t(arg);
  145. return slv;
  146. end function to_s;
  147. -- adds 1 to the LSB of the number
  148. procedure round_up (arg : in UNRESOLVED_ufixed;
  149. result : out UNRESOLVED_ufixed;
  150. overflowx : out BOOLEAN) is
  151. variable arguns, resuns : UNRESOLVED_UNSIGNED (arg'high-arg'low+1 downto 0)
  152. := (others => '0');
  153. begin -- round_up
  154. arguns (arguns'high-1 downto 0) := to_uns (arg);
  155. resuns := arguns + 1;
  156. result := to_fixed(resuns(arg'high-arg'low
  157. downto 0), arg'high, arg'low);
  158. overflowx := (resuns(resuns'high) = '1');
  159. end procedure round_up;
  160. -- adds 1 to the LSB of the number
  161. procedure round_up (arg : in UNRESOLVED_sfixed;
  162. result : out UNRESOLVED_sfixed;
  163. overflowx : out BOOLEAN) is
  164. variable args, ress : UNRESOLVED_SIGNED (arg'high-arg'low+1 downto 0);
  165. begin -- round_up
  166. args (args'high-1 downto 0) := to_s (arg);
  167. args(args'high) := arg(arg'high); -- sign extend
  168. ress := args + 1;
  169. result := to_fixed(ress (ress'high-1
  170. downto 0), arg'high, arg'low);
  171. overflowx := ((arg(arg'high) /= ress(ress'high-1))
  172. and (or (STD_ULOGIC_VECTOR(ress)) /= '0'));
  173. end procedure round_up;
  174. -- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up
  175. -- when the remainder is > 0.5. If the remainder IS 0.5 then if the
  176. -- bottom bit is a "1" it is rounded, otherwise it remains the same.
  177. function round_fixed (arg : UNRESOLVED_ufixed;
  178. remainder : UNRESOLVED_ufixed;
  179. overflow_style : fixed_overflow_style_type := fixed_overflow_style)
  180. return UNRESOLVED_ufixed
  181. is
  182. variable rounds : BOOLEAN;
  183. variable round_overflow : BOOLEAN;
  184. variable result : UNRESOLVED_ufixed (arg'range);
  185. begin
  186. rounds := false;
  187. if (remainder'length > 1) then
  188. if (remainder (remainder'high) = '1') then
  189. rounds := (arg(arg'low) = '1')
  190. or (or (to_sulv(remainder(remainder'high-1 downto
  191. remainder'low))) = '1');
  192. end if;
  193. else
  194. rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
  195. end if;
  196. if rounds then
  197. round_up(arg => arg,
  198. result => result,
  199. overflowx => round_overflow);
  200. else
  201. result := arg;
  202. end if;
  203. if (overflow_style = fixed_saturate) and round_overflow then
  204. result := saturate (result'high, result'low);
  205. end if;
  206. return result;
  207. end function round_fixed;
  208. -- Rounding case statement
  209. function round_fixed (arg : UNRESOLVED_sfixed;
  210. remainder : UNRESOLVED_sfixed;
  211. overflow_style : fixed_overflow_style_type := fixed_overflow_style)
  212. return UNRESOLVED_sfixed
  213. is
  214. variable rounds : BOOLEAN;
  215. variable round_overflow : BOOLEAN;
  216. variable result : UNRESOLVED_sfixed (arg'range);
  217. begin
  218. rounds := false;
  219. if (remainder'length > 1) then
  220. if (remainder (remainder'high) = '1') then
  221. rounds := (arg(arg'low) = '1')
  222. or (or (to_sulv(remainder(remainder'high-1 downto
  223. remainder'low))) = '1');
  224. end if;
  225. else
  226. rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
  227. end if;
  228. if rounds then
  229. round_up(arg => arg,
  230. result => result,
  231. overflowx => round_overflow);
  232. else
  233. result := arg;
  234. end if;
  235. if round_overflow then
  236. if (overflow_style = fixed_saturate) then
  237. if arg(arg'high) = '0' then
  238. result := saturate (result'high, result'low);
  239. else
  240. result := not saturate (result'high, result'low);
  241. end if;
  242. -- Sign bit not fixed when wrapping
  243. end if;
  244. end if;
  245. return result;
  246. end function round_fixed;
  247. -- converts an sfixed into a ufixed. The output is the same length as the
  248. -- input, because abs("1000") = "1000" = 8.
  249. function to_ufixed (
  250. arg : UNRESOLVED_sfixed)
  251. return UNRESOLVED_ufixed
  252. is
  253. constant left_index : INTEGER := arg'high;
  254. constant right_index : INTEGER := mine(arg'low, arg'low);
  255. variable xarg : UNRESOLVED_sfixed(left_index+1 downto right_index);
  256. variable result : UNRESOLVED_ufixed(left_index downto right_index);
  257. begin
  258. if arg'length < 1 then
  259. return NAUF;
  260. end if;
  261. xarg := abs(arg);
  262. result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
  263. return result;
  264. end function to_ufixed;
  265. -----------------------------------------------------------------------------
  266. -- Visible functions
  267. -----------------------------------------------------------------------------
  268. -- Conversion functions. These are needed for synthesis where typically
  269. -- the only input and output type is a std_logic_vector.
  270. function to_sulv (
  271. arg : UNRESOLVED_ufixed) -- fixed point vector
  272. return STD_ULOGIC_VECTOR
  273. is
  274. variable intermediate_result : UNRESOLVED_ufixed(arg'length-1 downto 0);
  275. begin
  276. if arg'length < 1 then
  277. return NSLV;
  278. end if;
  279. intermediate_result := arg;
  280. return STD_ULOGIC_VECTOR (intermediate_result);
  281. end function to_sulv;
  282. function to_sulv (
  283. arg : UNRESOLVED_sfixed) -- fixed point vector
  284. return STD_ULOGIC_VECTOR
  285. is
  286. variable intermediate_result : UNRESOLVED_sfixed(arg'length-1 downto 0);
  287. begin
  288. if arg'length < 1 then
  289. return NSLV;
  290. end if;
  291. intermediate_result := arg;
  292. return STD_ULOGIC_VECTOR (intermediate_result);
  293. end function to_sulv;
  294. function to_slv (
  295. arg : UNRESOLVED_ufixed) -- fixed point vector
  296. return STD_LOGIC_VECTOR is
  297. begin
  298. return to_sulv(arg);
  299. end function to_slv;
  300. function to_slv (
  301. arg : UNRESOLVED_sfixed) -- fixed point vector
  302. return STD_LOGIC_VECTOR is
  303. begin
  304. return to_sulv(arg);
  305. end function to_slv;
  306. function to_ufixed (
  307. arg : STD_ULOGIC_VECTOR; -- shifted vector
  308. constant left_index : INTEGER;
  309. constant right_index : INTEGER)
  310. return UNRESOLVED_ufixed
  311. is
  312. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  313. begin
  314. if (arg'length < 1 or right_index > left_index) then
  315. return NAUF;
  316. end if;
  317. if (arg'length /= result'length) then
  318. report fixed_generic_pkg'instance_name & "TO_UFIXED(SLV) "
  319. & "Vector lengths do not match. Input length is "
  320. & INTEGER'image(arg'length) & " and output will be "
  321. & INTEGER'image(result'length) & " wide."
  322. severity error;
  323. return NAUF;
  324. else
  325. result := to_fixed (arg => UNRESOLVED_UNSIGNED(arg),
  326. left_index => left_index,
  327. right_index => right_index);
  328. return result;
  329. end if;
  330. end function to_ufixed;
  331. function to_sfixed (
  332. arg : STD_ULOGIC_VECTOR; -- shifted vector
  333. constant left_index : INTEGER;
  334. constant right_index : INTEGER)
  335. return UNRESOLVED_sfixed
  336. is
  337. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  338. begin
  339. if (arg'length < 1 or right_index > left_index) then
  340. return NASF;
  341. end if;
  342. if (arg'length /= result'length) then
  343. report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) "
  344. & "Vector lengths do not match. Input length is "
  345. & INTEGER'image(arg'length) & " and output will be "
  346. & INTEGER'image(result'length) & " wide."
  347. severity error;
  348. return NASF;
  349. else
  350. result := to_fixed (arg => UNRESOLVED_SIGNED(arg),
  351. left_index => left_index,
  352. right_index => right_index);
  353. return result;
  354. end if;
  355. end function to_sfixed;
  356. -- Two's complement number, Grows the vector by 1 bit.
  357. -- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
  358. function "abs" (
  359. arg : UNRESOLVED_sfixed) -- fixed point input
  360. return UNRESOLVED_sfixed
  361. is
  362. constant left_index : INTEGER := arg'high;
  363. constant right_index : INTEGER := mine(arg'low, arg'low);
  364. variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
  365. variable result : UNRESOLVED_sfixed (left_index+1 downto right_index);
  366. begin
  367. if (arg'length < 1 or result'length < 1) then
  368. return NASF;
  369. end if;
  370. ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
  371. ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
  372. result := to_fixed (abs(ressns), left_index+1, right_index);
  373. return result;
  374. end function "abs";
  375. -- also grows the vector by 1 bit.
  376. function "-" (
  377. arg : UNRESOLVED_sfixed) -- fixed point input
  378. return UNRESOLVED_sfixed
  379. is
  380. constant left_index : INTEGER := arg'high+1;
  381. constant right_index : INTEGER := mine(arg'low, arg'low);
  382. variable ressns : UNRESOLVED_SIGNED (arg'length downto 0);
  383. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  384. begin
  385. if (arg'length < 1 or result'length < 1) then
  386. return NASF;
  387. end if;
  388. ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
  389. ressns (arg'length) := ressns (arg'length-1); -- expand sign bit
  390. result := to_fixed (-ressns, left_index, right_index);
  391. return result;
  392. end function "-";
  393. -- Addition
  394. function "+" (
  395. l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) + ufixed(c downto d) =
  396. return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
  397. is
  398. constant left_index : INTEGER := maximum(l'high, r'high)+1;
  399. constant right_index : INTEGER := mine(l'low, r'low);
  400. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  401. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  402. variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
  403. downto 0);
  404. variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
  405. downto 0);
  406. begin
  407. if (l'length < 1 or r'length < 1 or result'length < 1) then
  408. return NAUF;
  409. end if;
  410. lresize := resize (l, left_index, right_index);
  411. rresize := resize (r, left_index, right_index);
  412. lslv := to_uns (lresize);
  413. rslv := to_uns (rresize);
  414. result_slv := lslv + rslv;
  415. result := to_fixed(result_slv, left_index, right_index);
  416. return result;
  417. end function "+";
  418. function "+" (
  419. l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) + sfixed(c downto d) =
  420. return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
  421. is
  422. constant left_index : INTEGER := maximum(l'high, r'high)+1;
  423. constant right_index : INTEGER := mine(l'low, r'low);
  424. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  425. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  426. variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
  427. variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
  428. begin
  429. if (l'length < 1 or r'length < 1 or result'length < 1) then
  430. return NASF;
  431. end if;
  432. lresize := resize (l, left_index, right_index);
  433. rresize := resize (r, left_index, right_index);
  434. lslv := to_s (lresize);
  435. rslv := to_s (rresize);
  436. result_slv := lslv + rslv;
  437. result := to_fixed(result_slv, left_index, right_index);
  438. return result;
  439. end function "+";
  440. -- Subtraction
  441. function "-" (
  442. l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) - ufixed(c downto d) =
  443. return UNRESOLVED_ufixed -- ufixed(max(a,c)+1 downto min(b,d))
  444. is
  445. constant left_index : INTEGER := maximum(l'high, r'high)+1;
  446. constant right_index : INTEGER := mine(l'low, r'low);
  447. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  448. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  449. variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
  450. downto 0);
  451. variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
  452. downto 0);
  453. begin
  454. if (l'length < 1 or r'length < 1 or result'length < 1) then
  455. return NAUF;
  456. end if;
  457. lresize := resize (l, left_index, right_index);
  458. rresize := resize (r, left_index, right_index);
  459. lslv := to_uns (lresize);
  460. rslv := to_uns (rresize);
  461. result_slv := lslv - rslv;
  462. result := to_fixed(result_slv, left_index, right_index);
  463. return result;
  464. end function "-";
  465. function "-" (
  466. l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) - sfixed(c downto d) =
  467. return UNRESOLVED_sfixed -- sfixed(max(a,c)+1 downto min(b,d))
  468. is
  469. constant left_index : INTEGER := maximum(l'high, r'high)+1;
  470. constant right_index : INTEGER := mine(l'low, r'low);
  471. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  472. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  473. variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
  474. variable result_slv : UNRESOLVED_SIGNED (left_index-right_index downto 0);
  475. begin
  476. if (l'length < 1 or r'length < 1 or result'length < 1) then
  477. return NASF;
  478. end if;
  479. lresize := resize (l, left_index, right_index);
  480. rresize := resize (r, left_index, right_index);
  481. lslv := to_s (lresize);
  482. rslv := to_s (rresize);
  483. result_slv := lslv - rslv;
  484. result := to_fixed(result_slv, left_index, right_index);
  485. return result;
  486. end function "-";
  487. function "*" (
  488. l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) * ufixed(c downto d) =
  489. return UNRESOLVED_ufixed -- ufixed(a+c+1 downto b+d)
  490. is
  491. variable lslv : UNRESOLVED_UNSIGNED (l'length-1 downto 0);
  492. variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
  493. variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0);
  494. variable result : UNRESOLVED_ufixed (l'high + r'high+1 downto
  495. mine(l'low, l'low) + mine(r'low, r'low));
  496. begin
  497. if (l'length < 1 or r'length < 1 or
  498. result'length /= result_slv'length) then
  499. return NAUF;
  500. end if;
  501. lslv := to_uns (cleanvec(l));
  502. rslv := to_uns (cleanvec(r));
  503. result_slv := lslv * rslv;
  504. result := to_fixed (result_slv, result'high, result'low);
  505. return result;
  506. end function "*";
  507. function "*" (
  508. l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) * sfixed(c downto d) =
  509. return UNRESOLVED_sfixed -- sfixed(a+c+1 downto b+d)
  510. is
  511. variable lslv : UNRESOLVED_SIGNED (l'length-1 downto 0);
  512. variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
  513. variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0);
  514. variable result : UNRESOLVED_sfixed (l'high + r'high+1 downto
  515. mine(l'low, l'low) + mine(r'low, r'low));
  516. begin
  517. if (l'length < 1 or r'length < 1 or
  518. result'length /= result_slv'length) then
  519. return NASF;
  520. end if;
  521. lslv := to_s (cleanvec(l));
  522. rslv := to_s (cleanvec(r));
  523. result_slv := lslv * rslv;
  524. result := to_fixed (result_slv, result'high, result'low);
  525. return result;
  526. end function "*";
  527. function "/" (
  528. l, r : UNRESOLVED_ufixed) -- ufixed(a downto b) / ufixed(c downto d) =
  529. return UNRESOLVED_ufixed is -- ufixed(a-d downto b-c-1)
  530. begin
  531. return divide (l, r);
  532. end function "/";
  533. function "/" (
  534. l, r : UNRESOLVED_sfixed) -- sfixed(a downto b) / sfixed(c downto d) =
  535. return UNRESOLVED_sfixed is -- sfixed(a-d+1 downto b-c)
  536. begin
  537. return divide (l, r);
  538. end function "/";
  539. -- This version of divide gives the user more control
  540. -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
  541. function divide (
  542. l, r : UNRESOLVED_ufixed;
  543. constant round_style : fixed_round_style_type := fixed_round_style;
  544. constant guard_bits : NATURAL := fixed_guard_bits)
  545. return UNRESOLVED_ufixed
  546. is
  547. variable result : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto
  548. mine (l'low, l'low) - r'high -1);
  549. variable dresult : UNRESOLVED_ufixed (result'high downto result'low -guard_bits);
  550. variable lresize : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1);
  551. variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  552. variable rslv : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
  553. variable result_slv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  554. begin
  555. if (l'length < 1 or r'length < 1 or
  556. mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
  557. return NAUF;
  558. end if;
  559. lresize := resize (arg => l,
  560. left_index => lresize'high,
  561. right_index => lresize'low,
  562. overflow_style => fixed_wrap, -- vector only grows
  563. round_style => fixed_truncate);
  564. lslv := to_uns (cleanvec (lresize));
  565. rslv := to_uns (cleanvec (r));
  566. if (rslv = 0) then
  567. report fixed_generic_pkg'instance_name
  568. & "DIVIDE(ufixed) Division by zero" severity error;
  569. result := saturate (result'high, result'low); -- saturate
  570. else
  571. result_slv := lslv / rslv;
  572. dresult := to_fixed (result_slv, dresult'high, dresult'low);
  573. result := resize (arg => dresult,
  574. left_index => result'high,
  575. right_index => result'low,
  576. overflow_style => fixed_wrap, -- overflow impossible
  577. round_style => round_style);
  578. end if;
  579. return result;
  580. end function divide;
  581. -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
  582. function divide (
  583. l, r : UNRESOLVED_sfixed;
  584. constant round_style : fixed_round_style_type := fixed_round_style;
  585. constant guard_bits : NATURAL := fixed_guard_bits)
  586. return UNRESOLVED_sfixed
  587. is
  588. variable result : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto
  589. mine (l'low, l'low) - r'high);
  590. variable dresult : UNRESOLVED_sfixed (result'high downto result'low-guard_bits);
  591. variable lresize : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1);
  592. variable lslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  593. variable rslv : UNRESOLVED_SIGNED (r'length-1 downto 0);
  594. variable result_slv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  595. begin
  596. if (l'length < 1 or r'length < 1 or
  597. mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
  598. return NASF;
  599. end if;
  600. lresize := resize (arg => l,
  601. left_index => lresize'high,
  602. right_index => lresize'low,
  603. overflow_style => fixed_wrap, -- vector only grows
  604. round_style => fixed_truncate);
  605. lslv := to_s (cleanvec (lresize));
  606. rslv := to_s (cleanvec (r));
  607. if (rslv = 0) then
  608. report fixed_generic_pkg'instance_name
  609. & "DIVIDE(sfixed) Division by zero" severity error;
  610. result := saturate (result'high, result'low);
  611. else
  612. result_slv := lslv / rslv;
  613. dresult := to_fixed (result_slv, dresult'high, dresult'low);
  614. result := resize (arg => dresult,
  615. left_index => result'high,
  616. right_index => result'low,
  617. overflow_style => fixed_wrap, -- overflow impossible
  618. round_style => round_style);
  619. end if;
  620. return result;
  621. end function divide;
  622. -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
  623. function reciprocal (
  624. arg : UNRESOLVED_ufixed; -- fixed point input
  625. constant round_style : fixed_round_style_type := fixed_round_style;
  626. constant guard_bits : NATURAL := fixed_guard_bits)
  627. return UNRESOLVED_ufixed
  628. is
  629. constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
  630. begin
  631. return divide (l => one,
  632. r => arg,
  633. round_style => round_style,
  634. guard_bits => guard_bits);
  635. end function reciprocal;
  636. -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
  637. function reciprocal (
  638. arg : UNRESOLVED_sfixed; -- fixed point input
  639. constant round_style : fixed_round_style_type := fixed_round_style;
  640. constant guard_bits : NATURAL := fixed_guard_bits)
  641. return UNRESOLVED_sfixed
  642. is
  643. constant one : UNRESOLVED_sfixed (1 downto 0) := "01"; -- extra bit.
  644. variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
  645. begin
  646. if (arg'length < 1 or resultx'length < 1) then
  647. return NASF;
  648. else
  649. resultx := divide (l => one,
  650. r => arg,
  651. round_style => round_style,
  652. guard_bits => guard_bits);
  653. return resultx (resultx'high-1 downto resultx'low); -- remove extra bit
  654. end if;
  655. end function reciprocal;
  656. -- ufixed (a downto b) rem ufixed (c downto d)
  657. -- = ufixed (min(a,c) downto min(b,d))
  658. function "rem" (
  659. l, r : UNRESOLVED_ufixed) -- fixed point input
  660. return UNRESOLVED_ufixed is
  661. begin
  662. return remainder (l, r);
  663. end function "rem";
  664. -- remainder
  665. -- sfixed (a downto b) rem sfixed (c downto d)
  666. -- = sfixed (min(a,c) downto min(b,d))
  667. function "rem" (
  668. l, r : UNRESOLVED_sfixed) -- fixed point input
  669. return UNRESOLVED_sfixed is
  670. begin
  671. return remainder (l, r);
  672. end function "rem";
  673. -- ufixed (a downto b) rem ufixed (c downto d)
  674. -- = ufixed (min(a,c) downto min(b,d))
  675. function remainder (
  676. l, r : UNRESOLVED_ufixed; -- fixed point input
  677. constant round_style : fixed_round_style_type := fixed_round_style;
  678. constant guard_bits : NATURAL := fixed_guard_bits)
  679. return UNRESOLVED_ufixed
  680. is
  681. variable result : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
  682. mine(l'low, r'low));
  683. variable lresize : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
  684. mins(r'low, r'low)-guard_bits);
  685. variable rresize : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
  686. variable dresult : UNRESOLVED_ufixed (rresize'range);
  687. variable lslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  688. variable rslv : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0);
  689. variable result_slv : UNRESOLVED_UNSIGNED (rslv'range);
  690. begin
  691. if (l'length < 1 or r'length < 1 or
  692. mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
  693. return NAUF;
  694. end if;
  695. lresize := resize (arg => l,
  696. left_index => lresize'high,
  697. right_index => lresize'low,
  698. overflow_style => fixed_wrap, -- vector only grows
  699. round_style => fixed_truncate);
  700. lslv := to_uns (lresize);
  701. rresize := resize (arg => r,
  702. left_index => rresize'high,
  703. right_index => rresize'low,
  704. overflow_style => fixed_wrap, -- vector only grows
  705. round_style => fixed_truncate);
  706. rslv := to_uns (rresize);
  707. if (rslv = 0) then
  708. report fixed_generic_pkg'instance_name
  709. & "remainder(ufixed) Division by zero" severity error;
  710. result := saturate (result'high, result'low); -- saturate
  711. else
  712. if (r'low <= l'high) then
  713. result_slv := lslv rem rslv;
  714. dresult := to_fixed (result_slv, dresult'high, dresult'low);
  715. result := resize (arg => dresult,
  716. left_index => result'high,
  717. right_index => result'low,
  718. overflow_style => fixed_wrap, -- can't overflow
  719. round_style => round_style);
  720. end if;
  721. if l'low < r'low then
  722. result(mins(r'low-1, l'high) downto l'low) :=
  723. cleanvec(l(mins(r'low-1, l'high) downto l'low));
  724. end if;
  725. end if;
  726. return result;
  727. end function remainder;
  728. -- remainder
  729. -- sfixed (a downto b) rem sfixed (c downto d)
  730. -- = sfixed (min(a,c) downto min(b,d))
  731. function remainder (
  732. l, r : UNRESOLVED_sfixed; -- fixed point input
  733. constant round_style : fixed_round_style_type := fixed_round_style;
  734. constant guard_bits : NATURAL := fixed_guard_bits)
  735. return UNRESOLVED_sfixed
  736. is
  737. variable l_abs : UNRESOLVED_ufixed (l'range);
  738. variable r_abs : UNRESOLVED_ufixed (r'range);
  739. variable result : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
  740. mine(r'low, l'low));
  741. variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
  742. mins(r'low, l'low));
  743. begin
  744. if (l'length < 1 or r'length < 1 or
  745. mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
  746. return NASF;
  747. end if;
  748. l_abs := to_ufixed (l);
  749. r_abs := to_ufixed (r);
  750. result := UNRESOLVED_sfixed (remainder (
  751. l => l_abs,
  752. r => r_abs,
  753. round_style => round_style));
  754. neg_result := -result;
  755. if l(l'high) = '1' then
  756. result := neg_result(result'range);
  757. end if;
  758. return result;
  759. end function remainder;
  760. -- modulo
  761. -- ufixed (a downto b) mod ufixed (c downto d)
  762. -- = ufixed (min(a,c) downto min(b, d))
  763. function "mod" (
  764. l, r : UNRESOLVED_ufixed) -- fixed point input
  765. return UNRESOLVED_ufixed is
  766. begin
  767. return modulo (l, r);
  768. end function "mod";
  769. -- sfixed (a downto b) mod sfixed (c downto d)
  770. -- = sfixed (c downto min(b, d))
  771. function "mod" (
  772. l, r : UNRESOLVED_sfixed) -- fixed point input
  773. return UNRESOLVED_sfixed is
  774. begin
  775. return modulo(l, r);
  776. end function "mod";
  777. -- modulo
  778. -- ufixed (a downto b) mod ufixed (c downto d)
  779. -- = ufixed (min(a,c) downto min(b, d))
  780. function modulo (
  781. l, r : UNRESOLVED_ufixed; -- fixed point input
  782. constant round_style : fixed_round_style_type := fixed_round_style;
  783. constant guard_bits : NATURAL := fixed_guard_bits)
  784. return UNRESOLVED_ufixed is
  785. begin
  786. return remainder(l => l,
  787. r => r,
  788. round_style => round_style,
  789. guard_bits => guard_bits);
  790. end function modulo;
  791. -- sfixed (a downto b) mod sfixed (c downto d)
  792. -- = sfixed (c downto min(b, d))
  793. function modulo (
  794. l, r : UNRESOLVED_sfixed; -- fixed point input
  795. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  796. constant round_style : fixed_round_style_type := fixed_round_style;
  797. constant guard_bits : NATURAL := fixed_guard_bits)
  798. return UNRESOLVED_sfixed
  799. is
  800. variable l_abs : UNRESOLVED_ufixed (l'range);
  801. variable r_abs : UNRESOLVED_ufixed (r'range);
  802. variable result : UNRESOLVED_sfixed (r'high downto
  803. mine(r'low, l'low));
  804. variable dresult : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
  805. mins(r'low, l'low));
  806. variable dresult_not_zero : BOOLEAN;
  807. begin
  808. if (l'length < 1 or r'length < 1 or
  809. mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
  810. return NASF;
  811. end if;
  812. l_abs := to_ufixed (l);
  813. r_abs := to_ufixed (r);
  814. dresult := "0" & UNRESOLVED_sfixed(remainder (l => l_abs,
  815. r => r_abs,
  816. round_style => round_style));
  817. if (to_s(dresult) = 0) then
  818. dresult_not_zero := false;
  819. else
  820. dresult_not_zero := true;
  821. end if;
  822. if to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '0'
  823. and dresult_not_zero then
  824. result := resize (arg => r - dresult,
  825. left_index => result'high,
  826. right_index => result'low,
  827. overflow_style => overflow_style,
  828. round_style => round_style);
  829. elsif to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '1' then
  830. result := resize (arg => -dresult,
  831. left_index => result'high,
  832. right_index => result'low,
  833. overflow_style => overflow_style,
  834. round_style => round_style);
  835. elsif to_x01(l(l'high)) = '0' and to_x01(r(r'high)) = '1'
  836. and dresult_not_zero then
  837. result := resize (arg => dresult + r,
  838. left_index => result'high,
  839. right_index => result'low,
  840. overflow_style => overflow_style,
  841. round_style => round_style);
  842. else
  843. result := resize (arg => dresult,
  844. left_index => result'high,
  845. right_index => result'low,
  846. overflow_style => overflow_style,
  847. round_style => round_style);
  848. end if;
  849. return result;
  850. end function modulo;
  851. -- Procedure for those who need an "accumulator" function
  852. procedure add_carry (
  853. L, R : in UNRESOLVED_ufixed;
  854. c_in : in STD_ULOGIC;
  855. result : out UNRESOLVED_ufixed;
  856. c_out : out STD_ULOGIC) is
  857. constant left_index : INTEGER := maximum(L'high, R'high)+1;
  858. constant right_index : INTEGER := mins(L'low, R'low);
  859. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  860. variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
  861. downto 0);
  862. variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
  863. downto 0);
  864. variable cx : UNRESOLVED_UNSIGNED (0 downto 0); -- Carry in
  865. begin
  866. if (L'length < 1 or R'length < 1) then
  867. result := NAUF;
  868. c_out := '0';
  869. else
  870. cx (0) := c_in;
  871. lresize := resize (L, left_index, right_index);
  872. rresize := resize (R, left_index, right_index);
  873. lslv := to_uns (lresize);
  874. rslv := to_uns (rresize);
  875. result_slv := lslv + rslv + cx;
  876. c_out := result_slv(left_index-right_index);
  877. result := to_fixed(result_slv (left_index-right_index-1 downto 0),
  878. left_index-1, right_index);
  879. end if;
  880. end procedure add_carry;
  881. procedure add_carry (
  882. L, R : in UNRESOLVED_sfixed;
  883. c_in : in STD_ULOGIC;
  884. result : out UNRESOLVED_sfixed;
  885. c_out : out STD_ULOGIC) is
  886. constant left_index : INTEGER := maximum(L'high, R'high)+1;
  887. constant right_index : INTEGER := mins(L'low, R'low);
  888. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  889. variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index
  890. downto 0);
  891. variable result_slv : UNRESOLVED_SIGNED (left_index-right_index
  892. downto 0);
  893. variable cx : UNRESOLVED_SIGNED (1 downto 0); -- Carry in
  894. begin
  895. if (L'length < 1 or R'length < 1) then
  896. result := NASF;
  897. c_out := '0';
  898. else
  899. cx (1) := '0';
  900. cx (0) := c_in;
  901. lresize := resize (L, left_index, right_index);
  902. rresize := resize (R, left_index, right_index);
  903. lslv := to_s (lresize);
  904. rslv := to_s (rresize);
  905. result_slv := lslv + rslv + cx;
  906. c_out := result_slv(left_index-right_index);
  907. result := to_fixed(result_slv (left_index-right_index-1 downto 0),
  908. left_index-1, right_index);
  909. end if;
  910. end procedure add_carry;
  911. -- Scales the result by a power of 2. Width of input = width of output with
  912. -- the decimal point moved.
  913. function scalb (y : UNRESOLVED_ufixed; N : INTEGER)
  914. return UNRESOLVED_ufixed
  915. is
  916. variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N);
  917. begin
  918. if y'length < 1 then
  919. return NAUF;
  920. else
  921. result := y;
  922. return result;
  923. end if;
  924. end function scalb;
  925. function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED)
  926. return UNRESOLVED_ufixed is
  927. begin
  928. return scalb (y => y,
  929. N => to_integer(N));
  930. end function scalb;
  931. function scalb (y : UNRESOLVED_sfixed; N : INTEGER)
  932. return UNRESOLVED_sfixed
  933. is
  934. variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N);
  935. begin
  936. if y'length < 1 then
  937. return NASF;
  938. else
  939. result := y;
  940. return result;
  941. end if;
  942. end function scalb;
  943. function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED)
  944. return UNRESOLVED_sfixed is
  945. begin
  946. return scalb (y => y,
  947. N => to_integer(N));
  948. end function scalb;
  949. function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN is
  950. begin
  951. if to_X01(arg(arg'high)) = '1' then
  952. return true;
  953. else
  954. return false;
  955. end if;
  956. end function Is_Negative;
  957. function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
  958. return INTEGER is
  959. begin
  960. for_loop : for i in arg'reverse_range loop
  961. if arg(i) ?= y then
  962. return i;
  963. end if;
  964. end loop;
  965. return arg'high+1; -- return out of bounds 'high
  966. end function find_rightmost;
  967. function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
  968. return INTEGER is
  969. begin
  970. for_loop : for i in arg'range loop
  971. if arg(i) ?= y then
  972. return i;
  973. end if;
  974. end loop;
  975. return arg'low-1; -- return out of bounds 'low
  976. end function find_leftmost;
  977. function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
  978. return INTEGER is
  979. begin
  980. for_loop : for i in arg'reverse_range loop
  981. if arg(i) ?= y then
  982. return i;
  983. end if;
  984. end loop;
  985. return arg'high+1; -- return out of bounds 'high
  986. end function find_rightmost;
  987. function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
  988. return INTEGER is
  989. begin
  990. for_loop : for i in arg'range loop
  991. if arg(i) ?= y then
  992. return i;
  993. end if;
  994. end loop;
  995. return arg'low-1; -- return out of bounds 'low
  996. end function find_leftmost;
  997. function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
  998. return UNRESOLVED_ufixed
  999. is
  1000. variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
  1001. variable result : UNRESOLVED_ufixed (ARG'range);
  1002. begin
  1003. argslv := to_uns (ARG);
  1004. argslv := argslv sll COUNT;
  1005. result := to_fixed (argslv, result'high, result'low);
  1006. return result;
  1007. end function "sll";
  1008. function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
  1009. return UNRESOLVED_ufixed
  1010. is
  1011. variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
  1012. variable result : UNRESOLVED_ufixed (ARG'range);
  1013. begin
  1014. argslv := to_uns (ARG);
  1015. argslv := argslv srl COUNT;
  1016. result := to_fixed (argslv, result'high, result'low);
  1017. return result;
  1018. end function "srl";
  1019. function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
  1020. return UNRESOLVED_ufixed
  1021. is
  1022. variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
  1023. variable result : UNRESOLVED_ufixed (ARG'range);
  1024. begin
  1025. argslv := to_uns (ARG);
  1026. argslv := argslv rol COUNT;
  1027. result := to_fixed (argslv, result'high, result'low);
  1028. return result;
  1029. end function "rol";
  1030. function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
  1031. return UNRESOLVED_ufixed
  1032. is
  1033. variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
  1034. variable result : UNRESOLVED_ufixed (ARG'range);
  1035. begin
  1036. argslv := to_uns (ARG);
  1037. argslv := argslv ror COUNT;
  1038. result := to_fixed (argslv, result'high, result'low);
  1039. return result;
  1040. end function "ror";
  1041. function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
  1042. return UNRESOLVED_ufixed
  1043. is
  1044. variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
  1045. variable result : UNRESOLVED_ufixed (ARG'range);
  1046. begin
  1047. argslv := to_uns (ARG);
  1048. -- Arithmetic shift on an unsigned is a logical shift
  1049. argslv := argslv sll COUNT;
  1050. result := to_fixed (argslv, result'high, result'low);
  1051. return result;
  1052. end function "sla";
  1053. function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
  1054. return UNRESOLVED_ufixed
  1055. is
  1056. variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
  1057. variable result : UNRESOLVED_ufixed (ARG'range);
  1058. begin
  1059. argslv := to_uns (ARG);
  1060. -- Arithmetic shift on an unsigned is a logical shift
  1061. argslv := argslv srl COUNT;
  1062. result := to_fixed (argslv, result'high, result'low);
  1063. return result;
  1064. end function "sra";
  1065. function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
  1066. return UNRESOLVED_sfixed
  1067. is
  1068. variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
  1069. variable result : UNRESOLVED_sfixed (ARG'range);
  1070. begin
  1071. argslv := to_s (ARG);
  1072. argslv := argslv sll COUNT;
  1073. result := to_fixed (argslv, result'high, result'low);
  1074. return result;
  1075. end function "sll";
  1076. function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
  1077. return UNRESOLVED_sfixed
  1078. is
  1079. variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
  1080. variable result : UNRESOLVED_sfixed (ARG'range);
  1081. begin
  1082. argslv := to_s (ARG);
  1083. argslv := argslv srl COUNT;
  1084. result := to_fixed (argslv, result'high, result'low);
  1085. return result;
  1086. end function "srl";
  1087. function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
  1088. return UNRESOLVED_sfixed
  1089. is
  1090. variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
  1091. variable result : UNRESOLVED_sfixed (ARG'range);
  1092. begin
  1093. argslv := to_s (ARG);
  1094. argslv := argslv rol COUNT;
  1095. result := to_fixed (argslv, result'high, result'low);
  1096. return result;
  1097. end function "rol";
  1098. function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
  1099. return UNRESOLVED_sfixed
  1100. is
  1101. variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
  1102. variable result : UNRESOLVED_sfixed (ARG'range);
  1103. begin
  1104. argslv := to_s (ARG);
  1105. argslv := argslv ror COUNT;
  1106. result := to_fixed (argslv, result'high, result'low);
  1107. return result;
  1108. end function "ror";
  1109. function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
  1110. return UNRESOLVED_sfixed
  1111. is
  1112. variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
  1113. variable result : UNRESOLVED_sfixed (ARG'range);
  1114. begin
  1115. argslv := to_s (ARG);
  1116. if COUNT > 0 then
  1117. -- Arithmetic shift left on a 2's complement number is a logic shift
  1118. argslv := argslv sll COUNT;
  1119. else
  1120. argslv := argslv sra -COUNT;
  1121. end if;
  1122. result := to_fixed (argslv, result'high, result'low);
  1123. return result;
  1124. end function "sla";
  1125. function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
  1126. return UNRESOLVED_sfixed
  1127. is
  1128. variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
  1129. variable result : UNRESOLVED_sfixed (ARG'range);
  1130. begin
  1131. argslv := to_s (ARG);
  1132. if COUNT > 0 then
  1133. argslv := argslv sra COUNT;
  1134. else
  1135. -- Arithmetic shift left on a 2's complement number is a logic shift
  1136. argslv := argslv sll -COUNT;
  1137. end if;
  1138. result := to_fixed (argslv, result'high, result'low);
  1139. return result;
  1140. end function "sra";
  1141. -- Because some people want the older functions.
  1142. function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
  1143. return UNRESOLVED_ufixed is
  1144. begin
  1145. if (ARG'length < 1) then
  1146. return NAUF;
  1147. end if;
  1148. return ARG sla COUNT;
  1149. end function SHIFT_LEFT;
  1150. function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
  1151. return UNRESOLVED_ufixed is
  1152. begin
  1153. if (ARG'length < 1) then
  1154. return NAUF;
  1155. end if;
  1156. return ARG sra COUNT;
  1157. end function SHIFT_RIGHT;
  1158. function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
  1159. return UNRESOLVED_sfixed is
  1160. begin
  1161. if (ARG'length < 1) then
  1162. return NASF;
  1163. end if;
  1164. return ARG sla COUNT;
  1165. end function SHIFT_LEFT;
  1166. function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
  1167. return UNRESOLVED_sfixed is
  1168. begin
  1169. if (ARG'length < 1) then
  1170. return NASF;
  1171. end if;
  1172. return ARG sra COUNT;
  1173. end function SHIFT_RIGHT;
  1174. ----------------------------------------------------------------------------
  1175. -- logical functions
  1176. ----------------------------------------------------------------------------
  1177. function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1178. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1179. begin
  1180. RESULT := not to_sulv(L);
  1181. return to_ufixed(RESULT, L'high, L'low);
  1182. end function "not";
  1183. function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1184. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1185. begin
  1186. if (L'high = R'high and L'low = R'low) then
  1187. RESULT := to_sulv(L) and to_sulv(R);
  1188. else
  1189. assert no_warning
  1190. report fixed_generic_pkg'instance_name
  1191. & """and"": Range error L'RANGE /= R'RANGE"
  1192. severity warning;
  1193. RESULT := (others => 'X');
  1194. end if;
  1195. return to_ufixed(RESULT, L'high, L'low);
  1196. end function "and";
  1197. function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1198. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1199. begin
  1200. if (L'high = R'high and L'low = R'low) then
  1201. RESULT := to_sulv(L) or to_sulv(R);
  1202. else
  1203. assert no_warning
  1204. report fixed_generic_pkg'instance_name
  1205. & """or"": Range error L'RANGE /= R'RANGE"
  1206. severity warning;
  1207. RESULT := (others => 'X');
  1208. end if;
  1209. return to_ufixed(RESULT, L'high, L'low);
  1210. end function "or";
  1211. function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1212. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1213. begin
  1214. if (L'high = R'high and L'low = R'low) then
  1215. RESULT := to_sulv(L) nand to_sulv(R);
  1216. else
  1217. assert no_warning
  1218. report fixed_generic_pkg'instance_name
  1219. & """nand"": Range error L'RANGE /= R'RANGE"
  1220. severity warning;
  1221. RESULT := (others => 'X');
  1222. end if;
  1223. return to_ufixed(RESULT, L'high, L'low);
  1224. end function "nand";
  1225. function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1226. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1227. begin
  1228. if (L'high = R'high and L'low = R'low) then
  1229. RESULT := to_sulv(L) nor to_sulv(R);
  1230. else
  1231. assert no_warning
  1232. report fixed_generic_pkg'instance_name
  1233. & """nor"": Range error L'RANGE /= R'RANGE"
  1234. severity warning;
  1235. RESULT := (others => 'X');
  1236. end if;
  1237. return to_ufixed(RESULT, L'high, L'low);
  1238. end function "nor";
  1239. function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1240. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1241. begin
  1242. if (L'high = R'high and L'low = R'low) then
  1243. RESULT := to_sulv(L) xor to_sulv(R);
  1244. else
  1245. assert no_warning
  1246. report fixed_generic_pkg'instance_name
  1247. & """xor"": Range error L'RANGE /= R'RANGE"
  1248. severity warning;
  1249. RESULT := (others => 'X');
  1250. end if;
  1251. return to_ufixed(RESULT, L'high, L'low);
  1252. end function "xor";
  1253. function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  1254. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1255. begin
  1256. if (L'high = R'high and L'low = R'low) then
  1257. RESULT := to_sulv(L) xnor to_sulv(R);
  1258. else
  1259. assert no_warning
  1260. report fixed_generic_pkg'instance_name
  1261. & """xnor"": Range error L'RANGE /= R'RANGE"
  1262. severity warning;
  1263. RESULT := (others => 'X');
  1264. end if;
  1265. return to_ufixed(RESULT, L'high, L'low);
  1266. end function "xnor";
  1267. function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1268. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1269. begin
  1270. RESULT := not to_sulv(L);
  1271. return to_sfixed(RESULT, L'high, L'low);
  1272. end function "not";
  1273. function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1274. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1275. begin
  1276. if (L'high = R'high and L'low = R'low) then
  1277. RESULT := to_sulv(L) and to_sulv(R);
  1278. else
  1279. assert no_warning
  1280. report fixed_generic_pkg'instance_name
  1281. & """and"": Range error L'RANGE /= R'RANGE"
  1282. severity warning;
  1283. RESULT := (others => 'X');
  1284. end if;
  1285. return to_sfixed(RESULT, L'high, L'low);
  1286. end function "and";
  1287. function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1288. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1289. begin
  1290. if (L'high = R'high and L'low = R'low) then
  1291. RESULT := to_sulv(L) or to_sulv(R);
  1292. else
  1293. assert no_warning
  1294. report fixed_generic_pkg'instance_name
  1295. & """or"": Range error L'RANGE /= R'RANGE"
  1296. severity warning;
  1297. RESULT := (others => 'X');
  1298. end if;
  1299. return to_sfixed(RESULT, L'high, L'low);
  1300. end function "or";
  1301. function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1302. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1303. begin
  1304. if (L'high = R'high and L'low = R'low) then
  1305. RESULT := to_sulv(L) nand to_sulv(R);
  1306. else
  1307. assert no_warning
  1308. report fixed_generic_pkg'instance_name
  1309. & """nand"": Range error L'RANGE /= R'RANGE"
  1310. severity warning;
  1311. RESULT := (others => 'X');
  1312. end if;
  1313. return to_sfixed(RESULT, L'high, L'low);
  1314. end function "nand";
  1315. function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1316. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1317. begin
  1318. if (L'high = R'high and L'low = R'low) then
  1319. RESULT := to_sulv(L) nor to_sulv(R);
  1320. else
  1321. assert no_warning
  1322. report fixed_generic_pkg'instance_name
  1323. & """nor"": Range error L'RANGE /= R'RANGE"
  1324. severity warning;
  1325. RESULT := (others => 'X');
  1326. end if;
  1327. return to_sfixed(RESULT, L'high, L'low);
  1328. end function "nor";
  1329. function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1330. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1331. begin
  1332. if (L'high = R'high and L'low = R'low) then
  1333. RESULT := to_sulv(L) xor to_sulv(R);
  1334. else
  1335. assert no_warning
  1336. report fixed_generic_pkg'instance_name
  1337. & """xor"": Range error L'RANGE /= R'RANGE"
  1338. severity warning;
  1339. RESULT := (others => 'X');
  1340. end if;
  1341. return to_sfixed(RESULT, L'high, L'low);
  1342. end function "xor";
  1343. function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  1344. variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0); -- force downto
  1345. begin
  1346. if (L'high = R'high and L'low = R'low) then
  1347. RESULT := to_sulv(L) xnor to_sulv(R);
  1348. else
  1349. assert no_warning
  1350. report fixed_generic_pkg'instance_name
  1351. & """xnor"": Range error L'RANGE /= R'RANGE"
  1352. severity warning;
  1353. RESULT := (others => 'X');
  1354. end if;
  1355. return to_sfixed(RESULT, L'high, L'low);
  1356. end function "xnor";
  1357. -- Vector and std_ulogic functions, same as functions in numeric_std
  1358. function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
  1359. return UNRESOLVED_ufixed
  1360. is
  1361. variable result : UNRESOLVED_ufixed (R'range);
  1362. begin
  1363. for i in result'range loop
  1364. result(i) := L and R(i);
  1365. end loop;
  1366. return result;
  1367. end function "and";
  1368. function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
  1369. return UNRESOLVED_ufixed
  1370. is
  1371. variable result : UNRESOLVED_ufixed (L'range);
  1372. begin
  1373. for i in result'range loop
  1374. result(i) := L(i) and R;
  1375. end loop;
  1376. return result;
  1377. end function "and";
  1378. function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
  1379. return UNRESOLVED_ufixed
  1380. is
  1381. variable result : UNRESOLVED_ufixed (R'range);
  1382. begin
  1383. for i in result'range loop
  1384. result(i) := L or R(i);
  1385. end loop;
  1386. return result;
  1387. end function "or";
  1388. function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
  1389. return UNRESOLVED_ufixed
  1390. is
  1391. variable result : UNRESOLVED_ufixed (L'range);
  1392. begin
  1393. for i in result'range loop
  1394. result(i) := L(i) or R;
  1395. end loop;
  1396. return result;
  1397. end function "or";
  1398. function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
  1399. return UNRESOLVED_ufixed
  1400. is
  1401. variable result : UNRESOLVED_ufixed (R'range);
  1402. begin
  1403. for i in result'range loop
  1404. result(i) := L nand R(i);
  1405. end loop;
  1406. return result;
  1407. end function "nand";
  1408. function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
  1409. return UNRESOLVED_ufixed
  1410. is
  1411. variable result : UNRESOLVED_ufixed (L'range);
  1412. begin
  1413. for i in result'range loop
  1414. result(i) := L(i) nand R;
  1415. end loop;
  1416. return result;
  1417. end function "nand";
  1418. function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
  1419. return UNRESOLVED_ufixed
  1420. is
  1421. variable result : UNRESOLVED_ufixed (R'range);
  1422. begin
  1423. for i in result'range loop
  1424. result(i) := L nor R(i);
  1425. end loop;
  1426. return result;
  1427. end function "nor";
  1428. function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
  1429. return UNRESOLVED_ufixed
  1430. is
  1431. variable result : UNRESOLVED_ufixed (L'range);
  1432. begin
  1433. for i in result'range loop
  1434. result(i) := L(i) nor R;
  1435. end loop;
  1436. return result;
  1437. end function "nor";
  1438. function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
  1439. return UNRESOLVED_ufixed
  1440. is
  1441. variable result : UNRESOLVED_ufixed (R'range);
  1442. begin
  1443. for i in result'range loop
  1444. result(i) := L xor R(i);
  1445. end loop;
  1446. return result;
  1447. end function "xor";
  1448. function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
  1449. return UNRESOLVED_ufixed
  1450. is
  1451. variable result : UNRESOLVED_ufixed (L'range);
  1452. begin
  1453. for i in result'range loop
  1454. result(i) := L(i) xor R;
  1455. end loop;
  1456. return result;
  1457. end function "xor";
  1458. function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
  1459. return UNRESOLVED_ufixed
  1460. is
  1461. variable result : UNRESOLVED_ufixed (R'range);
  1462. begin
  1463. for i in result'range loop
  1464. result(i) := L xnor R(i);
  1465. end loop;
  1466. return result;
  1467. end function "xnor";
  1468. function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
  1469. return UNRESOLVED_ufixed
  1470. is
  1471. variable result : UNRESOLVED_ufixed (L'range);
  1472. begin
  1473. for i in result'range loop
  1474. result(i) := L(i) xnor R;
  1475. end loop;
  1476. return result;
  1477. end function "xnor";
  1478. function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
  1479. return UNRESOLVED_sfixed
  1480. is
  1481. variable result : UNRESOLVED_sfixed (R'range);
  1482. begin
  1483. for i in result'range loop
  1484. result(i) := L and R(i);
  1485. end loop;
  1486. return result;
  1487. end function "and";
  1488. function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
  1489. return UNRESOLVED_sfixed
  1490. is
  1491. variable result : UNRESOLVED_sfixed (L'range);
  1492. begin
  1493. for i in result'range loop
  1494. result(i) := L(i) and R;
  1495. end loop;
  1496. return result;
  1497. end function "and";
  1498. function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
  1499. return UNRESOLVED_sfixed
  1500. is
  1501. variable result : UNRESOLVED_sfixed (R'range);
  1502. begin
  1503. for i in result'range loop
  1504. result(i) := L or R(i);
  1505. end loop;
  1506. return result;
  1507. end function "or";
  1508. function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
  1509. return UNRESOLVED_sfixed
  1510. is
  1511. variable result : UNRESOLVED_sfixed (L'range);
  1512. begin
  1513. for i in result'range loop
  1514. result(i) := L(i) or R;
  1515. end loop;
  1516. return result;
  1517. end function "or";
  1518. function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
  1519. return UNRESOLVED_sfixed
  1520. is
  1521. variable result : UNRESOLVED_sfixed (R'range);
  1522. begin
  1523. for i in result'range loop
  1524. result(i) := L nand R(i);
  1525. end loop;
  1526. return result;
  1527. end function "nand";
  1528. function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
  1529. return UNRESOLVED_sfixed
  1530. is
  1531. variable result : UNRESOLVED_sfixed (L'range);
  1532. begin
  1533. for i in result'range loop
  1534. result(i) := L(i) nand R;
  1535. end loop;
  1536. return result;
  1537. end function "nand";
  1538. function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
  1539. return UNRESOLVED_sfixed
  1540. is
  1541. variable result : UNRESOLVED_sfixed (R'range);
  1542. begin
  1543. for i in result'range loop
  1544. result(i) := L nor R(i);
  1545. end loop;
  1546. return result;
  1547. end function "nor";
  1548. function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
  1549. return UNRESOLVED_sfixed
  1550. is
  1551. variable result : UNRESOLVED_sfixed (L'range);
  1552. begin
  1553. for i in result'range loop
  1554. result(i) := L(i) nor R;
  1555. end loop;
  1556. return result;
  1557. end function "nor";
  1558. function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
  1559. return UNRESOLVED_sfixed
  1560. is
  1561. variable result : UNRESOLVED_sfixed (R'range);
  1562. begin
  1563. for i in result'range loop
  1564. result(i) := L xor R(i);
  1565. end loop;
  1566. return result;
  1567. end function "xor";
  1568. function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
  1569. return UNRESOLVED_sfixed
  1570. is
  1571. variable result : UNRESOLVED_sfixed (L'range);
  1572. begin
  1573. for i in result'range loop
  1574. result(i) := L(i) xor R;
  1575. end loop;
  1576. return result;
  1577. end function "xor";
  1578. function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
  1579. return UNRESOLVED_sfixed
  1580. is
  1581. variable result : UNRESOLVED_sfixed (R'range);
  1582. begin
  1583. for i in result'range loop
  1584. result(i) := L xnor R(i);
  1585. end loop;
  1586. return result;
  1587. end function "xnor";
  1588. function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
  1589. return UNRESOLVED_sfixed
  1590. is
  1591. variable result : UNRESOLVED_sfixed (L'range);
  1592. begin
  1593. for i in result'range loop
  1594. result(i) := L(i) xnor R;
  1595. end loop;
  1596. return result;
  1597. end function "xnor";
  1598. -- Reduction operators
  1599. function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  1600. begin
  1601. return and to_sulv(l);
  1602. end function "and";
  1603. function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  1604. begin
  1605. return nand to_sulv(l);
  1606. end function "nand";
  1607. function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  1608. begin
  1609. return or to_sulv(l);
  1610. end function "or";
  1611. function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  1612. begin
  1613. return nor to_sulv(l);
  1614. end function "nor";
  1615. function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  1616. begin
  1617. return xor to_sulv(l);
  1618. end function "xor";
  1619. function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
  1620. begin
  1621. return xnor to_sulv(l);
  1622. end function "xnor";
  1623. function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  1624. begin
  1625. return and to_sulv(l);
  1626. end function "and";
  1627. function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  1628. begin
  1629. return nand to_sulv(l);
  1630. end function "nand";
  1631. function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  1632. begin
  1633. return or to_sulv(l);
  1634. end function "or";
  1635. function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  1636. begin
  1637. return nor to_sulv(l);
  1638. end function "nor";
  1639. function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  1640. begin
  1641. return xor to_sulv(l);
  1642. end function "xor";
  1643. function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
  1644. begin
  1645. return xnor to_sulv(l);
  1646. end function "xnor";
  1647. -- End reduction operators
  1648. function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
  1649. constant left_index : INTEGER := maximum(L'high, R'high);
  1650. constant right_index : INTEGER := mins(L'low, R'low);
  1651. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1652. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1653. begin -- ?=
  1654. if ((L'length < 1) or (R'length < 1)) then
  1655. assert no_warning
  1656. report fixed_generic_pkg'instance_name
  1657. & """?="": null detected, returning X"
  1658. severity warning;
  1659. return 'X';
  1660. else
  1661. lresize := resize (L, left_index, right_index);
  1662. rresize := resize (R, left_index, right_index);
  1663. lslv := to_uns (lresize);
  1664. rslv := to_uns (rresize);
  1665. return lslv ?= rslv;
  1666. end if;
  1667. end function "?=";
  1668. function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
  1669. constant left_index : INTEGER := maximum(L'high, R'high);
  1670. constant right_index : INTEGER := mins(L'low, R'low);
  1671. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1672. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1673. begin -- ?/=
  1674. if ((L'length < 1) or (R'length < 1)) then
  1675. assert no_warning
  1676. report fixed_generic_pkg'instance_name
  1677. & """?/="": null detected, returning X"
  1678. severity warning;
  1679. return 'X';
  1680. else
  1681. lresize := resize (L, left_index, right_index);
  1682. rresize := resize (R, left_index, right_index);
  1683. lslv := to_uns (lresize);
  1684. rslv := to_uns (rresize);
  1685. return lslv ?/= rslv;
  1686. end if;
  1687. end function "?/=";
  1688. function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
  1689. constant left_index : INTEGER := maximum(L'high, R'high);
  1690. constant right_index : INTEGER := mins(L'low, R'low);
  1691. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1692. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1693. begin -- ?>
  1694. if ((L'length < 1) or (R'length < 1)) then
  1695. assert no_warning
  1696. report fixed_generic_pkg'instance_name
  1697. & """?>"": null detected, returning X"
  1698. severity warning;
  1699. return 'X';
  1700. else
  1701. lresize := resize (L, left_index, right_index);
  1702. rresize := resize (R, left_index, right_index);
  1703. lslv := to_uns (lresize);
  1704. rslv := to_uns (rresize);
  1705. return lslv ?> rslv;
  1706. end if;
  1707. end function "?>";
  1708. function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
  1709. constant left_index : INTEGER := maximum(L'high, R'high);
  1710. constant right_index : INTEGER := mins(L'low, R'low);
  1711. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1712. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1713. begin -- ?>=
  1714. if ((L'length < 1) or (R'length < 1)) then
  1715. assert no_warning
  1716. report fixed_generic_pkg'instance_name
  1717. & """?>="": null detected, returning X"
  1718. severity warning;
  1719. return 'X';
  1720. else
  1721. lresize := resize (L, left_index, right_index);
  1722. rresize := resize (R, left_index, right_index);
  1723. lslv := to_uns (lresize);
  1724. rslv := to_uns (rresize);
  1725. return lslv ?>= rslv;
  1726. end if;
  1727. end function "?>=";
  1728. function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
  1729. constant left_index : INTEGER := maximum(L'high, R'high);
  1730. constant right_index : INTEGER := mins(L'low, R'low);
  1731. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1732. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1733. begin -- ?<
  1734. if ((L'length < 1) or (R'length < 1)) then
  1735. assert no_warning
  1736. report fixed_generic_pkg'instance_name
  1737. & """?<"": null detected, returning X"
  1738. severity warning;
  1739. return 'X';
  1740. else
  1741. lresize := resize (L, left_index, right_index);
  1742. rresize := resize (R, left_index, right_index);
  1743. lslv := to_uns (lresize);
  1744. rslv := to_uns (rresize);
  1745. return lslv ?< rslv;
  1746. end if;
  1747. end function "?<";
  1748. function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
  1749. constant left_index : INTEGER := maximum(L'high, R'high);
  1750. constant right_index : INTEGER := mins(L'low, R'low);
  1751. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1752. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1753. begin -- ?<=
  1754. if ((L'length < 1) or (R'length < 1)) then
  1755. assert no_warning
  1756. report fixed_generic_pkg'instance_name
  1757. & """?<="": null detected, returning X"
  1758. severity warning;
  1759. return 'X';
  1760. else
  1761. lresize := resize (L, left_index, right_index);
  1762. rresize := resize (R, left_index, right_index);
  1763. lslv := to_uns (lresize);
  1764. rslv := to_uns (rresize);
  1765. return lslv ?<= rslv;
  1766. end if;
  1767. end function "?<=";
  1768. function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
  1769. constant left_index : INTEGER := maximum(L'high, R'high);
  1770. constant right_index : INTEGER := mins(L'low, R'low);
  1771. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1772. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1773. begin -- ?=
  1774. if ((L'length < 1) or (R'length < 1)) then
  1775. assert no_warning
  1776. report fixed_generic_pkg'instance_name
  1777. & """?="": null detected, returning X"
  1778. severity warning;
  1779. return 'X';
  1780. else
  1781. lresize := resize (L, left_index, right_index);
  1782. rresize := resize (R, left_index, right_index);
  1783. lslv := to_s (lresize);
  1784. rslv := to_s (rresize);
  1785. return lslv ?= rslv;
  1786. end if;
  1787. end function "?=";
  1788. function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
  1789. constant left_index : INTEGER := maximum(L'high, R'high);
  1790. constant right_index : INTEGER := mins(L'low, R'low);
  1791. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1792. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1793. begin -- ?/=
  1794. if ((L'length < 1) or (R'length < 1)) then
  1795. assert no_warning
  1796. report fixed_generic_pkg'instance_name
  1797. & """?/="": null detected, returning X"
  1798. severity warning;
  1799. return 'X';
  1800. else
  1801. lresize := resize (L, left_index, right_index);
  1802. rresize := resize (R, left_index, right_index);
  1803. lslv := to_s (lresize);
  1804. rslv := to_s (rresize);
  1805. return lslv ?/= rslv;
  1806. end if;
  1807. end function "?/=";
  1808. function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
  1809. constant left_index : INTEGER := maximum(L'high, R'high);
  1810. constant right_index : INTEGER := mins(L'low, R'low);
  1811. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1812. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1813. begin -- ?>
  1814. if ((L'length < 1) or (R'length < 1)) then
  1815. assert no_warning
  1816. report fixed_generic_pkg'instance_name
  1817. & """?>"": null detected, returning X"
  1818. severity warning;
  1819. return 'X';
  1820. else
  1821. lresize := resize (L, left_index, right_index);
  1822. rresize := resize (R, left_index, right_index);
  1823. lslv := to_s (lresize);
  1824. rslv := to_s (rresize);
  1825. return lslv ?> rslv;
  1826. end if;
  1827. end function "?>";
  1828. function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
  1829. constant left_index : INTEGER := maximum(L'high, R'high);
  1830. constant right_index : INTEGER := mins(L'low, R'low);
  1831. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1832. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1833. begin -- ?>=
  1834. if ((L'length < 1) or (R'length < 1)) then
  1835. assert no_warning
  1836. report fixed_generic_pkg'instance_name
  1837. & """?>="": null detected, returning X"
  1838. severity warning;
  1839. return 'X';
  1840. else
  1841. lresize := resize (L, left_index, right_index);
  1842. rresize := resize (R, left_index, right_index);
  1843. lslv := to_s (lresize);
  1844. rslv := to_s (rresize);
  1845. return lslv ?>= rslv;
  1846. end if;
  1847. end function "?>=";
  1848. function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
  1849. constant left_index : INTEGER := maximum(L'high, R'high);
  1850. constant right_index : INTEGER := mins(L'low, R'low);
  1851. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1852. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1853. begin -- ?<
  1854. if ((L'length < 1) or (R'length < 1)) then
  1855. assert no_warning
  1856. report fixed_generic_pkg'instance_name
  1857. & """?<"": null detected, returning X"
  1858. severity warning;
  1859. return 'X';
  1860. else
  1861. lresize := resize (L, left_index, right_index);
  1862. rresize := resize (R, left_index, right_index);
  1863. lslv := to_s (lresize);
  1864. rslv := to_s (rresize);
  1865. return lslv ?< rslv;
  1866. end if;
  1867. end function "?<";
  1868. function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
  1869. constant left_index : INTEGER := maximum(L'high, R'high);
  1870. constant right_index : INTEGER := mins(L'low, R'low);
  1871. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1872. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1873. begin -- ?<=
  1874. if ((L'length < 1) or (R'length < 1)) then
  1875. assert no_warning
  1876. report fixed_generic_pkg'instance_name
  1877. & """?<="": null detected, returning X"
  1878. severity warning;
  1879. return 'X';
  1880. else
  1881. lresize := resize (L, left_index, right_index);
  1882. rresize := resize (R, left_index, right_index);
  1883. lslv := to_s (lresize);
  1884. rslv := to_s (rresize);
  1885. return lslv ?<= rslv;
  1886. end if;
  1887. end function "?<=";
  1888. -- Match function, similar to "std_match" from numeric_std
  1889. function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
  1890. begin
  1891. if (L'high = R'high and L'low = R'low) then
  1892. return std_match(to_sulv(L), to_sulv(R));
  1893. else
  1894. assert no_warning
  1895. report fixed_generic_pkg'instance_name
  1896. & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
  1897. severity warning;
  1898. return false;
  1899. end if;
  1900. end function std_match;
  1901. function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
  1902. begin
  1903. if (L'high = R'high and L'low = R'low) then
  1904. return std_match(to_sulv(L), to_sulv(R));
  1905. else
  1906. assert no_warning
  1907. report fixed_generic_pkg'instance_name
  1908. & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
  1909. severity warning;
  1910. return false;
  1911. end if;
  1912. end function std_match;
  1913. -- compare functions
  1914. function "=" (
  1915. l, r : UNRESOLVED_ufixed) -- fixed point input
  1916. return BOOLEAN
  1917. is
  1918. constant left_index : INTEGER := maximum(l'high, r'high);
  1919. constant right_index : INTEGER := mins(l'low, r'low);
  1920. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1921. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1922. begin
  1923. if (l'length < 1 or r'length < 1) then
  1924. assert no_warning
  1925. report fixed_generic_pkg'instance_name
  1926. & """="": null argument detected, returning FALSE"
  1927. severity warning;
  1928. return false;
  1929. elsif (Is_X(l) or Is_X(r)) then
  1930. assert no_warning
  1931. report fixed_generic_pkg'instance_name
  1932. & """="": metavalue detected, returning FALSE"
  1933. severity warning;
  1934. return false;
  1935. end if;
  1936. lresize := resize (l, left_index, right_index);
  1937. rresize := resize (r, left_index, right_index);
  1938. lslv := to_uns (lresize);
  1939. rslv := to_uns (rresize);
  1940. return lslv = rslv;
  1941. end function "=";
  1942. function "=" (
  1943. l, r : UNRESOLVED_sfixed) -- fixed point input
  1944. return BOOLEAN
  1945. is
  1946. constant left_index : INTEGER := maximum(l'high, r'high);
  1947. constant right_index : INTEGER := mins(l'low, r'low);
  1948. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  1949. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  1950. begin
  1951. if (l'length < 1 or r'length < 1) then
  1952. assert no_warning
  1953. report fixed_generic_pkg'instance_name
  1954. & """="": null argument detected, returning FALSE"
  1955. severity warning;
  1956. return false;
  1957. elsif (Is_X(l) or Is_X(r)) then
  1958. assert no_warning
  1959. report fixed_generic_pkg'instance_name
  1960. & """="": metavalue detected, returning FALSE"
  1961. severity warning;
  1962. return false;
  1963. end if;
  1964. lresize := resize (l, left_index, right_index);
  1965. rresize := resize (r, left_index, right_index);
  1966. lslv := to_s (lresize);
  1967. rslv := to_s (rresize);
  1968. return lslv = rslv;
  1969. end function "=";
  1970. function "/=" (
  1971. l, r : UNRESOLVED_ufixed) -- fixed point input
  1972. return BOOLEAN
  1973. is
  1974. constant left_index : INTEGER := maximum(l'high, r'high);
  1975. constant right_index : INTEGER := mins(l'low, r'low);
  1976. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  1977. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  1978. begin
  1979. if (l'length < 1 or r'length < 1) then
  1980. assert no_warning
  1981. report fixed_generic_pkg'instance_name
  1982. & """/="": null argument detected, returning TRUE"
  1983. severity warning;
  1984. return true;
  1985. elsif (Is_X(l) or Is_X(r)) then
  1986. assert no_warning
  1987. report fixed_generic_pkg'instance_name
  1988. & """/="": metavalue detected, returning TRUE"
  1989. severity warning;
  1990. return true;
  1991. end if;
  1992. lresize := resize (l, left_index, right_index);
  1993. rresize := resize (r, left_index, right_index);
  1994. lslv := to_uns (lresize);
  1995. rslv := to_uns (rresize);
  1996. return lslv /= rslv;
  1997. end function "/=";
  1998. function "/=" (
  1999. l, r : UNRESOLVED_sfixed) -- fixed point input
  2000. return BOOLEAN
  2001. is
  2002. constant left_index : INTEGER := maximum(l'high, r'high);
  2003. constant right_index : INTEGER := mins(l'low, r'low);
  2004. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2005. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  2006. begin
  2007. if (l'length < 1 or r'length < 1) then
  2008. assert no_warning
  2009. report fixed_generic_pkg'instance_name
  2010. & """/="": null argument detected, returning TRUE"
  2011. severity warning;
  2012. return true;
  2013. elsif (Is_X(l) or Is_X(r)) then
  2014. assert no_warning
  2015. report fixed_generic_pkg'instance_name
  2016. & """/="": metavalue detected, returning TRUE"
  2017. severity warning;
  2018. return true;
  2019. end if;
  2020. lresize := resize (l, left_index, right_index);
  2021. rresize := resize (r, left_index, right_index);
  2022. lslv := to_s (lresize);
  2023. rslv := to_s (rresize);
  2024. return lslv /= rslv;
  2025. end function "/=";
  2026. function ">" (
  2027. l, r : UNRESOLVED_ufixed) -- fixed point input
  2028. return BOOLEAN
  2029. is
  2030. constant left_index : INTEGER := maximum(l'high, r'high);
  2031. constant right_index : INTEGER := mins(l'low, r'low);
  2032. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  2033. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  2034. begin
  2035. if (l'length < 1 or r'length < 1) then
  2036. assert no_warning
  2037. report fixed_generic_pkg'instance_name
  2038. & """>"": null argument detected, returning FALSE"
  2039. severity warning;
  2040. return false;
  2041. elsif (Is_X(l) or Is_X(r)) then
  2042. assert no_warning
  2043. report fixed_generic_pkg'instance_name
  2044. & """>"": metavalue detected, returning FALSE"
  2045. severity warning;
  2046. return false;
  2047. end if;
  2048. lresize := resize (l, left_index, right_index);
  2049. rresize := resize (r, left_index, right_index);
  2050. lslv := to_uns (lresize);
  2051. rslv := to_uns (rresize);
  2052. return lslv > rslv;
  2053. end function ">";
  2054. function ">" (
  2055. l, r : UNRESOLVED_sfixed) -- fixed point input
  2056. return BOOLEAN
  2057. is
  2058. constant left_index : INTEGER := maximum(l'high, r'high);
  2059. constant right_index : INTEGER := mins(l'low, r'low);
  2060. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2061. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  2062. begin
  2063. if (l'length < 1 or r'length < 1) then
  2064. assert no_warning
  2065. report fixed_generic_pkg'instance_name
  2066. & """>"": null argument detected, returning FALSE"
  2067. severity warning;
  2068. return false;
  2069. elsif (Is_X(l) or Is_X(r)) then
  2070. assert no_warning
  2071. report fixed_generic_pkg'instance_name
  2072. & """>"": metavalue detected, returning FALSE"
  2073. severity warning;
  2074. return false;
  2075. end if;
  2076. lresize := resize (l, left_index, right_index);
  2077. rresize := resize (r, left_index, right_index);
  2078. lslv := to_s (lresize);
  2079. rslv := to_s (rresize);
  2080. return lslv > rslv;
  2081. end function ">";
  2082. function "<" (
  2083. l, r : UNRESOLVED_ufixed) -- fixed point input
  2084. return BOOLEAN
  2085. is
  2086. constant left_index : INTEGER := maximum(l'high, r'high);
  2087. constant right_index : INTEGER := mins(l'low, r'low);
  2088. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  2089. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  2090. begin
  2091. if (l'length < 1 or r'length < 1) then
  2092. assert no_warning
  2093. report fixed_generic_pkg'instance_name
  2094. & """<"": null argument detected, returning FALSE"
  2095. severity warning;
  2096. return false;
  2097. elsif (Is_X(l) or Is_X(r)) then
  2098. assert no_warning
  2099. report fixed_generic_pkg'instance_name
  2100. & """<"": metavalue detected, returning FALSE"
  2101. severity warning;
  2102. return false;
  2103. end if;
  2104. lresize := resize (l, left_index, right_index);
  2105. rresize := resize (r, left_index, right_index);
  2106. lslv := to_uns (lresize);
  2107. rslv := to_uns (rresize);
  2108. return lslv < rslv;
  2109. end function "<";
  2110. function "<" (
  2111. l, r : UNRESOLVED_sfixed) -- fixed point input
  2112. return BOOLEAN
  2113. is
  2114. constant left_index : INTEGER := maximum(l'high, r'high);
  2115. constant right_index : INTEGER := mins(l'low, r'low);
  2116. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2117. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  2118. begin
  2119. if (l'length < 1 or r'length < 1) then
  2120. assert no_warning
  2121. report fixed_generic_pkg'instance_name
  2122. & """<"": null argument detected, returning FALSE"
  2123. severity warning;
  2124. return false;
  2125. elsif (Is_X(l) or Is_X(r)) then
  2126. assert no_warning
  2127. report fixed_generic_pkg'instance_name
  2128. & """<"": metavalue detected, returning FALSE"
  2129. severity warning;
  2130. return false;
  2131. end if;
  2132. lresize := resize (l, left_index, right_index);
  2133. rresize := resize (r, left_index, right_index);
  2134. lslv := to_s (lresize);
  2135. rslv := to_s (rresize);
  2136. return lslv < rslv;
  2137. end function "<";
  2138. function ">=" (
  2139. l, r : UNRESOLVED_ufixed) -- fixed point input
  2140. return BOOLEAN
  2141. is
  2142. constant left_index : INTEGER := maximum(l'high, r'high);
  2143. constant right_index : INTEGER := mins(l'low, r'low);
  2144. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  2145. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  2146. begin
  2147. if (l'length < 1 or r'length < 1) then
  2148. assert no_warning
  2149. report fixed_generic_pkg'instance_name
  2150. & """>="": null argument detected, returning FALSE"
  2151. severity warning;
  2152. return false;
  2153. elsif (Is_X(l) or Is_X(r)) then
  2154. assert no_warning
  2155. report fixed_generic_pkg'instance_name
  2156. & """>="": metavalue detected, returning FALSE"
  2157. severity warning;
  2158. return false;
  2159. end if;
  2160. lresize := resize (l, left_index, right_index);
  2161. rresize := resize (r, left_index, right_index);
  2162. lslv := to_uns (lresize);
  2163. rslv := to_uns (rresize);
  2164. return lslv >= rslv;
  2165. end function ">=";
  2166. function ">=" (
  2167. l, r : UNRESOLVED_sfixed) -- fixed point input
  2168. return BOOLEAN
  2169. is
  2170. constant left_index : INTEGER := maximum(l'high, r'high);
  2171. constant right_index : INTEGER := mins(l'low, r'low);
  2172. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2173. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  2174. begin
  2175. if (l'length < 1 or r'length < 1) then
  2176. assert no_warning
  2177. report fixed_generic_pkg'instance_name
  2178. & """>="": null argument detected, returning FALSE"
  2179. severity warning;
  2180. return false;
  2181. elsif (Is_X(l) or Is_X(r)) then
  2182. assert no_warning
  2183. report fixed_generic_pkg'instance_name
  2184. & """>="": metavalue detected, returning FALSE"
  2185. severity warning;
  2186. return false;
  2187. end if;
  2188. lresize := resize (l, left_index, right_index);
  2189. rresize := resize (r, left_index, right_index);
  2190. lslv := to_s (lresize);
  2191. rslv := to_s (rresize);
  2192. return lslv >= rslv;
  2193. end function ">=";
  2194. function "<=" (
  2195. l, r : UNRESOLVED_ufixed) -- fixed point input
  2196. return BOOLEAN
  2197. is
  2198. constant left_index : INTEGER := maximum(l'high, r'high);
  2199. constant right_index : INTEGER := mins(l'low, r'low);
  2200. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  2201. variable lslv, rslv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
  2202. begin
  2203. if (l'length < 1 or r'length < 1) then
  2204. assert no_warning
  2205. report fixed_generic_pkg'instance_name
  2206. & """<="": null argument detected, returning FALSE"
  2207. severity warning;
  2208. return false;
  2209. elsif (Is_X(l) or Is_X(r)) then
  2210. assert no_warning
  2211. report fixed_generic_pkg'instance_name
  2212. & """<="": metavalue detected, returning FALSE"
  2213. severity warning;
  2214. return false;
  2215. end if;
  2216. lresize := resize (l, left_index, right_index);
  2217. rresize := resize (r, left_index, right_index);
  2218. lslv := to_uns (lresize);
  2219. rslv := to_uns (rresize);
  2220. return lslv <= rslv;
  2221. end function "<=";
  2222. function "<=" (
  2223. l, r : UNRESOLVED_sfixed) -- fixed point input
  2224. return BOOLEAN
  2225. is
  2226. constant left_index : INTEGER := maximum(l'high, r'high);
  2227. constant right_index : INTEGER := mins(l'low, r'low);
  2228. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2229. variable lslv, rslv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
  2230. begin
  2231. if (l'length < 1 or r'length < 1) then
  2232. assert no_warning
  2233. report fixed_generic_pkg'instance_name
  2234. & """<="": null argument detected, returning FALSE"
  2235. severity warning;
  2236. return false;
  2237. elsif (Is_X(l) or Is_X(r)) then
  2238. assert no_warning
  2239. report fixed_generic_pkg'instance_name
  2240. & """<="": metavalue detected, returning FALSE"
  2241. severity warning;
  2242. return false;
  2243. end if;
  2244. lresize := resize (l, left_index, right_index);
  2245. rresize := resize (r, left_index, right_index);
  2246. lslv := to_s (lresize);
  2247. rslv := to_s (rresize);
  2248. return lslv <= rslv;
  2249. end function "<=";
  2250. -- overloads of the default maximum and minimum functions
  2251. function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  2252. constant left_index : INTEGER := maximum(l'high, r'high);
  2253. constant right_index : INTEGER := mins(l'low, r'low);
  2254. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  2255. begin
  2256. if (l'length < 1 or r'length < 1) then
  2257. return NAUF;
  2258. end if;
  2259. lresize := resize (l, left_index, right_index);
  2260. rresize := resize (r, left_index, right_index);
  2261. return to_fixed(maximum(to_uns(lresize), to_uns(rresize)),
  2262. left_index, right_index);
  2263. end function maximum;
  2264. function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  2265. constant left_index : INTEGER := maximum(l'high, r'high);
  2266. constant right_index : INTEGER := mins(l'low, r'low);
  2267. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2268. begin
  2269. if (l'length < 1 or r'length < 1) then
  2270. return NASF;
  2271. end if;
  2272. lresize := resize (l, left_index, right_index);
  2273. rresize := resize (r, left_index, right_index);
  2274. return to_fixed(maximum(to_s(lresize), to_s(rresize)),
  2275. left_index, right_index);
  2276. end function maximum;
  2277. function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
  2278. constant left_index : INTEGER := maximum(l'high, r'high);
  2279. constant right_index : INTEGER := mins(l'low, r'low);
  2280. variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
  2281. begin
  2282. if (l'length < 1 or r'length < 1) then
  2283. return NAUF;
  2284. end if;
  2285. lresize := resize (l, left_index, right_index);
  2286. rresize := resize (r, left_index, right_index);
  2287. return to_fixed(minimum(to_uns(lresize), to_uns(rresize)),
  2288. left_index, right_index);
  2289. end function minimum;
  2290. function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
  2291. constant left_index : INTEGER := maximum(l'high, r'high);
  2292. constant right_index : INTEGER := mins(l'low, r'low);
  2293. variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
  2294. begin
  2295. if (l'length < 1 or r'length < 1) then
  2296. return NASF;
  2297. end if;
  2298. lresize := resize (l, left_index, right_index);
  2299. rresize := resize (r, left_index, right_index);
  2300. return to_fixed(minimum(to_s(lresize), to_s(rresize)),
  2301. left_index, right_index);
  2302. end function minimum;
  2303. function to_ufixed (
  2304. arg : NATURAL; -- integer
  2305. constant left_index : INTEGER; -- left index (high index)
  2306. constant right_index : INTEGER := 0; -- right index
  2307. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2308. constant round_style : fixed_round_style_type := fixed_round_style)
  2309. return UNRESOLVED_ufixed
  2310. is
  2311. constant fw : INTEGER := mins (right_index, right_index); -- catch literals
  2312. variable result : UNRESOLVED_ufixed (left_index downto fw);
  2313. variable sresult : UNRESOLVED_ufixed (left_index downto 0) :=
  2314. (others => '0'); -- integer portion
  2315. variable argx : NATURAL; -- internal version of arg
  2316. begin
  2317. if (result'length < 1) then
  2318. return NAUF;
  2319. end if;
  2320. if arg /= 0 then
  2321. argx := arg;
  2322. for I in 0 to sresult'left loop
  2323. if (argx mod 2) = 0 then
  2324. sresult(I) := '0';
  2325. else
  2326. sresult(I) := '1';
  2327. end if;
  2328. argx := argx/2;
  2329. end loop;
  2330. if argx /= 0 then
  2331. assert no_warning
  2332. report fixed_generic_pkg'instance_name
  2333. & "TO_UFIXED(NATURAL): vector truncated"
  2334. severity warning;
  2335. if overflow_style = fixed_saturate then
  2336. return saturate (left_index, right_index);
  2337. end if;
  2338. end if;
  2339. result := resize (arg => sresult,
  2340. left_index => left_index,
  2341. right_index => right_index,
  2342. round_style => round_style,
  2343. overflow_style => overflow_style);
  2344. else
  2345. result := (others => '0');
  2346. end if;
  2347. return result;
  2348. end function to_ufixed;
  2349. function to_sfixed (
  2350. arg : INTEGER; -- integer
  2351. constant left_index : INTEGER; -- left index (high index)
  2352. constant right_index : INTEGER := 0; -- right index
  2353. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2354. constant round_style : fixed_round_style_type := fixed_round_style)
  2355. return UNRESOLVED_sfixed
  2356. is
  2357. constant fw : INTEGER := mins (right_index, right_index); -- catch literals
  2358. variable result : UNRESOLVED_sfixed (left_index downto fw);
  2359. variable sresult : UNRESOLVED_sfixed (left_index downto 0) :=
  2360. (others => '0'); -- integer portion
  2361. variable argx : INTEGER; -- internal version of arg
  2362. variable sign : STD_ULOGIC; -- sign of input
  2363. begin
  2364. if (result'length < 1) then -- null range
  2365. return NASF;
  2366. end if;
  2367. if arg /= 0 then
  2368. if (arg < 0) then
  2369. sign := '1';
  2370. argx := -(arg + 1);
  2371. else
  2372. sign := '0';
  2373. argx := arg;
  2374. end if;
  2375. for I in 0 to sresult'left loop
  2376. if (argx mod 2) = 0 then
  2377. sresult(I) := sign;
  2378. else
  2379. sresult(I) := not sign;
  2380. end if;
  2381. argx := argx/2;
  2382. end loop;
  2383. if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then
  2384. assert no_warning
  2385. report fixed_generic_pkg'instance_name
  2386. & "TO_SFIXED(INTEGER): vector truncated"
  2387. severity warning;
  2388. if overflow_style = fixed_saturate then -- saturate
  2389. if arg < 0 then
  2390. result := not saturate (result'high, result'low); -- underflow
  2391. else
  2392. result := saturate (result'high, result'low); -- overflow
  2393. end if;
  2394. return result;
  2395. end if;
  2396. end if;
  2397. result := resize (arg => sresult,
  2398. left_index => left_index,
  2399. right_index => right_index,
  2400. round_style => round_style,
  2401. overflow_style => overflow_style);
  2402. else
  2403. result := (others => '0');
  2404. end if;
  2405. return result;
  2406. end function to_sfixed;
  2407. function to_ufixed (
  2408. arg : REAL; -- real
  2409. constant left_index : INTEGER; -- left index (high index)
  2410. constant right_index : INTEGER; -- right index
  2411. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2412. constant round_style : fixed_round_style_type := fixed_round_style;
  2413. constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
  2414. return UNRESOLVED_ufixed
  2415. is
  2416. constant fw : INTEGER := mins (right_index, right_index); -- catch literals
  2417. variable result : UNRESOLVED_ufixed (left_index downto fw) :=
  2418. (others => '0');
  2419. variable Xresult : UNRESOLVED_ufixed (left_index downto
  2420. fw-guard_bits) :=
  2421. (others => '0');
  2422. variable presult : REAL;
  2423. begin
  2424. -- If negative or null range, return.
  2425. if (left_index < fw) then
  2426. return NAUF;
  2427. end if;
  2428. if (arg < 0.0) then
  2429. report fixed_generic_pkg'instance_name
  2430. & "TO_UFIXED: Negative argument passed "
  2431. & REAL'image(arg) severity error;
  2432. return result;
  2433. end if;
  2434. presult := arg;
  2435. if presult >= (2.0**(left_index+1)) then
  2436. assert no_warning report fixed_generic_pkg'instance_name
  2437. & "TO_UFIXED(REAL): vector truncated"
  2438. severity warning;
  2439. if overflow_style = fixed_wrap then
  2440. presult := presult mod (2.0**(left_index+1)); -- wrap
  2441. else
  2442. return saturate (result'high, result'low);
  2443. end if;
  2444. end if;
  2445. for i in Xresult'range loop
  2446. if presult >= 2.0**i then
  2447. Xresult(i) := '1';
  2448. presult := presult - 2.0**i;
  2449. else
  2450. Xresult(i) := '0';
  2451. end if;
  2452. end loop;
  2453. if guard_bits > 0 and round_style = fixed_round then
  2454. result := round_fixed (arg => Xresult (left_index
  2455. downto right_index),
  2456. remainder => Xresult (right_index-1 downto
  2457. right_index-guard_bits),
  2458. overflow_style => overflow_style);
  2459. else
  2460. result := Xresult (result'range);
  2461. end if;
  2462. return result;
  2463. end function to_ufixed;
  2464. function to_sfixed (
  2465. arg : REAL; -- real
  2466. constant left_index : INTEGER; -- left index (high index)
  2467. constant right_index : INTEGER; -- right index
  2468. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2469. constant round_style : fixed_round_style_type := fixed_round_style;
  2470. constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
  2471. return UNRESOLVED_sfixed
  2472. is
  2473. constant fw : INTEGER := mins (right_index, right_index); -- catch literals
  2474. variable result : UNRESOLVED_sfixed (left_index downto fw) :=
  2475. (others => '0');
  2476. variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) :=
  2477. (others => '0');
  2478. variable presult : REAL;
  2479. begin
  2480. if (left_index < fw) then -- null range
  2481. return NASF;
  2482. end if;
  2483. if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then
  2484. assert no_warning report fixed_generic_pkg'instance_name
  2485. & "TO_SFIXED(REAL): vector truncated"
  2486. severity warning;
  2487. if overflow_style = fixed_saturate then
  2488. if arg < 0.0 then -- saturate
  2489. result := not saturate (result'high, result'low); -- underflow
  2490. else
  2491. result := saturate (result'high, result'low); -- overflow
  2492. end if;
  2493. return result;
  2494. else
  2495. presult := abs(arg) mod (2.0**(left_index+1)); -- wrap
  2496. end if;
  2497. else
  2498. presult := abs(arg);
  2499. end if;
  2500. for i in Xresult'range loop
  2501. if presult >= 2.0**i then
  2502. Xresult(i) := '1';
  2503. presult := presult - 2.0**i;
  2504. else
  2505. Xresult(i) := '0';
  2506. end if;
  2507. end loop;
  2508. if arg < 0.0 then
  2509. Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low);
  2510. end if;
  2511. if guard_bits > 0 and round_style = fixed_round then
  2512. result := round_fixed (arg => Xresult (left_index
  2513. downto right_index),
  2514. remainder => Xresult (right_index-1 downto
  2515. right_index-guard_bits),
  2516. overflow_style => overflow_style);
  2517. else
  2518. result := Xresult (result'range);
  2519. end if;
  2520. return result;
  2521. end function to_sfixed;
  2522. function to_ufixed (
  2523. arg : UNRESOLVED_UNSIGNED; -- unsigned
  2524. constant left_index : INTEGER; -- left index (high index)
  2525. constant right_index : INTEGER := 0; -- right index
  2526. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2527. constant round_style : fixed_round_style_type := fixed_round_style)
  2528. return UNRESOLVED_ufixed
  2529. is
  2530. constant ARG_LEFT : INTEGER := arg'length-1;
  2531. alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
  2532. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  2533. begin
  2534. if arg'length < 1 or (left_index < right_index) then
  2535. return NAUF;
  2536. end if;
  2537. result := resize (arg => UNRESOLVED_ufixed (XARG),
  2538. left_index => left_index,
  2539. right_index => right_index,
  2540. round_style => round_style,
  2541. overflow_style => overflow_style);
  2542. return result;
  2543. end function to_ufixed;
  2544. -- converted version
  2545. function to_ufixed (
  2546. arg : UNRESOLVED_UNSIGNED) -- unsigned
  2547. return UNRESOLVED_ufixed
  2548. is
  2549. constant ARG_LEFT : INTEGER := arg'length-1;
  2550. alias XARG : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
  2551. begin
  2552. if arg'length < 1 then
  2553. return NAUF;
  2554. end if;
  2555. return UNRESOLVED_ufixed(XARG);
  2556. end function to_ufixed;
  2557. function to_sfixed (
  2558. arg : UNRESOLVED_SIGNED; -- signed
  2559. constant left_index : INTEGER; -- left index (high index)
  2560. constant right_index : INTEGER := 0; -- right index
  2561. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2562. constant round_style : fixed_round_style_type := fixed_round_style)
  2563. return UNRESOLVED_sfixed
  2564. is
  2565. constant ARG_LEFT : INTEGER := arg'length-1;
  2566. alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
  2567. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  2568. begin
  2569. if arg'length < 1 or (left_index < right_index) then
  2570. return NASF;
  2571. end if;
  2572. result := resize (arg => UNRESOLVED_sfixed (XARG),
  2573. left_index => left_index,
  2574. right_index => right_index,
  2575. round_style => round_style,
  2576. overflow_style => overflow_style);
  2577. return result;
  2578. end function to_sfixed;
  2579. -- converted version
  2580. function to_sfixed (
  2581. arg : UNRESOLVED_SIGNED) -- signed
  2582. return UNRESOLVED_sfixed
  2583. is
  2584. constant ARG_LEFT : INTEGER := arg'length-1;
  2585. alias XARG : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
  2586. begin
  2587. if arg'length < 1 then
  2588. return NASF;
  2589. end if;
  2590. return UNRESOLVED_sfixed(XARG);
  2591. end function to_sfixed;
  2592. function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is
  2593. variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low);
  2594. begin
  2595. if arg'length < 1 then
  2596. return NASF;
  2597. end if;
  2598. result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg));
  2599. result (arg'high+1) := '0';
  2600. return result;
  2601. end function to_sfixed;
  2602. -- Because of the fairly complicated sizing rules in the fixed point
  2603. -- packages these functions are provided to compute the result ranges
  2604. -- Example:
  2605. -- signal uf1 : ufixed (3 downto -3);
  2606. -- signal uf2 : ufixed (4 downto -2);
  2607. -- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto
  2608. -- ufixed_low (3, -3, '*', 4, -2));
  2609. -- uf1multuf2 <= uf1 * uf2;
  2610. -- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod),
  2611. -- '1' (reciprocal), 'A', 'a' (abs), 'N', 'n' (-sfixed)
  2612. function ufixed_high (left_index, right_index : INTEGER;
  2613. operation : CHARACTER := 'X';
  2614. left_index2, right_index2 : INTEGER := 0)
  2615. return INTEGER is
  2616. begin
  2617. case operation is
  2618. when '+'| '-' => return maximum (left_index, left_index2) + 1;
  2619. when '*' => return left_index + left_index2 + 1;
  2620. when '/' => return left_index - right_index2;
  2621. when '1' => return -right_index; -- reciprocal
  2622. when 'R'|'r' => return mins (left_index, left_index2); -- "rem"
  2623. when 'M'|'m' => return mins (left_index, left_index2); -- "mod"
  2624. when others => return left_index; -- For abs and default
  2625. end case;
  2626. end function ufixed_high;
  2627. function ufixed_low (left_index, right_index : INTEGER;
  2628. operation : CHARACTER := 'X';
  2629. left_index2, right_index2 : INTEGER := 0)
  2630. return INTEGER is
  2631. begin
  2632. case operation is
  2633. when '+'| '-' => return mins (right_index, right_index2);
  2634. when '*' => return right_index + right_index2;
  2635. when '/' => return right_index - left_index2 - 1;
  2636. when '1' => return -left_index - 1; -- reciprocal
  2637. when 'R'|'r' => return mins (right_index, right_index2); -- "rem"
  2638. when 'M'|'m' => return mins (right_index, right_index2); -- "mod"
  2639. when others => return right_index; -- for abs and default
  2640. end case;
  2641. end function ufixed_low;
  2642. function sfixed_high (left_index, right_index : INTEGER;
  2643. operation : CHARACTER := 'X';
  2644. left_index2, right_index2 : INTEGER := 0)
  2645. return INTEGER is
  2646. begin
  2647. case operation is
  2648. when '+'| '-' => return maximum (left_index, left_index2) + 1;
  2649. when '*' => return left_index + left_index2 + 1;
  2650. when '/' => return left_index - right_index2 + 1;
  2651. when '1' => return -right_index + 1; -- reciprocal
  2652. when 'R'|'r' => return mins (left_index, left_index2); -- "rem"
  2653. when 'M'|'m' => return left_index2; -- "mod"
  2654. when 'A'|'a' => return left_index + 1; -- "abs"
  2655. when 'N'|'n' => return left_index + 1; -- -sfixed
  2656. when others => return left_index;
  2657. end case;
  2658. end function sfixed_high;
  2659. function sfixed_low (left_index, right_index : INTEGER;
  2660. operation : CHARACTER := 'X';
  2661. left_index2, right_index2 : INTEGER := 0)
  2662. return INTEGER is
  2663. begin
  2664. case operation is
  2665. when '+'| '-' => return mins (right_index, right_index2);
  2666. when '*' => return right_index + right_index2;
  2667. when '/' => return right_index - left_index2;
  2668. when '1' => return -left_index; -- reciprocal
  2669. when 'R'|'r' => return mins (right_index, right_index2); -- "rem"
  2670. when 'M'|'m' => return mins (right_index, right_index2); -- "mod"
  2671. when others => return right_index; -- default for abs, neg and default
  2672. end case;
  2673. end function sfixed_low;
  2674. -- Same as above, but using the "size_res" input only for their ranges:
  2675. -- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto
  2676. -- ufixed_low (uf1, '*', uf2));
  2677. -- uf1multuf2 <= uf1 * uf2;
  2678. function ufixed_high (size_res : UNRESOLVED_ufixed;
  2679. operation : CHARACTER := 'X';
  2680. size_res2 : UNRESOLVED_ufixed)
  2681. return INTEGER is
  2682. begin
  2683. return ufixed_high (left_index => size_res'high,
  2684. right_index => size_res'low,
  2685. operation => operation,
  2686. left_index2 => size_res2'high,
  2687. right_index2 => size_res2'low);
  2688. end function ufixed_high;
  2689. function ufixed_low (size_res : UNRESOLVED_ufixed;
  2690. operation : CHARACTER := 'X';
  2691. size_res2 : UNRESOLVED_ufixed)
  2692. return INTEGER is
  2693. begin
  2694. return ufixed_low (left_index => size_res'high,
  2695. right_index => size_res'low,
  2696. operation => operation,
  2697. left_index2 => size_res2'high,
  2698. right_index2 => size_res2'low);
  2699. end function ufixed_low;
  2700. function sfixed_high (size_res : UNRESOLVED_sfixed;
  2701. operation : CHARACTER := 'X';
  2702. size_res2 : UNRESOLVED_sfixed)
  2703. return INTEGER is
  2704. begin
  2705. return sfixed_high (left_index => size_res'high,
  2706. right_index => size_res'low,
  2707. operation => operation,
  2708. left_index2 => size_res2'high,
  2709. right_index2 => size_res2'low);
  2710. end function sfixed_high;
  2711. function sfixed_low (size_res : UNRESOLVED_sfixed;
  2712. operation : CHARACTER := 'X';
  2713. size_res2 : UNRESOLVED_sfixed)
  2714. return INTEGER is
  2715. begin
  2716. return sfixed_low (left_index => size_res'high,
  2717. right_index => size_res'low,
  2718. operation => operation,
  2719. left_index2 => size_res2'high,
  2720. right_index2 => size_res2'low);
  2721. end function sfixed_low;
  2722. -- purpose: returns a saturated number
  2723. function saturate (
  2724. constant left_index : INTEGER;
  2725. constant right_index : INTEGER)
  2726. return UNRESOLVED_ufixed
  2727. is
  2728. constant sat : UNRESOLVED_ufixed (left_index downto right_index) :=
  2729. (others => '1');
  2730. begin
  2731. return sat;
  2732. end function saturate;
  2733. -- purpose: returns a saturated number
  2734. function saturate (
  2735. constant left_index : INTEGER;
  2736. constant right_index : INTEGER)
  2737. return UNRESOLVED_sfixed
  2738. is
  2739. variable sat : UNRESOLVED_sfixed (left_index downto right_index) :=
  2740. (others => '1');
  2741. begin
  2742. -- saturate positive, to saturate negative, just do "not saturate()"
  2743. sat (left_index) := '0';
  2744. return sat;
  2745. end function saturate;
  2746. function saturate (
  2747. size_res : UNRESOLVED_ufixed) -- only the size of this is used
  2748. return UNRESOLVED_ufixed is
  2749. begin
  2750. return saturate (size_res'high, size_res'low);
  2751. end function saturate;
  2752. function saturate (
  2753. size_res : UNRESOLVED_sfixed) -- only the size of this is used
  2754. return UNRESOLVED_sfixed is
  2755. begin
  2756. return saturate (size_res'high, size_res'low);
  2757. end function saturate;
  2758. -- As a concession to those who use a graphical DSP environment,
  2759. -- these functions take parameters in those tools format and create
  2760. -- fixed point numbers. These functions are designed to convert from
  2761. -- a std_logic_vector to the VHDL fixed point format using the conventions
  2762. -- of these packages. In a pure VHDL environment you should use the
  2763. -- "to_ufixed" and "to_sfixed" routines.
  2764. -- Unsigned fixed point
  2765. function to_UFix (
  2766. arg : STD_ULOGIC_VECTOR;
  2767. width : NATURAL; -- width of vector
  2768. fraction : NATURAL) -- width of fraction
  2769. return UNRESOLVED_ufixed
  2770. is
  2771. variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction);
  2772. begin
  2773. if (arg'length /= result'length) then
  2774. report fixed_generic_pkg'instance_name
  2775. & "TO_UFIX (STD_ULOGIC_VECTOR) "
  2776. & "Vector lengths do not match. Input length is "
  2777. & INTEGER'image(arg'length) & " and output will be "
  2778. & INTEGER'image(result'length) & " wide."
  2779. severity error;
  2780. return NAUF;
  2781. else
  2782. result := to_ufixed (arg, result'high, result'low);
  2783. return result;
  2784. end if;
  2785. end function to_UFix;
  2786. -- signed fixed point
  2787. function to_SFix (
  2788. arg : STD_ULOGIC_VECTOR;
  2789. width : NATURAL; -- width of vector
  2790. fraction : NATURAL) -- width of fraction
  2791. return UNRESOLVED_sfixed
  2792. is
  2793. variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction);
  2794. begin
  2795. if (arg'length /= result'length) then
  2796. report fixed_generic_pkg'instance_name
  2797. & "TO_SFIX (STD_ULOGIC_VECTOR) "
  2798. & "Vector lengths do not match. Input length is "
  2799. & INTEGER'image(arg'length) & " and output will be "
  2800. & INTEGER'image(result'length) & " wide."
  2801. severity error;
  2802. return NASF;
  2803. else
  2804. result := to_sfixed (arg, result'high, result'low);
  2805. return result;
  2806. end if;
  2807. end function to_SFix;
  2808. -- finding the bounds of a number. These functions can be used like this:
  2809. -- signal xxx : ufixed (7 downto -3);
  2810. -- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))"
  2811. -- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3)
  2812. -- downto UFix_low(11, 3, "+", 11, 3));
  2813. -- Where "11" is the width of xxx (xxx'length),
  2814. -- and 3 is the lower bound (abs (xxx'low))
  2815. -- In a pure VHDL environment use "ufixed_high" and "ufixed_low"
  2816. function ufix_high (
  2817. width, fraction : NATURAL;
  2818. operation : CHARACTER := 'X';
  2819. width2, fraction2 : NATURAL := 0)
  2820. return INTEGER is
  2821. begin
  2822. return ufixed_high (left_index => width - 1 - fraction,
  2823. right_index => -fraction,
  2824. operation => operation,
  2825. left_index2 => width2 - 1 - fraction2,
  2826. right_index2 => -fraction2);
  2827. end function ufix_high;
  2828. function ufix_low (
  2829. width, fraction : NATURAL;
  2830. operation : CHARACTER := 'X';
  2831. width2, fraction2 : NATURAL := 0)
  2832. return INTEGER is
  2833. begin
  2834. return ufixed_low (left_index => width - 1 - fraction,
  2835. right_index => -fraction,
  2836. operation => operation,
  2837. left_index2 => width2 - 1 - fraction2,
  2838. right_index2 => -fraction2);
  2839. end function ufix_low;
  2840. function sfix_high (
  2841. width, fraction : NATURAL;
  2842. operation : CHARACTER := 'X';
  2843. width2, fraction2 : NATURAL := 0)
  2844. return INTEGER is
  2845. begin
  2846. return sfixed_high (left_index => width - fraction,
  2847. right_index => -fraction,
  2848. operation => operation,
  2849. left_index2 => width2 - fraction2,
  2850. right_index2 => -fraction2);
  2851. end function sfix_high;
  2852. function sfix_low (
  2853. width, fraction : NATURAL;
  2854. operation : CHARACTER := 'X';
  2855. width2, fraction2 : NATURAL := 0)
  2856. return INTEGER is
  2857. begin
  2858. return sfixed_low (left_index => width - fraction,
  2859. right_index => -fraction,
  2860. operation => operation,
  2861. left_index2 => width2 - fraction2,
  2862. right_index2 => -fraction2);
  2863. end function sfix_low;
  2864. function to_unsigned (
  2865. arg : UNRESOLVED_ufixed; -- ufixed point input
  2866. constant size : NATURAL; -- length of output
  2867. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2868. constant round_style : fixed_round_style_type := fixed_round_style)
  2869. return UNRESOLVED_UNSIGNED is
  2870. begin
  2871. return to_uns(resize (arg => arg,
  2872. left_index => size-1,
  2873. right_index => 0,
  2874. round_style => round_style,
  2875. overflow_style => overflow_style));
  2876. end function to_unsigned;
  2877. function to_unsigned (
  2878. arg : UNRESOLVED_ufixed; -- ufixed point input
  2879. size_res : UNRESOLVED_UNSIGNED; -- length of output
  2880. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2881. constant round_style : fixed_round_style_type := fixed_round_style)
  2882. return UNRESOLVED_UNSIGNED is
  2883. begin
  2884. return to_unsigned (arg => arg,
  2885. size => size_res'length,
  2886. round_style => round_style,
  2887. overflow_style => overflow_style);
  2888. end function to_unsigned;
  2889. function to_signed (
  2890. arg : UNRESOLVED_sfixed; -- sfixed point input
  2891. constant size : NATURAL; -- length of output
  2892. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2893. constant round_style : fixed_round_style_type := fixed_round_style)
  2894. return UNRESOLVED_SIGNED is
  2895. begin
  2896. return to_s(resize (arg => arg,
  2897. left_index => size-1,
  2898. right_index => 0,
  2899. round_style => round_style,
  2900. overflow_style => overflow_style));
  2901. end function to_signed;
  2902. function to_signed (
  2903. arg : UNRESOLVED_sfixed; -- sfixed point input
  2904. size_res : UNRESOLVED_SIGNED; -- used for length of output
  2905. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2906. constant round_style : fixed_round_style_type := fixed_round_style)
  2907. return UNRESOLVED_SIGNED is
  2908. begin
  2909. return to_signed (arg => arg,
  2910. size => size_res'length,
  2911. round_style => round_style,
  2912. overflow_style => overflow_style);
  2913. end function to_signed;
  2914. function to_real (
  2915. arg : UNRESOLVED_ufixed) -- ufixed point input
  2916. return REAL
  2917. is
  2918. constant left_index : INTEGER := arg'high;
  2919. constant right_index : INTEGER := arg'low;
  2920. variable result : REAL; -- result
  2921. variable arg_int : UNRESOLVED_ufixed (left_index downto right_index);
  2922. begin
  2923. if (arg'length < 1) then
  2924. return 0.0;
  2925. end if;
  2926. arg_int := To_X01(cleanvec(arg));
  2927. if (Is_X(arg_int)) then
  2928. assert no_warning
  2929. report fixed_generic_pkg'instance_name
  2930. & "TO_REAL (ufixed): metavalue detected, returning 0.0"
  2931. severity warning;
  2932. return 0.0;
  2933. end if;
  2934. result := 0.0;
  2935. for i in arg_int'range loop
  2936. if (arg_int(i) = '1') then
  2937. result := result + (2.0**i);
  2938. end if;
  2939. end loop;
  2940. return result;
  2941. end function to_real;
  2942. function to_real (
  2943. arg : UNRESOLVED_sfixed) -- ufixed point input
  2944. return REAL
  2945. is
  2946. constant left_index : INTEGER := arg'high;
  2947. constant right_index : INTEGER := arg'low;
  2948. variable result : REAL; -- result
  2949. variable arg_int : UNRESOLVED_sfixed (left_index downto right_index);
  2950. -- unsigned version of argument
  2951. variable arg_uns : UNRESOLVED_ufixed (left_index downto right_index);
  2952. -- absolute of argument
  2953. begin
  2954. if (arg'length < 1) then
  2955. return 0.0;
  2956. end if;
  2957. arg_int := to_X01(cleanvec(arg));
  2958. if (Is_X(arg_int)) then
  2959. assert no_warning
  2960. report fixed_generic_pkg'instance_name
  2961. & "TO_REAL (sfixed): metavalue detected, returning 0.0"
  2962. severity warning;
  2963. return 0.0;
  2964. end if;
  2965. arg_uns := to_ufixed (arg_int);
  2966. result := to_real (arg_uns);
  2967. if (arg_int(arg_int'high) = '1') then
  2968. result := -result;
  2969. end if;
  2970. return result;
  2971. end function to_real;
  2972. function to_integer (
  2973. arg : UNRESOLVED_ufixed; -- fixed point input
  2974. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  2975. constant round_style : fixed_round_style_type := fixed_round_style)
  2976. return NATURAL
  2977. is
  2978. constant left_index : INTEGER := arg'high;
  2979. variable arg_uns : UNRESOLVED_UNSIGNED (left_index+1 downto 0)
  2980. := (others => '0');
  2981. begin
  2982. if (arg'length < 1) then
  2983. return 0;
  2984. end if;
  2985. if (Is_X (arg)) then
  2986. assert no_warning
  2987. report fixed_generic_pkg'instance_name
  2988. & "TO_INTEGER (ufixed): metavalue detected, returning 0"
  2989. severity warning;
  2990. return 0;
  2991. end if;
  2992. if (left_index < -1) then
  2993. return 0;
  2994. end if;
  2995. arg_uns := to_uns(resize (arg => arg,
  2996. left_index => arg_uns'high,
  2997. right_index => 0,
  2998. round_style => round_style,
  2999. overflow_style => overflow_style));
  3000. return to_integer (arg_uns);
  3001. end function to_integer;
  3002. function to_integer (
  3003. arg : UNRESOLVED_sfixed; -- fixed point input
  3004. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3005. constant round_style : fixed_round_style_type := fixed_round_style)
  3006. return INTEGER
  3007. is
  3008. constant left_index : INTEGER := arg'high;
  3009. variable arg_s : UNRESOLVED_SIGNED (left_index+1 downto 0);
  3010. begin
  3011. if (arg'length < 1) then
  3012. return 0;
  3013. end if;
  3014. if (Is_X (arg)) then
  3015. assert no_warning
  3016. report fixed_generic_pkg'instance_name
  3017. & "TO_INTEGER (sfixed): metavalue detected, returning 0"
  3018. severity warning;
  3019. return 0;
  3020. end if;
  3021. if (left_index < -1) then
  3022. return 0;
  3023. end if;
  3024. arg_s := to_s(resize (arg => arg,
  3025. left_index => arg_s'high,
  3026. right_index => 0,
  3027. round_style => round_style,
  3028. overflow_style => overflow_style));
  3029. return to_integer (arg_s);
  3030. end function to_integer;
  3031. function to_01 (
  3032. s : UNRESOLVED_ufixed; -- ufixed point input
  3033. constant XMAP : STD_ULOGIC := '0') -- Map x to
  3034. return UNRESOLVED_ufixed
  3035. is
  3036. begin
  3037. if (s'length < 1) then
  3038. assert no_warning
  3039. report fixed_generic_pkg'instance_name
  3040. & "TO_01(ufixed): null detected, returning NULL"
  3041. severity warning;
  3042. return NAUF;
  3043. end if;
  3044. return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
  3045. end function to_01;
  3046. function to_01 (
  3047. s : UNRESOLVED_sfixed; -- sfixed point input
  3048. constant XMAP : STD_ULOGIC := '0') -- Map x to
  3049. return UNRESOLVED_sfixed
  3050. is
  3051. begin
  3052. if (s'length < 1) then
  3053. assert no_warning
  3054. report fixed_generic_pkg'instance_name
  3055. & "TO_01(sfixed): null detected, returning NULL"
  3056. severity warning;
  3057. return NASF;
  3058. end if;
  3059. return to_fixed (to_01(to_s(s), XMAP), s'high, s'low);
  3060. end function to_01;
  3061. function Is_X (
  3062. arg : UNRESOLVED_ufixed)
  3063. return BOOLEAN
  3064. is
  3065. variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv
  3066. begin
  3067. argslv := to_sulv(arg);
  3068. return Is_X (argslv);
  3069. end function Is_X;
  3070. function Is_X (
  3071. arg : UNRESOLVED_sfixed)
  3072. return BOOLEAN
  3073. is
  3074. variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0); -- slv
  3075. begin
  3076. argslv := to_sulv(arg);
  3077. return Is_X (argslv);
  3078. end function Is_X;
  3079. function To_X01 (
  3080. arg : UNRESOLVED_ufixed)
  3081. return UNRESOLVED_ufixed is
  3082. begin
  3083. return to_ufixed (To_X01(to_sulv(arg)), arg'high, arg'low);
  3084. end function To_X01;
  3085. function to_X01 (
  3086. arg : UNRESOLVED_sfixed)
  3087. return UNRESOLVED_sfixed is
  3088. begin
  3089. return to_sfixed (To_X01(to_sulv(arg)), arg'high, arg'low);
  3090. end function to_X01;
  3091. function To_X01Z (
  3092. arg : UNRESOLVED_ufixed)
  3093. return UNRESOLVED_ufixed is
  3094. begin
  3095. return to_ufixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
  3096. end function To_X01Z;
  3097. function to_X01Z (
  3098. arg : UNRESOLVED_sfixed)
  3099. return UNRESOLVED_sfixed is
  3100. begin
  3101. return to_sfixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
  3102. end function to_X01Z;
  3103. function To_UX01 (
  3104. arg : UNRESOLVED_ufixed)
  3105. return UNRESOLVED_ufixed is
  3106. begin
  3107. return to_ufixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
  3108. end function To_UX01;
  3109. function to_UX01 (
  3110. arg : UNRESOLVED_sfixed)
  3111. return UNRESOLVED_sfixed is
  3112. begin
  3113. return to_sfixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
  3114. end function to_UX01;
  3115. function resize (
  3116. arg : UNRESOLVED_ufixed; -- input
  3117. constant left_index : INTEGER; -- integer portion
  3118. constant right_index : INTEGER; -- size of fraction
  3119. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3120. constant round_style : fixed_round_style_type := fixed_round_style)
  3121. return UNRESOLVED_ufixed
  3122. is
  3123. constant arghigh : INTEGER := maximum (arg'high, arg'low);
  3124. constant arglow : INTEGER := mine (arg'high, arg'low);
  3125. variable invec : UNRESOLVED_ufixed (arghigh downto arglow);
  3126. variable result : UNRESOLVED_ufixed(left_index downto right_index) :=
  3127. (others => '0');
  3128. variable needs_rounding : BOOLEAN := false;
  3129. begin -- resize
  3130. if (arg'length < 1) or (result'length < 1) then
  3131. return NAUF;
  3132. elsif (invec'length < 1) then
  3133. return result; -- string literal value
  3134. else
  3135. invec := cleanvec(arg);
  3136. if (right_index > arghigh) then -- return top zeros
  3137. needs_rounding := (round_style = fixed_round) and
  3138. (right_index = arghigh+1);
  3139. elsif (left_index < arglow) then -- return overflow
  3140. if (overflow_style = fixed_saturate) and
  3141. (or(to_sulv(invec)) = '1') then
  3142. result := saturate (result'high, result'low); -- saturate
  3143. end if;
  3144. elsif (arghigh > left_index) then
  3145. -- wrap or saturate?
  3146. if (overflow_style = fixed_saturate and
  3147. or (to_sulv(invec(arghigh downto left_index+1))) = '1')
  3148. then
  3149. result := saturate (result'high, result'low); -- saturate
  3150. else
  3151. if (arglow >= right_index) then
  3152. result (left_index downto arglow) :=
  3153. invec(left_index downto arglow);
  3154. else
  3155. result (left_index downto right_index) :=
  3156. invec (left_index downto right_index);
  3157. needs_rounding := (round_style = fixed_round); -- round
  3158. end if;
  3159. end if;
  3160. else -- arghigh <= integer width
  3161. if (arglow >= right_index) then
  3162. result (arghigh downto arglow) := invec;
  3163. else
  3164. result (arghigh downto right_index) :=
  3165. invec (arghigh downto right_index);
  3166. needs_rounding := (round_style = fixed_round); -- round
  3167. end if;
  3168. end if;
  3169. -- Round result
  3170. if needs_rounding then
  3171. result := round_fixed (arg => result,
  3172. remainder => invec (right_index-1
  3173. downto arglow),
  3174. overflow_style => overflow_style);
  3175. end if;
  3176. return result;
  3177. end if;
  3178. end function resize;
  3179. function resize (
  3180. arg : UNRESOLVED_sfixed; -- input
  3181. constant left_index : INTEGER; -- integer portion
  3182. constant right_index : INTEGER; -- size of fraction
  3183. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3184. constant round_style : fixed_round_style_type := fixed_round_style)
  3185. return UNRESOLVED_sfixed
  3186. is
  3187. constant arghigh : INTEGER := maximum (arg'high, arg'low);
  3188. constant arglow : INTEGER := mine (arg'high, arg'low);
  3189. variable invec : UNRESOLVED_sfixed (arghigh downto arglow);
  3190. variable result : UNRESOLVED_sfixed(left_index downto right_index) :=
  3191. (others => '0');
  3192. variable reduced : STD_ULOGIC;
  3193. variable needs_rounding : BOOLEAN := false; -- rounding
  3194. begin -- resize
  3195. if (arg'length < 1) or (result'length < 1) then
  3196. return NASF;
  3197. elsif (invec'length < 1) then
  3198. return result; -- string literal value
  3199. else
  3200. invec := cleanvec(arg);
  3201. if (right_index > arghigh) then -- return top zeros
  3202. if (arg'low /= INTEGER'low) then -- check for a literal
  3203. result := (others => arg(arghigh)); -- sign extend
  3204. end if;
  3205. needs_rounding := (round_style = fixed_round) and
  3206. (right_index = arghigh+1);
  3207. elsif (left_index < arglow) then -- return overflow
  3208. if (overflow_style = fixed_saturate) then
  3209. reduced := or (to_sulv(invec));
  3210. if (reduced = '1') then
  3211. if (invec(arghigh) = '0') then
  3212. -- saturate POSITIVE
  3213. result := saturate (result'high, result'low);
  3214. else
  3215. -- saturate negative
  3216. result := not saturate (result'high, result'low);
  3217. end if;
  3218. -- else return 0 (input was 0)
  3219. end if;
  3220. -- else return 0 (wrap)
  3221. end if;
  3222. elsif (arghigh > left_index) then
  3223. if (invec(arghigh) = '0') then
  3224. reduced := or (to_sulv(invec(arghigh-1 downto
  3225. left_index)));
  3226. if overflow_style = fixed_saturate and reduced = '1' then
  3227. -- saturate positive
  3228. result := saturate (result'high, result'low);
  3229. else
  3230. if (right_index > arglow) then
  3231. result := invec (left_index downto right_index);
  3232. needs_rounding := (round_style = fixed_round);
  3233. else
  3234. result (left_index downto arglow) :=
  3235. invec (left_index downto arglow);
  3236. end if;
  3237. end if;
  3238. else
  3239. reduced := and (to_sulv(invec(arghigh-1 downto
  3240. left_index)));
  3241. if overflow_style = fixed_saturate and reduced = '0' then
  3242. result := not saturate (result'high, result'low);
  3243. else
  3244. if (right_index > arglow) then
  3245. result := invec (left_index downto right_index);
  3246. needs_rounding := (round_style = fixed_round);
  3247. else
  3248. result (left_index downto arglow) :=
  3249. invec (left_index downto arglow);
  3250. end if;
  3251. end if;
  3252. end if;
  3253. else -- arghigh <= integer width
  3254. if (arglow >= right_index) then
  3255. result (arghigh downto arglow) := invec;
  3256. else
  3257. result (arghigh downto right_index) :=
  3258. invec (arghigh downto right_index);
  3259. needs_rounding := (round_style = fixed_round); -- round
  3260. end if;
  3261. if (left_index > arghigh) then -- sign extend
  3262. result(left_index downto arghigh+1) := (others => invec(arghigh));
  3263. end if;
  3264. end if;
  3265. -- Round result
  3266. if (needs_rounding) then
  3267. result := round_fixed (arg => result,
  3268. remainder => invec (right_index-1
  3269. downto arglow),
  3270. overflow_style => overflow_style);
  3271. end if;
  3272. return result;
  3273. end if;
  3274. end function resize;
  3275. -- size_res functions
  3276. -- These functions compute the size from a passed variable named "size_res"
  3277. -- The only part of this variable used it it's size, it is never passed
  3278. -- to a lower level routine.
  3279. function to_ufixed (
  3280. arg : STD_ULOGIC_VECTOR; -- shifted vector
  3281. size_res : UNRESOLVED_ufixed) -- for size only
  3282. return UNRESOLVED_ufixed
  3283. is
  3284. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3285. variable result : UNRESOLVED_ufixed (size_res'left downto fw);
  3286. begin
  3287. if (result'length < 1 or arg'length < 1) then
  3288. return NAUF;
  3289. else
  3290. result := to_ufixed (arg => arg,
  3291. left_index => size_res'high,
  3292. right_index => size_res'low);
  3293. return result;
  3294. end if;
  3295. end function to_ufixed;
  3296. function to_sfixed (
  3297. arg : STD_ULOGIC_VECTOR; -- shifted vector
  3298. size_res : UNRESOLVED_sfixed) -- for size only
  3299. return UNRESOLVED_sfixed
  3300. is
  3301. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3302. variable result : UNRESOLVED_sfixed (size_res'left downto fw);
  3303. begin
  3304. if (result'length < 1 or arg'length < 1) then
  3305. return NASF;
  3306. else
  3307. result := to_sfixed (arg => arg,
  3308. left_index => size_res'high,
  3309. right_index => size_res'low);
  3310. return result;
  3311. end if;
  3312. end function to_sfixed;
  3313. function to_ufixed (
  3314. arg : NATURAL; -- integer
  3315. size_res : UNRESOLVED_ufixed; -- for size only
  3316. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3317. constant round_style : fixed_round_style_type := fixed_round_style)
  3318. return UNRESOLVED_ufixed
  3319. is
  3320. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3321. variable result : UNRESOLVED_ufixed (size_res'left downto fw);
  3322. begin
  3323. if (result'length < 1) then
  3324. return NAUF;
  3325. else
  3326. result := to_ufixed (arg => arg,
  3327. left_index => size_res'high,
  3328. right_index => size_res'low,
  3329. round_style => round_style,
  3330. overflow_style => overflow_style);
  3331. return result;
  3332. end if;
  3333. end function to_ufixed;
  3334. function to_sfixed (
  3335. arg : INTEGER; -- integer
  3336. size_res : UNRESOLVED_sfixed; -- for size only
  3337. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3338. constant round_style : fixed_round_style_type := fixed_round_style)
  3339. return UNRESOLVED_sfixed
  3340. is
  3341. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3342. variable result : UNRESOLVED_sfixed (size_res'left downto fw);
  3343. begin
  3344. if (result'length < 1) then
  3345. return NASF;
  3346. else
  3347. result := to_sfixed (arg => arg,
  3348. left_index => size_res'high,
  3349. right_index => size_res'low,
  3350. round_style => round_style,
  3351. overflow_style => overflow_style);
  3352. return result;
  3353. end if;
  3354. end function to_sfixed;
  3355. function to_ufixed (
  3356. arg : REAL; -- real
  3357. size_res : UNRESOLVED_ufixed; -- for size only
  3358. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3359. constant round_style : fixed_round_style_type := fixed_round_style;
  3360. constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
  3361. return UNRESOLVED_ufixed
  3362. is
  3363. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3364. variable result : UNRESOLVED_ufixed (size_res'left downto fw);
  3365. begin
  3366. if (result'length < 1) then
  3367. return NAUF;
  3368. else
  3369. result := to_ufixed (arg => arg,
  3370. left_index => size_res'high,
  3371. right_index => size_res'low,
  3372. guard_bits => guard_bits,
  3373. round_style => round_style,
  3374. overflow_style => overflow_style);
  3375. return result;
  3376. end if;
  3377. end function to_ufixed;
  3378. function to_sfixed (
  3379. arg : REAL; -- real
  3380. size_res : UNRESOLVED_sfixed; -- for size only
  3381. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3382. constant round_style : fixed_round_style_type := fixed_round_style;
  3383. constant guard_bits : NATURAL := fixed_guard_bits) -- # of guard bits
  3384. return UNRESOLVED_sfixed
  3385. is
  3386. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3387. variable result : UNRESOLVED_sfixed (size_res'left downto fw);
  3388. begin
  3389. if (result'length < 1) then
  3390. return NASF;
  3391. else
  3392. result := to_sfixed (arg => arg,
  3393. left_index => size_res'high,
  3394. right_index => size_res'low,
  3395. guard_bits => guard_bits,
  3396. round_style => round_style,
  3397. overflow_style => overflow_style);
  3398. return result;
  3399. end if;
  3400. end function to_sfixed;
  3401. function to_ufixed (
  3402. arg : UNRESOLVED_UNSIGNED; -- unsigned
  3403. size_res : UNRESOLVED_ufixed; -- for size only
  3404. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3405. constant round_style : fixed_round_style_type := fixed_round_style)
  3406. return UNRESOLVED_ufixed
  3407. is
  3408. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3409. variable result : UNRESOLVED_ufixed (size_res'left downto fw);
  3410. begin
  3411. if (result'length < 1 or arg'length < 1) then
  3412. return NAUF;
  3413. else
  3414. result := to_ufixed (arg => arg,
  3415. left_index => size_res'high,
  3416. right_index => size_res'low,
  3417. round_style => round_style,
  3418. overflow_style => overflow_style);
  3419. return result;
  3420. end if;
  3421. end function to_ufixed;
  3422. function to_sfixed (
  3423. arg : UNRESOLVED_SIGNED; -- signed
  3424. size_res : UNRESOLVED_sfixed; -- for size only
  3425. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3426. constant round_style : fixed_round_style_type := fixed_round_style)
  3427. return UNRESOLVED_sfixed
  3428. is
  3429. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3430. variable result : UNRESOLVED_sfixed (size_res'left downto fw);
  3431. begin
  3432. if (result'length < 1 or arg'length < 1) then
  3433. return NASF;
  3434. else
  3435. result := to_sfixed (arg => arg,
  3436. left_index => size_res'high,
  3437. right_index => size_res'low,
  3438. round_style => round_style,
  3439. overflow_style => overflow_style);
  3440. return result;
  3441. end if;
  3442. end function to_sfixed;
  3443. function resize (
  3444. arg : UNRESOLVED_ufixed; -- input
  3445. size_res : UNRESOLVED_ufixed; -- for size only
  3446. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3447. constant round_style : fixed_round_style_type := fixed_round_style)
  3448. return UNRESOLVED_ufixed
  3449. is
  3450. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3451. variable result : UNRESOLVED_ufixed (size_res'high downto fw);
  3452. begin
  3453. if (result'length < 1 or arg'length < 1) then
  3454. return NAUF;
  3455. else
  3456. result := resize (arg => arg,
  3457. left_index => size_res'high,
  3458. right_index => size_res'low,
  3459. round_style => round_style,
  3460. overflow_style => overflow_style);
  3461. return result;
  3462. end if;
  3463. end function resize;
  3464. function resize (
  3465. arg : UNRESOLVED_sfixed; -- input
  3466. size_res : UNRESOLVED_sfixed; -- for size only
  3467. constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
  3468. constant round_style : fixed_round_style_type := fixed_round_style)
  3469. return UNRESOLVED_sfixed
  3470. is
  3471. constant fw : INTEGER := mine (size_res'low, size_res'low); -- catch literals
  3472. variable result : UNRESOLVED_sfixed (size_res'high downto fw);
  3473. begin
  3474. if (result'length < 1 or arg'length < 1) then
  3475. return NASF;
  3476. else
  3477. result := resize (arg => arg,
  3478. left_index => size_res'high,
  3479. right_index => size_res'low,
  3480. round_style => round_style,
  3481. overflow_style => overflow_style);
  3482. return result;
  3483. end if;
  3484. end function resize;
  3485. -- Overloaded math functions for real
  3486. function "+" (
  3487. l : UNRESOLVED_ufixed; -- fixed point input
  3488. r : REAL)
  3489. return UNRESOLVED_ufixed is
  3490. begin
  3491. return (l + to_ufixed (r, l'high, l'low));
  3492. end function "+";
  3493. function "+" (
  3494. l : REAL;
  3495. r : UNRESOLVED_ufixed) -- fixed point input
  3496. return UNRESOLVED_ufixed is
  3497. begin
  3498. return (to_ufixed (l, r'high, r'low) + r);
  3499. end function "+";
  3500. function "+" (
  3501. l : UNRESOLVED_sfixed; -- fixed point input
  3502. r : REAL)
  3503. return UNRESOLVED_sfixed is
  3504. begin
  3505. return (l + to_sfixed (r, l'high, l'low));
  3506. end function "+";
  3507. function "+" (
  3508. l : REAL;
  3509. r : UNRESOLVED_sfixed) -- fixed point input
  3510. return UNRESOLVED_sfixed is
  3511. begin
  3512. return (to_sfixed (l, r'high, r'low) + r);
  3513. end function "+";
  3514. function "-" (
  3515. l : UNRESOLVED_ufixed; -- fixed point input
  3516. r : REAL)
  3517. return UNRESOLVED_ufixed is
  3518. begin
  3519. return (l - to_ufixed (r, l'high, l'low));
  3520. end function "-";
  3521. function "-" (
  3522. l : REAL;
  3523. r : UNRESOLVED_ufixed) -- fixed point input
  3524. return UNRESOLVED_ufixed is
  3525. begin
  3526. return (to_ufixed (l, r'high, r'low) - r);
  3527. end function "-";
  3528. function "-" (
  3529. l : UNRESOLVED_sfixed; -- fixed point input
  3530. r : REAL)
  3531. return UNRESOLVED_sfixed is
  3532. begin
  3533. return (l - to_sfixed (r, l'high, l'low));
  3534. end function "-";
  3535. function "-" (
  3536. l : REAL;
  3537. r : UNRESOLVED_sfixed) -- fixed point input
  3538. return UNRESOLVED_sfixed is
  3539. begin
  3540. return (to_sfixed (l, r'high, r'low) - r);
  3541. end function "-";
  3542. function "*" (
  3543. l : UNRESOLVED_ufixed; -- fixed point input
  3544. r : REAL)
  3545. return UNRESOLVED_ufixed is
  3546. begin
  3547. return (l * to_ufixed (r, l'high, l'low));
  3548. end function "*";
  3549. function "*" (
  3550. l : REAL;
  3551. r : UNRESOLVED_ufixed) -- fixed point input
  3552. return UNRESOLVED_ufixed is
  3553. begin
  3554. return (to_ufixed (l, r'high, r'low) * r);
  3555. end function "*";
  3556. function "*" (
  3557. l : UNRESOLVED_sfixed; -- fixed point input
  3558. r : REAL)
  3559. return UNRESOLVED_sfixed is
  3560. begin
  3561. return (l * to_sfixed (r, l'high, l'low));
  3562. end function "*";
  3563. function "*" (
  3564. l : REAL;
  3565. r : UNRESOLVED_sfixed) -- fixed point input
  3566. return UNRESOLVED_sfixed is
  3567. begin
  3568. return (to_sfixed (l, r'high, r'low) * r);
  3569. end function "*";
  3570. function "/" (
  3571. l : UNRESOLVED_ufixed; -- fixed point input
  3572. r : REAL)
  3573. return UNRESOLVED_ufixed is
  3574. begin
  3575. return (l / to_ufixed (r, l'high, l'low));
  3576. end function "/";
  3577. function "/" (
  3578. l : REAL;
  3579. r : UNRESOLVED_ufixed) -- fixed point input
  3580. return UNRESOLVED_ufixed is
  3581. begin
  3582. return (to_ufixed (l, r'high, r'low) / r);
  3583. end function "/";
  3584. function "/" (
  3585. l : UNRESOLVED_sfixed; -- fixed point input
  3586. r : REAL)
  3587. return UNRESOLVED_sfixed is
  3588. begin
  3589. return (l / to_sfixed (r, l'high, l'low));
  3590. end function "/";
  3591. function "/" (
  3592. l : REAL;
  3593. r : UNRESOLVED_sfixed) -- fixed point input
  3594. return UNRESOLVED_sfixed is
  3595. begin
  3596. return (to_sfixed (l, r'high, r'low) / r);
  3597. end function "/";
  3598. function "rem" (
  3599. l : UNRESOLVED_ufixed; -- fixed point input
  3600. r : REAL)
  3601. return UNRESOLVED_ufixed is
  3602. begin
  3603. return (l rem to_ufixed (r, l'high, l'low));
  3604. end function "rem";
  3605. function "rem" (
  3606. l : REAL;
  3607. r : UNRESOLVED_ufixed) -- fixed point input
  3608. return UNRESOLVED_ufixed is
  3609. begin
  3610. return (to_ufixed (l, r'high, r'low) rem r);
  3611. end function "rem";
  3612. function "rem" (
  3613. l : UNRESOLVED_sfixed; -- fixed point input
  3614. r : REAL)
  3615. return UNRESOLVED_sfixed is
  3616. begin
  3617. return (l rem to_sfixed (r, l'high, l'low));
  3618. end function "rem";
  3619. function "rem" (
  3620. l : REAL;
  3621. r : UNRESOLVED_sfixed) -- fixed point input
  3622. return UNRESOLVED_sfixed is
  3623. begin
  3624. return (to_sfixed (l, r'high, r'low) rem r);
  3625. end function "rem";
  3626. function "mod" (
  3627. l : UNRESOLVED_ufixed; -- fixed point input
  3628. r : REAL)
  3629. return UNRESOLVED_ufixed is
  3630. begin
  3631. return (l mod to_ufixed (r, l'high, l'low));
  3632. end function "mod";
  3633. function "mod" (
  3634. l : REAL;
  3635. r : UNRESOLVED_ufixed) -- fixed point input
  3636. return UNRESOLVED_ufixed is
  3637. begin
  3638. return (to_ufixed (l, r'high, r'low) mod r);
  3639. end function "mod";
  3640. function "mod" (
  3641. l : UNRESOLVED_sfixed; -- fixed point input
  3642. r : REAL)
  3643. return UNRESOLVED_sfixed is
  3644. begin
  3645. return (l mod to_sfixed (r, l'high, l'low));
  3646. end function "mod";
  3647. function "mod" (
  3648. l : REAL;
  3649. r : UNRESOLVED_sfixed) -- fixed point input
  3650. return UNRESOLVED_sfixed is
  3651. begin
  3652. return (to_sfixed (l, r'high, r'low) mod r);
  3653. end function "mod";
  3654. -- Overloaded math functions for integers
  3655. function "+" (
  3656. l : UNRESOLVED_ufixed; -- fixed point input
  3657. r : NATURAL)
  3658. return UNRESOLVED_ufixed is
  3659. begin
  3660. return (l + to_ufixed (r, l'high, 0));
  3661. end function "+";
  3662. function "+" (
  3663. l : NATURAL;
  3664. r : UNRESOLVED_ufixed) -- fixed point input
  3665. return UNRESOLVED_ufixed is
  3666. begin
  3667. return (to_ufixed (l, r'high, 0) + r);
  3668. end function "+";
  3669. function "+" (
  3670. l : UNRESOLVED_sfixed; -- fixed point input
  3671. r : INTEGER)
  3672. return UNRESOLVED_sfixed is
  3673. begin
  3674. return (l + to_sfixed (r, l'high, 0));
  3675. end function "+";
  3676. function "+" (
  3677. l : INTEGER;
  3678. r : UNRESOLVED_sfixed) -- fixed point input
  3679. return UNRESOLVED_sfixed is
  3680. begin
  3681. return (to_sfixed (l, r'high, 0) + r);
  3682. end function "+";
  3683. -- Overloaded functions
  3684. function "-" (
  3685. l : UNRESOLVED_ufixed; -- fixed point input
  3686. r : NATURAL)
  3687. return UNRESOLVED_ufixed is
  3688. begin
  3689. return (l - to_ufixed (r, l'high, 0));
  3690. end function "-";
  3691. function "-" (
  3692. l : NATURAL;
  3693. r : UNRESOLVED_ufixed) -- fixed point input
  3694. return UNRESOLVED_ufixed is
  3695. begin
  3696. return (to_ufixed (l, r'high, 0) - r);
  3697. end function "-";
  3698. function "-" (
  3699. l : UNRESOLVED_sfixed; -- fixed point input
  3700. r : INTEGER)
  3701. return UNRESOLVED_sfixed is
  3702. begin
  3703. return (l - to_sfixed (r, l'high, 0));
  3704. end function "-";
  3705. function "-" (
  3706. l : INTEGER;
  3707. r : UNRESOLVED_sfixed) -- fixed point input
  3708. return UNRESOLVED_sfixed is
  3709. begin
  3710. return (to_sfixed (l, r'high, 0) - r);
  3711. end function "-";
  3712. -- Overloaded functions
  3713. function "*" (
  3714. l : UNRESOLVED_ufixed; -- fixed point input
  3715. r : NATURAL)
  3716. return UNRESOLVED_ufixed is
  3717. begin
  3718. return (l * to_ufixed (r, l'high, 0));
  3719. end function "*";
  3720. function "*" (
  3721. l : NATURAL;
  3722. r : UNRESOLVED_ufixed) -- fixed point input
  3723. return UNRESOLVED_ufixed is
  3724. begin
  3725. return (to_ufixed (l, r'high, 0) * r);
  3726. end function "*";
  3727. function "*" (
  3728. l : UNRESOLVED_sfixed; -- fixed point input
  3729. r : INTEGER)
  3730. return UNRESOLVED_sfixed is
  3731. begin
  3732. return (l * to_sfixed (r, l'high, 0));
  3733. end function "*";
  3734. function "*" (
  3735. l : INTEGER;
  3736. r : UNRESOLVED_sfixed) -- fixed point input
  3737. return UNRESOLVED_sfixed is
  3738. begin
  3739. return (to_sfixed (l, r'high, 0) * r);
  3740. end function "*";
  3741. -- Overloaded functions
  3742. function "/" (
  3743. l : UNRESOLVED_ufixed; -- fixed point input
  3744. r : NATURAL)
  3745. return UNRESOLVED_ufixed is
  3746. begin
  3747. return (l / to_ufixed (r, l'high, 0));
  3748. end function "/";
  3749. function "/" (
  3750. l : NATURAL;
  3751. r : UNRESOLVED_ufixed) -- fixed point input
  3752. return UNRESOLVED_ufixed is
  3753. begin
  3754. return (to_ufixed (l, r'high, 0) / r);
  3755. end function "/";
  3756. function "/" (
  3757. l : UNRESOLVED_sfixed; -- fixed point input
  3758. r : INTEGER)
  3759. return UNRESOLVED_sfixed is
  3760. begin
  3761. return (l / to_sfixed (r, l'high, 0));
  3762. end function "/";
  3763. function "/" (
  3764. l : INTEGER;
  3765. r : UNRESOLVED_sfixed) -- fixed point input
  3766. return UNRESOLVED_sfixed is
  3767. begin
  3768. return (to_sfixed (l, r'high, 0) / r);
  3769. end function "/";
  3770. function "rem" (
  3771. l : UNRESOLVED_ufixed; -- fixed point input
  3772. r : NATURAL)
  3773. return UNRESOLVED_ufixed is
  3774. begin
  3775. return (l rem to_ufixed (r, l'high, 0));
  3776. end function "rem";
  3777. function "rem" (
  3778. l : NATURAL;
  3779. r : UNRESOLVED_ufixed) -- fixed point input
  3780. return UNRESOLVED_ufixed is
  3781. begin
  3782. return (to_ufixed (l, r'high, 0) rem r);
  3783. end function "rem";
  3784. function "rem" (
  3785. l : UNRESOLVED_sfixed; -- fixed point input
  3786. r : INTEGER)
  3787. return UNRESOLVED_sfixed is
  3788. begin
  3789. return (l rem to_sfixed (r, l'high, 0));
  3790. end function "rem";
  3791. function "rem" (
  3792. l : INTEGER;
  3793. r : UNRESOLVED_sfixed) -- fixed point input
  3794. return UNRESOLVED_sfixed is
  3795. begin
  3796. return (to_sfixed (l, r'high, 0) rem r);
  3797. end function "rem";
  3798. function "mod" (
  3799. l : UNRESOLVED_ufixed; -- fixed point input
  3800. r : NATURAL)
  3801. return UNRESOLVED_ufixed is
  3802. begin
  3803. return (l mod to_ufixed (r, l'high, 0));
  3804. end function "mod";
  3805. function "mod" (
  3806. l : NATURAL;
  3807. r : UNRESOLVED_ufixed) -- fixed point input
  3808. return UNRESOLVED_ufixed is
  3809. begin
  3810. return (to_ufixed (l, r'high, 0) mod r);
  3811. end function "mod";
  3812. function "mod" (
  3813. l : UNRESOLVED_sfixed; -- fixed point input
  3814. r : INTEGER)
  3815. return UNRESOLVED_sfixed is
  3816. begin
  3817. return (l mod to_sfixed (r, l'high, 0));
  3818. end function "mod";
  3819. function "mod" (
  3820. l : INTEGER;
  3821. r : UNRESOLVED_sfixed) -- fixed point input
  3822. return UNRESOLVED_sfixed is
  3823. begin
  3824. return (to_sfixed (l, r'high, 0) mod r);
  3825. end function "mod";
  3826. -- overloaded ufixed compare functions with integer
  3827. function "=" (
  3828. l : UNRESOLVED_ufixed;
  3829. r : NATURAL) -- fixed point input
  3830. return BOOLEAN is
  3831. begin
  3832. return (l = to_ufixed (r, l'high, l'low));
  3833. end function "=";
  3834. function "/=" (
  3835. l : UNRESOLVED_ufixed;
  3836. r : NATURAL) -- fixed point input
  3837. return BOOLEAN is
  3838. begin
  3839. return (l /= to_ufixed (r, l'high, l'low));
  3840. end function "/=";
  3841. function ">=" (
  3842. l : UNRESOLVED_ufixed;
  3843. r : NATURAL) -- fixed point input
  3844. return BOOLEAN is
  3845. begin
  3846. return (l >= to_ufixed (r, l'high, l'low));
  3847. end function ">=";
  3848. function "<=" (
  3849. l : UNRESOLVED_ufixed;
  3850. r : NATURAL) -- fixed point input
  3851. return BOOLEAN is
  3852. begin
  3853. return (l <= to_ufixed (r, l'high, l'low));
  3854. end function "<=";
  3855. function ">" (
  3856. l : UNRESOLVED_ufixed;
  3857. r : NATURAL) -- fixed point input
  3858. return BOOLEAN is
  3859. begin
  3860. return (l > to_ufixed (r, l'high, l'low));
  3861. end function ">";
  3862. function "<" (
  3863. l : UNRESOLVED_ufixed;
  3864. r : NATURAL) -- fixed point input
  3865. return BOOLEAN is
  3866. begin
  3867. return (l < to_ufixed (r, l'high, l'low));
  3868. end function "<";
  3869. function "?=" (
  3870. l : UNRESOLVED_ufixed;
  3871. r : NATURAL) -- fixed point input
  3872. return STD_ULOGIC is
  3873. begin
  3874. return (l ?= to_ufixed (r, l'high, l'low));
  3875. end function "?=";
  3876. function "?/=" (
  3877. l : UNRESOLVED_ufixed;
  3878. r : NATURAL) -- fixed point input
  3879. return STD_ULOGIC is
  3880. begin
  3881. return (l ?/= to_ufixed (r, l'high, l'low));
  3882. end function "?/=";
  3883. function "?>=" (
  3884. l : UNRESOLVED_ufixed;
  3885. r : NATURAL) -- fixed point input
  3886. return STD_ULOGIC is
  3887. begin
  3888. return (l ?>= to_ufixed (r, l'high, l'low));
  3889. end function "?>=";
  3890. function "?<=" (
  3891. l : UNRESOLVED_ufixed;
  3892. r : NATURAL) -- fixed point input
  3893. return STD_ULOGIC is
  3894. begin
  3895. return (l ?<= to_ufixed (r, l'high, l'low));
  3896. end function "?<=";
  3897. function "?>" (
  3898. l : UNRESOLVED_ufixed;
  3899. r : NATURAL) -- fixed point input
  3900. return STD_ULOGIC is
  3901. begin
  3902. return (l ?> to_ufixed (r, l'high, l'low));
  3903. end function "?>";
  3904. function "?<" (
  3905. l : UNRESOLVED_ufixed;
  3906. r : NATURAL) -- fixed point input
  3907. return STD_ULOGIC is
  3908. begin
  3909. return (l ?< to_ufixed (r, l'high, l'low));
  3910. end function "?<";
  3911. function maximum (
  3912. l : UNRESOLVED_ufixed; -- fixed point input
  3913. r : NATURAL)
  3914. return UNRESOLVED_ufixed is
  3915. begin
  3916. return maximum (l, to_ufixed (r, l'high, l'low));
  3917. end function maximum;
  3918. function minimum (
  3919. l : UNRESOLVED_ufixed; -- fixed point input
  3920. r : NATURAL)
  3921. return UNRESOLVED_ufixed is
  3922. begin
  3923. return minimum (l, to_ufixed (r, l'high, l'low));
  3924. end function minimum;
  3925. -- NATURAL to ufixed
  3926. function "=" (
  3927. l : NATURAL;
  3928. r : UNRESOLVED_ufixed) -- fixed point input
  3929. return BOOLEAN is
  3930. begin
  3931. return (to_ufixed (l, r'high, r'low) = r);
  3932. end function "=";
  3933. function "/=" (
  3934. l : NATURAL;
  3935. r : UNRESOLVED_ufixed) -- fixed point input
  3936. return BOOLEAN is
  3937. begin
  3938. return (to_ufixed (l, r'high, r'low) /= r);
  3939. end function "/=";
  3940. function ">=" (
  3941. l : NATURAL;
  3942. r : UNRESOLVED_ufixed) -- fixed point input
  3943. return BOOLEAN is
  3944. begin
  3945. return (to_ufixed (l, r'high, r'low) >= r);
  3946. end function ">=";
  3947. function "<=" (
  3948. l : NATURAL;
  3949. r : UNRESOLVED_ufixed) -- fixed point input
  3950. return BOOLEAN is
  3951. begin
  3952. return (to_ufixed (l, r'high, r'low) <= r);
  3953. end function "<=";
  3954. function ">" (
  3955. l : NATURAL;
  3956. r : UNRESOLVED_ufixed) -- fixed point input
  3957. return BOOLEAN is
  3958. begin
  3959. return (to_ufixed (l, r'high, r'low) > r);
  3960. end function ">";
  3961. function "<" (
  3962. l : NATURAL;
  3963. r : UNRESOLVED_ufixed) -- fixed point input
  3964. return BOOLEAN is
  3965. begin
  3966. return (to_ufixed (l, r'high, r'low) < r);
  3967. end function "<";
  3968. function "?=" (
  3969. l : NATURAL;
  3970. r : UNRESOLVED_ufixed) -- fixed point input
  3971. return STD_ULOGIC is
  3972. begin
  3973. return (to_ufixed (l, r'high, r'low) ?= r);
  3974. end function "?=";
  3975. function "?/=" (
  3976. l : NATURAL;
  3977. r : UNRESOLVED_ufixed) -- fixed point input
  3978. return STD_ULOGIC is
  3979. begin
  3980. return (to_ufixed (l, r'high, r'low) ?/= r);
  3981. end function "?/=";
  3982. function "?>=" (
  3983. l : NATURAL;
  3984. r : UNRESOLVED_ufixed) -- fixed point input
  3985. return STD_ULOGIC is
  3986. begin
  3987. return (to_ufixed (l, r'high, r'low) ?>= r);
  3988. end function "?>=";
  3989. function "?<=" (
  3990. l : NATURAL;
  3991. r : UNRESOLVED_ufixed) -- fixed point input
  3992. return STD_ULOGIC is
  3993. begin
  3994. return (to_ufixed (l, r'high, r'low) ?<= r);
  3995. end function "?<=";
  3996. function "?>" (
  3997. l : NATURAL;
  3998. r : UNRESOLVED_ufixed) -- fixed point input
  3999. return STD_ULOGIC is
  4000. begin
  4001. return (to_ufixed (l, r'high, r'low) ?> r);
  4002. end function "?>";
  4003. function "?<" (
  4004. l : NATURAL;
  4005. r : UNRESOLVED_ufixed) -- fixed point input
  4006. return STD_ULOGIC is
  4007. begin
  4008. return (to_ufixed (l, r'high, r'low) ?< r);
  4009. end function "?<";
  4010. function maximum (
  4011. l : NATURAL;
  4012. r : UNRESOLVED_ufixed) -- fixed point input
  4013. return UNRESOLVED_ufixed is
  4014. begin
  4015. return maximum (to_ufixed (l, r'high, r'low), r);
  4016. end function maximum;
  4017. function minimum (
  4018. l : NATURAL;
  4019. r : UNRESOLVED_ufixed) -- fixed point input
  4020. return UNRESOLVED_ufixed is
  4021. begin
  4022. return minimum (to_ufixed (l, r'high, r'low), r);
  4023. end function minimum;
  4024. -- overloaded ufixed compare functions with real
  4025. function "=" (
  4026. l : UNRESOLVED_ufixed;
  4027. r : REAL)
  4028. return BOOLEAN is
  4029. begin
  4030. return (l = to_ufixed (r, l'high, l'low));
  4031. end function "=";
  4032. function "/=" (
  4033. l : UNRESOLVED_ufixed;
  4034. r : REAL)
  4035. return BOOLEAN is
  4036. begin
  4037. return (l /= to_ufixed (r, l'high, l'low));
  4038. end function "/=";
  4039. function ">=" (
  4040. l : UNRESOLVED_ufixed;
  4041. r : REAL)
  4042. return BOOLEAN is
  4043. begin
  4044. return (l >= to_ufixed (r, l'high, l'low));
  4045. end function ">=";
  4046. function "<=" (
  4047. l : UNRESOLVED_ufixed;
  4048. r : REAL)
  4049. return BOOLEAN is
  4050. begin
  4051. return (l <= to_ufixed (r, l'high, l'low));
  4052. end function "<=";
  4053. function ">" (
  4054. l : UNRESOLVED_ufixed;
  4055. r : REAL)
  4056. return BOOLEAN is
  4057. begin
  4058. return (l > to_ufixed (r, l'high, l'low));
  4059. end function ">";
  4060. function "<" (
  4061. l : UNRESOLVED_ufixed;
  4062. r : REAL)
  4063. return BOOLEAN is
  4064. begin
  4065. return (l < to_ufixed (r, l'high, l'low));
  4066. end function "<";
  4067. function "?=" (
  4068. l : UNRESOLVED_ufixed;
  4069. r : REAL)
  4070. return STD_ULOGIC is
  4071. begin
  4072. return (l ?= to_ufixed (r, l'high, l'low));
  4073. end function "?=";
  4074. function "?/=" (
  4075. l : UNRESOLVED_ufixed;
  4076. r : REAL)
  4077. return STD_ULOGIC is
  4078. begin
  4079. return (l ?/= to_ufixed (r, l'high, l'low));
  4080. end function "?/=";
  4081. function "?>=" (
  4082. l : UNRESOLVED_ufixed;
  4083. r : REAL)
  4084. return STD_ULOGIC is
  4085. begin
  4086. return (l ?>= to_ufixed (r, l'high, l'low));
  4087. end function "?>=";
  4088. function "?<=" (
  4089. l : UNRESOLVED_ufixed;
  4090. r : REAL)
  4091. return STD_ULOGIC is
  4092. begin
  4093. return (l ?<= to_ufixed (r, l'high, l'low));
  4094. end function "?<=";
  4095. function "?>" (
  4096. l : UNRESOLVED_ufixed;
  4097. r : REAL)
  4098. return STD_ULOGIC is
  4099. begin
  4100. return (l ?> to_ufixed (r, l'high, l'low));
  4101. end function "?>";
  4102. function "?<" (
  4103. l : UNRESOLVED_ufixed;
  4104. r : REAL)
  4105. return STD_ULOGIC is
  4106. begin
  4107. return (l ?< to_ufixed (r, l'high, l'low));
  4108. end function "?<";
  4109. function maximum (
  4110. l : UNRESOLVED_ufixed;
  4111. r : REAL)
  4112. return UNRESOLVED_ufixed is
  4113. begin
  4114. return maximum (l, to_ufixed (r, l'high, l'low));
  4115. end function maximum;
  4116. function minimum (
  4117. l : UNRESOLVED_ufixed;
  4118. r : REAL)
  4119. return UNRESOLVED_ufixed is
  4120. begin
  4121. return minimum (l, to_ufixed (r, l'high, l'low));
  4122. end function minimum;
  4123. -- real and ufixed
  4124. function "=" (
  4125. l : REAL;
  4126. r : UNRESOLVED_ufixed) -- fixed point input
  4127. return BOOLEAN is
  4128. begin
  4129. return (to_ufixed (l, r'high, r'low) = r);
  4130. end function "=";
  4131. function "/=" (
  4132. l : REAL;
  4133. r : UNRESOLVED_ufixed) -- fixed point input
  4134. return BOOLEAN is
  4135. begin
  4136. return (to_ufixed (l, r'high, r'low) /= r);
  4137. end function "/=";
  4138. function ">=" (
  4139. l : REAL;
  4140. r : UNRESOLVED_ufixed) -- fixed point input
  4141. return BOOLEAN is
  4142. begin
  4143. return (to_ufixed (l, r'high, r'low) >= r);
  4144. end function ">=";
  4145. function "<=" (
  4146. l : REAL;
  4147. r : UNRESOLVED_ufixed) -- fixed point input
  4148. return BOOLEAN is
  4149. begin
  4150. return (to_ufixed (l, r'high, r'low) <= r);
  4151. end function "<=";
  4152. function ">" (
  4153. l : REAL;
  4154. r : UNRESOLVED_ufixed) -- fixed point input
  4155. return BOOLEAN is
  4156. begin
  4157. return (to_ufixed (l, r'high, r'low) > r);
  4158. end function ">";
  4159. function "<" (
  4160. l : REAL;
  4161. r : UNRESOLVED_ufixed) -- fixed point input
  4162. return BOOLEAN is
  4163. begin
  4164. return (to_ufixed (l, r'high, r'low) < r);
  4165. end function "<";
  4166. function "?=" (
  4167. l : REAL;
  4168. r : UNRESOLVED_ufixed) -- fixed point input
  4169. return STD_ULOGIC is
  4170. begin
  4171. return (to_ufixed (l, r'high, r'low) ?= r);
  4172. end function "?=";
  4173. function "?/=" (
  4174. l : REAL;
  4175. r : UNRESOLVED_ufixed) -- fixed point input
  4176. return STD_ULOGIC is
  4177. begin
  4178. return (to_ufixed (l, r'high, r'low) ?/= r);
  4179. end function "?/=";
  4180. function "?>=" (
  4181. l : REAL;
  4182. r : UNRESOLVED_ufixed) -- fixed point input
  4183. return STD_ULOGIC is
  4184. begin
  4185. return (to_ufixed (l, r'high, r'low) ?>= r);
  4186. end function "?>=";
  4187. function "?<=" (
  4188. l : REAL;
  4189. r : UNRESOLVED_ufixed) -- fixed point input
  4190. return STD_ULOGIC is
  4191. begin
  4192. return (to_ufixed (l, r'high, r'low) ?<= r);
  4193. end function "?<=";
  4194. function "?>" (
  4195. l : REAL;
  4196. r : UNRESOLVED_ufixed) -- fixed point input
  4197. return STD_ULOGIC is
  4198. begin
  4199. return (to_ufixed (l, r'high, r'low) ?> r);
  4200. end function "?>";
  4201. function "?<" (
  4202. l : REAL;
  4203. r : UNRESOLVED_ufixed) -- fixed point input
  4204. return STD_ULOGIC is
  4205. begin
  4206. return (to_ufixed (l, r'high, r'low) ?< r);
  4207. end function "?<";
  4208. function maximum (
  4209. l : REAL;
  4210. r : UNRESOLVED_ufixed) -- fixed point input
  4211. return UNRESOLVED_ufixed is
  4212. begin
  4213. return maximum (to_ufixed (l, r'high, r'low), r);
  4214. end function maximum;
  4215. function minimum (
  4216. l : REAL;
  4217. r : UNRESOLVED_ufixed) -- fixed point input
  4218. return UNRESOLVED_ufixed is
  4219. begin
  4220. return minimum (to_ufixed (l, r'high, r'low), r);
  4221. end function minimum;
  4222. -- overloaded sfixed compare functions with integer
  4223. function "=" (
  4224. l : UNRESOLVED_sfixed;
  4225. r : INTEGER)
  4226. return BOOLEAN is
  4227. begin
  4228. return (l = to_sfixed (r, l'high, l'low));
  4229. end function "=";
  4230. function "/=" (
  4231. l : UNRESOLVED_sfixed;
  4232. r : INTEGER)
  4233. return BOOLEAN is
  4234. begin
  4235. return (l /= to_sfixed (r, l'high, l'low));
  4236. end function "/=";
  4237. function ">=" (
  4238. l : UNRESOLVED_sfixed;
  4239. r : INTEGER)
  4240. return BOOLEAN is
  4241. begin
  4242. return (l >= to_sfixed (r, l'high, l'low));
  4243. end function ">=";
  4244. function "<=" (
  4245. l : UNRESOLVED_sfixed;
  4246. r : INTEGER)
  4247. return BOOLEAN is
  4248. begin
  4249. return (l <= to_sfixed (r, l'high, l'low));
  4250. end function "<=";
  4251. function ">" (
  4252. l : UNRESOLVED_sfixed;
  4253. r : INTEGER)
  4254. return BOOLEAN is
  4255. begin
  4256. return (l > to_sfixed (r, l'high, l'low));
  4257. end function ">";
  4258. function "<" (
  4259. l : UNRESOLVED_sfixed;
  4260. r : INTEGER)
  4261. return BOOLEAN is
  4262. begin
  4263. return (l < to_sfixed (r, l'high, l'low));
  4264. end function "<";
  4265. function "?=" (
  4266. l : UNRESOLVED_sfixed;
  4267. r : INTEGER)
  4268. return STD_ULOGIC is
  4269. begin
  4270. return (l ?= to_sfixed (r, l'high, l'low));
  4271. end function "?=";
  4272. function "?/=" (
  4273. l : UNRESOLVED_sfixed;
  4274. r : INTEGER)
  4275. return STD_ULOGIC is
  4276. begin
  4277. return (l ?/= to_sfixed (r, l'high, l'low));
  4278. end function "?/=";
  4279. function "?>=" (
  4280. l : UNRESOLVED_sfixed;
  4281. r : INTEGER)
  4282. return STD_ULOGIC is
  4283. begin
  4284. return (l ?>= to_sfixed (r, l'high, l'low));
  4285. end function "?>=";
  4286. function "?<=" (
  4287. l : UNRESOLVED_sfixed;
  4288. r : INTEGER)
  4289. return STD_ULOGIC is
  4290. begin
  4291. return (l ?<= to_sfixed (r, l'high, l'low));
  4292. end function "?<=";
  4293. function "?>" (
  4294. l : UNRESOLVED_sfixed;
  4295. r : INTEGER)
  4296. return STD_ULOGIC is
  4297. begin
  4298. return (l ?> to_sfixed (r, l'high, l'low));
  4299. end function "?>";
  4300. function "?<" (
  4301. l : UNRESOLVED_sfixed;
  4302. r : INTEGER)
  4303. return STD_ULOGIC is
  4304. begin
  4305. return (l ?< to_sfixed (r, l'high, l'low));
  4306. end function "?<";
  4307. function maximum (
  4308. l : UNRESOLVED_sfixed;
  4309. r : INTEGER)
  4310. return UNRESOLVED_sfixed is
  4311. begin
  4312. return maximum (l, to_sfixed (r, l'high, l'low));
  4313. end function maximum;
  4314. function minimum (
  4315. l : UNRESOLVED_sfixed;
  4316. r : INTEGER)
  4317. return UNRESOLVED_sfixed is
  4318. begin
  4319. return minimum (l, to_sfixed (r, l'high, l'low));
  4320. end function minimum;
  4321. -- integer and sfixed
  4322. function "=" (
  4323. l : INTEGER;
  4324. r : UNRESOLVED_sfixed) -- fixed point input
  4325. return BOOLEAN is
  4326. begin
  4327. return (to_sfixed (l, r'high, r'low) = r);
  4328. end function "=";
  4329. function "/=" (
  4330. l : INTEGER;
  4331. r : UNRESOLVED_sfixed) -- fixed point input
  4332. return BOOLEAN is
  4333. begin
  4334. return (to_sfixed (l, r'high, r'low) /= r);
  4335. end function "/=";
  4336. function ">=" (
  4337. l : INTEGER;
  4338. r : UNRESOLVED_sfixed) -- fixed point input
  4339. return BOOLEAN is
  4340. begin
  4341. return (to_sfixed (l, r'high, r'low) >= r);
  4342. end function ">=";
  4343. function "<=" (
  4344. l : INTEGER;
  4345. r : UNRESOLVED_sfixed) -- fixed point input
  4346. return BOOLEAN is
  4347. begin
  4348. return (to_sfixed (l, r'high, r'low) <= r);
  4349. end function "<=";
  4350. function ">" (
  4351. l : INTEGER;
  4352. r : UNRESOLVED_sfixed) -- fixed point input
  4353. return BOOLEAN is
  4354. begin
  4355. return (to_sfixed (l, r'high, r'low) > r);
  4356. end function ">";
  4357. function "<" (
  4358. l : INTEGER;
  4359. r : UNRESOLVED_sfixed) -- fixed point input
  4360. return BOOLEAN is
  4361. begin
  4362. return (to_sfixed (l, r'high, r'low) < r);
  4363. end function "<";
  4364. function "?=" (
  4365. l : INTEGER;
  4366. r : UNRESOLVED_sfixed) -- fixed point input
  4367. return STD_ULOGIC is
  4368. begin
  4369. return (to_sfixed (l, r'high, r'low) ?= r);
  4370. end function "?=";
  4371. function "?/=" (
  4372. l : INTEGER;
  4373. r : UNRESOLVED_sfixed) -- fixed point input
  4374. return STD_ULOGIC is
  4375. begin
  4376. return (to_sfixed (l, r'high, r'low) ?/= r);
  4377. end function "?/=";
  4378. function "?>=" (
  4379. l : INTEGER;
  4380. r : UNRESOLVED_sfixed) -- fixed point input
  4381. return STD_ULOGIC is
  4382. begin
  4383. return (to_sfixed (l, r'high, r'low) ?>= r);
  4384. end function "?>=";
  4385. function "?<=" (
  4386. l : INTEGER;
  4387. r : UNRESOLVED_sfixed) -- fixed point input
  4388. return STD_ULOGIC is
  4389. begin
  4390. return (to_sfixed (l, r'high, r'low) ?<= r);
  4391. end function "?<=";
  4392. function "?>" (
  4393. l : INTEGER;
  4394. r : UNRESOLVED_sfixed) -- fixed point input
  4395. return STD_ULOGIC is
  4396. begin
  4397. return (to_sfixed (l, r'high, r'low) ?> r);
  4398. end function "?>";
  4399. function "?<" (
  4400. l : INTEGER;
  4401. r : UNRESOLVED_sfixed) -- fixed point input
  4402. return STD_ULOGIC is
  4403. begin
  4404. return (to_sfixed (l, r'high, r'low) ?< r);
  4405. end function "?<";
  4406. function maximum (
  4407. l : INTEGER;
  4408. r : UNRESOLVED_sfixed)
  4409. return UNRESOLVED_sfixed is
  4410. begin
  4411. return maximum (to_sfixed (l, r'high, r'low), r);
  4412. end function maximum;
  4413. function minimum (
  4414. l : INTEGER;
  4415. r : UNRESOLVED_sfixed)
  4416. return UNRESOLVED_sfixed is
  4417. begin
  4418. return minimum (to_sfixed (l, r'high, r'low), r);
  4419. end function minimum;
  4420. -- overloaded sfixed compare functions with real
  4421. function "=" (
  4422. l : UNRESOLVED_sfixed;
  4423. r : REAL)
  4424. return BOOLEAN is
  4425. begin
  4426. return (l = to_sfixed (r, l'high, l'low));
  4427. end function "=";
  4428. function "/=" (
  4429. l : UNRESOLVED_sfixed;
  4430. r : REAL)
  4431. return BOOLEAN is
  4432. begin
  4433. return (l /= to_sfixed (r, l'high, l'low));
  4434. end function "/=";
  4435. function ">=" (
  4436. l : UNRESOLVED_sfixed;
  4437. r : REAL)
  4438. return BOOLEAN is
  4439. begin
  4440. return (l >= to_sfixed (r, l'high, l'low));
  4441. end function ">=";
  4442. function "<=" (
  4443. l : UNRESOLVED_sfixed;
  4444. r : REAL)
  4445. return BOOLEAN is
  4446. begin
  4447. return (l <= to_sfixed (r, l'high, l'low));
  4448. end function "<=";
  4449. function ">" (
  4450. l : UNRESOLVED_sfixed;
  4451. r : REAL)
  4452. return BOOLEAN is
  4453. begin
  4454. return (l > to_sfixed (r, l'high, l'low));
  4455. end function ">";
  4456. function "<" (
  4457. l : UNRESOLVED_sfixed;
  4458. r : REAL)
  4459. return BOOLEAN is
  4460. begin
  4461. return (l < to_sfixed (r, l'high, l'low));
  4462. end function "<";
  4463. function "?=" (
  4464. l : UNRESOLVED_sfixed;
  4465. r : REAL)
  4466. return STD_ULOGIC is
  4467. begin
  4468. return (l ?= to_sfixed (r, l'high, l'low));
  4469. end function "?=";
  4470. function "?/=" (
  4471. l : UNRESOLVED_sfixed;
  4472. r : REAL)
  4473. return STD_ULOGIC is
  4474. begin
  4475. return (l ?/= to_sfixed (r, l'high, l'low));
  4476. end function "?/=";
  4477. function "?>=" (
  4478. l : UNRESOLVED_sfixed;
  4479. r : REAL)
  4480. return STD_ULOGIC is
  4481. begin
  4482. return (l ?>= to_sfixed (r, l'high, l'low));
  4483. end function "?>=";
  4484. function "?<=" (
  4485. l : UNRESOLVED_sfixed;
  4486. r : REAL)
  4487. return STD_ULOGIC is
  4488. begin
  4489. return (l ?<= to_sfixed (r, l'high, l'low));
  4490. end function "?<=";
  4491. function "?>" (
  4492. l : UNRESOLVED_sfixed;
  4493. r : REAL)
  4494. return STD_ULOGIC is
  4495. begin
  4496. return (l ?> to_sfixed (r, l'high, l'low));
  4497. end function "?>";
  4498. function "?<" (
  4499. l : UNRESOLVED_sfixed;
  4500. r : REAL)
  4501. return STD_ULOGIC is
  4502. begin
  4503. return (l ?< to_sfixed (r, l'high, l'low));
  4504. end function "?<";
  4505. function maximum (
  4506. l : UNRESOLVED_sfixed;
  4507. r : REAL)
  4508. return UNRESOLVED_sfixed is
  4509. begin
  4510. return maximum (l, to_sfixed (r, l'high, l'low));
  4511. end function maximum;
  4512. function minimum (
  4513. l : UNRESOLVED_sfixed;
  4514. r : REAL)
  4515. return UNRESOLVED_sfixed is
  4516. begin
  4517. return minimum (l, to_sfixed (r, l'high, l'low));
  4518. end function minimum;
  4519. -- REAL and sfixed
  4520. function "=" (
  4521. l : REAL;
  4522. r : UNRESOLVED_sfixed) -- fixed point input
  4523. return BOOLEAN is
  4524. begin
  4525. return (to_sfixed (l, r'high, r'low) = r);
  4526. end function "=";
  4527. function "/=" (
  4528. l : REAL;
  4529. r : UNRESOLVED_sfixed) -- fixed point input
  4530. return BOOLEAN is
  4531. begin
  4532. return (to_sfixed (l, r'high, r'low) /= r);
  4533. end function "/=";
  4534. function ">=" (
  4535. l : REAL;
  4536. r : UNRESOLVED_sfixed) -- fixed point input
  4537. return BOOLEAN is
  4538. begin
  4539. return (to_sfixed (l, r'high, r'low) >= r);
  4540. end function ">=";
  4541. function "<=" (
  4542. l : REAL;
  4543. r : UNRESOLVED_sfixed) -- fixed point input
  4544. return BOOLEAN is
  4545. begin
  4546. return (to_sfixed (l, r'high, r'low) <= r);
  4547. end function "<=";
  4548. function ">" (
  4549. l : REAL;
  4550. r : UNRESOLVED_sfixed) -- fixed point input
  4551. return BOOLEAN is
  4552. begin
  4553. return (to_sfixed (l, r'high, r'low) > r);
  4554. end function ">";
  4555. function "<" (
  4556. l : REAL;
  4557. r : UNRESOLVED_sfixed) -- fixed point input
  4558. return BOOLEAN is
  4559. begin
  4560. return (to_sfixed (l, r'high, r'low) < r);
  4561. end function "<";
  4562. function "?=" (
  4563. l : REAL;
  4564. r : UNRESOLVED_sfixed) -- fixed point input
  4565. return STD_ULOGIC is
  4566. begin
  4567. return (to_sfixed (l, r'high, r'low) ?= r);
  4568. end function "?=";
  4569. function "?/=" (
  4570. l : REAL;
  4571. r : UNRESOLVED_sfixed) -- fixed point input
  4572. return STD_ULOGIC is
  4573. begin
  4574. return (to_sfixed (l, r'high, r'low) ?/= r);
  4575. end function "?/=";
  4576. function "?>=" (
  4577. l : REAL;
  4578. r : UNRESOLVED_sfixed) -- fixed point input
  4579. return STD_ULOGIC is
  4580. begin
  4581. return (to_sfixed (l, r'high, r'low) ?>= r);
  4582. end function "?>=";
  4583. function "?<=" (
  4584. l : REAL;
  4585. r : UNRESOLVED_sfixed) -- fixed point input
  4586. return STD_ULOGIC is
  4587. begin
  4588. return (to_sfixed (l, r'high, r'low) ?<= r);
  4589. end function "?<=";
  4590. function "?>" (
  4591. l : REAL;
  4592. r : UNRESOLVED_sfixed) -- fixed point input
  4593. return STD_ULOGIC is
  4594. begin
  4595. return (to_sfixed (l, r'high, r'low) ?> r);
  4596. end function "?>";
  4597. function "?<" (
  4598. l : REAL;
  4599. r : UNRESOLVED_sfixed) -- fixed point input
  4600. return STD_ULOGIC is
  4601. begin
  4602. return (to_sfixed (l, r'high, r'low) ?< r);
  4603. end function "?<";
  4604. function maximum (
  4605. l : REAL;
  4606. r : UNRESOLVED_sfixed)
  4607. return UNRESOLVED_sfixed is
  4608. begin
  4609. return maximum (to_sfixed (l, r'high, r'low), r);
  4610. end function maximum;
  4611. function minimum (
  4612. l : REAL;
  4613. r : UNRESOLVED_sfixed)
  4614. return UNRESOLVED_sfixed is
  4615. begin
  4616. return minimum (to_sfixed (l, r'high, r'low), r);
  4617. end function minimum;
  4618. -- copied from std_logic_textio
  4619. type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
  4620. type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
  4621. type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
  4622. type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
  4623. constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
  4624. constant char_to_MVL9 : MVL9_indexed_by_char :=
  4625. ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
  4626. 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
  4627. constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
  4628. ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
  4629. 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
  4630. constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
  4631. constant NUS : STRING(2 to 1) := (others => ' ');
  4632. -- purpose: Skips white space
  4633. procedure skip_whitespace (
  4634. L : inout LINE) is
  4635. variable c : CHARACTER;
  4636. variable left : positive;
  4637. begin
  4638. while L /= null and L.all'length /= 0 loop
  4639. left := L.all'left;
  4640. c := L.all(left);
  4641. if (c = ' ' or c = NBSP or c = HT) then
  4642. read (L, c);
  4643. else
  4644. exit;
  4645. end if;
  4646. end loop;
  4647. end procedure skip_whitespace;
  4648. -- purpose: writes fixed point into a line
  4649. procedure write (
  4650. L : inout LINE; -- input line
  4651. VALUE : in UNRESOLVED_ufixed; -- fixed point input
  4652. JUSTIFIED : in SIDE := right;
  4653. FIELD : in WIDTH := 0) is
  4654. variable s : STRING(1 to VALUE'length +1) := (others => ' ');
  4655. variable sindx : INTEGER;
  4656. begin -- function write Example: 0011.1100
  4657. sindx := 1;
  4658. for i in VALUE'high downto VALUE'low loop
  4659. if i = -1 then
  4660. s(sindx) := '.';
  4661. sindx := sindx + 1;
  4662. end if;
  4663. s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i)));
  4664. sindx := sindx + 1;
  4665. end loop;
  4666. write(L, s, JUSTIFIED, FIELD);
  4667. end procedure write;
  4668. -- purpose: writes fixed point into a line
  4669. procedure write (
  4670. L : inout LINE; -- input line
  4671. VALUE : in UNRESOLVED_sfixed; -- fixed point input
  4672. JUSTIFIED : in SIDE := right;
  4673. FIELD : in WIDTH := 0) is
  4674. variable s : STRING(1 to VALUE'length +1);
  4675. variable sindx : INTEGER;
  4676. begin -- function write Example: 0011.1100
  4677. sindx := 1;
  4678. for i in VALUE'high downto VALUE'low loop
  4679. if i = -1 then
  4680. s(sindx) := '.';
  4681. sindx := sindx + 1;
  4682. end if;
  4683. s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i)));
  4684. sindx := sindx + 1;
  4685. end loop;
  4686. write(L, s, JUSTIFIED, FIELD);
  4687. end procedure write;
  4688. procedure READ(L : inout LINE;
  4689. VALUE : out UNRESOLVED_ufixed) is
  4690. -- Possible data: 00000.0000000
  4691. -- 000000000000
  4692. variable c : CHARACTER;
  4693. variable readOk : BOOLEAN;
  4694. variable i : INTEGER; -- index variable
  4695. variable mv : ufixed (VALUE'range);
  4696. variable lastu : BOOLEAN := false; -- last character was an "_"
  4697. variable founddot : BOOLEAN := false; -- found a "."
  4698. begin -- READ
  4699. VALUE := (VALUE'range => 'U');
  4700. skip_whitespace (L);
  4701. if VALUE'length > 0 then -- non Null input string
  4702. read (L, c, readOk);
  4703. i := VALUE'high;
  4704. while i >= VALUE'low loop
  4705. if readOk = false then -- Bail out if there was a bad read
  4706. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4707. & "End of string encountered"
  4708. severity error;
  4709. return;
  4710. elsif c = '_' then
  4711. if i = VALUE'high then
  4712. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4713. & "String begins with an ""_""" severity error;
  4714. return;
  4715. elsif lastu then
  4716. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4717. & "Two underscores detected in input string ""__"""
  4718. severity error;
  4719. return;
  4720. else
  4721. lastu := true;
  4722. end if;
  4723. elsif c = '.' then -- binary point
  4724. if founddot then
  4725. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4726. & "Two binary points found in input string" severity error;
  4727. return;
  4728. elsif i /= -1 then -- Seperator in the wrong spot
  4729. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4730. & "Decimal point does not match number format "
  4731. severity error;
  4732. return;
  4733. end if;
  4734. founddot := true;
  4735. lastu := false;
  4736. elsif c = ' ' or c = NBSP or c = HT then -- reading done.
  4737. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4738. & "Short read, Space encounted in input string"
  4739. severity error;
  4740. return;
  4741. elsif char_to_MVL9plus(c) = error then
  4742. report fixed_generic_pkg'instance_name & "READ(ufixed) "
  4743. & "Character '" &
  4744. c & "' read, expected STD_ULOGIC literal."
  4745. severity error;
  4746. return;
  4747. else
  4748. mv(i) := char_to_MVL9(c);
  4749. i := i - 1;
  4750. if i < mv'low then
  4751. VALUE := mv;
  4752. return;
  4753. end if;
  4754. lastu := false;
  4755. end if;
  4756. read(L, c, readOk);
  4757. end loop;
  4758. end if;
  4759. end procedure READ;
  4760. procedure READ(L : inout LINE;
  4761. VALUE : out UNRESOLVED_ufixed;
  4762. GOOD : out BOOLEAN) is
  4763. -- Possible data: 00000.0000000
  4764. -- 000000000000
  4765. variable c : CHARACTER;
  4766. variable readOk : BOOLEAN;
  4767. variable mv : ufixed (VALUE'range);
  4768. variable i : INTEGER; -- index variable
  4769. variable lastu : BOOLEAN := false; -- last character was an "_"
  4770. variable founddot : BOOLEAN := false; -- found a "."
  4771. begin -- READ
  4772. VALUE := (VALUE'range => 'U');
  4773. skip_whitespace (L);
  4774. if VALUE'length > 0 then
  4775. read (L, c, readOk);
  4776. i := VALUE'high;
  4777. GOOD := false;
  4778. while i >= VALUE'low loop
  4779. if not readOk then -- Bail out if there was a bad read
  4780. return;
  4781. elsif c = '_' then
  4782. if i = VALUE'high then -- Begins with an "_"
  4783. return;
  4784. elsif lastu then -- "__" detected
  4785. return;
  4786. else
  4787. lastu := true;
  4788. end if;
  4789. elsif c = '.' then -- binary point
  4790. if founddot then
  4791. return;
  4792. elsif i /= -1 then -- Seperator in the wrong spot
  4793. return;
  4794. end if;
  4795. founddot := true;
  4796. lastu := false;
  4797. elsif (char_to_MVL9plus(c) = error) then -- Illegal character/short read
  4798. return;
  4799. else
  4800. mv(i) := char_to_MVL9(c);
  4801. i := i - 1;
  4802. if i < mv'low then -- reading done
  4803. GOOD := true;
  4804. VALUE := mv;
  4805. return;
  4806. end if;
  4807. lastu := false;
  4808. end if;
  4809. read(L, c, readOk);
  4810. end loop;
  4811. else
  4812. GOOD := true; -- read into a null array
  4813. end if;
  4814. end procedure READ;
  4815. procedure READ(L : inout LINE;
  4816. VALUE : out UNRESOLVED_sfixed) is
  4817. variable c : CHARACTER;
  4818. variable readOk : BOOLEAN;
  4819. variable i : INTEGER; -- index variable
  4820. variable mv : sfixed (VALUE'range);
  4821. variable lastu : BOOLEAN := false; -- last character was an "_"
  4822. variable founddot : BOOLEAN := false; -- found a "."
  4823. begin -- READ
  4824. VALUE := (VALUE'range => 'U');
  4825. skip_whitespace (L);
  4826. if VALUE'length > 0 then -- non Null input string
  4827. read (L, c, readOk);
  4828. i := VALUE'high;
  4829. while i >= VALUE'low loop
  4830. if readOk = false then -- Bail out if there was a bad read
  4831. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4832. & "End of string encountered"
  4833. severity error;
  4834. return;
  4835. elsif c = '_' then
  4836. if i = VALUE'high then
  4837. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4838. & "String begins with an ""_""" severity error;
  4839. return;
  4840. elsif lastu then
  4841. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4842. & "Two underscores detected in input string ""__"""
  4843. severity error;
  4844. return;
  4845. else
  4846. lastu := true;
  4847. end if;
  4848. elsif c = '.' then -- binary point
  4849. if founddot then
  4850. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4851. & "Two binary points found in input string" severity error;
  4852. return;
  4853. elsif i /= -1 then -- Seperator in the wrong spot
  4854. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4855. & "Decimal point does not match number format "
  4856. severity error;
  4857. return;
  4858. end if;
  4859. founddot := true;
  4860. lastu := false;
  4861. elsif c = ' ' or c = NBSP or c = HT then -- reading done.
  4862. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4863. & "Short read, Space encounted in input string"
  4864. severity error;
  4865. return;
  4866. elsif char_to_MVL9plus(c) = error then
  4867. report fixed_generic_pkg'instance_name & "READ(sfixed) "
  4868. & "Character '" &
  4869. c & "' read, expected STD_ULOGIC literal."
  4870. severity error;
  4871. return;
  4872. else
  4873. mv(i) := char_to_MVL9(c);
  4874. i := i - 1;
  4875. if i < mv'low then
  4876. VALUE := mv;
  4877. return;
  4878. end if;
  4879. lastu := false;
  4880. end if;
  4881. read(L, c, readOk);
  4882. end loop;
  4883. end if;
  4884. end procedure READ;
  4885. procedure READ(L : inout LINE;
  4886. VALUE : out UNRESOLVED_sfixed;
  4887. GOOD : out BOOLEAN) is
  4888. variable value_ufixed : UNRESOLVED_ufixed (VALUE'range);
  4889. begin -- READ
  4890. READ (L => L, VALUE => value_ufixed, GOOD => GOOD);
  4891. VALUE := UNRESOLVED_sfixed (value_ufixed);
  4892. end procedure READ;
  4893. -- octal read and write
  4894. procedure owrite (
  4895. L : inout LINE; -- input line
  4896. VALUE : in UNRESOLVED_ufixed; -- fixed point input
  4897. JUSTIFIED : in SIDE := right;
  4898. FIELD : in WIDTH := 0) is
  4899. begin -- Example 03.30
  4900. write (L => L,
  4901. VALUE => TO_OSTRING (VALUE),
  4902. JUSTIFIED => JUSTIFIED,
  4903. FIELD => FIELD);
  4904. end procedure owrite;
  4905. procedure owrite (
  4906. L : inout LINE; -- input line
  4907. VALUE : in UNRESOLVED_sfixed; -- fixed point input
  4908. JUSTIFIED : in SIDE := right;
  4909. FIELD : in WIDTH := 0) is
  4910. begin -- Example 03.30
  4911. write (L => L,
  4912. VALUE => TO_OSTRING (VALUE),
  4913. JUSTIFIED => JUSTIFIED,
  4914. FIELD => FIELD);
  4915. end procedure owrite;
  4916. -- Note that for Octal and Hex read, you can not start with a ".",
  4917. -- the read is for numbers formatted "A.BC". These routines go to
  4918. -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
  4919. procedure Char2TriBits (C : CHARACTER;
  4920. RESULT : out STD_ULOGIC_VECTOR(2 downto 0);
  4921. GOOD : out BOOLEAN;
  4922. ISSUE_ERROR : in BOOLEAN) is
  4923. begin
  4924. case C is
  4925. when '0' => RESULT := o"0"; GOOD := true;
  4926. when '1' => RESULT := o"1"; GOOD := true;
  4927. when '2' => RESULT := o"2"; GOOD := true;
  4928. when '3' => RESULT := o"3"; GOOD := true;
  4929. when '4' => RESULT := o"4"; GOOD := true;
  4930. when '5' => RESULT := o"5"; GOOD := true;
  4931. when '6' => RESULT := o"6"; GOOD := true;
  4932. when '7' => RESULT := o"7"; GOOD := true;
  4933. when 'Z' => RESULT := "ZZZ"; GOOD := true;
  4934. when 'X' => RESULT := "XXX"; GOOD := true;
  4935. when others =>
  4936. assert not ISSUE_ERROR
  4937. report fixed_generic_pkg'instance_name
  4938. & "OREAD Error: Read a '" & C &
  4939. "', expected an Octal character (0-7)."
  4940. severity error;
  4941. RESULT := "UUU";
  4942. GOOD := false;
  4943. end case;
  4944. end procedure Char2TriBits;
  4945. -- purpose: Routines common to the OREAD routines
  4946. procedure OREAD_common (
  4947. L : inout LINE;
  4948. slv : out STD_ULOGIC_VECTOR;
  4949. igood : out BOOLEAN;
  4950. idex : out INTEGER;
  4951. constant bpoint : in INTEGER; -- binary point
  4952. constant message : in BOOLEAN;
  4953. constant smath : in BOOLEAN) is
  4954. -- purpose: error message routine
  4955. procedure errmes (
  4956. constant mess : in STRING) is -- error message
  4957. begin
  4958. if message then
  4959. if smath then
  4960. report fixed_generic_pkg'instance_name
  4961. & "OREAD(sfixed) "
  4962. & mess
  4963. severity error;
  4964. else
  4965. report fixed_generic_pkg'instance_name
  4966. & "OREAD(ufixed) "
  4967. & mess
  4968. severity error;
  4969. end if;
  4970. end if;
  4971. end procedure errmes;
  4972. variable xgood : BOOLEAN;
  4973. variable nybble : STD_ULOGIC_VECTOR (2 downto 0); -- 3 bits
  4974. variable c : CHARACTER;
  4975. variable i : INTEGER;
  4976. variable lastu : BOOLEAN := false; -- last character was an "_"
  4977. variable founddot : BOOLEAN := false; -- found a dot.
  4978. begin
  4979. skip_whitespace (L);
  4980. if slv'length > 0 then
  4981. i := slv'high;
  4982. read (L, c, xgood);
  4983. while i > 0 loop
  4984. if xgood = false then
  4985. errmes ("Error: end of string encountered");
  4986. exit;
  4987. elsif c = '_' then
  4988. if i = slv'length then
  4989. errmes ("Error: String begins with an ""_""");
  4990. xgood := false;
  4991. exit;
  4992. elsif lastu then
  4993. errmes ("Error: Two underscores detected in input string ""__""");
  4994. xgood := false;
  4995. exit;
  4996. else
  4997. lastu := true;
  4998. end if;
  4999. elsif (c = '.') then
  5000. if (i + 1 /= bpoint) then
  5001. errmes ("encountered ""."" at wrong index");
  5002. xgood := false;
  5003. exit;
  5004. elsif i = slv'length then
  5005. errmes ("encounted a ""."" at the beginning of the line");
  5006. xgood := false;
  5007. exit;
  5008. elsif founddot then
  5009. errmes ("Two ""."" encounted in input string");
  5010. xgood := false;
  5011. exit;
  5012. end if;
  5013. founddot := true;
  5014. lastu := false;
  5015. else
  5016. Char2TriBits(c, nybble, xgood, message);
  5017. if not xgood then
  5018. exit;
  5019. end if;
  5020. slv (i downto i-2) := nybble;
  5021. i := i - 3;
  5022. lastu := false;
  5023. end if;
  5024. if i > 0 then
  5025. read (L, c, xgood);
  5026. end if;
  5027. end loop;
  5028. idex := i;
  5029. igood := xgood;
  5030. else
  5031. igood := true; -- read into a null array
  5032. idex := -1;
  5033. end if;
  5034. end procedure OREAD_common;
  5035. -- Note that for Octal and Hex read, you can not start with a ".",
  5036. -- the read is for numbers formatted "A.BC". These routines go to
  5037. -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
  5038. procedure OREAD (L : inout LINE;
  5039. VALUE : out UNRESOLVED_ufixed) is
  5040. constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
  5041. constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
  5042. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5043. variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
  5044. variable igood : BOOLEAN;
  5045. variable i : INTEGER;
  5046. begin
  5047. VALUE := (VALUE'range => 'U');
  5048. OREAD_common ( L => L,
  5049. slv => slv,
  5050. igood => igood,
  5051. idex => i,
  5052. bpoint => -lbv,
  5053. message => true,
  5054. smath => false);
  5055. if igood then -- We did not get another error
  5056. if not ((i = -1) and -- We read everything, and high bits 0
  5057. (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
  5058. report fixed_generic_pkg'instance_name
  5059. & "OREAD(ufixed): Vector truncated."
  5060. severity error;
  5061. else
  5062. if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
  5063. assert no_warning
  5064. report fixed_generic_pkg'instance_name
  5065. & "OREAD(ufixed): Vector truncated"
  5066. severity warning;
  5067. end if;
  5068. valuex := to_ufixed (slv, hbv, lbv);
  5069. VALUE := valuex (VALUE'range);
  5070. end if;
  5071. end if;
  5072. end procedure OREAD;
  5073. procedure OREAD(L : inout LINE;
  5074. VALUE : out UNRESOLVED_ufixed;
  5075. GOOD : out BOOLEAN) is
  5076. constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
  5077. constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
  5078. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5079. variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
  5080. variable igood : BOOLEAN;
  5081. variable i : INTEGER;
  5082. begin
  5083. VALUE := (VALUE'range => 'U');
  5084. OREAD_common ( L => L,
  5085. slv => slv,
  5086. igood => igood,
  5087. idex => i,
  5088. bpoint => -lbv,
  5089. message => false,
  5090. smath => false);
  5091. if (igood and -- We did not get another error
  5092. (i = -1) and -- We read everything, and high bits 0
  5093. (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
  5094. valuex := to_ufixed (slv, hbv, lbv);
  5095. VALUE := valuex (VALUE'range);
  5096. GOOD := true;
  5097. else
  5098. GOOD := false;
  5099. end if;
  5100. end procedure OREAD;
  5101. procedure OREAD(L : inout LINE;
  5102. VALUE : out UNRESOLVED_sfixed) is
  5103. constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
  5104. constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
  5105. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5106. variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
  5107. variable igood : BOOLEAN;
  5108. variable i : INTEGER;
  5109. begin
  5110. VALUE := (VALUE'range => 'U');
  5111. OREAD_common ( L => L,
  5112. slv => slv,
  5113. igood => igood,
  5114. idex => i,
  5115. bpoint => -lbv,
  5116. message => true,
  5117. smath => true);
  5118. if igood then -- We did not get another error
  5119. if not ((i = -1) and -- We read everything
  5120. ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
  5121. or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
  5122. (slv(VALUE'high-lbv) = '1' and
  5123. and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
  5124. report fixed_generic_pkg'instance_name
  5125. & "OREAD(sfixed): Vector truncated."
  5126. severity error;
  5127. else
  5128. if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
  5129. assert no_warning
  5130. report fixed_generic_pkg'instance_name
  5131. & "OREAD(sfixed): Vector truncated"
  5132. severity warning;
  5133. end if;
  5134. valuex := to_sfixed (slv, hbv, lbv);
  5135. VALUE := valuex (VALUE'range);
  5136. end if;
  5137. end if;
  5138. end procedure OREAD;
  5139. procedure OREAD(L : inout LINE;
  5140. VALUE : out UNRESOLVED_sfixed;
  5141. GOOD : out BOOLEAN) is
  5142. constant hbv : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
  5143. constant lbv : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
  5144. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5145. variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
  5146. variable igood : BOOLEAN;
  5147. variable i : INTEGER;
  5148. begin
  5149. VALUE := (VALUE'range => 'U');
  5150. OREAD_common ( L => L,
  5151. slv => slv,
  5152. igood => igood,
  5153. idex => i,
  5154. bpoint => -lbv,
  5155. message => false,
  5156. smath => true);
  5157. if (igood -- We did not get another error
  5158. and (i = -1) -- We read everything
  5159. and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
  5160. or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
  5161. (slv(VALUE'high-lbv) = '1' and
  5162. and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
  5163. valuex := to_sfixed (slv, hbv, lbv);
  5164. VALUE := valuex (VALUE'range);
  5165. GOOD := true;
  5166. else
  5167. GOOD := false;
  5168. end if;
  5169. end procedure OREAD;
  5170. -- hex read and write
  5171. procedure hwrite (
  5172. L : inout LINE; -- input line
  5173. VALUE : in UNRESOLVED_ufixed; -- fixed point input
  5174. JUSTIFIED : in SIDE := right;
  5175. FIELD : in WIDTH := 0) is
  5176. begin -- Example 03.30
  5177. write (L => L,
  5178. VALUE => TO_HSTRING (VALUE),
  5179. JUSTIFIED => JUSTIFIED,
  5180. FIELD => FIELD);
  5181. end procedure hwrite;
  5182. -- purpose: writes fixed point into a line
  5183. procedure hwrite (
  5184. L : inout LINE; -- input line
  5185. VALUE : in UNRESOLVED_sfixed; -- fixed point input
  5186. JUSTIFIED : in SIDE := right;
  5187. FIELD : in WIDTH := 0) is
  5188. begin -- Example 03.30
  5189. write (L => L,
  5190. VALUE => TO_HSTRING (VALUE),
  5191. JUSTIFIED => JUSTIFIED,
  5192. FIELD => FIELD);
  5193. end procedure hwrite;
  5194. -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
  5195. -- Modified from the original to be more forgiving.
  5196. procedure Char2QuadBits (C : CHARACTER;
  5197. RESULT : out STD_ULOGIC_VECTOR(3 downto 0);
  5198. GOOD : out BOOLEAN;
  5199. ISSUE_ERROR : in BOOLEAN) is
  5200. begin
  5201. case C is
  5202. when '0' => RESULT := x"0"; GOOD := true;
  5203. when '1' => RESULT := x"1"; GOOD := true;
  5204. when '2' => RESULT := x"2"; GOOD := true;
  5205. when '3' => RESULT := x"3"; GOOD := true;
  5206. when '4' => RESULT := x"4"; GOOD := true;
  5207. when '5' => RESULT := x"5"; GOOD := true;
  5208. when '6' => RESULT := x"6"; GOOD := true;
  5209. when '7' => RESULT := x"7"; GOOD := true;
  5210. when '8' => RESULT := x"8"; GOOD := true;
  5211. when '9' => RESULT := x"9"; GOOD := true;
  5212. when 'A' | 'a' => RESULT := x"A"; GOOD := true;
  5213. when 'B' | 'b' => RESULT := x"B"; GOOD := true;
  5214. when 'C' | 'c' => RESULT := x"C"; GOOD := true;
  5215. when 'D' | 'd' => RESULT := x"D"; GOOD := true;
  5216. when 'E' | 'e' => RESULT := x"E"; GOOD := true;
  5217. when 'F' | 'f' => RESULT := x"F"; GOOD := true;
  5218. when 'Z' => RESULT := "ZZZZ"; GOOD := true;
  5219. when 'X' => RESULT := "XXXX"; GOOD := true;
  5220. when others =>
  5221. assert not ISSUE_ERROR
  5222. report fixed_generic_pkg'instance_name
  5223. & "HREAD Error: Read a '" & C &
  5224. "', expected a Hex character (0-F)."
  5225. severity error;
  5226. RESULT := "UUUU";
  5227. GOOD := false;
  5228. end case;
  5229. end procedure Char2QuadBits;
  5230. -- purpose: Routines common to the HREAD routines
  5231. procedure HREAD_common (
  5232. L : inout LINE;
  5233. slv : out STD_ULOGIC_VECTOR;
  5234. igood : out BOOLEAN;
  5235. idex : out INTEGER;
  5236. constant bpoint : in INTEGER; -- binary point
  5237. constant message : in BOOLEAN;
  5238. constant smath : in BOOLEAN) is
  5239. -- purpose: error message routine
  5240. procedure errmes (
  5241. constant mess : in STRING) is -- error message
  5242. begin
  5243. if message then
  5244. if smath then
  5245. report fixed_generic_pkg'instance_name
  5246. & "HREAD(sfixed) "
  5247. & mess
  5248. severity error;
  5249. else
  5250. report fixed_generic_pkg'instance_name
  5251. & "HREAD(ufixed) "
  5252. & mess
  5253. severity error;
  5254. end if;
  5255. end if;
  5256. end procedure errmes;
  5257. variable xgood : BOOLEAN;
  5258. variable nybble : STD_ULOGIC_VECTOR (3 downto 0); -- 4 bits
  5259. variable c : CHARACTER;
  5260. variable i : INTEGER;
  5261. variable lastu : BOOLEAN := false; -- last character was an "_"
  5262. variable founddot : BOOLEAN := false; -- found a dot.
  5263. begin
  5264. skip_whitespace (L);
  5265. if slv'length > 0 then
  5266. i := slv'high;
  5267. read (L, c, xgood);
  5268. while i > 0 loop
  5269. if xgood = false then
  5270. errmes ("Error: end of string encountered");
  5271. exit;
  5272. elsif c = '_' then
  5273. if i = slv'length then
  5274. errmes ("Error: String begins with an ""_""");
  5275. xgood := false;
  5276. exit;
  5277. elsif lastu then
  5278. errmes ("Error: Two underscores detected in input string ""__""");
  5279. xgood := false;
  5280. exit;
  5281. else
  5282. lastu := true;
  5283. end if;
  5284. elsif (c = '.') then
  5285. if (i + 1 /= bpoint) then
  5286. errmes ("encountered ""."" at wrong index");
  5287. xgood := false;
  5288. exit;
  5289. elsif i = slv'length then
  5290. errmes ("encounted a ""."" at the beginning of the line");
  5291. xgood := false;
  5292. exit;
  5293. elsif founddot then
  5294. errmes ("Two ""."" encounted in input string");
  5295. xgood := false;
  5296. exit;
  5297. end if;
  5298. founddot := true;
  5299. lastu := false;
  5300. else
  5301. Char2QuadBits(c, nybble, xgood, message);
  5302. if not xgood then
  5303. exit;
  5304. end if;
  5305. slv (i downto i-3) := nybble;
  5306. i := i - 4;
  5307. lastu := false;
  5308. end if;
  5309. if i > 0 then
  5310. read (L, c, xgood);
  5311. end if;
  5312. end loop;
  5313. idex := i;
  5314. igood := xgood;
  5315. else
  5316. idex := -1;
  5317. igood := true; -- read null string
  5318. end if;
  5319. end procedure HREAD_common;
  5320. procedure HREAD(L : inout LINE;
  5321. VALUE : out UNRESOLVED_ufixed) is
  5322. constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
  5323. constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
  5324. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5325. variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
  5326. variable igood : BOOLEAN;
  5327. variable i : INTEGER;
  5328. begin
  5329. VALUE := (VALUE'range => 'U');
  5330. HREAD_common ( L => L,
  5331. slv => slv,
  5332. igood => igood,
  5333. idex => i,
  5334. bpoint => -lbv,
  5335. message => true,
  5336. smath => false);
  5337. if igood then
  5338. if not ((i = -1) and -- We read everything, and high bits 0
  5339. (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
  5340. report fixed_generic_pkg'instance_name
  5341. & "HREAD(ufixed): Vector truncated."
  5342. severity error;
  5343. else
  5344. if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
  5345. assert no_warning
  5346. report fixed_generic_pkg'instance_name
  5347. & "HREAD(ufixed): Vector truncated"
  5348. severity warning;
  5349. end if;
  5350. valuex := to_ufixed (slv, hbv, lbv);
  5351. VALUE := valuex (VALUE'range);
  5352. end if;
  5353. end if;
  5354. end procedure HREAD;
  5355. procedure HREAD(L : inout LINE;
  5356. VALUE : out UNRESOLVED_ufixed;
  5357. GOOD : out BOOLEAN) is
  5358. constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
  5359. constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
  5360. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5361. variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
  5362. variable igood : BOOLEAN;
  5363. variable i : INTEGER;
  5364. begin
  5365. VALUE := (VALUE'range => 'U');
  5366. HREAD_common ( L => L,
  5367. slv => slv,
  5368. igood => igood,
  5369. idex => i,
  5370. bpoint => -lbv,
  5371. message => false,
  5372. smath => false);
  5373. if (igood and -- We did not get another error
  5374. (i = -1) and -- We read everything, and high bits 0
  5375. (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
  5376. valuex := to_ufixed (slv, hbv, lbv);
  5377. VALUE := valuex (VALUE'range);
  5378. GOOD := true;
  5379. else
  5380. GOOD := false;
  5381. end if;
  5382. end procedure HREAD;
  5383. procedure HREAD(L : inout LINE;
  5384. VALUE : out UNRESOLVED_sfixed) is
  5385. constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
  5386. constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
  5387. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5388. variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
  5389. variable igood : BOOLEAN;
  5390. variable i : INTEGER;
  5391. begin
  5392. VALUE := (VALUE'range => 'U');
  5393. HREAD_common ( L => L,
  5394. slv => slv,
  5395. igood => igood,
  5396. idex => i,
  5397. bpoint => -lbv,
  5398. message => true,
  5399. smath => true);
  5400. if igood then -- We did not get another error
  5401. if not ((i = -1) -- We read everything
  5402. and ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
  5403. or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
  5404. (slv(VALUE'high-lbv) = '1' and
  5405. and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
  5406. report fixed_generic_pkg'instance_name
  5407. & "HREAD(sfixed): Vector truncated."
  5408. severity error;
  5409. else
  5410. if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
  5411. assert no_warning
  5412. report fixed_generic_pkg'instance_name
  5413. & "HREAD(sfixed): Vector truncated"
  5414. severity warning;
  5415. end if;
  5416. valuex := to_sfixed (slv, hbv, lbv);
  5417. VALUE := valuex (VALUE'range);
  5418. end if;
  5419. end if;
  5420. end procedure HREAD;
  5421. procedure HREAD(L : inout LINE;
  5422. VALUE : out UNRESOLVED_sfixed;
  5423. GOOD : out BOOLEAN) is
  5424. constant hbv : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
  5425. constant lbv : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
  5426. variable slv : STD_ULOGIC_VECTOR (hbv-lbv downto 0); -- high bits
  5427. variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
  5428. variable igood : BOOLEAN;
  5429. variable i : INTEGER;
  5430. begin
  5431. VALUE := (VALUE'range => 'U');
  5432. HREAD_common ( L => L,
  5433. slv => slv,
  5434. igood => igood,
  5435. idex => i,
  5436. bpoint => -lbv,
  5437. message => false,
  5438. smath => true);
  5439. if (igood and -- We did not get another error
  5440. (i = -1) and -- We read everything
  5441. ((slv(VALUE'high-lbv) = '0' and -- sign bits = extra bits
  5442. or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
  5443. (slv(VALUE'high-lbv) = '1' and
  5444. and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
  5445. valuex := to_sfixed (slv, hbv, lbv);
  5446. VALUE := valuex (VALUE'range);
  5447. GOOD := true;
  5448. else
  5449. GOOD := false;
  5450. end if;
  5451. end procedure HREAD;
  5452. -- TO_STRING functions. Useful in "report" statements.
  5453. -- Example: report "result was " & TO_STRING(result);
  5454. function TO_STRING (value : UNRESOLVED_ufixed) return STRING is
  5455. variable s : STRING(1 to value'length +1) := (others => ' ');
  5456. variable subval : UNRESOLVED_ufixed (value'high downto -1);
  5457. variable sindx : INTEGER;
  5458. begin
  5459. if value'length < 1 then
  5460. return NUS;
  5461. else
  5462. if value'high < 0 then
  5463. if value(value'high) = 'Z' then
  5464. return TO_STRING (resize (sfixed(value), 0, value'low));
  5465. else
  5466. return TO_STRING (resize (value, 0, value'low));
  5467. end if;
  5468. elsif value'low >= 0 then
  5469. if Is_X (value(value'low)) then
  5470. subval := (others => value(value'low));
  5471. subval (value'range) := value;
  5472. return TO_STRING(subval);
  5473. else
  5474. return TO_STRING (resize (value, value'high, -1));
  5475. end if;
  5476. else
  5477. sindx := 1;
  5478. for i in value'high downto value'low loop
  5479. if i = -1 then
  5480. s(sindx) := '.';
  5481. sindx := sindx + 1;
  5482. end if;
  5483. s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
  5484. sindx := sindx + 1;
  5485. end loop;
  5486. return s;
  5487. end if;
  5488. end if;
  5489. end function TO_STRING;
  5490. function TO_STRING (value : UNRESOLVED_sfixed) return STRING is
  5491. variable s : STRING(1 to value'length + 1) := (others => ' ');
  5492. variable subval : UNRESOLVED_sfixed (value'high downto -1);
  5493. variable sindx : INTEGER;
  5494. begin
  5495. if value'length < 1 then
  5496. return NUS;
  5497. else
  5498. if value'high < 0 then
  5499. return TO_STRING (resize (value, 0, value'low));
  5500. elsif value'low >= 0 then
  5501. if Is_X (value(value'low)) then
  5502. subval := (others => value(value'low));
  5503. subval (value'range) := value;
  5504. return TO_STRING(subval);
  5505. else
  5506. return TO_STRING (resize (value, value'high, -1));
  5507. end if;
  5508. else
  5509. sindx := 1;
  5510. for i in value'high downto value'low loop
  5511. if i = -1 then
  5512. s(sindx) := '.';
  5513. sindx := sindx + 1;
  5514. end if;
  5515. s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
  5516. sindx := sindx + 1;
  5517. end loop;
  5518. return s;
  5519. end if;
  5520. end if;
  5521. end function TO_STRING;
  5522. function TO_OSTRING (value : UNRESOLVED_ufixed) return STRING is
  5523. constant lne : INTEGER := (-value'low+2)/3;
  5524. variable subval : UNRESOLVED_ufixed (value'high downto -3);
  5525. variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1);
  5526. variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
  5527. begin
  5528. if value'length < 1 then
  5529. return NUS;
  5530. else
  5531. if value'high < 0 then
  5532. if value(value'high) = 'Z' then
  5533. return TO_OSTRING (resize (sfixed(value), 2, value'low));
  5534. else
  5535. return TO_OSTRING (resize (value, 2, value'low));
  5536. end if;
  5537. elsif value'low >= 0 then
  5538. if Is_X (value(value'low)) then
  5539. subval := (others => value(value'low));
  5540. subval (value'range) := value;
  5541. return TO_OSTRING(subval);
  5542. else
  5543. return TO_OSTRING (resize (value, value'high, -3));
  5544. end if;
  5545. else
  5546. slv := to_sulv (value);
  5547. if Is_X (value (value'low)) then
  5548. lpad := (others => value (value'low));
  5549. else
  5550. lpad := (others => '0');
  5551. end if;
  5552. return TO_OSTRING(slv(slv'high downto slv'high-value'high))
  5553. & "."
  5554. & TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
  5555. end if;
  5556. end if;
  5557. end function TO_OSTRING;
  5558. function TO_HSTRING (value : UNRESOLVED_ufixed) return STRING is
  5559. constant lne : INTEGER := (-value'low+3)/4;
  5560. variable subval : UNRESOLVED_ufixed (value'high downto -4);
  5561. variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1);
  5562. variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
  5563. begin
  5564. if value'length < 1 then
  5565. return NUS;
  5566. else
  5567. if value'high < 0 then
  5568. if value(value'high) = 'Z' then
  5569. return TO_HSTRING (resize (sfixed(value), 3, value'low));
  5570. else
  5571. return TO_HSTRING (resize (value, 3, value'low));
  5572. end if;
  5573. elsif value'low >= 0 then
  5574. if Is_X (value(value'low)) then
  5575. subval := (others => value(value'low));
  5576. subval (value'range) := value;
  5577. return TO_HSTRING(subval);
  5578. else
  5579. return TO_HSTRING (resize (value, value'high, -4));
  5580. end if;
  5581. else
  5582. slv := to_sulv (value);
  5583. if Is_X (value (value'low)) then
  5584. lpad := (others => value(value'low));
  5585. else
  5586. lpad := (others => '0');
  5587. end if;
  5588. return TO_HSTRING(slv(slv'high downto slv'high-value'high))
  5589. & "."
  5590. & TO_HSTRING(slv(slv'high-value'high-1 downto 0)&lpad);
  5591. end if;
  5592. end if;
  5593. end function TO_HSTRING;
  5594. function TO_OSTRING (value : UNRESOLVED_sfixed) return STRING is
  5595. constant ne : INTEGER := ((value'high+1)+2)/3;
  5596. variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - (value'high+1)) - 1);
  5597. constant lne : INTEGER := (-value'low+2)/3;
  5598. variable subval : UNRESOLVED_sfixed (value'high downto -3);
  5599. variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1);
  5600. variable slv : STD_ULOGIC_VECTOR (value'high - value'low downto 0);
  5601. begin
  5602. if value'length < 1 then
  5603. return NUS;
  5604. else
  5605. if value'high < 0 then
  5606. return TO_OSTRING (resize (value, 2, value'low));
  5607. elsif value'low >= 0 then
  5608. if Is_X (value(value'low)) then
  5609. subval := (others => value(value'low));
  5610. subval (value'range) := value;
  5611. return TO_OSTRING(subval);
  5612. else
  5613. return TO_OSTRING (resize (value, value'high, -3));
  5614. end if;
  5615. else
  5616. pad := (others => value(value'high));
  5617. slv := to_sulv (value);
  5618. if Is_X (value (value'low)) then
  5619. lpad := (others => value(value'low));
  5620. else
  5621. lpad := (others => '0');
  5622. end if;
  5623. return TO_OSTRING(pad & slv(slv'high downto slv'high-value'high))
  5624. & "."
  5625. & TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
  5626. end if;
  5627. end if;
  5628. end function TO_OSTRING;
  5629. function TO_HSTRING (value : UNRESOLVED_sfixed) return STRING is
  5630. constant ne : INTEGER := ((value'high+1)+3)/4;
  5631. variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - (value'high+1)) - 1);
  5632. constant lne : INTEGER := (-value'low+3)/4;
  5633. variable subval : UNRESOLVED_sfixed (value'high downto -4);
  5634. variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1);
  5635. variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
  5636. begin
  5637. if value'length < 1 then
  5638. return NUS;
  5639. else
  5640. if value'high < 0 then
  5641. return TO_HSTRING (resize (value, 3, value'low));
  5642. elsif value'low >= 0 then
  5643. if Is_X (value(value'low)) then
  5644. subval := (others => value(value'low));
  5645. subval (value'range) := value;
  5646. return TO_HSTRING(subval);
  5647. else
  5648. return TO_HSTRING (resize (value, value'high, -4));
  5649. end if;
  5650. else
  5651. slv := to_sulv (value);
  5652. pad := (others => value(value'high));
  5653. if Is_X (value (value'low)) then
  5654. lpad := (others => value(value'low));
  5655. else
  5656. lpad := (others => '0');
  5657. end if;
  5658. return TO_HSTRING(pad & slv(slv'high downto slv'high-value'high))
  5659. & "."
  5660. & TO_HSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
  5661. end if;
  5662. end if;
  5663. end function TO_HSTRING;
  5664. -- From string functions allow you to convert a string into a fixed
  5665. -- point number. Example:
  5666. -- signal uf1 : ufixed (3 downto -3);
  5667. -- uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5
  5668. -- The "." is optional in this syntax, however it exist and is
  5669. -- in the wrong location an error is produced. Overflow will
  5670. -- result in saturation.
  5671. function from_string (
  5672. bstring : STRING; -- binary string
  5673. constant left_index : INTEGER;
  5674. constant right_index : INTEGER)
  5675. return UNRESOLVED_ufixed
  5676. is
  5677. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  5678. variable L : LINE;
  5679. variable good : BOOLEAN;
  5680. begin
  5681. L := new STRING'(bstring);
  5682. READ (L, result, good);
  5683. deallocate (L);
  5684. assert (good)
  5685. report fixed_generic_pkg'instance_name
  5686. & "from_string: Bad string "& bstring severity error;
  5687. return result;
  5688. end function from_string;
  5689. -- Octal and hex conversions work as follows:
  5690. -- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
  5691. -- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
  5692. function from_ostring (
  5693. ostring : STRING; -- Octal string
  5694. constant left_index : INTEGER;
  5695. constant right_index : INTEGER)
  5696. return UNRESOLVED_ufixed
  5697. is
  5698. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  5699. variable L : LINE;
  5700. variable good : BOOLEAN;
  5701. begin
  5702. L := new STRING'(ostring);
  5703. OREAD (L, result, good);
  5704. deallocate (L);
  5705. assert (good)
  5706. report fixed_generic_pkg'instance_name
  5707. & "from_ostring: Bad string "& ostring severity error;
  5708. return result;
  5709. end function from_ostring;
  5710. function from_hstring (
  5711. hstring : STRING; -- hex string
  5712. constant left_index : INTEGER;
  5713. constant right_index : INTEGER)
  5714. return UNRESOLVED_ufixed
  5715. is
  5716. variable result : UNRESOLVED_ufixed (left_index downto right_index);
  5717. variable L : LINE;
  5718. variable good : BOOLEAN;
  5719. begin
  5720. L := new STRING'(hstring);
  5721. HREAD (L, result, good);
  5722. deallocate (L);
  5723. assert (good)
  5724. report fixed_generic_pkg'instance_name
  5725. & "from_hstring: Bad string "& hstring severity error;
  5726. return result;
  5727. end function from_hstring;
  5728. function from_string (
  5729. bstring : STRING; -- binary string
  5730. constant left_index : INTEGER;
  5731. constant right_index : INTEGER)
  5732. return UNRESOLVED_sfixed
  5733. is
  5734. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  5735. variable L : LINE;
  5736. variable good : BOOLEAN;
  5737. begin
  5738. L := new STRING'(bstring);
  5739. READ (L, result, good);
  5740. deallocate (L);
  5741. assert (good)
  5742. report fixed_generic_pkg'instance_name
  5743. & "from_string: Bad string "& bstring severity error;
  5744. return result;
  5745. end function from_string;
  5746. function from_ostring (
  5747. ostring : STRING; -- Octal string
  5748. constant left_index : INTEGER;
  5749. constant right_index : INTEGER)
  5750. return UNRESOLVED_sfixed
  5751. is
  5752. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  5753. variable L : LINE;
  5754. variable good : BOOLEAN;
  5755. begin
  5756. L := new STRING'(ostring);
  5757. OREAD (L, result, good);
  5758. deallocate (L);
  5759. assert (good)
  5760. report fixed_generic_pkg'instance_name
  5761. & "from_ostring: Bad string "& ostring severity error;
  5762. return result;
  5763. end function from_ostring;
  5764. function from_hstring (
  5765. hstring : STRING; -- hex string
  5766. constant left_index : INTEGER;
  5767. constant right_index : INTEGER)
  5768. return UNRESOLVED_sfixed
  5769. is
  5770. variable result : UNRESOLVED_sfixed (left_index downto right_index);
  5771. variable L : LINE;
  5772. variable good : BOOLEAN;
  5773. begin
  5774. L := new STRING'(hstring);
  5775. HREAD (L, result, good);
  5776. deallocate (L);
  5777. assert (good)
  5778. report fixed_generic_pkg'instance_name
  5779. & "from_hstring: Bad string "& hstring severity error;
  5780. return result;
  5781. end function from_hstring;
  5782. -- Same as above, "size_res" is used for it's range only.
  5783. function from_string (
  5784. bstring : STRING; -- binary string
  5785. size_res : UNRESOLVED_ufixed)
  5786. return UNRESOLVED_ufixed is
  5787. begin
  5788. return from_string (bstring, size_res'high, size_res'low);
  5789. end function from_string;
  5790. function from_ostring (
  5791. ostring : STRING; -- Octal string
  5792. size_res : UNRESOLVED_ufixed)
  5793. return UNRESOLVED_ufixed is
  5794. begin
  5795. return from_ostring (ostring, size_res'high, size_res'low);
  5796. end function from_ostring;
  5797. function from_hstring (
  5798. hstring : STRING; -- hex string
  5799. size_res : UNRESOLVED_ufixed)
  5800. return UNRESOLVED_ufixed is
  5801. begin
  5802. return from_hstring(hstring, size_res'high, size_res'low);
  5803. end function from_hstring;
  5804. function from_string (
  5805. bstring : STRING; -- binary string
  5806. size_res : UNRESOLVED_sfixed)
  5807. return UNRESOLVED_sfixed is
  5808. begin
  5809. return from_string (bstring, size_res'high, size_res'low);
  5810. end function from_string;
  5811. function from_ostring (
  5812. ostring : STRING; -- Octal string
  5813. size_res : UNRESOLVED_sfixed)
  5814. return UNRESOLVED_sfixed is
  5815. begin
  5816. return from_ostring (ostring, size_res'high, size_res'low);
  5817. end function from_ostring;
  5818. function from_hstring (
  5819. hstring : STRING; -- hex string
  5820. size_res : UNRESOLVED_sfixed)
  5821. return UNRESOLVED_sfixed is
  5822. begin
  5823. return from_hstring (hstring, size_res'high, size_res'low);
  5824. end function from_hstring;
  5825. -- Direct conversion functions. Example:
  5826. -- signal uf1 : ufixed (3 downto -3);
  5827. -- uf1 <= from_string ("0110.100"); -- 6.5
  5828. -- In this case the "." is not optional, and the size of
  5829. -- the output must match exactly.
  5830. -- purpose: Calculate the string boundaries
  5831. procedure calculate_string_boundry (
  5832. arg : in STRING; -- input string
  5833. left_index : out INTEGER; -- left
  5834. right_index : out INTEGER) is -- right
  5835. -- examples "10001.111" would return +4, -3
  5836. -- "07X.44" would return +2, -2 (then the octal routine would multiply)
  5837. -- "A_B_._C" would return +1, -1 (then the hex routine would multiply)
  5838. alias xarg : STRING (arg'length downto 1) is arg; -- make it downto range
  5839. variable l, r : INTEGER; -- internal indexes
  5840. variable founddot : BOOLEAN := false;
  5841. begin
  5842. if arg'length > 0 then
  5843. l := xarg'high - 1;
  5844. r := 0;
  5845. for i in xarg'range loop
  5846. if xarg(i) = '_' then
  5847. if r = 0 then
  5848. l := l - 1;
  5849. else
  5850. r := r + 1;
  5851. end if;
  5852. elsif xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT then
  5853. report fixed_generic_pkg'instance_name
  5854. & "Found a space in the input STRING " & xarg
  5855. severity error;
  5856. elsif xarg(i) = '.' then
  5857. if founddot then
  5858. report fixed_generic_pkg'instance_name
  5859. & "Found two binary points in input string " & xarg
  5860. severity error;
  5861. else
  5862. l := l - i;
  5863. r := -i + 1;
  5864. founddot := true;
  5865. end if;
  5866. end if;
  5867. end loop;
  5868. left_index := l;
  5869. right_index := r;
  5870. else
  5871. left_index := 0;
  5872. right_index := 0;
  5873. end if;
  5874. end procedure calculate_string_boundry;
  5875. -- Direct conversion functions. Example:
  5876. -- signal uf1 : ufixed (3 downto -3);
  5877. -- uf1 <= from_string ("0110.100"); -- 6.5
  5878. -- In this case the "." is not optional, and the size of
  5879. -- the output must match exactly.
  5880. function from_string (
  5881. bstring : STRING) -- binary string
  5882. return UNRESOLVED_ufixed
  5883. is
  5884. variable left_index, right_index : INTEGER;
  5885. begin
  5886. calculate_string_boundry (bstring, left_index, right_index);
  5887. return from_string (bstring, left_index, right_index);
  5888. end function from_string;
  5889. -- Direct octal and hex conversion functions. In this case
  5890. -- the string lengths must match. Example:
  5891. -- signal sf1 := sfixed (5 downto -3);
  5892. -- sf1 <= from_ostring ("71.4") -- -6.5
  5893. function from_ostring (
  5894. ostring : STRING) -- Octal string
  5895. return UNRESOLVED_ufixed
  5896. is
  5897. variable left_index, right_index : INTEGER;
  5898. begin
  5899. calculate_string_boundry (ostring, left_index, right_index);
  5900. return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
  5901. end function from_ostring;
  5902. function from_hstring (
  5903. hstring : STRING) -- hex string
  5904. return UNRESOLVED_ufixed
  5905. is
  5906. variable left_index, right_index : INTEGER;
  5907. begin
  5908. calculate_string_boundry (hstring, left_index, right_index);
  5909. return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
  5910. end function from_hstring;
  5911. function from_string (
  5912. bstring : STRING) -- binary string
  5913. return UNRESOLVED_sfixed
  5914. is
  5915. variable left_index, right_index : INTEGER;
  5916. begin
  5917. calculate_string_boundry (bstring, left_index, right_index);
  5918. return from_string (bstring, left_index, right_index);
  5919. end function from_string;
  5920. function from_ostring (
  5921. ostring : STRING) -- Octal string
  5922. return UNRESOLVED_sfixed
  5923. is
  5924. variable left_index, right_index : INTEGER;
  5925. begin
  5926. calculate_string_boundry (ostring, left_index, right_index);
  5927. return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
  5928. end function from_ostring;
  5929. function from_hstring (
  5930. hstring : STRING) -- hex string
  5931. return UNRESOLVED_sfixed
  5932. is
  5933. variable left_index, right_index : INTEGER;
  5934. begin
  5935. calculate_string_boundry (hstring, left_index, right_index);
  5936. return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
  5937. end function from_hstring;
  5938. end package body fixed_generic_pkg;