diff --git a/hls/auto/auto_compile.c b/hls/auto/auto_compile.c new file mode 100755 index 0000000000000000000000000000000000000000..2568d2ddb93a25cddde1a7921ca5abff3a4336fc --- /dev/null +++ b/hls/auto/auto_compile.c @@ -0,0 +1,30 @@ +#include +#include + +#define STRLEN 65536 + +int main(void){ + + char q[STRLEN], command[STRLEN]; + char dir[64] = "../lines256_length128"; + + FILE *fp; + fp = fopen("q.txt", "r"); + if(fp == NULL){ + printf("File does not exist.\n"); + exit(1); + } + + int counter = 1; + while(1){ + if(fscanf(fp, "%s", q) == EOF) break; + printf("Q. %d\n", counter++); + sprintf(command, "./%s/sim.exe %s", dir, q); + //printf("(command) %s\n", command); + int ret = system(command); + printf("ret: %d\n", ret); + } + fclose(fp); + return 0; +} + diff --git a/hls/auto/q.txt b/hls/auto/q.txt new file mode 100755 index 0000000000000000000000000000000000000000..13214da649192a4f4410353f0c022f8c1bb1f097 --- /dev/null +++ b/hls/auto/q.txt @@ -0,0 +1,29 @@ +X24Y24Z4L0613304164L1702122032L0101403204L1601420204L2117419044L0023116021L1520309084L1921116154L1709121031L1812103211L0905208142L0704412013L0421110094L2320100142L1500319034L0915104123L0907418124L2001109101L0122202213L2102422011L2120105211L2319117132L0404119103L1215322223L0607218074L1715113123L1217220172L1602320113L0003306053L0405413144L2006421214L1301103212L0614322183L1108323004L0004322043L0602322213L1210120142L1321419172L1202116012L1303103081L0820211202L1003116142L1701305123L0312223072L0720301063L1202214024L0506207072L1610417224L1309404154L1201408124L1704410064L0822110211L1210321153L1708116072L0000100111L0201112011L0808104103L0923210212L1210413134L1500421014 +X15Y15Z2L0202212102L0303211112L0404210122L0503209112L0402210102L0204212122L0203212112L0302211102L0403210112L0504209122L0502209102L0304211122 +X20Y20Z8L0203202066L0400403037L0403105088L0503101016L0500206038L0703317055L1001104054L0505317087L0108204086L0111101177L0810406188L0313406138L0413215177L0513106176L0317302158L0715100195L0318307064L1503212048L1702112058L1206318087L1007417036L1101317047L1406216094L1111217187L1310418146L1510315145L1014310177L1317219198L0919218177 +X72Y72Z8L0000171718L0036871001L0000800718L0036171008L0071171711L3671171368 +X08Y08Z4L0000107072L0100103032L0007106072L0503106032L0506101062L0001205062L0404106051L0700207032L0201202032L0205203052L0000307074L0100303034L0007306074L0503306034L0506301064L0001405064L0404306053L0700407034L0201402034L0205403054 +X48Y36Z8L0609109051L0608108091L0709109021L0306109041L0204109091L0207105091L0208105041L0209104041L0607109031L0516105191L0417106171L0418106181L0113103131L0213104211L0214107211L0413110211L0814108211L0221110221L0226103321L0331104251L0128105321L0329108321L0733109261L0629107261L0630107271L0233106281L1400123101L1503123061L1504122101L1508122081L1509122011L1606118111L1702122041L1212119211L1319115141L1316120151L1217118171L1313119221L2020122121L1517116221L1421116171L1527123351L1328120261L1533122251L1830121311L1334120291L1426119261L1632119251L1730122291L1431121341L2501131011L2708128051L2800134051L3400135111L2400132031L2704132081L2406125021L2504133101L2401128101L2522134151L2921134161L2513134171L3013134221L2614130171L3019135191L2415130181L3414135121L3524135341L2533135281L2727135351L2435129311L2734129351L2829131331L2833132321L3607146111L4207147111L4010147001L3600137101L3608144021L4509146051L4020145141L3614141151L4218147231L3612145201L3712143141L3623144181L3912146231L3624144301L4030147241L3635137321L3835147351L4132146351L3634145311L3726144291L3733142281L2935227213L0629622066L0606335013L1728617245L0814411182L2608416057 +X72Y72Z8L0000166038L0004128038L0013104688L0016158688L0030133688L0046120038L0071149038L7165169688 +X15Y15Z2L0602214082L1406114081L0901111112L0110100072L0405209012L1108112071L0707208011L0301107002L0014101142L0405103072L0006203042L1008111071L1301214132L1403114012L1404210011L1113207112L0206206052L0603104031L1211110121L0512202141L0201203032L0105101042L0809209062L0609100121L0501204022L1110211082L0809112091L0000201001L1304114051L0102100001L1114113141L0401101012L1007109132L0714204131L1005110031L0611103112L0112102131L0208102061L0708206092L0007100101L1409214112L1300211002L0501106001L1114212142L0511104111L0704107031L0702208022 +X23Y12Z6L0303122021L1102219103L0503504065L0302105101L0200305093L0907100081L1309100071L0706221102L0500212014L0301605026L0104216063L0204408034L0910502106L1805113052L1406116041L0409310114L2106122103L1710201033L0510412024L1411222072L1503421106L1310519035L1306220044L0101201112L1701221014L0802503105L0603107091L0407113012L0000513106L0201405045L2104320086L0202606086L1804120091L0609411104L1607522005L0000101102L2002320095L0610110111L0709500116L1603422006L0203109041L2201113011L0808611016L1807519006L0611316083L0910318074L1608415035L1001602076L1203603106 +X08Y04Z8L0000107018L0100103014L0000806018L0500406014L0500701017L0001205017L0400506006L0701107014L0201202014L0201603016L0002107038L0102103034L0002806038L0502406034L0502701037L0003205037L0402506026L0703107034L0203202034L0203603036 +X36Y19Z4L0101113011L0702107151L0804112071L0803108051L0802108071L1202108091L1503106151L1501106161L0204104041L1500101041L1612109161L0216104161L1114117161L1616114171L0503105161L1216117171L0203121091L0403103141L2606132061L2706131061L2907124111L2212128121L2112129121L3103122051L2503130041L2304128051L2213131151L2813123141L3014125151L2707126111L2608128111L2408129101L2309131101L0000205052L0101204042L0202203032L0007205122L0108204112L0209203102L0115204182L2301323143L0216203172L0700219122L0801218112L0902217102L1003216092L1104215082L1205214072L2100235002L2201235012L2302235022L2403235032L2504235042L2605235052L2706235062L2807235072L2908235082L3009235092L3110235102L3211235112L3312235122L3413235142L1302402134L0709413154L0000308033L0012308153L1300335153L1301334153L0215410154L1505415134L1615426154 +X72Y72Z8L0000109098L0000809091L0000401004L0001401014L0002401024L0003401034L0004401044L0005401054L0006401064L0007401074L0008401084L0009401094L0202403024L0203403034L0204403044L0205403054L0206403064L0208403084L0209403094L0200402014L0300404004L0307404074L0401405014L0402405024L0403405034L0404405044L0405405054L0406405064L0408405084L0409405094L0604406054L0704407054L0804408054L0904409054L0608406094L0708407094L0808408094L0908409094L0507406074L0500406004L0601407014L0602406034L0700408004L0703408034L0706408064L0707408074L0801408024L0900409014L0902409034L0906409074L0009109008L0900100098 +X10Y10Z2L0802106042L0001208031L0701209021L0206209011L0004100022L0000206071L0201102022L0105101072L0809106081L0805209091L0407207051L0208101061L0108200091L0303202012L0702205042L0008200032L0703207011L0601205022L0506204062L0904209052L0404104031L0203102021 +X60Y36Z8L1702113248L1503212078L1304112137L1105311206L1309202336L1508310125L1707105075L2306307228L1804417226L1514210145L1824104328L0421106315L0319308307L0728200297L0523306266L0427322325L0228305186L0131309237L0706108136L0604201114L0502114124L0303404128L0405208156L1428114338L1229116328L1530415237L1616316257L1426311225L0310305095L0213106115L1417207175L0921312184L2400420057L2500121028L2600325026L1934213316L2219422338L2119222348L2019326255L3233335335L3331436337L3332437336L2601232035L2101124046L2206321176L2604224067L2435137357L3708324344L2433238354L2103221068L3803133018L3517237327L3617335226L3717236306L3918339358L3126322287L2229127315L2230126306L2603134037L3503259165L3603437055L3411429198L3412330204L3413337125L2607324085L2309224157L2316124097L2907436085L3325432296L2317423197L2528430268L2805131094L3307235084L3713334204L3524235288L2318124218L3009227126L3711332228L2614227227L2609326125L4006144215L5917244205L5406244196L3906245197L4905445208L5420344264L4016154194L5519250344L5520349345L5521254275L4609348155L4816356326L5115344045L5504351165L4625344305L5113346265L4925253257L5309150256L5308253246L4506250057L4608149128L5530243326 +X15Y15Z4L0401105001L0601114013L0213213023L0105105051L0014102131L0704210074L1208211133L0812110081L0612306141L1201213003L0408300142L0911114064L0411300131L0007208004L0913409121L1210307101L0502401072L0108400032L0608105074L0103301021L0814308112L0510201083L0800106001L1414310134L1209313103L0604405023L0714206144L1109412083L0409205083L1207113051L1213314123L0514206143L1207212053L0804307013L0208302064L0302300054L1009413134L0412103111L0408203074L0810309093L0313302122L1410114071L0812209132L0902408034L0604208041L0203202021L1313113092L0709406104L0510302084L0709108081L1201412034L1307214104L0611206092L1100309044L0412203132L0301304003L1002409034L1411213101L0411402114L0101301011L0907209052L0900111001L0809308102L0101401044L1404314044L0310203092L0504305041L0111301112L0205202042L0612205122L0505406054L0314102141L0011400104L1210411104L1201113011L0305104051L0401405014L1002309023L0609405094L1108112081L0900310003 +X20Y35Z8L1916104218L1917204208L1406104196L1934305197L0905205206L1420404266L0016414195L1519410346L1520309348L1521414277L0609108158L0816316327L1115204046L1504411165L0625404306L1113406266L0925113258L1309210257L1308213248L0506410056L0608409126L1530403325L0017400346 +X36Y24Z1L0003102031L0302105021L0101104041L0005104011L0603108051L0605107011L0801110011L0802110041L0009102091L0308105081L0107104101L0011104071L0608108061L0606107101L0810110101L0809110071L1203114031L1502117021L1301116041L1205116011L1803120051L1805119011L2001122011L2002122041L1209114091L1508117081L1307116101L1211116071L1808120061L1806119101L2010122101L2009122071L2403126031L2702129021L2501128041L2405128011L3003132051L3005131011L3201134011L3202134041L2409126091L2708129081L2507128101L2411128071L3008132061L3006131101L3210134101L3209134071L0015102151L0314105141L0113104161L0017104131L0615108171L0617107131L0813110131L0814110161L0021102211L0320105201L0119104221L0023104191L0620108181L0618107221L0822110221L0821110191L1215114151L1514117141L1313116161L1217116131L1815120171L1817119131L2013122131L2014122161L1221114211L1520117201L1319116221L1223116191L1820120181L1818119221L2022122221L2021122191L2415126151L2714129141L2513128161L2417128131L3015132171L3017131131L3213134131L3214134161L2421126211L2720129201L2519128221L2423128191L3020132181L3018131221L3222134221L3221134191 +X72Y72Z5L0000171715L0001170715L0002169715L0003168715L0004167715L0005166715L0006165715L0007164715L0008163715L0009162715L0010161715L0011160715L0012159715L0013158715L0014157715L0015156715L0016155715L0017154715L0018153715L0019152715L0020151715L0021150715L0022149715L0023148715L0024147715L0025146715L0026145715L0027144715L0028143715L0029142715L0030141715L0031140715L0032139715L0033138715L0034137715L0035136715L0037135715L0038134715L0039133715L0040132715L0041131715L0042130715L0043129715L0044128715L0045127715L0046126715L0047125715L0048124715L0049123715L0050122715L0051121715L0052120715L0053119715L0054118715L0055117715L0056116715L0057115715L0058114715L0059113715L0060112715L0061111715L0062110715L0063109715L0064108715L0065107715L0066106715L0067105715L0068104715L0069103715L0070102715L0071101715L3600136004L0036535365 +X72Y72Z2L0000271712L0071271002 +X40Y40Z3L0313329331L1415127043L0237337351L0039335171L3816115013L0016121091L0206138381L1119118151L3703139001L0317137381L1000139393L0932139392L3611108333L3401100383L0125104033L1911124211L1727119261L3117132101L0015106341L1201116051L0025325061L0539333181L0508330061L3200326331L0700234041L0804109001L1614130331L0516122331L2007124221L1218128301L1804100392L1301133383L2125130073L1509105093L1118138393L2705137361L1429127341L3013138361L3007136121L3118137141L2100225033L0204205022L1412338392L0738339162L0028236043L1501236022L2811221232L1408209192L0622205052L2634237192L0633228073L3613212323L2101234042L3438219373L0802216032L2710219363L0038209372L0405207242L1124225112L1217217092L1732236343L1239214193L3008237113L0401303312L1316333152L1004217032L2628231272L1125224242L1227230172L0137210372L0504206062L0611326102L1932234372L0226207063L1512331202L3227236302L0509205162L0233207282L2124229112L1231219382L0314305222L2339334172L3226335352L2934336142L3026231133L2633236332L3502239083L0032301033L2434333393L0507310043L3617336333L1601333003L0907307333L3330336353L2023323233L1305324123L3501339073L0737311303L2239329073L0239304353L3731332303L1106324053L2705332163L0238306243L2029318283L1010310273L1521326153L1207320123L2206322123L0736311293L1334318253L1738319273L0315303173L0419304213L2120324213L2222327233L2319324233L0632307343L3019331273L3418335243L3409337103L3505336133L3605336073 +X15Y15Z3L1212303012L0506203113L0705209113L1102212113L1005110033L0414200012L0701302001L0107200083L0612305143L1102112001L0702109051L1105214022L0512110042L1309113071L0507206063L1212114121L0612213121L0303306033L1110112081L0312202142L1013214123L0710108071L0806302012L1108214062L0701203023L0900303021L1307313103L1114111121L0004100081L0011101101L0614104141L0914310133L0507106061L1101113011L0914108131L1010110071L0513303101L1204110011L0305304063L0809206082L1309214082L1301311002L0500107011L0901208002L1209311083L0506105031L0210202113L1106310053L0102301003L0802308043L0311203121L1111311123L0205301053L0313303143L0909309103L1013110141L1014311143 +X72Y72Z8L0000171023L0000271022L0000371021L0001171013L0001371011L0002171003L0002271002L0002371001 +X03Y03Z3L0000102002L0101101002L0200101012L0001101023L0001201013L0102102013 +X72Y72Z1L0100161061L2300164131L5500142501L0062106031L1771171341L2271166661L5967146631L2565161681L2665167661L2467159701L2369169691L5668157661L5569157671L0200159181L0116125331L4701170011L0209139261L6117103351L1628148341L0428103091L2400150061L1860119691L0114152461L2107156021L2158170361L0117112321L1213168041L0342114681L1643151591L5544161161L1115134161L1116134151L4342124521L0238146371L1449120631L0259113681L2243138471L0642146381L0404151031L5616159471L1216135161L1137126331L3911141261L0214159331L0269111321L6315168051L1741155561L0540109331L2322134211L4353129461L0713160351L1362118691L2244127471L0934108431L1120126191L1410140261L1957168571L5808146391L6653169311L0765166521L2719129191L3044125471L0425133311L1352110631L0405163111L0858110571L2645143541L5809165141L0515132261L2649141431L1252109611L0604141061L1955143411L1704153121L1448119541L2405145181L2447142511L1058113461L4605146211L1639122391L4613151111L4710146221L4414144181L0516105251L6822168331 +X40Y40Z3L0000139001L0001139011L0002139021L0003139031L0004139041L0005139051L0006139061L0007139071L0008139081L0009139091L0010139101L0011139111L0012139121L0013139131L0014139141L0015139151L0016139161L0017139171L0018139181L0019139191L0020139201L0021139211L0022139221L0023139231L0024139241L0025139251L0026139261L0027139271L0028139281L0029139291L0030139301L0031139311L0032139321L0033139331L0034139341L0035139351L0036139361L0037139371L0038139381L0039139391L0100101391L0500105391L0900109391L1300113391L1700117391L2100121391L2500125391L2900129391L3300133391L3700137391L0100201392L0300203392L0500205392L0700207392L0900209392L1100211392L1300213392L1500215392L1700217392L1900219392L2100221392L2300223392L2500225392L2700227392L2900229392L3100231392L3300233392L3500235392L3700237392L3900239392L0300303393L0700307393L1100311393L1500315393L1900319393L2300323393L2700327393L3100331393L3500335393L3900339393 +X30Y30Z3L1212111103L1811311041L0412101102L0410218072L2612328231L2411128111L0503313081L1810314062L2301315031L2415326192L2224229251L0323201211L2911229192L1801317002L1128115162L1629211293L2026212291L1701317033L1714120233L2105121031L1014309152L0716104051L2221128271L1205311042L0420308243L0718204271L1221311252L0223201273L0502209071L1314109142L0317204222L2312319131L2026119241L0302116022L1611118011L1224110263L2229116171L1319220271L1710114091L0607203032L0513203131L0109100161L1424315231L1727113241L1416111182L1213213112L2510316102L2521228222L0321306273L2305228003L1501310013L1918120182L2226222241L2313220152L0117203201L2700318033L2103228022L1806215073L2813329182L0318202172L0903109022L2629228193L2610123121L1528320243L1607115061L0124103231L0216103141L2506223051L0624307253L0902110011L1128201291L2907228011L0109202103L2923329263L1016309153L1912320142L1807118051L1216211143L2504124051L1714217113L1828312293L0200100032L0705208072L1321312173L2007120031L0001201002L1312315123L0819107181L0927210281L2410225071L2726121282L1705316033L2609328093L2503321011L0018101201L2328222261L0301306011L2617225202L1112115142L0712108111L0624109221L0606104101L2728228272L0607304073L0514206161L0800306003L1006107042L2013321143L0827310273L1206111051L2715128141L2608122081L0116301183L0313302102L0715209131L2120223212L1627217243L2324322203L0423303241L0818209193L1624315241L2512327101L1912117111L2003323033L2416325132L0504106051L1404314022L1618317143L1318213191L2811326112L2516325142L1619315203L1606118081L2102222013L2806223021L2622324223L0805112041L0923309252L2307324053L2625225232L2023122212L0521105191L0717307153L1920118181L1226312283L2116122141L0727104261L0615105141L2427325263L0204100062L0225200253L1713115131L1928320273L0308203052L1822214232L0811310123L2428123271L2522127231L1109310073L0405207053L0215201142L2815127152L2905128041L2217322152L1216113171L0105202022L2317320172L1810114093L2707128081L0528306263L2418124161L2802329032L0411207122L0619305163L0208201103L1725217272L1108112092L0702208013L2106122063L2921129231L2118123181L2619324193L2908229102L0819307192L0022101231L1315115151L0729209282L0125201272L2708227093L0922308233L1320212222L0424305242L2606328063L1413214123L1819316203L0317104181L1719315201L1315314162L1212312133L2609224092L1212211132L2717327172L1428117281L2010220093L1316213152L0507106081L0113101121L1428314293L1117211162L0812108131 +X40Y40Z4L0000139394L3900100394L0039139004L3939100004L3800100384L3700100374L3600100364L3500100354L3400100344L3300100334L3200100324L3100100314L3000100304L2900100294L2800100284L2700100274L2600100264L2500100254L2401100244L2301100234L2201100224L2101100214L2001100204L0601119011L3938101004L3937102004L3936103004L3935104014L3934105014L3933106014L3932107014L3931108014L3930109014L3929110014L3928111014L3927112014L3926113014L3925114014L3924115014L3923116014L3922117014L0121119391L0222118381L0323117371L0424116361L0525115351L0626114341L0727113331L0828112321L0929109311L3722121381L3623122371L3524123361L3425124351L3326125341L3227126331L3128127321L2829130291L1030111311L2930128311L1801422014L0220420384L0321419374L0422418364L0523417354L0624416344L0725415334L0826414324L0927413314L1028412284L1129412304L3823422394L3724423384L3625424374L3526425364L3427426354L3328427344L3229428334L3130431324L3031429324L0020219392L0121218382L0222217372L0323216362L0424215352L0525214342L0626213332L0727212322L0828211312L0929210302L3922222392L3823223382L3724224372L3625225362L3526226352L3427227342L3328228332L3229229322L3130230312L0000220283L0100220273L0200220263L0300220253L0401220243L0500220233L0600220223L0700220213L0800220203L0900220193L1000220183L3900211293L3800221283L3700221273L3600221263L3500221253L3400221243L3300221233L3200221223L3100221213L3000221203L0019221023L0119220033L0220220043L0321220053L0422220063L0523220073L0624220083L0725220093L0826220103L0927220113L2100223002L2500229002L3128221113L3227221103L3326221093L3425221083L3524221073L3623221063L3722221053L3821221043L3921221033L2019220382L1920219372L1821218362L1722217352L1623216342L1524215332L1425214322L1326213312L1227212302L1128211292L2121221382L2222222372L2323223362L2424224352L2525225342L2626226332L2727227322L2828228312L2929229302L1912319393L2012322393L0000339003L0001302013L0601339013L2702339023L0119338213L0220337223L0321336233L0422335243L0523334253L1918306243L1819307253L1720308263L1621309273L1522310273L1423311263L1324312253L2118333263L2119332273L2220331283L2321330283L2422329273L2523328263L2624327253L1230320383L1331319373L1432318363L1533317333L1634317353L2930321383L2831322373L2732323363L2433326333L2534324353L0121318383L0222317373L0323316363L0424315353L0525314343L0626313333L0727312323L0828311313L0929310303L3823323383L3724324373L3625325363L3526326353L3427327343L3328328333L3229329323L3130330313 +X72Y72Z1L0000108151L0004171321L0013171421L0016171431L0030100631L0046170601L7164100711L7165128711L1001170321L0500105031L0501107011L0502107021L0001100031L0002102021L0705107071L0506107061L0005106161L0105101111L0106105101L0117171541L0015170341L0014165331L0518165321L0017123261L0024133411L3330169531L2228100291L0025121281L0825108271L2312169321L2412168321L2512167321L0226108261L7065131701L7066135701L7067139701L4669169691L4968143701L2605166051L2705165051L2706165061L3706149061L2707150171L2708150161L2808151161L2809161131L6009162101L5309152141L5210152131L2810132101L5512153131L5610154111L5710157131L5810158131L0664144641L0764101691L4064102661L3664103681L1564103671L3264104671L2565122661L2864109661L0965120651L1664120641L1204162311L0031169571L3131124591L0045169581L1632100441L1521140211L6421164321L1905161231L1805137231L3020130221L3021136211L2247106591L1458170611L0062170621L1457121611L1749119501L1859120591L2149120601L1205117051L1605113171L1606114161L1417116191L1607115161L1507115151L2216145201L4420146201L4118143181L4117141191L3531168511L4034143341L4434134391L3933135391L3532138381L3632138371L3634136371L3734137371L3930155361L4035164521L4330155341L4831154311L5332154331L4036162521L4840160521L4941159511L5042158501L5143157491L5244156481L5345154461L5347155471L4137147391L4037145391L5738169491L6847169481L6039169461L5938167441L6239166431L6340164411L6540165421L0234104351L0342105441L0434125571L0433126571L1534107431L0836108431L0741109421L0943125431L1035125421L1036111381L1337114391L1040110421L1041113411L1831143561L1839142451L4145129551L1838140541L2932118371L2832118361L2833119361L1933127331L2033126331L2034126341L1456100611L1447100601L1354101591L1347100591L1247100521L1248101521L1148101511L0249102511L0250110501L4045132471L3845139471L4046139521L3645140511L3646134491L3547135491 +X40Y40Z2L0000139001L0100138001L0200137001L0300136001L0400135001L0500134001L0600133001L0700132001L0800131001L0900130001L1000129001L1100128001L1200127001L1300126001L1400125001L1500124001L1600123001L1700122001L1800121001L1900120001L0001100381L0002100371L0003100361L0004100351L0005100341L0006100331L0007100321L0008100311L0009100301L0010100291L0011100281L0012100271L0013100261L0014100251L0015100241L0016100231L0017100221L0018100211L0019100201L0039139391L0139138391L0239137391L0339136391L0439135391L0539134391L0639133391L0739132391L0839131391L0939130391L1039129391L1139128391L1239127391L1339126391L1439125391L1539124391L1639123391L1739122391L1839121391L1939120391L3901139381L3902139371L3903139361L3904139351L3905139341L3906139331L3907139321L3908139311L3909139301L3910139291L3911139281L3912139271L3913139261L3914139251L3915139241L3916139231L3917139221L3918139211L3919139201L1010129101L1110128101L1210127101L1310126101L1410125101L1510124101L1610123101L1710122101L1810121101L1910120101L1011110281L1012110271L1013110261L1014110251L1015110241L1016110231L1017110221L1018110211L1019110201L1029129291L1129128291L1229127291L1329126291L1429125291L1529124291L1629123291L1729122291L1829121291L1929120291L2911129281L2912129271L2913129261L2914129251L2915129241L2916129231L2917129221L2918129211L2919129201L1515124151L1615123151L1715122151L1815121151L1915120151L1516115231L1517115221L1518115211L1519115201L1524124241L1624123241L1724122241L1824121241L1924120241L2416124231L2417124221L2418124211L2419124201L1718122181L1818121181L1918120181L1719117201L1721122211L1821121211L1921120211L2219122201L0910209292L3010230292L1415214242L2515225242L1717222172L1719222192L1720222202L1722222222 diff --git a/hls/auto/q_old.txt b/hls/auto/q_old.txt new file mode 100755 index 0000000000000000000000000000000000000000..d335ae79c2ef34ca2bd25ef5a1f57300cd576959 --- /dev/null +++ b/hls/auto/q_old.txt @@ -0,0 +1,25 @@ +X24Y24Z4L0613304164L1702122032L0101403204L1601420204L2117419044L0023116021L1520309084L1921116154L1709121031L1812103211L0905208142L0704412013L0421110094L2320100142L1500319034L0915104123L0907418124L2001109101L0122202213L2102422011L2120105211L2319117132L0404119103L1215322223L0607218074L1715113123L1217220172L1602320113L0003306053L0405413144L2006421214L1301103212L0614322183L1108323004L0004322043L0602322213L1210120142L1321419172L1202116012L1303103081L0820211202L1003116142L1701305123L0312223072L0720301063L1202214024L0506207072L1610417224L1309404154L1201408124L1704410064L0822110211L1210321153L1708116072L0000100111L0201112011L0808104103L0923210212L1210413134L1500421014 +X15Y15Z2L0202212102L0303211112L0404210122L0503209112L0402210102L0204212122L0203212112L0302211102L0403210112L0504209122L0502209102L0304211122 +X20Y20Z8L0203202066L0400403037L0403105088L0503101016L0500206038L0703317055L1001104054L0505317087L0108204086L0111101177L0810406188L0313406138L0413215177L0513106176L0317302158L0715100195L0318307064L1503212048L1702112058L1206318087L1007417036L1101317047L1406216094L1111217187L1310418146L1510315145L1014310177L1317219198L0919218177 +X72Y72Z8L0000171718L0036871001L0000800718L0036171008L0071171711L3671171368 +X08Y08Z4L0000107072L0100103032L0007106072L0503106032L0506101062L0001205062L0404106051L0700207032L0201202032L0205203052L0000307074L0100303034L0007306074L0503306034L0506301064L0001405064L0404306053L0700407034L0201402034L0205403054 +X48Y36Z8L0609109051L0608108091L0709109021L0306109041L0204109091L0207105091L0208105041L0209104041L0607109031L0516105191L0417106171L0418106181L0113103131L0213104211L0214107211L0413110211L0814108211L0221110221L0226103321L0331104251L0128105321L0329108321L0733109261L0629107261L0630107271L0233106281L1400123101L1503123061L1504122101L1508122081L1509122011L1606118111L1702122041L1212119211L1319115141L1316120151L1217118171L1313119221L2020122121L1517116221L1421116171L1527123351L1328120261L1533122251L1830121311L1334120291L1426119261L1632119251L1730122291L1431121341L2501131011L2708128051L2800134051L3400135111L2400132031L2704132081L2406125021L2504133101L2401128101L2522134151L2921134161L2513134171L3013134221L2614130171L3019135191L2415130181L3414135121L3524135341L2533135281L2727135351L2435129311L2734129351L2829131331L2833132321L3607146111L4207147111L4010147001L3600137101L3608144021L4509146051L4020145141L3614141151L4218147231L3612145201L3712143141L3623144181L3912146231L3624144301L4030147241L3635137321L3835147351L4132146351L3634145311L3726144291L3733142281L2935227213L0629622066L0606335013L1728617245L0814411182L2608416057 +X72Y72Z8L0000166038L0004128038L0013104688L0016158688L0030133688L0046120038L0071149038L7165169688 +X15Y15Z2L0602214082L1406114081L0901111112L0110100072L0405209012L1108112071L0707208011L0301107002L0014101142L0405103072L0006203042L1008111071L1301214132L1403114012L1404210011L1113207112L0206206052L0603104031L1211110121L0512202141L0201203032L0105101042L0809209062L0609100121L0501204022L1110211082L0809112091L0000201001L1304114051L0102100001L1114113141L0401101012L1007109132L0714204131L1005110031L0611103112L0112102131L0208102061L0708206092L0007100101L1409214112L1300211002L0501106001L1114212142L0511104111L0704107031L0702208022 +X23Y12Z6L0303122021L1102219103L0503504065L0302105101L0200305093L0907100081L1309100071L0706221102L0500212014L0301605026L0104216063L0204408034L0910502106L1805113052L1406116041L0409310114L2106122103L1710201033L0510412024L1411222072L1503421106L1310519035L1306220044L0101201112L1701221014L0802503105L0603107091L0407113012L0000513106L0201405045L2104320086L0202606086L1804120091L0609411104L1607522005L0000101102L2002320095L0610110111L0709500116L1603422006L0203109041L2201113011L0808611016L1807519006L0611316083L0910318074L1608415035L1001602076L1203603106 +X08Y04Z8L0000107018L0100103014L0000806018L0500406014L0500701017L0001205017L0400506006L0701107014L0201202014L0201603016L0002107038L0102103034L0002806038L0502406034L0502701037L0003205037L0402506026L0703107034L0203202034L0203603036 +X36Y19Z4L0101113011L0702107151L0804112071L0803108051L0802108071L1202108091L1503106151L1501106161L0204104041L1500101041L1612109161L0216104161L1114117161L1616114171L0503105161L1216117171L0203121091L0403103141L2606132061L2706131061L2907124111L2212128121L2112129121L3103122051L2503130041L2304128051L2213131151L2813123141L3014125151L2707126111L2608128111L2408129101L2309131101L0000205052L0101204042L0202203032L0007205122L0108204112L0209203102L0115204182L2301323143L0216203172L0700219122L0801218112L0902217102L1003216092L1104215082L1205214072L2100235002L2201235012L2302235022L2403235032L2504235042L2605235052L2706235062L2807235072L2908235082L3009235092L3110235102L3211235112L3312235122L3413235142L1302402134L0709413154L0000308033L0012308153L1300335153L1301334153L0215410154L1505415134L1615426154 +X72Y72Z8L0000109098L0000809091L0000401004L0001401014L0002401024L0003401034L0004401044L0005401054L0006401064L0007401074L0008401084L0009401094L0202403024L0203403034L0204403044L0205403054L0206403064L0208403084L0209403094L0200402014L0300404004L0307404074L0401405014L0402405024L0403405034L0404405044L0405405054L0406405064L0408405084L0409405094L0604406054L0704407054L0804408054L0904409054L0608406094L0708407094L0808408094L0908409094L0507406074L0500406004L0601407014L0602406034L0700408004L0703408034L0706408064L0707408074L0801408024L0900409014L0902409034L0906409074L0009109008L0900100098 +X10Y10Z2L0802106042L0001208031L0701209021L0206209011L0004100022L0000206071L0201102022L0105101072L0809106081L0805209091L0407207051L0208101061L0108200091L0303202012L0702205042L0008200032L0703207011L0601205022L0506204062L0904209052L0404104031L0203102021 +X60Y36Z8L1702113248L1503212078L1304112137L1105311206L1309202336L1508310125L1707105075L2306307228L1804417226L1514210145L1824104328L0421106315L0319308307L0728200297L0523306266L0427322325L0228305186L0131309237L0706108136L0604201114L0502114124L0303404128L0405208156L1428114338L1229116328L1530415237L1616316257L1426311225L0310305095L0213106115L1417207175L0921312184L2400420057L2500121028L2600325026L1934213316L2219422338L2119222348L2019326255L3233335335L3331436337L3332437336L2601232035L2101124046L2206321176L2604224067L2435137357L3708324344L2433238354L2103221068L3803133018L3517237327L3617335226L3717236306L3918339358L3126322287L2229127315L2230126306L2603134037L3503259165L3603437055L3411429198L3412330204L3413337125L2607324085L2309224157L2316124097L2907436085L3325432296L2317423197L2528430268L2805131094L3307235084L3713334204L3524235288L2318124218L3009227126L3711332228L2614227227L2609326125L4006144215L5917244205L5406244196L3906245197L4905445208L5420344264L4016154194L5519250344L5520349345L5521254275L4609348155L4816356326L5115344045L5504351165L4625344305L5113346265L4925253257L5309150256L5308253246L4506250057L4608149128L5530243326 +X15Y15Z4L0401105001L0601114013L0213213023L0105105051L0014102131L0704210074L1208211133L0812110081L0612306141L1201213003L0408300142L0911114064L0411300131L0007208004L0913409121L1210307101L0502401072L0108400032L0608105074L0103301021L0814308112L0510201083L0800106001L1414310134L1209313103L0604405023L0714206144L1109412083L0409205083L1207113051L1213314123L0514206143L1207212053L0804307013L0208302064L0302300054L1009413134L0412103111L0408203074L0810309093L0313302122L1410114071L0812209132L0902408034L0604208041L0203202021L1313113092L0709406104L0510302084L0709108081L1201412034L1307214104L0611206092L1100309044L0412203132L0301304003L1002409034L1411213101L0411402114L0101301011L0907209052L0900111001L0809308102L0101401044L1404314044L0310203092L0504305041L0111301112L0205202042L0612205122L0505406054L0314102141L0011400104L1210411104L1201113011L0305104051L0401405014L1002309023L0609405094L1108112081L0900310003 +X20Y35Z8L1916104218L1917204208L1406104196L1934305197L0905205206L1420404266L0016414195L1519410346L1520309348L1521414277L0609108158L0816316327L1115204046L1504411165L0625404306L1113406266L0925113258L1309210257L1308213248L0506410056L0608409126L1530403325L0017400346 +X36Y24Z1L0003102031L0302105021L0101104041L0005104011L0603108051L0605107011L0801110011L0802110041L0009102091L0308105081L0107104101L0011104071L0608108061L0606107101L0810110101L0809110071L1203114031L1502117021L1301116041L1205116011L1803120051L1805119011L2001122011L2002122041L1209114091L1508117081L1307116101L1211116071L1808120061L1806119101L2010122101L2009122071L2403126031L2702129021L2501128041L2405128011L3003132051L3005131011L3201134011L3202134041L2409126091L2708129081L2507128101L2411128071L3008132061L3006131101L3210134101L3209134071L0015102151L0314105141L0113104161L0017104131L0615108171L0617107131L0813110131L0814110161L0021102211L0320105201L0119104221L0023104191L0620108181L0618107221L0822110221L0821110191L1215114151L1514117141L1313116161L1217116131L1815120171L1817119131L2013122131L2014122161L1221114211L1520117201L1319116221L1223116191L1820120181L1818119221L2022122221L2021122191L2415126151L2714129141L2513128161L2417128131L3015132171L3017131131L3213134131L3214134161L2421126211L2720129201L2519128221L2423128191L3020132181L3018131221L3222134221L3221134191 +X72Y72Z5L0000171715L0001170715L0002169715L0003168715L0004167715L0005166715L0006165715L0007164715L0008163715L0009162715L0010161715L0011160715L0012159715L0013158715L0014157715L0015156715L0016155715L0017154715L0018153715L0019152715L0020151715L0021150715L0022149715L0023148715L0024147715L0025146715L0026145715L0027144715L0028143715L0029142715L0030141715L0031140715L0032139715L0033138715L0034137715L0035136715L0037135715L0038134715L0039133715L0040132715L0041131715L0042130715L0043129715L0044128715L0045127715L0046126715L0047125715L0048124715L0049123715L0050122715L0051121715L0052120715L0053119715L0054118715L0055117715L0056116715L0057115715L0058114715L0059113715L0060112715L0061111715L0062110715L0063109715L0064108715L0065107715L0066106715L0067105715L0068104715L0069103715L0070102715L0071101715L3600136004L0036535365 +X72Y72Z2L0000271712L0071271002 +X40Y40Z3L0313329331L1415127043L0237337351L0039335171L3816115013L0016121091L0206138381L1119118151L3703139001L0317137381L1000139393L0932139392L3611108333L3401100383L0125104033L1911124211L1727119261L3117132101L0015106341L1201116051L0025325061L0539333181L0508330061L3200326331L0700234041L0804109001L1614130331L0516122331L2007124221L1218128301L1804100392L1301133383L2125130073L1509105093L1118138393L2705137361L1429127341L3013138361L3007136121L3118137141L2100225033L0204205022L1412338392L0738339162L0028236043L1501236022L2811221232L1408209192L0622205052L2634237192L0633228073L3613212323L2101234042L3438219373L0802216032L2710219363L0038209372L0405207242L1124225112L1217217092L1732236343L1239214193L3008237113L0401303312L1316333152L1004217032L2628231272L1125224242L1227230172L0137210372L0504206062L0611326102L1932234372L0226207063L1512331202L3227236302L0509205162L0233207282L2124229112L1231219382L0314305222L2339334172L3226335352L2934336142L3026231133L2633236332L3502239083L0032301033L2434333393L0507310043L3617336333L1601333003L0907307333L3330336353L2023323233L1305324123L3501339073L0737311303L2239329073L0239304353L3731332303L1106324053L2705332163L0238306243L2029318283L1010310273L1521326153L1207320123L2206322123L0736311293L1334318253L1738319273L0315303173L0419304213L2120324213L2222327233L2319324233L0632307343L3019331273L3418335243L3409337103L3505336133L3605336073 +X15Y15Z3L1212303012L0506203113L0705209113L1102212113L1005110033L0414200012L0701302001L0107200083L0612305143L1102112001L0702109051L1105214022L0512110042L1309113071L0507206063L1212114121L0612213121L0303306033L1110112081L0312202142L1013214123L0710108071L0806302012L1108214062L0701203023L0900303021L1307313103L1114111121L0004100081L0011101101L0614104141L0914310133L0507106061L1101113011L0914108131L1010110071L0513303101L1204110011L0305304063L0809206082L1309214082L1301311002L0500107011L0901208002L1209311083L0506105031L0210202113L1106310053L0102301003L0802308043L0311203121L1111311123L0205301053L0313303143L0909309103L1013110141L1014311143 +X72Y72Z8L0000171023L0000271022L0000371021L0001171013L0001371011L0002171003L0002271002L0002371001 +X03Y03Z3L0000102002L0101101002L0200101012L0001101023L0001201013L0102102013 +X72Y72Z1L0100161061L2300164131L5500142501L0062106031L1771171341L2271166661L5967146631L2565161681L2665167661L2467159701L2369169691L5668157661L5569157671L0200159181L0116125331L4701170011L0209139261L6117103351L1628148341L0428103091L2400150061L1860119691L0114152461L2107156021L2158170361L0117112321L1213168041L0342114681L1643151591L5544161161L1115134161L1116134151L4342124521L0238146371L1449120631L0259113681L2243138471L0642146381L0404151031L5616159471L1216135161L1137126331L3911141261L0214159331L0269111321L6315168051L1741155561L0540109331L2322134211L4353129461L0713160351L1362118691L2244127471L0934108431L1120126191L1410140261L1957168571L5808146391L6653169311L0765166521L2719129191L3044125471L0425133311L1352110631L0405163111L0858110571L2645143541L5809165141L0515132261L2649141431L1252109611L0604141061L1955143411L1704153121L1448119541L2405145181L2447142511L1058113461L4605146211L1639122391L4613151111L4710146221L4414144181L0516105251L6822168331 +X40Y40Z3L0000139001L0001139011L0002139021L0003139031L0004139041L0005139051L0006139061L0007139071L0008139081L0009139091L0010139101L0011139111L0012139121L0013139131L0014139141L0015139151L0016139161L0017139171L0018139181L0019139191L0020139201L0021139211L0022139221L0023139231L0024139241L0025139251L0026139261L0027139271L0028139281L0029139291L0030139301L0031139311L0032139321L0033139331L0034139341L0035139351L0036139361L0037139371L0038139381L0039139391L0100101391L0500105391L0900109391L1300113391L1700117391L2100121391L2500125391L2900129391L3300133391L3700137391L0100201392L0300203392L0500205392L0700207392L0900209392L1100211392L1300213392L1500215392L1700217392L1900219392L2100221392L2300223392L2500225392L2700227392L2900229392L3100231392L3300233392L3500235392L3700237392L3900239392L0300303393L0700307393L1100311393L1500315393L1900319393L2300323393L2700327393L3100331393L3500335393L3900339393 diff --git a/hls/lines128_length256/bitstream/router_design.bit b/hls/lines128_length256/bitstream/router_design.bit new file mode 100755 index 0000000000000000000000000000000000000000..fb931486840eb7a813e994b1f19168e2e666db02 Binary files /dev/null and b/hls/lines128_length256/bitstream/router_design.bit differ diff --git a/hls/lines128_length256/bitstream/router_design.tcl b/hls/lines128_length256/bitstream/router_design.tcl new file mode 100755 index 0000000000000000000000000000000000000000..e5347dff159dc309b6768469faa92beeede33e8e --- /dev/null +++ b/hls/lines128_length256/bitstream/router_design.tcl @@ -0,0 +1,1113 @@ + +################################################################ +# This is a generated script based on design: router_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source router_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name router_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_gpio:2.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:hls:pynqrouter:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set LD [ create_bd_port -dir O -from 3 -to 0 LD ] + + # Create instance: axi_gpio_0, and set properties + set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ] + set_property -dict [ list \ + CONFIG.C_GPIO_WIDTH {4} \ + ] $axi_gpio_0 + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {650.000000} \ + CONFIG.PCW_ACT_CAN0_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN1_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.096154} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_I2C_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_APU_CLK_RATIO_ENABLE {6:2:1} \ + CONFIG.PCW_APU_PERIPHERAL_FREQMHZ {650} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {26} \ + CONFIG.PCW_CAN0_BASEADDR {0xE0008000} \ + CONFIG.PCW_CAN0_CAN0_IO {} \ + CONFIG.PCW_CAN0_HIGHADDR {0xE0008FFF} \ + CONFIG.PCW_CAN0_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN0_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN1_BASEADDR {0xE0009000} \ + CONFIG.PCW_CAN1_CAN1_IO {} \ + CONFIG.PCW_CAN1_HIGHADDR {0xE0009FFF} \ + CONFIG.PCW_CAN1_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN1_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_CAN_PERIPHERAL_VALID {0} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CORE0_IRQ_INTR {0} \ + CONFIG.PCW_CORE1_FIQ_INTR {0} \ + CONFIG.PCW_CORE1_IRQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_6X4X_MAX_RANGE {667} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1300.000} \ + CONFIG.PCW_CPU_PERIPHERAL_CLKSRC {ARM PLL} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_DCI_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {52} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_FREQMHZ {10.159} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {21} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1050.000} \ + CONFIG.PCW_DDR_HPRLPR_QUEUE_PARTITION {HPR(0)/LPR(32)} \ + CONFIG.PCW_DDR_HPR_TO_CRITICAL_PRIORITY_LEVEL {15} \ + CONFIG.PCW_DDR_LPR_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DDR_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DDR_PORT0_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT1_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT2_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT3_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_2 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_2 {} \ + CONFIG.PCW_DDR_RAM_BASEADDR {0x00100000} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x1FFFFFFF} \ + CONFIG.PCW_DDR_WRITE_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DM_WIDTH {4} \ + CONFIG.PCW_DQS_WIDTH {4} \ + CONFIG.PCW_DQ_WIDTH {32} \ + CONFIG.PCW_ENET0_BASEADDR {0xE000B000} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {MIO 52 .. 53} \ + CONFIG.PCW_ENET0_HIGHADDR {0xE000BFFF} \ + CONFIG.PCW_ENET0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {1} \ + CONFIG.PCW_ENET0_RESET_IO {MIO 9} \ + CONFIG.PCW_ENET1_BASEADDR {0xE000C000} \ + CONFIG.PCW_ENET1_ENET1_IO {} \ + CONFIG.PCW_ENET1_HIGHADDR {0xE000CFFF} \ + CONFIG.PCW_ENET1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_RESET_IO {} \ + CONFIG.PCW_FTM_CTI_IN1 {} \ + CONFIG.PCW_FTM_CTI_IN3 {} \ + CONFIG.PCW_FTM_CTI_OUT1 {} \ + CONFIG.PCW_FTM_CTI_OUT3 {} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_HIGHADDR {0xE000AFFF} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_GPIO_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_BASEADDR {0xE0004000} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C0_GRP_INT_IO {} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_IO {} \ + CONFIG.PCW_I2C1_HIGHADDR {0xE0005FFF} \ + CONFIG.PCW_I2C1_I2C1_IO {} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {25} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_POLARITY {Active Low} \ + CONFIG.PCW_I2C_RESET_SELECT {} \ + CONFIG.PCW_NAND_NAND_IO {} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_IO {} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_SRAM_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_SRAM_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS1_WE_TIME {0} \ + CONFIG.PCW_OVERRIDE_BASIC_CLOCK {0} \ + CONFIG.PCW_P2F_CAN0_INTR {0} \ + CONFIG.PCW_P2F_CAN1_INTR {0} \ + CONFIG.PCW_P2F_CTI_INTR {0} \ + CONFIG.PCW_P2F_DMAC0_INTR {0} \ + CONFIG.PCW_P2F_DMAC1_INTR {0} \ + CONFIG.PCW_P2F_DMAC2_INTR {0} \ + CONFIG.PCW_P2F_DMAC3_INTR {0} \ + CONFIG.PCW_P2F_DMAC4_INTR {0} \ + CONFIG.PCW_P2F_DMAC5_INTR {0} \ + CONFIG.PCW_P2F_DMAC6_INTR {0} \ + CONFIG.PCW_P2F_DMAC7_INTR {0} \ + CONFIG.PCW_P2F_DMAC_ABORT_INTR {0} \ + CONFIG.PCW_P2F_ENET0_INTR {0} \ + CONFIG.PCW_P2F_ENET1_INTR {0} \ + CONFIG.PCW_P2F_GPIO_INTR {0} \ + CONFIG.PCW_P2F_I2C0_INTR {0} \ + CONFIG.PCW_P2F_I2C1_INTR {0} \ + CONFIG.PCW_P2F_QSPI_INTR {0} \ + CONFIG.PCW_P2F_SDIO0_INTR {0} \ + CONFIG.PCW_P2F_SDIO1_INTR {0} \ + CONFIG.PCW_P2F_SMC_INTR {0} \ + CONFIG.PCW_P2F_SPI0_INTR {0} \ + CONFIG.PCW_P2F_SPI1_INTR {0} \ + CONFIG.PCW_P2F_UART0_INTR {0} \ + CONFIG.PCW_P2F_UART1_INTR {0} \ + CONFIG.PCW_P2F_USB0_INTR {0} \ + CONFIG.PCW_P2F_USB1_INTR {0} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_PACKAGE_NAME {clg400} \ + CONFIG.PCW_PCAP_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PCAP_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_PERIPHERAL_BOARD_PRESET {None} \ + CONFIG.PCW_PJTAG_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PJTAG_PJTAG_IO {} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SS1_IO {} \ + CONFIG.PCW_SD0_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_WP_IO {} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_IO {} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SD1_SD1_IO {} \ + CONFIG.PCW_SPI0_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS1_IO {} \ + CONFIG.PCW_SPI0_HIGHADDR {0xE0006FFF} \ + CONFIG.PCW_SPI0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI0_SPI0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS1_IO {} \ + CONFIG.PCW_SPI1_HIGHADDR {0xE0007FFF} \ + CONFIG.PCW_SPI1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI1_SPI1_IO {} \ + CONFIG.PCW_TRACE_GRP_2BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_2BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_4BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_4BIT_IO {} \ + CONFIG.PCW_TRACE_INTERNAL_WIDTH {2} \ + CONFIG.PCW_TRACE_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TRACE_PIPELINE_WIDTH {8} \ + CONFIG.PCW_TRACE_TRACE_IO {} \ + CONFIG.PCW_TTC1_BASEADDR {0xE0105000} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_HIGHADDR {0xE0105fff} \ + CONFIG.PCW_TTC1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC1_TTC1_IO {} \ + CONFIG.PCW_UART0_HIGHADDR {0xE0000FFF} \ + CONFIG.PCW_UART0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} \ + CONFIG.PCW_UART1_BASEADDR {0xE0001000} \ + CONFIG.PCW_UART1_BAUD_RATE {115200} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_GRP_FULL_IO {} \ + CONFIG.PCW_UART_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {525.000000} \ + CONFIG.PCW_UIPARAM_DDR_ADV_ENABLE {0} \ + CONFIG.PCW_UIPARAM_DDR_AL {0} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BL {8} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {16 Bit} \ + CONFIG.PCW_UIPARAM_DDR_CL {7} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_STOP_EN {0} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {6} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_LENGTH_MM {15.6} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PACKAGE_LENGTH {105.056} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_LENGTH_MM {18.8} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PACKAGE_LENGTH {66.904} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PACKAGE_LENGTH {89.1715} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PACKAGE_LENGTH {113.63} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_LENGTH_MM {16.5} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PACKAGE_LENGTH {98.503} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_LENGTH_MM {18} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PACKAGE_LENGTH {68.5855} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PACKAGE_LENGTH {90.295} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PACKAGE_LENGTH {103.977} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} \ + CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} \ + CONFIG.PCW_UIPARAM_DDR_ENABLE {1} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {525} \ + CONFIG.PCW_UIPARAM_DDR_HIGH_TEMP {Normal (0-85)} \ + CONFIG.PCW_UIPARAM_DDR_MEMORY_TYPE {DDR 3} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41J256M16 RE-125} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {7} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {7} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} \ + CONFIG.PCW_UIPARAM_GENERATE_SUMMARY {NA} \ + CONFIG.PCW_USB0_BASEADDR {0xE0102000} \ + CONFIG.PCW_USB0_HIGHADDR {0xE0102fff} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {1} \ + CONFIG.PCW_USB0_RESET_IO {MIO 46} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_BASEADDR {0xE0103000} \ + CONFIG.PCW_USB1_HIGHADDR {0xE0103fff} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_RESET_IO {} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_POLARITY {Active Low} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_AXI_FABRIC_IDLE {0} \ + CONFIG.PCW_USE_AXI_NONSECURE {0} \ + CONFIG.PCW_USE_CORESIGHT {0} \ + CONFIG.PCW_USE_CROSS_TRIGGER {0} \ + CONFIG.PCW_USE_CR_FABRIC {1} \ + CONFIG.PCW_USE_DDR_BYPASS {0} \ + CONFIG.PCW_USE_DEBUG {0} \ + CONFIG.PCW_USE_DEFAULT_ACP_USER_VAL {0} \ + CONFIG.PCW_USE_DMA0 {0} \ + CONFIG.PCW_USE_DMA1 {0} \ + CONFIG.PCW_USE_DMA2 {0} \ + CONFIG.PCW_USE_DMA3 {0} \ + CONFIG.PCW_USE_EXPANDED_IOP {0} \ + CONFIG.PCW_USE_EXPANDED_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {0} \ + CONFIG.PCW_USE_HIGH_OCM {0} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {0} \ + CONFIG.PCW_USE_PROC_EVENT_BUS {0} \ + CONFIG.PCW_USE_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_S_AXI_ACP {0} \ + CONFIG.PCW_USE_S_AXI_GP0 {0} \ + CONFIG.PCW_USE_S_AXI_GP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP0 {0} \ + CONFIG.PCW_USE_S_AXI_HP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP2 {0} \ + CONFIG.PCW_USE_S_AXI_HP3 {0} \ + CONFIG.PCW_USE_TRACE {0} \ + CONFIG.PCW_USE_TRACE_DATA_EDGE_DETECTOR {0} \ + CONFIG.PCW_VALUE_SILVERSION {3} \ + CONFIG.PCW_WDT_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_WDT_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_WDT_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_WDT_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_WDT_WDT_IO {} \ + CONFIG.PCW_CAN0_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN0_GRP_CLK_IO {} \ + CONFIG.PCW_CAN1_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN1_GRP_CLK_IO {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_3 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_3 {} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_IO {} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_POLARITY {Active Low} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_4K_TIMER {0} \ + CONFIG.PCW_EN_CAN0 {0} \ + CONFIG.PCW_EN_CAN1 {0} \ + CONFIG.PCW_EN_CLK0_PORT {1} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {0} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG0_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG1_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG2_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG3_PORT {0} \ + CONFIG.PCW_EN_DDR {1} \ + CONFIG.PCW_EN_EMIO_CAN0 {0} \ + CONFIG.PCW_EN_EMIO_CAN1 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_ENET0 {0} \ + CONFIG.PCW_EN_EMIO_ENET1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {0} \ + CONFIG.PCW_EN_EMIO_I2C0 {0} \ + CONFIG.PCW_EN_EMIO_I2C1 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART0 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART1 {0} \ + CONFIG.PCW_EN_EMIO_PJTAG {0} \ + CONFIG.PCW_EN_EMIO_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_SPI0 {0} \ + CONFIG.PCW_EN_EMIO_SPI1 {0} \ + CONFIG.PCW_EN_EMIO_SRAM_INT {0} \ + CONFIG.PCW_EN_EMIO_TRACE {0} \ + CONFIG.PCW_EN_EMIO_TTC0 {0} \ + CONFIG.PCW_EN_EMIO_TTC1 {0} \ + CONFIG.PCW_EN_EMIO_UART0 {0} \ + CONFIG.PCW_EN_EMIO_UART1 {0} \ + CONFIG.PCW_EN_EMIO_WDT {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_ENET1 {0} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {0} \ + CONFIG.PCW_EN_I2C1 {0} \ + CONFIG.PCW_EN_MODEM_UART0 {0} \ + CONFIG.PCW_EN_MODEM_UART1 {0} \ + CONFIG.PCW_EN_PJTAG {0} \ + CONFIG.PCW_EN_PTP_ENET0 {0} \ + CONFIG.PCW_EN_PTP_ENET1 {0} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_RST0_PORT {1} \ + CONFIG.PCW_EN_RST1_PORT {0} \ + CONFIG.PCW_EN_RST2_PORT {0} \ + CONFIG.PCW_EN_RST3_PORT {0} \ + CONFIG.PCW_EN_SDIO0 {1} \ + CONFIG.PCW_EN_SDIO1 {0} \ + CONFIG.PCW_EN_SMC {0} \ + CONFIG.PCW_EN_SPI0 {0} \ + CONFIG.PCW_EN_SPI1 {0} \ + CONFIG.PCW_EN_TRACE {0} \ + CONFIG.PCW_EN_TTC0 {0} \ + CONFIG.PCW_EN_TTC1 {0} \ + CONFIG.PCW_EN_UART0 {1} \ + CONFIG.PCW_EN_UART1 {0} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {0} \ + CONFIG.PCW_EN_WDT {0} \ + CONFIG.PCW_FCLK0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK0_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_FTM_CTI_IN0 {} \ + CONFIG.PCW_FTM_CTI_IN2 {} \ + CONFIG.PCW_FTM_CTI_OUT0 {} \ + CONFIG.PCW_FTM_CTI_OUT2 {} \ + CONFIG.PCW_GPIO_BASEADDR {0xE000A000} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {} \ + CONFIG.PCW_I2C0_HIGHADDR {0xE0004FFF} \ + CONFIG.PCW_I2C0_I2C0_IO {} \ + CONFIG.PCW_I2C1_BASEADDR {0xE0005000} \ + CONFIG.PCW_I2C1_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C1_GRP_INT_IO {} \ + CONFIG.PCW_I2C1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_IO {} \ + CONFIG.PCW_IMPORT_BOARD_PRESET {None} \ + CONFIG.PCW_INCLUDE_ACP_TRANS_CHECK {0} \ + CONFIG.PCW_INCLUDE_TRACE_BUFFER {0} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {20} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {0} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {in} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {out} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {inout} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {inout} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {inout} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {out} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {in} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {inout} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {out} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {out} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_PRIMITIVE {54} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#Quad SPI Flash#ENET Reset#GPIO#GPIO#GPIO#GPIO#UART 0#UART 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#SD 0#SD 0#SD 0#SD 0#SD 0#SD 0#USB Reset#SD 0#GPIO#GPIO#GPIO#GPIO#Enet 0#Enet 0} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#qspi_fbclk#reset#gpio[10]#gpio[11]#gpio[12]#gpio[13]#rx#tx#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#clk#cmd#data[0]#data[1]#data[2]#data[3]#reset#cd#gpio[48]#gpio[49]#gpio[50]#gpio[51]#mdc#mdio} \ + CONFIG.PCW_M_AXI_GP0_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP0_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP0_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP0_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP1_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP1_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_NAND_CYCLES_T_AR {1} \ + CONFIG.PCW_NAND_CYCLES_T_CLR {1} \ + CONFIG.PCW_NAND_CYCLES_T_RC {11} \ + CONFIG.PCW_NAND_CYCLES_T_REA {1} \ + CONFIG.PCW_NAND_CYCLES_T_RR {1} \ + CONFIG.PCW_NAND_CYCLES_T_WC {11} \ + CONFIG.PCW_NAND_CYCLES_T_WP {1} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_GRP_D8_IO {} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_CS0_T_PC {1} \ + CONFIG.PCW_NOR_CS0_T_RC {11} \ + CONFIG.PCW_NOR_CS0_T_TR {1} \ + CONFIG.PCW_NOR_CS0_T_WC {11} \ + CONFIG.PCW_NOR_CS0_T_WP {1} \ + CONFIG.PCW_NOR_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_CS1_T_PC {1} \ + CONFIG.PCW_NOR_CS1_T_RC {11} \ + CONFIG.PCW_NOR_CS1_T_TR {1} \ + CONFIG.PCW_NOR_CS1_T_WC {11} \ + CONFIG.PCW_NOR_CS1_T_WP {1} \ + CONFIG.PCW_NOR_CS1_WE_TIME {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_IO {} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_IO {} \ + CONFIG.PCW_NOR_NOR_IO {} \ + CONFIG.PCW_PLL_BYPASSMODE_ENABLE {0} \ + CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_PS7_SI_REV {PRODUCTION} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_FBCLK_IO {MIO 8} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_IO {} \ + CONFIG.PCW_QSPI_INTERNAL_HIGHADDRESS {0xFCFFFFFF} \ + CONFIG.PCW_QSPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD0_GRP_CD_ENABLE {1} \ + CONFIG.PCW_SD0_GRP_CD_IO {MIO 47} \ + CONFIG.PCW_SD0_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_POW_IO {} \ + CONFIG.PCW_SD0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD0_SD0_IO {MIO 40 .. 45} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_CD_IO {} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_IO {} \ + CONFIG.PCW_SDIO0_BASEADDR {0xE0100000} \ + CONFIG.PCW_SDIO0_HIGHADDR {0xE0100FFF} \ + CONFIG.PCW_SDIO1_BASEADDR {0xE0101000} \ + CONFIG.PCW_SDIO1_HIGHADDR {0xE0101FFF} \ + CONFIG.PCW_SDIO_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_CYCLE_T0 {NA} \ + CONFIG.PCW_SMC_CYCLE_T1 {NA} \ + CONFIG.PCW_SMC_CYCLE_T2 {NA} \ + CONFIG.PCW_SMC_CYCLE_T3 {NA} \ + CONFIG.PCW_SMC_CYCLE_T4 {NA} \ + CONFIG.PCW_SMC_CYCLE_T5 {NA} \ + CONFIG.PCW_SMC_CYCLE_T6 {NA} \ + CONFIG.PCW_SMC_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SMC_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_SMC_PERIPHERAL_VALID {0} \ + CONFIG.PCW_SPI0_BASEADDR {0xE0006000} \ + CONFIG.PCW_SPI0_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS0_IO {} \ + CONFIG.PCW_SPI0_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS2_IO {} \ + CONFIG.PCW_SPI1_BASEADDR {0xE0007000} \ + CONFIG.PCW_SPI1_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS2_IO {} \ + CONFIG.PCW_SPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_FREQMHZ {166.666666} \ + CONFIG.PCW_SPI_PERIPHERAL_VALID {0} \ + CONFIG.PCW_S_AXI_ACP_ARUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_AWUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_ID_WIDTH {3} \ + CONFIG.PCW_S_AXI_GP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_GP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP0_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP1_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP2_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP2_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP3_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP3_ID_WIDTH {6} \ + CONFIG.PCW_TPIU_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_TRACE_BUFFER_CLOCK_DELAY {12} \ + CONFIG.PCW_TRACE_BUFFER_FIFO_SIZE {128} \ + CONFIG.PCW_TRACE_GRP_16BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_16BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_32BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_32BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_8BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_8BIT_IO {} \ + CONFIG.PCW_TTC0_BASEADDR {0xE0104000} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_HIGHADDR {0xE0104fff} \ + CONFIG.PCW_TTC0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC0_TTC0_IO {} \ + CONFIG.PCW_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_UART0_BASEADDR {0xE0000000} \ + CONFIG.PCW_UART0_BAUD_RATE {115200} \ + CONFIG.PCW_UART0_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART0_GRP_FULL_IO {} \ + CONFIG.PCW_UART1_HIGHADDR {0xE0001FFF} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_UART1_UART1_IO {} \ + CONFIG.PCW_USB1_USB1_IO {} \ + ] $processing_system7_0 + + # Create instance: ps7_0_axi_periph, and set properties + set ps7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps7_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {2} \ + ] $ps7_0_axi_periph + + # Create instance: pynqrouter_256x128_0, and set properties + set pynqrouter_256x128_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:pynqrouter_256x128:1.0 pynqrouter_256x128_0 ] + + # Create instance: rst_ps7_0_100M, and set properties + set rst_ps7_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps7_0_100M ] + + # Create interface connections + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_pins ps7_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M00_AXI [get_bd_intf_pins ps7_0_axi_periph/M00_AXI] [get_bd_intf_pins pynqrouter_256x128_0/s_axi_AXI4LS] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M01_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins ps7_0_axi_periph/M01_AXI] + + # Create port connections + connect_bd_net -net axi_gpio_0_gpio_io_o [get_bd_ports LD] [get_bd_pins axi_gpio_0/gpio_io_o] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins ps7_0_axi_periph/ACLK] [get_bd_pins ps7_0_axi_periph/M00_ACLK] [get_bd_pins ps7_0_axi_periph/M01_ACLK] [get_bd_pins ps7_0_axi_periph/S00_ACLK] [get_bd_pins pynqrouter_256x128_0/ap_clk] [get_bd_pins rst_ps7_0_100M/slowest_sync_clk] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins processing_system7_0/FCLK_RESET0_N] [get_bd_pins rst_ps7_0_100M/ext_reset_in] + connect_bd_net -net rst_ps7_0_100M_interconnect_aresetn [get_bd_pins ps7_0_axi_periph/ARESETN] [get_bd_pins rst_ps7_0_100M/interconnect_aresetn] + connect_bd_net -net rst_ps7_0_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins ps7_0_axi_periph/M00_ARESETN] [get_bd_pins ps7_0_axi_periph/M01_ARESETN] [get_bd_pins ps7_0_axi_periph/S00_ARESETN] [get_bd_pins pynqrouter_256x128_0/ap_rst_n] [get_bd_pins rst_ps7_0_100M/peripheral_aresetn] + + # Create address segments + create_bd_addr_seg -range 0x00010000 -offset 0x41200000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] SEG_axi_gpio_0_Reg + create_bd_addr_seg -range 0x00040000 -offset 0x43C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs pynqrouter_256x128_0/s_axi_AXI4LS/Reg] SEG_pynqrouter_256x128_0_Reg + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/hls/lines256_length128/main.cpp b/hls/lines256_length128/main.cpp index 38033932d4339090fd942d68ec2af89117b2b48c..49dfbc33274a4b2a327dc8d330f6b141d28131b1 100644 --- a/hls/lines256_length128/main.cpp +++ b/hls/lines256_length128/main.cpp @@ -17,6 +17,7 @@ #include "router.hpp" +#define PRINT_SOLUTION int main(int argc, char *argv[]) { using namespace std; @@ -50,9 +51,11 @@ int main(int argc, char *argv[]) { seed = atoi(argv[2]); } +#ifdef PRINT_SOLUTION int size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); int size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); int size_z = (boardstr[7] - '0'); +#endif // \os ap_int<32> status; @@ -68,6 +71,7 @@ int main(int argc, char *argv[]) { cout << "status = " << (int)status << endl; cout << "elapsed = " << ((double)(clock_done - clock_start) / CLOCKS_PER_SEC) << endl << endl; +#ifdef PRINT_SOLUTION // \ cout << "SOLUTION" << endl; cout << "========" << endl; @@ -80,12 +84,13 @@ int main(int argc, char *argv[]) { cout << ","; } int i = ((x * MAX_WIDTH + y) << BITWIDTH_Z) | z; - //cout << setfill('0') << setw(2) << right << (unsigned int)(unsigned char)(boardstr[i]); - cout << (unsigned int)(unsigned char)(boardstr[i]); + cout << setfill('0') << setw(3) << right << (unsigned int)(unsigned char)(boardstr[i]); + //cout << (unsigned int)(unsigned char)(boardstr[i]); } cout << endl; } } +#endif return 0; } diff --git a/hls/lines256_length128/router.cpp b/hls/lines256_length128/router.cpp index 08eb1f5a56f3e112d12223540e246cf532c26dcc..29ad14a9e96367a8268a47203dd9dc328945e524 100644 --- a/hls/lines256_length128/router.cpp +++ b/hls/lines256_length128/router.cpp @@ -210,7 +210,6 @@ bool pynqrouter_256x128(char boardstr[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<3 FIRST_ROUTING: for (ap_uint<9> i = 0; i < (ap_uint<9>)(line_num); i++) { #pragma HLS LOOP_TRIPCOUNT min=2 max=255 avg=50 -//#pragma HLS LOOP_TRIPCOUNT min=2 max=127 avg=50 //#pragma HLS PIPELINE //#pragma HLS UNROLL factor=2 @@ -245,6 +244,7 @@ bool pynqrouter_256x128(char boardstr[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<3 ap_uint<8> last_target = 255; // [Step 2] Rip-up 再ルーティング + cout << "Rip-up Routing" << endl; ROUTING: for (ap_uint<16> round = 1; round <= 32768 /* = (2048 * 16) */; round++) { #pragma HLS LOOP_TRIPCOUNT min=1 max=4000 avg=50 @@ -285,8 +285,6 @@ bool pynqrouter_256x128(char boardstr[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<3 #pragma HLS LOOP_TRIPCOUNT min=1 max=255 avg=50 weights[paths[target][j]] = 1; } - // 対象ラインのスタートの重みも一旦リセット あとで (*) で戻す - weights[starts[target]] = 1; // (2) 重みを更新 ap_uint<8> current_round_weight = new_weight(round); @@ -304,10 +302,18 @@ bool pynqrouter_256x128(char boardstr[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<3 } } } + WEIGHT_TERMINAL: + for (ap_uint<9> i = 0; i < (ap_uint<9>)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=255 avg=50 + weights[starts[i]] = MAX_WEIGHT; + weights[goals[i]] = MAX_WEIGHT; + } + // 対象ラインのスタートの重みも一旦リセット あとで (*) で戻す + weights[starts[target]] = 1; // 経路探索 #ifdef DEBUG_PRINT - cout << "LINE #" << (int)(target + 1) << endl; + cout << "(round: " << round << ")" << "LINE #" << (int)(target + 1) << endl; #endif search(&(paths_size[target]), paths[target], starts[target], goals[target], weights); @@ -612,18 +618,18 @@ void search(ap_uint<8> *path_size, ap_uint<16> path[MAX_PATH], ap_uint<16> start ap_uint<16> t = prev[goal]; #ifdef DEBUG_PRINT - int dbg_start_xy = start >> BITWIDTH_Z; - int dbg_start_x = dbg_start_xy / MAX_WIDTH; - int dbg_start_y = dbg_start_xy % MAX_WIDTH; - int dbg_start_z = start & BITMASK_Z; - - int dbg_goal_xy = goal >> BITWIDTH_Z; - int dbg_goal_x = dbg_goal_xy / MAX_WIDTH; - int dbg_goal_y = dbg_goal_xy % MAX_WIDTH; - int dbg_goal_z = goal & BITMASK_Z; - - cout << "(" << dbg_start_x << ", " << dbg_start_y << ", " << dbg_start_z << ") #" << start << " -> " - << "(" << dbg_goal_x << ", " << dbg_goal_y << ", " << dbg_goal_z << ") #" << goal << endl; + //int dbg_start_xy = start >> BITWIDTH_Z; + //int dbg_start_x = dbg_start_xy / MAX_WIDTH; + //int dbg_start_y = dbg_start_xy % MAX_WIDTH; + //int dbg_start_z = start & BITMASK_Z; + + //int dbg_goal_xy = goal >> BITWIDTH_Z; + //int dbg_goal_x = dbg_goal_xy / MAX_WIDTH; + //int dbg_goal_y = dbg_goal_xy % MAX_WIDTH; + //int dbg_goal_z = goal & BITMASK_Z; + + //cout << "(" << dbg_start_x << ", " << dbg_start_y << ", " << dbg_start_z << ") #" << start << " -> " + // << "(" << dbg_goal_x << ", " << dbg_goal_y << ", " << dbg_goal_z << ") #" << goal << endl; #endif // バックトラック @@ -634,11 +640,11 @@ void search(ap_uint<8> *path_size, ap_uint<16> path[MAX_PATH], ap_uint<16> start #pragma HLS PIPELINE II=2 #ifdef DEBUG_PRINT - int t_xy = prev[t] >> BITWIDTH_Z; - int t_x = t_xy / MAX_WIDTH; - int t_y = t_xy % MAX_WIDTH; - int t_z = prev[t] & BITMASK_Z; - cout << " via " << "(" << t_x << ", " << t_y << ", " << t_z << ") #" << prev[t] << " dist=" << dist[t] << endl; + //int t_xy = prev[t] >> BITWIDTH_Z; + //int t_x = t_xy / MAX_WIDTH; + //int t_y = t_xy % MAX_WIDTH; + //int t_z = prev[t] & BITMASK_Z; + //cout << " via " << "(" << t_x << ", " << t_y << ", " << t_z << ") #" << prev[t] << " dist=" << dist[t] << endl; #endif path[p] = t; // 記録 @@ -649,8 +655,8 @@ void search(ap_uint<8> *path_size, ap_uint<16> path[MAX_PATH], ap_uint<16> start *path_size = p; #ifdef DEBUG_PRINT - cout << "max_path_len = " << p << endl; - cout << "max_pq_len = " << max_pq_len << endl; + //cout << "max_path_len = " << p << endl; + //cout << "max_pq_len = " << max_pq_len << endl; #endif } @@ -676,6 +682,7 @@ void pq_push(ap_uint<16> priority, ap_uint<16> data, ap_uint<13> *pq_len, ap_uin #pragma HLS INLINE (*pq_len)++; + if ((*pq_len) == 0) { (*pq_len)--; } // Queue is full -> Last element is automatically removed ap_uint<13> i = (*pq_len); // target ap_uint<13> p = (*pq_len) >> 1; // i.e., (*pq_len) / 2; // 親 PQ_PUSH_LOOP: @@ -708,7 +715,7 @@ void pq_pop(ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint<13> *pq_le ap_uint<16> last_priority = (ap_uint<16>)(pq_nodes[*pq_len] & PQ_PRIORITY_MASK); // 末尾ノードの優先度 PQ_POP_LOOP: - while (1) { + while (!(i >> 11)) { // (2018.08.25) Loop condition fixed #pragma HLS LOOP_TRIPCOUNT min=1 max=8 avg=4 //#pragma HLS PIPELINE //#pragma HLS UNROLL factor=2 diff --git a/hls_2018/README.md b/hls_2018/README.md new file mode 100644 index 0000000000000000000000000000000000000000..063636aa3acc070e23c3ec01f073734be1827987 --- /dev/null +++ b/hls_2018/README.md @@ -0,0 +1,68 @@ +# pynq-router (sw) + +PYNQ-router for Vivado-HLS (2018 ver.) + +## Types of router + +|Name|Operation name|Description| +|:---|:---|:---| +|01|TBD|*Line-number-free* router for "PYNQ-Z1". Priority queue is implemented with circular array(non-parallel)| +|02|TBD|*Line-number-free* router for "PYNQ-Z1". Priority queue is implemented with circular array(parallel)| +|03|TBD|*Line-number-free* router for "PYNQ-Z1". Priority queue is implemented with heap(size:$`2^{15}`$)| +|04|TBD|*Line-number-free* router for "AVNET-Ultra96". Priority queue is implemented with heap(size:$`2^{16}`$)| +|05|TBD|*Low-memory-usage* router. No BRAMs are used for storing route information of each line.| + +## Memo + +* Vivado HLS 2018.2 +* Vivado 2018.2 + +Options: +* Part: xc7z020clg400-1 (PYNQ-Z1), xczu3eg-sbva484-1-e (AVNET-Ultra96) +* Clock Period: 10.0 ns +* Clock Uncertainty: 3.0 ns (--> 3.25 ns) +* Synthesis strategy: ~~Vivado Synthesis Defaults~~ Flow_PerfOptimized_high +* Implementation strategy: ~~Vivado Implementation Defaults~~ Performance_ExplorePostRoutePhysOpt + +## I/O +* Input/Output: boardstr(8bit\*41472), seed(32bit), &status(32bit), return(1bit) + +## Results +|Q|heap(seed:0)|c-array(seed:0)|OR| +|:---|:---|:---|:---| +|01|1|1|1| +|02|1|1|1| +|03|1|1|1| +|04|1|1|1| +|05|1|1|1| +|06|1|1|1| +|07|1|1|1| +|08|0|1|1| +|09|1|1|1| +|10|1|1|1| +|11|1|1|1| +|12|1|1|1| +|13|1|1|1| +|14|0|1|1| +|15|1|1|1| +|16|1|1|1| +|17|0|0|0| +|18|1|1|1| +|19|0|0|0| +|20|1|1|1| +|21|0|0|0| +|22|1|1|1| +|23|1|0|1| +|24|0|0|0| +|25|0|0|0| +|26|1|1|1| +|27|1|0|1| +|28|1|1|1| +|29|0|0|0| +|30|0|0|0| +|31|0|0|0| +|32|1|1|1| +|33|0|0|0| +|34|0|0|0| +|Total|22|22|24| + diff --git a/hls_2018/auto/auto_compile.c b/hls_2018/auto/auto_compile.c new file mode 100755 index 0000000000000000000000000000000000000000..d0589ddc4188ebf33907de7a14db1cc9dee1ca75 --- /dev/null +++ b/hls_2018/auto/auto_compile.c @@ -0,0 +1,30 @@ +#include +#include + +#define STRLEN 65536 + +int main(void){ + + char q[STRLEN], command[STRLEN]; + char dir[64] = "../router_01"; + + FILE *fp; + fp = fopen("q.txt", "r"); + if(fp == NULL){ + printf("File does not exist.\n"); + exit(1); + } + + int counter = 1; + while(1){ + if(fscanf(fp, "%s", q) == EOF) break; + printf("Q. %d\n", counter++); + sprintf(command, "./%s/sim.exe %s", dir, q); + //printf("(command) %s\n", command); + int ret = system(command); + printf("ret: %d\n", ret); + } + fclose(fp); + return 0; +} + diff --git a/hls_2018/auto/q.txt b/hls_2018/auto/q.txt new file mode 100755 index 0000000000000000000000000000000000000000..f7ee6af10a9aa0726d0816f7bc4cfc1371fa329b --- /dev/null +++ b/hls_2018/auto/q.txt @@ -0,0 +1,34 @@ +X24Y24Z4L0613304164L1702122032L0101403204L1601420204L2117419044L0023116021L1520309084L1921116154L1709121031L1812103211L0905208142L0704412013L0421110094L2320100142L1500319034L0915104123L0907418124L2001109101L0122202213L2102422011L2120105211L2319117132L0404119103L1215322223L0607218074L1715113123L1217220172L1602320113L0003306053L0405413144L2006421214L1301103212L0614322183L1108323004L0004322043L0602322213L1210120142L1321419172L1202116012L1303103081L0820211202L1003116142L1701305123L0312223072L0720301063L1202214024L0506207072L1610417224L1309404154L1201408124L1704410064L0822110211L1210321153L1708116072L0000100111L0201112011L0808104103L0923210212L1210413134L1500421014 +X15Y15Z2L0202212102L0303211112L0404210122L0503209112L0402210102L0204212122L0203212112L0302211102L0403210112L0504209122L0502209102L0304211122 +X20Y20Z8L0203202066L0400403037L0403105088L0503101016L0500206038L0703317055L1001104054L0505317087L0108204086L0111101177L0810406188L0313406138L0413215177L0513106176L0317302158L0715100195L0318307064L1503212048L1702112058L1206318087L1007417036L1101317047L1406216094L1111217187L1310418146L1510315145L1014310177L1317219198L0919218177 +X72Y72Z8L0000171718L0036871001L0000800718L0036171008L0071171711L3671171368 +X08Y08Z4L0000107072L0100103032L0007106072L0503106032L0506101062L0001205062L0404106051L0700207032L0201202032L0205203052L0000307074L0100303034L0007306074L0503306034L0506301064L0001405064L0404306053L0700407034L0201402034L0205403054 +X48Y36Z8L0609109051L0608108091L0709109021L0306109041L0204109091L0207105091L0208105041L0209104041L0607109031L0516105191L0417106171L0418106181L0113103131L0213104211L0214107211L0413110211L0814108211L0221110221L0226103321L0331104251L0128105321L0329108321L0733109261L0629107261L0630107271L0233106281L1400123101L1503123061L1504122101L1508122081L1509122011L1606118111L1702122041L1212119211L1319115141L1316120151L1217118171L1313119221L2020122121L1517116221L1421116171L1527123351L1328120261L1533122251L1830121311L1334120291L1426119261L1632119251L1730122291L1431121341L2501131011L2708128051L2800134051L3400135111L2400132031L2704132081L2406125021L2504133101L2401128101L2522134151L2921134161L2513134171L3013134221L2614130171L3019135191L2415130181L3414135121L3524135341L2533135281L2727135351L2435129311L2734129351L2829131331L2833132321L3607146111L4207147111L4010147001L3600137101L3608144021L4509146051L4020145141L3614141151L4218147231L3612145201L3712143141L3623144181L3912146231L3624144301L4030147241L3635137321L3835147351L4132146351L3634145311L3726144291L3733142281L2935227213L0629622066L0606335013L1728617245L0814411182L2608416057 +X72Y72Z8L0000166038L0004128038L0013104688L0016158688L0030133688L0046120038L0071149038L7165169688 +X70Y70Z8L1006530061L6936145414L0200136021L0349503538L6038613668L3754663198L5736462345L1925421692L2610640004L0836536045L5820736441L1344511357L4920658368L2319455092L5761834521L1203503086L6860757648L3133653206L4411730011L2624861188L6211867455L0645520521L3102432307L4908444021L0932510398L0841516497L6313158085L5746565678L1606405095L5753837421L3159825694L3753336537L6009349074L2012636101L3943238543L4466665497L2312224103L5369269585L6467265683L0038200558L0861220691L1111205002L5158452558L4029156215L2846714572L3030467483L3755137694L5849500646L6610667108L4761648684L4823235011L0820817098L2141114503L0361602618L1712200057L2700229021L2032713308L0964710682L6050858538L3838341491L6022363175L4400735031L4229837288L6110667088L6661368642L2804511005L0632803446L0817704004L2502529018L0214531131L4428345162L3900335061L1967511678L5856869694L4127653172L3855443656L4310561006L1318807218L3667234694L2806631045L5955466554L3621137221L4855147461L0736808428L0543201482L3446822598L4069223584L4446346462L1457716314L5249768692L3339324181L3003733086L6636844652L2929440362L2727518336L2355641666L2059831608L4730252231L0436421253L5350456605L3319536105L3903624138L4429540374L2263216691L2733116375L4105555217L5715666025L1312537134L4747547544L6012367533L4456566454L2649327638L4930563387L5219557168L2357221682L0529205321L1624115307L5640145442L1639722257L3739842397L4165337628L3731537276L2008723038L2940631346L4231151241L6104161024L3761739636L1659303485L2703226041L5116150151L5726556326L1418236114L5811158091L5538649413L6701264031L1708208112L3360532611L6218564205L4605646026L2210117013L4844148411L6837563188L4246144525L4204239041L4912860388L3057432624L0640112373L0812601373L4122529268L4930846361L1110513105L1827532425L6467569613L6914162331L1044725538L5230849268L3208332063L3857634627L5122252172L1344224408L1119306061L0244408364L0603208026L5645658554L2909223144L6945169391L4416449142L1007809255L5158237585L3861435594L1107308083L6401865017L2945831438L0207301044L0217511154L6358861628L1150604456L6165369675L3630138303L4317150121L5104757056L0224807207L1922318303L2123812227L6636660611L5551853586L4645444484L1830720344L1617808036L1957722597L5305153022L0822407362L5455556527L0416506195L1061815678L4215655238L4933549276L6414357154L5113834086L3146631614L4405645046L3540235616L4009445078L5064151674L0467413553L1706508105L3407535045L4546434375L5050648314L2142722472L6535560333L6254463453L1218708157L3918139143L4518842016L4144243382L3012131071L4663648587L6545668108L6613361126L4946550555L0407103062L4754747558L5721358192L4443844357L2253715508L3731136336L6264759472L2239516422L1541708398L3055727507L6841266443L6336360343L0524303211L1365201624L5143451371L1154712502L1354820571L3756535607L5326145424L6626359188L4152335487L0456110563L6437161348L4123344193L5542454474L1554518535L4651741547L2409211346L2039722336L0708605038L0337710387L1107209062L5117456165L0715506158L5407853067L1221100091L2348628466L6519363194L2701217012L0746208241L5901844005L2101815018L5267853588L3756235491L4230739307L5322856195L4918149201L2020518215L4543862438L5157349563L1112113153L2648326562L3025237322L6115260151L6061569628L3135841406L2341229332L1860817638L6957866578L5760249591L3810839117L3500736038L1335328332L5661858588L0225615054L3350131471L1254423488L3909343026L1823716184L6330364391L5363164573L3959647568L1128610356L5551252333L1401813015L2810226131L1034312353L3258236562L5638157345L1350609458L2941727487L5212652107L2140620417L4162751666L4937350393L1428325177L4143240442L0769609696L0538601518L2830329358L0732806276L3921736168L3013837148L5100143042L2461425693L1922224102L0009606146L0645201632L2015818188L5255153531L2550229452L6546666447L6334768358L0752108531L5412159103L0750806516L0418211165L0152103413L1107812106L1910518096L1838407372L6609560168L0942509462L6019458163L1533212241L2550624516L2369321693L4325742238L6213160144L6767859695L1906522008L4258639538L6368367575L4762557692L2601424018L2916516046L4863740697L0828704277L3531334274L4714543175L1161508662L0530309302L2527432296L6943268462L2439723376L4407749117L2112734037L0126801308L6431654308L1334818308L1660211673L2110527121L1621814208L3307529006L3724532137L6632869386L4203540046L3434337331L2957326424L3251634506L5431451311L6731262326L2122524164L2346528455L3769151691L3125835288L2529222252L6765767668L1112611146L3629329304L0236601306L5608556094L3935738317L2224321211L2339735405L0719401084L2845726457L0941721403L3357736594L0125214181L3440840404L1739519436L4761351694L6065163671L4264541618L3019337244L1061213671L5148856508L4553244481L4734248351L4361148572L4066743585L0307604056L1139313393L6129561325L0232205311L5231351293L0334208303L3629439275L4643151401L6618161103L3110525108L5844555425L5459555645L1868717696L0512207141L6833867328L5062352623L0302203031L0468109682L5207649001L3337533314L0739210373L2501519005L5923763266L4432145282L3735639346L6759265521L1837819377L5403656015L6761663647L3767538667L0835602371L5406455052L4053239543L6562569688L0367507652L3827238246L4708545025L3027232252L2109733146L3511731118L0761405521L1957320561L0545302594L6817559086L2764328685L5121252228L3347739388L2349219423L0363800695L6902566006L4424743238L4651152521L3403634008L4113138142L3647136491L2819331193L4117638137L4362239693L2727121281L5321250211L0950310496L1646513428L5153851551L2809629108L2661716698L6525167211L0156207531L1338617427L0769418673L0964209631L3036330402L0360202511L0946107461L3303832028L6148863508L5032251312L3820540195L3520130181L2719125124L1461113614L3707434105L4616152092L2514625166L1828324186L2501326021L3556635546L6024457254L5534667302L6951365533L0630301323L5963859658L5040730427L5706856038L4837745357L0958412587L5426268231L2255424535L5029552316L1030410324L6246163411L4601445005L6644266471L4224640237L1555604575L4643843388L6543647417L2429823328L4522236162L0947409483L0854807548L1339612406L0168708698L0238207432L0143700427L6140267314L4246446463L3512335142L2102418034L2063418694L2647128501L6648367491L0133808138L2461819687L2069620684L0425801248L2563226592L1457802485L6744562418L6904267002L5827360283L6040253361L3539440425L3317724234L0217300142L2660729597L3004328104L4041637487L5755445484L2203226037L1540515416L2601724006L5530651296L3436731297L5347251491L0458204571L0918609177L1132511344L5350251411L6138463403L5360151623L6829569334L1950318504L6616466184L2334121331L4015840165L0818306181L2823123193L2241420425L6252460521L4713440222L6114565171L0336205331L4709847107L1356413574L2302333011L4535545364L2205729053L3962638613L6247462444L1244820555L5643561464L1801821028L1504813048L3449435464L3857837598L1047416491L5353554525L6759465584L3269732657L0230302311L5506657027L2220824165L4812546077L3255624557L5729160282L6745768457L0928804308L5607355042L3962438622L2202116002L0765508664L5523457235L2063320663L2545226461L1039611417L5221251202L0336804358L2205319034L5259453614L2661824617L4439740427L3545135471L6524263225L5838659397L5611456086L1450614535L5830857318L4711648073L0926708288L6829469284L0036602376L1935720347L2062519634L6558163562L3468530638L4817449148L6417160171L4054542556L0823516177L6430561315L1662818628L2315619196L3152532515L4813652116L5500355024L6926869248L1362614646L1522820278L0366805658L1820709336L4228745307L6108562064L1865516591L5336549365L6117561186L0745406466L1640813408L3308132073L3321133251L5302153041L4904549065L3146534405L0169703686L3505535075L1323618287L6827862298L3847434485L2244324434L0755509587L2949426504L0457201572L5852656515L5320455215L6856267553L2767528645L6315565165L4721152101L0018400173L2155215501L4833445314L1901720046L0824607228L6249761538L1150714478L5605556035L1565312684L2633825328L5912659065L0816509145L2616830165L3609336073L6439668401L1907222091L5265447684L3452339611L0739602457L4942447454L3458837588L2664625647L0705806108L2221315123L3550543495L1126612266L4521245221L6433669364L1354611546L0103700047L1018215181L5521354193L0940110391L2617324173L5541258443L1610114141L6715165151L3665237561L6537767396L2445216462L1738121424L1855817565L2706531132L0056501496L0246503435L1733717344L0253701547L6917365114L1340412393L3822839258L4961448574L2959131641L4508650128L4627450232L3310531128L1156609556L4656142561L3015431134L6143758516L2168626658L5414151112L1232107331L4101844018L3952140571L4041442415L1457114591L4064440653L5200554034L1222503256L2632129341L2528424222L1403519032L6651469504L0758106601L3666633646L1549515484L2212823187L6833169312L4848754418L6140363451L0954309472L1854721537L1958418574L4363844606L5226253263L1406120074L0746809468L4035537354L0258101622L6104460034L4936846337L1816817178L6420861216L4850447524L0202104001L6207261111L1166611686L2429326303L1134821355L2235421335L3116128183L0214401188L6915468134L6728768296L0234508342L0041201382L5925764198L1526208321L6068846687L1011705068L2740628386L2503526045L6332863306L4553843548L0359306543L2852127542L5608453081L0943307422L0630504306L6609667086L1628111242L2340124381L4246745447L3022230192L1409416092L0314703155L0128207232L4227249241L4203238032L0436601347L6637869388L2753220522L5239754337L3941140401L3520735187L1830117292L5308853108L5067451592L2721324213L1607812057L1148410504L5500155031L5907157042L0311601157L3519432182L2567618698L6621665215L4750752466L3115229162L1428815248L0354405555L0558604595L4613747108L3300629008L4649346502L0446404495L3846141462L2210621094L4443441366L5033249363L3443436414L6503363003L0322312173L0154300581L4257340594L1544819456L2421823214L3467530647L2951626496L4902850018L6222166251L3945439494L2937332371L6650761537L4249340513L2956729548L6234162371L0264401675L1046411436L6163357641L4001342003L3568140655L2647427485L4208842128L3119631236L6702368032L5227254321L5020851216L3423538227L1256213611L5743257421L5127352276L4840849438L0026604178L4556250611L6843566385L6167660696L5727360301L4401347002L3430136291L6043859437L4305340054L4435539303L1503314004L4632626328L1244318451L4835449333L2525630257L6513668136L6258765557L6620264212L4521547225L6835667357L4827549272L6850466508L0668707675L3409833118L2529525306L0539806418L3667736658L1560718584L3917342154L2914333143L1936415364L5242651446L2214119221L0658704577L1663607605L4261442644L1236811358L4716650134L6043361444L2358323574L2763627616L6568265673L2804626075L5363753617L1902820018L1028107291L3821331223L6234463334L3948239512L2805823108L4843246432L4768247651L0341206411L2403221032L0512108171L5348354503L4367140671L5246854467L5145350442L4353141544L5824659217L6534269351L2528126301L0021101221L5039548373L0011601096L1704516068L3343331484L2855529504L4267746698L3433636334L6103160071L3003631046L1913217132L3643838388L0610204142L2349819487L5711458105L6468765677L2202320023L1625614277L4910648056L6459165571L6337461363L3855841467L3450330523L3642539425L0565206682L3004629137L1045710477L5965261671L6859669586L0502806027L5247753461L3913140142L0619109211L3539128381L0748509485L0751706497L3127136271L5606553065L0565302654L1810218114L6652468524L1027811298L4133842347L0750415505L2352126531L4407243061L5566757658L0469805688L3808837108L0255603505L6527566285L6443567416L0232504325L2444823458L3940834457L5724265232L6633768346L1510715077L1628816338L2843830458L3441733418L1153209523L5268153671L1328613315L1637317413L6966869647L5458352573L2424621224L6306366083L2813227144L2307621086L6710467095L2302721037L2427423264L4203747057L0006101051L3528336273L5660858608L5868259662L3701836028L4742446444L0623305283L6245663455 +X15Y15Z2L0602214082L1406114081L0901111112L0110100072L0405209012L1108112071L0707208011L0301107002L0014101142L0405103072L0006203042L1008111071L1301214132L1403114012L1404210011L1113207112L0206206052L0603104031L1211110121L0512202141L0201203032L0105101042L0809209062L0609100121L0501204022L1110211082L0809112091L0000201001L1304114051L0102100001L1114113141L0401101012L1007109132L0714204131L1005110031L0611103112L0112102131L0208102061L0708206092L0007100101L1409214112L1300211002L0501106001L1114212142L0511104111L0704107031L0702208022 +X23Y12Z6L0303122021L1102219103L0503504065L0302105101L0200305093L0907100081L1309100071L0706221102L0500212014L0301605026L0104216063L0204408034L0910502106L1805113052L1406116041L0409310114L2106122103L1710201033L0510412024L1411222072L1503421106L1310519035L1306220044L0101201112L1701221014L0802503105L0603107091L0407113012L0000513106L0201405045L2104320086L0202606086L1804120091L0609411104L1607522005L0000101102L2002320095L0610110111L0709500116L1603422006L0203109041L2201113011L0808611016L1807519006L0611316083L0910318074L1608415035L1001602076L1203603106 +X08Y04Z8L0000107018L0100103014L0000806018L0500406014L0500701017L0001205017L0400506006L0701107014L0201202014L0201603016L0002107038L0102103034L0002806038L0502406034L0502701037L0003205037L0402506026L0703107034L0203202034L0203603036 +X36Y19Z4L0101113011L0702107151L0804112071L0803108051L0802108071L1202108091L1503106151L1501106161L0204104041L1500101041L1612109161L0216104161L1114117161L1616114171L0503105161L1216117171L0203121091L0403103141L2606132061L2706131061L2907124111L2212128121L2112129121L3103122051L2503130041L2304128051L2213131151L2813123141L3014125151L2707126111L2608128111L2408129101L2309131101L0000205052L0101204042L0202203032L0007205122L0108204112L0209203102L0115204182L2301323143L0216203172L0700219122L0801218112L0902217102L1003216092L1104215082L1205214072L2100235002L2201235012L2302235022L2403235032L2504235042L2605235052L2706235062L2807235072L2908235082L3009235092L3110235102L3211235112L3312235122L3413235142L1302402134L0709413154L0000308033L0012308153L1300335153L1301334153L0215410154L1505415134L1615426154 +X72Y72Z8L0000109098L0000809091L0000401004L0001401014L0002401024L0003401034L0004401044L0005401054L0006401064L0007401074L0008401084L0009401094L0202403024L0203403034L0204403044L0205403054L0206403064L0208403084L0209403094L0200402014L0300404004L0307404074L0401405014L0402405024L0403405034L0404405044L0405405054L0406405064L0408405084L0409405094L0604406054L0704407054L0804408054L0904409054L0608406094L0708407094L0808408094L0908409094L0507406074L0500406004L0601407014L0602406034L0700408004L0703408034L0706408064L0707408074L0801408024L0900409014L0902409034L0906409074L0009109008L0900100098 +X10Y10Z2L0802106042L0001208031L0701209021L0206209011L0004100022L0000206071L0201102022L0105101072L0809106081L0805209091L0407207051L0208101061L0108200091L0303202012L0702205042L0008200032L0703207011L0601205022L0506204062L0904209052L0404104031L0203102021 +X60Y36Z8L1702113248L1503212078L1304112137L1105311206L1309202336L1508310125L1707105075L2306307228L1804417226L1514210145L1824104328L0421106315L0319308307L0728200297L0523306266L0427322325L0228305186L0131309237L0706108136L0604201114L0502114124L0303404128L0405208156L1428114338L1229116328L1530415237L1616316257L1426311225L0310305095L0213106115L1417207175L0921312184L2400420057L2500121028L2600325026L1934213316L2219422338L2119222348L2019326255L3233335335L3331436337L3332437336L2601232035L2101124046L2206321176L2604224067L2435137357L3708324344L2433238354L2103221068L3803133018L3517237327L3617335226L3717236306L3918339358L3126322287L2229127315L2230126306L2603134037L3503259165L3603437055L3411429198L3412330204L3413337125L2607324085L2309224157L2316124097L2907436085L3325432296L2317423197L2528430268L2805131094L3307235084L3713334204L3524235288L2318124218L3009227126L3711332228L2614227227L2609326125L4006144215L5917244205L5406244196L3906245197L4905445208L5420344264L4016154194L5519250344L5520349345L5521254275L4609348155L4816356326L5115344045L5504351165L4625344305L5113346265L4925253257L5309150256L5308253246L4506250057L4608149128L5530243326 +X15Y15Z4L0401105001L0601114013L0213213023L0105105051L0014102131L0704210074L1208211133L0812110081L0612306141L1201213003L0408300142L0911114064L0411300131L0007208004L0913409121L1210307101L0502401072L0108400032L0608105074L0103301021L0814308112L0510201083L0800106001L1414310134L1209313103L0604405023L0714206144L1109412083L0409205083L1207113051L1213314123L0514206143L1207212053L0804307013L0208302064L0302300054L1009413134L0412103111L0408203074L0810309093L0313302122L1410114071L0812209132L0902408034L0604208041L0203202021L1313113092L0709406104L0510302084L0709108081L1201412034L1307214104L0611206092L1100309044L0412203132L0301304003L1002409034L1411213101L0411402114L0101301011L0907209052L0900111001L0809308102L0101401044L1404314044L0310203092L0504305041L0111301112L0205202042L0612205122L0505406054L0314102141L0011400104L1210411104L1201113011L0305104051L0401405014L1002309023L0609405094L1108112081L0900310003 +X50Y50Z4L3445116362L1019117072L0522204221L0819441201L2000412094L4030442411L0104204201L2735421433L3813228071L3021210062L4302448011L2010412151L1144412472L3338127344L1220303101L4749131464L2330243241L1726217104L3522430223L0509210074L3019300001L0542301444L1505326093L1303421042L1431329254L4437325204L0310408073L4933349322L3008212084L1842321414L0640200234L1224205234L4223343312L2805222012L3649143492L0737139174L1011410083L1746243481L0813412131L4335123151L1133124311L3716338194L1713316183L1841426312L2224424224L4346434474L3325241251L4704346054L1729418154L4445346484L3227231314L3221336021L0508400002L3501330004L3541233473L2526425333L0805200011L1136431454L0645314481L3138435273L1324217263L3704327124L0635411131L4239129461L0731319114L2039121371L1928121203L0042425323L0006308083L2426117184L1217104442L2506230003L0530303273L1319217152L0634108311L4536247484L3945237413L1240404344L1806433064L4928149323L3100430091L2913228113L4637246462L4305443171L2923123191L1018313203L0736306353L4923239164L0839404354L4911445214L2341421484L0846407471L0215302151L0235201374L4801242031L3008431074L0313208122L1747115471L2426222254L3801436004L2114220061L2816420154L0607201041L3614330224L2709128102L0726306221L2942430452L0240201331L2421225164L4503349024L0540409322L4421342213L3237245363L0124100232L3723135172L2239425362L1524117241L0849205494L2724132241L3321135203L4613144131L3513134161L1301221002L2618129221L3831242302L0543403444L1904417063L0309303012L1642114421L3817240191L0926410274L1331413291L1911119113L0222302121L4125449253L2943233494L3120130133L2029212213L4844448473L4820448242L2947427462L2049122491L3634433344L2301324003L0722410253L3937330394L2428125291L4041235202L3314336102L0735411371L1705421004L2902327083L1737421343L3211229204L0028301323L0333204301L0042305413L2502126011L0737311282L0819301101L2719326143L2628225281L2639223403L4607241092L2608224061L2036312442L3749340493L2634126322L2025321283L1132413304L1832316302L0440204433L4505442002L4621149182L0343111393L0510107102L2447224452L4603148084L0112403124L0100320014L3738432404L4129239293L2826232262L2220423212L4635444454L3736241431L0516105142L3944443484L1625212271L0043411404L4442145451L0636307362L0839308414L0411202112L3204431054L2507323073L4208343064L0841206474L4841448384L0738206392L2829331213L0405301013L0929309263L1236111334L3901237022L3107129093L2110221122L0904405071L1941119441L3302332013L1049407494L0220413183L2641125451L0134400334L3236131372L0247402443L2937330363L3612240131L4736148364L0306403084L4628348293L2239320294L1146312471L1816120151L1523217232L1405316074L1602410052L3005133061L3430134293L4526141261L3304236013L0107203092L0629304313L2739125391L1420412254L4401143021L1737313394L0948311492L0505104093L0914110182L2929129372L2244425483L4113341153L4315240143L2348322461L0049204492L4743345444L0102301082L0604405074L3745137472L1422117221L3614440123L3503436044L0114209191L4629346321L2213122111L2722425224L0144103441L0437404394L0303204033L0118402174L3827443292L1649214492L3803138051L2829127251L3809339064L3739138331L1101207041L3739443394L4611245122L2902226023L0812410154L3238327384L0047102481L3644128393L3421134222L2340123421L0938210452L0902319013L0542105432L4021441204L0416407154L4831343314L1401217003L1333422332L4723347253L4047237471L3018132193L4305242062L2002116011L3337432384L3922340213L4123138231L4238142361L2408125103L1212311143L2620129182L3124128251L3218435174L0134202332L1840319453L1021211202L0718101161L0943110421L0643408434L1046408484L1503315064L0122303241L1333316361L1348412463L0649108481L4639243391L0027102291L0419406184L1409314181L2640325402L2105120042L4419443164L1209111121L4042239402L3042131443L1407311052L3134427343L4841249392L3709137071L3116331144L2336219391L4817148221L3340333383L4246143471L2600427023L3905239014L0742207413L0743108442L0147301481L4834447342L3414235111L4638446364L1818116181L3141330432L1242113391L0525308242L0431107311L1336214352L3928341293L2522228222L4849347393L2325225282L2401425034L2109117143L0801113033L4614242142L3140329403L0239104331L3846143451L1935216344L0219404184L0339104381L2720126162L3537437373L3435234341L1132313323L1035410323L4716348202L3836241352L3530235322L1934419303L2318422203L3733435313L2202118011L3605236041L0139403421L3149229482L3412236152L3911247081L0320101211L1500216003L2905332081L0524105261L1616415184L2844228422L0400404024L3309330093L3926341234L2817328193L2117319173L4243342403L1525314263L1101112023L4948145471L4101341033L1439216392L1428317293L4947146471L3204333033L0227406254L4920448173L3024231231L4535145342L4541444424L3425235251L0317201192L1605117052L4823447223L4703146021L4501447014L4815247131L3829239292L1014210162L3314131173L0613306153L4045338413L3740438393L0435105361L2038417364L2705126071L4107344073L0817410173L3323337244L4949148492L0628406331L2228123282L3831438294L1540415413L2831329303L2027318281L4004338022L1644316434L0214304143L4738148401L4318345193L4247239432L1022411214L2827338273L0448103462L4733446344L2704225074L0935409394L0226404243L4044342453L3436430352L2331221302L1324316243L4723147272L3039232392L3537234363L1507116081L4140140411L0336102381L0127401314L2447423484L0027300262L4814448124L3947341462L1424414223L2724229242L3504434034L4924149272L1805419034L2903129051L2143420443L0227203282L1239212413L4328243262L3446131461L2340222412L3348230482L2234120341L2120220212L4604148021L0903110041L4436441354L2424422274L1732216311L3344233462L2434324322L2543424414L2319323173L1225114253L1919320203L1544317464L2322122231L4333439374L1043310444L0201105001L0337202342L1622316232L4425346263L3134329324L1542114411L4320243222L3541137401L2218221192L2619224192L4510144071L0618203173L2235327372L4005242052L3834236342L1344113443L4112446114L2606127041L4518143192L0225203262L1103209033L1837420404L3438234361L4506445084L1122111223L2920229212L1617317192L4037341364L4210245102L4132340334L1019411184L0445302453L1821315214L0646304444L0436404383L4813148111L0348403472L0319402203L3432133302L2527426254L0125301264L0907210071L0206401074L1646417441L1637314373L4249242483L0415202152L2123422233L2405322053L2804329044L0629406274L0340101422L4842347413L0628207302L3440335393L0117101182L1946117461L3120229192L0511303113L0137201352L3906240072L1505214042L0205401044L3242233412L2721227243L2141121391L3827240251L2831229301L2306421064L1926319283L2041119431L1038209392L3012432134L3700238013L3744238443L3545136461L4303442014L4644447434L0320304222L0707408064L1932320322L0638207381L1526115291L0039302403L0405403044L4430344293L1528215274L3340434404L4631146291L0132202312L1000313002L1532214312L4043438434L4010139111L2301224023L4332344313L3317433153L1733417304L1913422134L4343242413L0227101271L0205102071L1904120031L3907438074L4112243122L1739418384L0700105021L4243441434L4743147461L1031111301L4704448054L4505244062L3530138291L3129432274L3746440474L0417203182L0235400354L3002431014L2747228484L4909149102L0234401334L0909109103L0514406134L3649336484L4217141161L1909420084L4543245421L3002329013L0428106291L1937219393L1949220482L4714245152L4814348134L3919139181L4226443254L3001130031L3006329043L3342134441L2842428404L1311213142L2618425184L1410212102L2338422374L4336444354L4349342493L0315102141L3542135443L4503446044L1223213233L0029100331L4833449344L0638405374L3710137121L0832409314L2413423123L2310125101L2640225422L1138411374L0708406083L4940249412L3641237432L0332204322L3914239132L1504415034L2715429154L3433336333L2836129361L4641246402L2505223043L2023319253L2907428084L4045138451L3106131051L3727435274L0541108411L1502116022L0534304343L3247332464L0946110461L1826418244L4209341083L1131112311L3220430204L3015130141L2012420114L2417123171L2315422154L0134300343L1612116101L3428133281L4943149451L4447345483L1135209352L0336301363L1228312293L2047321473L1427113271L3204232033L2041220422L1537316383L4118342193L1022208202L4721449234L1744418444L4910446104L0746307473L3729336293L4524145251L2844427444L3624336223L2623127231L4404344034L1029411294L2016421184L3135231362L2812127111L0102400024L4840448394L0837309373L4915148151L3230331303L2333422334L2323223242L3505435064L4230441304L4623246242L4301344013L1309313103L2813227132L2034318343L1129210292L0919309194L4009239092L3816139162L2822428214L0619106201L3925440254L4705246052L3223433234L4142342423L0603306023L3127130271L0815209152L1024310242L3124331242L4810348113L3443433444L3804338053L4422144211L4518445174L3416233162L1333112331L1849217492L4716448164L3301334013L1846219462L2023120221L2533126331L4616145161L3345234452L1703318033L0430203302L4547447474L0631306314L2142121431L3103431044L2914330143L1813218131L3825237252L1236312373L1141411424L1831418324L4247141471L3714138141L3023330234L2303222032L2728227292L0822107221L3115431164L3403234042L0116401174L2740227392L3408134091L1515115161L2102421034L2731327333L2344223432L0123202232L4211343113L0111401104L1813417134L1613316132L2521324213L1027109271L4336243352L3322333213L2818428174L4900449003L4718147171L2409325093L3928139271L1040111401L0146401474L2926230262L1306313053L0743407444L1013410144L3304133051L2902129011L0804208041L3810338104L1648417484L0041300414L3205332063L4039140401L1802219022L4804349043L2624225242L4205442064L0905308053L2246322464L3534434344L2243322434L1307413084L4541345423L3502335033L4844248432L3135431364L4838148391L1538116381L0025100241L0105401064L0711307123L3031230322L4100340003L2613125131L3947239482L4228242281L2516125151L4039441394L0901409024 +X20Y35Z8L1916104218L1917204208L1406104196L1934305197L0905205206L1420404266L0016414195L1519410346L1520309348L1521414277L0609108158L0816316327L1115204046L1504411165L0625404306L1113406266L0925113258L1309210257L1308213248L0506410056L0608409126L1530403325L0017400346 +X36Y24Z1L0003102031L0302105021L0101104041L0005104011L0603108051L0605107011L0801110011L0802110041L0009102091L0308105081L0107104101L0011104071L0608108061L0606107101L0810110101L0809110071L1203114031L1502117021L1301116041L1205116011L1803120051L1805119011L2001122011L2002122041L1209114091L1508117081L1307116101L1211116071L1808120061L1806119101L2010122101L2009122071L2403126031L2702129021L2501128041L2405128011L3003132051L3005131011L3201134011L3202134041L2409126091L2708129081L2507128101L2411128071L3008132061L3006131101L3210134101L3209134071L0015102151L0314105141L0113104161L0017104131L0615108171L0617107131L0813110131L0814110161L0021102211L0320105201L0119104221L0023104191L0620108181L0618107221L0822110221L0821110191L1215114151L1514117141L1313116161L1217116131L1815120171L1817119131L2013122131L2014122161L1221114211L1520117201L1319116221L1223116191L1820120181L1818119221L2022122221L2021122191L2415126151L2714129141L2513128161L2417128131L3015132171L3017131131L3213134131L3214134161L2421126211L2720129201L2519128221L2423128191L3020132181L3018131221L3222134221L3221134191 +X30Y30Z3L1212111103L1811311041L0412101102L0410218072L2612328231L2411128111L0503313081L1810314062L2301315031L2415326192L2224229251L0323201211L2911229192L1801317002L1128115162L1629211293L2026212291L1701317033L1714120233L2105121031L1014309152L0716104051L2221128271L1205311042L0420308243L0718204271L1221311252L0223201273L0502209071L1314109142L0317204222L2312319131L2026119241L0302116022L1611118011L1224110263L2229116171L1319220271L1710114091L0607203032L0513203131L0109100161L1424315231L1727113241L1416111182L1213213112L2510316102L2521228222L0321306273L2305228003L1501310013L1918120182L2226222241L2313220152L0117203201L2700318033L2103228022L1806215073L2813329182L0318202172L0903109022L2629228193L2610123121L1528320243L1607115061L0124103231L0216103141L2506223051L0624307253L0902110011L1128201291L2907228011L0109202103L2923329263L1016309153L1912320142L1807118051L1216211143L2504124051L1714217113L1828312293L0200100032L0705208072L1321312173L2007120031L0001201002L1312315123L0819107181L0927210281L2410225071L2726121282L1705316033L2609328093L2503321011L0018101201L2328222261L0301306011L2617225202L1112115142L0712108111L0624109221L0606104101L2728228272L0607304073L0514206161L0800306003L1006107042L2013321143L0827310273L1206111051L2715128141L2608122081L0116301183L0313302102L0715209131L2120223212L1627217243L2324322203L0423303241L0818209193L1624315241L2512327101L1912117111L2003323033L2416325132L0504106051L1404314022L1618317143L1318213191L2811326112L2516325142L1619315203L1606118081L2102222013L2806223021L2622324223L0805112041L0923309252L2307324053L2625225232L2023122212L0521105191L0717307153L1920118181L1226312283L2116122141L0727104261L0615105141L2427325263L0204100062L0225200253L1713115131L1928320273L0308203052L1822214232L0811310123L2428123271L2522127231L1109310073L0405207053L0215201142L2815127152L2905128041L2217322152L1216113171L0105202022L2317320172L1810114093L2707128081L0528306263L2418124161L2802329032L0411207122L0619305163L0208201103L1725217272L1108112092L0702208013L2106122063L2921129231L2118123181L2619324193L2908229102L0819307192L0022101231L1315115151L0729209282L0125201272L2708227093L0922308233L1320212222L0424305242L2606328063L1413214123L1819316203L0317104181L1719315201L1315314162L1212312133L2609224092L1212211132L2717327172L1428117281L2010220093L1316213152L0507106081L0113101121L1428314293L1117211162L0812108131 +X72Y72Z5L0000171715L0001170715L0002169715L0003168715L0004167715L0005166715L0006165715L0007164715L0008163715L0009162715L0010161715L0011160715L0012159715L0013158715L0014157715L0015156715L0016155715L0017154715L0018153715L0019152715L0020151715L0021150715L0022149715L0023148715L0024147715L0025146715L0026145715L0027144715L0028143715L0029142715L0030141715L0031140715L0032139715L0033138715L0034137715L0035136715L0037135715L0038134715L0039133715L0040132715L0041131715L0042130715L0043129715L0044128715L0045127715L0046126715L0047125715L0048124715L0049123715L0050122715L0051121715L0052120715L0053119715L0054118715L0055117715L0056116715L0057115715L0058114715L0059113715L0060112715L0061111715L0062110715L0063109715L0064108715L0065107715L0066106715L0067105715L0068104715L0069103715L0070102715L0071101715L3600136004L0036535365 +X72Y72Z2L0000271712L0071271002 +X40Y40Z3L0313329331L1415127043L0237337351L0039335171L3816115013L0016121091L0206138381L1119118151L3703139001L0317137381L1000139393L0932139392L3611108333L3401100383L0125104033L1911124211L1727119261L3117132101L0015106341L1201116051L0025325061L0539333181L0508330061L3200326331L0700234041L0804109001L1614130331L0516122331L2007124221L1218128301L1804100392L1301133383L2125130073L1509105093L1118138393L2705137361L1429127341L3013138361L3007136121L3118137141L2100225033L0204205022L1412338392L0738339162L0028236043L1501236022L2811221232L1408209192L0622205052L2634237192L0633228073L3613212323L2101234042L3438219373L0802216032L2710219363L0038209372L0405207242L1124225112L1217217092L1732236343L1239214193L3008237113L0401303312L1316333152L1004217032L2628231272L1125224242L1227230172L0137210372L0504206062L0611326102L1932234372L0226207063L1512331202L3227236302L0509205162L0233207282L2124229112L1231219382L0314305222L2339334172L3226335352L2934336142L3026231133L2633236332L3502239083L0032301033L2434333393L0507310043L3617336333L1601333003L0907307333L3330336353L2023323233L1305324123L3501339073L0737311303L2239329073L0239304353L3731332303L1106324053L2705332163L0238306243L2029318283L1010310273L1521326153L1207320123L2206322123L0736311293L1334318253L1738319273L0315303173L0419304213L2120324213L2222327233L2319324233L0632307343L3019331273L3418335243L3409337103L3505336133L3605336073 +X60Y60Z4L3639150041L4148440401L2447445584L1336216534L3530235114L5950244482L2922448111L0329310371L1009425043L1923157584L3623358004L1157414342L3634223362L0756215591L4141427494L3018338093L0451102401L4617436201L2415337113L2114425053L5326114374L5748452494L3337234341L2545134414L4027331243L2338328564L5945256401L4629259012L1423213231L1824440141L4850237392L0044309571L2726336231L3244436444L4714449101L4745437383L4540348391L1516328084L0445107391L0217304351L3401317084L2352324524L1225114234L5023355583L0314312441L3023305593L2204124041L4820248274L4218347002L4015432134L4101346002L0841304224L4637452364L5652153371L2723221171L1455410521L5255451584L3235131313L3613122121L2945424504L0248303351L1131415334L0855314544L0855412573L4445140323L2202319014L1306212032L1007305054L3604235041L3927335214L0157402564L5300354011L1726318351L1841138401L0803412004L1245410533L4559327501L1244321521L0641306411L5224340033L2704229083L2805429043L0853410554L5640352441L3513146121L1828313253L5631157321L2344422453L3202340011L5325157283L5907258194L4310352214L5753137582L1954220541L2815237081L5118157194L4750449534L4950243291L0645301344L0447408414L0720405224L2847322544L0914402081L5902155241L0531201342L4043336501L4828146254L2019317122L4705355142L5540155363L3314237124L3104329044L0253307581L5844451454L3943336392L2851131571L2111222131L0336301401L4922451222L3626221201L0048301391L1647115351L5914249044L4535353343L2508137102L1858416594L0821405214L4710140121L5314254202L2257119541L3445235491L1749219434L4946154451L0627316342L5948253451L3421417213L0344116393L1505416064L4836455313L0641403442L1509207021L5217448112L4330350284L0918113232L1640318423L2936427354L5329159411L1251126412L1246212421L2309325134L4719346283L4619453171L5556457524L3627437334L3537131321L1541417424L3205231022L3049435514L2823329223L1322309273L2221135251L3401238003L4255343562L2220315374L5615356164L3024137332L1230411284L1215410081L1002116011L0909109122L5655357541L1913420131L4225344252L2309226071L1444217481L4635452343L0634404331L5456252522L2403120111L5951259551L3401430012L1151220553L3947449524L3515134161L2717329142L4603247013L0738411344L4501441024L4012443104L4128437324L4144438444L3852236512L2531130302L5049154492L4203241022L2916129191L1958420554L4745159283L4939248434L4432447354L4845254442L2428115263L3437231363L2037322344L4753449531L4609345084L0830411313L4121238311L3231426274L5715256163L0313203043L1812316184L0326400184L5929453314L3110433114L0411401072L0051205422L4418343133L0151102531L0130306284L2359316522L4525344274L2650352403L4832444364L1011109101L4443247442L2504126021L3400138022L4244340444L3924438274L5722256243L2934331343L2422422204L5011355081L3325231242L2335118263L4152241584L3427326253L0351203532L5345454444L5257358543L0518100272L4022335161L4716241182L2205310022L0625405244L5232254322L3523332263L0522205211L2728335294L1741215361L5606458053L1047206464L2226122241L2128220292L4106438064L5021149201L5506158051L2433229303L2005215003L5836259314L0842407464L4632247332L0836107351L4208147081L3222435194L1351312521L2541434384L2629424264L2758426523L0424206221L0818202101L3730339274L1805419044L0412403142L1327113251L1746215501L3306333083L2442432473L5058148581L3229231262L4841249441L1035112374L4256143592L1929319314L5204250052L3722438264L4239240411L3658338532L1906323064L5441152412L3345439531L2724430244L5741456513L4917445183L2245228432L2027320281L1305114062L1025110231L1840118431L5312144163L2816122163L5416452154L2947430464L5853158511L5457253584L5500155003L0833109321L4320436212L5859152581L0822306222L4749337524L3719443224L1210211111L3251430554L0256205591L0726210292L2900136082L0847107412L2131219312L5609352082L0446404442L3020330174L2636126311L1747319464L1906223031L1647415481L1656416584L4603150031L0834310333L5247353453L1653315492L3335133331L2112222123L5658256571L2805328071L0127205252L3505438004L0506109074L4403447034L5527157203L1740318453L1242411434L0554403554L1923416204L5655455544L3815138201L2256124584L5749153363L1925420244L1555216582L4313141171L5749451524L2721326181L5647455413L0309402114L0231200194L2537326382L4432343283L3700336012L4324344234L0022203261L4350141482L3118231212L4823248271L3310136091L1520314191L3648338454L3317229171L2424425224L3908144021L1312411124L4421244184L0530206282L2920433194L3258333573L3925340252L2101320002L2845428474L1036109371L0255101581L2418323173L5740359472L2634325333L0653305523L3304232072L5139149371L5428357252L2402426023L1054111531L2351122521L1445411424L0011411211L1005208093L1438313361L0712408122L4729448323L2757230552L0546207452L2723326231L2307125051L4949248461L4215144102L3341331384L3459134571L0450103482L2416131141L5140452423L1551314504L1930125271L4158231584L1304209042L1720120221L1737217404L2417327191L2659129561L0925306253L1117412183L2308125062L5852259532L0247303463L5608356061L3653335553L3119231183L2832431314L3940441443L5655255501L4446145442L1515113171L1645314434L5727251282L5446252463L3903437034L3921142224L5407456094L4233141354L0453104571L2457125591L0322102191L1715217193L4218243172L5154352531L4139137371L2725228292L3005128061L5224148252L4527347263L0716106171L5117245191L1147208461L0809207082L3204431054L5519156181L3053329482L4035238352L2844128421L5013152091L0206301083L0012301154L0503406012L4143339432L5716454134L2534424364L5735456334L2100422024L1313213091L0437306314L3859437584L1315111131L2604225032L4127440244L0603306063L5509456113L2236419394L1729217272L5022347232L0650209472L2454420481L0203403003L5738453394L0302204012L2600321003L2142119421L1144311432L5039351403L1738116372L5136351352L3445138461L5610159132L1532319343L2301222004L3321234181L0119301211L1543115411L2306223053L1654419554L1305413074L5255254543L3558237572L3045231421L4134142351L3535433344L4452446543L2322220181L3340234411L3258234582L2853428514L2607425114L4833153321L0817306173L4845351423L0157300561L5320154191L2439424414L4610347113L1044313484L5522156211L2037416374L5458159591L3726334274L2816225151L0919308192L0903307024L2818427214L3006228031L2051419533L5931258292L4849349593L2733329314L0447207472L4308242071L1629318293L3537336394L5133450333L4631245283L1304307053L4618251161L0033301323L1031307322L5803254052L0511107131L0655106531L0420303281L2002317023L2652124521L1333416292L1232215322L2042221432L3355331553L5026252242L4228443293L5727454263L5703455043L3352236541L2121422253L2548125512L3140331433L4105241032L5500258012L2912427114L3327237313L4621445223L5925159242L3412235164L1038409344L3815440164L4846349482L1809217102L5017248193L2135324324L1913315171L5732355323L0637310373L2010319092L4932251303L1326214252L4040239392L5239154422L4749250481L4428148291L5511155092L4157143591L5535358372L4031139301L3631137232L4931350294L3342332434L4305143071L5747357413L2834327334L1835215333L1559215582L3141231394L3250431501L2654122541L2926328253L4146441473L4033340353L0724107224L3241234392L3403435044L2544326464L2955228533L1309411104L3602334022L1948423483L2342124401L2958428553L2858325593L3648438503L0151303533L2442322443L1907116081L1729316304L5556258563L2109224093L3902440023L3937336373L5908257093L4354141541L2700330003L1304414012L3150330523L4906144124L0045101461L1119212152L3512433134L3431232311L0154203552L1157115571L3841338404L5625254252L1857416573L4726145261L5529455264L2007221073L4817446172L1650416524L1310412133L3058233591L4814451124L2530220324L4641445404L4231343323L2835432354L1202411044L4914250112L4950147491L2434323322L4228140261L3957140581L0647206491L5803456044L4153341552L5539254371L5030148311L3315233174L1014309141L0549304504L5649256462L5256448564L1246311454L3606236072L1341313422L4203343034L0003100061L5442452424L1034209331L1105109061L1503113041L5329252302L1704218032L4807451074L1622416254L1631114311L4005338051L2437220351L0849114481L0144401424L4247140501L5348153511L3707337063L1349114501L0635209301L0125103241L3103431014L0635309353L1839219402L1626316252L3632140341L2017319173L5139351373L0407305101L3033229322L2600128013L0010100081L4358441574L0851108541L3458432584L3759135581L3546437464L0312200111L1134213341L2208422064L0955308584L0318301163L5906259023L2022319213L1911214141L1617415153L0252401544L0624106232L4137440383L0437101351L5645458454L4226342271L2356220572L1108211073L5452453534L2310118042L1736119381L5124456234L4507246062L1504215053L0920108201L0001300054L0615409154L0458403594L5531456313L5126452263L3041231413L2645325453L4756245551L2028319294L3143132441L4642247412L4343242432L5907358063L3228332271L4342344433L3351232492L2946232453L2340321383L5723156241L3614237133L1235211331L1858117571L0645206461L5743158471L4909445094L1447411474L0122202232L5536456384L4105444031L0215200142L4912349103L2332421324L3018431193L4044139492L0127401254L4847447464L4707447043L1546116462L1509314104L3522437204L0142101441L4016242142L0413103152L5704457053L3755236552L0049302494L1050210511L1116310183L2146122471L5916258152L1209311083L0216101171L0023200262L2845125461L5304451034L3017129192L3543335413L1704117021L1001112011L4451145522L5459358593L5032449324L2616427202L2509124101L4942150412L5421454223L3330335324L4401345013L2454323542L4523144241L0751105511L4447343483L5310350083L0130400294L1457314564L2418424213L2358221583L0911309104L3549233492L1852218512L0737403372L2757126561L1636318363L4110339111L3817338192L0331200301L0240201393L1059111581L0201102031L3506134082L2658228572L0430102301L3449434483L5256255551L5748258492L2126120272L3800137002L5811358112L3225130251L5707157051L5349253503L1016310174L2644424444L1058109591L2145222441L2228423294L2544124441L4856249572L2520425202L0321302202L2424222251L0339303422L2701228002L0927108262L3749137501L4320142231L0132100331L2447225482L1646415454L5449452484L0754207563L1326411264L3734338343L1337412394L0542305434L2015218152L5102250023L1907218062L4631347334L2814431123L4914448154L2327224252L0652307533L4416142161L0537305353L0127100291L2717427193L4233243331L4336241362L4337143381L1050410514L5909258093L0717109192L3917339183L4208340083L5558255572L1816117171L4552446534L3133131351L1103411024L4357342573L3314134151L5259153592L4643348424L4250444494L4639146362L2626225281L4547345464L5138151371L1811417114L0813408133L1457414583L2016319114L2723426244L4120241203L4740447414L1755315553L4304343022L5615257142L5143250422L1339214382L2246321474L3547134472L2842327433L3204131051L3624438254L0207104061L2631426304L1649318514L0305403064L3330133311L1207413064L1409312082L0202203012L1958122581L3758136582L1046112451L0848111491L1413315124L1040109391L4153442554L4230242282L4541445424L4453344523L3410435094L0044200422L1846118481L5801459004L4520146191L5022248222L1957420594L3402433014L1514117141L2214223142L4512449124L0053302534L1743215432L2110421084L3356431564L5739157351L4141342404L0456404574L4753144531L1522115211L0402304034L2257422564L2233122321L4826449253L1633417334L3544134441L0944409424L2915328153L5220251211L3108229082L0118202182L2222222202L3012130141L5906359043L1512215132L0431103311L1339315394L2152321533L5838458394L3510134101L4715247132L3708437094L4637147351L1655216541L1321313214L2508226092L0703107051L2655427564L3539135381L1255211542L3946339453L3644138442L5114250142L3921340222L1813318122L2414424134L3828237293L1244213442L5545454454L0111201102L2338426384L1014209152L2604327043L2840328394L3346433474L5036251362L5113151121L2748426484L0049100461L1220310203L0752208522L4107442074L0511406104L4900351004L3422233222L1910319102L4608144081L1848416484L1315413174L1330313293 +X40Y40Z4L0000139394L3900100394L0039139004L3939100004L3800100384L3700100374L3600100364L3500100354L3400100344L3300100334L3200100324L3100100314L3000100304L2900100294L2800100284L2700100274L2600100264L2500100254L2401100244L2301100234L2201100224L2101100214L2001100204L0601119011L3938101004L3937102004L3936103004L3935104014L3934105014L3933106014L3932107014L3931108014L3930109014L3929110014L3928111014L3927112014L3926113014L3925114014L3924115014L3923116014L3922117014L0121119391L0222118381L0323117371L0424116361L0525115351L0626114341L0727113331L0828112321L0929109311L3722121381L3623122371L3524123361L3425124351L3326125341L3227126331L3128127321L2829130291L1030111311L2930128311L1801422014L0220420384L0321419374L0422418364L0523417354L0624416344L0725415334L0826414324L0927413314L1028412284L1129412304L3823422394L3724423384L3625424374L3526425364L3427426354L3328427344L3229428334L3130431324L3031429324L0020219392L0121218382L0222217372L0323216362L0424215352L0525214342L0626213332L0727212322L0828211312L0929210302L3922222392L3823223382L3724224372L3625225362L3526226352L3427227342L3328228332L3229229322L3130230312L0000220283L0100220273L0200220263L0300220253L0401220243L0500220233L0600220223L0700220213L0800220203L0900220193L1000220183L3900211293L3800221283L3700221273L3600221263L3500221253L3400221243L3300221233L3200221223L3100221213L3000221203L0019221023L0119220033L0220220043L0321220053L0422220063L0523220073L0624220083L0725220093L0826220103L0927220113L2100223002L2500229002L3128221113L3227221103L3326221093L3425221083L3524221073L3623221063L3722221053L3821221043L3921221033L2019220382L1920219372L1821218362L1722217352L1623216342L1524215332L1425214322L1326213312L1227212302L1128211292L2121221382L2222222372L2323223362L2424224352L2525225342L2626226332L2727227322L2828228312L2929229302L1912319393L2012322393L0000339003L0001302013L0601339013L2702339023L0119338213L0220337223L0321336233L0422335243L0523334253L1918306243L1819307253L1720308263L1621309273L1522310273L1423311263L1324312253L2118333263L2119332273L2220331283L2321330283L2422329273L2523328263L2624327253L1230320383L1331319373L1432318363L1533317333L1634317353L2930321383L2831322373L2732323363L2433326333L2534324353L0121318383L0222317373L0323316363L0424315353L0525314343L0626313333L0727312323L0828311313L0929310303L3823323383L3724324373L3625325363L3526326353L3427327343L3328328333L3229329323L3130330313 +X15Y15Z3L1212303012L0506203113L0705209113L1102212113L1005110033L0414200012L0701302001L0107200083L0612305143L1102112001L0702109051L1105214022L0512110042L1309113071L0507206063L1212114121L0612213121L0303306033L1110112081L0312202142L1013214123L0710108071L0806302012L1108214062L0701203023L0900303021L1307313103L1114111121L0004100081L0011101101L0614104141L0914310133L0507106061L1101113011L0914108131L1010110071L0513303101L1204110011L0305304063L0809206082L1309214082L1301311002L0500107011L0901208002L1209311083L0506105031L0210202113L1106310053L0102301003L0802308043L0311203121L1111311123L0205301053L0313303143L0909309103L1013110141L1014311143 +X72Y72Z8L0000171023L0000271022L0000371021L0001171013L0001371011L0002171003L0002271002L0002371001 +X03Y03Z3L0000102002L0101101002L0200101012L0001101023L0001201013L0102102013 +X72Y72Z1L0100161061L2300164131L5500142501L0062106031L1771171341L2271166661L5967146631L2565161681L2665167661L2467159701L2369169691L5668157661L5569157671L0200159181L0116125331L4701170011L0209139261L6117103351L1628148341L0428103091L2400150061L1860119691L0114152461L2107156021L2158170361L0117112321L1213168041L0342114681L1643151591L5544161161L1115134161L1116134151L4342124521L0238146371L1449120631L0259113681L2243138471L0642146381L0404151031L5616159471L1216135161L1137126331L3911141261L0214159331L0269111321L6315168051L1741155561L0540109331L2322134211L4353129461L0713160351L1362118691L2244127471L0934108431L1120126191L1410140261L1957168571L5808146391L6653169311L0765166521L2719129191L3044125471L0425133311L1352110631L0405163111L0858110571L2645143541L5809165141L0515132261L2649141431L1252109611L0604141061L1955143411L1704153121L1448119541L2405145181L2447142511L1058113461L4605146211L1639122391L4613151111L4710146221L4414144181L0516105251L6822168331 +X72Y72Z1L0000108151L0004171321L0013171421L0016171431L0030100631L0046170601L7164100711L7165128711L1001170321L0500105031L0501107011L0502107021L0001100031L0002102021L0705107071L0506107061L0005106161L0105101111L0106105101L0117171541L0015170341L0014165331L0518165321L0017123261L0024133411L3330169531L2228100291L0025121281L0825108271L2312169321L2412168321L2512167321L0226108261L7065131701L7066135701L7067139701L4669169691L4968143701L2605166051L2705165051L2706165061L3706149061L2707150171L2708150161L2808151161L2809161131L6009162101L5309152141L5210152131L2810132101L5512153131L5610154111L5710157131L5810158131L0664144641L0764101691L4064102661L3664103681L1564103671L3264104671L2565122661L2864109661L0965120651L1664120641L1204162311L0031169571L3131124591L0045169581L1632100441L1521140211L6421164321L1905161231L1805137231L3020130221L3021136211L2247106591L1458170611L0062170621L1457121611L1749119501L1859120591L2149120601L1205117051L1605113171L1606114161L1417116191L1607115161L1507115151L2216145201L4420146201L4118143181L4117141191L3531168511L4034143341L4434134391L3933135391L3532138381L3632138371L3634136371L3734137371L3930155361L4035164521L4330155341L4831154311L5332154331L4036162521L4840160521L4941159511L5042158501L5143157491L5244156481L5345154461L5347155471L4137147391L4037145391L5738169491L6847169481L6039169461L5938167441L6239166431L6340164411L6540165421L0234104351L0342105441L0434125571L0433126571L1534107431L0836108431L0741109421L0943125431L1035125421L1036111381L1337114391L1040110421L1041113411L1831143561L1839142451L4145129551L1838140541L2932118371L2832118361L2833119361L1933127331L2033126331L2034126341L1456100611L1447100601L1354101591L1347100591L1247100521L1248101521L1148101511L0249102511L0250110501L4045132471L3845139471L4046139521L3645140511L3646134491L3547135491 +X16Y20Z5L0002100041L0004200044L0002300043L0002500045L0001100015L0005500091L0006200083L0007100084L0007200081L0010100105L0010400132L0011100112L0016100173L0015100182L0017500194L0016300184L0015300165L0102101041L0104201044L0102301043L0102501045L0101101015L0105501091L0106201083L0107101084L0107201081L0110101105L0110401132L0111101112L0116101173L0115101182L0117501194L0116301184L0115301165L0202102041L0204202044L0202302043L0202502045L0201102015L0205502091L0206202083L0207102084L0207202081L0210102105L0210402132L0211102112L0216102173L0215102182L0217502194L0216302184L0215302165L0302103041L0304203044L0302303043L0302503045L0301103015L0305503091L0306203083L0307103084L0307203081L0310103105L0310403132L0311103112L0316103173L0315103182L0317503194L0316303184L0315303165L0402104041L0404204044L0402304043L0402504045L0401104015L0405504091L0406204083L0407104084L0407204081L0410104105L0410404132L0411104112L0416104173L0415104182L0417504194L0416304184L0415304165L0502105041L0504205044L0502305043L0502505045L0501105015L0505505091L0506205083L0507105084L0507205081L0510105105L0510405132L0511105112L0516105173L0515105182L0517505194L0516305184L0515305165L0602106041L0604206044L0602306043L0602506045L0601106015L0605506091L0606206083L0607106084L0607206081L0610106105L0610406132L0611106112L0616106173L0615106182L0617506194L0616306184L0615306165L0702107041L0704207044L0702307043L0702507045L0701107015L0705507091L0706207083L0707107084L0707207081L0710107105L0710407132L0711107112L0716107173L0715107182L0717507194L0716307184L0715307165L0802108041L0804208044L0802308043L0802508045L0801108015L0805508091L0806208083L0807108084L0807208081L0810108105L0810408132L0811108112L0816108173L0815108182L0817508194L0816308184L0815308165L0902109041L0904209044L0902309043L0902509045L0901109015L0905509091L0906209083L0907109084L0907209081L0910109105L0910409132L0911109112L0916109173L0915109182L0917509194L0916309184L0915309165L1002110041L1004210044L1002310043L1002510045L1001110015L1005510091L1006210083L1007110084L1007210081L1010110105L1010410132L1011110112L1016110173L1015110182L1017510194L1016310184L1015310165L1102111041L1104211044L1102311043L1102511045L1101111015L1105511091L1106211083L1107111084L1107211081L1110111105L1110411132L1111111112L1116111173L1115111182L1117511194L1116311184L1115311165L1202112041L1204212044L1202312043L1202512045L1201112015L1205512091L1206212083L1207112084L1207212081L1210112105L1210412132L1211112112L1216112173L1215112182L1217512194L1216312184L1215312165L1302113041L1304213044L1302313043L1302513045L1301113015L1305513091L1306213083L1307113084L1307213081L1310113105L1310413132L1311113112L1316113173L1315113182L1317513194L1316313184L1315313165L1402114041L1404214044L1402314043L1402514045L1401114015L1405514091L1406214083L1407114084L1407214081L1410114105L1410414132L1411114112L1416114173L1415114182L1417514194L1416314184L1415314165L1502115041L1504215044L1502315043L1502515045L1501115015L1505515091L1506215083L1507115084L1507215081L1510115105L1510415132L1511115112L1516115173L1515115182L1517515194L1516315184L1515315165 +X40Y40Z3L3327238181L2637320341L2627222261L1100317123L0312103052L2902238051L2809330383L2404116163L2006318123L1836121351L0702304103L0429309233L3126238091L1039332023L2723233222L1122211391L0925315271L0532106281L1332110281L3004339001L1906108233L3928136321L1506317113L0632211373L1819221222L2309328002L1216308213L3826139241L1139217383L1504115132L3932336383L3813135173L2213218152L1824308323L2123239313L0420307201L0310102091L1631226213L1526315291L1030210213L0015203051L0039109351L1406115091L3721235172L0803108023L1519115161L3305334003L1101334173L2307123101L3120129242L2139322331L2237223293L3917339052L3002131011L0620307183L3827137171L3925139271L1435114291L2202109031L3435335283L1913119112L0023100211L3311224103L1037302383L3201330003L0223207263L2130217331L2739321361L3134232381L2319321223L1111307153L1724123211L2617324213L3929338193L2721127231L3725229273L2516219171L2526122231L3210230072L2315324183L0005101081L0908305093L0605209043L3207138063L0924105183L3207335033L1333108343L0031100331L0728112301L0230314293L0123106263L2327122313L3507234042L1438119381L0214207163L2935328312L2810237063L3314323103L2316221213L2520127212L0632113341L0811309112L2725326293L1621219192L0112309003L3834137321L2120115241L1223213293L0421206261L1026310283L3830233352L2101111001L0004101021L3018329153L3525231252L1302306073L1604112003L2406221043L0221203222L2515130171L0201202032L2217324121L0715106161L0331305272L3316132171L1425316253L0920114131L3108126033L3315233191L1807227002L3501136013L3020232223L2839218383L1635216363L0135101362L0330203332L2810127111L0235104363L0918314133L3413337133L3629137271L0738214361L3720236252L3735133333L1603214032L2818229173L3433137323L2403228042L3522236213L1501220011L3530337303L1605116013L2112119092L2201222051L1708215081L3739239362L1732315333L2506226053L3037329383L2200223013L1421113161L3130130291L0015301232L0722209232L2534125311L1826222253L1102210051L0810307093L1118208172L1632218322L1331311323L2235321333L1923217212L1420313223L3027334313L1218213183L3636334363L3128331272L2130118341L0305304042L3729239282L3220235213L3132133321L0239204391L3819138221L0634206303L1914319173L1111212122L1719320263L2809124092L3828334263L2424227282L2635122381L0534103351L0420103211L3102232021L0024200353L0603305023L1107210071L1926218291L2825329262L1224110241L0925209302L1927117271L3100333003L2121118241L0602106061L1902321012L1913223122L0113200161L3332333312L3904139021L3119232111L2601228013L0332302312L3314235143L0211200142L0234204321L2424123242L2932130352L2110222082L1635117391L2725124271L3402235012L3410237112L2508226092L2128122271L2720128161L2124320253L2833223323L1804119022L1420211161L2835229343L0814207152L1714315182L0915310183L1101216011L3613137142L3239332363L1109103091L0610104111L2537125391L3703238012L3834237361L1317113182L0613105111L0429104272L3019231191L2430223292L2115121171L2238320383L3032130312L2030221312L3735335363L1227114271L2414125161L2315223143L2624227252L0838303372L1921219223L2714226162L2723326223L3215331163L0937206381L0107204061L1006211073L1806218071L2735228372L2032319353L2738323363L3633236372L1506216061L2119320183L3005128061L1134210352L0733111341L1311108122L2538226372L0414302143L0125100241L1621115201L3235130341L3604135051L2115321173L2733228342L1011309141L2029320313L1733316353L0523305253L2626124263L3126133271L3319332203L0110102102L0405306053L1930220292L3622237232L3236130361L1716117141L2300122011L2000318003L1222113191L3102330033L0219203203L2605125041L1806317053L2529226302L2034221343L0736108351L1907220062L1823214232L1422315233L2115220162L2519224191L0011200092L3533337343L3108330082L1511216102L2625326273L1525215261L2012320133L0926110271L2515225143L2106325053L0608202072L2806328073L2510326103L2821328233L3707134071L0710307123L2911229091L3237234372L1219111181L3309135111L3411233113L2415226142L3909338103L3733136341L3406333063L1207213072L1213313133L1916119141L0614306153L2706227072L0919208192L1337313363L3408335093L1202212032L0022201221L3900338003L2815327143L1426313243L1320312203L0239103392L3703337043L3324331243L1034210341L0831309323L3423133232L1321113221L1022111221L1008310103L2113120131L1817218182L2322323233L1117209172L0101302013L3524336243L0902108021L2512225112L3134132341L0205202053L3413134141L3313332133L0613206122L0402105021L3616335163L0410205102L0326103271L3229131291L0232202332L2817327173L3818238172L3938239372L0137302373L3638137381L0001100021L1612117121L1821118221L0113101141L3809237092L1204113041L0731206312L3016130151L3535134351L3203232022L0212202132L2439325393L1232212323L1727317283L0824307243L1406314073L3339334393L3328334283L0315202152L2912328123L0727107261L1804219042L3531235302L1310213101L0705208052L3205232062L2432224332L1528215292L0234303343L0829108292L3803138041L2211222102L2302223012L1001210022L0126100261L0132100321L0604106031L3020330193L2928230282L3107331063L3039331393 +X40Y40Z2L0000139001L0100138001L0200137001L0300136001L0400135001L0500134001L0600133001L0700132001L0800131001L0900130001L1000129001L1100128001L1200127001L1300126001L1400125001L1500124001L1600123001L1700122001L1800121001L1900120001L0001100381L0002100371L0003100361L0004100351L0005100341L0006100331L0007100321L0008100311L0009100301L0010100291L0011100281L0012100271L0013100261L0014100251L0015100241L0016100231L0017100221L0018100211L0019100201L0039139391L0139138391L0239137391L0339136391L0439135391L0539134391L0639133391L0739132391L0839131391L0939130391L1039129391L1139128391L1239127391L1339126391L1439125391L1539124391L1639123391L1739122391L1839121391L1939120391L3901139381L3902139371L3903139361L3904139351L3905139341L3906139331L3907139321L3908139311L3909139301L3910139291L3911139281L3912139271L3913139261L3914139251L3915139241L3916139231L3917139221L3918139211L3919139201L1010129101L1110128101L1210127101L1310126101L1410125101L1510124101L1610123101L1710122101L1810121101L1910120101L1011110281L1012110271L1013110261L1014110251L1015110241L1016110231L1017110221L1018110211L1019110201L1029129291L1129128291L1229127291L1329126291L1429125291L1529124291L1629123291L1729122291L1829121291L1929120291L2911129281L2912129271L2913129261L2914129251L2915129241L2916129231L2917129221L2918129211L2919129201L1515124151L1615123151L1715122151L1815121151L1915120151L1516115231L1517115221L1518115211L1519115201L1524124241L1624123241L1724122241L1824121241L1924120241L2416124231L2417124221L2418124211L2419124201L1718122181L1818121181L1918120181L1719117201L1721122211L1821121211L1921120211L2219122201L0910209292L3010230292L1415214242L2515225242L1717222172L1719222192L1720222202L1722222222 +X40Y40Z3L0000139001L0001139011L0002139021L0003139031L0004139041L0005139051L0006139061L0007139071L0008139081L0009139091L0010139101L0011139111L0012139121L0013139131L0014139141L0015139151L0016139161L0017139171L0018139181L0019139191L0020139201L0021139211L0022139221L0023139231L0024139241L0025139251L0026139261L0027139271L0028139281L0029139291L0030139301L0031139311L0032139321L0033139331L0034139341L0035139351L0036139361L0037139371L0038139381L0039139391L0100101391L0500105391L0900109391L1300113391L1700117391L2100121391L2500125391L2900129391L3300133391L3700137391L0100201392L0300203392L0500205392L0700207392L0900209392L1100211392L1300213392L1500215392L1700217392L1900219392L2100221392L2300223392L2500225392L2700227392L2900229392L3100231392L3300233392L3500235392L3700237392L3900239392L0300303393L0700307393L1100311393L1500315393L1900319393L2300323393L2700327393L3100331393L3500335393L3900339393 diff --git a/hls_2018/router_01/Makefile b/hls_2018/router_01/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..8f79e7a62ede483ae7dcda810f306a02f915dfbb --- /dev/null +++ b/hls_2018/router_01/Makefile @@ -0,0 +1,20 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -o $@ $(OBJS) + +run: + python3 ../NLGenerator.py -x 20 -y 20 -z 6 -l 100;\ + python3 ./gen_boardstr.py Q-20x20x5_100_10.txt |\ + ./$(TARGET) - + + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_01/Makefile.cygwin b/hls_2018/router_01/Makefile.cygwin new file mode 100755 index 0000000000000000000000000000000000000000..866fdcdf2ea6a5fb67d1461ce4a19e353d0c9216 --- /dev/null +++ b/hls_2018/router_01/Makefile.cygwin @@ -0,0 +1,14 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -Wl,--stack,33554432 -o $@ $(OBJS) + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_01/ap_int.h b/hls_2018/router_01/ap_int.h new file mode 100755 index 0000000000000000000000000000000000000000..b8d9fdc96ac3f7eb9c86cc55d0eac0a57bf670b5 --- /dev/null +++ b/hls_2018/router_01/ap_int.h @@ -0,0 +1,521 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_AP_SIM_H__ +#define __AESL_AP_SIM_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#else + +#include "etc/ap_int_sim.h" +#include "etc/ap_fixed_sim.h" + +//Forward declaration +template class ap_fixed; +template class ap_ufixed; +template class ap_int; +template class ap_uint; + +//AP_INT +//-------------------------------------------------------- +template +class ap_int : public ap_private<_AP_W, true> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_private<_AP_W, true> Base; + + //Constructor + INLINE ap_int(): Base() {} + template + INLINE ap_int(const volatile ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_int(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_int(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_int(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE void operator = (const volatile ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE ap_int<_AP_W>& operator = (const volatile ap_int<_AP_W>& op2) { + Base::operator = (const_cast& >(op2)); + return *this; + } + + INLINE ap_int<_AP_W>& operator = (const ap_int<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, true>&)op2); + return *this; + } +}; + +//AP_UINT +//--------------------------------------------------------------- +template +class ap_uint: public ap_private<_AP_W, false> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_private<_AP_W, false> Base; + //Constructor + INLINE ap_uint(): Base() {} + INLINE ap_uint(const ap_uint<_AP_W>& op) :Base(dynamic_cast&>(op)) {} + INLINE ap_uint(const volatile ap_uint<_AP_W>& op):Base(dynamic_cast&>(op)){} + template + INLINE ap_uint(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_uint<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)){} + + template + INLINE ap_uint(const ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_uint(const volatile ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op) {} + + template + INLINE ap_uint(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_uint(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_uint(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_uint(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE void operator = (const volatile ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE ap_uint<_AP_W>& operator = (const volatile ap_uint<_AP_W>& op2) { + Base::operator = (op2); + return *this; + } + + INLINE ap_uint<_AP_W>& operator = (const ap_uint<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, false>&)(op2)); + return *this; + } +}; + +#define ap_bigint ap_int +#define ap_biguint ap_uint + +//AP_FIXED +//--------------------------------------------------------------------- +template +class ap_fixed: public ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> Base; + //Constructor + INLINE ap_fixed():Base() {} + + template + INLINE ap_fixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const ap_uint<_AP_W2>& op):Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_fixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const volatile ap_uint<_AP_W2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_fixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_fixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_fixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_fixed& operator = (const ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_fixed& operator = (const volatile ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } +}; + +//AP_ UFIXED +//--- ---------------------------------------------------------------- +template +class ap_ufixed : public ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> Base; + + //Constructor + INLINE ap_ufixed():Base() {} + + template + INLINE ap_ufixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_int<_AP_W2>& op): + Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_ufixed(const ap_uint<_AP_W2>& op): + Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_ufixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_uint<_AP_W2>& op): + Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_ufixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_ufixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_ufixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_ufixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_ufixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_ufixed& operator = (const ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_ufixed& operator = (const volatile ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::V = const_cast(op); + return *this; + } +}; + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_int<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_uint<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_fixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_ufixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif /* #if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) */ +#endif /* #ifndef __cplusplus */ +#endif /* #ifndef __AESL_AP_SIM_H__ */ \ No newline at end of file diff --git a/hls_2018/router_01/bitstream/router_design.bit b/hls_2018/router_01/bitstream/router_design.bit new file mode 100755 index 0000000000000000000000000000000000000000..5774d9ef5786cdc8d9ed35d0f2d614a6a545f391 Binary files /dev/null and b/hls_2018/router_01/bitstream/router_design.bit differ diff --git a/hls_2018/router_01/bitstream/router_design.tcl b/hls_2018/router_01/bitstream/router_design.tcl new file mode 100755 index 0000000000000000000000000000000000000000..e5347dff159dc309b6768469faa92beeede33e8e --- /dev/null +++ b/hls_2018/router_01/bitstream/router_design.tcl @@ -0,0 +1,1113 @@ + +################################################################ +# This is a generated script based on design: router_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source router_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name router_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_gpio:2.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:hls:pynqrouter:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set LD [ create_bd_port -dir O -from 3 -to 0 LD ] + + # Create instance: axi_gpio_0, and set properties + set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ] + set_property -dict [ list \ + CONFIG.C_GPIO_WIDTH {4} \ + ] $axi_gpio_0 + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {650.000000} \ + CONFIG.PCW_ACT_CAN0_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN1_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.096154} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_I2C_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_APU_CLK_RATIO_ENABLE {6:2:1} \ + CONFIG.PCW_APU_PERIPHERAL_FREQMHZ {650} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {26} \ + CONFIG.PCW_CAN0_BASEADDR {0xE0008000} \ + CONFIG.PCW_CAN0_CAN0_IO {} \ + CONFIG.PCW_CAN0_HIGHADDR {0xE0008FFF} \ + CONFIG.PCW_CAN0_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN0_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN1_BASEADDR {0xE0009000} \ + CONFIG.PCW_CAN1_CAN1_IO {} \ + CONFIG.PCW_CAN1_HIGHADDR {0xE0009FFF} \ + CONFIG.PCW_CAN1_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN1_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_CAN_PERIPHERAL_VALID {0} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CORE0_IRQ_INTR {0} \ + CONFIG.PCW_CORE1_FIQ_INTR {0} \ + CONFIG.PCW_CORE1_IRQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_6X4X_MAX_RANGE {667} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1300.000} \ + CONFIG.PCW_CPU_PERIPHERAL_CLKSRC {ARM PLL} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_DCI_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {52} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_FREQMHZ {10.159} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {21} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1050.000} \ + CONFIG.PCW_DDR_HPRLPR_QUEUE_PARTITION {HPR(0)/LPR(32)} \ + CONFIG.PCW_DDR_HPR_TO_CRITICAL_PRIORITY_LEVEL {15} \ + CONFIG.PCW_DDR_LPR_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DDR_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DDR_PORT0_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT1_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT2_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT3_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_2 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_2 {} \ + CONFIG.PCW_DDR_RAM_BASEADDR {0x00100000} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x1FFFFFFF} \ + CONFIG.PCW_DDR_WRITE_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DM_WIDTH {4} \ + CONFIG.PCW_DQS_WIDTH {4} \ + CONFIG.PCW_DQ_WIDTH {32} \ + CONFIG.PCW_ENET0_BASEADDR {0xE000B000} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {MIO 52 .. 53} \ + CONFIG.PCW_ENET0_HIGHADDR {0xE000BFFF} \ + CONFIG.PCW_ENET0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {1} \ + CONFIG.PCW_ENET0_RESET_IO {MIO 9} \ + CONFIG.PCW_ENET1_BASEADDR {0xE000C000} \ + CONFIG.PCW_ENET1_ENET1_IO {} \ + CONFIG.PCW_ENET1_HIGHADDR {0xE000CFFF} \ + CONFIG.PCW_ENET1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_RESET_IO {} \ + CONFIG.PCW_FTM_CTI_IN1 {} \ + CONFIG.PCW_FTM_CTI_IN3 {} \ + CONFIG.PCW_FTM_CTI_OUT1 {} \ + CONFIG.PCW_FTM_CTI_OUT3 {} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_HIGHADDR {0xE000AFFF} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_GPIO_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_BASEADDR {0xE0004000} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C0_GRP_INT_IO {} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_IO {} \ + CONFIG.PCW_I2C1_HIGHADDR {0xE0005FFF} \ + CONFIG.PCW_I2C1_I2C1_IO {} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {25} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_POLARITY {Active Low} \ + CONFIG.PCW_I2C_RESET_SELECT {} \ + CONFIG.PCW_NAND_NAND_IO {} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_IO {} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_SRAM_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_SRAM_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS1_WE_TIME {0} \ + CONFIG.PCW_OVERRIDE_BASIC_CLOCK {0} \ + CONFIG.PCW_P2F_CAN0_INTR {0} \ + CONFIG.PCW_P2F_CAN1_INTR {0} \ + CONFIG.PCW_P2F_CTI_INTR {0} \ + CONFIG.PCW_P2F_DMAC0_INTR {0} \ + CONFIG.PCW_P2F_DMAC1_INTR {0} \ + CONFIG.PCW_P2F_DMAC2_INTR {0} \ + CONFIG.PCW_P2F_DMAC3_INTR {0} \ + CONFIG.PCW_P2F_DMAC4_INTR {0} \ + CONFIG.PCW_P2F_DMAC5_INTR {0} \ + CONFIG.PCW_P2F_DMAC6_INTR {0} \ + CONFIG.PCW_P2F_DMAC7_INTR {0} \ + CONFIG.PCW_P2F_DMAC_ABORT_INTR {0} \ + CONFIG.PCW_P2F_ENET0_INTR {0} \ + CONFIG.PCW_P2F_ENET1_INTR {0} \ + CONFIG.PCW_P2F_GPIO_INTR {0} \ + CONFIG.PCW_P2F_I2C0_INTR {0} \ + CONFIG.PCW_P2F_I2C1_INTR {0} \ + CONFIG.PCW_P2F_QSPI_INTR {0} \ + CONFIG.PCW_P2F_SDIO0_INTR {0} \ + CONFIG.PCW_P2F_SDIO1_INTR {0} \ + CONFIG.PCW_P2F_SMC_INTR {0} \ + CONFIG.PCW_P2F_SPI0_INTR {0} \ + CONFIG.PCW_P2F_SPI1_INTR {0} \ + CONFIG.PCW_P2F_UART0_INTR {0} \ + CONFIG.PCW_P2F_UART1_INTR {0} \ + CONFIG.PCW_P2F_USB0_INTR {0} \ + CONFIG.PCW_P2F_USB1_INTR {0} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_PACKAGE_NAME {clg400} \ + CONFIG.PCW_PCAP_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PCAP_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_PERIPHERAL_BOARD_PRESET {None} \ + CONFIG.PCW_PJTAG_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PJTAG_PJTAG_IO {} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SS1_IO {} \ + CONFIG.PCW_SD0_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_WP_IO {} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_IO {} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SD1_SD1_IO {} \ + CONFIG.PCW_SPI0_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS1_IO {} \ + CONFIG.PCW_SPI0_HIGHADDR {0xE0006FFF} \ + CONFIG.PCW_SPI0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI0_SPI0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS1_IO {} \ + CONFIG.PCW_SPI1_HIGHADDR {0xE0007FFF} \ + CONFIG.PCW_SPI1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI1_SPI1_IO {} \ + CONFIG.PCW_TRACE_GRP_2BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_2BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_4BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_4BIT_IO {} \ + CONFIG.PCW_TRACE_INTERNAL_WIDTH {2} \ + CONFIG.PCW_TRACE_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TRACE_PIPELINE_WIDTH {8} \ + CONFIG.PCW_TRACE_TRACE_IO {} \ + CONFIG.PCW_TTC1_BASEADDR {0xE0105000} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_HIGHADDR {0xE0105fff} \ + CONFIG.PCW_TTC1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC1_TTC1_IO {} \ + CONFIG.PCW_UART0_HIGHADDR {0xE0000FFF} \ + CONFIG.PCW_UART0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} \ + CONFIG.PCW_UART1_BASEADDR {0xE0001000} \ + CONFIG.PCW_UART1_BAUD_RATE {115200} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_GRP_FULL_IO {} \ + CONFIG.PCW_UART_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {525.000000} \ + CONFIG.PCW_UIPARAM_DDR_ADV_ENABLE {0} \ + CONFIG.PCW_UIPARAM_DDR_AL {0} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BL {8} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {16 Bit} \ + CONFIG.PCW_UIPARAM_DDR_CL {7} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_STOP_EN {0} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {6} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_LENGTH_MM {15.6} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PACKAGE_LENGTH {105.056} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_LENGTH_MM {18.8} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PACKAGE_LENGTH {66.904} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PACKAGE_LENGTH {89.1715} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PACKAGE_LENGTH {113.63} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_LENGTH_MM {16.5} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PACKAGE_LENGTH {98.503} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_LENGTH_MM {18} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PACKAGE_LENGTH {68.5855} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PACKAGE_LENGTH {90.295} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PACKAGE_LENGTH {103.977} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} \ + CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} \ + CONFIG.PCW_UIPARAM_DDR_ENABLE {1} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {525} \ + CONFIG.PCW_UIPARAM_DDR_HIGH_TEMP {Normal (0-85)} \ + CONFIG.PCW_UIPARAM_DDR_MEMORY_TYPE {DDR 3} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41J256M16 RE-125} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {7} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {7} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} \ + CONFIG.PCW_UIPARAM_GENERATE_SUMMARY {NA} \ + CONFIG.PCW_USB0_BASEADDR {0xE0102000} \ + CONFIG.PCW_USB0_HIGHADDR {0xE0102fff} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {1} \ + CONFIG.PCW_USB0_RESET_IO {MIO 46} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_BASEADDR {0xE0103000} \ + CONFIG.PCW_USB1_HIGHADDR {0xE0103fff} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_RESET_IO {} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_POLARITY {Active Low} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_AXI_FABRIC_IDLE {0} \ + CONFIG.PCW_USE_AXI_NONSECURE {0} \ + CONFIG.PCW_USE_CORESIGHT {0} \ + CONFIG.PCW_USE_CROSS_TRIGGER {0} \ + CONFIG.PCW_USE_CR_FABRIC {1} \ + CONFIG.PCW_USE_DDR_BYPASS {0} \ + CONFIG.PCW_USE_DEBUG {0} \ + CONFIG.PCW_USE_DEFAULT_ACP_USER_VAL {0} \ + CONFIG.PCW_USE_DMA0 {0} \ + CONFIG.PCW_USE_DMA1 {0} \ + CONFIG.PCW_USE_DMA2 {0} \ + CONFIG.PCW_USE_DMA3 {0} \ + CONFIG.PCW_USE_EXPANDED_IOP {0} \ + CONFIG.PCW_USE_EXPANDED_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {0} \ + CONFIG.PCW_USE_HIGH_OCM {0} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {0} \ + CONFIG.PCW_USE_PROC_EVENT_BUS {0} \ + CONFIG.PCW_USE_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_S_AXI_ACP {0} \ + CONFIG.PCW_USE_S_AXI_GP0 {0} \ + CONFIG.PCW_USE_S_AXI_GP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP0 {0} \ + CONFIG.PCW_USE_S_AXI_HP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP2 {0} \ + CONFIG.PCW_USE_S_AXI_HP3 {0} \ + CONFIG.PCW_USE_TRACE {0} \ + CONFIG.PCW_USE_TRACE_DATA_EDGE_DETECTOR {0} \ + CONFIG.PCW_VALUE_SILVERSION {3} \ + CONFIG.PCW_WDT_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_WDT_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_WDT_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_WDT_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_WDT_WDT_IO {} \ + CONFIG.PCW_CAN0_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN0_GRP_CLK_IO {} \ + CONFIG.PCW_CAN1_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN1_GRP_CLK_IO {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_3 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_3 {} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_IO {} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_POLARITY {Active Low} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_4K_TIMER {0} \ + CONFIG.PCW_EN_CAN0 {0} \ + CONFIG.PCW_EN_CAN1 {0} \ + CONFIG.PCW_EN_CLK0_PORT {1} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {0} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG0_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG1_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG2_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG3_PORT {0} \ + CONFIG.PCW_EN_DDR {1} \ + CONFIG.PCW_EN_EMIO_CAN0 {0} \ + CONFIG.PCW_EN_EMIO_CAN1 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_ENET0 {0} \ + CONFIG.PCW_EN_EMIO_ENET1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {0} \ + CONFIG.PCW_EN_EMIO_I2C0 {0} \ + CONFIG.PCW_EN_EMIO_I2C1 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART0 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART1 {0} \ + CONFIG.PCW_EN_EMIO_PJTAG {0} \ + CONFIG.PCW_EN_EMIO_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_SPI0 {0} \ + CONFIG.PCW_EN_EMIO_SPI1 {0} \ + CONFIG.PCW_EN_EMIO_SRAM_INT {0} \ + CONFIG.PCW_EN_EMIO_TRACE {0} \ + CONFIG.PCW_EN_EMIO_TTC0 {0} \ + CONFIG.PCW_EN_EMIO_TTC1 {0} \ + CONFIG.PCW_EN_EMIO_UART0 {0} \ + CONFIG.PCW_EN_EMIO_UART1 {0} \ + CONFIG.PCW_EN_EMIO_WDT {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_ENET1 {0} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {0} \ + CONFIG.PCW_EN_I2C1 {0} \ + CONFIG.PCW_EN_MODEM_UART0 {0} \ + CONFIG.PCW_EN_MODEM_UART1 {0} \ + CONFIG.PCW_EN_PJTAG {0} \ + CONFIG.PCW_EN_PTP_ENET0 {0} \ + CONFIG.PCW_EN_PTP_ENET1 {0} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_RST0_PORT {1} \ + CONFIG.PCW_EN_RST1_PORT {0} \ + CONFIG.PCW_EN_RST2_PORT {0} \ + CONFIG.PCW_EN_RST3_PORT {0} \ + CONFIG.PCW_EN_SDIO0 {1} \ + CONFIG.PCW_EN_SDIO1 {0} \ + CONFIG.PCW_EN_SMC {0} \ + CONFIG.PCW_EN_SPI0 {0} \ + CONFIG.PCW_EN_SPI1 {0} \ + CONFIG.PCW_EN_TRACE {0} \ + CONFIG.PCW_EN_TTC0 {0} \ + CONFIG.PCW_EN_TTC1 {0} \ + CONFIG.PCW_EN_UART0 {1} \ + CONFIG.PCW_EN_UART1 {0} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {0} \ + CONFIG.PCW_EN_WDT {0} \ + CONFIG.PCW_FCLK0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK0_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_FTM_CTI_IN0 {} \ + CONFIG.PCW_FTM_CTI_IN2 {} \ + CONFIG.PCW_FTM_CTI_OUT0 {} \ + CONFIG.PCW_FTM_CTI_OUT2 {} \ + CONFIG.PCW_GPIO_BASEADDR {0xE000A000} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {} \ + CONFIG.PCW_I2C0_HIGHADDR {0xE0004FFF} \ + CONFIG.PCW_I2C0_I2C0_IO {} \ + CONFIG.PCW_I2C1_BASEADDR {0xE0005000} \ + CONFIG.PCW_I2C1_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C1_GRP_INT_IO {} \ + CONFIG.PCW_I2C1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_IO {} \ + CONFIG.PCW_IMPORT_BOARD_PRESET {None} \ + CONFIG.PCW_INCLUDE_ACP_TRANS_CHECK {0} \ + CONFIG.PCW_INCLUDE_TRACE_BUFFER {0} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {20} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {0} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {in} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {out} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {inout} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {inout} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {inout} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {out} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {in} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {inout} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {out} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {out} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_PRIMITIVE {54} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#Quad SPI Flash#ENET Reset#GPIO#GPIO#GPIO#GPIO#UART 0#UART 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#SD 0#SD 0#SD 0#SD 0#SD 0#SD 0#USB Reset#SD 0#GPIO#GPIO#GPIO#GPIO#Enet 0#Enet 0} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#qspi_fbclk#reset#gpio[10]#gpio[11]#gpio[12]#gpio[13]#rx#tx#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#clk#cmd#data[0]#data[1]#data[2]#data[3]#reset#cd#gpio[48]#gpio[49]#gpio[50]#gpio[51]#mdc#mdio} \ + CONFIG.PCW_M_AXI_GP0_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP0_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP0_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP0_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP1_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP1_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_NAND_CYCLES_T_AR {1} \ + CONFIG.PCW_NAND_CYCLES_T_CLR {1} \ + CONFIG.PCW_NAND_CYCLES_T_RC {11} \ + CONFIG.PCW_NAND_CYCLES_T_REA {1} \ + CONFIG.PCW_NAND_CYCLES_T_RR {1} \ + CONFIG.PCW_NAND_CYCLES_T_WC {11} \ + CONFIG.PCW_NAND_CYCLES_T_WP {1} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_GRP_D8_IO {} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_CS0_T_PC {1} \ + CONFIG.PCW_NOR_CS0_T_RC {11} \ + CONFIG.PCW_NOR_CS0_T_TR {1} \ + CONFIG.PCW_NOR_CS0_T_WC {11} \ + CONFIG.PCW_NOR_CS0_T_WP {1} \ + CONFIG.PCW_NOR_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_CS1_T_PC {1} \ + CONFIG.PCW_NOR_CS1_T_RC {11} \ + CONFIG.PCW_NOR_CS1_T_TR {1} \ + CONFIG.PCW_NOR_CS1_T_WC {11} \ + CONFIG.PCW_NOR_CS1_T_WP {1} \ + CONFIG.PCW_NOR_CS1_WE_TIME {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_IO {} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_IO {} \ + CONFIG.PCW_NOR_NOR_IO {} \ + CONFIG.PCW_PLL_BYPASSMODE_ENABLE {0} \ + CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_PS7_SI_REV {PRODUCTION} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_FBCLK_IO {MIO 8} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_IO {} \ + CONFIG.PCW_QSPI_INTERNAL_HIGHADDRESS {0xFCFFFFFF} \ + CONFIG.PCW_QSPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD0_GRP_CD_ENABLE {1} \ + CONFIG.PCW_SD0_GRP_CD_IO {MIO 47} \ + CONFIG.PCW_SD0_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_POW_IO {} \ + CONFIG.PCW_SD0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD0_SD0_IO {MIO 40 .. 45} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_CD_IO {} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_IO {} \ + CONFIG.PCW_SDIO0_BASEADDR {0xE0100000} \ + CONFIG.PCW_SDIO0_HIGHADDR {0xE0100FFF} \ + CONFIG.PCW_SDIO1_BASEADDR {0xE0101000} \ + CONFIG.PCW_SDIO1_HIGHADDR {0xE0101FFF} \ + CONFIG.PCW_SDIO_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_CYCLE_T0 {NA} \ + CONFIG.PCW_SMC_CYCLE_T1 {NA} \ + CONFIG.PCW_SMC_CYCLE_T2 {NA} \ + CONFIG.PCW_SMC_CYCLE_T3 {NA} \ + CONFIG.PCW_SMC_CYCLE_T4 {NA} \ + CONFIG.PCW_SMC_CYCLE_T5 {NA} \ + CONFIG.PCW_SMC_CYCLE_T6 {NA} \ + CONFIG.PCW_SMC_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SMC_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_SMC_PERIPHERAL_VALID {0} \ + CONFIG.PCW_SPI0_BASEADDR {0xE0006000} \ + CONFIG.PCW_SPI0_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS0_IO {} \ + CONFIG.PCW_SPI0_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS2_IO {} \ + CONFIG.PCW_SPI1_BASEADDR {0xE0007000} \ + CONFIG.PCW_SPI1_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS2_IO {} \ + CONFIG.PCW_SPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_FREQMHZ {166.666666} \ + CONFIG.PCW_SPI_PERIPHERAL_VALID {0} \ + CONFIG.PCW_S_AXI_ACP_ARUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_AWUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_ID_WIDTH {3} \ + CONFIG.PCW_S_AXI_GP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_GP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP0_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP1_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP2_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP2_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP3_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP3_ID_WIDTH {6} \ + CONFIG.PCW_TPIU_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_TRACE_BUFFER_CLOCK_DELAY {12} \ + CONFIG.PCW_TRACE_BUFFER_FIFO_SIZE {128} \ + CONFIG.PCW_TRACE_GRP_16BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_16BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_32BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_32BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_8BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_8BIT_IO {} \ + CONFIG.PCW_TTC0_BASEADDR {0xE0104000} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_HIGHADDR {0xE0104fff} \ + CONFIG.PCW_TTC0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC0_TTC0_IO {} \ + CONFIG.PCW_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_UART0_BASEADDR {0xE0000000} \ + CONFIG.PCW_UART0_BAUD_RATE {115200} \ + CONFIG.PCW_UART0_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART0_GRP_FULL_IO {} \ + CONFIG.PCW_UART1_HIGHADDR {0xE0001FFF} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_UART1_UART1_IO {} \ + CONFIG.PCW_USB1_USB1_IO {} \ + ] $processing_system7_0 + + # Create instance: ps7_0_axi_periph, and set properties + set ps7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps7_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {2} \ + ] $ps7_0_axi_periph + + # Create instance: pynqrouter_0, and set properties + set pynqrouter_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:pynqrouter:1.0 pynqrouter_0 ] + + # Create instance: rst_ps7_0_100M, and set properties + set rst_ps7_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps7_0_100M ] + + # Create interface connections + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_pins ps7_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M00_AXI [get_bd_intf_pins ps7_0_axi_periph/M00_AXI] [get_bd_intf_pins pynqrouter_0/s_axi_AXI4LS] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M01_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins ps7_0_axi_periph/M01_AXI] + + # Create port connections + connect_bd_net -net axi_gpio_0_gpio_io_o [get_bd_ports LD] [get_bd_pins axi_gpio_0/gpio_io_o] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins ps7_0_axi_periph/ACLK] [get_bd_pins ps7_0_axi_periph/M00_ACLK] [get_bd_pins ps7_0_axi_periph/M01_ACLK] [get_bd_pins ps7_0_axi_periph/S00_ACLK] [get_bd_pins pynqrouter_0/ap_clk] [get_bd_pins rst_ps7_0_100M/slowest_sync_clk] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins processing_system7_0/FCLK_RESET0_N] [get_bd_pins rst_ps7_0_100M/ext_reset_in] + connect_bd_net -net rst_ps7_0_100M_interconnect_aresetn [get_bd_pins ps7_0_axi_periph/ARESETN] [get_bd_pins rst_ps7_0_100M/interconnect_aresetn] + connect_bd_net -net rst_ps7_0_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins ps7_0_axi_periph/M00_ARESETN] [get_bd_pins ps7_0_axi_periph/M01_ARESETN] [get_bd_pins ps7_0_axi_periph/S00_ARESETN] [get_bd_pins pynqrouter_0/ap_rst_n] [get_bd_pins rst_ps7_0_100M/peripheral_aresetn] + + # Create address segments + create_bd_addr_seg -range 0x00010000 -offset 0x41200000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] SEG_axi_gpio_0_Reg + create_bd_addr_seg -range 0x00040000 -offset 0x43C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs pynqrouter_0/s_axi_AXI4LS/Reg] SEG_pynqrouter_0_Reg + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/hls_2018/router_02/bitstream/16/router_design.bit b/hls_2018/router_02/bitstream/16/router_design.bit new file mode 100755 index 0000000000000000000000000000000000000000..92b46cc1c13d5003a64f98cff6df6d32b1f2a070 Binary files /dev/null and b/hls_2018/router_02/bitstream/16/router_design.bit differ diff --git a/hls_2018/router_02/bitstream/16/router_design.tcl b/hls_2018/router_02/bitstream/16/router_design.tcl new file mode 100755 index 0000000000000000000000000000000000000000..e5347dff159dc309b6768469faa92beeede33e8e --- /dev/null +++ b/hls_2018/router_02/bitstream/16/router_design.tcl @@ -0,0 +1,1113 @@ + +################################################################ +# This is a generated script based on design: router_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source router_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name router_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_gpio:2.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:hls:pynqrouter:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set LD [ create_bd_port -dir O -from 3 -to 0 LD ] + + # Create instance: axi_gpio_0, and set properties + set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ] + set_property -dict [ list \ + CONFIG.C_GPIO_WIDTH {4} \ + ] $axi_gpio_0 + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {650.000000} \ + CONFIG.PCW_ACT_CAN0_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN1_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.096154} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_I2C_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_APU_CLK_RATIO_ENABLE {6:2:1} \ + CONFIG.PCW_APU_PERIPHERAL_FREQMHZ {650} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {26} \ + CONFIG.PCW_CAN0_BASEADDR {0xE0008000} \ + CONFIG.PCW_CAN0_CAN0_IO {} \ + CONFIG.PCW_CAN0_HIGHADDR {0xE0008FFF} \ + CONFIG.PCW_CAN0_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN0_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN1_BASEADDR {0xE0009000} \ + CONFIG.PCW_CAN1_CAN1_IO {} \ + CONFIG.PCW_CAN1_HIGHADDR {0xE0009FFF} \ + CONFIG.PCW_CAN1_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN1_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_CAN_PERIPHERAL_VALID {0} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CORE0_IRQ_INTR {0} \ + CONFIG.PCW_CORE1_FIQ_INTR {0} \ + CONFIG.PCW_CORE1_IRQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_6X4X_MAX_RANGE {667} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1300.000} \ + CONFIG.PCW_CPU_PERIPHERAL_CLKSRC {ARM PLL} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_DCI_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {52} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_FREQMHZ {10.159} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {21} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1050.000} \ + CONFIG.PCW_DDR_HPRLPR_QUEUE_PARTITION {HPR(0)/LPR(32)} \ + CONFIG.PCW_DDR_HPR_TO_CRITICAL_PRIORITY_LEVEL {15} \ + CONFIG.PCW_DDR_LPR_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DDR_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DDR_PORT0_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT1_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT2_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT3_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_2 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_2 {} \ + CONFIG.PCW_DDR_RAM_BASEADDR {0x00100000} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x1FFFFFFF} \ + CONFIG.PCW_DDR_WRITE_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DM_WIDTH {4} \ + CONFIG.PCW_DQS_WIDTH {4} \ + CONFIG.PCW_DQ_WIDTH {32} \ + CONFIG.PCW_ENET0_BASEADDR {0xE000B000} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {MIO 52 .. 53} \ + CONFIG.PCW_ENET0_HIGHADDR {0xE000BFFF} \ + CONFIG.PCW_ENET0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {1} \ + CONFIG.PCW_ENET0_RESET_IO {MIO 9} \ + CONFIG.PCW_ENET1_BASEADDR {0xE000C000} \ + CONFIG.PCW_ENET1_ENET1_IO {} \ + CONFIG.PCW_ENET1_HIGHADDR {0xE000CFFF} \ + CONFIG.PCW_ENET1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_RESET_IO {} \ + CONFIG.PCW_FTM_CTI_IN1 {} \ + CONFIG.PCW_FTM_CTI_IN3 {} \ + CONFIG.PCW_FTM_CTI_OUT1 {} \ + CONFIG.PCW_FTM_CTI_OUT3 {} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_HIGHADDR {0xE000AFFF} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_GPIO_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_BASEADDR {0xE0004000} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C0_GRP_INT_IO {} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_IO {} \ + CONFIG.PCW_I2C1_HIGHADDR {0xE0005FFF} \ + CONFIG.PCW_I2C1_I2C1_IO {} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {25} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_POLARITY {Active Low} \ + CONFIG.PCW_I2C_RESET_SELECT {} \ + CONFIG.PCW_NAND_NAND_IO {} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_IO {} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_SRAM_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_SRAM_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS1_WE_TIME {0} \ + CONFIG.PCW_OVERRIDE_BASIC_CLOCK {0} \ + CONFIG.PCW_P2F_CAN0_INTR {0} \ + CONFIG.PCW_P2F_CAN1_INTR {0} \ + CONFIG.PCW_P2F_CTI_INTR {0} \ + CONFIG.PCW_P2F_DMAC0_INTR {0} \ + CONFIG.PCW_P2F_DMAC1_INTR {0} \ + CONFIG.PCW_P2F_DMAC2_INTR {0} \ + CONFIG.PCW_P2F_DMAC3_INTR {0} \ + CONFIG.PCW_P2F_DMAC4_INTR {0} \ + CONFIG.PCW_P2F_DMAC5_INTR {0} \ + CONFIG.PCW_P2F_DMAC6_INTR {0} \ + CONFIG.PCW_P2F_DMAC7_INTR {0} \ + CONFIG.PCW_P2F_DMAC_ABORT_INTR {0} \ + CONFIG.PCW_P2F_ENET0_INTR {0} \ + CONFIG.PCW_P2F_ENET1_INTR {0} \ + CONFIG.PCW_P2F_GPIO_INTR {0} \ + CONFIG.PCW_P2F_I2C0_INTR {0} \ + CONFIG.PCW_P2F_I2C1_INTR {0} \ + CONFIG.PCW_P2F_QSPI_INTR {0} \ + CONFIG.PCW_P2F_SDIO0_INTR {0} \ + CONFIG.PCW_P2F_SDIO1_INTR {0} \ + CONFIG.PCW_P2F_SMC_INTR {0} \ + CONFIG.PCW_P2F_SPI0_INTR {0} \ + CONFIG.PCW_P2F_SPI1_INTR {0} \ + CONFIG.PCW_P2F_UART0_INTR {0} \ + CONFIG.PCW_P2F_UART1_INTR {0} \ + CONFIG.PCW_P2F_USB0_INTR {0} \ + CONFIG.PCW_P2F_USB1_INTR {0} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_PACKAGE_NAME {clg400} \ + CONFIG.PCW_PCAP_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PCAP_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_PERIPHERAL_BOARD_PRESET {None} \ + CONFIG.PCW_PJTAG_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PJTAG_PJTAG_IO {} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SS1_IO {} \ + CONFIG.PCW_SD0_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_WP_IO {} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_IO {} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SD1_SD1_IO {} \ + CONFIG.PCW_SPI0_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS1_IO {} \ + CONFIG.PCW_SPI0_HIGHADDR {0xE0006FFF} \ + CONFIG.PCW_SPI0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI0_SPI0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS1_IO {} \ + CONFIG.PCW_SPI1_HIGHADDR {0xE0007FFF} \ + CONFIG.PCW_SPI1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI1_SPI1_IO {} \ + CONFIG.PCW_TRACE_GRP_2BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_2BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_4BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_4BIT_IO {} \ + CONFIG.PCW_TRACE_INTERNAL_WIDTH {2} \ + CONFIG.PCW_TRACE_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TRACE_PIPELINE_WIDTH {8} \ + CONFIG.PCW_TRACE_TRACE_IO {} \ + CONFIG.PCW_TTC1_BASEADDR {0xE0105000} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_HIGHADDR {0xE0105fff} \ + CONFIG.PCW_TTC1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC1_TTC1_IO {} \ + CONFIG.PCW_UART0_HIGHADDR {0xE0000FFF} \ + CONFIG.PCW_UART0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} \ + CONFIG.PCW_UART1_BASEADDR {0xE0001000} \ + CONFIG.PCW_UART1_BAUD_RATE {115200} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_GRP_FULL_IO {} \ + CONFIG.PCW_UART_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {525.000000} \ + CONFIG.PCW_UIPARAM_DDR_ADV_ENABLE {0} \ + CONFIG.PCW_UIPARAM_DDR_AL {0} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BL {8} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {16 Bit} \ + CONFIG.PCW_UIPARAM_DDR_CL {7} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_STOP_EN {0} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {6} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_LENGTH_MM {15.6} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PACKAGE_LENGTH {105.056} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_LENGTH_MM {18.8} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PACKAGE_LENGTH {66.904} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PACKAGE_LENGTH {89.1715} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PACKAGE_LENGTH {113.63} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_LENGTH_MM {16.5} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PACKAGE_LENGTH {98.503} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_LENGTH_MM {18} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PACKAGE_LENGTH {68.5855} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PACKAGE_LENGTH {90.295} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PACKAGE_LENGTH {103.977} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} \ + CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} \ + CONFIG.PCW_UIPARAM_DDR_ENABLE {1} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {525} \ + CONFIG.PCW_UIPARAM_DDR_HIGH_TEMP {Normal (0-85)} \ + CONFIG.PCW_UIPARAM_DDR_MEMORY_TYPE {DDR 3} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41J256M16 RE-125} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {7} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {7} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} \ + CONFIG.PCW_UIPARAM_GENERATE_SUMMARY {NA} \ + CONFIG.PCW_USB0_BASEADDR {0xE0102000} \ + CONFIG.PCW_USB0_HIGHADDR {0xE0102fff} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {1} \ + CONFIG.PCW_USB0_RESET_IO {MIO 46} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_BASEADDR {0xE0103000} \ + CONFIG.PCW_USB1_HIGHADDR {0xE0103fff} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_RESET_IO {} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_POLARITY {Active Low} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_AXI_FABRIC_IDLE {0} \ + CONFIG.PCW_USE_AXI_NONSECURE {0} \ + CONFIG.PCW_USE_CORESIGHT {0} \ + CONFIG.PCW_USE_CROSS_TRIGGER {0} \ + CONFIG.PCW_USE_CR_FABRIC {1} \ + CONFIG.PCW_USE_DDR_BYPASS {0} \ + CONFIG.PCW_USE_DEBUG {0} \ + CONFIG.PCW_USE_DEFAULT_ACP_USER_VAL {0} \ + CONFIG.PCW_USE_DMA0 {0} \ + CONFIG.PCW_USE_DMA1 {0} \ + CONFIG.PCW_USE_DMA2 {0} \ + CONFIG.PCW_USE_DMA3 {0} \ + CONFIG.PCW_USE_EXPANDED_IOP {0} \ + CONFIG.PCW_USE_EXPANDED_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {0} \ + CONFIG.PCW_USE_HIGH_OCM {0} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {0} \ + CONFIG.PCW_USE_PROC_EVENT_BUS {0} \ + CONFIG.PCW_USE_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_S_AXI_ACP {0} \ + CONFIG.PCW_USE_S_AXI_GP0 {0} \ + CONFIG.PCW_USE_S_AXI_GP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP0 {0} \ + CONFIG.PCW_USE_S_AXI_HP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP2 {0} \ + CONFIG.PCW_USE_S_AXI_HP3 {0} \ + CONFIG.PCW_USE_TRACE {0} \ + CONFIG.PCW_USE_TRACE_DATA_EDGE_DETECTOR {0} \ + CONFIG.PCW_VALUE_SILVERSION {3} \ + CONFIG.PCW_WDT_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_WDT_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_WDT_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_WDT_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_WDT_WDT_IO {} \ + CONFIG.PCW_CAN0_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN0_GRP_CLK_IO {} \ + CONFIG.PCW_CAN1_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN1_GRP_CLK_IO {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_3 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_3 {} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_IO {} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_POLARITY {Active Low} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_4K_TIMER {0} \ + CONFIG.PCW_EN_CAN0 {0} \ + CONFIG.PCW_EN_CAN1 {0} \ + CONFIG.PCW_EN_CLK0_PORT {1} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {0} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG0_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG1_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG2_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG3_PORT {0} \ + CONFIG.PCW_EN_DDR {1} \ + CONFIG.PCW_EN_EMIO_CAN0 {0} \ + CONFIG.PCW_EN_EMIO_CAN1 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_ENET0 {0} \ + CONFIG.PCW_EN_EMIO_ENET1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {0} \ + CONFIG.PCW_EN_EMIO_I2C0 {0} \ + CONFIG.PCW_EN_EMIO_I2C1 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART0 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART1 {0} \ + CONFIG.PCW_EN_EMIO_PJTAG {0} \ + CONFIG.PCW_EN_EMIO_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_SPI0 {0} \ + CONFIG.PCW_EN_EMIO_SPI1 {0} \ + CONFIG.PCW_EN_EMIO_SRAM_INT {0} \ + CONFIG.PCW_EN_EMIO_TRACE {0} \ + CONFIG.PCW_EN_EMIO_TTC0 {0} \ + CONFIG.PCW_EN_EMIO_TTC1 {0} \ + CONFIG.PCW_EN_EMIO_UART0 {0} \ + CONFIG.PCW_EN_EMIO_UART1 {0} \ + CONFIG.PCW_EN_EMIO_WDT {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_ENET1 {0} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {0} \ + CONFIG.PCW_EN_I2C1 {0} \ + CONFIG.PCW_EN_MODEM_UART0 {0} \ + CONFIG.PCW_EN_MODEM_UART1 {0} \ + CONFIG.PCW_EN_PJTAG {0} \ + CONFIG.PCW_EN_PTP_ENET0 {0} \ + CONFIG.PCW_EN_PTP_ENET1 {0} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_RST0_PORT {1} \ + CONFIG.PCW_EN_RST1_PORT {0} \ + CONFIG.PCW_EN_RST2_PORT {0} \ + CONFIG.PCW_EN_RST3_PORT {0} \ + CONFIG.PCW_EN_SDIO0 {1} \ + CONFIG.PCW_EN_SDIO1 {0} \ + CONFIG.PCW_EN_SMC {0} \ + CONFIG.PCW_EN_SPI0 {0} \ + CONFIG.PCW_EN_SPI1 {0} \ + CONFIG.PCW_EN_TRACE {0} \ + CONFIG.PCW_EN_TTC0 {0} \ + CONFIG.PCW_EN_TTC1 {0} \ + CONFIG.PCW_EN_UART0 {1} \ + CONFIG.PCW_EN_UART1 {0} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {0} \ + CONFIG.PCW_EN_WDT {0} \ + CONFIG.PCW_FCLK0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK0_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_FTM_CTI_IN0 {} \ + CONFIG.PCW_FTM_CTI_IN2 {} \ + CONFIG.PCW_FTM_CTI_OUT0 {} \ + CONFIG.PCW_FTM_CTI_OUT2 {} \ + CONFIG.PCW_GPIO_BASEADDR {0xE000A000} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {} \ + CONFIG.PCW_I2C0_HIGHADDR {0xE0004FFF} \ + CONFIG.PCW_I2C0_I2C0_IO {} \ + CONFIG.PCW_I2C1_BASEADDR {0xE0005000} \ + CONFIG.PCW_I2C1_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C1_GRP_INT_IO {} \ + CONFIG.PCW_I2C1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_IO {} \ + CONFIG.PCW_IMPORT_BOARD_PRESET {None} \ + CONFIG.PCW_INCLUDE_ACP_TRANS_CHECK {0} \ + CONFIG.PCW_INCLUDE_TRACE_BUFFER {0} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {20} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {0} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {in} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {out} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {inout} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {inout} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {inout} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {out} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {in} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {inout} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {out} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {out} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_PRIMITIVE {54} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#Quad SPI Flash#ENET Reset#GPIO#GPIO#GPIO#GPIO#UART 0#UART 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#SD 0#SD 0#SD 0#SD 0#SD 0#SD 0#USB Reset#SD 0#GPIO#GPIO#GPIO#GPIO#Enet 0#Enet 0} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#qspi_fbclk#reset#gpio[10]#gpio[11]#gpio[12]#gpio[13]#rx#tx#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#clk#cmd#data[0]#data[1]#data[2]#data[3]#reset#cd#gpio[48]#gpio[49]#gpio[50]#gpio[51]#mdc#mdio} \ + CONFIG.PCW_M_AXI_GP0_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP0_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP0_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP0_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP1_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP1_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_NAND_CYCLES_T_AR {1} \ + CONFIG.PCW_NAND_CYCLES_T_CLR {1} \ + CONFIG.PCW_NAND_CYCLES_T_RC {11} \ + CONFIG.PCW_NAND_CYCLES_T_REA {1} \ + CONFIG.PCW_NAND_CYCLES_T_RR {1} \ + CONFIG.PCW_NAND_CYCLES_T_WC {11} \ + CONFIG.PCW_NAND_CYCLES_T_WP {1} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_GRP_D8_IO {} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_CS0_T_PC {1} \ + CONFIG.PCW_NOR_CS0_T_RC {11} \ + CONFIG.PCW_NOR_CS0_T_TR {1} \ + CONFIG.PCW_NOR_CS0_T_WC {11} \ + CONFIG.PCW_NOR_CS0_T_WP {1} \ + CONFIG.PCW_NOR_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_CS1_T_PC {1} \ + CONFIG.PCW_NOR_CS1_T_RC {11} \ + CONFIG.PCW_NOR_CS1_T_TR {1} \ + CONFIG.PCW_NOR_CS1_T_WC {11} \ + CONFIG.PCW_NOR_CS1_T_WP {1} \ + CONFIG.PCW_NOR_CS1_WE_TIME {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_IO {} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_IO {} \ + CONFIG.PCW_NOR_NOR_IO {} \ + CONFIG.PCW_PLL_BYPASSMODE_ENABLE {0} \ + CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_PS7_SI_REV {PRODUCTION} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_FBCLK_IO {MIO 8} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_IO {} \ + CONFIG.PCW_QSPI_INTERNAL_HIGHADDRESS {0xFCFFFFFF} \ + CONFIG.PCW_QSPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD0_GRP_CD_ENABLE {1} \ + CONFIG.PCW_SD0_GRP_CD_IO {MIO 47} \ + CONFIG.PCW_SD0_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_POW_IO {} \ + CONFIG.PCW_SD0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD0_SD0_IO {MIO 40 .. 45} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_CD_IO {} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_IO {} \ + CONFIG.PCW_SDIO0_BASEADDR {0xE0100000} \ + CONFIG.PCW_SDIO0_HIGHADDR {0xE0100FFF} \ + CONFIG.PCW_SDIO1_BASEADDR {0xE0101000} \ + CONFIG.PCW_SDIO1_HIGHADDR {0xE0101FFF} \ + CONFIG.PCW_SDIO_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_CYCLE_T0 {NA} \ + CONFIG.PCW_SMC_CYCLE_T1 {NA} \ + CONFIG.PCW_SMC_CYCLE_T2 {NA} \ + CONFIG.PCW_SMC_CYCLE_T3 {NA} \ + CONFIG.PCW_SMC_CYCLE_T4 {NA} \ + CONFIG.PCW_SMC_CYCLE_T5 {NA} \ + CONFIG.PCW_SMC_CYCLE_T6 {NA} \ + CONFIG.PCW_SMC_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SMC_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_SMC_PERIPHERAL_VALID {0} \ + CONFIG.PCW_SPI0_BASEADDR {0xE0006000} \ + CONFIG.PCW_SPI0_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS0_IO {} \ + CONFIG.PCW_SPI0_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS2_IO {} \ + CONFIG.PCW_SPI1_BASEADDR {0xE0007000} \ + CONFIG.PCW_SPI1_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS2_IO {} \ + CONFIG.PCW_SPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_FREQMHZ {166.666666} \ + CONFIG.PCW_SPI_PERIPHERAL_VALID {0} \ + CONFIG.PCW_S_AXI_ACP_ARUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_AWUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_ID_WIDTH {3} \ + CONFIG.PCW_S_AXI_GP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_GP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP0_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP1_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP2_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP2_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP3_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP3_ID_WIDTH {6} \ + CONFIG.PCW_TPIU_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_TRACE_BUFFER_CLOCK_DELAY {12} \ + CONFIG.PCW_TRACE_BUFFER_FIFO_SIZE {128} \ + CONFIG.PCW_TRACE_GRP_16BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_16BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_32BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_32BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_8BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_8BIT_IO {} \ + CONFIG.PCW_TTC0_BASEADDR {0xE0104000} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_HIGHADDR {0xE0104fff} \ + CONFIG.PCW_TTC0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC0_TTC0_IO {} \ + CONFIG.PCW_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_UART0_BASEADDR {0xE0000000} \ + CONFIG.PCW_UART0_BAUD_RATE {115200} \ + CONFIG.PCW_UART0_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART0_GRP_FULL_IO {} \ + CONFIG.PCW_UART1_HIGHADDR {0xE0001FFF} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_UART1_UART1_IO {} \ + CONFIG.PCW_USB1_USB1_IO {} \ + ] $processing_system7_0 + + # Create instance: ps7_0_axi_periph, and set properties + set ps7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps7_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {2} \ + ] $ps7_0_axi_periph + + # Create instance: pynqrouter_0, and set properties + set pynqrouter_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:pynqrouter:1.0 pynqrouter_0 ] + + # Create instance: rst_ps7_0_100M, and set properties + set rst_ps7_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps7_0_100M ] + + # Create interface connections + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_pins ps7_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M00_AXI [get_bd_intf_pins ps7_0_axi_periph/M00_AXI] [get_bd_intf_pins pynqrouter_0/s_axi_AXI4LS] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M01_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins ps7_0_axi_periph/M01_AXI] + + # Create port connections + connect_bd_net -net axi_gpio_0_gpio_io_o [get_bd_ports LD] [get_bd_pins axi_gpio_0/gpio_io_o] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins ps7_0_axi_periph/ACLK] [get_bd_pins ps7_0_axi_periph/M00_ACLK] [get_bd_pins ps7_0_axi_periph/M01_ACLK] [get_bd_pins ps7_0_axi_periph/S00_ACLK] [get_bd_pins pynqrouter_0/ap_clk] [get_bd_pins rst_ps7_0_100M/slowest_sync_clk] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins processing_system7_0/FCLK_RESET0_N] [get_bd_pins rst_ps7_0_100M/ext_reset_in] + connect_bd_net -net rst_ps7_0_100M_interconnect_aresetn [get_bd_pins ps7_0_axi_periph/ARESETN] [get_bd_pins rst_ps7_0_100M/interconnect_aresetn] + connect_bd_net -net rst_ps7_0_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins ps7_0_axi_periph/M00_ARESETN] [get_bd_pins ps7_0_axi_periph/M01_ARESETN] [get_bd_pins ps7_0_axi_periph/S00_ARESETN] [get_bd_pins pynqrouter_0/ap_rst_n] [get_bd_pins rst_ps7_0_100M/peripheral_aresetn] + + # Create address segments + create_bd_addr_seg -range 0x00010000 -offset 0x41200000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] SEG_axi_gpio_0_Reg + create_bd_addr_seg -range 0x00040000 -offset 0x43C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs pynqrouter_0/s_axi_AXI4LS/Reg] SEG_pynqrouter_0_Reg + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/hls_2018/router_02_boardstr/bitstream/16/router_design.bit b/hls_2018/router_02_boardstr/bitstream/16/router_design.bit new file mode 100755 index 0000000000000000000000000000000000000000..33bfd2d424f9fa29e50dfad094abea05d8d061fa Binary files /dev/null and b/hls_2018/router_02_boardstr/bitstream/16/router_design.bit differ diff --git a/hls_2018/router_02_boardstr/bitstream/16/router_design.tcl b/hls_2018/router_02_boardstr/bitstream/16/router_design.tcl new file mode 100755 index 0000000000000000000000000000000000000000..e5347dff159dc309b6768469faa92beeede33e8e --- /dev/null +++ b/hls_2018/router_02_boardstr/bitstream/16/router_design.tcl @@ -0,0 +1,1113 @@ + +################################################################ +# This is a generated script based on design: router_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source router_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name router_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_gpio:2.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:hls:pynqrouter:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set LD [ create_bd_port -dir O -from 3 -to 0 LD ] + + # Create instance: axi_gpio_0, and set properties + set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ] + set_property -dict [ list \ + CONFIG.C_GPIO_WIDTH {4} \ + ] $axi_gpio_0 + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {650.000000} \ + CONFIG.PCW_ACT_CAN0_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN1_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.096154} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_I2C_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_APU_CLK_RATIO_ENABLE {6:2:1} \ + CONFIG.PCW_APU_PERIPHERAL_FREQMHZ {650} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {26} \ + CONFIG.PCW_CAN0_BASEADDR {0xE0008000} \ + CONFIG.PCW_CAN0_CAN0_IO {} \ + CONFIG.PCW_CAN0_HIGHADDR {0xE0008FFF} \ + CONFIG.PCW_CAN0_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN0_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN1_BASEADDR {0xE0009000} \ + CONFIG.PCW_CAN1_CAN1_IO {} \ + CONFIG.PCW_CAN1_HIGHADDR {0xE0009FFF} \ + CONFIG.PCW_CAN1_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN1_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_CAN_PERIPHERAL_VALID {0} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CORE0_IRQ_INTR {0} \ + CONFIG.PCW_CORE1_FIQ_INTR {0} \ + CONFIG.PCW_CORE1_IRQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_6X4X_MAX_RANGE {667} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1300.000} \ + CONFIG.PCW_CPU_PERIPHERAL_CLKSRC {ARM PLL} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_DCI_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {52} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_FREQMHZ {10.159} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {21} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1050.000} \ + CONFIG.PCW_DDR_HPRLPR_QUEUE_PARTITION {HPR(0)/LPR(32)} \ + CONFIG.PCW_DDR_HPR_TO_CRITICAL_PRIORITY_LEVEL {15} \ + CONFIG.PCW_DDR_LPR_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DDR_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DDR_PORT0_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT1_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT2_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT3_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_2 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_2 {} \ + CONFIG.PCW_DDR_RAM_BASEADDR {0x00100000} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x1FFFFFFF} \ + CONFIG.PCW_DDR_WRITE_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DM_WIDTH {4} \ + CONFIG.PCW_DQS_WIDTH {4} \ + CONFIG.PCW_DQ_WIDTH {32} \ + CONFIG.PCW_ENET0_BASEADDR {0xE000B000} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {MIO 52 .. 53} \ + CONFIG.PCW_ENET0_HIGHADDR {0xE000BFFF} \ + CONFIG.PCW_ENET0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {1} \ + CONFIG.PCW_ENET0_RESET_IO {MIO 9} \ + CONFIG.PCW_ENET1_BASEADDR {0xE000C000} \ + CONFIG.PCW_ENET1_ENET1_IO {} \ + CONFIG.PCW_ENET1_HIGHADDR {0xE000CFFF} \ + CONFIG.PCW_ENET1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_RESET_IO {} \ + CONFIG.PCW_FTM_CTI_IN1 {} \ + CONFIG.PCW_FTM_CTI_IN3 {} \ + CONFIG.PCW_FTM_CTI_OUT1 {} \ + CONFIG.PCW_FTM_CTI_OUT3 {} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_HIGHADDR {0xE000AFFF} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_GPIO_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_BASEADDR {0xE0004000} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C0_GRP_INT_IO {} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_IO {} \ + CONFIG.PCW_I2C1_HIGHADDR {0xE0005FFF} \ + CONFIG.PCW_I2C1_I2C1_IO {} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {25} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_POLARITY {Active Low} \ + CONFIG.PCW_I2C_RESET_SELECT {} \ + CONFIG.PCW_NAND_NAND_IO {} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_IO {} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_SRAM_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_SRAM_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS1_WE_TIME {0} \ + CONFIG.PCW_OVERRIDE_BASIC_CLOCK {0} \ + CONFIG.PCW_P2F_CAN0_INTR {0} \ + CONFIG.PCW_P2F_CAN1_INTR {0} \ + CONFIG.PCW_P2F_CTI_INTR {0} \ + CONFIG.PCW_P2F_DMAC0_INTR {0} \ + CONFIG.PCW_P2F_DMAC1_INTR {0} \ + CONFIG.PCW_P2F_DMAC2_INTR {0} \ + CONFIG.PCW_P2F_DMAC3_INTR {0} \ + CONFIG.PCW_P2F_DMAC4_INTR {0} \ + CONFIG.PCW_P2F_DMAC5_INTR {0} \ + CONFIG.PCW_P2F_DMAC6_INTR {0} \ + CONFIG.PCW_P2F_DMAC7_INTR {0} \ + CONFIG.PCW_P2F_DMAC_ABORT_INTR {0} \ + CONFIG.PCW_P2F_ENET0_INTR {0} \ + CONFIG.PCW_P2F_ENET1_INTR {0} \ + CONFIG.PCW_P2F_GPIO_INTR {0} \ + CONFIG.PCW_P2F_I2C0_INTR {0} \ + CONFIG.PCW_P2F_I2C1_INTR {0} \ + CONFIG.PCW_P2F_QSPI_INTR {0} \ + CONFIG.PCW_P2F_SDIO0_INTR {0} \ + CONFIG.PCW_P2F_SDIO1_INTR {0} \ + CONFIG.PCW_P2F_SMC_INTR {0} \ + CONFIG.PCW_P2F_SPI0_INTR {0} \ + CONFIG.PCW_P2F_SPI1_INTR {0} \ + CONFIG.PCW_P2F_UART0_INTR {0} \ + CONFIG.PCW_P2F_UART1_INTR {0} \ + CONFIG.PCW_P2F_USB0_INTR {0} \ + CONFIG.PCW_P2F_USB1_INTR {0} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_PACKAGE_NAME {clg400} \ + CONFIG.PCW_PCAP_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PCAP_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_PERIPHERAL_BOARD_PRESET {None} \ + CONFIG.PCW_PJTAG_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PJTAG_PJTAG_IO {} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SS1_IO {} \ + CONFIG.PCW_SD0_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_WP_IO {} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_IO {} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SD1_SD1_IO {} \ + CONFIG.PCW_SPI0_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS1_IO {} \ + CONFIG.PCW_SPI0_HIGHADDR {0xE0006FFF} \ + CONFIG.PCW_SPI0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI0_SPI0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS1_IO {} \ + CONFIG.PCW_SPI1_HIGHADDR {0xE0007FFF} \ + CONFIG.PCW_SPI1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI1_SPI1_IO {} \ + CONFIG.PCW_TRACE_GRP_2BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_2BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_4BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_4BIT_IO {} \ + CONFIG.PCW_TRACE_INTERNAL_WIDTH {2} \ + CONFIG.PCW_TRACE_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TRACE_PIPELINE_WIDTH {8} \ + CONFIG.PCW_TRACE_TRACE_IO {} \ + CONFIG.PCW_TTC1_BASEADDR {0xE0105000} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_HIGHADDR {0xE0105fff} \ + CONFIG.PCW_TTC1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC1_TTC1_IO {} \ + CONFIG.PCW_UART0_HIGHADDR {0xE0000FFF} \ + CONFIG.PCW_UART0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} \ + CONFIG.PCW_UART1_BASEADDR {0xE0001000} \ + CONFIG.PCW_UART1_BAUD_RATE {115200} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_GRP_FULL_IO {} \ + CONFIG.PCW_UART_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {525.000000} \ + CONFIG.PCW_UIPARAM_DDR_ADV_ENABLE {0} \ + CONFIG.PCW_UIPARAM_DDR_AL {0} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BL {8} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {16 Bit} \ + CONFIG.PCW_UIPARAM_DDR_CL {7} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_STOP_EN {0} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {6} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_LENGTH_MM {15.6} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PACKAGE_LENGTH {105.056} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_LENGTH_MM {18.8} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PACKAGE_LENGTH {66.904} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PACKAGE_LENGTH {89.1715} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PACKAGE_LENGTH {113.63} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_LENGTH_MM {16.5} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PACKAGE_LENGTH {98.503} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_LENGTH_MM {18} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PACKAGE_LENGTH {68.5855} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PACKAGE_LENGTH {90.295} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PACKAGE_LENGTH {103.977} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} \ + CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} \ + CONFIG.PCW_UIPARAM_DDR_ENABLE {1} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {525} \ + CONFIG.PCW_UIPARAM_DDR_HIGH_TEMP {Normal (0-85)} \ + CONFIG.PCW_UIPARAM_DDR_MEMORY_TYPE {DDR 3} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41J256M16 RE-125} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {7} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {7} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} \ + CONFIG.PCW_UIPARAM_GENERATE_SUMMARY {NA} \ + CONFIG.PCW_USB0_BASEADDR {0xE0102000} \ + CONFIG.PCW_USB0_HIGHADDR {0xE0102fff} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {1} \ + CONFIG.PCW_USB0_RESET_IO {MIO 46} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_BASEADDR {0xE0103000} \ + CONFIG.PCW_USB1_HIGHADDR {0xE0103fff} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_RESET_IO {} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_POLARITY {Active Low} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_AXI_FABRIC_IDLE {0} \ + CONFIG.PCW_USE_AXI_NONSECURE {0} \ + CONFIG.PCW_USE_CORESIGHT {0} \ + CONFIG.PCW_USE_CROSS_TRIGGER {0} \ + CONFIG.PCW_USE_CR_FABRIC {1} \ + CONFIG.PCW_USE_DDR_BYPASS {0} \ + CONFIG.PCW_USE_DEBUG {0} \ + CONFIG.PCW_USE_DEFAULT_ACP_USER_VAL {0} \ + CONFIG.PCW_USE_DMA0 {0} \ + CONFIG.PCW_USE_DMA1 {0} \ + CONFIG.PCW_USE_DMA2 {0} \ + CONFIG.PCW_USE_DMA3 {0} \ + CONFIG.PCW_USE_EXPANDED_IOP {0} \ + CONFIG.PCW_USE_EXPANDED_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {0} \ + CONFIG.PCW_USE_HIGH_OCM {0} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {0} \ + CONFIG.PCW_USE_PROC_EVENT_BUS {0} \ + CONFIG.PCW_USE_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_S_AXI_ACP {0} \ + CONFIG.PCW_USE_S_AXI_GP0 {0} \ + CONFIG.PCW_USE_S_AXI_GP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP0 {0} \ + CONFIG.PCW_USE_S_AXI_HP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP2 {0} \ + CONFIG.PCW_USE_S_AXI_HP3 {0} \ + CONFIG.PCW_USE_TRACE {0} \ + CONFIG.PCW_USE_TRACE_DATA_EDGE_DETECTOR {0} \ + CONFIG.PCW_VALUE_SILVERSION {3} \ + CONFIG.PCW_WDT_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_WDT_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_WDT_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_WDT_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_WDT_WDT_IO {} \ + CONFIG.PCW_CAN0_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN0_GRP_CLK_IO {} \ + CONFIG.PCW_CAN1_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN1_GRP_CLK_IO {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_3 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_3 {} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_IO {} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_POLARITY {Active Low} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_4K_TIMER {0} \ + CONFIG.PCW_EN_CAN0 {0} \ + CONFIG.PCW_EN_CAN1 {0} \ + CONFIG.PCW_EN_CLK0_PORT {1} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {0} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG0_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG1_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG2_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG3_PORT {0} \ + CONFIG.PCW_EN_DDR {1} \ + CONFIG.PCW_EN_EMIO_CAN0 {0} \ + CONFIG.PCW_EN_EMIO_CAN1 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_ENET0 {0} \ + CONFIG.PCW_EN_EMIO_ENET1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {0} \ + CONFIG.PCW_EN_EMIO_I2C0 {0} \ + CONFIG.PCW_EN_EMIO_I2C1 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART0 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART1 {0} \ + CONFIG.PCW_EN_EMIO_PJTAG {0} \ + CONFIG.PCW_EN_EMIO_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_SPI0 {0} \ + CONFIG.PCW_EN_EMIO_SPI1 {0} \ + CONFIG.PCW_EN_EMIO_SRAM_INT {0} \ + CONFIG.PCW_EN_EMIO_TRACE {0} \ + CONFIG.PCW_EN_EMIO_TTC0 {0} \ + CONFIG.PCW_EN_EMIO_TTC1 {0} \ + CONFIG.PCW_EN_EMIO_UART0 {0} \ + CONFIG.PCW_EN_EMIO_UART1 {0} \ + CONFIG.PCW_EN_EMIO_WDT {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_ENET1 {0} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {0} \ + CONFIG.PCW_EN_I2C1 {0} \ + CONFIG.PCW_EN_MODEM_UART0 {0} \ + CONFIG.PCW_EN_MODEM_UART1 {0} \ + CONFIG.PCW_EN_PJTAG {0} \ + CONFIG.PCW_EN_PTP_ENET0 {0} \ + CONFIG.PCW_EN_PTP_ENET1 {0} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_RST0_PORT {1} \ + CONFIG.PCW_EN_RST1_PORT {0} \ + CONFIG.PCW_EN_RST2_PORT {0} \ + CONFIG.PCW_EN_RST3_PORT {0} \ + CONFIG.PCW_EN_SDIO0 {1} \ + CONFIG.PCW_EN_SDIO1 {0} \ + CONFIG.PCW_EN_SMC {0} \ + CONFIG.PCW_EN_SPI0 {0} \ + CONFIG.PCW_EN_SPI1 {0} \ + CONFIG.PCW_EN_TRACE {0} \ + CONFIG.PCW_EN_TTC0 {0} \ + CONFIG.PCW_EN_TTC1 {0} \ + CONFIG.PCW_EN_UART0 {1} \ + CONFIG.PCW_EN_UART1 {0} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {0} \ + CONFIG.PCW_EN_WDT {0} \ + CONFIG.PCW_FCLK0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK0_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_FTM_CTI_IN0 {} \ + CONFIG.PCW_FTM_CTI_IN2 {} \ + CONFIG.PCW_FTM_CTI_OUT0 {} \ + CONFIG.PCW_FTM_CTI_OUT2 {} \ + CONFIG.PCW_GPIO_BASEADDR {0xE000A000} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {} \ + CONFIG.PCW_I2C0_HIGHADDR {0xE0004FFF} \ + CONFIG.PCW_I2C0_I2C0_IO {} \ + CONFIG.PCW_I2C1_BASEADDR {0xE0005000} \ + CONFIG.PCW_I2C1_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C1_GRP_INT_IO {} \ + CONFIG.PCW_I2C1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_IO {} \ + CONFIG.PCW_IMPORT_BOARD_PRESET {None} \ + CONFIG.PCW_INCLUDE_ACP_TRANS_CHECK {0} \ + CONFIG.PCW_INCLUDE_TRACE_BUFFER {0} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {20} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {0} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {in} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {out} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {inout} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {inout} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {inout} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {out} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {in} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {inout} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {out} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {out} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_PRIMITIVE {54} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#Quad SPI Flash#ENET Reset#GPIO#GPIO#GPIO#GPIO#UART 0#UART 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#SD 0#SD 0#SD 0#SD 0#SD 0#SD 0#USB Reset#SD 0#GPIO#GPIO#GPIO#GPIO#Enet 0#Enet 0} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#qspi_fbclk#reset#gpio[10]#gpio[11]#gpio[12]#gpio[13]#rx#tx#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#clk#cmd#data[0]#data[1]#data[2]#data[3]#reset#cd#gpio[48]#gpio[49]#gpio[50]#gpio[51]#mdc#mdio} \ + CONFIG.PCW_M_AXI_GP0_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP0_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP0_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP0_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP1_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP1_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_NAND_CYCLES_T_AR {1} \ + CONFIG.PCW_NAND_CYCLES_T_CLR {1} \ + CONFIG.PCW_NAND_CYCLES_T_RC {11} \ + CONFIG.PCW_NAND_CYCLES_T_REA {1} \ + CONFIG.PCW_NAND_CYCLES_T_RR {1} \ + CONFIG.PCW_NAND_CYCLES_T_WC {11} \ + CONFIG.PCW_NAND_CYCLES_T_WP {1} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_GRP_D8_IO {} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_CS0_T_PC {1} \ + CONFIG.PCW_NOR_CS0_T_RC {11} \ + CONFIG.PCW_NOR_CS0_T_TR {1} \ + CONFIG.PCW_NOR_CS0_T_WC {11} \ + CONFIG.PCW_NOR_CS0_T_WP {1} \ + CONFIG.PCW_NOR_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_CS1_T_PC {1} \ + CONFIG.PCW_NOR_CS1_T_RC {11} \ + CONFIG.PCW_NOR_CS1_T_TR {1} \ + CONFIG.PCW_NOR_CS1_T_WC {11} \ + CONFIG.PCW_NOR_CS1_T_WP {1} \ + CONFIG.PCW_NOR_CS1_WE_TIME {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_IO {} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_IO {} \ + CONFIG.PCW_NOR_NOR_IO {} \ + CONFIG.PCW_PLL_BYPASSMODE_ENABLE {0} \ + CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_PS7_SI_REV {PRODUCTION} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_FBCLK_IO {MIO 8} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_IO {} \ + CONFIG.PCW_QSPI_INTERNAL_HIGHADDRESS {0xFCFFFFFF} \ + CONFIG.PCW_QSPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD0_GRP_CD_ENABLE {1} \ + CONFIG.PCW_SD0_GRP_CD_IO {MIO 47} \ + CONFIG.PCW_SD0_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_POW_IO {} \ + CONFIG.PCW_SD0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD0_SD0_IO {MIO 40 .. 45} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_CD_IO {} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_IO {} \ + CONFIG.PCW_SDIO0_BASEADDR {0xE0100000} \ + CONFIG.PCW_SDIO0_HIGHADDR {0xE0100FFF} \ + CONFIG.PCW_SDIO1_BASEADDR {0xE0101000} \ + CONFIG.PCW_SDIO1_HIGHADDR {0xE0101FFF} \ + CONFIG.PCW_SDIO_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_CYCLE_T0 {NA} \ + CONFIG.PCW_SMC_CYCLE_T1 {NA} \ + CONFIG.PCW_SMC_CYCLE_T2 {NA} \ + CONFIG.PCW_SMC_CYCLE_T3 {NA} \ + CONFIG.PCW_SMC_CYCLE_T4 {NA} \ + CONFIG.PCW_SMC_CYCLE_T5 {NA} \ + CONFIG.PCW_SMC_CYCLE_T6 {NA} \ + CONFIG.PCW_SMC_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SMC_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_SMC_PERIPHERAL_VALID {0} \ + CONFIG.PCW_SPI0_BASEADDR {0xE0006000} \ + CONFIG.PCW_SPI0_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS0_IO {} \ + CONFIG.PCW_SPI0_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS2_IO {} \ + CONFIG.PCW_SPI1_BASEADDR {0xE0007000} \ + CONFIG.PCW_SPI1_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS2_IO {} \ + CONFIG.PCW_SPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_FREQMHZ {166.666666} \ + CONFIG.PCW_SPI_PERIPHERAL_VALID {0} \ + CONFIG.PCW_S_AXI_ACP_ARUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_AWUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_ID_WIDTH {3} \ + CONFIG.PCW_S_AXI_GP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_GP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP0_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP1_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP2_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP2_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP3_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP3_ID_WIDTH {6} \ + CONFIG.PCW_TPIU_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_TRACE_BUFFER_CLOCK_DELAY {12} \ + CONFIG.PCW_TRACE_BUFFER_FIFO_SIZE {128} \ + CONFIG.PCW_TRACE_GRP_16BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_16BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_32BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_32BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_8BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_8BIT_IO {} \ + CONFIG.PCW_TTC0_BASEADDR {0xE0104000} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_HIGHADDR {0xE0104fff} \ + CONFIG.PCW_TTC0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC0_TTC0_IO {} \ + CONFIG.PCW_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_UART0_BASEADDR {0xE0000000} \ + CONFIG.PCW_UART0_BAUD_RATE {115200} \ + CONFIG.PCW_UART0_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART0_GRP_FULL_IO {} \ + CONFIG.PCW_UART1_HIGHADDR {0xE0001FFF} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_UART1_UART1_IO {} \ + CONFIG.PCW_USB1_USB1_IO {} \ + ] $processing_system7_0 + + # Create instance: ps7_0_axi_periph, and set properties + set ps7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps7_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {2} \ + ] $ps7_0_axi_periph + + # Create instance: pynqrouter_0, and set properties + set pynqrouter_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:pynqrouter:1.0 pynqrouter_0 ] + + # Create instance: rst_ps7_0_100M, and set properties + set rst_ps7_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps7_0_100M ] + + # Create interface connections + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_pins ps7_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M00_AXI [get_bd_intf_pins ps7_0_axi_periph/M00_AXI] [get_bd_intf_pins pynqrouter_0/s_axi_AXI4LS] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M01_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins ps7_0_axi_periph/M01_AXI] + + # Create port connections + connect_bd_net -net axi_gpio_0_gpio_io_o [get_bd_ports LD] [get_bd_pins axi_gpio_0/gpio_io_o] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins ps7_0_axi_periph/ACLK] [get_bd_pins ps7_0_axi_periph/M00_ACLK] [get_bd_pins ps7_0_axi_periph/M01_ACLK] [get_bd_pins ps7_0_axi_periph/S00_ACLK] [get_bd_pins pynqrouter_0/ap_clk] [get_bd_pins rst_ps7_0_100M/slowest_sync_clk] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins processing_system7_0/FCLK_RESET0_N] [get_bd_pins rst_ps7_0_100M/ext_reset_in] + connect_bd_net -net rst_ps7_0_100M_interconnect_aresetn [get_bd_pins ps7_0_axi_periph/ARESETN] [get_bd_pins rst_ps7_0_100M/interconnect_aresetn] + connect_bd_net -net rst_ps7_0_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins ps7_0_axi_periph/M00_ARESETN] [get_bd_pins ps7_0_axi_periph/M01_ARESETN] [get_bd_pins ps7_0_axi_periph/S00_ARESETN] [get_bd_pins pynqrouter_0/ap_rst_n] [get_bd_pins rst_ps7_0_100M/peripheral_aresetn] + + # Create address segments + create_bd_addr_seg -range 0x00010000 -offset 0x41200000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] SEG_axi_gpio_0_Reg + create_bd_addr_seg -range 0x00040000 -offset 0x43C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs pynqrouter_0/s_axi_AXI4LS/Reg] SEG_pynqrouter_0_Reg + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/hls_2018/router_03/bitstream/router_design_old.bit b/hls_2018/router_03/bitstream/router_design_old.bit new file mode 100755 index 0000000000000000000000000000000000000000..150747142a8534c603edf07766cea052f14d1fbe Binary files /dev/null and b/hls_2018/router_03/bitstream/router_design_old.bit differ diff --git a/hls_2018/router_03/bitstream/router_design_old.tcl b/hls_2018/router_03/bitstream/router_design_old.tcl new file mode 100755 index 0000000000000000000000000000000000000000..e5347dff159dc309b6768469faa92beeede33e8e --- /dev/null +++ b/hls_2018/router_03/bitstream/router_design_old.tcl @@ -0,0 +1,1113 @@ + +################################################################ +# This is a generated script based on design: router_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source router_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name router_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_gpio:2.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:hls:pynqrouter:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set LD [ create_bd_port -dir O -from 3 -to 0 LD ] + + # Create instance: axi_gpio_0, and set properties + set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ] + set_property -dict [ list \ + CONFIG.C_GPIO_WIDTH {4} \ + ] $axi_gpio_0 + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {650.000000} \ + CONFIG.PCW_ACT_CAN0_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN1_PERIPHERAL_FREQMHZ {23.8095} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.096154} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_I2C_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_ACT_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {108.333336} \ + CONFIG.PCW_APU_CLK_RATIO_ENABLE {6:2:1} \ + CONFIG.PCW_APU_PERIPHERAL_FREQMHZ {650} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {26} \ + CONFIG.PCW_CAN0_BASEADDR {0xE0008000} \ + CONFIG.PCW_CAN0_CAN0_IO {} \ + CONFIG.PCW_CAN0_HIGHADDR {0xE0008FFF} \ + CONFIG.PCW_CAN0_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN0_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN1_BASEADDR {0xE0009000} \ + CONFIG.PCW_CAN1_CAN1_IO {} \ + CONFIG.PCW_CAN1_HIGHADDR {0xE0009FFF} \ + CONFIG.PCW_CAN1_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_CAN1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_CAN1_PERIPHERAL_FREQMHZ {-1} \ + CONFIG.PCW_CAN_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_CAN_PERIPHERAL_VALID {0} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CORE0_IRQ_INTR {0} \ + CONFIG.PCW_CORE1_FIQ_INTR {0} \ + CONFIG.PCW_CORE1_IRQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_6X4X_MAX_RANGE {667} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1300.000} \ + CONFIG.PCW_CPU_PERIPHERAL_CLKSRC {ARM PLL} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_DCI_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {52} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_FREQMHZ {10.159} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {21} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1050.000} \ + CONFIG.PCW_DDR_HPRLPR_QUEUE_PARTITION {HPR(0)/LPR(32)} \ + CONFIG.PCW_DDR_HPR_TO_CRITICAL_PRIORITY_LEVEL {15} \ + CONFIG.PCW_DDR_LPR_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DDR_PERIPHERAL_CLKSRC {DDR PLL} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DDR_PORT0_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT1_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT2_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PORT3_HPR_ENABLE {0} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_2 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_0 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_2 {} \ + CONFIG.PCW_DDR_RAM_BASEADDR {0x00100000} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x1FFFFFFF} \ + CONFIG.PCW_DDR_WRITE_TO_CRITICAL_PRIORITY_LEVEL {2} \ + CONFIG.PCW_DM_WIDTH {4} \ + CONFIG.PCW_DQS_WIDTH {4} \ + CONFIG.PCW_DQ_WIDTH {32} \ + CONFIG.PCW_ENET0_BASEADDR {0xE000B000} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {MIO 52 .. 53} \ + CONFIG.PCW_ENET0_HIGHADDR {0xE000BFFF} \ + CONFIG.PCW_ENET0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {1} \ + CONFIG.PCW_ENET0_RESET_IO {MIO 9} \ + CONFIG.PCW_ENET1_BASEADDR {0xE000C000} \ + CONFIG.PCW_ENET1_ENET1_IO {} \ + CONFIG.PCW_ENET1_HIGHADDR {0xE000CFFF} \ + CONFIG.PCW_ENET1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_RESET_IO {} \ + CONFIG.PCW_FTM_CTI_IN1 {} \ + CONFIG.PCW_FTM_CTI_IN3 {} \ + CONFIG.PCW_FTM_CTI_OUT1 {} \ + CONFIG.PCW_FTM_CTI_OUT3 {} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_HIGHADDR {0xE000AFFF} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_GPIO_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_BASEADDR {0xE0004000} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C0_GRP_INT_IO {} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C0_RESET_IO {} \ + CONFIG.PCW_I2C1_HIGHADDR {0xE0005FFF} \ + CONFIG.PCW_I2C1_I2C1_IO {} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {25} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_POLARITY {Active Low} \ + CONFIG.PCW_I2C_RESET_SELECT {} \ + CONFIG.PCW_NAND_NAND_IO {} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_IO {} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_SRAM_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS0_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_SRAM_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_PC {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_RC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_TR {1} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WC {11} \ + CONFIG.PCW_NOR_SRAM_CS1_T_WP {1} \ + CONFIG.PCW_NOR_SRAM_CS1_WE_TIME {0} \ + CONFIG.PCW_OVERRIDE_BASIC_CLOCK {0} \ + CONFIG.PCW_P2F_CAN0_INTR {0} \ + CONFIG.PCW_P2F_CAN1_INTR {0} \ + CONFIG.PCW_P2F_CTI_INTR {0} \ + CONFIG.PCW_P2F_DMAC0_INTR {0} \ + CONFIG.PCW_P2F_DMAC1_INTR {0} \ + CONFIG.PCW_P2F_DMAC2_INTR {0} \ + CONFIG.PCW_P2F_DMAC3_INTR {0} \ + CONFIG.PCW_P2F_DMAC4_INTR {0} \ + CONFIG.PCW_P2F_DMAC5_INTR {0} \ + CONFIG.PCW_P2F_DMAC6_INTR {0} \ + CONFIG.PCW_P2F_DMAC7_INTR {0} \ + CONFIG.PCW_P2F_DMAC_ABORT_INTR {0} \ + CONFIG.PCW_P2F_ENET0_INTR {0} \ + CONFIG.PCW_P2F_ENET1_INTR {0} \ + CONFIG.PCW_P2F_GPIO_INTR {0} \ + CONFIG.PCW_P2F_I2C0_INTR {0} \ + CONFIG.PCW_P2F_I2C1_INTR {0} \ + CONFIG.PCW_P2F_QSPI_INTR {0} \ + CONFIG.PCW_P2F_SDIO0_INTR {0} \ + CONFIG.PCW_P2F_SDIO1_INTR {0} \ + CONFIG.PCW_P2F_SMC_INTR {0} \ + CONFIG.PCW_P2F_SPI0_INTR {0} \ + CONFIG.PCW_P2F_SPI1_INTR {0} \ + CONFIG.PCW_P2F_UART0_INTR {0} \ + CONFIG.PCW_P2F_UART1_INTR {0} \ + CONFIG.PCW_P2F_USB0_INTR {0} \ + CONFIG.PCW_P2F_USB1_INTR {0} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_PACKAGE_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_PACKAGE_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_PACKAGE_NAME {clg400} \ + CONFIG.PCW_PCAP_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PCAP_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_PERIPHERAL_BOARD_PRESET {None} \ + CONFIG.PCW_PJTAG_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PJTAG_PJTAG_IO {} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SS1_IO {} \ + CONFIG.PCW_SD0_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_WP_IO {} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_IO {} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SD1_SD1_IO {} \ + CONFIG.PCW_SPI0_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS1_IO {} \ + CONFIG.PCW_SPI0_HIGHADDR {0xE0006FFF} \ + CONFIG.PCW_SPI0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI0_SPI0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS1_IO {} \ + CONFIG.PCW_SPI1_HIGHADDR {0xE0007FFF} \ + CONFIG.PCW_SPI1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_SPI1_SPI1_IO {} \ + CONFIG.PCW_TRACE_GRP_2BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_2BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_4BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_4BIT_IO {} \ + CONFIG.PCW_TRACE_INTERNAL_WIDTH {2} \ + CONFIG.PCW_TRACE_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TRACE_PIPELINE_WIDTH {8} \ + CONFIG.PCW_TRACE_TRACE_IO {} \ + CONFIG.PCW_TTC1_BASEADDR {0xE0105000} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC1_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC1_HIGHADDR {0xE0105fff} \ + CONFIG.PCW_TTC1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC1_TTC1_IO {} \ + CONFIG.PCW_UART0_HIGHADDR {0xE0000FFF} \ + CONFIG.PCW_UART0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} \ + CONFIG.PCW_UART1_BASEADDR {0xE0001000} \ + CONFIG.PCW_UART1_BAUD_RATE {115200} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_GRP_FULL_IO {} \ + CONFIG.PCW_UART_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {525.000000} \ + CONFIG.PCW_UIPARAM_DDR_ADV_ENABLE {0} \ + CONFIG.PCW_UIPARAM_DDR_AL {0} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BL {8} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.223} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.212} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.085} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.092} \ + CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {16 Bit} \ + CONFIG.PCW_UIPARAM_DDR_CL {7} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_LENGTH_MM {25.8} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PACKAGE_LENGTH {80.4535} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_CLOCK_STOP_EN {0} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {6} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_LENGTH_MM {15.6} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PACKAGE_LENGTH {105.056} \ + CONFIG.PCW_UIPARAM_DDR_DQS_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_LENGTH_MM {18.8} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PACKAGE_LENGTH {66.904} \ + CONFIG.PCW_UIPARAM_DDR_DQS_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PACKAGE_LENGTH {89.1715} \ + CONFIG.PCW_UIPARAM_DDR_DQS_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PACKAGE_LENGTH {113.63} \ + CONFIG.PCW_UIPARAM_DDR_DQS_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.040} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.058} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {-0.009} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {-0.033} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_LENGTH_MM {16.5} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PACKAGE_LENGTH {98.503} \ + CONFIG.PCW_UIPARAM_DDR_DQ_0_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_LENGTH_MM {18} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PACKAGE_LENGTH {68.5855} \ + CONFIG.PCW_UIPARAM_DDR_DQ_1_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PACKAGE_LENGTH {90.295} \ + CONFIG.PCW_UIPARAM_DDR_DQ_2_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_LENGTH_MM {0} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PACKAGE_LENGTH {103.977} \ + CONFIG.PCW_UIPARAM_DDR_DQ_3_PROPOGATION_DELAY {160} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} \ + CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} \ + CONFIG.PCW_UIPARAM_DDR_ENABLE {1} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {525} \ + CONFIG.PCW_UIPARAM_DDR_HIGH_TEMP {Normal (0-85)} \ + CONFIG.PCW_UIPARAM_DDR_MEMORY_TYPE {DDR 3} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41J256M16 RE-125} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} \ + CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {7} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {7} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} \ + CONFIG.PCW_UIPARAM_GENERATE_SUMMARY {NA} \ + CONFIG.PCW_USB0_BASEADDR {0xE0102000} \ + CONFIG.PCW_USB0_HIGHADDR {0xE0102fff} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {1} \ + CONFIG.PCW_USB0_RESET_IO {MIO 46} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_BASEADDR {0xE0103000} \ + CONFIG.PCW_USB1_HIGHADDR {0xE0103fff} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_RESET_IO {} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_POLARITY {Active Low} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_AXI_FABRIC_IDLE {0} \ + CONFIG.PCW_USE_AXI_NONSECURE {0} \ + CONFIG.PCW_USE_CORESIGHT {0} \ + CONFIG.PCW_USE_CROSS_TRIGGER {0} \ + CONFIG.PCW_USE_CR_FABRIC {1} \ + CONFIG.PCW_USE_DDR_BYPASS {0} \ + CONFIG.PCW_USE_DEBUG {0} \ + CONFIG.PCW_USE_DEFAULT_ACP_USER_VAL {0} \ + CONFIG.PCW_USE_DMA0 {0} \ + CONFIG.PCW_USE_DMA1 {0} \ + CONFIG.PCW_USE_DMA2 {0} \ + CONFIG.PCW_USE_DMA3 {0} \ + CONFIG.PCW_USE_EXPANDED_IOP {0} \ + CONFIG.PCW_USE_EXPANDED_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {0} \ + CONFIG.PCW_USE_HIGH_OCM {0} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {0} \ + CONFIG.PCW_USE_PROC_EVENT_BUS {0} \ + CONFIG.PCW_USE_PS_SLCR_REGISTERS {0} \ + CONFIG.PCW_USE_S_AXI_ACP {0} \ + CONFIG.PCW_USE_S_AXI_GP0 {0} \ + CONFIG.PCW_USE_S_AXI_GP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP0 {0} \ + CONFIG.PCW_USE_S_AXI_HP1 {0} \ + CONFIG.PCW_USE_S_AXI_HP2 {0} \ + CONFIG.PCW_USE_S_AXI_HP3 {0} \ + CONFIG.PCW_USE_TRACE {0} \ + CONFIG.PCW_USE_TRACE_DATA_EDGE_DETECTOR {0} \ + CONFIG.PCW_VALUE_SILVERSION {3} \ + CONFIG.PCW_WDT_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_WDT_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_WDT_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_WDT_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_WDT_WDT_IO {} \ + CONFIG.PCW_CAN0_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN0_GRP_CLK_IO {} \ + CONFIG.PCW_CAN1_GRP_CLK_ENABLE {0} \ + CONFIG.PCW_CAN1_GRP_CLK_IO {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_READPORT_3 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_1 {} \ + CONFIG.PCW_DDR_PRIORITY_WRITEPORT_3 {} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_IO {} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_POLARITY {Active Low} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_4K_TIMER {0} \ + CONFIG.PCW_EN_CAN0 {0} \ + CONFIG.PCW_EN_CAN1 {0} \ + CONFIG.PCW_EN_CLK0_PORT {1} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {0} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG0_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG1_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG2_PORT {0} \ + CONFIG.PCW_EN_CLKTRIG3_PORT {0} \ + CONFIG.PCW_EN_DDR {1} \ + CONFIG.PCW_EN_EMIO_CAN0 {0} \ + CONFIG.PCW_EN_EMIO_CAN1 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_ENET0 {0} \ + CONFIG.PCW_EN_EMIO_ENET1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {0} \ + CONFIG.PCW_EN_EMIO_I2C0 {0} \ + CONFIG.PCW_EN_EMIO_I2C1 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART0 {0} \ + CONFIG.PCW_EN_EMIO_MODEM_UART1 {0} \ + CONFIG.PCW_EN_EMIO_PJTAG {0} \ + CONFIG.PCW_EN_EMIO_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_SPI0 {0} \ + CONFIG.PCW_EN_EMIO_SPI1 {0} \ + CONFIG.PCW_EN_EMIO_SRAM_INT {0} \ + CONFIG.PCW_EN_EMIO_TRACE {0} \ + CONFIG.PCW_EN_EMIO_TTC0 {0} \ + CONFIG.PCW_EN_EMIO_TTC1 {0} \ + CONFIG.PCW_EN_EMIO_UART0 {0} \ + CONFIG.PCW_EN_EMIO_UART1 {0} \ + CONFIG.PCW_EN_EMIO_WDT {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO0 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_ENET1 {0} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {0} \ + CONFIG.PCW_EN_I2C1 {0} \ + CONFIG.PCW_EN_MODEM_UART0 {0} \ + CONFIG.PCW_EN_MODEM_UART1 {0} \ + CONFIG.PCW_EN_PJTAG {0} \ + CONFIG.PCW_EN_PTP_ENET0 {0} \ + CONFIG.PCW_EN_PTP_ENET1 {0} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_RST0_PORT {1} \ + CONFIG.PCW_EN_RST1_PORT {0} \ + CONFIG.PCW_EN_RST2_PORT {0} \ + CONFIG.PCW_EN_RST3_PORT {0} \ + CONFIG.PCW_EN_SDIO0 {1} \ + CONFIG.PCW_EN_SDIO1 {0} \ + CONFIG.PCW_EN_SMC {0} \ + CONFIG.PCW_EN_SPI0 {0} \ + CONFIG.PCW_EN_SPI1 {0} \ + CONFIG.PCW_EN_TRACE {0} \ + CONFIG.PCW_EN_TTC0 {0} \ + CONFIG.PCW_EN_TTC1 {0} \ + CONFIG.PCW_EN_UART0 {1} \ + CONFIG.PCW_EN_UART1 {0} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {0} \ + CONFIG.PCW_EN_WDT {0} \ + CONFIG.PCW_FCLK0_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK0_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_FTM_CTI_IN0 {} \ + CONFIG.PCW_FTM_CTI_IN2 {} \ + CONFIG.PCW_FTM_CTI_OUT0 {} \ + CONFIG.PCW_FTM_CTI_OUT2 {} \ + CONFIG.PCW_GPIO_BASEADDR {0xE000A000} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {} \ + CONFIG.PCW_I2C0_HIGHADDR {0xE0004FFF} \ + CONFIG.PCW_I2C0_I2C0_IO {} \ + CONFIG.PCW_I2C1_BASEADDR {0xE0005000} \ + CONFIG.PCW_I2C1_GRP_INT_ENABLE {0} \ + CONFIG.PCW_I2C1_GRP_INT_IO {} \ + CONFIG.PCW_I2C1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_IO {} \ + CONFIG.PCW_IMPORT_BOARD_PRESET {None} \ + CONFIG.PCW_INCLUDE_ACP_TRANS_CHECK {0} \ + CONFIG.PCW_INCLUDE_TRACE_BUFFER {0} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {20} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {0} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {in} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {out} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {inout} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {inout} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {inout} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {out} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {in} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {inout} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {out} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {out} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_PRIMITIVE {54} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#Quad SPI Flash#ENET Reset#GPIO#GPIO#GPIO#GPIO#UART 0#UART 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#SD 0#SD 0#SD 0#SD 0#SD 0#SD 0#USB Reset#SD 0#GPIO#GPIO#GPIO#GPIO#Enet 0#Enet 0} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#qspi_fbclk#reset#gpio[10]#gpio[11]#gpio[12]#gpio[13]#rx#tx#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#clk#cmd#data[0]#data[1]#data[2]#data[3]#reset#cd#gpio[48]#gpio[49]#gpio[50]#gpio[51]#mdc#mdio} \ + CONFIG.PCW_M_AXI_GP0_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP0_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP0_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP0_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_ENABLE_STATIC_REMAP {0} \ + CONFIG.PCW_M_AXI_GP1_ID_WIDTH {12} \ + CONFIG.PCW_M_AXI_GP1_SUPPORT_NARROW_BURST {0} \ + CONFIG.PCW_M_AXI_GP1_THREAD_ID_WIDTH {12} \ + CONFIG.PCW_NAND_CYCLES_T_AR {1} \ + CONFIG.PCW_NAND_CYCLES_T_CLR {1} \ + CONFIG.PCW_NAND_CYCLES_T_RC {11} \ + CONFIG.PCW_NAND_CYCLES_T_REA {1} \ + CONFIG.PCW_NAND_CYCLES_T_RR {1} \ + CONFIG.PCW_NAND_CYCLES_T_WC {11} \ + CONFIG.PCW_NAND_CYCLES_T_WP {1} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_GRP_D8_IO {} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_CS0_T_CEOE {1} \ + CONFIG.PCW_NOR_CS0_T_PC {1} \ + CONFIG.PCW_NOR_CS0_T_RC {11} \ + CONFIG.PCW_NOR_CS0_T_TR {1} \ + CONFIG.PCW_NOR_CS0_T_WC {11} \ + CONFIG.PCW_NOR_CS0_T_WP {1} \ + CONFIG.PCW_NOR_CS0_WE_TIME {0} \ + CONFIG.PCW_NOR_CS1_T_CEOE {1} \ + CONFIG.PCW_NOR_CS1_T_PC {1} \ + CONFIG.PCW_NOR_CS1_T_RC {11} \ + CONFIG.PCW_NOR_CS1_T_TR {1} \ + CONFIG.PCW_NOR_CS1_T_WC {11} \ + CONFIG.PCW_NOR_CS1_T_WP {1} \ + CONFIG.PCW_NOR_CS1_WE_TIME {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_IO {} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_IO {} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_IO {} \ + CONFIG.PCW_NOR_NOR_IO {} \ + CONFIG.PCW_PLL_BYPASSMODE_ENABLE {0} \ + CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_PS7_SI_REV {PRODUCTION} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_FBCLK_IO {MIO 8} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_IO {} \ + CONFIG.PCW_QSPI_INTERNAL_HIGHADDRESS {0xFCFFFFFF} \ + CONFIG.PCW_QSPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD0_GRP_CD_ENABLE {1} \ + CONFIG.PCW_SD0_GRP_CD_IO {MIO 47} \ + CONFIG.PCW_SD0_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD0_GRP_POW_IO {} \ + CONFIG.PCW_SD0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD0_SD0_IO {MIO 40 .. 45} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_CD_IO {} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_IO {} \ + CONFIG.PCW_SDIO0_BASEADDR {0xE0100000} \ + CONFIG.PCW_SDIO0_HIGHADDR {0xE0100FFF} \ + CONFIG.PCW_SDIO1_BASEADDR {0xE0101000} \ + CONFIG.PCW_SDIO1_HIGHADDR {0xE0101FFF} \ + CONFIG.PCW_SDIO_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_CYCLE_T0 {NA} \ + CONFIG.PCW_SMC_CYCLE_T1 {NA} \ + CONFIG.PCW_SMC_CYCLE_T2 {NA} \ + CONFIG.PCW_SMC_CYCLE_T3 {NA} \ + CONFIG.PCW_SMC_CYCLE_T4 {NA} \ + CONFIG.PCW_SMC_CYCLE_T5 {NA} \ + CONFIG.PCW_SMC_CYCLE_T6 {NA} \ + CONFIG.PCW_SMC_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SMC_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_SMC_PERIPHERAL_VALID {0} \ + CONFIG.PCW_SPI0_BASEADDR {0xE0006000} \ + CONFIG.PCW_SPI0_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS0_IO {} \ + CONFIG.PCW_SPI0_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI0_GRP_SS2_IO {} \ + CONFIG.PCW_SPI1_BASEADDR {0xE0007000} \ + CONFIG.PCW_SPI1_GRP_SS0_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS0_IO {} \ + CONFIG.PCW_SPI1_GRP_SS2_ENABLE {0} \ + CONFIG.PCW_SPI1_GRP_SS2_IO {} \ + CONFIG.PCW_SPI_PERIPHERAL_CLKSRC {IO PLL} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_FREQMHZ {166.666666} \ + CONFIG.PCW_SPI_PERIPHERAL_VALID {0} \ + CONFIG.PCW_S_AXI_ACP_ARUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_AWUSER_VAL {31} \ + CONFIG.PCW_S_AXI_ACP_ID_WIDTH {3} \ + CONFIG.PCW_S_AXI_GP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_GP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP0_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP0_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP1_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP1_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP2_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP2_ID_WIDTH {6} \ + CONFIG.PCW_S_AXI_HP3_DATA_WIDTH {64} \ + CONFIG.PCW_S_AXI_HP3_ID_WIDTH {6} \ + CONFIG.PCW_TPIU_PERIPHERAL_CLKSRC {External} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_TRACE_BUFFER_CLOCK_DELAY {12} \ + CONFIG.PCW_TRACE_BUFFER_FIFO_SIZE {128} \ + CONFIG.PCW_TRACE_GRP_16BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_16BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_32BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_32BIT_IO {} \ + CONFIG.PCW_TRACE_GRP_8BIT_ENABLE {0} \ + CONFIG.PCW_TRACE_GRP_8BIT_IO {} \ + CONFIG.PCW_TTC0_BASEADDR {0xE0104000} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK0_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK1_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_CLKSRC {CPU_1X} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TTC0_CLK2_PERIPHERAL_FREQMHZ {133.333333} \ + CONFIG.PCW_TTC0_HIGHADDR {0xE0104fff} \ + CONFIG.PCW_TTC0_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_TTC0_TTC0_IO {} \ + CONFIG.PCW_TTC_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_UART0_BASEADDR {0xE0000000} \ + CONFIG.PCW_UART0_BAUD_RATE {115200} \ + CONFIG.PCW_UART0_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART0_GRP_FULL_IO {} \ + CONFIG.PCW_UART1_HIGHADDR {0xE0001FFF} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_UART1_UART1_IO {} \ + CONFIG.PCW_USB1_USB1_IO {} \ + ] $processing_system7_0 + + # Create instance: ps7_0_axi_periph, and set properties + set ps7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps7_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {2} \ + ] $ps7_0_axi_periph + + # Create instance: pynqrouter_0, and set properties + set pynqrouter_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:pynqrouter:1.0 pynqrouter_0 ] + + # Create instance: rst_ps7_0_100M, and set properties + set rst_ps7_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps7_0_100M ] + + # Create interface connections + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_pins ps7_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M00_AXI [get_bd_intf_pins ps7_0_axi_periph/M00_AXI] [get_bd_intf_pins pynqrouter_0/s_axi_AXI4LS] + connect_bd_intf_net -intf_net ps7_0_axi_periph_M01_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins ps7_0_axi_periph/M01_AXI] + + # Create port connections + connect_bd_net -net axi_gpio_0_gpio_io_o [get_bd_ports LD] [get_bd_pins axi_gpio_0/gpio_io_o] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins ps7_0_axi_periph/ACLK] [get_bd_pins ps7_0_axi_periph/M00_ACLK] [get_bd_pins ps7_0_axi_periph/M01_ACLK] [get_bd_pins ps7_0_axi_periph/S00_ACLK] [get_bd_pins pynqrouter_0/ap_clk] [get_bd_pins rst_ps7_0_100M/slowest_sync_clk] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins processing_system7_0/FCLK_RESET0_N] [get_bd_pins rst_ps7_0_100M/ext_reset_in] + connect_bd_net -net rst_ps7_0_100M_interconnect_aresetn [get_bd_pins ps7_0_axi_periph/ARESETN] [get_bd_pins rst_ps7_0_100M/interconnect_aresetn] + connect_bd_net -net rst_ps7_0_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins ps7_0_axi_periph/M00_ARESETN] [get_bd_pins ps7_0_axi_periph/M01_ARESETN] [get_bd_pins ps7_0_axi_periph/S00_ARESETN] [get_bd_pins pynqrouter_0/ap_rst_n] [get_bd_pins rst_ps7_0_100M/peripheral_aresetn] + + # Create address segments + create_bd_addr_seg -range 0x00010000 -offset 0x41200000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] SEG_axi_gpio_0_Reg + create_bd_addr_seg -range 0x00040000 -offset 0x43C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs pynqrouter_0/s_axi_AXI4LS/Reg] SEG_pynqrouter_0_Reg + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/hls_2018/router_03_boardstr/etc/ap_fixed_sim.h b/hls_2018/router_03_boardstr/etc/ap_fixed_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..5be571dd70e490d282d279a4eeed32db069703e9 --- /dev/null +++ b/hls_2018/router_03_boardstr/etc/ap_fixed_sim.h @@ -0,0 +1,2451 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_FIXED_H__ +#define __AESL_GCC_AP_FIXED_H__ + +#ifndef __cplusplus + #error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + + +#include +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_int_sim.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#define FLOAT_MAN 23 +#define FLOAT_EXP 8 +#define DOUBLE_MAN 52 +#define DOUBLE_EXP 11 +// #define DOUBLE_MAN_MASK (~0ULL >> (64-DOUBLE_MAN-2)) +#define DOUBLE_MAN_MASK 0x3fffffffffffffULL +#define BIAS(e) ((1ULL<<(e-1))-1) +#define FLOAT_BIAS BIAS(FLOAT_EXP) +#define DOUBLE_BIAS BIAS(DOUBLE_EXP) + +/// Forward declaration. +template struct ap_fixed_base; + +///Proxy class, which allows bit selection to be used as both rvalue(for reading) and +//lvalue(for writing) +template +struct af_bit_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& d_bv; + int d_index; +public: + INLINE af_bit_ref(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE af_bit_ref(ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>* bv, int index=0): + d_bv(*bv),d_index(index) {} + + INLINE operator bool() const { + return d_bv.V[d_index]; + } + + INLINE af_bit_ref& operator=(unsigned long long val) { + if (val) + d_bv.V.set(d_index); + else + d_bv.V.clear(d_index); + return *this; + } + + template + INLINE af_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + return operator=(val!=0); + } + + INLINE af_bit_ref& operator =(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref operator=(const af_bit_ref<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref& operator = ( const ap_bit_ref<_AP_W2, _AP_S2> &val) { + return operator =((unsigned long long) (bool) val); + } + + template + INLINE af_bit_ref& operator = ( const ap_range_ref<_AP_W2,_AP_S2>& val) { + return operator =((const ap_private<_AP_W2, false>) val); + } + + template + INLINE af_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE af_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2> >(*this, const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + template + INLINE bool operator == (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() != op.get(); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv.V)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { + return 1; + } + + INLINE bool get() { + return d_bv.V[d_index]; + } + + INLINE bool get() const { + return d_bv.V[d_index]; + } + + INLINE std::string to_string() const { + return d_bv.V[d_index] ? "1" : "0"; + } +}; + +///Range(slice) reference +//------------------------------------------------------------ +template +struct af_range_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &d_bv; + int l_index; + int h_index; + +public: + INLINE af_range_ref(const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE af_range_ref(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + // fprintf(stderr, + //"Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + if (h_index >= l_index) { + ap_private<_AP_W, false> val(d_bv.V); + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + return val&=mask; + } else { + ap_private<_AP_W, false> val = 0; + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } + } + + INLINE operator unsigned long long() const { + return get().to_uint64(); + } + + template + INLINE af_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W, false> vval= ap_private<_AP_W, false>(val); + if (l_index > h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv.V &= mask; + d_bv.V |= vval; + } + return *this; + } + + INLINE af_range_ref& operator = (unsigned long long val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE af_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + const ap_private<_AP_W2, false> tmp= val.get(); + return operator = (tmp); + } + + INLINE af_range_ref& operator= (const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + const ap_private<_AP_W, false> tmp= val.get(); + return operator = (tmp); + } + + template + INLINE af_range_ref& operator= (const ap_fixed_base<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE bool operator == (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE void set(const ap_private<_AP_W2,false>& val) { + ap_private<_AP_W,_AP_S> vval=val; + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,_AP_S> mask(-1); + if (l_index>0) { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } + + } + + INLINE ap_private<_AP_W,false> get() const { + if (h_index val(0); + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } else { + ap_private<_AP_W, false> val = ap_private<_AP_W,false>(d_bv.V); + val>>= l_index; + if (h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + return val; + } + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& > (op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + INLINE int length() const { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + INLINE int to_int() const { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + INLINE unsigned int to_uint() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + INLINE long to_long() const { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + INLINE unsigned long to_ulong() const { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + INLINE ap_slong to_int64() const { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + INLINE ap_ulong to_uint64() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix) const { + return get().to_string(radix); + } + +}; + +//----------------------------------------------------------------------------- +///ap_fixed_base: AutoPilot fixed point +//----------------------------------------------------------------------------- +template +struct ap_fixed_base { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + template friend struct +ap_fixed_base; + template friend struct +af_bit_ref; + + INLINE void overflow_adjust(bool underflow, bool overflow, + bool lD, bool sign) { + if (!overflow && !underflow) return; + switch (_AP_O) { + case AP_WRAP: + if (_AP_N == 0) + return; + if (_AP_S) { + //signed SC_WRAP + //n_bits == 1; + if (_AP_N > 1) { + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= ~mask; + } + sign ? V.set(_AP_W - 1) : V.clear(_AP_W - 1); + } else { + //unsigned SC_WRAP + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + mask.flip(); + V |= mask; + } + break; + case AP_SAT_ZERO: + V.clear(); + break; + case AP_WRAP_SM: + { + bool Ro = ap_private_ops::get<_AP_W, _AP_S, _AP_W -1>(V); // V[_AP_W -1]; + if (_AP_N == 0) { + if (lD != Ro) { + V.flip(); + lD ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : + ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } else { + if (_AP_N == 1 && sign != Ro) { + V.flip(); + } else if (_AP_N > 1) { + bool lNo = ap_private_ops::get<_AP_W, _AP_S, _AP_W - _AP_N> (V); // V[_AP_W - _AP_N]; + if (lNo == sign) + V.flip(); + ap_private<_AP_W, false> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= mask.flip(); + sign ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } + } + break; + default: + if (_AP_S) { + if (overflow) { + V.set(); ap_private_ops::clear<_AP_W, _AP_S, _AP_W-1>(V); + } else if (underflow) { + V.clear(); + ap_private_ops::set<_AP_W, _AP_S, _AP_W-1>(V); + if (_AP_O == AP_SAT_SYM) + ap_private_ops::set<_AP_W, _AP_S, 0>(V); + } + } else { + if (overflow) + V.set(); + else if (underflow) + V.clear(); + } + } + } + + INLINE bool quantization_adjust(bool qb, bool r, bool s) { + bool carry=ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V); + switch (_AP_Q) { + case AP_TRN: + return false; + case AP_RND_ZERO: + qb &= s || r; + break; + case AP_RND_MIN_INF: + qb &= r; + break; + case AP_RND_INF: + qb &= !s || r; + break; + case AP_RND_CONV: + qb &= ap_private_ops::get<_AP_W, _AP_S, 0>(V) || r; + break; + case AP_TRN_ZERO: + qb = s && ( qb || r ); + break; + default:; + + } + if (qb) ++V; + //only when old V[_AP_W-1]==1 && new V[_AP_W-1]==0 + return carry && !(ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V)); //(!V[_AP_W-1]); + } + + template + struct RType { + enum { + _AP_F=_AP_W-_AP_I, + F2=_AP_W2-_AP_I2, + mult_w = _AP_W+_AP_W2, + mult_i = _AP_I+_AP_I2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + plus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + minus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + minus_s = true, +#ifndef __SC_COMPATIBLE__ + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2, +#else + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2 + AP_MAX(_AP_I2, 0), +#endif /* #ifndef __SC_COMPATIBLE__ */ + div_i = _AP_I + (_AP_W2-_AP_I2) + _AP_S2, + div_s = _AP_S||_AP_S2, + logic_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+AP_MAX(_AP_F,F2), + logic_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + + typedef ap_fixed_base mult; + typedef ap_fixed_base plus; + typedef ap_fixed_base minus; + typedef ap_fixed_base logic; + typedef ap_fixed_base div; + typedef ap_fixed_base<_AP_W, _AP_I, _AP_S> arg1; + }; + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024):" + " for synthesis, please define macro AP_INT_TYPE_EXT(N) to" + " extend the valid range.\n", _AP_W); + } else +#endif /* #if 0 */ + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sfixed<%d, ...>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + /// Constructors. + // ------------------------------------------------------------------------- +#if 0 + #ifdef __SC_COMPATIBLE__ + INLINE ap_fixed_base():V(uint32_t(_AP_W), uint64_t(0)) {} + #else + INLINE ap_fixed_base():V(uint32_t(_AP_W)) {} + #endif /* #ifdef __SC_COMPATIBLE__ */ +#else + INLINE ap_fixed_base():V(0) {} +#endif /* #if 0 */ + // INLINE ap_fixed_base():V() {} + // INLINE explicit ap_fixed_base(const ap_private<_AP_W+_AP_I, _AP_S>& _V):V(_V) {} + INLINE ap_fixed_base(const ap_fixed_base& op):V(op.V) {} + template + INLINE ap_fixed_base(const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op):V(0) { + enum {N2=_AP_W2,_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2,QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || + (_AP_Q==AP_TRN_ZERO && !_AP_S2))}; + if (!op) return; + bool carry=false; + //handle quantization + enum { sh_amt =(F2>_AP_F)?F2-_AP_F:_AP_F-F2}; + const ap_private<_AP_W2, _AP_S2>& val = op.V; + bool neg_src=val.isNegative(); + if (F2==_AP_F) + V=val; + + else if (F2>_AP_F) { + if (sh_amt >= _AP_W2) + V = neg_src ? -1 : 0; + else + V = _AP_S2?val.ashr(sh_amt):val.lshr(sh_amt); + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + bool qb = false; + if (F2-_AP_F>_AP_W2) + qb = neg_src; + else + qb = ap_private_ops::get<_AP_W2, _AP_S2, F2-_AP_F-1>(val); + + bool r=false; + enum { pos3 = F2-_AP_F-2}; + if (pos3>=_AP_W2-1) + r=val!=0; + else if (pos3>=0) + r = (val<<(_AP_W2-1-pos3))!=0; + carry = quantization_adjust(qb,r,neg_src); + } + } else { //no quantization + if (sh_amt < _AP_W) { + V=val; + V <<= sh_amt; + } + } + //hanle overflow/underflow + if ((_AP_O!=AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2 - _AP_S2 + (QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)))) {//saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool lD=(_AP_I2>_AP_I && _AP_W2-_AP_I2+_AP_I>=0) && + ap_private_ops::get<_AP_W2, _AP_S2, _AP_W2-_AP_I2+_AP_I>(val); + enum { pos1=F2-_AP_F+_AP_W, pos2=F2-_AP_F+_AP_W+1}; + if (pos1 < _AP_W2) { + bool Range1_all_ones= true; + bool Range1_all_zeros= true; + if (pos1 >= 0) { + enum { __W = (_AP_W2-pos1) > 0 ? (_AP_W2-pos1) : 1 }; + const ap_private<__W, _AP_S2> Range1=ap_private<__W, _AP_S2>(val.lshr(pos1)); + Range1_all_ones=Range1.isAllOnesValue(); + Range1_all_zeros=Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros=val.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + enum { __W = (_AP_W2-pos2)>0 ? (_AP_W2-pos2) : 1}; + ap_private<__W, true> Range2=ap_private<__W, true>(val.lshr(pos2)); + Range2_all_ones=Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) + :Range1_all_ones; + neg_src= neg_src&&!(carry && Range1_all_ones); + } else + neg_src = neg_src && V[_AP_W-1]; + + bool neg_trg= V.isNegative(); + bool overflow=(neg_trg||!deleted_zeros) && !val.isNegative(); + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow, overflow, lD, neg_src); + } + report(); + } + + template + INLINE ap_fixed_base(const volatile ap_fixed_base<_AP_W2,_AP_I2, + _AP_S2,_AP_Q2,_AP_O2, _AP_N2> &op) : V(op.V) { + *this = const_cast&>(op); + } + + template + INLINE ap_fixed_base(const ap_private<_AP_W2,_AP_S2>& op) { + ap_fixed_base<_AP_W2,_AP_W2,_AP_S2> f_op; + f_op.V=op; + *this = f_op; + } + + INLINE ap_fixed_base(bool b) { + *this=(ap_private<1,false>)b; + report(); + } + + INLINE ap_fixed_base(char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed char b) { + *this=(ap_private<8,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed short b) { + *this=(ap_private<16,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned short b) { + *this=(ap_private<16,false>)b; + report(); + } + + INLINE ap_fixed_base(signed int b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned int b) { + *this=(ap_private<32,false>)b; + report(); + } +# if defined __x86_64__ + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<64,false>)b; + report(); + } +# else + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<32,false>)b; + report(); + } +# endif + + INLINE ap_fixed_base(ap_slong b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(ap_ulong b) { + *this=(ap_private<64,false>)b; + report(); + } + +#if 1 + INLINE ap_fixed_base(const char* val):V(0) { + ap_private<_AP_W, _AP_S> Tmp(val); + V = Tmp; + } + + INLINE ap_fixed_base(const char* val, signed char rd): V(0) { + ap_private<_AP_W, _AP_S> Tmp(val, rd); + V = Tmp; + } + +#endif + + INLINE ap_fixed_base(const std::string& val) { + ap_private<_AP_W, _AP_S> Tmp(val, 2); + V = Tmp; + report(); + } + + template + INLINE ap_fixed_base(const ap_bit_ref<_AP_W2, _AP_S2>& op) { + *this = ((bool)op); + report(); + } + + template + INLINE ap_fixed_base(const ap_range_ref<_AP_W2, _AP_S2>& op) { + *this = ap_private<_AP_W2, _AP_S2>(op); + report(); + } + + template + INLINE ap_fixed_base(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op) { + *this = ((const ap_private<_AP_W2 + _AP_W3, false>&)(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (bool(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (ap_private<_AP_W2, false>(op)); + report(); + } + + //helper function + INLINE unsigned long long doubleToRawBits(double pf)const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__D=pf; + return LD.__L; + } + + + INLINE double rawBitsToDouble(unsigned long long pi) const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__L=pi; + return LD.__D; + } + + INLINE float rawBitsToFloat(uint32_t pi) const { + union { + uint32_t __L; + float __D; + }LD; + LD.__L = pi; + return LD.__D; + } + + INLINE ap_fixed_base(double d):V(0) { + if (!d) return; + const bool isneg=d<0; + + const uint64_t ireg=doubleToRawBits(isneg?-d:d); + if ((ireg&0x7fffffffffffffffULL)!=0) { + const int32_t exp=(((ireg)>>DOUBLE_MAN)&0x07ff)-DOUBLE_BIAS; + ap_private man = ireg & DOUBLE_MAN_MASK; + man.clear(DOUBLE_MAN+1); + man.set(DOUBLE_MAN); + if (isneg) { + man.flip(); + man++; + } + + enum {_AP_S2=true, _AP_W2=DOUBLE_MAN+2,_AP_F=_AP_W -_AP_I }; + const int _AP_I2=exp+2; + const int F2=_AP_W2-_AP_I2; + const bool QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || (_AP_Q==AP_TRN_ZERO && + !_AP_S2)); + bool carry=false; + //handle quantization + const unsigned sh_amt=abs(F2-_AP_F); // sh_amt = F2>_AP_F ? F2 -_AP_F : _AP_F-F2; + if (F2==_AP_F ) + V=man; + else if (F2>_AP_F) { + if (sh_amt >= DOUBLE_MAN+2) + V=isneg?-1:0; + else + V=(man>>sh_amt) | ((man & 1ULL<<(DOUBLE_MAN+1)) ? (DOUBLE_MAN_MASK>>(DOUBLE_MAN+2-sh_amt) <<(DOUBLE_MAN+2-sh_amt)):0); + + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + const bool qb=((F2-_AP_F > DOUBLE_MAN+2) ? isneg : (man & (1ULL<<(F2-_AP_F-1))) != 0); + const int pos3=F2-_AP_F-2; + const bool r = (pos3>= 0) ? (man << AP_MAX(0, _AP_W2-pos3-1)& DOUBLE_MAN_MASK)!=0 : false; + carry = quantization_adjust(qb,r,isneg); + } + } + else { //no quantization + // V=man; + if (sh_amt < _AP_W) { + V = man; + V <<= sh_amt; + } + } + //handle overflow/underflow + if ((_AP_O != AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2-_AP_S2+(QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)) )) {// saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool neg_src; + const bool lD=(_AP_I2>_AP_I) && (_AP_W2-_AP_I2+_AP_I>=0) && (man & (1ULL <<(DOUBLE_MAN+2-_AP_I2+_AP_I))); + int pos1=F2+_AP_W-_AP_F; + if (pos1 < _AP_W2) { + int pos2=pos1+1; + bool Range1_all_ones=true; + bool Range1_all_zeros=true; + if (pos1>=0) { + ap_private<_AP_W,_AP_S> Range1= + ap_private<_AP_W,_AP_S>((man >> pos1) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos1) <<(DOUBLE_MAN+2-pos1)):0)); + Range1_all_ones = Range1.isAllOnesValue(); // Range1.isAllOnesValue(); + Range1_all_zeros = Range1.isMinValue(); // Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros = man==0; // man.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + ap_private<_AP_W, _AP_S> Range2= + ap_private<_AP_W, _AP_S>((man >> pos2) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos2) <<(DOUBLE_MAN+2-pos2)):0)); + Range2_all_ones=Range2.isAllOnesValue(); // Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) : Range1_all_ones; + neg_src=isneg&&!(carry&Range1_all_ones); + } else + neg_src = isneg && V[_AP_W -1]; + + const bool neg_trg=V.isNegative(); + const bool overflow=(neg_trg||!deleted_zeros) && !isneg; + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow,overflow,lD, neg_src); + } + } + report(); + } + + + ///assign operators + //------------------------------------------------------------------------- + + INLINE volatile ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + INLINE volatile ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + // Set this ap_fixed_base with a bits string. That means the ssdm_int::V + // inside this ap_fixed_base is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + INLINE ap_fixed_base& setBits(unsigned long long bv) { + V=bv; + return *this; + } + + // Return a ap_fixed_base object whose ssdm_int::V is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + static INLINE ap_fixed_base bitsToFixed(unsigned long long bv) { + ap_fixed_base Tmp=bv; + return Tmp; + } + + // Explicit conversion functions to ap_private that captures + // all integer bits (bits are truncated) + INLINE ap_private + to_ap_private(bool Cnative = true) const { + ap_private ret = ap_private ((_AP_I >= 1) ? (_AP_S==true ? V.ashr(AP_MAX(0,_AP_W - _AP_I)) : V.lshr(AP_MAX(0,_AP_W - _AP_I))) : ap_private<_AP_W, _AP_S>(0)); + + if (Cnative) { + bool r = false; + if (_AP_I < _AP_W) { + if (_AP_I > 0) r = !(V.getLoBits(_AP_W - _AP_I).isMinValue()); + else r = !(V.isMinValue()); + } + if (r && V.isNegative()) { // if this is negative integer + ++ret;//ap_private(1,_AP_S); + } + } else { + //Follow OSCI library, conversion from sc_fixed to sc_int + } + return ret; + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2> () const { + return (ap_private<_AP_W2,_AP_S2>)to_ap_private(); + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2,_AP_N2> () const { + return (ap_private<_AP_W2,_AP_S2,_AP_N2>)to_ap_private(); + } + + //Explict conversion function to C built-in integral type + INLINE int to_int() const { + return to_ap_private().to_int(); + } + + INLINE int to_uint() const { + return to_ap_private().to_uint(); + } + + INLINE ap_slong to_int64() const { + return to_ap_private().to_int64(); + } + + INLINE ap_ulong to_uint64() const { + return to_ap_private().to_uint64(); + } + + INLINE double to_double() const { + if (!V) + return 0; + if (_AP_W>64 || (_AP_W - _AP_I) > 0) { + bool isneg = _AP_S && V[_AP_W-1]; + uint64_t res = isneg ? 0x8000000000000000ULL : 0; + ap_private<_AP_W, false> tmp = V; + if (isneg) tmp = -tmp; + int i = _AP_W -1 - tmp.countLeadingZeros(); + int exp = _AP_I-(_AP_W-i); + res|=((uint64_t)(exp+DOUBLE_BIAS))<DOUBLE_MAN)?tmp.lshr(i-DOUBLE_MAN):tmp).to_uint64() & DOUBLE_MAN_MASK; + res |= i 0) { + /* This specialization is disabled. It is giving wrong results in some cases. + bool isneg=V.isNegative(); + double dp = V.get(); + dp /= (1<< (_AP_W - _AP_I)); + return dp;*/ + } else + return double(to_int64()); + } + + INLINE float to_float() const { + uint32_t res=0; + if (V==0) + return 0; + bool isneg=V.isNegative(); + ap_private<_AP_W, _AP_S> tmp=V; + if (isneg) tmp = -tmp; + if (_AP_W-_AP_I>0||_AP_W>64) { + if (isneg) + res=0x80000000; + int i=_AP_W-1; + i-=tmp.countLeadingZeros(); + int exp=_AP_I-(_AP_W-i); + res|=(exp+FLOAT_BIAS)< man = 0; + if (i!=0) { + tmp.clear(i); + if (i>FLOAT_MAN) + man=tmp.lshr(i-FLOAT_MAN); + else + man=tmp; + res |= i < FLOAT_MAN?man.getZExtValue()<<(FLOAT_MAN-i):man.getZExtValue(); + } + } else { + return float(to_int64()); + } + float dp=rawBitsToFloat(res); + return dp; + } + + INLINE operator double () const { + return to_double(); + } +#ifndef __SC_COMPATIBLE__ + INLINE operator float () const { + return to_float(); + } + + INLINE operator char () const { + return (char) to_int(); + } + + INLINE operator unsigned char () const { + return (unsigned char) to_uint(); + } + + INLINE operator short () const { + return (short) to_int(); + } + + INLINE operator unsigned short () const { + return (unsigned short) to_uint(); + } + + INLINE operator int () const { + return to_int(); + } + + INLINE operator unsigned int () const { + return to_uint(); + } +#if 1 +#ifdef __x86_64__ + INLINE operator long () const { + return (long)to_int64(); + } + + INLINE operator unsigned long () const { + return (unsigned long) to_uint64(); + } +#else + INLINE operator long () const { + return to_int64(); + } + + INLINE operator unsigned long () const { + return to_uint64(); + } + +#endif +#endif + INLINE operator unsigned long long () const { + return to_uint64(); + } + + INLINE operator long long () const { + return to_int64(); + } +#endif + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const; + + INLINE ap_slong bits_to_int64() const { + ap_private res(V); + return (ap_slong) res; + } + + INLINE ap_ulong bits_to_uint64() const { + ap_private res(V); + return (ap_ulong) res; + } + + INLINE int length() const {return _AP_W;} + + // Count the number of zeros from the most significant bit + // to the first one bit. Note this is only for ap_fixed_base whose + // _AP_W <= 64, otherwise will incur assertion. + INLINE int countLeadingZeros() { + return V.countLeadingZeros(); + } + + ///Arithmetic:Binary + //------------------------------------------------------------------------- + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::mult + operator * (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + typename RType<_AP_W2,_AP_I2,_AP_S2>::mult r; + r.V = V * op2.V; + return r; + } + + template + static INLINE ap_fixed_base multiply(const ap_fixed_base<_AP_W1,_AP_I1,_AP_S1>& op1, const + ap_fixed_base<_AP_W2,_AP_I2,_AP_S2>& op2) { + ap_private<_AP_W+_AP_W2, _AP_S> OP1=op1.V; + ap_private<_AP_W2,_AP_S2> OP2=op2.V; + return OP1*OP2; + } + + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::div + operator / (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {F2 = _AP_W2-_AP_I2, _W1=AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2), + _W2=AP_MAX(_AP_W2,AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2))}; + ap_private<_W1, _AP_S> dividend = (ap_private<_W1, _AP_S>(V)) << ((_W1>_AP_W)?F2:0); + ap_private<_W1, _AP_S2> divisior = ap_private<_W2, _AP_S2>(op2.V); + ap_private<_W1, _AP_S> ret = ap_private<_W1,_AP_S> ((_AP_S||_AP_S2) ? dividend.sdiv(divisior): dividend.udiv(divisior)); + typename RType<_AP_W2, _AP_I2, _AP_S2>::div r; + r.V = ret; + return r; + } +#define OP_BIN_AF(Sym, Rty, Width, Sign, Fun) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + enum {_AP_F=_AP_W-_AP_I, F2=_AP_W2-_AP_I2}; \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V = lhs.V.Fun(rhs.V); \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + + OP_BIN_AF(+, plus, plus_w, plus_s, Add) + OP_BIN_AF(-, minus, minus_w, minus_s, Sub) + +#define OP_LOGIC_BIN_AF(Sym, Rty, Width, Sign) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V=lhs.V Sym rhs.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty operator Sym(int op2) const \ + { \ + return V Sym (op2<<(_AP_W - _AP_I)); \ + } + OP_LOGIC_BIN_AF(&, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(|, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(^, logic, logic_w, logic_s) + + ///Arithmic : assign + //------------------------------------------------------------------------- +#define OP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2) ; \ + return *this; \ + } + + OP_ASSIGN_AF(+) + OP_ASSIGN_AF(-) + OP_ASSIGN_AF(&) + OP_ASSIGN_AF(|) + OP_ASSIGN_AF(^) + OP_ASSIGN_AF(*) + OP_ASSIGN_AF(/) + + ///Prefix increment, decrement + //------------------------------------------------------------------------- + INLINE ap_fixed_base& operator ++() { + operator+=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + INLINE ap_fixed_base& operator --() { + operator-=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + //Postfix increment, decrement + //------------------------------------------------------------------------- + INLINE const ap_fixed_base operator ++(int) { + ap_fixed_base t(*this); + operator++(); + return t; + } + + INLINE const ap_fixed_base operator --(int) { + ap_fixed_base t = *this; + operator--(); + return t; + } + + ///Unary arithmetic + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator +() {return *this;} + + INLINE ap_fixed_base<_AP_W + 1, _AP_I + 1, true> operator -() const { + ap_fixed_base<_AP_W + 1, _AP_I + 1, true> Tmp(*this); + Tmp.V = - Tmp.V; + return Tmp; + } + + INLINE ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> getNeg() { + ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> Tmp(*this); + Tmp.V=-Tmp.V; + return Tmp; + } + + ///Not (!) + //------------------------------------------------------------------------- + INLINE bool operator !() const { + return !V; + } + + ///Bitwise complement + //------------------------------------------------------------------------- + INLINE ap_fixed_base<_AP_W, _AP_I, _AP_S> + operator ~() const { + ap_fixed_base<_AP_W, _AP_I, _AP_S> res(*this); + res.V.flip(); + return res; + } + + ///Shift + ///template argument as shift value + template + INLINE ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> lshift () const { + ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + template + INLINE ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> rshift () const { + ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + //Because the return type is the type of the the first operand, shift assign + //operators do not carry out any quantization or overflow + //While systemc, shift assigns for sc_fixed/sc_ufixed will result in + //quantization or overflow (depending on the mode of the first operand) + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator << (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + bool NegSrc = V.isNegative(); + if (isNeg) { + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); + } else { + if (shiftoverflow) + r.V.clear(); + else + r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == false && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator<<(const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator << (sh); + } + + INLINE ap_fixed_base operator << (unsigned int sh ) const { + ap_fixed_base r; + bool shiftoverflow = sh >= _AP_W; + r.V = shiftoverflow ? ap_private<_AP_W, _AP_S >(0) : V << sh; + if (sh == 0) return r; +#ifdef __SC_COMPATIBLE__ + bool NegSrc = V.isNegative(); + if (_AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh -1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator << (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator << (sh); + } + + INLINE ap_fixed_base operator >> (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + bool NegSrc = V.isNegative(); + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + if (isNeg && !shiftoverflow) r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == true && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator >> (sh); + } + + INLINE ap_fixed_base operator >> (unsigned int sh) const { + ap_fixed_base r; + bool NegSrc = V.isNegative(); + bool shiftoverflow = sh >= _AP_W; + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); +#ifdef __SC_COMPATIBLE__ + if (sh == 0) return r; + if (_AP_Q != AP_TRN) { + bool qb = false; + if (sh <= _AP_W) qb = V[sh - 1]; + bool rb = false; + if (sh > 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator >> (sh); + } + + ///shift assign + //------------------------------------------------------------------------- +#define OP_AP_SHIFT_AP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AP_ASSIGN_AF(<<) + OP_AP_SHIFT_AP_ASSIGN_AF(>>) + + ///Support shift(ap_fixed_base) +#define OP_AP_SHIFT_AF(Sym) \ + template \ + INLINE ap_fixed_base operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + return operator Sym (op2.to_ap_private()); \ + } \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AF(<<) + OP_AP_SHIFT_AF(>>) + + INLINE ap_fixed_base& operator >>= (unsigned int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (unsigned int sh) { + *this = operator << (sh); + return *this; + } + + INLINE ap_fixed_base& operator >>= (int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (int sh) { + *this = operator << (sh); + return *this; + } + + ///Comparisons + //------------------------------------------------------------------------- + template + INLINE bool operator == (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator != (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this==op2); + } + + template + INLINE bool operator > (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator <= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this>op2); + } + + template + INLINE bool operator < (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator >= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this) + DOUBLE_CMP_AF(>=) + DOUBLE_CMP_AF(<) + DOUBLE_CMP_AF(<=) + + // Bit and Slice Select + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> operator [] (unsigned int index) { + assert(index<_AP_W&&"Attemping to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit(unsigned int index) { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit (const ap_private<_AP_W2,_AP_S2>& index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int()); + } + + INLINE bool bit (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + INLINE bool operator [] (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + template + INLINE bool bit (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + template + INLINE bool operator [] (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit(int index) { + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + assert(index >= _AP_I - _AP_W&& "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index + _AP_W - _AP_I); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit (const ap_private<_AP_W2, true>& index) { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int() + _AP_W - _AP_I); + } + + INLINE bool get_bit (int index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index + _AP_W - _AP_I]; + } + + template + INLINE bool get_bit (const ap_private<_AP_W2, true>& index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index.to_int() + _AP_W - _AP_I]; + } + + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W) &&"Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast(this), Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) const { + return this->range(Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast< + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>*>(this), + Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() { + return this->range(_AP_W - 1, 0); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() const { + return this->range(_AP_W - 1, 0); + } + + INLINE bool is_zero () const { + return V.isMinValue(); + } + + INLINE bool is_neg () const { + if (V.isNegative()) + return true; + return false; + } + + INLINE int wl () const { + return _AP_W; + } + + INLINE int iwl () const { + return _AP_I; + } + + INLINE ap_q_mode q_mode () const { + return _AP_Q; + } + + INLINE ap_o_mode o_mode () const { + return _AP_O; + } + + INLINE int n_bits () const { + return 0; + } + + //private: +public: + ap_private<_AP_W, _AP_S> V; +}; + +template +std::string ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>::to_string( + uint8_t radix, bool sign) const { + std::string str; + str.clear(); + char step; + std::string prefix; + switch (radix) { + case 2 : prefix = "0b"; step = 1; break; + case 8 : prefix = "0o"; step = 3; break; + case 16 : prefix = "0x"; step = 4; break; + default : break; + } + if (_AP_W <= _AP_I) + str = this->to_ap_private().to_string(radix, + radix == 10 ? _AP_S : sign); + else { + if (radix == 10) { + bool isNeg = _AP_S && V.isNegative(); + if (_AP_I > 0) { + ap_private int_part(0); + int_part = this->to_ap_private(); + str += int_part.to_string(radix, false); + } else { + if (isNeg) str += '-'; + } + ap_fixed_base<_AP_W, _AP_I, _AP_S> tmp(*this); + if (isNeg && _AP_I <= 0) tmp = -tmp; + ap_fixed_base<_AP_W - AP_MIN(_AP_I, 0), 0, false> frac_part = tmp; + if (frac_part == 0) return str; + str += "."; + while (frac_part != 0) { + char digit = (frac_part * radix).to_ap_private(); + str += static_cast(digit + '0'); + frac_part *= radix; + } + } else { + if (_AP_I > 0) { + for (signed i = _AP_W - _AP_I; i < _AP_W; i += step) { + + char digit = (char)(this->range(AP_MIN(i + step - 1, _AP_W - 1), i)); + str = (digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a')) + str; + } + } + str += '.'; + ap_fixed_base tmp(*this); + for (signed i = _AP_W - _AP_I - 1; i >= 0; i -= step) { + char digit = (char)(tmp.range(i, AP_MAX(0, i - step + 1))); + str += digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a'); + } + } + } + str = prefix + str; + return str; +} + +template +INLINE void b_not(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = op.V; + ret.V.flip(); +} + +template +INLINE void b_and(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V & op2.V; +} + +template +INLINE void b_or(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V | op2.V; +} + +template +INLINE void b_xor(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V ^ op2.V; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + ap_fixed_base<_AP_W2+!_AP_S2, _AP_I2+!_AP_S2, true, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp.V = - op.V; + ret = Tmp; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = -op.V; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_W2 - _AP_I2 + AP_MAX(_AP_I, _AP_I2), AP_MAX(_AP_I, _AP_I2), _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V <<= i; + ret = Tmp; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = op.V << i; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_I2 + AP_MAX(_AP_W - _AP_I, _AP_W2 - _AP_I2), _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V = _AP_S2 ? Tmp.V.ashr(i): Tmp.V.lshr(i); + ret = Tmp; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = _AP_S ? op.V.ashr(i): op.V.lshr(i); +} + +#define AF_CTOR_SPEC_BASE(_AP_W,_AP_S,C_TYPE) \ + template<> INLINE ap_fixed_base<_AP_W,_AP_W,_AP_S,AP_TRN,AP_WRAP>::ap_fixed_base(C_TYPE i_op):V(i_op) \ + { \ + } + +#define AF_CTOR_SPEC(__W,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,true,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,false,C_TYPE) + +AF_CTOR_SPEC(1,bool) +AF_CTOR_SPEC(8, signed char) +AF_CTOR_SPEC(8, unsigned char) +AF_CTOR_SPEC(16, signed short) +AF_CTOR_SPEC(16, unsigned short) +AF_CTOR_SPEC(32, signed int) +AF_CTOR_SPEC(32, unsigned int) +AF_CTOR_SPEC(64, ap_slong) +AF_CTOR_SPEC(64, ap_ulong) + +///Output streaming +//----------------------------------------------------------------------------- +template +INLINE std::ostream& +operator <<(std::ostream& os, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + os << x.to_double(); + return os; +} + +///Input streaming +//----------------------------------------------------------------------------- +template +INLINE std::istream& +operator >> (std::istream& os, ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + double d; + os >> d; + x = ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(x); + return os; +} + +template +INLINE void print(const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + ap_private<_AP_W,_AP_S> data=x.V; + if (_AP_I>0) { + const ap_private<_AP_I,_AP_S> p1=data>>(_AP_W-_AP_I); + print(p1); + + } else + printf("0"); + printf("."); + if (_AP_I<_AP_W) { + const ap_private<_AP_W-_AP_I,false> p2=data; + print(p2,false); + } +} + +///Operators mixing Integers with ap_fixed_base +//----------------------------------------------------------------------------- +#if 1 +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP(ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#else +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op BIN_OP (i_op); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V BIN_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#endif +#if 1 +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator REL_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } +#else +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V.operator REL_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return (i_op<<(_AP_W-_AP_I)) REL_OP (op.V.VAL); \ + } +#endif +#if 1 +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#else +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#endif + +#define AF_OPS_WITH_INT(C_TYPE, WI, SI) \ + AF_BIN_OP_WITH_INT(+, C_TYPE, WI, SI, plus) \ + AF_BIN_OP_WITH_INT(-, C_TYPE, WI, SI, minus) \ + AF_BIN_OP_WITH_INT(*, C_TYPE, WI, SI, mult) \ + AF_BIN_OP_WITH_INT(/, C_TYPE, WI, SI, div) \ + AF_BIN_OP_WITH_INT_SF(>>, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT_SF(<<, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT(&, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(|, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(^, C_TYPE, WI, SI, logic) \ + \ + AF_REL_OP_WITH_INT(==, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(!=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<=, C_TYPE, WI, SI) \ + \ + AF_ASSIGN_OP_WITH_INT(+=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(-=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(*=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(/=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(>>=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(<<=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(&=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(|=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(^=, C_TYPE, WI, SI) + +AF_OPS_WITH_INT(bool, 1, false) +AF_OPS_WITH_INT(char, 8, true) +AF_OPS_WITH_INT(signed char, 8, true) +AF_OPS_WITH_INT(unsigned char, 8, false) +AF_OPS_WITH_INT(short, 16, true) +AF_OPS_WITH_INT(unsigned short, 16, false) +AF_OPS_WITH_INT(int, 32, true) +AF_OPS_WITH_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_OPS_WITH_INT(long, 64, true) +AF_OPS_WITH_INT(unsigned long, 64, false) +# else +AF_OPS_WITH_INT(long, 32, true) +AF_OPS_WITH_INT(unsigned long, 32, false) +# endif +AF_OPS_WITH_INT(ap_slong, 64, true) +AF_OPS_WITH_INT(ap_ulong, 64, false) + +#define AF_BIN_OP_WITH_AP_INT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>::template RType<_AP_W,_AP_I,_AP_S>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } + +#define AF_REL_OP_WITH_AP_INT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator REL_OP ( ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } + +#define AF_ASSIGN_OP_WITH_AP_INT(ASSIGN_OP) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE ap_private<_AP_W2,_AP_S2>& operator ASSIGN_OP ( ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return i_op.operator ASSIGN_OP (op.to_ap_private()); \ + } + +AF_BIN_OP_WITH_AP_INT(+, plus) +AF_BIN_OP_WITH_AP_INT(-, minus) +AF_BIN_OP_WITH_AP_INT(*, mult) +AF_BIN_OP_WITH_AP_INT(/, div) +AF_BIN_OP_WITH_AP_INT(&, logic) +AF_BIN_OP_WITH_AP_INT(|, logic) +AF_BIN_OP_WITH_AP_INT(^, logic) + +AF_REL_OP_WITH_AP_INT(==) +AF_REL_OP_WITH_AP_INT(!=) +AF_REL_OP_WITH_AP_INT(>) +AF_REL_OP_WITH_AP_INT(>=) +AF_REL_OP_WITH_AP_INT(<) +AF_REL_OP_WITH_AP_INT(<=) + +AF_ASSIGN_OP_WITH_AP_INT(+=) +AF_ASSIGN_OP_WITH_AP_INT(-=) +AF_ASSIGN_OP_WITH_AP_INT(*=) +AF_ASSIGN_OP_WITH_AP_INT(/=) +AF_ASSIGN_OP_WITH_AP_INT(&=) +AF_ASSIGN_OP_WITH_AP_INT(|=) +AF_ASSIGN_OP_WITH_AP_INT(^=) + +#define AF_REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2 REL_OP (bool(op)); \ + } + +#define AF_REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +AF_REF_REL_MIX_INT(bool, 1, false) +AF_REF_REL_MIX_INT(char, 8, true) +AF_REF_REL_MIX_INT(signed char, 8, true) +AF_REF_REL_MIX_INT(unsigned char, 8, false) +AF_REF_REL_MIX_INT(short, 16, true) +AF_REF_REL_MIX_INT(unsigned short, 16, false) +AF_REF_REL_MIX_INT(int, 32, true) +AF_REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_REF_REL_MIX_INT(long, 64, true) +AF_REF_REL_MIX_INT(unsigned long, 64, false) +# else +AF_REF_REL_MIX_INT(long, 32, true) +AF_REF_REL_MIX_INT(unsigned long, 32, false) +# endif +AF_REF_REL_MIX_INT(ap_slong, 64, true) +AF_REF_REL_MIX_INT(ap_ulong, 64, false) + +#define AF_REF_REL_OP_AP_INT(REL_OP) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S> &op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP (const ap_private<_AP_W2, _AP_S2> &op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S2> &op2) { \ + return (ap_private<1, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2, _AP_S2> &op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<1,false>(op)); \ + } + +AF_REF_REL_OP_AP_INT(>) +AF_REF_REL_OP_AP_INT(<) +AF_REF_REL_OP_AP_INT(>=) +AF_REF_REL_OP_AP_INT(<=) +AF_REF_REL_OP_AP_INT(==) +AF_REF_REL_OP_AP_INT(!=) + +// Relational Operators with double +template +INLINE bool operator == ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator == (op1); +} + +template +INLINE bool operator != ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator != (op1); +} + +template +INLINE bool operator > ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator < (op1); +} + +template +INLINE bool operator >= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator <= (op1); +} + +template +INLINE bool operator < ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator > (op1); +} + +template +INLINE bool operator <= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator >= (op1); +} + +#endif /* #ifndef __AESL_GCC_AP_FIXED_H__ */ \ No newline at end of file diff --git a/hls_2018/router_03_boardstr/etc/ap_int_sim.h b/hls_2018/router_03_boardstr/etc/ap_int_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..887ccd88bfd52d1777db8661d72c57703ccf736a --- /dev/null +++ b/hls_2018/router_03_boardstr/etc/ap_int_sim.h @@ -0,0 +1,1629 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_INT_H__ +#define __AESL_GCC_AP_INT_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + +#undef _AP_DEBUG_ +#include +#include + +// for safety +#if (defined(_AP_N)|| defined(_AP_C)) +#error One or more of the following is defined: _AP_N, _AP_C. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_N)|| defined(_AP_C)) */ + +// for safety +#if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) +#error One or more of the following is defined: _AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) */ + +//for safety +#if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) +#error One or more of the following is defined: _AP_W3, _AP_S3, _AP_W4,_AP_S4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) */ + +//for safety +#if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) +#error One or more of the following is defined: _AP_W1, _AP_S1, _AP_I1, _AP_T, _AP_T1, _AP_T2, _AP_T3, _AP_T4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) */ + +#define __AESL_APDT_IN_SCFLOW__ +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_private.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#ifdef _AP_DEBUG_ + #define AP_DEBUG(s) s +#else + #define AP_DEBUG(s) +#endif /* #ifdef _AP_DEBUG_ */ + +#ifndef __SIMULATION__ + #define __SIMULATION__ +#endif /* #ifndef __SIMULATION__ */ + +#if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) + #ifndef SC_TRN + #define SC_TRN AP_TRN + #endif /* #ifndef SC_TRN */ + #ifndef SC_RND + #define SC_RND AP_RND + #endif /* #ifndef SC_RND */ + #ifndef SC_TRN_ZERO + #define SC_TRN_ZERO AP_TRN_ZERO + #endif /* #ifndef SC_TRN_ZERO */ + #ifndef SC_RND_ZERO + #define SC_RND_ZERO AP_RND_ZERO + #endif /* #ifndef SC_RND_ZERO */ + #ifndef SC_RND_INF + #define SC_RND_INF AP_RND_INF + #endif /* #ifndef SC_RND_INF */ + #ifndef SC_RND_MIN_INF + #define SC_RND_MIN_INF AP_RND_MIN_INF + #endif /* #ifndef SC_RND_MIN_INF */ + #ifndef SC_RND_CONV + #define SC_RND_CONV AP_RND_CONV + #endif /* #ifndef SC_RND_CONV */ + #ifndef SC_WRAP + #define SC_WRAP AP_WRAP + #endif /* #ifndef SC_WRAP */ + #ifndef SC_SAT + #define SC_SAT AP_SAT + #endif /* #ifndef SC_SAT */ + #ifndef SC_SAT_ZERO + #define SC_SAT_ZERO AP_SAT_ZERO + #endif /* #ifndef SC_SAT_ZERO */ + #ifndef SC_SAT_SYM + #define SC_SAT_SYM AP_SAT_SYM + #endif /* #ifndef SC_SAT_SYM */ + #ifndef SC_WRAP_SM + #define SC_WRAP_SM AP_WRAP_SM + #endif /* #ifndef SC_WRAP_SM */ + #ifndef SC_BIN + #define SC_BIN AP_BIN + #endif /* #ifndef SC_BIN */ + #ifndef SC_OCT + #define SC_OCT AP_OCT + #endif /* #ifndef SC_OCT */ + #ifndef SC_DEC + #define SC_DEC AP_DEC + #endif /* #ifndef SC_DEC */ + #ifndef SC_HEX + #define SC_HEX AP_HEX + #endif /* #ifndef SC_HEX */ +#endif /* #if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) */ +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +///Forward declaration +template struct ap_range_ref; +template struct ap_bit_ref; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; +template class ap_uint; + +enum { + AP_BIN = 2, + AP_OCT = 8, + AP_DEC = 10, + AP_HEX = 16 +}; + +///Why to use reference? +///Because we will operate the original object indirectly by operating the +///result object directly after concating or part selecting + +///Proxy class which allows concatination to be used as rvalue(for reading) and +//lvalue(for writing) + +/// Concatination reference. +// ---------------------------------------------------------------- +template +struct ap_concat_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + enum {_AP_WR=_AP_W1+_AP_W2,}; + _AP_T1& mbv1; + _AP_T2& mbv2; + + INLINE ap_concat_ref(const ap_concat_ref<_AP_W1, _AP_T1, + _AP_W2, _AP_T2>& ref): + mbv1(ref.mbv1), mbv2(ref.mbv2) {} + + INLINE ap_concat_ref(_AP_T1& bv1, _AP_T2& bv2):mbv1(bv1),mbv2(bv2) {} + + template + INLINE ap_concat_ref& operator = (const ap_private<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + return *this; + } + + INLINE ap_concat_ref& operator = (unsigned long long val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W1, _AP_T1, _AP_W2, _AP_T2>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_concat_ref& operator= (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = ((const ap_private<_AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref& operator= (const ap_fixed_base<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = (val.to_ap_private()); + } + + template + INLINE ap_concat_ref& operator= (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + + INLINE operator ap_private<_AP_WR, false> () const { + return get(); + } + + INLINE operator unsigned long long () const { + return get().to_uint64(); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_range_ref<_AP_W3, _AP_S3> > + operator, (const ap_range_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_range_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (const ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, + const_cast&>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, 1, ap_bit_ref<_AP_W3, _AP_S3> > + operator, (const ap_bit_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + 1, ap_bit_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> > + operator, (const ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> &a2) + { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4, + _AP_T4> >(*this, const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE ap_private + operator & (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() & a2; + } + + + template + INLINE ap_private + operator | (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() | a2; + } + + + template + INLINE ap_private + operator ^ (const ap_private<_AP_W3,_AP_S3>& a2) { + return ap_private(get() ^ a2); + } + + INLINE const ap_private<_AP_WR, false> get() const + { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> (mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + INLINE const ap_private<_AP_WR, false> get() { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> ( mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + template + INLINE void set(const ap_private<_AP_W3,false> & val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + } + + INLINE int length() const { + return mbv1.length()+mbv2.length(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } +}; + +///Proxy class, which allows part selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Range(slice) reference +//------------------------------------------------------------ +template +struct ap_range_ref { +#ifdef _MSC_VER + #pragma warning( disable : 4521 4522 ) +#endif /* #ifdef _MSC_VER */ + ap_private<_AP_W,_AP_S> &d_bv; + int l_index; + int h_index; + +public: + INLINE ap_range_ref(const ap_range_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE ap_range_ref(ap_private<_AP_W,_AP_S>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + //fprintf(stderr, "Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + ap_private<_AP_W, false> val(0); + if(h_index>=l_index) { + if (_AP_W > 64) { + val=d_bv; + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + val&=mask; + } else { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val = (d_bv >> l_index) & (mask >>(_AP_W-(h_index-l_index+1))); + } + } else { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } + return val; + } + + INLINE operator unsigned long long () const { + return to_uint64(); + } + + template + INLINE ap_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W,false> vval=ap_private<_AP_W,false>(val); + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W > 64) { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + unsigned shift = 64-_AP_W; + uint64_t mask = ~0ULL>>(shift); + if(l_index>0) + { + vval = mask & vval << l_index; + mask = mask & mask << l_index; + } + if(h_index<_AP_W-1) + { + uint64_t mask2 = mask; + mask2 >>= (_AP_W-h_index-1); + mask&=mask2; + vval&=mask2; + } + mask = ~mask; + d_bv&=mask; + d_bv|=vval; + } + } + return *this; + } + + INLINE ap_range_ref& operator = (unsigned long long val) + { + const ap_private<_AP_W,_AP_S> vval=val; + return operator = (vval); + } + + + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W, _AP_S>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + + + template + INLINE ap_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, _AP_S2>)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE ap_range_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_bit_ref<_AP_W2, _AP_S2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, + ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast& >(a2)); + } + + + template + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2,_AP_S2>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W,ap_private<_AP_W,_AP_S> > + operator , (ap_private<_AP_W, _AP_S>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W, + ap_private<_AP_W,_AP_S> >(*this, a2); + } + + + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,1,ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, 1, + ap_bit_ref<_AP_W2,_AP_S2> >(*this, const_cast& >(a2)); + } + + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) + { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + + template + INLINE void set(const ap_private<_AP_W2,false>& val) + { + ap_private<_AP_W,_AP_S> vval=val; + if(l_index>h_index) + { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W>64 ) { + ap_private<_AP_W,_AP_S> mask(-1); + if(l_index>0) + { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + uint64_t mask = ~0ULL >> (64-_AP_W); + if(l_index>0) + { + uint64_t mask1 = mask; + mask1=mask & (mask1>>(_AP_W-l_index)); + vval =mask&( vval <> (64-_AP_W); + mask2 = mask &(mask2<<(h_index+1)); + mask&=~mask2; + vval&=~mask2; + } + d_bv&=(~mask&(~0ULL >> (64-_AP_W))); + d_bv|=vval; + } + } + } + + + INLINE ap_private<_AP_W,false> get() const + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64) { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val &= (mask>> (_AP_W-(h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE ap_private<_AP_W,false> get() + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64 ) { + static const uint64_t mask = ~0ULL>> (64>_AP_W ? (64-_AP_W):0); + return val &= ( (mask) >> (_AP_W - (h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE int length() const + { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + + INLINE int to_int() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + + INLINE unsigned int to_uint() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + + INLINE long to_long() const + { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + + INLINE unsigned long to_ulong() const + { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + + INLINE ap_slong to_int64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + + INLINE ap_ulong to_uint64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } + +}; + +///Proxy class, which allows bit selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Bit reference +//-------------------------------------------------------------- +template +struct ap_bit_ref { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif + ap_private<_AP_W,_AP_S>& d_bv; + int d_index; + +public: + INLINE ap_bit_ref(const ap_bit_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE ap_bit_ref(ap_private<_AP_W,_AP_S>& bv, int index=0): + d_bv(bv),d_index(index) + { +#ifdef _AP_DEBUG_ + assert(d_index<_AP_W&&"index out of bound"); +#endif + } + + + INLINE operator bool () const + { + return d_bv.get_bit(d_index); + } + + + INLINE bool to_bool() const + { + return operator bool (); + } + + + INLINE ap_bit_ref& operator = (unsigned long long val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } + + +#if 0 + INLINE ap_bit_ref& operator = (bool val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } +#endif + template + INLINE ap_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(val != 0)); + } + + + template + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool)val); + } + + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W,_AP_S>& val) + { + return operator =((unsigned long long)(bool)val); + } + + template + INLINE ap_bit_ref& operator =(const ap_range_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool) val); + } + + + template + INLINE ap_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE ap_bit_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2, _AP_S2>& a2) + { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref > + operator, (const ap_bit_ref &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref >(*this, + const_cast(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> > + operator, (const ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> &a2) + { + return + ap_concat_ref<1,ap_bit_ref,_AP_W2+_AP_W3, + ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() != op.get(); + } + + + INLINE bool get() const + { + return operator bool (); + } + + + INLINE bool get() + { + return operator bool (); + } + + + template + INLINE void set(const ap_private<_AP_W3, false>& val) + { + operator = (val); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { return 1; } + + INLINE std::string to_string() const { + bool val = get(); + return val ? "1" : "0"; + } +}; + +/// Operators mixing Integers with AP_Int +// ---------------------------------------------------------------- +#if 1 +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#else +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#endif +#define OP_REL_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator REL_OP (ap_private<_AP_W2, _AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (op); \ + } +#define OP_ASSIGN_MIX_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } + +#define OP_BIN_SHIFT_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + C_TYPE operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return i_op BIN_OP (op.getVal()); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (i_op); \ + } +#define OP_ASSIGN_RSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator >> (op2); \ + return op; \ + } +#define OP_ASSIGN_LSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator << (op2); \ + return op; \ + } + +#define OPS_MIX_INT(C_TYPE, WI, SI) \ + OP_BIN_MIX_INT(*, C_TYPE, WI, SI, mult) \ + OP_BIN_MIX_INT(+, C_TYPE, WI, SI, plus) \ + OP_BIN_MIX_INT(-, C_TYPE, WI, SI, minus) \ + OP_BIN_MIX_INT(/, C_TYPE, WI, SI, div) \ + OP_BIN_MIX_INT(%, C_TYPE, WI, SI, mod) \ + OP_BIN_MIX_INT(&, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(|, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(^, C_TYPE, WI, SI, logic) \ + OP_BIN_SHIFT_INT(>>, C_TYPE, WI, SI, arg1) \ + OP_BIN_SHIFT_INT(<<, C_TYPE, WI, SI, arg1) \ + \ + OP_REL_MIX_INT(==, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(!=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<=, C_TYPE, WI, SI) \ + \ + OP_ASSIGN_MIX_INT(+=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(-=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(*=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(/=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(%=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(&=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(|=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(^=, C_TYPE, WI, SI) \ + OP_ASSIGN_RSHIFT_INT(>>=, C_TYPE, WI, SI) \ + OP_ASSIGN_LSHIFT_INT(<<=, C_TYPE, WI, SI) + + +OPS_MIX_INT(bool, 1, false) +OPS_MIX_INT(char, 8, true) +OPS_MIX_INT(signed char, 8, true) +OPS_MIX_INT(unsigned char, 8, false) +OPS_MIX_INT(short, 16, true) +OPS_MIX_INT(unsigned short, 16, false) +OPS_MIX_INT(int, 32, true) +OPS_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +OPS_MIX_INT(long, 64, true) +OPS_MIX_INT(unsigned long, 64, false) +# else +OPS_MIX_INT(long, 32, true) +OPS_MIX_INT(unsigned long, 32, false) +# endif +OPS_MIX_INT(ap_slong, 64, true) +OPS_MIX_INT(ap_ulong, 64, false) + +#define OP_BIN_MIX_RANGE(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<_AP_W2, false>(op2)); \ + } + +#define OP_REL_MIX_RANGE(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (op2.operator ap_private<_AP_W2, false>()); \ + } + +#define OP_ASSIGN_MIX_RANGE(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<_AP_W2, false>(op2)); \ + } \ + template \ + INLINE ap_range_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP (ap_range_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<_AP_W1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_RANGE(+=) +OP_ASSIGN_MIX_RANGE(-=) +OP_ASSIGN_MIX_RANGE(*=) +OP_ASSIGN_MIX_RANGE(/=) +OP_ASSIGN_MIX_RANGE(%=) +OP_ASSIGN_MIX_RANGE(>>=) +OP_ASSIGN_MIX_RANGE(<<=) +OP_ASSIGN_MIX_RANGE(&=) +OP_ASSIGN_MIX_RANGE(|=) +OP_ASSIGN_MIX_RANGE(^=) + +OP_REL_MIX_RANGE(==) +OP_REL_MIX_RANGE(!=) +OP_REL_MIX_RANGE(>) +OP_REL_MIX_RANGE(>=) +OP_REL_MIX_RANGE(<) +OP_REL_MIX_RANGE(<=) + +OP_BIN_MIX_RANGE(+, plus) +OP_BIN_MIX_RANGE(-, minus) +OP_BIN_MIX_RANGE(*, mult) +OP_BIN_MIX_RANGE(/, div) +OP_BIN_MIX_RANGE(%, mod) +OP_BIN_MIX_RANGE(>>, arg1) +OP_BIN_MIX_RANGE(<<, arg1) +OP_BIN_MIX_RANGE(&, logic) +OP_BIN_MIX_RANGE(|, logic) +OP_BIN_MIX_RANGE(^, logic) + +#define OP_BIN_MIX_BIT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<1, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<1,false>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<1, false>(op2)); \ + } + +#define OP_REL_MIX_BIT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (ap_private<1, false>(op2)); \ + } + +#define OP_ASSIGN_MIX_BIT(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<1, false>(op2)); \ + } \ + template \ + INLINE ap_bit_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_bit_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_BIT(+=) +OP_ASSIGN_MIX_BIT(-=) +OP_ASSIGN_MIX_BIT(*=) +OP_ASSIGN_MIX_BIT(/=) +OP_ASSIGN_MIX_BIT(%=) +OP_ASSIGN_MIX_BIT(>>=) +OP_ASSIGN_MIX_BIT(<<=) +OP_ASSIGN_MIX_BIT(&=) +OP_ASSIGN_MIX_BIT(|=) +OP_ASSIGN_MIX_BIT(^=) + +OP_REL_MIX_BIT(==) +OP_REL_MIX_BIT(!=) +OP_REL_MIX_BIT(>) +OP_REL_MIX_BIT(>=) +OP_REL_MIX_BIT(<) +OP_REL_MIX_BIT(<=) + +OP_BIN_MIX_BIT(+, plus) +OP_BIN_MIX_BIT(-, minus) +OP_BIN_MIX_BIT(*, mult) +OP_BIN_MIX_BIT(/, div) +OP_BIN_MIX_BIT(%, mod) +OP_BIN_MIX_BIT(>>, arg1) +OP_BIN_MIX_BIT(<<, arg1) +OP_BIN_MIX_BIT(&, logic) +OP_BIN_MIX_BIT(|, logic) +OP_BIN_MIX_BIT(^, logic) + +#define REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_bit_ref<_AP_W,_AP_S> &op) { \ + return op2 REL_OP (bool(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op, C_TYPE op2) { \ + return (ap_private<_AP_W + _AP_W1, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W + _AP_W1, false>(op)); \ + } + +#define REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +REF_REL_MIX_INT(bool, 1, false) +REF_REL_MIX_INT(char, 8, true) +REF_REL_MIX_INT(signed char, 8, true) +REF_REL_MIX_INT(unsigned char, 8, false) +REF_REL_MIX_INT(short, 16, true) +REF_REL_MIX_INT(unsigned short, 16, false) +REF_REL_MIX_INT(int, 32, true) +REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_REL_MIX_INT(long, 64, true) +REF_REL_MIX_INT(unsigned long, 64, false) +# else +REF_REL_MIX_INT(long, 32, true) +REF_REL_MIX_INT(unsigned long, 32, false) +# endif +REF_REL_MIX_INT(ap_slong, 64, true) +REF_REL_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP_MIX_INT(BIN_OP, RTYPE, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator BIN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE typename ap_private<_AP_W2, _AP_S2>::template RType<_AP_W,false>::RTYPE \ + operator BIN_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator BIN_OP (ap_private<_AP_W, false>(op)); \ + } + +#define REF_BIN_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(+, plus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(-, minus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(*, mult, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(/, div, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(%, mod, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(>>, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(<<, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(&, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(|, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(^, logic, C_TYPE, _AP_WI, _AP_SI) + +REF_BIN_MIX_INT(bool, 1, false) +REF_BIN_MIX_INT(char, 8, true) +REF_BIN_MIX_INT(signed char, 8, true) +REF_BIN_MIX_INT(unsigned char, 8, false) +REF_BIN_MIX_INT(short, 16, true) +REF_BIN_MIX_INT(unsigned short, 16, false) +REF_BIN_MIX_INT(int, 32, true) +REF_BIN_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_BIN_MIX_INT(long, 64, true) +REF_BIN_MIX_INT(unsigned long, 64, false) +#else +REF_BIN_MIX_INT(long, 32, true) +REF_BIN_MIX_INT(unsigned long, 32, false) +#endif +REF_BIN_MIX_INT(ap_slong, 64, true) +REF_BIN_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP(BIN_OP, RTYPE) \ +template \ +INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2, false>::RTYPE \ +operator BIN_OP (const ap_range_ref<_AP_W,_AP_S> &lhs, const ap_range_ref<_AP_W2,_AP_S2> &rhs) { \ + return ap_private<_AP_W,false>(lhs).operator BIN_OP (ap_private<_AP_W2, false>(rhs)); \ +} + +REF_BIN_OP(+, plus) +REF_BIN_OP(-, minus) +REF_BIN_OP(*, mult) +REF_BIN_OP(/, div) +REF_BIN_OP(%, mod) +REF_BIN_OP(>>, arg1) +REF_BIN_OP(<<, arg1) +REF_BIN_OP(&, logic) +REF_BIN_OP(|, logic) +REF_BIN_OP(^, logic) + +#if 1 +#define CONCAT_OP_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_private<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret |= val; \ + return ret;\ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_private<_AP_W, _AP_S>& op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + if (_AP_S) { \ + ret <<= _AP_WI; ret >>= _AP_WI; \ + } \ + ret |= val << _AP_W; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_range_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + } \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_range_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (const ap_bit_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, false> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (C_TYPE op1, const ap_bit_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + 1, false> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op1, C_TYPE op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op2);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op1);\ + if (_AP_SI) { \ + val <<= _AP_W + _AP_W2; val >>= _AP_W + _AP_W2; \ + } \ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +}\ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op1);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op2);\ + int len = op2.length(); \ + val <<= len; \ + ret |= val;\ + return ret; \ +}\ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const af_range_ref<_AP_W, _AP_I, _AP_S, \ + _AP_Q, _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, \ + _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (C_TYPE op1, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q,\ + _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} + +CONCAT_OP_MIX_INT(bool, 1, false) +CONCAT_OP_MIX_INT(char, 8, true) +CONCAT_OP_MIX_INT(signed char, 8, true) +CONCAT_OP_MIX_INT(unsigned char, 8, false) +CONCAT_OP_MIX_INT(short, 16, true) +CONCAT_OP_MIX_INT(unsigned short, 16, false) +CONCAT_OP_MIX_INT(int, 32, true) +CONCAT_OP_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +CONCAT_OP_MIX_INT(long, 64, true) +CONCAT_OP_MIX_INT(unsigned long, 64, false) +# else +CONCAT_OP_MIX_INT(long, 32, true) +CONCAT_OP_MIX_INT(unsigned long, 32, false) +# endif +CONCAT_OP_MIX_INT(ap_slong, 64, true) +CONCAT_OP_MIX_INT(ap_ulong, 64, false) +#endif + +#if 1 +#define CONCAT_SHIFT_MIX_INT(C_TYPE, op) \ +template \ +INLINE ap_uint<_AP_W+_AP_W1> operator op (const ap_concat_ref<_AP_W, _AP_T, _AP_W1, _AP_T1> lhs, C_TYPE rhs) { \ + return ((ap_uint<_AP_W+_AP_W1>)lhs.get()) op ((int)rhs); \ +} + +CONCAT_SHIFT_MIX_INT(long, <<) +CONCAT_SHIFT_MIX_INT(unsigned long, <<) +CONCAT_SHIFT_MIX_INT(unsigned int, <<) +CONCAT_SHIFT_MIX_INT(ap_ulong, <<) +CONCAT_SHIFT_MIX_INT(ap_slong, <<) +CONCAT_SHIFT_MIX_INT(long, >>) +CONCAT_SHIFT_MIX_INT(unsigned long, >>) +CONCAT_SHIFT_MIX_INT(unsigned int, >>) +CONCAT_SHIFT_MIX_INT(ap_ulong, >>) +CONCAT_SHIFT_MIX_INT(ap_slong, >>) +#endif + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_private<_AP_W, _AP_S> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_private<_AP_W,_AP_S> &op) +{ + ap_private<_AP_W, _AP_S> v=op; + const std::ios_base::fmtflags basefield = out.flags() & std::ios_base::basefield; + unsigned radix = (basefield == std::ios_base::hex) ? 16 : + ((basefield == std::ios_base::oct) ? 8 : 10); + std::string str=v.toString(radix,_AP_S); + out< +INLINE std::istream& operator >> (std::istream& in, ap_private<_AP_W,_AP_S> &op) +{ + std::string str; + in >> str; + op = ap_private<_AP_W, _AP_S>(str.c_str()); + return in; + +} + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator<<(out, ap_private<_AP_W, _AP_S>(op)); +} + +template +INLINE std::istream& operator >> (std::istream& in, ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator>>(in, ap_private<_AP_W, _AP_S>(op));; +} + +template +INLINE void print(const ap_private<_AP_W,_AP_S> &op, bool fill=true ) +{ + ap_private<_AP_W, _AP_S> v=op; + uint32_t ws=v.getNumWords(); + const uint64_t *ptr=v.getRawData(); + int i=ws-1; +#if 0 + if(fill) + printf("%016llx",*(ptr+i)); + else + printf("%llx",*(ptr+i)); +#else +//match SystemC output + if(_AP_W%64 != 0) { + uint32_t offset=_AP_W%64; + uint32_t count=(offset+3)/4; + int64_t data=*(ptr+i); + if(_AP_S) + data=(data<<(64-offset))>>(64-offset); + else + count=(offset+4)/4; + while(count-->0) + printf("%llx",(data>>(count*4))&0xf); + } else { + if(_AP_S==false) + printf("0"); + printf("%016llx",*(ptr+i)); + } +#endif + for(--i;i>=0;i--) + printf("%016llx",*(ptr+i)); + printf("\n"); + +} +#endif /* #ifndef __AESL_GCC_AP_INT_H__ */ \ No newline at end of file diff --git a/hls_2018/router_03_boardstr/etc/ap_private.h b/hls_2018/router_03_boardstr/etc/ap_private.h new file mode 100755 index 0000000000000000000000000000000000000000..1a68a9e56e950d7108a3014149623c017023d809 --- /dev/null +++ b/hls_2018/router_03_boardstr/etc/ap_private.h @@ -0,0 +1,5858 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LLVM_SUPPORT_MATHEXTRAS_H +#define LLVM_SUPPORT_MATHEXTRAS_H + +#ifdef _MSC_VER +#if _MSC_VER <= 1500 +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else if +#include +#endif /* #if _MSC_VER <= 1500 */ +#else +#include +#endif /* #if _MSC_VER <= 1500 */ +#undef INLINE +#if 1 +#define INLINE inline +#else +//Enable to debug ap_int/ap_fixed +#define INLINE __attribute__((weak)) +#endif +#define AP_MAX(a,b) ((a) > (b) ? (a) : (b)) +#define AP_MIN(a,b) ((a) < (b) ? (a) : (b)) +#define AP_ABS(a) ((a)>=0 ? (a):-(a)) +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +// NOTE: The following support functions use the _32/_64 extensions instead of +// type overloading so that signed and unsigned integers can be used without +// ambiguity. + +/// Hi_32 - This function returns the high 32 bits of a 64 bit value. +INLINE uint32_t Hi_32(uint64_t Value) { + return static_cast(Value >> 32); +} + +/// Lo_32 - This function returns the low 32 bits of a 64 bit value. +INLINE uint32_t Lo_32(uint64_t Value) { + return static_cast(Value); +} + +/// ByteSwap_16 - This function returns a byte-swapped representation of the +/// 16-bit argument, Value. +INLINE uint16_t ByteSwap_16(uint16_t Value) { +#if defined(_MSC_VER) && !defined(_DEBUG) + // The DLL version of the runtime lacks these functions (bug!?), but in a + // release build they're replaced with BSWAP instructions anyway. + return (uint16_t)(_byteswap_ushort(Value)); +#else + uint16_t Hi = (uint16_t)((Value) << 8); + uint16_t Lo = (uint16_t)((Value) >> 8); + return Hi | Lo; +#endif +} + +/// ByteSwap_32 - This function returns a byte-swapped representation of the +/// 32-bit argument, Value. +INLINE uint32_t ByteSwap_32(uint32_t Value) { + uint32_t Byte0 = Value & 0x000000FF; + uint32_t Byte1 = Value & 0x0000FF00; + uint32_t Byte2 = Value & 0x00FF0000; + uint32_t Byte3 = Value & 0xFF000000; + return ((Byte0) << 24) | ((Byte1) << 8) | ((Byte2) >> 8) | ((Byte3) >> 24); +} + +/// ByteSwap_64 - This function returns a byte-swapped representation of the +/// 64-bit argument, Value. +INLINE uint64_t ByteSwap_64(uint64_t Value) { + uint64_t Hi = ByteSwap_32(uint32_t(Value)); + uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32)); + return ((Hi) << 32) | Lo; +} + +/// CountLeadingZeros_32 - this function performs the platform optimal form of +/// counting the number of zeros from the most significant bit to the first one +/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. +/// Returns 32 if the word is zero. +INLINE unsigned CountLeadingZeros_32(uint32_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clz(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (Value == 0) return 32; +#endif + Count = __builtin_clz(Value); +#else + if (Value == 0) return 32; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) { + uint32_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } +#endif + return Count; +} + +/// CountLeadingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the most significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountLeadingZeros_64(uint64_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clzll(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (!Value) return 64; +#endif + Count = __builtin_clzll(Value); +#else + if (sizeof(long) == sizeof(int64_t)) { + if (!Value) return 64; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) { + uint64_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } + } else { + // get hi portion + uint32_t Hi = Hi_32(Value); + + // if some bits in hi portion + if (Hi) { + // leading zeros in hi portion plus all bits in lo portion + Count = CountLeadingZeros_32(Hi); + } else { + // get lo portion + uint32_t Lo = Lo_32(Value); + // same as 32 bit value + Count = CountLeadingZeros_32(Lo)+32; + } + } +#endif + return Count; +} + +/// CountTrailingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the least significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountTrailingZeros_64(uint64_t Value) { +#if __GNUC__ >= 4 + return (Value != 0) ? __builtin_ctzll(Value) : 64; +#else + static const unsigned Mod67Position[] = { + 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, + 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, + 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, + 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, + 7, 48, 35, 6, 34, 33, 0 + }; + return Mod67Position[(uint64_t)(-(int64_t)Value & (int64_t)Value) % 67]; +#endif +} + +/// CountPopulation_64 - this function counts the number of set bits in a value, +/// (64 bit edition.) +INLINE unsigned CountPopulation_64(uint64_t Value) { +#if __GNUC__ >= 4 + return __builtin_popcountll(Value); +#else + uint64_t v = Value - (((Value) >> 1) & 0x5555555555555555ULL); + v = (v & 0x3333333333333333ULL) + (((v) >> 2) & 0x3333333333333333ULL); + v = (v + ((v) >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); +#endif +} + +#endif // LLVM_SUPPORT_MATHEXTRAS_H + + +#ifndef AP_PRIVATE_H +#define AP_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AESL_std { + template + DataType INLINE min(DataType a, DataType b) { + // if (a >= b) return b; + // else return a; + return (a>=b) ? b : a; + } + + template + DataType INLINE max(DataType a, DataType b) { + // if (a >= b) return a; + // else return b; + return (a>=b) ? a : b; + } +} +enum ap_q_mode { + AP_RND, // rounding to plus infinity + AP_RND_ZERO,// rounding to zero + AP_RND_MIN_INF,// rounding to minus infinity + AP_RND_INF,// rounding to infinity + AP_RND_CONV, // convergent rounding + AP_TRN, // truncation + AP_TRN_ZERO // truncation to zero + +}; +enum ap_o_mode { + AP_SAT, // saturation + AP_SAT_ZERO, // saturation to zero + AP_SAT_SYM, // symmetrical saturation + AP_WRAP, // wrap-around (*) + AP_WRAP_SM // sign magnitude wrap-around (*) +}; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; + +template struct ap_range_ref; +template struct ap_bit_ref; +template struct ap_concat_ref; +static bool InvalidDigit(const char* str, unsigned len, unsigned start, unsigned radix) { + unsigned i; + for (i = start; i < len; ++i) + if ((radix == 2 && (str[i] == '0' || str[i] == '1')) || + (radix == 8 && str[i] >= '0' && str[i] <= '7') || + (radix == 10 && str[i] >= '0' && str[i] <= '9') || + (radix == 16 && ((str[i] >= '0' && str[i] <= '9') || + (str[i] >= 'a' && str[i] <= 'f') || + (str[i] >= 'A' && str[i] <= 'F')))) + continue; + else + return true; + return false; +} + +static void ap_parse_sign(const char* str, uint32_t &base, bool &neg) { + if (str[0] == '+' || str[0] == '-') base = 1; + if (str[0] == '-') neg = true; + else neg = false; + return; +} + +static void ap_parse_prefix(const char* str, uint32_t &offset, uint32_t &radix) { + if (str[0] == '0') { + switch (str[1]) { + case 'b': + case 'B': offset = 2; radix = 2; break; + case 'x': + case 'X': offset = 2; radix = 16; break; + case 'd': + case 'D': offset = 2; radix = 10; break; + case 'o': + case 'O': offset = 2; radix = 8; break; + default: break; + } + } + if (offset == 0) + for (int i=0, len = strlen(str); i= 'a') || (str[i] <= 'F' && str[i] >= 'A')) { + radix = 16; + break; + } + return; +} + +/// sub_1 - This function subtracts a single "digit" (64-bit word), y, from +/// the multi-digit integer array, x[], propagating the borrowed 1 value until +/// no further borrowing is neeeded or it runs out of "digits" in x. The result +/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. +/// In other words, if y > x then this function returns 1, otherwise 0. +/// @returns the borrow out of the subtraction +static bool sub_1(uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + uint64_t __X = x[i]; + x[i] -= y; + if (y > __X) + y = 1; // We have to "borrow 1" from next "digit" + else { + y = 0; // No need to borrow + break; // Remaining digits are unchanged so exit early + } + } + return (y != 0); +} + + /// This enumeration just provides for internal constants used in this + /// translation unit. + enum { + MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MIN_INT_BITS + MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MAX_INT_BITS + }; + + /// A utility function for allocating memory and checking for allocation + /// failure. The content is not zeroed. + static uint64_t* getMemory(uint32_t numWords) { + return (uint64_t*) malloc(numWords*sizeof(uint64_t)); + } + + //===----------------------------------------------------------------------===// + // ap_private Class + //===----------------------------------------------------------------------===// + + /// ap_private - This class represents arbitrary precision constant integral values. + /// It is a functional replacement for common case unsigned integer type like + /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width + /// integer sizes and large integer value types such as 3-bits, 15-bits, or more + /// than 64-bits of precision. ap_private provides a variety of arithmetic operators + /// and methods to manipulate integer values of any bit-width. It supports both + /// the typical integer arithmetic and comparison operations as well as bitwise + /// manipulation. + /// + /// The class has several invariants worth noting: + /// * All bit, byte, and word positions are zero-based. + /// * Once the bit width is set, it doesn't change except by the Truncate, + /// SignExtend, or ZeroExtend operations. + /// * All binary operators must be on ap_private instances of the same bit width. + /// Attempting to use these operators on instances with different bit + /// widths will yield an assertion. + /// * The value is stored canonically as an unsigned value. For operations + /// where it makes a difference, there are both signed and unsigned variants + /// of the operation. For example, sdiv and udiv. However, because the bit + /// widths must be the same, operations such as Mul and Add produce the same + /// results regardless of whether the values are interpreted as signed or + /// not. + /// * In general, the class tries to follow the style of computation that LLVM + /// uses in its IR. This simplifies its use for LLVM. + /// + /// @brief Class for arbitrary precision integers. + template class ap_private; + namespace ap_private_ops{ + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + } + +#if defined(_MSC_VER) +# if _MSC_VER < 1400 && !defined(for) +# define for if(0);else for +# endif + typedef unsigned __int64 ap_ulong; + typedef signed __int64 ap_slong; +#else + typedef unsigned long long ap_ulong; + typedef signed long long ap_slong; +#endif + template struct retval { + }; + template<> struct retval { + typedef ap_slong Type; + }; + template<> struct retval { + typedef ap_ulong Type; + }; + + template + class ap_private { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template friend struct ap_fixed_base; + ///return type of variety of operations + //---------------------------------------------------------- + template + struct RType { + enum { + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024): for" + " synthesis: please define macro AP_INT_TYPE_EXT(N)" + " to extend the valid range.\n", _AP_W); + } else +#endif + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sint<%d>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + enum { BitWidth = _AP_W }; + /// This union is used to store the integer value. When the + /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal. + + /// This enum is used to hold the constants we needed for ap_private. + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t pVal[_AP_N]; ///< Used to store the >64 bits integer value. + + /// This enum is used to hold the constants we needed for ap_private. + enum { + APINT_BITS_PER_WORD = sizeof(uint64_t) * 8, ///< Bits in a word + APINT_WORD_SIZE = sizeof(uint64_t) ///< Byte size of a word + }; + + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + + /// This constructor is used only internally for speed of construction of + /// temporaries. It is unsafe for general use so it is not public. + /* Constructors */ + + ap_private(const char* val) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 16; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + ap_private(const char* val, int rd) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + // uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + // ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + ap_private ap_private_val(strp , strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + /// Note that numWords can be smaller or larger than the corresponding bit + /// width but any extraneous bits will be dropped. + /// @param numBits the bit width of the constructed ap_private + /// @param numWords the number of words in bigVal + /// @param bigVal a sequence of words to form the initial value of the ap_private + /// @brief Construct an ap_private of numBits width, initialized as bigVal[]. + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(0) { + assert(bigVal && "Null pointer detected!"); + { + // Get memory, cleared to 0 + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Calculate the number of words to copy + uint32_t words = AESL_std::min(numWords, _AP_N); + // Copy the words from bigVal to pVal + memcpy(pVal, bigVal, words * APINT_WORD_SIZE); + if (words >= _AP_W) + clearUnusedBits(); + // Make sure unused high bits are cleared + } + } + + /// This constructor interprets Val as a string in the given radix. The + /// interpretation stops when the first charater that is not suitable for the + /// radix is encountered. Acceptable radix values are 2, 8, 10 and 16. It is + /// an error for the value implied by the string to require more bits than + /// numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param val the string to be interpreted + /// @param radix the radix of Val to use for the intepretation + /// @brief Construct an ap_private from a string representation. + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0) { + assert(!val.empty() && "The input string is empty."); + const char *c_str = val.c_str(); + fromString(c_str+base+offset, val.size()-base-offset, radix); + } + + /// This constructor interprets the slen characters starting at StrStart as + /// a string in the given radix. The interpretation stops when the first + /// character that is not suitable for the radix is encountered. Acceptable + /// radix values are 2, 8, 10 and 16. It is an error for the value implied by + /// the string to require more bits than numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param strStart the start of the string to be interpreted + /// @param slen the maximum number of characters to interpret + /// @param radix the radix to use for the conversion + /// @brief Construct an ap_private from a string representation. + /// This method does not consider whether it is negative or not. + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0) { + fromString(strStart+base+offset, slen-base-offset, radix); + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) { + *this = ((uint64_t)(bool)ref); + report(); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + report(); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = (uint64_t)(bool)val; + report(); + } + + /// Simply makes *this a copy of that. + /// @brief Copy Constructor. + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (const_cast& >(that)); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (that); + } + + template + explicit ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that): VAL(0) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (that.isNegative()) { + pVal[0] = that.VAL|that_sign_ext_mask; + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); + } else { + pVal[0] = that.VAL; + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); + } + clearUnusedBits(); + } + + ap_private(const ap_private& that): VAL(0) { + memcpy(pVal, that.pVal, _AP_N * APINT_WORD_SIZE); + clearUnusedBits(); + } + + /// @brief Destructor. + virtual ~ap_private() {} + + /// Default constructor that creates an uninitialized ap_private. This is useful + /// for object deserialization (pair this with the static method Read). + ap_private(){memset(pVal, 0, sizeof(uint64_t)*(_AP_N));} + + ap_private(uint64_t* val, uint32_t bits=_AP_W) {assert(0);} + ap_private(const uint64_t *const val, uint32_t bits) {assert(0);} + + /// @name Constructors + /// @{ + /// If isSigned is true then val is treated as if it were a signed value + /// (i.e. as an int64_t) and the appropriate sign extension to the bit width + /// will be done. Otherwise, no sign extension occurs (high order bits beyond + /// the range of val are zero filled). + /// @param numBits the bit width of the constructed ap_private + /// @param val the initial value of the ap_private + /// @param isSigned how to treat signedness of val + /// @brief Create a new ap_private of numBits width, initialized as val. +#define CTOR(TYPE, SIGNED) \ + ap_private(TYPE val, bool isSigned=SIGNED) { \ + pVal[0] = val; \ + if (isSigned && int64_t(pVal[0]) < 0) { \ + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); \ + } else { \ + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); \ + } \ + clearUnusedBits(); \ + } +#if 1 + CTOR(int, true) + CTOR(bool, false) + CTOR(signed char, true) + CTOR(unsigned char, false) + CTOR(short, true) + CTOR(unsigned short, false) + CTOR(unsigned int, false) + CTOR(long, true) + CTOR(unsigned long, false) + CTOR(unsigned long long, false) + CTOR(long long, true) + CTOR(float, false) + CTOR(double, false) +#undef CTOR +#else + CTOR(uint64_t) +#undef CTOR +#endif + + + /// @returns true if the number of bits <= 64, false otherwise. + /// @brief Determine if this ap_private just has one word to store value. + INLINE bool isSingleWord() const { + return false; + } + + /// @returns the word position for the specified bit position. + /// @brief Determine which word a bit is in. + static uint32_t whichWord(uint32_t bitPosition) { + // return bitPosition / APINT_BITS_PER_WORD; + return (bitPosition) >> 6; + } + + /// @returns the bit position in a word for the specified bit position + /// in the ap_private. + /// @brief Determine which bit in a word a bit is in. + static uint32_t whichBit(uint32_t bitPosition) { + // return bitPosition % APINT_BITS_PER_WORD; + return bitPosition & 0x3f; + } + + /// bit at a specific bit position. This is used to mask the bit in the + /// corresponding word. + /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set + /// @brief Get a single bit mask. + static uint64_t maskBit(uint32_t bitPosition) { + return 1ULL << (whichBit(bitPosition)); + } + + /// @returns the corresponding word for the specified bit position. + /// @brief Get the word corresponding to a bit position + INLINE uint64_t getWord(uint32_t bitPosition) const { + return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; + } + + /// This method is used internally to clear the to "N" bits in the high order + /// word that are not used by the ap_private. This is needed after the most + /// significant word is assigned a value to ensure that those bits are + /// zero'd out. + /// @brief Clear unused high order bits + INLINE void clearUnusedBits(void) { + pVal[_AP_N-1] = _AP_S ? ((((int64_t)pVal[_AP_N-1])<<(excess_bits))>> excess_bits) : (excess_bits ? ((pVal[_AP_N-1])<<(excess_bits))>>(excess_bits) : pVal[_AP_N-1]); + } + + INLINE void clearUnusedBitsToZero(void) { + pVal[_AP_N-1] &= mask; + } + + INLINE void clearUnusedBitsToOne(void) { + pVal[_AP_N-1] |= mask; + } + + /// This is used by the constructors that take string arguments. + /// @brief Convert a char array into an ap_private + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix) ; + + INLINE ap_private read() volatile { + return *this; + } + + INLINE void write(const ap_private& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + operator ValType() const { + return getVal(); + } + + INLINE ValType getVal() const{ + return *pVal; + } + + INLINE int to_int() const { + return int(*this); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + INLINE ap_private& set(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] |= maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + INLINE void set() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] = ~0ULL; + clearUnusedBits(); + } + + //Get the value of ith bit + INLINE bool get (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + /// Set the given bit to 0 whose position is given as "bitPosition". + /// @brief Set a given bit to 0. + ap_private& clear(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + /// @brief Set every bit to 0. + void clear() { + memset(pVal, 0, _AP_N * APINT_WORD_SIZE); + } + + /// @brief Toggle every bit to its opposite value. + ap_private& flip() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] ^= ~0ULL; + clearUnusedBits(); + return *this; + } + + /// Toggle a given bit to its opposite value whose position is given + /// as "bitPosition". + /// @brief Toggles a given bit to its opposite value. + ap_private& flip(uint32_t bitPosition) { + assert(bitPosition < BitWidth && "Out of the bit-width range!"); + if ((*this)[bitPosition]) clear(bitPosition); + else set(bitPosition); + return *this; + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + ap_private getLoBits(uint32_t numBits) const { + return ap_private_ops::lshr(ap_private_ops::shl(*this, _AP_W - numBits), + _AP_W - numBits); + } + + ap_private getHiBits(uint32_t numBits) const { + return ap_private_ops::lshr(*this, _AP_W - numBits); + } + + //Binary Arithmetic + //----------------------------------------------------------- + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + ///Arithmetic assign + //------------------------------------------------------------- + +#define OP_BIN_LOGIC_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { \ + uint32_t numWords = AESL_std::min(_AP_N, _AP_N1); \ + uint32_t i; \ + for (i = 0; i < numWords; ++i) \ + pVal[i] Sym RHS.pVal[i]; \ + if (_AP_N1 < _AP_N) { \ + uint64_t ext = RHS.isNegative()?~0ULL:0; \ + for (;i<_AP_N; i++) \ + pVal[i] Sym ext; \ + } \ + clearUnusedBits(); \ + return *this; \ + } + + OP_BIN_LOGIC_ASSIGN_AP(&=); + OP_BIN_LOGIC_ASSIGN_AP(|=); + OP_BIN_LOGIC_ASSIGN_AP(^=); +#undef OP_BIN_LOGIC_ASSIGN_AP + + /// Adds the RHS APint to this ap_private. + /// @returns this, after addition of RHS. + /// @brief Addition assignment operator. + template + INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + add(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + sub(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + ap_private& operator*=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) { + // 0 * X ===> 0 + return *this; + } + + ap_private dupRHS = RHS; + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = dupRHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + clear(); + return *this; + } + + // Allocate space for the result + uint32_t destWords = rhsWords + lhsWords; + uint64_t *dest = getMemory(destWords); + + // Perform the long multiply + mul(dest, pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + // Copy result back into *this + clear(); + uint32_t wordsToCopy = destWords >= _AP_N ? _AP_N : destWords; + + memcpy(pVal, dest, wordsToCopy* APINT_WORD_SIZE); + + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0ULL; + for (int i=wordsToCopy; i<_AP_N; i++) + pVal[i]=ext; + clearUnusedBits(); + // delete dest array and return + free(dest); + return *this; + } + +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP(/) + OP_ASSIGN_AP(%) +#undef OP_ASSIGN_AP + +#define OP_BIN_LOGIC_AP(Sym) \ + template \ + INLINE \ + typename RType<_AP_W1, _AP_S1>::logic \ + operator Sym (const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { \ + enum { numWords = (RType<_AP_W1, _AP_S1>::logic_w +APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; \ + typename RType<_AP_W1, _AP_S1>::logic Result; \ + uint64_t *val = Result.pVal; \ + uint32_t i; \ + uint32_t min_N = std::min(_AP_N, _AP_N1); \ + uint32_t max_N = std::max(_AP_N, _AP_N1); \ + for (i = 0; i < min_N; ++i) \ + val[i] = pVal[i] Sym RHS.pVal[i]; \ + if (numWords > i) { \ + const uint64_t* tmpVal = (_AP_N>_AP_N1 ? pVal : RHS.pVal)+i; \ + uint64_t ext = ((_AP_N<_AP_N1 && isNegative() )||(_AP_N1 < _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + for (;i i) { \ + uint64_t ext2 = ((_AP_N>_AP_N1 && isNegative() )||(_AP_N1 > _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + val[i] = ext Sym ext2; \ + } \ + } \ + Result.clearUnusedBits(); \ + return Result; \ + } + + OP_BIN_LOGIC_AP(|); + OP_BIN_LOGIC_AP(&); + OP_BIN_LOGIC_AP(^); + +#undef OP_BIN_LOGIC_AP + + template + INLINE typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + // assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + typename RType<_AP_W1,_AP_S1>::plus Result; + bool carry = add(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::plus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::plus_w + 63) / 64> std::max(_AP_W, _AP_W1) ) + Result.pVal[(RType<_AP_W1,_AP_S1>::plus_w + 63)/64 - 1] = carry; + Result.clearUnusedBits(); + return Result; + } + + template + INLINE typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + typename RType<_AP_W1,_AP_S1>::minus Result; + bool borrow = sub(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::minus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::minus_w + 63) / 64 > AESL_std::max(_AP_W, _AP_W1) ) { + Result.pVal[(RType<_AP_W1,_AP_S1>::minus_w+63)/64 - 1] = borrow; + } + Result.clearUnusedBits(); + return Result; + } + + template + typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) + // 0 * X ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + } + + //extend size to avoid result loss + typename RType<_AP_W1, _AP_S1>::mult dupLHS = *this; + typename RType<_AP_W1, _AP_S1>::mult dupRHS = RHS; + lhsBits = dupLHS.getActiveBits(); + lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + rhsBits = dupRHS.getActiveBits(); + rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + + // Allocate space for the result + enum { destWords =(RType<_AP_W1, _AP_S1>::mult_w+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + int destw = destWords; + typename RType<_AP_W1, _AP_S1>::mult Result; + uint64_t *dest = Result.pVal; + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0; + + // Perform the long multiply + mul(dest, dupLHS.pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + for (int i=lhsWords+rhsWords; i + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=*this; + ap_private rhs= op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod(_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + template + INLINE ap_private + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private + operator << (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=length()); + if(overflow) + r.clear(); + else + r = ap_private(r.shl(sh)); + return r; + } + + template + INLINE ap_private + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private + operator >> (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + INLINE ap_private& operator Sym##=(unsigned int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } + OP_ASSIGN_AP(>>) + OP_ASSIGN_AP(<<) +#undef OP_ASSIGN_AP + ///Comparisons + //----------------------------------------------------------------- + bool operator==(const ap_private& RHS) const { + // Get some facts about the number of bits used in the two operands. + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If the number of bits isn't the same, they aren't equal + if (n1 != n2) + return false; + + // If the number of bits fits in a word, we only need to compare the low word. + if (n1 <= APINT_BITS_PER_WORD) + return pVal[0] == RHS.pVal[0]; + + // Otherwise, compare everything + for (int i = whichWord(n1 - 1); i >= 0; --i) + if (pVal[i] != RHS.pVal[i]) + return false; + return true; + } + + template + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S|_AP_S2> lhs(*this); + ap_private<_AP_MAX_W, _AP_S|_AP_S2> rhs(op); + return lhs==rhs; + } + + bool operator==(uint64_t Val) const { + uint32_t n = getActiveBits(); + if (n <= APINT_BITS_PER_WORD) + return pVal[0] == Val; + else + return false; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2>& op) const { + return !(*this==op); + } + + template + INLINE bool operator!=(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !((*this) == RHS); + } + + INLINE bool operator!=(uint64_t Val) const { + return !((*this) == Val); + } + + + template + INLINE bool operator <= (const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this>op); + } + + INLINE bool operator <(const ap_private& op) const { + return _AP_S ? slt(op):ult(op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.sgt(rhs):lhs.ugt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + } + + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE bool operator [](uint32_t bitPosition) const { + return (maskBit(bitPosition) & (pVal[whichWord(bitPosition)])) != 0; + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + INLINE ap_private<_AP_W,false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + /// @} + /// @name Value Tests + /// @{ + /// This tests the high bit of this ap_private to determine if it is set. + /// @returns true if this ap_private is negative, false otherwise + /// @brief Determine sign of this ap_private. + INLINE bool isNegative() const { + //just for get rid of warnings + enum {shift = (_AP_W-APINT_BITS_PER_WORD*(_AP_N-1)-1)}; + static const uint64_t mask = 1ULL << (shift); + return _AP_S && (pVal[_AP_N-1]&mask); + } + + /// This tests the high bit of the ap_private to determine if it is unset. + /// @brief Determine if this ap_private Value is positive (not negative). + INLINE bool isPositive() const { + return !isNegative(); + } + + /// This tests if the value of this ap_private is strictly positive (> 0). + /// @returns true if this ap_private is Positive and not zero. + /// @brief Determine if this ap_private Value is strictly positive. + INLINE bool isStrictlyPositive() const { + return isPositive() && (*this) != 0; + } + + /// This checks to see if the value has all bits of the ap_private are set or not. + /// @brief Determine if all bits are set + INLINE bool isAllOnesValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest unsigned value. + INLINE bool isMaxValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest signed value. + INLINE bool isMaxSignedValue() const { + return BitWidth == 1 ? VAL == 0 : + !isNegative() && countPopulation() == _AP_W - 1; + } + + /// This checks to see if the value of this ap_private is the minimum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest unsigned value. + INLINE bool isMinValue() const { + return countPopulation() == 0; + } + + /// This checks to see if the value of this ap_private is the minimum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest signed value. + INLINE bool isMinSignedValue() const { + return BitWidth == 1 ? VAL == 1 : + isNegative() && countPopulation() == 1; + } + + /// This function returns a pointer to the internal storage of the ap_private. + /// This is useful for writing out the ap_private in binary form without any + /// conversions. + INLINE const uint64_t* getRawData() const { + if (isSingleWord()) + return &VAL; + return &pVal[0]; + } + + ap_private sqrt() const; + + /// @} + /// @Assignment Operators + /// @{ + /// @returns *this after assignment of RHS. + /// @brief Copy assignment operator. + INLINE ap_private& operator=(const ap_private& RHS) { + if (this != &RHS) + memcpy(pVal, RHS.pVal, _AP_N * APINT_WORD_SIZE); + return *this; + } + INLINE ap_private& operator=(const volatile ap_private& RHS) { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + /// @} + /// @name Unary Operators + /// @{ + /// @returns a new ap_private value representing *this incremented by one + /// @brief Postfix increment operator. + INLINE const ap_private operator++(int) { + ap_private API(*this); + ++(*this); + return API; + } + + /// @returns *this incremented by one + /// @brief Prefix increment operator. + INLINE ap_private& operator++() { + add_1(pVal, pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// @returns a new ap_private representing *this decremented by one. + /// @brief Postfix decrement operator. + INLINE const ap_private operator--(int) { + ap_private API(*this); + --(*this); + return API; + } + + /// @returns *this decremented by one. + /// @brief Prefix decrement operator. + INLINE ap_private& operator--() { + sub_1(pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// Performs a bitwise complement operation on this ap_private. + /// @returns an ap_private that is the bitwise complement of *this + /// @brief Unary bitwise complement operator. + INLINE ap_private operator~() const { + ap_private Result(*this); + Result.flip(); + return Result; + } + + /// Negates *this using two's complement logic. + /// @returns An ap_private value representing the negation of *this. + /// @brief Unary negation operator + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + /// Performs logical negation operation on this ap_private. + /// @returns true if *this is zero, false otherwise. + /// @brief Logical negation operator. + INLINE bool operator !() const { + for (uint32_t i = 0; i < _AP_N; ++i) + if (pVal[i]) + return false; + return true; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator&(RHS); + } + template + INLINE ap_private Or(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator|(RHS); + } + template + ap_private Xor(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator^(RHS); + } + + ap_private Mul(const ap_private& RHS) const { + ap_private Result(*this); + Result *= RHS; + return Result; + } + + ap_private Add(const ap_private& RHS) const { + ap_private Result(0); + bool carry = add(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + ap_private Sub(const ap_private& RHS) const { + ap_private Result(0); + sub(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + /// Arithmetic right-shift this ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + ap_private ashr(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + // Handle a degenerate case + if (shiftAmt == 0) + return *this; + + // Handle single word shifts with built-in ashr + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(/*BitWidth, 0*/); // undefined + else { + uint32_t SignBit = APINT_BITS_PER_WORD - BitWidth; + return ap_private(/*BitWidth,*/ + (((int64_t(VAL) << (SignBit)) >> (SignBit)) >> (shiftAmt))); + } + } + + // If all the bits were shifted out, the result is, technically, undefined. + // We return -1 if it was negative, 0 otherwise. We check this early to avoid + // issues in the algorithm below. + if (shiftAmt == BitWidth) { + if (isNegative()) + return ap_private(-1); + else + return ap_private(0); + } + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // Compute some values needed by the following shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; // bits to shift per word + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; // word offset for shift + uint32_t breakWord = _AP_N - 1 - offset; // last word affected + uint32_t bitsInWord = whichBit(BitWidth); // how many bits in last word? + if (bitsInWord == 0) + bitsInWord = APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + // Move the words containing significant bits + for (uint32_t i = 0; i <= breakWord; ++i) + val[i] = pVal[i+offset]; // move whole word + + // Adjust the top significant word for sign bit fill, if negative + if (isNegative()) + if (bitsInWord < APINT_BITS_PER_WORD) + val[breakWord] |= ~0ULL << (bitsInWord); // set high bits + } else { + // Shift the low order words + for (uint32_t i = 0; i < breakWord; ++i) { + // This combines the shifted corresponding word with the low bits from + // the next word (shifted into this word's high bits). + val[i] = ((pVal[i+offset]) >> (wordShift)); + val[i] |= ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + } + + // Shift the break word. In this case there are no bits from the next word + // to include in this word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Deal with sign extenstion in the break word, and possibly the word before + // it. + if (isNegative()) { + if (wordShift > bitsInWord) { + if (breakWord > 0) + val[breakWord-1] |= + ~0ULL << (APINT_BITS_PER_WORD - (wordShift - bitsInWord)); + val[breakWord] |= ~0ULL; + } else + val[breakWord] |= (~0ULL << (bitsInWord - wordShift)); + } + } + + // Remaining words are 0 or -1, just assign them. + uint64_t fillValue = (isNegative() ? ~0ULL : 0); + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = fillValue; + Retval.clearUnusedBits(); + return Retval; + } + + /// Logical right-shift this ap_private by shiftAmt. + /// @brief Logical right-shift function. + ap_private lshr(uint32_t shiftAmt) const { + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); + else + return ap_private((this->VAL) >> (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids + // issues with shifting byt he size of the integer type, which produces + // undefined results in the code below. This is also an optimization. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // If we are shifting less than a word, compute the shift with a simple carry + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (int i = _AP_N-1; i >= 0; --i) { + val[i] = ((pVal[i]) >> (shiftAmt)) | carry; + carry = (pVal[i]) << (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < _AP_N - offset; ++i) + val[i] = pVal[i+offset]; + for (uint32_t i = _AP_N-offset; i < _AP_N; i++) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + // Shift the low order words + uint32_t breakWord = _AP_N - offset -1; + for (uint32_t i = 0; i < breakWord; ++i) + val[i] = ((pVal[i+offset]) >> (wordShift)) | + ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + // Shift the break word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Remaining words are 0 + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + /// Left-shift this ap_private by shiftAmt. + /// @brief Left-shift function. + ap_private shl(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); // avoid undefined shift results + return ap_private((VAL) << (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids a + // lshr by the words size in the loop below which can produce incorrect + // results. It also avoids the expensive computation below for a common case. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t* val = Retval.pVal; + // If we are shifting less than a word, do it the easy way + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (uint32_t i = 0; i < _AP_N; i++) { + val[i] = ((pVal[i]) << (shiftAmt)) | carry; + carry = (pVal[i]) >> (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < offset; i++) + val[i] = 0; + for (uint32_t i = offset; i < _AP_N; i++) + val[i] = pVal[i-offset]; + Retval.clearUnusedBits(); + return Retval; + } + + // Copy whole words from this to Result. + uint32_t i = _AP_N - 1; + for (; i > offset; --i) + val[i] = (pVal[i-offset]) << (wordShift) | + (pVal[i-offset-1]) >> (APINT_BITS_PER_WORD - wordShift); + val[offset] = (pVal[0]) << (wordShift); + for (i = 0; i < offset; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + INLINE ap_private rotl(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + hi.shl(rotateAmt); + lo.lshr(BitWidth - rotateAmt); + return hi | lo; + } + + INLINE ap_private rotr(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + lo.lshr(rotateAmt); + hi.shl(BitWidth - rotateAmt); + return hi | lo; + } + + /// Perform an unsigned divide operation on this ap_private by RHS. Both this and + /// RHS are treated as unsigned quantities for purposes of this division. + /// @returns a new ap_private value containing the division result + /// @brief Unsigned division operation. + ap_private udiv(const ap_private& RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + + // First, deal with the easy case + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Divide by zero?"); + return ap_private(VAL / RHS.VAL); + } + + // Get some facts about the LHS and RHS number of bits and words + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Divided by zero???"); + uint32_t lhsBits = this->getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Deal with some degenerate cases + if (!lhsWords) + // 0 / X ===> 0 + return ap_private(0); + else if (lhsWords < rhsWords || this->ult(RHS)) { + // X / Y ===> 0, iff X < Y + return ap_private(0); + } else if (*this == RHS) { + // X / X ===> 1 + return ap_private(1); + } else if (lhsWords == 1 && rhsWords == 1) { + // All high words are zero, just use native divide + return ap_private(this->pVal[0] / RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Quotient(0); // to hold result. + divide(*this, lhsWords, RHS, rhsWords, &Quotient, (ap_private*)0); + return Quotient; + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(const ap_private& RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Perform an unsigned remainder operation on this ap_private with RHS being the + /// divisor. Both this and RHS are treated as unsigned quantities for purposes + /// of this operation. Note that this is a true remainder operation and not + /// a modulo operation because the sign follows the sign of the dividend + /// which is *this. + /// @returns a new ap_private value containing the remainder result + /// @brief Unsigned remainder operation. + ap_private urem(const ap_private& RHS) const { + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Remainder by zero?"); + return ap_private(VAL % RHS.VAL); + } + + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Get some facts about the RHS + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, rhsWords, (ap_private*)(0), &Remainder); + return Remainder; + } + + ap_private urem(uint64_t RHS) const { + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + // Get some facts about the RHS + uint32_t rhsBits = 64 - CountLeadingZeros_64(RHS); // RHS.getActiveBits(); + uint32_t rhsWords = 1;//!rhsBits ? 0 : (ap_private<_AP_W, _AP_S, _AP_N>::whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, (ap_private*)(0), &Remainder); + return Remainder; + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(const ap_private& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + /// Sometimes it is convenient to divide two ap_private values and obtain both + /// the quotient and remainder. This function does both operations in the + /// same computation making it a little more efficient. + /// @brief Dual division/remainder interface. + static void udivrem(const ap_private& LHS, const ap_private& RHS, ap_private &Quotient, ap_private& Remainder) { + // Get some size facts about the dividend and divisor + uint32_t lhsBits = LHS.getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (ap_private::whichWord(lhsBits - 1) + 1); + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (ap_private::whichWord(rhsBits - 1) + 1); + + // Check the degenerate cases + if (lhsWords == 0) { + Quotient = 0; // 0 / Y ===> 0 + Remainder = 0; // 0 % Y ===> 0 + return; + } + + if (lhsWords < rhsWords || LHS.ult(RHS)) { + Quotient = 0; // X / Y ===> 0, iff X < Y + Remainder = LHS; // X % Y ===> X, iff X < Y + return; + } + + if (LHS == RHS) { + Quotient = 1; // X / X ===> 1 + Remainder = 0; // X % X ===> 0; + return; + } + + if (lhsWords == 1 && rhsWords == 1) { + // There is only one word to consider so use the native versions. + if (LHS.isSingleWord()) { + Quotient = ap_private(LHS.VAL / RHS.VAL); + Remainder = ap_private(LHS.VAL % RHS.VAL); + } else { + Quotient = ap_private(LHS.pVal[0] / RHS.pVal[0]); + Remainder = ap_private(LHS.pVal[0] % RHS.pVal[0]); + } + return; + } + + // Okay, lets do it the long way + divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder); + } + + static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + /// Compares this ap_private with RHS for the validity of the equality + /// relationship. + /// @returns true if *this == Val + /// @brief Equality comparison. + template + INLINE bool eq(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return (*this) == RHS; + } + + /// Compares this ap_private with RHS for the validity of the inequality + /// relationship. + /// @returns true if *this != Val + /// @brief Inequality comparison + template + INLINE bool ne(const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template + INLINE bool ult(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS.pVal[0]; + + // Otherwise, compare all words + uint32_t topWord = whichWord(AESL_std::max(n1,n2)-1); + for (int i = topWord; i >= 0; --i) { + if (pVal[i] > RHS.pVal[i]) + return false; + if (pVal[i] < RHS.pVal[i]) + return true; + } + return false; + } + + INLINE bool ult(uint64_t RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = 64 - CountLeadingZeros_64(RHS); //RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS; + assert(0); + } + + template + INLINE bool slt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + ap_private lhs(*this); + ap_private<_AP_W, _AP_S1, _AP_N> rhs(RHS); + bool lhsNeg = isNegative(); + bool rhsNeg = rhs.isNegative(); + if (lhsNeg) { + // Sign bit is set so perform two's complement to make it positive + lhs.flip(); + lhs++; + } + if (rhsNeg) { + // Sign bit is set so perform two's complement to make it positive + rhs.flip(); + rhs++; + } + + // Now we have unsigned values to compare so do the comparison if necessary + // based on the negativeness of the values. + if (lhsNeg) + if (rhsNeg) + return lhs.ugt(rhs); + else + return true; + else if (rhsNeg) + return false; + else + return lhs.ult(rhs); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template + INLINE bool ule(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template + INLINE bool sle(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template + INLINE bool ugt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template + INLINE bool sgt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template + INLINE bool uge(const ap_private<_AP_W, _AP_S, _AP_N>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template + INLINE bool sge(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS); + } + + template + void cpTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 > BitWidth && "Invalid ap_private Truncate request"); + assert(_AP_W1 >= MIN_INT_BITS && "Can't truncate to 0 bits"); + memcpy(pVal, that.pVal, _AP_N*APINT_WORD_SIZE); + } + + // Sign extend to a new width. + template + void cpSext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private SignExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + // If the sign bit isn't set, this is the same as zext. + if (!that.isNegative()) { + cpZext(that); + return; + } + + // The sign bit is set. First, get some facts + enum { wordBits = _AP_W1 % APINT_BITS_PER_WORD}; + + // Mask the high order word appropriately + if (_AP_N1 == _AP_N) { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + if (_AP_N1 == 1) { + assert(0); + } else { + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + return; + } + } + + if (_AP_N1 == 1) { + assert(0);// newVal[0] = VAL | mask; + } else { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + } + for (uint32_t i=_AP_N1; i < _AP_N-1; i++) + pVal[i] = ~0ULL; + pVal[_AP_N-1] = ~0ULL; + clearUnusedBits(); + return; + } + + // Zero extend to a new width. + template + void cpZext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private ZeroExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + uint32_t wordsAfter = _AP_N; + if (wordsAfter==1) { + assert(0); // return ap_private<_AP_W1, _AP_S, _AP_N1> (_AP_W1, VAL, _AP_S); + } else { + if (_AP_N1 == 1) { + assert(0); + // newVal[0] = VAL; + } else { + uint32_t i = 0; + for (; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + for (; i < _AP_N; ++i) + pVal[i] = 0; + } + } + clearUnusedBits(); + } + + template + void cpZextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpZext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i]=that.pVal[i]; + clearUnusedBits(); + } + } + + template + void cpSextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpSext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i] = that.pVal[i]; + clearUnusedBits(); + } + } + + /// @name Value Characterization Functions + /// @{ + + /// @returns the total number of bits. + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + /// Here one word's bitwidth equals to that of uint64_t. + /// @returns the number of words to hold the integer value of this ap_private. + /// @brief Get the number of words. + INLINE uint32_t getNumWords() const { + return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; + } + + /// This function returns the number of active bits which is defined as the + /// bit width minus the number of leading zeros. This is used in several + /// computations to see how "wide" the value is. + /// @brief Compute the number of active bits in the value + INLINE uint32_t getActiveBits() const { + uint32_t bits=BitWidth - countLeadingZeros(); + return bits?bits:1; + } + + + /// This method attempts to return the value of this ap_private as a zero extended + /// uint64_t. The bitwidth must be <= 64 or the value must fit within a + /// uint64_t. Otherwise an assertion will result. + /// @brief Get zero extended value + INLINE uint64_t getZExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for uint64_t"); + return *pVal; + } + + /// This method attempts to return the value of this ap_private as a sign extended + /// int64_t. The bit width must be <= 64 or the value must fit within an + /// int64_t. Otherwise an assertion will result. + /// @brief Get sign extended value + INLINE int64_t getSExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for int64_t"); + return int64_t(pVal[0]); + } + + /// This method determines how many bits are required to hold the ap_private + /// equivalent of the string given by \p str of length \p slen. + /// @brief Get bits required for string value. + static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix); + + /// countLeadingZeros - This function is an ap_private version of the + /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number + /// of zeros from the most significant bit to the first one bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the most significant bit to the first + /// one bits. + INLINE uint32_t countLeadingZeros() const ; + + /// countLeadingOnes - This function counts the number of contiguous 1 bits + /// in the high order bits. The count stops when the first 0 bit is reached. + /// @returns 0 if the high order bit is not set + /// @returns the number of 1 bits from the most significant to the least + /// @brief Count the number of leading one bits. + INLINE uint32_t countLeadingOnes() const ; + + /// countTrailingZeros - This function is an ap_private version of the + /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts + /// the number of zeros from the least significant bit to the first set bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the least significant bit to the first + /// one bit. + /// @brief Count the number of trailing zero bits. + INLINE uint32_t countTrailingZeros() const ; + + /// countPopulation - This function is an ap_private version of the + /// countPopulation_{32,64} functions in MathExtras.h. It counts the number + /// of 1 bits in the ap_private value. + /// @returns 0 if the value is zero. + /// @returns the number of set bits. + /// @brief Count the number of bits set. + INLINE uint32_t countPopulation() const { + uint32_t Count = 0; + for (uint32_t i = 0; i<_AP_N-1 ; ++i) + Count += CountPopulation_64(pVal[i]); + Count += CountPopulation_64(pVal[_AP_N-1]&mask); + return Count; + } + + /// @} + /// @name Conversion Functions + /// @{ + + /// This is used internally to convert an ap_private to a string. + /// @brief Converts an ap_private to a std::string + INLINE std::string toString(uint8_t radix, bool wantSigned) const + ; + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + + /// @returns a byte-swapped representation of this ap_private Value. + INLINE ap_private byteSwap() const ; + + /// @brief Converts this ap_private to a double value. + INLINE double roundToDouble(bool isSigned) const ; + + /// @brief Converts this unsigned ap_private to a double value. + INLINE double roundToDouble() const { + return roundToDouble(false); + } + + /// @brief Converts this signed ap_private to a double value. + INLINE double signedRoundToDouble() const { + return roundToDouble(true); + } + + /// The conversion does not do a translation from integer to double, it just + /// re-interprets the bits as a double. Note that it is valid to do this on + /// any bit width. Exactly 64 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE double bitsToDouble() const { + union { + uint64_t __I; + double __D; + } __T; + __T.__I = pVal[0]; + return __T.__D; + } + + /// The conversion does not do a translation from integer to float, it just + /// re-interprets the bits as a float. Note that it is valid to do this on + /// any bit width. Exactly 32 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE float bitsToFloat() const { + union { + uint32_t __I; + float __F; + } __T; + __T.__I = uint32_t(pVal[0]); + return __T.__F; + } + + /// The conversion does not do a translation from double to integer, it just + /// re-interprets the bits of the double. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a double to ap_private bits. + INLINE ap_private& doubleToBits(double __V) { + union { + uint64_t __I; + double __D; + } __T; + __T.__D = __V; + pVal[0] = __T.__I; + return *this; + } + + /// The conversion does not do a translation from float to integer, it just + /// re-interprets the bits of the float. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a float to ap_private bits. + INLINE ap_private& floatToBits(float __V) { + union { + uint32_t __I; + float __F; + } __T; + __T.__F = __V; + pVal[0] = __T.__I; + } + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return isMaxValue(); + } + + INLINE bool nand_reduce() const { + return isMinValue(); + } + + INLINE bool or_reduce() const { + return (bool)countPopulation(); + } + + INLINE bool nor_reduce() const { + return countPopulation()==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + INLINE std::string to_string(uint8_t radix=16, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; + +template +INLINE bool operator==(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 == V1; +} + +template +INLINE bool operator!=(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 != V1; +} + +namespace ap_private_ops { + enum {APINT_BITS_PER_WORD=64}; + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.slt(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.sgt(RHS) ? LHS : RHS; + } + + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ult(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be unsigned. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ugt(RHS) ? LHS : RHS; + } + + /// @brief Check if the specified ap_private has a N-bits integer value. + template + INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); + } + + /// @returns true if the argument ap_private value is a sequence of ones + /// starting at the least significant bit with the remainder zero. + template + INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; + } + + /// @returns true if the argument ap_private value contains a sequence of ones + /// with the remainder zero. + template + INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); + } + + /// @returns a byte-swapped representation of the specified ap_private Value. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> byteSwap(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.byteSwap(); + } + + /// @returns the floor log base 2 of the specified ap_private value. + template INLINE uint32_t logBase2(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.logBase2(); + } + + /// GreatestCommonDivisor - This function returns the greatest common + /// divisor of the two ap_private values using Enclid's algorithm. + /// @returns the greatest common divisor of Val1 and Val2 + /// @brief Compute GCD of two ap_private values. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& Val1, const ap_private<_AP_W, _AP_S, _AP_N>& Val2) + ; + + /// Treats the ap_private as an unsigned value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double Roundap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.roundToDouble(); + } + + /// Treats the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double RoundSignedap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.signedRoundToDouble(); + } + + /// @brief Converts the given ap_private to a float vlalue. + template INLINE float Roundap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(Roundap_privateToDouble(APIVal)); + } + + /// Treast the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a float value. + template INLINE float RoundSignedap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(APIVal.signedRoundToDouble()); + } + + /// RoundDoubleToap_private - This function convert a double value to an ap_private value. + /// @brief Converts the given double value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundDoubleToap_private(double Double, uint32_t width) ; + + /// RoundFloatToap_private - Converts a float value into an ap_private value. + /// @brief Converts a float value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundFloatToap_private(float Float, uint32_t width) { + return RoundDoubleToap_private<_AP_W, _AP_S, _AP_N>(double(Float), width); + } + + /// Arithmetic right-shift the ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> ashr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.ashr(shiftAmt); + } + + /// Logical right-shift the ap_private by shiftAmt. + /// @brief Logical right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.lshr(shiftAmt); + } + + /// Left-shift the ap_private by shiftAmt. + /// @brief Left-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.shl(shiftAmt); + } + + /// Signed divide ap_private LHS by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sdiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.sdiv(RHS); + } + + /// Unsigned divide ap_private LHS by ap_private RHS. + /// @brief Unsigned division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> udiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.udiv(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> srem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.srem(RHS); + } + + /// Unsigned remainder operation on ap_private. + /// @brief Function for unsigned remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> urem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.urem(RHS); + } + + /// Performs multiplication on ap_private values. + /// @brief Function for multiplication operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> mul(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS * RHS; + } + + /// Performs addition on ap_private values. + /// @brief Function for addition operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> add(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS + RHS; + } + + /// Performs subtraction on ap_private values. + /// @brief Function for subtraction operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sub(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS - RHS; + } + + /// Performs bitwise AND operation on ap_private LHS and + /// ap_private RHS. + /// @brief Bitwise AND function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS & RHS; + } + + /// Performs bitwise OR operation on ap_private LHS and ap_private RHS. + /// @brief Bitwise OR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Or(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS | RHS; + } + + /// Performs bitwise XOR operation on ap_private. + /// @brief Bitwise XOR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Xor(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS ^ RHS; + } + + /// Performs a bitwise complement operation on ap_private. + /// @brief Bitwise complement function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> Not(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return ~APIVal; + } + + template void clearUnusedBits(uint64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(uint64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + template void clearUnusedBits(int64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(int64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + // template + template + INLINE ap_private<_AP_W, _AP_S> ashr(const ap_private<_AP_W, _AP_S>& a) { + return ashr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S>& a) { + return lshr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, true> ashr(const ap_private<_AP_W, true, 1>& a) { + enum {APINT_BITS_PER_WORD=64, excess_bits=APINT_BITS_PER_WORD-_AP_W}; + static const uint64_t sign_bit = (1ULL<<(_AP_W-1)); + static const uint64_t sign_ext_mask = (_AP_W-shiftAmt>0)?~0ULL<<(APINT_BITS_PER_WORD-_AP_W+shiftAmt):~0ULL; + return ap_private<_AP_W, true>((((int64_t)a.VAL) >> (shiftAmt)) | (a.VAL & sign_bit? sign_ext_mask : 0ULL)); + } + + template + INLINE ap_private<_AP_W, false> ashr(const ap_private<_AP_W, false, 1>& a) { + return ap_private<_AP_W, false>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~0ULL<<_AP_W; + return ap_private<_AP_W, _AP_S>((a.VAL&mask) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W-shiftAmt, _AP_S> shr(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W-shiftAmt, _AP_S>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W+shiftAmt, _AP_S> shl(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W+shiftAmt, _AP_S>((a.VAL) << (shiftAmt)); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S, 1>& a) { + unsigned shift = (index%APINT_BITS_PER_WORD); + static const uint64_t mask=1ULL << (shift); + return ((mask & a.VAL) != 0); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S>& a) { + static const uint64_t mask=1ULL << (index&0x3f); + return ((mask & a.pVal[(index)>>6]) != 0); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.VAL |= mask; + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~(~0ULL >> (lsb) <<(APINT_BITS_PER_WORD-msb+lsb-1) >> (APINT_BITS_PER_WORD-msb-1)); + a.VAL &= mask; + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word==lsb_word) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[msb_word] |= mask; + } else { + const uint64_t lsb_mask = ~0ULL >> (lsb) << (lsb); + const uint64_t msb_mask = ~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[lsb_word] |=lsb_mask; + for (int i=lsb_word+1; i + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word == lsb_word) { + const uint64_t mask = ~(~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[msb_word] &= mask; + } else { + const uint64_t lsb_mask = ~(~0ULL >> (lsb) << (lsb)); + const uint64_t msb_mask = ~(~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[lsb_word] &=lsb_mask; + for (int i=lsb_word+1; i + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=1ULL << (index); + a.VAL |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=~(1ULL << (index)); + a.VAL &= mask; + a.clearUnusedBits(); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=1ULL << (index%APINT_BITS_PER_WORD); + a.pVal[word] |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=~(1ULL << (index%APINT_BITS_PER_WORD)); + a.pVal[word] &= mask; + a.clearUnusedBits(); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, false>& a) { + return false; + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true, 1>& a) { + static const uint64_t sign_mask = (1ULL << (_AP_W-1)); + return ((sign_mask & a.VAL) != 0); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true>& a) { + enum {APINT_BITS_PER_WORD=64,_AP_N=(_AP_W+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + static const uint64_t sign_mask = (1ULL << (_AP_W%APINT_BITS_PER_WORD-1)); + return sign_mask & a.pVal[_AP_N-1]; + } +} // End of ap_private_ops namespace + +/// @brief Check if the specified ap_private has a N-bits integer value. +template +INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); +} + +/// @returns true if the argument ap_private value is a sequence of ones +/// starting at the least significant bit with the remainder zero. +template +INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; +} + +/// @returns true if the argument ap_private value contains a sequence of ones +/// with the remainder zero. +template +INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); +} + +#if 0 +/// add_1 - This function adds a single "digit" integer, y, to the multiple +/// "digit" integer array, x[]. x[] is modified to reflect the addition and +/// 1 is returned if there is a carry out, otherwise 0 is returned. +/// @returns the carry of the addition. +static bool add_1(uint64_t dest[], uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + dest[i] = y + x[i]; + if (dest[i] < y) + y = 1; // Carry one to next digit. + else { + y = 0; // No need to carry so exit early + break; + } + } + return (y != 0); +} +#endif + +#if 0 +/// add - This function adds the integer array x to the integer array Y and +/// places the result in dest. +/// @returns the carry out from the addition +/// @brief General addition of 64-bit integer arrays +static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool carry = false; + uint32_t len = AESL_std::min(xlen, ylen); + uint32_t i; + for (i = 0; i< len && i < destlen; ++i) { + uint64_t limit = AESL_std::min(x[i],y[i]); // must come first in case dest == x + dest[i] = x[i] + y[i] + carry; + carry = dest[i] < limit || (carry && dest[i] == limit); + } + if (xlen > ylen) { + const uint64_t yext = xsigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t limit = AESL_std::min(x[i], yext); + dest[i] = x[i] + yext + carry; + carry = (dest[i] < limit)||(carry && dest[i] == x[i]); + } + } else if (ylen> xlen) { + const uint64_t xext = ysigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t limit = AESL_std::min(xext, y[i]); + dest[i] = xext + y[i] + carry; + carry = (dest[i] < limit)||(carry && dest[i] == y[i]); + } + } + return carry; +} +#endif + +#if 0 +/// @returns returns the borrow out. +/// @brief Generalized subtraction of 64-bit integer arrays. +static bool sub(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool borrow = false; + uint32_t i; + uint32_t len = AESL_std::min(xlen, ylen); + for (i = 0; i < len && i < destlen; ++i) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = y[i] > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - y[i]; + } + if (xlen > ylen) { + const uint64_t yext = ysigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = yext > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - yext; + } + } else if (ylen> xlen) { + const uint64_t xext = xsigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t x_tmp = borrow ? xext - 1 : xext; + borrow = y[i] > x_tmp || (borrow && xext==0); + dest[i] = x_tmp - y[i]; + } + } + return borrow; +} +#endif + +/// Subtracts the RHS ap_private from this ap_private +/// @returns this, after subtraction +/// @brief Subtraction assignment operator. + +#if 0 +/// Multiplies an integer array, x by a a uint64_t integer and places the result +/// into dest. +/// @returns the carry out of the multiplication. +/// @brief Multiply a multi-digit ap_private by a single digit (64-bit) integer. +static uint64_t mul_1(uint64_t dest[], const uint64_t x[], uint32_t len, uint64_t y) { + // Split y into high 32-bit part (hy) and low 32-bit part (ly) + uint64_t ly = y & 0xffffffffULL, hy = (y) >> 32; + uint64_t carry = 0; + static const uint64_t two_power_32 = 1ULL << 32; + // For each digit of x. + for (uint32_t i = 0; i < len; ++i) { + // Split x into high and low words + uint64_t lx = x[i] & 0xffffffffULL; + uint64_t hx = (x[i]) >> 32; + // hasCarry - A flag to indicate if there is a carry to the next digit. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + dest[i] = carry + lx * ly; + // Determine if the add above introduces carry. + hasCarry = (dest[i] < carry) ? 1 : 0; + carry = hx * ly + ((dest[i]) >> 32) + (hasCarry ? two_power_32 : 0); + // The upper limit of carry can be (2^32 - 1)(2^32 - 1) + + // (2^32 - 1) + 2^32 = 2^64. + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + + carry += (lx * hy) & 0xffffffffULL; + dest[i] = ((carry) << 32) | (dest[i] & 0xffffffffULL); + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? two_power_32 : 0) + + ((carry) >> 32) + ((lx * hy) >> 32) + hx * hy; + } + return carry; +} +#endif + +#if 0 +/// Multiplies integer array x by integer array y and stores the result into +/// the integer array dest. Note that dest's size must be >= xlen + ylen. +/// @brief Generalized multiplicate of integer arrays. +static void mul(uint64_t dest[], const uint64_t x[], uint32_t xlen, const uint64_t y[], + uint32_t ylen, uint32_t destlen) { + dest[xlen] = mul_1(dest, x, xlen, y[0]); + for (uint32_t i = 1; i < ylen; ++i) { + uint64_t ly = y[i] & 0xffffffffULL, hy = (y[i]) >> 32; + uint64_t carry = 0, lx = 0, hx = 0; + for (uint32_t j = 0; j < xlen; ++j) { + lx = x[j] & 0xffffffffULL; + hx = (x[j]) >> 32; + // hasCarry - A flag to indicate if has carry. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + uint64_t resul = carry + lx * ly; + hasCarry = (resul < carry) ? 1 : 0; + carry = (hasCarry ? (1ULL << 32) : 0) + hx * ly + ((resul) >> 32); + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + carry += (lx * hy) & 0xffffffffULL; + resul = ((carry) << 32) | (resul & 0xffffffffULL); + dest[i+j] += resul; + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0)+ + ((carry) >> 32) + (dest[i+j] < resul ? 1 : 0) + + ((lx * hy) >> 32) + hx * hy; + } + dest[i+xlen] = carry; + } +} +#endif + + + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + assert(str != 0 && "Invalid value string"); + assert(slen > 0 && "Invalid string length"); + + // Each computation below needs to know if its negative + uint32_t isNegative = str[0] == '-'; + if (isNegative) { + slen--; + str++; + } + // For radixes of power-of-two values, the bits required is accurately and + // easily computed + if (radix == 2) + return slen + isNegative; + if (radix == 8) + return slen * 3 + isNegative; + if (radix == 16) + return slen * 4 + isNegative; + + // Otherwise it must be radix == 10, the hard case + assert(radix == 10 && "Invalid radix"); + + // Convert to the actual binary value. + //ap_private<_AP_W, _AP_S, _AP_N> tmp(sufficient, str, slen, radix); + + // Compute how many bits are required. + //return isNegative + tmp.logBase2() + 1; + return isNegative + slen * 4; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingZeros() const { + enum { msw_bits = (BitWidth % APINT_BITS_PER_WORD)?(BitWidth % APINT_BITS_PER_WORD):APINT_BITS_PER_WORD, + excessBits = APINT_BITS_PER_WORD - msw_bits }; + uint32_t Count = CountLeadingZeros_64(pVal[_AP_N-1]); + if (Count>=excessBits) + Count -= excessBits; + if (!pVal[_AP_N-1]) { + for (uint32_t i = _AP_N-1 ; i ; --i) { + if (!pVal[i-1]) + Count += APINT_BITS_PER_WORD; + else { + Count += CountLeadingZeros_64(pVal[i-1]); + break; + } + } + } + return Count; +} + +static uint32_t countLeadingOnes_64(uint64_t __V, uint32_t skip) { + uint32_t Count = 0; + if (skip) + (__V) <<= (skip); + while (__V && (__V & (1ULL << 63))) { + Count++; + (__V) <<= 1; + } + return Count; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingOnes() const { + if (isSingleWord()) + return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth); + + uint32_t highWordBits = BitWidth % APINT_BITS_PER_WORD; + uint32_t shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits); + int i = _AP_N - 1; + uint32_t Count = countLeadingOnes_64(pVal[i], shift); + if (Count == highWordBits) { + for (i--; i >= 0; --i) { + if (pVal[i] == ~0ULL) + Count += APINT_BITS_PER_WORD; + else { + Count += countLeadingOnes_64(pVal[i], 0); + break; + } + } + } + return Count; +} + +template +INLINE uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countTrailingZeros() const { + if (isSingleWord()) + return AESL_std::min(uint32_t(CountTrailingZeros_64(VAL)), BitWidth); + uint32_t Count = 0; + uint32_t i = 0; + for (; i < _AP_N && pVal[i] == 0; ++i) + Count += APINT_BITS_PER_WORD; + if (i < _AP_N) + Count += CountTrailingZeros_64(pVal[i]); + return AESL_std::min(Count, BitWidth); +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::byteSwap() const { + assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!"); + if (BitWidth == 16) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_16(uint16_t(VAL))); + else if (BitWidth == 32) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_32(uint32_t(VAL))); + else if (BitWidth == 48) { + uint32_t Tmp1 = uint32_t((VAL) >> 16); + Tmp1 = ByteSwap_32(Tmp1); + uint16_t Tmp2 = uint16_t(VAL); + Tmp2 = ByteSwap_16(Tmp2); + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ((uint64_t(Tmp2)) << 32) | Tmp1); + } else if (BitWidth == 64) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_64(VAL)); + else { + ap_private<_AP_W, _AP_S, _AP_N> Result(0); + char *pByte = (char*)Result.pVal; + for (uint32_t i = 0; i < BitWidth / APINT_WORD_SIZE / 2; ++i) { + char Tmp = pByte[i]; + pByte[i] = pByte[BitWidth / APINT_WORD_SIZE - 1 - i]; + pByte[BitWidth / APINT_WORD_SIZE - i - 1] = Tmp; + } + return Result; + } +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& API1, const ap_private<_AP_W, _AP_S, _AP_N>& API2) { + ap_private<_AP_W, _AP_S, _AP_N> __A = API1, __B = API2; + while (!!__B) { + ap_private<_AP_W, _AP_S, _AP_N> __T = __B; + __B = ap_private_ops::urem(__A, __B); + __A = __T; + } + return __A; +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::RoundDoubleToap_private(double Double, uint32_t width) { + union { + double __D; + uint64_t __I; + } __T; + __T.__D = Double; + + // Get the sign bit from the highest order bit + bool isNeg = (__T.__I) >> 63; + + // Get the 11-bit exponent and adjust for the 1023 bit bias + int64_t exp = (((__T.__I) >> 52) & 0x7ffULL) - 1023; + + // If the exponent is negative, the value is < 0 so just return 0. + if (exp < 0) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0u); + + // Extract the mantissa by clearing the top 12 bits (sign + exponent). + uint64_t mantissa = (__T.__I & (~0ULL >> 12)) | 1ULL << 52; + + // If the exponent doesn't shift all bits out of the mantissa + if (exp < 52) + return isNeg ? -ap_private<_AP_W, _AP_S, _AP_N>(width, (mantissa) >> (52 - exp)) : + ap_private<_AP_W, _AP_S, _AP_N>((mantissa) >> (52 - exp)); + + // If the client didn't provide enough bits for us to shift the mantissa into + // then the result is undefined, just return 0 + if (width <= exp - 52) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0); + + // Otherwise, we have to shift the mantissa bits up to the right location + ap_private<_AP_W, _AP_S, _AP_N> Tmp(width, mantissa); + Tmp = Tmp.shl(exp - 52); + return isNeg ? -Tmp : Tmp; +} + +/// RoundToDouble - This function convert this ap_private to a double. +/// The layout for double is as following (IEEE Standard 754): +/// -------------------------------------- +/// | Sign Exponent Fraction Bias | +/// |-------------------------------------- | +/// | 1[63] 11[62-52] 52[51-00] 1023 | +/// -------------------------------------- +template +double ap_private<_AP_W, _AP_S, _AP_N>::roundToDouble(bool isSigned) const { + + // Handle the simple case where the value is contained in one uint64_t. + if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) { + uint64_t val; + if (isSingleWord()) val = VAL; + else val = pVal[0]; + if (isSigned) { + int64_t sext = ((int64_t(val)) << (64-BitWidth)) >> (64-BitWidth); + return double(sext); + } else + return double(val); + } + + // Determine if the value is negative. + bool isNeg = isSigned ? (*this)[BitWidth-1] : false; + + // Construct the absolute value if we're negative. + ap_private<_AP_W, _AP_S, _AP_N> Tmp(isNeg ? -(*this) : (*this)); + + // Figure out how many bits we're using. + uint32_t n = Tmp.getActiveBits(); + + // The exponent (without bias normalization) is just the number of bits + // we are using. Note that the sign bit is gone since we constructed the + // absolute value. + uint64_t exp = n; + + // Return infinity for exponent overflow + if (exp > 1023) { + if (!isSigned || !isNeg) + return std::numeric_limits::infinity(); + else + return -std::numeric_limits::infinity(); + } + exp += 1023; // Increment for 1023 bias + + // Number of bits in mantissa is 52. To obtain the mantissa value, we must + // extract the high 52 bits from the correct words in pVal. + uint64_t mantissa; + unsigned hiWord = whichWord(n-1); + if (hiWord == 0) { + mantissa = Tmp.pVal[0]; + if (n > 52) + (mantissa) >>= (n - 52); // shift down, we want the top 52 bits. + } else { + assert(hiWord > 0 && "High word is negative?"); + uint64_t hibits = (Tmp.pVal[hiWord]) << (52 - n % APINT_BITS_PER_WORD); + uint64_t lobits = (Tmp.pVal[hiWord-1]) >> (11 + n % APINT_BITS_PER_WORD); + mantissa = hibits | lobits; + } + + // The leading bit of mantissa is implicit, so get rid of it. + uint64_t sign = isNeg ? (1ULL << (APINT_BITS_PER_WORD - 1)) : 0; + union { + double __D; + uint64_t __I; + } __T; + __T.__I = sign | ((exp) << 52) | mantissa; + return __T.__D; +} + +// Square Root - this method computes and returns the square root of "this". +// Three mechanisms are used for computation. For small values (<= 5 bits), +// a table lookup is done. This gets some performance for common cases. For +// values using less than 52 bits, the value is converted to double and then +// the libc sqrt function is called. The result is rounded and then converted +// back to a uint64_t which is then used to construct the result. Finally, +// the Babylonian method for computing square roots is used. +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::sqrt() const { + + // Determine the magnitude of the value. + uint32_t magnitude = getActiveBits(); + + // Use a fast table for some small values. This also gets rid of some + // rounding errors in libc sqrt for small values. + if (magnitude <= 5) { + static const uint8_t results[32] = { + /* 0 */ 0, + /* 1- 2 */ 1, 1, + /* 3- 6 */ 2, 2, 2, 2, + /* 7-12 */ 3, 3, 3, 3, 3, 3, + /* 13-20 */ 4, 4, 4, 4, 4, 4, 4, 4, + /* 21-30 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 31 */ 6 + }; + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ results[ (isSingleWord() ? VAL : pVal[0]) ]); + } + + // If the magnitude of the value fits in less than 52 bits (the precision of + // an IEEE double precision floating point value), then we can use the + // libc sqrt function which will probably use a hardware sqrt computation. + // This should be faster than the algorithm below. + if (magnitude < 52) { +#ifdef _MSC_VER + // Amazingly, VC++ doesn't have round(). + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0]))) + 0.5); +#else + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0]))))); +#endif + } + + // Okay, all the short cuts are exhausted. We must compute it. The following + // is a classical Babylonian method for computing the square root. This code + // was adapted to APINt from a wikipedia article on such computations. + // See http://www.wikipedia.org/ and go to the page named + // Calculate_an_integer_square_root. + uint32_t nbits = BitWidth, i = 4; + ap_private<_AP_W, _AP_S, _AP_N> testy(16); + ap_private<_AP_W, _AP_S, _AP_N> x_old(/*BitWidth,*/ 1); + ap_private<_AP_W, _AP_S, _AP_N> x_new(0); + ap_private<_AP_W, _AP_S, _AP_N> two(/*BitWidth,*/ 2); + + // Select a good starting value using binary logarithms. + for (;; i += 2, testy = testy.shl(2)) + if (i >= nbits || this->ule(testy)) { + x_old = x_old.shl(i / 2); + break; + } + + // Use the Babylonian method to arrive at the integer square root: + for (;;) { + x_new = (this->udiv(x_old) + x_old).udiv(two); + if (x_old.ule(x_new)) + break; + x_old = x_new; + } + + // Make sure we return the closest approximation + // NOTE: The rounding calculation below is correct. It will produce an + // off-by-one discrepancy with results from pari/gp. That discrepancy has been + // determined to be a rounding issue with pari/gp as it begins to use a + // floating point representation after 192 bits. There are no discrepancies + // between this algorithm and pari/gp for bit widths < 192 bits. + ap_private<_AP_W, _AP_S, _AP_N> square(x_old * x_old); + ap_private<_AP_W, _AP_S, _AP_N> nextSquare((x_old + 1) * (x_old +1)); + if (this->ult(square)) + return x_old; + else if (this->ule(nextSquare)) { + ap_private<_AP_W, _AP_S, _AP_N> midpoint((nextSquare - square).udiv(two)); + ap_private<_AP_W, _AP_S, _AP_N> offset(*this - square); + if (offset.ult(midpoint)) + return x_old; + else + return x_old + 1; + } else + assert(0 && "Error in ap_private<_AP_W, _AP_S, _AP_N>::sqrt computation"); + return x_old + 1; +} + +/// Implementation of Knuth's Algorithm D (Division of nonnegative integers) +/// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The +/// variables here have the same names as in the algorithm. Comments explain +/// the algorithm and any deviation from it. +static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r, + uint32_t m, uint32_t n) { + assert(u && "Must provide dividend"); + assert(v && "Must provide divisor"); + assert(q && "Must provide quotient"); + assert(u != v && u != q && v != q && "Must us different memory"); + assert(n>1 && "n must be > 1"); + + // Knuth uses the value b as the base of the number system. In our case b + // is 2^31 so we just set it to -1u. + uint64_t b = uint64_t(1) << 32; + + //DEBUG(cerr << "KnuthDiv: m=" << m << " n=" << n << '\n'); + //DEBUG(cerr << "KnuthDiv: original:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of + // u and v by d. Note that we have taken Knuth's advice here to use a power + // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of + // 2 allows us to shift instead of multiply and it is easy to determine the + // shift amount from the leading zeros. We are basically normalizing the u + // and v so that its high bits are shifted to the top of v's range without + // overflow. Note that this can require an extra word in u so that u must + // be of length m+n+1. + uint32_t shift = CountLeadingZeros_32(v[n-1]); + uint32_t v_carry = 0; + uint32_t u_carry = 0; + if (shift) { + for (uint32_t i = 0; i < m+n; ++i) { + uint32_t u_tmp = (u[i]) >> (32 - shift); + u[i] = ((u[i]) << (shift)) | u_carry; + u_carry = u_tmp; + } + for (uint32_t i = 0; i < n; ++i) { + uint32_t v_tmp = (v[i]) >> (32 - shift); + v[i] = ((v[i]) << (shift)) | v_carry; + v_carry = v_tmp; + } + } + u[m+n] = u_carry; + //DEBUG(cerr << "KnuthDiv: normal:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + + // D2. [Initialize j.] Set j to m. This is the loop counter over the places. + int j = m; + do { + //DEBUG(cerr << "KnuthDiv: quotient digit #" << j << '\n'); + // D3. [Calculate q'.]. + // Set qp = (u[j+n]*b + u[j+n-1]) / v[n-1]. (qp=qprime=q') + // Set rp = (u[j+n]*b + u[j+n-1]) % v[n-1]. (rp=rprime=r') + // Now test if qp == b or qp*v[n-2] > b*rp + u[j+n-2]; if so, decrease + // qp by 1, inrease rp by v[n-1], and repeat this test if rp < b. The test + // on v[n-2] determines at high speed most of the cases in which the trial + // value qp is one too large, and it eliminates all cases where qp is two + // too large. + uint64_t dividend = ((uint64_t(u[j+n]) << 32) + u[j+n-1]); + //DEBUG(cerr << "KnuthDiv: dividend == " << dividend << '\n'); + uint64_t qp = dividend / v[n-1]; + uint64_t rp = dividend % v[n-1]; + if (qp == b || qp*v[n-2] > b*rp + u[j+n-2]) { + qp--; + rp += v[n-1]; + if (rp < b && (qp == b || qp*v[n-2] > b*rp + u[j+n-2])) + qp--; + } + //DEBUG(cerr << "KnuthDiv: qp == " << qp << ", rp == " << rp << '\n'); + + // D4. [Multiply and subtract.] Replace (u[j+n]u[j+n-1]...u[j]) with + // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation + // consists of a simple multiplication by a one-place number, combined with + // a subtraction. + bool isNeg = false; + for (uint32_t i = 0; i < n; ++i) { + uint64_t u_tmp = uint64_t(u[j+i]) | ((uint64_t(u[j+i+1])) << 32); + uint64_t subtrahend = uint64_t(qp) * uint64_t(v[i]); + bool borrow = subtrahend > u_tmp; + /*DEBUG(cerr << "KnuthDiv: u_tmp == " << u_tmp + << ", subtrahend == " << subtrahend + << ", borrow = " << borrow << '\n');*/ + + uint64_t result = u_tmp - subtrahend; + uint32_t k = j + i; + u[k++] = (uint32_t)(result & (b-1)); // subtract low word + u[k++] = (uint32_t)((result) >> 32); // subtract high word + while (borrow && k <= m+n) { // deal with borrow to the left + borrow = u[k] == 0; + u[k]--; + k++; + } + isNeg |= borrow; + /*DEBUG(cerr << "KnuthDiv: u[j+i] == " << u[j+i] << ", u[j+i+1] == " << + u[j+i+1] << '\n');*/ + } + /*DEBUG(cerr << "KnuthDiv: after subtraction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + // The digits (u[j+n]...u[j]) should be kept positive; if the result of + // this step is actually negative, (u[j+n]...u[j]) should be left as the + // true value plus b**(n+1), namely as the b's complement of + // the true value, and a "borrow" to the left should be remembered. + // + if (isNeg) { + bool carry = true; // true because b's complement is "complement + 1" + for (uint32_t i = 0; i <= m+n; ++i) { + u[i] = ~u[i] + carry; // b's complement + carry = carry && u[i] == 0; + } + } + /*DEBUG(cerr << "KnuthDiv: after complement:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + + // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was + // negative, go to step D6; otherwise go on to step D7. + q[j] = (uint32_t)qp; + if (isNeg) { + // D6. [Add back]. The probability that this step is necessary is very + // small, on the order of only 2/b. Make sure that test data accounts for + // this possibility. Decrease q[j] by 1 + q[j]--; + // and add (0v[n-1]...v[1]v[0]) to (u[j+n]u[j+n-1]...u[j+1]u[j]). + // A carry will occur to the left of u[j+n], and it should be ignored + // since it cancels with the borrow that occurred in D4. + bool carry = false; + for (uint32_t i = 0; i < n; i++) { + uint32_t limit = AESL_std::min(u[j+i],v[i]); + u[j+i] += v[i] + carry; + carry = u[j+i] < limit || (carry && u[j+i] == limit); + } + u[j+n] += carry; + } + /*DEBUG(cerr << "KnuthDiv: after correction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr <<" " << u[i]); + DEBUG(cerr << "\nKnuthDiv: digit result = " << q[j] << '\n');*/ + + // D7. [Loop on j.] Decrease j by one. Now if j >= 0, go back to D3. + } while (--j >= 0); + + /*DEBUG(cerr << "KnuthDiv: quotient:"); + DEBUG(for (int i = m; i >=0; i--) cerr <<" " << q[i]); + DEBUG(cerr << '\n');*/ + + // D8. [Unnormalize]. Now q[...] is the desired quotient, and the desired + // remainder may be obtained by dividing u[...] by d. If r is non-null we + // compute the remainder (urem uses this). + if (r) { + // The value d is expressed by the "shift" value above since we avoided + // multiplication by d by using a shift left. So, all we have to do is + // shift right here. In order to mak + if (shift) { + uint32_t carry = 0; + //DEBUG(cerr << "KnuthDiv: remainder:"); + for (int i = n-1; i >= 0; i--) { + r[i] = ((u[i]) >> (shift)) | carry; + carry = (u[i]) << (32 - shift); + //DEBUG(cerr << " " << r[i]); + } + } else { + for (int i = n-1; i >= 0; i--) { + r[i] = u[i]; + //DEBUG(cerr << " " << r[i]); + } + } + //DEBUG(cerr << '\n'); + } + //DEBUG(cerr << std::setbase(10) << '\n'); +} + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + const ap_private<_AP_W, _AP_S, _AP_N>& RHS, uint32_t rhsWords, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = rhsWords * 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = (uint32_t)(tmp & mask); + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + for (unsigned i = 0; i < rhsWords; ++i) { + uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]); + __V[i * 2] = (uint32_t)(tmp & mask); + __V[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = (uint32_t)partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = (uint32_t)(partial_dividend / divisor); + remainder = (uint32_t)(partial_dividend - (__Q[i] * divisor)); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != RHS.BitWidth) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + + +template +void ap_private<_AP_W, _AP_S, _AP_N>::fromString(const char *str, uint32_t slen, uint8_t radix) { + enum { numbits=_AP_W}; + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(str && "String is null?"); + bool isNeg = str[0] == '-'; + if (isNeg) + str++, slen--; + + //skip any leading zero + while(*str == '0' && *(str+1) != '\0') {str++; slen--;} + assert((slen <= numbits || radix != 2) && "Insufficient bit width"); + assert(((slen - 1)*3 <= numbits || radix != 8) && "Insufficient bit width"); + assert(((slen - 1)*4 <= numbits || radix != 16) && "Insufficient bit width"); + assert((((slen -1)*64)/22 <= numbits || radix != 10) && "Insufficient bit width"); + + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Figure out if we can shift instead of multiply + uint32_t shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0); + + // Set up an ap_private for the digit to add outside the loop so we don't + // constantly construct/destruct it. + uint64_t bigVal[_AP_N]; + memset(bigVal, 0, _AP_N * sizeof(uint64_t)); + ap_private<_AP_W, _AP_S, _AP_N> apdigit(getBitWidth(), bigVal); + ap_private<_AP_W, _AP_S, _AP_N> apradix(radix); + + // Enter digit traversal loop + for (unsigned i = 0; i < slen; i++) { + // Get a digit + uint32_t digit = 0; + char cdigit = str[i]; + if (radix == 16) { +#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#define isdigit(c) ((c) >= '0' && (c) <= '9') + if (!isxdigit(cdigit)) + assert(0 && "Invalid hex digit in string"); + if (isdigit(cdigit)) + digit = cdigit - '0'; + else if (cdigit >= 'a') + digit = cdigit - 'a' + 10; + else if (cdigit >= 'A') + digit = cdigit - 'A' + 10; + else + assert(0 && "huh? we shouldn't get here"); + } else if (isdigit(cdigit)) { + digit = cdigit - '0'; + } else { + assert(0 && "Invalid character in digit string"); + } +#undef isxdigit +#undef isdigit + // Shift or multiply the value by the radix + if (shift) + *this <<= shift; + else + *this *= apradix; + + // Add in the digit we just interpreted + if (apdigit.isSingleWord()) + apdigit.VAL = digit; + else + apdigit.pVal[0] = digit; + *this += apdigit; + } + // If its negative, put it in two's complement form + if (isNeg) { + (*this)--; + this->flip(); + } + clearUnusedBits(); +} + +template +std::string ap_private<_AP_W, _AP_S, _AP_N>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" + }; + std::string result; + uint32_t bits_used = getActiveBits(); + + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, _AP_N> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, _AP_N> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask; + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, _AP_N> tmp(*this); + ap_private<_AP_W, false, _AP_N> divisor(radix); + ap_private<_AP_W, false, _AP_N> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, _AP_N>(0)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, _AP_N> APdigit(0); + ap_private<_AP_W, false, _AP_N> tmp2(0); + divide(tmp, tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2, + &APdigit); + uint32_t digit = APdigit.getZExtValue(); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + + return result; +} + +// This implements a variety of operations on a representation of +// arbitrary precision, two's-complement, bignum integer values. + +/* Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe + and unrestricting assumption. */ + +/* Some handy functions local to this file. */ + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + uint64_t RHS, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + uint32_t rhsWords=1; + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = tmp & mask; + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + __V[0] = RHS & mask; + __V[1] = (RHS) >> (sizeof(uint32_t)*8); + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = partial_dividend / divisor; + remainder = partial_dividend - (__Q[i] * divisor); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + else + delete [] Quotient->pVal; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != 64 /* RHS.BitWidth */) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in __R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + +//When bitwidth < 64 +template class ap_private <_AP_W, _AP_S, 1> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template + struct RType { + enum { + _AP_N =1, + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, //?? why + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, //shouldn't it be AP_MAX(_AP_W,_AP_W2)+!(_AP_S^_AP_S2)+1 ???? + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + enum { APINT_BITS_PER_WORD = 64}; + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + static const uint64_t not_mask = ~mask; + static const uint64_t sign_bit_mask = 1ULL << (APINT_BITS_PER_WORD-1); + template struct sign_ext_mask { static const uint64_t mask=~0ULL<<_AP_W1;}; + + enum { BitWidth=_AP_W}; + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + const uint64_t *const pVal; + + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + volatile ap_private& operator=(const ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const volatile ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + template + INLINE ap_private& operator = (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + *this = ap_private<_AP_W2, false>(op2); + return *this; + } + + explicit INLINE ap_private(uint64_t* val) : VAL(val[0]), pVal(&VAL){ + clearUnusedBits(); + } + + INLINE bool isSingleWord() const { return true; } + + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix, int offset=0) { + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(strStart && "String is null?"); + strStart+=offset; + switch(radix) { + case 2: + // sscanf(strStart,"%b",&VAL); + VAL = *strStart =='1' ? ~0ULL : 0; + for (;*strStart; ++strStart) { + assert((*strStart=='0'|| *strStart=='1')&&("Wrong binary number") ); + VAL <<=1; + VAL |= (*strStart-'0'); + } + break; + case 8: +#if __WIN32__ + sscanf(strStart,"%I64o",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lo",&VAL); +#else + sscanf(strStart,"%llo",&VAL); +#endif + +#endif + break; + case 10: +#if __WIN32__ + sscanf(strStart,"%I64u",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lu",&VAL); +#else + sscanf(strStart,"%llu",&VAL); +#endif + +#endif + break; + case 16: +#if __WIN32__ + sscanf(strStart,"%I64x",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lx",&VAL); +#else + sscanf(strStart,"%llx",&VAL); +#endif + +#endif + break; + default: + assert(true && "Unknown radix"); + // error + } + clearUnusedBits(); + } + + INLINE ap_private() : pVal(&VAL){VAL = 0ULL;} + +#define CTOR(TYPE) \ + INLINE ap_private(TYPE v) : VAL((uint64_t)v), pVal(&VAL) { \ + clearUnusedBits(); \ + } + CTOR(int) + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) +#undef CTOR + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(bigVal[0]), pVal(&VAL) {clearUnusedBits();} + + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0), pVal(&VAL) { + assert(!val.empty() && "String empty?"); + fromString(val.c_str()+base, val.size()-base, radix); + } + + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0), pVal(&VAL) { + fromString(strStart+base, slen-base, radix, offset); + } + + ap_private(const ap_private& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + +#if 0 +template + explicit ap_private(const ap_private<_AP_W1, true, 1+_AP_W1/64>& that) + : VAL((_AP_W1>_AP_W) ? that.VAL & mask : ((1ULL<<(_AP_W1-1)&that.pVal[0]) ? sign_ext_mask<_AP_W1>::mask | that.VAL : that.pVal[0])), pVal(&VAL) {} + +template + explicit ap_private(const ap_private<_AP_W1, false, (_AP_W1+63)/64>& that) + : VAL(that.VAL & mask), pVal(&VAL) {} +#endif + + explicit ap_private(const char* val) : pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 10; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private<_AP_W, _AP_S> ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + ap_private(const char* val, signed char rd): pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + ap_private<_AP_W, _AP_S> ap_private_val(strp , strLen, radix, base, offset); + //ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + if (strp[0] == '-') + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + INLINE bool isNegative() const { + static const uint64_t sign_mask = 1ULL << (_AP_W-1); + return _AP_S && (sign_mask & VAL); + } + + INLINE bool isPositive() const { + return !isNegative(); + } + + INLINE bool isStrictlyPositive() const { + return !isNegative() && VAL!=0; + } + + INLINE bool isAllOnesValue() const { + return (mask & VAL) == mask; + } + + template + INLINE bool operator==(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + return (VAL == RHS.VAL); + } + + INLINE bool operator==(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL == RHS.VAL; } + INLINE bool operator==(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() == RHS.getVal(); } + INLINE bool operator==(uint64_t Val) const { return (VAL == Val); } + INLINE bool operator!=(uint64_t Val) const { return (VAL != Val); } + INLINE bool operator!=(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL != RHS.VAL; } + INLINE bool operator!=(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() != RHS.getVal(); } + const ap_private operator++() { ++VAL; clearUnusedBits(); return *this; } + const ap_private operator--(int) { + ap_private orig(*this); + --VAL; clearUnusedBits(); + return orig; + } + const ap_private operator--() { --VAL; clearUnusedBits(); return *this;} + INLINE bool operator !() const { return !VAL;} + + const ap_private operator++(int) { + ap_private orig(*this); + VAL++; clearUnusedBits(); + return orig; + } + + const ap_private operator~() {return ap_private(~VAL);} + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + INLINE std::string toString(uint8_t radix, bool wantSigned) const ; + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + INLINE void clear() { + VAL=0; + } + INLINE ap_private& clear(uint32_t bitPosition) { VAL &= ~(1ULL<<(bitPosition)); clearUnusedBits(); return *this;} + + INLINE ap_private ashr(uint32_t shiftAmt) const { + enum {excess_bits = APINT_BITS_PER_WORD - BitWidth}; + if (_AP_S) + return ap_private((shiftAmt == BitWidth) ? 0 : ((int64_t)VAL) >> (shiftAmt)); + else + return ap_private((shiftAmt == BitWidth) ? 0 : (VAL) >> (shiftAmt)); + } + + INLINE ap_private lshr(uint32_t shiftAmt) const { + return ap_private((shiftAmt == BitWidth) ? ap_private(0) : ap_private((VAL&mask) >> (shiftAmt))); + } + + INLINE ap_private shl(uint32_t shiftAmt) const { + if (shiftAmt > BitWidth) { + if (!isNegative()) + return ap_private(0); + else return ap_private(-1); + } + if (shiftAmt == BitWidth) return ap_private(0); + else return ap_private((VAL) << (shiftAmt)); + //return ap_private((shiftAmt == BitWidth) ? ap_private(0ULL) : ap_private(VAL << shiftAmt)); + } + + INLINE int64_t getSExtValue() const { + return VAL; + } + + INLINE uint64_t getZExtValue() const { + return VAL & mask; + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this = ((uint64_t)(bool)ref); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = (uint64_t)(bool)val; + } + + INLINE void write(const ap_private<_AP_W, _AP_S>& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + ValType getVal() const { + return VAL; + } + operator ValType () const { + return getVal(); + } + INLINE int to_int() const { + // ap_private<64 /* _AP_W */, _AP_S> res(V); + return (int) getVal(); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE bool isMinValue() const { return VAL == 0;} + template INLINE ap_private& operator&=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL&RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator|=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL|RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator^=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL^RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator*=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL*RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL+RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL-RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + INLINE const ap_private& operator<<=(uint32_t shiftAmt) { VAL<<=shiftAmt; clearUnusedBits(); return *this; } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator&(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL & RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret & RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator^(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL ^ RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret ^ RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator|(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL | RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret | RHS; + } + } + + INLINE ap_private<_AP_W, _AP_S> And(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL & RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Or(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL | RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Xor(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL ^ RHS.VAL); + } +#if 1 + template + INLINE typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::mult_w <= 64) { + typename RType<_AP_W1, _AP_S1>::mult Result(VAL * RHS.VAL); + return Result; + } else { + typename RType<_AP_W1, _AP_S1>::mult Result = typename RType<_AP_W1, _AP_S1>::mult(*this); + Result *= RHS; + return Result; + } + } +#endif + INLINE ap_private<_AP_W, _AP_S> Mul(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL * RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Add(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL + RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Sub(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL - RHS.VAL); + } + +#if 1 + INLINE ap_private& operator&=(uint64_t RHS) { VAL &= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator|=(uint64_t RHS) { VAL |= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator^=(uint64_t RHS){ VAL ^= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator*=(uint64_t RHS){ VAL *= RHS; clearUnusedBits(); return *this; } + INLINE ap_private& operator+=(uint64_t RHS){ VAL += RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator-=(uint64_t RHS){ VAL -= RHS; clearUnusedBits(); return *this; } + INLINE ap_private operator&(uint64_t RHS) const { return ap_private(VAL & RHS); } + INLINE ap_private operator|(uint64_t RHS) const { return ap_private(VAL | RHS); } + INLINE ap_private operator^(uint64_t RHS) const { return ap_private(VAL ^ RHS); } + INLINE ap_private operator*(uint64_t RHS) const { return ap_private(VAL * RHS); } + INLINE ap_private operator/(uint64_t RHS) const { return ap_private(VAL / RHS); } + INLINE ap_private operator+(uint64_t RHS) const { return ap_private(VAL + RHS); } + INLINE ap_private operator-(uint64_t RHS) const { return ap_private(VAL - RHS); } +#endif + INLINE bool isMinSignedValue() const { + static const uint64_t min_mask = ~(~0ULL << (_AP_W-1)); + return BitWidth == 1 ? VAL == 1 : + (ap_private_ops::isNegative<_AP_W>(*this) && ((min_mask & VAL)==0)); + } + +#if 1 + + template INLINE + typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::plus_w <=64) + return typename RType<_AP_W1,_AP_S1>::plus(RType<_AP_W1,_AP_S1>::plus_s ? int64_t(VAL+RHS.VAL):uint64_t(VAL+RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::plus Result=RHS; + Result += VAL; + return Result; + } + + template INLINE + typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::minus_w <=64) + return typename RType<_AP_W1,_AP_S1>::minus(int64_t(VAL-RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::minus Result=*this; + Result -= RHS; + return Result; + } +#endif // #if 1 + + INLINE ap_private& flip() { + VAL = (~0ULL^VAL)&mask; + clearUnusedBits(); + return *this; + } + + uint32_t countPopulation() const { return CountPopulation_64(VAL);} + uint32_t countLeadingZeros() const { + int remainder = BitWidth % APINT_BITS_PER_WORD; + int excessBits = (APINT_BITS_PER_WORD - remainder) % APINT_BITS_PER_WORD; + //enum { remainder = BitWidth % APINT_BITS_PER_WORD, excessBits = APINT_BITS_PER_WORD - remainder}; + uint32_t Count = CountLeadingZeros_64(VAL); + if (Count) + Count-=excessBits; + return AESL_std::min(Count, (uint32_t)_AP_W); + } + + /// HiBits - This function returns the high "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getHiBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret(*this); + ret = (ret)>>(BitWidth - numBits); + return ret; + } + + /// LoBits - This function returns the low "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getLoBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret((VAL) << (BitWidth - numBits)); + ret = (ret)>>(BitWidth - numBits); + return ret; + //return ap_private(numBits, (VAL << (BitWidth - numBits))>> (BitWidth - numBits)); + } + + ap_private<_AP_W, _AP_S,1>& set(uint32_t bitPosition) { + VAL |= (1ULL << (bitPosition)); + clearUnusedBits(); + return *this; // clearUnusedBits(); + } + + void set() { + VAL = ~0ULL; + clearUnusedBits(); + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + INLINE void set(const ap_private & val) { + operator = (val); + } + + bool operator[](uint32_t bitPosition) const { + return (((1ULL << (bitPosition)) & VAL) != 0); + } + + INLINE void clearUnusedBits(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + VAL = _AP_S ? ((((int64_t)VAL)<<(excess_bits))>> (excess_bits)) : (excess_bits ? ((VAL)<<(excess_bits))>>(excess_bits) : VAL); + } + + INLINE void clearUnusedBitsToZero(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + static uint64_t mask = ~0ULL >> (excess_bits); + VAL &= mask; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> udiv(const ap_private<_AP_W, _AP_S1>& RHS) const { + return ap_private<_AP_W, _AP_S||_AP_S1>(VAL / RHS.VAL); + } + + INLINE ap_private udiv(uint64_t RHS) const { + return ap_private(VAL / RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> sdiv(const ap_private<_AP_W, _AP_S1> & RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS<0) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + template + INLINE ap_private urem(const ap_private<_AP_W, _AP_S2>& RHS) const { + assert(RHS.VAL != 0 && "Divide by 0"); + return ap_private(VAL%RHS.VAL); + } + + INLINE ap_private urem(uint64_t RHS) const { + assert(RHS != 0 && "Divide by 0"); + return ap_private(VAL%RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private srem(const ap_private<_AP_W, _AP_S2>& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + INLINE static void udivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS.VAl; + Remainder = LHS.VAL % RHS.VAL; + } + + INLINE static void udivrem(const ap_private &LHS, uint64_t RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS; + Remainder = LHS.VAL % RHS; + } + + INLINE static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + INLINE static void sdivrem(const ap_private &LHS, int64_t RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS<0) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS<0) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + template INLINE bool eq(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return (*this) == RHS; + } + + template INLINE bool ne(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template INLINE bool ult(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + uint64_t lhsZext = ((uint64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + uint64_t rhsZext = ((uint64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsZext < rhsZext; + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered signed. + /// @brief Signed less than comparison + template INLINE bool slt(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + int64_t lhsSext = ((int64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + int64_t rhsSext = ((int64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsSext < rhsSext; + } + + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template INLINE bool ule(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template INLINE bool sle(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template INLINE bool ugt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template INLINE bool sgt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template INLINE bool uge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template INLINE bool sge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS); + } + + INLINE ap_private abs() const { + if (isNegative()) + return -(*this); + return *this; + } + + ap_private<_AP_W, false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + INLINE static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + return _AP_W; + } + + INLINE uint32_t getActiveBits() const { + uint32_t bits=_AP_W - countLeadingZeros(); + return bits?bits:1; + } + + INLINE double roundToDouble(bool isSigned=false) const { + const static uint64_t mask = ~0ULL << (APINT_BITS_PER_WORD - _AP_W); + return double(VAL); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + //Binary Arithmetic + //----------------------------------------------------------- +#define OP_BIN_AP(Sym,Rty, Fun) \ + template \ + INLINE \ + typename RType<_AP_W2,_AP_S2>::Rty \ + operator Sym (const ap_private<_AP_W2,_AP_S2>& op) const { \ + typename RType<_AP_W2,_AP_S2>::Rty lhs(*this); \ + typename RType<_AP_W2,_AP_S2>::Rty rhs(op); \ + return lhs.Fun(rhs); \ + } \ + + ///Bitwise and, or, xor + //OP_BIN_AP(&,logic, And) + //OP_BIN_AP(|,logic, Or) + //OP_BIN_AP(^,logic, Xor) + +#undef OP_BIN_AP + template + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=*this; + ap_private rhs=op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod (_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + +#define OP_ASSIGN_AP_2(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP_2(/) + OP_ASSIGN_AP_2(%) +#undef OP_ASSIGN_AP_2 + + ///Bitwise assign: and, or, xor + //------------------------------------------------------------- + // OP_ASSIGN_AP(&) + // OP_ASSIGN_AP(^) + // OP_ASSIGN_AP(|) +#undef OP_ASSIGN_AP +#if 1 + + template + INLINE ap_private<_AP_W, _AP_S> + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator << (uint32_t sh) const { + return shl(sh); + } + +#endif + + template + INLINE ap_private<_AP_W, _AP_S> + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator >>(uint32_t sh) const { + ap_private<_AP_W, _AP_S> r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP_3_SINGLE(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op.getVal()); \ + return *this; \ + } + OP_ASSIGN_AP_3_SINGLE(>>) +#undef OP_ASSIGN_AP_3_SINGLE + + ///Comparisons + //----------------------------------------------------------------- + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this==op); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return op < *this; + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this>op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else if (_AP_W < 32 && _AP_W2 < 32) + return lhs.slt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op == *this; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return !(op==*this); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op < (*this); + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op >= *this; + } + + template + INLINE bool operator <(const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op > *this; + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2,_AP_N2>& op) const { + return op <= *this; + } + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S> (*this, (int)index); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return (VAL & mask) == mask; + } + + INLINE bool nand_reduce() const { + return (VAL & mask) != mask; + } + + INLINE bool or_reduce() const { + return (bool)VAL; + } + + INLINE bool nor_reduce() const { + return VAL==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; +template +std::string ap_private<_AP_W, _AP_S, 1>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f" + }; + std::string result; + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, 1> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, 1> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (unsigned)(tmp.VAL & mask); + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, 1> tmp(*this); + ap_private<6, false, 1> divisor(radix); + ap_private<_AP_W, _AP_S, 1> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, 1>(0ULL)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, 1> APdigit = tmp%divisor; + ap_private<_AP_W, false, 1> tmp2 = tmp/divisor; + uint32_t digit = (uint32_t)(APdigit.getZExtValue()); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + return result; + +} + +#endif /* #ifndef LLVM_SUPPORT_MATHEXTRAS_H */ \ No newline at end of file diff --git a/hls_2018/router_03_boardstr/main.cpp b/hls_2018/router_03_boardstr/main.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2de79fc3624c71a11ed8c2513163805ae5c0a5ea --- /dev/null +++ b/hls_2018/router_03_boardstr/main.cpp @@ -0,0 +1,99 @@ +/** + * main.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#ifdef CALCTIME +#include +#include +#endif + +#include "router.hpp" + +#define PRINT_SOLUTION + + +int main(int argc, char *argv[]) { + using namespace std; + + // Test data // + // NL_Q00.txt + //char boardstr[BOARDSTR_SIZE] = "X10Y05Z3L0000107041L0004107002L0102102021L0900100003"; + // NL_Q06.txt + char boardstr[BOARDSTR_SIZE] = "X10Y18Z2L0900109002L0901105012L0902103052L0903103062L0904100102L0905106012L0906109022L0717109102L0808109112L0017209172L0401200072L0912208152L0009201092L0709209092L0901206052L0309204092L0701209072L0101201022L0011202152L0016202162"; + // NL_Q08.txt + //char boardstr[BOARDSTR_SIZE] = "X17Y20Z2L0000103022L1603115052L0916107032L0302108012L1104111042L1002100002L0919116162L1616113182L1001115012L0500201182L1603213152L0600210022"; + char boardstr_high[BOARDSTR_SIZE] = {}; + + // Read boardstr from command line + if (1 < argc) { + // From stdin + if(argv[1][0]!='X') + { + char* c_p=fgets(boardstr, BOARDSTR_SIZE, stdin); + int length=strlen(c_p); + boardstr[length-1]=0; + } + else + { + strcpy(boardstr, argv[1]); + } + } + + // Seed value + int seed = 12345; + if (2 < argc) { + seed = atoi(argv[2]); + } + +#ifdef PRINT_SOLUTION + int size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + int size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + int size_z = (boardstr[7] - '0'); +#endif + + // Solver + ap_int<32> status; + clock_t clock_start, clock_done; + clock_start = clock(); + bool result = pynqrouter(boardstr, boardstr_high, seed, &status); + clock_done = clock(); + if (result) { + cout << endl << "Test Passed!" << endl; + } else { + cout << endl << "Test Failed!" << endl; + } + cout << "status = " << (int)status << endl; + cout << "elapsed = " << ((double)(clock_done - clock_start) / CLOCKS_PER_SEC) << endl << endl; + +#ifdef PRINT_SOLUTION + cout << "SOLUTION" << endl; + cout << "========" << endl; + cout << "SIZE " << size_x << "X" << size_y << "X" << size_z << endl; + for (int z = 0; z < size_z; z++) { + cout << "LAYER " << (z + 1) << endl; + for (int y = 0; y < size_y; y++) { + for (int x = 0; x < size_x; x++) { + if (x != 0) { + cout << ","; + } + int i = ((x * MAX_WIDTH + y) << BITWIDTH_Z) | z; + unsigned int num = (unsigned char)(boardstr[i]) + ((unsigned char)(boardstr_high[i]) << 8); + cout << setfill('0') << setw(3) << right << num; + //cout << num; + } + cout << endl; + } + } +#endif + + return 0; +} + diff --git a/hls_2018/router_03_boardstr/router.cpp b/hls_2018/router_03_boardstr/router.cpp new file mode 100755 index 0000000000000000000000000000000000000000..93ea27366574b27014a5f04347b22d7f467e3093 --- /dev/null +++ b/hls_2018/router_03_boardstr/router.cpp @@ -0,0 +1,518 @@ +/** + * router.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#include "./router.hpp" + +// Set weight +ap_uint<8> new_weight(ap_uint<16> x) { +#pragma HLS INLINE + // K. Terada: y = 1~32 (8bit) + ap_uint<8> y; + y = ((x & 255) >> 3) + 1; + return y; +} + + +// Global values +static ap_uint<7> size_x; // X +static ap_uint<7> size_y; // Y +static ap_uint<4> size_z; // Z + +static ap_uint line_num = 0; // #Lines + +#ifdef DEBUG_PRINT +int max_queue_length; // Max length of priority queue +int max_search_count; // Max count of queue pop +int max_buffer_length; // Max length of line buffer +#endif + + +bool pynqrouter(char boardstr[BOARDSTR_SIZE], char boardstr_high[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status) { +#pragma HLS INTERFACE s_axilite port=boardstr bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=boardstr_high bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=seed bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=status bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=return bundle=AXI4LS + + // status(0:Solved, 1:Not solved) + *status = -1; + + // For all lines + ap_uint paths[MAX_BUFFER]; // Line buffer + + // For each line + // Note: Should not partition completely + bool adjacents[MAX_LINES]; // Line has adjacent terminals? + ap_uint starts[MAX_LINES]; // Start list + ap_uint goals[MAX_LINES]; // Goal list + ap_uint s_idx[MAX_LINES]; // Start point on line buffer + + ap_uint<8> weights[MAX_CELLS]; // Weight of each cell + // Note: Should not partition weight array + // since each element will be accessed in "random" order + + + // ================================ + // (Step.0) Initialization (BEGIN) + // ================================ + + // Note: Loop counter -> need an extra bit (for condition determination) + + INIT_WEIGHTS: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + weights[i] = 1; + } + + /// Parse /// + size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + size_z = (boardstr[7] - '0'); + + INIT_BOARDS: + for (ap_uint idx = 8; idx < (ap_uint)(BOARDSTR_SIZE); idx+=11) { + + // NULL-terminated + if (boardstr[idx] == 0) break; + + // Start & Goal of each line + ap_uint<7> s_x = (boardstr[idx+1] - '0') * 10 + (boardstr[idx+2] - '0'); + ap_uint<7> s_y = (boardstr[idx+3] - '0') * 10 + (boardstr[idx+4] - '0'); + ap_uint<3> s_z = (boardstr[idx+5] - '0') - 1; + ap_uint<7> g_x = (boardstr[idx+6] - '0') * 10 + (boardstr[idx+7] - '0'); + ap_uint<7> g_y = (boardstr[idx+8] - '0') * 10 + (boardstr[idx+9] - '0'); + ap_uint<3> g_z = (boardstr[idx+10] - '0') - 1; + + ap_uint start_id = (((ap_uint)s_x * MAX_WIDTH + (ap_uint)s_y) << BITWIDTH_Z) | (ap_uint)s_z; + ap_uint goal_id = (((ap_uint)g_x * MAX_WIDTH + (ap_uint)g_y) << BITWIDTH_Z) | (ap_uint)g_z; + starts[line_num] = start_id; + goals[line_num] = goal_id; + weights[start_id] = MAX_WEIGHT; + weights[goal_id] = MAX_WEIGHT; + + // Line has adjacent terminals? + adjacents[line_num] = false; + ap_int<8> dx = (ap_int<8>)g_x - (ap_int<8>)s_x; // Min: -71, Max: 71 (Signed 8bit) + ap_int<8> dy = (ap_int<8>)g_y - (ap_int<8>)s_y; // Min: -71, Max: 71 (Signed 8bit) + ap_int<4> dz = (ap_int<4>)g_z - (ap_int<4>)s_z; // Min: -7, Max: 7 (Signed 4bit) + if ((dx == 0 && dy == 0 && (dz == 1 || dz == -1)) || (dx == 0 && (dy == 1 || dy == -1) && dz == 0) || ((dx == 1 || dx == -1) && dy == 0 && dz == 0)) { + adjacents[line_num] = true; + } + + line_num++; + } + + // ================================ + // (Step.0) Initialization (END) + // ================================ + +#ifdef DEBUG_PRINT + max_queue_length = 0; + max_search_count = 0; + max_buffer_length = 0; +#endif + + ap_uint pointer = 0; // Pointer for line buffer + + // ================================ + // (Step.1) Initial Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Initial Routing ..." << endl; +#endif + + FIRST_ROUTING: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + + s_idx[i] = pointer; + + if (adjacents[i] == true) continue; // Skip routing + +#ifdef DEBUG_PRINT + //cout << "LINE #" << (int)(i + 1) << endl; +#endif + // Routing + pointer = search(s_idx[i], paths, starts[i], goals[i], weights); + } + + // ================================ + // (Step.1) Initial Routing (END) + // ================================ + + + // Memories for Overlap Check + ap_uint<1> overlap_checks[MAX_CELLS]; + bool has_overlap = false; + + // ================================ + // (Step.2) Rip-up Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Rip-up Routing ..." << endl; +#endif + + ROUTING: + for (ap_uint<16> round = 0; round < 32768 /* = (2048 * 16) */; round++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=32768 + + // Target line + ap_uint target = round % line_num; + ap_uint next_target = target + 1; + if (next_target == line_num) next_target = 0; + +#ifdef DEBUG_PRINT + //cout << "(round " << round << ") LINE #" << (int)(target + 1); + //cout << " -> " << pointer << endl; +#endif +#ifdef DEBUG_PRINT + int buffer_length = pointer - s_idx[target]; + if (max_buffer_length < buffer_length) { max_buffer_length = buffer_length; } +#endif + + // Skip routing + if (adjacents[target] == true) { + s_idx[target] = pointer; continue; + } + + + // (Step.2-1) Reset weights of target line + WEIGHT_RESET: + for (ap_uint j = s_idx[target]; j != s_idx[next_target]; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + weights[paths[j]] = 1; + } + + // (Step.2-2) Set weights of non-target lines and terminals + ap_uint<8> current_round_weight = new_weight(round); + WEIGHT_PATH: + for (ap_uint j = s_idx[next_target]; j != pointer; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=8192 + weights[paths[j]] = current_round_weight; + } + WEIGHT_TERMINAL: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + weights[starts[i]] = MAX_WEIGHT; + weights[goals[i]] = MAX_WEIGHT; + } + // Reset weight of start terminal of target line (bug avoiding) + // Restore original settings in (*) + weights[starts[target]] = 1; + + // (Step.2-3) Routing + s_idx[target] = pointer; + pointer = search(s_idx[target], paths, starts[target], goals[target], weights); + + // (*) + weights[starts[target]] = MAX_WEIGHT; + +#ifdef DEBUG_PRINT + bool ng = false; + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { + if (weights[starts[i]] != 255 || weights[goals[i]] != 255) { + cout << i << " "; ng = true; + } + } + if(ng) { cout << endl; } +#endif + + // (Step.2-4) Overlap check + has_overlap = false; + OVERLAP_RESET: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + overlap_checks[i] = 0; + } + OVERLAP_CHECK_LINE: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + overlap_checks[starts[i]] = 1; + overlap_checks[goals[i]] = 1; + } + OVERLAP_CHECK_PATH: + for (ap_uint j = s_idx[next_target]; j != pointer; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=8192 + ap_uint cell_id = paths[j]; + if (overlap_checks[cell_id]) { + has_overlap = true; break; + } + overlap_checks[cell_id] = 1; + } +#ifdef DEBUG_PRINT + if(!has_overlap){ cout << "ROUND: " << round << endl; } +#endif + if (!has_overlap) break; // Finish routing? + } + +#ifdef DEBUG_PRINT + cout << "MAX PQ LENGTH: " << max_queue_length << endl; + cout << "MAX SEARCH COUNT: " << max_search_count << endl; + cout << "MAX BUFFER: " << max_buffer_length << endl; +#endif + + // Not solved + if (has_overlap) { + *status = 1; return false; + } + + // ================================ + // (Step.2) Rip-up Routing (END) + // ================================ + + + // ================================ + // (Step.3) Output (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Output ..." << endl; +#endif + + // Init: Blank = 0 + OUTPUT_INIT: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + boardstr[i] = 0; + boardstr_high[i] = 0; + } + // Line + OUTPUT_LINE: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + boardstr[starts[i]] = (i + 1); + boardstr[goals[i]] = (i + 1); + boardstr_high[starts[i]] = (i + 1) >> 8; + boardstr_high[goals[i]] = (i + 1) >> 8; + + ap_uint p1; // p1: s_idx of target + ap_uint p2; // p2: s_idx of next target + p1 = s_idx[i]; + if (i == (ap_uint)(line_num-1)) { + p2 = s_idx[0]; + } + else { + p2 = s_idx[i+1]; + } + if ((ap_uint)(p2 - p1) > 8192){ + p2 = pointer; + } + OUTPUT_LINE_PATH: + for (ap_uint j = p1; j != p2; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + boardstr[paths[j]] = (i + 1); + boardstr_high[paths[j]] = (i + 1) >> 8; + } + } + + // ================================ + // (Step.3) Output (END) + // ================================ + + *status = 0; return true; +} + + +// ================================ // +// For Routing +// ================================ // + +// Max: 71, Min: 0 (7bit) +ap_uint<7> abs_uint7(ap_uint<7> a, ap_uint<7> b) { +#pragma HLS INLINE + if (a < b) { return b - a; } + else { return a - b; } +} +// Max: 7, Min: 0 (3bit) +ap_uint<3> abs_uint3(ap_uint<3> a, ap_uint<3> b) { +#pragma HLS INLINE + if (a < b) { return b - a; } + else { return a - b; } +} + +// Reference codes: +// http://lethe2211.hatenablog.com/entry/2014/12/30/011030 +// http://www.redblobgames.com/pathfinding/a-star/implementation.html +// Need to modify "array partition factor" +ap_uint search(ap_uint idx, ap_uint paths[MAX_BUFFER], ap_uint start, ap_uint goal, ap_uint<8> w[MAX_CELLS]) { + + ap_uint dist[MAX_CELLS]; + ap_uint prev[MAX_CELLS]; + + SEARCH_INIT_DIST: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + dist[i] = 65535; // = (2^16 - 1) + } + + // Priority queue (Heap) + ap_uint pq_len = 0; + bool is_empty = true; + ap_uint<32> pq_nodes[MAX_PQ]; + +#ifdef DEBUG_PRINT + int queue_length = 0; + int search_count = 0; +#endif + + // Point of goal terminal + ap_uint<13> goal_xy = (ap_uint<13>)(goal >> BITWIDTH_Z); + ap_uint<7> goal_x = (ap_uint<7>)(goal_xy / MAX_WIDTH); + ap_uint<7> goal_y = (ap_uint<7>)(goal_xy - goal_x * MAX_WIDTH); + ap_uint<3> goal_z = (ap_uint<3>)(goal & BITMASK_Z); + + dist[start] = 0; + pq_push(pq_nodes, 0, start, &pq_len, &is_empty); // push start terminal + + SEARCH_PQ: + while (!is_empty) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=1000 +#pragma HLS LOOP_FLATTEN off + + ap_uint<16> prev_cost; + ap_uint<16> src; // target cell + pq_pop(pq_nodes, &prev_cost, &src, &pq_len, &is_empty); +#ifdef DEBUG_PRINT + search_count++; +#endif + + + // End routing + if (src == goal) break; + + + // Target cell + ap_uint<16> dist_src = dist[src]; + ap_uint<8> cost = w[src]; + // Point of target cell + ap_uint<13> src_xy = (ap_uint<13>)(src >> BITWIDTH_Z); + ap_uint<7> src_x = (ap_uint<7>)(src_xy / MAX_WIDTH); + ap_uint<7> src_y = (ap_uint<7>)(src_xy - src_x * MAX_WIDTH); + ap_uint<3> src_z = (ap_uint<3>)(src & BITMASK_Z); + + // Search adjacent cells + SEARCH_ADJACENTS: + for (ap_uint<3> a = 0; a < 6; a++) { + ap_int<8> dest_x = (ap_int<8>)src_x; // Min: -1, Max: 72 (Signed 8bit) + ap_int<8> dest_y = (ap_int<8>)src_y; // Min: -1, Max: 72 (Signed 8bit) + ap_int<5> dest_z = (ap_int<5>)src_z; // Min: -1, Max: 8 (Signed 5bit) + if (a == 0) { dest_x -= 1; } + if (a == 1) { dest_x += 1; } + if (a == 2) { dest_y -= 1; } + if (a == 3) { dest_y += 1; } + if (a == 4) { dest_z -= 1; } + if (a == 5) { dest_z += 1; } + + // Inside the board ? // + if (0 <= dest_x && dest_x < (ap_int<8>)size_x && 0 <= dest_y && dest_y < (ap_int<8>)size_y && 0 <= dest_z && dest_z < (ap_int<5>)size_z) { + // Adjacent cell + ap_uint<16> dest = (((ap_uint<16>)dest_x * MAX_WIDTH + (ap_uint<16>)dest_y) << BITWIDTH_Z) | (ap_uint<16>)dest_z; + ap_uint<16> dist_new = dist_src + cost; + + if (dist[dest] > dist_new) { + dist[dest] = dist_new; // Update dist + prev[dest] = src; // Recode previous cell + dist_new += abs_uint7(dest_x, goal_x) + abs_uint7(dest_y, goal_y) + abs_uint3(dest_z, goal_z); // A* heuristic + pq_push(pq_nodes, dist_new, dest, &pq_len, &is_empty); // push adjacent cell + } + } + } +#ifdef DEBUG_PRINT + if (queue_length < pq_len) { queue_length = pq_len; } +#endif + } + + // Output target path + // Note: Do not include start & goal terminals + ap_uint<16> t = prev[goal]; + + // Backtracking + ap_uint p = idx; // buffer-idx + SEARCH_BACKTRACK: + while (t != start) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + paths[p] = t; + p++; + t = prev[t]; + } + +#ifdef DEBUG_PRINT + if (max_queue_length < queue_length) { max_queue_length = queue_length; } + if (max_search_count < search_count) { max_search_count = search_count; } +#endif + + return p; +} + +// Queue push (Enqueue) +// Need to modify "trip count" (1) +void pq_push(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> priority, ap_uint<16> data, ap_uint *pq_len, bool *is_empty) { +#pragma HLS INLINE + + (*pq_len)++; + if ((*pq_len) == 0) { (*pq_len)--; } // Queue is full -> Last element is automatically removed + + // Binary search for circular list + ap_uint i = (*pq_len); + ap_uint p = (*pq_len) >> 1; // parent node + PQ_PUSH_LOOP: + while (i > 1 && (ap_uint<16>)(pq_nodes[p] & PQ_PRIORITY_MASK) >= priority) { +#pragma HLS LOOP_TRIPCOUNT min=0 max=15 +/** Set!: min=0 max=PQ_BIT **/ + pq_nodes[i] = pq_nodes[p]; + i = p; + p = p >> 1; // parent node + } + pq_nodes[i] = ((ap_uint<32>)data << PQ_PRIORITY_WIDTH) | (ap_uint<32>)priority; + *is_empty = false; +} + +// Queue pop (Dequeue) +// Need to modify "trip count" (1) +void pq_pop(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint *pq_len, bool *is_empty) { +#pragma HLS INLINE + + *ret_priority = (ap_uint<16>)(pq_nodes[1] & PQ_PRIORITY_MASK); + *ret_data = (ap_uint<16>)(pq_nodes[1] >> PQ_PRIORITY_WIDTH); + + ap_uint i = 1; // root node + ap_uint last_priority = (ap_uint<16>)(pq_nodes[*pq_len] & PQ_PRIORITY_MASK); // Priority of last element + + PQ_POP_LOOP: + while (!(i >> (PQ_BIT-1))) { // (2018.08.24) Loop condition fixed +#pragma HLS LOOP_TRIPCOUNT min=1 max=15 +/** Set!: min=0 max=PQ_BIT **/ + ap_uint c1 = i << 1; // child node(left) + ap_uint c2 = c1 + 1; // child node(right) + if (c1 < *pq_len && (ap_uint<16>)(pq_nodes[c1] & PQ_PRIORITY_MASK) <= last_priority) { + if (c2 < *pq_len && (ap_uint<16>)(pq_nodes[c2] & PQ_PRIORITY_MASK) <= (ap_uint<16>)(pq_nodes[c1] & PQ_PRIORITY_MASK)) { + pq_nodes[i] = pq_nodes[c2]; + i = c2; + } + else { + pq_nodes[i] = pq_nodes[c1]; + i = c1; + } + } + else { + if (c2 < *pq_len && (ap_uint<16>)(pq_nodes[c2] & PQ_PRIORITY_MASK) <= last_priority) { + pq_nodes[i] = pq_nodes[c2]; + i = c2; + } + else { + break; + } + } + } + pq_nodes[i] = pq_nodes[*pq_len]; + (*pq_len)--; + if ((*pq_len) == 0) { *is_empty = true; } +} + diff --git a/hls_2018/router_03_boardstr/router.hpp b/hls_2018/router_03_boardstr/router.hpp new file mode 100755 index 0000000000000000000000000000000000000000..cdc6ef0da5145c01c3eb17371973cab305cd76b2 --- /dev/null +++ b/hls_2018/router_03_boardstr/router.hpp @@ -0,0 +1,56 @@ +/** + * router.hpp + * + * for Vivado HLS + */ + +#ifndef __ROUTER_HPP__ +#define __ROUTER_HPP__ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +//#define DEBUG_PRINT // for debug + +#ifdef DEBUG_PRINT +using namespace std; +#endif + +// Parameters +#define MAX_WIDTH 72 // Max of X, Y +#define BITWIDTH_XY 13 +#define BITMASK_XY 65528 // 1111 1111 1111 1000 +#define MAX_LAYER 8 // Max of Z +#define BITWIDTH_Z 3 +#define BITMASK_Z 7 // 0000 0000 0000 0111 + +#define MAX_CELLS 41472 // Max #cells (16bit) +#define MAX_LINES 1024 // Max #lines (10bit) +#define MAX_PQ 32768 // Queue size (15bit) +#define MAX_BUFFER 16384 // Line buffer size (14bit) +#define CELL_BIT 16 +#define LINE_BIT 10 +#define PQ_BIT 15 +#define BUFF_BIT 14 + +#define PQ_PRIORITY_WIDTH 16 +#define PQ_PRIORITY_MASK 65535 // 0000 0000 0000 0000 1111 1111 1111 1111 +#define PQ_DATA_WIDTH 16 +#define PQ_DATA_MASK 4294901760 // 1111 1111 1111 1111 0000 0000 0000 0000 + +#define MAX_WEIGHT 255 // Max weight +#define BOARDSTR_SIZE 41472 // Size of I/O + +ap_uint<8> new_weight(ap_uint<16> x); +bool pynqrouter(char boardstr[BOARDSTR_SIZE], char boardstr_high[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status); + +ap_uint<7> abs_uint7(ap_uint<7> a, ap_uint<7> b); +ap_uint<3> abs_uint3(ap_uint<3> a, ap_uint<3> b); +ap_uint search(ap_uint idx, ap_uint paths[MAX_BUFFER], ap_uint start, ap_uint goal, ap_uint<8> w[MAX_WEIGHT]); +void pq_push(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> priority, ap_uint<16> data, ap_uint *pq_len, bool *is_empty); +void pq_pop(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint *pq_len, bool *is_empty); + +#endif /* __ROUTER_HPP__ */ diff --git a/hls_2018/router_04/Makefile b/hls_2018/router_04/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..8f79e7a62ede483ae7dcda810f306a02f915dfbb --- /dev/null +++ b/hls_2018/router_04/Makefile @@ -0,0 +1,20 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -o $@ $(OBJS) + +run: + python3 ../NLGenerator.py -x 20 -y 20 -z 6 -l 100;\ + python3 ./gen_boardstr.py Q-20x20x5_100_10.txt |\ + ./$(TARGET) - + + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_04/Makefile.cygwin b/hls_2018/router_04/Makefile.cygwin new file mode 100755 index 0000000000000000000000000000000000000000..866fdcdf2ea6a5fb67d1461ce4a19e353d0c9216 --- /dev/null +++ b/hls_2018/router_04/Makefile.cygwin @@ -0,0 +1,14 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -Wl,--stack,33554432 -o $@ $(OBJS) + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_04/ap_int.h b/hls_2018/router_04/ap_int.h new file mode 100755 index 0000000000000000000000000000000000000000..b8d9fdc96ac3f7eb9c86cc55d0eac0a57bf670b5 --- /dev/null +++ b/hls_2018/router_04/ap_int.h @@ -0,0 +1,521 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_AP_SIM_H__ +#define __AESL_AP_SIM_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#else + +#include "etc/ap_int_sim.h" +#include "etc/ap_fixed_sim.h" + +//Forward declaration +template class ap_fixed; +template class ap_ufixed; +template class ap_int; +template class ap_uint; + +//AP_INT +//-------------------------------------------------------- +template +class ap_int : public ap_private<_AP_W, true> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_private<_AP_W, true> Base; + + //Constructor + INLINE ap_int(): Base() {} + template + INLINE ap_int(const volatile ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_int(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_int(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_int(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE void operator = (const volatile ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE ap_int<_AP_W>& operator = (const volatile ap_int<_AP_W>& op2) { + Base::operator = (const_cast& >(op2)); + return *this; + } + + INLINE ap_int<_AP_W>& operator = (const ap_int<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, true>&)op2); + return *this; + } +}; + +//AP_UINT +//--------------------------------------------------------------- +template +class ap_uint: public ap_private<_AP_W, false> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_private<_AP_W, false> Base; + //Constructor + INLINE ap_uint(): Base() {} + INLINE ap_uint(const ap_uint<_AP_W>& op) :Base(dynamic_cast&>(op)) {} + INLINE ap_uint(const volatile ap_uint<_AP_W>& op):Base(dynamic_cast&>(op)){} + template + INLINE ap_uint(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_uint<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)){} + + template + INLINE ap_uint(const ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_uint(const volatile ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op) {} + + template + INLINE ap_uint(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_uint(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_uint(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_uint(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE void operator = (const volatile ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE ap_uint<_AP_W>& operator = (const volatile ap_uint<_AP_W>& op2) { + Base::operator = (op2); + return *this; + } + + INLINE ap_uint<_AP_W>& operator = (const ap_uint<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, false>&)(op2)); + return *this; + } +}; + +#define ap_bigint ap_int +#define ap_biguint ap_uint + +//AP_FIXED +//--------------------------------------------------------------------- +template +class ap_fixed: public ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> Base; + //Constructor + INLINE ap_fixed():Base() {} + + template + INLINE ap_fixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const ap_uint<_AP_W2>& op):Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_fixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const volatile ap_uint<_AP_W2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_fixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_fixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_fixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_fixed& operator = (const ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_fixed& operator = (const volatile ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } +}; + +//AP_ UFIXED +//--- ---------------------------------------------------------------- +template +class ap_ufixed : public ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> Base; + + //Constructor + INLINE ap_ufixed():Base() {} + + template + INLINE ap_ufixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_int<_AP_W2>& op): + Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_ufixed(const ap_uint<_AP_W2>& op): + Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_ufixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_uint<_AP_W2>& op): + Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_ufixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_ufixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_ufixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_ufixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_ufixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_ufixed& operator = (const ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_ufixed& operator = (const volatile ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::V = const_cast(op); + return *this; + } +}; + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_int<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_uint<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_fixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_ufixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif /* #if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) */ +#endif /* #ifndef __cplusplus */ +#endif /* #ifndef __AESL_AP_SIM_H__ */ \ No newline at end of file diff --git a/hls_2018/router_04/etc/ap_fixed_sim.h b/hls_2018/router_04/etc/ap_fixed_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..5be571dd70e490d282d279a4eeed32db069703e9 --- /dev/null +++ b/hls_2018/router_04/etc/ap_fixed_sim.h @@ -0,0 +1,2451 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_FIXED_H__ +#define __AESL_GCC_AP_FIXED_H__ + +#ifndef __cplusplus + #error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + + +#include +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_int_sim.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#define FLOAT_MAN 23 +#define FLOAT_EXP 8 +#define DOUBLE_MAN 52 +#define DOUBLE_EXP 11 +// #define DOUBLE_MAN_MASK (~0ULL >> (64-DOUBLE_MAN-2)) +#define DOUBLE_MAN_MASK 0x3fffffffffffffULL +#define BIAS(e) ((1ULL<<(e-1))-1) +#define FLOAT_BIAS BIAS(FLOAT_EXP) +#define DOUBLE_BIAS BIAS(DOUBLE_EXP) + +/// Forward declaration. +template struct ap_fixed_base; + +///Proxy class, which allows bit selection to be used as both rvalue(for reading) and +//lvalue(for writing) +template +struct af_bit_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& d_bv; + int d_index; +public: + INLINE af_bit_ref(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE af_bit_ref(ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>* bv, int index=0): + d_bv(*bv),d_index(index) {} + + INLINE operator bool() const { + return d_bv.V[d_index]; + } + + INLINE af_bit_ref& operator=(unsigned long long val) { + if (val) + d_bv.V.set(d_index); + else + d_bv.V.clear(d_index); + return *this; + } + + template + INLINE af_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + return operator=(val!=0); + } + + INLINE af_bit_ref& operator =(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref operator=(const af_bit_ref<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref& operator = ( const ap_bit_ref<_AP_W2, _AP_S2> &val) { + return operator =((unsigned long long) (bool) val); + } + + template + INLINE af_bit_ref& operator = ( const ap_range_ref<_AP_W2,_AP_S2>& val) { + return operator =((const ap_private<_AP_W2, false>) val); + } + + template + INLINE af_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE af_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2> >(*this, const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + template + INLINE bool operator == (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() != op.get(); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv.V)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { + return 1; + } + + INLINE bool get() { + return d_bv.V[d_index]; + } + + INLINE bool get() const { + return d_bv.V[d_index]; + } + + INLINE std::string to_string() const { + return d_bv.V[d_index] ? "1" : "0"; + } +}; + +///Range(slice) reference +//------------------------------------------------------------ +template +struct af_range_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &d_bv; + int l_index; + int h_index; + +public: + INLINE af_range_ref(const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE af_range_ref(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + // fprintf(stderr, + //"Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + if (h_index >= l_index) { + ap_private<_AP_W, false> val(d_bv.V); + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + return val&=mask; + } else { + ap_private<_AP_W, false> val = 0; + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } + } + + INLINE operator unsigned long long() const { + return get().to_uint64(); + } + + template + INLINE af_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W, false> vval= ap_private<_AP_W, false>(val); + if (l_index > h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv.V &= mask; + d_bv.V |= vval; + } + return *this; + } + + INLINE af_range_ref& operator = (unsigned long long val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE af_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + const ap_private<_AP_W2, false> tmp= val.get(); + return operator = (tmp); + } + + INLINE af_range_ref& operator= (const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + const ap_private<_AP_W, false> tmp= val.get(); + return operator = (tmp); + } + + template + INLINE af_range_ref& operator= (const ap_fixed_base<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE bool operator == (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE void set(const ap_private<_AP_W2,false>& val) { + ap_private<_AP_W,_AP_S> vval=val; + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,_AP_S> mask(-1); + if (l_index>0) { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } + + } + + INLINE ap_private<_AP_W,false> get() const { + if (h_index val(0); + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } else { + ap_private<_AP_W, false> val = ap_private<_AP_W,false>(d_bv.V); + val>>= l_index; + if (h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + return val; + } + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& > (op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + INLINE int length() const { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + INLINE int to_int() const { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + INLINE unsigned int to_uint() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + INLINE long to_long() const { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + INLINE unsigned long to_ulong() const { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + INLINE ap_slong to_int64() const { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + INLINE ap_ulong to_uint64() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix) const { + return get().to_string(radix); + } + +}; + +//----------------------------------------------------------------------------- +///ap_fixed_base: AutoPilot fixed point +//----------------------------------------------------------------------------- +template +struct ap_fixed_base { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + template friend struct +ap_fixed_base; + template friend struct +af_bit_ref; + + INLINE void overflow_adjust(bool underflow, bool overflow, + bool lD, bool sign) { + if (!overflow && !underflow) return; + switch (_AP_O) { + case AP_WRAP: + if (_AP_N == 0) + return; + if (_AP_S) { + //signed SC_WRAP + //n_bits == 1; + if (_AP_N > 1) { + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= ~mask; + } + sign ? V.set(_AP_W - 1) : V.clear(_AP_W - 1); + } else { + //unsigned SC_WRAP + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + mask.flip(); + V |= mask; + } + break; + case AP_SAT_ZERO: + V.clear(); + break; + case AP_WRAP_SM: + { + bool Ro = ap_private_ops::get<_AP_W, _AP_S, _AP_W -1>(V); // V[_AP_W -1]; + if (_AP_N == 0) { + if (lD != Ro) { + V.flip(); + lD ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : + ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } else { + if (_AP_N == 1 && sign != Ro) { + V.flip(); + } else if (_AP_N > 1) { + bool lNo = ap_private_ops::get<_AP_W, _AP_S, _AP_W - _AP_N> (V); // V[_AP_W - _AP_N]; + if (lNo == sign) + V.flip(); + ap_private<_AP_W, false> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= mask.flip(); + sign ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } + } + break; + default: + if (_AP_S) { + if (overflow) { + V.set(); ap_private_ops::clear<_AP_W, _AP_S, _AP_W-1>(V); + } else if (underflow) { + V.clear(); + ap_private_ops::set<_AP_W, _AP_S, _AP_W-1>(V); + if (_AP_O == AP_SAT_SYM) + ap_private_ops::set<_AP_W, _AP_S, 0>(V); + } + } else { + if (overflow) + V.set(); + else if (underflow) + V.clear(); + } + } + } + + INLINE bool quantization_adjust(bool qb, bool r, bool s) { + bool carry=ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V); + switch (_AP_Q) { + case AP_TRN: + return false; + case AP_RND_ZERO: + qb &= s || r; + break; + case AP_RND_MIN_INF: + qb &= r; + break; + case AP_RND_INF: + qb &= !s || r; + break; + case AP_RND_CONV: + qb &= ap_private_ops::get<_AP_W, _AP_S, 0>(V) || r; + break; + case AP_TRN_ZERO: + qb = s && ( qb || r ); + break; + default:; + + } + if (qb) ++V; + //only when old V[_AP_W-1]==1 && new V[_AP_W-1]==0 + return carry && !(ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V)); //(!V[_AP_W-1]); + } + + template + struct RType { + enum { + _AP_F=_AP_W-_AP_I, + F2=_AP_W2-_AP_I2, + mult_w = _AP_W+_AP_W2, + mult_i = _AP_I+_AP_I2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + plus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + minus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + minus_s = true, +#ifndef __SC_COMPATIBLE__ + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2, +#else + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2 + AP_MAX(_AP_I2, 0), +#endif /* #ifndef __SC_COMPATIBLE__ */ + div_i = _AP_I + (_AP_W2-_AP_I2) + _AP_S2, + div_s = _AP_S||_AP_S2, + logic_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+AP_MAX(_AP_F,F2), + logic_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + + typedef ap_fixed_base mult; + typedef ap_fixed_base plus; + typedef ap_fixed_base minus; + typedef ap_fixed_base logic; + typedef ap_fixed_base div; + typedef ap_fixed_base<_AP_W, _AP_I, _AP_S> arg1; + }; + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024):" + " for synthesis, please define macro AP_INT_TYPE_EXT(N) to" + " extend the valid range.\n", _AP_W); + } else +#endif /* #if 0 */ + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sfixed<%d, ...>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + /// Constructors. + // ------------------------------------------------------------------------- +#if 0 + #ifdef __SC_COMPATIBLE__ + INLINE ap_fixed_base():V(uint32_t(_AP_W), uint64_t(0)) {} + #else + INLINE ap_fixed_base():V(uint32_t(_AP_W)) {} + #endif /* #ifdef __SC_COMPATIBLE__ */ +#else + INLINE ap_fixed_base():V(0) {} +#endif /* #if 0 */ + // INLINE ap_fixed_base():V() {} + // INLINE explicit ap_fixed_base(const ap_private<_AP_W+_AP_I, _AP_S>& _V):V(_V) {} + INLINE ap_fixed_base(const ap_fixed_base& op):V(op.V) {} + template + INLINE ap_fixed_base(const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op):V(0) { + enum {N2=_AP_W2,_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2,QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || + (_AP_Q==AP_TRN_ZERO && !_AP_S2))}; + if (!op) return; + bool carry=false; + //handle quantization + enum { sh_amt =(F2>_AP_F)?F2-_AP_F:_AP_F-F2}; + const ap_private<_AP_W2, _AP_S2>& val = op.V; + bool neg_src=val.isNegative(); + if (F2==_AP_F) + V=val; + + else if (F2>_AP_F) { + if (sh_amt >= _AP_W2) + V = neg_src ? -1 : 0; + else + V = _AP_S2?val.ashr(sh_amt):val.lshr(sh_amt); + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + bool qb = false; + if (F2-_AP_F>_AP_W2) + qb = neg_src; + else + qb = ap_private_ops::get<_AP_W2, _AP_S2, F2-_AP_F-1>(val); + + bool r=false; + enum { pos3 = F2-_AP_F-2}; + if (pos3>=_AP_W2-1) + r=val!=0; + else if (pos3>=0) + r = (val<<(_AP_W2-1-pos3))!=0; + carry = quantization_adjust(qb,r,neg_src); + } + } else { //no quantization + if (sh_amt < _AP_W) { + V=val; + V <<= sh_amt; + } + } + //hanle overflow/underflow + if ((_AP_O!=AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2 - _AP_S2 + (QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)))) {//saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool lD=(_AP_I2>_AP_I && _AP_W2-_AP_I2+_AP_I>=0) && + ap_private_ops::get<_AP_W2, _AP_S2, _AP_W2-_AP_I2+_AP_I>(val); + enum { pos1=F2-_AP_F+_AP_W, pos2=F2-_AP_F+_AP_W+1}; + if (pos1 < _AP_W2) { + bool Range1_all_ones= true; + bool Range1_all_zeros= true; + if (pos1 >= 0) { + enum { __W = (_AP_W2-pos1) > 0 ? (_AP_W2-pos1) : 1 }; + const ap_private<__W, _AP_S2> Range1=ap_private<__W, _AP_S2>(val.lshr(pos1)); + Range1_all_ones=Range1.isAllOnesValue(); + Range1_all_zeros=Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros=val.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + enum { __W = (_AP_W2-pos2)>0 ? (_AP_W2-pos2) : 1}; + ap_private<__W, true> Range2=ap_private<__W, true>(val.lshr(pos2)); + Range2_all_ones=Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) + :Range1_all_ones; + neg_src= neg_src&&!(carry && Range1_all_ones); + } else + neg_src = neg_src && V[_AP_W-1]; + + bool neg_trg= V.isNegative(); + bool overflow=(neg_trg||!deleted_zeros) && !val.isNegative(); + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow, overflow, lD, neg_src); + } + report(); + } + + template + INLINE ap_fixed_base(const volatile ap_fixed_base<_AP_W2,_AP_I2, + _AP_S2,_AP_Q2,_AP_O2, _AP_N2> &op) : V(op.V) { + *this = const_cast&>(op); + } + + template + INLINE ap_fixed_base(const ap_private<_AP_W2,_AP_S2>& op) { + ap_fixed_base<_AP_W2,_AP_W2,_AP_S2> f_op; + f_op.V=op; + *this = f_op; + } + + INLINE ap_fixed_base(bool b) { + *this=(ap_private<1,false>)b; + report(); + } + + INLINE ap_fixed_base(char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed char b) { + *this=(ap_private<8,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed short b) { + *this=(ap_private<16,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned short b) { + *this=(ap_private<16,false>)b; + report(); + } + + INLINE ap_fixed_base(signed int b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned int b) { + *this=(ap_private<32,false>)b; + report(); + } +# if defined __x86_64__ + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<64,false>)b; + report(); + } +# else + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<32,false>)b; + report(); + } +# endif + + INLINE ap_fixed_base(ap_slong b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(ap_ulong b) { + *this=(ap_private<64,false>)b; + report(); + } + +#if 1 + INLINE ap_fixed_base(const char* val):V(0) { + ap_private<_AP_W, _AP_S> Tmp(val); + V = Tmp; + } + + INLINE ap_fixed_base(const char* val, signed char rd): V(0) { + ap_private<_AP_W, _AP_S> Tmp(val, rd); + V = Tmp; + } + +#endif + + INLINE ap_fixed_base(const std::string& val) { + ap_private<_AP_W, _AP_S> Tmp(val, 2); + V = Tmp; + report(); + } + + template + INLINE ap_fixed_base(const ap_bit_ref<_AP_W2, _AP_S2>& op) { + *this = ((bool)op); + report(); + } + + template + INLINE ap_fixed_base(const ap_range_ref<_AP_W2, _AP_S2>& op) { + *this = ap_private<_AP_W2, _AP_S2>(op); + report(); + } + + template + INLINE ap_fixed_base(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op) { + *this = ((const ap_private<_AP_W2 + _AP_W3, false>&)(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (bool(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (ap_private<_AP_W2, false>(op)); + report(); + } + + //helper function + INLINE unsigned long long doubleToRawBits(double pf)const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__D=pf; + return LD.__L; + } + + + INLINE double rawBitsToDouble(unsigned long long pi) const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__L=pi; + return LD.__D; + } + + INLINE float rawBitsToFloat(uint32_t pi) const { + union { + uint32_t __L; + float __D; + }LD; + LD.__L = pi; + return LD.__D; + } + + INLINE ap_fixed_base(double d):V(0) { + if (!d) return; + const bool isneg=d<0; + + const uint64_t ireg=doubleToRawBits(isneg?-d:d); + if ((ireg&0x7fffffffffffffffULL)!=0) { + const int32_t exp=(((ireg)>>DOUBLE_MAN)&0x07ff)-DOUBLE_BIAS; + ap_private man = ireg & DOUBLE_MAN_MASK; + man.clear(DOUBLE_MAN+1); + man.set(DOUBLE_MAN); + if (isneg) { + man.flip(); + man++; + } + + enum {_AP_S2=true, _AP_W2=DOUBLE_MAN+2,_AP_F=_AP_W -_AP_I }; + const int _AP_I2=exp+2; + const int F2=_AP_W2-_AP_I2; + const bool QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || (_AP_Q==AP_TRN_ZERO && + !_AP_S2)); + bool carry=false; + //handle quantization + const unsigned sh_amt=abs(F2-_AP_F); // sh_amt = F2>_AP_F ? F2 -_AP_F : _AP_F-F2; + if (F2==_AP_F ) + V=man; + else if (F2>_AP_F) { + if (sh_amt >= DOUBLE_MAN+2) + V=isneg?-1:0; + else + V=(man>>sh_amt) | ((man & 1ULL<<(DOUBLE_MAN+1)) ? (DOUBLE_MAN_MASK>>(DOUBLE_MAN+2-sh_amt) <<(DOUBLE_MAN+2-sh_amt)):0); + + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + const bool qb=((F2-_AP_F > DOUBLE_MAN+2) ? isneg : (man & (1ULL<<(F2-_AP_F-1))) != 0); + const int pos3=F2-_AP_F-2; + const bool r = (pos3>= 0) ? (man << AP_MAX(0, _AP_W2-pos3-1)& DOUBLE_MAN_MASK)!=0 : false; + carry = quantization_adjust(qb,r,isneg); + } + } + else { //no quantization + // V=man; + if (sh_amt < _AP_W) { + V = man; + V <<= sh_amt; + } + } + //handle overflow/underflow + if ((_AP_O != AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2-_AP_S2+(QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)) )) {// saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool neg_src; + const bool lD=(_AP_I2>_AP_I) && (_AP_W2-_AP_I2+_AP_I>=0) && (man & (1ULL <<(DOUBLE_MAN+2-_AP_I2+_AP_I))); + int pos1=F2+_AP_W-_AP_F; + if (pos1 < _AP_W2) { + int pos2=pos1+1; + bool Range1_all_ones=true; + bool Range1_all_zeros=true; + if (pos1>=0) { + ap_private<_AP_W,_AP_S> Range1= + ap_private<_AP_W,_AP_S>((man >> pos1) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos1) <<(DOUBLE_MAN+2-pos1)):0)); + Range1_all_ones = Range1.isAllOnesValue(); // Range1.isAllOnesValue(); + Range1_all_zeros = Range1.isMinValue(); // Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros = man==0; // man.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + ap_private<_AP_W, _AP_S> Range2= + ap_private<_AP_W, _AP_S>((man >> pos2) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos2) <<(DOUBLE_MAN+2-pos2)):0)); + Range2_all_ones=Range2.isAllOnesValue(); // Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) : Range1_all_ones; + neg_src=isneg&&!(carry&Range1_all_ones); + } else + neg_src = isneg && V[_AP_W -1]; + + const bool neg_trg=V.isNegative(); + const bool overflow=(neg_trg||!deleted_zeros) && !isneg; + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow,overflow,lD, neg_src); + } + } + report(); + } + + + ///assign operators + //------------------------------------------------------------------------- + + INLINE volatile ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + INLINE volatile ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + // Set this ap_fixed_base with a bits string. That means the ssdm_int::V + // inside this ap_fixed_base is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + INLINE ap_fixed_base& setBits(unsigned long long bv) { + V=bv; + return *this; + } + + // Return a ap_fixed_base object whose ssdm_int::V is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + static INLINE ap_fixed_base bitsToFixed(unsigned long long bv) { + ap_fixed_base Tmp=bv; + return Tmp; + } + + // Explicit conversion functions to ap_private that captures + // all integer bits (bits are truncated) + INLINE ap_private + to_ap_private(bool Cnative = true) const { + ap_private ret = ap_private ((_AP_I >= 1) ? (_AP_S==true ? V.ashr(AP_MAX(0,_AP_W - _AP_I)) : V.lshr(AP_MAX(0,_AP_W - _AP_I))) : ap_private<_AP_W, _AP_S>(0)); + + if (Cnative) { + bool r = false; + if (_AP_I < _AP_W) { + if (_AP_I > 0) r = !(V.getLoBits(_AP_W - _AP_I).isMinValue()); + else r = !(V.isMinValue()); + } + if (r && V.isNegative()) { // if this is negative integer + ++ret;//ap_private(1,_AP_S); + } + } else { + //Follow OSCI library, conversion from sc_fixed to sc_int + } + return ret; + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2> () const { + return (ap_private<_AP_W2,_AP_S2>)to_ap_private(); + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2,_AP_N2> () const { + return (ap_private<_AP_W2,_AP_S2,_AP_N2>)to_ap_private(); + } + + //Explict conversion function to C built-in integral type + INLINE int to_int() const { + return to_ap_private().to_int(); + } + + INLINE int to_uint() const { + return to_ap_private().to_uint(); + } + + INLINE ap_slong to_int64() const { + return to_ap_private().to_int64(); + } + + INLINE ap_ulong to_uint64() const { + return to_ap_private().to_uint64(); + } + + INLINE double to_double() const { + if (!V) + return 0; + if (_AP_W>64 || (_AP_W - _AP_I) > 0) { + bool isneg = _AP_S && V[_AP_W-1]; + uint64_t res = isneg ? 0x8000000000000000ULL : 0; + ap_private<_AP_W, false> tmp = V; + if (isneg) tmp = -tmp; + int i = _AP_W -1 - tmp.countLeadingZeros(); + int exp = _AP_I-(_AP_W-i); + res|=((uint64_t)(exp+DOUBLE_BIAS))<DOUBLE_MAN)?tmp.lshr(i-DOUBLE_MAN):tmp).to_uint64() & DOUBLE_MAN_MASK; + res |= i 0) { + /* This specialization is disabled. It is giving wrong results in some cases. + bool isneg=V.isNegative(); + double dp = V.get(); + dp /= (1<< (_AP_W - _AP_I)); + return dp;*/ + } else + return double(to_int64()); + } + + INLINE float to_float() const { + uint32_t res=0; + if (V==0) + return 0; + bool isneg=V.isNegative(); + ap_private<_AP_W, _AP_S> tmp=V; + if (isneg) tmp = -tmp; + if (_AP_W-_AP_I>0||_AP_W>64) { + if (isneg) + res=0x80000000; + int i=_AP_W-1; + i-=tmp.countLeadingZeros(); + int exp=_AP_I-(_AP_W-i); + res|=(exp+FLOAT_BIAS)< man = 0; + if (i!=0) { + tmp.clear(i); + if (i>FLOAT_MAN) + man=tmp.lshr(i-FLOAT_MAN); + else + man=tmp; + res |= i < FLOAT_MAN?man.getZExtValue()<<(FLOAT_MAN-i):man.getZExtValue(); + } + } else { + return float(to_int64()); + } + float dp=rawBitsToFloat(res); + return dp; + } + + INLINE operator double () const { + return to_double(); + } +#ifndef __SC_COMPATIBLE__ + INLINE operator float () const { + return to_float(); + } + + INLINE operator char () const { + return (char) to_int(); + } + + INLINE operator unsigned char () const { + return (unsigned char) to_uint(); + } + + INLINE operator short () const { + return (short) to_int(); + } + + INLINE operator unsigned short () const { + return (unsigned short) to_uint(); + } + + INLINE operator int () const { + return to_int(); + } + + INLINE operator unsigned int () const { + return to_uint(); + } +#if 1 +#ifdef __x86_64__ + INLINE operator long () const { + return (long)to_int64(); + } + + INLINE operator unsigned long () const { + return (unsigned long) to_uint64(); + } +#else + INLINE operator long () const { + return to_int64(); + } + + INLINE operator unsigned long () const { + return to_uint64(); + } + +#endif +#endif + INLINE operator unsigned long long () const { + return to_uint64(); + } + + INLINE operator long long () const { + return to_int64(); + } +#endif + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const; + + INLINE ap_slong bits_to_int64() const { + ap_private res(V); + return (ap_slong) res; + } + + INLINE ap_ulong bits_to_uint64() const { + ap_private res(V); + return (ap_ulong) res; + } + + INLINE int length() const {return _AP_W;} + + // Count the number of zeros from the most significant bit + // to the first one bit. Note this is only for ap_fixed_base whose + // _AP_W <= 64, otherwise will incur assertion. + INLINE int countLeadingZeros() { + return V.countLeadingZeros(); + } + + ///Arithmetic:Binary + //------------------------------------------------------------------------- + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::mult + operator * (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + typename RType<_AP_W2,_AP_I2,_AP_S2>::mult r; + r.V = V * op2.V; + return r; + } + + template + static INLINE ap_fixed_base multiply(const ap_fixed_base<_AP_W1,_AP_I1,_AP_S1>& op1, const + ap_fixed_base<_AP_W2,_AP_I2,_AP_S2>& op2) { + ap_private<_AP_W+_AP_W2, _AP_S> OP1=op1.V; + ap_private<_AP_W2,_AP_S2> OP2=op2.V; + return OP1*OP2; + } + + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::div + operator / (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {F2 = _AP_W2-_AP_I2, _W1=AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2), + _W2=AP_MAX(_AP_W2,AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2))}; + ap_private<_W1, _AP_S> dividend = (ap_private<_W1, _AP_S>(V)) << ((_W1>_AP_W)?F2:0); + ap_private<_W1, _AP_S2> divisior = ap_private<_W2, _AP_S2>(op2.V); + ap_private<_W1, _AP_S> ret = ap_private<_W1,_AP_S> ((_AP_S||_AP_S2) ? dividend.sdiv(divisior): dividend.udiv(divisior)); + typename RType<_AP_W2, _AP_I2, _AP_S2>::div r; + r.V = ret; + return r; + } +#define OP_BIN_AF(Sym, Rty, Width, Sign, Fun) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + enum {_AP_F=_AP_W-_AP_I, F2=_AP_W2-_AP_I2}; \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V = lhs.V.Fun(rhs.V); \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + + OP_BIN_AF(+, plus, plus_w, plus_s, Add) + OP_BIN_AF(-, minus, minus_w, minus_s, Sub) + +#define OP_LOGIC_BIN_AF(Sym, Rty, Width, Sign) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V=lhs.V Sym rhs.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty operator Sym(int op2) const \ + { \ + return V Sym (op2<<(_AP_W - _AP_I)); \ + } + OP_LOGIC_BIN_AF(&, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(|, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(^, logic, logic_w, logic_s) + + ///Arithmic : assign + //------------------------------------------------------------------------- +#define OP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2) ; \ + return *this; \ + } + + OP_ASSIGN_AF(+) + OP_ASSIGN_AF(-) + OP_ASSIGN_AF(&) + OP_ASSIGN_AF(|) + OP_ASSIGN_AF(^) + OP_ASSIGN_AF(*) + OP_ASSIGN_AF(/) + + ///Prefix increment, decrement + //------------------------------------------------------------------------- + INLINE ap_fixed_base& operator ++() { + operator+=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + INLINE ap_fixed_base& operator --() { + operator-=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + //Postfix increment, decrement + //------------------------------------------------------------------------- + INLINE const ap_fixed_base operator ++(int) { + ap_fixed_base t(*this); + operator++(); + return t; + } + + INLINE const ap_fixed_base operator --(int) { + ap_fixed_base t = *this; + operator--(); + return t; + } + + ///Unary arithmetic + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator +() {return *this;} + + INLINE ap_fixed_base<_AP_W + 1, _AP_I + 1, true> operator -() const { + ap_fixed_base<_AP_W + 1, _AP_I + 1, true> Tmp(*this); + Tmp.V = - Tmp.V; + return Tmp; + } + + INLINE ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> getNeg() { + ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> Tmp(*this); + Tmp.V=-Tmp.V; + return Tmp; + } + + ///Not (!) + //------------------------------------------------------------------------- + INLINE bool operator !() const { + return !V; + } + + ///Bitwise complement + //------------------------------------------------------------------------- + INLINE ap_fixed_base<_AP_W, _AP_I, _AP_S> + operator ~() const { + ap_fixed_base<_AP_W, _AP_I, _AP_S> res(*this); + res.V.flip(); + return res; + } + + ///Shift + ///template argument as shift value + template + INLINE ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> lshift () const { + ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + template + INLINE ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> rshift () const { + ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + //Because the return type is the type of the the first operand, shift assign + //operators do not carry out any quantization or overflow + //While systemc, shift assigns for sc_fixed/sc_ufixed will result in + //quantization or overflow (depending on the mode of the first operand) + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator << (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + bool NegSrc = V.isNegative(); + if (isNeg) { + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); + } else { + if (shiftoverflow) + r.V.clear(); + else + r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == false && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator<<(const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator << (sh); + } + + INLINE ap_fixed_base operator << (unsigned int sh ) const { + ap_fixed_base r; + bool shiftoverflow = sh >= _AP_W; + r.V = shiftoverflow ? ap_private<_AP_W, _AP_S >(0) : V << sh; + if (sh == 0) return r; +#ifdef __SC_COMPATIBLE__ + bool NegSrc = V.isNegative(); + if (_AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh -1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator << (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator << (sh); + } + + INLINE ap_fixed_base operator >> (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + bool NegSrc = V.isNegative(); + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + if (isNeg && !shiftoverflow) r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == true && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator >> (sh); + } + + INLINE ap_fixed_base operator >> (unsigned int sh) const { + ap_fixed_base r; + bool NegSrc = V.isNegative(); + bool shiftoverflow = sh >= _AP_W; + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); +#ifdef __SC_COMPATIBLE__ + if (sh == 0) return r; + if (_AP_Q != AP_TRN) { + bool qb = false; + if (sh <= _AP_W) qb = V[sh - 1]; + bool rb = false; + if (sh > 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator >> (sh); + } + + ///shift assign + //------------------------------------------------------------------------- +#define OP_AP_SHIFT_AP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AP_ASSIGN_AF(<<) + OP_AP_SHIFT_AP_ASSIGN_AF(>>) + + ///Support shift(ap_fixed_base) +#define OP_AP_SHIFT_AF(Sym) \ + template \ + INLINE ap_fixed_base operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + return operator Sym (op2.to_ap_private()); \ + } \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AF(<<) + OP_AP_SHIFT_AF(>>) + + INLINE ap_fixed_base& operator >>= (unsigned int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (unsigned int sh) { + *this = operator << (sh); + return *this; + } + + INLINE ap_fixed_base& operator >>= (int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (int sh) { + *this = operator << (sh); + return *this; + } + + ///Comparisons + //------------------------------------------------------------------------- + template + INLINE bool operator == (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator != (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this==op2); + } + + template + INLINE bool operator > (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator <= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this>op2); + } + + template + INLINE bool operator < (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator >= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this) + DOUBLE_CMP_AF(>=) + DOUBLE_CMP_AF(<) + DOUBLE_CMP_AF(<=) + + // Bit and Slice Select + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> operator [] (unsigned int index) { + assert(index<_AP_W&&"Attemping to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit(unsigned int index) { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit (const ap_private<_AP_W2,_AP_S2>& index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int()); + } + + INLINE bool bit (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + INLINE bool operator [] (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + template + INLINE bool bit (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + template + INLINE bool operator [] (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit(int index) { + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + assert(index >= _AP_I - _AP_W&& "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index + _AP_W - _AP_I); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit (const ap_private<_AP_W2, true>& index) { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int() + _AP_W - _AP_I); + } + + INLINE bool get_bit (int index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index + _AP_W - _AP_I]; + } + + template + INLINE bool get_bit (const ap_private<_AP_W2, true>& index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index.to_int() + _AP_W - _AP_I]; + } + + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W) &&"Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast(this), Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) const { + return this->range(Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast< + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>*>(this), + Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() { + return this->range(_AP_W - 1, 0); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() const { + return this->range(_AP_W - 1, 0); + } + + INLINE bool is_zero () const { + return V.isMinValue(); + } + + INLINE bool is_neg () const { + if (V.isNegative()) + return true; + return false; + } + + INLINE int wl () const { + return _AP_W; + } + + INLINE int iwl () const { + return _AP_I; + } + + INLINE ap_q_mode q_mode () const { + return _AP_Q; + } + + INLINE ap_o_mode o_mode () const { + return _AP_O; + } + + INLINE int n_bits () const { + return 0; + } + + //private: +public: + ap_private<_AP_W, _AP_S> V; +}; + +template +std::string ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>::to_string( + uint8_t radix, bool sign) const { + std::string str; + str.clear(); + char step; + std::string prefix; + switch (radix) { + case 2 : prefix = "0b"; step = 1; break; + case 8 : prefix = "0o"; step = 3; break; + case 16 : prefix = "0x"; step = 4; break; + default : break; + } + if (_AP_W <= _AP_I) + str = this->to_ap_private().to_string(radix, + radix == 10 ? _AP_S : sign); + else { + if (radix == 10) { + bool isNeg = _AP_S && V.isNegative(); + if (_AP_I > 0) { + ap_private int_part(0); + int_part = this->to_ap_private(); + str += int_part.to_string(radix, false); + } else { + if (isNeg) str += '-'; + } + ap_fixed_base<_AP_W, _AP_I, _AP_S> tmp(*this); + if (isNeg && _AP_I <= 0) tmp = -tmp; + ap_fixed_base<_AP_W - AP_MIN(_AP_I, 0), 0, false> frac_part = tmp; + if (frac_part == 0) return str; + str += "."; + while (frac_part != 0) { + char digit = (frac_part * radix).to_ap_private(); + str += static_cast(digit + '0'); + frac_part *= radix; + } + } else { + if (_AP_I > 0) { + for (signed i = _AP_W - _AP_I; i < _AP_W; i += step) { + + char digit = (char)(this->range(AP_MIN(i + step - 1, _AP_W - 1), i)); + str = (digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a')) + str; + } + } + str += '.'; + ap_fixed_base tmp(*this); + for (signed i = _AP_W - _AP_I - 1; i >= 0; i -= step) { + char digit = (char)(tmp.range(i, AP_MAX(0, i - step + 1))); + str += digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a'); + } + } + } + str = prefix + str; + return str; +} + +template +INLINE void b_not(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = op.V; + ret.V.flip(); +} + +template +INLINE void b_and(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V & op2.V; +} + +template +INLINE void b_or(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V | op2.V; +} + +template +INLINE void b_xor(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V ^ op2.V; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + ap_fixed_base<_AP_W2+!_AP_S2, _AP_I2+!_AP_S2, true, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp.V = - op.V; + ret = Tmp; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = -op.V; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_W2 - _AP_I2 + AP_MAX(_AP_I, _AP_I2), AP_MAX(_AP_I, _AP_I2), _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V <<= i; + ret = Tmp; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = op.V << i; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_I2 + AP_MAX(_AP_W - _AP_I, _AP_W2 - _AP_I2), _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V = _AP_S2 ? Tmp.V.ashr(i): Tmp.V.lshr(i); + ret = Tmp; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = _AP_S ? op.V.ashr(i): op.V.lshr(i); +} + +#define AF_CTOR_SPEC_BASE(_AP_W,_AP_S,C_TYPE) \ + template<> INLINE ap_fixed_base<_AP_W,_AP_W,_AP_S,AP_TRN,AP_WRAP>::ap_fixed_base(C_TYPE i_op):V(i_op) \ + { \ + } + +#define AF_CTOR_SPEC(__W,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,true,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,false,C_TYPE) + +AF_CTOR_SPEC(1,bool) +AF_CTOR_SPEC(8, signed char) +AF_CTOR_SPEC(8, unsigned char) +AF_CTOR_SPEC(16, signed short) +AF_CTOR_SPEC(16, unsigned short) +AF_CTOR_SPEC(32, signed int) +AF_CTOR_SPEC(32, unsigned int) +AF_CTOR_SPEC(64, ap_slong) +AF_CTOR_SPEC(64, ap_ulong) + +///Output streaming +//----------------------------------------------------------------------------- +template +INLINE std::ostream& +operator <<(std::ostream& os, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + os << x.to_double(); + return os; +} + +///Input streaming +//----------------------------------------------------------------------------- +template +INLINE std::istream& +operator >> (std::istream& os, ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + double d; + os >> d; + x = ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(x); + return os; +} + +template +INLINE void print(const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + ap_private<_AP_W,_AP_S> data=x.V; + if (_AP_I>0) { + const ap_private<_AP_I,_AP_S> p1=data>>(_AP_W-_AP_I); + print(p1); + + } else + printf("0"); + printf("."); + if (_AP_I<_AP_W) { + const ap_private<_AP_W-_AP_I,false> p2=data; + print(p2,false); + } +} + +///Operators mixing Integers with ap_fixed_base +//----------------------------------------------------------------------------- +#if 1 +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP(ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#else +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op BIN_OP (i_op); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V BIN_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#endif +#if 1 +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator REL_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } +#else +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V.operator REL_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return (i_op<<(_AP_W-_AP_I)) REL_OP (op.V.VAL); \ + } +#endif +#if 1 +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#else +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#endif + +#define AF_OPS_WITH_INT(C_TYPE, WI, SI) \ + AF_BIN_OP_WITH_INT(+, C_TYPE, WI, SI, plus) \ + AF_BIN_OP_WITH_INT(-, C_TYPE, WI, SI, minus) \ + AF_BIN_OP_WITH_INT(*, C_TYPE, WI, SI, mult) \ + AF_BIN_OP_WITH_INT(/, C_TYPE, WI, SI, div) \ + AF_BIN_OP_WITH_INT_SF(>>, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT_SF(<<, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT(&, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(|, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(^, C_TYPE, WI, SI, logic) \ + \ + AF_REL_OP_WITH_INT(==, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(!=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<=, C_TYPE, WI, SI) \ + \ + AF_ASSIGN_OP_WITH_INT(+=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(-=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(*=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(/=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(>>=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(<<=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(&=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(|=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(^=, C_TYPE, WI, SI) + +AF_OPS_WITH_INT(bool, 1, false) +AF_OPS_WITH_INT(char, 8, true) +AF_OPS_WITH_INT(signed char, 8, true) +AF_OPS_WITH_INT(unsigned char, 8, false) +AF_OPS_WITH_INT(short, 16, true) +AF_OPS_WITH_INT(unsigned short, 16, false) +AF_OPS_WITH_INT(int, 32, true) +AF_OPS_WITH_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_OPS_WITH_INT(long, 64, true) +AF_OPS_WITH_INT(unsigned long, 64, false) +# else +AF_OPS_WITH_INT(long, 32, true) +AF_OPS_WITH_INT(unsigned long, 32, false) +# endif +AF_OPS_WITH_INT(ap_slong, 64, true) +AF_OPS_WITH_INT(ap_ulong, 64, false) + +#define AF_BIN_OP_WITH_AP_INT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>::template RType<_AP_W,_AP_I,_AP_S>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } + +#define AF_REL_OP_WITH_AP_INT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator REL_OP ( ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } + +#define AF_ASSIGN_OP_WITH_AP_INT(ASSIGN_OP) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE ap_private<_AP_W2,_AP_S2>& operator ASSIGN_OP ( ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return i_op.operator ASSIGN_OP (op.to_ap_private()); \ + } + +AF_BIN_OP_WITH_AP_INT(+, plus) +AF_BIN_OP_WITH_AP_INT(-, minus) +AF_BIN_OP_WITH_AP_INT(*, mult) +AF_BIN_OP_WITH_AP_INT(/, div) +AF_BIN_OP_WITH_AP_INT(&, logic) +AF_BIN_OP_WITH_AP_INT(|, logic) +AF_BIN_OP_WITH_AP_INT(^, logic) + +AF_REL_OP_WITH_AP_INT(==) +AF_REL_OP_WITH_AP_INT(!=) +AF_REL_OP_WITH_AP_INT(>) +AF_REL_OP_WITH_AP_INT(>=) +AF_REL_OP_WITH_AP_INT(<) +AF_REL_OP_WITH_AP_INT(<=) + +AF_ASSIGN_OP_WITH_AP_INT(+=) +AF_ASSIGN_OP_WITH_AP_INT(-=) +AF_ASSIGN_OP_WITH_AP_INT(*=) +AF_ASSIGN_OP_WITH_AP_INT(/=) +AF_ASSIGN_OP_WITH_AP_INT(&=) +AF_ASSIGN_OP_WITH_AP_INT(|=) +AF_ASSIGN_OP_WITH_AP_INT(^=) + +#define AF_REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2 REL_OP (bool(op)); \ + } + +#define AF_REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +AF_REF_REL_MIX_INT(bool, 1, false) +AF_REF_REL_MIX_INT(char, 8, true) +AF_REF_REL_MIX_INT(signed char, 8, true) +AF_REF_REL_MIX_INT(unsigned char, 8, false) +AF_REF_REL_MIX_INT(short, 16, true) +AF_REF_REL_MIX_INT(unsigned short, 16, false) +AF_REF_REL_MIX_INT(int, 32, true) +AF_REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_REF_REL_MIX_INT(long, 64, true) +AF_REF_REL_MIX_INT(unsigned long, 64, false) +# else +AF_REF_REL_MIX_INT(long, 32, true) +AF_REF_REL_MIX_INT(unsigned long, 32, false) +# endif +AF_REF_REL_MIX_INT(ap_slong, 64, true) +AF_REF_REL_MIX_INT(ap_ulong, 64, false) + +#define AF_REF_REL_OP_AP_INT(REL_OP) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S> &op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP (const ap_private<_AP_W2, _AP_S2> &op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S2> &op2) { \ + return (ap_private<1, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2, _AP_S2> &op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<1,false>(op)); \ + } + +AF_REF_REL_OP_AP_INT(>) +AF_REF_REL_OP_AP_INT(<) +AF_REF_REL_OP_AP_INT(>=) +AF_REF_REL_OP_AP_INT(<=) +AF_REF_REL_OP_AP_INT(==) +AF_REF_REL_OP_AP_INT(!=) + +// Relational Operators with double +template +INLINE bool operator == ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator == (op1); +} + +template +INLINE bool operator != ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator != (op1); +} + +template +INLINE bool operator > ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator < (op1); +} + +template +INLINE bool operator >= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator <= (op1); +} + +template +INLINE bool operator < ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator > (op1); +} + +template +INLINE bool operator <= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator >= (op1); +} + +#endif /* #ifndef __AESL_GCC_AP_FIXED_H__ */ \ No newline at end of file diff --git a/hls_2018/router_04/etc/ap_int_sim.h b/hls_2018/router_04/etc/ap_int_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..887ccd88bfd52d1777db8661d72c57703ccf736a --- /dev/null +++ b/hls_2018/router_04/etc/ap_int_sim.h @@ -0,0 +1,1629 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_INT_H__ +#define __AESL_GCC_AP_INT_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + +#undef _AP_DEBUG_ +#include +#include + +// for safety +#if (defined(_AP_N)|| defined(_AP_C)) +#error One or more of the following is defined: _AP_N, _AP_C. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_N)|| defined(_AP_C)) */ + +// for safety +#if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) +#error One or more of the following is defined: _AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) */ + +//for safety +#if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) +#error One or more of the following is defined: _AP_W3, _AP_S3, _AP_W4,_AP_S4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) */ + +//for safety +#if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) +#error One or more of the following is defined: _AP_W1, _AP_S1, _AP_I1, _AP_T, _AP_T1, _AP_T2, _AP_T3, _AP_T4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) */ + +#define __AESL_APDT_IN_SCFLOW__ +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_private.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#ifdef _AP_DEBUG_ + #define AP_DEBUG(s) s +#else + #define AP_DEBUG(s) +#endif /* #ifdef _AP_DEBUG_ */ + +#ifndef __SIMULATION__ + #define __SIMULATION__ +#endif /* #ifndef __SIMULATION__ */ + +#if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) + #ifndef SC_TRN + #define SC_TRN AP_TRN + #endif /* #ifndef SC_TRN */ + #ifndef SC_RND + #define SC_RND AP_RND + #endif /* #ifndef SC_RND */ + #ifndef SC_TRN_ZERO + #define SC_TRN_ZERO AP_TRN_ZERO + #endif /* #ifndef SC_TRN_ZERO */ + #ifndef SC_RND_ZERO + #define SC_RND_ZERO AP_RND_ZERO + #endif /* #ifndef SC_RND_ZERO */ + #ifndef SC_RND_INF + #define SC_RND_INF AP_RND_INF + #endif /* #ifndef SC_RND_INF */ + #ifndef SC_RND_MIN_INF + #define SC_RND_MIN_INF AP_RND_MIN_INF + #endif /* #ifndef SC_RND_MIN_INF */ + #ifndef SC_RND_CONV + #define SC_RND_CONV AP_RND_CONV + #endif /* #ifndef SC_RND_CONV */ + #ifndef SC_WRAP + #define SC_WRAP AP_WRAP + #endif /* #ifndef SC_WRAP */ + #ifndef SC_SAT + #define SC_SAT AP_SAT + #endif /* #ifndef SC_SAT */ + #ifndef SC_SAT_ZERO + #define SC_SAT_ZERO AP_SAT_ZERO + #endif /* #ifndef SC_SAT_ZERO */ + #ifndef SC_SAT_SYM + #define SC_SAT_SYM AP_SAT_SYM + #endif /* #ifndef SC_SAT_SYM */ + #ifndef SC_WRAP_SM + #define SC_WRAP_SM AP_WRAP_SM + #endif /* #ifndef SC_WRAP_SM */ + #ifndef SC_BIN + #define SC_BIN AP_BIN + #endif /* #ifndef SC_BIN */ + #ifndef SC_OCT + #define SC_OCT AP_OCT + #endif /* #ifndef SC_OCT */ + #ifndef SC_DEC + #define SC_DEC AP_DEC + #endif /* #ifndef SC_DEC */ + #ifndef SC_HEX + #define SC_HEX AP_HEX + #endif /* #ifndef SC_HEX */ +#endif /* #if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) */ +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +///Forward declaration +template struct ap_range_ref; +template struct ap_bit_ref; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; +template class ap_uint; + +enum { + AP_BIN = 2, + AP_OCT = 8, + AP_DEC = 10, + AP_HEX = 16 +}; + +///Why to use reference? +///Because we will operate the original object indirectly by operating the +///result object directly after concating or part selecting + +///Proxy class which allows concatination to be used as rvalue(for reading) and +//lvalue(for writing) + +/// Concatination reference. +// ---------------------------------------------------------------- +template +struct ap_concat_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + enum {_AP_WR=_AP_W1+_AP_W2,}; + _AP_T1& mbv1; + _AP_T2& mbv2; + + INLINE ap_concat_ref(const ap_concat_ref<_AP_W1, _AP_T1, + _AP_W2, _AP_T2>& ref): + mbv1(ref.mbv1), mbv2(ref.mbv2) {} + + INLINE ap_concat_ref(_AP_T1& bv1, _AP_T2& bv2):mbv1(bv1),mbv2(bv2) {} + + template + INLINE ap_concat_ref& operator = (const ap_private<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + return *this; + } + + INLINE ap_concat_ref& operator = (unsigned long long val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W1, _AP_T1, _AP_W2, _AP_T2>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_concat_ref& operator= (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = ((const ap_private<_AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref& operator= (const ap_fixed_base<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = (val.to_ap_private()); + } + + template + INLINE ap_concat_ref& operator= (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + + INLINE operator ap_private<_AP_WR, false> () const { + return get(); + } + + INLINE operator unsigned long long () const { + return get().to_uint64(); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_range_ref<_AP_W3, _AP_S3> > + operator, (const ap_range_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_range_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (const ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, + const_cast&>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, 1, ap_bit_ref<_AP_W3, _AP_S3> > + operator, (const ap_bit_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + 1, ap_bit_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> > + operator, (const ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> &a2) + { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4, + _AP_T4> >(*this, const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE ap_private + operator & (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() & a2; + } + + + template + INLINE ap_private + operator | (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() | a2; + } + + + template + INLINE ap_private + operator ^ (const ap_private<_AP_W3,_AP_S3>& a2) { + return ap_private(get() ^ a2); + } + + INLINE const ap_private<_AP_WR, false> get() const + { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> (mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + INLINE const ap_private<_AP_WR, false> get() { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> ( mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + template + INLINE void set(const ap_private<_AP_W3,false> & val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + } + + INLINE int length() const { + return mbv1.length()+mbv2.length(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } +}; + +///Proxy class, which allows part selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Range(slice) reference +//------------------------------------------------------------ +template +struct ap_range_ref { +#ifdef _MSC_VER + #pragma warning( disable : 4521 4522 ) +#endif /* #ifdef _MSC_VER */ + ap_private<_AP_W,_AP_S> &d_bv; + int l_index; + int h_index; + +public: + INLINE ap_range_ref(const ap_range_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE ap_range_ref(ap_private<_AP_W,_AP_S>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + //fprintf(stderr, "Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + ap_private<_AP_W, false> val(0); + if(h_index>=l_index) { + if (_AP_W > 64) { + val=d_bv; + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + val&=mask; + } else { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val = (d_bv >> l_index) & (mask >>(_AP_W-(h_index-l_index+1))); + } + } else { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } + return val; + } + + INLINE operator unsigned long long () const { + return to_uint64(); + } + + template + INLINE ap_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W,false> vval=ap_private<_AP_W,false>(val); + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W > 64) { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + unsigned shift = 64-_AP_W; + uint64_t mask = ~0ULL>>(shift); + if(l_index>0) + { + vval = mask & vval << l_index; + mask = mask & mask << l_index; + } + if(h_index<_AP_W-1) + { + uint64_t mask2 = mask; + mask2 >>= (_AP_W-h_index-1); + mask&=mask2; + vval&=mask2; + } + mask = ~mask; + d_bv&=mask; + d_bv|=vval; + } + } + return *this; + } + + INLINE ap_range_ref& operator = (unsigned long long val) + { + const ap_private<_AP_W,_AP_S> vval=val; + return operator = (vval); + } + + + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W, _AP_S>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + + + template + INLINE ap_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, _AP_S2>)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE ap_range_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_bit_ref<_AP_W2, _AP_S2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, + ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast& >(a2)); + } + + + template + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2,_AP_S2>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W,ap_private<_AP_W,_AP_S> > + operator , (ap_private<_AP_W, _AP_S>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W, + ap_private<_AP_W,_AP_S> >(*this, a2); + } + + + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,1,ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, 1, + ap_bit_ref<_AP_W2,_AP_S2> >(*this, const_cast& >(a2)); + } + + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) + { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + + template + INLINE void set(const ap_private<_AP_W2,false>& val) + { + ap_private<_AP_W,_AP_S> vval=val; + if(l_index>h_index) + { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W>64 ) { + ap_private<_AP_W,_AP_S> mask(-1); + if(l_index>0) + { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + uint64_t mask = ~0ULL >> (64-_AP_W); + if(l_index>0) + { + uint64_t mask1 = mask; + mask1=mask & (mask1>>(_AP_W-l_index)); + vval =mask&( vval <> (64-_AP_W); + mask2 = mask &(mask2<<(h_index+1)); + mask&=~mask2; + vval&=~mask2; + } + d_bv&=(~mask&(~0ULL >> (64-_AP_W))); + d_bv|=vval; + } + } + } + + + INLINE ap_private<_AP_W,false> get() const + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64) { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val &= (mask>> (_AP_W-(h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE ap_private<_AP_W,false> get() + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64 ) { + static const uint64_t mask = ~0ULL>> (64>_AP_W ? (64-_AP_W):0); + return val &= ( (mask) >> (_AP_W - (h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE int length() const + { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + + INLINE int to_int() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + + INLINE unsigned int to_uint() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + + INLINE long to_long() const + { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + + INLINE unsigned long to_ulong() const + { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + + INLINE ap_slong to_int64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + + INLINE ap_ulong to_uint64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } + +}; + +///Proxy class, which allows bit selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Bit reference +//-------------------------------------------------------------- +template +struct ap_bit_ref { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif + ap_private<_AP_W,_AP_S>& d_bv; + int d_index; + +public: + INLINE ap_bit_ref(const ap_bit_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE ap_bit_ref(ap_private<_AP_W,_AP_S>& bv, int index=0): + d_bv(bv),d_index(index) + { +#ifdef _AP_DEBUG_ + assert(d_index<_AP_W&&"index out of bound"); +#endif + } + + + INLINE operator bool () const + { + return d_bv.get_bit(d_index); + } + + + INLINE bool to_bool() const + { + return operator bool (); + } + + + INLINE ap_bit_ref& operator = (unsigned long long val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } + + +#if 0 + INLINE ap_bit_ref& operator = (bool val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } +#endif + template + INLINE ap_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(val != 0)); + } + + + template + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool)val); + } + + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W,_AP_S>& val) + { + return operator =((unsigned long long)(bool)val); + } + + template + INLINE ap_bit_ref& operator =(const ap_range_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool) val); + } + + + template + INLINE ap_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE ap_bit_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2, _AP_S2>& a2) + { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref > + operator, (const ap_bit_ref &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref >(*this, + const_cast(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> > + operator, (const ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> &a2) + { + return + ap_concat_ref<1,ap_bit_ref,_AP_W2+_AP_W3, + ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() != op.get(); + } + + + INLINE bool get() const + { + return operator bool (); + } + + + INLINE bool get() + { + return operator bool (); + } + + + template + INLINE void set(const ap_private<_AP_W3, false>& val) + { + operator = (val); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { return 1; } + + INLINE std::string to_string() const { + bool val = get(); + return val ? "1" : "0"; + } +}; + +/// Operators mixing Integers with AP_Int +// ---------------------------------------------------------------- +#if 1 +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#else +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#endif +#define OP_REL_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator REL_OP (ap_private<_AP_W2, _AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (op); \ + } +#define OP_ASSIGN_MIX_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } + +#define OP_BIN_SHIFT_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + C_TYPE operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return i_op BIN_OP (op.getVal()); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (i_op); \ + } +#define OP_ASSIGN_RSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator >> (op2); \ + return op; \ + } +#define OP_ASSIGN_LSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator << (op2); \ + return op; \ + } + +#define OPS_MIX_INT(C_TYPE, WI, SI) \ + OP_BIN_MIX_INT(*, C_TYPE, WI, SI, mult) \ + OP_BIN_MIX_INT(+, C_TYPE, WI, SI, plus) \ + OP_BIN_MIX_INT(-, C_TYPE, WI, SI, minus) \ + OP_BIN_MIX_INT(/, C_TYPE, WI, SI, div) \ + OP_BIN_MIX_INT(%, C_TYPE, WI, SI, mod) \ + OP_BIN_MIX_INT(&, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(|, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(^, C_TYPE, WI, SI, logic) \ + OP_BIN_SHIFT_INT(>>, C_TYPE, WI, SI, arg1) \ + OP_BIN_SHIFT_INT(<<, C_TYPE, WI, SI, arg1) \ + \ + OP_REL_MIX_INT(==, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(!=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<=, C_TYPE, WI, SI) \ + \ + OP_ASSIGN_MIX_INT(+=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(-=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(*=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(/=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(%=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(&=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(|=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(^=, C_TYPE, WI, SI) \ + OP_ASSIGN_RSHIFT_INT(>>=, C_TYPE, WI, SI) \ + OP_ASSIGN_LSHIFT_INT(<<=, C_TYPE, WI, SI) + + +OPS_MIX_INT(bool, 1, false) +OPS_MIX_INT(char, 8, true) +OPS_MIX_INT(signed char, 8, true) +OPS_MIX_INT(unsigned char, 8, false) +OPS_MIX_INT(short, 16, true) +OPS_MIX_INT(unsigned short, 16, false) +OPS_MIX_INT(int, 32, true) +OPS_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +OPS_MIX_INT(long, 64, true) +OPS_MIX_INT(unsigned long, 64, false) +# else +OPS_MIX_INT(long, 32, true) +OPS_MIX_INT(unsigned long, 32, false) +# endif +OPS_MIX_INT(ap_slong, 64, true) +OPS_MIX_INT(ap_ulong, 64, false) + +#define OP_BIN_MIX_RANGE(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<_AP_W2, false>(op2)); \ + } + +#define OP_REL_MIX_RANGE(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (op2.operator ap_private<_AP_W2, false>()); \ + } + +#define OP_ASSIGN_MIX_RANGE(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<_AP_W2, false>(op2)); \ + } \ + template \ + INLINE ap_range_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP (ap_range_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<_AP_W1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_RANGE(+=) +OP_ASSIGN_MIX_RANGE(-=) +OP_ASSIGN_MIX_RANGE(*=) +OP_ASSIGN_MIX_RANGE(/=) +OP_ASSIGN_MIX_RANGE(%=) +OP_ASSIGN_MIX_RANGE(>>=) +OP_ASSIGN_MIX_RANGE(<<=) +OP_ASSIGN_MIX_RANGE(&=) +OP_ASSIGN_MIX_RANGE(|=) +OP_ASSIGN_MIX_RANGE(^=) + +OP_REL_MIX_RANGE(==) +OP_REL_MIX_RANGE(!=) +OP_REL_MIX_RANGE(>) +OP_REL_MIX_RANGE(>=) +OP_REL_MIX_RANGE(<) +OP_REL_MIX_RANGE(<=) + +OP_BIN_MIX_RANGE(+, plus) +OP_BIN_MIX_RANGE(-, minus) +OP_BIN_MIX_RANGE(*, mult) +OP_BIN_MIX_RANGE(/, div) +OP_BIN_MIX_RANGE(%, mod) +OP_BIN_MIX_RANGE(>>, arg1) +OP_BIN_MIX_RANGE(<<, arg1) +OP_BIN_MIX_RANGE(&, logic) +OP_BIN_MIX_RANGE(|, logic) +OP_BIN_MIX_RANGE(^, logic) + +#define OP_BIN_MIX_BIT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<1, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<1,false>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<1, false>(op2)); \ + } + +#define OP_REL_MIX_BIT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (ap_private<1, false>(op2)); \ + } + +#define OP_ASSIGN_MIX_BIT(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<1, false>(op2)); \ + } \ + template \ + INLINE ap_bit_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_bit_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_BIT(+=) +OP_ASSIGN_MIX_BIT(-=) +OP_ASSIGN_MIX_BIT(*=) +OP_ASSIGN_MIX_BIT(/=) +OP_ASSIGN_MIX_BIT(%=) +OP_ASSIGN_MIX_BIT(>>=) +OP_ASSIGN_MIX_BIT(<<=) +OP_ASSIGN_MIX_BIT(&=) +OP_ASSIGN_MIX_BIT(|=) +OP_ASSIGN_MIX_BIT(^=) + +OP_REL_MIX_BIT(==) +OP_REL_MIX_BIT(!=) +OP_REL_MIX_BIT(>) +OP_REL_MIX_BIT(>=) +OP_REL_MIX_BIT(<) +OP_REL_MIX_BIT(<=) + +OP_BIN_MIX_BIT(+, plus) +OP_BIN_MIX_BIT(-, minus) +OP_BIN_MIX_BIT(*, mult) +OP_BIN_MIX_BIT(/, div) +OP_BIN_MIX_BIT(%, mod) +OP_BIN_MIX_BIT(>>, arg1) +OP_BIN_MIX_BIT(<<, arg1) +OP_BIN_MIX_BIT(&, logic) +OP_BIN_MIX_BIT(|, logic) +OP_BIN_MIX_BIT(^, logic) + +#define REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_bit_ref<_AP_W,_AP_S> &op) { \ + return op2 REL_OP (bool(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op, C_TYPE op2) { \ + return (ap_private<_AP_W + _AP_W1, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W + _AP_W1, false>(op)); \ + } + +#define REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +REF_REL_MIX_INT(bool, 1, false) +REF_REL_MIX_INT(char, 8, true) +REF_REL_MIX_INT(signed char, 8, true) +REF_REL_MIX_INT(unsigned char, 8, false) +REF_REL_MIX_INT(short, 16, true) +REF_REL_MIX_INT(unsigned short, 16, false) +REF_REL_MIX_INT(int, 32, true) +REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_REL_MIX_INT(long, 64, true) +REF_REL_MIX_INT(unsigned long, 64, false) +# else +REF_REL_MIX_INT(long, 32, true) +REF_REL_MIX_INT(unsigned long, 32, false) +# endif +REF_REL_MIX_INT(ap_slong, 64, true) +REF_REL_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP_MIX_INT(BIN_OP, RTYPE, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator BIN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE typename ap_private<_AP_W2, _AP_S2>::template RType<_AP_W,false>::RTYPE \ + operator BIN_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator BIN_OP (ap_private<_AP_W, false>(op)); \ + } + +#define REF_BIN_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(+, plus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(-, minus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(*, mult, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(/, div, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(%, mod, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(>>, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(<<, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(&, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(|, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(^, logic, C_TYPE, _AP_WI, _AP_SI) + +REF_BIN_MIX_INT(bool, 1, false) +REF_BIN_MIX_INT(char, 8, true) +REF_BIN_MIX_INT(signed char, 8, true) +REF_BIN_MIX_INT(unsigned char, 8, false) +REF_BIN_MIX_INT(short, 16, true) +REF_BIN_MIX_INT(unsigned short, 16, false) +REF_BIN_MIX_INT(int, 32, true) +REF_BIN_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_BIN_MIX_INT(long, 64, true) +REF_BIN_MIX_INT(unsigned long, 64, false) +#else +REF_BIN_MIX_INT(long, 32, true) +REF_BIN_MIX_INT(unsigned long, 32, false) +#endif +REF_BIN_MIX_INT(ap_slong, 64, true) +REF_BIN_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP(BIN_OP, RTYPE) \ +template \ +INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2, false>::RTYPE \ +operator BIN_OP (const ap_range_ref<_AP_W,_AP_S> &lhs, const ap_range_ref<_AP_W2,_AP_S2> &rhs) { \ + return ap_private<_AP_W,false>(lhs).operator BIN_OP (ap_private<_AP_W2, false>(rhs)); \ +} + +REF_BIN_OP(+, plus) +REF_BIN_OP(-, minus) +REF_BIN_OP(*, mult) +REF_BIN_OP(/, div) +REF_BIN_OP(%, mod) +REF_BIN_OP(>>, arg1) +REF_BIN_OP(<<, arg1) +REF_BIN_OP(&, logic) +REF_BIN_OP(|, logic) +REF_BIN_OP(^, logic) + +#if 1 +#define CONCAT_OP_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_private<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret |= val; \ + return ret;\ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_private<_AP_W, _AP_S>& op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + if (_AP_S) { \ + ret <<= _AP_WI; ret >>= _AP_WI; \ + } \ + ret |= val << _AP_W; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_range_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + } \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_range_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (const ap_bit_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, false> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (C_TYPE op1, const ap_bit_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + 1, false> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op1, C_TYPE op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op2);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op1);\ + if (_AP_SI) { \ + val <<= _AP_W + _AP_W2; val >>= _AP_W + _AP_W2; \ + } \ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +}\ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op1);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op2);\ + int len = op2.length(); \ + val <<= len; \ + ret |= val;\ + return ret; \ +}\ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const af_range_ref<_AP_W, _AP_I, _AP_S, \ + _AP_Q, _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, \ + _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (C_TYPE op1, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q,\ + _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} + +CONCAT_OP_MIX_INT(bool, 1, false) +CONCAT_OP_MIX_INT(char, 8, true) +CONCAT_OP_MIX_INT(signed char, 8, true) +CONCAT_OP_MIX_INT(unsigned char, 8, false) +CONCAT_OP_MIX_INT(short, 16, true) +CONCAT_OP_MIX_INT(unsigned short, 16, false) +CONCAT_OP_MIX_INT(int, 32, true) +CONCAT_OP_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +CONCAT_OP_MIX_INT(long, 64, true) +CONCAT_OP_MIX_INT(unsigned long, 64, false) +# else +CONCAT_OP_MIX_INT(long, 32, true) +CONCAT_OP_MIX_INT(unsigned long, 32, false) +# endif +CONCAT_OP_MIX_INT(ap_slong, 64, true) +CONCAT_OP_MIX_INT(ap_ulong, 64, false) +#endif + +#if 1 +#define CONCAT_SHIFT_MIX_INT(C_TYPE, op) \ +template \ +INLINE ap_uint<_AP_W+_AP_W1> operator op (const ap_concat_ref<_AP_W, _AP_T, _AP_W1, _AP_T1> lhs, C_TYPE rhs) { \ + return ((ap_uint<_AP_W+_AP_W1>)lhs.get()) op ((int)rhs); \ +} + +CONCAT_SHIFT_MIX_INT(long, <<) +CONCAT_SHIFT_MIX_INT(unsigned long, <<) +CONCAT_SHIFT_MIX_INT(unsigned int, <<) +CONCAT_SHIFT_MIX_INT(ap_ulong, <<) +CONCAT_SHIFT_MIX_INT(ap_slong, <<) +CONCAT_SHIFT_MIX_INT(long, >>) +CONCAT_SHIFT_MIX_INT(unsigned long, >>) +CONCAT_SHIFT_MIX_INT(unsigned int, >>) +CONCAT_SHIFT_MIX_INT(ap_ulong, >>) +CONCAT_SHIFT_MIX_INT(ap_slong, >>) +#endif + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_private<_AP_W, _AP_S> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_private<_AP_W,_AP_S> &op) +{ + ap_private<_AP_W, _AP_S> v=op; + const std::ios_base::fmtflags basefield = out.flags() & std::ios_base::basefield; + unsigned radix = (basefield == std::ios_base::hex) ? 16 : + ((basefield == std::ios_base::oct) ? 8 : 10); + std::string str=v.toString(radix,_AP_S); + out< +INLINE std::istream& operator >> (std::istream& in, ap_private<_AP_W,_AP_S> &op) +{ + std::string str; + in >> str; + op = ap_private<_AP_W, _AP_S>(str.c_str()); + return in; + +} + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator<<(out, ap_private<_AP_W, _AP_S>(op)); +} + +template +INLINE std::istream& operator >> (std::istream& in, ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator>>(in, ap_private<_AP_W, _AP_S>(op));; +} + +template +INLINE void print(const ap_private<_AP_W,_AP_S> &op, bool fill=true ) +{ + ap_private<_AP_W, _AP_S> v=op; + uint32_t ws=v.getNumWords(); + const uint64_t *ptr=v.getRawData(); + int i=ws-1; +#if 0 + if(fill) + printf("%016llx",*(ptr+i)); + else + printf("%llx",*(ptr+i)); +#else +//match SystemC output + if(_AP_W%64 != 0) { + uint32_t offset=_AP_W%64; + uint32_t count=(offset+3)/4; + int64_t data=*(ptr+i); + if(_AP_S) + data=(data<<(64-offset))>>(64-offset); + else + count=(offset+4)/4; + while(count-->0) + printf("%llx",(data>>(count*4))&0xf); + } else { + if(_AP_S==false) + printf("0"); + printf("%016llx",*(ptr+i)); + } +#endif + for(--i;i>=0;i--) + printf("%016llx",*(ptr+i)); + printf("\n"); + +} +#endif /* #ifndef __AESL_GCC_AP_INT_H__ */ \ No newline at end of file diff --git a/hls_2018/router_04/etc/ap_private.h b/hls_2018/router_04/etc/ap_private.h new file mode 100755 index 0000000000000000000000000000000000000000..1a68a9e56e950d7108a3014149623c017023d809 --- /dev/null +++ b/hls_2018/router_04/etc/ap_private.h @@ -0,0 +1,5858 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LLVM_SUPPORT_MATHEXTRAS_H +#define LLVM_SUPPORT_MATHEXTRAS_H + +#ifdef _MSC_VER +#if _MSC_VER <= 1500 +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else if +#include +#endif /* #if _MSC_VER <= 1500 */ +#else +#include +#endif /* #if _MSC_VER <= 1500 */ +#undef INLINE +#if 1 +#define INLINE inline +#else +//Enable to debug ap_int/ap_fixed +#define INLINE __attribute__((weak)) +#endif +#define AP_MAX(a,b) ((a) > (b) ? (a) : (b)) +#define AP_MIN(a,b) ((a) < (b) ? (a) : (b)) +#define AP_ABS(a) ((a)>=0 ? (a):-(a)) +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +// NOTE: The following support functions use the _32/_64 extensions instead of +// type overloading so that signed and unsigned integers can be used without +// ambiguity. + +/// Hi_32 - This function returns the high 32 bits of a 64 bit value. +INLINE uint32_t Hi_32(uint64_t Value) { + return static_cast(Value >> 32); +} + +/// Lo_32 - This function returns the low 32 bits of a 64 bit value. +INLINE uint32_t Lo_32(uint64_t Value) { + return static_cast(Value); +} + +/// ByteSwap_16 - This function returns a byte-swapped representation of the +/// 16-bit argument, Value. +INLINE uint16_t ByteSwap_16(uint16_t Value) { +#if defined(_MSC_VER) && !defined(_DEBUG) + // The DLL version of the runtime lacks these functions (bug!?), but in a + // release build they're replaced with BSWAP instructions anyway. + return (uint16_t)(_byteswap_ushort(Value)); +#else + uint16_t Hi = (uint16_t)((Value) << 8); + uint16_t Lo = (uint16_t)((Value) >> 8); + return Hi | Lo; +#endif +} + +/// ByteSwap_32 - This function returns a byte-swapped representation of the +/// 32-bit argument, Value. +INLINE uint32_t ByteSwap_32(uint32_t Value) { + uint32_t Byte0 = Value & 0x000000FF; + uint32_t Byte1 = Value & 0x0000FF00; + uint32_t Byte2 = Value & 0x00FF0000; + uint32_t Byte3 = Value & 0xFF000000; + return ((Byte0) << 24) | ((Byte1) << 8) | ((Byte2) >> 8) | ((Byte3) >> 24); +} + +/// ByteSwap_64 - This function returns a byte-swapped representation of the +/// 64-bit argument, Value. +INLINE uint64_t ByteSwap_64(uint64_t Value) { + uint64_t Hi = ByteSwap_32(uint32_t(Value)); + uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32)); + return ((Hi) << 32) | Lo; +} + +/// CountLeadingZeros_32 - this function performs the platform optimal form of +/// counting the number of zeros from the most significant bit to the first one +/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. +/// Returns 32 if the word is zero. +INLINE unsigned CountLeadingZeros_32(uint32_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clz(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (Value == 0) return 32; +#endif + Count = __builtin_clz(Value); +#else + if (Value == 0) return 32; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) { + uint32_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } +#endif + return Count; +} + +/// CountLeadingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the most significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountLeadingZeros_64(uint64_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clzll(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (!Value) return 64; +#endif + Count = __builtin_clzll(Value); +#else + if (sizeof(long) == sizeof(int64_t)) { + if (!Value) return 64; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) { + uint64_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } + } else { + // get hi portion + uint32_t Hi = Hi_32(Value); + + // if some bits in hi portion + if (Hi) { + // leading zeros in hi portion plus all bits in lo portion + Count = CountLeadingZeros_32(Hi); + } else { + // get lo portion + uint32_t Lo = Lo_32(Value); + // same as 32 bit value + Count = CountLeadingZeros_32(Lo)+32; + } + } +#endif + return Count; +} + +/// CountTrailingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the least significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountTrailingZeros_64(uint64_t Value) { +#if __GNUC__ >= 4 + return (Value != 0) ? __builtin_ctzll(Value) : 64; +#else + static const unsigned Mod67Position[] = { + 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, + 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, + 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, + 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, + 7, 48, 35, 6, 34, 33, 0 + }; + return Mod67Position[(uint64_t)(-(int64_t)Value & (int64_t)Value) % 67]; +#endif +} + +/// CountPopulation_64 - this function counts the number of set bits in a value, +/// (64 bit edition.) +INLINE unsigned CountPopulation_64(uint64_t Value) { +#if __GNUC__ >= 4 + return __builtin_popcountll(Value); +#else + uint64_t v = Value - (((Value) >> 1) & 0x5555555555555555ULL); + v = (v & 0x3333333333333333ULL) + (((v) >> 2) & 0x3333333333333333ULL); + v = (v + ((v) >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); +#endif +} + +#endif // LLVM_SUPPORT_MATHEXTRAS_H + + +#ifndef AP_PRIVATE_H +#define AP_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AESL_std { + template + DataType INLINE min(DataType a, DataType b) { + // if (a >= b) return b; + // else return a; + return (a>=b) ? b : a; + } + + template + DataType INLINE max(DataType a, DataType b) { + // if (a >= b) return a; + // else return b; + return (a>=b) ? a : b; + } +} +enum ap_q_mode { + AP_RND, // rounding to plus infinity + AP_RND_ZERO,// rounding to zero + AP_RND_MIN_INF,// rounding to minus infinity + AP_RND_INF,// rounding to infinity + AP_RND_CONV, // convergent rounding + AP_TRN, // truncation + AP_TRN_ZERO // truncation to zero + +}; +enum ap_o_mode { + AP_SAT, // saturation + AP_SAT_ZERO, // saturation to zero + AP_SAT_SYM, // symmetrical saturation + AP_WRAP, // wrap-around (*) + AP_WRAP_SM // sign magnitude wrap-around (*) +}; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; + +template struct ap_range_ref; +template struct ap_bit_ref; +template struct ap_concat_ref; +static bool InvalidDigit(const char* str, unsigned len, unsigned start, unsigned radix) { + unsigned i; + for (i = start; i < len; ++i) + if ((radix == 2 && (str[i] == '0' || str[i] == '1')) || + (radix == 8 && str[i] >= '0' && str[i] <= '7') || + (radix == 10 && str[i] >= '0' && str[i] <= '9') || + (radix == 16 && ((str[i] >= '0' && str[i] <= '9') || + (str[i] >= 'a' && str[i] <= 'f') || + (str[i] >= 'A' && str[i] <= 'F')))) + continue; + else + return true; + return false; +} + +static void ap_parse_sign(const char* str, uint32_t &base, bool &neg) { + if (str[0] == '+' || str[0] == '-') base = 1; + if (str[0] == '-') neg = true; + else neg = false; + return; +} + +static void ap_parse_prefix(const char* str, uint32_t &offset, uint32_t &radix) { + if (str[0] == '0') { + switch (str[1]) { + case 'b': + case 'B': offset = 2; radix = 2; break; + case 'x': + case 'X': offset = 2; radix = 16; break; + case 'd': + case 'D': offset = 2; radix = 10; break; + case 'o': + case 'O': offset = 2; radix = 8; break; + default: break; + } + } + if (offset == 0) + for (int i=0, len = strlen(str); i= 'a') || (str[i] <= 'F' && str[i] >= 'A')) { + radix = 16; + break; + } + return; +} + +/// sub_1 - This function subtracts a single "digit" (64-bit word), y, from +/// the multi-digit integer array, x[], propagating the borrowed 1 value until +/// no further borrowing is neeeded or it runs out of "digits" in x. The result +/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. +/// In other words, if y > x then this function returns 1, otherwise 0. +/// @returns the borrow out of the subtraction +static bool sub_1(uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + uint64_t __X = x[i]; + x[i] -= y; + if (y > __X) + y = 1; // We have to "borrow 1" from next "digit" + else { + y = 0; // No need to borrow + break; // Remaining digits are unchanged so exit early + } + } + return (y != 0); +} + + /// This enumeration just provides for internal constants used in this + /// translation unit. + enum { + MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MIN_INT_BITS + MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MAX_INT_BITS + }; + + /// A utility function for allocating memory and checking for allocation + /// failure. The content is not zeroed. + static uint64_t* getMemory(uint32_t numWords) { + return (uint64_t*) malloc(numWords*sizeof(uint64_t)); + } + + //===----------------------------------------------------------------------===// + // ap_private Class + //===----------------------------------------------------------------------===// + + /// ap_private - This class represents arbitrary precision constant integral values. + /// It is a functional replacement for common case unsigned integer type like + /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width + /// integer sizes and large integer value types such as 3-bits, 15-bits, or more + /// than 64-bits of precision. ap_private provides a variety of arithmetic operators + /// and methods to manipulate integer values of any bit-width. It supports both + /// the typical integer arithmetic and comparison operations as well as bitwise + /// manipulation. + /// + /// The class has several invariants worth noting: + /// * All bit, byte, and word positions are zero-based. + /// * Once the bit width is set, it doesn't change except by the Truncate, + /// SignExtend, or ZeroExtend operations. + /// * All binary operators must be on ap_private instances of the same bit width. + /// Attempting to use these operators on instances with different bit + /// widths will yield an assertion. + /// * The value is stored canonically as an unsigned value. For operations + /// where it makes a difference, there are both signed and unsigned variants + /// of the operation. For example, sdiv and udiv. However, because the bit + /// widths must be the same, operations such as Mul and Add produce the same + /// results regardless of whether the values are interpreted as signed or + /// not. + /// * In general, the class tries to follow the style of computation that LLVM + /// uses in its IR. This simplifies its use for LLVM. + /// + /// @brief Class for arbitrary precision integers. + template class ap_private; + namespace ap_private_ops{ + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + } + +#if defined(_MSC_VER) +# if _MSC_VER < 1400 && !defined(for) +# define for if(0);else for +# endif + typedef unsigned __int64 ap_ulong; + typedef signed __int64 ap_slong; +#else + typedef unsigned long long ap_ulong; + typedef signed long long ap_slong; +#endif + template struct retval { + }; + template<> struct retval { + typedef ap_slong Type; + }; + template<> struct retval { + typedef ap_ulong Type; + }; + + template + class ap_private { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template friend struct ap_fixed_base; + ///return type of variety of operations + //---------------------------------------------------------- + template + struct RType { + enum { + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024): for" + " synthesis: please define macro AP_INT_TYPE_EXT(N)" + " to extend the valid range.\n", _AP_W); + } else +#endif + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sint<%d>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + enum { BitWidth = _AP_W }; + /// This union is used to store the integer value. When the + /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal. + + /// This enum is used to hold the constants we needed for ap_private. + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t pVal[_AP_N]; ///< Used to store the >64 bits integer value. + + /// This enum is used to hold the constants we needed for ap_private. + enum { + APINT_BITS_PER_WORD = sizeof(uint64_t) * 8, ///< Bits in a word + APINT_WORD_SIZE = sizeof(uint64_t) ///< Byte size of a word + }; + + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + + /// This constructor is used only internally for speed of construction of + /// temporaries. It is unsafe for general use so it is not public. + /* Constructors */ + + ap_private(const char* val) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 16; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + ap_private(const char* val, int rd) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + // uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + // ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + ap_private ap_private_val(strp , strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + /// Note that numWords can be smaller or larger than the corresponding bit + /// width but any extraneous bits will be dropped. + /// @param numBits the bit width of the constructed ap_private + /// @param numWords the number of words in bigVal + /// @param bigVal a sequence of words to form the initial value of the ap_private + /// @brief Construct an ap_private of numBits width, initialized as bigVal[]. + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(0) { + assert(bigVal && "Null pointer detected!"); + { + // Get memory, cleared to 0 + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Calculate the number of words to copy + uint32_t words = AESL_std::min(numWords, _AP_N); + // Copy the words from bigVal to pVal + memcpy(pVal, bigVal, words * APINT_WORD_SIZE); + if (words >= _AP_W) + clearUnusedBits(); + // Make sure unused high bits are cleared + } + } + + /// This constructor interprets Val as a string in the given radix. The + /// interpretation stops when the first charater that is not suitable for the + /// radix is encountered. Acceptable radix values are 2, 8, 10 and 16. It is + /// an error for the value implied by the string to require more bits than + /// numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param val the string to be interpreted + /// @param radix the radix of Val to use for the intepretation + /// @brief Construct an ap_private from a string representation. + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0) { + assert(!val.empty() && "The input string is empty."); + const char *c_str = val.c_str(); + fromString(c_str+base+offset, val.size()-base-offset, radix); + } + + /// This constructor interprets the slen characters starting at StrStart as + /// a string in the given radix. The interpretation stops when the first + /// character that is not suitable for the radix is encountered. Acceptable + /// radix values are 2, 8, 10 and 16. It is an error for the value implied by + /// the string to require more bits than numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param strStart the start of the string to be interpreted + /// @param slen the maximum number of characters to interpret + /// @param radix the radix to use for the conversion + /// @brief Construct an ap_private from a string representation. + /// This method does not consider whether it is negative or not. + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0) { + fromString(strStart+base+offset, slen-base-offset, radix); + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) { + *this = ((uint64_t)(bool)ref); + report(); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + report(); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = (uint64_t)(bool)val; + report(); + } + + /// Simply makes *this a copy of that. + /// @brief Copy Constructor. + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (const_cast& >(that)); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (that); + } + + template + explicit ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that): VAL(0) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (that.isNegative()) { + pVal[0] = that.VAL|that_sign_ext_mask; + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); + } else { + pVal[0] = that.VAL; + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); + } + clearUnusedBits(); + } + + ap_private(const ap_private& that): VAL(0) { + memcpy(pVal, that.pVal, _AP_N * APINT_WORD_SIZE); + clearUnusedBits(); + } + + /// @brief Destructor. + virtual ~ap_private() {} + + /// Default constructor that creates an uninitialized ap_private. This is useful + /// for object deserialization (pair this with the static method Read). + ap_private(){memset(pVal, 0, sizeof(uint64_t)*(_AP_N));} + + ap_private(uint64_t* val, uint32_t bits=_AP_W) {assert(0);} + ap_private(const uint64_t *const val, uint32_t bits) {assert(0);} + + /// @name Constructors + /// @{ + /// If isSigned is true then val is treated as if it were a signed value + /// (i.e. as an int64_t) and the appropriate sign extension to the bit width + /// will be done. Otherwise, no sign extension occurs (high order bits beyond + /// the range of val are zero filled). + /// @param numBits the bit width of the constructed ap_private + /// @param val the initial value of the ap_private + /// @param isSigned how to treat signedness of val + /// @brief Create a new ap_private of numBits width, initialized as val. +#define CTOR(TYPE, SIGNED) \ + ap_private(TYPE val, bool isSigned=SIGNED) { \ + pVal[0] = val; \ + if (isSigned && int64_t(pVal[0]) < 0) { \ + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); \ + } else { \ + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); \ + } \ + clearUnusedBits(); \ + } +#if 1 + CTOR(int, true) + CTOR(bool, false) + CTOR(signed char, true) + CTOR(unsigned char, false) + CTOR(short, true) + CTOR(unsigned short, false) + CTOR(unsigned int, false) + CTOR(long, true) + CTOR(unsigned long, false) + CTOR(unsigned long long, false) + CTOR(long long, true) + CTOR(float, false) + CTOR(double, false) +#undef CTOR +#else + CTOR(uint64_t) +#undef CTOR +#endif + + + /// @returns true if the number of bits <= 64, false otherwise. + /// @brief Determine if this ap_private just has one word to store value. + INLINE bool isSingleWord() const { + return false; + } + + /// @returns the word position for the specified bit position. + /// @brief Determine which word a bit is in. + static uint32_t whichWord(uint32_t bitPosition) { + // return bitPosition / APINT_BITS_PER_WORD; + return (bitPosition) >> 6; + } + + /// @returns the bit position in a word for the specified bit position + /// in the ap_private. + /// @brief Determine which bit in a word a bit is in. + static uint32_t whichBit(uint32_t bitPosition) { + // return bitPosition % APINT_BITS_PER_WORD; + return bitPosition & 0x3f; + } + + /// bit at a specific bit position. This is used to mask the bit in the + /// corresponding word. + /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set + /// @brief Get a single bit mask. + static uint64_t maskBit(uint32_t bitPosition) { + return 1ULL << (whichBit(bitPosition)); + } + + /// @returns the corresponding word for the specified bit position. + /// @brief Get the word corresponding to a bit position + INLINE uint64_t getWord(uint32_t bitPosition) const { + return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; + } + + /// This method is used internally to clear the to "N" bits in the high order + /// word that are not used by the ap_private. This is needed after the most + /// significant word is assigned a value to ensure that those bits are + /// zero'd out. + /// @brief Clear unused high order bits + INLINE void clearUnusedBits(void) { + pVal[_AP_N-1] = _AP_S ? ((((int64_t)pVal[_AP_N-1])<<(excess_bits))>> excess_bits) : (excess_bits ? ((pVal[_AP_N-1])<<(excess_bits))>>(excess_bits) : pVal[_AP_N-1]); + } + + INLINE void clearUnusedBitsToZero(void) { + pVal[_AP_N-1] &= mask; + } + + INLINE void clearUnusedBitsToOne(void) { + pVal[_AP_N-1] |= mask; + } + + /// This is used by the constructors that take string arguments. + /// @brief Convert a char array into an ap_private + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix) ; + + INLINE ap_private read() volatile { + return *this; + } + + INLINE void write(const ap_private& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + operator ValType() const { + return getVal(); + } + + INLINE ValType getVal() const{ + return *pVal; + } + + INLINE int to_int() const { + return int(*this); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + INLINE ap_private& set(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] |= maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + INLINE void set() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] = ~0ULL; + clearUnusedBits(); + } + + //Get the value of ith bit + INLINE bool get (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + /// Set the given bit to 0 whose position is given as "bitPosition". + /// @brief Set a given bit to 0. + ap_private& clear(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + /// @brief Set every bit to 0. + void clear() { + memset(pVal, 0, _AP_N * APINT_WORD_SIZE); + } + + /// @brief Toggle every bit to its opposite value. + ap_private& flip() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] ^= ~0ULL; + clearUnusedBits(); + return *this; + } + + /// Toggle a given bit to its opposite value whose position is given + /// as "bitPosition". + /// @brief Toggles a given bit to its opposite value. + ap_private& flip(uint32_t bitPosition) { + assert(bitPosition < BitWidth && "Out of the bit-width range!"); + if ((*this)[bitPosition]) clear(bitPosition); + else set(bitPosition); + return *this; + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + ap_private getLoBits(uint32_t numBits) const { + return ap_private_ops::lshr(ap_private_ops::shl(*this, _AP_W - numBits), + _AP_W - numBits); + } + + ap_private getHiBits(uint32_t numBits) const { + return ap_private_ops::lshr(*this, _AP_W - numBits); + } + + //Binary Arithmetic + //----------------------------------------------------------- + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + ///Arithmetic assign + //------------------------------------------------------------- + +#define OP_BIN_LOGIC_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { \ + uint32_t numWords = AESL_std::min(_AP_N, _AP_N1); \ + uint32_t i; \ + for (i = 0; i < numWords; ++i) \ + pVal[i] Sym RHS.pVal[i]; \ + if (_AP_N1 < _AP_N) { \ + uint64_t ext = RHS.isNegative()?~0ULL:0; \ + for (;i<_AP_N; i++) \ + pVal[i] Sym ext; \ + } \ + clearUnusedBits(); \ + return *this; \ + } + + OP_BIN_LOGIC_ASSIGN_AP(&=); + OP_BIN_LOGIC_ASSIGN_AP(|=); + OP_BIN_LOGIC_ASSIGN_AP(^=); +#undef OP_BIN_LOGIC_ASSIGN_AP + + /// Adds the RHS APint to this ap_private. + /// @returns this, after addition of RHS. + /// @brief Addition assignment operator. + template + INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + add(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + sub(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + ap_private& operator*=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) { + // 0 * X ===> 0 + return *this; + } + + ap_private dupRHS = RHS; + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = dupRHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + clear(); + return *this; + } + + // Allocate space for the result + uint32_t destWords = rhsWords + lhsWords; + uint64_t *dest = getMemory(destWords); + + // Perform the long multiply + mul(dest, pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + // Copy result back into *this + clear(); + uint32_t wordsToCopy = destWords >= _AP_N ? _AP_N : destWords; + + memcpy(pVal, dest, wordsToCopy* APINT_WORD_SIZE); + + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0ULL; + for (int i=wordsToCopy; i<_AP_N; i++) + pVal[i]=ext; + clearUnusedBits(); + // delete dest array and return + free(dest); + return *this; + } + +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP(/) + OP_ASSIGN_AP(%) +#undef OP_ASSIGN_AP + +#define OP_BIN_LOGIC_AP(Sym) \ + template \ + INLINE \ + typename RType<_AP_W1, _AP_S1>::logic \ + operator Sym (const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { \ + enum { numWords = (RType<_AP_W1, _AP_S1>::logic_w +APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; \ + typename RType<_AP_W1, _AP_S1>::logic Result; \ + uint64_t *val = Result.pVal; \ + uint32_t i; \ + uint32_t min_N = std::min(_AP_N, _AP_N1); \ + uint32_t max_N = std::max(_AP_N, _AP_N1); \ + for (i = 0; i < min_N; ++i) \ + val[i] = pVal[i] Sym RHS.pVal[i]; \ + if (numWords > i) { \ + const uint64_t* tmpVal = (_AP_N>_AP_N1 ? pVal : RHS.pVal)+i; \ + uint64_t ext = ((_AP_N<_AP_N1 && isNegative() )||(_AP_N1 < _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + for (;i i) { \ + uint64_t ext2 = ((_AP_N>_AP_N1 && isNegative() )||(_AP_N1 > _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + val[i] = ext Sym ext2; \ + } \ + } \ + Result.clearUnusedBits(); \ + return Result; \ + } + + OP_BIN_LOGIC_AP(|); + OP_BIN_LOGIC_AP(&); + OP_BIN_LOGIC_AP(^); + +#undef OP_BIN_LOGIC_AP + + template + INLINE typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + // assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + typename RType<_AP_W1,_AP_S1>::plus Result; + bool carry = add(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::plus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::plus_w + 63) / 64> std::max(_AP_W, _AP_W1) ) + Result.pVal[(RType<_AP_W1,_AP_S1>::plus_w + 63)/64 - 1] = carry; + Result.clearUnusedBits(); + return Result; + } + + template + INLINE typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + typename RType<_AP_W1,_AP_S1>::minus Result; + bool borrow = sub(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::minus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::minus_w + 63) / 64 > AESL_std::max(_AP_W, _AP_W1) ) { + Result.pVal[(RType<_AP_W1,_AP_S1>::minus_w+63)/64 - 1] = borrow; + } + Result.clearUnusedBits(); + return Result; + } + + template + typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) + // 0 * X ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + } + + //extend size to avoid result loss + typename RType<_AP_W1, _AP_S1>::mult dupLHS = *this; + typename RType<_AP_W1, _AP_S1>::mult dupRHS = RHS; + lhsBits = dupLHS.getActiveBits(); + lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + rhsBits = dupRHS.getActiveBits(); + rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + + // Allocate space for the result + enum { destWords =(RType<_AP_W1, _AP_S1>::mult_w+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + int destw = destWords; + typename RType<_AP_W1, _AP_S1>::mult Result; + uint64_t *dest = Result.pVal; + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0; + + // Perform the long multiply + mul(dest, dupLHS.pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + for (int i=lhsWords+rhsWords; i + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=*this; + ap_private rhs= op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod(_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + template + INLINE ap_private + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private + operator << (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=length()); + if(overflow) + r.clear(); + else + r = ap_private(r.shl(sh)); + return r; + } + + template + INLINE ap_private + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private + operator >> (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + INLINE ap_private& operator Sym##=(unsigned int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } + OP_ASSIGN_AP(>>) + OP_ASSIGN_AP(<<) +#undef OP_ASSIGN_AP + ///Comparisons + //----------------------------------------------------------------- + bool operator==(const ap_private& RHS) const { + // Get some facts about the number of bits used in the two operands. + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If the number of bits isn't the same, they aren't equal + if (n1 != n2) + return false; + + // If the number of bits fits in a word, we only need to compare the low word. + if (n1 <= APINT_BITS_PER_WORD) + return pVal[0] == RHS.pVal[0]; + + // Otherwise, compare everything + for (int i = whichWord(n1 - 1); i >= 0; --i) + if (pVal[i] != RHS.pVal[i]) + return false; + return true; + } + + template + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S|_AP_S2> lhs(*this); + ap_private<_AP_MAX_W, _AP_S|_AP_S2> rhs(op); + return lhs==rhs; + } + + bool operator==(uint64_t Val) const { + uint32_t n = getActiveBits(); + if (n <= APINT_BITS_PER_WORD) + return pVal[0] == Val; + else + return false; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2>& op) const { + return !(*this==op); + } + + template + INLINE bool operator!=(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !((*this) == RHS); + } + + INLINE bool operator!=(uint64_t Val) const { + return !((*this) == Val); + } + + + template + INLINE bool operator <= (const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this>op); + } + + INLINE bool operator <(const ap_private& op) const { + return _AP_S ? slt(op):ult(op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.sgt(rhs):lhs.ugt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + } + + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE bool operator [](uint32_t bitPosition) const { + return (maskBit(bitPosition) & (pVal[whichWord(bitPosition)])) != 0; + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + INLINE ap_private<_AP_W,false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + /// @} + /// @name Value Tests + /// @{ + /// This tests the high bit of this ap_private to determine if it is set. + /// @returns true if this ap_private is negative, false otherwise + /// @brief Determine sign of this ap_private. + INLINE bool isNegative() const { + //just for get rid of warnings + enum {shift = (_AP_W-APINT_BITS_PER_WORD*(_AP_N-1)-1)}; + static const uint64_t mask = 1ULL << (shift); + return _AP_S && (pVal[_AP_N-1]&mask); + } + + /// This tests the high bit of the ap_private to determine if it is unset. + /// @brief Determine if this ap_private Value is positive (not negative). + INLINE bool isPositive() const { + return !isNegative(); + } + + /// This tests if the value of this ap_private is strictly positive (> 0). + /// @returns true if this ap_private is Positive and not zero. + /// @brief Determine if this ap_private Value is strictly positive. + INLINE bool isStrictlyPositive() const { + return isPositive() && (*this) != 0; + } + + /// This checks to see if the value has all bits of the ap_private are set or not. + /// @brief Determine if all bits are set + INLINE bool isAllOnesValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest unsigned value. + INLINE bool isMaxValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest signed value. + INLINE bool isMaxSignedValue() const { + return BitWidth == 1 ? VAL == 0 : + !isNegative() && countPopulation() == _AP_W - 1; + } + + /// This checks to see if the value of this ap_private is the minimum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest unsigned value. + INLINE bool isMinValue() const { + return countPopulation() == 0; + } + + /// This checks to see if the value of this ap_private is the minimum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest signed value. + INLINE bool isMinSignedValue() const { + return BitWidth == 1 ? VAL == 1 : + isNegative() && countPopulation() == 1; + } + + /// This function returns a pointer to the internal storage of the ap_private. + /// This is useful for writing out the ap_private in binary form without any + /// conversions. + INLINE const uint64_t* getRawData() const { + if (isSingleWord()) + return &VAL; + return &pVal[0]; + } + + ap_private sqrt() const; + + /// @} + /// @Assignment Operators + /// @{ + /// @returns *this after assignment of RHS. + /// @brief Copy assignment operator. + INLINE ap_private& operator=(const ap_private& RHS) { + if (this != &RHS) + memcpy(pVal, RHS.pVal, _AP_N * APINT_WORD_SIZE); + return *this; + } + INLINE ap_private& operator=(const volatile ap_private& RHS) { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + /// @} + /// @name Unary Operators + /// @{ + /// @returns a new ap_private value representing *this incremented by one + /// @brief Postfix increment operator. + INLINE const ap_private operator++(int) { + ap_private API(*this); + ++(*this); + return API; + } + + /// @returns *this incremented by one + /// @brief Prefix increment operator. + INLINE ap_private& operator++() { + add_1(pVal, pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// @returns a new ap_private representing *this decremented by one. + /// @brief Postfix decrement operator. + INLINE const ap_private operator--(int) { + ap_private API(*this); + --(*this); + return API; + } + + /// @returns *this decremented by one. + /// @brief Prefix decrement operator. + INLINE ap_private& operator--() { + sub_1(pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// Performs a bitwise complement operation on this ap_private. + /// @returns an ap_private that is the bitwise complement of *this + /// @brief Unary bitwise complement operator. + INLINE ap_private operator~() const { + ap_private Result(*this); + Result.flip(); + return Result; + } + + /// Negates *this using two's complement logic. + /// @returns An ap_private value representing the negation of *this. + /// @brief Unary negation operator + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + /// Performs logical negation operation on this ap_private. + /// @returns true if *this is zero, false otherwise. + /// @brief Logical negation operator. + INLINE bool operator !() const { + for (uint32_t i = 0; i < _AP_N; ++i) + if (pVal[i]) + return false; + return true; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator&(RHS); + } + template + INLINE ap_private Or(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator|(RHS); + } + template + ap_private Xor(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator^(RHS); + } + + ap_private Mul(const ap_private& RHS) const { + ap_private Result(*this); + Result *= RHS; + return Result; + } + + ap_private Add(const ap_private& RHS) const { + ap_private Result(0); + bool carry = add(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + ap_private Sub(const ap_private& RHS) const { + ap_private Result(0); + sub(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + /// Arithmetic right-shift this ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + ap_private ashr(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + // Handle a degenerate case + if (shiftAmt == 0) + return *this; + + // Handle single word shifts with built-in ashr + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(/*BitWidth, 0*/); // undefined + else { + uint32_t SignBit = APINT_BITS_PER_WORD - BitWidth; + return ap_private(/*BitWidth,*/ + (((int64_t(VAL) << (SignBit)) >> (SignBit)) >> (shiftAmt))); + } + } + + // If all the bits were shifted out, the result is, technically, undefined. + // We return -1 if it was negative, 0 otherwise. We check this early to avoid + // issues in the algorithm below. + if (shiftAmt == BitWidth) { + if (isNegative()) + return ap_private(-1); + else + return ap_private(0); + } + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // Compute some values needed by the following shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; // bits to shift per word + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; // word offset for shift + uint32_t breakWord = _AP_N - 1 - offset; // last word affected + uint32_t bitsInWord = whichBit(BitWidth); // how many bits in last word? + if (bitsInWord == 0) + bitsInWord = APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + // Move the words containing significant bits + for (uint32_t i = 0; i <= breakWord; ++i) + val[i] = pVal[i+offset]; // move whole word + + // Adjust the top significant word for sign bit fill, if negative + if (isNegative()) + if (bitsInWord < APINT_BITS_PER_WORD) + val[breakWord] |= ~0ULL << (bitsInWord); // set high bits + } else { + // Shift the low order words + for (uint32_t i = 0; i < breakWord; ++i) { + // This combines the shifted corresponding word with the low bits from + // the next word (shifted into this word's high bits). + val[i] = ((pVal[i+offset]) >> (wordShift)); + val[i] |= ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + } + + // Shift the break word. In this case there are no bits from the next word + // to include in this word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Deal with sign extenstion in the break word, and possibly the word before + // it. + if (isNegative()) { + if (wordShift > bitsInWord) { + if (breakWord > 0) + val[breakWord-1] |= + ~0ULL << (APINT_BITS_PER_WORD - (wordShift - bitsInWord)); + val[breakWord] |= ~0ULL; + } else + val[breakWord] |= (~0ULL << (bitsInWord - wordShift)); + } + } + + // Remaining words are 0 or -1, just assign them. + uint64_t fillValue = (isNegative() ? ~0ULL : 0); + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = fillValue; + Retval.clearUnusedBits(); + return Retval; + } + + /// Logical right-shift this ap_private by shiftAmt. + /// @brief Logical right-shift function. + ap_private lshr(uint32_t shiftAmt) const { + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); + else + return ap_private((this->VAL) >> (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids + // issues with shifting byt he size of the integer type, which produces + // undefined results in the code below. This is also an optimization. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // If we are shifting less than a word, compute the shift with a simple carry + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (int i = _AP_N-1; i >= 0; --i) { + val[i] = ((pVal[i]) >> (shiftAmt)) | carry; + carry = (pVal[i]) << (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < _AP_N - offset; ++i) + val[i] = pVal[i+offset]; + for (uint32_t i = _AP_N-offset; i < _AP_N; i++) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + // Shift the low order words + uint32_t breakWord = _AP_N - offset -1; + for (uint32_t i = 0; i < breakWord; ++i) + val[i] = ((pVal[i+offset]) >> (wordShift)) | + ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + // Shift the break word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Remaining words are 0 + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + /// Left-shift this ap_private by shiftAmt. + /// @brief Left-shift function. + ap_private shl(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); // avoid undefined shift results + return ap_private((VAL) << (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids a + // lshr by the words size in the loop below which can produce incorrect + // results. It also avoids the expensive computation below for a common case. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t* val = Retval.pVal; + // If we are shifting less than a word, do it the easy way + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (uint32_t i = 0; i < _AP_N; i++) { + val[i] = ((pVal[i]) << (shiftAmt)) | carry; + carry = (pVal[i]) >> (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < offset; i++) + val[i] = 0; + for (uint32_t i = offset; i < _AP_N; i++) + val[i] = pVal[i-offset]; + Retval.clearUnusedBits(); + return Retval; + } + + // Copy whole words from this to Result. + uint32_t i = _AP_N - 1; + for (; i > offset; --i) + val[i] = (pVal[i-offset]) << (wordShift) | + (pVal[i-offset-1]) >> (APINT_BITS_PER_WORD - wordShift); + val[offset] = (pVal[0]) << (wordShift); + for (i = 0; i < offset; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + INLINE ap_private rotl(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + hi.shl(rotateAmt); + lo.lshr(BitWidth - rotateAmt); + return hi | lo; + } + + INLINE ap_private rotr(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + lo.lshr(rotateAmt); + hi.shl(BitWidth - rotateAmt); + return hi | lo; + } + + /// Perform an unsigned divide operation on this ap_private by RHS. Both this and + /// RHS are treated as unsigned quantities for purposes of this division. + /// @returns a new ap_private value containing the division result + /// @brief Unsigned division operation. + ap_private udiv(const ap_private& RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + + // First, deal with the easy case + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Divide by zero?"); + return ap_private(VAL / RHS.VAL); + } + + // Get some facts about the LHS and RHS number of bits and words + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Divided by zero???"); + uint32_t lhsBits = this->getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Deal with some degenerate cases + if (!lhsWords) + // 0 / X ===> 0 + return ap_private(0); + else if (lhsWords < rhsWords || this->ult(RHS)) { + // X / Y ===> 0, iff X < Y + return ap_private(0); + } else if (*this == RHS) { + // X / X ===> 1 + return ap_private(1); + } else if (lhsWords == 1 && rhsWords == 1) { + // All high words are zero, just use native divide + return ap_private(this->pVal[0] / RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Quotient(0); // to hold result. + divide(*this, lhsWords, RHS, rhsWords, &Quotient, (ap_private*)0); + return Quotient; + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(const ap_private& RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Perform an unsigned remainder operation on this ap_private with RHS being the + /// divisor. Both this and RHS are treated as unsigned quantities for purposes + /// of this operation. Note that this is a true remainder operation and not + /// a modulo operation because the sign follows the sign of the dividend + /// which is *this. + /// @returns a new ap_private value containing the remainder result + /// @brief Unsigned remainder operation. + ap_private urem(const ap_private& RHS) const { + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Remainder by zero?"); + return ap_private(VAL % RHS.VAL); + } + + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Get some facts about the RHS + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, rhsWords, (ap_private*)(0), &Remainder); + return Remainder; + } + + ap_private urem(uint64_t RHS) const { + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + // Get some facts about the RHS + uint32_t rhsBits = 64 - CountLeadingZeros_64(RHS); // RHS.getActiveBits(); + uint32_t rhsWords = 1;//!rhsBits ? 0 : (ap_private<_AP_W, _AP_S, _AP_N>::whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, (ap_private*)(0), &Remainder); + return Remainder; + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(const ap_private& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + /// Sometimes it is convenient to divide two ap_private values and obtain both + /// the quotient and remainder. This function does both operations in the + /// same computation making it a little more efficient. + /// @brief Dual division/remainder interface. + static void udivrem(const ap_private& LHS, const ap_private& RHS, ap_private &Quotient, ap_private& Remainder) { + // Get some size facts about the dividend and divisor + uint32_t lhsBits = LHS.getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (ap_private::whichWord(lhsBits - 1) + 1); + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (ap_private::whichWord(rhsBits - 1) + 1); + + // Check the degenerate cases + if (lhsWords == 0) { + Quotient = 0; // 0 / Y ===> 0 + Remainder = 0; // 0 % Y ===> 0 + return; + } + + if (lhsWords < rhsWords || LHS.ult(RHS)) { + Quotient = 0; // X / Y ===> 0, iff X < Y + Remainder = LHS; // X % Y ===> X, iff X < Y + return; + } + + if (LHS == RHS) { + Quotient = 1; // X / X ===> 1 + Remainder = 0; // X % X ===> 0; + return; + } + + if (lhsWords == 1 && rhsWords == 1) { + // There is only one word to consider so use the native versions. + if (LHS.isSingleWord()) { + Quotient = ap_private(LHS.VAL / RHS.VAL); + Remainder = ap_private(LHS.VAL % RHS.VAL); + } else { + Quotient = ap_private(LHS.pVal[0] / RHS.pVal[0]); + Remainder = ap_private(LHS.pVal[0] % RHS.pVal[0]); + } + return; + } + + // Okay, lets do it the long way + divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder); + } + + static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + /// Compares this ap_private with RHS for the validity of the equality + /// relationship. + /// @returns true if *this == Val + /// @brief Equality comparison. + template + INLINE bool eq(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return (*this) == RHS; + } + + /// Compares this ap_private with RHS for the validity of the inequality + /// relationship. + /// @returns true if *this != Val + /// @brief Inequality comparison + template + INLINE bool ne(const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template + INLINE bool ult(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS.pVal[0]; + + // Otherwise, compare all words + uint32_t topWord = whichWord(AESL_std::max(n1,n2)-1); + for (int i = topWord; i >= 0; --i) { + if (pVal[i] > RHS.pVal[i]) + return false; + if (pVal[i] < RHS.pVal[i]) + return true; + } + return false; + } + + INLINE bool ult(uint64_t RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = 64 - CountLeadingZeros_64(RHS); //RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS; + assert(0); + } + + template + INLINE bool slt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + ap_private lhs(*this); + ap_private<_AP_W, _AP_S1, _AP_N> rhs(RHS); + bool lhsNeg = isNegative(); + bool rhsNeg = rhs.isNegative(); + if (lhsNeg) { + // Sign bit is set so perform two's complement to make it positive + lhs.flip(); + lhs++; + } + if (rhsNeg) { + // Sign bit is set so perform two's complement to make it positive + rhs.flip(); + rhs++; + } + + // Now we have unsigned values to compare so do the comparison if necessary + // based on the negativeness of the values. + if (lhsNeg) + if (rhsNeg) + return lhs.ugt(rhs); + else + return true; + else if (rhsNeg) + return false; + else + return lhs.ult(rhs); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template + INLINE bool ule(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template + INLINE bool sle(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template + INLINE bool ugt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template + INLINE bool sgt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template + INLINE bool uge(const ap_private<_AP_W, _AP_S, _AP_N>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template + INLINE bool sge(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS); + } + + template + void cpTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 > BitWidth && "Invalid ap_private Truncate request"); + assert(_AP_W1 >= MIN_INT_BITS && "Can't truncate to 0 bits"); + memcpy(pVal, that.pVal, _AP_N*APINT_WORD_SIZE); + } + + // Sign extend to a new width. + template + void cpSext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private SignExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + // If the sign bit isn't set, this is the same as zext. + if (!that.isNegative()) { + cpZext(that); + return; + } + + // The sign bit is set. First, get some facts + enum { wordBits = _AP_W1 % APINT_BITS_PER_WORD}; + + // Mask the high order word appropriately + if (_AP_N1 == _AP_N) { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + if (_AP_N1 == 1) { + assert(0); + } else { + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + return; + } + } + + if (_AP_N1 == 1) { + assert(0);// newVal[0] = VAL | mask; + } else { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + } + for (uint32_t i=_AP_N1; i < _AP_N-1; i++) + pVal[i] = ~0ULL; + pVal[_AP_N-1] = ~0ULL; + clearUnusedBits(); + return; + } + + // Zero extend to a new width. + template + void cpZext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private ZeroExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + uint32_t wordsAfter = _AP_N; + if (wordsAfter==1) { + assert(0); // return ap_private<_AP_W1, _AP_S, _AP_N1> (_AP_W1, VAL, _AP_S); + } else { + if (_AP_N1 == 1) { + assert(0); + // newVal[0] = VAL; + } else { + uint32_t i = 0; + for (; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + for (; i < _AP_N; ++i) + pVal[i] = 0; + } + } + clearUnusedBits(); + } + + template + void cpZextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpZext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i]=that.pVal[i]; + clearUnusedBits(); + } + } + + template + void cpSextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpSext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i] = that.pVal[i]; + clearUnusedBits(); + } + } + + /// @name Value Characterization Functions + /// @{ + + /// @returns the total number of bits. + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + /// Here one word's bitwidth equals to that of uint64_t. + /// @returns the number of words to hold the integer value of this ap_private. + /// @brief Get the number of words. + INLINE uint32_t getNumWords() const { + return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; + } + + /// This function returns the number of active bits which is defined as the + /// bit width minus the number of leading zeros. This is used in several + /// computations to see how "wide" the value is. + /// @brief Compute the number of active bits in the value + INLINE uint32_t getActiveBits() const { + uint32_t bits=BitWidth - countLeadingZeros(); + return bits?bits:1; + } + + + /// This method attempts to return the value of this ap_private as a zero extended + /// uint64_t. The bitwidth must be <= 64 or the value must fit within a + /// uint64_t. Otherwise an assertion will result. + /// @brief Get zero extended value + INLINE uint64_t getZExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for uint64_t"); + return *pVal; + } + + /// This method attempts to return the value of this ap_private as a sign extended + /// int64_t. The bit width must be <= 64 or the value must fit within an + /// int64_t. Otherwise an assertion will result. + /// @brief Get sign extended value + INLINE int64_t getSExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for int64_t"); + return int64_t(pVal[0]); + } + + /// This method determines how many bits are required to hold the ap_private + /// equivalent of the string given by \p str of length \p slen. + /// @brief Get bits required for string value. + static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix); + + /// countLeadingZeros - This function is an ap_private version of the + /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number + /// of zeros from the most significant bit to the first one bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the most significant bit to the first + /// one bits. + INLINE uint32_t countLeadingZeros() const ; + + /// countLeadingOnes - This function counts the number of contiguous 1 bits + /// in the high order bits. The count stops when the first 0 bit is reached. + /// @returns 0 if the high order bit is not set + /// @returns the number of 1 bits from the most significant to the least + /// @brief Count the number of leading one bits. + INLINE uint32_t countLeadingOnes() const ; + + /// countTrailingZeros - This function is an ap_private version of the + /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts + /// the number of zeros from the least significant bit to the first set bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the least significant bit to the first + /// one bit. + /// @brief Count the number of trailing zero bits. + INLINE uint32_t countTrailingZeros() const ; + + /// countPopulation - This function is an ap_private version of the + /// countPopulation_{32,64} functions in MathExtras.h. It counts the number + /// of 1 bits in the ap_private value. + /// @returns 0 if the value is zero. + /// @returns the number of set bits. + /// @brief Count the number of bits set. + INLINE uint32_t countPopulation() const { + uint32_t Count = 0; + for (uint32_t i = 0; i<_AP_N-1 ; ++i) + Count += CountPopulation_64(pVal[i]); + Count += CountPopulation_64(pVal[_AP_N-1]&mask); + return Count; + } + + /// @} + /// @name Conversion Functions + /// @{ + + /// This is used internally to convert an ap_private to a string. + /// @brief Converts an ap_private to a std::string + INLINE std::string toString(uint8_t radix, bool wantSigned) const + ; + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + + /// @returns a byte-swapped representation of this ap_private Value. + INLINE ap_private byteSwap() const ; + + /// @brief Converts this ap_private to a double value. + INLINE double roundToDouble(bool isSigned) const ; + + /// @brief Converts this unsigned ap_private to a double value. + INLINE double roundToDouble() const { + return roundToDouble(false); + } + + /// @brief Converts this signed ap_private to a double value. + INLINE double signedRoundToDouble() const { + return roundToDouble(true); + } + + /// The conversion does not do a translation from integer to double, it just + /// re-interprets the bits as a double. Note that it is valid to do this on + /// any bit width. Exactly 64 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE double bitsToDouble() const { + union { + uint64_t __I; + double __D; + } __T; + __T.__I = pVal[0]; + return __T.__D; + } + + /// The conversion does not do a translation from integer to float, it just + /// re-interprets the bits as a float. Note that it is valid to do this on + /// any bit width. Exactly 32 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE float bitsToFloat() const { + union { + uint32_t __I; + float __F; + } __T; + __T.__I = uint32_t(pVal[0]); + return __T.__F; + } + + /// The conversion does not do a translation from double to integer, it just + /// re-interprets the bits of the double. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a double to ap_private bits. + INLINE ap_private& doubleToBits(double __V) { + union { + uint64_t __I; + double __D; + } __T; + __T.__D = __V; + pVal[0] = __T.__I; + return *this; + } + + /// The conversion does not do a translation from float to integer, it just + /// re-interprets the bits of the float. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a float to ap_private bits. + INLINE ap_private& floatToBits(float __V) { + union { + uint32_t __I; + float __F; + } __T; + __T.__F = __V; + pVal[0] = __T.__I; + } + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return isMaxValue(); + } + + INLINE bool nand_reduce() const { + return isMinValue(); + } + + INLINE bool or_reduce() const { + return (bool)countPopulation(); + } + + INLINE bool nor_reduce() const { + return countPopulation()==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + INLINE std::string to_string(uint8_t radix=16, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; + +template +INLINE bool operator==(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 == V1; +} + +template +INLINE bool operator!=(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 != V1; +} + +namespace ap_private_ops { + enum {APINT_BITS_PER_WORD=64}; + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.slt(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.sgt(RHS) ? LHS : RHS; + } + + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ult(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be unsigned. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ugt(RHS) ? LHS : RHS; + } + + /// @brief Check if the specified ap_private has a N-bits integer value. + template + INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); + } + + /// @returns true if the argument ap_private value is a sequence of ones + /// starting at the least significant bit with the remainder zero. + template + INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; + } + + /// @returns true if the argument ap_private value contains a sequence of ones + /// with the remainder zero. + template + INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); + } + + /// @returns a byte-swapped representation of the specified ap_private Value. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> byteSwap(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.byteSwap(); + } + + /// @returns the floor log base 2 of the specified ap_private value. + template INLINE uint32_t logBase2(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.logBase2(); + } + + /// GreatestCommonDivisor - This function returns the greatest common + /// divisor of the two ap_private values using Enclid's algorithm. + /// @returns the greatest common divisor of Val1 and Val2 + /// @brief Compute GCD of two ap_private values. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& Val1, const ap_private<_AP_W, _AP_S, _AP_N>& Val2) + ; + + /// Treats the ap_private as an unsigned value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double Roundap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.roundToDouble(); + } + + /// Treats the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double RoundSignedap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.signedRoundToDouble(); + } + + /// @brief Converts the given ap_private to a float vlalue. + template INLINE float Roundap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(Roundap_privateToDouble(APIVal)); + } + + /// Treast the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a float value. + template INLINE float RoundSignedap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(APIVal.signedRoundToDouble()); + } + + /// RoundDoubleToap_private - This function convert a double value to an ap_private value. + /// @brief Converts the given double value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundDoubleToap_private(double Double, uint32_t width) ; + + /// RoundFloatToap_private - Converts a float value into an ap_private value. + /// @brief Converts a float value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundFloatToap_private(float Float, uint32_t width) { + return RoundDoubleToap_private<_AP_W, _AP_S, _AP_N>(double(Float), width); + } + + /// Arithmetic right-shift the ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> ashr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.ashr(shiftAmt); + } + + /// Logical right-shift the ap_private by shiftAmt. + /// @brief Logical right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.lshr(shiftAmt); + } + + /// Left-shift the ap_private by shiftAmt. + /// @brief Left-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.shl(shiftAmt); + } + + /// Signed divide ap_private LHS by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sdiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.sdiv(RHS); + } + + /// Unsigned divide ap_private LHS by ap_private RHS. + /// @brief Unsigned division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> udiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.udiv(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> srem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.srem(RHS); + } + + /// Unsigned remainder operation on ap_private. + /// @brief Function for unsigned remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> urem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.urem(RHS); + } + + /// Performs multiplication on ap_private values. + /// @brief Function for multiplication operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> mul(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS * RHS; + } + + /// Performs addition on ap_private values. + /// @brief Function for addition operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> add(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS + RHS; + } + + /// Performs subtraction on ap_private values. + /// @brief Function for subtraction operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sub(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS - RHS; + } + + /// Performs bitwise AND operation on ap_private LHS and + /// ap_private RHS. + /// @brief Bitwise AND function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS & RHS; + } + + /// Performs bitwise OR operation on ap_private LHS and ap_private RHS. + /// @brief Bitwise OR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Or(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS | RHS; + } + + /// Performs bitwise XOR operation on ap_private. + /// @brief Bitwise XOR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Xor(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS ^ RHS; + } + + /// Performs a bitwise complement operation on ap_private. + /// @brief Bitwise complement function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> Not(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return ~APIVal; + } + + template void clearUnusedBits(uint64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(uint64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + template void clearUnusedBits(int64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(int64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + // template + template + INLINE ap_private<_AP_W, _AP_S> ashr(const ap_private<_AP_W, _AP_S>& a) { + return ashr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S>& a) { + return lshr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, true> ashr(const ap_private<_AP_W, true, 1>& a) { + enum {APINT_BITS_PER_WORD=64, excess_bits=APINT_BITS_PER_WORD-_AP_W}; + static const uint64_t sign_bit = (1ULL<<(_AP_W-1)); + static const uint64_t sign_ext_mask = (_AP_W-shiftAmt>0)?~0ULL<<(APINT_BITS_PER_WORD-_AP_W+shiftAmt):~0ULL; + return ap_private<_AP_W, true>((((int64_t)a.VAL) >> (shiftAmt)) | (a.VAL & sign_bit? sign_ext_mask : 0ULL)); + } + + template + INLINE ap_private<_AP_W, false> ashr(const ap_private<_AP_W, false, 1>& a) { + return ap_private<_AP_W, false>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~0ULL<<_AP_W; + return ap_private<_AP_W, _AP_S>((a.VAL&mask) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W-shiftAmt, _AP_S> shr(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W-shiftAmt, _AP_S>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W+shiftAmt, _AP_S> shl(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W+shiftAmt, _AP_S>((a.VAL) << (shiftAmt)); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S, 1>& a) { + unsigned shift = (index%APINT_BITS_PER_WORD); + static const uint64_t mask=1ULL << (shift); + return ((mask & a.VAL) != 0); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S>& a) { + static const uint64_t mask=1ULL << (index&0x3f); + return ((mask & a.pVal[(index)>>6]) != 0); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.VAL |= mask; + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~(~0ULL >> (lsb) <<(APINT_BITS_PER_WORD-msb+lsb-1) >> (APINT_BITS_PER_WORD-msb-1)); + a.VAL &= mask; + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word==lsb_word) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[msb_word] |= mask; + } else { + const uint64_t lsb_mask = ~0ULL >> (lsb) << (lsb); + const uint64_t msb_mask = ~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[lsb_word] |=lsb_mask; + for (int i=lsb_word+1; i + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word == lsb_word) { + const uint64_t mask = ~(~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[msb_word] &= mask; + } else { + const uint64_t lsb_mask = ~(~0ULL >> (lsb) << (lsb)); + const uint64_t msb_mask = ~(~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[lsb_word] &=lsb_mask; + for (int i=lsb_word+1; i + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=1ULL << (index); + a.VAL |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=~(1ULL << (index)); + a.VAL &= mask; + a.clearUnusedBits(); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=1ULL << (index%APINT_BITS_PER_WORD); + a.pVal[word] |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=~(1ULL << (index%APINT_BITS_PER_WORD)); + a.pVal[word] &= mask; + a.clearUnusedBits(); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, false>& a) { + return false; + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true, 1>& a) { + static const uint64_t sign_mask = (1ULL << (_AP_W-1)); + return ((sign_mask & a.VAL) != 0); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true>& a) { + enum {APINT_BITS_PER_WORD=64,_AP_N=(_AP_W+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + static const uint64_t sign_mask = (1ULL << (_AP_W%APINT_BITS_PER_WORD-1)); + return sign_mask & a.pVal[_AP_N-1]; + } +} // End of ap_private_ops namespace + +/// @brief Check if the specified ap_private has a N-bits integer value. +template +INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); +} + +/// @returns true if the argument ap_private value is a sequence of ones +/// starting at the least significant bit with the remainder zero. +template +INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; +} + +/// @returns true if the argument ap_private value contains a sequence of ones +/// with the remainder zero. +template +INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); +} + +#if 0 +/// add_1 - This function adds a single "digit" integer, y, to the multiple +/// "digit" integer array, x[]. x[] is modified to reflect the addition and +/// 1 is returned if there is a carry out, otherwise 0 is returned. +/// @returns the carry of the addition. +static bool add_1(uint64_t dest[], uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + dest[i] = y + x[i]; + if (dest[i] < y) + y = 1; // Carry one to next digit. + else { + y = 0; // No need to carry so exit early + break; + } + } + return (y != 0); +} +#endif + +#if 0 +/// add - This function adds the integer array x to the integer array Y and +/// places the result in dest. +/// @returns the carry out from the addition +/// @brief General addition of 64-bit integer arrays +static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool carry = false; + uint32_t len = AESL_std::min(xlen, ylen); + uint32_t i; + for (i = 0; i< len && i < destlen; ++i) { + uint64_t limit = AESL_std::min(x[i],y[i]); // must come first in case dest == x + dest[i] = x[i] + y[i] + carry; + carry = dest[i] < limit || (carry && dest[i] == limit); + } + if (xlen > ylen) { + const uint64_t yext = xsigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t limit = AESL_std::min(x[i], yext); + dest[i] = x[i] + yext + carry; + carry = (dest[i] < limit)||(carry && dest[i] == x[i]); + } + } else if (ylen> xlen) { + const uint64_t xext = ysigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t limit = AESL_std::min(xext, y[i]); + dest[i] = xext + y[i] + carry; + carry = (dest[i] < limit)||(carry && dest[i] == y[i]); + } + } + return carry; +} +#endif + +#if 0 +/// @returns returns the borrow out. +/// @brief Generalized subtraction of 64-bit integer arrays. +static bool sub(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool borrow = false; + uint32_t i; + uint32_t len = AESL_std::min(xlen, ylen); + for (i = 0; i < len && i < destlen; ++i) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = y[i] > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - y[i]; + } + if (xlen > ylen) { + const uint64_t yext = ysigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = yext > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - yext; + } + } else if (ylen> xlen) { + const uint64_t xext = xsigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t x_tmp = borrow ? xext - 1 : xext; + borrow = y[i] > x_tmp || (borrow && xext==0); + dest[i] = x_tmp - y[i]; + } + } + return borrow; +} +#endif + +/// Subtracts the RHS ap_private from this ap_private +/// @returns this, after subtraction +/// @brief Subtraction assignment operator. + +#if 0 +/// Multiplies an integer array, x by a a uint64_t integer and places the result +/// into dest. +/// @returns the carry out of the multiplication. +/// @brief Multiply a multi-digit ap_private by a single digit (64-bit) integer. +static uint64_t mul_1(uint64_t dest[], const uint64_t x[], uint32_t len, uint64_t y) { + // Split y into high 32-bit part (hy) and low 32-bit part (ly) + uint64_t ly = y & 0xffffffffULL, hy = (y) >> 32; + uint64_t carry = 0; + static const uint64_t two_power_32 = 1ULL << 32; + // For each digit of x. + for (uint32_t i = 0; i < len; ++i) { + // Split x into high and low words + uint64_t lx = x[i] & 0xffffffffULL; + uint64_t hx = (x[i]) >> 32; + // hasCarry - A flag to indicate if there is a carry to the next digit. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + dest[i] = carry + lx * ly; + // Determine if the add above introduces carry. + hasCarry = (dest[i] < carry) ? 1 : 0; + carry = hx * ly + ((dest[i]) >> 32) + (hasCarry ? two_power_32 : 0); + // The upper limit of carry can be (2^32 - 1)(2^32 - 1) + + // (2^32 - 1) + 2^32 = 2^64. + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + + carry += (lx * hy) & 0xffffffffULL; + dest[i] = ((carry) << 32) | (dest[i] & 0xffffffffULL); + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? two_power_32 : 0) + + ((carry) >> 32) + ((lx * hy) >> 32) + hx * hy; + } + return carry; +} +#endif + +#if 0 +/// Multiplies integer array x by integer array y and stores the result into +/// the integer array dest. Note that dest's size must be >= xlen + ylen. +/// @brief Generalized multiplicate of integer arrays. +static void mul(uint64_t dest[], const uint64_t x[], uint32_t xlen, const uint64_t y[], + uint32_t ylen, uint32_t destlen) { + dest[xlen] = mul_1(dest, x, xlen, y[0]); + for (uint32_t i = 1; i < ylen; ++i) { + uint64_t ly = y[i] & 0xffffffffULL, hy = (y[i]) >> 32; + uint64_t carry = 0, lx = 0, hx = 0; + for (uint32_t j = 0; j < xlen; ++j) { + lx = x[j] & 0xffffffffULL; + hx = (x[j]) >> 32; + // hasCarry - A flag to indicate if has carry. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + uint64_t resul = carry + lx * ly; + hasCarry = (resul < carry) ? 1 : 0; + carry = (hasCarry ? (1ULL << 32) : 0) + hx * ly + ((resul) >> 32); + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + carry += (lx * hy) & 0xffffffffULL; + resul = ((carry) << 32) | (resul & 0xffffffffULL); + dest[i+j] += resul; + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0)+ + ((carry) >> 32) + (dest[i+j] < resul ? 1 : 0) + + ((lx * hy) >> 32) + hx * hy; + } + dest[i+xlen] = carry; + } +} +#endif + + + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + assert(str != 0 && "Invalid value string"); + assert(slen > 0 && "Invalid string length"); + + // Each computation below needs to know if its negative + uint32_t isNegative = str[0] == '-'; + if (isNegative) { + slen--; + str++; + } + // For radixes of power-of-two values, the bits required is accurately and + // easily computed + if (radix == 2) + return slen + isNegative; + if (radix == 8) + return slen * 3 + isNegative; + if (radix == 16) + return slen * 4 + isNegative; + + // Otherwise it must be radix == 10, the hard case + assert(radix == 10 && "Invalid radix"); + + // Convert to the actual binary value. + //ap_private<_AP_W, _AP_S, _AP_N> tmp(sufficient, str, slen, radix); + + // Compute how many bits are required. + //return isNegative + tmp.logBase2() + 1; + return isNegative + slen * 4; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingZeros() const { + enum { msw_bits = (BitWidth % APINT_BITS_PER_WORD)?(BitWidth % APINT_BITS_PER_WORD):APINT_BITS_PER_WORD, + excessBits = APINT_BITS_PER_WORD - msw_bits }; + uint32_t Count = CountLeadingZeros_64(pVal[_AP_N-1]); + if (Count>=excessBits) + Count -= excessBits; + if (!pVal[_AP_N-1]) { + for (uint32_t i = _AP_N-1 ; i ; --i) { + if (!pVal[i-1]) + Count += APINT_BITS_PER_WORD; + else { + Count += CountLeadingZeros_64(pVal[i-1]); + break; + } + } + } + return Count; +} + +static uint32_t countLeadingOnes_64(uint64_t __V, uint32_t skip) { + uint32_t Count = 0; + if (skip) + (__V) <<= (skip); + while (__V && (__V & (1ULL << 63))) { + Count++; + (__V) <<= 1; + } + return Count; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingOnes() const { + if (isSingleWord()) + return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth); + + uint32_t highWordBits = BitWidth % APINT_BITS_PER_WORD; + uint32_t shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits); + int i = _AP_N - 1; + uint32_t Count = countLeadingOnes_64(pVal[i], shift); + if (Count == highWordBits) { + for (i--; i >= 0; --i) { + if (pVal[i] == ~0ULL) + Count += APINT_BITS_PER_WORD; + else { + Count += countLeadingOnes_64(pVal[i], 0); + break; + } + } + } + return Count; +} + +template +INLINE uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countTrailingZeros() const { + if (isSingleWord()) + return AESL_std::min(uint32_t(CountTrailingZeros_64(VAL)), BitWidth); + uint32_t Count = 0; + uint32_t i = 0; + for (; i < _AP_N && pVal[i] == 0; ++i) + Count += APINT_BITS_PER_WORD; + if (i < _AP_N) + Count += CountTrailingZeros_64(pVal[i]); + return AESL_std::min(Count, BitWidth); +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::byteSwap() const { + assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!"); + if (BitWidth == 16) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_16(uint16_t(VAL))); + else if (BitWidth == 32) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_32(uint32_t(VAL))); + else if (BitWidth == 48) { + uint32_t Tmp1 = uint32_t((VAL) >> 16); + Tmp1 = ByteSwap_32(Tmp1); + uint16_t Tmp2 = uint16_t(VAL); + Tmp2 = ByteSwap_16(Tmp2); + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ((uint64_t(Tmp2)) << 32) | Tmp1); + } else if (BitWidth == 64) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_64(VAL)); + else { + ap_private<_AP_W, _AP_S, _AP_N> Result(0); + char *pByte = (char*)Result.pVal; + for (uint32_t i = 0; i < BitWidth / APINT_WORD_SIZE / 2; ++i) { + char Tmp = pByte[i]; + pByte[i] = pByte[BitWidth / APINT_WORD_SIZE - 1 - i]; + pByte[BitWidth / APINT_WORD_SIZE - i - 1] = Tmp; + } + return Result; + } +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& API1, const ap_private<_AP_W, _AP_S, _AP_N>& API2) { + ap_private<_AP_W, _AP_S, _AP_N> __A = API1, __B = API2; + while (!!__B) { + ap_private<_AP_W, _AP_S, _AP_N> __T = __B; + __B = ap_private_ops::urem(__A, __B); + __A = __T; + } + return __A; +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::RoundDoubleToap_private(double Double, uint32_t width) { + union { + double __D; + uint64_t __I; + } __T; + __T.__D = Double; + + // Get the sign bit from the highest order bit + bool isNeg = (__T.__I) >> 63; + + // Get the 11-bit exponent and adjust for the 1023 bit bias + int64_t exp = (((__T.__I) >> 52) & 0x7ffULL) - 1023; + + // If the exponent is negative, the value is < 0 so just return 0. + if (exp < 0) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0u); + + // Extract the mantissa by clearing the top 12 bits (sign + exponent). + uint64_t mantissa = (__T.__I & (~0ULL >> 12)) | 1ULL << 52; + + // If the exponent doesn't shift all bits out of the mantissa + if (exp < 52) + return isNeg ? -ap_private<_AP_W, _AP_S, _AP_N>(width, (mantissa) >> (52 - exp)) : + ap_private<_AP_W, _AP_S, _AP_N>((mantissa) >> (52 - exp)); + + // If the client didn't provide enough bits for us to shift the mantissa into + // then the result is undefined, just return 0 + if (width <= exp - 52) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0); + + // Otherwise, we have to shift the mantissa bits up to the right location + ap_private<_AP_W, _AP_S, _AP_N> Tmp(width, mantissa); + Tmp = Tmp.shl(exp - 52); + return isNeg ? -Tmp : Tmp; +} + +/// RoundToDouble - This function convert this ap_private to a double. +/// The layout for double is as following (IEEE Standard 754): +/// -------------------------------------- +/// | Sign Exponent Fraction Bias | +/// |-------------------------------------- | +/// | 1[63] 11[62-52] 52[51-00] 1023 | +/// -------------------------------------- +template +double ap_private<_AP_W, _AP_S, _AP_N>::roundToDouble(bool isSigned) const { + + // Handle the simple case where the value is contained in one uint64_t. + if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) { + uint64_t val; + if (isSingleWord()) val = VAL; + else val = pVal[0]; + if (isSigned) { + int64_t sext = ((int64_t(val)) << (64-BitWidth)) >> (64-BitWidth); + return double(sext); + } else + return double(val); + } + + // Determine if the value is negative. + bool isNeg = isSigned ? (*this)[BitWidth-1] : false; + + // Construct the absolute value if we're negative. + ap_private<_AP_W, _AP_S, _AP_N> Tmp(isNeg ? -(*this) : (*this)); + + // Figure out how many bits we're using. + uint32_t n = Tmp.getActiveBits(); + + // The exponent (without bias normalization) is just the number of bits + // we are using. Note that the sign bit is gone since we constructed the + // absolute value. + uint64_t exp = n; + + // Return infinity for exponent overflow + if (exp > 1023) { + if (!isSigned || !isNeg) + return std::numeric_limits::infinity(); + else + return -std::numeric_limits::infinity(); + } + exp += 1023; // Increment for 1023 bias + + // Number of bits in mantissa is 52. To obtain the mantissa value, we must + // extract the high 52 bits from the correct words in pVal. + uint64_t mantissa; + unsigned hiWord = whichWord(n-1); + if (hiWord == 0) { + mantissa = Tmp.pVal[0]; + if (n > 52) + (mantissa) >>= (n - 52); // shift down, we want the top 52 bits. + } else { + assert(hiWord > 0 && "High word is negative?"); + uint64_t hibits = (Tmp.pVal[hiWord]) << (52 - n % APINT_BITS_PER_WORD); + uint64_t lobits = (Tmp.pVal[hiWord-1]) >> (11 + n % APINT_BITS_PER_WORD); + mantissa = hibits | lobits; + } + + // The leading bit of mantissa is implicit, so get rid of it. + uint64_t sign = isNeg ? (1ULL << (APINT_BITS_PER_WORD - 1)) : 0; + union { + double __D; + uint64_t __I; + } __T; + __T.__I = sign | ((exp) << 52) | mantissa; + return __T.__D; +} + +// Square Root - this method computes and returns the square root of "this". +// Three mechanisms are used for computation. For small values (<= 5 bits), +// a table lookup is done. This gets some performance for common cases. For +// values using less than 52 bits, the value is converted to double and then +// the libc sqrt function is called. The result is rounded and then converted +// back to a uint64_t which is then used to construct the result. Finally, +// the Babylonian method for computing square roots is used. +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::sqrt() const { + + // Determine the magnitude of the value. + uint32_t magnitude = getActiveBits(); + + // Use a fast table for some small values. This also gets rid of some + // rounding errors in libc sqrt for small values. + if (magnitude <= 5) { + static const uint8_t results[32] = { + /* 0 */ 0, + /* 1- 2 */ 1, 1, + /* 3- 6 */ 2, 2, 2, 2, + /* 7-12 */ 3, 3, 3, 3, 3, 3, + /* 13-20 */ 4, 4, 4, 4, 4, 4, 4, 4, + /* 21-30 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 31 */ 6 + }; + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ results[ (isSingleWord() ? VAL : pVal[0]) ]); + } + + // If the magnitude of the value fits in less than 52 bits (the precision of + // an IEEE double precision floating point value), then we can use the + // libc sqrt function which will probably use a hardware sqrt computation. + // This should be faster than the algorithm below. + if (magnitude < 52) { +#ifdef _MSC_VER + // Amazingly, VC++ doesn't have round(). + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0]))) + 0.5); +#else + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0]))))); +#endif + } + + // Okay, all the short cuts are exhausted. We must compute it. The following + // is a classical Babylonian method for computing the square root. This code + // was adapted to APINt from a wikipedia article on such computations. + // See http://www.wikipedia.org/ and go to the page named + // Calculate_an_integer_square_root. + uint32_t nbits = BitWidth, i = 4; + ap_private<_AP_W, _AP_S, _AP_N> testy(16); + ap_private<_AP_W, _AP_S, _AP_N> x_old(/*BitWidth,*/ 1); + ap_private<_AP_W, _AP_S, _AP_N> x_new(0); + ap_private<_AP_W, _AP_S, _AP_N> two(/*BitWidth,*/ 2); + + // Select a good starting value using binary logarithms. + for (;; i += 2, testy = testy.shl(2)) + if (i >= nbits || this->ule(testy)) { + x_old = x_old.shl(i / 2); + break; + } + + // Use the Babylonian method to arrive at the integer square root: + for (;;) { + x_new = (this->udiv(x_old) + x_old).udiv(two); + if (x_old.ule(x_new)) + break; + x_old = x_new; + } + + // Make sure we return the closest approximation + // NOTE: The rounding calculation below is correct. It will produce an + // off-by-one discrepancy with results from pari/gp. That discrepancy has been + // determined to be a rounding issue with pari/gp as it begins to use a + // floating point representation after 192 bits. There are no discrepancies + // between this algorithm and pari/gp for bit widths < 192 bits. + ap_private<_AP_W, _AP_S, _AP_N> square(x_old * x_old); + ap_private<_AP_W, _AP_S, _AP_N> nextSquare((x_old + 1) * (x_old +1)); + if (this->ult(square)) + return x_old; + else if (this->ule(nextSquare)) { + ap_private<_AP_W, _AP_S, _AP_N> midpoint((nextSquare - square).udiv(two)); + ap_private<_AP_W, _AP_S, _AP_N> offset(*this - square); + if (offset.ult(midpoint)) + return x_old; + else + return x_old + 1; + } else + assert(0 && "Error in ap_private<_AP_W, _AP_S, _AP_N>::sqrt computation"); + return x_old + 1; +} + +/// Implementation of Knuth's Algorithm D (Division of nonnegative integers) +/// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The +/// variables here have the same names as in the algorithm. Comments explain +/// the algorithm and any deviation from it. +static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r, + uint32_t m, uint32_t n) { + assert(u && "Must provide dividend"); + assert(v && "Must provide divisor"); + assert(q && "Must provide quotient"); + assert(u != v && u != q && v != q && "Must us different memory"); + assert(n>1 && "n must be > 1"); + + // Knuth uses the value b as the base of the number system. In our case b + // is 2^31 so we just set it to -1u. + uint64_t b = uint64_t(1) << 32; + + //DEBUG(cerr << "KnuthDiv: m=" << m << " n=" << n << '\n'); + //DEBUG(cerr << "KnuthDiv: original:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of + // u and v by d. Note that we have taken Knuth's advice here to use a power + // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of + // 2 allows us to shift instead of multiply and it is easy to determine the + // shift amount from the leading zeros. We are basically normalizing the u + // and v so that its high bits are shifted to the top of v's range without + // overflow. Note that this can require an extra word in u so that u must + // be of length m+n+1. + uint32_t shift = CountLeadingZeros_32(v[n-1]); + uint32_t v_carry = 0; + uint32_t u_carry = 0; + if (shift) { + for (uint32_t i = 0; i < m+n; ++i) { + uint32_t u_tmp = (u[i]) >> (32 - shift); + u[i] = ((u[i]) << (shift)) | u_carry; + u_carry = u_tmp; + } + for (uint32_t i = 0; i < n; ++i) { + uint32_t v_tmp = (v[i]) >> (32 - shift); + v[i] = ((v[i]) << (shift)) | v_carry; + v_carry = v_tmp; + } + } + u[m+n] = u_carry; + //DEBUG(cerr << "KnuthDiv: normal:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + + // D2. [Initialize j.] Set j to m. This is the loop counter over the places. + int j = m; + do { + //DEBUG(cerr << "KnuthDiv: quotient digit #" << j << '\n'); + // D3. [Calculate q'.]. + // Set qp = (u[j+n]*b + u[j+n-1]) / v[n-1]. (qp=qprime=q') + // Set rp = (u[j+n]*b + u[j+n-1]) % v[n-1]. (rp=rprime=r') + // Now test if qp == b or qp*v[n-2] > b*rp + u[j+n-2]; if so, decrease + // qp by 1, inrease rp by v[n-1], and repeat this test if rp < b. The test + // on v[n-2] determines at high speed most of the cases in which the trial + // value qp is one too large, and it eliminates all cases where qp is two + // too large. + uint64_t dividend = ((uint64_t(u[j+n]) << 32) + u[j+n-1]); + //DEBUG(cerr << "KnuthDiv: dividend == " << dividend << '\n'); + uint64_t qp = dividend / v[n-1]; + uint64_t rp = dividend % v[n-1]; + if (qp == b || qp*v[n-2] > b*rp + u[j+n-2]) { + qp--; + rp += v[n-1]; + if (rp < b && (qp == b || qp*v[n-2] > b*rp + u[j+n-2])) + qp--; + } + //DEBUG(cerr << "KnuthDiv: qp == " << qp << ", rp == " << rp << '\n'); + + // D4. [Multiply and subtract.] Replace (u[j+n]u[j+n-1]...u[j]) with + // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation + // consists of a simple multiplication by a one-place number, combined with + // a subtraction. + bool isNeg = false; + for (uint32_t i = 0; i < n; ++i) { + uint64_t u_tmp = uint64_t(u[j+i]) | ((uint64_t(u[j+i+1])) << 32); + uint64_t subtrahend = uint64_t(qp) * uint64_t(v[i]); + bool borrow = subtrahend > u_tmp; + /*DEBUG(cerr << "KnuthDiv: u_tmp == " << u_tmp + << ", subtrahend == " << subtrahend + << ", borrow = " << borrow << '\n');*/ + + uint64_t result = u_tmp - subtrahend; + uint32_t k = j + i; + u[k++] = (uint32_t)(result & (b-1)); // subtract low word + u[k++] = (uint32_t)((result) >> 32); // subtract high word + while (borrow && k <= m+n) { // deal with borrow to the left + borrow = u[k] == 0; + u[k]--; + k++; + } + isNeg |= borrow; + /*DEBUG(cerr << "KnuthDiv: u[j+i] == " << u[j+i] << ", u[j+i+1] == " << + u[j+i+1] << '\n');*/ + } + /*DEBUG(cerr << "KnuthDiv: after subtraction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + // The digits (u[j+n]...u[j]) should be kept positive; if the result of + // this step is actually negative, (u[j+n]...u[j]) should be left as the + // true value plus b**(n+1), namely as the b's complement of + // the true value, and a "borrow" to the left should be remembered. + // + if (isNeg) { + bool carry = true; // true because b's complement is "complement + 1" + for (uint32_t i = 0; i <= m+n; ++i) { + u[i] = ~u[i] + carry; // b's complement + carry = carry && u[i] == 0; + } + } + /*DEBUG(cerr << "KnuthDiv: after complement:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + + // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was + // negative, go to step D6; otherwise go on to step D7. + q[j] = (uint32_t)qp; + if (isNeg) { + // D6. [Add back]. The probability that this step is necessary is very + // small, on the order of only 2/b. Make sure that test data accounts for + // this possibility. Decrease q[j] by 1 + q[j]--; + // and add (0v[n-1]...v[1]v[0]) to (u[j+n]u[j+n-1]...u[j+1]u[j]). + // A carry will occur to the left of u[j+n], and it should be ignored + // since it cancels with the borrow that occurred in D4. + bool carry = false; + for (uint32_t i = 0; i < n; i++) { + uint32_t limit = AESL_std::min(u[j+i],v[i]); + u[j+i] += v[i] + carry; + carry = u[j+i] < limit || (carry && u[j+i] == limit); + } + u[j+n] += carry; + } + /*DEBUG(cerr << "KnuthDiv: after correction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr <<" " << u[i]); + DEBUG(cerr << "\nKnuthDiv: digit result = " << q[j] << '\n');*/ + + // D7. [Loop on j.] Decrease j by one. Now if j >= 0, go back to D3. + } while (--j >= 0); + + /*DEBUG(cerr << "KnuthDiv: quotient:"); + DEBUG(for (int i = m; i >=0; i--) cerr <<" " << q[i]); + DEBUG(cerr << '\n');*/ + + // D8. [Unnormalize]. Now q[...] is the desired quotient, and the desired + // remainder may be obtained by dividing u[...] by d. If r is non-null we + // compute the remainder (urem uses this). + if (r) { + // The value d is expressed by the "shift" value above since we avoided + // multiplication by d by using a shift left. So, all we have to do is + // shift right here. In order to mak + if (shift) { + uint32_t carry = 0; + //DEBUG(cerr << "KnuthDiv: remainder:"); + for (int i = n-1; i >= 0; i--) { + r[i] = ((u[i]) >> (shift)) | carry; + carry = (u[i]) << (32 - shift); + //DEBUG(cerr << " " << r[i]); + } + } else { + for (int i = n-1; i >= 0; i--) { + r[i] = u[i]; + //DEBUG(cerr << " " << r[i]); + } + } + //DEBUG(cerr << '\n'); + } + //DEBUG(cerr << std::setbase(10) << '\n'); +} + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + const ap_private<_AP_W, _AP_S, _AP_N>& RHS, uint32_t rhsWords, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = rhsWords * 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = (uint32_t)(tmp & mask); + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + for (unsigned i = 0; i < rhsWords; ++i) { + uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]); + __V[i * 2] = (uint32_t)(tmp & mask); + __V[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = (uint32_t)partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = (uint32_t)(partial_dividend / divisor); + remainder = (uint32_t)(partial_dividend - (__Q[i] * divisor)); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != RHS.BitWidth) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + + +template +void ap_private<_AP_W, _AP_S, _AP_N>::fromString(const char *str, uint32_t slen, uint8_t radix) { + enum { numbits=_AP_W}; + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(str && "String is null?"); + bool isNeg = str[0] == '-'; + if (isNeg) + str++, slen--; + + //skip any leading zero + while(*str == '0' && *(str+1) != '\0') {str++; slen--;} + assert((slen <= numbits || radix != 2) && "Insufficient bit width"); + assert(((slen - 1)*3 <= numbits || radix != 8) && "Insufficient bit width"); + assert(((slen - 1)*4 <= numbits || radix != 16) && "Insufficient bit width"); + assert((((slen -1)*64)/22 <= numbits || radix != 10) && "Insufficient bit width"); + + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Figure out if we can shift instead of multiply + uint32_t shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0); + + // Set up an ap_private for the digit to add outside the loop so we don't + // constantly construct/destruct it. + uint64_t bigVal[_AP_N]; + memset(bigVal, 0, _AP_N * sizeof(uint64_t)); + ap_private<_AP_W, _AP_S, _AP_N> apdigit(getBitWidth(), bigVal); + ap_private<_AP_W, _AP_S, _AP_N> apradix(radix); + + // Enter digit traversal loop + for (unsigned i = 0; i < slen; i++) { + // Get a digit + uint32_t digit = 0; + char cdigit = str[i]; + if (radix == 16) { +#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#define isdigit(c) ((c) >= '0' && (c) <= '9') + if (!isxdigit(cdigit)) + assert(0 && "Invalid hex digit in string"); + if (isdigit(cdigit)) + digit = cdigit - '0'; + else if (cdigit >= 'a') + digit = cdigit - 'a' + 10; + else if (cdigit >= 'A') + digit = cdigit - 'A' + 10; + else + assert(0 && "huh? we shouldn't get here"); + } else if (isdigit(cdigit)) { + digit = cdigit - '0'; + } else { + assert(0 && "Invalid character in digit string"); + } +#undef isxdigit +#undef isdigit + // Shift or multiply the value by the radix + if (shift) + *this <<= shift; + else + *this *= apradix; + + // Add in the digit we just interpreted + if (apdigit.isSingleWord()) + apdigit.VAL = digit; + else + apdigit.pVal[0] = digit; + *this += apdigit; + } + // If its negative, put it in two's complement form + if (isNeg) { + (*this)--; + this->flip(); + } + clearUnusedBits(); +} + +template +std::string ap_private<_AP_W, _AP_S, _AP_N>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" + }; + std::string result; + uint32_t bits_used = getActiveBits(); + + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, _AP_N> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, _AP_N> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask; + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, _AP_N> tmp(*this); + ap_private<_AP_W, false, _AP_N> divisor(radix); + ap_private<_AP_W, false, _AP_N> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, _AP_N>(0)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, _AP_N> APdigit(0); + ap_private<_AP_W, false, _AP_N> tmp2(0); + divide(tmp, tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2, + &APdigit); + uint32_t digit = APdigit.getZExtValue(); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + + return result; +} + +// This implements a variety of operations on a representation of +// arbitrary precision, two's-complement, bignum integer values. + +/* Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe + and unrestricting assumption. */ + +/* Some handy functions local to this file. */ + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + uint64_t RHS, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + uint32_t rhsWords=1; + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = tmp & mask; + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + __V[0] = RHS & mask; + __V[1] = (RHS) >> (sizeof(uint32_t)*8); + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = partial_dividend / divisor; + remainder = partial_dividend - (__Q[i] * divisor); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + else + delete [] Quotient->pVal; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != 64 /* RHS.BitWidth */) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in __R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + +//When bitwidth < 64 +template class ap_private <_AP_W, _AP_S, 1> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template + struct RType { + enum { + _AP_N =1, + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, //?? why + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, //shouldn't it be AP_MAX(_AP_W,_AP_W2)+!(_AP_S^_AP_S2)+1 ???? + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + enum { APINT_BITS_PER_WORD = 64}; + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + static const uint64_t not_mask = ~mask; + static const uint64_t sign_bit_mask = 1ULL << (APINT_BITS_PER_WORD-1); + template struct sign_ext_mask { static const uint64_t mask=~0ULL<<_AP_W1;}; + + enum { BitWidth=_AP_W}; + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + const uint64_t *const pVal; + + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + volatile ap_private& operator=(const ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const volatile ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + template + INLINE ap_private& operator = (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + *this = ap_private<_AP_W2, false>(op2); + return *this; + } + + explicit INLINE ap_private(uint64_t* val) : VAL(val[0]), pVal(&VAL){ + clearUnusedBits(); + } + + INLINE bool isSingleWord() const { return true; } + + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix, int offset=0) { + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(strStart && "String is null?"); + strStart+=offset; + switch(radix) { + case 2: + // sscanf(strStart,"%b",&VAL); + VAL = *strStart =='1' ? ~0ULL : 0; + for (;*strStart; ++strStart) { + assert((*strStart=='0'|| *strStart=='1')&&("Wrong binary number") ); + VAL <<=1; + VAL |= (*strStart-'0'); + } + break; + case 8: +#if __WIN32__ + sscanf(strStart,"%I64o",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lo",&VAL); +#else + sscanf(strStart,"%llo",&VAL); +#endif + +#endif + break; + case 10: +#if __WIN32__ + sscanf(strStart,"%I64u",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lu",&VAL); +#else + sscanf(strStart,"%llu",&VAL); +#endif + +#endif + break; + case 16: +#if __WIN32__ + sscanf(strStart,"%I64x",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lx",&VAL); +#else + sscanf(strStart,"%llx",&VAL); +#endif + +#endif + break; + default: + assert(true && "Unknown radix"); + // error + } + clearUnusedBits(); + } + + INLINE ap_private() : pVal(&VAL){VAL = 0ULL;} + +#define CTOR(TYPE) \ + INLINE ap_private(TYPE v) : VAL((uint64_t)v), pVal(&VAL) { \ + clearUnusedBits(); \ + } + CTOR(int) + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) +#undef CTOR + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(bigVal[0]), pVal(&VAL) {clearUnusedBits();} + + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0), pVal(&VAL) { + assert(!val.empty() && "String empty?"); + fromString(val.c_str()+base, val.size()-base, radix); + } + + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0), pVal(&VAL) { + fromString(strStart+base, slen-base, radix, offset); + } + + ap_private(const ap_private& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + +#if 0 +template + explicit ap_private(const ap_private<_AP_W1, true, 1+_AP_W1/64>& that) + : VAL((_AP_W1>_AP_W) ? that.VAL & mask : ((1ULL<<(_AP_W1-1)&that.pVal[0]) ? sign_ext_mask<_AP_W1>::mask | that.VAL : that.pVal[0])), pVal(&VAL) {} + +template + explicit ap_private(const ap_private<_AP_W1, false, (_AP_W1+63)/64>& that) + : VAL(that.VAL & mask), pVal(&VAL) {} +#endif + + explicit ap_private(const char* val) : pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 10; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private<_AP_W, _AP_S> ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + ap_private(const char* val, signed char rd): pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + ap_private<_AP_W, _AP_S> ap_private_val(strp , strLen, radix, base, offset); + //ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + if (strp[0] == '-') + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + INLINE bool isNegative() const { + static const uint64_t sign_mask = 1ULL << (_AP_W-1); + return _AP_S && (sign_mask & VAL); + } + + INLINE bool isPositive() const { + return !isNegative(); + } + + INLINE bool isStrictlyPositive() const { + return !isNegative() && VAL!=0; + } + + INLINE bool isAllOnesValue() const { + return (mask & VAL) == mask; + } + + template + INLINE bool operator==(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + return (VAL == RHS.VAL); + } + + INLINE bool operator==(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL == RHS.VAL; } + INLINE bool operator==(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() == RHS.getVal(); } + INLINE bool operator==(uint64_t Val) const { return (VAL == Val); } + INLINE bool operator!=(uint64_t Val) const { return (VAL != Val); } + INLINE bool operator!=(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL != RHS.VAL; } + INLINE bool operator!=(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() != RHS.getVal(); } + const ap_private operator++() { ++VAL; clearUnusedBits(); return *this; } + const ap_private operator--(int) { + ap_private orig(*this); + --VAL; clearUnusedBits(); + return orig; + } + const ap_private operator--() { --VAL; clearUnusedBits(); return *this;} + INLINE bool operator !() const { return !VAL;} + + const ap_private operator++(int) { + ap_private orig(*this); + VAL++; clearUnusedBits(); + return orig; + } + + const ap_private operator~() {return ap_private(~VAL);} + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + INLINE std::string toString(uint8_t radix, bool wantSigned) const ; + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + INLINE void clear() { + VAL=0; + } + INLINE ap_private& clear(uint32_t bitPosition) { VAL &= ~(1ULL<<(bitPosition)); clearUnusedBits(); return *this;} + + INLINE ap_private ashr(uint32_t shiftAmt) const { + enum {excess_bits = APINT_BITS_PER_WORD - BitWidth}; + if (_AP_S) + return ap_private((shiftAmt == BitWidth) ? 0 : ((int64_t)VAL) >> (shiftAmt)); + else + return ap_private((shiftAmt == BitWidth) ? 0 : (VAL) >> (shiftAmt)); + } + + INLINE ap_private lshr(uint32_t shiftAmt) const { + return ap_private((shiftAmt == BitWidth) ? ap_private(0) : ap_private((VAL&mask) >> (shiftAmt))); + } + + INLINE ap_private shl(uint32_t shiftAmt) const { + if (shiftAmt > BitWidth) { + if (!isNegative()) + return ap_private(0); + else return ap_private(-1); + } + if (shiftAmt == BitWidth) return ap_private(0); + else return ap_private((VAL) << (shiftAmt)); + //return ap_private((shiftAmt == BitWidth) ? ap_private(0ULL) : ap_private(VAL << shiftAmt)); + } + + INLINE int64_t getSExtValue() const { + return VAL; + } + + INLINE uint64_t getZExtValue() const { + return VAL & mask; + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this = ((uint64_t)(bool)ref); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = (uint64_t)(bool)val; + } + + INLINE void write(const ap_private<_AP_W, _AP_S>& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + ValType getVal() const { + return VAL; + } + operator ValType () const { + return getVal(); + } + INLINE int to_int() const { + // ap_private<64 /* _AP_W */, _AP_S> res(V); + return (int) getVal(); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE bool isMinValue() const { return VAL == 0;} + template INLINE ap_private& operator&=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL&RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator|=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL|RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator^=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL^RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator*=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL*RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL+RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL-RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + INLINE const ap_private& operator<<=(uint32_t shiftAmt) { VAL<<=shiftAmt; clearUnusedBits(); return *this; } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator&(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL & RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret & RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator^(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL ^ RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret ^ RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator|(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL | RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret | RHS; + } + } + + INLINE ap_private<_AP_W, _AP_S> And(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL & RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Or(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL | RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Xor(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL ^ RHS.VAL); + } +#if 1 + template + INLINE typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::mult_w <= 64) { + typename RType<_AP_W1, _AP_S1>::mult Result(VAL * RHS.VAL); + return Result; + } else { + typename RType<_AP_W1, _AP_S1>::mult Result = typename RType<_AP_W1, _AP_S1>::mult(*this); + Result *= RHS; + return Result; + } + } +#endif + INLINE ap_private<_AP_W, _AP_S> Mul(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL * RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Add(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL + RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Sub(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL - RHS.VAL); + } + +#if 1 + INLINE ap_private& operator&=(uint64_t RHS) { VAL &= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator|=(uint64_t RHS) { VAL |= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator^=(uint64_t RHS){ VAL ^= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator*=(uint64_t RHS){ VAL *= RHS; clearUnusedBits(); return *this; } + INLINE ap_private& operator+=(uint64_t RHS){ VAL += RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator-=(uint64_t RHS){ VAL -= RHS; clearUnusedBits(); return *this; } + INLINE ap_private operator&(uint64_t RHS) const { return ap_private(VAL & RHS); } + INLINE ap_private operator|(uint64_t RHS) const { return ap_private(VAL | RHS); } + INLINE ap_private operator^(uint64_t RHS) const { return ap_private(VAL ^ RHS); } + INLINE ap_private operator*(uint64_t RHS) const { return ap_private(VAL * RHS); } + INLINE ap_private operator/(uint64_t RHS) const { return ap_private(VAL / RHS); } + INLINE ap_private operator+(uint64_t RHS) const { return ap_private(VAL + RHS); } + INLINE ap_private operator-(uint64_t RHS) const { return ap_private(VAL - RHS); } +#endif + INLINE bool isMinSignedValue() const { + static const uint64_t min_mask = ~(~0ULL << (_AP_W-1)); + return BitWidth == 1 ? VAL == 1 : + (ap_private_ops::isNegative<_AP_W>(*this) && ((min_mask & VAL)==0)); + } + +#if 1 + + template INLINE + typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::plus_w <=64) + return typename RType<_AP_W1,_AP_S1>::plus(RType<_AP_W1,_AP_S1>::plus_s ? int64_t(VAL+RHS.VAL):uint64_t(VAL+RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::plus Result=RHS; + Result += VAL; + return Result; + } + + template INLINE + typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::minus_w <=64) + return typename RType<_AP_W1,_AP_S1>::minus(int64_t(VAL-RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::minus Result=*this; + Result -= RHS; + return Result; + } +#endif // #if 1 + + INLINE ap_private& flip() { + VAL = (~0ULL^VAL)&mask; + clearUnusedBits(); + return *this; + } + + uint32_t countPopulation() const { return CountPopulation_64(VAL);} + uint32_t countLeadingZeros() const { + int remainder = BitWidth % APINT_BITS_PER_WORD; + int excessBits = (APINT_BITS_PER_WORD - remainder) % APINT_BITS_PER_WORD; + //enum { remainder = BitWidth % APINT_BITS_PER_WORD, excessBits = APINT_BITS_PER_WORD - remainder}; + uint32_t Count = CountLeadingZeros_64(VAL); + if (Count) + Count-=excessBits; + return AESL_std::min(Count, (uint32_t)_AP_W); + } + + /// HiBits - This function returns the high "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getHiBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret(*this); + ret = (ret)>>(BitWidth - numBits); + return ret; + } + + /// LoBits - This function returns the low "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getLoBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret((VAL) << (BitWidth - numBits)); + ret = (ret)>>(BitWidth - numBits); + return ret; + //return ap_private(numBits, (VAL << (BitWidth - numBits))>> (BitWidth - numBits)); + } + + ap_private<_AP_W, _AP_S,1>& set(uint32_t bitPosition) { + VAL |= (1ULL << (bitPosition)); + clearUnusedBits(); + return *this; // clearUnusedBits(); + } + + void set() { + VAL = ~0ULL; + clearUnusedBits(); + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + INLINE void set(const ap_private & val) { + operator = (val); + } + + bool operator[](uint32_t bitPosition) const { + return (((1ULL << (bitPosition)) & VAL) != 0); + } + + INLINE void clearUnusedBits(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + VAL = _AP_S ? ((((int64_t)VAL)<<(excess_bits))>> (excess_bits)) : (excess_bits ? ((VAL)<<(excess_bits))>>(excess_bits) : VAL); + } + + INLINE void clearUnusedBitsToZero(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + static uint64_t mask = ~0ULL >> (excess_bits); + VAL &= mask; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> udiv(const ap_private<_AP_W, _AP_S1>& RHS) const { + return ap_private<_AP_W, _AP_S||_AP_S1>(VAL / RHS.VAL); + } + + INLINE ap_private udiv(uint64_t RHS) const { + return ap_private(VAL / RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> sdiv(const ap_private<_AP_W, _AP_S1> & RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS<0) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + template + INLINE ap_private urem(const ap_private<_AP_W, _AP_S2>& RHS) const { + assert(RHS.VAL != 0 && "Divide by 0"); + return ap_private(VAL%RHS.VAL); + } + + INLINE ap_private urem(uint64_t RHS) const { + assert(RHS != 0 && "Divide by 0"); + return ap_private(VAL%RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private srem(const ap_private<_AP_W, _AP_S2>& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + INLINE static void udivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS.VAl; + Remainder = LHS.VAL % RHS.VAL; + } + + INLINE static void udivrem(const ap_private &LHS, uint64_t RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS; + Remainder = LHS.VAL % RHS; + } + + INLINE static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + INLINE static void sdivrem(const ap_private &LHS, int64_t RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS<0) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS<0) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + template INLINE bool eq(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return (*this) == RHS; + } + + template INLINE bool ne(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template INLINE bool ult(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + uint64_t lhsZext = ((uint64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + uint64_t rhsZext = ((uint64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsZext < rhsZext; + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered signed. + /// @brief Signed less than comparison + template INLINE bool slt(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + int64_t lhsSext = ((int64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + int64_t rhsSext = ((int64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsSext < rhsSext; + } + + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template INLINE bool ule(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template INLINE bool sle(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template INLINE bool ugt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template INLINE bool sgt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template INLINE bool uge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template INLINE bool sge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS); + } + + INLINE ap_private abs() const { + if (isNegative()) + return -(*this); + return *this; + } + + ap_private<_AP_W, false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + INLINE static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + return _AP_W; + } + + INLINE uint32_t getActiveBits() const { + uint32_t bits=_AP_W - countLeadingZeros(); + return bits?bits:1; + } + + INLINE double roundToDouble(bool isSigned=false) const { + const static uint64_t mask = ~0ULL << (APINT_BITS_PER_WORD - _AP_W); + return double(VAL); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + //Binary Arithmetic + //----------------------------------------------------------- +#define OP_BIN_AP(Sym,Rty, Fun) \ + template \ + INLINE \ + typename RType<_AP_W2,_AP_S2>::Rty \ + operator Sym (const ap_private<_AP_W2,_AP_S2>& op) const { \ + typename RType<_AP_W2,_AP_S2>::Rty lhs(*this); \ + typename RType<_AP_W2,_AP_S2>::Rty rhs(op); \ + return lhs.Fun(rhs); \ + } \ + + ///Bitwise and, or, xor + //OP_BIN_AP(&,logic, And) + //OP_BIN_AP(|,logic, Or) + //OP_BIN_AP(^,logic, Xor) + +#undef OP_BIN_AP + template + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=*this; + ap_private rhs=op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod (_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + +#define OP_ASSIGN_AP_2(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP_2(/) + OP_ASSIGN_AP_2(%) +#undef OP_ASSIGN_AP_2 + + ///Bitwise assign: and, or, xor + //------------------------------------------------------------- + // OP_ASSIGN_AP(&) + // OP_ASSIGN_AP(^) + // OP_ASSIGN_AP(|) +#undef OP_ASSIGN_AP +#if 1 + + template + INLINE ap_private<_AP_W, _AP_S> + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator << (uint32_t sh) const { + return shl(sh); + } + +#endif + + template + INLINE ap_private<_AP_W, _AP_S> + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator >>(uint32_t sh) const { + ap_private<_AP_W, _AP_S> r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP_3_SINGLE(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op.getVal()); \ + return *this; \ + } + OP_ASSIGN_AP_3_SINGLE(>>) +#undef OP_ASSIGN_AP_3_SINGLE + + ///Comparisons + //----------------------------------------------------------------- + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this==op); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return op < *this; + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this>op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else if (_AP_W < 32 && _AP_W2 < 32) + return lhs.slt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op == *this; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return !(op==*this); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op < (*this); + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op >= *this; + } + + template + INLINE bool operator <(const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op > *this; + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2,_AP_N2>& op) const { + return op <= *this; + } + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S> (*this, (int)index); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return (VAL & mask) == mask; + } + + INLINE bool nand_reduce() const { + return (VAL & mask) != mask; + } + + INLINE bool or_reduce() const { + return (bool)VAL; + } + + INLINE bool nor_reduce() const { + return VAL==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; +template +std::string ap_private<_AP_W, _AP_S, 1>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f" + }; + std::string result; + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, 1> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, 1> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (unsigned)(tmp.VAL & mask); + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, 1> tmp(*this); + ap_private<6, false, 1> divisor(radix); + ap_private<_AP_W, _AP_S, 1> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, 1>(0ULL)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, 1> APdigit = tmp%divisor; + ap_private<_AP_W, false, 1> tmp2 = tmp/divisor; + uint32_t digit = (uint32_t)(APdigit.getZExtValue()); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + return result; + +} + +#endif /* #ifndef LLVM_SUPPORT_MATHEXTRAS_H */ \ No newline at end of file diff --git a/hls_2018/router_04/main.cpp b/hls_2018/router_04/main.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2a4e7f57e0847d5f3c8441e0357a13b54d92ead2 --- /dev/null +++ b/hls_2018/router_04/main.cpp @@ -0,0 +1,97 @@ +/** + * main.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#ifdef CALCTIME +#include +#include +#endif + +#include "router.hpp" + +#define PRINT_SOLUTION + + +int main(int argc, char *argv[]) { + using namespace std; + + // Test data // + // NL_Q00.txt + //char boardstr[BOARDSTR_SIZE] = "X10Y05Z3L0000107041L0004107002L0102102021L0900100003"; + // NL_Q06.txt + char boardstr[BOARDSTR_SIZE] = "X10Y18Z2L0900109002L0901105012L0902103052L0903103062L0904100102L0905106012L0906109022L0717109102L0808109112L0017209172L0401200072L0912208152L0009201092L0709209092L0901206052L0309204092L0701209072L0101201022L0011202152L0016202162"; + // NL_Q08.txt + //char boardstr[BOARDSTR_SIZE] = "X17Y20Z2L0000103022L1603115052L0916107032L0302108012L1104111042L1002100002L0919116162L1616113182L1001115012L0500201182L1603213152L0600210022"; + + // Read boardstr from command line + if (1 < argc) { + // From stdin + if(argv[1][0]!='X') + { + char* c_p=fgets(boardstr, BOARDSTR_SIZE, stdin); + int length=strlen(c_p); + boardstr[length-1]=0; + } + else + { + strcpy(boardstr, argv[1]); + } + } + + // Seed value + int seed = 12345; + if (2 < argc) { + seed = atoi(argv[2]); + } + +#ifdef PRINT_SOLUTION + int size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + int size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + int size_z = (boardstr[7] - '0'); +#endif + + // Solver + ap_int<32> status; + clock_t clock_start, clock_done; + clock_start = clock(); + bool result = pynqrouter(boardstr, seed, &status); + clock_done = clock(); + if (result) { + cout << endl << "Test Passed!" << endl; + } else { + cout << endl << "Test Failed!" << endl; + } + cout << "status = " << (int)status << endl; + cout << "elapsed = " << ((double)(clock_done - clock_start) / CLOCKS_PER_SEC) << endl << endl; + +#ifdef PRINT_SOLUTION + cout << "SOLUTION" << endl; + cout << "========" << endl; + cout << "SIZE " << size_x << "X" << size_y << "X" << size_z << endl; + for (int z = 0; z < size_z; z++) { + cout << "LAYER " << (z + 1) << endl; + for (int y = 0; y < size_y; y++) { + for (int x = 0; x < size_x; x++) { + if (x != 0) { + cout << ","; + } + int i = ((x * MAX_WIDTH + y) << BITWIDTH_Z) | z; + cout << setfill('0') << setw(3) << right << (unsigned int)(unsigned char)(boardstr[i]); + //cout << (unsigned int)(unsigned char)(boardstr[i]); + } + cout << endl; + } + } +#endif + + return 0; +} + diff --git a/hls_2018/router_04/router.cpp b/hls_2018/router_04/router.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2fde0ec022aa49ef5d00a89c194fefa9fb8efab9 --- /dev/null +++ b/hls_2018/router_04/router.cpp @@ -0,0 +1,513 @@ +/** + * router.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#include "./router.hpp" + +// Set weight +ap_uint<8> new_weight(ap_uint<16> x) { +#pragma HLS INLINE + // K. Terada: y = 1~32 (8bit) + ap_uint<8> y; + y = ((x & 255) >> 3) + 1; + return y; +} + + +// Global values +static ap_uint<7> size_x; // X +static ap_uint<7> size_y; // Y +static ap_uint<4> size_z; // Z + +static ap_uint line_num = 0; // #Lines + +#ifdef DEBUG_PRINT +int max_queue_length; // Max length of priority queue +int max_search_count; // Max count of queue pop +int max_buffer_length; // Max length of line buffer +#endif + + +bool pynqrouter(char boardstr[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status) { +#pragma HLS INTERFACE s_axilite port=boardstr bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=seed bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=status bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=return bundle=AXI4LS + + // status(0:Solved, 1:Not solved) + *status = -1; + + // For all lines + ap_uint paths[MAX_BUFFER]; // Line buffer + + // For each line + // Note: Should not partition completely + bool adjacents[MAX_LINES]; // Line has adjacent terminals? + ap_uint starts[MAX_LINES]; // Start list + ap_uint goals[MAX_LINES]; // Goal list + ap_uint s_idx[MAX_LINES]; // Start point on line buffer + + ap_uint<8> weights[MAX_CELLS]; // Weight of each cell + // Note: Should not partition weight array + // since each element will be accessed in "random" order + + + // ================================ + // (Step.0) Initialization (BEGIN) + // ================================ + + // Note: Loop counter -> need an extra bit (for condition determination) + + INIT_WEIGHTS: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + weights[i] = 1; + } + + /// Parse /// + size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + size_z = (boardstr[7] - '0'); + + INIT_BOARDS: + for (ap_uint idx = 8; idx < (ap_uint)(BOARDSTR_SIZE); idx+=11) { + + // NULL-terminated + if (boardstr[idx] == 0) break; + + // Start & Goal of each line + ap_uint<7> s_x = (boardstr[idx+1] - '0') * 10 + (boardstr[idx+2] - '0'); + ap_uint<7> s_y = (boardstr[idx+3] - '0') * 10 + (boardstr[idx+4] - '0'); + ap_uint<3> s_z = (boardstr[idx+5] - '0') - 1; + ap_uint<7> g_x = (boardstr[idx+6] - '0') * 10 + (boardstr[idx+7] - '0'); + ap_uint<7> g_y = (boardstr[idx+8] - '0') * 10 + (boardstr[idx+9] - '0'); + ap_uint<3> g_z = (boardstr[idx+10] - '0') - 1; + + ap_uint start_id = (((ap_uint)s_x * MAX_WIDTH + (ap_uint)s_y) << BITWIDTH_Z) | (ap_uint)s_z; + ap_uint goal_id = (((ap_uint)g_x * MAX_WIDTH + (ap_uint)g_y) << BITWIDTH_Z) | (ap_uint)g_z; + starts[line_num] = start_id; + goals[line_num] = goal_id; + weights[start_id] = MAX_WEIGHT; + weights[goal_id] = MAX_WEIGHT; + + // Line has adjacent terminals? + adjacents[line_num] = false; + ap_int<8> dx = (ap_int<8>)g_x - (ap_int<8>)s_x; // Min: -71, Max: 71 (Signed 8bit) + ap_int<8> dy = (ap_int<8>)g_y - (ap_int<8>)s_y; // Min: -71, Max: 71 (Signed 8bit) + ap_int<4> dz = (ap_int<4>)g_z - (ap_int<4>)s_z; // Min: -7, Max: 7 (Signed 4bit) + if ((dx == 0 && dy == 0 && (dz == 1 || dz == -1)) || (dx == 0 && (dy == 1 || dy == -1) && dz == 0) || ((dx == 1 || dx == -1) && dy == 0 && dz == 0)) { + adjacents[line_num] = true; + } + + line_num++; + } + + // ================================ + // (Step.0) Initialization (END) + // ================================ + +#ifdef DEBUG_PRINT + max_queue_length = 0; + max_search_count = 0; + max_buffer_length = 0; +#endif + + ap_uint pointer = 0; // Pointer for line buffer + + // ================================ + // (Step.1) Initial Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Initial Routing ..." << endl; +#endif + + FIRST_ROUTING: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + + s_idx[i] = pointer; + + if (adjacents[i] == true) continue; // Skip routing + +#ifdef DEBUG_PRINT + //cout << "LINE #" << (int)(i + 1) << endl; +#endif + // Routing + pointer = search(s_idx[i], paths, starts[i], goals[i], weights); + } + + // ================================ + // (Step.1) Initial Routing (END) + // ================================ + + + // Memories for Overlap Check + ap_uint<1> overlap_checks[MAX_CELLS]; + bool has_overlap = false; + + // ================================ + // (Step.2) Rip-up Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Rip-up Routing ..." << endl; +#endif + + ROUTING: + for (ap_uint<16> round = 0; round < 32768 /* = (2048 * 16) */; round++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=32768 + + // Target line + ap_uint target = round % line_num; + ap_uint next_target = target + 1; + if (next_target == line_num) next_target = 0; + +#ifdef DEBUG_PRINT + //cout << "(round " << round << ") LINE #" << (int)(target + 1); + //cout << " -> " << pointer << endl; +#endif +#ifdef DEBUG_PRINT + int buffer_length = pointer - s_idx[target]; + if (max_buffer_length < buffer_length) { max_buffer_length = buffer_length; } +#endif + + // Skip routing + if (adjacents[target] == true) { + s_idx[target] = pointer; continue; + } + + + // (Step.2-1) Reset weights of target line + WEIGHT_RESET: + for (ap_uint j = s_idx[target]; j != s_idx[next_target]; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + weights[paths[j]] = 1; + } + + // (Step.2-2) Set weights of non-target lines and terminals + ap_uint<8> current_round_weight = new_weight(round); + WEIGHT_PATH: + for (ap_uint j = s_idx[next_target]; j != pointer; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=8192 + weights[paths[j]] = current_round_weight; + } + WEIGHT_TERMINAL: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + weights[starts[i]] = MAX_WEIGHT; + weights[goals[i]] = MAX_WEIGHT; + } + // Reset weight of start terminal of target line (bug avoiding) + // Restore original settings in (*) + weights[starts[target]] = 1; + + // (Step.2-3) Routing + s_idx[target] = pointer; + pointer = search(s_idx[target], paths, starts[target], goals[target], weights); + + // (*) + weights[starts[target]] = MAX_WEIGHT; + +#ifdef DEBUG_PRINT + bool ng = false; + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { + if (weights[starts[i]] != 255 || weights[goals[i]] != 255) { + cout << i << " "; ng = true; + } + } + if(ng) { cout << endl; } +#endif + + // (Step.2-4) Overlap check + has_overlap = false; + OVERLAP_RESET: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + overlap_checks[i] = 0; + } + OVERLAP_CHECK_LINE: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + overlap_checks[starts[i]] = 1; + overlap_checks[goals[i]] = 1; + } + OVERLAP_CHECK_PATH: + for (ap_uint j = s_idx[next_target]; j != pointer; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=8192 + ap_uint cell_id = paths[j]; + if (overlap_checks[cell_id]) { + has_overlap = true; break; + } + overlap_checks[cell_id] = 1; + } +#ifdef DEBUG_PRINT + if(!has_overlap){ cout << "ROUND: " << round << endl; } +#endif + if (!has_overlap) break; // Finish routing? + } + +#ifdef DEBUG_PRINT + cout << "MAX PQ LENGTH: " << max_queue_length << endl; + cout << "MAX SEARCH COUNT: " << max_search_count << endl; + cout << "MAX BUFFER: " << max_buffer_length << endl; +#endif + + // Not solved + if (has_overlap) { + *status = 1; return false; + } + + // ================================ + // (Step.2) Rip-up Routing (END) + // ================================ + + + // ================================ + // (Step.3) Output (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Output ..." << endl; +#endif + + // Init: Blank = 0 + OUTPUT_INIT: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + boardstr[i] = 0; + } + // Line + OUTPUT_LINE: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + boardstr[starts[i]] = (i + 1); + boardstr[goals[i]] = (i + 1); + + ap_uint p1; // p1: s_idx of target + ap_uint p2; // p2: s_idx of next target + p1 = s_idx[i]; + if (i == (ap_uint)(line_num-1)) { + p2 = s_idx[0]; + } + else { + p2 = s_idx[i+1]; + } + if ((ap_uint)(p2 - p1) > 8192){ + p2 = pointer; + } + OUTPUT_LINE_PATH: + for (ap_uint j = p1; j != p2; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + boardstr[paths[j]] = (i + 1); + } + } + + // ================================ + // (Step.3) Output (END) + // ================================ + + *status = 0; return true; +} + + +// ================================ // +// For Routing +// ================================ // + +// Max: 71, Min: 0 (7bit) +ap_uint<7> abs_uint7(ap_uint<7> a, ap_uint<7> b) { +#pragma HLS INLINE + if (a < b) { return b - a; } + else { return a - b; } +} +// Max: 7, Min: 0 (3bit) +ap_uint<3> abs_uint3(ap_uint<3> a, ap_uint<3> b) { +#pragma HLS INLINE + if (a < b) { return b - a; } + else { return a - b; } +} + +// Reference codes: +// http://lethe2211.hatenablog.com/entry/2014/12/30/011030 +// http://www.redblobgames.com/pathfinding/a-star/implementation.html +// Need to modify "array partition factor" +ap_uint search(ap_uint idx, ap_uint paths[MAX_BUFFER], ap_uint start, ap_uint goal, ap_uint<8> w[MAX_CELLS]) { + + ap_uint dist[MAX_CELLS]; + ap_uint prev[MAX_CELLS]; + + SEARCH_INIT_DIST: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + dist[i] = 65535; // = (2^16 - 1) + } + + // Priority queue (Heap) + ap_uint pq_len = 0; + bool is_empty = true; + ap_uint<32> pq_nodes[MAX_PQ]; + +#ifdef DEBUG_PRINT + int queue_length = 0; + int search_count = 0; +#endif + + // Point of goal terminal + ap_uint<13> goal_xy = (ap_uint<13>)(goal >> BITWIDTH_Z); + ap_uint<7> goal_x = (ap_uint<7>)(goal_xy / MAX_WIDTH); + ap_uint<7> goal_y = (ap_uint<7>)(goal_xy - goal_x * MAX_WIDTH); + ap_uint<3> goal_z = (ap_uint<3>)(goal & BITMASK_Z); + + dist[start] = 0; + pq_push(pq_nodes, 0, start, &pq_len, &is_empty); // push start terminal + + SEARCH_PQ: + while (!is_empty) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=1000 +#pragma HLS LOOP_FLATTEN off + + ap_uint<16> prev_cost; + ap_uint<16> src; // target cell + pq_pop(pq_nodes, &prev_cost, &src, &pq_len, &is_empty); +#ifdef DEBUG_PRINT + search_count++; +#endif + + + // End routing + if (src == goal) break; + + + // Target cell + ap_uint<16> dist_src = dist[src]; + ap_uint<8> cost = w[src]; + // Point of target cell + ap_uint<13> src_xy = (ap_uint<13>)(src >> BITWIDTH_Z); + ap_uint<7> src_x = (ap_uint<7>)(src_xy / MAX_WIDTH); + ap_uint<7> src_y = (ap_uint<7>)(src_xy - src_x * MAX_WIDTH); + ap_uint<3> src_z = (ap_uint<3>)(src & BITMASK_Z); + + // Search adjacent cells + SEARCH_ADJACENTS: + for (ap_uint<3> a = 0; a < 6; a++) { + ap_int<8> dest_x = (ap_int<8>)src_x; // Min: -1, Max: 72 (Signed 8bit) + ap_int<8> dest_y = (ap_int<8>)src_y; // Min: -1, Max: 72 (Signed 8bit) + ap_int<5> dest_z = (ap_int<5>)src_z; // Min: -1, Max: 8 (Signed 5bit) + if (a == 0) { dest_x -= 1; } + if (a == 1) { dest_x += 1; } + if (a == 2) { dest_y -= 1; } + if (a == 3) { dest_y += 1; } + if (a == 4) { dest_z -= 1; } + if (a == 5) { dest_z += 1; } + + // Inside the board ? // + if (0 <= dest_x && dest_x < (ap_int<8>)size_x && 0 <= dest_y && dest_y < (ap_int<8>)size_y && 0 <= dest_z && dest_z < (ap_int<5>)size_z) { + // Adjacent cell + ap_uint<16> dest = (((ap_uint<16>)dest_x * MAX_WIDTH + (ap_uint<16>)dest_y) << BITWIDTH_Z) | (ap_uint<16>)dest_z; + ap_uint<16> dist_new = dist_src + cost; + + if (dist[dest] > dist_new) { + dist[dest] = dist_new; // Update dist + prev[dest] = src; // Recode previous cell + dist_new += abs_uint7(dest_x, goal_x) + abs_uint7(dest_y, goal_y) + abs_uint3(dest_z, goal_z); // A* heuristic + pq_push(pq_nodes, dist_new, dest, &pq_len, &is_empty); // push adjacent cell + } + } + } +#ifdef DEBUG_PRINT + if (queue_length < pq_len) { queue_length = pq_len; } +#endif + } + + // Output target path + // Note: Do not include start & goal terminals + ap_uint<16> t = prev[goal]; + + // Backtracking + ap_uint p = idx; // buffer-idx + SEARCH_BACKTRACK: + while (t != start) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + paths[p] = t; + p++; + t = prev[t]; + } + +#ifdef DEBUG_PRINT + if (max_queue_length < queue_length) { max_queue_length = queue_length; } + if (max_search_count < search_count) { max_search_count = search_count; } +#endif + + return p; +} + +// Queue push (Enqueue) +// Need to modify "trip count" (1) +void pq_push(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> priority, ap_uint<16> data, ap_uint *pq_len, bool *is_empty) { +#pragma HLS INLINE + + (*pq_len)++; + if ((*pq_len) == 0) { (*pq_len)--; } // Queue is full -> Last element is automatically removed + + // Binary search for circular list + ap_uint i = (*pq_len); + ap_uint p = (*pq_len) >> 1; // parent node + PQ_PUSH_LOOP: + while (i > 1 && (ap_uint<16>)(pq_nodes[p] & PQ_PRIORITY_MASK) >= priority) { +#pragma HLS LOOP_TRIPCOUNT min=0 max=16 +/** Set!: min=0 max=PQ_BIT **/ + pq_nodes[i] = pq_nodes[p]; + i = p; + p = p >> 1; // parent node + } + pq_nodes[i] = ((ap_uint<32>)data << PQ_PRIORITY_WIDTH) | (ap_uint<32>)priority; + *is_empty = false; +} + +// Queue pop (Dequeue) +// Need to modify "trip count" (1) +void pq_pop(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint *pq_len, bool *is_empty) { +#pragma HLS INLINE + + *ret_priority = (ap_uint<16>)(pq_nodes[1] & PQ_PRIORITY_MASK); + *ret_data = (ap_uint<16>)(pq_nodes[1] >> PQ_PRIORITY_WIDTH); + + ap_uint i = 1; // root node + ap_uint last_priority = (ap_uint<16>)(pq_nodes[*pq_len] & PQ_PRIORITY_MASK); // Priority of last element + + PQ_POP_LOOP: + while (!(i >> (PQ_BIT-1))) { // (2018.08.24) Loop condition fixed +#pragma HLS LOOP_TRIPCOUNT min=1 max=16 +/** Set!: min=0 max=PQ_BIT **/ + ap_uint c1 = i << 1; // child node(left) + ap_uint c2 = c1 + 1; // child node(right) + if (c1 < *pq_len && (ap_uint<16>)(pq_nodes[c1] & PQ_PRIORITY_MASK) <= last_priority) { + if (c2 < *pq_len && (ap_uint<16>)(pq_nodes[c2] & PQ_PRIORITY_MASK) <= (ap_uint<16>)(pq_nodes[c1] & PQ_PRIORITY_MASK)) { + pq_nodes[i] = pq_nodes[c2]; + i = c2; + } + else { + pq_nodes[i] = pq_nodes[c1]; + i = c1; + } + } + else { + if (c2 < *pq_len && (ap_uint<16>)(pq_nodes[c2] & PQ_PRIORITY_MASK) <= last_priority) { + pq_nodes[i] = pq_nodes[c2]; + i = c2; + } + else { + break; + } + } + } + pq_nodes[i] = pq_nodes[*pq_len]; + (*pq_len)--; + if ((*pq_len) == 0) { *is_empty = true; } +} + diff --git a/hls_2018/router_04/router.hpp b/hls_2018/router_04/router.hpp new file mode 100755 index 0000000000000000000000000000000000000000..cb3ba270db83101a6172eb15aec4187d25a8d72a --- /dev/null +++ b/hls_2018/router_04/router.hpp @@ -0,0 +1,56 @@ +/** + * router.hpp + * + * for Vivado HLS + */ + +#ifndef __ROUTER_HPP__ +#define __ROUTER_HPP__ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +//#define DEBUG_PRINT // for debug + +#ifdef DEBUG_PRINT +using namespace std; +#endif + +// Parameters +#define MAX_WIDTH 72 // Max of X, Y +#define BITWIDTH_XY 13 +#define BITMASK_XY 65528 // 1111 1111 1111 1000 +#define MAX_LAYER 8 // Max of Z +#define BITWIDTH_Z 3 +#define BITMASK_Z 7 // 0000 0000 0000 0111 + +#define MAX_CELLS 41472 // Max #cells (16bit) +#define MAX_LINES 1024 // Max #lines (10bit) +#define MAX_PQ 65536 // Queue size (16bit) +#define MAX_BUFFER 16384 // Line buffer size (14bit) +#define CELL_BIT 16 +#define LINE_BIT 10 +#define PQ_BIT 16 +#define BUFF_BIT 14 + +#define PQ_PRIORITY_WIDTH 16 +#define PQ_PRIORITY_MASK 65535 // 0000 0000 0000 0000 1111 1111 1111 1111 +#define PQ_DATA_WIDTH 16 +#define PQ_DATA_MASK 4294901760 // 1111 1111 1111 1111 0000 0000 0000 0000 + +#define MAX_WEIGHT 255 // Max weight +#define BOARDSTR_SIZE 41472 // Size of I/O + +ap_uint<8> new_weight(ap_uint<16> x); +bool pynqrouter(char boardstr[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status); + +ap_uint<7> abs_uint7(ap_uint<7> a, ap_uint<7> b); +ap_uint<3> abs_uint3(ap_uint<3> a, ap_uint<3> b); +ap_uint search(ap_uint idx, ap_uint paths[MAX_BUFFER], ap_uint start, ap_uint goal, ap_uint<8> w[MAX_WEIGHT]); +void pq_push(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> priority, ap_uint<16> data, ap_uint *pq_len, bool *is_empty); +void pq_pop(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint *pq_len, bool *is_empty); + +#endif /* __ROUTER_HPP__ */ diff --git a/hls_2018/router_04_boardstr/Makefile b/hls_2018/router_04_boardstr/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..8f79e7a62ede483ae7dcda810f306a02f915dfbb --- /dev/null +++ b/hls_2018/router_04_boardstr/Makefile @@ -0,0 +1,20 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -o $@ $(OBJS) + +run: + python3 ../NLGenerator.py -x 20 -y 20 -z 6 -l 100;\ + python3 ./gen_boardstr.py Q-20x20x5_100_10.txt |\ + ./$(TARGET) - + + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_04_boardstr/Makefile.cygwin b/hls_2018/router_04_boardstr/Makefile.cygwin new file mode 100755 index 0000000000000000000000000000000000000000..866fdcdf2ea6a5fb67d1461ce4a19e353d0c9216 --- /dev/null +++ b/hls_2018/router_04_boardstr/Makefile.cygwin @@ -0,0 +1,14 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -Wl,--stack,33554432 -o $@ $(OBJS) + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_04_boardstr/ap_int.h b/hls_2018/router_04_boardstr/ap_int.h new file mode 100755 index 0000000000000000000000000000000000000000..b8d9fdc96ac3f7eb9c86cc55d0eac0a57bf670b5 --- /dev/null +++ b/hls_2018/router_04_boardstr/ap_int.h @@ -0,0 +1,521 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_AP_SIM_H__ +#define __AESL_AP_SIM_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#else + +#include "etc/ap_int_sim.h" +#include "etc/ap_fixed_sim.h" + +//Forward declaration +template class ap_fixed; +template class ap_ufixed; +template class ap_int; +template class ap_uint; + +//AP_INT +//-------------------------------------------------------- +template +class ap_int : public ap_private<_AP_W, true> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_private<_AP_W, true> Base; + + //Constructor + INLINE ap_int(): Base() {} + template + INLINE ap_int(const volatile ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_int(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_int(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_int(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE void operator = (const volatile ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE ap_int<_AP_W>& operator = (const volatile ap_int<_AP_W>& op2) { + Base::operator = (const_cast& >(op2)); + return *this; + } + + INLINE ap_int<_AP_W>& operator = (const ap_int<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, true>&)op2); + return *this; + } +}; + +//AP_UINT +//--------------------------------------------------------------- +template +class ap_uint: public ap_private<_AP_W, false> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_private<_AP_W, false> Base; + //Constructor + INLINE ap_uint(): Base() {} + INLINE ap_uint(const ap_uint<_AP_W>& op) :Base(dynamic_cast&>(op)) {} + INLINE ap_uint(const volatile ap_uint<_AP_W>& op):Base(dynamic_cast&>(op)){} + template + INLINE ap_uint(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_uint<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)){} + + template + INLINE ap_uint(const ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_uint(const volatile ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op) {} + + template + INLINE ap_uint(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_uint(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_uint(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_uint(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE void operator = (const volatile ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE ap_uint<_AP_W>& operator = (const volatile ap_uint<_AP_W>& op2) { + Base::operator = (op2); + return *this; + } + + INLINE ap_uint<_AP_W>& operator = (const ap_uint<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, false>&)(op2)); + return *this; + } +}; + +#define ap_bigint ap_int +#define ap_biguint ap_uint + +//AP_FIXED +//--------------------------------------------------------------------- +template +class ap_fixed: public ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> Base; + //Constructor + INLINE ap_fixed():Base() {} + + template + INLINE ap_fixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const ap_uint<_AP_W2>& op):Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_fixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const volatile ap_uint<_AP_W2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_fixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_fixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_fixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_fixed& operator = (const ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_fixed& operator = (const volatile ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } +}; + +//AP_ UFIXED +//--- ---------------------------------------------------------------- +template +class ap_ufixed : public ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> Base; + + //Constructor + INLINE ap_ufixed():Base() {} + + template + INLINE ap_ufixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_int<_AP_W2>& op): + Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_ufixed(const ap_uint<_AP_W2>& op): + Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_ufixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_uint<_AP_W2>& op): + Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_ufixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_ufixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_ufixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_ufixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_ufixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_ufixed& operator = (const ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_ufixed& operator = (const volatile ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::V = const_cast(op); + return *this; + } +}; + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_int<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_uint<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_fixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_ufixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif /* #if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) */ +#endif /* #ifndef __cplusplus */ +#endif /* #ifndef __AESL_AP_SIM_H__ */ \ No newline at end of file diff --git a/hls_2018/router_04_boardstr/bitstream/router_design.bit b/hls_2018/router_04_boardstr/bitstream/router_design.bit new file mode 100755 index 0000000000000000000000000000000000000000..ff18863db2877ef2c92e741df2f47c44f41c3498 Binary files /dev/null and b/hls_2018/router_04_boardstr/bitstream/router_design.bit differ diff --git a/hls_2018/router_04_boardstr/bitstream/router_design.tcl b/hls_2018/router_04_boardstr/bitstream/router_design.tcl new file mode 100755 index 0000000000000000000000000000000000000000..48425529f62524b8fe2400c7af4fa74fb981b349 --- /dev/null +++ b/hls_2018/router_04_boardstr/bitstream/router_design.tcl @@ -0,0 +1,844 @@ + +################################################################ +# This is a generated script based on design: router_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source router_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xczu3eg-sbva484-1-e + set_property BOARD_PART em.avnet.com:ultra96:part0:1.0 [current_project] +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name router_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:hls:pynqrouter:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:zynq_ultra_ps_e:3.2\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + + # Create ports + + # Create instance: ps8_0_axi_periph, and set properties + set ps8_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps8_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + CONFIG.NUM_SI {2} \ + ] $ps8_0_axi_periph + + # Create instance: pynqrouter_0, and set properties + set pynqrouter_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:pynqrouter:1.0 pynqrouter_0 ] + + # Create instance: rst_ps8_0_100M, and set properties + set rst_ps8_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_100M ] + + # Create instance: zynq_ultra_ps_e_0, and set properties + set zynq_ultra_ps_e_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.2 zynq_ultra_ps_e_0 ] + set_property -dict [ list \ + CONFIG.PSU_BANK_0_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_1_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_2_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_3_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_DDR_RAM_HIGHADDR {0x7FFFFFFF} \ + CONFIG.PSU_DDR_RAM_HIGHADDR_OFFSET {0x00000002} \ + CONFIG.PSU_DDR_RAM_LOWADDR_OFFSET {0x80000000} \ + CONFIG.PSU_MIO_0_DIRECTION {out} \ + CONFIG.PSU_MIO_0_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_10_DIRECTION {inout} \ + CONFIG.PSU_MIO_11_DIRECTION {inout} \ + CONFIG.PSU_MIO_12_DIRECTION {inout} \ + CONFIG.PSU_MIO_13_DIRECTION {inout} \ + CONFIG.PSU_MIO_13_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_14_DIRECTION {inout} \ + CONFIG.PSU_MIO_14_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_15_DIRECTION {inout} \ + CONFIG.PSU_MIO_15_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_16_DIRECTION {inout} \ + CONFIG.PSU_MIO_16_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_17_DIRECTION {inout} \ + CONFIG.PSU_MIO_18_DIRECTION {inout} \ + CONFIG.PSU_MIO_19_DIRECTION {inout} \ + CONFIG.PSU_MIO_1_DIRECTION {in} \ + CONFIG.PSU_MIO_1_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_1_SLEW {slow} \ + CONFIG.PSU_MIO_20_DIRECTION {inout} \ + CONFIG.PSU_MIO_21_DIRECTION {inout} \ + CONFIG.PSU_MIO_21_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_22_DIRECTION {out} \ + CONFIG.PSU_MIO_22_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_22_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_23_DIRECTION {inout} \ + CONFIG.PSU_MIO_24_DIRECTION {in} \ + CONFIG.PSU_MIO_24_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_24_SLEW {slow} \ + CONFIG.PSU_MIO_25_DIRECTION {inout} \ + CONFIG.PSU_MIO_26_DIRECTION {in} \ + CONFIG.PSU_MIO_26_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_26_SLEW {slow} \ + CONFIG.PSU_MIO_27_DIRECTION {out} \ + CONFIG.PSU_MIO_27_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_28_DIRECTION {in} \ + CONFIG.PSU_MIO_28_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_28_SLEW {slow} \ + CONFIG.PSU_MIO_29_DIRECTION {out} \ + CONFIG.PSU_MIO_29_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_2_DIRECTION {in} \ + CONFIG.PSU_MIO_2_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_2_SLEW {slow} \ + CONFIG.PSU_MIO_30_DIRECTION {in} \ + CONFIG.PSU_MIO_30_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_30_SLEW {slow} \ + CONFIG.PSU_MIO_31_DIRECTION {inout} \ + CONFIG.PSU_MIO_32_DIRECTION {out} \ + CONFIG.PSU_MIO_32_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_33_DIRECTION {out} \ + CONFIG.PSU_MIO_33_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_34_DIRECTION {out} \ + CONFIG.PSU_MIO_34_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_35_DIRECTION {inout} \ + CONFIG.PSU_MIO_36_DIRECTION {inout} \ + CONFIG.PSU_MIO_37_DIRECTION {inout} \ + CONFIG.PSU_MIO_38_DIRECTION {inout} \ + CONFIG.PSU_MIO_39_DIRECTION {inout} \ + CONFIG.PSU_MIO_39_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_39_SLEW {slow} \ + CONFIG.PSU_MIO_3_DIRECTION {out} \ + CONFIG.PSU_MIO_3_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_40_DIRECTION {inout} \ + CONFIG.PSU_MIO_41_DIRECTION {inout} \ + CONFIG.PSU_MIO_42_DIRECTION {inout} \ + CONFIG.PSU_MIO_43_DIRECTION {inout} \ + CONFIG.PSU_MIO_44_DIRECTION {inout} \ + CONFIG.PSU_MIO_45_DIRECTION {inout} \ + CONFIG.PSU_MIO_46_DIRECTION {inout} \ + CONFIG.PSU_MIO_47_DIRECTION {inout} \ + CONFIG.PSU_MIO_48_DIRECTION {inout} \ + CONFIG.PSU_MIO_49_DIRECTION {inout} \ + CONFIG.PSU_MIO_4_DIRECTION {inout} \ + CONFIG.PSU_MIO_50_DIRECTION {inout} \ + CONFIG.PSU_MIO_51_DIRECTION {out} \ + CONFIG.PSU_MIO_51_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_52_DIRECTION {in} \ + CONFIG.PSU_MIO_52_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_52_SLEW {slow} \ + CONFIG.PSU_MIO_53_DIRECTION {in} \ + CONFIG.PSU_MIO_53_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_53_SLEW {slow} \ + CONFIG.PSU_MIO_54_DIRECTION {inout} \ + CONFIG.PSU_MIO_55_DIRECTION {in} \ + CONFIG.PSU_MIO_55_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_55_SLEW {slow} \ + CONFIG.PSU_MIO_56_DIRECTION {inout} \ + CONFIG.PSU_MIO_57_DIRECTION {inout} \ + CONFIG.PSU_MIO_58_DIRECTION {out} \ + CONFIG.PSU_MIO_58_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_59_DIRECTION {inout} \ + CONFIG.PSU_MIO_5_DIRECTION {inout} \ + CONFIG.PSU_MIO_60_DIRECTION {inout} \ + CONFIG.PSU_MIO_61_DIRECTION {inout} \ + CONFIG.PSU_MIO_62_DIRECTION {inout} \ + CONFIG.PSU_MIO_63_DIRECTION {inout} \ + CONFIG.PSU_MIO_64_DIRECTION {in} \ + CONFIG.PSU_MIO_64_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_64_SLEW {slow} \ + CONFIG.PSU_MIO_65_DIRECTION {in} \ + CONFIG.PSU_MIO_65_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_65_SLEW {slow} \ + CONFIG.PSU_MIO_66_DIRECTION {inout} \ + CONFIG.PSU_MIO_67_DIRECTION {in} \ + CONFIG.PSU_MIO_67_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_67_SLEW {slow} \ + CONFIG.PSU_MIO_68_DIRECTION {inout} \ + CONFIG.PSU_MIO_69_DIRECTION {inout} \ + CONFIG.PSU_MIO_6_DIRECTION {inout} \ + CONFIG.PSU_MIO_70_DIRECTION {out} \ + CONFIG.PSU_MIO_70_INPUT_TYPE {schmitt} \ + CONFIG.PSU_MIO_71_DIRECTION {inout} \ + CONFIG.PSU_MIO_72_DIRECTION {inout} \ + CONFIG.PSU_MIO_73_DIRECTION {inout} \ + CONFIG.PSU_MIO_74_DIRECTION {inout} \ + CONFIG.PSU_MIO_75_DIRECTION {inout} \ + CONFIG.PSU_MIO_76_DIRECTION {inout} \ + CONFIG.PSU_MIO_77_DIRECTION {inout} \ + CONFIG.PSU_MIO_7_DIRECTION {inout} \ + CONFIG.PSU_MIO_8_DIRECTION {inout} \ + CONFIG.PSU_MIO_9_DIRECTION {inout} \ + CONFIG.PSU_MIO_TREE_PERIPHERALS {UART 1#UART 1#UART 0#UART 0#I2C 1#I2C 1#SPI 1#GPIO0 MIO#GPIO0 MIO#SPI 1#SPI 1#SPI 1#GPIO0 MIO#SD 0#SD 0#SD 0#SD 0#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#SD 0#SD 0#GPIO0 MIO#SD 0#GPIO0 MIO#PMU GPI 0#DPAUX#DPAUX#DPAUX#DPAUX#GPIO1 MIO#PMU GPO 0#PMU GPO 1#PMU GPO 2#GPIO1 MIO#GPIO1 MIO#GPIO1 MIO#SPI 0#GPIO1 MIO#GPIO1 MIO#SPI 0#SPI 0#SPI 0#GPIO1 MIO#GPIO1 MIO#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#GPIO2 MIO#GPIO2 MIO} \ + CONFIG.PSU_MIO_TREE_SIGNALS {txd#rxd#rxd#txd#scl_out#sda_out#sclk_out#gpio0[7]#gpio0[8]#n_ss_out[0]#miso#mosi#gpio0[12]#sdio0_data_out[0]#sdio0_data_out[1]#sdio0_data_out[2]#sdio0_data_out[3]#gpio0[17]#gpio0[18]#gpio0[19]#gpio0[20]#sdio0_cmd_out#sdio0_clk_out#gpio0[23]#sdio0_cd_n#gpio0[25]#gpi[0]#dp_aux_data_out#dp_hot_plug_detect#dp_aux_data_oe#dp_aux_data_in#gpio1[31]#gpo[0]#gpo[1]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#sclk_out#gpio1[39]#gpio1[40]#n_ss_out[0]#miso#mosi#gpio1[44]#gpio1[45]#sdio1_data_out[0]#sdio1_data_out[1]#sdio1_data_out[2]#sdio1_data_out[3]#sdio1_cmd_out#sdio1_clk_out#ulpi_clk_in#ulpi_dir#ulpi_tx_data[2]#ulpi_nxt#ulpi_tx_data[0]#ulpi_tx_data[1]#ulpi_stp#ulpi_tx_data[3]#ulpi_tx_data[4]#ulpi_tx_data[5]#ulpi_tx_data[6]#ulpi_tx_data[7]#ulpi_clk_in#ulpi_dir#ulpi_tx_data[2]#ulpi_nxt#ulpi_tx_data[0]#ulpi_tx_data[1]#ulpi_stp#ulpi_tx_data[3]#ulpi_tx_data[4]#ulpi_tx_data[5]#ulpi_tx_data[6]#ulpi_tx_data[7]#gpio2[76]#gpio2[77]} \ + CONFIG.PSU_SD0_INTERNAL_BUS_WIDTH {4} \ + CONFIG.PSU_SD1_INTERNAL_BUS_WIDTH {4} \ + CONFIG.PSU__ACT_DDR_FREQ_MHZ {525.000000} \ + CONFIG.PSU__CAN1__GRP_CLK__ENABLE {0} \ + CONFIG.PSU__CAN1__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__ACT_FREQMHZ {1200.000024} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__DIVISOR0 {1} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__FREQMHZ {1200} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__FBDIV {72} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__APLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRF_APB__APLL_TO_LPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__ACT_FREQMHZ {250.000005} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__ACT_FREQMHZ {250.000005} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__ACT_FREQMHZ {262.500005} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__FREQMHZ {533} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__ACT_FREQMHZ {600.000012} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__FBDIV {63} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__DPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRF_APB__DPLL_TO_LPD_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__ACT_FREQMHZ {25.000000} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__DIVISOR0 {16} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_AUDIO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__ACT_FREQMHZ {26.666667} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__ACT_FREQMHZ {300.000006} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__SRCSEL {VPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__ACT_FREQMHZ {600.000012} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__ACT_FREQMHZ {500.000010} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__DIVISOR0 {1} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__ACT_FREQMHZ {525.000011} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__FREQMHZ {533.33} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__FBDIV {90} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__VPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRF_APB__VPLL_TO_LPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__ACT_FREQMHZ {500.000010} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__ACT_FREQMHZ {50.000001} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__DIVISOR0 {30} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__ACT_FREQMHZ {500.000010} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__ACT_FREQMHZ {250.000005} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__ACT_FREQMHZ {1499.999985} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__FBDIV {90} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__IOPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRL_APB__IOPLL_TO_FPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__ACT_FREQMHZ {250.000005} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__ACT_FREQMHZ {500.000010} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__ACT_FREQMHZ {187.500004} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__DIVISOR0 {8} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__FBDIV {72} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__RPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRL_APB__RPLL_TO_FPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__ACT_FREQMHZ {200.000004} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__ACT_FREQMHZ {187.500004} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__DIVISOR0 {8} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__ACT_FREQMHZ {200.000004} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__ACT_FREQMHZ {200.000004} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__ACT_FREQMHZ {100.000002} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__ACT_FREQMHZ {250.000005} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__ACT_FREQMHZ {250.000005} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__ACT_FREQMHZ {20.000000} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__DIVISOR0 {25} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__DIVISOR1 {3} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__FREQMHZ {20} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3__ENABLE {1} \ + CONFIG.PSU__CSUPMU__PERIPHERAL__VALID {1} \ + CONFIG.PSU__DDRC__ADDR_MIRROR {1} \ + CONFIG.PSU__DDRC__AL {0} \ + CONFIG.PSU__DDRC__BANK_ADDR_COUNT {3} \ + CONFIG.PSU__DDRC__BG_ADDR_COUNT {NA} \ + CONFIG.PSU__DDRC__BRC_MAPPING {ROW_BANK_COL} \ + CONFIG.PSU__DDRC__BUS_WIDTH {32 Bit} \ + CONFIG.PSU__DDRC__CL {NA} \ + CONFIG.PSU__DDRC__CLOCK_STOP_EN {0} \ + CONFIG.PSU__DDRC__COL_ADDR_COUNT {10} \ + CONFIG.PSU__DDRC__COMPONENTS {Components} \ + CONFIG.PSU__DDRC__CWL {NA} \ + CONFIG.PSU__DDRC__DDR4_ADDR_MAPPING {NA} \ + CONFIG.PSU__DDRC__DDR4_CAL_MODE_ENABLE {NA} \ + CONFIG.PSU__DDRC__DDR4_CRC_CONTROL {NA} \ + CONFIG.PSU__DDRC__DDR4_MAXPWR_SAVING_EN {NA} \ + CONFIG.PSU__DDRC__DDR4_T_REF_MODE {NA} \ + CONFIG.PSU__DDRC__DDR4_T_REF_RANGE {NA} \ + CONFIG.PSU__DDRC__DEEP_PWR_DOWN_EN {0} \ + CONFIG.PSU__DDRC__DEVICE_CAPACITY {16384 MBits} \ + CONFIG.PSU__DDRC__DIMM_ADDR_MIRROR {0} \ + CONFIG.PSU__DDRC__DM_DBI {DM_NO_DBI} \ + CONFIG.PSU__DDRC__DQMAP_0_3 {0} \ + CONFIG.PSU__DDRC__DQMAP_12_15 {0} \ + CONFIG.PSU__DDRC__DQMAP_16_19 {0} \ + CONFIG.PSU__DDRC__DQMAP_20_23 {0} \ + CONFIG.PSU__DDRC__DQMAP_24_27 {0} \ + CONFIG.PSU__DDRC__DQMAP_28_31 {0} \ + CONFIG.PSU__DDRC__DQMAP_32_35 {0} \ + CONFIG.PSU__DDRC__DQMAP_36_39 {0} \ + CONFIG.PSU__DDRC__DQMAP_40_43 {0} \ + CONFIG.PSU__DDRC__DQMAP_44_47 {0} \ + CONFIG.PSU__DDRC__DQMAP_48_51 {0} \ + CONFIG.PSU__DDRC__DQMAP_4_7 {0} \ + CONFIG.PSU__DDRC__DQMAP_52_55 {0} \ + CONFIG.PSU__DDRC__DQMAP_56_59 {0} \ + CONFIG.PSU__DDRC__DQMAP_60_63 {0} \ + CONFIG.PSU__DDRC__DQMAP_64_67 {0} \ + CONFIG.PSU__DDRC__DQMAP_68_71 {0} \ + CONFIG.PSU__DDRC__DQMAP_8_11 {0} \ + CONFIG.PSU__DDRC__DRAM_WIDTH {32 Bits} \ + CONFIG.PSU__DDRC__ECC {Disabled} \ + CONFIG.PSU__DDRC__ENABLE_2T_TIMING {0} \ + CONFIG.PSU__DDRC__ENABLE_DP_SWITCH {1} \ + CONFIG.PSU__DDRC__ENABLE_LP4_HAS_ECC_COMP {0} \ + CONFIG.PSU__DDRC__ENABLE_LP4_SLOWBOOT {0} \ + CONFIG.PSU__DDRC__FGRM {NA} \ + CONFIG.PSU__DDRC__LP_ASR {NA} \ + CONFIG.PSU__DDRC__MEMORY_TYPE {LPDDR 4} \ + CONFIG.PSU__DDRC__PARITY_ENABLE {NA} \ + CONFIG.PSU__DDRC__PER_BANK_REFRESH {0} \ + CONFIG.PSU__DDRC__PHY_DBI_MODE {0} \ + CONFIG.PSU__DDRC__RANK_ADDR_COUNT {0} \ + CONFIG.PSU__DDRC__ROW_ADDR_COUNT {16} \ + CONFIG.PSU__DDRC__SB_TARGET {NA} \ + CONFIG.PSU__DDRC__SELF_REF_ABORT {NA} \ + CONFIG.PSU__DDRC__SPEED_BIN {LPDDR4_1066} \ + CONFIG.PSU__DDRC__STATIC_RD_MODE {0} \ + CONFIG.PSU__DDRC__TRAIN_DATA_EYE {1} \ + CONFIG.PSU__DDRC__TRAIN_READ_GATE {1} \ + CONFIG.PSU__DDRC__TRAIN_WRITE_LEVEL {1} \ + CONFIG.PSU__DDRC__T_FAW {40.0} \ + CONFIG.PSU__DDRC__T_RAS_MIN {42} \ + CONFIG.PSU__DDRC__T_RC {63} \ + CONFIG.PSU__DDRC__T_RCD {15} \ + CONFIG.PSU__DDRC__T_RP {15} \ + CONFIG.PSU__DDRC__VENDOR_PART {OTHERS} \ + CONFIG.PSU__DDRC__VREF {0} \ + CONFIG.PSU__DDR_HIGH_ADDRESS_GUI_ENABLE {0} \ + CONFIG.PSU__DDR_QOS_ENABLE {1} \ + CONFIG.PSU__DDR_QOS_HP0_RDQOS {7} \ + CONFIG.PSU__DDR_QOS_HP0_WRQOS {15} \ + CONFIG.PSU__DDR_QOS_HP1_RDQOS {3} \ + CONFIG.PSU__DDR_QOS_HP1_WRQOS {3} \ + CONFIG.PSU__DDR_QOS_HP2_RDQOS {3} \ + CONFIG.PSU__DDR_QOS_HP2_WRQOS {3} \ + CONFIG.PSU__DDR_QOS_HP3_RDQOS {3} \ + CONFIG.PSU__DDR_QOS_HP3_WRQOS {3} \ + CONFIG.PSU__DDR_QOS_PORT0_TYPE {Low Latency} \ + CONFIG.PSU__DDR_QOS_PORT1_VN1_TYPE {Low Latency} \ + CONFIG.PSU__DDR_QOS_PORT1_VN2_TYPE {Best Effort} \ + CONFIG.PSU__DDR_QOS_PORT2_VN1_TYPE {Low Latency} \ + CONFIG.PSU__DDR_QOS_PORT2_VN2_TYPE {Best Effort} \ + CONFIG.PSU__DDR_QOS_PORT3_TYPE {Video Traffic} \ + CONFIG.PSU__DDR_QOS_PORT4_TYPE {Best Effort} \ + CONFIG.PSU__DDR_QOS_PORT5_TYPE {Best Effort} \ + CONFIG.PSU__DDR_QOS_RD_HPR_THRSHLD {0} \ + CONFIG.PSU__DDR_QOS_RD_LPR_THRSHLD {16} \ + CONFIG.PSU__DDR_QOS_WR_THRSHLD {16} \ + CONFIG.PSU__DDR__INTERFACE__FREQMHZ {266.500} \ + CONFIG.PSU__DISPLAYPORT__LANE0__ENABLE {1} \ + CONFIG.PSU__DISPLAYPORT__LANE0__IO {GT Lane1} \ + CONFIG.PSU__DISPLAYPORT__LANE1__ENABLE {1} \ + CONFIG.PSU__DISPLAYPORT__LANE1__IO {GT Lane0} \ + CONFIG.PSU__DISPLAYPORT__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DLL__ISUSED {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__IO {MIO 27 .. 30} \ + CONFIG.PSU__DP__LANE_SEL {Dual Lower} \ + CONFIG.PSU__DP__REF_CLK_FREQ {27} \ + CONFIG.PSU__DP__REF_CLK_SEL {Ref Clk1} \ + CONFIG.PSU__ENET3__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET3__GRP_MDIO__ENABLE {0} \ + CONFIG.PSU__ENET3__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET3__PTP__ENABLE {0} \ + CONFIG.PSU__ENET3__TSU__ENABLE {0} \ + CONFIG.PSU__FPD_SLCR__WDT1__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__FPD_SLCR__WDT1__FREQMHZ {100.000000} \ + CONFIG.PSU__FPD_SLCR__WDT_CLK_SEL__SELECT {APB} \ + CONFIG.PSU__FPGA_PL0_ENABLE {1} \ + CONFIG.PSU__GEM3_COHERENCY {0} \ + CONFIG.PSU__GPIO0_MIO__IO {MIO 0 .. 25} \ + CONFIG.PSU__GPIO0_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO1_MIO__IO {MIO 26 .. 51} \ + CONFIG.PSU__GPIO1_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO2_MIO__IO {MIO 52 .. 77} \ + CONFIG.PSU__GPIO2_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GT__LINK_SPEED {HBR} \ + CONFIG.PSU__GT__PRE_EMPH_LVL_4 {0} \ + CONFIG.PSU__GT__VLT_SWNG_LVL_4 {0} \ + CONFIG.PSU__I2C0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__I2C1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__I2C1__PERIPHERAL__IO {MIO 4 .. 5} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC0_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC1_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC2_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC3_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__TTC0__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC0__FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC1__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC1__FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC2__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC2__FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC3__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC3__FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__WDT0__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__WDT0__FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__WDT_CLK_SEL__SELECT {APB} \ + CONFIG.PSU__LPD_SLCR__CSUPMU__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__LPD_SLCR__CSUPMU__FREQMHZ {100.000000} \ + CONFIG.PSU__MAXIGP0__DATA_WIDTH {128} \ + CONFIG.PSU__MAXIGP1__DATA_WIDTH {128} \ + CONFIG.PSU__MAXIGP2__DATA_WIDTH {32} \ + CONFIG.PSU__OVERRIDE__BASIC_CLOCK {0} \ + CONFIG.PSU__PL_CLK0_BUF {TRUE} \ + CONFIG.PSU__PMU_COHERENCY {0} \ + CONFIG.PSU__PMU__AIBACK__ENABLE {0} \ + CONFIG.PSU__PMU__EMIO_GPI__ENABLE {0} \ + CONFIG.PSU__PMU__EMIO_GPO__ENABLE {0} \ + CONFIG.PSU__PMU__GPI0__ENABLE {1} \ + CONFIG.PSU__PMU__GPI0__IO {MIO 26} \ + CONFIG.PSU__PMU__GPI1__ENABLE {0} \ + CONFIG.PSU__PMU__GPI2__ENABLE {0} \ + CONFIG.PSU__PMU__GPI3__ENABLE {0} \ + CONFIG.PSU__PMU__GPI4__ENABLE {0} \ + CONFIG.PSU__PMU__GPI5__ENABLE {0} \ + CONFIG.PSU__PMU__GPO0__ENABLE {1} \ + CONFIG.PSU__PMU__GPO0__IO {MIO 32} \ + CONFIG.PSU__PMU__GPO1__ENABLE {1} \ + CONFIG.PSU__PMU__GPO1__IO {MIO 33} \ + CONFIG.PSU__PMU__GPO2__ENABLE {1} \ + CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ + CONFIG.PSU__PMU__GPO2__POLARITY {high} \ + CONFIG.PSU__PMU__GPO3__ENABLE {0} \ + CONFIG.PSU__PMU__GPO4__ENABLE {0} \ + CONFIG.PSU__PMU__GPO5__ENABLE {0} \ + CONFIG.PSU__PMU__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__PMU__PLERROR__ENABLE {0} \ + CONFIG.PSU__PRESET_APPLIED {1} \ + CONFIG.PSU__PROTECTION__MASTERS {USB1:NonSecure;1|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;0|S_AXI_HPC0_FPD:NA;0|S_AXI_HP3_FPD:NA;0|S_AXI_HP2_FPD:NA;0|S_AXI_HP1_FPD:NA;0|S_AXI_HP0_FPD:NA;0|S_AXI_ACP:NA;0|S_AXI_ACE:NA;0|SD1:NonSecure;1|SD0:NonSecure;1|SATA1:NonSecure;0|SATA0:NonSecure;0|RPU1:Secure;1|RPU0:Secure;1|QSPI:NonSecure;0|PMU:NA;1|PCIe:NonSecure;0|NAND:NonSecure;0|LDMA:NonSecure;1|GPU:NonSecure;1|GEM3:NonSecure;0|GEM2:NonSecure;0|GEM1:NonSecure;0|GEM0:NonSecure;0|FDMA:NonSecure;1|DP:NonSecure;1|DAP:NA;1|Coresight:NA;1|CSU:NA;1|APU:NA;1} \ + CONFIG.PSU__PROTECTION__SLAVES {LPD;USB3_1_XHCI;FE300000;FE3FFFFF;1|LPD;USB3_1;FF9E0000;FF9EFFFF;1|LPD;USB3_0_XHCI;FE200000;FE2FFFFF;1|LPD;USB3_0;FF9D0000;FF9DFFFF;1|LPD;UART1;FF010000;FF01FFFF;1|LPD;UART0;FF000000;FF00FFFF;1|LPD;TTC3;FF140000;FF14FFFF;1|LPD;TTC2;FF130000;FF13FFFF;1|LPD;TTC1;FF120000;FF12FFFF;1|LPD;TTC0;FF110000;FF11FFFF;1|FPD;SWDT1;FD4D0000;FD4DFFFF;1|LPD;SWDT0;FF150000;FF15FFFF;1|LPD;SPI1;FF050000;FF05FFFF;1|LPD;SPI0;FF040000;FF04FFFF;1|FPD;SMMU_REG;FD5F0000;FD5FFFFF;1|FPD;SMMU;FD800000;FDFFFFFF;1|FPD;SIOU;FD3D0000;FD3DFFFF;1|FPD;SERDES;FD400000;FD47FFFF;1|LPD;SD1;FF170000;FF17FFFF;1|LPD;SD0;FF160000;FF16FFFF;1|FPD;SATA;FD0C0000;FD0CFFFF;0|LPD;RTC;FFA60000;FFA6FFFF;1|LPD;RSA_CORE;FFCE0000;FFCEFFFF;1|LPD;RPU;FF9A0000;FF9AFFFF;1|FPD;RCPU_GIC;F9000000;F900FFFF;1|LPD;R5_TCM_RAM_GLOBAL;FFE00000;FFE3FFFF;1|LPD;R5_1_Instruction_Cache;FFEC0000;FFECFFFF;1|LPD;R5_1_Data_Cache;FFED0000;FFEDFFFF;1|LPD;R5_1_BTCM_GLOBAL;FFEB0000;FFEBFFFF;1|LPD;R5_1_ATCM_GLOBAL;FFE90000;FFE9FFFF;1|LPD;R5_0_Instruction_Cache;FFE40000;FFE4FFFF;1|LPD;R5_0_Data_Cache;FFE50000;FFE5FFFF;1|LPD;R5_0_BTCM_GLOBAL;FFE20000;FFE2FFFF;1|LPD;R5_0_ATCM_GLOBAL;FFE00000;FFE0FFFF;1|LPD;QSPI_Linear_Address;C0000000;DFFFFFFF;1|LPD;QSPI;FF0F0000;FF0FFFFF;0|LPD;PMU_RAM;FFDC0000;FFDDFFFF;1|LPD;PMU_GLOBAL;FFD80000;FFDBFFFF;1|FPD;PCIE_MAIN;FD0E0000;FD0EFFFF;0|FPD;PCIE_LOW;E0000000;EFFFFFFF;0|FPD;PCIE_HIGH2;8000000000;BFFFFFFFFF;0|FPD;PCIE_HIGH1;600000000;7FFFFFFFF;0|FPD;PCIE_DMA;FD0F0000;FD0FFFFF;0|FPD;PCIE_ATTRIB;FD480000;FD48FFFF;0|LPD;OCM_XMPU_CFG;FFA70000;FFA7FFFF;1|LPD;OCM_SLCR;FF960000;FF96FFFF;1|OCM;OCM;FFFC0000;FFFFFFFF;1|LPD;NAND;FF100000;FF10FFFF;0|LPD;MBISTJTAG;FFCF0000;FFCFFFFF;1|LPD;LPD_XPPU_SINK;FF9C0000;FF9CFFFF;1|LPD;LPD_XPPU;FF980000;FF98FFFF;1|LPD;LPD_SLCR_SECURE;FF4B0000;FF4DFFFF;1|LPD;LPD_SLCR;FF410000;FF4AFFFF;1|LPD;LPD_GPV;FE100000;FE1FFFFF;1|LPD;LPD_DMA_7;FFAF0000;FFAFFFFF;1|LPD;LPD_DMA_6;FFAE0000;FFAEFFFF;1|LPD;LPD_DMA_5;FFAD0000;FFADFFFF;1|LPD;LPD_DMA_4;FFAC0000;FFACFFFF;1|LPD;LPD_DMA_3;FFAB0000;FFABFFFF;1|LPD;LPD_DMA_2;FFAA0000;FFAAFFFF;1|LPD;LPD_DMA_1;FFA90000;FFA9FFFF;1|LPD;LPD_DMA_0;FFA80000;FFA8FFFF;1|LPD;IPI_CTRL;FF380000;FF3FFFFF;1|LPD;IOU_SLCR;FF180000;FF23FFFF;1|LPD;IOU_SECURE_SLCR;FF240000;FF24FFFF;1|LPD;IOU_SCNTRS;FF260000;FF26FFFF;1|LPD;IOU_SCNTR;FF250000;FF25FFFF;1|LPD;IOU_GPV;FE000000;FE0FFFFF;1|LPD;I2C1;FF030000;FF03FFFF;1|LPD;I2C0;FF020000;FF02FFFF;0|FPD;GPU;FD4B0000;FD4BFFFF;1|LPD;GPIO;FF0A0000;FF0AFFFF;1|LPD;GEM3;FF0E0000;FF0EFFFF;0|LPD;GEM2;FF0D0000;FF0DFFFF;0|LPD;GEM1;FF0C0000;FF0CFFFF;0|LPD;GEM0;FF0B0000;FF0BFFFF;0|FPD;FPD_XMPU_SINK;FD4F0000;FD4FFFFF;1|FPD;FPD_XMPU_CFG;FD5D0000;FD5DFFFF;1|FPD;FPD_SLCR_SECURE;FD690000;FD6CFFFF;1|FPD;FPD_SLCR;FD610000;FD68FFFF;1|FPD;FPD_GPV;FD700000;FD7FFFFF;1|FPD;FPD_DMA_CH7;FD570000;FD57FFFF;1|FPD;FPD_DMA_CH6;FD560000;FD56FFFF;1|FPD;FPD_DMA_CH5;FD550000;FD55FFFF;1|FPD;FPD_DMA_CH4;FD540000;FD54FFFF;1|FPD;FPD_DMA_CH3;FD530000;FD53FFFF;1|FPD;FPD_DMA_CH2;FD520000;FD52FFFF;1|FPD;FPD_DMA_CH1;FD510000;FD51FFFF;1|FPD;FPD_DMA_CH0;FD500000;FD50FFFF;1|LPD;EFUSE;FFCC0000;FFCCFFFF;1|FPD;Display Port;FD4A0000;FD4AFFFF;1|FPD;DPDMA;FD4C0000;FD4CFFFF;1|FPD;DDR_XMPU5_CFG;FD050000;FD05FFFF;1|FPD;DDR_XMPU4_CFG;FD040000;FD04FFFF;1|FPD;DDR_XMPU3_CFG;FD030000;FD03FFFF;1|FPD;DDR_XMPU2_CFG;FD020000;FD02FFFF;1|FPD;DDR_XMPU1_CFG;FD010000;FD01FFFF;1|FPD;DDR_XMPU0_CFG;FD000000;FD00FFFF;1|FPD;DDR_QOS_CTRL;FD090000;FD09FFFF;1|FPD;DDR_PHY;FD080000;FD08FFFF;1|DDR;DDR_LOW;0;7FFFFFFF;1|DDR;DDR_HIGH;800000000;800000000;0|FPD;DDDR_CTRL;FD070000;FD070FFF;1|LPD;Coresight;FE800000;FEFFFFFF;1|LPD;CSU_DMA;FFC80000;FFC9FFFF;1|LPD;CSU;FFCA0000;FFCAFFFF;0|LPD;CRL_APB;FF5E0000;FF85FFFF;1|FPD;CRF_APB;FD1A0000;FD2DFFFF;1|FPD;CCI_REG;FD5E0000;FD5EFFFF;1|FPD;CCI_GPV;FD6E0000;FD6EFFFF;1|LPD;CAN1;FF070000;FF07FFFF;0|LPD;CAN0;FF060000;FF06FFFF;0|FPD;APU;FD5C0000;FD5CFFFF;1|LPD;APM_INTC_IOU;FFA20000;FFA2FFFF;1|LPD;APM_FPD_LPD;FFA30000;FFA3FFFF;1|FPD;APM_5;FD490000;FD49FFFF;1|FPD;APM_0;FD0B0000;FD0BFFFF;1|LPD;APM2;FFA10000;FFA1FFFF;1|LPD;APM1;FFA00000;FFA0FFFF;1|LPD;AMS;FFA50000;FFA5FFFF;1|FPD;AFI_5;FD3B0000;FD3BFFFF;1|FPD;AFI_4;FD3A0000;FD3AFFFF;1|FPD;AFI_3;FD390000;FD39FFFF;1|FPD;AFI_2;FD380000;FD38FFFF;1|FPD;AFI_1;FD370000;FD37FFFF;1|FPD;AFI_0;FD360000;FD36FFFF;1|LPD;AFIFM6;FF9B0000;FF9BFFFF;1|FPD;ACPU_GIC;F9000000;F907FFFF;1} \ + CONFIG.PSU__PSS_REF_CLK__FREQMHZ {33.333333} \ + CONFIG.PSU__QSPI_COHERENCY {0} \ + CONFIG.PSU__QSPI__GRP_FBCLK__ENABLE {0} \ + CONFIG.PSU__QSPI__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__SATA__LANE0__ENABLE {0} \ + CONFIG.PSU__SATA__LANE1__ENABLE {0} \ + CONFIG.PSU__SATA__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__SD0_COHERENCY {0} \ + CONFIG.PSU__SD0__DATA_TRANSFER_MODE {4Bit} \ + CONFIG.PSU__SD0__GRP_CD__ENABLE {1} \ + CONFIG.PSU__SD0__GRP_CD__IO {MIO 24} \ + CONFIG.PSU__SD0__GRP_POW__ENABLE {0} \ + CONFIG.PSU__SD0__GRP_WP__ENABLE {0} \ + CONFIG.PSU__SD0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SD0__PERIPHERAL__IO {MIO 13 .. 16 21 22} \ + CONFIG.PSU__SD0__RESET__ENABLE {0} \ + CONFIG.PSU__SD0__SLOT_TYPE {SD 2.0} \ + CONFIG.PSU__SD1_COHERENCY {0} \ + CONFIG.PSU__SD1__DATA_TRANSFER_MODE {4Bit} \ + CONFIG.PSU__SD1__GRP_CD__ENABLE {0} \ + CONFIG.PSU__SD1__GRP_POW__ENABLE {0} \ + CONFIG.PSU__SD1__GRP_WP__ENABLE {0} \ + CONFIG.PSU__SD1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SD1__PERIPHERAL__IO {MIO 46 .. 51} \ + CONFIG.PSU__SD1__RESET__ENABLE {0} \ + CONFIG.PSU__SD1__SLOT_TYPE {SD 2.0} \ + CONFIG.PSU__SPI0__GRP_SS0__ENABLE {1} \ + CONFIG.PSU__SPI0__GRP_SS0__IO {MIO 41} \ + CONFIG.PSU__SPI0__GRP_SS1__ENABLE {0} \ + CONFIG.PSU__SPI0__GRP_SS2__ENABLE {0} \ + CONFIG.PSU__SPI0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SPI0__PERIPHERAL__IO {MIO 38 .. 43} \ + CONFIG.PSU__SPI1__GRP_SS0__ENABLE {1} \ + CONFIG.PSU__SPI1__GRP_SS0__IO {MIO 9} \ + CONFIG.PSU__SPI1__GRP_SS1__ENABLE {0} \ + CONFIG.PSU__SPI1__GRP_SS2__ENABLE {0} \ + CONFIG.PSU__SPI1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SPI1__PERIPHERAL__IO {MIO 6 .. 11} \ + CONFIG.PSU__SWDT0__CLOCK__ENABLE {0} \ + CONFIG.PSU__SWDT0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SWDT0__RESET__ENABLE {0} \ + CONFIG.PSU__SWDT1__CLOCK__ENABLE {0} \ + CONFIG.PSU__SWDT1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SWDT1__RESET__ENABLE {0} \ + CONFIG.PSU__TTC0__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC0__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC1__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC1__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC2__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC2__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC2__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC3__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC3__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC3__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__UART0__BAUD_RATE {115200} \ + CONFIG.PSU__UART0__MODEM__ENABLE {0} \ + CONFIG.PSU__UART0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__UART0__PERIPHERAL__IO {MIO 2 .. 3} \ + CONFIG.PSU__UART1__BAUD_RATE {115200} \ + CONFIG.PSU__UART1__MODEM__ENABLE {0} \ + CONFIG.PSU__UART1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__UART1__PERIPHERAL__IO {MIO 0 .. 1} \ + CONFIG.PSU__USB0_COHERENCY {0} \ + CONFIG.PSU__USB0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB0__PERIPHERAL__IO {MIO 52 .. 63} \ + CONFIG.PSU__USB0__REF_CLK_FREQ {26} \ + CONFIG.PSU__USB0__REF_CLK_SEL {Ref Clk0} \ + CONFIG.PSU__USB1_COHERENCY {0} \ + CONFIG.PSU__USB1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB1__PERIPHERAL__IO {MIO 64 .. 75} \ + CONFIG.PSU__USB1__REF_CLK_FREQ {26} \ + CONFIG.PSU__USB1__REF_CLK_SEL {Ref Clk0} \ + CONFIG.PSU__USB2_0__EMIO__ENABLE {0} \ + CONFIG.PSU__USB2_1__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_0__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB3_0__PERIPHERAL__IO {GT Lane2} \ + CONFIG.PSU__USB3_1__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB3_1__PERIPHERAL__IO {GT Lane3} \ + CONFIG.PSU__USE__IRQ0 {1} \ + CONFIG.PSU__USE__M_AXI_GP0 {1} \ + CONFIG.PSU__USE__M_AXI_GP1 {1} \ + CONFIG.PSU__USE__M_AXI_GP2 {0} \ + CONFIG.SUBPRESET1 {Custom} \ + ] $zynq_ultra_ps_e_0 + + # Create interface connections + connect_bd_intf_net -intf_net ps8_0_axi_periph_M00_AXI [get_bd_intf_pins ps8_0_axi_periph/M00_AXI] [get_bd_intf_pins pynqrouter_0/s_axi_AXI4LS] + connect_bd_intf_net -intf_net zynq_ultra_ps_e_0_M_AXI_HPM0_FPD [get_bd_intf_pins ps8_0_axi_periph/S00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM0_FPD] + connect_bd_intf_net -intf_net zynq_ultra_ps_e_0_M_AXI_HPM1_FPD [get_bd_intf_pins ps8_0_axi_periph/S01_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] + + # Create port connections + connect_bd_net -net rst_ps8_0_100M_interconnect_aresetn [get_bd_pins ps8_0_axi_periph/ARESETN] [get_bd_pins rst_ps8_0_100M/interconnect_aresetn] + connect_bd_net -net rst_ps8_0_100M_peripheral_aresetn [get_bd_pins ps8_0_axi_periph/M00_ARESETN] [get_bd_pins ps8_0_axi_periph/S00_ARESETN] [get_bd_pins ps8_0_axi_periph/S01_ARESETN] [get_bd_pins pynqrouter_0/ap_rst_n] [get_bd_pins rst_ps8_0_100M/peripheral_aresetn] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins ps8_0_axi_periph/ACLK] [get_bd_pins ps8_0_axi_periph/M00_ACLK] [get_bd_pins ps8_0_axi_periph/S00_ACLK] [get_bd_pins ps8_0_axi_periph/S01_ACLK] [get_bd_pins pynqrouter_0/ap_clk] [get_bd_pins rst_ps8_0_100M/slowest_sync_clk] [get_bd_pins zynq_ultra_ps_e_0/maxihpm0_fpd_aclk] [get_bd_pins zynq_ultra_ps_e_0/maxihpm1_fpd_aclk] [get_bd_pins zynq_ultra_ps_e_0/pl_clk0] + connect_bd_net -net zynq_ultra_ps_e_0_pl_resetn0 [get_bd_pins rst_ps8_0_100M/ext_reset_in] [get_bd_pins zynq_ultra_ps_e_0/pl_resetn0] + + # Create address segments + create_bd_addr_seg -range 0x00040000 -offset 0xA0000000 [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs pynqrouter_0/s_axi_AXI4LS/Reg] SEG_pynqrouter_0_Reg + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/hls_2018/router_04_boardstr/etc/ap_fixed_sim.h b/hls_2018/router_04_boardstr/etc/ap_fixed_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..5be571dd70e490d282d279a4eeed32db069703e9 --- /dev/null +++ b/hls_2018/router_04_boardstr/etc/ap_fixed_sim.h @@ -0,0 +1,2451 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_FIXED_H__ +#define __AESL_GCC_AP_FIXED_H__ + +#ifndef __cplusplus + #error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + + +#include +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_int_sim.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#define FLOAT_MAN 23 +#define FLOAT_EXP 8 +#define DOUBLE_MAN 52 +#define DOUBLE_EXP 11 +// #define DOUBLE_MAN_MASK (~0ULL >> (64-DOUBLE_MAN-2)) +#define DOUBLE_MAN_MASK 0x3fffffffffffffULL +#define BIAS(e) ((1ULL<<(e-1))-1) +#define FLOAT_BIAS BIAS(FLOAT_EXP) +#define DOUBLE_BIAS BIAS(DOUBLE_EXP) + +/// Forward declaration. +template struct ap_fixed_base; + +///Proxy class, which allows bit selection to be used as both rvalue(for reading) and +//lvalue(for writing) +template +struct af_bit_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& d_bv; + int d_index; +public: + INLINE af_bit_ref(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE af_bit_ref(ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>* bv, int index=0): + d_bv(*bv),d_index(index) {} + + INLINE operator bool() const { + return d_bv.V[d_index]; + } + + INLINE af_bit_ref& operator=(unsigned long long val) { + if (val) + d_bv.V.set(d_index); + else + d_bv.V.clear(d_index); + return *this; + } + + template + INLINE af_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + return operator=(val!=0); + } + + INLINE af_bit_ref& operator =(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref operator=(const af_bit_ref<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref& operator = ( const ap_bit_ref<_AP_W2, _AP_S2> &val) { + return operator =((unsigned long long) (bool) val); + } + + template + INLINE af_bit_ref& operator = ( const ap_range_ref<_AP_W2,_AP_S2>& val) { + return operator =((const ap_private<_AP_W2, false>) val); + } + + template + INLINE af_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE af_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2> >(*this, const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + template + INLINE bool operator == (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() != op.get(); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv.V)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { + return 1; + } + + INLINE bool get() { + return d_bv.V[d_index]; + } + + INLINE bool get() const { + return d_bv.V[d_index]; + } + + INLINE std::string to_string() const { + return d_bv.V[d_index] ? "1" : "0"; + } +}; + +///Range(slice) reference +//------------------------------------------------------------ +template +struct af_range_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &d_bv; + int l_index; + int h_index; + +public: + INLINE af_range_ref(const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE af_range_ref(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + // fprintf(stderr, + //"Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + if (h_index >= l_index) { + ap_private<_AP_W, false> val(d_bv.V); + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + return val&=mask; + } else { + ap_private<_AP_W, false> val = 0; + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } + } + + INLINE operator unsigned long long() const { + return get().to_uint64(); + } + + template + INLINE af_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W, false> vval= ap_private<_AP_W, false>(val); + if (l_index > h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv.V &= mask; + d_bv.V |= vval; + } + return *this; + } + + INLINE af_range_ref& operator = (unsigned long long val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE af_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + const ap_private<_AP_W2, false> tmp= val.get(); + return operator = (tmp); + } + + INLINE af_range_ref& operator= (const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + const ap_private<_AP_W, false> tmp= val.get(); + return operator = (tmp); + } + + template + INLINE af_range_ref& operator= (const ap_fixed_base<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE bool operator == (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE void set(const ap_private<_AP_W2,false>& val) { + ap_private<_AP_W,_AP_S> vval=val; + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,_AP_S> mask(-1); + if (l_index>0) { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } + + } + + INLINE ap_private<_AP_W,false> get() const { + if (h_index val(0); + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } else { + ap_private<_AP_W, false> val = ap_private<_AP_W,false>(d_bv.V); + val>>= l_index; + if (h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + return val; + } + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& > (op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + INLINE int length() const { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + INLINE int to_int() const { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + INLINE unsigned int to_uint() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + INLINE long to_long() const { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + INLINE unsigned long to_ulong() const { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + INLINE ap_slong to_int64() const { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + INLINE ap_ulong to_uint64() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix) const { + return get().to_string(radix); + } + +}; + +//----------------------------------------------------------------------------- +///ap_fixed_base: AutoPilot fixed point +//----------------------------------------------------------------------------- +template +struct ap_fixed_base { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + template friend struct +ap_fixed_base; + template friend struct +af_bit_ref; + + INLINE void overflow_adjust(bool underflow, bool overflow, + bool lD, bool sign) { + if (!overflow && !underflow) return; + switch (_AP_O) { + case AP_WRAP: + if (_AP_N == 0) + return; + if (_AP_S) { + //signed SC_WRAP + //n_bits == 1; + if (_AP_N > 1) { + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= ~mask; + } + sign ? V.set(_AP_W - 1) : V.clear(_AP_W - 1); + } else { + //unsigned SC_WRAP + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + mask.flip(); + V |= mask; + } + break; + case AP_SAT_ZERO: + V.clear(); + break; + case AP_WRAP_SM: + { + bool Ro = ap_private_ops::get<_AP_W, _AP_S, _AP_W -1>(V); // V[_AP_W -1]; + if (_AP_N == 0) { + if (lD != Ro) { + V.flip(); + lD ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : + ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } else { + if (_AP_N == 1 && sign != Ro) { + V.flip(); + } else if (_AP_N > 1) { + bool lNo = ap_private_ops::get<_AP_W, _AP_S, _AP_W - _AP_N> (V); // V[_AP_W - _AP_N]; + if (lNo == sign) + V.flip(); + ap_private<_AP_W, false> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= mask.flip(); + sign ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } + } + break; + default: + if (_AP_S) { + if (overflow) { + V.set(); ap_private_ops::clear<_AP_W, _AP_S, _AP_W-1>(V); + } else if (underflow) { + V.clear(); + ap_private_ops::set<_AP_W, _AP_S, _AP_W-1>(V); + if (_AP_O == AP_SAT_SYM) + ap_private_ops::set<_AP_W, _AP_S, 0>(V); + } + } else { + if (overflow) + V.set(); + else if (underflow) + V.clear(); + } + } + } + + INLINE bool quantization_adjust(bool qb, bool r, bool s) { + bool carry=ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V); + switch (_AP_Q) { + case AP_TRN: + return false; + case AP_RND_ZERO: + qb &= s || r; + break; + case AP_RND_MIN_INF: + qb &= r; + break; + case AP_RND_INF: + qb &= !s || r; + break; + case AP_RND_CONV: + qb &= ap_private_ops::get<_AP_W, _AP_S, 0>(V) || r; + break; + case AP_TRN_ZERO: + qb = s && ( qb || r ); + break; + default:; + + } + if (qb) ++V; + //only when old V[_AP_W-1]==1 && new V[_AP_W-1]==0 + return carry && !(ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V)); //(!V[_AP_W-1]); + } + + template + struct RType { + enum { + _AP_F=_AP_W-_AP_I, + F2=_AP_W2-_AP_I2, + mult_w = _AP_W+_AP_W2, + mult_i = _AP_I+_AP_I2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + plus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + minus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + minus_s = true, +#ifndef __SC_COMPATIBLE__ + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2, +#else + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2 + AP_MAX(_AP_I2, 0), +#endif /* #ifndef __SC_COMPATIBLE__ */ + div_i = _AP_I + (_AP_W2-_AP_I2) + _AP_S2, + div_s = _AP_S||_AP_S2, + logic_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+AP_MAX(_AP_F,F2), + logic_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + + typedef ap_fixed_base mult; + typedef ap_fixed_base plus; + typedef ap_fixed_base minus; + typedef ap_fixed_base logic; + typedef ap_fixed_base div; + typedef ap_fixed_base<_AP_W, _AP_I, _AP_S> arg1; + }; + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024):" + " for synthesis, please define macro AP_INT_TYPE_EXT(N) to" + " extend the valid range.\n", _AP_W); + } else +#endif /* #if 0 */ + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sfixed<%d, ...>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + /// Constructors. + // ------------------------------------------------------------------------- +#if 0 + #ifdef __SC_COMPATIBLE__ + INLINE ap_fixed_base():V(uint32_t(_AP_W), uint64_t(0)) {} + #else + INLINE ap_fixed_base():V(uint32_t(_AP_W)) {} + #endif /* #ifdef __SC_COMPATIBLE__ */ +#else + INLINE ap_fixed_base():V(0) {} +#endif /* #if 0 */ + // INLINE ap_fixed_base():V() {} + // INLINE explicit ap_fixed_base(const ap_private<_AP_W+_AP_I, _AP_S>& _V):V(_V) {} + INLINE ap_fixed_base(const ap_fixed_base& op):V(op.V) {} + template + INLINE ap_fixed_base(const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op):V(0) { + enum {N2=_AP_W2,_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2,QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || + (_AP_Q==AP_TRN_ZERO && !_AP_S2))}; + if (!op) return; + bool carry=false; + //handle quantization + enum { sh_amt =(F2>_AP_F)?F2-_AP_F:_AP_F-F2}; + const ap_private<_AP_W2, _AP_S2>& val = op.V; + bool neg_src=val.isNegative(); + if (F2==_AP_F) + V=val; + + else if (F2>_AP_F) { + if (sh_amt >= _AP_W2) + V = neg_src ? -1 : 0; + else + V = _AP_S2?val.ashr(sh_amt):val.lshr(sh_amt); + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + bool qb = false; + if (F2-_AP_F>_AP_W2) + qb = neg_src; + else + qb = ap_private_ops::get<_AP_W2, _AP_S2, F2-_AP_F-1>(val); + + bool r=false; + enum { pos3 = F2-_AP_F-2}; + if (pos3>=_AP_W2-1) + r=val!=0; + else if (pos3>=0) + r = (val<<(_AP_W2-1-pos3))!=0; + carry = quantization_adjust(qb,r,neg_src); + } + } else { //no quantization + if (sh_amt < _AP_W) { + V=val; + V <<= sh_amt; + } + } + //hanle overflow/underflow + if ((_AP_O!=AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2 - _AP_S2 + (QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)))) {//saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool lD=(_AP_I2>_AP_I && _AP_W2-_AP_I2+_AP_I>=0) && + ap_private_ops::get<_AP_W2, _AP_S2, _AP_W2-_AP_I2+_AP_I>(val); + enum { pos1=F2-_AP_F+_AP_W, pos2=F2-_AP_F+_AP_W+1}; + if (pos1 < _AP_W2) { + bool Range1_all_ones= true; + bool Range1_all_zeros= true; + if (pos1 >= 0) { + enum { __W = (_AP_W2-pos1) > 0 ? (_AP_W2-pos1) : 1 }; + const ap_private<__W, _AP_S2> Range1=ap_private<__W, _AP_S2>(val.lshr(pos1)); + Range1_all_ones=Range1.isAllOnesValue(); + Range1_all_zeros=Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros=val.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + enum { __W = (_AP_W2-pos2)>0 ? (_AP_W2-pos2) : 1}; + ap_private<__W, true> Range2=ap_private<__W, true>(val.lshr(pos2)); + Range2_all_ones=Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) + :Range1_all_ones; + neg_src= neg_src&&!(carry && Range1_all_ones); + } else + neg_src = neg_src && V[_AP_W-1]; + + bool neg_trg= V.isNegative(); + bool overflow=(neg_trg||!deleted_zeros) && !val.isNegative(); + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow, overflow, lD, neg_src); + } + report(); + } + + template + INLINE ap_fixed_base(const volatile ap_fixed_base<_AP_W2,_AP_I2, + _AP_S2,_AP_Q2,_AP_O2, _AP_N2> &op) : V(op.V) { + *this = const_cast&>(op); + } + + template + INLINE ap_fixed_base(const ap_private<_AP_W2,_AP_S2>& op) { + ap_fixed_base<_AP_W2,_AP_W2,_AP_S2> f_op; + f_op.V=op; + *this = f_op; + } + + INLINE ap_fixed_base(bool b) { + *this=(ap_private<1,false>)b; + report(); + } + + INLINE ap_fixed_base(char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed char b) { + *this=(ap_private<8,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed short b) { + *this=(ap_private<16,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned short b) { + *this=(ap_private<16,false>)b; + report(); + } + + INLINE ap_fixed_base(signed int b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned int b) { + *this=(ap_private<32,false>)b; + report(); + } +# if defined __x86_64__ + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<64,false>)b; + report(); + } +# else + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<32,false>)b; + report(); + } +# endif + + INLINE ap_fixed_base(ap_slong b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(ap_ulong b) { + *this=(ap_private<64,false>)b; + report(); + } + +#if 1 + INLINE ap_fixed_base(const char* val):V(0) { + ap_private<_AP_W, _AP_S> Tmp(val); + V = Tmp; + } + + INLINE ap_fixed_base(const char* val, signed char rd): V(0) { + ap_private<_AP_W, _AP_S> Tmp(val, rd); + V = Tmp; + } + +#endif + + INLINE ap_fixed_base(const std::string& val) { + ap_private<_AP_W, _AP_S> Tmp(val, 2); + V = Tmp; + report(); + } + + template + INLINE ap_fixed_base(const ap_bit_ref<_AP_W2, _AP_S2>& op) { + *this = ((bool)op); + report(); + } + + template + INLINE ap_fixed_base(const ap_range_ref<_AP_W2, _AP_S2>& op) { + *this = ap_private<_AP_W2, _AP_S2>(op); + report(); + } + + template + INLINE ap_fixed_base(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op) { + *this = ((const ap_private<_AP_W2 + _AP_W3, false>&)(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (bool(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (ap_private<_AP_W2, false>(op)); + report(); + } + + //helper function + INLINE unsigned long long doubleToRawBits(double pf)const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__D=pf; + return LD.__L; + } + + + INLINE double rawBitsToDouble(unsigned long long pi) const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__L=pi; + return LD.__D; + } + + INLINE float rawBitsToFloat(uint32_t pi) const { + union { + uint32_t __L; + float __D; + }LD; + LD.__L = pi; + return LD.__D; + } + + INLINE ap_fixed_base(double d):V(0) { + if (!d) return; + const bool isneg=d<0; + + const uint64_t ireg=doubleToRawBits(isneg?-d:d); + if ((ireg&0x7fffffffffffffffULL)!=0) { + const int32_t exp=(((ireg)>>DOUBLE_MAN)&0x07ff)-DOUBLE_BIAS; + ap_private man = ireg & DOUBLE_MAN_MASK; + man.clear(DOUBLE_MAN+1); + man.set(DOUBLE_MAN); + if (isneg) { + man.flip(); + man++; + } + + enum {_AP_S2=true, _AP_W2=DOUBLE_MAN+2,_AP_F=_AP_W -_AP_I }; + const int _AP_I2=exp+2; + const int F2=_AP_W2-_AP_I2; + const bool QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || (_AP_Q==AP_TRN_ZERO && + !_AP_S2)); + bool carry=false; + //handle quantization + const unsigned sh_amt=abs(F2-_AP_F); // sh_amt = F2>_AP_F ? F2 -_AP_F : _AP_F-F2; + if (F2==_AP_F ) + V=man; + else if (F2>_AP_F) { + if (sh_amt >= DOUBLE_MAN+2) + V=isneg?-1:0; + else + V=(man>>sh_amt) | ((man & 1ULL<<(DOUBLE_MAN+1)) ? (DOUBLE_MAN_MASK>>(DOUBLE_MAN+2-sh_amt) <<(DOUBLE_MAN+2-sh_amt)):0); + + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + const bool qb=((F2-_AP_F > DOUBLE_MAN+2) ? isneg : (man & (1ULL<<(F2-_AP_F-1))) != 0); + const int pos3=F2-_AP_F-2; + const bool r = (pos3>= 0) ? (man << AP_MAX(0, _AP_W2-pos3-1)& DOUBLE_MAN_MASK)!=0 : false; + carry = quantization_adjust(qb,r,isneg); + } + } + else { //no quantization + // V=man; + if (sh_amt < _AP_W) { + V = man; + V <<= sh_amt; + } + } + //handle overflow/underflow + if ((_AP_O != AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2-_AP_S2+(QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)) )) {// saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool neg_src; + const bool lD=(_AP_I2>_AP_I) && (_AP_W2-_AP_I2+_AP_I>=0) && (man & (1ULL <<(DOUBLE_MAN+2-_AP_I2+_AP_I))); + int pos1=F2+_AP_W-_AP_F; + if (pos1 < _AP_W2) { + int pos2=pos1+1; + bool Range1_all_ones=true; + bool Range1_all_zeros=true; + if (pos1>=0) { + ap_private<_AP_W,_AP_S> Range1= + ap_private<_AP_W,_AP_S>((man >> pos1) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos1) <<(DOUBLE_MAN+2-pos1)):0)); + Range1_all_ones = Range1.isAllOnesValue(); // Range1.isAllOnesValue(); + Range1_all_zeros = Range1.isMinValue(); // Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros = man==0; // man.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + ap_private<_AP_W, _AP_S> Range2= + ap_private<_AP_W, _AP_S>((man >> pos2) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos2) <<(DOUBLE_MAN+2-pos2)):0)); + Range2_all_ones=Range2.isAllOnesValue(); // Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) : Range1_all_ones; + neg_src=isneg&&!(carry&Range1_all_ones); + } else + neg_src = isneg && V[_AP_W -1]; + + const bool neg_trg=V.isNegative(); + const bool overflow=(neg_trg||!deleted_zeros) && !isneg; + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow,overflow,lD, neg_src); + } + } + report(); + } + + + ///assign operators + //------------------------------------------------------------------------- + + INLINE volatile ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + INLINE volatile ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + // Set this ap_fixed_base with a bits string. That means the ssdm_int::V + // inside this ap_fixed_base is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + INLINE ap_fixed_base& setBits(unsigned long long bv) { + V=bv; + return *this; + } + + // Return a ap_fixed_base object whose ssdm_int::V is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + static INLINE ap_fixed_base bitsToFixed(unsigned long long bv) { + ap_fixed_base Tmp=bv; + return Tmp; + } + + // Explicit conversion functions to ap_private that captures + // all integer bits (bits are truncated) + INLINE ap_private + to_ap_private(bool Cnative = true) const { + ap_private ret = ap_private ((_AP_I >= 1) ? (_AP_S==true ? V.ashr(AP_MAX(0,_AP_W - _AP_I)) : V.lshr(AP_MAX(0,_AP_W - _AP_I))) : ap_private<_AP_W, _AP_S>(0)); + + if (Cnative) { + bool r = false; + if (_AP_I < _AP_W) { + if (_AP_I > 0) r = !(V.getLoBits(_AP_W - _AP_I).isMinValue()); + else r = !(V.isMinValue()); + } + if (r && V.isNegative()) { // if this is negative integer + ++ret;//ap_private(1,_AP_S); + } + } else { + //Follow OSCI library, conversion from sc_fixed to sc_int + } + return ret; + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2> () const { + return (ap_private<_AP_W2,_AP_S2>)to_ap_private(); + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2,_AP_N2> () const { + return (ap_private<_AP_W2,_AP_S2,_AP_N2>)to_ap_private(); + } + + //Explict conversion function to C built-in integral type + INLINE int to_int() const { + return to_ap_private().to_int(); + } + + INLINE int to_uint() const { + return to_ap_private().to_uint(); + } + + INLINE ap_slong to_int64() const { + return to_ap_private().to_int64(); + } + + INLINE ap_ulong to_uint64() const { + return to_ap_private().to_uint64(); + } + + INLINE double to_double() const { + if (!V) + return 0; + if (_AP_W>64 || (_AP_W - _AP_I) > 0) { + bool isneg = _AP_S && V[_AP_W-1]; + uint64_t res = isneg ? 0x8000000000000000ULL : 0; + ap_private<_AP_W, false> tmp = V; + if (isneg) tmp = -tmp; + int i = _AP_W -1 - tmp.countLeadingZeros(); + int exp = _AP_I-(_AP_W-i); + res|=((uint64_t)(exp+DOUBLE_BIAS))<DOUBLE_MAN)?tmp.lshr(i-DOUBLE_MAN):tmp).to_uint64() & DOUBLE_MAN_MASK; + res |= i 0) { + /* This specialization is disabled. It is giving wrong results in some cases. + bool isneg=V.isNegative(); + double dp = V.get(); + dp /= (1<< (_AP_W - _AP_I)); + return dp;*/ + } else + return double(to_int64()); + } + + INLINE float to_float() const { + uint32_t res=0; + if (V==0) + return 0; + bool isneg=V.isNegative(); + ap_private<_AP_W, _AP_S> tmp=V; + if (isneg) tmp = -tmp; + if (_AP_W-_AP_I>0||_AP_W>64) { + if (isneg) + res=0x80000000; + int i=_AP_W-1; + i-=tmp.countLeadingZeros(); + int exp=_AP_I-(_AP_W-i); + res|=(exp+FLOAT_BIAS)< man = 0; + if (i!=0) { + tmp.clear(i); + if (i>FLOAT_MAN) + man=tmp.lshr(i-FLOAT_MAN); + else + man=tmp; + res |= i < FLOAT_MAN?man.getZExtValue()<<(FLOAT_MAN-i):man.getZExtValue(); + } + } else { + return float(to_int64()); + } + float dp=rawBitsToFloat(res); + return dp; + } + + INLINE operator double () const { + return to_double(); + } +#ifndef __SC_COMPATIBLE__ + INLINE operator float () const { + return to_float(); + } + + INLINE operator char () const { + return (char) to_int(); + } + + INLINE operator unsigned char () const { + return (unsigned char) to_uint(); + } + + INLINE operator short () const { + return (short) to_int(); + } + + INLINE operator unsigned short () const { + return (unsigned short) to_uint(); + } + + INLINE operator int () const { + return to_int(); + } + + INLINE operator unsigned int () const { + return to_uint(); + } +#if 1 +#ifdef __x86_64__ + INLINE operator long () const { + return (long)to_int64(); + } + + INLINE operator unsigned long () const { + return (unsigned long) to_uint64(); + } +#else + INLINE operator long () const { + return to_int64(); + } + + INLINE operator unsigned long () const { + return to_uint64(); + } + +#endif +#endif + INLINE operator unsigned long long () const { + return to_uint64(); + } + + INLINE operator long long () const { + return to_int64(); + } +#endif + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const; + + INLINE ap_slong bits_to_int64() const { + ap_private res(V); + return (ap_slong) res; + } + + INLINE ap_ulong bits_to_uint64() const { + ap_private res(V); + return (ap_ulong) res; + } + + INLINE int length() const {return _AP_W;} + + // Count the number of zeros from the most significant bit + // to the first one bit. Note this is only for ap_fixed_base whose + // _AP_W <= 64, otherwise will incur assertion. + INLINE int countLeadingZeros() { + return V.countLeadingZeros(); + } + + ///Arithmetic:Binary + //------------------------------------------------------------------------- + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::mult + operator * (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + typename RType<_AP_W2,_AP_I2,_AP_S2>::mult r; + r.V = V * op2.V; + return r; + } + + template + static INLINE ap_fixed_base multiply(const ap_fixed_base<_AP_W1,_AP_I1,_AP_S1>& op1, const + ap_fixed_base<_AP_W2,_AP_I2,_AP_S2>& op2) { + ap_private<_AP_W+_AP_W2, _AP_S> OP1=op1.V; + ap_private<_AP_W2,_AP_S2> OP2=op2.V; + return OP1*OP2; + } + + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::div + operator / (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {F2 = _AP_W2-_AP_I2, _W1=AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2), + _W2=AP_MAX(_AP_W2,AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2))}; + ap_private<_W1, _AP_S> dividend = (ap_private<_W1, _AP_S>(V)) << ((_W1>_AP_W)?F2:0); + ap_private<_W1, _AP_S2> divisior = ap_private<_W2, _AP_S2>(op2.V); + ap_private<_W1, _AP_S> ret = ap_private<_W1,_AP_S> ((_AP_S||_AP_S2) ? dividend.sdiv(divisior): dividend.udiv(divisior)); + typename RType<_AP_W2, _AP_I2, _AP_S2>::div r; + r.V = ret; + return r; + } +#define OP_BIN_AF(Sym, Rty, Width, Sign, Fun) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + enum {_AP_F=_AP_W-_AP_I, F2=_AP_W2-_AP_I2}; \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V = lhs.V.Fun(rhs.V); \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + + OP_BIN_AF(+, plus, plus_w, plus_s, Add) + OP_BIN_AF(-, minus, minus_w, minus_s, Sub) + +#define OP_LOGIC_BIN_AF(Sym, Rty, Width, Sign) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V=lhs.V Sym rhs.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty operator Sym(int op2) const \ + { \ + return V Sym (op2<<(_AP_W - _AP_I)); \ + } + OP_LOGIC_BIN_AF(&, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(|, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(^, logic, logic_w, logic_s) + + ///Arithmic : assign + //------------------------------------------------------------------------- +#define OP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2) ; \ + return *this; \ + } + + OP_ASSIGN_AF(+) + OP_ASSIGN_AF(-) + OP_ASSIGN_AF(&) + OP_ASSIGN_AF(|) + OP_ASSIGN_AF(^) + OP_ASSIGN_AF(*) + OP_ASSIGN_AF(/) + + ///Prefix increment, decrement + //------------------------------------------------------------------------- + INLINE ap_fixed_base& operator ++() { + operator+=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + INLINE ap_fixed_base& operator --() { + operator-=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + //Postfix increment, decrement + //------------------------------------------------------------------------- + INLINE const ap_fixed_base operator ++(int) { + ap_fixed_base t(*this); + operator++(); + return t; + } + + INLINE const ap_fixed_base operator --(int) { + ap_fixed_base t = *this; + operator--(); + return t; + } + + ///Unary arithmetic + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator +() {return *this;} + + INLINE ap_fixed_base<_AP_W + 1, _AP_I + 1, true> operator -() const { + ap_fixed_base<_AP_W + 1, _AP_I + 1, true> Tmp(*this); + Tmp.V = - Tmp.V; + return Tmp; + } + + INLINE ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> getNeg() { + ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> Tmp(*this); + Tmp.V=-Tmp.V; + return Tmp; + } + + ///Not (!) + //------------------------------------------------------------------------- + INLINE bool operator !() const { + return !V; + } + + ///Bitwise complement + //------------------------------------------------------------------------- + INLINE ap_fixed_base<_AP_W, _AP_I, _AP_S> + operator ~() const { + ap_fixed_base<_AP_W, _AP_I, _AP_S> res(*this); + res.V.flip(); + return res; + } + + ///Shift + ///template argument as shift value + template + INLINE ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> lshift () const { + ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + template + INLINE ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> rshift () const { + ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + //Because the return type is the type of the the first operand, shift assign + //operators do not carry out any quantization or overflow + //While systemc, shift assigns for sc_fixed/sc_ufixed will result in + //quantization or overflow (depending on the mode of the first operand) + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator << (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + bool NegSrc = V.isNegative(); + if (isNeg) { + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); + } else { + if (shiftoverflow) + r.V.clear(); + else + r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == false && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator<<(const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator << (sh); + } + + INLINE ap_fixed_base operator << (unsigned int sh ) const { + ap_fixed_base r; + bool shiftoverflow = sh >= _AP_W; + r.V = shiftoverflow ? ap_private<_AP_W, _AP_S >(0) : V << sh; + if (sh == 0) return r; +#ifdef __SC_COMPATIBLE__ + bool NegSrc = V.isNegative(); + if (_AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh -1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator << (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator << (sh); + } + + INLINE ap_fixed_base operator >> (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + bool NegSrc = V.isNegative(); + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + if (isNeg && !shiftoverflow) r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == true && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator >> (sh); + } + + INLINE ap_fixed_base operator >> (unsigned int sh) const { + ap_fixed_base r; + bool NegSrc = V.isNegative(); + bool shiftoverflow = sh >= _AP_W; + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); +#ifdef __SC_COMPATIBLE__ + if (sh == 0) return r; + if (_AP_Q != AP_TRN) { + bool qb = false; + if (sh <= _AP_W) qb = V[sh - 1]; + bool rb = false; + if (sh > 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator >> (sh); + } + + ///shift assign + //------------------------------------------------------------------------- +#define OP_AP_SHIFT_AP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AP_ASSIGN_AF(<<) + OP_AP_SHIFT_AP_ASSIGN_AF(>>) + + ///Support shift(ap_fixed_base) +#define OP_AP_SHIFT_AF(Sym) \ + template \ + INLINE ap_fixed_base operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + return operator Sym (op2.to_ap_private()); \ + } \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AF(<<) + OP_AP_SHIFT_AF(>>) + + INLINE ap_fixed_base& operator >>= (unsigned int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (unsigned int sh) { + *this = operator << (sh); + return *this; + } + + INLINE ap_fixed_base& operator >>= (int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (int sh) { + *this = operator << (sh); + return *this; + } + + ///Comparisons + //------------------------------------------------------------------------- + template + INLINE bool operator == (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator != (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this==op2); + } + + template + INLINE bool operator > (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator <= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this>op2); + } + + template + INLINE bool operator < (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator >= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this) + DOUBLE_CMP_AF(>=) + DOUBLE_CMP_AF(<) + DOUBLE_CMP_AF(<=) + + // Bit and Slice Select + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> operator [] (unsigned int index) { + assert(index<_AP_W&&"Attemping to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit(unsigned int index) { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit (const ap_private<_AP_W2,_AP_S2>& index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int()); + } + + INLINE bool bit (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + INLINE bool operator [] (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + template + INLINE bool bit (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + template + INLINE bool operator [] (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit(int index) { + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + assert(index >= _AP_I - _AP_W&& "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index + _AP_W - _AP_I); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit (const ap_private<_AP_W2, true>& index) { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int() + _AP_W - _AP_I); + } + + INLINE bool get_bit (int index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index + _AP_W - _AP_I]; + } + + template + INLINE bool get_bit (const ap_private<_AP_W2, true>& index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index.to_int() + _AP_W - _AP_I]; + } + + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W) &&"Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast(this), Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) const { + return this->range(Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast< + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>*>(this), + Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() { + return this->range(_AP_W - 1, 0); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() const { + return this->range(_AP_W - 1, 0); + } + + INLINE bool is_zero () const { + return V.isMinValue(); + } + + INLINE bool is_neg () const { + if (V.isNegative()) + return true; + return false; + } + + INLINE int wl () const { + return _AP_W; + } + + INLINE int iwl () const { + return _AP_I; + } + + INLINE ap_q_mode q_mode () const { + return _AP_Q; + } + + INLINE ap_o_mode o_mode () const { + return _AP_O; + } + + INLINE int n_bits () const { + return 0; + } + + //private: +public: + ap_private<_AP_W, _AP_S> V; +}; + +template +std::string ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>::to_string( + uint8_t radix, bool sign) const { + std::string str; + str.clear(); + char step; + std::string prefix; + switch (radix) { + case 2 : prefix = "0b"; step = 1; break; + case 8 : prefix = "0o"; step = 3; break; + case 16 : prefix = "0x"; step = 4; break; + default : break; + } + if (_AP_W <= _AP_I) + str = this->to_ap_private().to_string(radix, + radix == 10 ? _AP_S : sign); + else { + if (radix == 10) { + bool isNeg = _AP_S && V.isNegative(); + if (_AP_I > 0) { + ap_private int_part(0); + int_part = this->to_ap_private(); + str += int_part.to_string(radix, false); + } else { + if (isNeg) str += '-'; + } + ap_fixed_base<_AP_W, _AP_I, _AP_S> tmp(*this); + if (isNeg && _AP_I <= 0) tmp = -tmp; + ap_fixed_base<_AP_W - AP_MIN(_AP_I, 0), 0, false> frac_part = tmp; + if (frac_part == 0) return str; + str += "."; + while (frac_part != 0) { + char digit = (frac_part * radix).to_ap_private(); + str += static_cast(digit + '0'); + frac_part *= radix; + } + } else { + if (_AP_I > 0) { + for (signed i = _AP_W - _AP_I; i < _AP_W; i += step) { + + char digit = (char)(this->range(AP_MIN(i + step - 1, _AP_W - 1), i)); + str = (digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a')) + str; + } + } + str += '.'; + ap_fixed_base tmp(*this); + for (signed i = _AP_W - _AP_I - 1; i >= 0; i -= step) { + char digit = (char)(tmp.range(i, AP_MAX(0, i - step + 1))); + str += digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a'); + } + } + } + str = prefix + str; + return str; +} + +template +INLINE void b_not(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = op.V; + ret.V.flip(); +} + +template +INLINE void b_and(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V & op2.V; +} + +template +INLINE void b_or(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V | op2.V; +} + +template +INLINE void b_xor(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V ^ op2.V; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + ap_fixed_base<_AP_W2+!_AP_S2, _AP_I2+!_AP_S2, true, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp.V = - op.V; + ret = Tmp; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = -op.V; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_W2 - _AP_I2 + AP_MAX(_AP_I, _AP_I2), AP_MAX(_AP_I, _AP_I2), _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V <<= i; + ret = Tmp; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = op.V << i; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_I2 + AP_MAX(_AP_W - _AP_I, _AP_W2 - _AP_I2), _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V = _AP_S2 ? Tmp.V.ashr(i): Tmp.V.lshr(i); + ret = Tmp; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = _AP_S ? op.V.ashr(i): op.V.lshr(i); +} + +#define AF_CTOR_SPEC_BASE(_AP_W,_AP_S,C_TYPE) \ + template<> INLINE ap_fixed_base<_AP_W,_AP_W,_AP_S,AP_TRN,AP_WRAP>::ap_fixed_base(C_TYPE i_op):V(i_op) \ + { \ + } + +#define AF_CTOR_SPEC(__W,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,true,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,false,C_TYPE) + +AF_CTOR_SPEC(1,bool) +AF_CTOR_SPEC(8, signed char) +AF_CTOR_SPEC(8, unsigned char) +AF_CTOR_SPEC(16, signed short) +AF_CTOR_SPEC(16, unsigned short) +AF_CTOR_SPEC(32, signed int) +AF_CTOR_SPEC(32, unsigned int) +AF_CTOR_SPEC(64, ap_slong) +AF_CTOR_SPEC(64, ap_ulong) + +///Output streaming +//----------------------------------------------------------------------------- +template +INLINE std::ostream& +operator <<(std::ostream& os, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + os << x.to_double(); + return os; +} + +///Input streaming +//----------------------------------------------------------------------------- +template +INLINE std::istream& +operator >> (std::istream& os, ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + double d; + os >> d; + x = ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(x); + return os; +} + +template +INLINE void print(const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + ap_private<_AP_W,_AP_S> data=x.V; + if (_AP_I>0) { + const ap_private<_AP_I,_AP_S> p1=data>>(_AP_W-_AP_I); + print(p1); + + } else + printf("0"); + printf("."); + if (_AP_I<_AP_W) { + const ap_private<_AP_W-_AP_I,false> p2=data; + print(p2,false); + } +} + +///Operators mixing Integers with ap_fixed_base +//----------------------------------------------------------------------------- +#if 1 +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP(ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#else +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op BIN_OP (i_op); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V BIN_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#endif +#if 1 +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator REL_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } +#else +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V.operator REL_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return (i_op<<(_AP_W-_AP_I)) REL_OP (op.V.VAL); \ + } +#endif +#if 1 +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#else +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#endif + +#define AF_OPS_WITH_INT(C_TYPE, WI, SI) \ + AF_BIN_OP_WITH_INT(+, C_TYPE, WI, SI, plus) \ + AF_BIN_OP_WITH_INT(-, C_TYPE, WI, SI, minus) \ + AF_BIN_OP_WITH_INT(*, C_TYPE, WI, SI, mult) \ + AF_BIN_OP_WITH_INT(/, C_TYPE, WI, SI, div) \ + AF_BIN_OP_WITH_INT_SF(>>, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT_SF(<<, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT(&, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(|, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(^, C_TYPE, WI, SI, logic) \ + \ + AF_REL_OP_WITH_INT(==, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(!=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<=, C_TYPE, WI, SI) \ + \ + AF_ASSIGN_OP_WITH_INT(+=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(-=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(*=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(/=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(>>=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(<<=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(&=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(|=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(^=, C_TYPE, WI, SI) + +AF_OPS_WITH_INT(bool, 1, false) +AF_OPS_WITH_INT(char, 8, true) +AF_OPS_WITH_INT(signed char, 8, true) +AF_OPS_WITH_INT(unsigned char, 8, false) +AF_OPS_WITH_INT(short, 16, true) +AF_OPS_WITH_INT(unsigned short, 16, false) +AF_OPS_WITH_INT(int, 32, true) +AF_OPS_WITH_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_OPS_WITH_INT(long, 64, true) +AF_OPS_WITH_INT(unsigned long, 64, false) +# else +AF_OPS_WITH_INT(long, 32, true) +AF_OPS_WITH_INT(unsigned long, 32, false) +# endif +AF_OPS_WITH_INT(ap_slong, 64, true) +AF_OPS_WITH_INT(ap_ulong, 64, false) + +#define AF_BIN_OP_WITH_AP_INT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>::template RType<_AP_W,_AP_I,_AP_S>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } + +#define AF_REL_OP_WITH_AP_INT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator REL_OP ( ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } + +#define AF_ASSIGN_OP_WITH_AP_INT(ASSIGN_OP) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE ap_private<_AP_W2,_AP_S2>& operator ASSIGN_OP ( ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return i_op.operator ASSIGN_OP (op.to_ap_private()); \ + } + +AF_BIN_OP_WITH_AP_INT(+, plus) +AF_BIN_OP_WITH_AP_INT(-, minus) +AF_BIN_OP_WITH_AP_INT(*, mult) +AF_BIN_OP_WITH_AP_INT(/, div) +AF_BIN_OP_WITH_AP_INT(&, logic) +AF_BIN_OP_WITH_AP_INT(|, logic) +AF_BIN_OP_WITH_AP_INT(^, logic) + +AF_REL_OP_WITH_AP_INT(==) +AF_REL_OP_WITH_AP_INT(!=) +AF_REL_OP_WITH_AP_INT(>) +AF_REL_OP_WITH_AP_INT(>=) +AF_REL_OP_WITH_AP_INT(<) +AF_REL_OP_WITH_AP_INT(<=) + +AF_ASSIGN_OP_WITH_AP_INT(+=) +AF_ASSIGN_OP_WITH_AP_INT(-=) +AF_ASSIGN_OP_WITH_AP_INT(*=) +AF_ASSIGN_OP_WITH_AP_INT(/=) +AF_ASSIGN_OP_WITH_AP_INT(&=) +AF_ASSIGN_OP_WITH_AP_INT(|=) +AF_ASSIGN_OP_WITH_AP_INT(^=) + +#define AF_REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2 REL_OP (bool(op)); \ + } + +#define AF_REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +AF_REF_REL_MIX_INT(bool, 1, false) +AF_REF_REL_MIX_INT(char, 8, true) +AF_REF_REL_MIX_INT(signed char, 8, true) +AF_REF_REL_MIX_INT(unsigned char, 8, false) +AF_REF_REL_MIX_INT(short, 16, true) +AF_REF_REL_MIX_INT(unsigned short, 16, false) +AF_REF_REL_MIX_INT(int, 32, true) +AF_REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_REF_REL_MIX_INT(long, 64, true) +AF_REF_REL_MIX_INT(unsigned long, 64, false) +# else +AF_REF_REL_MIX_INT(long, 32, true) +AF_REF_REL_MIX_INT(unsigned long, 32, false) +# endif +AF_REF_REL_MIX_INT(ap_slong, 64, true) +AF_REF_REL_MIX_INT(ap_ulong, 64, false) + +#define AF_REF_REL_OP_AP_INT(REL_OP) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S> &op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP (const ap_private<_AP_W2, _AP_S2> &op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S2> &op2) { \ + return (ap_private<1, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2, _AP_S2> &op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<1,false>(op)); \ + } + +AF_REF_REL_OP_AP_INT(>) +AF_REF_REL_OP_AP_INT(<) +AF_REF_REL_OP_AP_INT(>=) +AF_REF_REL_OP_AP_INT(<=) +AF_REF_REL_OP_AP_INT(==) +AF_REF_REL_OP_AP_INT(!=) + +// Relational Operators with double +template +INLINE bool operator == ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator == (op1); +} + +template +INLINE bool operator != ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator != (op1); +} + +template +INLINE bool operator > ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator < (op1); +} + +template +INLINE bool operator >= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator <= (op1); +} + +template +INLINE bool operator < ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator > (op1); +} + +template +INLINE bool operator <= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator >= (op1); +} + +#endif /* #ifndef __AESL_GCC_AP_FIXED_H__ */ \ No newline at end of file diff --git a/hls_2018/router_04_boardstr/etc/ap_int_sim.h b/hls_2018/router_04_boardstr/etc/ap_int_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..887ccd88bfd52d1777db8661d72c57703ccf736a --- /dev/null +++ b/hls_2018/router_04_boardstr/etc/ap_int_sim.h @@ -0,0 +1,1629 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_INT_H__ +#define __AESL_GCC_AP_INT_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + +#undef _AP_DEBUG_ +#include +#include + +// for safety +#if (defined(_AP_N)|| defined(_AP_C)) +#error One or more of the following is defined: _AP_N, _AP_C. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_N)|| defined(_AP_C)) */ + +// for safety +#if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) +#error One or more of the following is defined: _AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) */ + +//for safety +#if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) +#error One or more of the following is defined: _AP_W3, _AP_S3, _AP_W4,_AP_S4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) */ + +//for safety +#if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) +#error One or more of the following is defined: _AP_W1, _AP_S1, _AP_I1, _AP_T, _AP_T1, _AP_T2, _AP_T3, _AP_T4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) */ + +#define __AESL_APDT_IN_SCFLOW__ +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_private.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#ifdef _AP_DEBUG_ + #define AP_DEBUG(s) s +#else + #define AP_DEBUG(s) +#endif /* #ifdef _AP_DEBUG_ */ + +#ifndef __SIMULATION__ + #define __SIMULATION__ +#endif /* #ifndef __SIMULATION__ */ + +#if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) + #ifndef SC_TRN + #define SC_TRN AP_TRN + #endif /* #ifndef SC_TRN */ + #ifndef SC_RND + #define SC_RND AP_RND + #endif /* #ifndef SC_RND */ + #ifndef SC_TRN_ZERO + #define SC_TRN_ZERO AP_TRN_ZERO + #endif /* #ifndef SC_TRN_ZERO */ + #ifndef SC_RND_ZERO + #define SC_RND_ZERO AP_RND_ZERO + #endif /* #ifndef SC_RND_ZERO */ + #ifndef SC_RND_INF + #define SC_RND_INF AP_RND_INF + #endif /* #ifndef SC_RND_INF */ + #ifndef SC_RND_MIN_INF + #define SC_RND_MIN_INF AP_RND_MIN_INF + #endif /* #ifndef SC_RND_MIN_INF */ + #ifndef SC_RND_CONV + #define SC_RND_CONV AP_RND_CONV + #endif /* #ifndef SC_RND_CONV */ + #ifndef SC_WRAP + #define SC_WRAP AP_WRAP + #endif /* #ifndef SC_WRAP */ + #ifndef SC_SAT + #define SC_SAT AP_SAT + #endif /* #ifndef SC_SAT */ + #ifndef SC_SAT_ZERO + #define SC_SAT_ZERO AP_SAT_ZERO + #endif /* #ifndef SC_SAT_ZERO */ + #ifndef SC_SAT_SYM + #define SC_SAT_SYM AP_SAT_SYM + #endif /* #ifndef SC_SAT_SYM */ + #ifndef SC_WRAP_SM + #define SC_WRAP_SM AP_WRAP_SM + #endif /* #ifndef SC_WRAP_SM */ + #ifndef SC_BIN + #define SC_BIN AP_BIN + #endif /* #ifndef SC_BIN */ + #ifndef SC_OCT + #define SC_OCT AP_OCT + #endif /* #ifndef SC_OCT */ + #ifndef SC_DEC + #define SC_DEC AP_DEC + #endif /* #ifndef SC_DEC */ + #ifndef SC_HEX + #define SC_HEX AP_HEX + #endif /* #ifndef SC_HEX */ +#endif /* #if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) */ +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +///Forward declaration +template struct ap_range_ref; +template struct ap_bit_ref; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; +template class ap_uint; + +enum { + AP_BIN = 2, + AP_OCT = 8, + AP_DEC = 10, + AP_HEX = 16 +}; + +///Why to use reference? +///Because we will operate the original object indirectly by operating the +///result object directly after concating or part selecting + +///Proxy class which allows concatination to be used as rvalue(for reading) and +//lvalue(for writing) + +/// Concatination reference. +// ---------------------------------------------------------------- +template +struct ap_concat_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + enum {_AP_WR=_AP_W1+_AP_W2,}; + _AP_T1& mbv1; + _AP_T2& mbv2; + + INLINE ap_concat_ref(const ap_concat_ref<_AP_W1, _AP_T1, + _AP_W2, _AP_T2>& ref): + mbv1(ref.mbv1), mbv2(ref.mbv2) {} + + INLINE ap_concat_ref(_AP_T1& bv1, _AP_T2& bv2):mbv1(bv1),mbv2(bv2) {} + + template + INLINE ap_concat_ref& operator = (const ap_private<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + return *this; + } + + INLINE ap_concat_ref& operator = (unsigned long long val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W1, _AP_T1, _AP_W2, _AP_T2>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_concat_ref& operator= (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = ((const ap_private<_AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref& operator= (const ap_fixed_base<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = (val.to_ap_private()); + } + + template + INLINE ap_concat_ref& operator= (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + + INLINE operator ap_private<_AP_WR, false> () const { + return get(); + } + + INLINE operator unsigned long long () const { + return get().to_uint64(); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_range_ref<_AP_W3, _AP_S3> > + operator, (const ap_range_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_range_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (const ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, + const_cast&>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, 1, ap_bit_ref<_AP_W3, _AP_S3> > + operator, (const ap_bit_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + 1, ap_bit_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> > + operator, (const ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> &a2) + { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4, + _AP_T4> >(*this, const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE ap_private + operator & (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() & a2; + } + + + template + INLINE ap_private + operator | (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() | a2; + } + + + template + INLINE ap_private + operator ^ (const ap_private<_AP_W3,_AP_S3>& a2) { + return ap_private(get() ^ a2); + } + + INLINE const ap_private<_AP_WR, false> get() const + { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> (mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + INLINE const ap_private<_AP_WR, false> get() { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> ( mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + template + INLINE void set(const ap_private<_AP_W3,false> & val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + } + + INLINE int length() const { + return mbv1.length()+mbv2.length(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } +}; + +///Proxy class, which allows part selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Range(slice) reference +//------------------------------------------------------------ +template +struct ap_range_ref { +#ifdef _MSC_VER + #pragma warning( disable : 4521 4522 ) +#endif /* #ifdef _MSC_VER */ + ap_private<_AP_W,_AP_S> &d_bv; + int l_index; + int h_index; + +public: + INLINE ap_range_ref(const ap_range_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE ap_range_ref(ap_private<_AP_W,_AP_S>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + //fprintf(stderr, "Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + ap_private<_AP_W, false> val(0); + if(h_index>=l_index) { + if (_AP_W > 64) { + val=d_bv; + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + val&=mask; + } else { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val = (d_bv >> l_index) & (mask >>(_AP_W-(h_index-l_index+1))); + } + } else { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } + return val; + } + + INLINE operator unsigned long long () const { + return to_uint64(); + } + + template + INLINE ap_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W,false> vval=ap_private<_AP_W,false>(val); + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W > 64) { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + unsigned shift = 64-_AP_W; + uint64_t mask = ~0ULL>>(shift); + if(l_index>0) + { + vval = mask & vval << l_index; + mask = mask & mask << l_index; + } + if(h_index<_AP_W-1) + { + uint64_t mask2 = mask; + mask2 >>= (_AP_W-h_index-1); + mask&=mask2; + vval&=mask2; + } + mask = ~mask; + d_bv&=mask; + d_bv|=vval; + } + } + return *this; + } + + INLINE ap_range_ref& operator = (unsigned long long val) + { + const ap_private<_AP_W,_AP_S> vval=val; + return operator = (vval); + } + + + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W, _AP_S>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + + + template + INLINE ap_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, _AP_S2>)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE ap_range_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_bit_ref<_AP_W2, _AP_S2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, + ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast& >(a2)); + } + + + template + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2,_AP_S2>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W,ap_private<_AP_W,_AP_S> > + operator , (ap_private<_AP_W, _AP_S>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W, + ap_private<_AP_W,_AP_S> >(*this, a2); + } + + + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,1,ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, 1, + ap_bit_ref<_AP_W2,_AP_S2> >(*this, const_cast& >(a2)); + } + + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) + { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + + template + INLINE void set(const ap_private<_AP_W2,false>& val) + { + ap_private<_AP_W,_AP_S> vval=val; + if(l_index>h_index) + { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W>64 ) { + ap_private<_AP_W,_AP_S> mask(-1); + if(l_index>0) + { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + uint64_t mask = ~0ULL >> (64-_AP_W); + if(l_index>0) + { + uint64_t mask1 = mask; + mask1=mask & (mask1>>(_AP_W-l_index)); + vval =mask&( vval <> (64-_AP_W); + mask2 = mask &(mask2<<(h_index+1)); + mask&=~mask2; + vval&=~mask2; + } + d_bv&=(~mask&(~0ULL >> (64-_AP_W))); + d_bv|=vval; + } + } + } + + + INLINE ap_private<_AP_W,false> get() const + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64) { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val &= (mask>> (_AP_W-(h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE ap_private<_AP_W,false> get() + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64 ) { + static const uint64_t mask = ~0ULL>> (64>_AP_W ? (64-_AP_W):0); + return val &= ( (mask) >> (_AP_W - (h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE int length() const + { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + + INLINE int to_int() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + + INLINE unsigned int to_uint() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + + INLINE long to_long() const + { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + + INLINE unsigned long to_ulong() const + { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + + INLINE ap_slong to_int64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + + INLINE ap_ulong to_uint64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } + +}; + +///Proxy class, which allows bit selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Bit reference +//-------------------------------------------------------------- +template +struct ap_bit_ref { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif + ap_private<_AP_W,_AP_S>& d_bv; + int d_index; + +public: + INLINE ap_bit_ref(const ap_bit_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE ap_bit_ref(ap_private<_AP_W,_AP_S>& bv, int index=0): + d_bv(bv),d_index(index) + { +#ifdef _AP_DEBUG_ + assert(d_index<_AP_W&&"index out of bound"); +#endif + } + + + INLINE operator bool () const + { + return d_bv.get_bit(d_index); + } + + + INLINE bool to_bool() const + { + return operator bool (); + } + + + INLINE ap_bit_ref& operator = (unsigned long long val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } + + +#if 0 + INLINE ap_bit_ref& operator = (bool val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } +#endif + template + INLINE ap_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(val != 0)); + } + + + template + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool)val); + } + + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W,_AP_S>& val) + { + return operator =((unsigned long long)(bool)val); + } + + template + INLINE ap_bit_ref& operator =(const ap_range_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool) val); + } + + + template + INLINE ap_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE ap_bit_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2, _AP_S2>& a2) + { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref > + operator, (const ap_bit_ref &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref >(*this, + const_cast(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> > + operator, (const ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> &a2) + { + return + ap_concat_ref<1,ap_bit_ref,_AP_W2+_AP_W3, + ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() != op.get(); + } + + + INLINE bool get() const + { + return operator bool (); + } + + + INLINE bool get() + { + return operator bool (); + } + + + template + INLINE void set(const ap_private<_AP_W3, false>& val) + { + operator = (val); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { return 1; } + + INLINE std::string to_string() const { + bool val = get(); + return val ? "1" : "0"; + } +}; + +/// Operators mixing Integers with AP_Int +// ---------------------------------------------------------------- +#if 1 +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#else +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#endif +#define OP_REL_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator REL_OP (ap_private<_AP_W2, _AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (op); \ + } +#define OP_ASSIGN_MIX_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } + +#define OP_BIN_SHIFT_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + C_TYPE operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return i_op BIN_OP (op.getVal()); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (i_op); \ + } +#define OP_ASSIGN_RSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator >> (op2); \ + return op; \ + } +#define OP_ASSIGN_LSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator << (op2); \ + return op; \ + } + +#define OPS_MIX_INT(C_TYPE, WI, SI) \ + OP_BIN_MIX_INT(*, C_TYPE, WI, SI, mult) \ + OP_BIN_MIX_INT(+, C_TYPE, WI, SI, plus) \ + OP_BIN_MIX_INT(-, C_TYPE, WI, SI, minus) \ + OP_BIN_MIX_INT(/, C_TYPE, WI, SI, div) \ + OP_BIN_MIX_INT(%, C_TYPE, WI, SI, mod) \ + OP_BIN_MIX_INT(&, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(|, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(^, C_TYPE, WI, SI, logic) \ + OP_BIN_SHIFT_INT(>>, C_TYPE, WI, SI, arg1) \ + OP_BIN_SHIFT_INT(<<, C_TYPE, WI, SI, arg1) \ + \ + OP_REL_MIX_INT(==, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(!=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<=, C_TYPE, WI, SI) \ + \ + OP_ASSIGN_MIX_INT(+=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(-=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(*=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(/=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(%=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(&=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(|=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(^=, C_TYPE, WI, SI) \ + OP_ASSIGN_RSHIFT_INT(>>=, C_TYPE, WI, SI) \ + OP_ASSIGN_LSHIFT_INT(<<=, C_TYPE, WI, SI) + + +OPS_MIX_INT(bool, 1, false) +OPS_MIX_INT(char, 8, true) +OPS_MIX_INT(signed char, 8, true) +OPS_MIX_INT(unsigned char, 8, false) +OPS_MIX_INT(short, 16, true) +OPS_MIX_INT(unsigned short, 16, false) +OPS_MIX_INT(int, 32, true) +OPS_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +OPS_MIX_INT(long, 64, true) +OPS_MIX_INT(unsigned long, 64, false) +# else +OPS_MIX_INT(long, 32, true) +OPS_MIX_INT(unsigned long, 32, false) +# endif +OPS_MIX_INT(ap_slong, 64, true) +OPS_MIX_INT(ap_ulong, 64, false) + +#define OP_BIN_MIX_RANGE(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<_AP_W2, false>(op2)); \ + } + +#define OP_REL_MIX_RANGE(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (op2.operator ap_private<_AP_W2, false>()); \ + } + +#define OP_ASSIGN_MIX_RANGE(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<_AP_W2, false>(op2)); \ + } \ + template \ + INLINE ap_range_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP (ap_range_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<_AP_W1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_RANGE(+=) +OP_ASSIGN_MIX_RANGE(-=) +OP_ASSIGN_MIX_RANGE(*=) +OP_ASSIGN_MIX_RANGE(/=) +OP_ASSIGN_MIX_RANGE(%=) +OP_ASSIGN_MIX_RANGE(>>=) +OP_ASSIGN_MIX_RANGE(<<=) +OP_ASSIGN_MIX_RANGE(&=) +OP_ASSIGN_MIX_RANGE(|=) +OP_ASSIGN_MIX_RANGE(^=) + +OP_REL_MIX_RANGE(==) +OP_REL_MIX_RANGE(!=) +OP_REL_MIX_RANGE(>) +OP_REL_MIX_RANGE(>=) +OP_REL_MIX_RANGE(<) +OP_REL_MIX_RANGE(<=) + +OP_BIN_MIX_RANGE(+, plus) +OP_BIN_MIX_RANGE(-, minus) +OP_BIN_MIX_RANGE(*, mult) +OP_BIN_MIX_RANGE(/, div) +OP_BIN_MIX_RANGE(%, mod) +OP_BIN_MIX_RANGE(>>, arg1) +OP_BIN_MIX_RANGE(<<, arg1) +OP_BIN_MIX_RANGE(&, logic) +OP_BIN_MIX_RANGE(|, logic) +OP_BIN_MIX_RANGE(^, logic) + +#define OP_BIN_MIX_BIT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<1, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<1,false>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<1, false>(op2)); \ + } + +#define OP_REL_MIX_BIT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (ap_private<1, false>(op2)); \ + } + +#define OP_ASSIGN_MIX_BIT(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<1, false>(op2)); \ + } \ + template \ + INLINE ap_bit_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_bit_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_BIT(+=) +OP_ASSIGN_MIX_BIT(-=) +OP_ASSIGN_MIX_BIT(*=) +OP_ASSIGN_MIX_BIT(/=) +OP_ASSIGN_MIX_BIT(%=) +OP_ASSIGN_MIX_BIT(>>=) +OP_ASSIGN_MIX_BIT(<<=) +OP_ASSIGN_MIX_BIT(&=) +OP_ASSIGN_MIX_BIT(|=) +OP_ASSIGN_MIX_BIT(^=) + +OP_REL_MIX_BIT(==) +OP_REL_MIX_BIT(!=) +OP_REL_MIX_BIT(>) +OP_REL_MIX_BIT(>=) +OP_REL_MIX_BIT(<) +OP_REL_MIX_BIT(<=) + +OP_BIN_MIX_BIT(+, plus) +OP_BIN_MIX_BIT(-, minus) +OP_BIN_MIX_BIT(*, mult) +OP_BIN_MIX_BIT(/, div) +OP_BIN_MIX_BIT(%, mod) +OP_BIN_MIX_BIT(>>, arg1) +OP_BIN_MIX_BIT(<<, arg1) +OP_BIN_MIX_BIT(&, logic) +OP_BIN_MIX_BIT(|, logic) +OP_BIN_MIX_BIT(^, logic) + +#define REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_bit_ref<_AP_W,_AP_S> &op) { \ + return op2 REL_OP (bool(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op, C_TYPE op2) { \ + return (ap_private<_AP_W + _AP_W1, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W + _AP_W1, false>(op)); \ + } + +#define REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +REF_REL_MIX_INT(bool, 1, false) +REF_REL_MIX_INT(char, 8, true) +REF_REL_MIX_INT(signed char, 8, true) +REF_REL_MIX_INT(unsigned char, 8, false) +REF_REL_MIX_INT(short, 16, true) +REF_REL_MIX_INT(unsigned short, 16, false) +REF_REL_MIX_INT(int, 32, true) +REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_REL_MIX_INT(long, 64, true) +REF_REL_MIX_INT(unsigned long, 64, false) +# else +REF_REL_MIX_INT(long, 32, true) +REF_REL_MIX_INT(unsigned long, 32, false) +# endif +REF_REL_MIX_INT(ap_slong, 64, true) +REF_REL_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP_MIX_INT(BIN_OP, RTYPE, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator BIN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE typename ap_private<_AP_W2, _AP_S2>::template RType<_AP_W,false>::RTYPE \ + operator BIN_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator BIN_OP (ap_private<_AP_W, false>(op)); \ + } + +#define REF_BIN_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(+, plus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(-, minus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(*, mult, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(/, div, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(%, mod, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(>>, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(<<, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(&, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(|, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(^, logic, C_TYPE, _AP_WI, _AP_SI) + +REF_BIN_MIX_INT(bool, 1, false) +REF_BIN_MIX_INT(char, 8, true) +REF_BIN_MIX_INT(signed char, 8, true) +REF_BIN_MIX_INT(unsigned char, 8, false) +REF_BIN_MIX_INT(short, 16, true) +REF_BIN_MIX_INT(unsigned short, 16, false) +REF_BIN_MIX_INT(int, 32, true) +REF_BIN_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_BIN_MIX_INT(long, 64, true) +REF_BIN_MIX_INT(unsigned long, 64, false) +#else +REF_BIN_MIX_INT(long, 32, true) +REF_BIN_MIX_INT(unsigned long, 32, false) +#endif +REF_BIN_MIX_INT(ap_slong, 64, true) +REF_BIN_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP(BIN_OP, RTYPE) \ +template \ +INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2, false>::RTYPE \ +operator BIN_OP (const ap_range_ref<_AP_W,_AP_S> &lhs, const ap_range_ref<_AP_W2,_AP_S2> &rhs) { \ + return ap_private<_AP_W,false>(lhs).operator BIN_OP (ap_private<_AP_W2, false>(rhs)); \ +} + +REF_BIN_OP(+, plus) +REF_BIN_OP(-, minus) +REF_BIN_OP(*, mult) +REF_BIN_OP(/, div) +REF_BIN_OP(%, mod) +REF_BIN_OP(>>, arg1) +REF_BIN_OP(<<, arg1) +REF_BIN_OP(&, logic) +REF_BIN_OP(|, logic) +REF_BIN_OP(^, logic) + +#if 1 +#define CONCAT_OP_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_private<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret |= val; \ + return ret;\ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_private<_AP_W, _AP_S>& op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + if (_AP_S) { \ + ret <<= _AP_WI; ret >>= _AP_WI; \ + } \ + ret |= val << _AP_W; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_range_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + } \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_range_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (const ap_bit_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, false> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (C_TYPE op1, const ap_bit_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + 1, false> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op1, C_TYPE op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op2);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op1);\ + if (_AP_SI) { \ + val <<= _AP_W + _AP_W2; val >>= _AP_W + _AP_W2; \ + } \ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +}\ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op1);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op2);\ + int len = op2.length(); \ + val <<= len; \ + ret |= val;\ + return ret; \ +}\ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const af_range_ref<_AP_W, _AP_I, _AP_S, \ + _AP_Q, _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, \ + _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (C_TYPE op1, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q,\ + _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} + +CONCAT_OP_MIX_INT(bool, 1, false) +CONCAT_OP_MIX_INT(char, 8, true) +CONCAT_OP_MIX_INT(signed char, 8, true) +CONCAT_OP_MIX_INT(unsigned char, 8, false) +CONCAT_OP_MIX_INT(short, 16, true) +CONCAT_OP_MIX_INT(unsigned short, 16, false) +CONCAT_OP_MIX_INT(int, 32, true) +CONCAT_OP_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +CONCAT_OP_MIX_INT(long, 64, true) +CONCAT_OP_MIX_INT(unsigned long, 64, false) +# else +CONCAT_OP_MIX_INT(long, 32, true) +CONCAT_OP_MIX_INT(unsigned long, 32, false) +# endif +CONCAT_OP_MIX_INT(ap_slong, 64, true) +CONCAT_OP_MIX_INT(ap_ulong, 64, false) +#endif + +#if 1 +#define CONCAT_SHIFT_MIX_INT(C_TYPE, op) \ +template \ +INLINE ap_uint<_AP_W+_AP_W1> operator op (const ap_concat_ref<_AP_W, _AP_T, _AP_W1, _AP_T1> lhs, C_TYPE rhs) { \ + return ((ap_uint<_AP_W+_AP_W1>)lhs.get()) op ((int)rhs); \ +} + +CONCAT_SHIFT_MIX_INT(long, <<) +CONCAT_SHIFT_MIX_INT(unsigned long, <<) +CONCAT_SHIFT_MIX_INT(unsigned int, <<) +CONCAT_SHIFT_MIX_INT(ap_ulong, <<) +CONCAT_SHIFT_MIX_INT(ap_slong, <<) +CONCAT_SHIFT_MIX_INT(long, >>) +CONCAT_SHIFT_MIX_INT(unsigned long, >>) +CONCAT_SHIFT_MIX_INT(unsigned int, >>) +CONCAT_SHIFT_MIX_INT(ap_ulong, >>) +CONCAT_SHIFT_MIX_INT(ap_slong, >>) +#endif + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_private<_AP_W, _AP_S> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_private<_AP_W,_AP_S> &op) +{ + ap_private<_AP_W, _AP_S> v=op; + const std::ios_base::fmtflags basefield = out.flags() & std::ios_base::basefield; + unsigned radix = (basefield == std::ios_base::hex) ? 16 : + ((basefield == std::ios_base::oct) ? 8 : 10); + std::string str=v.toString(radix,_AP_S); + out< +INLINE std::istream& operator >> (std::istream& in, ap_private<_AP_W,_AP_S> &op) +{ + std::string str; + in >> str; + op = ap_private<_AP_W, _AP_S>(str.c_str()); + return in; + +} + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator<<(out, ap_private<_AP_W, _AP_S>(op)); +} + +template +INLINE std::istream& operator >> (std::istream& in, ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator>>(in, ap_private<_AP_W, _AP_S>(op));; +} + +template +INLINE void print(const ap_private<_AP_W,_AP_S> &op, bool fill=true ) +{ + ap_private<_AP_W, _AP_S> v=op; + uint32_t ws=v.getNumWords(); + const uint64_t *ptr=v.getRawData(); + int i=ws-1; +#if 0 + if(fill) + printf("%016llx",*(ptr+i)); + else + printf("%llx",*(ptr+i)); +#else +//match SystemC output + if(_AP_W%64 != 0) { + uint32_t offset=_AP_W%64; + uint32_t count=(offset+3)/4; + int64_t data=*(ptr+i); + if(_AP_S) + data=(data<<(64-offset))>>(64-offset); + else + count=(offset+4)/4; + while(count-->0) + printf("%llx",(data>>(count*4))&0xf); + } else { + if(_AP_S==false) + printf("0"); + printf("%016llx",*(ptr+i)); + } +#endif + for(--i;i>=0;i--) + printf("%016llx",*(ptr+i)); + printf("\n"); + +} +#endif /* #ifndef __AESL_GCC_AP_INT_H__ */ \ No newline at end of file diff --git a/hls_2018/router_04_boardstr/etc/ap_private.h b/hls_2018/router_04_boardstr/etc/ap_private.h new file mode 100755 index 0000000000000000000000000000000000000000..1a68a9e56e950d7108a3014149623c017023d809 --- /dev/null +++ b/hls_2018/router_04_boardstr/etc/ap_private.h @@ -0,0 +1,5858 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LLVM_SUPPORT_MATHEXTRAS_H +#define LLVM_SUPPORT_MATHEXTRAS_H + +#ifdef _MSC_VER +#if _MSC_VER <= 1500 +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else if +#include +#endif /* #if _MSC_VER <= 1500 */ +#else +#include +#endif /* #if _MSC_VER <= 1500 */ +#undef INLINE +#if 1 +#define INLINE inline +#else +//Enable to debug ap_int/ap_fixed +#define INLINE __attribute__((weak)) +#endif +#define AP_MAX(a,b) ((a) > (b) ? (a) : (b)) +#define AP_MIN(a,b) ((a) < (b) ? (a) : (b)) +#define AP_ABS(a) ((a)>=0 ? (a):-(a)) +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +// NOTE: The following support functions use the _32/_64 extensions instead of +// type overloading so that signed and unsigned integers can be used without +// ambiguity. + +/// Hi_32 - This function returns the high 32 bits of a 64 bit value. +INLINE uint32_t Hi_32(uint64_t Value) { + return static_cast(Value >> 32); +} + +/// Lo_32 - This function returns the low 32 bits of a 64 bit value. +INLINE uint32_t Lo_32(uint64_t Value) { + return static_cast(Value); +} + +/// ByteSwap_16 - This function returns a byte-swapped representation of the +/// 16-bit argument, Value. +INLINE uint16_t ByteSwap_16(uint16_t Value) { +#if defined(_MSC_VER) && !defined(_DEBUG) + // The DLL version of the runtime lacks these functions (bug!?), but in a + // release build they're replaced with BSWAP instructions anyway. + return (uint16_t)(_byteswap_ushort(Value)); +#else + uint16_t Hi = (uint16_t)((Value) << 8); + uint16_t Lo = (uint16_t)((Value) >> 8); + return Hi | Lo; +#endif +} + +/// ByteSwap_32 - This function returns a byte-swapped representation of the +/// 32-bit argument, Value. +INLINE uint32_t ByteSwap_32(uint32_t Value) { + uint32_t Byte0 = Value & 0x000000FF; + uint32_t Byte1 = Value & 0x0000FF00; + uint32_t Byte2 = Value & 0x00FF0000; + uint32_t Byte3 = Value & 0xFF000000; + return ((Byte0) << 24) | ((Byte1) << 8) | ((Byte2) >> 8) | ((Byte3) >> 24); +} + +/// ByteSwap_64 - This function returns a byte-swapped representation of the +/// 64-bit argument, Value. +INLINE uint64_t ByteSwap_64(uint64_t Value) { + uint64_t Hi = ByteSwap_32(uint32_t(Value)); + uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32)); + return ((Hi) << 32) | Lo; +} + +/// CountLeadingZeros_32 - this function performs the platform optimal form of +/// counting the number of zeros from the most significant bit to the first one +/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. +/// Returns 32 if the word is zero. +INLINE unsigned CountLeadingZeros_32(uint32_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clz(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (Value == 0) return 32; +#endif + Count = __builtin_clz(Value); +#else + if (Value == 0) return 32; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) { + uint32_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } +#endif + return Count; +} + +/// CountLeadingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the most significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountLeadingZeros_64(uint64_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clzll(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (!Value) return 64; +#endif + Count = __builtin_clzll(Value); +#else + if (sizeof(long) == sizeof(int64_t)) { + if (!Value) return 64; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) { + uint64_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } + } else { + // get hi portion + uint32_t Hi = Hi_32(Value); + + // if some bits in hi portion + if (Hi) { + // leading zeros in hi portion plus all bits in lo portion + Count = CountLeadingZeros_32(Hi); + } else { + // get lo portion + uint32_t Lo = Lo_32(Value); + // same as 32 bit value + Count = CountLeadingZeros_32(Lo)+32; + } + } +#endif + return Count; +} + +/// CountTrailingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the least significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountTrailingZeros_64(uint64_t Value) { +#if __GNUC__ >= 4 + return (Value != 0) ? __builtin_ctzll(Value) : 64; +#else + static const unsigned Mod67Position[] = { + 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, + 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, + 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, + 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, + 7, 48, 35, 6, 34, 33, 0 + }; + return Mod67Position[(uint64_t)(-(int64_t)Value & (int64_t)Value) % 67]; +#endif +} + +/// CountPopulation_64 - this function counts the number of set bits in a value, +/// (64 bit edition.) +INLINE unsigned CountPopulation_64(uint64_t Value) { +#if __GNUC__ >= 4 + return __builtin_popcountll(Value); +#else + uint64_t v = Value - (((Value) >> 1) & 0x5555555555555555ULL); + v = (v & 0x3333333333333333ULL) + (((v) >> 2) & 0x3333333333333333ULL); + v = (v + ((v) >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); +#endif +} + +#endif // LLVM_SUPPORT_MATHEXTRAS_H + + +#ifndef AP_PRIVATE_H +#define AP_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AESL_std { + template + DataType INLINE min(DataType a, DataType b) { + // if (a >= b) return b; + // else return a; + return (a>=b) ? b : a; + } + + template + DataType INLINE max(DataType a, DataType b) { + // if (a >= b) return a; + // else return b; + return (a>=b) ? a : b; + } +} +enum ap_q_mode { + AP_RND, // rounding to plus infinity + AP_RND_ZERO,// rounding to zero + AP_RND_MIN_INF,// rounding to minus infinity + AP_RND_INF,// rounding to infinity + AP_RND_CONV, // convergent rounding + AP_TRN, // truncation + AP_TRN_ZERO // truncation to zero + +}; +enum ap_o_mode { + AP_SAT, // saturation + AP_SAT_ZERO, // saturation to zero + AP_SAT_SYM, // symmetrical saturation + AP_WRAP, // wrap-around (*) + AP_WRAP_SM // sign magnitude wrap-around (*) +}; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; + +template struct ap_range_ref; +template struct ap_bit_ref; +template struct ap_concat_ref; +static bool InvalidDigit(const char* str, unsigned len, unsigned start, unsigned radix) { + unsigned i; + for (i = start; i < len; ++i) + if ((radix == 2 && (str[i] == '0' || str[i] == '1')) || + (radix == 8 && str[i] >= '0' && str[i] <= '7') || + (radix == 10 && str[i] >= '0' && str[i] <= '9') || + (radix == 16 && ((str[i] >= '0' && str[i] <= '9') || + (str[i] >= 'a' && str[i] <= 'f') || + (str[i] >= 'A' && str[i] <= 'F')))) + continue; + else + return true; + return false; +} + +static void ap_parse_sign(const char* str, uint32_t &base, bool &neg) { + if (str[0] == '+' || str[0] == '-') base = 1; + if (str[0] == '-') neg = true; + else neg = false; + return; +} + +static void ap_parse_prefix(const char* str, uint32_t &offset, uint32_t &radix) { + if (str[0] == '0') { + switch (str[1]) { + case 'b': + case 'B': offset = 2; radix = 2; break; + case 'x': + case 'X': offset = 2; radix = 16; break; + case 'd': + case 'D': offset = 2; radix = 10; break; + case 'o': + case 'O': offset = 2; radix = 8; break; + default: break; + } + } + if (offset == 0) + for (int i=0, len = strlen(str); i= 'a') || (str[i] <= 'F' && str[i] >= 'A')) { + radix = 16; + break; + } + return; +} + +/// sub_1 - This function subtracts a single "digit" (64-bit word), y, from +/// the multi-digit integer array, x[], propagating the borrowed 1 value until +/// no further borrowing is neeeded or it runs out of "digits" in x. The result +/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. +/// In other words, if y > x then this function returns 1, otherwise 0. +/// @returns the borrow out of the subtraction +static bool sub_1(uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + uint64_t __X = x[i]; + x[i] -= y; + if (y > __X) + y = 1; // We have to "borrow 1" from next "digit" + else { + y = 0; // No need to borrow + break; // Remaining digits are unchanged so exit early + } + } + return (y != 0); +} + + /// This enumeration just provides for internal constants used in this + /// translation unit. + enum { + MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MIN_INT_BITS + MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MAX_INT_BITS + }; + + /// A utility function for allocating memory and checking for allocation + /// failure. The content is not zeroed. + static uint64_t* getMemory(uint32_t numWords) { + return (uint64_t*) malloc(numWords*sizeof(uint64_t)); + } + + //===----------------------------------------------------------------------===// + // ap_private Class + //===----------------------------------------------------------------------===// + + /// ap_private - This class represents arbitrary precision constant integral values. + /// It is a functional replacement for common case unsigned integer type like + /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width + /// integer sizes and large integer value types such as 3-bits, 15-bits, or more + /// than 64-bits of precision. ap_private provides a variety of arithmetic operators + /// and methods to manipulate integer values of any bit-width. It supports both + /// the typical integer arithmetic and comparison operations as well as bitwise + /// manipulation. + /// + /// The class has several invariants worth noting: + /// * All bit, byte, and word positions are zero-based. + /// * Once the bit width is set, it doesn't change except by the Truncate, + /// SignExtend, or ZeroExtend operations. + /// * All binary operators must be on ap_private instances of the same bit width. + /// Attempting to use these operators on instances with different bit + /// widths will yield an assertion. + /// * The value is stored canonically as an unsigned value. For operations + /// where it makes a difference, there are both signed and unsigned variants + /// of the operation. For example, sdiv and udiv. However, because the bit + /// widths must be the same, operations such as Mul and Add produce the same + /// results regardless of whether the values are interpreted as signed or + /// not. + /// * In general, the class tries to follow the style of computation that LLVM + /// uses in its IR. This simplifies its use for LLVM. + /// + /// @brief Class for arbitrary precision integers. + template class ap_private; + namespace ap_private_ops{ + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + } + +#if defined(_MSC_VER) +# if _MSC_VER < 1400 && !defined(for) +# define for if(0);else for +# endif + typedef unsigned __int64 ap_ulong; + typedef signed __int64 ap_slong; +#else + typedef unsigned long long ap_ulong; + typedef signed long long ap_slong; +#endif + template struct retval { + }; + template<> struct retval { + typedef ap_slong Type; + }; + template<> struct retval { + typedef ap_ulong Type; + }; + + template + class ap_private { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template friend struct ap_fixed_base; + ///return type of variety of operations + //---------------------------------------------------------- + template + struct RType { + enum { + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024): for" + " synthesis: please define macro AP_INT_TYPE_EXT(N)" + " to extend the valid range.\n", _AP_W); + } else +#endif + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sint<%d>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + enum { BitWidth = _AP_W }; + /// This union is used to store the integer value. When the + /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal. + + /// This enum is used to hold the constants we needed for ap_private. + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t pVal[_AP_N]; ///< Used to store the >64 bits integer value. + + /// This enum is used to hold the constants we needed for ap_private. + enum { + APINT_BITS_PER_WORD = sizeof(uint64_t) * 8, ///< Bits in a word + APINT_WORD_SIZE = sizeof(uint64_t) ///< Byte size of a word + }; + + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + + /// This constructor is used only internally for speed of construction of + /// temporaries. It is unsafe for general use so it is not public. + /* Constructors */ + + ap_private(const char* val) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 16; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + ap_private(const char* val, int rd) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + // uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + // ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + ap_private ap_private_val(strp , strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + /// Note that numWords can be smaller or larger than the corresponding bit + /// width but any extraneous bits will be dropped. + /// @param numBits the bit width of the constructed ap_private + /// @param numWords the number of words in bigVal + /// @param bigVal a sequence of words to form the initial value of the ap_private + /// @brief Construct an ap_private of numBits width, initialized as bigVal[]. + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(0) { + assert(bigVal && "Null pointer detected!"); + { + // Get memory, cleared to 0 + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Calculate the number of words to copy + uint32_t words = AESL_std::min(numWords, _AP_N); + // Copy the words from bigVal to pVal + memcpy(pVal, bigVal, words * APINT_WORD_SIZE); + if (words >= _AP_W) + clearUnusedBits(); + // Make sure unused high bits are cleared + } + } + + /// This constructor interprets Val as a string in the given radix. The + /// interpretation stops when the first charater that is not suitable for the + /// radix is encountered. Acceptable radix values are 2, 8, 10 and 16. It is + /// an error for the value implied by the string to require more bits than + /// numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param val the string to be interpreted + /// @param radix the radix of Val to use for the intepretation + /// @brief Construct an ap_private from a string representation. + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0) { + assert(!val.empty() && "The input string is empty."); + const char *c_str = val.c_str(); + fromString(c_str+base+offset, val.size()-base-offset, radix); + } + + /// This constructor interprets the slen characters starting at StrStart as + /// a string in the given radix. The interpretation stops when the first + /// character that is not suitable for the radix is encountered. Acceptable + /// radix values are 2, 8, 10 and 16. It is an error for the value implied by + /// the string to require more bits than numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param strStart the start of the string to be interpreted + /// @param slen the maximum number of characters to interpret + /// @param radix the radix to use for the conversion + /// @brief Construct an ap_private from a string representation. + /// This method does not consider whether it is negative or not. + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0) { + fromString(strStart+base+offset, slen-base-offset, radix); + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) { + *this = ((uint64_t)(bool)ref); + report(); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + report(); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = (uint64_t)(bool)val; + report(); + } + + /// Simply makes *this a copy of that. + /// @brief Copy Constructor. + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (const_cast& >(that)); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (that); + } + + template + explicit ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that): VAL(0) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (that.isNegative()) { + pVal[0] = that.VAL|that_sign_ext_mask; + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); + } else { + pVal[0] = that.VAL; + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); + } + clearUnusedBits(); + } + + ap_private(const ap_private& that): VAL(0) { + memcpy(pVal, that.pVal, _AP_N * APINT_WORD_SIZE); + clearUnusedBits(); + } + + /// @brief Destructor. + virtual ~ap_private() {} + + /// Default constructor that creates an uninitialized ap_private. This is useful + /// for object deserialization (pair this with the static method Read). + ap_private(){memset(pVal, 0, sizeof(uint64_t)*(_AP_N));} + + ap_private(uint64_t* val, uint32_t bits=_AP_W) {assert(0);} + ap_private(const uint64_t *const val, uint32_t bits) {assert(0);} + + /// @name Constructors + /// @{ + /// If isSigned is true then val is treated as if it were a signed value + /// (i.e. as an int64_t) and the appropriate sign extension to the bit width + /// will be done. Otherwise, no sign extension occurs (high order bits beyond + /// the range of val are zero filled). + /// @param numBits the bit width of the constructed ap_private + /// @param val the initial value of the ap_private + /// @param isSigned how to treat signedness of val + /// @brief Create a new ap_private of numBits width, initialized as val. +#define CTOR(TYPE, SIGNED) \ + ap_private(TYPE val, bool isSigned=SIGNED) { \ + pVal[0] = val; \ + if (isSigned && int64_t(pVal[0]) < 0) { \ + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); \ + } else { \ + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); \ + } \ + clearUnusedBits(); \ + } +#if 1 + CTOR(int, true) + CTOR(bool, false) + CTOR(signed char, true) + CTOR(unsigned char, false) + CTOR(short, true) + CTOR(unsigned short, false) + CTOR(unsigned int, false) + CTOR(long, true) + CTOR(unsigned long, false) + CTOR(unsigned long long, false) + CTOR(long long, true) + CTOR(float, false) + CTOR(double, false) +#undef CTOR +#else + CTOR(uint64_t) +#undef CTOR +#endif + + + /// @returns true if the number of bits <= 64, false otherwise. + /// @brief Determine if this ap_private just has one word to store value. + INLINE bool isSingleWord() const { + return false; + } + + /// @returns the word position for the specified bit position. + /// @brief Determine which word a bit is in. + static uint32_t whichWord(uint32_t bitPosition) { + // return bitPosition / APINT_BITS_PER_WORD; + return (bitPosition) >> 6; + } + + /// @returns the bit position in a word for the specified bit position + /// in the ap_private. + /// @brief Determine which bit in a word a bit is in. + static uint32_t whichBit(uint32_t bitPosition) { + // return bitPosition % APINT_BITS_PER_WORD; + return bitPosition & 0x3f; + } + + /// bit at a specific bit position. This is used to mask the bit in the + /// corresponding word. + /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set + /// @brief Get a single bit mask. + static uint64_t maskBit(uint32_t bitPosition) { + return 1ULL << (whichBit(bitPosition)); + } + + /// @returns the corresponding word for the specified bit position. + /// @brief Get the word corresponding to a bit position + INLINE uint64_t getWord(uint32_t bitPosition) const { + return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; + } + + /// This method is used internally to clear the to "N" bits in the high order + /// word that are not used by the ap_private. This is needed after the most + /// significant word is assigned a value to ensure that those bits are + /// zero'd out. + /// @brief Clear unused high order bits + INLINE void clearUnusedBits(void) { + pVal[_AP_N-1] = _AP_S ? ((((int64_t)pVal[_AP_N-1])<<(excess_bits))>> excess_bits) : (excess_bits ? ((pVal[_AP_N-1])<<(excess_bits))>>(excess_bits) : pVal[_AP_N-1]); + } + + INLINE void clearUnusedBitsToZero(void) { + pVal[_AP_N-1] &= mask; + } + + INLINE void clearUnusedBitsToOne(void) { + pVal[_AP_N-1] |= mask; + } + + /// This is used by the constructors that take string arguments. + /// @brief Convert a char array into an ap_private + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix) ; + + INLINE ap_private read() volatile { + return *this; + } + + INLINE void write(const ap_private& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + operator ValType() const { + return getVal(); + } + + INLINE ValType getVal() const{ + return *pVal; + } + + INLINE int to_int() const { + return int(*this); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + INLINE ap_private& set(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] |= maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + INLINE void set() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] = ~0ULL; + clearUnusedBits(); + } + + //Get the value of ith bit + INLINE bool get (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + /// Set the given bit to 0 whose position is given as "bitPosition". + /// @brief Set a given bit to 0. + ap_private& clear(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + /// @brief Set every bit to 0. + void clear() { + memset(pVal, 0, _AP_N * APINT_WORD_SIZE); + } + + /// @brief Toggle every bit to its opposite value. + ap_private& flip() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] ^= ~0ULL; + clearUnusedBits(); + return *this; + } + + /// Toggle a given bit to its opposite value whose position is given + /// as "bitPosition". + /// @brief Toggles a given bit to its opposite value. + ap_private& flip(uint32_t bitPosition) { + assert(bitPosition < BitWidth && "Out of the bit-width range!"); + if ((*this)[bitPosition]) clear(bitPosition); + else set(bitPosition); + return *this; + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + ap_private getLoBits(uint32_t numBits) const { + return ap_private_ops::lshr(ap_private_ops::shl(*this, _AP_W - numBits), + _AP_W - numBits); + } + + ap_private getHiBits(uint32_t numBits) const { + return ap_private_ops::lshr(*this, _AP_W - numBits); + } + + //Binary Arithmetic + //----------------------------------------------------------- + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + ///Arithmetic assign + //------------------------------------------------------------- + +#define OP_BIN_LOGIC_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { \ + uint32_t numWords = AESL_std::min(_AP_N, _AP_N1); \ + uint32_t i; \ + for (i = 0; i < numWords; ++i) \ + pVal[i] Sym RHS.pVal[i]; \ + if (_AP_N1 < _AP_N) { \ + uint64_t ext = RHS.isNegative()?~0ULL:0; \ + for (;i<_AP_N; i++) \ + pVal[i] Sym ext; \ + } \ + clearUnusedBits(); \ + return *this; \ + } + + OP_BIN_LOGIC_ASSIGN_AP(&=); + OP_BIN_LOGIC_ASSIGN_AP(|=); + OP_BIN_LOGIC_ASSIGN_AP(^=); +#undef OP_BIN_LOGIC_ASSIGN_AP + + /// Adds the RHS APint to this ap_private. + /// @returns this, after addition of RHS. + /// @brief Addition assignment operator. + template + INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + add(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + sub(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + ap_private& operator*=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) { + // 0 * X ===> 0 + return *this; + } + + ap_private dupRHS = RHS; + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = dupRHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + clear(); + return *this; + } + + // Allocate space for the result + uint32_t destWords = rhsWords + lhsWords; + uint64_t *dest = getMemory(destWords); + + // Perform the long multiply + mul(dest, pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + // Copy result back into *this + clear(); + uint32_t wordsToCopy = destWords >= _AP_N ? _AP_N : destWords; + + memcpy(pVal, dest, wordsToCopy* APINT_WORD_SIZE); + + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0ULL; + for (int i=wordsToCopy; i<_AP_N; i++) + pVal[i]=ext; + clearUnusedBits(); + // delete dest array and return + free(dest); + return *this; + } + +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP(/) + OP_ASSIGN_AP(%) +#undef OP_ASSIGN_AP + +#define OP_BIN_LOGIC_AP(Sym) \ + template \ + INLINE \ + typename RType<_AP_W1, _AP_S1>::logic \ + operator Sym (const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { \ + enum { numWords = (RType<_AP_W1, _AP_S1>::logic_w +APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; \ + typename RType<_AP_W1, _AP_S1>::logic Result; \ + uint64_t *val = Result.pVal; \ + uint32_t i; \ + uint32_t min_N = std::min(_AP_N, _AP_N1); \ + uint32_t max_N = std::max(_AP_N, _AP_N1); \ + for (i = 0; i < min_N; ++i) \ + val[i] = pVal[i] Sym RHS.pVal[i]; \ + if (numWords > i) { \ + const uint64_t* tmpVal = (_AP_N>_AP_N1 ? pVal : RHS.pVal)+i; \ + uint64_t ext = ((_AP_N<_AP_N1 && isNegative() )||(_AP_N1 < _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + for (;i i) { \ + uint64_t ext2 = ((_AP_N>_AP_N1 && isNegative() )||(_AP_N1 > _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + val[i] = ext Sym ext2; \ + } \ + } \ + Result.clearUnusedBits(); \ + return Result; \ + } + + OP_BIN_LOGIC_AP(|); + OP_BIN_LOGIC_AP(&); + OP_BIN_LOGIC_AP(^); + +#undef OP_BIN_LOGIC_AP + + template + INLINE typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + // assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + typename RType<_AP_W1,_AP_S1>::plus Result; + bool carry = add(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::plus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::plus_w + 63) / 64> std::max(_AP_W, _AP_W1) ) + Result.pVal[(RType<_AP_W1,_AP_S1>::plus_w + 63)/64 - 1] = carry; + Result.clearUnusedBits(); + return Result; + } + + template + INLINE typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + typename RType<_AP_W1,_AP_S1>::minus Result; + bool borrow = sub(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::minus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::minus_w + 63) / 64 > AESL_std::max(_AP_W, _AP_W1) ) { + Result.pVal[(RType<_AP_W1,_AP_S1>::minus_w+63)/64 - 1] = borrow; + } + Result.clearUnusedBits(); + return Result; + } + + template + typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) + // 0 * X ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + } + + //extend size to avoid result loss + typename RType<_AP_W1, _AP_S1>::mult dupLHS = *this; + typename RType<_AP_W1, _AP_S1>::mult dupRHS = RHS; + lhsBits = dupLHS.getActiveBits(); + lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + rhsBits = dupRHS.getActiveBits(); + rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + + // Allocate space for the result + enum { destWords =(RType<_AP_W1, _AP_S1>::mult_w+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + int destw = destWords; + typename RType<_AP_W1, _AP_S1>::mult Result; + uint64_t *dest = Result.pVal; + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0; + + // Perform the long multiply + mul(dest, dupLHS.pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + for (int i=lhsWords+rhsWords; i + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=*this; + ap_private rhs= op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod(_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + template + INLINE ap_private + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private + operator << (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=length()); + if(overflow) + r.clear(); + else + r = ap_private(r.shl(sh)); + return r; + } + + template + INLINE ap_private + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private + operator >> (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + INLINE ap_private& operator Sym##=(unsigned int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } + OP_ASSIGN_AP(>>) + OP_ASSIGN_AP(<<) +#undef OP_ASSIGN_AP + ///Comparisons + //----------------------------------------------------------------- + bool operator==(const ap_private& RHS) const { + // Get some facts about the number of bits used in the two operands. + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If the number of bits isn't the same, they aren't equal + if (n1 != n2) + return false; + + // If the number of bits fits in a word, we only need to compare the low word. + if (n1 <= APINT_BITS_PER_WORD) + return pVal[0] == RHS.pVal[0]; + + // Otherwise, compare everything + for (int i = whichWord(n1 - 1); i >= 0; --i) + if (pVal[i] != RHS.pVal[i]) + return false; + return true; + } + + template + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S|_AP_S2> lhs(*this); + ap_private<_AP_MAX_W, _AP_S|_AP_S2> rhs(op); + return lhs==rhs; + } + + bool operator==(uint64_t Val) const { + uint32_t n = getActiveBits(); + if (n <= APINT_BITS_PER_WORD) + return pVal[0] == Val; + else + return false; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2>& op) const { + return !(*this==op); + } + + template + INLINE bool operator!=(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !((*this) == RHS); + } + + INLINE bool operator!=(uint64_t Val) const { + return !((*this) == Val); + } + + + template + INLINE bool operator <= (const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this>op); + } + + INLINE bool operator <(const ap_private& op) const { + return _AP_S ? slt(op):ult(op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.sgt(rhs):lhs.ugt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + } + + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE bool operator [](uint32_t bitPosition) const { + return (maskBit(bitPosition) & (pVal[whichWord(bitPosition)])) != 0; + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + INLINE ap_private<_AP_W,false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + /// @} + /// @name Value Tests + /// @{ + /// This tests the high bit of this ap_private to determine if it is set. + /// @returns true if this ap_private is negative, false otherwise + /// @brief Determine sign of this ap_private. + INLINE bool isNegative() const { + //just for get rid of warnings + enum {shift = (_AP_W-APINT_BITS_PER_WORD*(_AP_N-1)-1)}; + static const uint64_t mask = 1ULL << (shift); + return _AP_S && (pVal[_AP_N-1]&mask); + } + + /// This tests the high bit of the ap_private to determine if it is unset. + /// @brief Determine if this ap_private Value is positive (not negative). + INLINE bool isPositive() const { + return !isNegative(); + } + + /// This tests if the value of this ap_private is strictly positive (> 0). + /// @returns true if this ap_private is Positive and not zero. + /// @brief Determine if this ap_private Value is strictly positive. + INLINE bool isStrictlyPositive() const { + return isPositive() && (*this) != 0; + } + + /// This checks to see if the value has all bits of the ap_private are set or not. + /// @brief Determine if all bits are set + INLINE bool isAllOnesValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest unsigned value. + INLINE bool isMaxValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest signed value. + INLINE bool isMaxSignedValue() const { + return BitWidth == 1 ? VAL == 0 : + !isNegative() && countPopulation() == _AP_W - 1; + } + + /// This checks to see if the value of this ap_private is the minimum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest unsigned value. + INLINE bool isMinValue() const { + return countPopulation() == 0; + } + + /// This checks to see if the value of this ap_private is the minimum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest signed value. + INLINE bool isMinSignedValue() const { + return BitWidth == 1 ? VAL == 1 : + isNegative() && countPopulation() == 1; + } + + /// This function returns a pointer to the internal storage of the ap_private. + /// This is useful for writing out the ap_private in binary form without any + /// conversions. + INLINE const uint64_t* getRawData() const { + if (isSingleWord()) + return &VAL; + return &pVal[0]; + } + + ap_private sqrt() const; + + /// @} + /// @Assignment Operators + /// @{ + /// @returns *this after assignment of RHS. + /// @brief Copy assignment operator. + INLINE ap_private& operator=(const ap_private& RHS) { + if (this != &RHS) + memcpy(pVal, RHS.pVal, _AP_N * APINT_WORD_SIZE); + return *this; + } + INLINE ap_private& operator=(const volatile ap_private& RHS) { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + /// @} + /// @name Unary Operators + /// @{ + /// @returns a new ap_private value representing *this incremented by one + /// @brief Postfix increment operator. + INLINE const ap_private operator++(int) { + ap_private API(*this); + ++(*this); + return API; + } + + /// @returns *this incremented by one + /// @brief Prefix increment operator. + INLINE ap_private& operator++() { + add_1(pVal, pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// @returns a new ap_private representing *this decremented by one. + /// @brief Postfix decrement operator. + INLINE const ap_private operator--(int) { + ap_private API(*this); + --(*this); + return API; + } + + /// @returns *this decremented by one. + /// @brief Prefix decrement operator. + INLINE ap_private& operator--() { + sub_1(pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// Performs a bitwise complement operation on this ap_private. + /// @returns an ap_private that is the bitwise complement of *this + /// @brief Unary bitwise complement operator. + INLINE ap_private operator~() const { + ap_private Result(*this); + Result.flip(); + return Result; + } + + /// Negates *this using two's complement logic. + /// @returns An ap_private value representing the negation of *this. + /// @brief Unary negation operator + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + /// Performs logical negation operation on this ap_private. + /// @returns true if *this is zero, false otherwise. + /// @brief Logical negation operator. + INLINE bool operator !() const { + for (uint32_t i = 0; i < _AP_N; ++i) + if (pVal[i]) + return false; + return true; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator&(RHS); + } + template + INLINE ap_private Or(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator|(RHS); + } + template + ap_private Xor(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator^(RHS); + } + + ap_private Mul(const ap_private& RHS) const { + ap_private Result(*this); + Result *= RHS; + return Result; + } + + ap_private Add(const ap_private& RHS) const { + ap_private Result(0); + bool carry = add(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + ap_private Sub(const ap_private& RHS) const { + ap_private Result(0); + sub(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + /// Arithmetic right-shift this ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + ap_private ashr(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + // Handle a degenerate case + if (shiftAmt == 0) + return *this; + + // Handle single word shifts with built-in ashr + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(/*BitWidth, 0*/); // undefined + else { + uint32_t SignBit = APINT_BITS_PER_WORD - BitWidth; + return ap_private(/*BitWidth,*/ + (((int64_t(VAL) << (SignBit)) >> (SignBit)) >> (shiftAmt))); + } + } + + // If all the bits were shifted out, the result is, technically, undefined. + // We return -1 if it was negative, 0 otherwise. We check this early to avoid + // issues in the algorithm below. + if (shiftAmt == BitWidth) { + if (isNegative()) + return ap_private(-1); + else + return ap_private(0); + } + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // Compute some values needed by the following shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; // bits to shift per word + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; // word offset for shift + uint32_t breakWord = _AP_N - 1 - offset; // last word affected + uint32_t bitsInWord = whichBit(BitWidth); // how many bits in last word? + if (bitsInWord == 0) + bitsInWord = APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + // Move the words containing significant bits + for (uint32_t i = 0; i <= breakWord; ++i) + val[i] = pVal[i+offset]; // move whole word + + // Adjust the top significant word for sign bit fill, if negative + if (isNegative()) + if (bitsInWord < APINT_BITS_PER_WORD) + val[breakWord] |= ~0ULL << (bitsInWord); // set high bits + } else { + // Shift the low order words + for (uint32_t i = 0; i < breakWord; ++i) { + // This combines the shifted corresponding word with the low bits from + // the next word (shifted into this word's high bits). + val[i] = ((pVal[i+offset]) >> (wordShift)); + val[i] |= ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + } + + // Shift the break word. In this case there are no bits from the next word + // to include in this word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Deal with sign extenstion in the break word, and possibly the word before + // it. + if (isNegative()) { + if (wordShift > bitsInWord) { + if (breakWord > 0) + val[breakWord-1] |= + ~0ULL << (APINT_BITS_PER_WORD - (wordShift - bitsInWord)); + val[breakWord] |= ~0ULL; + } else + val[breakWord] |= (~0ULL << (bitsInWord - wordShift)); + } + } + + // Remaining words are 0 or -1, just assign them. + uint64_t fillValue = (isNegative() ? ~0ULL : 0); + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = fillValue; + Retval.clearUnusedBits(); + return Retval; + } + + /// Logical right-shift this ap_private by shiftAmt. + /// @brief Logical right-shift function. + ap_private lshr(uint32_t shiftAmt) const { + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); + else + return ap_private((this->VAL) >> (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids + // issues with shifting byt he size of the integer type, which produces + // undefined results in the code below. This is also an optimization. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // If we are shifting less than a word, compute the shift with a simple carry + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (int i = _AP_N-1; i >= 0; --i) { + val[i] = ((pVal[i]) >> (shiftAmt)) | carry; + carry = (pVal[i]) << (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < _AP_N - offset; ++i) + val[i] = pVal[i+offset]; + for (uint32_t i = _AP_N-offset; i < _AP_N; i++) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + // Shift the low order words + uint32_t breakWord = _AP_N - offset -1; + for (uint32_t i = 0; i < breakWord; ++i) + val[i] = ((pVal[i+offset]) >> (wordShift)) | + ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + // Shift the break word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Remaining words are 0 + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + /// Left-shift this ap_private by shiftAmt. + /// @brief Left-shift function. + ap_private shl(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); // avoid undefined shift results + return ap_private((VAL) << (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids a + // lshr by the words size in the loop below which can produce incorrect + // results. It also avoids the expensive computation below for a common case. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t* val = Retval.pVal; + // If we are shifting less than a word, do it the easy way + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (uint32_t i = 0; i < _AP_N; i++) { + val[i] = ((pVal[i]) << (shiftAmt)) | carry; + carry = (pVal[i]) >> (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < offset; i++) + val[i] = 0; + for (uint32_t i = offset; i < _AP_N; i++) + val[i] = pVal[i-offset]; + Retval.clearUnusedBits(); + return Retval; + } + + // Copy whole words from this to Result. + uint32_t i = _AP_N - 1; + for (; i > offset; --i) + val[i] = (pVal[i-offset]) << (wordShift) | + (pVal[i-offset-1]) >> (APINT_BITS_PER_WORD - wordShift); + val[offset] = (pVal[0]) << (wordShift); + for (i = 0; i < offset; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + INLINE ap_private rotl(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + hi.shl(rotateAmt); + lo.lshr(BitWidth - rotateAmt); + return hi | lo; + } + + INLINE ap_private rotr(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + lo.lshr(rotateAmt); + hi.shl(BitWidth - rotateAmt); + return hi | lo; + } + + /// Perform an unsigned divide operation on this ap_private by RHS. Both this and + /// RHS are treated as unsigned quantities for purposes of this division. + /// @returns a new ap_private value containing the division result + /// @brief Unsigned division operation. + ap_private udiv(const ap_private& RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + + // First, deal with the easy case + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Divide by zero?"); + return ap_private(VAL / RHS.VAL); + } + + // Get some facts about the LHS and RHS number of bits and words + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Divided by zero???"); + uint32_t lhsBits = this->getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Deal with some degenerate cases + if (!lhsWords) + // 0 / X ===> 0 + return ap_private(0); + else if (lhsWords < rhsWords || this->ult(RHS)) { + // X / Y ===> 0, iff X < Y + return ap_private(0); + } else if (*this == RHS) { + // X / X ===> 1 + return ap_private(1); + } else if (lhsWords == 1 && rhsWords == 1) { + // All high words are zero, just use native divide + return ap_private(this->pVal[0] / RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Quotient(0); // to hold result. + divide(*this, lhsWords, RHS, rhsWords, &Quotient, (ap_private*)0); + return Quotient; + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(const ap_private& RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Perform an unsigned remainder operation on this ap_private with RHS being the + /// divisor. Both this and RHS are treated as unsigned quantities for purposes + /// of this operation. Note that this is a true remainder operation and not + /// a modulo operation because the sign follows the sign of the dividend + /// which is *this. + /// @returns a new ap_private value containing the remainder result + /// @brief Unsigned remainder operation. + ap_private urem(const ap_private& RHS) const { + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Remainder by zero?"); + return ap_private(VAL % RHS.VAL); + } + + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Get some facts about the RHS + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, rhsWords, (ap_private*)(0), &Remainder); + return Remainder; + } + + ap_private urem(uint64_t RHS) const { + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + // Get some facts about the RHS + uint32_t rhsBits = 64 - CountLeadingZeros_64(RHS); // RHS.getActiveBits(); + uint32_t rhsWords = 1;//!rhsBits ? 0 : (ap_private<_AP_W, _AP_S, _AP_N>::whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, (ap_private*)(0), &Remainder); + return Remainder; + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(const ap_private& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + /// Sometimes it is convenient to divide two ap_private values and obtain both + /// the quotient and remainder. This function does both operations in the + /// same computation making it a little more efficient. + /// @brief Dual division/remainder interface. + static void udivrem(const ap_private& LHS, const ap_private& RHS, ap_private &Quotient, ap_private& Remainder) { + // Get some size facts about the dividend and divisor + uint32_t lhsBits = LHS.getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (ap_private::whichWord(lhsBits - 1) + 1); + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (ap_private::whichWord(rhsBits - 1) + 1); + + // Check the degenerate cases + if (lhsWords == 0) { + Quotient = 0; // 0 / Y ===> 0 + Remainder = 0; // 0 % Y ===> 0 + return; + } + + if (lhsWords < rhsWords || LHS.ult(RHS)) { + Quotient = 0; // X / Y ===> 0, iff X < Y + Remainder = LHS; // X % Y ===> X, iff X < Y + return; + } + + if (LHS == RHS) { + Quotient = 1; // X / X ===> 1 + Remainder = 0; // X % X ===> 0; + return; + } + + if (lhsWords == 1 && rhsWords == 1) { + // There is only one word to consider so use the native versions. + if (LHS.isSingleWord()) { + Quotient = ap_private(LHS.VAL / RHS.VAL); + Remainder = ap_private(LHS.VAL % RHS.VAL); + } else { + Quotient = ap_private(LHS.pVal[0] / RHS.pVal[0]); + Remainder = ap_private(LHS.pVal[0] % RHS.pVal[0]); + } + return; + } + + // Okay, lets do it the long way + divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder); + } + + static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + /// Compares this ap_private with RHS for the validity of the equality + /// relationship. + /// @returns true if *this == Val + /// @brief Equality comparison. + template + INLINE bool eq(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return (*this) == RHS; + } + + /// Compares this ap_private with RHS for the validity of the inequality + /// relationship. + /// @returns true if *this != Val + /// @brief Inequality comparison + template + INLINE bool ne(const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template + INLINE bool ult(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS.pVal[0]; + + // Otherwise, compare all words + uint32_t topWord = whichWord(AESL_std::max(n1,n2)-1); + for (int i = topWord; i >= 0; --i) { + if (pVal[i] > RHS.pVal[i]) + return false; + if (pVal[i] < RHS.pVal[i]) + return true; + } + return false; + } + + INLINE bool ult(uint64_t RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = 64 - CountLeadingZeros_64(RHS); //RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS; + assert(0); + } + + template + INLINE bool slt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + ap_private lhs(*this); + ap_private<_AP_W, _AP_S1, _AP_N> rhs(RHS); + bool lhsNeg = isNegative(); + bool rhsNeg = rhs.isNegative(); + if (lhsNeg) { + // Sign bit is set so perform two's complement to make it positive + lhs.flip(); + lhs++; + } + if (rhsNeg) { + // Sign bit is set so perform two's complement to make it positive + rhs.flip(); + rhs++; + } + + // Now we have unsigned values to compare so do the comparison if necessary + // based on the negativeness of the values. + if (lhsNeg) + if (rhsNeg) + return lhs.ugt(rhs); + else + return true; + else if (rhsNeg) + return false; + else + return lhs.ult(rhs); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template + INLINE bool ule(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template + INLINE bool sle(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template + INLINE bool ugt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template + INLINE bool sgt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template + INLINE bool uge(const ap_private<_AP_W, _AP_S, _AP_N>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template + INLINE bool sge(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS); + } + + template + void cpTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 > BitWidth && "Invalid ap_private Truncate request"); + assert(_AP_W1 >= MIN_INT_BITS && "Can't truncate to 0 bits"); + memcpy(pVal, that.pVal, _AP_N*APINT_WORD_SIZE); + } + + // Sign extend to a new width. + template + void cpSext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private SignExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + // If the sign bit isn't set, this is the same as zext. + if (!that.isNegative()) { + cpZext(that); + return; + } + + // The sign bit is set. First, get some facts + enum { wordBits = _AP_W1 % APINT_BITS_PER_WORD}; + + // Mask the high order word appropriately + if (_AP_N1 == _AP_N) { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + if (_AP_N1 == 1) { + assert(0); + } else { + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + return; + } + } + + if (_AP_N1 == 1) { + assert(0);// newVal[0] = VAL | mask; + } else { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + } + for (uint32_t i=_AP_N1; i < _AP_N-1; i++) + pVal[i] = ~0ULL; + pVal[_AP_N-1] = ~0ULL; + clearUnusedBits(); + return; + } + + // Zero extend to a new width. + template + void cpZext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private ZeroExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + uint32_t wordsAfter = _AP_N; + if (wordsAfter==1) { + assert(0); // return ap_private<_AP_W1, _AP_S, _AP_N1> (_AP_W1, VAL, _AP_S); + } else { + if (_AP_N1 == 1) { + assert(0); + // newVal[0] = VAL; + } else { + uint32_t i = 0; + for (; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + for (; i < _AP_N; ++i) + pVal[i] = 0; + } + } + clearUnusedBits(); + } + + template + void cpZextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpZext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i]=that.pVal[i]; + clearUnusedBits(); + } + } + + template + void cpSextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpSext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i] = that.pVal[i]; + clearUnusedBits(); + } + } + + /// @name Value Characterization Functions + /// @{ + + /// @returns the total number of bits. + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + /// Here one word's bitwidth equals to that of uint64_t. + /// @returns the number of words to hold the integer value of this ap_private. + /// @brief Get the number of words. + INLINE uint32_t getNumWords() const { + return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; + } + + /// This function returns the number of active bits which is defined as the + /// bit width minus the number of leading zeros. This is used in several + /// computations to see how "wide" the value is. + /// @brief Compute the number of active bits in the value + INLINE uint32_t getActiveBits() const { + uint32_t bits=BitWidth - countLeadingZeros(); + return bits?bits:1; + } + + + /// This method attempts to return the value of this ap_private as a zero extended + /// uint64_t. The bitwidth must be <= 64 or the value must fit within a + /// uint64_t. Otherwise an assertion will result. + /// @brief Get zero extended value + INLINE uint64_t getZExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for uint64_t"); + return *pVal; + } + + /// This method attempts to return the value of this ap_private as a sign extended + /// int64_t. The bit width must be <= 64 or the value must fit within an + /// int64_t. Otherwise an assertion will result. + /// @brief Get sign extended value + INLINE int64_t getSExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for int64_t"); + return int64_t(pVal[0]); + } + + /// This method determines how many bits are required to hold the ap_private + /// equivalent of the string given by \p str of length \p slen. + /// @brief Get bits required for string value. + static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix); + + /// countLeadingZeros - This function is an ap_private version of the + /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number + /// of zeros from the most significant bit to the first one bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the most significant bit to the first + /// one bits. + INLINE uint32_t countLeadingZeros() const ; + + /// countLeadingOnes - This function counts the number of contiguous 1 bits + /// in the high order bits. The count stops when the first 0 bit is reached. + /// @returns 0 if the high order bit is not set + /// @returns the number of 1 bits from the most significant to the least + /// @brief Count the number of leading one bits. + INLINE uint32_t countLeadingOnes() const ; + + /// countTrailingZeros - This function is an ap_private version of the + /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts + /// the number of zeros from the least significant bit to the first set bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the least significant bit to the first + /// one bit. + /// @brief Count the number of trailing zero bits. + INLINE uint32_t countTrailingZeros() const ; + + /// countPopulation - This function is an ap_private version of the + /// countPopulation_{32,64} functions in MathExtras.h. It counts the number + /// of 1 bits in the ap_private value. + /// @returns 0 if the value is zero. + /// @returns the number of set bits. + /// @brief Count the number of bits set. + INLINE uint32_t countPopulation() const { + uint32_t Count = 0; + for (uint32_t i = 0; i<_AP_N-1 ; ++i) + Count += CountPopulation_64(pVal[i]); + Count += CountPopulation_64(pVal[_AP_N-1]&mask); + return Count; + } + + /// @} + /// @name Conversion Functions + /// @{ + + /// This is used internally to convert an ap_private to a string. + /// @brief Converts an ap_private to a std::string + INLINE std::string toString(uint8_t radix, bool wantSigned) const + ; + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + + /// @returns a byte-swapped representation of this ap_private Value. + INLINE ap_private byteSwap() const ; + + /// @brief Converts this ap_private to a double value. + INLINE double roundToDouble(bool isSigned) const ; + + /// @brief Converts this unsigned ap_private to a double value. + INLINE double roundToDouble() const { + return roundToDouble(false); + } + + /// @brief Converts this signed ap_private to a double value. + INLINE double signedRoundToDouble() const { + return roundToDouble(true); + } + + /// The conversion does not do a translation from integer to double, it just + /// re-interprets the bits as a double. Note that it is valid to do this on + /// any bit width. Exactly 64 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE double bitsToDouble() const { + union { + uint64_t __I; + double __D; + } __T; + __T.__I = pVal[0]; + return __T.__D; + } + + /// The conversion does not do a translation from integer to float, it just + /// re-interprets the bits as a float. Note that it is valid to do this on + /// any bit width. Exactly 32 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE float bitsToFloat() const { + union { + uint32_t __I; + float __F; + } __T; + __T.__I = uint32_t(pVal[0]); + return __T.__F; + } + + /// The conversion does not do a translation from double to integer, it just + /// re-interprets the bits of the double. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a double to ap_private bits. + INLINE ap_private& doubleToBits(double __V) { + union { + uint64_t __I; + double __D; + } __T; + __T.__D = __V; + pVal[0] = __T.__I; + return *this; + } + + /// The conversion does not do a translation from float to integer, it just + /// re-interprets the bits of the float. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a float to ap_private bits. + INLINE ap_private& floatToBits(float __V) { + union { + uint32_t __I; + float __F; + } __T; + __T.__F = __V; + pVal[0] = __T.__I; + } + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return isMaxValue(); + } + + INLINE bool nand_reduce() const { + return isMinValue(); + } + + INLINE bool or_reduce() const { + return (bool)countPopulation(); + } + + INLINE bool nor_reduce() const { + return countPopulation()==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + INLINE std::string to_string(uint8_t radix=16, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; + +template +INLINE bool operator==(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 == V1; +} + +template +INLINE bool operator!=(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 != V1; +} + +namespace ap_private_ops { + enum {APINT_BITS_PER_WORD=64}; + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.slt(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.sgt(RHS) ? LHS : RHS; + } + + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ult(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be unsigned. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ugt(RHS) ? LHS : RHS; + } + + /// @brief Check if the specified ap_private has a N-bits integer value. + template + INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); + } + + /// @returns true if the argument ap_private value is a sequence of ones + /// starting at the least significant bit with the remainder zero. + template + INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; + } + + /// @returns true if the argument ap_private value contains a sequence of ones + /// with the remainder zero. + template + INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); + } + + /// @returns a byte-swapped representation of the specified ap_private Value. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> byteSwap(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.byteSwap(); + } + + /// @returns the floor log base 2 of the specified ap_private value. + template INLINE uint32_t logBase2(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.logBase2(); + } + + /// GreatestCommonDivisor - This function returns the greatest common + /// divisor of the two ap_private values using Enclid's algorithm. + /// @returns the greatest common divisor of Val1 and Val2 + /// @brief Compute GCD of two ap_private values. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& Val1, const ap_private<_AP_W, _AP_S, _AP_N>& Val2) + ; + + /// Treats the ap_private as an unsigned value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double Roundap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.roundToDouble(); + } + + /// Treats the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double RoundSignedap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.signedRoundToDouble(); + } + + /// @brief Converts the given ap_private to a float vlalue. + template INLINE float Roundap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(Roundap_privateToDouble(APIVal)); + } + + /// Treast the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a float value. + template INLINE float RoundSignedap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(APIVal.signedRoundToDouble()); + } + + /// RoundDoubleToap_private - This function convert a double value to an ap_private value. + /// @brief Converts the given double value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundDoubleToap_private(double Double, uint32_t width) ; + + /// RoundFloatToap_private - Converts a float value into an ap_private value. + /// @brief Converts a float value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundFloatToap_private(float Float, uint32_t width) { + return RoundDoubleToap_private<_AP_W, _AP_S, _AP_N>(double(Float), width); + } + + /// Arithmetic right-shift the ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> ashr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.ashr(shiftAmt); + } + + /// Logical right-shift the ap_private by shiftAmt. + /// @brief Logical right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.lshr(shiftAmt); + } + + /// Left-shift the ap_private by shiftAmt. + /// @brief Left-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.shl(shiftAmt); + } + + /// Signed divide ap_private LHS by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sdiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.sdiv(RHS); + } + + /// Unsigned divide ap_private LHS by ap_private RHS. + /// @brief Unsigned division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> udiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.udiv(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> srem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.srem(RHS); + } + + /// Unsigned remainder operation on ap_private. + /// @brief Function for unsigned remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> urem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.urem(RHS); + } + + /// Performs multiplication on ap_private values. + /// @brief Function for multiplication operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> mul(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS * RHS; + } + + /// Performs addition on ap_private values. + /// @brief Function for addition operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> add(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS + RHS; + } + + /// Performs subtraction on ap_private values. + /// @brief Function for subtraction operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sub(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS - RHS; + } + + /// Performs bitwise AND operation on ap_private LHS and + /// ap_private RHS. + /// @brief Bitwise AND function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS & RHS; + } + + /// Performs bitwise OR operation on ap_private LHS and ap_private RHS. + /// @brief Bitwise OR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Or(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS | RHS; + } + + /// Performs bitwise XOR operation on ap_private. + /// @brief Bitwise XOR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Xor(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS ^ RHS; + } + + /// Performs a bitwise complement operation on ap_private. + /// @brief Bitwise complement function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> Not(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return ~APIVal; + } + + template void clearUnusedBits(uint64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(uint64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + template void clearUnusedBits(int64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(int64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + // template + template + INLINE ap_private<_AP_W, _AP_S> ashr(const ap_private<_AP_W, _AP_S>& a) { + return ashr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S>& a) { + return lshr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, true> ashr(const ap_private<_AP_W, true, 1>& a) { + enum {APINT_BITS_PER_WORD=64, excess_bits=APINT_BITS_PER_WORD-_AP_W}; + static const uint64_t sign_bit = (1ULL<<(_AP_W-1)); + static const uint64_t sign_ext_mask = (_AP_W-shiftAmt>0)?~0ULL<<(APINT_BITS_PER_WORD-_AP_W+shiftAmt):~0ULL; + return ap_private<_AP_W, true>((((int64_t)a.VAL) >> (shiftAmt)) | (a.VAL & sign_bit? sign_ext_mask : 0ULL)); + } + + template + INLINE ap_private<_AP_W, false> ashr(const ap_private<_AP_W, false, 1>& a) { + return ap_private<_AP_W, false>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~0ULL<<_AP_W; + return ap_private<_AP_W, _AP_S>((a.VAL&mask) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W-shiftAmt, _AP_S> shr(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W-shiftAmt, _AP_S>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W+shiftAmt, _AP_S> shl(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W+shiftAmt, _AP_S>((a.VAL) << (shiftAmt)); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S, 1>& a) { + unsigned shift = (index%APINT_BITS_PER_WORD); + static const uint64_t mask=1ULL << (shift); + return ((mask & a.VAL) != 0); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S>& a) { + static const uint64_t mask=1ULL << (index&0x3f); + return ((mask & a.pVal[(index)>>6]) != 0); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.VAL |= mask; + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~(~0ULL >> (lsb) <<(APINT_BITS_PER_WORD-msb+lsb-1) >> (APINT_BITS_PER_WORD-msb-1)); + a.VAL &= mask; + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word==lsb_word) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[msb_word] |= mask; + } else { + const uint64_t lsb_mask = ~0ULL >> (lsb) << (lsb); + const uint64_t msb_mask = ~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[lsb_word] |=lsb_mask; + for (int i=lsb_word+1; i + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word == lsb_word) { + const uint64_t mask = ~(~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[msb_word] &= mask; + } else { + const uint64_t lsb_mask = ~(~0ULL >> (lsb) << (lsb)); + const uint64_t msb_mask = ~(~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[lsb_word] &=lsb_mask; + for (int i=lsb_word+1; i + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=1ULL << (index); + a.VAL |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=~(1ULL << (index)); + a.VAL &= mask; + a.clearUnusedBits(); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=1ULL << (index%APINT_BITS_PER_WORD); + a.pVal[word] |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=~(1ULL << (index%APINT_BITS_PER_WORD)); + a.pVal[word] &= mask; + a.clearUnusedBits(); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, false>& a) { + return false; + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true, 1>& a) { + static const uint64_t sign_mask = (1ULL << (_AP_W-1)); + return ((sign_mask & a.VAL) != 0); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true>& a) { + enum {APINT_BITS_PER_WORD=64,_AP_N=(_AP_W+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + static const uint64_t sign_mask = (1ULL << (_AP_W%APINT_BITS_PER_WORD-1)); + return sign_mask & a.pVal[_AP_N-1]; + } +} // End of ap_private_ops namespace + +/// @brief Check if the specified ap_private has a N-bits integer value. +template +INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); +} + +/// @returns true if the argument ap_private value is a sequence of ones +/// starting at the least significant bit with the remainder zero. +template +INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; +} + +/// @returns true if the argument ap_private value contains a sequence of ones +/// with the remainder zero. +template +INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); +} + +#if 0 +/// add_1 - This function adds a single "digit" integer, y, to the multiple +/// "digit" integer array, x[]. x[] is modified to reflect the addition and +/// 1 is returned if there is a carry out, otherwise 0 is returned. +/// @returns the carry of the addition. +static bool add_1(uint64_t dest[], uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + dest[i] = y + x[i]; + if (dest[i] < y) + y = 1; // Carry one to next digit. + else { + y = 0; // No need to carry so exit early + break; + } + } + return (y != 0); +} +#endif + +#if 0 +/// add - This function adds the integer array x to the integer array Y and +/// places the result in dest. +/// @returns the carry out from the addition +/// @brief General addition of 64-bit integer arrays +static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool carry = false; + uint32_t len = AESL_std::min(xlen, ylen); + uint32_t i; + for (i = 0; i< len && i < destlen; ++i) { + uint64_t limit = AESL_std::min(x[i],y[i]); // must come first in case dest == x + dest[i] = x[i] + y[i] + carry; + carry = dest[i] < limit || (carry && dest[i] == limit); + } + if (xlen > ylen) { + const uint64_t yext = xsigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t limit = AESL_std::min(x[i], yext); + dest[i] = x[i] + yext + carry; + carry = (dest[i] < limit)||(carry && dest[i] == x[i]); + } + } else if (ylen> xlen) { + const uint64_t xext = ysigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t limit = AESL_std::min(xext, y[i]); + dest[i] = xext + y[i] + carry; + carry = (dest[i] < limit)||(carry && dest[i] == y[i]); + } + } + return carry; +} +#endif + +#if 0 +/// @returns returns the borrow out. +/// @brief Generalized subtraction of 64-bit integer arrays. +static bool sub(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool borrow = false; + uint32_t i; + uint32_t len = AESL_std::min(xlen, ylen); + for (i = 0; i < len && i < destlen; ++i) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = y[i] > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - y[i]; + } + if (xlen > ylen) { + const uint64_t yext = ysigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = yext > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - yext; + } + } else if (ylen> xlen) { + const uint64_t xext = xsigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t x_tmp = borrow ? xext - 1 : xext; + borrow = y[i] > x_tmp || (borrow && xext==0); + dest[i] = x_tmp - y[i]; + } + } + return borrow; +} +#endif + +/// Subtracts the RHS ap_private from this ap_private +/// @returns this, after subtraction +/// @brief Subtraction assignment operator. + +#if 0 +/// Multiplies an integer array, x by a a uint64_t integer and places the result +/// into dest. +/// @returns the carry out of the multiplication. +/// @brief Multiply a multi-digit ap_private by a single digit (64-bit) integer. +static uint64_t mul_1(uint64_t dest[], const uint64_t x[], uint32_t len, uint64_t y) { + // Split y into high 32-bit part (hy) and low 32-bit part (ly) + uint64_t ly = y & 0xffffffffULL, hy = (y) >> 32; + uint64_t carry = 0; + static const uint64_t two_power_32 = 1ULL << 32; + // For each digit of x. + for (uint32_t i = 0; i < len; ++i) { + // Split x into high and low words + uint64_t lx = x[i] & 0xffffffffULL; + uint64_t hx = (x[i]) >> 32; + // hasCarry - A flag to indicate if there is a carry to the next digit. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + dest[i] = carry + lx * ly; + // Determine if the add above introduces carry. + hasCarry = (dest[i] < carry) ? 1 : 0; + carry = hx * ly + ((dest[i]) >> 32) + (hasCarry ? two_power_32 : 0); + // The upper limit of carry can be (2^32 - 1)(2^32 - 1) + + // (2^32 - 1) + 2^32 = 2^64. + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + + carry += (lx * hy) & 0xffffffffULL; + dest[i] = ((carry) << 32) | (dest[i] & 0xffffffffULL); + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? two_power_32 : 0) + + ((carry) >> 32) + ((lx * hy) >> 32) + hx * hy; + } + return carry; +} +#endif + +#if 0 +/// Multiplies integer array x by integer array y and stores the result into +/// the integer array dest. Note that dest's size must be >= xlen + ylen. +/// @brief Generalized multiplicate of integer arrays. +static void mul(uint64_t dest[], const uint64_t x[], uint32_t xlen, const uint64_t y[], + uint32_t ylen, uint32_t destlen) { + dest[xlen] = mul_1(dest, x, xlen, y[0]); + for (uint32_t i = 1; i < ylen; ++i) { + uint64_t ly = y[i] & 0xffffffffULL, hy = (y[i]) >> 32; + uint64_t carry = 0, lx = 0, hx = 0; + for (uint32_t j = 0; j < xlen; ++j) { + lx = x[j] & 0xffffffffULL; + hx = (x[j]) >> 32; + // hasCarry - A flag to indicate if has carry. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + uint64_t resul = carry + lx * ly; + hasCarry = (resul < carry) ? 1 : 0; + carry = (hasCarry ? (1ULL << 32) : 0) + hx * ly + ((resul) >> 32); + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + carry += (lx * hy) & 0xffffffffULL; + resul = ((carry) << 32) | (resul & 0xffffffffULL); + dest[i+j] += resul; + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0)+ + ((carry) >> 32) + (dest[i+j] < resul ? 1 : 0) + + ((lx * hy) >> 32) + hx * hy; + } + dest[i+xlen] = carry; + } +} +#endif + + + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + assert(str != 0 && "Invalid value string"); + assert(slen > 0 && "Invalid string length"); + + // Each computation below needs to know if its negative + uint32_t isNegative = str[0] == '-'; + if (isNegative) { + slen--; + str++; + } + // For radixes of power-of-two values, the bits required is accurately and + // easily computed + if (radix == 2) + return slen + isNegative; + if (radix == 8) + return slen * 3 + isNegative; + if (radix == 16) + return slen * 4 + isNegative; + + // Otherwise it must be radix == 10, the hard case + assert(radix == 10 && "Invalid radix"); + + // Convert to the actual binary value. + //ap_private<_AP_W, _AP_S, _AP_N> tmp(sufficient, str, slen, radix); + + // Compute how many bits are required. + //return isNegative + tmp.logBase2() + 1; + return isNegative + slen * 4; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingZeros() const { + enum { msw_bits = (BitWidth % APINT_BITS_PER_WORD)?(BitWidth % APINT_BITS_PER_WORD):APINT_BITS_PER_WORD, + excessBits = APINT_BITS_PER_WORD - msw_bits }; + uint32_t Count = CountLeadingZeros_64(pVal[_AP_N-1]); + if (Count>=excessBits) + Count -= excessBits; + if (!pVal[_AP_N-1]) { + for (uint32_t i = _AP_N-1 ; i ; --i) { + if (!pVal[i-1]) + Count += APINT_BITS_PER_WORD; + else { + Count += CountLeadingZeros_64(pVal[i-1]); + break; + } + } + } + return Count; +} + +static uint32_t countLeadingOnes_64(uint64_t __V, uint32_t skip) { + uint32_t Count = 0; + if (skip) + (__V) <<= (skip); + while (__V && (__V & (1ULL << 63))) { + Count++; + (__V) <<= 1; + } + return Count; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingOnes() const { + if (isSingleWord()) + return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth); + + uint32_t highWordBits = BitWidth % APINT_BITS_PER_WORD; + uint32_t shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits); + int i = _AP_N - 1; + uint32_t Count = countLeadingOnes_64(pVal[i], shift); + if (Count == highWordBits) { + for (i--; i >= 0; --i) { + if (pVal[i] == ~0ULL) + Count += APINT_BITS_PER_WORD; + else { + Count += countLeadingOnes_64(pVal[i], 0); + break; + } + } + } + return Count; +} + +template +INLINE uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countTrailingZeros() const { + if (isSingleWord()) + return AESL_std::min(uint32_t(CountTrailingZeros_64(VAL)), BitWidth); + uint32_t Count = 0; + uint32_t i = 0; + for (; i < _AP_N && pVal[i] == 0; ++i) + Count += APINT_BITS_PER_WORD; + if (i < _AP_N) + Count += CountTrailingZeros_64(pVal[i]); + return AESL_std::min(Count, BitWidth); +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::byteSwap() const { + assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!"); + if (BitWidth == 16) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_16(uint16_t(VAL))); + else if (BitWidth == 32) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_32(uint32_t(VAL))); + else if (BitWidth == 48) { + uint32_t Tmp1 = uint32_t((VAL) >> 16); + Tmp1 = ByteSwap_32(Tmp1); + uint16_t Tmp2 = uint16_t(VAL); + Tmp2 = ByteSwap_16(Tmp2); + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ((uint64_t(Tmp2)) << 32) | Tmp1); + } else if (BitWidth == 64) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_64(VAL)); + else { + ap_private<_AP_W, _AP_S, _AP_N> Result(0); + char *pByte = (char*)Result.pVal; + for (uint32_t i = 0; i < BitWidth / APINT_WORD_SIZE / 2; ++i) { + char Tmp = pByte[i]; + pByte[i] = pByte[BitWidth / APINT_WORD_SIZE - 1 - i]; + pByte[BitWidth / APINT_WORD_SIZE - i - 1] = Tmp; + } + return Result; + } +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& API1, const ap_private<_AP_W, _AP_S, _AP_N>& API2) { + ap_private<_AP_W, _AP_S, _AP_N> __A = API1, __B = API2; + while (!!__B) { + ap_private<_AP_W, _AP_S, _AP_N> __T = __B; + __B = ap_private_ops::urem(__A, __B); + __A = __T; + } + return __A; +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::RoundDoubleToap_private(double Double, uint32_t width) { + union { + double __D; + uint64_t __I; + } __T; + __T.__D = Double; + + // Get the sign bit from the highest order bit + bool isNeg = (__T.__I) >> 63; + + // Get the 11-bit exponent and adjust for the 1023 bit bias + int64_t exp = (((__T.__I) >> 52) & 0x7ffULL) - 1023; + + // If the exponent is negative, the value is < 0 so just return 0. + if (exp < 0) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0u); + + // Extract the mantissa by clearing the top 12 bits (sign + exponent). + uint64_t mantissa = (__T.__I & (~0ULL >> 12)) | 1ULL << 52; + + // If the exponent doesn't shift all bits out of the mantissa + if (exp < 52) + return isNeg ? -ap_private<_AP_W, _AP_S, _AP_N>(width, (mantissa) >> (52 - exp)) : + ap_private<_AP_W, _AP_S, _AP_N>((mantissa) >> (52 - exp)); + + // If the client didn't provide enough bits for us to shift the mantissa into + // then the result is undefined, just return 0 + if (width <= exp - 52) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0); + + // Otherwise, we have to shift the mantissa bits up to the right location + ap_private<_AP_W, _AP_S, _AP_N> Tmp(width, mantissa); + Tmp = Tmp.shl(exp - 52); + return isNeg ? -Tmp : Tmp; +} + +/// RoundToDouble - This function convert this ap_private to a double. +/// The layout for double is as following (IEEE Standard 754): +/// -------------------------------------- +/// | Sign Exponent Fraction Bias | +/// |-------------------------------------- | +/// | 1[63] 11[62-52] 52[51-00] 1023 | +/// -------------------------------------- +template +double ap_private<_AP_W, _AP_S, _AP_N>::roundToDouble(bool isSigned) const { + + // Handle the simple case where the value is contained in one uint64_t. + if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) { + uint64_t val; + if (isSingleWord()) val = VAL; + else val = pVal[0]; + if (isSigned) { + int64_t sext = ((int64_t(val)) << (64-BitWidth)) >> (64-BitWidth); + return double(sext); + } else + return double(val); + } + + // Determine if the value is negative. + bool isNeg = isSigned ? (*this)[BitWidth-1] : false; + + // Construct the absolute value if we're negative. + ap_private<_AP_W, _AP_S, _AP_N> Tmp(isNeg ? -(*this) : (*this)); + + // Figure out how many bits we're using. + uint32_t n = Tmp.getActiveBits(); + + // The exponent (without bias normalization) is just the number of bits + // we are using. Note that the sign bit is gone since we constructed the + // absolute value. + uint64_t exp = n; + + // Return infinity for exponent overflow + if (exp > 1023) { + if (!isSigned || !isNeg) + return std::numeric_limits::infinity(); + else + return -std::numeric_limits::infinity(); + } + exp += 1023; // Increment for 1023 bias + + // Number of bits in mantissa is 52. To obtain the mantissa value, we must + // extract the high 52 bits from the correct words in pVal. + uint64_t mantissa; + unsigned hiWord = whichWord(n-1); + if (hiWord == 0) { + mantissa = Tmp.pVal[0]; + if (n > 52) + (mantissa) >>= (n - 52); // shift down, we want the top 52 bits. + } else { + assert(hiWord > 0 && "High word is negative?"); + uint64_t hibits = (Tmp.pVal[hiWord]) << (52 - n % APINT_BITS_PER_WORD); + uint64_t lobits = (Tmp.pVal[hiWord-1]) >> (11 + n % APINT_BITS_PER_WORD); + mantissa = hibits | lobits; + } + + // The leading bit of mantissa is implicit, so get rid of it. + uint64_t sign = isNeg ? (1ULL << (APINT_BITS_PER_WORD - 1)) : 0; + union { + double __D; + uint64_t __I; + } __T; + __T.__I = sign | ((exp) << 52) | mantissa; + return __T.__D; +} + +// Square Root - this method computes and returns the square root of "this". +// Three mechanisms are used for computation. For small values (<= 5 bits), +// a table lookup is done. This gets some performance for common cases. For +// values using less than 52 bits, the value is converted to double and then +// the libc sqrt function is called. The result is rounded and then converted +// back to a uint64_t which is then used to construct the result. Finally, +// the Babylonian method for computing square roots is used. +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::sqrt() const { + + // Determine the magnitude of the value. + uint32_t magnitude = getActiveBits(); + + // Use a fast table for some small values. This also gets rid of some + // rounding errors in libc sqrt for small values. + if (magnitude <= 5) { + static const uint8_t results[32] = { + /* 0 */ 0, + /* 1- 2 */ 1, 1, + /* 3- 6 */ 2, 2, 2, 2, + /* 7-12 */ 3, 3, 3, 3, 3, 3, + /* 13-20 */ 4, 4, 4, 4, 4, 4, 4, 4, + /* 21-30 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 31 */ 6 + }; + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ results[ (isSingleWord() ? VAL : pVal[0]) ]); + } + + // If the magnitude of the value fits in less than 52 bits (the precision of + // an IEEE double precision floating point value), then we can use the + // libc sqrt function which will probably use a hardware sqrt computation. + // This should be faster than the algorithm below. + if (magnitude < 52) { +#ifdef _MSC_VER + // Amazingly, VC++ doesn't have round(). + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0]))) + 0.5); +#else + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0]))))); +#endif + } + + // Okay, all the short cuts are exhausted. We must compute it. The following + // is a classical Babylonian method for computing the square root. This code + // was adapted to APINt from a wikipedia article on such computations. + // See http://www.wikipedia.org/ and go to the page named + // Calculate_an_integer_square_root. + uint32_t nbits = BitWidth, i = 4; + ap_private<_AP_W, _AP_S, _AP_N> testy(16); + ap_private<_AP_W, _AP_S, _AP_N> x_old(/*BitWidth,*/ 1); + ap_private<_AP_W, _AP_S, _AP_N> x_new(0); + ap_private<_AP_W, _AP_S, _AP_N> two(/*BitWidth,*/ 2); + + // Select a good starting value using binary logarithms. + for (;; i += 2, testy = testy.shl(2)) + if (i >= nbits || this->ule(testy)) { + x_old = x_old.shl(i / 2); + break; + } + + // Use the Babylonian method to arrive at the integer square root: + for (;;) { + x_new = (this->udiv(x_old) + x_old).udiv(two); + if (x_old.ule(x_new)) + break; + x_old = x_new; + } + + // Make sure we return the closest approximation + // NOTE: The rounding calculation below is correct. It will produce an + // off-by-one discrepancy with results from pari/gp. That discrepancy has been + // determined to be a rounding issue with pari/gp as it begins to use a + // floating point representation after 192 bits. There are no discrepancies + // between this algorithm and pari/gp for bit widths < 192 bits. + ap_private<_AP_W, _AP_S, _AP_N> square(x_old * x_old); + ap_private<_AP_W, _AP_S, _AP_N> nextSquare((x_old + 1) * (x_old +1)); + if (this->ult(square)) + return x_old; + else if (this->ule(nextSquare)) { + ap_private<_AP_W, _AP_S, _AP_N> midpoint((nextSquare - square).udiv(two)); + ap_private<_AP_W, _AP_S, _AP_N> offset(*this - square); + if (offset.ult(midpoint)) + return x_old; + else + return x_old + 1; + } else + assert(0 && "Error in ap_private<_AP_W, _AP_S, _AP_N>::sqrt computation"); + return x_old + 1; +} + +/// Implementation of Knuth's Algorithm D (Division of nonnegative integers) +/// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The +/// variables here have the same names as in the algorithm. Comments explain +/// the algorithm and any deviation from it. +static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r, + uint32_t m, uint32_t n) { + assert(u && "Must provide dividend"); + assert(v && "Must provide divisor"); + assert(q && "Must provide quotient"); + assert(u != v && u != q && v != q && "Must us different memory"); + assert(n>1 && "n must be > 1"); + + // Knuth uses the value b as the base of the number system. In our case b + // is 2^31 so we just set it to -1u. + uint64_t b = uint64_t(1) << 32; + + //DEBUG(cerr << "KnuthDiv: m=" << m << " n=" << n << '\n'); + //DEBUG(cerr << "KnuthDiv: original:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of + // u and v by d. Note that we have taken Knuth's advice here to use a power + // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of + // 2 allows us to shift instead of multiply and it is easy to determine the + // shift amount from the leading zeros. We are basically normalizing the u + // and v so that its high bits are shifted to the top of v's range without + // overflow. Note that this can require an extra word in u so that u must + // be of length m+n+1. + uint32_t shift = CountLeadingZeros_32(v[n-1]); + uint32_t v_carry = 0; + uint32_t u_carry = 0; + if (shift) { + for (uint32_t i = 0; i < m+n; ++i) { + uint32_t u_tmp = (u[i]) >> (32 - shift); + u[i] = ((u[i]) << (shift)) | u_carry; + u_carry = u_tmp; + } + for (uint32_t i = 0; i < n; ++i) { + uint32_t v_tmp = (v[i]) >> (32 - shift); + v[i] = ((v[i]) << (shift)) | v_carry; + v_carry = v_tmp; + } + } + u[m+n] = u_carry; + //DEBUG(cerr << "KnuthDiv: normal:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + + // D2. [Initialize j.] Set j to m. This is the loop counter over the places. + int j = m; + do { + //DEBUG(cerr << "KnuthDiv: quotient digit #" << j << '\n'); + // D3. [Calculate q'.]. + // Set qp = (u[j+n]*b + u[j+n-1]) / v[n-1]. (qp=qprime=q') + // Set rp = (u[j+n]*b + u[j+n-1]) % v[n-1]. (rp=rprime=r') + // Now test if qp == b or qp*v[n-2] > b*rp + u[j+n-2]; if so, decrease + // qp by 1, inrease rp by v[n-1], and repeat this test if rp < b. The test + // on v[n-2] determines at high speed most of the cases in which the trial + // value qp is one too large, and it eliminates all cases where qp is two + // too large. + uint64_t dividend = ((uint64_t(u[j+n]) << 32) + u[j+n-1]); + //DEBUG(cerr << "KnuthDiv: dividend == " << dividend << '\n'); + uint64_t qp = dividend / v[n-1]; + uint64_t rp = dividend % v[n-1]; + if (qp == b || qp*v[n-2] > b*rp + u[j+n-2]) { + qp--; + rp += v[n-1]; + if (rp < b && (qp == b || qp*v[n-2] > b*rp + u[j+n-2])) + qp--; + } + //DEBUG(cerr << "KnuthDiv: qp == " << qp << ", rp == " << rp << '\n'); + + // D4. [Multiply and subtract.] Replace (u[j+n]u[j+n-1]...u[j]) with + // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation + // consists of a simple multiplication by a one-place number, combined with + // a subtraction. + bool isNeg = false; + for (uint32_t i = 0; i < n; ++i) { + uint64_t u_tmp = uint64_t(u[j+i]) | ((uint64_t(u[j+i+1])) << 32); + uint64_t subtrahend = uint64_t(qp) * uint64_t(v[i]); + bool borrow = subtrahend > u_tmp; + /*DEBUG(cerr << "KnuthDiv: u_tmp == " << u_tmp + << ", subtrahend == " << subtrahend + << ", borrow = " << borrow << '\n');*/ + + uint64_t result = u_tmp - subtrahend; + uint32_t k = j + i; + u[k++] = (uint32_t)(result & (b-1)); // subtract low word + u[k++] = (uint32_t)((result) >> 32); // subtract high word + while (borrow && k <= m+n) { // deal with borrow to the left + borrow = u[k] == 0; + u[k]--; + k++; + } + isNeg |= borrow; + /*DEBUG(cerr << "KnuthDiv: u[j+i] == " << u[j+i] << ", u[j+i+1] == " << + u[j+i+1] << '\n');*/ + } + /*DEBUG(cerr << "KnuthDiv: after subtraction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + // The digits (u[j+n]...u[j]) should be kept positive; if the result of + // this step is actually negative, (u[j+n]...u[j]) should be left as the + // true value plus b**(n+1), namely as the b's complement of + // the true value, and a "borrow" to the left should be remembered. + // + if (isNeg) { + bool carry = true; // true because b's complement is "complement + 1" + for (uint32_t i = 0; i <= m+n; ++i) { + u[i] = ~u[i] + carry; // b's complement + carry = carry && u[i] == 0; + } + } + /*DEBUG(cerr << "KnuthDiv: after complement:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + + // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was + // negative, go to step D6; otherwise go on to step D7. + q[j] = (uint32_t)qp; + if (isNeg) { + // D6. [Add back]. The probability that this step is necessary is very + // small, on the order of only 2/b. Make sure that test data accounts for + // this possibility. Decrease q[j] by 1 + q[j]--; + // and add (0v[n-1]...v[1]v[0]) to (u[j+n]u[j+n-1]...u[j+1]u[j]). + // A carry will occur to the left of u[j+n], and it should be ignored + // since it cancels with the borrow that occurred in D4. + bool carry = false; + for (uint32_t i = 0; i < n; i++) { + uint32_t limit = AESL_std::min(u[j+i],v[i]); + u[j+i] += v[i] + carry; + carry = u[j+i] < limit || (carry && u[j+i] == limit); + } + u[j+n] += carry; + } + /*DEBUG(cerr << "KnuthDiv: after correction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr <<" " << u[i]); + DEBUG(cerr << "\nKnuthDiv: digit result = " << q[j] << '\n');*/ + + // D7. [Loop on j.] Decrease j by one. Now if j >= 0, go back to D3. + } while (--j >= 0); + + /*DEBUG(cerr << "KnuthDiv: quotient:"); + DEBUG(for (int i = m; i >=0; i--) cerr <<" " << q[i]); + DEBUG(cerr << '\n');*/ + + // D8. [Unnormalize]. Now q[...] is the desired quotient, and the desired + // remainder may be obtained by dividing u[...] by d. If r is non-null we + // compute the remainder (urem uses this). + if (r) { + // The value d is expressed by the "shift" value above since we avoided + // multiplication by d by using a shift left. So, all we have to do is + // shift right here. In order to mak + if (shift) { + uint32_t carry = 0; + //DEBUG(cerr << "KnuthDiv: remainder:"); + for (int i = n-1; i >= 0; i--) { + r[i] = ((u[i]) >> (shift)) | carry; + carry = (u[i]) << (32 - shift); + //DEBUG(cerr << " " << r[i]); + } + } else { + for (int i = n-1; i >= 0; i--) { + r[i] = u[i]; + //DEBUG(cerr << " " << r[i]); + } + } + //DEBUG(cerr << '\n'); + } + //DEBUG(cerr << std::setbase(10) << '\n'); +} + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + const ap_private<_AP_W, _AP_S, _AP_N>& RHS, uint32_t rhsWords, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = rhsWords * 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = (uint32_t)(tmp & mask); + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + for (unsigned i = 0; i < rhsWords; ++i) { + uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]); + __V[i * 2] = (uint32_t)(tmp & mask); + __V[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = (uint32_t)partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = (uint32_t)(partial_dividend / divisor); + remainder = (uint32_t)(partial_dividend - (__Q[i] * divisor)); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != RHS.BitWidth) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + + +template +void ap_private<_AP_W, _AP_S, _AP_N>::fromString(const char *str, uint32_t slen, uint8_t radix) { + enum { numbits=_AP_W}; + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(str && "String is null?"); + bool isNeg = str[0] == '-'; + if (isNeg) + str++, slen--; + + //skip any leading zero + while(*str == '0' && *(str+1) != '\0') {str++; slen--;} + assert((slen <= numbits || radix != 2) && "Insufficient bit width"); + assert(((slen - 1)*3 <= numbits || radix != 8) && "Insufficient bit width"); + assert(((slen - 1)*4 <= numbits || radix != 16) && "Insufficient bit width"); + assert((((slen -1)*64)/22 <= numbits || radix != 10) && "Insufficient bit width"); + + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Figure out if we can shift instead of multiply + uint32_t shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0); + + // Set up an ap_private for the digit to add outside the loop so we don't + // constantly construct/destruct it. + uint64_t bigVal[_AP_N]; + memset(bigVal, 0, _AP_N * sizeof(uint64_t)); + ap_private<_AP_W, _AP_S, _AP_N> apdigit(getBitWidth(), bigVal); + ap_private<_AP_W, _AP_S, _AP_N> apradix(radix); + + // Enter digit traversal loop + for (unsigned i = 0; i < slen; i++) { + // Get a digit + uint32_t digit = 0; + char cdigit = str[i]; + if (radix == 16) { +#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#define isdigit(c) ((c) >= '0' && (c) <= '9') + if (!isxdigit(cdigit)) + assert(0 && "Invalid hex digit in string"); + if (isdigit(cdigit)) + digit = cdigit - '0'; + else if (cdigit >= 'a') + digit = cdigit - 'a' + 10; + else if (cdigit >= 'A') + digit = cdigit - 'A' + 10; + else + assert(0 && "huh? we shouldn't get here"); + } else if (isdigit(cdigit)) { + digit = cdigit - '0'; + } else { + assert(0 && "Invalid character in digit string"); + } +#undef isxdigit +#undef isdigit + // Shift or multiply the value by the radix + if (shift) + *this <<= shift; + else + *this *= apradix; + + // Add in the digit we just interpreted + if (apdigit.isSingleWord()) + apdigit.VAL = digit; + else + apdigit.pVal[0] = digit; + *this += apdigit; + } + // If its negative, put it in two's complement form + if (isNeg) { + (*this)--; + this->flip(); + } + clearUnusedBits(); +} + +template +std::string ap_private<_AP_W, _AP_S, _AP_N>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" + }; + std::string result; + uint32_t bits_used = getActiveBits(); + + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, _AP_N> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, _AP_N> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask; + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, _AP_N> tmp(*this); + ap_private<_AP_W, false, _AP_N> divisor(radix); + ap_private<_AP_W, false, _AP_N> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, _AP_N>(0)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, _AP_N> APdigit(0); + ap_private<_AP_W, false, _AP_N> tmp2(0); + divide(tmp, tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2, + &APdigit); + uint32_t digit = APdigit.getZExtValue(); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + + return result; +} + +// This implements a variety of operations on a representation of +// arbitrary precision, two's-complement, bignum integer values. + +/* Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe + and unrestricting assumption. */ + +/* Some handy functions local to this file. */ + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + uint64_t RHS, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + uint32_t rhsWords=1; + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = tmp & mask; + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + __V[0] = RHS & mask; + __V[1] = (RHS) >> (sizeof(uint32_t)*8); + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = partial_dividend / divisor; + remainder = partial_dividend - (__Q[i] * divisor); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + else + delete [] Quotient->pVal; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != 64 /* RHS.BitWidth */) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in __R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + +//When bitwidth < 64 +template class ap_private <_AP_W, _AP_S, 1> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template + struct RType { + enum { + _AP_N =1, + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, //?? why + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, //shouldn't it be AP_MAX(_AP_W,_AP_W2)+!(_AP_S^_AP_S2)+1 ???? + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + enum { APINT_BITS_PER_WORD = 64}; + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + static const uint64_t not_mask = ~mask; + static const uint64_t sign_bit_mask = 1ULL << (APINT_BITS_PER_WORD-1); + template struct sign_ext_mask { static const uint64_t mask=~0ULL<<_AP_W1;}; + + enum { BitWidth=_AP_W}; + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + const uint64_t *const pVal; + + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + volatile ap_private& operator=(const ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const volatile ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + template + INLINE ap_private& operator = (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + *this = ap_private<_AP_W2, false>(op2); + return *this; + } + + explicit INLINE ap_private(uint64_t* val) : VAL(val[0]), pVal(&VAL){ + clearUnusedBits(); + } + + INLINE bool isSingleWord() const { return true; } + + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix, int offset=0) { + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(strStart && "String is null?"); + strStart+=offset; + switch(radix) { + case 2: + // sscanf(strStart,"%b",&VAL); + VAL = *strStart =='1' ? ~0ULL : 0; + for (;*strStart; ++strStart) { + assert((*strStart=='0'|| *strStart=='1')&&("Wrong binary number") ); + VAL <<=1; + VAL |= (*strStart-'0'); + } + break; + case 8: +#if __WIN32__ + sscanf(strStart,"%I64o",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lo",&VAL); +#else + sscanf(strStart,"%llo",&VAL); +#endif + +#endif + break; + case 10: +#if __WIN32__ + sscanf(strStart,"%I64u",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lu",&VAL); +#else + sscanf(strStart,"%llu",&VAL); +#endif + +#endif + break; + case 16: +#if __WIN32__ + sscanf(strStart,"%I64x",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lx",&VAL); +#else + sscanf(strStart,"%llx",&VAL); +#endif + +#endif + break; + default: + assert(true && "Unknown radix"); + // error + } + clearUnusedBits(); + } + + INLINE ap_private() : pVal(&VAL){VAL = 0ULL;} + +#define CTOR(TYPE) \ + INLINE ap_private(TYPE v) : VAL((uint64_t)v), pVal(&VAL) { \ + clearUnusedBits(); \ + } + CTOR(int) + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) +#undef CTOR + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(bigVal[0]), pVal(&VAL) {clearUnusedBits();} + + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0), pVal(&VAL) { + assert(!val.empty() && "String empty?"); + fromString(val.c_str()+base, val.size()-base, radix); + } + + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0), pVal(&VAL) { + fromString(strStart+base, slen-base, radix, offset); + } + + ap_private(const ap_private& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + +#if 0 +template + explicit ap_private(const ap_private<_AP_W1, true, 1+_AP_W1/64>& that) + : VAL((_AP_W1>_AP_W) ? that.VAL & mask : ((1ULL<<(_AP_W1-1)&that.pVal[0]) ? sign_ext_mask<_AP_W1>::mask | that.VAL : that.pVal[0])), pVal(&VAL) {} + +template + explicit ap_private(const ap_private<_AP_W1, false, (_AP_W1+63)/64>& that) + : VAL(that.VAL & mask), pVal(&VAL) {} +#endif + + explicit ap_private(const char* val) : pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 10; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private<_AP_W, _AP_S> ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + ap_private(const char* val, signed char rd): pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + ap_private<_AP_W, _AP_S> ap_private_val(strp , strLen, radix, base, offset); + //ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + if (strp[0] == '-') + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + INLINE bool isNegative() const { + static const uint64_t sign_mask = 1ULL << (_AP_W-1); + return _AP_S && (sign_mask & VAL); + } + + INLINE bool isPositive() const { + return !isNegative(); + } + + INLINE bool isStrictlyPositive() const { + return !isNegative() && VAL!=0; + } + + INLINE bool isAllOnesValue() const { + return (mask & VAL) == mask; + } + + template + INLINE bool operator==(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + return (VAL == RHS.VAL); + } + + INLINE bool operator==(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL == RHS.VAL; } + INLINE bool operator==(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() == RHS.getVal(); } + INLINE bool operator==(uint64_t Val) const { return (VAL == Val); } + INLINE bool operator!=(uint64_t Val) const { return (VAL != Val); } + INLINE bool operator!=(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL != RHS.VAL; } + INLINE bool operator!=(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() != RHS.getVal(); } + const ap_private operator++() { ++VAL; clearUnusedBits(); return *this; } + const ap_private operator--(int) { + ap_private orig(*this); + --VAL; clearUnusedBits(); + return orig; + } + const ap_private operator--() { --VAL; clearUnusedBits(); return *this;} + INLINE bool operator !() const { return !VAL;} + + const ap_private operator++(int) { + ap_private orig(*this); + VAL++; clearUnusedBits(); + return orig; + } + + const ap_private operator~() {return ap_private(~VAL);} + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + INLINE std::string toString(uint8_t radix, bool wantSigned) const ; + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + INLINE void clear() { + VAL=0; + } + INLINE ap_private& clear(uint32_t bitPosition) { VAL &= ~(1ULL<<(bitPosition)); clearUnusedBits(); return *this;} + + INLINE ap_private ashr(uint32_t shiftAmt) const { + enum {excess_bits = APINT_BITS_PER_WORD - BitWidth}; + if (_AP_S) + return ap_private((shiftAmt == BitWidth) ? 0 : ((int64_t)VAL) >> (shiftAmt)); + else + return ap_private((shiftAmt == BitWidth) ? 0 : (VAL) >> (shiftAmt)); + } + + INLINE ap_private lshr(uint32_t shiftAmt) const { + return ap_private((shiftAmt == BitWidth) ? ap_private(0) : ap_private((VAL&mask) >> (shiftAmt))); + } + + INLINE ap_private shl(uint32_t shiftAmt) const { + if (shiftAmt > BitWidth) { + if (!isNegative()) + return ap_private(0); + else return ap_private(-1); + } + if (shiftAmt == BitWidth) return ap_private(0); + else return ap_private((VAL) << (shiftAmt)); + //return ap_private((shiftAmt == BitWidth) ? ap_private(0ULL) : ap_private(VAL << shiftAmt)); + } + + INLINE int64_t getSExtValue() const { + return VAL; + } + + INLINE uint64_t getZExtValue() const { + return VAL & mask; + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this = ((uint64_t)(bool)ref); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = (uint64_t)(bool)val; + } + + INLINE void write(const ap_private<_AP_W, _AP_S>& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + ValType getVal() const { + return VAL; + } + operator ValType () const { + return getVal(); + } + INLINE int to_int() const { + // ap_private<64 /* _AP_W */, _AP_S> res(V); + return (int) getVal(); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE bool isMinValue() const { return VAL == 0;} + template INLINE ap_private& operator&=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL&RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator|=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL|RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator^=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL^RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator*=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL*RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL+RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL-RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + INLINE const ap_private& operator<<=(uint32_t shiftAmt) { VAL<<=shiftAmt; clearUnusedBits(); return *this; } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator&(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL & RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret & RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator^(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL ^ RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret ^ RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator|(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL | RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret | RHS; + } + } + + INLINE ap_private<_AP_W, _AP_S> And(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL & RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Or(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL | RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Xor(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL ^ RHS.VAL); + } +#if 1 + template + INLINE typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::mult_w <= 64) { + typename RType<_AP_W1, _AP_S1>::mult Result(VAL * RHS.VAL); + return Result; + } else { + typename RType<_AP_W1, _AP_S1>::mult Result = typename RType<_AP_W1, _AP_S1>::mult(*this); + Result *= RHS; + return Result; + } + } +#endif + INLINE ap_private<_AP_W, _AP_S> Mul(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL * RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Add(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL + RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Sub(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL - RHS.VAL); + } + +#if 1 + INLINE ap_private& operator&=(uint64_t RHS) { VAL &= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator|=(uint64_t RHS) { VAL |= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator^=(uint64_t RHS){ VAL ^= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator*=(uint64_t RHS){ VAL *= RHS; clearUnusedBits(); return *this; } + INLINE ap_private& operator+=(uint64_t RHS){ VAL += RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator-=(uint64_t RHS){ VAL -= RHS; clearUnusedBits(); return *this; } + INLINE ap_private operator&(uint64_t RHS) const { return ap_private(VAL & RHS); } + INLINE ap_private operator|(uint64_t RHS) const { return ap_private(VAL | RHS); } + INLINE ap_private operator^(uint64_t RHS) const { return ap_private(VAL ^ RHS); } + INLINE ap_private operator*(uint64_t RHS) const { return ap_private(VAL * RHS); } + INLINE ap_private operator/(uint64_t RHS) const { return ap_private(VAL / RHS); } + INLINE ap_private operator+(uint64_t RHS) const { return ap_private(VAL + RHS); } + INLINE ap_private operator-(uint64_t RHS) const { return ap_private(VAL - RHS); } +#endif + INLINE bool isMinSignedValue() const { + static const uint64_t min_mask = ~(~0ULL << (_AP_W-1)); + return BitWidth == 1 ? VAL == 1 : + (ap_private_ops::isNegative<_AP_W>(*this) && ((min_mask & VAL)==0)); + } + +#if 1 + + template INLINE + typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::plus_w <=64) + return typename RType<_AP_W1,_AP_S1>::plus(RType<_AP_W1,_AP_S1>::plus_s ? int64_t(VAL+RHS.VAL):uint64_t(VAL+RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::plus Result=RHS; + Result += VAL; + return Result; + } + + template INLINE + typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::minus_w <=64) + return typename RType<_AP_W1,_AP_S1>::minus(int64_t(VAL-RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::minus Result=*this; + Result -= RHS; + return Result; + } +#endif // #if 1 + + INLINE ap_private& flip() { + VAL = (~0ULL^VAL)&mask; + clearUnusedBits(); + return *this; + } + + uint32_t countPopulation() const { return CountPopulation_64(VAL);} + uint32_t countLeadingZeros() const { + int remainder = BitWidth % APINT_BITS_PER_WORD; + int excessBits = (APINT_BITS_PER_WORD - remainder) % APINT_BITS_PER_WORD; + //enum { remainder = BitWidth % APINT_BITS_PER_WORD, excessBits = APINT_BITS_PER_WORD - remainder}; + uint32_t Count = CountLeadingZeros_64(VAL); + if (Count) + Count-=excessBits; + return AESL_std::min(Count, (uint32_t)_AP_W); + } + + /// HiBits - This function returns the high "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getHiBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret(*this); + ret = (ret)>>(BitWidth - numBits); + return ret; + } + + /// LoBits - This function returns the low "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getLoBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret((VAL) << (BitWidth - numBits)); + ret = (ret)>>(BitWidth - numBits); + return ret; + //return ap_private(numBits, (VAL << (BitWidth - numBits))>> (BitWidth - numBits)); + } + + ap_private<_AP_W, _AP_S,1>& set(uint32_t bitPosition) { + VAL |= (1ULL << (bitPosition)); + clearUnusedBits(); + return *this; // clearUnusedBits(); + } + + void set() { + VAL = ~0ULL; + clearUnusedBits(); + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + INLINE void set(const ap_private & val) { + operator = (val); + } + + bool operator[](uint32_t bitPosition) const { + return (((1ULL << (bitPosition)) & VAL) != 0); + } + + INLINE void clearUnusedBits(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + VAL = _AP_S ? ((((int64_t)VAL)<<(excess_bits))>> (excess_bits)) : (excess_bits ? ((VAL)<<(excess_bits))>>(excess_bits) : VAL); + } + + INLINE void clearUnusedBitsToZero(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + static uint64_t mask = ~0ULL >> (excess_bits); + VAL &= mask; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> udiv(const ap_private<_AP_W, _AP_S1>& RHS) const { + return ap_private<_AP_W, _AP_S||_AP_S1>(VAL / RHS.VAL); + } + + INLINE ap_private udiv(uint64_t RHS) const { + return ap_private(VAL / RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> sdiv(const ap_private<_AP_W, _AP_S1> & RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS<0) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + template + INLINE ap_private urem(const ap_private<_AP_W, _AP_S2>& RHS) const { + assert(RHS.VAL != 0 && "Divide by 0"); + return ap_private(VAL%RHS.VAL); + } + + INLINE ap_private urem(uint64_t RHS) const { + assert(RHS != 0 && "Divide by 0"); + return ap_private(VAL%RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private srem(const ap_private<_AP_W, _AP_S2>& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + INLINE static void udivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS.VAl; + Remainder = LHS.VAL % RHS.VAL; + } + + INLINE static void udivrem(const ap_private &LHS, uint64_t RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS; + Remainder = LHS.VAL % RHS; + } + + INLINE static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + INLINE static void sdivrem(const ap_private &LHS, int64_t RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS<0) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS<0) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + template INLINE bool eq(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return (*this) == RHS; + } + + template INLINE bool ne(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template INLINE bool ult(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + uint64_t lhsZext = ((uint64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + uint64_t rhsZext = ((uint64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsZext < rhsZext; + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered signed. + /// @brief Signed less than comparison + template INLINE bool slt(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + int64_t lhsSext = ((int64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + int64_t rhsSext = ((int64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsSext < rhsSext; + } + + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template INLINE bool ule(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template INLINE bool sle(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template INLINE bool ugt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template INLINE bool sgt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template INLINE bool uge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template INLINE bool sge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS); + } + + INLINE ap_private abs() const { + if (isNegative()) + return -(*this); + return *this; + } + + ap_private<_AP_W, false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + INLINE static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + return _AP_W; + } + + INLINE uint32_t getActiveBits() const { + uint32_t bits=_AP_W - countLeadingZeros(); + return bits?bits:1; + } + + INLINE double roundToDouble(bool isSigned=false) const { + const static uint64_t mask = ~0ULL << (APINT_BITS_PER_WORD - _AP_W); + return double(VAL); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + //Binary Arithmetic + //----------------------------------------------------------- +#define OP_BIN_AP(Sym,Rty, Fun) \ + template \ + INLINE \ + typename RType<_AP_W2,_AP_S2>::Rty \ + operator Sym (const ap_private<_AP_W2,_AP_S2>& op) const { \ + typename RType<_AP_W2,_AP_S2>::Rty lhs(*this); \ + typename RType<_AP_W2,_AP_S2>::Rty rhs(op); \ + return lhs.Fun(rhs); \ + } \ + + ///Bitwise and, or, xor + //OP_BIN_AP(&,logic, And) + //OP_BIN_AP(|,logic, Or) + //OP_BIN_AP(^,logic, Xor) + +#undef OP_BIN_AP + template + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=*this; + ap_private rhs=op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod (_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + +#define OP_ASSIGN_AP_2(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP_2(/) + OP_ASSIGN_AP_2(%) +#undef OP_ASSIGN_AP_2 + + ///Bitwise assign: and, or, xor + //------------------------------------------------------------- + // OP_ASSIGN_AP(&) + // OP_ASSIGN_AP(^) + // OP_ASSIGN_AP(|) +#undef OP_ASSIGN_AP +#if 1 + + template + INLINE ap_private<_AP_W, _AP_S> + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator << (uint32_t sh) const { + return shl(sh); + } + +#endif + + template + INLINE ap_private<_AP_W, _AP_S> + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator >>(uint32_t sh) const { + ap_private<_AP_W, _AP_S> r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP_3_SINGLE(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op.getVal()); \ + return *this; \ + } + OP_ASSIGN_AP_3_SINGLE(>>) +#undef OP_ASSIGN_AP_3_SINGLE + + ///Comparisons + //----------------------------------------------------------------- + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this==op); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return op < *this; + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this>op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else if (_AP_W < 32 && _AP_W2 < 32) + return lhs.slt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op == *this; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return !(op==*this); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op < (*this); + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op >= *this; + } + + template + INLINE bool operator <(const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op > *this; + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2,_AP_N2>& op) const { + return op <= *this; + } + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S> (*this, (int)index); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return (VAL & mask) == mask; + } + + INLINE bool nand_reduce() const { + return (VAL & mask) != mask; + } + + INLINE bool or_reduce() const { + return (bool)VAL; + } + + INLINE bool nor_reduce() const { + return VAL==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; +template +std::string ap_private<_AP_W, _AP_S, 1>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f" + }; + std::string result; + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, 1> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, 1> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (unsigned)(tmp.VAL & mask); + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, 1> tmp(*this); + ap_private<6, false, 1> divisor(radix); + ap_private<_AP_W, _AP_S, 1> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, 1>(0ULL)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, 1> APdigit = tmp%divisor; + ap_private<_AP_W, false, 1> tmp2 = tmp/divisor; + uint32_t digit = (uint32_t)(APdigit.getZExtValue()); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + return result; + +} + +#endif /* #ifndef LLVM_SUPPORT_MATHEXTRAS_H */ \ No newline at end of file diff --git a/hls_2018/router_04_boardstr/main.cpp b/hls_2018/router_04_boardstr/main.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2de79fc3624c71a11ed8c2513163805ae5c0a5ea --- /dev/null +++ b/hls_2018/router_04_boardstr/main.cpp @@ -0,0 +1,99 @@ +/** + * main.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#ifdef CALCTIME +#include +#include +#endif + +#include "router.hpp" + +#define PRINT_SOLUTION + + +int main(int argc, char *argv[]) { + using namespace std; + + // Test data // + // NL_Q00.txt + //char boardstr[BOARDSTR_SIZE] = "X10Y05Z3L0000107041L0004107002L0102102021L0900100003"; + // NL_Q06.txt + char boardstr[BOARDSTR_SIZE] = "X10Y18Z2L0900109002L0901105012L0902103052L0903103062L0904100102L0905106012L0906109022L0717109102L0808109112L0017209172L0401200072L0912208152L0009201092L0709209092L0901206052L0309204092L0701209072L0101201022L0011202152L0016202162"; + // NL_Q08.txt + //char boardstr[BOARDSTR_SIZE] = "X17Y20Z2L0000103022L1603115052L0916107032L0302108012L1104111042L1002100002L0919116162L1616113182L1001115012L0500201182L1603213152L0600210022"; + char boardstr_high[BOARDSTR_SIZE] = {}; + + // Read boardstr from command line + if (1 < argc) { + // From stdin + if(argv[1][0]!='X') + { + char* c_p=fgets(boardstr, BOARDSTR_SIZE, stdin); + int length=strlen(c_p); + boardstr[length-1]=0; + } + else + { + strcpy(boardstr, argv[1]); + } + } + + // Seed value + int seed = 12345; + if (2 < argc) { + seed = atoi(argv[2]); + } + +#ifdef PRINT_SOLUTION + int size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + int size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + int size_z = (boardstr[7] - '0'); +#endif + + // Solver + ap_int<32> status; + clock_t clock_start, clock_done; + clock_start = clock(); + bool result = pynqrouter(boardstr, boardstr_high, seed, &status); + clock_done = clock(); + if (result) { + cout << endl << "Test Passed!" << endl; + } else { + cout << endl << "Test Failed!" << endl; + } + cout << "status = " << (int)status << endl; + cout << "elapsed = " << ((double)(clock_done - clock_start) / CLOCKS_PER_SEC) << endl << endl; + +#ifdef PRINT_SOLUTION + cout << "SOLUTION" << endl; + cout << "========" << endl; + cout << "SIZE " << size_x << "X" << size_y << "X" << size_z << endl; + for (int z = 0; z < size_z; z++) { + cout << "LAYER " << (z + 1) << endl; + for (int y = 0; y < size_y; y++) { + for (int x = 0; x < size_x; x++) { + if (x != 0) { + cout << ","; + } + int i = ((x * MAX_WIDTH + y) << BITWIDTH_Z) | z; + unsigned int num = (unsigned char)(boardstr[i]) + ((unsigned char)(boardstr_high[i]) << 8); + cout << setfill('0') << setw(3) << right << num; + //cout << num; + } + cout << endl; + } + } +#endif + + return 0; +} + diff --git a/hls_2018/router_04_boardstr/router.cpp b/hls_2018/router_04_boardstr/router.cpp new file mode 100755 index 0000000000000000000000000000000000000000..367b122e70388f09c5462b971ade2d5a16aa0cae --- /dev/null +++ b/hls_2018/router_04_boardstr/router.cpp @@ -0,0 +1,530 @@ +/** + * router.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#include "./router.hpp" + +// Set weight +ap_uint<8> new_weight(ap_uint<16> x) { +#pragma HLS INLINE + // K. Terada: y = 1~32 (8bit) + ap_uint<8> y; + y = ((x & 255) >> 3) + 1; + return y; +} + + +// Global values +static ap_uint<7> size_x; // X +static ap_uint<7> size_y; // Y +static ap_uint<4> size_z; // Z + +static ap_uint line_num = 0; // #Lines + +#ifdef DEBUG_PRINT +int max_queue_length; // Max length of priority queue +int max_search_count; // Max count of queue pop +int max_buffer_length; // Max length of line buffer +#endif + + +bool pynqrouter(char boardstr[BOARDSTR_SIZE], char boardstr_high[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status) { +#pragma HLS INTERFACE s_axilite port=boardstr bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=boardstr_high bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=seed bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=status bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=return bundle=AXI4LS + + // status(0:Solved, 1:Not solved) + *status = -1; + + // For all lines + ap_uint paths[MAX_BUFFER]; // Line buffer + + // For each line + // Note: Should not partition completely + bool adjacents[MAX_LINES]; // Line has adjacent terminals? + ap_uint starts[MAX_LINES]; // Start list + ap_uint goals[MAX_LINES]; // Goal list + ap_uint s_idx[MAX_LINES]; // Start point on line buffer + + ap_uint<8> weights[MAX_CELLS]; // Weight of each cell + // Note: Should not partition weight array + // since each element will be accessed in "random" order + + + // ================================ + // (Step.0) Initialization (BEGIN) + // ================================ + + // Note: Loop counter -> need an extra bit (for condition determination) + + INIT_WEIGHTS: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { +#pragma HLS UNROLL factor=2 + weights[i] = 1; + } + + /// Parse /// + size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + size_z = (boardstr[7] - '0'); + + INIT_BOARDS: + for (ap_uint idx = 8; idx < (ap_uint)(BOARDSTR_SIZE); idx+=11) { + + // NULL-terminated + if (boardstr[idx] == 0) break; + + // Start & Goal of each line + ap_uint<7> s_x = (boardstr[idx+1] - '0') * 10 + (boardstr[idx+2] - '0'); + ap_uint<7> s_y = (boardstr[idx+3] - '0') * 10 + (boardstr[idx+4] - '0'); + ap_uint<3> s_z = (boardstr[idx+5] - '0') - 1; + ap_uint<7> g_x = (boardstr[idx+6] - '0') * 10 + (boardstr[idx+7] - '0'); + ap_uint<7> g_y = (boardstr[idx+8] - '0') * 10 + (boardstr[idx+9] - '0'); + ap_uint<3> g_z = (boardstr[idx+10] - '0') - 1; + + ap_uint start_id = (((ap_uint)s_x * MAX_WIDTH + (ap_uint)s_y) << BITWIDTH_Z) | (ap_uint)s_z; + ap_uint goal_id = (((ap_uint)g_x * MAX_WIDTH + (ap_uint)g_y) << BITWIDTH_Z) | (ap_uint)g_z; + starts[line_num] = start_id; + goals[line_num] = goal_id; + weights[start_id] = MAX_WEIGHT; + weights[goal_id] = MAX_WEIGHT; + + // Line has adjacent terminals? + adjacents[line_num] = false; + ap_int<8> dx = (ap_int<8>)g_x - (ap_int<8>)s_x; // Min: -71, Max: 71 (Signed 8bit) + ap_int<8> dy = (ap_int<8>)g_y - (ap_int<8>)s_y; // Min: -71, Max: 71 (Signed 8bit) + ap_int<4> dz = (ap_int<4>)g_z - (ap_int<4>)s_z; // Min: -7, Max: 7 (Signed 4bit) + if ((dx == 0 && dy == 0 && (dz == 1 || dz == -1)) || (dx == 0 && (dy == 1 || dy == -1) && dz == 0) || ((dx == 1 || dx == -1) && dy == 0 && dz == 0)) { + adjacents[line_num] = true; + } + + line_num++; + } + + // ================================ + // (Step.0) Initialization (END) + // ================================ + +#ifdef DEBUG_PRINT + max_queue_length = 0; + max_search_count = 0; + max_buffer_length = 0; +#endif + + ap_uint pointer = 0; // Pointer for line buffer + + // ================================ + // (Step.1) Initial Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Initial Routing ..." << endl; +#endif + + FIRST_ROUTING: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + + s_idx[i] = pointer; + + if (adjacents[i] == true) continue; // Skip routing + +#ifdef DEBUG_PRINT + //cout << "LINE #" << (int)(i + 1) << endl; +#endif + // Routing + pointer = search(s_idx[i], paths, starts[i], goals[i], weights); + } + + // ================================ + // (Step.1) Initial Routing (END) + // ================================ + + + // Memories for Overlap Check + ap_uint<1> overlap_checks[MAX_CELLS]; +#pragma HLS ARRAY_PARTITION variable=overlap_checks cyclic factor=32 dim=1 + bool has_overlap = false; + + // ================================ + // (Step.2) Rip-up Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Rip-up Routing ..." << endl; +#endif + + ap_uint target = line_num - 1, next_target; + + ROUTING: + for (ap_uint<16> round = 0; round < 32768 /* = (2048 * 16) */; round++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=32768 + + // Target line + target = round % line_num; + next_target = target + 1; + if (next_target == line_num) next_target = 0; + +#ifdef DEBUG_PRINT + //cout << "(round " << round << ") LINE #" << (int)(target + 1); + //cout << " -> " << pointer << endl; +#endif +#ifdef DEBUG_PRINT + int buffer_length = pointer - s_idx[target]; + if (max_buffer_length < buffer_length) { max_buffer_length = buffer_length; } +#endif + + // Skip routing + if (adjacents[target] == true) { + s_idx[target] = pointer; continue; + } + + + // (Step.2-1) Reset weights of target line + WEIGHT_RESET: + for (ap_uint j = s_idx[target]; j != s_idx[next_target]; j++) { +#pragma HLS UNROLL factor=2 +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + weights[paths[j]] = 1; + } + + // (Step.2-2) Set weights of non-target lines and terminals + ap_uint<8> current_round_weight = new_weight(round); + WEIGHT_PATH: + for (ap_uint j = s_idx[next_target]; j != pointer; j++) { +#pragma HLS UNROLL factor=2 +#pragma HLS LOOP_TRIPCOUNT min=1 max=8192 + weights[paths[j]] = current_round_weight; + } + WEIGHT_TERMINAL: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS UNROLL factor=2 +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + weights[starts[i]] = MAX_WEIGHT; + weights[goals[i]] = MAX_WEIGHT; + } + // Reset weight of start terminal of target line (bug avoiding) + // Restore original settings in (*) + weights[starts[target]] = 1; + + // (Step.2-3) Routing + s_idx[target] = pointer; + pointer = search(s_idx[target], paths, starts[target], goals[target], weights); + + // (*) + weights[starts[target]] = MAX_WEIGHT; + +#ifdef DEBUG_PRINT + bool ng = false; + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { + if (weights[starts[i]] != 255 || weights[goals[i]] != 255) { + cout << i << " "; ng = true; + } + } + if(ng) { cout << endl; } +#endif + + // (Step.2-4) Overlap check + has_overlap = false; + OVERLAP_RESET: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { +#pragma HLS UNROLL factor=64 + overlap_checks[i] = 0; + } + OVERLAP_CHECK_LINE: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS UNROLL factor=2 +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + overlap_checks[starts[i]] = 1; + overlap_checks[goals[i]] = 1; + } + OVERLAP_CHECK_PATH: + for (ap_uint j = s_idx[next_target]; j != pointer; j++) { +#pragma HLS UNROLL factor=2 +#pragma HLS LOOP_TRIPCOUNT min=1 max=8192 + ap_uint cell_id = paths[j]; + if (overlap_checks[cell_id]) { + has_overlap = true; break; + } + overlap_checks[cell_id] = 1; + } +#ifdef DEBUG_PRINT + if(!has_overlap){ cout << "ROUND: " << round << endl; } +#endif + if (!has_overlap) break; // Finish routing? + } + +#ifdef DEBUG_PRINT + cout << "MAX PQ LENGTH: " << max_queue_length << endl; + cout << "MAX SEARCH COUNT: " << max_search_count << endl; + cout << "MAX BUFFER: " << max_buffer_length << endl; +#endif + + // Not solved + if (has_overlap) { + *status = 1; return false; + } + + // ================================ + // (Step.2) Rip-up Routing (END) + // ================================ + + + // ================================ + // (Step.3) Output (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Output ..." << endl; +#endif + + // Init: Blank = 0 + OUTPUT_INIT: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + boardstr[i] = 0; + boardstr_high[i] = 0; + } + // Line + OUTPUT_LINE: + for (ap_uint i = 0; i < (ap_uint)(line_num); i++) { +#pragma HLS LOOP_TRIPCOUNT min=2 max=999 + boardstr[starts[i]] = (i + 1); + boardstr[goals[i]] = (i + 1); + boardstr_high[starts[i]] = (i + 1) >> 8; + boardstr_high[goals[i]] = (i + 1) >> 8; + + ap_uint p1; // p1: s_idx of target + ap_uint p2; // p2: s_idx of next target + p1 = s_idx[i]; + if (i == (ap_uint)(line_num-1)) { + p2 = s_idx[0]; + } + else { + p2 = s_idx[i+1]; + } + if (i == target) { + p2 = pointer; + } + OUTPUT_LINE_PATH: + for (ap_uint j = p1; j != p2; j++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + boardstr[paths[j]] = (i + 1); + boardstr_high[paths[j]] = (i + 1) >> 8; + } + } + + // ================================ + // (Step.3) Output (END) + // ================================ + + *status = 0; return true; +} + + +// ================================ // +// For Routing +// ================================ // + +// Max: 71, Min: 0 (7bit) +ap_uint<7> abs_uint7(ap_uint<7> a, ap_uint<7> b) { +#pragma HLS INLINE + if (a < b) { return b - a; } + else { return a - b; } +} +// Max: 7, Min: 0 (3bit) +ap_uint<3> abs_uint3(ap_uint<3> a, ap_uint<3> b) { +#pragma HLS INLINE + if (a < b) { return b - a; } + else { return a - b; } +} + +// Reference codes: +// http://lethe2211.hatenablog.com/entry/2014/12/30/011030 +// http://www.redblobgames.com/pathfinding/a-star/implementation.html +// Need to modify "array partition factor" +ap_uint search(ap_uint idx, ap_uint paths[MAX_BUFFER], ap_uint start, ap_uint goal, ap_uint<8> w[MAX_CELLS]) { + + ap_uint dist[MAX_CELLS]; +#pragma HLS ARRAY_PARTITION variable=dist cyclic factor=64 dim=1 + ap_uint prev[MAX_CELLS]; + + SEARCH_INIT_DIST: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { +#pragma HLS UNROLL factor=128 + dist[i] = 65535; // = (2^16 - 1) + } + + // Priority queue (Heap) + ap_uint pq_len = 0; + bool is_empty = true; + ap_uint<32> pq_nodes[MAX_PQ]; + +#ifdef DEBUG_PRINT + int queue_length = 0; + int search_count = 0; +#endif + + // Point of goal terminal + ap_uint<13> goal_xy = (ap_uint<13>)(goal >> BITWIDTH_Z); + ap_uint<7> goal_x = (ap_uint<7>)(goal_xy / MAX_WIDTH); + ap_uint<7> goal_y = (ap_uint<7>)(goal_xy - goal_x * MAX_WIDTH); + ap_uint<3> goal_z = (ap_uint<3>)(goal & BITMASK_Z); + + dist[start] = 0; + pq_push(pq_nodes, 0, start, &pq_len, &is_empty); // push start terminal + + SEARCH_PQ: + while (!is_empty) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=1000 +#pragma HLS LOOP_FLATTEN off + + ap_uint<16> prev_cost; + ap_uint<16> src; // target cell + pq_pop(pq_nodes, &prev_cost, &src, &pq_len, &is_empty); +#ifdef DEBUG_PRINT + search_count++; +#endif + + + // End routing + if (src == goal) break; + + + // Target cell + ap_uint<16> dist_src = dist[src]; + ap_uint<8> cost = w[src]; + // Point of target cell + ap_uint<13> src_xy = (ap_uint<13>)(src >> BITWIDTH_Z); + ap_uint<7> src_x = (ap_uint<7>)(src_xy / MAX_WIDTH); + ap_uint<7> src_y = (ap_uint<7>)(src_xy - src_x * MAX_WIDTH); + ap_uint<3> src_z = (ap_uint<3>)(src & BITMASK_Z); + + // Search adjacent cells + SEARCH_ADJACENTS: + for (ap_uint<3> a = 0; a < 6; a++) { + ap_int<8> dest_x = (ap_int<8>)src_x; // Min: -1, Max: 72 (Signed 8bit) + ap_int<8> dest_y = (ap_int<8>)src_y; // Min: -1, Max: 72 (Signed 8bit) + ap_int<5> dest_z = (ap_int<5>)src_z; // Min: -1, Max: 8 (Signed 5bit) + if (a == 0) { dest_x -= 1; } + if (a == 1) { dest_x += 1; } + if (a == 2) { dest_y -= 1; } + if (a == 3) { dest_y += 1; } + if (a == 4) { dest_z -= 1; } + if (a == 5) { dest_z += 1; } + + // Inside the board ? // + if (0 <= dest_x && dest_x < (ap_int<8>)size_x && 0 <= dest_y && dest_y < (ap_int<8>)size_y && 0 <= dest_z && dest_z < (ap_int<5>)size_z) { + // Adjacent cell + ap_uint<16> dest = (((ap_uint<16>)dest_x * MAX_WIDTH + (ap_uint<16>)dest_y) << BITWIDTH_Z) | (ap_uint<16>)dest_z; + ap_uint<16> dist_new = dist_src + cost; + + if (dist[dest] > dist_new) { + dist[dest] = dist_new; // Update dist + prev[dest] = src; // Recode previous cell + dist_new += abs_uint7(dest_x, goal_x) + abs_uint7(dest_y, goal_y) + abs_uint3(dest_z, goal_z); // A* heuristic + pq_push(pq_nodes, dist_new, dest, &pq_len, &is_empty); // push adjacent cell + } + } + } +#ifdef DEBUG_PRINT + if (queue_length < pq_len) { queue_length = pq_len; } +#endif + } + + // Output target path + // Note: Do not include start & goal terminals + ap_uint<16> t = prev[goal]; + + // Backtracking + ap_uint p = idx; // buffer-idx + SEARCH_BACKTRACK: + while (t != start) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=256 + paths[p] = t; + p++; + t = prev[t]; + } + +#ifdef DEBUG_PRINT + if (max_queue_length < queue_length) { max_queue_length = queue_length; } + if (max_search_count < search_count) { max_search_count = search_count; } +#endif + + return p; +} + +// Queue push (Enqueue) +// Need to modify "trip count" (1) +void pq_push(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> priority, ap_uint<16> data, ap_uint *pq_len, bool *is_empty) { +#pragma HLS INLINE + + (*pq_len)++; + if ((*pq_len) == 0) { (*pq_len)--; } // Queue is full -> Last element is automatically removed + + // Binary search for circular list + ap_uint i = (*pq_len); + ap_uint p = (*pq_len) >> 1; // parent node + PQ_PUSH_LOOP: + while (i > 1 && (ap_uint<16>)(pq_nodes[p] & PQ_PRIORITY_MASK) >= priority) { +#pragma HLS LOOP_TRIPCOUNT min=0 max=16 +/** Set!: min=0 max=PQ_BIT **/ + pq_nodes[i] = pq_nodes[p]; + i = p; + p = p >> 1; // parent node + } + pq_nodes[i] = ((ap_uint<32>)data << PQ_PRIORITY_WIDTH) | (ap_uint<32>)priority; + *is_empty = false; +} + +// Queue pop (Dequeue) +// Need to modify "trip count" (1) +void pq_pop(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint *pq_len, bool *is_empty) { +#pragma HLS INLINE + + *ret_priority = (ap_uint<16>)(pq_nodes[1] & PQ_PRIORITY_MASK); + *ret_data = (ap_uint<16>)(pq_nodes[1] >> PQ_PRIORITY_WIDTH); + + ap_uint i = 1; // root node + ap_uint last_priority = (ap_uint<16>)(pq_nodes[*pq_len] & PQ_PRIORITY_MASK); // Priority of last element + + PQ_POP_LOOP: + while (!(i >> (PQ_BIT-1))) { // (2018.08.24) Loop condition fixed +#pragma HLS LOOP_TRIPCOUNT min=1 max=16 +/** Set!: min=0 max=PQ_BIT **/ + ap_uint c1 = i << 1; // child node(left) + ap_uint c2 = c1 + 1; // child node(right) + if (c1 < *pq_len && (ap_uint<16>)(pq_nodes[c1] & PQ_PRIORITY_MASK) <= last_priority) { + if (c2 < *pq_len && (ap_uint<16>)(pq_nodes[c2] & PQ_PRIORITY_MASK) <= (ap_uint<16>)(pq_nodes[c1] & PQ_PRIORITY_MASK)) { + pq_nodes[i] = pq_nodes[c2]; + i = c2; + } + else { + pq_nodes[i] = pq_nodes[c1]; + i = c1; + } + } + else { + if (c2 < *pq_len && (ap_uint<16>)(pq_nodes[c2] & PQ_PRIORITY_MASK) <= last_priority) { + pq_nodes[i] = pq_nodes[c2]; + i = c2; + } + else { + break; + } + } + } + pq_nodes[i] = pq_nodes[*pq_len]; + (*pq_len)--; + if ((*pq_len) == 0) { *is_empty = true; } +} + diff --git a/hls_2018/router_04_boardstr/router.hpp b/hls_2018/router_04_boardstr/router.hpp new file mode 100755 index 0000000000000000000000000000000000000000..0c0452b170773166ac40f2687fa39bc4817fc291 --- /dev/null +++ b/hls_2018/router_04_boardstr/router.hpp @@ -0,0 +1,56 @@ +/** + * router.hpp + * + * for Vivado HLS + */ + +#ifndef __ROUTER_HPP__ +#define __ROUTER_HPP__ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +//#define DEBUG_PRINT // for debug + +#ifdef DEBUG_PRINT +using namespace std; +#endif + +// Parameters +#define MAX_WIDTH 72 // Max of X, Y +#define BITWIDTH_XY 13 +#define BITMASK_XY 65528 // 1111 1111 1111 1000 +#define MAX_LAYER 8 // Max of Z +#define BITWIDTH_Z 3 +#define BITMASK_Z 7 // 0000 0000 0000 0111 + +#define MAX_CELLS 41472 // Max #cells (16bit) +#define MAX_LINES 2048 // Max #lines (11bit) +#define MAX_PQ 65536 // Queue size (16bit) +#define MAX_BUFFER 32768 // Line buffer size (15bit) +#define CELL_BIT 16 +#define LINE_BIT 11 +#define PQ_BIT 16 +#define BUFF_BIT 15 + +#define PQ_PRIORITY_WIDTH 16 +#define PQ_PRIORITY_MASK 65535 // 0000 0000 0000 0000 1111 1111 1111 1111 +#define PQ_DATA_WIDTH 16 +#define PQ_DATA_MASK 4294901760 // 1111 1111 1111 1111 0000 0000 0000 0000 + +#define MAX_WEIGHT 255 // Max weight +#define BOARDSTR_SIZE 41472 // Size of I/O + +ap_uint<8> new_weight(ap_uint<16> x); +bool pynqrouter(char boardstr[BOARDSTR_SIZE], char boardstr_high[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status); + +ap_uint<7> abs_uint7(ap_uint<7> a, ap_uint<7> b); +ap_uint<3> abs_uint3(ap_uint<3> a, ap_uint<3> b); +ap_uint search(ap_uint idx, ap_uint paths[MAX_BUFFER], ap_uint start, ap_uint goal, ap_uint<8> w[MAX_WEIGHT]); +void pq_push(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> priority, ap_uint<16> data, ap_uint *pq_len, bool *is_empty); +void pq_pop(ap_uint<32> pq_nodes[MAX_PQ], ap_uint<16> *ret_priority, ap_uint<16> *ret_data, ap_uint *pq_len, bool *is_empty); + +#endif /* __ROUTER_HPP__ */ diff --git a/hls_2018/router_05/Makefile b/hls_2018/router_05/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..8f79e7a62ede483ae7dcda810f306a02f915dfbb --- /dev/null +++ b/hls_2018/router_05/Makefile @@ -0,0 +1,20 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -o $@ $(OBJS) + +run: + python3 ../NLGenerator.py -x 20 -y 20 -z 6 -l 100;\ + python3 ./gen_boardstr.py Q-20x20x5_100_10.txt |\ + ./$(TARGET) - + + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_05/Makefile.cygwin b/hls_2018/router_05/Makefile.cygwin new file mode 100755 index 0000000000000000000000000000000000000000..866fdcdf2ea6a5fb67d1461ce4a19e353d0c9216 --- /dev/null +++ b/hls_2018/router_05/Makefile.cygwin @@ -0,0 +1,14 @@ +TARGET = sim +OBJS = $(CPPS:.cpp=.o) +CPPS = $(wildcard *.cpp) +CXX = g++ +CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -O3 -Wl,--stack,33554432 -o $@ $(OBJS) + +clean: + rm *.o + rm $(TARGET) diff --git a/hls_2018/router_05/ap_int.h b/hls_2018/router_05/ap_int.h new file mode 100755 index 0000000000000000000000000000000000000000..b8d9fdc96ac3f7eb9c86cc55d0eac0a57bf670b5 --- /dev/null +++ b/hls_2018/router_05/ap_int.h @@ -0,0 +1,521 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_AP_SIM_H__ +#define __AESL_AP_SIM_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#else + +#include "etc/ap_int_sim.h" +#include "etc/ap_fixed_sim.h" + +//Forward declaration +template class ap_fixed; +template class ap_ufixed; +template class ap_int; +template class ap_uint; + +//AP_INT +//-------------------------------------------------------- +template +class ap_int : public ap_private<_AP_W, true> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_private<_AP_W, true> Base; + + //Constructor + INLINE ap_int(): Base() {} + template + INLINE ap_int(const volatile ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_int<_AP_W2> &op):Base((const ap_private<_AP_W2,true> &)(op)) {} + + template + INLINE ap_int(const ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2,false> &)(op)) {} + + template + INLINE ap_int(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_int(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_int(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_int(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_int(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_int(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_int(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE void operator = (const volatile ap_int<_AP_W>& op2) volatile { + const_cast(this)->operator = (op2); + } + + INLINE ap_int<_AP_W>& operator = (const volatile ap_int<_AP_W>& op2) { + Base::operator = (const_cast& >(op2)); + return *this; + } + + INLINE ap_int<_AP_W>& operator = (const ap_int<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, true>&)op2); + return *this; + } +}; + +//AP_UINT +//--------------------------------------------------------------- +template +class ap_uint: public ap_private<_AP_W, false> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_private<_AP_W, false> Base; + //Constructor + INLINE ap_uint(): Base() {} + INLINE ap_uint(const ap_uint<_AP_W>& op) :Base(dynamic_cast&>(op)) {} + INLINE ap_uint(const volatile ap_uint<_AP_W>& op):Base(dynamic_cast&>(op)){} + template + INLINE ap_uint(const volatile ap_uint<_AP_W2> &op):Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_uint<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)){} + + template + INLINE ap_uint(const ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_uint(const volatile ap_int<_AP_W2> &op) : Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_uint(const ap_range_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_bit_ref<_AP_W2, _AP_S2>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref):Base(ref) {} + + template + INLINE ap_uint(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op.to_ap_private()) {} + + template + INLINE ap_uint(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, _AP_N2>& op) + :Base(op) {} + + template + INLINE ap_uint(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + template + INLINE ap_uint(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2>& op):Base(op) {} + + template + INLINE ap_uint(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op.to_ap_private()) {} + +#define CTOR(TYPE) \ + INLINE ap_uint(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_uint(const char* str, signed char rd):Base(str, rd) {} + //Assignment + //Another form of "write" + INLINE void operator = (const ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE void operator = (const volatile ap_uint<_AP_W>& op2) volatile { + Base::operator = (op2); + } + + INLINE ap_uint<_AP_W>& operator = (const volatile ap_uint<_AP_W>& op2) { + Base::operator = (op2); + return *this; + } + + INLINE ap_uint<_AP_W>& operator = (const ap_uint<_AP_W>& op2) { + Base::operator = ((const ap_private<_AP_W, false>&)(op2)); + return *this; + } +}; + +#define ap_bigint ap_int +#define ap_biguint ap_uint + +//AP_FIXED +//--------------------------------------------------------------------- +template +class ap_fixed: public ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef ap_fixed_base<_AP_W, _AP_I, true, _AP_Q, _AP_O, _AP_N> Base; + //Constructor + INLINE ap_fixed():Base() {} + + template + INLINE ap_fixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const ap_uint<_AP_W2>& op):Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_fixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, _AP_O2, + _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_fixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_fixed(const volatile ap_uint<_AP_W2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_fixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_fixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_fixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_fixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_fixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_fixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_fixed& operator = (const ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_fixed& operator = (const volatile ap_fixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } +}; + +//AP_ UFIXED +//--- ---------------------------------------------------------------- +template +class ap_ufixed : public ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> { +#ifdef _MSC_VER +#pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + typedef ap_fixed_base<_AP_W, _AP_I, false, _AP_Q, _AP_O, _AP_N> Base; + + //Constructor + INLINE ap_ufixed():Base() {} + + template + INLINE ap_ufixed(const ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const ap_int<_AP_W2>& op): + Base((const ap_private<_AP_W2, true>&)(op)) {} + + template + INLINE ap_ufixed(const ap_uint<_AP_W2>& op): + Base((const ap_private<_AP_W2, false>&)(op)) {} + + template + INLINE ap_ufixed(const volatile ap_fixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op) : Base(ap_fixed_base<_AP_W2, + _AP_I2, true, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_ufixed<_AP_W2, _AP_I2, _AP_Q2, + _AP_O2, _AP_N2>& op): Base(ap_fixed_base<_AP_W2, _AP_I2, + false, _AP_Q2, _AP_O2, _AP_N2>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_int<_AP_W2>& op): + Base(ap_private<_AP_W2, true>(op)) {} + + template + INLINE ap_ufixed(const volatile ap_uint<_AP_W2>& op): + Base(ap_private<_AP_W2, false>(op)) {} + + template + INLINE ap_ufixed(const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2>& op):Base(op) {} + + template + INLINE ap_ufixed(const ap_bit_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_range_ref<_AP_W2, _AP_S2>& op): + Base(op) {} + + template + INLINE ap_ufixed(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op): + Base(op) {} + + template + INLINE ap_ufixed(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& op): Base(op) {} + + template + INLINE ap_ufixed(const ap_private<_AP_W2, _AP_S2>& op):Base(op) {} + + #define CTOR(TYPE) \ + INLINE ap_ufixed(TYPE v):Base(v) {} + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(int) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) + CTOR(const char*) + CTOR(const std::string&) +#undef CTOR + INLINE ap_ufixed(const char* str, signed char rd):Base(str, rd) {} + + //Assignment + INLINE ap_ufixed& operator = (const ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::operator = (op); + return *this; + } + + INLINE ap_ufixed& operator = (const volatile ap_ufixed<_AP_W, _AP_I, + _AP_Q, _AP_O, _AP_N>& op) { + Base::V = const_cast(op); + return *this; + } +}; + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_int<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_uint<_AP_W> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_fixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} + +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_ufixed<_AP_W, _AP_I, _AP_Q, _AP_O, _AP_N >&op, const std::string &name) { + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif /* #if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) */ +#endif /* #ifndef __cplusplus */ +#endif /* #ifndef __AESL_AP_SIM_H__ */ \ No newline at end of file diff --git a/hls_2018/router_05/etc/ap_fixed_sim.h b/hls_2018/router_05/etc/ap_fixed_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..5be571dd70e490d282d279a4eeed32db069703e9 --- /dev/null +++ b/hls_2018/router_05/etc/ap_fixed_sim.h @@ -0,0 +1,2451 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_FIXED_H__ +#define __AESL_GCC_AP_FIXED_H__ + +#ifndef __cplusplus + #error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + + +#include +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_int_sim.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#define FLOAT_MAN 23 +#define FLOAT_EXP 8 +#define DOUBLE_MAN 52 +#define DOUBLE_EXP 11 +// #define DOUBLE_MAN_MASK (~0ULL >> (64-DOUBLE_MAN-2)) +#define DOUBLE_MAN_MASK 0x3fffffffffffffULL +#define BIAS(e) ((1ULL<<(e-1))-1) +#define FLOAT_BIAS BIAS(FLOAT_EXP) +#define DOUBLE_BIAS BIAS(DOUBLE_EXP) + +/// Forward declaration. +template struct ap_fixed_base; + +///Proxy class, which allows bit selection to be used as both rvalue(for reading) and +//lvalue(for writing) +template +struct af_bit_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& d_bv; + int d_index; +public: + INLINE af_bit_ref(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE af_bit_ref(ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>* bv, int index=0): + d_bv(*bv),d_index(index) {} + + INLINE operator bool() const { + return d_bv.V[d_index]; + } + + INLINE af_bit_ref& operator=(unsigned long long val) { + if (val) + d_bv.V.set(d_index); + else + d_bv.V.clear(d_index); + return *this; + } + + template + INLINE af_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + return operator=(val!=0); + } + + INLINE af_bit_ref& operator =(const af_bit_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref operator=(const af_bit_ref<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)val); + } + + template + INLINE af_bit_ref& operator = ( const ap_bit_ref<_AP_W2, _AP_S2> &val) { + return operator =((unsigned long long) (bool) val); + } + + template + INLINE af_bit_ref& operator = ( const ap_range_ref<_AP_W2,_AP_S2>& val) { + return operator =((const ap_private<_AP_W2, false>) val); + } + + template + INLINE af_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE af_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, + _AP_N2> >(*this, const_cast& >(op)); + } + + template + INLINE ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<1, af_bit_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + template + INLINE bool operator == (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const af_bit_ref<_AP_W2, _AP_I2, + _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + return get() != op.get(); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv.V)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { + return 1; + } + + INLINE bool get() { + return d_bv.V[d_index]; + } + + INLINE bool get() const { + return d_bv.V[d_index]; + } + + INLINE std::string to_string() const { + return d_bv.V[d_index] ? "1" : "0"; + } +}; + +///Range(slice) reference +//------------------------------------------------------------ +template +struct af_range_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &d_bv; + int l_index; + int h_index; + +public: + INLINE af_range_ref(const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE af_range_ref(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + // fprintf(stderr, + //"Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + if (h_index >= l_index) { + ap_private<_AP_W, false> val(d_bv.V); + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + return val&=mask; + } else { + ap_private<_AP_W, false> val = 0; + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } + } + + INLINE operator unsigned long long() const { + return get().to_uint64(); + } + + template + INLINE af_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W, false> vval= ap_private<_AP_W, false>(val); + if (l_index > h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv.V &= mask; + d_bv.V |= vval; + } + return *this; + } + + INLINE af_range_ref& operator = (unsigned long long val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE af_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE af_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + const ap_private<_AP_W2, false> tmp= val.get(); + return operator = (tmp); + } + + INLINE af_range_ref& operator= (const af_range_ref<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& val) { + const ap_private<_AP_W, false> tmp= val.get(); + return operator = (tmp); + } + + template + INLINE af_range_ref& operator= (const ap_fixed_base<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE bool operator == (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + template + INLINE bool operator != (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + template + INLINE bool operator > (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + template + INLINE bool operator >= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + template + INLINE bool operator < (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op2) { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + template + INLINE void set(const ap_private<_AP_W2,false>& val) { + ap_private<_AP_W,_AP_S> vval=val; + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + vval[i]? d_bv.V.set(j):d_bv.V.clear(j); + } else { + ap_private<_AP_W,_AP_S> mask(-1); + if (l_index>0) { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if (h_index<_AP_W-1) { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } + + } + + INLINE ap_private<_AP_W,false> get() const { + if (h_index val(0); + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if ((d_bv.V)[j]) val.set(i); + return val; + } else { + ap_private<_AP_W, false> val = ap_private<_AP_W,false>(d_bv.V); + val>>= l_index; + if (h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + return val; + } + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_private<_AP_W2, _AP_S2> >(*this, op); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2 + _AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, _AP_W2, + af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& > (op)); + } + + template + INLINE ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &op) { + return ap_concat_ref<_AP_W, af_range_ref, 1, + af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(op)); + } + + INLINE int length() const { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + INLINE int to_int() const { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + INLINE unsigned int to_uint() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + INLINE long to_long() const { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + INLINE unsigned long to_ulong() const { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + INLINE ap_slong to_int64() const { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + INLINE ap_ulong to_uint64() const { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix) const { + return get().to_string(radix); + } + +}; + +//----------------------------------------------------------------------------- +///ap_fixed_base: AutoPilot fixed point +//----------------------------------------------------------------------------- +template +struct ap_fixed_base { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ +public: + template friend struct +ap_fixed_base; + template friend struct +af_bit_ref; + + INLINE void overflow_adjust(bool underflow, bool overflow, + bool lD, bool sign) { + if (!overflow && !underflow) return; + switch (_AP_O) { + case AP_WRAP: + if (_AP_N == 0) + return; + if (_AP_S) { + //signed SC_WRAP + //n_bits == 1; + if (_AP_N > 1) { + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= ~mask; + } + sign ? V.set(_AP_W - 1) : V.clear(_AP_W - 1); + } else { + //unsigned SC_WRAP + ap_private<_AP_W, _AP_S> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + mask.flip(); + V |= mask; + } + break; + case AP_SAT_ZERO: + V.clear(); + break; + case AP_WRAP_SM: + { + bool Ro = ap_private_ops::get<_AP_W, _AP_S, _AP_W -1>(V); // V[_AP_W -1]; + if (_AP_N == 0) { + if (lD != Ro) { + V.flip(); + lD ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : + ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } else { + if (_AP_N == 1 && sign != Ro) { + V.flip(); + } else if (_AP_N > 1) { + bool lNo = ap_private_ops::get<_AP_W, _AP_S, _AP_W - _AP_N> (V); // V[_AP_W - _AP_N]; + if (lNo == sign) + V.flip(); + ap_private<_AP_W, false> mask(-1); + if (_AP_N >= _AP_W) mask = 0; + else mask.lshr(_AP_N); + if (sign) + V &= mask; + else + V |= mask.flip(); + sign ? ap_private_ops::set<_AP_W, _AP_S, _AP_W - 1>(V) : ap_private_ops::clear<_AP_W, _AP_S, _AP_W - 1>(V); + } + } + } + break; + default: + if (_AP_S) { + if (overflow) { + V.set(); ap_private_ops::clear<_AP_W, _AP_S, _AP_W-1>(V); + } else if (underflow) { + V.clear(); + ap_private_ops::set<_AP_W, _AP_S, _AP_W-1>(V); + if (_AP_O == AP_SAT_SYM) + ap_private_ops::set<_AP_W, _AP_S, 0>(V); + } + } else { + if (overflow) + V.set(); + else if (underflow) + V.clear(); + } + } + } + + INLINE bool quantization_adjust(bool qb, bool r, bool s) { + bool carry=ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V); + switch (_AP_Q) { + case AP_TRN: + return false; + case AP_RND_ZERO: + qb &= s || r; + break; + case AP_RND_MIN_INF: + qb &= r; + break; + case AP_RND_INF: + qb &= !s || r; + break; + case AP_RND_CONV: + qb &= ap_private_ops::get<_AP_W, _AP_S, 0>(V) || r; + break; + case AP_TRN_ZERO: + qb = s && ( qb || r ); + break; + default:; + + } + if (qb) ++V; + //only when old V[_AP_W-1]==1 && new V[_AP_W-1]==0 + return carry && !(ap_private_ops::get<_AP_W, _AP_S, _AP_W-1>(V)); //(!V[_AP_W-1]); + } + + template + struct RType { + enum { + _AP_F=_AP_W-_AP_I, + F2=_AP_W2-_AP_I2, + mult_w = _AP_W+_AP_W2, + mult_i = _AP_I+_AP_I2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + plus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1+AP_MAX(_AP_F,F2), + minus_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+1, + minus_s = true, +#ifndef __SC_COMPATIBLE__ + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2, +#else + div_w = _AP_W + AP_MAX(_AP_W2 - _AP_I2, 0) + _AP_S2 + AP_MAX(_AP_I2, 0), +#endif /* #ifndef __SC_COMPATIBLE__ */ + div_i = _AP_I + (_AP_W2-_AP_I2) + _AP_S2, + div_s = _AP_S||_AP_S2, + logic_w = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2))+AP_MAX(_AP_F,F2), + logic_i = AP_MAX(_AP_I+(_AP_S2&&!_AP_S),_AP_I2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + + typedef ap_fixed_base mult; + typedef ap_fixed_base plus; + typedef ap_fixed_base minus; + typedef ap_fixed_base logic; + typedef ap_fixed_base div; + typedef ap_fixed_base<_AP_W, _AP_I, _AP_S> arg1; + }; + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024):" + " for synthesis, please define macro AP_INT_TYPE_EXT(N) to" + " extend the valid range.\n", _AP_W); + } else +#endif /* #if 0 */ + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sfixed<%d, ...>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + /// Constructors. + // ------------------------------------------------------------------------- +#if 0 + #ifdef __SC_COMPATIBLE__ + INLINE ap_fixed_base():V(uint32_t(_AP_W), uint64_t(0)) {} + #else + INLINE ap_fixed_base():V(uint32_t(_AP_W)) {} + #endif /* #ifdef __SC_COMPATIBLE__ */ +#else + INLINE ap_fixed_base():V(0) {} +#endif /* #if 0 */ + // INLINE ap_fixed_base():V() {} + // INLINE explicit ap_fixed_base(const ap_private<_AP_W+_AP_I, _AP_S>& _V):V(_V) {} + INLINE ap_fixed_base(const ap_fixed_base& op):V(op.V) {} + template + INLINE ap_fixed_base(const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op):V(0) { + enum {N2=_AP_W2,_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2,QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || + (_AP_Q==AP_TRN_ZERO && !_AP_S2))}; + if (!op) return; + bool carry=false; + //handle quantization + enum { sh_amt =(F2>_AP_F)?F2-_AP_F:_AP_F-F2}; + const ap_private<_AP_W2, _AP_S2>& val = op.V; + bool neg_src=val.isNegative(); + if (F2==_AP_F) + V=val; + + else if (F2>_AP_F) { + if (sh_amt >= _AP_W2) + V = neg_src ? -1 : 0; + else + V = _AP_S2?val.ashr(sh_amt):val.lshr(sh_amt); + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + bool qb = false; + if (F2-_AP_F>_AP_W2) + qb = neg_src; + else + qb = ap_private_ops::get<_AP_W2, _AP_S2, F2-_AP_F-1>(val); + + bool r=false; + enum { pos3 = F2-_AP_F-2}; + if (pos3>=_AP_W2-1) + r=val!=0; + else if (pos3>=0) + r = (val<<(_AP_W2-1-pos3))!=0; + carry = quantization_adjust(qb,r,neg_src); + } + } else { //no quantization + if (sh_amt < _AP_W) { + V=val; + V <<= sh_amt; + } + } + //hanle overflow/underflow + if ((_AP_O!=AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2 - _AP_S2 + (QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)))) {//saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool lD=(_AP_I2>_AP_I && _AP_W2-_AP_I2+_AP_I>=0) && + ap_private_ops::get<_AP_W2, _AP_S2, _AP_W2-_AP_I2+_AP_I>(val); + enum { pos1=F2-_AP_F+_AP_W, pos2=F2-_AP_F+_AP_W+1}; + if (pos1 < _AP_W2) { + bool Range1_all_ones= true; + bool Range1_all_zeros= true; + if (pos1 >= 0) { + enum { __W = (_AP_W2-pos1) > 0 ? (_AP_W2-pos1) : 1 }; + const ap_private<__W, _AP_S2> Range1=ap_private<__W, _AP_S2>(val.lshr(pos1)); + Range1_all_ones=Range1.isAllOnesValue(); + Range1_all_zeros=Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros=val.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + enum { __W = (_AP_W2-pos2)>0 ? (_AP_W2-pos2) : 1}; + ap_private<__W, true> Range2=ap_private<__W, true>(val.lshr(pos2)); + Range2_all_ones=Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) + :Range1_all_ones; + neg_src= neg_src&&!(carry && Range1_all_ones); + } else + neg_src = neg_src && V[_AP_W-1]; + + bool neg_trg= V.isNegative(); + bool overflow=(neg_trg||!deleted_zeros) && !val.isNegative(); + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow, overflow, lD, neg_src); + } + report(); + } + + template + INLINE ap_fixed_base(const volatile ap_fixed_base<_AP_W2,_AP_I2, + _AP_S2,_AP_Q2,_AP_O2, _AP_N2> &op) : V(op.V) { + *this = const_cast&>(op); + } + + template + INLINE ap_fixed_base(const ap_private<_AP_W2,_AP_S2>& op) { + ap_fixed_base<_AP_W2,_AP_W2,_AP_S2> f_op; + f_op.V=op; + *this = f_op; + } + + INLINE ap_fixed_base(bool b) { + *this=(ap_private<1,false>)b; + report(); + } + + INLINE ap_fixed_base(char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed char b) { + *this=(ap_private<8,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned char b) { + *this=(ap_private<8,false>)b; + report(); + } + + INLINE ap_fixed_base(signed short b) { + *this=(ap_private<16,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned short b) { + *this=(ap_private<16,false>)b; + report(); + } + + INLINE ap_fixed_base(signed int b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned int b) { + *this=(ap_private<32,false>)b; + report(); + } +# if defined __x86_64__ + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<64,false>)b; + report(); + } +# else + INLINE ap_fixed_base(signed long b) { + *this=(ap_private<32,true>)b; + report(); + } + + INLINE ap_fixed_base(unsigned long b) { + *this=(ap_private<32,false>)b; + report(); + } +# endif + + INLINE ap_fixed_base(ap_slong b) { + *this=(ap_private<64,true>)b; + report(); + } + + INLINE ap_fixed_base(ap_ulong b) { + *this=(ap_private<64,false>)b; + report(); + } + +#if 1 + INLINE ap_fixed_base(const char* val):V(0) { + ap_private<_AP_W, _AP_S> Tmp(val); + V = Tmp; + } + + INLINE ap_fixed_base(const char* val, signed char rd): V(0) { + ap_private<_AP_W, _AP_S> Tmp(val, rd); + V = Tmp; + } + +#endif + + INLINE ap_fixed_base(const std::string& val) { + ap_private<_AP_W, _AP_S> Tmp(val, 2); + V = Tmp; + report(); + } + + template + INLINE ap_fixed_base(const ap_bit_ref<_AP_W2, _AP_S2>& op) { + *this = ((bool)op); + report(); + } + + template + INLINE ap_fixed_base(const ap_range_ref<_AP_W2, _AP_S2>& op) { + *this = ap_private<_AP_W2, _AP_S2>(op); + report(); + } + + template + INLINE ap_fixed_base(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op) { + *this = ((const ap_private<_AP_W2 + _AP_W3, false>&)(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (bool(op)); + report(); + } + + template + INLINE ap_fixed_base(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + *this = (ap_private<_AP_W2, false>(op)); + report(); + } + + //helper function + INLINE unsigned long long doubleToRawBits(double pf)const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__D=pf; + return LD.__L; + } + + + INLINE double rawBitsToDouble(unsigned long long pi) const { + union { + unsigned long long __L; + double __D; + }LD; + LD.__L=pi; + return LD.__D; + } + + INLINE float rawBitsToFloat(uint32_t pi) const { + union { + uint32_t __L; + float __D; + }LD; + LD.__L = pi; + return LD.__D; + } + + INLINE ap_fixed_base(double d):V(0) { + if (!d) return; + const bool isneg=d<0; + + const uint64_t ireg=doubleToRawBits(isneg?-d:d); + if ((ireg&0x7fffffffffffffffULL)!=0) { + const int32_t exp=(((ireg)>>DOUBLE_MAN)&0x07ff)-DOUBLE_BIAS; + ap_private man = ireg & DOUBLE_MAN_MASK; + man.clear(DOUBLE_MAN+1); + man.set(DOUBLE_MAN); + if (isneg) { + man.flip(); + man++; + } + + enum {_AP_S2=true, _AP_W2=DOUBLE_MAN+2,_AP_F=_AP_W -_AP_I }; + const int _AP_I2=exp+2; + const int F2=_AP_W2-_AP_I2; + const bool QUAN_INC=F2>_AP_F && !(_AP_Q==AP_TRN || (_AP_Q==AP_TRN_ZERO && + !_AP_S2)); + bool carry=false; + //handle quantization + const unsigned sh_amt=abs(F2-_AP_F); // sh_amt = F2>_AP_F ? F2 -_AP_F : _AP_F-F2; + if (F2==_AP_F ) + V=man; + else if (F2>_AP_F) { + if (sh_amt >= DOUBLE_MAN+2) + V=isneg?-1:0; + else + V=(man>>sh_amt) | ((man & 1ULL<<(DOUBLE_MAN+1)) ? (DOUBLE_MAN_MASK>>(DOUBLE_MAN+2-sh_amt) <<(DOUBLE_MAN+2-sh_amt)):0); + + if (_AP_Q!=AP_TRN && !(_AP_Q==AP_TRN_ZERO && !_AP_S2)) { + const bool qb=((F2-_AP_F > DOUBLE_MAN+2) ? isneg : (man & (1ULL<<(F2-_AP_F-1))) != 0); + const int pos3=F2-_AP_F-2; + const bool r = (pos3>= 0) ? (man << AP_MAX(0, _AP_W2-pos3-1)& DOUBLE_MAN_MASK)!=0 : false; + carry = quantization_adjust(qb,r,isneg); + } + } + else { //no quantization + // V=man; + if (sh_amt < _AP_W) { + V = man; + V <<= sh_amt; + } + } + //handle overflow/underflow + if ((_AP_O != AP_WRAP || _AP_N != 0) && + ((!_AP_S && _AP_S2) || _AP_I-_AP_S < + _AP_I2-_AP_S2+(QUAN_INC|| (_AP_S2 && + _AP_O==AP_SAT_SYM)) )) {// saturation + bool deleted_zeros = _AP_S2?true:!carry, + deleted_ones = true; + bool neg_src; + const bool lD=(_AP_I2>_AP_I) && (_AP_W2-_AP_I2+_AP_I>=0) && (man & (1ULL <<(DOUBLE_MAN+2-_AP_I2+_AP_I))); + int pos1=F2+_AP_W-_AP_F; + if (pos1 < _AP_W2) { + int pos2=pos1+1; + bool Range1_all_ones=true; + bool Range1_all_zeros=true; + if (pos1>=0) { + ap_private<_AP_W,_AP_S> Range1= + ap_private<_AP_W,_AP_S>((man >> pos1) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos1) <<(DOUBLE_MAN+2-pos1)):0)); + Range1_all_ones = Range1.isAllOnesValue(); // Range1.isAllOnesValue(); + Range1_all_zeros = Range1.isMinValue(); // Range1.isMinValue(); + } else { + Range1_all_ones=false; + Range1_all_zeros = man==0; // man.isMinValue(); + } + bool Range2_all_ones=true; + if (pos2<_AP_W2 && pos2>=0) { + ap_private<_AP_W, _AP_S> Range2= + ap_private<_AP_W, _AP_S>((man >> pos2) | ((1ULL<<(DOUBLE_MAN+1)&man) ? (DOUBLE_MAN_MASK >> (DOUBLE_MAN+2-pos2) <<(DOUBLE_MAN+2-pos2)):0)); + Range2_all_ones=Range2.isAllOnesValue(); // Range2.isAllOnesValue(); + } else if (pos2<0) + Range2_all_ones=false; + deleted_zeros=deleted_zeros && (carry?Range1_all_ones:Range1_all_zeros); + deleted_ones=carry?Range2_all_ones&&(F2-_AP_F+_AP_W<0||!lD) : Range1_all_ones; + neg_src=isneg&&!(carry&Range1_all_ones); + } else + neg_src = isneg && V[_AP_W -1]; + + const bool neg_trg=V.isNegative(); + const bool overflow=(neg_trg||!deleted_zeros) && !isneg; + bool underflow=(!neg_trg||!deleted_ones)&&neg_src; + //printf("neg_src = %d, neg_trg = %d, deleted_zeros = %d, + // deleted_ones = %d, overflow = %d, underflow = %d\n", + // neg_src, neg_trg, deleted_zeros, deleted_ones, + // overflow, underflow); + if (_AP_O==AP_SAT_SYM && _AP_S2 && _AP_S) + underflow |= neg_src && (_AP_W>1?V.isMinSignedValue():true); + overflow_adjust(underflow,overflow,lD, neg_src); + } + } + report(); + } + + + ///assign operators + //------------------------------------------------------------------------- + + INLINE volatile ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + INLINE volatile ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) volatile { + V = op.V; + return *this; + } + + INLINE ap_fixed_base& operator=(const volatile ap_fixed_base<_AP_W, _AP_I, _AP_S, + _AP_Q, _AP_O, _AP_N>& op) { + V = op.V; + return *this; + } + + // Set this ap_fixed_base with a bits string. That means the ssdm_int::V + // inside this ap_fixed_base is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + INLINE ap_fixed_base& setBits(unsigned long long bv) { + V=bv; + return *this; + } + + // Return a ap_fixed_base object whose ssdm_int::V is assigned by bv. + // Note the input parameter should be a fixed-point formatted bit string. + static INLINE ap_fixed_base bitsToFixed(unsigned long long bv) { + ap_fixed_base Tmp=bv; + return Tmp; + } + + // Explicit conversion functions to ap_private that captures + // all integer bits (bits are truncated) + INLINE ap_private + to_ap_private(bool Cnative = true) const { + ap_private ret = ap_private ((_AP_I >= 1) ? (_AP_S==true ? V.ashr(AP_MAX(0,_AP_W - _AP_I)) : V.lshr(AP_MAX(0,_AP_W - _AP_I))) : ap_private<_AP_W, _AP_S>(0)); + + if (Cnative) { + bool r = false; + if (_AP_I < _AP_W) { + if (_AP_I > 0) r = !(V.getLoBits(_AP_W - _AP_I).isMinValue()); + else r = !(V.isMinValue()); + } + if (r && V.isNegative()) { // if this is negative integer + ++ret;//ap_private(1,_AP_S); + } + } else { + //Follow OSCI library, conversion from sc_fixed to sc_int + } + return ret; + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2> () const { + return (ap_private<_AP_W2,_AP_S2>)to_ap_private(); + } + + template + INLINE operator ap_private<_AP_W2,_AP_S2,_AP_N2> () const { + return (ap_private<_AP_W2,_AP_S2,_AP_N2>)to_ap_private(); + } + + //Explict conversion function to C built-in integral type + INLINE int to_int() const { + return to_ap_private().to_int(); + } + + INLINE int to_uint() const { + return to_ap_private().to_uint(); + } + + INLINE ap_slong to_int64() const { + return to_ap_private().to_int64(); + } + + INLINE ap_ulong to_uint64() const { + return to_ap_private().to_uint64(); + } + + INLINE double to_double() const { + if (!V) + return 0; + if (_AP_W>64 || (_AP_W - _AP_I) > 0) { + bool isneg = _AP_S && V[_AP_W-1]; + uint64_t res = isneg ? 0x8000000000000000ULL : 0; + ap_private<_AP_W, false> tmp = V; + if (isneg) tmp = -tmp; + int i = _AP_W -1 - tmp.countLeadingZeros(); + int exp = _AP_I-(_AP_W-i); + res|=((uint64_t)(exp+DOUBLE_BIAS))<DOUBLE_MAN)?tmp.lshr(i-DOUBLE_MAN):tmp).to_uint64() & DOUBLE_MAN_MASK; + res |= i 0) { + /* This specialization is disabled. It is giving wrong results in some cases. + bool isneg=V.isNegative(); + double dp = V.get(); + dp /= (1<< (_AP_W - _AP_I)); + return dp;*/ + } else + return double(to_int64()); + } + + INLINE float to_float() const { + uint32_t res=0; + if (V==0) + return 0; + bool isneg=V.isNegative(); + ap_private<_AP_W, _AP_S> tmp=V; + if (isneg) tmp = -tmp; + if (_AP_W-_AP_I>0||_AP_W>64) { + if (isneg) + res=0x80000000; + int i=_AP_W-1; + i-=tmp.countLeadingZeros(); + int exp=_AP_I-(_AP_W-i); + res|=(exp+FLOAT_BIAS)< man = 0; + if (i!=0) { + tmp.clear(i); + if (i>FLOAT_MAN) + man=tmp.lshr(i-FLOAT_MAN); + else + man=tmp; + res |= i < FLOAT_MAN?man.getZExtValue()<<(FLOAT_MAN-i):man.getZExtValue(); + } + } else { + return float(to_int64()); + } + float dp=rawBitsToFloat(res); + return dp; + } + + INLINE operator double () const { + return to_double(); + } +#ifndef __SC_COMPATIBLE__ + INLINE operator float () const { + return to_float(); + } + + INLINE operator char () const { + return (char) to_int(); + } + + INLINE operator unsigned char () const { + return (unsigned char) to_uint(); + } + + INLINE operator short () const { + return (short) to_int(); + } + + INLINE operator unsigned short () const { + return (unsigned short) to_uint(); + } + + INLINE operator int () const { + return to_int(); + } + + INLINE operator unsigned int () const { + return to_uint(); + } +#if 1 +#ifdef __x86_64__ + INLINE operator long () const { + return (long)to_int64(); + } + + INLINE operator unsigned long () const { + return (unsigned long) to_uint64(); + } +#else + INLINE operator long () const { + return to_int64(); + } + + INLINE operator unsigned long () const { + return to_uint64(); + } + +#endif +#endif + INLINE operator unsigned long long () const { + return to_uint64(); + } + + INLINE operator long long () const { + return to_int64(); + } +#endif + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const; + + INLINE ap_slong bits_to_int64() const { + ap_private res(V); + return (ap_slong) res; + } + + INLINE ap_ulong bits_to_uint64() const { + ap_private res(V); + return (ap_ulong) res; + } + + INLINE int length() const {return _AP_W;} + + // Count the number of zeros from the most significant bit + // to the first one bit. Note this is only for ap_fixed_base whose + // _AP_W <= 64, otherwise will incur assertion. + INLINE int countLeadingZeros() { + return V.countLeadingZeros(); + } + + ///Arithmetic:Binary + //------------------------------------------------------------------------- + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::mult + operator * (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + typename RType<_AP_W2,_AP_I2,_AP_S2>::mult r; + r.V = V * op2.V; + return r; + } + + template + static INLINE ap_fixed_base multiply(const ap_fixed_base<_AP_W1,_AP_I1,_AP_S1>& op1, const + ap_fixed_base<_AP_W2,_AP_I2,_AP_S2>& op2) { + ap_private<_AP_W+_AP_W2, _AP_S> OP1=op1.V; + ap_private<_AP_W2,_AP_S2> OP2=op2.V; + return OP1*OP2; + } + + template + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::div + operator / (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {F2 = _AP_W2-_AP_I2, _W1=AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2), + _W2=AP_MAX(_AP_W2,AP_MAX(_AP_W + AP_MAX(F2, 0), _AP_W2))}; + ap_private<_W1, _AP_S> dividend = (ap_private<_W1, _AP_S>(V)) << ((_W1>_AP_W)?F2:0); + ap_private<_W1, _AP_S2> divisior = ap_private<_W2, _AP_S2>(op2.V); + ap_private<_W1, _AP_S> ret = ap_private<_W1,_AP_S> ((_AP_S||_AP_S2) ? dividend.sdiv(divisior): dividend.udiv(divisior)); + typename RType<_AP_W2, _AP_I2, _AP_S2>::div r; + r.V = ret; + return r; + } +#define OP_BIN_AF(Sym, Rty, Width, Sign, Fun) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + enum {_AP_F=_AP_W-_AP_I, F2=_AP_W2-_AP_I2}; \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V = lhs.V.Fun(rhs.V); \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + + OP_BIN_AF(+, plus, plus_w, plus_s, Add) + OP_BIN_AF(-, minus, minus_w, minus_s, Sub) + +#define OP_LOGIC_BIN_AF(Sym, Rty, Width, Sign) \ + template \ + INLINE typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty \ + operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + typename RType<_AP_W2,_AP_I2,_AP_S2>::Rty r, lhs(*this), rhs(op2); \ + r.V=lhs.V Sym rhs.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty \ + operator Sym (const ap_fixed_base& op2) const \ + { \ + typename RType<_AP_W,_AP_I,_AP_S>::Rty r; \ + r.V = V Sym op2.V; \ + return r; \ + } \ + INLINE typename RType<_AP_W,_AP_I,_AP_S>::Rty operator Sym(int op2) const \ + { \ + return V Sym (op2<<(_AP_W - _AP_I)); \ + } + OP_LOGIC_BIN_AF(&, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(|, logic, logic_w, logic_s) + OP_LOGIC_BIN_AF(^, logic, logic_w, logic_s) + + ///Arithmic : assign + //------------------------------------------------------------------------- +#define OP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2) ; \ + return *this; \ + } + + OP_ASSIGN_AF(+) + OP_ASSIGN_AF(-) + OP_ASSIGN_AF(&) + OP_ASSIGN_AF(|) + OP_ASSIGN_AF(^) + OP_ASSIGN_AF(*) + OP_ASSIGN_AF(/) + + ///Prefix increment, decrement + //------------------------------------------------------------------------- + INLINE ap_fixed_base& operator ++() { + operator+=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + INLINE ap_fixed_base& operator --() { + operator-=(ap_fixed_base<1,1,false>(1)); //SystemC's semantics + return *this; + } + + //Postfix increment, decrement + //------------------------------------------------------------------------- + INLINE const ap_fixed_base operator ++(int) { + ap_fixed_base t(*this); + operator++(); + return t; + } + + INLINE const ap_fixed_base operator --(int) { + ap_fixed_base t = *this; + operator--(); + return t; + } + + ///Unary arithmetic + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator +() {return *this;} + + INLINE ap_fixed_base<_AP_W + 1, _AP_I + 1, true> operator -() const { + ap_fixed_base<_AP_W + 1, _AP_I + 1, true> Tmp(*this); + Tmp.V = - Tmp.V; + return Tmp; + } + + INLINE ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> getNeg() { + ap_fixed_base<_AP_W,_AP_I,true,_AP_Q,_AP_O, _AP_N> Tmp(*this); + Tmp.V=-Tmp.V; + return Tmp; + } + + ///Not (!) + //------------------------------------------------------------------------- + INLINE bool operator !() const { + return !V; + } + + ///Bitwise complement + //------------------------------------------------------------------------- + INLINE ap_fixed_base<_AP_W, _AP_I, _AP_S> + operator ~() const { + ap_fixed_base<_AP_W, _AP_I, _AP_S> res(*this); + res.V.flip(); + return res; + } + + ///Shift + ///template argument as shift value + template + INLINE ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> lshift () const { + ap_fixed_base<_AP_W, _AP_I + _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + template + INLINE ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> rshift () const { + ap_fixed_base<_AP_W, _AP_I - _AP_SHIFT, _AP_S> r; + r.V = V; + return r; + } + + //Because the return type is the type of the the first operand, shift assign + //operators do not carry out any quantization or overflow + //While systemc, shift assigns for sc_fixed/sc_ufixed will result in + //quantization or overflow (depending on the mode of the first operand) + //------------------------------------------------------------------------- + INLINE ap_fixed_base operator << (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + bool NegSrc = V.isNegative(); + if (isNeg) { + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); + } else { + if (shiftoverflow) + r.V.clear(); + else + r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == false && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator<<(const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator << (sh); + } + + INLINE ap_fixed_base operator << (unsigned int sh ) const { + ap_fixed_base r; + bool shiftoverflow = sh >= _AP_W; + r.V = shiftoverflow ? ap_private<_AP_W, _AP_S >(0) : V << sh; + if (sh == 0) return r; +#ifdef __SC_COMPATIBLE__ + bool NegSrc = V.isNegative(); + if (_AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh -1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator << (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator << (sh); + } + + INLINE ap_fixed_base operator >> (int sh) const { + ap_fixed_base r; + bool isNeg=(sh&0x80000000) != 0; + bool NegSrc = V.isNegative(); + sh=isNeg?-sh:sh; + bool shiftoverflow = sh >= _AP_W; + if (isNeg && !shiftoverflow) r.V=V< 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } else if (isNeg == true && _AP_O != AP_WRAP) { + bool allones, allzeros; + if (sh < _AP_W ) { + ap_private<_AP_W, _AP_S > range1 = V.lshr(_AP_W - sh - 1); + allones = range1.isAllOnesValue(); + allzeros = range1.isMinValue(); + } else { + allones = false; + allzeros = V.isMinValue(); + } + bool overflow = !allzeros && !NegSrc; + bool underflow = !allones && NegSrc; + if (_AP_O == AP_SAT_SYM && _AP_S) + underflow |= NegSrc && (_AP_W > 1 ? r.V.isMinSignedValue():true); + bool lD = false; + if ( sh < _AP_W ) lD = V[_AP_W - sh - 1]; + r.overflow_adjust(underflow, overflow, lD, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,true>& op2) const { + int sh = op2.to_int(); + return operator >> (sh); + } + + INLINE ap_fixed_base operator >> (unsigned int sh) const { + ap_fixed_base r; + bool NegSrc = V.isNegative(); + bool shiftoverflow = sh >= _AP_W; + if (shiftoverflow) + NegSrc?r.V.set():r.V.clear(); + else + r.V=_AP_S?V.ashr(sh):V.lshr(sh); +#ifdef __SC_COMPATIBLE__ + if (sh == 0) return r; + if (_AP_Q != AP_TRN) { + bool qb = false; + if (sh <= _AP_W) qb = V[sh - 1]; + bool rb = false; + if (sh > 1 && sh <= _AP_W) + rb = (V << (_AP_W - sh + 1 )) != 0; + else if (sh > _AP_W) + rb = V != 0; + r.quantization_adjust(qb, rb, NegSrc); + } +#endif + return r; + } + + template + INLINE ap_fixed_base operator >> (const ap_private<_AP_W2,false>& op2) const { + unsigned int sh = op2.to_uint(); + return operator >> (sh); + } + + ///shift assign + //------------------------------------------------------------------------- +#define OP_AP_SHIFT_AP_ASSIGN_AF(Sym) \ + template \ + INLINE ap_fixed_base& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AP_ASSIGN_AF(<<) + OP_AP_SHIFT_AP_ASSIGN_AF(>>) + + ///Support shift(ap_fixed_base) +#define OP_AP_SHIFT_AF(Sym) \ + template \ + INLINE ap_fixed_base operator Sym (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const \ + { \ + return operator Sym (op2.to_ap_private()); \ + } \ + template \ + INLINE ap_fixed_base& operator Sym##= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) \ + { \ + *this=operator Sym (op2); \ + return *this; \ + } + + OP_AP_SHIFT_AF(<<) + OP_AP_SHIFT_AF(>>) + + INLINE ap_fixed_base& operator >>= (unsigned int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (unsigned int sh) { + *this = operator << (sh); + return *this; + } + + INLINE ap_fixed_base& operator >>= (int sh) { + *this = operator >> (sh); + return *this; + } + + INLINE ap_fixed_base& operator <<= (int sh) { + *this = operator << (sh); + return *this; + } + + ///Comparisons + //------------------------------------------------------------------------- + template + INLINE bool operator == (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator != (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this==op2); + } + + template + INLINE bool operator > (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator <= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this>op2); + } + + template + INLINE bool operator < (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + enum {_AP_F=_AP_W-_AP_I,F2=_AP_W2-_AP_I2, shAmt1 = AP_MAX(F2-_AP_F, 0), shAmt2 = AP_MAX(_AP_F-F2,0), _AP_W3 = (_AP_F==F2) ? AP_MAX(_AP_W,_AP_W2) : AP_MAX(_AP_W+shAmt1, _AP_W2+shAmt2)}; + ap_private<_AP_W3, _AP_S > OP1= ap_private<_AP_W3, _AP_S >(V)< OP2=ap_private<_AP_W3,_AP_S2 >(op2.V)< + INLINE bool operator >= (const ap_fixed_base<_AP_W2,_AP_I2,_AP_S2,_AP_Q2,_AP_O2, _AP_N2>& op2) const { + return !(*this) + DOUBLE_CMP_AF(>=) + DOUBLE_CMP_AF(<) + DOUBLE_CMP_AF(<=) + + // Bit and Slice Select + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> operator [] (unsigned int index) { + assert(index<_AP_W&&"Attemping to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit(unsigned int index) { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> bit (const ap_private<_AP_W2,_AP_S2>& index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int()); + } + + INLINE bool bit (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + INLINE bool operator [] (unsigned int index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index]; + } + + template + INLINE bool bit (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + template + INLINE bool operator [] (const ap_private<_AP_W2, _AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return V[index.to_uint()]; + } + + INLINE af_bit_ref<_AP_W, _AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit(int index) { + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + assert(index >= _AP_I - _AP_W&& "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index + _AP_W - _AP_I); + } + + template + INLINE af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N> get_bit (const ap_private<_AP_W2, true>& index) { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return af_bit_ref<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(this, index.to_int() + _AP_W - _AP_I); + } + + INLINE bool get_bit (int index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index + _AP_W - _AP_I]; + } + + template + INLINE bool get_bit (const ap_private<_AP_W2, true>& index) const { + assert(index >= _AP_I - _AP_W && "Attempting to read bit with negative index"); + assert(index < _AP_I && "Attempting to read bit beyond MSB"); + return V[index.to_int() + _AP_W - _AP_I]; + } + + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range(int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W) &&"Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast(this), Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + operator () (int Hi, int Lo) const { + return this->range(Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(this, Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + range(const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>(const_cast< + ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>*>(this), + Hi, Lo); + } + + template + INLINE af_range_ref<_AP_W,_AP_I,_AP_S, _AP_Q, _AP_O, _AP_N> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() { + return this->range(_AP_W - 1, 0); + } + + INLINE af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> + range() const { + return this->range(_AP_W - 1, 0); + } + + INLINE bool is_zero () const { + return V.isMinValue(); + } + + INLINE bool is_neg () const { + if (V.isNegative()) + return true; + return false; + } + + INLINE int wl () const { + return _AP_W; + } + + INLINE int iwl () const { + return _AP_I; + } + + INLINE ap_q_mode q_mode () const { + return _AP_Q; + } + + INLINE ap_o_mode o_mode () const { + return _AP_O; + } + + INLINE int n_bits () const { + return 0; + } + + //private: +public: + ap_private<_AP_W, _AP_S> V; +}; + +template +std::string ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>::to_string( + uint8_t radix, bool sign) const { + std::string str; + str.clear(); + char step; + std::string prefix; + switch (radix) { + case 2 : prefix = "0b"; step = 1; break; + case 8 : prefix = "0o"; step = 3; break; + case 16 : prefix = "0x"; step = 4; break; + default : break; + } + if (_AP_W <= _AP_I) + str = this->to_ap_private().to_string(radix, + radix == 10 ? _AP_S : sign); + else { + if (radix == 10) { + bool isNeg = _AP_S && V.isNegative(); + if (_AP_I > 0) { + ap_private int_part(0); + int_part = this->to_ap_private(); + str += int_part.to_string(radix, false); + } else { + if (isNeg) str += '-'; + } + ap_fixed_base<_AP_W, _AP_I, _AP_S> tmp(*this); + if (isNeg && _AP_I <= 0) tmp = -tmp; + ap_fixed_base<_AP_W - AP_MIN(_AP_I, 0), 0, false> frac_part = tmp; + if (frac_part == 0) return str; + str += "."; + while (frac_part != 0) { + char digit = (frac_part * radix).to_ap_private(); + str += static_cast(digit + '0'); + frac_part *= radix; + } + } else { + if (_AP_I > 0) { + for (signed i = _AP_W - _AP_I; i < _AP_W; i += step) { + + char digit = (char)(this->range(AP_MIN(i + step - 1, _AP_W - 1), i)); + str = (digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a')) + str; + } + } + str += '.'; + ap_fixed_base tmp(*this); + for (signed i = _AP_W - _AP_I - 1; i >= 0; i -= step) { + char digit = (char)(tmp.range(i, AP_MAX(0, i - step + 1))); + str += digit < 10 ? static_cast(digit + '0') : + static_cast(digit - 10 + 'a'); + } + } + } + str = prefix + str; + return str; +} + +template +INLINE void b_not(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = op.V; + ret.V.flip(); +} + +template +INLINE void b_and(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V & op2.V; +} + +template +INLINE void b_or(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V | op2.V; +} + +template +INLINE void b_xor(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op1, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op2) { + ret.V = op1.V ^ op2.V; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) { + ap_fixed_base<_AP_W2+!_AP_S2, _AP_I2+!_AP_S2, true, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp.V = - op.V; + ret = Tmp; +} + +template +INLINE void neg(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op) { + ret.V = -op.V; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_W2 - _AP_I2 + AP_MAX(_AP_I, _AP_I2), AP_MAX(_AP_I, _AP_I2), _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V <<= i; + ret = Tmp; +} + +template +INLINE void lshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = op.V << i; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op, + int i) { + ap_fixed_base<_AP_I2 + AP_MAX(_AP_W - _AP_I, _AP_W2 - _AP_I2), _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> Tmp; + Tmp = op; + Tmp.V = _AP_S2 ? Tmp.V.ashr(i): Tmp.V.lshr(i); + ret = Tmp; +} + +template +INLINE void rshift(ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& ret, + const ap_fixed_base<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N>& op, + int i) { + ret.V = _AP_S ? op.V.ashr(i): op.V.lshr(i); +} + +#define AF_CTOR_SPEC_BASE(_AP_W,_AP_S,C_TYPE) \ + template<> INLINE ap_fixed_base<_AP_W,_AP_W,_AP_S,AP_TRN,AP_WRAP>::ap_fixed_base(C_TYPE i_op):V(i_op) \ + { \ + } + +#define AF_CTOR_SPEC(__W,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,true,C_TYPE) \ + AF_CTOR_SPEC_BASE(__W,false,C_TYPE) + +AF_CTOR_SPEC(1,bool) +AF_CTOR_SPEC(8, signed char) +AF_CTOR_SPEC(8, unsigned char) +AF_CTOR_SPEC(16, signed short) +AF_CTOR_SPEC(16, unsigned short) +AF_CTOR_SPEC(32, signed int) +AF_CTOR_SPEC(32, unsigned int) +AF_CTOR_SPEC(64, ap_slong) +AF_CTOR_SPEC(64, ap_ulong) + +///Output streaming +//----------------------------------------------------------------------------- +template +INLINE std::ostream& +operator <<(std::ostream& os, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + os << x.to_double(); + return os; +} + +///Input streaming +//----------------------------------------------------------------------------- +template +INLINE std::istream& +operator >> (std::istream& os, ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + double d; + os >> d; + x = ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>(x); + return os; +} + +template +INLINE void print(const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& x) { + ap_private<_AP_W,_AP_S> data=x.V; + if (_AP_I>0) { + const ap_private<_AP_I,_AP_S> p1=data>>(_AP_W-_AP_I); + print(p1); + + } else + printf("0"); + printf("."); + if (_AP_I<_AP_W) { + const ap_private<_AP_W-_AP_I,false> p2=data; + print(p2,false); + } +} + +///Operators mixing Integers with ap_fixed_base +//----------------------------------------------------------------------------- +#if 1 +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP(ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#else +#define AF_BIN_OP_WITH_INT_SF(BIN_OP,C_TYPE,_AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op BIN_OP (i_op); \ + } +#define AF_BIN_OP_WITH_INT(BIN_OP, C_TYPE, _AP_W2,_AP_S2,RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V BIN_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } + +#endif +#if 1 +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.operator REL_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } +#else +#define AF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2,_AP_S2) \ + template \ + INLINE bool operator REL_OP (const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) \ + { \ + return op.V.operator REL_OP (i_op<<(_AP_W-_AP_I)); \ + } \ + \ + \ + template \ + INLINE bool operator REL_OP (C_TYPE i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) \ + { \ + return (i_op<<(_AP_W-_AP_I)) REL_OP (op.V.VAL); \ + } +#endif +#if 1 +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(i_op)); \ + } +#else +#define AF_ASSIGN_OP_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#define AF_ASSIGN_OP_WITH_INT_SF(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, C_TYPE i_op) { \ + return op.V.operator ASSIGN_OP (i_op); \ + } +#endif + +#define AF_OPS_WITH_INT(C_TYPE, WI, SI) \ + AF_BIN_OP_WITH_INT(+, C_TYPE, WI, SI, plus) \ + AF_BIN_OP_WITH_INT(-, C_TYPE, WI, SI, minus) \ + AF_BIN_OP_WITH_INT(*, C_TYPE, WI, SI, mult) \ + AF_BIN_OP_WITH_INT(/, C_TYPE, WI, SI, div) \ + AF_BIN_OP_WITH_INT_SF(>>, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT_SF(<<, C_TYPE, WI, SI, arg1) \ + AF_BIN_OP_WITH_INT(&, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(|, C_TYPE, WI, SI, logic) \ + AF_BIN_OP_WITH_INT(^, C_TYPE, WI, SI, logic) \ + \ + AF_REL_OP_WITH_INT(==, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(!=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(>=, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<, C_TYPE, WI, SI) \ + AF_REL_OP_WITH_INT(<=, C_TYPE, WI, SI) \ + \ + AF_ASSIGN_OP_WITH_INT(+=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(-=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(*=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(/=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(>>=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT_SF(<<=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(&=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(|=, C_TYPE, WI, SI) \ + AF_ASSIGN_OP_WITH_INT(^=, C_TYPE, WI, SI) + +AF_OPS_WITH_INT(bool, 1, false) +AF_OPS_WITH_INT(char, 8, true) +AF_OPS_WITH_INT(signed char, 8, true) +AF_OPS_WITH_INT(unsigned char, 8, false) +AF_OPS_WITH_INT(short, 16, true) +AF_OPS_WITH_INT(unsigned short, 16, false) +AF_OPS_WITH_INT(int, 32, true) +AF_OPS_WITH_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_OPS_WITH_INT(long, 64, true) +AF_OPS_WITH_INT(unsigned long, 64, false) +# else +AF_OPS_WITH_INT(long, 32, true) +AF_OPS_WITH_INT(unsigned long, 32, false) +# endif +AF_OPS_WITH_INT(ap_slong, 64, true) +AF_OPS_WITH_INT(ap_ulong, 64, false) + +#define AF_BIN_OP_WITH_AP_INT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>::template RType<_AP_W,_AP_I,_AP_S>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_fixed_base<_AP_W,_AP_I,_AP_S>::template RType<_AP_W2,_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator BIN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } + +#define AF_REL_OP_WITH_AP_INT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator REL_OP ( ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op).operator REL_OP (op); \ + } + +#define AF_ASSIGN_OP_WITH_AP_INT(ASSIGN_OP) \ + template \ + INLINE ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& operator ASSIGN_OP ( ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op, const ap_private<_AP_W2,_AP_S2>& i_op) { \ + return op.operator ASSIGN_OP (ap_fixed_base<_AP_W2,_AP_W2,_AP_S2>(i_op)); \ + } \ + template \ + INLINE ap_private<_AP_W2,_AP_S2>& operator ASSIGN_OP ( ap_private<_AP_W2,_AP_S2>& i_op, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op) { \ + return i_op.operator ASSIGN_OP (op.to_ap_private()); \ + } + +AF_BIN_OP_WITH_AP_INT(+, plus) +AF_BIN_OP_WITH_AP_INT(-, minus) +AF_BIN_OP_WITH_AP_INT(*, mult) +AF_BIN_OP_WITH_AP_INT(/, div) +AF_BIN_OP_WITH_AP_INT(&, logic) +AF_BIN_OP_WITH_AP_INT(|, logic) +AF_BIN_OP_WITH_AP_INT(^, logic) + +AF_REL_OP_WITH_AP_INT(==) +AF_REL_OP_WITH_AP_INT(!=) +AF_REL_OP_WITH_AP_INT(>) +AF_REL_OP_WITH_AP_INT(>=) +AF_REL_OP_WITH_AP_INT(<) +AF_REL_OP_WITH_AP_INT(<=) + +AF_ASSIGN_OP_WITH_AP_INT(+=) +AF_ASSIGN_OP_WITH_AP_INT(-=) +AF_ASSIGN_OP_WITH_AP_INT(*=) +AF_ASSIGN_OP_WITH_AP_INT(/=) +AF_ASSIGN_OP_WITH_AP_INT(&=) +AF_ASSIGN_OP_WITH_AP_INT(|=) +AF_ASSIGN_OP_WITH_AP_INT(^=) + +#define AF_REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ +template \ + INLINE bool operator REL_OP ( C_TYPE op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2 REL_OP (bool(op)); \ + } + +#define AF_REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +AF_REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +AF_REF_REL_MIX_INT(bool, 1, false) +AF_REF_REL_MIX_INT(char, 8, true) +AF_REF_REL_MIX_INT(signed char, 8, true) +AF_REF_REL_MIX_INT(unsigned char, 8, false) +AF_REF_REL_MIX_INT(short, 16, true) +AF_REF_REL_MIX_INT(unsigned short, 16, false) +AF_REF_REL_MIX_INT(int, 32, true) +AF_REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +AF_REF_REL_MIX_INT(long, 64, true) +AF_REF_REL_MIX_INT(unsigned long, 64, false) +# else +AF_REF_REL_MIX_INT(long, 32, true) +AF_REF_REL_MIX_INT(unsigned long, 32, false) +# endif +AF_REF_REL_MIX_INT(ap_slong, 64, true) +AF_REF_REL_MIX_INT(ap_ulong, 64, false) + +#define AF_REF_REL_OP_AP_INT(REL_OP) \ +template \ + INLINE bool operator REL_OP ( const af_range_ref<_AP_W,_AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S> &op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP (const ap_private<_AP_W2, _AP_S2> &op2, const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ +template \ + INLINE bool operator REL_OP ( const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op, const ap_private<_AP_W2, _AP_S2> &op2) { \ + return (ap_private<1, false>(op)).operator REL_OP (op2); \ + } \ +template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W2, _AP_S2> &op2, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op) { \ + return op2.operator REL_OP (ap_private<1,false>(op)); \ + } + +AF_REF_REL_OP_AP_INT(>) +AF_REF_REL_OP_AP_INT(<) +AF_REF_REL_OP_AP_INT(>=) +AF_REF_REL_OP_AP_INT(<=) +AF_REF_REL_OP_AP_INT(==) +AF_REF_REL_OP_AP_INT(!=) + +// Relational Operators with double +template +INLINE bool operator == ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator == (op1); +} + +template +INLINE bool operator != ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator != (op1); +} + +template +INLINE bool operator > ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator < (op1); +} + +template +INLINE bool operator >= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator <= (op1); +} + +template +INLINE bool operator < ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator > (op1); +} + +template +INLINE bool operator <= ( double op1, const ap_fixed_base<_AP_W,_AP_I,_AP_S,_AP_Q,_AP_O, _AP_N>& op2) { + return op2.operator >= (op1); +} + +#endif /* #ifndef __AESL_GCC_AP_FIXED_H__ */ \ No newline at end of file diff --git a/hls_2018/router_05/etc/ap_int_sim.h b/hls_2018/router_05/etc/ap_int_sim.h new file mode 100755 index 0000000000000000000000000000000000000000..887ccd88bfd52d1777db8661d72c57703ccf736a --- /dev/null +++ b/hls_2018/router_05/etc/ap_int_sim.h @@ -0,0 +1,1629 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AESL_GCC_AP_INT_H__ +#define __AESL_GCC_AP_INT_H__ + +#ifndef __cplusplus +#error C++ is required to include this header file +#endif /* #ifndef __cplusplus */ + +#undef _AP_DEBUG_ +#include +#include + +// for safety +#if (defined(_AP_N)|| defined(_AP_C)) +#error One or more of the following is defined: _AP_N, _AP_C. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_N)|| defined(_AP_C)) */ + +// for safety +#if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) +#error One or more of the following is defined: _AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W) || defined(_AP_I) || defined(_AP_S) || defined(_AP_Q) || defined(_AP_O) || defined(_AP_W2) || defined(_AP_I2) || defined(_AP_S2) || defined(_AP_Q2) || defined(_AP_O2)) */ + +//for safety +#if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) +#error One or more of the following is defined: _AP_W3, _AP_S3, _AP_W4,_AP_S4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W3) || defined(_AP_S3) || defined(_AP_W4) || defined(_AP_S4)) */ + +//for safety +#if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) +#error One or more of the following is defined: _AP_W1, _AP_S1, _AP_I1, _AP_T, _AP_T1, _AP_T2, _AP_T3, _AP_T4. Definition conflicts with their usage as template parameters. +#endif /* #if (defined(_AP_W1) || defined(_AP_S1) || defined(_AP_I1) || defined(_AP_T) || defined(_AP_T1) || defined(_AP_T2) || defined(_AP_T3) || defined(_AP_T4)) */ + +#define __AESL_APDT_IN_SCFLOW__ +#ifndef __AESL_APDT_IN_SCFLOW__ + #include "etc/ap_private.h" +#else + #include "../etc/ap_private.h" +#endif /* #ifndef __AESL_APDT_IN_SCFLOW__ */ + +#ifdef _AP_DEBUG_ + #define AP_DEBUG(s) s +#else + #define AP_DEBUG(s) +#endif /* #ifdef _AP_DEBUG_ */ + +#ifndef __SIMULATION__ + #define __SIMULATION__ +#endif /* #ifndef __SIMULATION__ */ + +#if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) + #ifndef SC_TRN + #define SC_TRN AP_TRN + #endif /* #ifndef SC_TRN */ + #ifndef SC_RND + #define SC_RND AP_RND + #endif /* #ifndef SC_RND */ + #ifndef SC_TRN_ZERO + #define SC_TRN_ZERO AP_TRN_ZERO + #endif /* #ifndef SC_TRN_ZERO */ + #ifndef SC_RND_ZERO + #define SC_RND_ZERO AP_RND_ZERO + #endif /* #ifndef SC_RND_ZERO */ + #ifndef SC_RND_INF + #define SC_RND_INF AP_RND_INF + #endif /* #ifndef SC_RND_INF */ + #ifndef SC_RND_MIN_INF + #define SC_RND_MIN_INF AP_RND_MIN_INF + #endif /* #ifndef SC_RND_MIN_INF */ + #ifndef SC_RND_CONV + #define SC_RND_CONV AP_RND_CONV + #endif /* #ifndef SC_RND_CONV */ + #ifndef SC_WRAP + #define SC_WRAP AP_WRAP + #endif /* #ifndef SC_WRAP */ + #ifndef SC_SAT + #define SC_SAT AP_SAT + #endif /* #ifndef SC_SAT */ + #ifndef SC_SAT_ZERO + #define SC_SAT_ZERO AP_SAT_ZERO + #endif /* #ifndef SC_SAT_ZERO */ + #ifndef SC_SAT_SYM + #define SC_SAT_SYM AP_SAT_SYM + #endif /* #ifndef SC_SAT_SYM */ + #ifndef SC_WRAP_SM + #define SC_WRAP_SM AP_WRAP_SM + #endif /* #ifndef SC_WRAP_SM */ + #ifndef SC_BIN + #define SC_BIN AP_BIN + #endif /* #ifndef SC_BIN */ + #ifndef SC_OCT + #define SC_OCT AP_OCT + #endif /* #ifndef SC_OCT */ + #ifndef SC_DEC + #define SC_DEC AP_DEC + #endif /* #ifndef SC_DEC */ + #ifndef SC_HEX + #define SC_HEX AP_HEX + #endif /* #ifndef SC_HEX */ +#endif /* #if !(defined SYSTEMC_H) && !(defined SYSTEMC_INCLUDED) */ +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +///Forward declaration +template struct ap_range_ref; +template struct ap_bit_ref; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; +template class ap_uint; + +enum { + AP_BIN = 2, + AP_OCT = 8, + AP_DEC = 10, + AP_HEX = 16 +}; + +///Why to use reference? +///Because we will operate the original object indirectly by operating the +///result object directly after concating or part selecting + +///Proxy class which allows concatination to be used as rvalue(for reading) and +//lvalue(for writing) + +/// Concatination reference. +// ---------------------------------------------------------------- +template +struct ap_concat_ref { +#ifdef _MSC_VER + #pragma warning(disable: 4521 4522) +#endif /* #ifdef _MSC_VER */ + enum {_AP_WR=_AP_W1+_AP_W2,}; + _AP_T1& mbv1; + _AP_T2& mbv2; + + INLINE ap_concat_ref(const ap_concat_ref<_AP_W1, _AP_T1, + _AP_W2, _AP_T2>& ref): + mbv1(ref.mbv1), mbv2(ref.mbv2) {} + + INLINE ap_concat_ref(_AP_T1& bv1, _AP_T2& bv2):mbv1(bv1),mbv2(bv2) {} + + template + INLINE ap_concat_ref& operator = (const ap_private<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + return *this; + } + + INLINE ap_concat_ref& operator = (unsigned long long val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + INLINE ap_concat_ref& operator = + (const ap_concat_ref <_AP_W1, _AP_T1, _AP_W2, _AP_T2>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_bit_ref<_AP_W3, _AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_concat_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) { + ap_private<_AP_W1+_AP_W2, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_concat_ref& operator= (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = ((const ap_private<_AP_W3, false>)(val)); + } + + template + INLINE ap_concat_ref& operator= (const ap_fixed_base<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator = (val.to_ap_private()); + } + + template + INLINE ap_concat_ref& operator= (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, + _AP_Q3, _AP_O3, _AP_N3>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + + INLINE operator ap_private<_AP_WR, false> () const { + return get(); + } + + INLINE operator unsigned long long () const { + return get().to_uint64(); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_range_ref<_AP_W3, _AP_S3> > + operator, (const ap_range_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_range_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_private<_AP_W3, _AP_S3> > + operator, (const ap_private<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3, ap_private<_AP_W3, _AP_S3> >(*this, + const_cast&>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, 1, ap_bit_ref<_AP_W3, _AP_S3> > + operator, (const ap_bit_ref<_AP_W3, _AP_S3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, + 1, ap_bit_ref<_AP_W3, _AP_S3> >(*this, + const_cast &>(a2)); + } + + template + INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> > + operator, (const ap_concat_ref<_AP_W3,_AP_T3,_AP_W4,_AP_T4> &a2) + { + return ap_concat_ref<_AP_WR, ap_concat_ref, + _AP_W3+_AP_W4, ap_concat_ref<_AP_W3,_AP_T3,_AP_W4, + _AP_T4> >(*this, const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, af_range_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> > + operator, (const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, + _AP_O3, _AP_N3> &a2) { + return ap_concat_ref<_AP_WR, ap_concat_ref, 1, af_bit_ref<_AP_W3, + _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(*this, + const_cast& >(a2)); + } + + template + INLINE ap_private + operator & (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() & a2; + } + + + template + INLINE ap_private + operator | (const ap_private<_AP_W3,_AP_S3>& a2) { + return get() | a2; + } + + + template + INLINE ap_private + operator ^ (const ap_private<_AP_W3,_AP_S3>& a2) { + return ap_private(get() ^ a2); + } + + INLINE const ap_private<_AP_WR, false> get() const + { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> (mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + INLINE const ap_private<_AP_WR, false> get() { + ap_private<_AP_W1+_AP_W2, false> tmpVal = ap_private<_AP_W1+_AP_W2, false> ( mbv1.get()); + ap_private<_AP_W1+_AP_W2, false> tmpVal2 = ap_private<_AP_W1+_AP_W2, false> (mbv2.get()); + int W_ref2 = mbv2.length(); + tmpVal <<= W_ref2; + tmpVal |= tmpVal2; + return tmpVal; + } + + template + INLINE void set(const ap_private<_AP_W3,false> & val) { + ap_private<_AP_W1+_AP_W2, false> vval(val); + int W_ref1=mbv1.length(); + int W_ref2=mbv2.length(); + ap_private<_AP_W1,false> mask1(-1); + mask1>>=_AP_W1-W_ref1; + ap_private<_AP_W2,false> mask2(-1); + mask2>>=_AP_W2-W_ref2; + mbv1.set(ap_private<_AP_W1,false>((vval>>W_ref2)&mask1)); + mbv2.set(ap_private<_AP_W2,false>(vval&mask2)); + } + + INLINE int length() const { + return mbv1.length()+mbv2.length(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } +}; + +///Proxy class, which allows part selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Range(slice) reference +//------------------------------------------------------------ +template +struct ap_range_ref { +#ifdef _MSC_VER + #pragma warning( disable : 4521 4522 ) +#endif /* #ifdef _MSC_VER */ + ap_private<_AP_W,_AP_S> &d_bv; + int l_index; + int h_index; + +public: + INLINE ap_range_ref(const ap_range_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {} + + INLINE ap_range_ref(ap_private<_AP_W,_AP_S>* bv, int h, int l): + d_bv(*bv),l_index(l),h_index(h) { + //if (h < l) + //fprintf(stderr, "Warning! The bits selected will be returned in reverse order\n"); + } + + INLINE operator ap_private<_AP_W, false> () const { + ap_private<_AP_W, false> val(0); + if(h_index>=l_index) { + if (_AP_W > 64) { + val=d_bv; + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val>>=l_index; + val&=mask; + } else { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val = (d_bv >> l_index) & (mask >>(_AP_W-(h_index-l_index+1))); + } + } else { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } + return val; + } + + INLINE operator unsigned long long () const { + return to_uint64(); + } + + template + INLINE ap_range_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) { + ap_private<_AP_W,false> vval=ap_private<_AP_W,false>(val); + if (l_index>h_index) { + for (int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W > 64) { + ap_private<_AP_W,false> mask(-1); + if (l_index>0) { + mask<<=l_index; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2>>=_AP_W-h_index-1; + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + unsigned shift = 64-_AP_W; + uint64_t mask = ~0ULL>>(shift); + if(l_index>0) + { + vval = mask & vval << l_index; + mask = mask & mask << l_index; + } + if(h_index<_AP_W-1) + { + uint64_t mask2 = mask; + mask2 >>= (_AP_W-h_index-1); + mask&=mask2; + vval&=mask2; + } + mask = ~mask; + d_bv&=mask; + d_bv|=vval; + } + } + return *this; + } + + INLINE ap_range_ref& operator = (unsigned long long val) + { + const ap_private<_AP_W,_AP_S> vval=val; + return operator = (vval); + } + + + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W, _AP_S>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + + + template + INLINE ap_range_ref& operator = + (const ap_concat_ref <_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator = (tmpVal); + } + + template + INLINE ap_range_ref& operator =(const ap_range_ref<_AP_W3,_AP_S3>& val) + { + const ap_private<_AP_W, false> tmpVal(val); + return operator =(tmpVal); + } + + template + INLINE ap_range_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, _AP_S2>)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=(val.to_ap_private()); + } + + template + INLINE ap_range_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_range_ref& operator= (const ap_bit_ref<_AP_W2, _AP_S2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, + ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast& >(a2)); + } + + + template + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W2,ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2,_AP_S2>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + INLINE ap_concat_ref<_AP_W,ap_range_ref,_AP_W,ap_private<_AP_W,_AP_S> > + operator , (ap_private<_AP_W, _AP_S>& a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, _AP_W, + ap_private<_AP_W,_AP_S> >(*this, a2); + } + + + + template + INLINE + ap_concat_ref<_AP_W,ap_range_ref,1,ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2,_AP_S2> &a2) + { + return + ap_concat_ref<_AP_W, ap_range_ref, 1, + ap_bit_ref<_AP_W2,_AP_S2> >(*this, const_cast& >(a2)); + } + + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) + { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_range_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs==rhs; + } + + + template + INLINE bool operator != (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs!=rhs; + } + + + template + INLINE bool operator > (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>rhs; + } + + + template + INLINE bool operator >= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs>=rhs; + } + + + template + INLINE bool operator < (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs + INLINE bool operator <= (const ap_range_ref<_AP_W2, _AP_S2>& op2) + { + ap_private<_AP_W,false> lhs=get(); + ap_private<_AP_W2,false> rhs=op2.get(); + return lhs<=rhs; + } + + + template + INLINE void set(const ap_private<_AP_W2,false>& val) + { + ap_private<_AP_W,_AP_S> vval=val; + if(l_index>h_index) + { + for(int i=0, j=l_index;j>=0&&j>=h_index;j--,i++) + (vval)[i]? d_bv.set(j):d_bv.clear(j); + } else { + if (_AP_W>64 ) { + ap_private<_AP_W,_AP_S> mask(-1); + if(l_index>0) + { + ap_private<_AP_W,false> mask1(-1); + mask1>>=_AP_W-l_index; + mask1.flip(); + mask=mask1; + //vval&=mask1; + vval<<=l_index; + } + if(h_index<_AP_W-1) + { + ap_private<_AP_W,false> mask2(-1); + mask2<<=h_index+1; + mask2.flip(); + mask&=mask2; + vval&=mask2; + } + mask.flip(); + d_bv&=mask; + d_bv|=vval; + } else { + uint64_t mask = ~0ULL >> (64-_AP_W); + if(l_index>0) + { + uint64_t mask1 = mask; + mask1=mask & (mask1>>(_AP_W-l_index)); + vval =mask&( vval <> (64-_AP_W); + mask2 = mask &(mask2<<(h_index+1)); + mask&=~mask2; + vval&=~mask2; + } + d_bv&=(~mask&(~0ULL >> (64-_AP_W))); + d_bv|=vval; + } + } + } + + + INLINE ap_private<_AP_W,false> get() const + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64) { + const static uint64_t mask = (~0ULL>> (64>_AP_W ? (64-_AP_W):0)); + val &= (mask>> (_AP_W-(h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE ap_private<_AP_W,false> get() + { + ap_private<_AP_W,false> val(0); + if(h_index=0&&j>=h_index;j--,i++) + if((d_bv)[j]) val.set(i); + } else { + val=d_bv; + val>>=l_index; + if(h_index<_AP_W-1) + { + if (_AP_W <= 64 ) { + static const uint64_t mask = ~0ULL>> (64>_AP_W ? (64-_AP_W):0); + return val &= ( (mask) >> (_AP_W - (h_index-l_index+1))); + } else { + ap_private<_AP_W,false> mask(-1); + mask>>=_AP_W-(h_index-l_index+1); + val&=mask; + } + } + } + return val; + } + + + INLINE int length() const + { + return h_index>=l_index?h_index-l_index+1:l_index-h_index+1; + } + + + INLINE int to_int() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int(); + } + + + INLINE unsigned int to_uint() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint(); + } + + + INLINE long to_long() const + { + ap_private<_AP_W,false> val=get(); + return val.to_long(); + } + + + INLINE unsigned long to_ulong() const + { + ap_private<_AP_W,false> val=get(); + return val.to_ulong(); + } + + + INLINE ap_slong to_int64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_int64(); + } + + + INLINE ap_ulong to_uint64() const + { + ap_private<_AP_W,false> val=get(); + return val.to_uint64(); + } + + INLINE std::string to_string(uint8_t radix=2) const { + return get().to_string(radix); + } + +}; + +///Proxy class, which allows bit selection to be used as rvalue(for reading) and +//lvalue(for writing) + +///Bit reference +//-------------------------------------------------------------- +template +struct ap_bit_ref { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif + ap_private<_AP_W,_AP_S>& d_bv; + int d_index; + +public: + INLINE ap_bit_ref(const ap_bit_ref<_AP_W, _AP_S>& ref): + d_bv(ref.d_bv), d_index(ref.d_index) {} + + INLINE ap_bit_ref(ap_private<_AP_W,_AP_S>& bv, int index=0): + d_bv(bv),d_index(index) + { +#ifdef _AP_DEBUG_ + assert(d_index<_AP_W&&"index out of bound"); +#endif + } + + + INLINE operator bool () const + { + return d_bv.get_bit(d_index); + } + + + INLINE bool to_bool() const + { + return operator bool (); + } + + + INLINE ap_bit_ref& operator = (unsigned long long val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } + + +#if 0 + INLINE ap_bit_ref& operator = (bool val) + { + if(val) + d_bv.set(d_index); + else + d_bv.clear(d_index); + return *this; + } +#endif + template + INLINE ap_bit_ref& operator =(const ap_private<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(val != 0)); + } + + + template + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool)val); + } + + INLINE ap_bit_ref& operator =(const ap_bit_ref<_AP_W,_AP_S>& val) + { + return operator =((unsigned long long)(bool)val); + } + + template + INLINE ap_bit_ref& operator =(const ap_range_ref<_AP_W2,_AP_S2>& val) + { + return operator =((unsigned long long)(bool) val); + } + + + template + INLINE ap_bit_ref& operator= (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((const ap_private<_AP_W2, false>)(val)); + } + + template + INLINE ap_bit_ref& operator= (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2>& val) { + return operator=((unsigned long long)(bool)(val)); + } + + template + INLINE ap_bit_ref& operator= (const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) { + return operator=((const ap_private<_AP_W2 + _AP_W3, false>)(val)); + } + + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> > + operator , (ap_private<_AP_W2, _AP_S2>& a2) + { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2,_AP_S2> >(*this, + const_cast &>(a2)); + } + + + INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref > + operator, (const ap_bit_ref &a2) + { + return + ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref >(*this, + const_cast(a2)); + } + + + template + INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> > + operator, (const ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> &a2) + { + return + ap_concat_ref<1,ap_bit_ref,_AP_W2+_AP_W3, + ap_concat_ref<_AP_W2,_AP_T2,_AP_W3,_AP_T3> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, + const_cast& >(a2)); + } + + template + INLINE bool operator == (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() == op.get(); + } + + template + INLINE bool operator != (const ap_bit_ref<_AP_W2, _AP_S2>& op) { + return get() != op.get(); + } + + + INLINE bool get() const + { + return operator bool (); + } + + + INLINE bool get() + { + return operator bool (); + } + + + template + INLINE void set(const ap_private<_AP_W3, false>& val) + { + operator = (val); + } + + INLINE bool operator ~ () const { + bool bit = (d_bv)[d_index]; + return bit ? false : true; + } + + INLINE int length() const { return 1; } + + INLINE std::string to_string() const { + bool val = get(); + return val ? "1" : "0"; + } +}; + +/// Operators mixing Integers with AP_Int +// ---------------------------------------------------------------- +#if 1 +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#else +#define OP_BIN_MIX_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + INLINE typename ap_private<_AP_WI,_AP_SI>::template RType<_AP_W,_AP_S>::RTYPE \ + operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_WI,_AP_SI>(i_op).operator BIN_OP (op); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (ap_private<_AP_WI,_AP_SI>(i_op)); \ + } +#endif +#define OP_REL_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator REL_OP (ap_private<_AP_W2, _AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_private<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (op); \ + } +#define OP_ASSIGN_MIX_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return op.operator ASSIGN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } + +#define OP_BIN_SHIFT_INT(BIN_OP, C_TYPE, _AP_WI, _AP_SI, RTYPE) \ + template \ + C_TYPE operator BIN_OP ( C_TYPE i_op, const ap_private<_AP_W,_AP_S> &op) { \ + return i_op BIN_OP (op.getVal()); \ + } \ + template \ + INLINE typename ap_private<_AP_W,_AP_S>::template RType<_AP_WI,_AP_SI>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W,_AP_S> &op, C_TYPE i_op) { \ + return op.operator BIN_OP (i_op); \ + } +#define OP_ASSIGN_RSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator >> (op2); \ + return op; \ + } +#define OP_ASSIGN_LSHIFT_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE ap_private<_AP_W,_AP_S> &operator ASSIGN_OP ( ap_private<_AP_W,_AP_S> &op, C_TYPE op2) { \ + op = op.operator << (op2); \ + return op; \ + } + +#define OPS_MIX_INT(C_TYPE, WI, SI) \ + OP_BIN_MIX_INT(*, C_TYPE, WI, SI, mult) \ + OP_BIN_MIX_INT(+, C_TYPE, WI, SI, plus) \ + OP_BIN_MIX_INT(-, C_TYPE, WI, SI, minus) \ + OP_BIN_MIX_INT(/, C_TYPE, WI, SI, div) \ + OP_BIN_MIX_INT(%, C_TYPE, WI, SI, mod) \ + OP_BIN_MIX_INT(&, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(|, C_TYPE, WI, SI, logic) \ + OP_BIN_MIX_INT(^, C_TYPE, WI, SI, logic) \ + OP_BIN_SHIFT_INT(>>, C_TYPE, WI, SI, arg1) \ + OP_BIN_SHIFT_INT(<<, C_TYPE, WI, SI, arg1) \ + \ + OP_REL_MIX_INT(==, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(!=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(>=, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<, C_TYPE, WI, SI) \ + OP_REL_MIX_INT(<=, C_TYPE, WI, SI) \ + \ + OP_ASSIGN_MIX_INT(+=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(-=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(*=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(/=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(%=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(&=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(|=, C_TYPE, WI, SI) \ + OP_ASSIGN_MIX_INT(^=, C_TYPE, WI, SI) \ + OP_ASSIGN_RSHIFT_INT(>>=, C_TYPE, WI, SI) \ + OP_ASSIGN_LSHIFT_INT(<<=, C_TYPE, WI, SI) + + +OPS_MIX_INT(bool, 1, false) +OPS_MIX_INT(char, 8, true) +OPS_MIX_INT(signed char, 8, true) +OPS_MIX_INT(unsigned char, 8, false) +OPS_MIX_INT(short, 16, true) +OPS_MIX_INT(unsigned short, 16, false) +OPS_MIX_INT(int, 32, true) +OPS_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +OPS_MIX_INT(long, 64, true) +OPS_MIX_INT(unsigned long, 64, false) +# else +OPS_MIX_INT(long, 32, true) +OPS_MIX_INT(unsigned long, 32, false) +# endif +OPS_MIX_INT(ap_slong, 64, true) +OPS_MIX_INT(ap_ulong, 64, false) + +#define OP_BIN_MIX_RANGE(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<_AP_W2, false>(op2)); \ + } + +#define OP_REL_MIX_RANGE(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (op2.operator ap_private<_AP_W2, false>()); \ + } + +#define OP_ASSIGN_MIX_RANGE(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, const ap_range_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<_AP_W2, false>(op2)); \ + } \ + template \ + INLINE ap_range_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP (ap_range_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<_AP_W1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_RANGE(+=) +OP_ASSIGN_MIX_RANGE(-=) +OP_ASSIGN_MIX_RANGE(*=) +OP_ASSIGN_MIX_RANGE(/=) +OP_ASSIGN_MIX_RANGE(%=) +OP_ASSIGN_MIX_RANGE(>>=) +OP_ASSIGN_MIX_RANGE(<<=) +OP_ASSIGN_MIX_RANGE(&=) +OP_ASSIGN_MIX_RANGE(|=) +OP_ASSIGN_MIX_RANGE(^=) + +OP_REL_MIX_RANGE(==) +OP_REL_MIX_RANGE(!=) +OP_REL_MIX_RANGE(>) +OP_REL_MIX_RANGE(>=) +OP_REL_MIX_RANGE(<) +OP_REL_MIX_RANGE(<=) + +OP_BIN_MIX_RANGE(+, plus) +OP_BIN_MIX_RANGE(-, minus) +OP_BIN_MIX_RANGE(*, mult) +OP_BIN_MIX_RANGE(/, div) +OP_BIN_MIX_RANGE(%, mod) +OP_BIN_MIX_RANGE(>>, arg1) +OP_BIN_MIX_RANGE(<<, arg1) +OP_BIN_MIX_RANGE(&, logic) +OP_BIN_MIX_RANGE(|, logic) +OP_BIN_MIX_RANGE(^, logic) + +#define OP_BIN_MIX_BIT(BIN_OP, RTYPE) \ + template \ + INLINE typename ap_private<1, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<1, false>(op1).operator BIN_OP (op2); \ + } \ + template \ + INLINE typename ap_private<_AP_W1,_AP_S1>::template RType<1,false>::RTYPE \ + operator BIN_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator BIN_OP (ap_private<1, false>(op2)); \ + } + +#define OP_REL_MIX_BIT(REL_OP) \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W1,_AP_S1>& op1, const ap_private<_AP_W2,_AP_S2>& op2) { \ + return ap_private<_AP_W1,false>(op1).operator REL_OP (op2); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_private<_AP_W1,_AP_S1>& op1, const ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator REL_OP (ap_private<1, false>(op2)); \ + } + +#define OP_ASSIGN_MIX_BIT(ASSIGN_OP) \ + template \ + INLINE ap_private<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_private<_AP_W1,_AP_S1>& op1, ap_bit_ref<_AP_W2,_AP_S2>& op2) { \ + return op1.operator ASSIGN_OP (ap_private<1, false>(op2)); \ + } \ + template \ + INLINE ap_bit_ref<_AP_W1,_AP_S1>& operator ASSIGN_OP ( ap_bit_ref<_AP_W1,_AP_S1>& op1, ap_private<_AP_W2,_AP_S2>& op2) { \ + ap_private<1, false> tmp(op1); \ + tmp.operator ASSIGN_OP (op2); \ + op1 = tmp; \ + return op1; \ + } + + +OP_ASSIGN_MIX_BIT(+=) +OP_ASSIGN_MIX_BIT(-=) +OP_ASSIGN_MIX_BIT(*=) +OP_ASSIGN_MIX_BIT(/=) +OP_ASSIGN_MIX_BIT(%=) +OP_ASSIGN_MIX_BIT(>>=) +OP_ASSIGN_MIX_BIT(<<=) +OP_ASSIGN_MIX_BIT(&=) +OP_ASSIGN_MIX_BIT(|=) +OP_ASSIGN_MIX_BIT(^=) + +OP_REL_MIX_BIT(==) +OP_REL_MIX_BIT(!=) +OP_REL_MIX_BIT(>) +OP_REL_MIX_BIT(>=) +OP_REL_MIX_BIT(<) +OP_REL_MIX_BIT(<=) + +OP_BIN_MIX_BIT(+, plus) +OP_BIN_MIX_BIT(-, minus) +OP_BIN_MIX_BIT(*, mult) +OP_BIN_MIX_BIT(/, div) +OP_BIN_MIX_BIT(%, mod) +OP_BIN_MIX_BIT(>>, arg1) +OP_BIN_MIX_BIT(<<, arg1) +OP_BIN_MIX_BIT(&, logic) +OP_BIN_MIX_BIT(|, logic) +OP_BIN_MIX_BIT(^, logic) + +#define REF_REL_OP_MIX_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE bool operator REL_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W, false>(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_bit_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (bool(op)) REL_OP op2; \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_bit_ref<_AP_W,_AP_S> &op) { \ + return op2 REL_OP (bool(op)); \ + } \ + template \ + INLINE bool operator REL_OP ( const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op, C_TYPE op2) { \ + return (ap_private<_AP_W + _AP_W1, false>(op)).operator REL_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE bool operator REL_OP ( C_TYPE op2, const ap_concat_ref<_AP_W,_AP_T, _AP_W1, _AP_T1> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator REL_OP (ap_private<_AP_W + _AP_W1, false>(op)); \ + } + +#define REF_REL_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(>=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(<=, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(==, C_TYPE, _AP_WI, _AP_SI) \ +REF_REL_OP_MIX_INT(!=, C_TYPE, _AP_WI, _AP_SI) + +REF_REL_MIX_INT(bool, 1, false) +REF_REL_MIX_INT(char, 8, true) +REF_REL_MIX_INT(signed char, 8, true) +REF_REL_MIX_INT(unsigned char, 8, false) +REF_REL_MIX_INT(short, 16, true) +REF_REL_MIX_INT(unsigned short, 16, false) +REF_REL_MIX_INT(int, 32, true) +REF_REL_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_REL_MIX_INT(long, 64, true) +REF_REL_MIX_INT(unsigned long, 64, false) +# else +REF_REL_MIX_INT(long, 32, true) +REF_REL_MIX_INT(unsigned long, 32, false) +# endif +REF_REL_MIX_INT(ap_slong, 64, true) +REF_REL_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP_MIX_INT(BIN_OP, RTYPE, C_TYPE, _AP_W2, _AP_S2) \ + template \ + INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2,_AP_S2>::RTYPE \ + operator BIN_OP ( const ap_range_ref<_AP_W,_AP_S> &op, C_TYPE op2) { \ + return (ap_private<_AP_W, false>(op)).operator BIN_OP (ap_private<_AP_W2,_AP_S2>(op2)); \ + } \ + template \ + INLINE typename ap_private<_AP_W2, _AP_S2>::template RType<_AP_W,false>::RTYPE \ + operator BIN_OP ( C_TYPE op2, const ap_range_ref<_AP_W,_AP_S> &op) { \ + return ap_private<_AP_W2,_AP_S2>(op2).operator BIN_OP (ap_private<_AP_W, false>(op)); \ + } + +#define REF_BIN_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(+, plus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(-, minus, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(*, mult, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(/, div, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(%, mod, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(>>, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(<<, arg1, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(&, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(|, logic, C_TYPE, _AP_WI, _AP_SI) \ +REF_BIN_OP_MIX_INT(^, logic, C_TYPE, _AP_WI, _AP_SI) + +REF_BIN_MIX_INT(bool, 1, false) +REF_BIN_MIX_INT(char, 8, true) +REF_BIN_MIX_INT(signed char, 8, true) +REF_BIN_MIX_INT(unsigned char, 8, false) +REF_BIN_MIX_INT(short, 16, true) +REF_BIN_MIX_INT(unsigned short, 16, false) +REF_BIN_MIX_INT(int, 32, true) +REF_BIN_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +REF_BIN_MIX_INT(long, 64, true) +REF_BIN_MIX_INT(unsigned long, 64, false) +#else +REF_BIN_MIX_INT(long, 32, true) +REF_BIN_MIX_INT(unsigned long, 32, false) +#endif +REF_BIN_MIX_INT(ap_slong, 64, true) +REF_BIN_MIX_INT(ap_ulong, 64, false) + +#define REF_BIN_OP(BIN_OP, RTYPE) \ +template \ +INLINE typename ap_private<_AP_W, false>::template RType<_AP_W2, false>::RTYPE \ +operator BIN_OP (const ap_range_ref<_AP_W,_AP_S> &lhs, const ap_range_ref<_AP_W2,_AP_S2> &rhs) { \ + return ap_private<_AP_W,false>(lhs).operator BIN_OP (ap_private<_AP_W2, false>(rhs)); \ +} + +REF_BIN_OP(+, plus) +REF_BIN_OP(-, minus) +REF_BIN_OP(*, mult) +REF_BIN_OP(/, div) +REF_BIN_OP(%, mod) +REF_BIN_OP(>>, arg1) +REF_BIN_OP(<<, arg1) +REF_BIN_OP(&, logic) +REF_BIN_OP(|, logic) +REF_BIN_OP(^, logic) + +#if 1 +#define CONCAT_OP_MIX_INT(C_TYPE, _AP_WI, _AP_SI) \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_private<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret |= val; \ + return ret;\ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_private<_AP_W, _AP_S>& op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + if (_AP_S) { \ + ret <<= _AP_WI; ret >>= _AP_WI; \ + } \ + ret |= val << _AP_W; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const ap_range_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + ret <<= _AP_WI; \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + } \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_range_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (const ap_bit_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, false> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_WI + 1, false > \ + operator, (C_TYPE op1, const ap_bit_ref<_AP_W, _AP_S> &op2) { \ + ap_private<_AP_WI + 1, false> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} \ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op1, C_TYPE op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op2);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op1);\ + if (_AP_SI) { \ + val <<= _AP_W + _AP_W2; val >>= _AP_W + _AP_W2; \ + } \ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +}\ +template \ +INLINE \ +ap_private<_AP_W + _AP_W2 + _AP_WI, false > \ + operator, (C_TYPE op1, const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op2) {\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op1);\ + ap_private<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op2);\ + int len = op2.length(); \ + val <<= len; \ + ret |= val;\ + return ret; \ +}\ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op2); \ + ap_private<_AP_WI + _AP_W, false> ret(op1); \ + if (_AP_SI) { \ + val <<= _AP_W; val >>= _AP_W; \ + }\ + ret <<= _AP_WI; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< _AP_W + _AP_WI, false > \ + operator, (C_TYPE op1, const af_range_ref<_AP_W, _AP_I, _AP_S, \ + _AP_Q, _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + _AP_W, false> val(op1); \ + ap_private<_AP_WI + _AP_W, false> ret(op2); \ + int len = op2.length(); \ + val <<= len; \ + ret |= val; \ + return ret; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, \ + _AP_N> &op1, C_TYPE op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op2); \ + val[_AP_WI] = op1; \ + return val; \ +} \ +template \ +INLINE \ +ap_private< 1 + _AP_WI, false> \ + operator, (C_TYPE op1, const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q,\ + _AP_O, _AP_N> &op2) { \ + ap_private<_AP_WI + 1, _AP_SI> val(op1); \ + val <<= 1; \ + val[0] = op2; \ + return val; \ +} + +CONCAT_OP_MIX_INT(bool, 1, false) +CONCAT_OP_MIX_INT(char, 8, true) +CONCAT_OP_MIX_INT(signed char, 8, true) +CONCAT_OP_MIX_INT(unsigned char, 8, false) +CONCAT_OP_MIX_INT(short, 16, true) +CONCAT_OP_MIX_INT(unsigned short, 16, false) +CONCAT_OP_MIX_INT(int, 32, true) +CONCAT_OP_MIX_INT(unsigned int, 32, false) +# if defined __x86_64__ +CONCAT_OP_MIX_INT(long, 64, true) +CONCAT_OP_MIX_INT(unsigned long, 64, false) +# else +CONCAT_OP_MIX_INT(long, 32, true) +CONCAT_OP_MIX_INT(unsigned long, 32, false) +# endif +CONCAT_OP_MIX_INT(ap_slong, 64, true) +CONCAT_OP_MIX_INT(ap_ulong, 64, false) +#endif + +#if 1 +#define CONCAT_SHIFT_MIX_INT(C_TYPE, op) \ +template \ +INLINE ap_uint<_AP_W+_AP_W1> operator op (const ap_concat_ref<_AP_W, _AP_T, _AP_W1, _AP_T1> lhs, C_TYPE rhs) { \ + return ((ap_uint<_AP_W+_AP_W1>)lhs.get()) op ((int)rhs); \ +} + +CONCAT_SHIFT_MIX_INT(long, <<) +CONCAT_SHIFT_MIX_INT(unsigned long, <<) +CONCAT_SHIFT_MIX_INT(unsigned int, <<) +CONCAT_SHIFT_MIX_INT(ap_ulong, <<) +CONCAT_SHIFT_MIX_INT(ap_slong, <<) +CONCAT_SHIFT_MIX_INT(long, >>) +CONCAT_SHIFT_MIX_INT(unsigned long, >>) +CONCAT_SHIFT_MIX_INT(unsigned int, >>) +CONCAT_SHIFT_MIX_INT(ap_ulong, >>) +CONCAT_SHIFT_MIX_INT(ap_slong, >>) +#endif + +#if defined(SYSTEMC_H) || defined(SYSTEMC_INCLUDED) +template +INLINE void sc_trace(sc_core::sc_trace_file *tf, const ap_private<_AP_W, _AP_S> &op, + const std::string &name) { + if (tf) + tf->trace(sc_dt::sc_lv<_AP_W>(op.to_string(2).c_str()), name); +} +#endif + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_private<_AP_W,_AP_S> &op) +{ + ap_private<_AP_W, _AP_S> v=op; + const std::ios_base::fmtflags basefield = out.flags() & std::ios_base::basefield; + unsigned radix = (basefield == std::ios_base::hex) ? 16 : + ((basefield == std::ios_base::oct) ? 8 : 10); + std::string str=v.toString(radix,_AP_S); + out< +INLINE std::istream& operator >> (std::istream& in, ap_private<_AP_W,_AP_S> &op) +{ + std::string str; + in >> str; + op = ap_private<_AP_W, _AP_S>(str.c_str()); + return in; + +} + +template +INLINE std::ostream& operator<<(std::ostream& out, const ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator<<(out, ap_private<_AP_W, _AP_S>(op)); +} + +template +INLINE std::istream& operator >> (std::istream& in, ap_range_ref<_AP_W,_AP_S> &op) +{ + return operator>>(in, ap_private<_AP_W, _AP_S>(op));; +} + +template +INLINE void print(const ap_private<_AP_W,_AP_S> &op, bool fill=true ) +{ + ap_private<_AP_W, _AP_S> v=op; + uint32_t ws=v.getNumWords(); + const uint64_t *ptr=v.getRawData(); + int i=ws-1; +#if 0 + if(fill) + printf("%016llx",*(ptr+i)); + else + printf("%llx",*(ptr+i)); +#else +//match SystemC output + if(_AP_W%64 != 0) { + uint32_t offset=_AP_W%64; + uint32_t count=(offset+3)/4; + int64_t data=*(ptr+i); + if(_AP_S) + data=(data<<(64-offset))>>(64-offset); + else + count=(offset+4)/4; + while(count-->0) + printf("%llx",(data>>(count*4))&0xf); + } else { + if(_AP_S==false) + printf("0"); + printf("%016llx",*(ptr+i)); + } +#endif + for(--i;i>=0;i--) + printf("%016llx",*(ptr+i)); + printf("\n"); + +} +#endif /* #ifndef __AESL_GCC_AP_INT_H__ */ \ No newline at end of file diff --git a/hls_2018/router_05/etc/ap_private.h b/hls_2018/router_05/etc/ap_private.h new file mode 100755 index 0000000000000000000000000000000000000000..1a68a9e56e950d7108a3014149623c017023d809 --- /dev/null +++ b/hls_2018/router_05/etc/ap_private.h @@ -0,0 +1,5858 @@ +/* + * Copyright 2012 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LLVM_SUPPORT_MATHEXTRAS_H +#define LLVM_SUPPORT_MATHEXTRAS_H + +#ifdef _MSC_VER +#if _MSC_VER <= 1500 +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else if +#include +#endif /* #if _MSC_VER <= 1500 */ +#else +#include +#endif /* #if _MSC_VER <= 1500 */ +#undef INLINE +#if 1 +#define INLINE inline +#else +//Enable to debug ap_int/ap_fixed +#define INLINE __attribute__((weak)) +#endif +#define AP_MAX(a,b) ((a) > (b) ? (a) : (b)) +#define AP_MIN(a,b) ((a) < (b) ? (a) : (b)) +#define AP_ABS(a) ((a)>=0 ? (a):-(a)) +#ifndef AP_INT_MAX_W +#define AP_INT_MAX_W 1024 +#endif +#define BIT_WIDTH_UPPER_LIMIT (1 << 15) +#if AP_INT_MAX_W > BIT_WIDTH_UPPER_LIMIT +#error "Bitwidth exceeds 32768 (1 << 15), the maximum allowed value" +#endif +#define MAX_MODE(BITS) ((BITS + 1023) / 1024) + +// NOTE: The following support functions use the _32/_64 extensions instead of +// type overloading so that signed and unsigned integers can be used without +// ambiguity. + +/// Hi_32 - This function returns the high 32 bits of a 64 bit value. +INLINE uint32_t Hi_32(uint64_t Value) { + return static_cast(Value >> 32); +} + +/// Lo_32 - This function returns the low 32 bits of a 64 bit value. +INLINE uint32_t Lo_32(uint64_t Value) { + return static_cast(Value); +} + +/// ByteSwap_16 - This function returns a byte-swapped representation of the +/// 16-bit argument, Value. +INLINE uint16_t ByteSwap_16(uint16_t Value) { +#if defined(_MSC_VER) && !defined(_DEBUG) + // The DLL version of the runtime lacks these functions (bug!?), but in a + // release build they're replaced with BSWAP instructions anyway. + return (uint16_t)(_byteswap_ushort(Value)); +#else + uint16_t Hi = (uint16_t)((Value) << 8); + uint16_t Lo = (uint16_t)((Value) >> 8); + return Hi | Lo; +#endif +} + +/// ByteSwap_32 - This function returns a byte-swapped representation of the +/// 32-bit argument, Value. +INLINE uint32_t ByteSwap_32(uint32_t Value) { + uint32_t Byte0 = Value & 0x000000FF; + uint32_t Byte1 = Value & 0x0000FF00; + uint32_t Byte2 = Value & 0x00FF0000; + uint32_t Byte3 = Value & 0xFF000000; + return ((Byte0) << 24) | ((Byte1) << 8) | ((Byte2) >> 8) | ((Byte3) >> 24); +} + +/// ByteSwap_64 - This function returns a byte-swapped representation of the +/// 64-bit argument, Value. +INLINE uint64_t ByteSwap_64(uint64_t Value) { + uint64_t Hi = ByteSwap_32(uint32_t(Value)); + uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32)); + return ((Hi) << 32) | Lo; +} + +/// CountLeadingZeros_32 - this function performs the platform optimal form of +/// counting the number of zeros from the most significant bit to the first one +/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8. +/// Returns 32 if the word is zero. +INLINE unsigned CountLeadingZeros_32(uint32_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clz(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (Value == 0) return 32; +#endif + Count = __builtin_clz(Value); +#else + if (Value == 0) return 32; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) { + uint32_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } +#endif + return Count; +} + +/// CountLeadingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the most significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountLeadingZeros_64(uint64_t Value) { + unsigned Count; // result +#if __GNUC__ >= 4 + // PowerPC is defined for __builtin_clzll(0) +#if !defined(__ppc__) && !defined(__ppc64__) + if (!Value) return 64; +#endif + Count = __builtin_clzll(Value); +#else + if (sizeof(long) == sizeof(int64_t)) { + if (!Value) return 64; + Count = 0; + // bisecton method for count leading zeros + for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) { + uint64_t Tmp = (Value) >> (Shift); + if (Tmp) { + Value = Tmp; + } else { + Count |= Shift; + } + } + } else { + // get hi portion + uint32_t Hi = Hi_32(Value); + + // if some bits in hi portion + if (Hi) { + // leading zeros in hi portion plus all bits in lo portion + Count = CountLeadingZeros_32(Hi); + } else { + // get lo portion + uint32_t Lo = Lo_32(Value); + // same as 32 bit value + Count = CountLeadingZeros_32(Lo)+32; + } + } +#endif + return Count; +} + +/// CountTrailingZeros_64 - This function performs the platform optimal form +/// of counting the number of zeros from the least significant bit to the first +/// one bit (64 bit edition.) +/// Returns 64 if the word is zero. +INLINE unsigned CountTrailingZeros_64(uint64_t Value) { +#if __GNUC__ >= 4 + return (Value != 0) ? __builtin_ctzll(Value) : 64; +#else + static const unsigned Mod67Position[] = { + 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, + 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, + 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27, + 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56, + 7, 48, 35, 6, 34, 33, 0 + }; + return Mod67Position[(uint64_t)(-(int64_t)Value & (int64_t)Value) % 67]; +#endif +} + +/// CountPopulation_64 - this function counts the number of set bits in a value, +/// (64 bit edition.) +INLINE unsigned CountPopulation_64(uint64_t Value) { +#if __GNUC__ >= 4 + return __builtin_popcountll(Value); +#else + uint64_t v = Value - (((Value) >> 1) & 0x5555555555555555ULL); + v = (v & 0x3333333333333333ULL) + (((v) >> 2) & 0x3333333333333333ULL); + v = (v + ((v) >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); +#endif +} + +#endif // LLVM_SUPPORT_MATHEXTRAS_H + + +#ifndef AP_PRIVATE_H +#define AP_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AESL_std { + template + DataType INLINE min(DataType a, DataType b) { + // if (a >= b) return b; + // else return a; + return (a>=b) ? b : a; + } + + template + DataType INLINE max(DataType a, DataType b) { + // if (a >= b) return a; + // else return b; + return (a>=b) ? a : b; + } +} +enum ap_q_mode { + AP_RND, // rounding to plus infinity + AP_RND_ZERO,// rounding to zero + AP_RND_MIN_INF,// rounding to minus infinity + AP_RND_INF,// rounding to infinity + AP_RND_CONV, // convergent rounding + AP_TRN, // truncation + AP_TRN_ZERO // truncation to zero + +}; +enum ap_o_mode { + AP_SAT, // saturation + AP_SAT_ZERO, // saturation to zero + AP_SAT_SYM, // symmetrical saturation + AP_WRAP, // wrap-around (*) + AP_WRAP_SM // sign magnitude wrap-around (*) +}; + +template struct ap_fixed_base; +template struct af_range_ref; +template struct af_bit_ref; + +template struct ap_range_ref; +template struct ap_bit_ref; +template struct ap_concat_ref; +static bool InvalidDigit(const char* str, unsigned len, unsigned start, unsigned radix) { + unsigned i; + for (i = start; i < len; ++i) + if ((radix == 2 && (str[i] == '0' || str[i] == '1')) || + (radix == 8 && str[i] >= '0' && str[i] <= '7') || + (radix == 10 && str[i] >= '0' && str[i] <= '9') || + (radix == 16 && ((str[i] >= '0' && str[i] <= '9') || + (str[i] >= 'a' && str[i] <= 'f') || + (str[i] >= 'A' && str[i] <= 'F')))) + continue; + else + return true; + return false; +} + +static void ap_parse_sign(const char* str, uint32_t &base, bool &neg) { + if (str[0] == '+' || str[0] == '-') base = 1; + if (str[0] == '-') neg = true; + else neg = false; + return; +} + +static void ap_parse_prefix(const char* str, uint32_t &offset, uint32_t &radix) { + if (str[0] == '0') { + switch (str[1]) { + case 'b': + case 'B': offset = 2; radix = 2; break; + case 'x': + case 'X': offset = 2; radix = 16; break; + case 'd': + case 'D': offset = 2; radix = 10; break; + case 'o': + case 'O': offset = 2; radix = 8; break; + default: break; + } + } + if (offset == 0) + for (int i=0, len = strlen(str); i= 'a') || (str[i] <= 'F' && str[i] >= 'A')) { + radix = 16; + break; + } + return; +} + +/// sub_1 - This function subtracts a single "digit" (64-bit word), y, from +/// the multi-digit integer array, x[], propagating the borrowed 1 value until +/// no further borrowing is neeeded or it runs out of "digits" in x. The result +/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. +/// In other words, if y > x then this function returns 1, otherwise 0. +/// @returns the borrow out of the subtraction +static bool sub_1(uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + uint64_t __X = x[i]; + x[i] -= y; + if (y > __X) + y = 1; // We have to "borrow 1" from next "digit" + else { + y = 0; // No need to borrow + break; // Remaining digits are unchanged so exit early + } + } + return (y != 0); +} + + /// This enumeration just provides for internal constants used in this + /// translation unit. + enum { + MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MIN_INT_BITS + MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified + ///< Note that this must remain synchronized with IntegerType::MAX_INT_BITS + }; + + /// A utility function for allocating memory and checking for allocation + /// failure. The content is not zeroed. + static uint64_t* getMemory(uint32_t numWords) { + return (uint64_t*) malloc(numWords*sizeof(uint64_t)); + } + + //===----------------------------------------------------------------------===// + // ap_private Class + //===----------------------------------------------------------------------===// + + /// ap_private - This class represents arbitrary precision constant integral values. + /// It is a functional replacement for common case unsigned integer type like + /// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width + /// integer sizes and large integer value types such as 3-bits, 15-bits, or more + /// than 64-bits of precision. ap_private provides a variety of arithmetic operators + /// and methods to manipulate integer values of any bit-width. It supports both + /// the typical integer arithmetic and comparison operations as well as bitwise + /// manipulation. + /// + /// The class has several invariants worth noting: + /// * All bit, byte, and word positions are zero-based. + /// * Once the bit width is set, it doesn't change except by the Truncate, + /// SignExtend, or ZeroExtend operations. + /// * All binary operators must be on ap_private instances of the same bit width. + /// Attempting to use these operators on instances with different bit + /// widths will yield an assertion. + /// * The value is stored canonically as an unsigned value. For operations + /// where it makes a difference, there are both signed and unsigned variants + /// of the operation. For example, sdiv and udiv. However, because the bit + /// widths must be the same, operations such as Mul and Add produce the same + /// results regardless of whether the values are interpreted as signed or + /// not. + /// * In general, the class tries to follow the style of computation that LLVM + /// uses in its IR. This simplifies its use for LLVM. + /// + /// @brief Class for arbitrary precision integers. + template class ap_private; + namespace ap_private_ops{ + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + template + INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt); + } + +#if defined(_MSC_VER) +# if _MSC_VER < 1400 && !defined(for) +# define for if(0);else for +# endif + typedef unsigned __int64 ap_ulong; + typedef signed __int64 ap_slong; +#else + typedef unsigned long long ap_ulong; + typedef signed long long ap_slong; +#endif + template struct retval { + }; + template<> struct retval { + typedef ap_slong Type; + }; + template<> struct retval { + typedef ap_ulong Type; + }; + + template + class ap_private { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template friend struct ap_fixed_base; + ///return type of variety of operations + //---------------------------------------------------------- + template + struct RType { + enum { + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + + INLINE void report() { +#if 0 + if (_AP_W > 1024 && _AP_W <= 4096) { + fprintf(stderr, "[W] W=%d is out of bound (1<=W<=1024): for" + " synthesis: please define macro AP_INT_TYPE_EXT(N)" + " to extend the valid range.\n", _AP_W); + } else +#endif + if (_AP_W > MAX_MODE(AP_INT_MAX_W) * 1024) { + fprintf(stderr, "[E] ap_%sint<%d>: Bitwidth exceeds the " + "default max value %d. Please use macro " + "AP_INT_MAX_W to set a larger max value.\n", + _AP_S?"":"u", _AP_W, + MAX_MODE(AP_INT_MAX_W) * 1024); + exit(1); + } + } + + enum { BitWidth = _AP_W }; + /// This union is used to store the integer value. When the + /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal. + + /// This enum is used to hold the constants we needed for ap_private. + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t pVal[_AP_N]; ///< Used to store the >64 bits integer value. + + /// This enum is used to hold the constants we needed for ap_private. + enum { + APINT_BITS_PER_WORD = sizeof(uint64_t) * 8, ///< Bits in a word + APINT_WORD_SIZE = sizeof(uint64_t) ///< Byte size of a word + }; + + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + + /// This constructor is used only internally for speed of construction of + /// temporaries. It is unsafe for general use so it is not public. + /* Constructors */ + + ap_private(const char* val) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 16; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + ap_private(const char* val, int rd) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + // uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + // ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + ap_private ap_private_val(strp , strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + report(); + } + + /// Note that numWords can be smaller or larger than the corresponding bit + /// width but any extraneous bits will be dropped. + /// @param numBits the bit width of the constructed ap_private + /// @param numWords the number of words in bigVal + /// @param bigVal a sequence of words to form the initial value of the ap_private + /// @brief Construct an ap_private of numBits width, initialized as bigVal[]. + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(0) { + assert(bigVal && "Null pointer detected!"); + { + // Get memory, cleared to 0 + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Calculate the number of words to copy + uint32_t words = AESL_std::min(numWords, _AP_N); + // Copy the words from bigVal to pVal + memcpy(pVal, bigVal, words * APINT_WORD_SIZE); + if (words >= _AP_W) + clearUnusedBits(); + // Make sure unused high bits are cleared + } + } + + /// This constructor interprets Val as a string in the given radix. The + /// interpretation stops when the first charater that is not suitable for the + /// radix is encountered. Acceptable radix values are 2, 8, 10 and 16. It is + /// an error for the value implied by the string to require more bits than + /// numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param val the string to be interpreted + /// @param radix the radix of Val to use for the intepretation + /// @brief Construct an ap_private from a string representation. + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0) { + assert(!val.empty() && "The input string is empty."); + const char *c_str = val.c_str(); + fromString(c_str+base+offset, val.size()-base-offset, radix); + } + + /// This constructor interprets the slen characters starting at StrStart as + /// a string in the given radix. The interpretation stops when the first + /// character that is not suitable for the radix is encountered. Acceptable + /// radix values are 2, 8, 10 and 16. It is an error for the value implied by + /// the string to require more bits than numBits. + /// @param numBits the bit width of the constructed ap_private + /// @param strStart the start of the string to be interpreted + /// @param slen the maximum number of characters to interpret + /// @param radix the radix to use for the conversion + /// @brief Construct an ap_private from a string representation. + /// This method does not consider whether it is negative or not. + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0) { + fromString(strStart+base+offset, slen-base-offset, radix); + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) { + *this = ((uint64_t)(bool)ref); + report(); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) { + *this=ref.get(); + report(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + report(); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) { + *this = (uint64_t)(bool)val; + report(); + } + + /// Simply makes *this a copy of that. + /// @brief Copy Constructor. + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (const_cast& >(that)); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that): VAL(0) { + operator = (that); + } + + template + explicit ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that): VAL(0) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (that.isNegative()) { + pVal[0] = that.VAL|that_sign_ext_mask; + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); + } else { + pVal[0] = that.VAL; + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); + } + clearUnusedBits(); + } + + ap_private(const ap_private& that): VAL(0) { + memcpy(pVal, that.pVal, _AP_N * APINT_WORD_SIZE); + clearUnusedBits(); + } + + /// @brief Destructor. + virtual ~ap_private() {} + + /// Default constructor that creates an uninitialized ap_private. This is useful + /// for object deserialization (pair this with the static method Read). + ap_private(){memset(pVal, 0, sizeof(uint64_t)*(_AP_N));} + + ap_private(uint64_t* val, uint32_t bits=_AP_W) {assert(0);} + ap_private(const uint64_t *const val, uint32_t bits) {assert(0);} + + /// @name Constructors + /// @{ + /// If isSigned is true then val is treated as if it were a signed value + /// (i.e. as an int64_t) and the appropriate sign extension to the bit width + /// will be done. Otherwise, no sign extension occurs (high order bits beyond + /// the range of val are zero filled). + /// @param numBits the bit width of the constructed ap_private + /// @param val the initial value of the ap_private + /// @param isSigned how to treat signedness of val + /// @brief Create a new ap_private of numBits width, initialized as val. +#define CTOR(TYPE, SIGNED) \ + ap_private(TYPE val, bool isSigned=SIGNED) { \ + pVal[0] = val; \ + if (isSigned && int64_t(pVal[0]) < 0) { \ + memset(pVal+1, ~0, sizeof(uint64_t)*(_AP_N-1)); \ + } else { \ + memset(pVal+1, 0, sizeof(uint64_t)*(_AP_N-1)); \ + } \ + clearUnusedBits(); \ + } +#if 1 + CTOR(int, true) + CTOR(bool, false) + CTOR(signed char, true) + CTOR(unsigned char, false) + CTOR(short, true) + CTOR(unsigned short, false) + CTOR(unsigned int, false) + CTOR(long, true) + CTOR(unsigned long, false) + CTOR(unsigned long long, false) + CTOR(long long, true) + CTOR(float, false) + CTOR(double, false) +#undef CTOR +#else + CTOR(uint64_t) +#undef CTOR +#endif + + + /// @returns true if the number of bits <= 64, false otherwise. + /// @brief Determine if this ap_private just has one word to store value. + INLINE bool isSingleWord() const { + return false; + } + + /// @returns the word position for the specified bit position. + /// @brief Determine which word a bit is in. + static uint32_t whichWord(uint32_t bitPosition) { + // return bitPosition / APINT_BITS_PER_WORD; + return (bitPosition) >> 6; + } + + /// @returns the bit position in a word for the specified bit position + /// in the ap_private. + /// @brief Determine which bit in a word a bit is in. + static uint32_t whichBit(uint32_t bitPosition) { + // return bitPosition % APINT_BITS_PER_WORD; + return bitPosition & 0x3f; + } + + /// bit at a specific bit position. This is used to mask the bit in the + /// corresponding word. + /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set + /// @brief Get a single bit mask. + static uint64_t maskBit(uint32_t bitPosition) { + return 1ULL << (whichBit(bitPosition)); + } + + /// @returns the corresponding word for the specified bit position. + /// @brief Get the word corresponding to a bit position + INLINE uint64_t getWord(uint32_t bitPosition) const { + return isSingleWord() ? VAL : pVal[whichWord(bitPosition)]; + } + + /// This method is used internally to clear the to "N" bits in the high order + /// word that are not used by the ap_private. This is needed after the most + /// significant word is assigned a value to ensure that those bits are + /// zero'd out. + /// @brief Clear unused high order bits + INLINE void clearUnusedBits(void) { + pVal[_AP_N-1] = _AP_S ? ((((int64_t)pVal[_AP_N-1])<<(excess_bits))>> excess_bits) : (excess_bits ? ((pVal[_AP_N-1])<<(excess_bits))>>(excess_bits) : pVal[_AP_N-1]); + } + + INLINE void clearUnusedBitsToZero(void) { + pVal[_AP_N-1] &= mask; + } + + INLINE void clearUnusedBitsToOne(void) { + pVal[_AP_N-1] |= mask; + } + + /// This is used by the constructors that take string arguments. + /// @brief Convert a char array into an ap_private + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix) ; + + INLINE ap_private read() volatile { + return *this; + } + + INLINE void write(const ap_private& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + operator ValType() const { + return getVal(); + } + + INLINE ValType getVal() const{ + return *pVal; + } + + INLINE int to_int() const { + return int(*this); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + INLINE ap_private& set(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] |= maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + INLINE void set() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] = ~0ULL; + clearUnusedBits(); + } + + //Get the value of ith bit + INLINE bool get (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + /// Set the given bit to 0 whose position is given as "bitPosition". + /// @brief Set a given bit to 0. + ap_private& clear(uint32_t bitPosition) { + pVal[whichWord(bitPosition)] &= ~maskBit(bitPosition); + clearUnusedBits(); + return *this; + } + + /// @brief Set every bit to 0. + void clear() { + memset(pVal, 0, _AP_N * APINT_WORD_SIZE); + } + + /// @brief Toggle every bit to its opposite value. + ap_private& flip() { + for (uint32_t i = 0; i < _AP_N; ++i) + pVal[i] ^= ~0ULL; + clearUnusedBits(); + return *this; + } + + /// Toggle a given bit to its opposite value whose position is given + /// as "bitPosition". + /// @brief Toggles a given bit to its opposite value. + ap_private& flip(uint32_t bitPosition) { + assert(bitPosition < BitWidth && "Out of the bit-width range!"); + if ((*this)[bitPosition]) clear(bitPosition); + else set(bitPosition); + return *this; + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + ap_private getLoBits(uint32_t numBits) const { + return ap_private_ops::lshr(ap_private_ops::shl(*this, _AP_W - numBits), + _AP_W - numBits); + } + + ap_private getHiBits(uint32_t numBits) const { + return ap_private_ops::lshr(*this, _AP_W - numBits); + } + + //Binary Arithmetic + //----------------------------------------------------------- + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + ///Arithmetic assign + //------------------------------------------------------------- + +#define OP_BIN_LOGIC_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { \ + uint32_t numWords = AESL_std::min(_AP_N, _AP_N1); \ + uint32_t i; \ + for (i = 0; i < numWords; ++i) \ + pVal[i] Sym RHS.pVal[i]; \ + if (_AP_N1 < _AP_N) { \ + uint64_t ext = RHS.isNegative()?~0ULL:0; \ + for (;i<_AP_N; i++) \ + pVal[i] Sym ext; \ + } \ + clearUnusedBits(); \ + return *this; \ + } + + OP_BIN_LOGIC_ASSIGN_AP(&=); + OP_BIN_LOGIC_ASSIGN_AP(|=); + OP_BIN_LOGIC_ASSIGN_AP(^=); +#undef OP_BIN_LOGIC_ASSIGN_AP + + /// Adds the RHS APint to this ap_private. + /// @returns this, after addition of RHS. + /// @brief Addition assignment operator. + template + INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + add(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + sub(pVal, pVal, RHS.pVal, _AP_N, _AP_N, _AP_N1, _AP_S, _AP_S1); + clearUnusedBits(); + return *this; + } + + template + ap_private& operator*=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) { + // 0 * X ===> 0 + return *this; + } + + ap_private dupRHS = RHS; + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = dupRHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + clear(); + return *this; + } + + // Allocate space for the result + uint32_t destWords = rhsWords + lhsWords; + uint64_t *dest = getMemory(destWords); + + // Perform the long multiply + mul(dest, pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + // Copy result back into *this + clear(); + uint32_t wordsToCopy = destWords >= _AP_N ? _AP_N : destWords; + + memcpy(pVal, dest, wordsToCopy* APINT_WORD_SIZE); + + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0ULL; + for (int i=wordsToCopy; i<_AP_N; i++) + pVal[i]=ext; + clearUnusedBits(); + // delete dest array and return + free(dest); + return *this; + } + +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP(/) + OP_ASSIGN_AP(%) +#undef OP_ASSIGN_AP + +#define OP_BIN_LOGIC_AP(Sym) \ + template \ + INLINE \ + typename RType<_AP_W1, _AP_S1>::logic \ + operator Sym (const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { \ + enum { numWords = (RType<_AP_W1, _AP_S1>::logic_w +APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; \ + typename RType<_AP_W1, _AP_S1>::logic Result; \ + uint64_t *val = Result.pVal; \ + uint32_t i; \ + uint32_t min_N = std::min(_AP_N, _AP_N1); \ + uint32_t max_N = std::max(_AP_N, _AP_N1); \ + for (i = 0; i < min_N; ++i) \ + val[i] = pVal[i] Sym RHS.pVal[i]; \ + if (numWords > i) { \ + const uint64_t* tmpVal = (_AP_N>_AP_N1 ? pVal : RHS.pVal)+i; \ + uint64_t ext = ((_AP_N<_AP_N1 && isNegative() )||(_AP_N1 < _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + for (;i i) { \ + uint64_t ext2 = ((_AP_N>_AP_N1 && isNegative() )||(_AP_N1 > _AP_N && RHS.isNegative())) ? ~0ULL : 0; \ + val[i] = ext Sym ext2; \ + } \ + } \ + Result.clearUnusedBits(); \ + return Result; \ + } + + OP_BIN_LOGIC_AP(|); + OP_BIN_LOGIC_AP(&); + OP_BIN_LOGIC_AP(^); + +#undef OP_BIN_LOGIC_AP + + template + INLINE typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + // assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + typename RType<_AP_W1,_AP_S1>::plus Result; + bool carry = add(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::plus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::plus_w + 63) / 64> std::max(_AP_W, _AP_W1) ) + Result.pVal[(RType<_AP_W1,_AP_S1>::plus_w + 63)/64 - 1] = carry; + Result.clearUnusedBits(); + return Result; + } + + template + INLINE typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + typename RType<_AP_W1,_AP_S1>::minus Result; + bool borrow = sub(Result.pVal, this->pVal, RHS.pVal, (RType<_AP_W1,_AP_S1>::minus_w + 63) / 64, _AP_N, _AP_N1, _AP_S, _AP_S1); + if ((RType<_AP_W1,_AP_S1>::minus_w + 63) / 64 > AESL_std::max(_AP_W, _AP_W1) ) { + Result.pVal[(RType<_AP_W1,_AP_S1>::minus_w+63)/64 - 1] = borrow; + } + Result.clearUnusedBits(); + return Result; + } + + template + typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) const { + + // Get some bit facts about LHS and check for zero + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + if (!lhsWords) + // 0 * X ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + + // Get some bit facts about RHS and check for zero + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + if (!rhsWords) { + // X * 0 ===> 0 + return typename RType<_AP_W1, _AP_S1>::mult(); + } + + //extend size to avoid result loss + typename RType<_AP_W1, _AP_S1>::mult dupLHS = *this; + typename RType<_AP_W1, _AP_S1>::mult dupRHS = RHS; + lhsBits = dupLHS.getActiveBits(); + lhsWords = !lhsBits ? 0 : whichWord(lhsBits - 1) + 1; + rhsBits = dupRHS.getActiveBits(); + rhsWords = !rhsBits ? 0 : whichWord(rhsBits - 1) + 1; + + // Allocate space for the result + enum { destWords =(RType<_AP_W1, _AP_S1>::mult_w+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + int destw = destWords; + typename RType<_AP_W1, _AP_S1>::mult Result; + uint64_t *dest = Result.pVal; + uint64_t ext = (isNegative() ^ RHS.isNegative()) ? ~0ULL : 0; + + // Perform the long multiply + mul(dest, dupLHS.pVal, lhsWords, dupRHS.pVal, rhsWords, destWords); + + for (int i=lhsWords+rhsWords; i + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>& op) const { + ap_private lhs=*this; + ap_private rhs= op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod(_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + template + INLINE ap_private + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private + operator << (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=length()); + if(overflow) + r.clear(); + else + r = ap_private(r.shl(sh)); + return r; + } + + template + INLINE ap_private + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private + operator >> (uint32_t sh) const { + ap_private r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP(Sym) \ + template \ + INLINE ap_private& operator Sym##=(int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + INLINE ap_private& operator Sym##=(unsigned int op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } \ + template \ + INLINE ap_private& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this = operator Sym (op); \ + return *this; \ + } + OP_ASSIGN_AP(>>) + OP_ASSIGN_AP(<<) +#undef OP_ASSIGN_AP + ///Comparisons + //----------------------------------------------------------------- + bool operator==(const ap_private& RHS) const { + // Get some facts about the number of bits used in the two operands. + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If the number of bits isn't the same, they aren't equal + if (n1 != n2) + return false; + + // If the number of bits fits in a word, we only need to compare the low word. + if (n1 <= APINT_BITS_PER_WORD) + return pVal[0] == RHS.pVal[0]; + + // Otherwise, compare everything + for (int i = whichWord(n1 - 1); i >= 0; --i) + if (pVal[i] != RHS.pVal[i]) + return false; + return true; + } + + template + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S|_AP_S2> lhs(*this); + ap_private<_AP_MAX_W, _AP_S|_AP_S2> rhs(op); + return lhs==rhs; + } + + bool operator==(uint64_t Val) const { + uint32_t n = getActiveBits(); + if (n <= APINT_BITS_PER_WORD) + return pVal[0] == Val; + else + return false; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2>& op) const { + return !(*this==op); + } + + template + INLINE bool operator!=(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !((*this) == RHS); + } + + INLINE bool operator!=(uint64_t Val) const { + return !((*this) == Val); + } + + + template + INLINE bool operator <= (const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this>op); + } + + INLINE bool operator <(const ap_private& op) const { + return _AP_S ? slt(op):ult(op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2>& op) const { + return !(*this + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.sgt(rhs):lhs.ugt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ugt(rhs); + else + return lhs.sgt(rhs); + } + + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE bool operator [](uint32_t bitPosition) const { + return (maskBit(bitPosition) & (pVal[whichWord(bitPosition)])) != 0; + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE + ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + INLINE ap_private<_AP_W,false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + /// @} + /// @name Value Tests + /// @{ + /// This tests the high bit of this ap_private to determine if it is set. + /// @returns true if this ap_private is negative, false otherwise + /// @brief Determine sign of this ap_private. + INLINE bool isNegative() const { + //just for get rid of warnings + enum {shift = (_AP_W-APINT_BITS_PER_WORD*(_AP_N-1)-1)}; + static const uint64_t mask = 1ULL << (shift); + return _AP_S && (pVal[_AP_N-1]&mask); + } + + /// This tests the high bit of the ap_private to determine if it is unset. + /// @brief Determine if this ap_private Value is positive (not negative). + INLINE bool isPositive() const { + return !isNegative(); + } + + /// This tests if the value of this ap_private is strictly positive (> 0). + /// @returns true if this ap_private is Positive and not zero. + /// @brief Determine if this ap_private Value is strictly positive. + INLINE bool isStrictlyPositive() const { + return isPositive() && (*this) != 0; + } + + /// This checks to see if the value has all bits of the ap_private are set or not. + /// @brief Determine if all bits are set + INLINE bool isAllOnesValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest unsigned value. + INLINE bool isMaxValue() const { + return countPopulation() == _AP_W; + } + + /// This checks to see if the value of this ap_private is the maximum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the largest signed value. + INLINE bool isMaxSignedValue() const { + return BitWidth == 1 ? VAL == 0 : + !isNegative() && countPopulation() == _AP_W - 1; + } + + /// This checks to see if the value of this ap_private is the minimum unsigned + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest unsigned value. + INLINE bool isMinValue() const { + return countPopulation() == 0; + } + + /// This checks to see if the value of this ap_private is the minimum signed + /// value for the ap_private's bit width. + /// @brief Determine if this is the smallest signed value. + INLINE bool isMinSignedValue() const { + return BitWidth == 1 ? VAL == 1 : + isNegative() && countPopulation() == 1; + } + + /// This function returns a pointer to the internal storage of the ap_private. + /// This is useful for writing out the ap_private in binary form without any + /// conversions. + INLINE const uint64_t* getRawData() const { + if (isSingleWord()) + return &VAL; + return &pVal[0]; + } + + ap_private sqrt() const; + + /// @} + /// @Assignment Operators + /// @{ + /// @returns *this after assignment of RHS. + /// @brief Copy assignment operator. + INLINE ap_private& operator=(const ap_private& RHS) { + if (this != &RHS) + memcpy(pVal, RHS.pVal, _AP_N * APINT_WORD_SIZE); + return *this; + } + INLINE ap_private& operator=(const volatile ap_private& RHS) { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + INLINE volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + if (this != &RHS) + for (int i=0; i<_AP_N; ++i) + pVal[i] = RHS.pVal[i]; + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + if (_AP_S1) + cpSextOrTrunc(RHS); + else + cpZextOrTrunc(RHS); + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + template + INLINE ap_private& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + static const uint64_t that_sign_ext_mask = (_AP_W1==APINT_BITS_PER_WORD)?0:~0ULL>>(_AP_W1%APINT_BITS_PER_WORD)<<(_AP_W1%APINT_BITS_PER_WORD); + if (RHS.isNegative()) { + pVal[0] = RHS.VAL | that_sign_ext_mask; + memset(pVal+1,~0, APINT_WORD_SIZE*(_AP_N-1)); + } else { + pVal[0] = RHS.VAL; + memset(pVal+1, 0, APINT_WORD_SIZE*(_AP_N-1)); + } + clearUnusedBits(); + return *this; + } + + /// @} + /// @name Unary Operators + /// @{ + /// @returns a new ap_private value representing *this incremented by one + /// @brief Postfix increment operator. + INLINE const ap_private operator++(int) { + ap_private API(*this); + ++(*this); + return API; + } + + /// @returns *this incremented by one + /// @brief Prefix increment operator. + INLINE ap_private& operator++() { + add_1(pVal, pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// @returns a new ap_private representing *this decremented by one. + /// @brief Postfix decrement operator. + INLINE const ap_private operator--(int) { + ap_private API(*this); + --(*this); + return API; + } + + /// @returns *this decremented by one. + /// @brief Prefix decrement operator. + INLINE ap_private& operator--() { + sub_1(pVal, _AP_N, 1); + clearUnusedBits(); + return *this; + } + + /// Performs a bitwise complement operation on this ap_private. + /// @returns an ap_private that is the bitwise complement of *this + /// @brief Unary bitwise complement operator. + INLINE ap_private operator~() const { + ap_private Result(*this); + Result.flip(); + return Result; + } + + /// Negates *this using two's complement logic. + /// @returns An ap_private value representing the negation of *this. + /// @brief Unary negation operator + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + /// Performs logical negation operation on this ap_private. + /// @returns true if *this is zero, false otherwise. + /// @brief Logical negation operator. + INLINE bool operator !() const { + for (uint32_t i = 0; i < _AP_N; ++i) + if (pVal[i]) + return false; + return true; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator&(RHS); + } + template + INLINE ap_private Or(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator|(RHS); + } + template + ap_private Xor(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return this->operator^(RHS); + } + + ap_private Mul(const ap_private& RHS) const { + ap_private Result(*this); + Result *= RHS; + return Result; + } + + ap_private Add(const ap_private& RHS) const { + ap_private Result(0); + bool carry = add(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + ap_private Sub(const ap_private& RHS) const { + ap_private Result(0); + sub(Result.pVal, this->pVal, RHS.pVal, _AP_N, _AP_N, _AP_N, _AP_S, _AP_S); + Result.clearUnusedBits(); + return Result; + } + + /// Arithmetic right-shift this ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + ap_private ashr(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + // Handle a degenerate case + if (shiftAmt == 0) + return *this; + + // Handle single word shifts with built-in ashr + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(/*BitWidth, 0*/); // undefined + else { + uint32_t SignBit = APINT_BITS_PER_WORD - BitWidth; + return ap_private(/*BitWidth,*/ + (((int64_t(VAL) << (SignBit)) >> (SignBit)) >> (shiftAmt))); + } + } + + // If all the bits were shifted out, the result is, technically, undefined. + // We return -1 if it was negative, 0 otherwise. We check this early to avoid + // issues in the algorithm below. + if (shiftAmt == BitWidth) { + if (isNegative()) + return ap_private(-1); + else + return ap_private(0); + } + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // Compute some values needed by the following shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; // bits to shift per word + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; // word offset for shift + uint32_t breakWord = _AP_N - 1 - offset; // last word affected + uint32_t bitsInWord = whichBit(BitWidth); // how many bits in last word? + if (bitsInWord == 0) + bitsInWord = APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + // Move the words containing significant bits + for (uint32_t i = 0; i <= breakWord; ++i) + val[i] = pVal[i+offset]; // move whole word + + // Adjust the top significant word for sign bit fill, if negative + if (isNegative()) + if (bitsInWord < APINT_BITS_PER_WORD) + val[breakWord] |= ~0ULL << (bitsInWord); // set high bits + } else { + // Shift the low order words + for (uint32_t i = 0; i < breakWord; ++i) { + // This combines the shifted corresponding word with the low bits from + // the next word (shifted into this word's high bits). + val[i] = ((pVal[i+offset]) >> (wordShift)); + val[i] |= ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + } + + // Shift the break word. In this case there are no bits from the next word + // to include in this word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Deal with sign extenstion in the break word, and possibly the word before + // it. + if (isNegative()) { + if (wordShift > bitsInWord) { + if (breakWord > 0) + val[breakWord-1] |= + ~0ULL << (APINT_BITS_PER_WORD - (wordShift - bitsInWord)); + val[breakWord] |= ~0ULL; + } else + val[breakWord] |= (~0ULL << (bitsInWord - wordShift)); + } + } + + // Remaining words are 0 or -1, just assign them. + uint64_t fillValue = (isNegative() ? ~0ULL : 0); + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = fillValue; + Retval.clearUnusedBits(); + return Retval; + } + + /// Logical right-shift this ap_private by shiftAmt. + /// @brief Logical right-shift function. + ap_private lshr(uint32_t shiftAmt) const { + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); + else + return ap_private((this->VAL) >> (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids + // issues with shifting byt he size of the integer type, which produces + // undefined results in the code below. This is also an optimization. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t * val = Retval.pVal; + + // If we are shifting less than a word, compute the shift with a simple carry + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (int i = _AP_N-1; i >= 0; --i) { + val[i] = ((pVal[i]) >> (shiftAmt)) | carry; + carry = (pVal[i]) << (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < _AP_N - offset; ++i) + val[i] = pVal[i+offset]; + for (uint32_t i = _AP_N-offset; i < _AP_N; i++) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + // Shift the low order words + uint32_t breakWord = _AP_N - offset -1; + for (uint32_t i = 0; i < breakWord; ++i) + val[i] = ((pVal[i+offset]) >> (wordShift)) | + ((pVal[i+offset+1]) << (APINT_BITS_PER_WORD - wordShift)); + // Shift the break word. + val[breakWord] = (pVal[breakWord+offset]) >> (wordShift); + + // Remaining words are 0 + for (uint32_t i = breakWord+1; i < _AP_N; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + /// Left-shift this ap_private by shiftAmt. + /// @brief Left-shift function. + ap_private shl(uint32_t shiftAmt) const { + assert(shiftAmt <= BitWidth && "Invalid shift amount, too big"); + if (isSingleWord()) { + if (shiftAmt == BitWidth) + return ap_private(0); // avoid undefined shift results + return ap_private((VAL) << (shiftAmt)); + } + + // If all the bits were shifted out, the result is 0. This avoids issues + // with shifting by the size of the integer type, which produces undefined + // results. We define these "undefined results" to always be 0. + if (shiftAmt == BitWidth) + return ap_private(0); + + // If none of the bits are shifted out, the result is *this. This avoids a + // lshr by the words size in the loop below which can produce incorrect + // results. It also avoids the expensive computation below for a common case. + if (shiftAmt == 0) + return *this; + + // Create some space for the result. + ap_private Retval(0); + uint64_t* val = Retval.pVal; + // If we are shifting less than a word, do it the easy way + if (shiftAmt < APINT_BITS_PER_WORD) { + uint64_t carry = 0; + for (uint32_t i = 0; i < _AP_N; i++) { + val[i] = ((pVal[i]) << (shiftAmt)) | carry; + carry = (pVal[i]) >> (APINT_BITS_PER_WORD - shiftAmt); + } + Retval.clearUnusedBits(); + return Retval; + } + + // Compute some values needed by the remaining shift algorithms + uint32_t wordShift = shiftAmt % APINT_BITS_PER_WORD; + uint32_t offset = shiftAmt / APINT_BITS_PER_WORD; + + // If we are shifting whole words, just move whole words + if (wordShift == 0) { + for (uint32_t i = 0; i < offset; i++) + val[i] = 0; + for (uint32_t i = offset; i < _AP_N; i++) + val[i] = pVal[i-offset]; + Retval.clearUnusedBits(); + return Retval; + } + + // Copy whole words from this to Result. + uint32_t i = _AP_N - 1; + for (; i > offset; --i) + val[i] = (pVal[i-offset]) << (wordShift) | + (pVal[i-offset-1]) >> (APINT_BITS_PER_WORD - wordShift); + val[offset] = (pVal[0]) << (wordShift); + for (i = 0; i < offset; ++i) + val[i] = 0; + Retval.clearUnusedBits(); + return Retval; + } + + INLINE ap_private rotl(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + hi.shl(rotateAmt); + lo.lshr(BitWidth - rotateAmt); + return hi | lo; + } + + INLINE ap_private rotr(uint32_t rotateAmt) const { + if (rotateAmt == 0) + return *this; + // Don't get too fancy, just use existing shift/or facilities + ap_private hi(*this); + ap_private lo(*this); + lo.lshr(rotateAmt); + hi.shl(BitWidth - rotateAmt); + return hi | lo; + } + + /// Perform an unsigned divide operation on this ap_private by RHS. Both this and + /// RHS are treated as unsigned quantities for purposes of this division. + /// @returns a new ap_private value containing the division result + /// @brief Unsigned division operation. + ap_private udiv(const ap_private& RHS) const { + assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); + + // First, deal with the easy case + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Divide by zero?"); + return ap_private(VAL / RHS.VAL); + } + + // Get some facts about the LHS and RHS number of bits and words + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Divided by zero???"); + uint32_t lhsBits = this->getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Deal with some degenerate cases + if (!lhsWords) + // 0 / X ===> 0 + return ap_private(0); + else if (lhsWords < rhsWords || this->ult(RHS)) { + // X / Y ===> 0, iff X < Y + return ap_private(0); + } else if (*this == RHS) { + // X / X ===> 1 + return ap_private(1); + } else if (lhsWords == 1 && rhsWords == 1) { + // All high words are zero, just use native divide + return ap_private(this->pVal[0] / RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Quotient(0); // to hold result. + divide(*this, lhsWords, RHS, rhsWords, &Quotient, (ap_private*)0); + return Quotient; + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(const ap_private& RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Perform an unsigned remainder operation on this ap_private with RHS being the + /// divisor. Both this and RHS are treated as unsigned quantities for purposes + /// of this operation. Note that this is a true remainder operation and not + /// a modulo operation because the sign follows the sign of the dividend + /// which is *this. + /// @returns a new ap_private value containing the remainder result + /// @brief Unsigned remainder operation. + ap_private urem(const ap_private& RHS) const { + if (isSingleWord()) { + assert(RHS.VAL != 0 && "Remainder by zero?"); + return ap_private(VAL % RHS.VAL); + } + + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + + // Get some facts about the RHS + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS.pVal[0]); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, rhsWords, (ap_private*)(0), &Remainder); + return Remainder; + } + + ap_private urem(uint64_t RHS) const { + // Get some facts about the LHS + uint32_t lhsBits = getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (whichWord(lhsBits - 1) + 1); + // Get some facts about the RHS + uint32_t rhsBits = 64 - CountLeadingZeros_64(RHS); // RHS.getActiveBits(); + uint32_t rhsWords = 1;//!rhsBits ? 0 : (ap_private<_AP_W, _AP_S, _AP_N>::whichWord(rhsBits - 1) + 1); + assert(rhsWords && "Performing remainder operation by zero ???"); + // Check the degenerate cases + if (lhsWords == 0) { + // 0 % Y ===> 0 + return ap_private(0); + } else if (lhsWords < rhsWords || this->ult(RHS)) { + // X % Y ===> X, iff X < Y + return *this; + } else if (*this == RHS) { + // X % X == 0; + return ap_private(0); + } else if (lhsWords == 1) { + // All high words are zero, just use native remainder + return ap_private(pVal[0] % RHS); + } + + // We have to compute it the hard way. Invoke the Knuth divide algorithm. + ap_private Remainder(0); + divide(*this, lhsWords, RHS, (ap_private*)(0), &Remainder); + return Remainder; + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(const ap_private& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + /// Sometimes it is convenient to divide two ap_private values and obtain both + /// the quotient and remainder. This function does both operations in the + /// same computation making it a little more efficient. + /// @brief Dual division/remainder interface. + static void udivrem(const ap_private& LHS, const ap_private& RHS, ap_private &Quotient, ap_private& Remainder) { + // Get some size facts about the dividend and divisor + uint32_t lhsBits = LHS.getActiveBits(); + uint32_t lhsWords = !lhsBits ? 0 : (ap_private::whichWord(lhsBits - 1) + 1); + uint32_t rhsBits = RHS.getActiveBits(); + uint32_t rhsWords = !rhsBits ? 0 : (ap_private::whichWord(rhsBits - 1) + 1); + + // Check the degenerate cases + if (lhsWords == 0) { + Quotient = 0; // 0 / Y ===> 0 + Remainder = 0; // 0 % Y ===> 0 + return; + } + + if (lhsWords < rhsWords || LHS.ult(RHS)) { + Quotient = 0; // X / Y ===> 0, iff X < Y + Remainder = LHS; // X % Y ===> X, iff X < Y + return; + } + + if (LHS == RHS) { + Quotient = 1; // X / X ===> 1 + Remainder = 0; // X % X ===> 0; + return; + } + + if (lhsWords == 1 && rhsWords == 1) { + // There is only one word to consider so use the native versions. + if (LHS.isSingleWord()) { + Quotient = ap_private(LHS.VAL / RHS.VAL); + Remainder = ap_private(LHS.VAL % RHS.VAL); + } else { + Quotient = ap_private(LHS.pVal[0] / RHS.pVal[0]); + Remainder = ap_private(LHS.pVal[0] % RHS.pVal[0]); + } + return; + } + + // Okay, lets do it the long way + divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder); + } + + static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + /// Compares this ap_private with RHS for the validity of the equality + /// relationship. + /// @returns true if *this == Val + /// @brief Equality comparison. + template + INLINE bool eq(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return (*this) == RHS; + } + + /// Compares this ap_private with RHS for the validity of the inequality + /// relationship. + /// @returns true if *this != Val + /// @brief Inequality comparison + template + INLINE bool ne(const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template + INLINE bool ult(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS.pVal[0]; + + // Otherwise, compare all words + uint32_t topWord = whichWord(AESL_std::max(n1,n2)-1); + for (int i = topWord; i >= 0; --i) { + if (pVal[i] > RHS.pVal[i]) + return false; + if (pVal[i] < RHS.pVal[i]) + return true; + } + return false; + } + + INLINE bool ult(uint64_t RHS) const { + // Get active bit length of both operands + uint32_t n1 = getActiveBits(); + uint32_t n2 = 64 - CountLeadingZeros_64(RHS); //RHS.getActiveBits(); + + // If magnitude of LHS is less than RHS, return true. + if (n1 < n2) + return true; + + // If magnitude of RHS is greather than LHS, return false. + if (n2 < n1) + return false; + + // If they bot fit in a word, just compare the low order word + if (n1 <= APINT_BITS_PER_WORD && n2 <= APINT_BITS_PER_WORD) + return pVal[0] < RHS; + assert(0); + } + + template + INLINE bool slt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + ap_private lhs(*this); + ap_private<_AP_W, _AP_S1, _AP_N> rhs(RHS); + bool lhsNeg = isNegative(); + bool rhsNeg = rhs.isNegative(); + if (lhsNeg) { + // Sign bit is set so perform two's complement to make it positive + lhs.flip(); + lhs++; + } + if (rhsNeg) { + // Sign bit is set so perform two's complement to make it positive + rhs.flip(); + rhs++; + } + + // Now we have unsigned values to compare so do the comparison if necessary + // based on the negativeness of the values. + if (lhsNeg) + if (rhsNeg) + return lhs.ugt(rhs); + else + return true; + else if (rhsNeg) + return false; + else + return lhs.ult(rhs); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template + INLINE bool ule(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template + INLINE bool sle(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template + INLINE bool ugt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template + INLINE bool sgt(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template + INLINE bool uge(const ap_private<_AP_W, _AP_S, _AP_N>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template + INLINE bool sge(const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) const { + return !slt(RHS); + } + + template + void cpTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 > BitWidth && "Invalid ap_private Truncate request"); + assert(_AP_W1 >= MIN_INT_BITS && "Can't truncate to 0 bits"); + memcpy(pVal, that.pVal, _AP_N*APINT_WORD_SIZE); + } + + // Sign extend to a new width. + template + void cpSext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private SignExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + // If the sign bit isn't set, this is the same as zext. + if (!that.isNegative()) { + cpZext(that); + return; + } + + // The sign bit is set. First, get some facts + enum { wordBits = _AP_W1 % APINT_BITS_PER_WORD}; + + // Mask the high order word appropriately + if (_AP_N1 == _AP_N) { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + if (_AP_N1 == 1) { + assert(0); + } else { + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + return; + } + } + + if (_AP_N1 == 1) { + assert(0);// newVal[0] = VAL | mask; + } else { + enum { newWordBits = _AP_W % APINT_BITS_PER_WORD}; + // The extension is contained to the wordsBefore-1th word. + static const uint64_t mask = wordBits?(~0ULL<<(wordBits)):0ULL; + for (uint32_t i = 0; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + pVal[_AP_N1-1] |= mask; + } + for (uint32_t i=_AP_N1; i < _AP_N-1; i++) + pVal[i] = ~0ULL; + pVal[_AP_N-1] = ~0ULL; + clearUnusedBits(); + return; + } + + // Zero extend to a new width. + template + void cpZext(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + assert(_AP_W1 < BitWidth && "Invalid ap_private ZeroExtend request"); + assert(_AP_W1 <= MAX_INT_BITS && "Too many bits"); + uint32_t wordsAfter = _AP_N; + if (wordsAfter==1) { + assert(0); // return ap_private<_AP_W1, _AP_S, _AP_N1> (_AP_W1, VAL, _AP_S); + } else { + if (_AP_N1 == 1) { + assert(0); + // newVal[0] = VAL; + } else { + uint32_t i = 0; + for (; i < _AP_N1; ++i) + pVal[i] = that.pVal[i]; + for (; i < _AP_N; ++i) + pVal[i] = 0; + } + } + clearUnusedBits(); + } + + template + void cpZextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpZext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i]=that.pVal[i]; + clearUnusedBits(); + } + } + + template + void cpSextOrTrunc(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) { + if (BitWidth > _AP_W1) + cpSext(that); + else if (BitWidth < _AP_W1) + cpTrunc(that); + else { + for (int i=0; i<_AP_N1; ++i) + pVal[i] = that.pVal[i]; + clearUnusedBits(); + } + } + + /// @name Value Characterization Functions + /// @{ + + /// @returns the total number of bits. + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + /// Here one word's bitwidth equals to that of uint64_t. + /// @returns the number of words to hold the integer value of this ap_private. + /// @brief Get the number of words. + INLINE uint32_t getNumWords() const { + return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD; + } + + /// This function returns the number of active bits which is defined as the + /// bit width minus the number of leading zeros. This is used in several + /// computations to see how "wide" the value is. + /// @brief Compute the number of active bits in the value + INLINE uint32_t getActiveBits() const { + uint32_t bits=BitWidth - countLeadingZeros(); + return bits?bits:1; + } + + + /// This method attempts to return the value of this ap_private as a zero extended + /// uint64_t. The bitwidth must be <= 64 or the value must fit within a + /// uint64_t. Otherwise an assertion will result. + /// @brief Get zero extended value + INLINE uint64_t getZExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for uint64_t"); + return *pVal; + } + + /// This method attempts to return the value of this ap_private as a sign extended + /// int64_t. The bit width must be <= 64 or the value must fit within an + /// int64_t. Otherwise an assertion will result. + /// @brief Get sign extended value + INLINE int64_t getSExtValue() const { + assert(getActiveBits() <= 64 && "Too many bits for int64_t"); + return int64_t(pVal[0]); + } + + /// This method determines how many bits are required to hold the ap_private + /// equivalent of the string given by \p str of length \p slen. + /// @brief Get bits required for string value. + static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix); + + /// countLeadingZeros - This function is an ap_private version of the + /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number + /// of zeros from the most significant bit to the first one bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the most significant bit to the first + /// one bits. + INLINE uint32_t countLeadingZeros() const ; + + /// countLeadingOnes - This function counts the number of contiguous 1 bits + /// in the high order bits. The count stops when the first 0 bit is reached. + /// @returns 0 if the high order bit is not set + /// @returns the number of 1 bits from the most significant to the least + /// @brief Count the number of leading one bits. + INLINE uint32_t countLeadingOnes() const ; + + /// countTrailingZeros - This function is an ap_private version of the + /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts + /// the number of zeros from the least significant bit to the first set bit. + /// @returns BitWidth if the value is zero. + /// @returns the number of zeros from the least significant bit to the first + /// one bit. + /// @brief Count the number of trailing zero bits. + INLINE uint32_t countTrailingZeros() const ; + + /// countPopulation - This function is an ap_private version of the + /// countPopulation_{32,64} functions in MathExtras.h. It counts the number + /// of 1 bits in the ap_private value. + /// @returns 0 if the value is zero. + /// @returns the number of set bits. + /// @brief Count the number of bits set. + INLINE uint32_t countPopulation() const { + uint32_t Count = 0; + for (uint32_t i = 0; i<_AP_N-1 ; ++i) + Count += CountPopulation_64(pVal[i]); + Count += CountPopulation_64(pVal[_AP_N-1]&mask); + return Count; + } + + /// @} + /// @name Conversion Functions + /// @{ + + /// This is used internally to convert an ap_private to a string. + /// @brief Converts an ap_private to a std::string + INLINE std::string toString(uint8_t radix, bool wantSigned) const + ; + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + + /// Considers the ap_private to be unsigned and converts it into a string in the + /// radix given. The radix can be 2, 8, 10 or 16. + /// @returns a character interpretation of the ap_private + /// @brief Convert unsigned ap_private to string representation. + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + + /// @returns a byte-swapped representation of this ap_private Value. + INLINE ap_private byteSwap() const ; + + /// @brief Converts this ap_private to a double value. + INLINE double roundToDouble(bool isSigned) const ; + + /// @brief Converts this unsigned ap_private to a double value. + INLINE double roundToDouble() const { + return roundToDouble(false); + } + + /// @brief Converts this signed ap_private to a double value. + INLINE double signedRoundToDouble() const { + return roundToDouble(true); + } + + /// The conversion does not do a translation from integer to double, it just + /// re-interprets the bits as a double. Note that it is valid to do this on + /// any bit width. Exactly 64 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE double bitsToDouble() const { + union { + uint64_t __I; + double __D; + } __T; + __T.__I = pVal[0]; + return __T.__D; + } + + /// The conversion does not do a translation from integer to float, it just + /// re-interprets the bits as a float. Note that it is valid to do this on + /// any bit width. Exactly 32 bits will be translated. + /// @brief Converts ap_private bits to a double + INLINE float bitsToFloat() const { + union { + uint32_t __I; + float __F; + } __T; + __T.__I = uint32_t(pVal[0]); + return __T.__F; + } + + /// The conversion does not do a translation from double to integer, it just + /// re-interprets the bits of the double. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a double to ap_private bits. + INLINE ap_private& doubleToBits(double __V) { + union { + uint64_t __I; + double __D; + } __T; + __T.__D = __V; + pVal[0] = __T.__I; + return *this; + } + + /// The conversion does not do a translation from float to integer, it just + /// re-interprets the bits of the float. Note that it is valid to do this on + /// any bit width but bits from V may get truncated. + /// @brief Converts a float to ap_private bits. + INLINE ap_private& floatToBits(float __V) { + union { + uint32_t __I; + float __F; + } __T; + __T.__F = __V; + pVal[0] = __T.__I; + } + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return isMaxValue(); + } + + INLINE bool nand_reduce() const { + return isMinValue(); + } + + INLINE bool or_reduce() const { + return (bool)countPopulation(); + } + + INLINE bool nor_reduce() const { + return countPopulation()==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + INLINE std::string to_string(uint8_t radix=16, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; + +template +INLINE bool operator==(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 == V1; +} + +template +INLINE bool operator!=(uint64_t V1, const ap_private<_AP_W, _AP_S, _AP_N>& V2) { + return V2 != V1; +} + +namespace ap_private_ops { + enum {APINT_BITS_PER_WORD=64}; + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.slt(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> smax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.sgt(RHS) ? LHS : RHS; + } + + /// @brief Determine the smaller of two ap_privates considered to be signed. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umin(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ult(RHS) ? LHS : RHS; + } + + /// @brief Determine the larger of two ap_privates considered to be unsigned. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> umax(const ap_private<_AP_W, _AP_S, _AP_N> &LHS, const ap_private<_AP_W, _AP_S1, _AP_N> &RHS) { + return LHS.ugt(RHS) ? LHS : RHS; + } + + /// @brief Check if the specified ap_private has a N-bits integer value. + template + INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); + } + + /// @returns true if the argument ap_private value is a sequence of ones + /// starting at the least significant bit with the remainder zero. + template + INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; + } + + /// @returns true if the argument ap_private value contains a sequence of ones + /// with the remainder zero. + template + INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); + } + + /// @returns a byte-swapped representation of the specified ap_private Value. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> byteSwap(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.byteSwap(); + } + + /// @returns the floor log base 2 of the specified ap_private value. + template INLINE uint32_t logBase2(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.logBase2(); + } + + /// GreatestCommonDivisor - This function returns the greatest common + /// divisor of the two ap_private values using Enclid's algorithm. + /// @returns the greatest common divisor of Val1 and Val2 + /// @brief Compute GCD of two ap_private values. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& Val1, const ap_private<_AP_W, _AP_S, _AP_N>& Val2) + ; + + /// Treats the ap_private as an unsigned value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double Roundap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.roundToDouble(); + } + + /// Treats the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a double value. + template INLINE double RoundSignedap_privateToDouble(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.signedRoundToDouble(); + } + + /// @brief Converts the given ap_private to a float vlalue. + template INLINE float Roundap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(Roundap_privateToDouble(APIVal)); + } + + /// Treast the ap_private as a signed value for conversion purposes. + /// @brief Converts the given ap_private to a float value. + template INLINE float RoundSignedap_privateToFloat(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return float(APIVal.signedRoundToDouble()); + } + + /// RoundDoubleToap_private - This function convert a double value to an ap_private value. + /// @brief Converts the given double value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundDoubleToap_private(double Double, uint32_t width) ; + + /// RoundFloatToap_private - Converts a float value into an ap_private value. + /// @brief Converts a float value into a ap_private. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> RoundFloatToap_private(float Float, uint32_t width) { + return RoundDoubleToap_private<_AP_W, _AP_S, _AP_N>(double(Float), width); + } + + /// Arithmetic right-shift the ap_private by shiftAmt. + /// @brief Arithmetic right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> ashr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.ashr(shiftAmt); + } + + /// Logical right-shift the ap_private by shiftAmt. + /// @brief Logical right-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> lshr(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.lshr(shiftAmt); + } + + /// Left-shift the ap_private by shiftAmt. + /// @brief Left-shift function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> shl(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t shiftAmt) { + return LHS.shl(shiftAmt); + } + + /// Signed divide ap_private LHS by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sdiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.sdiv(RHS); + } + + /// Unsigned divide ap_private LHS by ap_private RHS. + /// @brief Unsigned division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> udiv(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.udiv(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> srem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.srem(RHS); + } + + /// Unsigned remainder operation on ap_private. + /// @brief Function for unsigned remainder operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> urem(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS.urem(RHS); + } + + /// Performs multiplication on ap_private values. + /// @brief Function for multiplication operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> mul(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS * RHS; + } + + /// Performs addition on ap_private values. + /// @brief Function for addition operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> add(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS + RHS; + } + + /// Performs subtraction on ap_private values. + /// @brief Function for subtraction operation. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> sub(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS - RHS; + } + + /// Performs bitwise AND operation on ap_private LHS and + /// ap_private RHS. + /// @brief Bitwise AND function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> And(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS & RHS; + } + + /// Performs bitwise OR operation on ap_private LHS and ap_private RHS. + /// @brief Bitwise OR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Or(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS | RHS; + } + + /// Performs bitwise XOR operation on ap_private. + /// @brief Bitwise XOR function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1, _AP_N> Xor(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, const ap_private<_AP_W, _AP_S1, _AP_N>& RHS) { + return LHS ^ RHS; + } + + /// Performs a bitwise complement operation on ap_private. + /// @brief Bitwise complement function. + template INLINE ap_private<_AP_W, _AP_S, _AP_N> Not(const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return ~APIVal; + } + + template void clearUnusedBits(uint64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(uint64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + template void clearUnusedBits(int64_t& msw) { + // Compute how many bits are used in the final word + // uint32_t wordBits = APIVal.getBitWidth() & 0x3f; + if (wordBits == 0) + // If all bits are used, we want to leave the value alone. This also + // avoids the undefined behavior of >> when the shfit is the same size as + // the word size (64). + return; + + // Mask out the hight bits. + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- wordBits); + msw &= mask; + } + template <> INLINE void clearUnusedBits<1>(int64_t& msw) { + uint64_t mask = ~uint64_t(0ULL) >> (64 /*ap_private::APINT_BITS_PER_WORD */- 1); + msw &= mask; + } + // template + template + INLINE ap_private<_AP_W, _AP_S> ashr(const ap_private<_AP_W, _AP_S>& a) { + return ashr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S>& a) { + return lshr(a, shiftAmt); + } + + template + INLINE ap_private<_AP_W, true> ashr(const ap_private<_AP_W, true, 1>& a) { + enum {APINT_BITS_PER_WORD=64, excess_bits=APINT_BITS_PER_WORD-_AP_W}; + static const uint64_t sign_bit = (1ULL<<(_AP_W-1)); + static const uint64_t sign_ext_mask = (_AP_W-shiftAmt>0)?~0ULL<<(APINT_BITS_PER_WORD-_AP_W+shiftAmt):~0ULL; + return ap_private<_AP_W, true>((((int64_t)a.VAL) >> (shiftAmt)) | (a.VAL & sign_bit? sign_ext_mask : 0ULL)); + } + + template + INLINE ap_private<_AP_W, false> ashr(const ap_private<_AP_W, false, 1>& a) { + return ap_private<_AP_W, false>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W, _AP_S> lshr(const ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~0ULL<<_AP_W; + return ap_private<_AP_W, _AP_S>((a.VAL&mask) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W-shiftAmt, _AP_S> shr(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W-shiftAmt, _AP_S>((a.VAL) >> (shiftAmt)); + } + + template + INLINE ap_private<_AP_W+shiftAmt, _AP_S> shl(const ap_private<_AP_W, _AP_S>& a) { + return ap_private<_AP_W+shiftAmt, _AP_S>((a.VAL) << (shiftAmt)); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S, 1>& a) { + unsigned shift = (index%APINT_BITS_PER_WORD); + static const uint64_t mask=1ULL << (shift); + return ((mask & a.VAL) != 0); + } + + template + INLINE bool get(const ap_private<_AP_W, _AP_S>& a) { + static const uint64_t mask=1ULL << (index&0x3f); + return ((mask & a.pVal[(index)>>6]) != 0); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.VAL |= mask; + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask = ~(~0ULL >> (lsb) <<(APINT_BITS_PER_WORD-msb+lsb-1) >> (APINT_BITS_PER_WORD-msb-1)); + a.VAL &= mask; + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word==lsb_word) { + const uint64_t mask = ~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[msb_word] |= mask; + } else { + const uint64_t lsb_mask = ~0ULL >> (lsb) << (lsb); + const uint64_t msb_mask = ~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1); + a.pVal[lsb_word] |=lsb_mask; + for (int i=lsb_word+1; i + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, + lsb_word = lsb_index /APINT_BITS_PER_WORD, + msb_word = msb_index / APINT_BITS_PER_WORD, + msb = msb_index % APINT_BITS_PER_WORD, + lsb=lsb_index % APINT_BITS_PER_WORD}; + if (msb_word == lsb_word) { + const uint64_t mask = ~(~0ULL >> (lsb) << (APINT_BITS_PER_WORD-msb+lsb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[msb_word] &= mask; + } else { + const uint64_t lsb_mask = ~(~0ULL >> (lsb) << (lsb)); + const uint64_t msb_mask = ~(~0ULL << (APINT_BITS_PER_WORD-msb-1)>>(APINT_BITS_PER_WORD-msb-1)); + a.pVal[lsb_word] &=lsb_mask; + for (int i=lsb_word+1; i + INLINE void set(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=1ULL << (index); + a.VAL |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S, 1>& a) { + static const uint64_t mask=~(1ULL << (index)); + a.VAL &= mask; + a.clearUnusedBits(); + } + + template + INLINE void set(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=1ULL << (index%APINT_BITS_PER_WORD); + a.pVal[word] |= mask; + a.clearUnusedBits(); + } + + template + INLINE void clear(ap_private<_AP_W, _AP_S>& a) { + enum { APINT_BITS_PER_WORD=64, word = index/APINT_BITS_PER_WORD}; + static const uint64_t mask=~(1ULL << (index%APINT_BITS_PER_WORD)); + a.pVal[word] &= mask; + a.clearUnusedBits(); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, false>& a) { + return false; + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true, 1>& a) { + static const uint64_t sign_mask = (1ULL << (_AP_W-1)); + return ((sign_mask & a.VAL) != 0); + } + + template + INLINE bool isNegative(const ap_private<_AP_W, true>& a) { + enum {APINT_BITS_PER_WORD=64,_AP_N=(_AP_W+APINT_BITS_PER_WORD-1)/APINT_BITS_PER_WORD}; + static const uint64_t sign_mask = (1ULL << (_AP_W%APINT_BITS_PER_WORD-1)); + return sign_mask & a.pVal[_AP_N-1]; + } +} // End of ap_private_ops namespace + +/// @brief Check if the specified ap_private has a N-bits integer value. +template +INLINE bool isIntN(uint32_t __N, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.isIntN(__N); +} + +/// @returns true if the argument ap_private value is a sequence of ones +/// starting at the least significant bit with the remainder zero. +template +INLINE bool isMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return APIVal.getBoolValue() && ((APIVal + ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) & APIVal) == 0; +} + +/// @returns true if the argument ap_private value contains a sequence of ones +/// with the remainder zero. +template +INLINE bool isShiftedMask(uint32_t numBits, const ap_private<_AP_W, _AP_S, _AP_N>& APIVal) { + return isMask(numBits, (APIVal - ap_private<_AP_W, _AP_S, _AP_N>(numBits,1)) | APIVal); +} + +#if 0 +/// add_1 - This function adds a single "digit" integer, y, to the multiple +/// "digit" integer array, x[]. x[] is modified to reflect the addition and +/// 1 is returned if there is a carry out, otherwise 0 is returned. +/// @returns the carry of the addition. +static bool add_1(uint64_t dest[], uint64_t x[], uint32_t len, uint64_t y) { + for (uint32_t i = 0; i < len; ++i) { + dest[i] = y + x[i]; + if (dest[i] < y) + y = 1; // Carry one to next digit. + else { + y = 0; // No need to carry so exit early + break; + } + } + return (y != 0); +} +#endif + +#if 0 +/// add - This function adds the integer array x to the integer array Y and +/// places the result in dest. +/// @returns the carry out from the addition +/// @brief General addition of 64-bit integer arrays +static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool carry = false; + uint32_t len = AESL_std::min(xlen, ylen); + uint32_t i; + for (i = 0; i< len && i < destlen; ++i) { + uint64_t limit = AESL_std::min(x[i],y[i]); // must come first in case dest == x + dest[i] = x[i] + y[i] + carry; + carry = dest[i] < limit || (carry && dest[i] == limit); + } + if (xlen > ylen) { + const uint64_t yext = xsigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t limit = AESL_std::min(x[i], yext); + dest[i] = x[i] + yext + carry; + carry = (dest[i] < limit)||(carry && dest[i] == x[i]); + } + } else if (ylen> xlen) { + const uint64_t xext = ysigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t limit = AESL_std::min(xext, y[i]); + dest[i] = xext + y[i] + carry; + carry = (dest[i] < limit)||(carry && dest[i] == y[i]); + } + } + return carry; +} +#endif + +#if 0 +/// @returns returns the borrow out. +/// @brief Generalized subtraction of 64-bit integer arrays. +static bool sub(uint64_t *dest, const uint64_t *x, const uint64_t *y, + uint32_t destlen, uint32_t xlen, uint32_t ylen, bool xsigned, bool ysigned) { + bool borrow = false; + uint32_t i; + uint32_t len = AESL_std::min(xlen, ylen); + for (i = 0; i < len && i < destlen; ++i) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = y[i] > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - y[i]; + } + if (xlen > ylen) { + const uint64_t yext = ysigned && int64_t(y[ylen-1])<0 ? -1 : 0; + for (i=ylen; i< xlen && i < destlen; i++) { + uint64_t x_tmp = borrow ? x[i] - 1 : x[i]; + borrow = yext > x_tmp || (borrow && x[i] == 0); + dest[i] = x_tmp - yext; + } + } else if (ylen> xlen) { + const uint64_t xext = xsigned && int64_t(x[xlen-1])<0 ? -1 : 0; + for (i=xlen; i< ylen && i < destlen; i++) { + uint64_t x_tmp = borrow ? xext - 1 : xext; + borrow = y[i] > x_tmp || (borrow && xext==0); + dest[i] = x_tmp - y[i]; + } + } + return borrow; +} +#endif + +/// Subtracts the RHS ap_private from this ap_private +/// @returns this, after subtraction +/// @brief Subtraction assignment operator. + +#if 0 +/// Multiplies an integer array, x by a a uint64_t integer and places the result +/// into dest. +/// @returns the carry out of the multiplication. +/// @brief Multiply a multi-digit ap_private by a single digit (64-bit) integer. +static uint64_t mul_1(uint64_t dest[], const uint64_t x[], uint32_t len, uint64_t y) { + // Split y into high 32-bit part (hy) and low 32-bit part (ly) + uint64_t ly = y & 0xffffffffULL, hy = (y) >> 32; + uint64_t carry = 0; + static const uint64_t two_power_32 = 1ULL << 32; + // For each digit of x. + for (uint32_t i = 0; i < len; ++i) { + // Split x into high and low words + uint64_t lx = x[i] & 0xffffffffULL; + uint64_t hx = (x[i]) >> 32; + // hasCarry - A flag to indicate if there is a carry to the next digit. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + dest[i] = carry + lx * ly; + // Determine if the add above introduces carry. + hasCarry = (dest[i] < carry) ? 1 : 0; + carry = hx * ly + ((dest[i]) >> 32) + (hasCarry ? two_power_32 : 0); + // The upper limit of carry can be (2^32 - 1)(2^32 - 1) + + // (2^32 - 1) + 2^32 = 2^64. + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + + carry += (lx * hy) & 0xffffffffULL; + dest[i] = ((carry) << 32) | (dest[i] & 0xffffffffULL); + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? two_power_32 : 0) + + ((carry) >> 32) + ((lx * hy) >> 32) + hx * hy; + } + return carry; +} +#endif + +#if 0 +/// Multiplies integer array x by integer array y and stores the result into +/// the integer array dest. Note that dest's size must be >= xlen + ylen. +/// @brief Generalized multiplicate of integer arrays. +static void mul(uint64_t dest[], const uint64_t x[], uint32_t xlen, const uint64_t y[], + uint32_t ylen, uint32_t destlen) { + dest[xlen] = mul_1(dest, x, xlen, y[0]); + for (uint32_t i = 1; i < ylen; ++i) { + uint64_t ly = y[i] & 0xffffffffULL, hy = (y[i]) >> 32; + uint64_t carry = 0, lx = 0, hx = 0; + for (uint32_t j = 0; j < xlen; ++j) { + lx = x[j] & 0xffffffffULL; + hx = (x[j]) >> 32; + // hasCarry - A flag to indicate if has carry. + // hasCarry == 0, no carry + // hasCarry == 1, has carry + // hasCarry == 2, no carry and the calculation result == 0. + uint8_t hasCarry = 0; + uint64_t resul = carry + lx * ly; + hasCarry = (resul < carry) ? 1 : 0; + carry = (hasCarry ? (1ULL << 32) : 0) + hx * ly + ((resul) >> 32); + hasCarry = (!carry && hasCarry) ? 1 : (!carry ? 2 : 0); + carry += (lx * hy) & 0xffffffffULL; + resul = ((carry) << 32) | (resul & 0xffffffffULL); + dest[i+j] += resul; + carry = (((!carry && hasCarry != 2) || hasCarry == 1) ? (1ULL << 32) : 0)+ + ((carry) >> 32) + (dest[i+j] < resul ? 1 : 0) + + ((lx * hy) >> 32) + hx * hy; + } + dest[i+xlen] = carry; + } +} +#endif + + + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + assert(str != 0 && "Invalid value string"); + assert(slen > 0 && "Invalid string length"); + + // Each computation below needs to know if its negative + uint32_t isNegative = str[0] == '-'; + if (isNegative) { + slen--; + str++; + } + // For radixes of power-of-two values, the bits required is accurately and + // easily computed + if (radix == 2) + return slen + isNegative; + if (radix == 8) + return slen * 3 + isNegative; + if (radix == 16) + return slen * 4 + isNegative; + + // Otherwise it must be radix == 10, the hard case + assert(radix == 10 && "Invalid radix"); + + // Convert to the actual binary value. + //ap_private<_AP_W, _AP_S, _AP_N> tmp(sufficient, str, slen, radix); + + // Compute how many bits are required. + //return isNegative + tmp.logBase2() + 1; + return isNegative + slen * 4; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingZeros() const { + enum { msw_bits = (BitWidth % APINT_BITS_PER_WORD)?(BitWidth % APINT_BITS_PER_WORD):APINT_BITS_PER_WORD, + excessBits = APINT_BITS_PER_WORD - msw_bits }; + uint32_t Count = CountLeadingZeros_64(pVal[_AP_N-1]); + if (Count>=excessBits) + Count -= excessBits; + if (!pVal[_AP_N-1]) { + for (uint32_t i = _AP_N-1 ; i ; --i) { + if (!pVal[i-1]) + Count += APINT_BITS_PER_WORD; + else { + Count += CountLeadingZeros_64(pVal[i-1]); + break; + } + } + } + return Count; +} + +static uint32_t countLeadingOnes_64(uint64_t __V, uint32_t skip) { + uint32_t Count = 0; + if (skip) + (__V) <<= (skip); + while (__V && (__V & (1ULL << 63))) { + Count++; + (__V) <<= 1; + } + return Count; +} + +template +uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countLeadingOnes() const { + if (isSingleWord()) + return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth); + + uint32_t highWordBits = BitWidth % APINT_BITS_PER_WORD; + uint32_t shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits); + int i = _AP_N - 1; + uint32_t Count = countLeadingOnes_64(pVal[i], shift); + if (Count == highWordBits) { + for (i--; i >= 0; --i) { + if (pVal[i] == ~0ULL) + Count += APINT_BITS_PER_WORD; + else { + Count += countLeadingOnes_64(pVal[i], 0); + break; + } + } + } + return Count; +} + +template +INLINE uint32_t ap_private<_AP_W, _AP_S, _AP_N>::countTrailingZeros() const { + if (isSingleWord()) + return AESL_std::min(uint32_t(CountTrailingZeros_64(VAL)), BitWidth); + uint32_t Count = 0; + uint32_t i = 0; + for (; i < _AP_N && pVal[i] == 0; ++i) + Count += APINT_BITS_PER_WORD; + if (i < _AP_N) + Count += CountTrailingZeros_64(pVal[i]); + return AESL_std::min(Count, BitWidth); +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::byteSwap() const { + assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!"); + if (BitWidth == 16) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_16(uint16_t(VAL))); + else if (BitWidth == 32) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_32(uint32_t(VAL))); + else if (BitWidth == 48) { + uint32_t Tmp1 = uint32_t((VAL) >> 16); + Tmp1 = ByteSwap_32(Tmp1); + uint16_t Tmp2 = uint16_t(VAL); + Tmp2 = ByteSwap_16(Tmp2); + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ((uint64_t(Tmp2)) << 32) | Tmp1); + } else if (BitWidth == 64) + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ ByteSwap_64(VAL)); + else { + ap_private<_AP_W, _AP_S, _AP_N> Result(0); + char *pByte = (char*)Result.pVal; + for (uint32_t i = 0; i < BitWidth / APINT_WORD_SIZE / 2; ++i) { + char Tmp = pByte[i]; + pByte[i] = pByte[BitWidth / APINT_WORD_SIZE - 1 - i]; + pByte[BitWidth / APINT_WORD_SIZE - i - 1] = Tmp; + } + return Result; + } +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::GreatestCommonDivisor(const ap_private<_AP_W, _AP_S, _AP_N>& API1, const ap_private<_AP_W, _AP_S, _AP_N>& API2) { + ap_private<_AP_W, _AP_S, _AP_N> __A = API1, __B = API2; + while (!!__B) { + ap_private<_AP_W, _AP_S, _AP_N> __T = __B; + __B = ap_private_ops::urem(__A, __B); + __A = __T; + } + return __A; +} + +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private_ops::RoundDoubleToap_private(double Double, uint32_t width) { + union { + double __D; + uint64_t __I; + } __T; + __T.__D = Double; + + // Get the sign bit from the highest order bit + bool isNeg = (__T.__I) >> 63; + + // Get the 11-bit exponent and adjust for the 1023 bit bias + int64_t exp = (((__T.__I) >> 52) & 0x7ffULL) - 1023; + + // If the exponent is negative, the value is < 0 so just return 0. + if (exp < 0) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0u); + + // Extract the mantissa by clearing the top 12 bits (sign + exponent). + uint64_t mantissa = (__T.__I & (~0ULL >> 12)) | 1ULL << 52; + + // If the exponent doesn't shift all bits out of the mantissa + if (exp < 52) + return isNeg ? -ap_private<_AP_W, _AP_S, _AP_N>(width, (mantissa) >> (52 - exp)) : + ap_private<_AP_W, _AP_S, _AP_N>((mantissa) >> (52 - exp)); + + // If the client didn't provide enough bits for us to shift the mantissa into + // then the result is undefined, just return 0 + if (width <= exp - 52) + return ap_private<_AP_W, _AP_S, _AP_N>(width, 0); + + // Otherwise, we have to shift the mantissa bits up to the right location + ap_private<_AP_W, _AP_S, _AP_N> Tmp(width, mantissa); + Tmp = Tmp.shl(exp - 52); + return isNeg ? -Tmp : Tmp; +} + +/// RoundToDouble - This function convert this ap_private to a double. +/// The layout for double is as following (IEEE Standard 754): +/// -------------------------------------- +/// | Sign Exponent Fraction Bias | +/// |-------------------------------------- | +/// | 1[63] 11[62-52] 52[51-00] 1023 | +/// -------------------------------------- +template +double ap_private<_AP_W, _AP_S, _AP_N>::roundToDouble(bool isSigned) const { + + // Handle the simple case where the value is contained in one uint64_t. + if (isSingleWord() || getActiveBits() <= APINT_BITS_PER_WORD) { + uint64_t val; + if (isSingleWord()) val = VAL; + else val = pVal[0]; + if (isSigned) { + int64_t sext = ((int64_t(val)) << (64-BitWidth)) >> (64-BitWidth); + return double(sext); + } else + return double(val); + } + + // Determine if the value is negative. + bool isNeg = isSigned ? (*this)[BitWidth-1] : false; + + // Construct the absolute value if we're negative. + ap_private<_AP_W, _AP_S, _AP_N> Tmp(isNeg ? -(*this) : (*this)); + + // Figure out how many bits we're using. + uint32_t n = Tmp.getActiveBits(); + + // The exponent (without bias normalization) is just the number of bits + // we are using. Note that the sign bit is gone since we constructed the + // absolute value. + uint64_t exp = n; + + // Return infinity for exponent overflow + if (exp > 1023) { + if (!isSigned || !isNeg) + return std::numeric_limits::infinity(); + else + return -std::numeric_limits::infinity(); + } + exp += 1023; // Increment for 1023 bias + + // Number of bits in mantissa is 52. To obtain the mantissa value, we must + // extract the high 52 bits from the correct words in pVal. + uint64_t mantissa; + unsigned hiWord = whichWord(n-1); + if (hiWord == 0) { + mantissa = Tmp.pVal[0]; + if (n > 52) + (mantissa) >>= (n - 52); // shift down, we want the top 52 bits. + } else { + assert(hiWord > 0 && "High word is negative?"); + uint64_t hibits = (Tmp.pVal[hiWord]) << (52 - n % APINT_BITS_PER_WORD); + uint64_t lobits = (Tmp.pVal[hiWord-1]) >> (11 + n % APINT_BITS_PER_WORD); + mantissa = hibits | lobits; + } + + // The leading bit of mantissa is implicit, so get rid of it. + uint64_t sign = isNeg ? (1ULL << (APINT_BITS_PER_WORD - 1)) : 0; + union { + double __D; + uint64_t __I; + } __T; + __T.__I = sign | ((exp) << 52) | mantissa; + return __T.__D; +} + +// Square Root - this method computes and returns the square root of "this". +// Three mechanisms are used for computation. For small values (<= 5 bits), +// a table lookup is done. This gets some performance for common cases. For +// values using less than 52 bits, the value is converted to double and then +// the libc sqrt function is called. The result is rounded and then converted +// back to a uint64_t which is then used to construct the result. Finally, +// the Babylonian method for computing square roots is used. +template +ap_private<_AP_W, _AP_S, _AP_N> ap_private<_AP_W, _AP_S, _AP_N>::sqrt() const { + + // Determine the magnitude of the value. + uint32_t magnitude = getActiveBits(); + + // Use a fast table for some small values. This also gets rid of some + // rounding errors in libc sqrt for small values. + if (magnitude <= 5) { + static const uint8_t results[32] = { + /* 0 */ 0, + /* 1- 2 */ 1, 1, + /* 3- 6 */ 2, 2, 2, 2, + /* 7-12 */ 3, 3, 3, 3, 3, 3, + /* 13-20 */ 4, 4, 4, 4, 4, 4, 4, 4, + /* 21-30 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 31 */ 6 + }; + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ results[ (isSingleWord() ? VAL : pVal[0]) ]); + } + + // If the magnitude of the value fits in less than 52 bits (the precision of + // an IEEE double precision floating point value), then we can use the + // libc sqrt function which will probably use a hardware sqrt computation. + // This should be faster than the algorithm below. + if (magnitude < 52) { +#ifdef _MSC_VER + // Amazingly, VC++ doesn't have round(). + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0]))) + 0.5); +#else + return ap_private<_AP_W, _AP_S, _AP_N>(/*BitWidth,*/ + uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0]))))); +#endif + } + + // Okay, all the short cuts are exhausted. We must compute it. The following + // is a classical Babylonian method for computing the square root. This code + // was adapted to APINt from a wikipedia article on such computations. + // See http://www.wikipedia.org/ and go to the page named + // Calculate_an_integer_square_root. + uint32_t nbits = BitWidth, i = 4; + ap_private<_AP_W, _AP_S, _AP_N> testy(16); + ap_private<_AP_W, _AP_S, _AP_N> x_old(/*BitWidth,*/ 1); + ap_private<_AP_W, _AP_S, _AP_N> x_new(0); + ap_private<_AP_W, _AP_S, _AP_N> two(/*BitWidth,*/ 2); + + // Select a good starting value using binary logarithms. + for (;; i += 2, testy = testy.shl(2)) + if (i >= nbits || this->ule(testy)) { + x_old = x_old.shl(i / 2); + break; + } + + // Use the Babylonian method to arrive at the integer square root: + for (;;) { + x_new = (this->udiv(x_old) + x_old).udiv(two); + if (x_old.ule(x_new)) + break; + x_old = x_new; + } + + // Make sure we return the closest approximation + // NOTE: The rounding calculation below is correct. It will produce an + // off-by-one discrepancy with results from pari/gp. That discrepancy has been + // determined to be a rounding issue with pari/gp as it begins to use a + // floating point representation after 192 bits. There are no discrepancies + // between this algorithm and pari/gp for bit widths < 192 bits. + ap_private<_AP_W, _AP_S, _AP_N> square(x_old * x_old); + ap_private<_AP_W, _AP_S, _AP_N> nextSquare((x_old + 1) * (x_old +1)); + if (this->ult(square)) + return x_old; + else if (this->ule(nextSquare)) { + ap_private<_AP_W, _AP_S, _AP_N> midpoint((nextSquare - square).udiv(two)); + ap_private<_AP_W, _AP_S, _AP_N> offset(*this - square); + if (offset.ult(midpoint)) + return x_old; + else + return x_old + 1; + } else + assert(0 && "Error in ap_private<_AP_W, _AP_S, _AP_N>::sqrt computation"); + return x_old + 1; +} + +/// Implementation of Knuth's Algorithm D (Division of nonnegative integers) +/// from "Art of Computer Programming, Volume 2", section 4.3.1, p. 272. The +/// variables here have the same names as in the algorithm. Comments explain +/// the algorithm and any deviation from it. +static void KnuthDiv(uint32_t *u, uint32_t *v, uint32_t *q, uint32_t* r, + uint32_t m, uint32_t n) { + assert(u && "Must provide dividend"); + assert(v && "Must provide divisor"); + assert(q && "Must provide quotient"); + assert(u != v && u != q && v != q && "Must us different memory"); + assert(n>1 && "n must be > 1"); + + // Knuth uses the value b as the base of the number system. In our case b + // is 2^31 so we just set it to -1u. + uint64_t b = uint64_t(1) << 32; + + //DEBUG(cerr << "KnuthDiv: m=" << m << " n=" << n << '\n'); + //DEBUG(cerr << "KnuthDiv: original:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of + // u and v by d. Note that we have taken Knuth's advice here to use a power + // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of + // 2 allows us to shift instead of multiply and it is easy to determine the + // shift amount from the leading zeros. We are basically normalizing the u + // and v so that its high bits are shifted to the top of v's range without + // overflow. Note that this can require an extra word in u so that u must + // be of length m+n+1. + uint32_t shift = CountLeadingZeros_32(v[n-1]); + uint32_t v_carry = 0; + uint32_t u_carry = 0; + if (shift) { + for (uint32_t i = 0; i < m+n; ++i) { + uint32_t u_tmp = (u[i]) >> (32 - shift); + u[i] = ((u[i]) << (shift)) | u_carry; + u_carry = u_tmp; + } + for (uint32_t i = 0; i < n; ++i) { + uint32_t v_tmp = (v[i]) >> (32 - shift); + v[i] = ((v[i]) << (shift)) | v_carry; + v_carry = v_tmp; + } + } + u[m+n] = u_carry; + //DEBUG(cerr << "KnuthDiv: normal:"); + //DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]); + //DEBUG(cerr << " by"); + //DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]); + //DEBUG(cerr << '\n'); + + // D2. [Initialize j.] Set j to m. This is the loop counter over the places. + int j = m; + do { + //DEBUG(cerr << "KnuthDiv: quotient digit #" << j << '\n'); + // D3. [Calculate q'.]. + // Set qp = (u[j+n]*b + u[j+n-1]) / v[n-1]. (qp=qprime=q') + // Set rp = (u[j+n]*b + u[j+n-1]) % v[n-1]. (rp=rprime=r') + // Now test if qp == b or qp*v[n-2] > b*rp + u[j+n-2]; if so, decrease + // qp by 1, inrease rp by v[n-1], and repeat this test if rp < b. The test + // on v[n-2] determines at high speed most of the cases in which the trial + // value qp is one too large, and it eliminates all cases where qp is two + // too large. + uint64_t dividend = ((uint64_t(u[j+n]) << 32) + u[j+n-1]); + //DEBUG(cerr << "KnuthDiv: dividend == " << dividend << '\n'); + uint64_t qp = dividend / v[n-1]; + uint64_t rp = dividend % v[n-1]; + if (qp == b || qp*v[n-2] > b*rp + u[j+n-2]) { + qp--; + rp += v[n-1]; + if (rp < b && (qp == b || qp*v[n-2] > b*rp + u[j+n-2])) + qp--; + } + //DEBUG(cerr << "KnuthDiv: qp == " << qp << ", rp == " << rp << '\n'); + + // D4. [Multiply and subtract.] Replace (u[j+n]u[j+n-1]...u[j]) with + // (u[j+n]u[j+n-1]..u[j]) - qp * (v[n-1]...v[1]v[0]). This computation + // consists of a simple multiplication by a one-place number, combined with + // a subtraction. + bool isNeg = false; + for (uint32_t i = 0; i < n; ++i) { + uint64_t u_tmp = uint64_t(u[j+i]) | ((uint64_t(u[j+i+1])) << 32); + uint64_t subtrahend = uint64_t(qp) * uint64_t(v[i]); + bool borrow = subtrahend > u_tmp; + /*DEBUG(cerr << "KnuthDiv: u_tmp == " << u_tmp + << ", subtrahend == " << subtrahend + << ", borrow = " << borrow << '\n');*/ + + uint64_t result = u_tmp - subtrahend; + uint32_t k = j + i; + u[k++] = (uint32_t)(result & (b-1)); // subtract low word + u[k++] = (uint32_t)((result) >> 32); // subtract high word + while (borrow && k <= m+n) { // deal with borrow to the left + borrow = u[k] == 0; + u[k]--; + k++; + } + isNeg |= borrow; + /*DEBUG(cerr << "KnuthDiv: u[j+i] == " << u[j+i] << ", u[j+i+1] == " << + u[j+i+1] << '\n');*/ + } + /*DEBUG(cerr << "KnuthDiv: after subtraction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + // The digits (u[j+n]...u[j]) should be kept positive; if the result of + // this step is actually negative, (u[j+n]...u[j]) should be left as the + // true value plus b**(n+1), namely as the b's complement of + // the true value, and a "borrow" to the left should be remembered. + // + if (isNeg) { + bool carry = true; // true because b's complement is "complement + 1" + for (uint32_t i = 0; i <= m+n; ++i) { + u[i] = ~u[i] + carry; // b's complement + carry = carry && u[i] == 0; + } + } + /*DEBUG(cerr << "KnuthDiv: after complement:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << u[i]); + DEBUG(cerr << '\n');*/ + + // D5. [Test remainder.] Set q[j] = qp. If the result of step D4 was + // negative, go to step D6; otherwise go on to step D7. + q[j] = (uint32_t)qp; + if (isNeg) { + // D6. [Add back]. The probability that this step is necessary is very + // small, on the order of only 2/b. Make sure that test data accounts for + // this possibility. Decrease q[j] by 1 + q[j]--; + // and add (0v[n-1]...v[1]v[0]) to (u[j+n]u[j+n-1]...u[j+1]u[j]). + // A carry will occur to the left of u[j+n], and it should be ignored + // since it cancels with the borrow that occurred in D4. + bool carry = false; + for (uint32_t i = 0; i < n; i++) { + uint32_t limit = AESL_std::min(u[j+i],v[i]); + u[j+i] += v[i] + carry; + carry = u[j+i] < limit || (carry && u[j+i] == limit); + } + u[j+n] += carry; + } + /*DEBUG(cerr << "KnuthDiv: after correction:"); + DEBUG(for (int i = m+n; i >=0; i--) cerr <<" " << u[i]); + DEBUG(cerr << "\nKnuthDiv: digit result = " << q[j] << '\n');*/ + + // D7. [Loop on j.] Decrease j by one. Now if j >= 0, go back to D3. + } while (--j >= 0); + + /*DEBUG(cerr << "KnuthDiv: quotient:"); + DEBUG(for (int i = m; i >=0; i--) cerr <<" " << q[i]); + DEBUG(cerr << '\n');*/ + + // D8. [Unnormalize]. Now q[...] is the desired quotient, and the desired + // remainder may be obtained by dividing u[...] by d. If r is non-null we + // compute the remainder (urem uses this). + if (r) { + // The value d is expressed by the "shift" value above since we avoided + // multiplication by d by using a shift left. So, all we have to do is + // shift right here. In order to mak + if (shift) { + uint32_t carry = 0; + //DEBUG(cerr << "KnuthDiv: remainder:"); + for (int i = n-1; i >= 0; i--) { + r[i] = ((u[i]) >> (shift)) | carry; + carry = (u[i]) << (32 - shift); + //DEBUG(cerr << " " << r[i]); + } + } else { + for (int i = n-1; i >= 0; i--) { + r[i] = u[i]; + //DEBUG(cerr << " " << r[i]); + } + } + //DEBUG(cerr << '\n'); + } + //DEBUG(cerr << std::setbase(10) << '\n'); +} + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + const ap_private<_AP_W, _AP_S, _AP_N>& RHS, uint32_t rhsWords, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = rhsWords * 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = (uint32_t)(tmp & mask); + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + for (unsigned i = 0; i < rhsWords; ++i) { + uint64_t tmp = (RHS.getNumWords() == 1 ? RHS.VAL : RHS.pVal[i]); + __V[i * 2] = (uint32_t)(tmp & mask); + __V[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = (uint32_t)partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = (uint32_t)(partial_dividend / divisor); + remainder = (uint32_t)(partial_dividend - (__Q[i] * divisor)); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != RHS.BitWidth) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + + +template +void ap_private<_AP_W, _AP_S, _AP_N>::fromString(const char *str, uint32_t slen, uint8_t radix) { + enum { numbits=_AP_W}; + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(str && "String is null?"); + bool isNeg = str[0] == '-'; + if (isNeg) + str++, slen--; + + //skip any leading zero + while(*str == '0' && *(str+1) != '\0') {str++; slen--;} + assert((slen <= numbits || radix != 2) && "Insufficient bit width"); + assert(((slen - 1)*3 <= numbits || radix != 8) && "Insufficient bit width"); + assert(((slen - 1)*4 <= numbits || radix != 16) && "Insufficient bit width"); + assert((((slen -1)*64)/22 <= numbits || radix != 10) && "Insufficient bit width"); + + memset(pVal, 0, _AP_N * sizeof(uint64_t)); + + // Figure out if we can shift instead of multiply + uint32_t shift = (radix == 16 ? 4 : radix == 8 ? 3 : radix == 2 ? 1 : 0); + + // Set up an ap_private for the digit to add outside the loop so we don't + // constantly construct/destruct it. + uint64_t bigVal[_AP_N]; + memset(bigVal, 0, _AP_N * sizeof(uint64_t)); + ap_private<_AP_W, _AP_S, _AP_N> apdigit(getBitWidth(), bigVal); + ap_private<_AP_W, _AP_S, _AP_N> apradix(radix); + + // Enter digit traversal loop + for (unsigned i = 0; i < slen; i++) { + // Get a digit + uint32_t digit = 0; + char cdigit = str[i]; + if (radix == 16) { +#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#define isdigit(c) ((c) >= '0' && (c) <= '9') + if (!isxdigit(cdigit)) + assert(0 && "Invalid hex digit in string"); + if (isdigit(cdigit)) + digit = cdigit - '0'; + else if (cdigit >= 'a') + digit = cdigit - 'a' + 10; + else if (cdigit >= 'A') + digit = cdigit - 'A' + 10; + else + assert(0 && "huh? we shouldn't get here"); + } else if (isdigit(cdigit)) { + digit = cdigit - '0'; + } else { + assert(0 && "Invalid character in digit string"); + } +#undef isxdigit +#undef isdigit + // Shift or multiply the value by the radix + if (shift) + *this <<= shift; + else + *this *= apradix; + + // Add in the digit we just interpreted + if (apdigit.isSingleWord()) + apdigit.VAL = digit; + else + apdigit.pVal[0] = digit; + *this += apdigit; + } + // If its negative, put it in two's complement form + if (isNeg) { + (*this)--; + this->flip(); + } + clearUnusedBits(); +} + +template +std::string ap_private<_AP_W, _AP_S, _AP_N>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F" + }; + std::string result; + uint32_t bits_used = getActiveBits(); + + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, _AP_N> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, _AP_N> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask; + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, _AP_N> tmp(*this); + ap_private<_AP_W, false, _AP_N> divisor(radix); + ap_private<_AP_W, false, _AP_N> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + tmp.clearUnusedBitsToZero(); + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, _AP_N>(0)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, _AP_N> APdigit(0); + ap_private<_AP_W, false, _AP_N> tmp2(0); + divide(tmp, tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2, + &APdigit); + uint32_t digit = APdigit.getZExtValue(); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + + return result; +} + +// This implements a variety of operations on a representation of +// arbitrary precision, two's-complement, bignum integer values. + +/* Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe + and unrestricting assumption. */ + +/* Some handy functions local to this file. */ + +template +void divide(const ap_private<_AP_W, _AP_S, _AP_N>& LHS, uint32_t lhsWords, + uint64_t RHS, + ap_private<_AP_W, _AP_S, _AP_N> *Quotient, ap_private<_AP_W, _AP_S, _AP_N> *Remainder) { + uint32_t rhsWords=1; + assert(lhsWords >= rhsWords && "Fractional result"); + enum {APINT_BITS_PER_WORD=64}; + // First, compose the values into an array of 32-bit words instead of + // 64-bit words. This is a necessity of both the "short division" algorithm + // and the the Knuth "classical algorithm" which requires there to be native + // operations for +, -, and * on an m bit value with an m*2 bit result. We + // can't use 64-bit operands here because we don't have native results of + // 128-bits. Furthremore, casting the 64-bit values to 32-bit values won't + // work on large-endian machines. + uint64_t mask = ~0ull >> (sizeof(uint32_t)*8); + uint32_t n = 2; + uint32_t m = (lhsWords * 2) - n; + + // Allocate space for the temporary values we need either on the stack, if + // it will fit, or on the heap if it won't. + uint32_t SPACE[128]; + uint32_t *__U = 0; + uint32_t *__V = 0; + uint32_t *__Q = 0; + uint32_t *__R = 0; + if ((Remainder?4:3)*n+2*m+1 <= 128) { + __U = &SPACE[0]; + __V = &SPACE[m+n+1]; + __Q = &SPACE[(m+n+1) + n]; + if (Remainder) + __R = &SPACE[(m+n+1) + n + (m+n)]; + } else { + __U = new uint32_t[m + n + 1]; + __V = new uint32_t[n]; + __Q = new uint32_t[m+n]; + if (Remainder) + __R = new uint32_t[n]; + } + + // Initialize the dividend + memset(__U, 0, (m+n+1)*sizeof(uint32_t)); + for (unsigned i = 0; i < lhsWords; ++i) { + uint64_t tmp = (LHS.getNumWords() == 1 ? LHS.VAL : LHS.pVal[i]); + __U[i * 2] = tmp & mask; + __U[i * 2 + 1] = (tmp) >> (sizeof(uint32_t)*8); + } + __U[m+n] = 0; // this extra word is for "spill" in the Knuth algorithm. + + // Initialize the divisor + memset(__V, 0, (n)*sizeof(uint32_t)); + __V[0] = RHS & mask; + __V[1] = (RHS) >> (sizeof(uint32_t)*8); + + // initialize the quotient and remainder + memset(__Q, 0, (m+n) * sizeof(uint32_t)); + if (Remainder) + memset(__R, 0, n * sizeof(uint32_t)); + + // Now, adjust m and n for the Knuth division. n is the number of words in + // the divisor. m is the number of words by which the dividend exceeds the + // divisor (i.e. m+n is the length of the dividend). These sizes must not + // contain any zero words or the Knuth algorithm fails. + for (unsigned i = n; i > 0 && __V[i-1] == 0; i--) { + n--; + m++; + } + for (unsigned i = m+n; i > 0 && __U[i-1] == 0; i--) + m--; + + // If we're left with only a single word for the divisor, Knuth doesn't work + // so we implement the short division algorithm here. This is much simpler + // and faster because we are certain that we can divide a 64-bit quantity + // by a 32-bit quantity at hardware speed and short division is simply a + // series of such operations. This is just like doing short division but we + // are using base 2^32 instead of base 10. + assert(n != 0 && "Divide by zero?"); + if (n == 1) { + uint32_t divisor = __V[0]; + uint32_t remainder = 0; + for (int i = m+n-1; i >= 0; i--) { + uint64_t partial_dividend = (uint64_t(remainder)) << 32 | __U[i]; + if (partial_dividend == 0) { + __Q[i] = 0; + remainder = 0; + } else if (partial_dividend < divisor) { + __Q[i] = 0; + remainder = partial_dividend; + } else if (partial_dividend == divisor) { + __Q[i] = 1; + remainder = 0; + } else { + __Q[i] = partial_dividend / divisor; + remainder = partial_dividend - (__Q[i] * divisor); + } + } + if (__R) + __R[0] = remainder; + } else { + // Now we're ready to invoke the Knuth classical divide algorithm. In this + // case n > 1. + KnuthDiv(__U, __V, __Q, __R, m, n); + } + + // If the caller wants the quotient + if (Quotient) { + // Set up the Quotient value's memory. + if (Quotient->BitWidth != LHS.BitWidth) { + if (Quotient->isSingleWord()) + Quotient->VAL = 0; + else + delete [] Quotient->pVal; + } else + Quotient->clear(); + + // The quotient is in Q. Reconstitute the quotient into Quotient's low + // order words. + if (lhsWords == 1) { + uint64_t tmp = + uint64_t(__Q[0]) | ((uint64_t(__Q[1])) << (APINT_BITS_PER_WORD / 2)); + if (Quotient->isSingleWord()) + Quotient->VAL = tmp; + else + Quotient->pVal[0] = tmp; + } else { + assert(!Quotient->isSingleWord() && "Quotient ap_private not large enough"); + for (unsigned i = 0; i < lhsWords; ++i) + Quotient->pVal[i] = + uint64_t(__Q[i*2]) | ((uint64_t(__Q[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Quotient->clearUnusedBits(); + } + + // If the caller wants the remainder + if (Remainder) { + // Set up the Remainder value's memory. + if (Remainder->BitWidth != 64 /* RHS.BitWidth */) { + if (Remainder->isSingleWord()) + Remainder->VAL = 0; + } else + Remainder->clear(); + + // The remainder is in __R. Reconstitute the remainder into Remainder's low + // order words. + if (rhsWords == 1) { + uint64_t tmp = + uint64_t(__R[0]) | ((uint64_t(__R[1])) << (APINT_BITS_PER_WORD / 2)); + if (Remainder->isSingleWord()) + Remainder->VAL = tmp; + else + Remainder->pVal[0] = tmp; + } else { + assert(!Remainder->isSingleWord() && "Remainder ap_private not large enough"); + for (unsigned i = 0; i < rhsWords; ++i) + Remainder->pVal[i] = + uint64_t(__R[i*2]) | ((uint64_t(__R[i*2+1])) << (APINT_BITS_PER_WORD / 2)); + } + Remainder->clearUnusedBits(); + } + + // Clean up the memory we allocated. + if (__U != &SPACE[0]) { + delete [] __U; + delete [] __V; + delete [] __Q; + delete [] __R; + } +} + +//When bitwidth < 64 +template class ap_private <_AP_W, _AP_S, 1> { +#ifdef _MSC_VER +#pragma warning( disable : 4521 4522 ) +#endif +public: + typedef typename retval<_AP_S>::Type ValType; + template + struct RType { + enum { + _AP_N =1, + mult_w = _AP_W+_AP_W2, + mult_s = _AP_S||_AP_S2, //?? why + plus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, //shouldn't it be AP_MAX(_AP_W,_AP_W2)+!(_AP_S^_AP_S2)+1 ???? + plus_s = _AP_S||_AP_S2, + minus_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2))+1, + minus_s = true, + div_w = _AP_W+_AP_S2, + div_s = _AP_S||_AP_S2, + mod_w = AP_MIN(_AP_W,_AP_W2+(!_AP_S2&&_AP_S)), + mod_s = _AP_S, + logic_w = AP_MAX(_AP_W+(_AP_S2&&!_AP_S),_AP_W2+(_AP_S&&!_AP_S2)), + logic_s = _AP_S||_AP_S2 + }; + typedef ap_private mult; + typedef ap_private plus; + typedef ap_private minus; + typedef ap_private logic; + typedef ap_private div; + typedef ap_private mod; + typedef ap_private<_AP_W, _AP_S> arg1; + typedef bool reduce; + }; + enum { APINT_BITS_PER_WORD = 64}; + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -(_AP_W%APINT_BITS_PER_WORD) : 0}; + static const uint64_t mask = ((uint64_t)~0ULL >> (excess_bits)); + static const uint64_t not_mask = ~mask; + static const uint64_t sign_bit_mask = 1ULL << (APINT_BITS_PER_WORD-1); + template struct sign_ext_mask { static const uint64_t mask=~0ULL<<_AP_W1;}; + + enum { BitWidth=_AP_W}; + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + const uint64_t *const pVal; + + INLINE uint32_t getBitWidth() const { + return BitWidth; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& RHS) { + VAL = RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + template + ap_private<_AP_W, _AP_S, 1>& operator=(const volatile ap_private<_AP_W1, _AP_S1, 1>& RHS) { + VAL = RHS.VAL; + clearUnusedBits(); + return *this; + } + + volatile ap_private& operator=(const ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + volatile ap_private& operator=(const volatile ap_private& RHS) volatile { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + ap_private& operator=(const volatile ap_private& RHS) { + // Don't do anything for X = X + VAL = RHS.VAL; // No need to check because no harm done by copying. + return *this; + } + + template + INLINE ap_private& operator = (const ap_range_ref<_AP_W2, _AP_S2>& op2) { + *this = ap_private<_AP_W2, false>(op2); + return *this; + } + + explicit INLINE ap_private(uint64_t* val) : VAL(val[0]), pVal(&VAL){ + clearUnusedBits(); + } + + INLINE bool isSingleWord() const { return true; } + + INLINE void fromString(const char *strStart, uint32_t slen, + uint8_t radix, int offset=0) { + // Check our assumptions here + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + assert(strStart && "String is null?"); + strStart+=offset; + switch(radix) { + case 2: + // sscanf(strStart,"%b",&VAL); + VAL = *strStart =='1' ? ~0ULL : 0; + for (;*strStart; ++strStart) { + assert((*strStart=='0'|| *strStart=='1')&&("Wrong binary number") ); + VAL <<=1; + VAL |= (*strStart-'0'); + } + break; + case 8: +#if __WIN32__ + sscanf(strStart,"%I64o",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lo",&VAL); +#else + sscanf(strStart,"%llo",&VAL); +#endif + +#endif + break; + case 10: +#if __WIN32__ + sscanf(strStart,"%I64u",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lu",&VAL); +#else + sscanf(strStart,"%llu",&VAL); +#endif + +#endif + break; + case 16: +#if __WIN32__ + sscanf(strStart,"%I64x",&VAL); +#else + +#if defined __x86_64__ + sscanf(strStart,"%lx",&VAL); +#else + sscanf(strStart,"%llx",&VAL); +#endif + +#endif + break; + default: + assert(true && "Unknown radix"); + // error + } + clearUnusedBits(); + } + + INLINE ap_private() : pVal(&VAL){VAL = 0ULL;} + +#define CTOR(TYPE) \ + INLINE ap_private(TYPE v) : VAL((uint64_t)v), pVal(&VAL) { \ + clearUnusedBits(); \ + } + CTOR(int) + CTOR(bool) + CTOR(signed char) + CTOR(unsigned char) + CTOR(short) + CTOR(unsigned short) + CTOR(unsigned int) + CTOR(long) + CTOR(unsigned long) + CTOR(unsigned long long) + CTOR(long long) + CTOR(float) + CTOR(double) +#undef CTOR + ap_private(uint32_t numWords, const uint64_t bigVal[]): VAL(bigVal[0]), pVal(&VAL) {clearUnusedBits();} + + ap_private(const std::string& val, uint8_t radix=2, int base=0, int offset=0): VAL(0), pVal(&VAL) { + assert(!val.empty() && "String empty?"); + fromString(val.c_str()+base, val.size()-base, radix); + } + + ap_private(const char strStart[], uint32_t slen, uint8_t radix, int base=0, int offset=0) : VAL(0), pVal(&VAL) { + fromString(strStart+base, slen-base, radix, offset); + } + + ap_private(const ap_private& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, 1>& that) : VAL(that.VAL), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + + template + ap_private(const volatile ap_private<_AP_W1, _AP_S1, _AP_N1>& that) : VAL(that.pVal[0]), pVal(&VAL) { + clearUnusedBits(); + } + +#if 0 +template + explicit ap_private(const ap_private<_AP_W1, true, 1+_AP_W1/64>& that) + : VAL((_AP_W1>_AP_W) ? that.VAL & mask : ((1ULL<<(_AP_W1-1)&that.pVal[0]) ? sign_ext_mask<_AP_W1>::mask | that.VAL : that.pVal[0])), pVal(&VAL) {} + +template + explicit ap_private(const ap_private<_AP_W1, false, (_AP_W1+63)/64>& that) + : VAL(that.VAL & mask), pVal(&VAL) {} +#endif + + explicit ap_private(const char* val) : pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + bool neg = false; + uint32_t radix = 10; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + ap_private<_AP_W, _AP_S> ap_private_val(str.c_str(), strLen, radix, base, offset); + if (neg) + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + ap_private(const char* val, signed char rd): pVal(&VAL) { + std::string str(val); + uint32_t strLen = str.length(); + const char *strp = str.c_str(); + uint32_t offset = 0; + uint32_t base = 0; + uint32_t radix = rd; + bool neg = false; + ap_parse_sign(strp, base, neg); + ap_parse_prefix(strp + base, offset, radix); + + if ((radix != 10 && neg) || + (strLen - base - offset <= 0) || + InvalidDigit(strp, strLen, base + offset, radix)) { + fprintf(stderr, "invalid character string %s !\n", val); + assert(0); + } + + uint32_t bitsNeeded = ap_private<_AP_W, _AP_S>::getBitsNeeded(strp, strLen, radix); + ap_private<_AP_W, _AP_S> ap_private_val(strp , strLen, radix, base, offset); + //ap_private<_AP_W, _AP_S> ap_private_val(bitsNeeded, strp , strLen, radix, base, offset); + if (strp[0] == '-') + ap_private_val = -ap_private_val; + operator = (ap_private_val); + } + + INLINE bool isNegative() const { + static const uint64_t sign_mask = 1ULL << (_AP_W-1); + return _AP_S && (sign_mask & VAL); + } + + INLINE bool isPositive() const { + return !isNegative(); + } + + INLINE bool isStrictlyPositive() const { + return !isNegative() && VAL!=0; + } + + INLINE bool isAllOnesValue() const { + return (mask & VAL) == mask; + } + + template + INLINE bool operator==(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + return (VAL == RHS.VAL); + } + + INLINE bool operator==(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL == RHS.VAL; } + INLINE bool operator==(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() == RHS.getVal(); } + INLINE bool operator==(uint64_t Val) const { return (VAL == Val); } + INLINE bool operator!=(uint64_t Val) const { return (VAL != Val); } + INLINE bool operator!=(const ap_private<_AP_W, _AP_S>& RHS) const { return VAL != RHS.VAL; } + INLINE bool operator!=(const ap_private<_AP_W, !_AP_S>& RHS) const { return getVal() != RHS.getVal(); } + const ap_private operator++() { ++VAL; clearUnusedBits(); return *this; } + const ap_private operator--(int) { + ap_private orig(*this); + --VAL; clearUnusedBits(); + return orig; + } + const ap_private operator--() { --VAL; clearUnusedBits(); return *this;} + INLINE bool operator !() const { return !VAL;} + + const ap_private operator++(int) { + ap_private orig(*this); + VAL++; clearUnusedBits(); + return orig; + } + + const ap_private operator~() {return ap_private(~VAL);} + INLINE typename RType<1,false>::minus operator-() const { + return ap_private<1,false>(0) - (*this); + } + + INLINE std::string toString(uint8_t radix, bool wantSigned) const ; + INLINE std::string toStringUnsigned(uint8_t radix = 10) const { + return toString(radix, false); + } + INLINE std::string toStringSigned(uint8_t radix = 10) const { + return toString(radix, true); + } + INLINE void clear() { + VAL=0; + } + INLINE ap_private& clear(uint32_t bitPosition) { VAL &= ~(1ULL<<(bitPosition)); clearUnusedBits(); return *this;} + + INLINE ap_private ashr(uint32_t shiftAmt) const { + enum {excess_bits = APINT_BITS_PER_WORD - BitWidth}; + if (_AP_S) + return ap_private((shiftAmt == BitWidth) ? 0 : ((int64_t)VAL) >> (shiftAmt)); + else + return ap_private((shiftAmt == BitWidth) ? 0 : (VAL) >> (shiftAmt)); + } + + INLINE ap_private lshr(uint32_t shiftAmt) const { + return ap_private((shiftAmt == BitWidth) ? ap_private(0) : ap_private((VAL&mask) >> (shiftAmt))); + } + + INLINE ap_private shl(uint32_t shiftAmt) const { + if (shiftAmt > BitWidth) { + if (!isNegative()) + return ap_private(0); + else return ap_private(-1); + } + if (shiftAmt == BitWidth) return ap_private(0); + else return ap_private((VAL) << (shiftAmt)); + //return ap_private((shiftAmt == BitWidth) ? ap_private(0ULL) : ap_private(VAL << shiftAmt)); + } + + INLINE int64_t getSExtValue() const { + return VAL; + } + + INLINE uint64_t getZExtValue() const { + return VAL & mask; + } + + template + INLINE ap_private(const ap_range_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const ap_bit_ref<_AP_W2,_AP_S2>& ref) : pVal(&VAL) { + *this = ((uint64_t)(bool)ref); + } + + template + INLINE ap_private(const ap_concat_ref<_AP_W2, _AP_T2,_AP_W3, _AP_T3>& ref) : pVal(&VAL) { + *this=ref.get(); + } + + template + INLINE ap_private(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = ((val.operator ap_private<_AP_W2, false> ())); + } + + template + INLINE ap_private(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, + _AP_Q2, _AP_O2, _AP_N2> &val) : pVal(&VAL) { + *this = (uint64_t)(bool)val; + } + + INLINE void write(const ap_private<_AP_W, _AP_S>& op2) volatile { + *this = (op2); + } + + //Explicit conversions to C interger types + //----------------------------------------------------------- + ValType getVal() const { + return VAL; + } + operator ValType () const { + return getVal(); + } + INLINE int to_int() const { + // ap_private<64 /* _AP_W */, _AP_S> res(V); + return (int) getVal(); + } + + INLINE unsigned to_uint() const { + return (unsigned) getVal(); + } + + INLINE long to_long() const { + return (long) getVal(); + } + + INLINE unsigned long to_ulong() const { + return (unsigned long) getVal(); + } + + INLINE ap_slong to_int64() const { + return (ap_slong) getVal(); + } + + INLINE ap_ulong to_uint64() const { + return (ap_ulong) getVal(); + } + + INLINE double to_double() const { + if (isNegative()) + return roundToDouble(true); + else + return roundToDouble(false); + } + + INLINE bool isMinValue() const { return VAL == 0;} + template INLINE ap_private& operator&=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL&RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator|=(const ap_private<_AP_W1, _AP_S1>& RHS) { + VAL = VAL|RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator^=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL^RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator*=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL*RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator+=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL+RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + + template INLINE ap_private& operator-=(const ap_private<_AP_W1, _AP_S1>& RHS){ + VAL = VAL-RHS.pVal[0]; + clearUnusedBits(); + return *this; + } + INLINE const ap_private& operator<<=(uint32_t shiftAmt) { VAL<<=shiftAmt; clearUnusedBits(); return *this; } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator&(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL & RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret & RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator^(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL ^ RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret ^ RHS; + } + } + + template INLINE typename RType<_AP_W1, _AP_S1>::logic operator|(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::logic_w <= 64) { + typename RType<_AP_W1, _AP_S1>::logic Ret(VAL | RHS.VAL); + return Ret; + } else { + typename RType<_AP_W1, _AP_S1>::logic Ret = *this; + return Ret | RHS; + } + } + + INLINE ap_private<_AP_W, _AP_S> And(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL & RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Or(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL | RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Xor(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL ^ RHS.VAL); + } +#if 1 + template + INLINE typename RType<_AP_W1, _AP_S1>::mult operator*(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1, _AP_S1>::mult_w <= 64) { + typename RType<_AP_W1, _AP_S1>::mult Result(VAL * RHS.VAL); + return Result; + } else { + typename RType<_AP_W1, _AP_S1>::mult Result = typename RType<_AP_W1, _AP_S1>::mult(*this); + Result *= RHS; + return Result; + } + } +#endif + INLINE ap_private<_AP_W, _AP_S> Mul(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL * RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Add(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL + RHS.VAL); + } + + INLINE ap_private<_AP_W, _AP_S> Sub(const ap_private<_AP_W, _AP_S>& RHS) const { + return ap_private<_AP_W, _AP_S>(VAL - RHS.VAL); + } + +#if 1 + INLINE ap_private& operator&=(uint64_t RHS) { VAL &= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator|=(uint64_t RHS) { VAL |= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator^=(uint64_t RHS){ VAL ^= RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator*=(uint64_t RHS){ VAL *= RHS; clearUnusedBits(); return *this; } + INLINE ap_private& operator+=(uint64_t RHS){ VAL += RHS; clearUnusedBits(); return *this;} + INLINE ap_private& operator-=(uint64_t RHS){ VAL -= RHS; clearUnusedBits(); return *this; } + INLINE ap_private operator&(uint64_t RHS) const { return ap_private(VAL & RHS); } + INLINE ap_private operator|(uint64_t RHS) const { return ap_private(VAL | RHS); } + INLINE ap_private operator^(uint64_t RHS) const { return ap_private(VAL ^ RHS); } + INLINE ap_private operator*(uint64_t RHS) const { return ap_private(VAL * RHS); } + INLINE ap_private operator/(uint64_t RHS) const { return ap_private(VAL / RHS); } + INLINE ap_private operator+(uint64_t RHS) const { return ap_private(VAL + RHS); } + INLINE ap_private operator-(uint64_t RHS) const { return ap_private(VAL - RHS); } +#endif + INLINE bool isMinSignedValue() const { + static const uint64_t min_mask = ~(~0ULL << (_AP_W-1)); + return BitWidth == 1 ? VAL == 1 : + (ap_private_ops::isNegative<_AP_W>(*this) && ((min_mask & VAL)==0)); + } + +#if 1 + + template INLINE + typename RType<_AP_W1,_AP_S1>::plus operator+(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::plus_w <=64) + return typename RType<_AP_W1,_AP_S1>::plus(RType<_AP_W1,_AP_S1>::plus_s ? int64_t(VAL+RHS.VAL):uint64_t(VAL+RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::plus Result=RHS; + Result += VAL; + return Result; + } + + template INLINE + typename RType<_AP_W1,_AP_S1>::minus operator-(const ap_private<_AP_W1, _AP_S1>& RHS) const { + if (RType<_AP_W1,_AP_S1>::minus_w <=64) + return typename RType<_AP_W1,_AP_S1>::minus(int64_t(VAL-RHS.VAL)); + typename RType<_AP_W1,_AP_S1>::minus Result=*this; + Result -= RHS; + return Result; + } +#endif // #if 1 + + INLINE ap_private& flip() { + VAL = (~0ULL^VAL)&mask; + clearUnusedBits(); + return *this; + } + + uint32_t countPopulation() const { return CountPopulation_64(VAL);} + uint32_t countLeadingZeros() const { + int remainder = BitWidth % APINT_BITS_PER_WORD; + int excessBits = (APINT_BITS_PER_WORD - remainder) % APINT_BITS_PER_WORD; + //enum { remainder = BitWidth % APINT_BITS_PER_WORD, excessBits = APINT_BITS_PER_WORD - remainder}; + uint32_t Count = CountLeadingZeros_64(VAL); + if (Count) + Count-=excessBits; + return AESL_std::min(Count, (uint32_t)_AP_W); + } + + /// HiBits - This function returns the high "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getHiBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret(*this); + ret = (ret)>>(BitWidth - numBits); + return ret; + } + + /// LoBits - This function returns the low "numBits" bits of this ap_private. + ap_private<_AP_W, _AP_S, 1> getLoBits(uint32_t numBits) const { + ap_private<_AP_W, _AP_S, 1> ret((VAL) << (BitWidth - numBits)); + ret = (ret)>>(BitWidth - numBits); + return ret; + //return ap_private(numBits, (VAL << (BitWidth - numBits))>> (BitWidth - numBits)); + } + + ap_private<_AP_W, _AP_S,1>& set(uint32_t bitPosition) { + VAL |= (1ULL << (bitPosition)); + clearUnusedBits(); + return *this; // clearUnusedBits(); + } + + void set() { + VAL = ~0ULL; + clearUnusedBits(); + } + + template + INLINE void set(const ap_private<_AP_W3, false> & val) { + operator = (ap_private<_AP_W3, _AP_S>(val)); + } + + INLINE void set(const ap_private & val) { + operator = (val); + } + + bool operator[](uint32_t bitPosition) const { + return (((1ULL << (bitPosition)) & VAL) != 0); + } + + INLINE void clearUnusedBits(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + VAL = _AP_S ? ((((int64_t)VAL)<<(excess_bits))>> (excess_bits)) : (excess_bits ? ((VAL)<<(excess_bits))>>(excess_bits) : VAL); + } + + INLINE void clearUnusedBitsToZero(void) { + enum { excess_bits = (_AP_W%APINT_BITS_PER_WORD) ? APINT_BITS_PER_WORD -_AP_W%APINT_BITS_PER_WORD : 0}; + static uint64_t mask = ~0ULL >> (excess_bits); + VAL &= mask; + } + + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> udiv(const ap_private<_AP_W, _AP_S1>& RHS) const { + return ap_private<_AP_W, _AP_S||_AP_S1>(VAL / RHS.VAL); + } + + INLINE ap_private udiv(uint64_t RHS) const { + return ap_private(VAL / RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + template + INLINE ap_private<_AP_W, _AP_S||_AP_S1> sdiv(const ap_private<_AP_W, _AP_S1> & RHS) const { + if (isNegative()) + if (RHS.isNegative()) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS.isNegative()) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + /// Signed divide this ap_private by ap_private RHS. + /// @brief Signed division function for ap_private. + INLINE ap_private sdiv(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return (-(*this)).udiv(-RHS); + else + return -((-(*this)).udiv(RHS)); + else if (RHS<0) + return -(this->udiv(-RHS)); + return this->udiv(RHS); + } + + template + INLINE ap_private urem(const ap_private<_AP_W, _AP_S2>& RHS) const { + assert(RHS.VAL != 0 && "Divide by 0"); + return ap_private(VAL%RHS.VAL); + } + + INLINE ap_private urem(uint64_t RHS) const { + assert(RHS != 0 && "Divide by 0"); + return ap_private(VAL%RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + template + INLINE ap_private srem(const ap_private<_AP_W, _AP_S2>& RHS) const { + if (isNegative()) { + ap_private lhs = -(*this); + if (RHS.isNegative()) { + ap_private rhs = -RHS; + return -(lhs.urem(rhs)); + } else + return -(lhs.urem(RHS)); + } else if (RHS.isNegative()) { + ap_private rhs = -RHS; + return this->urem(rhs); + } + return this->urem(RHS); + } + + /// Signed remainder operation on ap_private. + /// @brief Function for signed remainder operation. + INLINE ap_private srem(int64_t RHS) const { + if (isNegative()) + if (RHS<0) + return -((-(*this)).urem(-RHS)); + else + return -((-(*this)).urem(RHS)); + else if (RHS<0) + return this->urem(-RHS); + return this->urem(RHS); + } + + INLINE static void udivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS.VAl; + Remainder = LHS.VAL % RHS.VAL; + } + + INLINE static void udivrem(const ap_private &LHS, uint64_t RHS, + ap_private &Quotient, ap_private &Remainder){ + assert(RHS!=0 && "Divide by 0"); + Quotient = LHS.VAl/RHS; + Remainder = LHS.VAL % RHS; + } + + INLINE static void sdivrem(const ap_private &LHS, const ap_private &RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS.isNegative()) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS.isNegative()) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + INLINE static void sdivrem(const ap_private &LHS, int64_t RHS, + ap_private &Quotient, ap_private &Remainder) { + if (LHS.isNegative()) { + if (RHS<0) + ap_private::udivrem(-LHS, -RHS, Quotient, Remainder); + else + ap_private::udivrem(-LHS, RHS, Quotient, Remainder); + Quotient = -Quotient; + Remainder = -Remainder; + } else if (RHS<0) { + ap_private::udivrem(LHS, -RHS, Quotient, Remainder); + Quotient = -Quotient; + } else { + ap_private::udivrem(LHS, RHS, Quotient, Remainder); + } + } + + template INLINE bool eq(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return (*this) == RHS; + } + + template INLINE bool ne(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !((*this) == RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered unsigned. + /// @brief Unsigned less than comparison + template INLINE bool ult(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + uint64_t lhsZext = ((uint64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + uint64_t rhsZext = ((uint64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsZext < rhsZext; + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-than relationship. + /// @returns true if *this < RHS when both are considered signed. + /// @brief Signed less than comparison + template INLINE bool slt(const ap_private<_AP_W1, _AP_S1, 1>& RHS) const { + int64_t lhsSext = ((int64_t(VAL)) << (64-_AP_W)) >> (64-_AP_W); + int64_t rhsSext = ((int64_t(RHS.VAL)) << (64-_AP_W1)) >> (64-_AP_W1); + return lhsSext < rhsSext; + } + + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered unsigned. + /// @brief Unsigned less or equal comparison + template INLINE bool ule(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return ult(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the less-or-equal relationship. + /// @returns true if *this <= RHS when both are considered signed. + /// @brief Signed less or equal comparison + template INLINE bool sle(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return slt(RHS) || eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered unsigned. + /// @brief Unsigned greather than comparison + template INLINE bool ugt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// the validity of the greater-than relationship. + /// @returns true if *this > RHS when both are considered signed. + /// @brief Signed greather than comparison + template INLINE bool sgt(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS) && !eq(RHS); + } + + /// Regards both *this and RHS as unsigned quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered unsigned. + /// @brief Unsigned greater or equal comparison + template INLINE bool uge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !ult(RHS); + } + + /// Regards both *this and RHS as signed quantities and compares them for + /// validity of the greater-or-equal relationship. + /// @returns true if *this >= RHS when both are considered signed. + /// @brief Signed greather or equal comparison + template INLINE bool sge(const ap_private<_AP_W1, _AP_S1>& RHS) const { + return !slt(RHS); + } + + INLINE ap_private abs() const { + if (isNegative()) + return -(*this); + return *this; + } + + ap_private<_AP_W, false> get() const { + ap_private<_AP_W,false> ret(*this); + return ret; + } + + INLINE static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) { + return _AP_W; + } + + INLINE uint32_t getActiveBits() const { + uint32_t bits=_AP_W - countLeadingZeros(); + return bits?bits:1; + } + + INLINE double roundToDouble(bool isSigned=false) const { + const static uint64_t mask = ~0ULL << (APINT_BITS_PER_WORD - _AP_W); + return double(VAL); + } + + INLINE unsigned length() const { return _AP_W; } + + /*Reverse the contents of ap_private instance. I.e. LSB becomes MSB and vise versa*/ + INLINE ap_private& reverse () { + for (int i = 0; i < _AP_W/2; ++i) { + bool tmp = operator[](i); + if (operator[](_AP_W - 1 - i)) + set(i); + else + clear(i); + if (tmp) + set(_AP_W - 1 - i); + else + clear(_AP_W - 1 - i); + } + clearUnusedBits(); + return *this; + } + + /*Return true if the value of ap_private instance is zero*/ + INLINE bool iszero () const { + return isMinValue(); + } + + /* x < 0 */ + INLINE bool sign () const { + if (isNegative()) + return true; + return false; + } + + /* x[i] = !x[i] */ + INLINE void invert (int i) { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + flip(i); + } + + /* x[i] */ + INLINE bool test (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator[](i); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the left + INLINE void lrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (shl(n) | lshr(_AP_W - n)); + } + + //This is used for sc_lv and sc_bv, which is implemented by sc_uint + //Rotate an ap_private object n places to the right + INLINE void rrotate(int n) { + assert( n >= 0 && "Attempting to shift negative index"); + assert( n < _AP_W && "Shift value larger than bit width"); + operator = (lshr(n) | shl(_AP_W - n)); + } + + //Set the ith bit into v + INLINE void set (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Set the ith bit into v + INLINE void set_bit (int i, bool v) { + assert( i >= 0 && "Attempting to write bit with negative index"); + assert( i < _AP_W && "Attempting to write bit beyond MSB"); + v ? set(i) : clear(i); + } + + //Get the value of ith bit + INLINE bool get_bit (int i) const { + assert( i >= 0 && "Attempting to read bit with negative index"); + assert( i < _AP_W && "Attempting to read bit beyond MSB"); + return operator [](i); + } + + //complements every bit + INLINE void b_not() { + flip(); + } + + //Binary Arithmetic + //----------------------------------------------------------- +#define OP_BIN_AP(Sym,Rty, Fun) \ + template \ + INLINE \ + typename RType<_AP_W2,_AP_S2>::Rty \ + operator Sym (const ap_private<_AP_W2,_AP_S2>& op) const { \ + typename RType<_AP_W2,_AP_S2>::Rty lhs(*this); \ + typename RType<_AP_W2,_AP_S2>::Rty rhs(op); \ + return lhs.Fun(rhs); \ + } \ + + ///Bitwise and, or, xor + //OP_BIN_AP(&,logic, And) + //OP_BIN_AP(|,logic, Or) + //OP_BIN_AP(^,logic, Xor) + +#undef OP_BIN_AP + template + INLINE typename RType<_AP_W2,_AP_S2>::div + operator / (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=ap_private(*this); + ap_private rhs=ap_private(op); + return typename RType<_AP_W2,_AP_S2>::div((_AP_S||_AP_S2)?lhs.sdiv(rhs):lhs.udiv(rhs)); + } + + + template + INLINE typename RType<_AP_W2,_AP_S2>::mod + operator % (const ap_private<_AP_W2,_AP_S2>&op) const { + ap_private lhs=*this; + ap_private rhs=op; + typename RType<_AP_W2,_AP_S2>::mod res = typename RType<_AP_W2,_AP_S2>::mod (_AP_S?lhs.srem(rhs):lhs.urem(rhs)); + return res; + } + + +#define OP_ASSIGN_AP_2(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op); \ + return *this; \ + } \ + + OP_ASSIGN_AP_2(/) + OP_ASSIGN_AP_2(%) +#undef OP_ASSIGN_AP_2 + + ///Bitwise assign: and, or, xor + //------------------------------------------------------------- + // OP_ASSIGN_AP(&) + // OP_ASSIGN_AP(^) + // OP_ASSIGN_AP(|) +#undef OP_ASSIGN_AP +#if 1 + + template + INLINE ap_private<_AP_W, _AP_S> + operator << (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh=op2.to_uint(); + return *this << sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator << (uint32_t sh) const { + return shl(sh); + } + +#endif + + template + INLINE ap_private<_AP_W, _AP_S> + operator >> (const ap_private<_AP_W2, _AP_S2>& op2) const { + uint32_t sh = op2.to_uint(); + return *this >> sh; + } + + INLINE ap_private<_AP_W, _AP_S> + operator >>(uint32_t sh) const { + ap_private<_AP_W, _AP_S> r(*this); + bool overflow=(sh>=_AP_W); + bool neg_v=r.isNegative(); + if(_AP_S) { + if(overflow) + neg_v?r.set():r.clear(); + else + return r.ashr(sh); + } else { + if(overflow) + r.clear(); + else + return r.lshr(sh); + } + return r; + } + + ///Shift assign + //------------------------------------------------------------------ +#define OP_ASSIGN_AP_3_SINGLE(Sym) \ + template \ + INLINE ap_private<_AP_W, _AP_S>& operator Sym##=(const ap_private<_AP_W2,_AP_S2>& op) \ + { \ + *this=operator Sym (op.getVal()); \ + return *this; \ + } + OP_ASSIGN_AP_3_SINGLE(>>) +#undef OP_ASSIGN_AP_3_SINGLE + + ///Comparisons + //----------------------------------------------------------------- + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this==op); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return op < *this; + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this>op); + } + + template + INLINE bool operator < (const ap_private<_AP_W2, _AP_S2, 1>& op) const { + enum { _AP_MAX_W = AP_MAX(_AP_W+(_AP_S||_AP_S2),_AP_W2+(_AP_S||_AP_S2))}; + ap_private<_AP_MAX_W, _AP_S> lhs(*this); + ap_private<_AP_MAX_W, _AP_S2> rhs(op); + if (_AP_S == _AP_S2) + return _AP_S?lhs.slt(rhs):lhs.ult(rhs); + else if (_AP_W < 32 && _AP_W2 < 32) + return lhs.slt(rhs); + else + if (_AP_S) + if (_AP_W2 >= _AP_W) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + else + if (_AP_W >= _AP_W2) + return lhs.ult(rhs); + else + return lhs.slt(rhs); + } + + template + INLINE bool operator >=(const ap_private<_AP_W2, _AP_S2, 1>& op) const { + return !(*this + INLINE bool operator == (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op == *this; + } + + template + INLINE bool operator != (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return !(op==*this); + } + + template + INLINE bool operator > (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op < (*this); + } + + template + INLINE bool operator <= (const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op >= *this; + } + + template + INLINE bool operator <(const ap_private<_AP_W2, _AP_S2, _AP_N2>& op) const { + return op > *this; + } + + template + INLINE bool operator >=(const ap_private<_AP_W2,_AP_S2,_AP_N2>& op) const { + return op <= *this; + } + ///Bit and Part Select + //-------------------------------------------------------------- + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast*>(this), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) const { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>((const_cast*> (this)), Hi, Lo); + } + + INLINE ap_range_ref<_AP_W,_AP_S> + range (int Hi, int Lo) { + assert((Hi < _AP_W) && (Lo < _AP_W)&&"Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(this, Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + range (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + assert((Hi < _AP_W) && (Lo < _AP_W) && "Out of bounds in range()"); + return ap_range_ref<_AP_W,_AP_S>(const_cast(this), Hi, Lo); + } + + template + INLINE ap_range_ref<_AP_W,_AP_S> + operator () (const ap_private<_AP_W2, _AP_S2> &HiIdx, + const ap_private<_AP_W3, _AP_S3> &LoIdx) const { + int Hi = HiIdx.to_int(); + int Lo = LoIdx.to_int(); + return this->range(Hi, Lo); + } + + + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (uint32_t index) { + assert(index >= 0&&"Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S> (*this, (int)index); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> operator [] (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + template + INLINE bool operator [] (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br =operator [] (index); + return br.to_bool(); + } + + INLINE ap_bit_ref<_AP_W,_AP_S> bit (int index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index ); + } + + template + INLINE ap_bit_ref<_AP_W,_AP_S> bit (const ap_private<_AP_W2,_AP_S2> &index) { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W &&"Attempting to read bit beyond MSB"); + return ap_bit_ref<_AP_W,_AP_S>( *this, index.to_int() ); + } + + INLINE bool bit (int index) const { + assert(index >= 0 && "Attempting to read bit with negative index"); + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br(const_cast*>(this), index); + return br.to_bool(); + } + + template + INLINE bool bit (const ap_private<_AP_W2,_AP_S2>& index) const { + assert(index < _AP_W && "Attempting to read bit beyond MSB"); + ap_bit_ref<_AP_W,_AP_S> br = bit(index); + return br.to_bool(); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(const ap_private<_AP_W2,_AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W,ap_private<_AP_W, _AP_S>,_AP_W2,ap_private<_AP_W2,_AP_S2> > concat(ap_private<_AP_W2,_AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_private<_AP_W2,_AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (const ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(const_cast& >(*this), a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, _AP_S2> > + operator, (ap_private<_AP_W2, _AP_S2>& a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, ap_private<_AP_W2, + _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (const ap_range_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> > + operator, (ap_range_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2, + ap_range_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (const ap_bit_ref<_AP_W2, _AP_S2> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, ap_bit_ref<_AP_W2, _AP_S2> > + operator, (ap_bit_ref<_AP_W2, _AP_S2> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, 1, + ap_bit_ref<_AP_W2, _AP_S2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) const { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> > + operator, (ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) { + return ap_concat_ref<_AP_W, ap_private<_AP_W, _AP_S>, _AP_W2+_AP_W3, + ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, _AP_W2, af_range_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) const { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(const_cast& >(*this), + const_cast& >(a2)); + } + + template + INLINE ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> > + operator, (af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, + _AP_O2, _AP_N2> &a2) { + return ap_concat_ref<_AP_W, ap_private, 1, af_bit_ref<_AP_W2, + _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2); + } + + template + INLINE ap_private + operator & (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this & a2.get(); + } + + template + INLINE ap_private + operator | (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this | a2.get(); + } + + template + INLINE ap_private + operator ^ (const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) { + return *this ^ a2.get(); + } + + + //Reduce operation + //----------------------------------------------------------- + INLINE bool and_reduce() const { + return (VAL & mask) == mask; + } + + INLINE bool nand_reduce() const { + return (VAL & mask) != mask; + } + + INLINE bool or_reduce() const { + return (bool)VAL; + } + + INLINE bool nor_reduce() const { + return VAL==0; + } + + INLINE bool xor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?true:false; + } + + INLINE bool xnor_reduce() const { + unsigned int i=countPopulation(); + return (i%2)?false:true; + } + + INLINE std::string to_string(uint8_t radix=2, bool sign=false) const { + return toString(radix, radix==10?_AP_S:sign); + } +}; +template +std::string ap_private<_AP_W, _AP_S, 1>::toString(uint8_t radix, bool wantSigned) const { + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && + "Radix should be 2, 8, 10, or 16!"); + static const char *digits[] = { + "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f" + }; + std::string result; + if (radix != 10) { + // For the 2, 8 and 16 bit cases, we can just shift instead of divide + // because the number of bits per digit (1,3 and 4 respectively) divides + // equaly. We just shift until there value is zero. + + // First, check for a zero value and just short circuit the logic below. + if (*this == (uint64_t)(0)) + result = "0"; + else { + ap_private<_AP_W, false, 1> tmp(*this); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + // Just shift tmp right for each digit width until it becomes zero + uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1)); + uint64_t mask = radix - 1; + ap_private<_AP_W, false, 1> zero(0); + while (tmp.ne(zero)) { + unsigned digit = (unsigned)(tmp.VAL & mask); + result.insert(insert_at, digits[digit]); + tmp = tmp.lshr(shift); + } + } + return result; + } + + ap_private<_AP_W, false, 1> tmp(*this); + ap_private<6, false, 1> divisor(radix); + ap_private<_AP_W, _AP_S, 1> zero(0); + size_t insert_at = 0; + if (wantSigned && isNegative()) { + // They want to print the signed version and it is a negative value + // Flip the bits and add one to turn it into the equivalent positive + // value and put a '-' in the result. + tmp.flip(); + tmp++; + result = "-"; + insert_at = 1; + } + if (tmp == ap_private<_AP_W, false, 1>(0ULL)) + result = "0"; + else while (tmp.ne(zero)) { + ap_private<_AP_W, false, 1> APdigit = tmp%divisor; + ap_private<_AP_W, false, 1> tmp2 = tmp/divisor; + uint32_t digit = (uint32_t)(APdigit.getZExtValue()); + assert(digit < radix && "divide failed"); + result.insert(insert_at,digits[digit]); + tmp = tmp2; + } + return result; + +} + +#endif /* #ifndef LLVM_SUPPORT_MATHEXTRAS_H */ \ No newline at end of file diff --git a/hls_2018/router_05/main.cpp b/hls_2018/router_05/main.cpp new file mode 100755 index 0000000000000000000000000000000000000000..60f08ea2e519a8ff39686c2aa7a561ab4249b229 --- /dev/null +++ b/hls_2018/router_05/main.cpp @@ -0,0 +1,99 @@ +/** + * main.cpp + * + * for Vivado HLS + */ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#ifdef CALCTIME +#include +#include +#endif + +#include "router.hpp" + +#define PRINT_SOLUTION + + +int main(int argc, char *argv[]) { + using namespace std; + + // Test data // + // NL_Q00.txt + //char boardstr[BOARDSTR_SIZE] = "X10Y05Z3L0000107041L0004107002L0102102021L0900100003"; + // NL_Q06.txt + char boardstr[BOARDSTR_SIZE] = "X10Y18Z2L0900109002L0901105012L0902103052L0903103062L0904100102L0905106012L0906109022L0717109102L0808109112L0017209172L0401200072L0912208152L0009201092L0709209092L0901206052L0309204092L0701209072L0101201022L0011202152L0016202162"; + // NL_Q08.txt + //char boardstr[BOARDSTR_SIZE] = "X17Y20Z2L0000103022L1603115052L0916107032L0302108012L1104111042L1002100002L0919116162L1616113182L1001115012L0500201182L1603213152L0600210022"; + char boardstr_high[BOARDSTR_SIZE] = {}; + + // Read boardstr from command line + if (1 < argc) { + // From stdin + if(argv[1][0]!='X') + { + char* c_p=fgets(boardstr, BOARDSTR_SIZE, stdin); + int length=strlen(c_p); + boardstr[length-1]=0; + } + else + { + strcpy(boardstr, argv[1]); + } + } + + // Seed value + int seed = 12345; + if (2 < argc) { + seed = atoi(argv[2]); + } + +#ifdef PRINT_SOLUTION + int size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + int size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + int size_z = (boardstr[7] - '0'); +#endif + + // Solver + ap_int<32> status; + clock_t clock_start, clock_done; + clock_start = clock(); + bool result = pynqrouter(boardstr, boardstr_high, seed, &status); + clock_done = clock(); + if (result) { + cout << endl << "Test Passed!" << endl; + } else { + cout << endl << "Test Failed!" << endl; + } + cout << "status = " << (int)status << endl; + cout << "elapsed = " << ((double)(clock_done - clock_start) / CLOCKS_PER_SEC) << endl << endl; + +#ifdef PRINT_SOLUTION + cout << "SOLUTION" << endl; + cout << "========" << endl; + cout << "SIZE " << size_x << "X" << size_y << "X" << size_z << endl; + for (int z = 0; z < size_z; z++) { + cout << "LAYER " << (z + 1) << endl; + for (int y = 0; y < size_y; y++) { + for (int x = 0; x < size_x; x++) { + if (x != 0) { + cout << ","; + } + int i = ((x * MAX_WIDTH + y) << BITWIDTH_Z) | z; + unsigned int num = (unsigned char)(boardstr[i]) + ((unsigned char)(boardstr_high[i]) << 8); + cout << setfill('0') << setw(5) << right << num; + //cout << (unsigned int)(unsigned char)(boardstr[i]); + } + cout << endl; + } + } +#endif + + return 0; +} + diff --git a/hls_2018/router_05/router.cpp b/hls_2018/router_05/router.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d086860d0e1da2ff5a01a8c86936208398ce611e --- /dev/null +++ b/hls_2018/router_05/router.cpp @@ -0,0 +1,457 @@ +/** + * router.cpp + * + * for Vivado HLS +*/ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +#include "./router.hpp" + + + +static ap_uint<32> lfsr; + +void lfsr_random_init(ap_uint<32> seed) { + + lfsr = seed; +} + +ap_uint<32> lfsr_random() { + + bool b_32 = lfsr.get_bit(32-32); + bool b_22 = lfsr.get_bit(32-22); + bool b_2 = lfsr.get_bit(32-2); + bool b_1 = lfsr.get_bit(32-1); + bool new_bit = b_32 ^ b_22 ^ b_2 ^ b_1; + lfsr = lfsr >> 1; + lfsr.set_bit(31, new_bit); + + return lfsr.to_uint(); +} + + + +// Global values +static ap_uint<7> size_x; // X +static ap_uint<7> size_y; // Y +static ap_uint<4> size_z; // Z + +static ap_uint line_num = 0; // #Lines + +bool pynqrouter(char boardstr[BOARDSTR_SIZE], char boardstr_high[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status) { +#pragma HLS INTERFACE s_axilite port=boardstr bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=boardstr_high bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=seed bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=status bundle=AXI4LS +#pragma HLS INTERFACE s_axilite port=return bundle=AXI4LS + + // status(0:Solved, 1:Not solved) + *status = -1; + + // board + ap_int board[MAX_CELLS]; // -1024 ~ 1023 (Negative values mean terminals) + INIT_BOARD_ARRAY: + for (ap_uint i = 0; i < (ap_uint)(BOARDSTR_SIZE); i++) { + board[i] = 0; + } + + + // ================================ + // (Step.0) Initialization (BEGIN) + // ================================ + + // Note: Loop counter -> need an extra bit (for condition determination) + + /// Parse /// + size_x = (boardstr[1] - '0') * 10 + (boardstr[2] - '0'); + size_y = (boardstr[4] - '0') * 10 + (boardstr[5] - '0'); + size_z = (boardstr[7] - '0'); + + INIT_BOARDS: + for (ap_uint idx = 8; idx < (ap_uint)(BOARDSTR_SIZE); idx+=11) { + + // NULL-terminated + if (boardstr[idx] == 0) break; + + line_num++; + + // Start & Goal of each line + ap_uint<7> s_x = (boardstr[idx+1] - '0') * 10 + (boardstr[idx+2] - '0'); + ap_uint<7> s_y = (boardstr[idx+3] - '0') * 10 + (boardstr[idx+4] - '0'); + ap_uint<3> s_z = (boardstr[idx+5] - '0') - 1; + ap_uint<7> g_x = (boardstr[idx+6] - '0') * 10 + (boardstr[idx+7] - '0'); + ap_uint<7> g_y = (boardstr[idx+8] - '0') * 10 + (boardstr[idx+9] - '0'); + ap_uint<3> g_z = (boardstr[idx+10] - '0') - 1; + + ap_uint start_id = (((ap_uint)s_x * MAX_WIDTH + (ap_uint)s_y) << BITWIDTH_Z) | (ap_uint)s_z; + ap_uint goal_id = (((ap_uint)g_x * MAX_WIDTH + (ap_uint)g_y) << BITWIDTH_Z) | (ap_uint)g_z; + board[start_id] = -line_num; + board[goal_id] = -line_num; + } + + // For each line + ap_uint connected_line_num = 0; + bool connected[MAX_LINES]; + INIT_CONNECTED: + for (ap_uint i = 1; i <= (ap_uint)(line_num); i++) { + connected[i] = false; + } + + lfsr_random_init(seed); + + // ================================ + // (Step.0) Initialization (END) + // ================================ + + + // ================================ + // (Step.2) Rip-up Routing (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Routing ..." << endl; +#endif + + bool solved = false; + + ROUTING: + for (ap_uint<16> round = 0; round < 32768 ; round++) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=32768 + + // Target line + ap_uint target = lfsr_random() % line_num + 1; + +#ifdef DEBUG_PRINT + cout << "(round " << round << ") LINE #" << (int)target << " " << lfsr_random() << endl; +#endif + + if (connected[target]) continue; + + if (connectable(board, target, 0)) { + connected[target] = true; connected_line_num++; + } + else { + ap_uint<16> j; + for (j = 0; j < 10000; j++) { + + // Ripped-up line + ap_uint rip_up = lfsr_random() % line_num + 1; + if (connectable(board, target, rip_up)) { + connected[target] = true; + connected[rip_up] = false; + break; + } + } + if (j == 10000) break; + } + if (connected_line_num == line_num) { + solved = true; + break; + } + } + + // Not solved + if (!solved) { + *status = 1; return false; + } + + // ================================ + // (Step.2) Rip-up Routing (END) + // ================================ + + + // ================================ + // (Step.3) Output (BEGIN) + // ================================ + +#ifdef DEBUG_PRINT + cout << "Output ..." << endl; +#endif + + // Init: Blank = 0 + OUTPUT_INIT: + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + + if (board[i] < 0) { + boardstr[i] = (unsigned char)(((-1) * board[i])); + boardstr_high[i] = (unsigned char)(((-1) * board[i]) >> 8); + } + else { + boardstr[i] = (unsigned char)((board[i])); + boardstr_high[i] = (unsigned char)((board[i]) >> 8); + } + } + + // ================================ + // (Step.3) Output (END) + // ================================ + + *status = 0; return true; +} + + +// ================================ // +// For Routing +// ================================ // + +bool inside_board(ap_uint cell_id) { + + ap_uint<13> cell_xy = (ap_uint<13>)(cell_id >> BITWIDTH_Z); + ap_uint<7> cell_x = (ap_uint<7>)(cell_xy / MAX_WIDTH); + ap_uint<7> cell_y = (ap_uint<7>)(cell_xy - cell_x * MAX_WIDTH); + ap_uint<3> cell_z = (ap_uint<3>)(cell_id & BITMASK_Z); + + bool ret = false; + if (cell_x < size_x && cell_y < size_y && cell_z < size_z) { + ret = true; + } + else { + ret = false; + } + + return ret; +} + +bool connectable(ap_int board[MAX_CELLS], ap_uint target, ap_uint rip_up) { + + ap_uint<2> avail[MAX_CELLS]; + ap_uint prev[MAX_CELLS]; + + ap_uint start_id = 65535, goal_id = 65535; + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + + if (!inside_board(i)) continue; + + prev[i] = 65535; // init. + + if (board[i] == target * (-1)) { + if (start_id == 65535) { + start_id = i; + avail[i] = 3; + } + else { + goal_id = i; + avail[i] = 0; + } + } + else if (board[i] == 0 || board[i] == rip_up || board[i] == target) { + avail[i] = 1; + } + else { + avail[i] = 0; + } + } + + bool try_connect = available(avail, prev, start_id, goal_id); + if (try_connect) { + if (rip_up > 0) { + remove_line(board, rip_up); + } + // Connect line for target + ap_uint id = prev[goal_id]; + BACKTRACK: + while (id != start_id) { + board[id] = target; id = prev[id]; + } + } + + return try_connect; +} + +void remove_line(ap_int board[MAX_CELLS], ap_uint rip_up) { + + for (ap_uint i = 0; i < (ap_uint)(MAX_CELLS); i++) { + + if (!inside_board(i)) continue; + if (board[i] == rip_up) board[i] = 0; + } +} + +bool available(ap_uint<2> avail[MAX_CELLS], ap_uint prev[MAX_CELLS], ap_uint start_id, ap_uint goal_id) { + + // Priority queue (Circular list) + ap_uint top = 1, bottom = 0; + bool is_empty = true; + ap_uint qu_nodes[MAX_PQ]; + + // Point of goal terminal + ap_uint<13> goal_xy = (ap_uint<13>)(goal_id >> BITWIDTH_Z); + ap_uint<7> goal_x = (ap_uint<7>)(goal_xy / MAX_WIDTH); + ap_uint<7> goal_y = (ap_uint<7>)(goal_xy - goal_x * MAX_WIDTH); + ap_uint<3> goal_z = (ap_uint<3>)(goal_id & BITMASK_Z); + + qu_push(qu_nodes, start_id, &top, &bottom, &is_empty); + + bool complete = false; + + SEARCH_QUEUE: + while (!is_empty) { +#pragma HLS LOOP_TRIPCOUNT min=1 max=1000 +#pragma HLS LOOP_FLATTEN off + + ap_uint src_id; // target cell + qu_pop(qu_nodes, &src_id, &top, &bottom, &is_empty); + + + // End routing + //if (avail[src_id] == -1) { complete = true; break; } // goal + + if (avail[src_id] != 1 && avail[src_id] != 3) continue; // Keep searching + + // Point of target cell + ap_uint<13> src_xy = (ap_uint<13>)(src_id >> BITWIDTH_Z); + ap_uint<7> src_x = (ap_uint<7>)(src_xy / MAX_WIDTH); + ap_uint<7> src_y = (ap_uint<7>)(src_xy - src_x * MAX_WIDTH); + ap_uint<3> src_z = (ap_uint<3>)(src_id & BITMASK_Z); + + ap_uint<3> isbranch = 0; + ap_uint tmp_dest_id = 65535; + // Search adjacent cells (1) + SEARCH_ADJACENTS_1: + for (ap_uint<3> a = 0; a < 6; a++) { + ap_int<8> dest_x = (ap_int<8>)src_x; // Min: -1, Max: 72 (Signed 8bit) + ap_int<8> dest_y = (ap_int<8>)src_y; // Min: -1, Max: 72 (Signed 8bit) + ap_int<5> dest_z = (ap_int<5>)src_z; // Min: -1, Max: 8 (Signed 5bit) + if (a == 0) { dest_x -= 1; } + if (a == 1) { dest_x += 1; } + if (a == 2) { dest_y -= 1; } + if (a == 3) { dest_y += 1; } + if (a == 4) { dest_z -= 1; } + if (a == 5) { dest_z += 1; } + + // Inside the board ? // + if (0 <= dest_x && dest_x < (ap_int<8>)size_x && 0 <= dest_y && dest_y < (ap_int<8>)size_y && 0 <= dest_z && dest_z < (ap_int<5>)size_z) { + + // Adjacent cell + ap_uint dest_id = (((ap_uint)dest_x * MAX_WIDTH + (ap_uint)dest_y) << BITWIDTH_Z) | (ap_uint)dest_z; + if (avail[dest_id] >= 2) { + isbranch++; + tmp_dest_id = dest_id; + } + } + } + if (isbranch > 1) { avail[src_id] = 0; continue; } + if (avail[src_id] == 1) { + avail[src_id] = 2; + prev[src_id] = tmp_dest_id; + } + + ap_uint<3> p = 0; + ap_uint<3> search_order[6]; + if (src_x > goal_x) { + search_order[p++] = 0; // To src_x-- + } + else { + search_order[5+p] = 0; + } + if (src_y > goal_y) { + search_order[p++] = 1; // To src_y-- + } + else { + search_order[4+p] = 1; + } + if (src_z > goal_z) { + search_order[p++] = 2; // To src_z-- + } + else { + search_order[3+p] = 2; + } + if (src_x < goal_x) { + search_order[p++] = 3; // To src_x++ + } + else { + search_order[2+p] = 3; + } + if (src_y < goal_y) { + search_order[p++] = 4; // To src_y++ + } + else { + search_order[1+p] = 4; + } + if (src_z < goal_z) { + search_order[p++] = 5; // To src_z++ + } + else { + search_order[0+p] = 5; + } + + ap_uint<3> j, t; + SHUFFLE_1: + for (ap_uint<3> a = 0; a < p; a++) { + j = lfsr_random() % p; + t = search_order[a]; + search_order[a] = search_order[j]; + search_order[j] = t; + } + SHUFFLE_2: + for (ap_uint<3> a = p; a < 6; a++) { + j = lfsr_random() % (6-p) + p; + t = search_order[a]; + search_order[a] = search_order[j]; + search_order[j] = t; + } + + //cout << "(" << src_x << ", " << src_y << ", " << src_z << ")->"; + //cout << "(" << goal_x << ", " << goal_y << ", " << goal_z << "): p = " << p << " ["; + //for (ap_uint<3> a = 0; a < 6; a++) { + // cout << search_order[a]; + // if (a != 5) cout << " "; + //} + //cout << "]" << endl; + + // Search adjacent cells (2) + SEARCH_ADJACENTS_2: + for (ap_uint<3> a = 0; a < 6; a++) { + ap_int<8> dest_x = (ap_int<8>)src_x; // Min: -1, Max: 72 (Signed 8bit) + ap_int<8> dest_y = (ap_int<8>)src_y; // Min: -1, Max: 72 (Signed 8bit) + ap_int<5> dest_z = (ap_int<5>)src_z; // Min: -1, Max: 8 (Signed 5bit) + if (search_order[5-a] == 0) { dest_x -= 1; } + if (search_order[5-a] == 1) { dest_y -= 1; } + if (search_order[5-a] == 2) { dest_z -= 1; } + if (search_order[5-a] == 3) { dest_x += 1; } + if (search_order[5-a] == 4) { dest_y += 1; } + if (search_order[5-a] == 5) { dest_z += 1; } + + // Inside the board ? // + if (0 <= dest_x && dest_x < (ap_int<8>)size_x && 0 <= dest_y && dest_y < (ap_int<8>)size_y && 0 <= dest_z && dest_z < (ap_int<5>)size_z) { + + // Adjacent cell + ap_uint dest_id = (((ap_uint)dest_x * MAX_WIDTH + (ap_uint)dest_y) << BITWIDTH_Z) | (ap_uint)dest_z; + if (dest_id == goal_id) { + prev[dest_id] = src_id; + complete = true; + } + qu_push(qu_nodes, dest_id, &top, &bottom, &is_empty); + } + } + if (complete) break; + } + + return complete; +} + +// Queue push (Enqueue) +// First In Last Out +void qu_push(ap_uint qu_nodes[MAX_PQ], ap_uint id, ap_uint *top, ap_uint *bottom, bool *is_empty) { +#pragma HLS INLINE + + (*bottom)++; + if ((*bottom) == (*top) && !(*is_empty)) { (*top)++; } // Queue is full -> First element is automatically removed + qu_nodes[(*bottom)] = id; + *is_empty = false; +} + +// Queue pop (Dequeue) +// First In Last Out +void qu_pop(ap_uint qu_nodes[MAX_PQ], ap_uint *id, ap_uint *top, ap_uint *bottom, bool *is_empty) { +#pragma HLS INLINE + + *id = qu_nodes[(*bottom)]; + (*bottom)--; + if (((*bottom)-(*top)+1) == 0) { *is_empty = true; } +} diff --git a/hls_2018/router_05/router.hpp b/hls_2018/router_05/router.hpp new file mode 100755 index 0000000000000000000000000000000000000000..08d93637549ded9591f8a06d7b60b2f55b564778 --- /dev/null +++ b/hls_2018/router_05/router.hpp @@ -0,0 +1,53 @@ +/** + * router.hpp + * + * for Vivado HLS + */ + +#ifndef __ROUTER_HPP__ +#define __ROUTER_HPP__ + +#ifdef SOFTWARE +#include "ap_int.h" +#else +#include +#endif + +//#define DEBUG_PRINT // for debug + +#ifdef DEBUG_PRINT +using namespace std; +#endif + +// Parameters +#define MAX_WIDTH 72 // Max of X, Y +#define BITWIDTH_XY 13 +#define BITMASK_XY 65528 // 1111 1111 1111 1000 +#define MAX_LAYER 8 // Max of Z +#define BITWIDTH_Z 3 +#define BITMASK_Z 7 // 0000 0000 0000 0111 + +#define MAX_CELLS 41472 // Max #cells (16bit) +#define MAX_LINES 32768 // Max #lines (15bit) +#define MAX_PQ 16384 // Queue size (14bit) +#define MAX_BUFFER 16384 // Line buffer size (14bit) +#define CELL_BIT 16 +#define LINE_BIT 15 +#define PQ_BIT 14 +#define BUFF_BIT 14 + +#define BOARDSTR_SIZE 41472 // Size of I/O + +// For random num generation +void lfsr_random_init(ap_uint<32> seed); +ap_uint<32> lfsr_random(); + +bool pynqrouter(char boardstr[BOARDSTR_SIZE], char boardstr_high[BOARDSTR_SIZE], ap_uint<32> seed, ap_int<32> *status); +bool inside_board(ap_uint cell_id); +bool connectable(ap_int board[MAX_CELLS], ap_uint target, ap_uint rip_up); +void remove_line(ap_int board[MAX_CELLS], ap_uint rip_up); +bool available(ap_uint<2> avail[MAX_CELLS], ap_uint prev[MAX_CELLS], ap_uint start_id, ap_uint goal_id); +void qu_push(ap_uint qu_nodes[MAX_PQ], ap_uint id, ap_uint *top, ap_uint *bottom, bool *is_empty); +void qu_pop(ap_uint qu_nodes[MAX_PQ], ap_uint *id, ap_uint *top, ap_uint *bottom, bool *is_empty); + +#endif /* __ROUTER_HPP__ */ diff --git a/solver/pynqrouter.py b/solver/pynqrouter.py index bbd9ff13d99ad522557ba5c530fb89cc17ccddca..e27c9695479516c9fe93e7ed767cc3f6f093f3c5 100644 --- a/solver/pynqrouter.py +++ b/solver/pynqrouter.py @@ -42,15 +42,17 @@ def solve(boardstr, seed=12345, zero_padding=False): size_z = (ord(boardstr[7]) - ord('0')) # Overlay 読み込み - OL = Overlay('pynqrouter.bit') + OL = Overlay('router_design.bit') OL.download() print(OL.ip_dict) print('Overlay loaded!') # MMIO 接続 (pynqrouter) + # mmio = MMIO(int(PL.ip_dict[IP][0],16), int(PL.ip_dict[IP][1],16)) mmio = MMIO(int(PL.ip_dict[IP][0]), int(PL.ip_dict[IP][1])) # MMIO 接続 & リセット (LED) + # mmio_led = MMIO(int(PL.ip_dict[IP_LED][0],16), int(PL.ip_dict[IP_LED][1],16)) mmio_led = MMIO(int(PL.ip_dict[IP_LED][0]), int(PL.ip_dict[IP_LED][1])) mmio_led.write(0, 0)