From b76226a6632988d213c6fa01b1ba50312e51ce8d Mon Sep 17 00:00:00 2001 From: Peter Lemmens
a07d@TGBEOW@QS^WtB#HCrgLLs>`N zN#2lROUJ=5(^+N4Z^iV(XbC(e@ziENrsd7UN7FxaY#1~oj8x5$us4?$`9fJgHIf#E zcn6k%+LscnSd7XuW;b(%q1c{VnB?$+Sa+Ak(SvaY!`GsR_WWVf#CTznC_zzuKpke| z*^YFO!wp5QS-a7+*Xaw^l;*E#^e- dYQ}ovf348j^R+i{u zxz>}jO0BPkmY8ch(#=JAta{_8?!?bymICSKpB9&dSpnRN&go~fOqd-hzQ~WT;u8A5 z`tMZNFN&g+RG-9iP7Y54r%d1;fI8o);H1!LUSWmG!S+*Wz;H*>S}rUN_J|u=Of+ME z4Az@nbu{&X@_3NMIUP7@;`oRa8b+M^WDNFRYgw3|@zQ^6afPK7WDMjrkdpcN5%RSy0l0oXawI}y z-705sGAkg?9mP>=8ud_E#FzgA(0V>oSMziUswYTIVy(5`Rje5qhl52iYwwXBJC|D? z>}jtVR<_EGmQ3#0gZ2XAY%y%#VH(x&UFMqAVSLhj%Shk+p_$a0#*WK-NtlE=88Rqz z>kmB{9#3CbK9fnP2bV0p1I`ILW|?>9<^|>}BTT;X^@rhpc{Imo CSQ y4y&nU=*B#d+)EkBF+C}<1$ zm3eSakcZnh8xe;4MK1}lij}nIr6wKTL5y(8C}h-F!MGti@u};lz$O1xerqc+>_xkP zp>R3UwyGg~FyeTf+?96C^EVE+lD#`z<#Dd5PlX8!d6={T&Au!x_pwGs+}I~jL5Fp- znCxf6oRii3?&W5eBZ0@TZjNYYVfSKr$KQE)?=8H)m2=2rNV~Sn8J6yAk8FlWlXO2r zOl})>8YtaE5w{>?KsSQ-+Ugs*6xGzG1T^YJ{J8ry _WS}`1i<}o%+0k1IRKoDi$#zp`DHDU3@FUyyNr zaua2qT15ATVRXJhgX85Rk^HfBLD!(XHL-(5F*){iYf*XC0XT?qyg!sKPS2S<>sYjP zP3z846iI%3x_{9YRiEBr+Kvl&ws&0s5m}{Zkx7=KQi`*T?kHU}zJ47xSN;AIxyE!T zuZix}@B<=-VB+G z&R~h{QOdQs)$ON!EzSz2=lPx2ZQL#4Z4l;^ zj&E{ZTW^{OyMS?GYy86MMSS)2&_#mZIvo-<<@kPd(JG1Zih^uQ*^N|;K|gK9aXc&^ z*Ka&I zuu)b4wh(kx#z4v p9bi1Z**C#zI 8T2J2s{-go&BX`mtedZa$K&EWhTr!;crMJRnEZf7x%U-HyZFgP zcVM3 CQ{Z?PmCC*|FT|=Q_E=Ah8y`M^BMs@_&u_yZ8N#B5HZ+Az6nQmYi0_ zm-lApUpx~#&&T%8(^y@m9sxqCs!yBF*^5^y@-q}1U2GeS^lc0L3)eYJQ^Tf|Ys5mS zz!QotS1=Kj7rpe_191yilc5c@oXBdwtz6N@GAUK)NVlvL5*;O(m-vtwA(Becf{a)f zy8SCo6yU|n?(tSXBQrM&>g`Ur{%un8aV}YANc?S)Uf+}nzn~!Mns?xv5bK=HklvpS z_I3C|$_Mvn{L2SRT^`x0*^dkynCj2dKoi`l054$|#BNCF71C|2L?8!ifArAX=M?GO zB+XR=42#amp5FJnK9ybssjj?L>4YmD5=q@>k%d{s<$dyx;c>Ix#-ot(n)xtYRjXEk z;|llJ7%lihoGUig$PFn3STaJPP_Q9xt4zbd+Y3r;(#-8ueixh99yq$(ZUoDbK-xuu zi6c=yftF{tzIQ^aWN@t4(To7co08>)T!L|8O|Bt{AU#LY@8hTzSWi!1zC9aK9_7n& z#u-~sZisol!^cyi`ex0RRZ;3H@ TC;$anPN;nFp=sG@DqizI{lEj@4(X2yp@|}y52Wg zsA)UmfVkXcY5WW)6 geSv%_B z_qIVLVWw qIpfj3 @K?j1I(483~=>KGB~akpIY99zX7DGB8iZ;*bN99;hKSSi2?C4k|{ zH*qp-jd|X SBK9aEOlar{yvF8@Qh041y)HTRA<*|Ggy2-V#K!(Z2(g~_vmX+E} zc02Z6eBrM!i9OE7wRT>hsNaPE=BNIxT%sgGV({&P-;yY+ZTgM}xw>%(a=jy32Lhpy z-}#`|H#CrHy0>hi3PqKIYP0{tX5M$=h7x6!k8SFupL=KI)H`U6S{#;giKp+j-nhDd z3~On;T-ROSlt@jk2C@n7i*S?!78k&EZjbosoP$+zAFH3^GQUb$^n@8Uysn(@ip;H( zX29Y<=Fk*71&e=$QPVM5?M|hLm}#XjGQgbWVbm21UD_L6i8q99_AIn{LJ7Q4+p;Us zKxH-^+VeDHXnQPl`o@jGn}c^AdAy(EUt?o-r E@cY13~;nXWtd4mYj;xSKTLN zR^oSd7C}rDcr0d_j*ce%gzJ+HCuWRBBoowFLa~zI)}_FTGN7tB6z)6uNI*hD^V8iP z^!fzCU@iIiAVpK`sWoi+=40^5#w+`^`uq$t$|rv)KlEe)?tM37P%q{B7O91wXyo-* z=#GymT1O-a5S<35pX`&C>V%-EeK>QMWNqMy=*@`Y9)n%HdcqJddwp{Cdd@fZV6lyO zy^0$zgf5|G?`2l@SQ8B1{W_;(K~076Q37Ejrmtswk4Jh;%~JwK!dHFs8*Tv7uJucB zYDT(_WfSlM9 7fZ?_B*yc7)G?{G7v;CfFB aD$B@=-} z=!Ov!O*vw-X6n>L6fzK9v?@NV-%5I<@3YR9k|3~_k=bf}p_&U?GogPtoolONq@8qF z(lx)FAkWAgNlYWqKI{aDFQ1BhQZ ?Vn&* z1?SZY9VGl38NAJ(*;0H#HRmBIZ)$4h5$X&{RgLiIW1yue-e5l72JNZ6MuF>h;dM37 zo>mN2(^tbaf^9MeeC*YTuC 2NE?*;>%R)ck)J18ItJCJPxn#{NTSM{v;dzhzn_+3)@AAP-+qZ|A?$`!xZvUSpB zq?W8;3l%opf )v*# _d~5pjy7MXs$QBkpMZ_(T z7kzLfs=$G%f4lmXAmInMeB wx zu?il*yo}8L Mq-oBe1*0AqKz`1;R|>(FPYgU7L3Y{TG43qD2nF>KQrhp_ZU?5 Z^b?~}a&SH^GG|c*k<%BNrIR^uO$hSniW dwtyNQU=Kbrg3JQ=9{?tr?$zMBMbXjwZ#siSNjYA=s~q2*r5Y&cNR`dxrpzM yq4Cie1NKi338LTj5OEImF&!7cJLz zKhO=0_s3k=g2uNS0vBP%C{J@icwNep6}NrwvV4^SOmeq(_liLLtV)IL4mEn(9^38> zNra$GJNCR^3EPk=m7;~?&C%(_RKs*5@%KcJPBME2V{0>uNGKt2@~0a#aJIMgUe9Kd z9>-|c;XWB_P5xI&v=Yk)kKwiF>jvl)GibXp;^TymTVOG9V0gE27)M_H?@Tl(3x3?? z;sS<)$3){3%DCS`b7!oq`iH$i=oM>DkFP(SvC?%h5mL9#M^&=GMKvf h zwRH_ECpm2^6;zhWtGm~nkLhF9)(n)rTl2^#PeYslIvJWUvIgs&4;&^mm-D2v=hRU( zRX1+k8jmgk(WjcTD2f#QfIV%kt1_xxk6i~cD&w@oEst#8Tx5aHfWBItlxK}!{+)IA zyLsbJ_&XeMs@SoXM;1P4q^jwBezPbtR;KPjvhy?3mWhpq@j!k}-{b)=|7afXvX_4g zG+D*sY@b_e>OXfbi<|M(o@;Dw65cbk PtO)&V>^WC0B5q6YiOjh&!EU zi%RkaDWiK^YOVX4Dwch|Vf_F@PFuRmW$P_Ck?J~TfA}=QPMa53>HQ1> Q>K%Mk~uJb0hv&-M6LVar1FGheT9(WWDslBty5h4@SLoESDtD~6@tD2!7 zzP~K__-#mz_tAUJm6^#L!xiUC4IZerIGrjAlZ2ZRKAUkpO<$l Y%9mNG##m* zIYOk>*tn-6V4_L}r%&L=2&C{nwo#05794N4_WR`CLaF0wI2Vc6tn6Y 94x=%UR*SqySws2JfqC KOc!Z_ 5-vvI)lIFXOJI{du{e1by+le8tFlNQth^a0l014>EBjm z$W4Dbc_9o%muR(g>KdtZzTRDW3I)v`Q>JmwIfyZmi#y%f7ahw^E35kyYG~+>;&A%J zm^oT2J=d1t4(-W|qi-)mgTMq+ w$;853gYnxIdU{*zB7kIj&c ziVFkDv;0ox$F3+*>WZuHKpj8#1hy$O2NtnvLW`K{y~_ps054`+m!GMe5|T2=D4AvK zPddtK#)X^TbxI#gt&z^%8M7RYpc!FVn)JB{mfyb?^qqBFfViJeti@}XqeOCMeLBRU zndQLyS3xgRJSH_yce!=Cxrl$_@zeaiKi`g+5QmzA!mbZLv0?-Ue!OcFiJ$t7{>zw~ z)I&VRNl{lI(o}l|l~P`rzB#WpDRLs}SMw60Eb~Lx&08Kjiwv&eBJv?4xsx42NYb)d zRkD7#aM%?iXY40ujR1h)fhA{rBPBPY7G8QT69$2`vWfZnruZY63CifC qAO@ zD|Gln3iy{UTYWxpQS7n}PQDI?y7#z`CugUmcoX{9p6e9XNx&0e4R)*}h9KfKflhwo zGeR%9KWp%37_b28O=Bvb=McCUDSP$z&?KNWn|i|U5%C$J%5;waRE^C8n#O+p|7k^| zTY84S`r cF00fW*GYvnNxv44gFAG!Cq%iJAQ*>1#TGGKX zIGz`%0upk?&J8yCi?+Z^{fA~lDYF>tUpO-ZR%#H3Fgi$$75T6JE{n*&$NB$<-}S=( z{%`&mtKeVbE^O2wH4#)07u&z|T-Z2~{(a^E`olA1!$kTwP6AZQru9ds;fbx}FX4t# ze&>IACl=)WKR`c_z95s{A8^Hg!Y 0g`2)-N-!cPQ5hS7dWBq@RMPOiv{#W3IvcLhIVv&G2h0y;J{Ld8rGmH;xAOj&1 z@juoYZ)|2?!NS0VzF-yqDOAM<1LJ7sWNT&V=FZ`2VfA;cf2ZnMh!pOK9YiL~^q05) zjD+$(J212ypeZ5tzf%84$CLvkAwmEOVnxRI*W~}xU c1Ey`-j144$x0ls{f-+ zEkX*1%K2iN;V(~rx>B5=AU3l9BIn5oQeYzk6^J0x{hj$g4&eUnh4CNWsyIPdqWq$N ylGP*QE9dfZR@Ki51B3bxA$YErg?0CN!Bqa2Wd#L^lEPI9fpSF|5y?dU=>0zw;(4tA delta 9886 zcmb7qWmH_tvhd&@28Uq5-GjRmG`PFl;4Tv&xCI8+0KqLV!Gi~PcL)+JXn?`tOU}9X ze&@dR{=8bdcUSi=>8@V8rMgywhJCQ!Dj^`^0|2N1fMck85|-kN- zp?>9T?P)IL Z)k2Q0E0U_dxqPn4_l |gC!3Gwpa z+?+PqhUTDrvxJO_s_)2OE31JYgVtOh{YWl~bU!dlxoyv>skYMq;UbbU)_m2r$Inx* zZ()g!IjTi~EGlGsOesp1$t((W`ODU~V@I&~bj2x|66!g8R^&PGtRx;D(504lLwxPa zcs+{}MRYo;OO4lb)f{1L-_X_r;*TmFm)9?O1Fny!0DZ5s$PbwV?%G*oRt2~@tYYiN z$5quh9F}}e?b-)@3Is1e8(U|Mk1IbL!j85Drh(auWYrwm#cRGh^|vp(E%10 WnU0mbgtw~uFEQ;rE8;?IMDc_w+rgfg3I-+YxD8#O@*8tD~^ zqK!RTO-ZG7i*m4K|7e3OeHW?@E#%|1W>3A3>bq5sg|Dny9T3UjvCQSC!{L=SJkEon zhuYd}4DKnxuhK+vbfFmKR#|#?KB(RjUdo9i*3dA6)5y(tZ*0aAaS1200!62lK{WO7 zrZRdO_vQViv{pjbKqX-MVIA68TSLA3hws?R6Nbtmo2L2lJm*RITcii2%f9>FEN7k6 z-wXVex6$;ZDuXrox-p$GGw?*s5oAgDrZX_#$|3{6a{(>A^0OP7#YG1d^4*#fNqOR& zN!;tyg0L-SS4+J^I9s^Uq{z?4Hx;fIpFU1V?~!nRD8sF&>vfxm#+bGG8s?szQ2BXX zwV0N6ookF9ae}X(3r{fSv$vUufoB;9Ild4PE*+sr49T8zS{dBnI~~=*wy&Nz#1$ ehZ+={uSwSG*t?#;uI z0=J-ruO)CGI*fGO!Z0dQl;vu}U;zBouD+q#QmA9Q5@}21Tq9|6Svpa*0%wbmUP5T# zYHlDIyZy?b;E>AaPtIo6UAwFd*J-UAt6o0zZ>1QL6|;lci=Z{GODJAQZctDG?UOzc zwe40Maj7g;zp_Q^Ou5$F3(c?sO*EfmFk6(2wkdHf=)HVCHUE!hR|(8FJ-Ub{_N~GU z?)^ P&)JOc#=g^H zem{{+kxJfCU#*{XIr7+7-gvQ*U_i6pX#xVny;VX%eb+_q9fSk`@Y4VQf6x4=sHlHt ze#kl+IoQzHWlI1*Xu}kzPGe5&6V=-iXCcoycplBvMyNys)F7T3Lj0M&j;B#`|LLv) zFF7I&2${^q9#djEZ{IV@4+wJByn`i%pW0)8;FfW1v!R%GeEIE#8%|!M<8_hG-J9dY zi;eZ Y73=$VS)HX`trlvE62WN!9*I;(8g3I6ml a!)UcK1gXjG0?E({Ji2;_ z=DbW&H)uxnA7XyvoIVp03(%mog%{CBZJl^;S16!hX8lz+fclEa!L|NXl(1jIjT6{S zAddG|2ult@I^n=w38>;Sl(K|Q+HhgD5xaoNGmU~*_k4i&U1BXfVPJft|B)rAs_)c# z_1GYP6u2Pv>WCUz5)DdSyd4a1T7XGNEb8|&2EXM&f16}iSNH>`3M-ry61Za IInt@B&5%Tzv$I~AUs=0KcdKuV1`S#IDtm5Q)g%VD( zrR=|%=_l;zw2&bo0in_}yT1_*?^-0|(h;gj($i6H3-@pa7K?Gz*m@5af1$5Ikx-vi zK$mI*+N@{2OWvcSRWCNt{36Wm3L6x-to)Y2v_YQQY@jS>!eAtZLPeChHwd1h$@wBH zC$4LAHl^H>rjGJ1lnJSul>~^rQ%&Pv#L>=}QcdCd!njSnNxm?C0T*{^=1Rf|{ewF# zIv-DJj+X${Ij8h<%qHYr?Wn2PT%Q=0>v)Dpu)ix#qM{c!WR3Hp|61^3XNs)wK-nqJ za;s(7|C{R2zW)M2%e+A8b`rR)HE--xRSnwF@Uc!wU-shbh@$@&k2jj{s%oSPxWd23 zilybfomS>)Kb6;?tj?FJrYyFLUv0M$ 4yD!sEaL@~(o>ie^Pt z2sIJZN>$7X{7(uj!%7_vl1KF#XJgB^XEg!l*rz8bxp|GIre7T!4N#Oa%!*3u%x6~x znAttSST%B@0h0kPOs>vyJdS(m?f#;CK;5lxu-n?W<}UBRg*?2&WobH-XeUDIpRL?_ zmg#0=QlH1|CYvIQVyD25lO?V(-$Ig?%j$QiL&DZ&uWg4YF=WFU2dJ!9`#mxCx15B! zq_-Ik<_bEkLBc*wMcu~W{FfI94G+7B7iu#PU&VZX`dKhpeW*Ny4Cv@uhv|8r#(2hS zA_)<}FL>JkEcdm42-l7B=X>~St;k`vaWop}GAssEWtc&WKT3ih{3@}S=!TVEC7upC zXr;cwHlWM4O6Ws_hX*r2)yo$?c? a>FCG3e_89_RHQ6&PO=$4 zOtKjuf^-?MW=gurzlhqjVC+nE)Z->#%#LooNF%%0&9Fj6wL9F!Ci{J=vC9QNB+{ps zEh&*8Ntl0)?E?nbK#Adte3+8(At&Vthv}E}5z2=4uj|W3ZQ+>LV`=pKbgEzOLK;_D zM#*bd*z8DagPM)iR#rFbH$q|i1FIriox-!*M9$bZ-I*|d*|szl5H}qxW9vw?)5*D$ zBIe$QBGUhysOgu;iz`JA(4ilhgEgC=>QiK3PDilV=oT+nQ;^c;T(LYYF?9Uwr_}Rb zPbXit_*D2)nfLm!@p`9ef5XOWY f|(hH}YufIeRO-Y`| sd>G zI33j*Bolb}9U(2MFtpha`(x677&uod*E7`dC|YkLEKTZ#h3c`gwfPu2s2<|C$4Zh! zd}Y51HJ>Df$vI&D5ceb?U!|H#&usB_Hubs}1+($l)YZ+@@FKn|=3+PC&!ip*e)odG z^I5<{vSAv%{m4mMjmd|9tA=66kki{hn|KU2uG(L)-!Z`V`aJyWnDb7MkA7OKZf2`t z+TE{5XI=-WmAdgt*n0k4S>lK$wmbpSX=?Ea%%wuzrzy+J{F;l~wAas{2rNA?c>7#` z!TkJtO-4aYvtHZwL;(Ok^8I^_{@3YD4n8>RMwA!;5G95L;!1*v5#Pv2YWe0Iuc7H_ z>Mo<4WoPFep}l7_M^V?&4}DemN)Nvw)T_3v0p?LYGP z-=JEV+Ikv=9`hX@mE8#*4UG!TN{t@P%y?2!L}&7Pp%m!Cz8SIiyffzKG2TvFITr)> z?#00yN`UXO#3uk`hKU!v8~BM;s5q<3+|mI{70PT7T?4|Tw&5*XMrEbXblrR5X=K~a zW`iDC;+&FoLt#`{qpd{i2vX!KNQ}e)t*lhI%zbwvB;m1JcBAhNHqxp7QZmGPwv};d z^`g93M-_Iqo8+ajg5{%Yln7nIhp*^Fkmz4h(9iO2e{}wN<~a-wp`5@8^gAR~Jmnfm zqi=G_I*<67b)~;5?A;Z(DtaGYW}Q@9n&W%lE42`(++SYtQ45w7wwNNTd6ZQDn(`sA zX@8F7aTaC6Z%=pp(}HP&m450iWp&j^77pE7dkejH)Mc5N&zl!&+0W-MtxvY%U|5c$ zElS9BNl&~0_;EQf`d+xaosLoK3C;LR_Koa`2?Z__M?TpF!itvy+RIe}cjUqk{;RXt zy{L`PtZdrx1vC!Jaytpw!u4Ro;^BQ?fgoc#VH-{?9)3P( AsCE)48UsjW4 z&QN)FPTkLBm!_CoGXrH|B(UO(-%$qf%zSo)q!W5;Cz1rX=RlW91)8MfQW|jRb289t zJmO6jpDjEZ=mpgpOeb1<-H(LpvJ#R^wvg Elj{nciRi3@l2E8g`VYh=$++)Ltgrn98+dGYDOQq!P{3#Ch*nZYy?$cWw zBVU#|4ABT2$}#ZlsILEmrofExWLUfL>Z<<(OBW>=J_{AV6@@Q>NsR;yQ-J%H6Q818 zJDp@y^-|kWm>sCGv%s9K>{O5ra8dW<`!@D6pvXu;eO6Hgvqqw;cv~Tn>{4S~PEqqK zh={Oyt@GX&I?fOPy6Nu(CEZ(h<^}qv2iF%-fj~D)>x^otjMqn%JzIoq0d&1 g>e|oTy`oa>>=k;(egXSUgxPt~w%!n0^ z1_>Mea%$AkqGauk=ch$@ka9*U&Dl$~B;#fyEl*gMyhat9eACOV1i6-~!tn3(e0dx$ zWM lz0_v>t2ESYv1>}OtDiEv|BpW^8vme9$H7)*xxQWby0|E9E0~d z9}1bBlLIyr;tiSo?D5b{*~GuYhJT%Zo%Ry8Qhy}%u3h~+htK2TrhNZnO#G;9Ix>=n zG~r?L!|g5W-6nbDN<{y6Oe%S8dj76}CzBsI)Zvimm(`gPKK87wFS+ %xk~ zwlHP~%DUSl#&!>S(!5Ef#}vYAAEaqdr=C8BbXMCyQziDemKQ@nqJ9D~0+#EJFj94C z;fREORP|u{ZjuUG{&e$z)r=c79w*Y`J_g0iFesto1Ihc#OM4i3q_PUzI0snNc<{p~ zHPmoH&34Sfo>HeD1Me{?&fCTG1zh!7FGwX%-<6%oszS_EL?8U1g*$eF;#690tvUHA zv?YRI+K>E_S~r|URR;cZtZFcr?|u`nOt4ngV|%(lHN$C_giB<_S^3QnwKtnGA7D@} zu!yx1+aW*p^P)*01#GY2Ocb2^mO!jkP3mp2(E@}p>BL4~1u~fJ>9@AgxEG(9Pg=_> zryOl xpw*E(Z6kC;2wPu(w`_{|e*h z6b(>sYQ{9Cal_y&JtTomu5;_5&@w#47;Cf>%yF>jwdgnnCKryXzAa`@!=uyWv2+$D z{t3gULmV_*V`#rh+!KZw!Is_*T*J+7(V(PUN(?O)dwe9i8#q+q!3k~(@mqLdrM`Pa zqAG^(>y(o)>s(2|S&&idoSY??Cxv`|(iUh`{gNgZ>p0vt0-Ds?U{G)sXFpvj?PGn@ zo`0DxIFrr>R@pQFwK;CZo@{{Had@pAbi@hYA1 Y8#;? zR#=9%i~|7}BzYvN9JWBO+ #K4q~*pfn9Vd0n`eRy%Y zG~v>C0N>065hO7GApSqykv$%}mx;vIh!i`W1rb^VIc<`~DLXv`!?e{udn2TDu5Y8U z+q&X+%sM@#)@ybeo%@N&>b2O _+ThZ} z<#zpg1&p+)^t>&G`7v#qs`?dp=z3Hx#)H}2>Ef=|A7^UPx_hD18uG$vH%qWj=v7|+ zi853 uLZv62s5>XKq4NNxV){oOL;QL%cSCZ;MUXR!Tw zI4PT$^GkAu{rP~Sl@gH7A=2vIAuK8wv@Fyz=Tx_9LS1ln#jOSsL lQX}@7E`f5M(iM4cbETtv zQt#Bk#hY*H?9|N2BP9Oe>rFW!hv4j-S7OYV307DF0ewb>$9MC|Xup2CVLD?JW&gnJ ziySkNJj^#2ls<(UApux?&VhS1pKU|k U=i{U zXQbCon 8TBzrGzKli~tPjDjn|IrcU+b%TkEj9Z#$Ju49X->8w7){cKCIjOh#p=KYf z(s{xliwwI?A$oe}Rps`!q23S!)`qEOw^|1)-8V9|zAY}Jb7R--H18k7HRQyZIO?nD zjJgfTFpuw@89cbwK+KX?_^fbL4KitX44rsbT^hlop+?BugrLuZ#K1c9CxT998v98? z;Dm>7#j!g(%kcwPnDvDb!a-|kBrq1dk#w2XDKwui)NPJh^IADKx5MvN_kW7lESun5 z^{*UYWrJ;$vj`-8o=7%aO6=0dd%MUPK7 jMc-%dO=HVQJb(=Qhtd_z-l+QXbCLfjL^wpl+Tt?cZyB8>N^gL>I&_dMhPGkCUX zZE3EA@eeUdSF?RAB$(Kh}IjH;#y?5Pkdj!S5?c&$$R za~^ZrFrU_ajd9d5;PY!!T{VK!tZM3B`N(m1J`Kbinf_{jS=sZ p(TS^T^kRM@ za$&a5^MhJhhdta2Lqo0APv$DOEHIYcjss@M{NU@Ik=xQ}v`${;$WOlaHZpCoj4*w6 z `jeYA$}C_DQnR4 qLKZ*UUS5MX>wQW7Ur zoQU5cSK(+ZNx(0J=IC|eda8M2#QGZi=I|o`V&rgzj=2SOmG;nH>XVy7q@*9saZ@#A z3?v#D1JfR?Fk&K4>9r3m_3&G)=Npn*xH}=VOTw`HIhFzjUJ%)Q8qE$nc2RptAk#NJ zz<#)R3&9d>>~&mx2FEHE5lyI2uGfp5+O+^3Hlz aC<`h6^Lx0WXgF#HMQXJ*5obIk4s>Ln{OWb~{?LF$@ zp7lq@)< 4t6HlnImApFr>c$l8 z_gVFt(z6G-n6AZ9L9-s^s$yWcvt|L(azoKB5Fxp5fQ7E(%Cu{+Zy*r*Ve63HrtT<= zRZabBDAd452+sCS{!U*je!&{qel2y8e`aSuKQwR52&Fx3rdFf*&3Zp>X63l4OPN ToiZ2o=LcA=D`T6UFnfLfW&R8v*!*&V0Fn@lqhU&)jqn^+6a%ma9_d1JbpT(h68 zI|3HZEG{IcIBYdtHTIh57x`(qFhkS(c6`l;p_uK}OYyOo@(oxS#PG!PG%l-6-z-gO zLL_g9Eu^k4OwT9r=7hh+x_S2(Hg?V`wUsYs+*!+1RT^n4`PN#H-CEpDYp{L)7nxQm z^Y8WAd*0P9gAW!V`?FwJ%==qG$z{vu;A@Qg!keX>ukrWz?7>`NkB$?h 1j zU2z(Ln$@CVE+%$Gt=>o}kg}%IZ(!z1k=$!94TYblU~b7H=+hZVwhJRcS|$4LbDLbl zPOVs3e01AHK`;2qIsbEq#tr^c_sKW76Hlr&omrWYCqn)D&J5YFYP!%ijJ6G1g5J~L z_C>PnLOEm!=U|q2qxA@b-AJm8pD;94J=`3-G~iVqXsNuZW*;1x)M~xAc!;?!ny4~1 z-4V0sR*;fc@*dWDUJmohv9F!LBY3=@nd#PqIKId&s|WXwlgqNNw)OHUJp8)C;Y1Gn z`1`-4AXmYstLRf;y}zv)a!Lf^v=kOrD5jqb&}c{Wp>V|t8P@x^3UC4ksuQ@(2D)h# zGU_C&k_*Q*t$K;iy6>bmSx7RyiXW_|1b-}MpiJx?O+N0Vt&&0H2ad+fb4leHgge-b zKHlEN1%e09!bebqV_wPoJuUj#n^P%qpIS#83ls^7XC+W3ErFB8H@J|U8k {`|o|I|QHBMp@hAG~2+G%|=CH6sqsc5h%k;P%9o#M`vXLHpy*g zQUnuv=5WuJshbr7%){mssrYi*%*ZovdYH?!vcmKxeDytB&qVj%TV8M vvyN>vi_PbiTRn4+V-(P(%LIq$ z(+bl =0y)o&T?I zDjZZ00S?^%;3uN!|3#<5!GZGcTjv%Itv_^7AZH2cUr399%ir2rgn0f(C=$d;h*AGf zbkaXBu`&M`;6DID002C!Jw5F~wjS)h&Q5QY;NbBA_<(<@ll!M@9pgV-e-JvzvCzv` zf299^Cp!S}+t>aNm%KvVTEEB|8_~l=Qh!G~G%whrnoXtV@Hr5`V z?Cw@J{}%Kw_dWzugcN>>86wV315p-1|BJ2QcNHNEWK)>&KSfm*$XiiDNSw&u7XCvK z!2; %^!C9zoh*sva>=~MX6E#NnynbG2$R& z{%_0uF~jeGu)l!eU-{oz7As_sg9)M}hWVFJ12IyebJpL(;OXaN{l5;vhaRajHaGyF W01*Hn_-|3XkXkVYWOV*Nwf_%4AF8$h diff --git a/code/soda_4source.vhd b/code/soda_4source.vhd index 2b1e536..e74e3da 100644 --- a/code/soda_4source.vhd +++ b/code/soda_4source.vhd @@ -50,6 +50,8 @@ architecture Behavioral of soda_4source is signal soda_cmd_pending_S : std_logic := '0'; signal start_of_superburst_S : std_logic := '0'; signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal soda_reset_S : std_logic; + signal soda_enable_S : std_logic; -- signal soda_40mhz_cycle_S : std_logic := '0'; -- Signals @@ -64,15 +66,22 @@ architecture Behavioral of soda_4source is signal start_calibration_S : t_HUB_BIT_ARRAY := (others => '0'); signal calib_data_valid_S : t_HUB_BIT_ARRAY := (others => '0'); signal calibration_time_S : t_HUB_WORD_ARRAY := (others => (others => '0')); - signal calib_register_s : t_HUB_LWORD_ARRAY := (others => (others => '0')); +-- signal calib_register_s : t_HUB_LWORD_ARRAY := (others => (others => '0')); signal reply_timeout_error_S : t_HUB_BIT_ARRAY := (others => '0'); signal channel_timeout_status_S : t_HUB_BIT_ARRAY := (others => '0'); signal downstream_error_S : t_HUB_BIT_ARRAY := (others => '0'); + signal report_error_S : t_HUB_BIT_ARRAY; + + --signal common_reply_timeout_error_S : std_logic; + signal common_timeout_status_S : std_logic; + signal common_downstream_error_S : std_logic; + signal common_report_error_S : std_logic; signal dead_channel_S : t_HUB_BIT_ARRAY := (others => '0'); - signal CTRL_STATUS_register_S : t_HUB_LWORD_ARRAY := (others => (others => '0')); - + signal COMMON_CTRL_STATUS_register_S: std_logic_vector(31 downto 0); + signal CTRL_STATUS_register_S : t_HUB_LWORD_ARRAY; -- := (others => (others => '0')); + signal TXstart_of_superburst_S : t_HUB_BIT_ARRAY := (others => '0'); signal TXsuper_burst_nr_S : t_HUB_LWORD_ARRAY; -- from super-burst-nr-generator signal TXsoda_cmd_valid_S : t_HUB_BIT_ARRAY; @@ -101,21 +110,21 @@ begin generic map(BURST_COUNT => 16) port map( SODACLK => SODACLK, - RESET => RESET, - --Internal Connection + RESET => soda_reset_S, + ENABLE => soda_enable_S, SODA_BURST_PULSE_IN => SODA_BURST_PULSE_IN, START_OF_SUPERBURST_OUT => start_of_superburst_S, SUPER_BURST_NR_OUT => super_burst_nr_S, SODA_CMD_WINDOW_OUT => soda_cmd_window_S - ); - + ); + channel :for i in c_HUB_CHILDREN-1 downto 0 generate TXsoda_cmd_valid_S(i) <= trb_cmd_strobe_S; --trb_cmd_valid_S; TXsoda_cmd_window_S(i) <= soda_cmd_window_S; TXstart_of_superburst_S(i) <= start_of_superburst_S; TXsoda_cmd_word_S(i) <= '0' & trb_cmd_word_S; - TXsuper_burst_nr_S(i) <= '0' & super_burst_nr_S; + TXsuper_burst_nr_S(i) <= '0' & super_burst_nr_S; start_calibration_S(i) <= send_start_calibration_S(i); @@ -124,151 +133,126 @@ begin SODACLK => SODACLK, RESET => RESET, --Internal Connection - LINK_PHASE_IN => LINK_PHASE_IN(i), --link_phase_S, PL! + LINK_PHASE_IN => LINK_PHASE_IN(i), --link_phase_S, PL! SODA_CYCLE_IN => SODA_CYCLE_IN, - - SODA_CMD_STROBE_IN => TXsoda_cmd_valid_S(i), SODA_CMD_WINDOW_IN => TXsoda_cmd_window_S(i), + SODA_CMD_STROBE_IN => TXsoda_cmd_valid_S(i), START_OF_SUPERBURST => TXstart_of_superburst_S(i), SUPER_BURST_NR_IN => TXsuper_burst_nr_S(i)(30 downto 0), SODA_CMD_WORD_IN => TXsoda_cmd_word_S(i)(30 downto 0), EXPECTED_REPLY_OUT => expected_reply_S(i), - TIME_CAL_OUT => send_start_calibration_S(i), + SEND_TIME_CAL_OUT => send_start_calibration_S(i), TX_DLM_PREVIEW_OUT => TX_DLM_PREVIEW_OUT(i), TX_DLM_OUT => TX_DLM_OUT(i), TX_DLM_WORD_OUT => TX_DLM_WORD_OUT(i) ); - hub_reply_handler : soda_reply_handler - port map( - SODACLK => SODACLK, - RESET => RESET, - CLEAR => '0', - CLK_EN => '1', - --Internal Connection --- LAST_PACKET => last_packet_sent_S, - EXPECTED_REPLY_IN => expected_reply_S(i), - RX_DLM_IN => RX_DLM_IN(i), - RX_DLM_WORD_IN => RX_DLM_WORD_IN(i), - REPLY_VALID_OUT => reply_data_valid_S(i), - REPLY_OK_OUT => reply_OK_S(i) - ); + hub_reply_handler : soda_reply_handler + port map( + SODACLK => SODACLK, + RESET => RESET, + CLEAR => '0', + CLK_EN => '1', + EXPECTED_REPLY_IN => expected_reply_S(i), + RX_DLM_IN => RX_DLM_IN(i), + RX_DLM_WORD_IN => RX_DLM_WORD_IN(i), + REPLY_VALID_OUT => reply_data_valid_S(i), + REPLY_OK_OUT => reply_OK_S(i) + ); - hub_calibration_timer : soda_calibration_timer - port map( - SODACLK => SODACLK, - RESET => RESET, - CLEAR => '0', - CLK_EN => '1', - --Internal Connection - START_CALIBRATION => start_calibration_S(i), - END_CALIBRATION => reply_data_valid_S(i), - VALID_OUT => calib_data_valid_S(i), - CALIB_TIME_OUT => calibration_time_S(i), - TIMEOUT_ERROR => reply_timeout_error_S(i) - ); - - sodahub_calib_timeout_proc : process(SYSCLK) -- converting to sysclk domain - begin - if rising_edge(SYSCLK) then - if( RESET = '1' ) then - calib_register_S(i) <= (others => '0'); - channel_timeout_status_S(i) <= '0'; - downstream_error_S(i) <= '0'; - CTRL_STATUS_register_S(i)(16) <= '0'; -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(17) <= '0'; -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(31) <= '0'; -- reset REPORT_ERROR status-bit - elsif (start_calibration_S(i) = '1') then -- reset registers at start of new calibration - calib_register_S(i) <= (others => '0'); - channel_timeout_status_S(i) <= '0'; - downstream_error_S(i) <= '0'; - CTRL_STATUS_register_S(i)(16) <= '0'; -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(17) <= '0'; -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(31) <= '0'; -- reset REPORT_ERROR status-bit - elsif (calib_data_valid_S(i) = '1') then -- calibration finished in time - calib_register_S(i) <= x"0000" & calibration_time_S(i); - channel_timeout_status_S(i) <= '0'; - elsif (reply_data_valid_S(i) = '1') then -- the reply was correct - channel_timeout_status_S(i) <= '0'; - if (reply_OK_S(i) = '1') then - downstream_error_S(i) <= '0'; - elsif (dead_channel_S(i) = '0') then - downstream_error_S(i) <= '1'; - CTRL_STATUS_register_S(i)(16) <= '1'; -- set DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(31) <= '1'; -- set REPORT_ERROR status-bit + hub_calibration_timer : soda_calibration_timer + port map( + SODACLK => SODACLK, + RESET => soda_reset_S, --RESET, + CLEAR => '0', + CLK_EN => '1', + --Internal Connection + START_CALIBRATION => start_calibration_S(i), + END_CALIBRATION => reply_data_valid_S(i), + VALID_OUT => calib_data_valid_S(i), + CALIB_TIME_OUT => calibration_time_S(i), + TIMEOUT_ERROR => reply_timeout_error_S(i) + ); + + sodahub_calib_timeout_proc : process(SODACLK) + begin + if rising_edge(SODACLK) then + if( RESET = '1' ) then + downstream_error_S(i) <= '0'; + channel_timeout_status_S(i) <= '0'; + report_error_S(i) <= '0'; + elsif (soda_reset_S = '1') then -- check if slowcontrol wants to reset errors + channel_timeout_status_S(i) <= '0'; + downstream_error_S(i) <= '0'; -- set CALIBRATION_TIMEOUT_ERROR status-bit + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + elsif (reply_data_valid_S(i) = '1') then -- the reply was correct + channel_timeout_status_S(i) <= '0'; + if (reply_OK_S(i) = '1') then + downstream_error_S(i) <= '0'; + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + elsif (dead_channel_S(i) = '0') then + downstream_error_S(i) <= '1'; + report_error_S(i) <= '1'; -- set REPORT_ERROR status-bit + else + downstream_error_S(i) <= '1'; + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + end if; + elsif (reply_timeout_error_S(i) = '1') then --and (reply_OK_S(i) = '1')) then + if (dead_channel_S(i) = '0') then + channel_timeout_status_S(i) <= '1'; + report_error_S(i) <= '1'; -- set REPORT_ERROR status-bit + else + channel_timeout_status_S(i) <= '1'; + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + end if; end if; - elsif ((reply_timeout_error_S(i) = '1') and (reply_OK_S(i) = '1')) then - channel_timeout_status_S(i) <= '1'; - CTRL_STATUS_register_S(i)(17) <= '1'; -- set CALIBRATION_TIMEOUT_ERROR status-bit - CTRL_STATUS_register_S(i)(31) <= '1'; -- set REPORT_ERROR status-bit - elsif (CTRL_STATUS_register_S(i)(15) = '1') then -- check if slowcontrol wants to reset errors - CTRL_STATUS_register_S(i)(16) <= '0'; -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(17) <= '0'; -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(31) <= '0'; -- reset REPORT_ERROR status-bit end if; - end if; - end process; + end process; --- hub_store_calib_proc : process(SYSCLK) --- begin --- if rising_edge(SYSCLK) then --- if( RESET = '1' ) then --- calib_register_S(i) <= (others => '0'); --- else --- calib_register_S(i)(15 downto 0) <= calibration_time_S(i); --- end if; --- end if; --- end process; - - ----------------------------------------------------------- - -- Reply status report -- - ----------------------------------------------------------- --- reply_report_proc : process(SYSCLK) --- begin --- if rising_edge(SYSCLK) then --- if( RESET = '1' ) then --- channel_status_S(i) <= '0'; --- elsif (reply_data_valid_S(i)='1') then --- channel_status_S(i) <= reply_OK_S(i) or dead_channels_S(i); --- else --- channel_status_S(i) <= '0'; --- end if; --- end if; --- --- end process; + --------------------------------------------------------- + -- Control bits -- + --------------------------------------------------------- + dead_channel_S(i) <= CTRL_STATUS_register_S(i)(29); -- slow-control can declare a channel dead + --------------------------------------------------------- + -- Status bits -- + --------------------------------------------------------- + CTRL_STATUS_SYNC: signal_sync + generic map( + DEPTH => 1, + WIDTH => 3 + ) + port map( + RESET => RESET, + D_IN(0) => report_error_S(i), + D_IN(1) => downstream_error_S(i), + D_IN(2) => channel_timeout_status_S(i), + CLK0 => SYSCLK, + CLK1 => SODACLK, + D_OUT(0) => CTRL_STATUS_register_S(i)(15), + D_OUT(1) => CTRL_STATUS_register_S(i)(1), + D_OUT(2) => CTRL_STATUS_register_S(i)(0) + ); + + --CTRL_STATUS_register_S(i)(15) <= report_error_S(i); + CTRL_STATUS_register_S(i)(14 downto 2) <= (others => '0'); + --CTRL_STATUS_register_S(i)(1) <= downstream_error_S(i); + --CTRL_STATUS_register_S(i)(0) <= channel_timeout_status_S(i); end generate; ------------------------------------------------------------ --- Reset the unused bits of channel_status_S -- ------------------------------------------------------------ --- other_bits :for j in 31 downto c_HUB_CHILDREN generate --- init_unused_bits_proc : process(SYSCLK) --- begin --- if rising_edge(SYSCLK) then --- if( RESET = '1' ) then --- channel_status_S(j) <= '0'; -- reset status bits --- end if; --- end if; --- end process; --- end generate; - ------------------------------------------------------------ --- Transmission history for reply-checking -- ------------------------------------------------------------ --- packet_history_proc : process(SYSCLK) --- begin --- if rising_edge(SYSCLK) then --- if( RESET = '1' ) then --- last_packet_sent_S <= c_NO_PACKET; --- elsif (start_of_superburst_S='1') then --- last_packet_sent_S <= c_BST_PACKET; --- elsif (trb_cmd_strobe_S='1') then --- last_packet_sent_S <= c_CMD_PACKET; --- end if; --- end if; --- end process; - + soda_reset_S <= (RESET or COMMON_CTRL_STATUS_register_S(31)); + soda_enable_S <= COMMON_CTRL_STATUS_register_S(30); + common_downstream_error_S <= '1' when ((downstream_error_S(0)='1') or (downstream_error_S(1)='1') or (downstream_error_S(2)='1') or (downstream_error_S(3)='1')) + else '0'; + common_report_error_S <= '1' when ((report_error_S(0)='1') or (report_error_S(1)='1') or (report_error_S(2)='1') or (report_error_S(3)='1')) + else '0'; + common_timeout_status_S <= '1' when ((channel_timeout_status_S(0)='1') or (channel_timeout_status_S(1)='1') or (channel_timeout_status_S(2)='1')) or ((channel_timeout_status_S(3)='1')) + else '0'; + COMMON_CTRL_STATUS_register_S(15) <= common_report_error_S; + COMMON_CTRL_STATUS_register_S(14 downto 2) <= (others => '0'); + COMMON_CTRL_STATUS_register_S(1) <= common_downstream_error_S; + COMMON_CTRL_STATUS_register_S(0) <= common_timeout_status_S; + --------------------------------------------------------- -- RegIO Statemachine --------------------------------------------------------- @@ -333,7 +317,7 @@ begin NEXT_STATE <= SLEEP; end case; end process TRANSFORM; - + soda_cmd_strobe_posedge_to_pulse: posedge_to_pulse port map( @@ -343,25 +327,7 @@ soda_cmd_strobe_posedge_to_pulse: posedge_to_pulse SIGNAL_IN => trb_cmd_strobe_S, PULSE_OUT => trb_cmd_strobe_sodaclk_S ); - -SODA_CMD_FLOWCTRL : process(SODACLK) - begin - if( rising_edge(SODACLK) ) then - if( RESET = '1' ) then - trb_cmd_pending_S <= '0'; - trb_send_cmd_S <= '0'; - elsif trb_cmd_strobe_sodaclk_S = '1' then - trb_cmd_pending_S <= '1'; - elsif soda_cmd_window_S = '1' and trb_cmd_pending_S = '1' then - trb_send_cmd_S <= '1'; - trb_cmd_pending_S <= '0'; - else - trb_cmd_pending_S <= '0'; - trb_send_cmd_S <= '0'; - end if; - end if; - end process SODA_CMD_FLOWCTRL; - + --------------------------------------------------------- -- data handling -- --------------------------------------------------------- @@ -371,37 +337,37 @@ SODA_CMD_FLOWCTRL : process(SODACLK) begin if( rising_edge(SYSCLK) ) then if ( RESET = '1' ) then - trb_cmd_strobe_S <= '0'; - trb_cmd_word_S <= (others => '0'); - CTRL_STATUS_register_S(0)(15 downto 0) <= (others => '0'); - CTRL_STATUS_register_S(1)(15 downto 0) <= (others => '0'); - CTRL_STATUS_register_S(2)(15 downto 0) <= (others => '0'); - CTRL_STATUS_register_S(3)(15 downto 0) <= (others => '0'); + trb_cmd_strobe_S <= '0'; + trb_cmd_word_S <= (others => '0'); + COMMON_CTRL_STATUS_register_S(31 downto 16) <= (30 => '1', others => '0'); -- enable soda by default + CTRL_STATUS_register_S(0)(31 downto 16) <= (others => '0'); + CTRL_STATUS_register_S(1)(31 downto 16) <= (others => '0'); + CTRL_STATUS_register_S(2)(31 downto 16) <= (others => '0'); + CTRL_STATUS_register_S(3)(31 downto 16) <= (others => '0'); elsif( (store_wr = '1') and (SODA_ADDR_IN = "0000") ) then trb_cmd_strobe_S <= '1'; trb_cmd_word_S <= SODA_DATA_IN(30 downto 0); - elsif( (store_wr = '1') and (SODA_ADDR_IN = "0001") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(0)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control - elsif( (store_wr = '1') and (SODA_ADDR_IN = "0010") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(1)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control elsif( (store_wr = '1') and (SODA_ADDR_IN = "0011") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(2)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + trb_cmd_strobe_S <= '0'; + COMMON_CTRL_STATUS_register_S(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control elsif( (store_wr = '1') and (SODA_ADDR_IN = "0100") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(3)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(0)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0101") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(1)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0110") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(2)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0111") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(3)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control else - trb_cmd_strobe_S <= '0'; + trb_cmd_strobe_S <= '0'; end if; end if; end process THE_WRITE_REG_PROC; - dead_channel_S(0) <= CTRL_STATUS_register_S(0)(8); -- slow-control can declare a channel dead - dead_channel_S(1) <= CTRL_STATUS_register_S(1)(8); -- slow-control can declare a channel dead - dead_channel_S(2) <= CTRL_STATUS_register_S(2)(8); -- slow-control can declare a channel dead - dead_channel_S(3) <= CTRL_STATUS_register_S(3)(8); -- slow-control can declare a channel dead -- register read THE_READ_REG_PROC: process( SYSCLK ) @@ -413,71 +379,31 @@ SODA_CMD_FLOWCTRL : process(SODACLK) buf_bus_data_out <= '0' & trb_cmd_word_S; elsif( (store_rd = '1') and (SODA_ADDR_IN = "0001") ) then buf_bus_data_out <= '0' & super_burst_nr_S; + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0011") ) then + buf_bus_data_out <= COMMON_CTRL_STATUS_register_S; elsif( (store_rd = '1') and (SODA_ADDR_IN = "0100") ) then - buf_bus_data_out <= calib_register_S(0); + buf_bus_data_out <= CTRL_STATUS_register_S(0); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0101") ) then - buf_bus_data_out <= calib_register_S(1); + buf_bus_data_out <= CTRL_STATUS_register_S(1); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0110") ) then - buf_bus_data_out <= calib_register_S(2); + buf_bus_data_out <= CTRL_STATUS_register_S(2); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0111") ) then - buf_bus_data_out <= calib_register_S(3); + buf_bus_data_out <= CTRL_STATUS_register_S(3); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1000") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(0); + buf_bus_data_out <= x"0000" & calibration_time_S(0); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1001") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(1); + buf_bus_data_out <= x"0000" & calibration_time_S(1); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1010") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(2); + buf_bus_data_out <= x"0000" & calibration_time_S(2); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1011") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(3); + buf_bus_data_out <= x"0000" & calibration_time_S(3); end if; end if; end process THE_READ_REG_PROC; --- buf_bus_data_out <= debug_status_S; --- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0100") ) then --- buf_bus_data_out <= debug_rx_cnt_S; --- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0101") ) then --- buf_bus_data_out <= debug_tx_cnt_S; --- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0110") ) then --- buf_bus_data_out <= debug_sos_cnt_S; --- elsif( (store_rd = '1') and (SODA_ADDR_IN = "0111") ) then --- buf_bus_data_out <= debug_cmd_cnt_S; --- end if; --- end if; --- end process THE_READ_REG_PROC; - --- debug signals - --DEBUG_HUB : process(SODACLK) - --begin - --if( rising_edge(SODACLK) ) then - --debug_status_S(0) <= RESET; - --debug_status_S(1) <= CLEAR; - --debug_status_S(2) <= CLK_EN; - --if ( RESET = '1' ) then - --debug_rx_cnt_S <= (others => '0'); - --debug_tx_cnt_S <= (others => '0'); - --else - --if (txup_dlm_out_S = '1') then - --debug_tx_cnt_S <= debug_tx_cnt_S + 1; - --end if; - --if (RXUP_DLM_IN = '1') then - --debug_rx_cnt_S <= debug_rx_cnt_S + 1; - --end if; - --if (start_of_superburst_S = '1') then - --debug_sos_cnt_S <= debug_sos_cnt_S + 1; - --end if; - --if (soda_cmd_valid_S = '1') then - --debug_cmd_cnt_S <= debug_cmd_cnt_S + 1; - --end if; - --end if; - --end if; - --end process; - --debug_status_S(31 downto 3) <= LINK_DEBUG_IN(31 downto 3); --- TXUP_DLM_OUT <= txup_dlm_out_S; --- output signals LEDS_OUT <= (others => '0'); --LEDregister_i(3 downto 0); SODA_DATA_OUT <= buf_bus_data_out; SODA_ACK_OUT <= bus_ack; -end architecture; +end architecture; \ No newline at end of file diff --git a/code/soda_calibration_timer.vhd b/code/soda_calibration_timer.vhd index 951aa53..bbd46f9 100644 --- a/code/soda_calibration_timer.vhd +++ b/code/soda_calibration_timer.vhd @@ -40,7 +40,7 @@ begin CALIBRATION_RUNNING <= calibration_running_S; - packet_fsm_proc : process(SODACLK)--, RESET, packet_state_S, crc_valid_S, START_OF_SUPERBURST, soda_cmd_strobe_S) + calibration_fsm_proc : process(SODACLK) begin if rising_edge(SODACLK) then if (RESET='1') then diff --git a/code/soda_components.vhd b/code/soda_components.vhd index 515cb6b..df80d96 100644 --- a/code/soda_components.vhd +++ b/code/soda_components.vhd @@ -666,12 +666,12 @@ package soda_components is SCI_READ : in std_logic := '0'; SCI_WRITE : in std_logic := '0'; SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; + SCI_NACK : out std_logic := '0'--; -- Status and control port -- STAT_OP : out t_HUB_WORD; --std_logic_vector (15 downto 0); -- CTRL_OP : in t_HUB_WORD; --std_logic_vector (15 downto 0) := (others => '0'); - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') +-- STAT_DEBUG : out std_logic_vector (63 downto 0); +-- CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0') ); end component; diff --git a/code/soda_hub.vhd b/code/soda_hub.vhd index 7c927cd..6739dba 100644 --- a/code/soda_hub.vhd +++ b/code/soda_hub.vhd @@ -48,12 +48,14 @@ end soda_hub; architecture Behavioral of soda_hub is --SODA + signal soda_reset_S : std_logic; + signal soda_enable_S : std_logic; + signal soda_cmd_word_S : std_logic_vector(30 downto 0) := (others => '0'); signal soda_cmd_valid_S : std_logic := '0'; signal soda_cmd_strobe_S : std_logic := '0'; -- for commands sent in a SODA package signal soda_cmd_strobe_sodaclk_S : std_logic := '0'; -- for commands sent in a SODA package signal trb_cmd_word_S : std_logic_vector(30 downto 0) := (others => '0'); - signal trb_cmd_valid_S : std_logic := '0'; signal trb_cmd_strobe_S : std_logic := '0'; -- for commands sent over trbnet signal trb_cmd_strobe_sodaclk_S : std_logic := '0'; -- for commands sent over trbnet -- signal soda_cmd_pending_S : std_logic := '0'; @@ -67,7 +69,6 @@ architecture Behavioral of soda_hub is type STATES is (SLEEP,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE); signal CURRENT_STATE, NEXT_STATE: STATES; - signal last_packet_sent_S : t_PACKET_TYPE_SENT; signal expected_reply_S : t_HUB_BYTE_ARRAY := (others => (others => '0')); signal reply_data_valid_S : t_HUB_BIT_ARRAY := (others => '0'); signal reply_OK_S : t_HUB_BIT_ARRAY := (others => '0'); @@ -77,15 +78,21 @@ architecture Behavioral of soda_hub is signal stop_calibration_S : t_HUB_BIT_ARRAY := (others => '0'); signal calib_data_valid_S : t_HUB_BIT_ARRAY := (others => '0'); signal calibration_time_S : t_HUB_WORD_ARRAY := (others => (others => '0')); - signal calib_register_s : t_HUB_LWORD_ARRAY := (others => (others => '0')); - signal calib_timeout_error_S : t_HUB_BIT_ARRAY; signal calibration_running_S : t_HUB_BIT_ARRAY; - signal channel_timeout_status_S : t_HUB_BIT_ARRAY; +-- signal calib_register_s : t_HUB_LWORD_ARRAY := (others => (others => '0')); + signal reply_timeout_error_S : t_HUB_BIT_ARRAY := (others => '0'); + signal channel_timeout_status_S : t_HUB_BIT_ARRAY := (others => '0'); + signal downstream_error_S : t_HUB_BIT_ARRAY := (others => '0'); signal report_error_S : t_HUB_BIT_ARRAY; - signal downstream_error_S : t_HUB_BIT_ARRAY; + --signal common_reply_timeout_error_S : std_logic; + signal common_timeout_status_S : std_logic; + signal common_downstream_error_S : std_logic; + signal common_report_error_S : std_logic; + signal dead_channel_S : t_HUB_BIT_ARRAY := (others => '0'); + signal COMMON_CTRL_STATUS_register_S: std_logic_vector(31 downto 0); signal CTRL_STATUS_register_S : t_HUB_LWORD_ARRAY := (others => (others => '0')); signal TXstart_of_superburst_S : t_HUB_BIT_ARRAY; @@ -147,44 +154,26 @@ begin channel :for i in c_HUB_CHILDREN-1 downto 0 generate - --X_clk_domain : process(TX_SODACLK(i)) - --begin - --if rising_edge(TX_SODACLK(i)) then - --if RESET='1' then - --TXsoda_cmd_valid_S(i) <= '0'; - --TXstart_of_superburst_S(i) <= '0'; - --TXsoda_cmd_word_S(i) <= (others => '0'); - --TXsuper_burst_nr_S(i) <= (others => '0'); - --else - -- TXsoda_cmd_valid_S(i) <= soda_cmd_valid_S; - -- TXstart_of_superburst_S(i) <= start_of_superburst_S; - -- TXsoda_cmd_word_S(i) <= '0' & soda_cmd_word_S; - -- TXsuper_burst_nr_S(i) <= '0' & super_burst_nr_S; - --end if; - --end if; - --end process; - - - - start_calibration_S(i) <= send_start_calibration_S(i); + start_calibration_S(i) <= send_start_calibration_S(i); - packet_builder : soda_packet_builder - port map( - SODACLK => SODACLK, - RESET => RESET, - --Internal Connection - LINK_PHASE_IN => UPLINK_PHASE_IN, --link_phase_S, PL! 17092014 vergeten ??? of niet nodig ? - SODA_CYCLE_IN => '1', -- 40MHz cycle is only required to sync superbursts at the source PL! 24022015 - SODA_CMD_STROBE_IN => trb_cmd_strobe_S, --soda_cmd_valid_S, --TXsoda_cmd_valid_S(i), - START_OF_SUPERBURST => start_of_superburst_S, --TXstart_of_superburst_S(i), - SUPER_BURST_NR_IN => super_burst_nr_S, --TXsuper_burst_nr_S(i)(30 downto 0), - SODA_CMD_WORD_IN => trb_cmd_word_S, --soda_cmd_word_S, --TXsoda_cmd_word_S(i)(30 downto 0), - EXPECTED_REPLY_OUT => expected_reply_S(i), - SEND_TIME_CAL_OUT => send_start_calibration_S(i), - TX_DLM_PREVIEW_OUT => TXDN_DLM_PREVIEW_OUT(i), - TX_DLM_OUT => TXDN_DLM_OUT(i), - TX_DLM_WORD_OUT => TXDN_DLM_WORD_OUT(i) - ); + packet_builder : soda_packet_builder + port map( + SODACLK => SODACLK, + RESET => RESET, + --Internal Connection + LINK_PHASE_IN => UPLINK_PHASE_IN, --link_phase_S, PL! 17092014 vergeten ??? of niet nodig ? + SODA_CYCLE_IN => '1', -- 40MHz cycle is only required to sync superbursts at the source PL! 24022015 + SODA_CMD_WINDOW_IN => '1', -- soda-source determines the sending of a command; hub always copies + SODA_CMD_STROBE_IN => trb_cmd_strobe_S, --soda_cmd_valid_S, --TXsoda_cmd_valid_S(i), + START_OF_SUPERBURST => start_of_superburst_S, --TXstart_of_superburst_S(i), + SUPER_BURST_NR_IN => super_burst_nr_S, --TXsuper_burst_nr_S(i)(30 downto 0), + SODA_CMD_WORD_IN => trb_cmd_word_S, --soda_cmd_word_S, --TXsoda_cmd_word_S(i)(30 downto 0), + EXPECTED_REPLY_OUT => expected_reply_S(i), + SEND_TIME_CAL_OUT => send_start_calibration_S(i), + TX_DLM_PREVIEW_OUT => TXDN_DLM_PREVIEW_OUT(i), + TX_DLM_OUT => TXDN_DLM_OUT(i), + TX_DLM_WORD_OUT => TXDN_DLM_WORD_OUT(i) + ); hub_reply_handler : soda_reply_handler port map( @@ -192,8 +181,6 @@ begin RESET => RESET, CLEAR => '0', CLK_EN => '1', - --Internal Connection - -- LAST_PACKET => last_packet_sent_S, EXPECTED_REPLY_IN => expected_reply_S(i), RX_DLM_IN => RXDN_DLM_IN(i), RX_DLM_WORD_IN => RXDN_DLM_WORD_IN(i), @@ -213,62 +200,93 @@ begin CALIBRATION_RUNNING => calibration_running_S(i), VALID_OUT => calib_data_valid_S(i), CALIB_TIME_OUT => calibration_time_S(i), - TIMEOUT_ERROR => calib_timeout_error_S(i) + TIMEOUT_ERROR => reply_timeout_error_S(i) ); - stop_calibration_S(i) <= '1' when ((calibration_running_S(i)='1') and ((reply_data_valid_S(i) = '1') or (calib_timeout_error_S(i)='1'))) else '0'; - channel_timeout_status_S(i) <= '1' when ((calibration_running_S(i)='0') and (calib_timeout_error_S(i)='1')) else '0'; - downstream_error_S(i) <= '1' when ((reply_data_valid_S(i) = '1') and (reply_OK_S(i) = '0')) else '0'; - report_error_S(i) <= '1' when ((dead_channel_S(i) = '0') and ((downstream_error_S(i)='1') or (channel_timeout_status_S(i)='1'))) else '0'; + stop_calibration_S(i) <= '1' when ((calibration_running_S(i)='1') and ((reply_data_valid_S(i) = '1') or (reply_timeout_error_S(i)='1'))) else '0'; +-- channel_timeout_status_S(i) <= '1' when ((calibration_running_S(i)='0') and (reply_timeout_error_S(i)='1')) else '0'; +-- downstream_error_S(i) <= '1' when ((reply_data_valid_S(i) = '1') and (reply_OK_S(i) = '0')) else '0'; +-- report_error_S(i) <= '1' when ((dead_channel_S(i) = '0') and ((downstream_error_S(i)='1') or (channel_timeout_status_S(i)='1'))) else '0'; - sodahub_calib_timeout_proc : process(SYSCLK) -- converting to sysclk domain + sodahub_calib_timeout_proc : process(SODACLK) begin - if rising_edge(SYSCLK) then + if rising_edge(SODACLK) then if( RESET = '1' ) then - CTRL_STATUS_register_S(i)(31 downto 16) <= (others => '0'); -- reset REPORT_ERROR status-bit - calib_register_S(i) <= (others => '0'); -- reset REPORT_ERROR status-bit - else - CTRL_STATUS_register_S(i)(16) <= downstream_error_S(i); -- reset DOWNSTREAM_ERROR status-bit - CTRL_STATUS_register_S(i)(17) <= channel_timeout_status_S(i); -- reset CALIBRATION_TIMEOUT_ERROR status-bit - CTRL_STATUS_register_S(i)(31) <= report_error_S(i); -- reset REPORT_ERROR status-bit - if (reply_data_valid_S(i) = '1') then -- calibration time has ended and there is a reply - calib_register_S(i) <= x"0000" & calibration_time_S(i); -- store the elapsed time + downstream_error_S(i) <= '0'; + channel_timeout_status_S(i) <= '0'; + report_error_S(i) <= '0'; + elsif (soda_reset_S = '1') then -- check if slowcontrol wants to reset errors + channel_timeout_status_S(i) <= '0'; + downstream_error_S(i) <= '0'; -- set CALIBRATION_TIMEOUT_ERROR status-bit + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + elsif (reply_data_valid_S(i) = '1') then -- the reply was correct + channel_timeout_status_S(i) <= '0'; + if (reply_OK_S(i) = '1') then + downstream_error_S(i) <= '0'; + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + elsif (dead_channel_S(i) = '0') then + downstream_error_S(i) <= '1'; + report_error_S(i) <= '1'; -- set REPORT_ERROR status-bit + else + downstream_error_S(i) <= '1'; + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit + end if; + elsif (reply_timeout_error_S(i) = '1') then --and (reply_OK_S(i) = '1')) then + if (dead_channel_S(i) = '0') then + channel_timeout_status_S(i) <= '1'; + report_error_S(i) <= '1'; -- set REPORT_ERROR status-bit + else + channel_timeout_status_S(i) <= '1'; + report_error_S(i) <= '0'; -- reset REPORT_ERROR status-bit end if; end if; end if; end process; - end generate; ------------------------------------------------------------ --- Reset the unused bits of channel_status_S -- ------------------------------------------------------------ --- other_bits :for j in 31 downto c_HUB_CHILDREN generate --- init_unused_bits_proc : process(SYSCLK) --- begin --- if rising_edge(SYSCLK) then --- if( RESET = '1' ) then --- channel_status_S(j) <= '0'; -- reset status bits --- end if; --- end if; --- end process; --- end generate; + --------------------------------------------------------- + -- Control bits -- + --------------------------------------------------------- + dead_channel_S(i) <= CTRL_STATUS_register_S(i)(29); -- slow-control can declare a channel dead + --------------------------------------------------------- + -- Status bits -- + --------------------------------------------------------- + CTRL_STATUS_SYNC: signal_sync + generic map( + DEPTH => 1, + WIDTH => 3 + ) + port map( + RESET => RESET, + D_IN(0) => report_error_S(i), + D_IN(1) => downstream_error_S(i), + D_IN(2) => channel_timeout_status_S(i), + CLK0 => SYSCLK, + CLK1 => SODACLK, + D_OUT(0) => CTRL_STATUS_register_S(i)(15), + D_OUT(1) => CTRL_STATUS_register_S(i)(1), + D_OUT(2) => CTRL_STATUS_register_S(i)(0) + ); + + --CTRL_STATUS_register_S(i)(15) <= report_error_S(i); + CTRL_STATUS_register_S(i)(14 downto 2) <= (others => '0'); + --CTRL_STATUS_register_S(i)(1) <= downstream_error_S(i); + --CTRL_STATUS_register_S(i)(0) <= channel_timeout_status_S(i); ------------------------------------------------------------ --- Transmission history for reply-checking -- ------------------------------------------------------------ - packet_history_proc : process(SYSCLK) - begin - if rising_edge(SYSCLK) then - if( RESET = '1' ) then - last_packet_sent_S <= c_NO_PACKET; - elsif (start_of_superburst_S='1') then - last_packet_sent_S <= c_BST_PACKET; - elsif (soda_cmd_valid_S='1') then - last_packet_sent_S <= c_CMD_PACKET; - end if; - end if; - end process; + end generate; + + soda_reset_S <= (RESET or COMMON_CTRL_STATUS_register_S(31)); + soda_enable_S <= COMMON_CTRL_STATUS_register_S(30); + common_downstream_error_S <= '1' when ((downstream_error_S(0)='1') or (downstream_error_S(1)='1') or (downstream_error_S(2)='1') or (downstream_error_S(3)='1')) + else '0'; + common_report_error_S <= '1' when ((report_error_S(0)='1') or (report_error_S(1)='1') or (report_error_S(2)='1') or (report_error_S(3)='1')) + else '0'; + common_timeout_status_S <= '1' when ((channel_timeout_status_S(0)='1') or (channel_timeout_status_S(1)='1') or (channel_timeout_status_S(2)='1')) or ((channel_timeout_status_S(3)='1')) + else '0'; + COMMON_CTRL_STATUS_register_S(15) <= common_report_error_S; + COMMON_CTRL_STATUS_register_S(14 downto 2) <= (others => '0'); + COMMON_CTRL_STATUS_register_S(1) <= common_downstream_error_S; + COMMON_CTRL_STATUS_register_S(0) <= common_timeout_status_S; --------------------------------------------------------- -- RegIO Statemachine @@ -335,6 +353,14 @@ begin end case; end process TRANSFORM; +soda_cmd_strobe_posedge_to_pulse: posedge_to_pulse + port map( + IN_CLK => SYSCLK, + OUT_CLK => SODACLK, + CLK_EN => '1', + SIGNAL_IN => trb_cmd_strobe_S, + PULSE_OUT => trb_cmd_strobe_sodaclk_S + ); --------------------------------------------------------- -- data handling -- @@ -345,37 +371,37 @@ end process TRANSFORM; begin if( rising_edge(SYSCLK) ) then if ( RESET = '1' ) then - trb_cmd_strobe_S <= '0'; - trb_cmd_word_S <= (others => '0'); - CTRL_STATUS_register_S(0)(15 downto 0) <= (others => '0'); - CTRL_STATUS_register_S(1)(15 downto 0) <= (others => '0'); - CTRL_STATUS_register_S(2)(15 downto 0) <= (others => '0'); - CTRL_STATUS_register_S(3)(15 downto 0) <= (others => '0'); + trb_cmd_strobe_S <= '0'; + trb_cmd_word_S <= (others => '0'); + COMMON_CTRL_STATUS_register_S(31 downto 16) <= (30 => '1', others => '0'); -- enable soda by default + CTRL_STATUS_register_S(0)(31 downto 16) <= (others => '0'); + CTRL_STATUS_register_S(1)(31 downto 16) <= (others => '0'); + CTRL_STATUS_register_S(2)(31 downto 16) <= (others => '0'); + CTRL_STATUS_register_S(3)(31 downto 16) <= (others => '0'); elsif( (store_wr = '1') and (SODA_ADDR_IN = "0000") ) then trb_cmd_strobe_S <= '1'; trb_cmd_word_S <= SODA_DATA_IN(30 downto 0); - elsif( (store_wr = '1') and (SODA_ADDR_IN = "0001") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(0)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control - elsif( (store_wr = '1') and (SODA_ADDR_IN = "0010") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(1)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control elsif( (store_wr = '1') and (SODA_ADDR_IN = "0011") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(2)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + trb_cmd_strobe_S <= '0'; + COMMON_CTRL_STATUS_register_S(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control elsif( (store_wr = '1') and (SODA_ADDR_IN = "0100") ) then - trb_cmd_strobe_S <= '0'; - CTRL_STATUS_register_S(3)(15 downto 0) <= SODA_DATA_IN(15 downto 0); -- use only the 16 lower bits for control + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(0)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0101") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(1)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0110") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(2)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control + elsif( (store_wr = '1') and (SODA_ADDR_IN = "0111") ) then + trb_cmd_strobe_S <= '0'; + CTRL_STATUS_register_S(3)(31 downto 16) <= SODA_DATA_IN(31 downto 16); -- use only the 16 lower bits for control else - trb_cmd_strobe_S <= '0'; + trb_cmd_strobe_S <= '0'; end if; end if; end process THE_WRITE_REG_PROC; - dead_channel_S(0) <= CTRL_STATUS_register_S(0)(8); -- slow-control can declare a channel dead - dead_channel_S(1) <= CTRL_STATUS_register_S(1)(8); -- slow-control can declare a channel dead - dead_channel_S(2) <= CTRL_STATUS_register_S(2)(8); -- slow-control can declare a channel dead - dead_channel_S(3) <= CTRL_STATUS_register_S(3)(8); -- slow-control can declare a channel dead -- register read THE_READ_REG_PROC: process( SYSCLK ) @@ -384,25 +410,27 @@ end process TRANSFORM; if ( RESET = '1' ) then buf_bus_data_out <= (others => '0'); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0000") ) then - buf_bus_data_out <= '0' & soda_cmd_word_S; + buf_bus_data_out <= '0' & trb_cmd_word_S; elsif( (store_rd = '1') and (SODA_ADDR_IN = "0001") ) then buf_bus_data_out <= '0' & super_burst_nr_S; + elsif( (store_rd = '1') and (SODA_ADDR_IN = "0011") ) then + buf_bus_data_out <= COMMON_CTRL_STATUS_register_S; elsif( (store_rd = '1') and (SODA_ADDR_IN = "0100") ) then - buf_bus_data_out <= calib_register_S(0); + buf_bus_data_out <= CTRL_STATUS_register_S(0); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0101") ) then - buf_bus_data_out <= calib_register_S(1); + buf_bus_data_out <= CTRL_STATUS_register_S(1); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0110") ) then - buf_bus_data_out <= calib_register_S(2); + buf_bus_data_out <= CTRL_STATUS_register_S(2); elsif( (store_rd = '1') and (SODA_ADDR_IN = "0111") ) then - buf_bus_data_out <= calib_register_S(3); + buf_bus_data_out <= CTRL_STATUS_register_S(3); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1000") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(0); + buf_bus_data_out <= x"0000" & calibration_time_S(0); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1001") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(1); + buf_bus_data_out <= x"0000" & calibration_time_S(1); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1010") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(2); + buf_bus_data_out <= x"0000" & calibration_time_S(2); elsif( (store_rd = '1') and (SODA_ADDR_IN = "1011") ) then - buf_bus_data_out <= CTRL_STATUS_register_S(3); + buf_bus_data_out <= x"0000" & calibration_time_S(3); end if; end if; end process THE_READ_REG_PROC; diff --git a/code/trb3_periph_EP_soda4source.vhd b/code/trb3_periph_EP_soda4source.vhd index a43a376..768e594 100644 --- a/code/trb3_periph_EP_soda4source.vhd +++ b/code/trb3_periph_EP_soda4source.vhd @@ -656,16 +656,15 @@ MED_ECP3_SODA_QUAD_SOURCE : med_ecp3_sfp_4_soda SCI_READ => sci2_read, SCI_WRITE => sci2_write, SCI_ACK => sci2_ack, - SCI_NACK => sci2_nack, + SCI_NACK => sci2_nack--, --Status and control port -- STAT_OP(0) => med_stat_op(15 downto 0), --med_stat_op(1*16+15 downto 1*16), -- CTRL_OP(0) => med_ctrl_op(15 downto 0), --med_ctrl_op(0*16+15 downto 0*16), - - STAT_DEBUG => open, - CTRL_DEBUG => (others => '0') -); - +-- STAT_DEBUG => open, +-- CTRL_DEBUG => (others => '0') + ); + SFP_TXDIS <= sfp_txdis_S; @@ -738,7 +737,7 @@ THE_SOB_SOURCE : soda_start_of_burst_control end if; end process; - blink_H : process (clk_200_osc) + blink_H : process (clk_200_osc, time_counter_S) begin if (rising_edge(clk_200_osc) and (time_counter_S(15 downto 0) = x"FFFF"))then if ((time_counter_S(31 downto 16) = x"FFFF") and (time_counter_S(15 downto 0) = x"FFFF")) then diff --git a/ctsh.ldf b/ctsh.ldf index 649498b..151adf3 100644 --- a/ctsh.ldf +++ b/ctsh.ldf @@ -18,6 +18,9 @@ + + + diff --git a/soda4srcEP.ldf b/soda4srcEP.ldf index 63077e8..d98efa6 100644 --- a/soda4srcEP.ldf +++ b/soda4srcEP.ldf @@ -15,6 +15,15 @@ + + ++ + ++ + + @@ -48,9 +57,6 @@ - - - @@ -60,9 +66,6 @@ - - - @@ -75,9 +78,6 @@ - - - diff --git a/soda_source.ldf b/soda_source.ldf index 02e2c21..afa532b 100644 --- a/soda_source.ldf +++ b/soda_source.ldf @@ -4,7 +4,7 @@ - + diff --git a/trb3_soda_source.xcf b/trb3_soda_source.xcf index ac352bd..5e6f4c4 100644 --- a/trb3_soda_source.xcf +++ b/trb3_soda_source.xcf @@ -139,8 +139,9 @@ 1 0 -/local/lemmens/lattice/soda/trb3_periph_sodasource_20150318.bit -03/18/15 15:40:50 +/local/lemmens/lattice/soda/trb3_periph_sodasource_20150319.bit +03/19/15 08:09:52 +N/A Fast Program