Lattice ICE40 UltraPlus FPGA (Procesamiento de Imágenes Demo Parte 1)

Esta es una series de artículos relacionados a una demonstración que realiza un procesamiento de imágen clásico en la plataforma Lattice ICE40 UltraPlus FPGA. El sistema usado en este demo es el Lattice ICE40 FPGA UltraPlus Breakout Board.

image

Estaremos usando una imágen codificada con caracteres para este demo. Estos caracteres se usan para comunicarse por la interfaz 4 wire SPI. La imágen fue exportada desde el programa GIMP como un archivo (header de C) en este caso cup.h generado desde la imagen original RGB reducida en resolución (para conservar memoria), y fue integrada a un programa C++ en la computadora x86 con Linux como sigue,

/*  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\\^````````````````````````````````````````````"
	"````````````````````````````````````````````````````````````````"
	"";

para esta demonstración de procesamiento de imágines. Especificamente fue derivada de la siguiente imágen,

y la imágen actual de 64x64 de resolución codificada con caracters (solo para propósitos de ilustración) es como la siguiente,

En realidad, la imágen original RGB fue codificada, formalmente hablando, usando caracteres que representan la imágen usando el siguiente 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; \
}

Para recobrar la imágen original en este esquema de codificación de caracteres realizado por el
macro, la operación en reversa se usa para ontener la imágen original. No obstante, la imágen el escala de grises se usa en estos artículos (derivado de la imágen GIMP RGB exportado como archivo header) sin perder la descripción real de estos procesos.

El siguiente esquema fue usado en este demo de procesamiento de imágenes. El mismo está ilustrado en el siguiente diagrama,

La aplicación en C++ que reside en la computadora x86 se comunica con la máquina de estados finitos interna en el FPGA via el interfaz 4 wire SPI y coordina los diferentes tipos de procesamiento de imágenes y las transformaciones que se realizan dentro del FPGA y luego enviadas hacia la computadora x86. El primer paso de este demo es enviar esta imagen (generada por GIMP descrita en el próximo artículo) a el FPGA y se lee sin ningun tipo de transformación en la imagen mostrada luego. Esto es un demo real, y luego de implementar la transmisión via el interfaz 4 wire SPI y leyendola de la máquina de estados finitos interna (en este caso sin niguna modificación de la imagen) implementada en Verilog HDL dentro del FPGA. Las siguientes imágenes ilustradas en la próxima ilustración, son las que están actualmente en el demo,

La imagen fue enviada y leida exitosamente en este demo inicial de de la serie procesamiento de imágenes en la plataforma Lattice ICE40 FPGA UltraPlus Breakout Board. En el próximo artículo de esta series, se estará describiendo mas detalles de como realizar mas transformadas a esta imagen luego. La plataforma Lattice ICE40 FPGA UltraPlus Breakout Board es una excelente, de bajo costo, pero sumamente poderosa para realizar hasta procesamiento de imágenes y está disponible en DigiKey.

Que tenga un buen día.

Este artculo está disponible en inglés.

This article is available in english.

1 Like