This the first part in a series of articles related to a demo that will perform classical image processing in the Lattice ICE40 UltraPlus FPGA. The system that will be used is the Lattice ICE40 FPGA UltraPlus Breakout Board.
We will be using an encoded image with characters for transmission and reception over the 4 SPI interface inside a header file cup.h generated from the original RGB downscaled in resolution (to conserve memory resources) from GIMP and integrated into the C++ program in the x86 host as follows,
/* GIMP header image file format (RGB): /DigiKeyCoffeeCup/cup.h */
static unsigned int image_width = 64;
static unsigned int image_height = 64;
/* Call this macro repeatedly. After each use, the pixel data can be extracted */
#define HEADER_PIXEL(data,pixel) {\
pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
data += 4; \
}
static char *header_data =
"````````````````````````````````````````````````````````````````"
"````````````````_PHZ\\_\\N\\OXM^P8V`@X]````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````@X]]`(QZO,BY>T=[/4F^0,S_`P\\`P\\_````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"``````````\\__PHY\\?DGZ.X<Y>H9Y.L;Z/$A\\?PL^P<W`0T]`P\\_````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````0P\\]O`N[/(?Z>X;Z>`=Z?$@Z.`AYN`BZ/,E\\/PM^@8V_`P\\`P\\_````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````@T]^@0R[_4BZN\\;Z_$>[O4D[_<I[?8JZ/(GX^TCX>PAYO$E[_LM^P8V`@X]"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`@X]^P0R\\?<D[?$=[?(>[_4C\\/@I\\?DL[_@MZ_4KY_$HX^XEXNTDX^\\DZ/0G]0$Q"
"_PL[`P\\_````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````````````````PX^"
"^P0R[_4A[>`=[_,@\\/<D\\?@H\\?DK\\/HM[_DM[/<LZO4KZO4KZ?0KYO$HX>TCX>TA"
"[OHK_0DY`P\\_````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````````````P\\__`HY"
"[_0@[.\\:[_(>\\?8C\\ODH\\OLK\\OLM\\?LN\\/LN[ODM[ODM[_DN[ODOZ_8MY?$HW>D?"
"W.@=[OHL_@H[`P\\_````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````````````@X]^@,P"
"Y^D3Z^T8[?$>[O0B\\?@H\\_PM]/XO]/XP\\_TP\\?PO\\?PO\\?PP\\/LO[?@NZ?0KXNTE"
"V>4=W^H?]P(S`0T]````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````````````0P\\]/PH"
"Y.8-YN@3YNL7Z.X>[/0E\\/DK\\_TP]?\\Q]?\\R]/XQ\\_TQ\\OTQ\\/LO[?<NZ?0KX^\\F"
"W.@@V.,;Z?0H^P8W`@X^````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````````````0P\\\\_PH"
"XN0+X>,-Y>D6Z>\\?ZO(E[/0H[_DL\\_TP]?\\R]O\\S]?\\S\\_XR\\/LP[?@MZ/,JX^\\E"
"W>D?V>0:W^H?[_HM^`<X`@X^````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````````````@T\\]?XJ"
"XN0*W^$*YNH6Z_$B[/0GZ_,IZ_0J[?<L\\?LP]/XR]/\\S\\_XR\\?PP[?@LZ/,HXNTD"
"WND?WND?X^TDY_$G\\/HN^P8X`@X^````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````P\\_`0T\\_@@V\\?@B"
"X>,)WM\\'Y.@4Z_$A[?8H[?8KZ_4KZO0KZ_4L[?<M[_HO\\/LP[_HN[/@KY_,FXNXA"
"X>PAY_$GZ_8MZO0KY_(H[ODL^00U_`P\\`P\\_````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````P\\_`0T]^`@X]P(R\\_XM]/TJ\\/8@Z.L4"
"Y.8.W=`(XN82Z>\\>[?4H[O@M[O@N[/8MZO0LZO0KZ_4LZ_8LZ_8LZO4JY_,FY?$D"
"Z/0G[ODN\\/HQ[/@NXNXEU^$7V.,5Y?$A\\O\\O^`@W`0T]`P\\_````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````P\\__`P\\]`0SY_,BS=@'NL'OQ<CTX>0.Z>P6[.X9"
"Z^T7X^8.X^<2Y^X;[/0E[_@L\\/HP[_DP[?<NZO4LZ?0KZ/0JZ/,IY_(HY_(HZ?0I"
"[OHM\\?PP\\/LP[/@MX>PCR-$&J*W>F)S)IZ[<Q]'`Y.`@]P,S_`P\\`P\\_````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````0T]]`,SW^L:N</RG:/1J:O6R,GSWM`*Y^D3[.X9\\?0?"
"\\O4@ZNP7Y^L6Z.X<Z_(C[O<J\\/HP\\?LR[_DQ[/<NZO4LZ/,KY_(IYO$HYO$HY_,I"
"[/@K[_HN[OHLZ?8JX>TBU]\\1S\\[YQ;W?L*3%EXZSDI.^L+GGVN85]P,S`0T]````"
"````````````````````````````````````````````````````````````````"
"`````````````P\\_^`@XY.`?N,/RCI;$DI6`N[OFV]T'Y^D3Z.D4ZNP7\\/,?]?LE"
"]OLF\\/,?ZNX;ZN\\<Z_(B[?<H\\/HN\\/LQ\\/HR[_DQ[/<OZO4LY_,JYO(IY?$HY?$H"
"Y_(IZO4JZ_<KZ?,IX>PCU]`6TMD+U-@#UM/ZS\\7FN*C&E(:FA(6PJK3CX.T<_0DX"
"`P\\_````````````````````````````````````````````````````````````"
"`````````P\\^]P,STMX-H*G8C)\"]J*C2S,OSXN,,Z^T7Z^T7ZNP6[.X;\\_@E]_\\K"
"]_XJ]/DF[_0A[?0A[?4D[O<I[_DM\\/HP\\/HR\\/HQ[O@P[/8NZ/0KYO(IY?$HY.`H"
"Y.`GY?$HZ/,JZ?,JY>\\FW.8<U=\\5U-X3U]\\1V=P)UL_TQK//HXNC?7:<A8V\\P\\_^"
"]0$P`@T]````````````````````````````````````````````````````````"
"`````P\\_]@(QR-0#DYK(D(^ZM[3>UM7^YN<1[N\\:[^`;Z^P6ZNL4[N`<]?DF]_\\K"
"]OXJ]?PH\\ODF[_<D[O8E[O<H[_@L\\/HO\\/HP[_DQ[O@P[?<OZO4LY_,JY?$IY.`H"
"X^XHX^XGY>`HZ?,JZ?0KY>`GX.HAVN0;V>(8VN(5VML'U,?HQJJ^L9JR@WR@<GJH"
"L;SL[?HI_`P\\````````````````````````````````````````````````````"
"````^`@WSMD(D9;$B7VALZ7(UL_WZ>D3\\O,?]/8A\\?,=Z^P5Z.D1[>\\:]/@E]?PH"
"]/PI]/LI\\ODH[_<E[?4D[?4F[?<J[O@M[ODO[O@O[?<O[/8NZ_4LZ?,KY_(JY>`I"
"X^XGX^XGYO$IZ?0KZ_4KZ?,JY.XEW><>V>,:VN,9V^$3U]/^SKK8Q:>^NJC$A'^F"
":7&?M\\+R[_PK`0T]````````````````````````````````````````````````"
"`@X^YO,AG*32@W.4K)*LT\\3EZ>4-]/0A^/HG^/HG]/8A[>\\7Z.D0ZNP5[_,?\\/<D"
"\\/<E\\/<F[_8E[/0BZ_(@Z_(BZ_0F[/4I[/8K[/8LZ_8LZ_4LZO0KZ?,KZ/,KY_(J"
"Y.`HY.\\GYO$IZO0KZ_8LZ_4LY_$HX>LBV^4<V>,9VN,8V^$3V-4#S[[DR[71N*?%"
";V:*=X\"NS]L*]`0S`P\\_````````````````````````````````````````````"
"_@HZQ,_^@(&KFGZ4R;+,YMT!]/,=^?HH^_PJ^OPI]_DE\\?$;ZNH2Z>H2Z^X:ZN`="
"Z_$>ZO$?ZO$?Z>`=Z>\\=Z>\\?Z?$BZ?(EZ?,GZO,HZO,IZ?,IZ?(IZ/(JZ/(JZ/,J"
"Y_(IY_$IZ/,J[/8M[?<N[/8MZ?,JY>\\FX.LBW.8>V>,:V.(8V=`4U]D)TLCOQK#*"
"FX.:96&(HJW<Y_0D_`P\\````````````````````````````````````````````"
"^`@WI['A>'&7JHN>UL+<[><+]_<B^OPJ^_XK^_XK^?LH]/4?[>T5Z>L3Z>P8Z>T:"
"Z.T:Z.X;Z.X;Z>T;Z.T;Z.X>Z.\\@Y^\\BY^`CY^`DZ/$FZ/$FZ/$GY_$HZ/(IZ?0J"
"ZO4KZ_8L[?@N[_HO[_DP[O@OZ_4LZ/(IY.XFX>LBW><>VN0;V>,9V^,6U]<%R+76"
"JXB<;UQ[?82RV.04^`@X```_````````````````````````````````````````"
"^P<WG:?6>V^2LY2DV\\??[N<(]?0=^/DE^OPH^_XJ^_TJ^/DE\\O,=[N\\9[>\\:[.\\<"
"[.`=[/$>[/$>Z^`=ZN\\<Z>X=Z.X?Y^X?YN\\@YN\\AYN\\BY^`DZ/$EZ?(GZO0I[/<L"
"[ODN\\/LO\\OTQ\\OTR\\?LQ[_DP[/8MZ?,KYN`HX^TEX.HAW><=V^08V]`2U,_[PJ;%"
"K(\"2>UYX<W6AS]L*^00T`P\\_````````````````````````````````````````"
"^P<WIJ_>@7::M9>FVL37Z]_[\\>P.\\_$7]?4=^/DC^OPG^OPH^/DE]O<B]?<B]?@D"
"]ODF]OHH]?HH\\_DF\\/4B[?(@ZN`?Z>\\?Z.`?Z?$AZO(CZ_0F[/4H[O<K\\/HN\\OPP"
"]/\\R]/\\S]/\\S\\_XR\\?PR[_DP[?<NZO0KYN`HX^TDX.H@WN<:W>(2U]/_R;+3N(^B"
"JGJ*@&!Z>'BDT=T+^@4U`P\\_````````````````````````````````````````"
"_@DYO\\CXA8&IJ8N:T+*_Y,_B[.#Z\\.D&\\NX.]/(6]_8>^?HE^OPH^_TJ_/\\K_@$M"
"_P(O_@,P_@,Q^`(O^/\\L]?LH\\O@E\\/8D\\/<E\\/@G\\OHK\\_PN\\_TP]/XQ]O`T]`$U"
"]`$U]?`T]/\\S\\_XR\\OPR\\/HQ[O@OZ_4LYN`HXNLAW^@<WN45W-P&TL+DOYJMM(63"
"I76$>%QY@X.PUM\\.]OXN_00T_P<W`@L[`PX^````````````````````````````"
"`0P]W^H8EIK&DGN4N9BBU[K&Y]3E[>+Y\\.@#\\NP*].`2]_4<^?HD^_TI_0$M_@0O"
"_P4Q_@4R_P4S_@0R_@,R^`(Q^P$O^?`O^/`O^0$Q^0$S]`$T]`$U]`$U]`$U]`$U"
"]O`T]?\\S]/XT]/TT\\_TS\\?LR[_HQ[/8NYN`GX.D>W>45W=\\*V<_RS+''NY*?KX&."
"FFM^:U%UCWNLRKWNW<[`X\\`\"Z=<)\\>87^/4F_@,S`@P\\`P\\_````````````````"
"`P\\_]P,RP,?UC8>OFG^1OY^IVL#-Z-;I[N+Z\\>D$\\^X,]?(3]_4:^/DA^?TH^P$L"
"^`,N^`,P_0,Q_@,Q_@,S_@0S_00T_00T_00T^`0U^P,U^@,V^0(V^0(V]`$U]`$U"
"]O`T]O`T]?\\U]?XU]/TT\\_PS\\?LR[?<NYN`FW^<9V]X*V='UTKW5QJ.QMXR7I7B'"
"@%QV;#YLE4B!KV2<NFNBQFNDSW\"JU(&ZW*/9Z,W`]?(C_`@X`P\\_````````````"
"`````0T]Z_4DL;3BAGNAF7Z1OJ\"NV+W-YM+G[N#Z\\NH'].X.]?$2]O07]_<>^/LF"
"^/XJ^?`M^P$O^`$P^`(R^`(S^`,S^`,T^`,T^P,U^P,V^@,V^0(V^0(V^0(V^0(V"
"^0(V]`$U]O`T]?\\T]/XS\\_PR\\?LP[O<MY^`DW^03V-+WT+S4QZBVO):AJX*0C&A_"
":D1NBRIJI!=GK!%DM!)FPA1KS!5OSR1VT$.(TW6OW[+H\\>D;_P8W`P\\_````````"
"````````_0@WVMT+HIG&@VV2E7B0M9:FS[/\"X<W@[-[W\\.@$\\NP*\\^X.].`2]?0;"
"]ODD]OPH]_TL]_XO^/\\Q^/`R^/`R^/`R]_`S]`$T]`$T]O`T]O`T]O`T]O`T]`$U"
"^0(V]`$U]?\\S]/TQ\\OPN\\?HM\\/DK[?8IY^\\@W]`*U<?FQZJ\\N)*?J8&1CVV&;DYY"
"BCM]JR]ZL1QLLA%DNA!ER!1KT1URU1]WU1IXU\"V!TV.DVZ?=[N46_`@Y````````"
"`````````0L[ZNL:OZG8E6R;?%B!@6>&H(:<P*:XU[_1Y-'HZMWY[>4\"[^D&\\>T-"
"\\O(7\\_0=]/<E]/HI]/PM]?TO]?TO]?TP]?TP]/XQ]/XQ\\_TQ\\_TQ\\_TQ\\_TQ\\_TQ"
"]/XQ]?\\R]?TP\\_PM\\OHJ\\?@H[_8F[/(AY>@3VM/YS+C5N9NQH'Z3AF:$<5!_AT^,"
"KDN3O$>2N2QYMQ5IP!ANS25WU21YV!EVV!)VUQ)XU\"=_T%^?V:O@]/(C`@T]````"
"`````````0T\\[_(AR:[>J6F<E4M`@$AY<$UV>V)`FX\"6N9ZQS[C-W,K@Y-;NZ-WY"
"Z^,\"[.8)[>L4[O$=\\/4D\\?@H\\ODJ\\OHK\\OHM\\?LN\\?LN\\?HN\\/HM\\/HM[_DL[_@L"
"[_DI\\/@G[_8D[_4C[O0B[/$>Z.L6XM`(ULWRP*_/I(JEAFR)<55];T1W?SUZET.&"
"KC.#N3:&N2=YMQ9MOC)^RDZ7TDJ4U#%`TQARTQ1QTA1ST3:\"TG*NX+[S_@0T``\\_"
"`````````PX]]/@GS[/ELFB>I4%^FT!ZBT%V=T%R:$=Q;5E]AW*0HHJANYZQRK##"
"UL'8VLCBX-3TX]S`Y>('Z.</ZNH5Z^T9Z^\\=Z^`@Z_$AZN`?ZN`>ZO$?Z^`@ZN\\>"
"Z>X;Z.P8Y>@3XN,-W=P%U,_UQ[W?M*?(FXRN@&Z3;5)];$%V=3IV?#)S@B=NER5U"
"K\"1^L2!WK1ALJ2AMJD6!KER5L6J@M&ZDMVNANUZ7PD>%R\"ETRT&&U)#(\\>L<`0P\\"
"`````````PX^]OLKT;?IMFB@K3A]J#1YGS9WDSIVA3UV=S]T:4-S9$QU<EQ`C'.1"
"HX>AK9*KNJ.\\PJS$R+/-S;K6T<'?U,CIU<WRU]'WU]+XU\\_SU\\[OVM+UVM/YU<SS"
"TLCNR\\+GPKG>N*W1K)_#FHRRA'6=<E^*;DY^=D)Y?S=U@R]SA2URB\"EPB1IIF\"%R"
"I2%VHQMMG3MXI7>IP[3CW]X,[_,A]/DG\\?8DX^$0R++CM&ZCO#Q`RFJIW+SO_@4V"
"``````````\\_^?\\OU;SNN&RDL#=^KRU[K2QZIC!YFC-VBS5S?C=R=SIR<SQS;T-U"
";4QX;E5_>&.*A'\"4CGF<E7ZAF82GG(JMH(^QI).WJ9F]K)V_JYN\\J)F\\JIK!I9:^"
"EH6NC'JDA7*=?6>4=UN)=D^\">45^?#Y[@3IZAS=XC3)WDS)XES=\\E2MTCAYIERMS"
"FQQNF#EYJHB[UM4$\\OLJ_PDY`@X]`P\\^`PX^_0<WY^T<O[+BHEJ2MT2'S(W%\\_,C"
"````````````^`(RV<3UNW:ML3N!L\"1XL\")WKBQZJ3!ZGBESDREOB2MN@RUM?3%N"
">39Q=SMU>4-Z?4Z#?%.&=E&$<4Y`;TY_;D]_;U*!<5:&=%J*=EJ*>5N,@6\"2@%N/"
"?4Z&?DB\"@$5_@4%]@#QZ@#AW@C5VA3)UB2]UCRMTE2=TF25UFR9UEB%ND29MF3I]"
"DBIRF6J?TL[^]?XM`@T]`````````````````0P\\[O@GP<'PC668G31WPG:PY-<("
"````````````_04TW<W^OH*XL4*%KR!VKQ=SKQIRK1URJ1]QHR-QF1ILDQIJCR)L"
"C\"IPB\"QPAS%SB#MZAD)_@3]\\?3EX>S=V>3AV>3EW>SIY?3M[?CU]@$!_A$2#@SY^"
"@3E[@C=Y@S1WA3)UAC!TARUSBBERCR9SEB=VG\"IYG2AYG\"!UFQEREAELD2MNEDN%"
"G'2HO+'B[O4E`0P\\````````````````````_`L[Z?,BN+CH?E^1BC9UN&ZHU;OM"
"````````````_@<VX=<'P8_#L4J*KQ]UKQ1QKA!NK1%MJQ1MIQ9LH1%IG!%IF!-I"
"EA=KE1AMEA]PFC-\\G$6)F$\"%DC1[CBYUBBYTB#!UB#)VBC5YCCE]DSV\"ET\"&D#9]"
"C#1ZBS%WC2QVD\"=TDR)REAYRF!IRFQ=RG1YTH\"EYH\"MZG2)VFA=QE2-NEE\"(KY3%"
"U=,\"[_8E_PHZ`P\\_````````````````````_0@XW^<7I:#0=$Q`?RUKJU^7RJC:"
"````````````_P@XY=`0Q)O.L5*/KB%TKQ9RKA%NK1)LJQ5LJ!AKHQ)HGQ%GG!!G"
"FA%IFQ-KG!5MGBAVHCR#H#9_GB5VG\"%UFRIYFBYZFBYZG2][HS%_J#.#J3.$I\"9Z"
"HRU\\HRY\\I2E[I2%XI1IUI1MVI!IUHA5SH1ERH2=WH2Q[GB1XFAEQES5WIWNOWMT,"
"^@,R`@T]`````````````````````````PX^]?`OSM(\"CW^P;S%J?B=EI%J1QZ;7"
"````````````_`HZZN@8R:78LEJ5K2-UKQESKA1OK11LK!MMJB%OI!1HH!!EGA!F"
"G1)HG1)IGA%JGQ9LH2-RHQ]RI!5QIA]VJ32!JT\")JSZ(K#*!KB-\\L\"%]L2-^KAIX"
"KAUVKB!WKR5ZKAQVK!=TJB!WJ\")XIA]VI\"-VHR]\\HC9`H#%]FR5TF#Y\\L([!\\_DI"
"`PX]````````````````````````````_@@XY>L;M:W?@%J.<AM<@BEFIF*8SK?G"
"`````````````0P\\[^`@S:[ALF\":K2AWKQ]UKA5OK!)JJQ5JJ1AKI!)GH1!EH!!E"
"GQ%FH!5JHA1JI!QNIAANJ!)NJA%PK!MTKS%_LD&*LD&*L\"]^L!=VL1AXLR1]L2%X"
"KR)VKAUTL\"EZKA]TK!5PJAARJ!]UIRAYIS!^I#-^H#)]GS-\\G\"UVF#YZKXR_\\_DI"
"`@X]`````````````````````````0P\\\\/<GRL;WEWNO>3)L>117B2QFK6ZDV\\__"
"`````````````PX^]/<GT;?JM&>@KC-\\L\"]ZKR1SK!1JJA!HJ!!HI1!HHQ!FHA5G"
"HRQSI3!WI21PIRIUJ2-RJB)TK2IYKRQ[L#!^L31`L\"Y[KQUTKQ)QL!-SL1MVL!]U"
"L3=`KB-TKB5UK1MQJQ-NJ15PJ\"%UIRQ[I3-_H3![G21TG\"!QFA]MEC-RIWFNY-\\/"
"_`HY```_`````````````````0P\\\\?HJT<_`I8[!@T9\\>Q)5@Q-4ECAPN(.W[.H9"
"`````````````P\\_]_TMU+_RM6^GKD2%M%22M5F6L$B(JR=RJ1%IIQ%IHQ%GHAUI"
"IC]`IC^\"I\"ERI21PIR!PJRYZKCR&L#R%L#5`L\"][KQ]SKA!NKQ!OL!!QL!)QL!UT"
"L3B!KR5UK1IQK!=OJQ1NJ1EPIR1VI\"=WH21UGAYQG!5NFQ)LFA1IER)IGU.-R*'6"
"\\?8E_@DX`@X^``\\_`@X^^`8VZ?(BRLGZIHZ`C$Z#A!M:AQ!/DR-<J5J/RJS>^?`O"
"````````````````^@$QV,CYMWJPKU20NGBPPI''OH>_LV*?JS5[IA1HHA!DH11E"
"HBAOHB=OHAEIHQ5II11JJ!UOJR=UK2IWKBUZKRMXKQUQKQ%NL!-PL1-SL15TL1QT"
"L\"5VKR9VK1URK!YRJQUQIQANI!EOH1IPGA9NG!%LG!%MG1=NGAMMG!=FH\"]QN&6>"
"R[OMW^(1Y^\\?[O8FZ?$BU-D*L:W>E':IC$)YD!Q;E!!2FA!1I3APNX.VX]T-_`LZ"
"````````````````^`0TW=(\"O(>\\L5N6O7^VR*39RJSDPIC2M6^MK%&1IT:&H1YI"
"H!)EH!!DH1%FHQ1II1-HIQ%GJ1!IJQ)KK!=NK1ANK11MKQ-NL!=RL1=VL19VL!9R"
"KA1OK!=OJQ1MJAIPJB-SIQ]PHQ5LH!-LGA-LG!%LFQ%LG!1MGQINHAEHJ!EEM3)S"
"JEV3I'>JHH*UJ9#\"HXJ\\E'*EC5\"%E2QEH!)4IA!2J!!3JR5AM5Z3S:_A]_TM`PX_"
"````````````````_08VXML+P97*LV&;O'NRQY[4R:GBQJ;BQ*#=OY#.MH*`HC=["
"GR-NH\")MH1IJI2%PIAMMIQ-HJ!!HJA!IJQ-MK!QQK1]RK1=QKA)RKQ%VL!%VKA)P"
"K!!MJQ!MJA!LJ1)MIQIOIBIVI3I`HCM`GBUWFQ=MFQ)LG1IQHR5VJ29TKQILN\"1P"
"KAMEKB5KK2IMJS)NIRQGJ!]?L!-<MQ!9N1!5N!!4MQI<N4Z%R9C*Y^,3_`HZ````"
"````````````````_P@XZ.45QZ/7M66?NG.KQIK0R:GAQZGEQJKGNI#/MXC(HT*("
"J%.5J%.3HS=\\HR-PI3)YJ$.&JD2(K$*'KTB-L4R2L4>/L$:-LE\"6LTN5L2R#KR5Z"
"K\"!UJQ-OJAEPJC9_JDF.JER>KWFXKGNZI%R<G\"UWFQ)LG15NH1=MIQ5IK1)HLQ1H"
"LQ%BM1-CN!IGMQEBNA->P1%?QQ!AR1!@QQ!<PQA?P$J\"R([!X-4%^`0T`P\\_````"
"`````````````````0L[[>X>S*_BM&>AMVFCQ97,RJGAR:WHR[3PQ*7DQZ[MJFBI"
"MHS+LX?%JVVLIU>8KVVMO9+1P)C9P)?7PIW;OY32N'R]O8S+R:SKQZ+BMF&HM%JA"
"LE^CK%*6K5\"4M'BXNY33MY+1N)G9M)'1IFBHG\"]YFA5NG!9OH!=MI1)HJ1!DKQ)F"
"N1UNO1]KQC-XRS!UT\"%MU!9KU!=LT1=HS!]GR$^'S)+$X-4%^@(Q`P\\^````````"
"`````````````````@T]\\_8FT;GLM&JCLE\"/OW^XS*;>TKKTS[GTQ*;CS;KXMY'/"
"Q[KXOZGHP['PPJSKMI+1MY33O)W=P:CGQK/QQ:WKP9_>QJSJR[;TP934NWR_PZ3B"
"RK3TS;W[Q*KIP*7DP:KJNZ#@NZ'AMI35J&JLG3J\"FRIVFB9SFB1NFA9CHA-BJB%I"
"NT.(R#9^TB9TUR)SV1YSVBIZV3N&U$B+SVNCU*;9Z.$1^`0T`P\\_````````````"
"`````````````````P\\_]OPLUL+UMG*JKCA^M$V/NW&NP(_*P9;2P)C5S;GUN973"
"R;SYN);5OJ7DQ;+QO:'AOZCGPJOJPZOJQK7RR+?UR+7TS+OZQZCHOH+%QJ3CSL0!"
"O9[>QK7UQ;'SPJ_OP;#OOJCHO:;FM)+3I&2FFC-]F2UVF#!VE#)TD39TFDJ$H$^("
"K4V)Q4N*TDR.UUF>V%B=UEN;T7*LU)_4XM(#]/8F_PDY`P\\_````````````````"
"````````````````````^P$QW,W_NH\"VKCY`L#)\\L#F!KT.'KU&1M7.OP9S9L(\"^"
"PZ_KNIK8OJCEQK;TOJ7DPJSKQ;#OPZ[MQK3SQ[7TR+3SS;S[RJ[MPX[0R:_OT,P("
"Q[7TP*?GN8[0O9K<Q+#PQ;CWP*[NL(O+GE&4EQ]OER=QES-XEE2.GX:ZO+7FPKOM"
"P[7HSK7ITK+FU++GU[KMW\\W_Z^45]?DI_@<W`@T]````````````````````````"
"````````````````````_04UXMD*P9+&KTR*KB]YKBIWJAEMJ!MKJ#=ZJ4^-I$>("
"K7:RNIW7QK?SRKW[OZ;EP*CFPJGGP:?FPZWKPJ?FOIK9Q*GGS+?URJ?FQ:CGS,#]"
"QK#OQ*7DLW*TK6&CLG^_N9G8MI74J'*QFS^#EAMLEB%NF46#KXR`U]D)]/\\O^0,T"
"^0(S^@,S^@(R^P(R^P,S_08V_`LZ`@X^````````````````````````````````"
"````````````````````_PDYZN@8R:C;L5V7K3)ZK3!YJ1]OIQ%EI1!BH1!AGA5E"
"H#]_L8:`OZGEQ++PMY/2LX3#M(+!M87$MXW+MH7$L&VNM7N[PYS:QIK9MG2WMX#!"
"LG*SK6&BIT\"%ICR!J%65IE^?HE:7G#Z#F\")PEAAKEB5NG%6/O:;8[_4E`@X^````"
"````````````````````````````````````````````````````````````````"
"`````````````````````@T]]/@GUL'SMW:LK#9\\JRAUJ!EKIA!DI!!CH1!CG1%A"
"FR!HH522JWBVLH?%JVRLI4Z0I$.%I4>'IDR,ITB)ISE_JT:+N&:HP'&TL$./JCB#"
"J#!\\HQ=LHA-IHB1OH3%WGBQUFA]OF!=LEQ9KEAEKES9WI7*GR\\#Q^0(R`P\\_````"
"````````````````````````````````````````````````````````````````"
"```````````````````````__04TY=\\/Q)W0KU60JB=SJ!=KIA!DHQ!CGQ!BG!)@"
"FA1BFB9MG#M]H$>'H3U`H\"USGR!IGQ9CH!-CH1MHI!]LIRATLDB.O5^CKC>&IQIQ"
"IC!YHB-QH!]NH!YLGRISG\"9PF1YLF2%NF\")OEB)NFU\"+MIG,X>$1_PDY````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````@P\\]/@HU\\?YN(&WJCQ^IQ9LIA9HI!QHH!-CG15B"
"FAIEFRQQF!QGF15DG25MGS!TGRMPGAUHGQ=FH\"!JHR9OIR]WLTR0P&:HKSV)IBEV"
"ICY`H2YUH3%WH#)XH3^!GCA[FB=PF2-OF\"1PF#Q]IWNPS</U]/PL`PX^````````"
"````````````````````````````````````````````````````````````````"
"```````````````````````````__P@X[.T=SKCJLW*IIS1YIB!OI2=PH!9FG11C"
"FQUGG3-VF2)JF!1DFAIGFR)JG!]GG!9CG19CH\"-JHRUSIS5[LTV0P&:HKCV)I2MW"
"HS-XGR5OGR]TH#A[HD:&GSY`FBMSEQ]MEC-VH6VCPK+CZ.P<_PHZ````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````P\\__04UZ>D9S+3FLG.JI35YHQULH1AHG19E"
"FQ5CFB)JF!AFEQ)DF!-DF!)BF1%?FA!>FQ)@G1EDH\"!II\"MSL4>,OE^BK3F%HQ]O"
"H25OGAEIG!UJG\"IQGCI\\FC-XE\")MD2QPFV6;NZG;X>03^P4U`P\\_````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````P\\__08VZ^P<S;KLKW:JH3)UH!MJG1MI"
"F1%BEQ!BEA!CEA)EEQEHF!=EF!)AF!!>F1!=FQ%>G1%AHB%MKD&&NEF<JSV&H2!N"
"H2UTG1]KFQIIF2)KE25MD1UJCB]PF&:;MJ;8W=\\/^0(R`P\\_````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````P\\__@@X[O,BT,/SKH\"SG$)^EQAF"
"ERQPE!IGE!)FEQAJF1]NF1QJF!1DEQ%?F!!=F1%=G!1AH!UKIS)[KDB-J$.(GR=Q"
"GB=OF2%KF\"ANEC9VCB]PBT%[F76HNK'AW^03^0(R`@X^````````````````````"
"````````````````````````````````````````````````````````````````"
"``````````````````````````````````````````\\__`L[]/PKVM<&M9O-GFN@"
"EU:/BBUOC!=GE25RFS%ZFRIUEQIJE1-BE1ICER!EF1YFFQAGGR%PHC%[H#5\\FB)O"
"F2=OD2)JBS!QB$5^BER1H8Z`R,;WZ?$A^`<W`P\\_````````````````````````"
"````````````````````````````````````````````````````````````````"
"`````````````````````````````````````````````````@X^_08V[O0DT<__"
"IYC)D'.EB%N1B$>\"D$*\"DC=[CB)MC!MGCBUOD3AVD3-SD\"-KEB]UGD:'G$N*CR]T"
"ARYP@4)[@UV0C7JKKJO;V-\\.]/XN_`P\\`P\\_````````````````````````````"
"````````````````````````````````````````````````````````````````"
"``````````````````````````````````````````````````````\\_`@X^_@DX"
"\\OPJW.,1PL3UHIW.BG>J?UZ2?E2*?T^%?4I`>T9\\>T-Z?D1\\A$Z%BER2AF28@F>:"
"AW:HGYK+OL'PVN(0\\/LJ_@DY`P\\_````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"`P\\^`0P\\_@DY\\_XNV^03P<7TL[3DJJK:G)K)CHNYB8:RC(BUF);$KK#?P,;UT=@'"
"Z?(A]`,R_0DX`0P\\`P\\^````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"";
for this image processing demo. Specifically it was derived from the following image,
and the actual 64x64 character encoded image (only for illustration purposes) is like this one.
In reality the original RGB image was encoded, formally speaking, using “characters” using the following macro,
#define HEADER_PIXEL(data,pixel) {\
pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
data += 4; \
}
So in order to recover it from this encoding scheme of “characters” performed by the macro, the reverse operation needs to be performed. Nevertheless, the “gray scale image” will be used in the pictures (derived from the GIMP RGB image exported as a .header file as an character encoded image) without loosing any accuracy of the description of these processes.
The setup used in this image processing demo is shown in the following diagram,
The application C++ program that resides on the x86 host will communicate with the internal finite state machine inside the FPGA via the 4 wire SPI interface and will coordinate different types of image processing transformations which are performed inside the FPGA and sent back to the x86 host. The first step in this demo is to send this image (generated in GIMP to be described later in the next article) to the FPGA and read it back without any type of transformation on the image itself as shown below. This is a real demo, and after implementing an image transmission via the 4 wire SPI interface and reading it back from the internal finite state machine (in this case without any modification on the image) implemented in Verilog HDL inside the FPGA. The following images illustrated in the next picture, are actual images used in this demo,
The image was sent and read back successfully in this initial demo of the image processing series in the Lattice ICE40 FPGA UltraPlus Breakout Board. In the next article in this series we will be describing how to do this in more detail and cover more image processing transformations for this image later. The Lattice ICE40 FPGA UltraPlus Breakout Board is an excellent, low cost, but powerful enough to even tackle image processing applications and is available at DigiKey.
Have a wonderful day!
This article is available in spanish here.
Este artículo está disponible en español aquí.




