From a4c5cfb856026771dfcf31eb22434b8b6ff20ad4 Mon Sep 17 00:00:00 2001 From: Fabian Stemmler Date: Tue, 7 May 2019 13:32:29 +0200 Subject: [PATCH] Added era.mi; Project containing provisional simulator core --- era.mi/.classpath | 11 + era.mi/.project | 17 ++ era.mi/.settings/org.eclipse.jdt.core.prefs | 12 + era.mi/bin/era/mi/logic/Bit.class | Bin 0 -> 2299 bytes era.mi/bin/era/mi/logic/Simulation.class | Bin 0 -> 586 bytes era.mi/bin/era/mi/logic/Util$BitOp.class | Bin 0 -> 247 bytes era.mi/bin/era/mi/logic/Util.class | Bin 0 -> 3046 bytes era.mi/bin/era/mi/logic/WireArray.class | Bin 0 -> 5848 bytes .../bin/era/mi/logic/WireArrayObserver.class | Bin 0 -> 175 bytes .../mi/logic/components/BasicComponent.class | Bin 0 -> 1594 bytes .../bin/era/mi/logic/components/Clock.class | Bin 0 -> 1313 bytes .../bin/era/mi/logic/components/Merger.class | Bin 0 -> 1923 bytes .../bin/era/mi/logic/components/Merger2.class | Bin 0 -> 1985 bytes era.mi/bin/era/mi/logic/components/Mux.class | Bin 0 -> 2247 bytes .../era/mi/logic/components/Splitter.class | Bin 0 -> 1934 bytes .../mi/logic/components/gates/AndGate.class | Bin 0 -> 1236 bytes .../mi/logic/components/gates/NotGate.class | Bin 0 -> 1068 bytes .../mi/logic/components/gates/OrGate.class | Bin 0 -> 1232 bytes .../mi/logic/components/gates/XorGate.class | Bin 0 -> 1236 bytes .../era/mi/logic/tests/ComponentTest.class | Bin 0 -> 5424 bytes .../logic/timeline/Timeline$InnerEvent.class | Bin 0 -> 1090 bytes .../bin/era/mi/logic/timeline/Timeline.class | Bin 0 -> 2556 bytes .../era/mi/logic/timeline/TimelineEvent.class | Bin 0 -> 448 bytes .../logic/timeline/TimelineEventHandler.class | Bin 0 -> 203 bytes era.mi/src/era/mi/logic/Bit.java | 62 ++++++ era.mi/src/era/mi/logic/Simulation.java | 12 + era.mi/src/era/mi/logic/Util.java | 92 ++++++++ era.mi/src/era/mi/logic/WireArray.java | 208 ++++++++++++++++++ .../src/era/mi/logic/WireArrayObserver.java | 6 + .../mi/logic/components/BasicComponent.java | 29 +++ era.mi/src/era/mi/logic/components/Clock.java | 31 +++ .../src/era/mi/logic/components/Merger.java | 61 +++++ .../src/era/mi/logic/components/Merger2.java | 70 ++++++ era.mi/src/era/mi/logic/components/Mux.java | 77 +++++++ .../src/era/mi/logic/components/Splitter.java | 53 +++++ .../mi/logic/components/gates/AndGate.java | 40 ++++ .../mi/logic/components/gates/NotGate.java | 33 +++ .../era/mi/logic/components/gates/OrGate.java | 40 ++++ .../mi/logic/components/gates/XorGate.java | 40 ++++ .../src/era/mi/logic/tests/ComponentTest.java | 206 +++++++++++++++++ .../src/era/mi/logic/timeline/Timeline.java | 90 ++++++++ .../era/mi/logic/timeline/TimelineEvent.java | 17 ++ .../logic/timeline/TimelineEventHandler.java | 6 + 43 files changed, 1213 insertions(+) create mode 100644 era.mi/.classpath create mode 100644 era.mi/.project create mode 100644 era.mi/.settings/org.eclipse.jdt.core.prefs create mode 100644 era.mi/bin/era/mi/logic/Bit.class create mode 100644 era.mi/bin/era/mi/logic/Simulation.class create mode 100644 era.mi/bin/era/mi/logic/Util$BitOp.class create mode 100644 era.mi/bin/era/mi/logic/Util.class create mode 100644 era.mi/bin/era/mi/logic/WireArray.class create mode 100644 era.mi/bin/era/mi/logic/WireArrayObserver.class create mode 100644 era.mi/bin/era/mi/logic/components/BasicComponent.class create mode 100644 era.mi/bin/era/mi/logic/components/Clock.class create mode 100644 era.mi/bin/era/mi/logic/components/Merger.class create mode 100644 era.mi/bin/era/mi/logic/components/Merger2.class create mode 100644 era.mi/bin/era/mi/logic/components/Mux.class create mode 100644 era.mi/bin/era/mi/logic/components/Splitter.class create mode 100644 era.mi/bin/era/mi/logic/components/gates/AndGate.class create mode 100644 era.mi/bin/era/mi/logic/components/gates/NotGate.class create mode 100644 era.mi/bin/era/mi/logic/components/gates/OrGate.class create mode 100644 era.mi/bin/era/mi/logic/components/gates/XorGate.class create mode 100644 era.mi/bin/era/mi/logic/tests/ComponentTest.class create mode 100644 era.mi/bin/era/mi/logic/timeline/Timeline$InnerEvent.class create mode 100644 era.mi/bin/era/mi/logic/timeline/Timeline.class create mode 100644 era.mi/bin/era/mi/logic/timeline/TimelineEvent.class create mode 100644 era.mi/bin/era/mi/logic/timeline/TimelineEventHandler.class create mode 100644 era.mi/src/era/mi/logic/Bit.java create mode 100644 era.mi/src/era/mi/logic/Simulation.java create mode 100644 era.mi/src/era/mi/logic/Util.java create mode 100644 era.mi/src/era/mi/logic/WireArray.java create mode 100644 era.mi/src/era/mi/logic/WireArrayObserver.java create mode 100644 era.mi/src/era/mi/logic/components/BasicComponent.java create mode 100644 era.mi/src/era/mi/logic/components/Clock.java create mode 100644 era.mi/src/era/mi/logic/components/Merger.java create mode 100644 era.mi/src/era/mi/logic/components/Merger2.java create mode 100644 era.mi/src/era/mi/logic/components/Mux.java create mode 100644 era.mi/src/era/mi/logic/components/Splitter.java create mode 100644 era.mi/src/era/mi/logic/components/gates/AndGate.java create mode 100644 era.mi/src/era/mi/logic/components/gates/NotGate.java create mode 100644 era.mi/src/era/mi/logic/components/gates/OrGate.java create mode 100644 era.mi/src/era/mi/logic/components/gates/XorGate.java create mode 100644 era.mi/src/era/mi/logic/tests/ComponentTest.java create mode 100644 era.mi/src/era/mi/logic/timeline/Timeline.java create mode 100644 era.mi/src/era/mi/logic/timeline/TimelineEvent.java create mode 100644 era.mi/src/era/mi/logic/timeline/TimelineEventHandler.java diff --git a/era.mi/.classpath b/era.mi/.classpath new file mode 100644 index 00000000..bc8d71b0 --- /dev/null +++ b/era.mi/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/era.mi/.project b/era.mi/.project new file mode 100644 index 00000000..9a89f37b --- /dev/null +++ b/era.mi/.project @@ -0,0 +1,17 @@ + + + era.mi + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/era.mi/.settings/org.eclipse.jdt.core.prefs b/era.mi/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..a54bb93c --- /dev/null +++ b/era.mi/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=10 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=10 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=10 diff --git a/era.mi/bin/era/mi/logic/Bit.class b/era.mi/bin/era/mi/logic/Bit.class new file mode 100644 index 0000000000000000000000000000000000000000..9bba9f0cee30de7022888b360e01f711c37bbd00 GIT binary patch literal 2299 zcmah~TUQ%Z6#fn~$s}QDxkhMHE)v@$AQ7ZM8!R`2O$kst0UCI44Pk_-xzr))Dv$n* z`UhOgCk$&*R#lcyKKP^5y-%hxlDLF5v*$bK?8~<=Cx86;?h?QZ_B6B!bXty?EZNCo z<D4QE;f$r?}(|}B) zkH5+-EoakFQizu9s5BoX^8#&q8G-in#@2dtdnvn>HUxV1S{V+^7m9Y-u0A67vG_K5 zTB#gZ0r)~76&=0k6Y$TwN5Zk}RnSJ&vCD_4Onf^?XFt&4gFgU`!7Uvcg8+j&Isy!W z42E?C;peXpb?E32xS6%f)<&(gZ#g-0zi4p=Dh0E+Z8|n%xfp_i9ty5{WFJ$cX8Ay1 zF4jz_c_rSw#MBZx?qN*eZVMwVR4DBxJ^QSh)bR->DJ#~uHM2T{erdl2m^GE3;U$WPI@!wGUwxk2QQj?dhrM$#K;x>B!)TK+tp? z^Q2IDc|!SW!7<}$2A6h*x`85*o;Sai>Gc?IG)zlg3O01CfqMMD*V9VTJU&i&{J2dQ z_bl=7q`0HLz<_*}ylwc?fkjfzn#9Ie_`@gVIu6-Pt6K**@noPxD#bLRzU zcqUkZ$Q$-y*{s$aT8>`xHs9P+k5Y@18!N_ZGA`>;^3l0S_&v?UHRlYmkTx5v^gO zHA1vTJu&ynd5B>B+xc*Jm?v~>-O{Ztc;{)QDlAasAI_`RQ>pQF{ zRA0I)T-P&PbTS>TVs+UPjPBZ8lJO-$X|=}$^(uUDG!zNV|H(RZ zlniX3OvrVY8fvTG9v48^G>}D(P_}sBVCGMpXe1_{L#SGzExfUaWRj;v9SXJ+sXWh* zALSEacisAGZT77CLI#9->)u+eKa3+8xSezb5xFc;`=d?Jhv6);ooktRDX(Ug3 literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/Util$BitOp.class b/era.mi/bin/era/mi/logic/Util$BitOp.class new file mode 100644 index 0000000000000000000000000000000000000000..6e5fd47a25c9771241091804063fc91c2f35c6b6 GIT binary patch literal 247 zcmZXPJqp4=5QX2U$tE#^R$jnD8@Cg|PC*ca6ygEau!Ie3BKZ-|X5j%mlsHKj(#(U$ zd-KhFfA0@~4JHBu!dw?h-i@?*Vq$r%j9u(a6+Hw-glVdtN?MgAGPPVq)0766i_iXh#H`^^x`B8aU{&dWTMdfgD?FH zed*_uukDLc`!#*<*I&_>zP3N0rRz+BNnlES$ec6#?6daTYwvR=zy9;G1YiPRD{u+4 zXn8fdsYkPBMo&kVEj_EiBhdUneWXUSs*#B8K;Rf-q)j8OGT2~v zbv3b{Lu}B&CeWDFGlpsv^9*@vYH9M|zG!;Gx88ZoyIlCtmoKX;AU#Z5LKrFmk-x{;J6>~6Anz{~>Zmn$W@gUA) zLO{{Bv~s@7+572)x7xP2lLJ;p@QlKHF8@5$o=`~6GC$1Aa=C0au9pKHC zlz_|3x022{mDrL~7seYfCm^YYY%L3+$68(s$&NJFL)yclnhljpGNRxr8)83l0P~0| zxGvCHw^UU?s&#`JgzHn0Y96%g(@{D}+Bt!)dgm%W9o%NoQZU5{i3^0Cv~|+Uk1Mzn z#3GVx$o(}e$8N}~o2fN*U{w091aVI0;!4fPyQePU3f0ss%Us!WPVV_Ih-tZJ&p0NH zp9FDP8vRMLm``ihba|OI%A7{zy+NI4P17n^c{R77S@+Ggf*)&GS3tL#n?*MsnHyR( zVN;}|x~`@zGrt`~20TN7&8kV@x7u@B*;xj^&SR0)3Ihq#+$iQ^HD|YS&(v7zHZE=F zv|9JqUo3|_eDC1FuyblQo762W*5pIF88_tN$_BB78#HXtP_aD>;se{3tJ)p~@sVvS z(k2j$8-|vj%c_Nf#;=8!^;^s-_*~$0_3Exms9q)oUkdac?#lbDtSQ@u&B?n1kd*l~ z<5S^Vl%wG2jl4j^51hE@0DGB61UL_t9XKB0+c!9hCVDm7zAX|&^wHnP_w`8WTO9cb zt#@17UZCR__f+KWq_;HTaZf)(bCn`agTNHplg9+Y1%X4 zd4}FdyJyTjY!9U!oGef7O+WF7c2A`Abock+?-|K$vz)LQ1;{fQsr?+XB9DE9*lu>Y?T)Q|9ue2x_71Xv1jg)_k*i!IIL~(HpM224CEno+4 z%Y$^QYn>xzASa3ZGY5scWp{ zJpWt7srEcWzH5^jFNb?2SF9ozDbOQ9F*{ki1xn~<2b`>_VgT-zzY$PyQ?yatMck_7 z@CC~(&&)}ia>9M_8JdQAB0XczaXb0MC3<8({xwwP*?3oexWi{ zg`baIA-V8cM!U_$Wp|Vxt_qbvvtM2-6)KbDFT2JU8QQ_}VGZNMdw8Fo@(kbQOb~}x zkrU49ew^A~al+yC<%IL`ew^AiIeKg_NTrEe1l*v$tDm$G?fi8ghp5i(3$`y)aoQVNd`8%ad(ms z+jJut_3d(lrV|r6ej}JC& z?b~JaTM7!t^w_A8Qc$t8Ge@%Bw89GfR#G1`V%_Gjp+Jc!C{FaHjO3V+q)1t(t#8ya zV@;iAO7<6bnS*iN8clNhsu{0aat)-RZFMzMSGB~Zz_XKZ3R}#$X|*aSsEb7Ew=3|iPectryr|SrhWQG-b@kg-ETn@O zuy#ZQu^$UiSquedYbb_aMYV#(nIJ`CF=J4VtxFD$4jXZ+V^6;^Vws7!ibV<*X7+Vi zNi#m!K5E9IMzRP&1xEEgjUVx*Ch`Cy#Um`E#^;6 z(v)X+(Ps^rq~%#>;2GI9r_0j&cW>55YzY;Yki;`tFL>5zC_rH`TCrZkThT%8Um-?k z?xjk_R8TTt7*U(~G1^~Hm#38Kw-@6wbgI}y=H#g9GKWWFy3k6)W^7^nx+9xAIwM+{^8w4|iW1w}u81$)Fh@5w=UAEobbclLW{0RB&n3E`zkl(x@Nr#MLUUQZO%5$C0>Y3>rxd zI{Fl-c5B=^AQ{c6Gj|)K5ygNCMm(#rI@H%N2sW`of*RJ@tS-(|O*^xy$!W*oyw$P` zF%`R~jo97RZeS@5!-&&}am}bM#H%OqGS0Xv^DNc(`Z0oQR1|7Rf`SG8u|%A10~6C7o1zQrBKb(Qy_`}LLd+)re-KBa)bpXqbz;C|y^-lMAi*n1+wzLnLn^88zd2jCx38ZWz{67E@ZpJ+2ucL{6d0R3Jj1)9@MWm&1ycF>41IWyYh%9tLb$ zmqV3EeIBxKx1B>mwNEu)pD8fr)1`c>OW0GU38-MnnYcB*C0yTIf`fQO#TV(mo%i&> zqTx$8M6=X5uwNUTIsI)_`*w#|sU9xlOA z99MCSXG#Xq^ji%lq$qvtaF&WEXZG4zwoC8?p3?9%zRVE}SLA`ZF57 zid)GOAtnuxX$d*`zAl6+6(&6|XW#?E$Zu$P(LMuvRlLMmDN{UK5?!PHLzkLHEZUJw zCXy;j>3&Qf?u+WR90kJpj>6oe=06AQiATYAH1uL4vC*TYZ%Qs>ex-tzyv^xN>5+*` z!H>lLIH!@W#AveLxYU&6b#6KX%Ow)5&-O&ZN^w#i*=$%tiD=4?pW~M*evvawn(?v3 zZlkHw4h}c!1A0F>!Y27E{F;4iIJ2bS#q8$dN;=A&qc~ODnMmv&9SLVO9CudCTFDXY zo)|H*x4-$9j>$Kc%|5wY&Fl48tc#@(E-l2*6x7XNLJ<(yRj zk4%NUE0<}N{~q~h;M)@WUgJ9FS)j}>HN>?FzAM8#US&>ugwmp?Ei{FS&stWUKNTW z?>sVzyV%F5!Nawsq0r-4^(0!4pv~KI0Hu6v3mis!*Iq>l$h-ZgU&{boK$n3<4A41* z7$l@~P|JV{s0EHf7t|cWzLZcD8w$T<|AR86ga`5lY;-YP=3*#6j7X^AIJN>bxOx&@ zV$fqp#BVEYV9Xn{jFhK6FGmkEsNg2)E3V$VnN9I+gTQY%c@NH$WR&kLcoN zxU#FqCokphDEjS`(C>z$F!!N6)G&#}(->h$m>w(R{n<8IR*)ns31=0Wu^R2TkbX92 zf!mMd1Qd>aQ8oiAS$$R#pqS0$F%Hs|BJm0{)Z=|6J zzbH4+|4tHfOBSr=G_2+{tY#OM8-t3)^!^sy>c-#>0v1Ls6T>}gd?#DIYY!k$<*Q!R z*>D)Q-4Bg_cifKx@4>wurMhPS=~sLQDd5zLL&qx!sh1?&i6yuK4Y)EZ8OvNq6{PD2 z&_S~Tq!QlKERORTQz@DcCA9rr@w)ob1TMr<76dx9lHLE7^(d7^E z70UqJEvW@d0W1V(ZISn2p!$ZEYTurrU6LT6Us+Ep`p~qI=d>2d=vt^U8t(HQE}e*;8}v!7RKE@AooOH#2ItFnqV68n?4u z-I0Z_*2P!Ap5Wk{%bwuit0oaYoyNzo{}+qdlN1h}pXF7$=?aEJqFEU7PU4Sl5{}kq%+;*swj}03iYz1c_K@= zAT9hLeQH@F|`oFR|E8;e5QDWwp))zL0tRnr&4| zdmcQe8CyB@xPFv}cUcihdzTC5F+!2ZUUnGI_B;#Up&du@+{q{Wn?h_etZd)b1MuzO zLpvYT>4z8iP&oZ?8y^ashn~mq>>=i^jG3(_z#2Bjdj5xS0gL$*kA*fC<|*2g)7?p& zX1gF<6}U@Kyivu=r)9L@zg$jXQ|_hABZHIcz#2E2g`tKid^>YcI?5Ze;!~I=U?IMX z@4-Vo9JX9NVYd^gJbI?^!8> Szv4B%lWFR2_y_)ls{aA;S3?v4 literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/WireArrayObserver.class b/era.mi/bin/era/mi/logic/WireArrayObserver.class new file mode 100644 index 0000000000000000000000000000000000000000..51ff213ab1cdd20cc44d7ed46f633242b438e93b GIT binary patch literal 175 zcmX^0Z`VEs1_m<*PId++Mh3amqD1}NO#Phv^vq=a@XVrA$D*RdO8=zd)S|M~B6bEA zMh1bb#Ii*FoW#6zegCAa)Z`LI2DZ|Il*E!$Mh0mOAM7SrYlbm0a0Ta=7A2>;W##~t kieZ?p2QrwAk%5tc8R#Si21cM|tPE@*76UtwWMbd|03?GhMgRZ+ literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/components/BasicComponent.class b/era.mi/bin/era/mi/logic/components/BasicComponent.class new file mode 100644 index 0000000000000000000000000000000000000000..30dad6ead5eac322f1aa28f53e494324bfb99e59 GIT binary patch literal 1594 zcmbVMTT|0O7(LsD21=kUpxl(3fNe#BHx!E(s4#Y>z(YIuyiHeFNRv*IGQ*$o)n^^W z86Nxrj=xF#wyl(cAmc-_yC=KnobR&v@$2|IfJLn92r9 zZ?1A*TG>Bq9U4P?j~{T;=FX0}RoW9)pd-RC*2eHodSb=%_~BN`7v6#J7`m&TYYE>k z%8FoMIflrxbY$?7K}+UR+cad|vWOy#9s^zIWe6uz+g%_<13EexVtMI^&03`-ydp2z zMAMgdEpBgfPpWkj)Ph~lnC&+YFt>+{Riyx4FhJ(e5drT-X$osgj~5nLaAYxPb{wQhs*1 zQ&v%KpL20}D5-z&uN_cT-_~ipOcZx8qhtDf@h-SBFpIks2QQcF1Plx399=llCRDF( zmnyd8flIwG)NZqtRR&!JS5vv~w0Wge=F+xazurA9%dFA%b1E>__ngPjxIZOto%=bPn8oVdm@BX(NBn zEeiS2z%wk-C8)F@hM&p&g_8~PMv46CyzB1Qs+lv}3V|n`owG<&vT?9@SQY>Gu_1Z& z+0+>$P1!8B?Sc$MCKkctIObFZUKqHCxtNY+0vL>(;|MQnbKe)fj#VnlwZhi%hFbIL zt#nHoInpLcI809mJt6hKpqr%8ybH=wH?4faLp1iKzrje4et2vbTwRM(HzHw+_=ku%zfQ|$zjNP%gZ>Tw_*QkibjFVU#zJJLtE-=d5V s4Ek5KLg_fA>wt*``X0uEx`l^$M595-bHXxsiC1_{h)UrKvRK3LZ+VrKi2wiq literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/components/Clock.class b/era.mi/bin/era/mi/logic/components/Clock.class new file mode 100644 index 0000000000000000000000000000000000000000..e2014fc8806c269dba4ddd0dbe7c5c362b9299c1 GIT binary patch literal 1313 zcma)6ZBNrs6n^encG*^73>^saCL&u=3i!fwh$5MRWU$1M5%E*$>L_$ADFx$C@fYw_ ziC|))AN}Bu63?v_Qih3Xd++J#bIy6r%k9r!U%vx*ghh@R!=UNuTGP^Ow_zEY;WqbN z$8`LCZOL|xT@INcy`vxMnyotxt+KUa8a_vyL5&#tR@1aC$JEwCp>#-ImUX9Yn;t{l zcN-1cWMG^0ykqDqN6a@Y&s_98{e6+J^Oj@z3k(Cfe}VEf26@S?n@LFMQjkKLLCWQ8 z2{2?7aI_2Qnt}w93|(bnwsz3mGQD+uOVG%aT|>8Px@U>^P$~P{);_~zP_?rDzB`S7)GKzT6`CixP{vs zV+=zPr!7bYSW zR3J#3I@eM4bz^r`-wRsK@q}S4!r^L5j(LWjE80rjh%+fCODJZmd&|4)y0A1=AbgI$`y4A@O^n3~o zuG5-TT>fl7=FH-mV|I_DCcegYYvzIrBn%EX-gFir8bmK<;ErX8n!08nawWNOK18& zoL+IOGnRIAM6dlDUiuRp#pg>>0tg)@e5d#DywCf*`^UdO9|D-irUswDm~@Ox#mtoL zl3B`K+Pq~+E!>(VJnM?*lM`jyY)b8%4sBuQH%++8^vO) z`iYC+zBS1vzSN)#jJMcbE0<--D6cprufis*J}=0sYuZ*D#sw;yyHY2mq)fM;>J|3K zv`V_AA5&V>P0O`)Hc+p4HCNv?_N3lGt1s!sOuDg;C-jtV%$_`@(`j{Q9p9xRxPnQ= z*n0x8c&>#p?>bDIRn&InOiSMPDm&8IG`=8V( zh@fY&S^=@feO(*^9eLL%e7$Z|>(Mks1T^LAxl+T7K;N0}-!|Q>>dN&f=5RwGT$1jV zQT8Mu#Nvr_t#9HZ4Ic{hoND|d*DOb|0HxG|Z50fvIT7F9K0!uf9I}ksBB*(%Ff2u} zjE|{|r&1R4X2~+jMA08V2Si<}JEoe3OH6SJh$@Msn8abpZ#F#6--_c9)Xt?a=@I?}4_amH}^(ZoGqQYuIO~bW0^pU*n zIR$yoRB~uZU96sHZRY#IWS>(t+^eoq`$St#GQYtH!WxIybx+3TVn=PL#t}>^e zzaV`4)c>0@m>h(eLH9C`1uh5fBy+WUVdFsi6b~qpM&j`KZ)!xHM`jN&n}6XG_0!?YqrXybF#kKI*ZJBvb%4cIy<_AXtRhVGoy0%H z^&0V~iEW-pReeb&W2$C-VZPnM3W2nfi`%sG@g|HrnBh)U#ftwyr-r+tlUA#^*94vA zyN~ah0y#YU1Gm09=^+{b)AeNi4U=OsHGIMp9@AK|&|2*FXFolnG zXaZx>wF*tU&}h}|YN6U{uD2ZNcpHTU>DHxN)Dadq^~l<^3JuGt7Zz6@$*QL#DlmHB z=mXo8v#x7>xwx_+-A(BVgj#J+U~vBExROBBcGlb8hQQFn$YQiWr0iSrLppVD&4;Y0L#BaooE7M?YPEfJCXOTiUq~tQsg5@U&hD#U zX*6WrYRtOzc9UJY{kSUEJ-g*};k-ce-kLNiIVCk)t7el8q-dsNc3QJx+K$&U*c-ucCYHPG!bLC6r3-YeuN#q15}L#Zbh8fxB3weANbx z#DSq^``r(|4^%g{)M~p`dB;|5H}<|Jc@@ZE;B4?8;Z;*J#_y4)rp~`}(s}BLZnL!MJ)mF@LDP7Ck zxT(|(i1qrB7Z7EYaXM#+)hMO10YZo5Fz)zDMX9)=t1&u`cYUQaHA;KAzv7z^&yR&> zo}yRDkSgZBLnQU=i6&BN&;I_QJ!44F&VIio)4X1xjjpn>(`>*spM)7ebx4fiJ)eZ; zw^)%-t?5GOZ$w0oMhcbxr{Ikv6?~sw2^74{yK+U3BD{_HUva3Hw_bwi=``U(9@6m9 Ezp&etzW@LL literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/components/Mux.class b/era.mi/bin/era/mi/logic/components/Mux.class new file mode 100644 index 0000000000000000000000000000000000000000..9f6da5f5a1d657e2d317288b173447706c9f9e05 GIT binary patch literal 2247 zcmb_dTUQfT6#h{}oDU;5IwuGQ9lJAqngd}~&6&fatO<@@&DXY$Km-#rI#7PbbD!ZFh| z(p4*MI~A*xE;-e8r)Jg~_4Iu6fd-$#nO7N18g;8Qwd6;Ke0A${lP6h)p=iF4U7DJ`y_A{EO-C6eTD77rP|-&^~ zs>6?f&^V*x4a5|BjB6nzRYK~jBYKARQFYB1bj6(NrR8k2sWv93y%<9PED#@&wW;t(F7=-pm zVjaw-PZP-Ln8yMy$cj{NKOUAPV3Zox2DxL|4sa9$>0 z>R1!acXRssq6XfK@XHBZaPrO4of*rt%hRswxEgvDf_bOumdqJT2B?d#q?9<|Byo88 z5(~g1lT67Yli1oheXX7I$h}`~9MBgO(9|`09>77aec-|mNPffE zUZlCc&HO-^Xpa%caYQkQ6o&8)PT&F}7$>L8IEAYi#xQyQVzrOf*}Lst~7-H`GVFyyvM(SRyFV|V~B5&gyXqq zILCct8}DypJoSjrWBf^G$r<7=%=6(Kmn5yGwsGYl;?%-FVq)Gq{t)`;;A70?zwoL- zdHnT@-^7+hzVfmzDd`RpL^{IwDJ04IJlT$s=M>S;65j&%RiZR_A~i|0QSQ{l&mmkS zS4I0Fe8}o~cqtF#IwN~q{6h%*ff#A~djEv3A+NfAZ;ikbZtPG`a~EoUA{^eN;AwSD zqJl3D$*Q*vcCsogcXW>Lcg}QlE_8HG?suN)=)BU=d1Sxy+<%?>x=7;!iS&`s6P8El zU44wz)t}+pEIh-l=RXAJ5|8l-d+u9&2w#E992IR>F{lJ~l`<87TUmXA)lD|04+9+U z3dj2l;@lH#vc)#uQu-h@YNv6yvxk5YZ}?Zk^L-Wp%7l zNPiE58-zkJ6DMXRbkQf33B}XfNx2`o@FABnBjI?PvY-b#wL~#vs0{vCp+1AXK&Iqwo z`U5W9F`R;edD8eqPbm&_4sI&=^aR68`%Oo$MR5y@^sGrrm+OsvflMy~-W(K)J)j(m zis@~c+)@;`LC!{=>3XGPR4vV9dhygL*-0G3O-HkxqE*pfFs$2SW=Mifj+`e^hWMtDt!{^4lRgpn0gz>bC>uZUR~8NX7N=NUt^8KTsFxv4hlVYiO{Z@ zoNhHLn#23VS;IiKggIyrqsYk-WQm4jXil9EMYvRN*=7B{A?Y)4{Pg5x7);W}&wmg; z{y43Cy?k<3xd!n)$r|dUFvZx#`g!~J^ z*NBZPvEbZdAUPg5K;r50%bOeur=#!|e44G8n}i*CoVokCF$tfRCv?&m@@=Qb==^J6VEocd`f{b#L)m$S_8R zH(CAznBjdE{v%AIPk~SnS1`+_b2keNA7KoE9yw@2P}?~CjgT93)4!DY8N&z2ultu@ zLmozxbFA+-Twe^#B*p{&j_4QM@b(grLZTyoy7ba7lJa=?>gdld6juoVkYM_kSVWRw zOz^8Ri%FIT}~CU_+wf#h2{_t~2|2*FoGA{sY@Bqyzu} literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/components/gates/AndGate.class b/era.mi/bin/era/mi/logic/components/gates/AndGate.class new file mode 100644 index 0000000000000000000000000000000000000000..f5ca302cb6cd16079d137d9b82fa1f3babf4bd61 GIT binary patch literal 1236 zcmb7DU2hUW6g|VIz_t`BP^5l9E#1Yo>qo5*7?aY(hJ@IMR+{M303(ip-DY=b;(zeR zXd-BQ@CW##jCU5QrCADHln?q?1?7r-pU3++L zTf*{Ov(G)@ng>?zh@3bg4An)c4erYB;U$!TafY?lT=toC#DU}Rk99ikFof-q#}Ioi zE$O{rXz9&G`TrX?+6<9HyC;$eV@X2-%M{R?Mmqt96%A3ulE~s_9IFiZV3itj$TOsP zuXo&Wg>xYsh7Emzmdlj7@kZ5H(-22YdABs&K#U>Xl9qTi8g_(p$~yzWkZsvrK4^1C zs{Je&@!m_9VQaq3qMp!Arp_I^D_r+f4vCXB8R9B?X&b+TV$h@kwB83DcXJV^MFdN^bJ~VdyMpUZGy~MZD)+a&eSbN#wdRA zIZE`rLyW)@F)b5M8Y{GN$e=_GDPtAubh<~U#ERRLt$r2U#XYL2Jf$n-drFy7TTzpQ z2(2>tQ)NeVqVkKiul_$h!3MbnGT*T^!OlNHNuREOHCn2;HU-X#Gd#lM8L3HDkw%Fr o{h6E)sRq?n!SyTP=wI-YKycwYxEu)H3j`OhgR6nyr@p@ZKP+7L0RR91 literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/components/gates/NotGate.class b/era.mi/bin/era/mi/logic/components/gates/NotGate.class new file mode 100644 index 0000000000000000000000000000000000000000..eb7dda8300e412de03879fae90a2bbe6da0d78a8 GIT binary patch literal 1068 zcmZ`%+iuf95IvilTgSa55K~g1l+xBVY0XW%1R-c8P^74RXh|h_+Bi#CM_E1|mpe zx6cz1y9Z(Nh71h_hOJqtdpwrj{w0(lCj*9+_Eh?bjKr%b;-8xg`EZypl%C5#CNCJC zTCG{Rv*LD#p|BtJgpNE619MoQfYq`)^I%vqP((>b1=loG8O-cT3|vQzq0D=|!)`31 zGZ8UtSTi&)Q=0ZWrE$Z6h7xJDWgrfQgRY223DjpTeKN< z%bu?A>TZ-M=}@hQeiRNPPrR0@r^aLtcR%qnj&L*f z5+m0!``i_dd2An&jUvQQSr*ykj_e*>A{iKG$hQ`v&!jE(ZJU2=&~=9)XpLQl$a6W8 z?hA&NezYw9f6t9JL+HTji8z8-(GbHb9q30!I|ha|4Piv$NaJP{>kL_cl^Qb0G9-Af zcieG=eIaayEq#fW%aDfgM&-zBh$5oATN-X4!jNpqk$5#8c7%P(I|IRxZdqMEXmeYt z{roWGzLyTwc`?nBmQW!R=eE@qj&mx9M9GdAqAGao(k`eQZS|Ym8t$RO5bF!K%?D#a z2{O9zb}>g&x{Ww=RHHB$QVT_S?aG0M2dFUwEGk1o_W}DH`R7PuM}vunr2d@{y%X6V z@d0Vd`muVwB;os1O5IqLe08Ei6w{<}B6FWaD;`B|>?vob>l&i&W(5kfwlC|m-sk3T*f?R#(7D5vgzIYr( z`raW%V1<}gi6@CQS{bBJq;{0Bjt#oqrCVafZHiV;8JoCEIhCh$1w2nFQ)&zC$+a19o}A$k9?wZlvWhfJOv%sW m1V}X~w>sRo0uKKLKk)_Uu7gXy;9XyE;X1hD3x4Y9+xr7Gk@d9z literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/components/gates/XorGate.class b/era.mi/bin/era/mi/logic/components/gates/XorGate.class new file mode 100644 index 0000000000000000000000000000000000000000..d5b5adb6e2aeb2db13d6c48f2d0341ad4a25ac72 GIT binary patch literal 1236 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 literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/timeline/Timeline$InnerEvent.class b/era.mi/bin/era/mi/logic/timeline/Timeline$InnerEvent.class new file mode 100644 index 0000000000000000000000000000000000000000..41d0ab6885175b7a3a0eee4474dfdc28e195f16a GIT binary patch literal 1090 zcma)5O>+`K5PiKY5XeH1dp^&m*}NJZMH;B*nx zPK;6UtC=!M7A~Q55zfLO3e7Nh-@j0UgplDRZH5Hu5LP}<%^=ZZLuhqxE^Uh*hvqC& zahs4<(uA;gn>5B}l5;(&JtyogNf7LzHadApnAVqpm)!qH`Zm~hr_m$0N8>Y<1L2N` zRd{)%uPnokK<`PP_MN-uJCXA4rJO0o*lxYD4a~xB#Rbd=Vnq|?`m$b%SxtrVCFh%~s I(ZoKSzu0v7asU7T literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/timeline/Timeline.class b/era.mi/bin/era/mi/logic/timeline/Timeline.class new file mode 100644 index 0000000000000000000000000000000000000000..7bdc178cea702c184812fc42262c6b45ce57b3f1 GIT binary patch literal 2556 zcmbVN+j10D6kTU7>CB{a=MqSaAqg@w0U8w%9pn~+Bo5b!fq=J@o|B|W&-7GJcZ3h{ z4}8(`-4}eYN}vj=ET1hu$+BFhyCDrif=()Z`t06k?X}n5z59>9AO8m61eyji0^`b; zR@1RuZ_Tl-z-cPiX(?+lxiOFv7`P)hrRB=jnssI6jP06e@=(1o+fCI9r`{unxTMLAeU24 z%Lz^k^%g$wWmvv(5w=~H^CQ3NSCr)Rs+17r& z^+4Jimt;E$*rV<$I}DUQr%xOM_(m5pZLyuj4<$wz03IERmQlg#NBT_`W< zTtCr4*F!3pBRG%6M>@LO4n=Wtp78P0zTeg-`;PC69KNU!z z&sVw#o9bzqyMmC^c zY%=MhK1jmOO4qGBfvWa*VOii%I;Hr7kcLbw<@o`8UF6iYO^rL=D>TR4Z}On#J`zLD{0^&DnR$q}nFW{kUL<~ic~5fOPw|^KogzMxgy~^gC-DK% z1wO>_B#OltnoOQi27l&FCdIatVw+E31gg&{o*_kjxHqPFDpGihS6@`CBdp0$R>Vqy z^*#eTgR=>f4n@xsY)Ug3`&ORUpif{eS7x5z-131(nC1V4hnT<%s7Lu5g#3_b9HiU9tm3-O&kwZ+K33z<7lsYoXP-iNbe3AfLU@^+y<) z=PMfb%P?_vQIXy3pFL6hi74%H)X7Qz#<3X5uKhlvcLuuR1!VuiP_A%Rck~hs8Qj24 cuDUtCqD`U!g;iRH_{^epjq5t@z{S3Q01~%j;s5{u literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/timeline/TimelineEvent.class b/era.mi/bin/era/mi/logic/timeline/TimelineEvent.class new file mode 100644 index 0000000000000000000000000000000000000000..7eac32e0416ca5c7076dbe6854f3602658621a2b GIT binary patch literal 448 zcma)2xlY4C5Pf4iHg=qYE0hQ!q$EYQqXE$%QbZ9HMDEvSWj69587F^5fdoRL-~;$5 z#CUN-$4aw1$J;k==Ii_86Tmr+JXnNNRY{R+k(H@VM6Gj`=|YKB>)dQrQG0L*!?oN> zk;x(zckx;!HNj=LE>Z$5IJne>uCEBrcrl6ixh@}602|#99zudWo{)Ccb~xj+H|J_o52o*I$8YGp7|ek0zNz?d5HPljA?HTse}G-) pYffNTc}v*GLCYx^LtN`jU(tJJ$3jErn&iOHguj56hHz+5qaVRDQmp_0 literal 0 HcmV?d00001 diff --git a/era.mi/bin/era/mi/logic/timeline/TimelineEventHandler.class b/era.mi/bin/era/mi/logic/timeline/TimelineEventHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..7a4a6f7811b07600a1d6d16b9bad0e62cdf741c3 GIT binary patch literal 203 zcmX^0Z`VEs1_m<*PId++Mh30aqD1}NO#Phv^vq=alFZ!HoXosb{SYX_wJbHS#3L~; zB`39roq>gsK_Dx!EKxrvF)v-;KPf9UxrC8{Edwmi$e^L&LxgG8nqiC#T*3LJMaijd pnK`M943gMv(*s$=#>l|PzzlRQ0|O(_a#jX55Q~8wNHQ^S005GaIV=DG literal 0 HcmV?d00001 diff --git a/era.mi/src/era/mi/logic/Bit.java b/era.mi/src/era/mi/logic/Bit.java new file mode 100644 index 00000000..b18c5974 --- /dev/null +++ b/era.mi/src/era/mi/logic/Bit.java @@ -0,0 +1,62 @@ +package era.mi.logic; + + +public enum Bit +{ + ONE, ZERO, Z, X; + + public static Bit and(Bit a, Bit b) + { + return a.and(b); + } + + public Bit and(Bit other) + { + if(equals(Bit.ZERO) || other.equals(Bit.ZERO)) + return Bit.ZERO; + else if(equals(other) && equals(Bit.ONE)) + return Bit.ONE; + else + return Bit.X; + } + + public static Bit or(Bit a, Bit b) + { + return a.or(b); + } + + public Bit or(Bit other) + { + if(equals(Bit.ONE) || other.equals(Bit.ONE)) + return Bit.ONE; + else if(equals(other) && equals(Bit.ZERO)) + return Bit.ZERO; + else + return Bit.X; + } + + public static Bit xor(Bit a, Bit b) + { + return a.xor(b); + } + + public Bit xor(Bit other) + { + //I'm uncertain how this should behave for cases where one value is neither 1 nor 0. + //TODO: Implement xor + return Bit.X; + } + + public Bit not() + { + switch(this) + { + case ONE: + return Bit.ZERO; + case ZERO: + return Bit.ONE; + default: + return Bit.X; + } + } +} diff --git a/era.mi/src/era/mi/logic/Simulation.java b/era.mi/src/era/mi/logic/Simulation.java new file mode 100644 index 00000000..6a63e155 --- /dev/null +++ b/era.mi/src/era/mi/logic/Simulation.java @@ -0,0 +1,12 @@ +package era.mi.logic; + +import era.mi.logic.timeline.Timeline; + +public class Simulation +{ + public final static Timeline TIMELINE = new Timeline(11); + + public static void main(String[] args) + { + } +} \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/Util.java b/era.mi/src/era/mi/logic/Util.java new file mode 100644 index 00000000..6f1b93ff --- /dev/null +++ b/era.mi/src/era/mi/logic/Util.java @@ -0,0 +1,92 @@ +package era.mi.logic; + +import java.util.Arrays; + +public final class Util +{ + + @SuppressWarnings("unchecked") + public static T[] concat(T[]... arrays) + { + if(arrays.length == 0) + throw new IllegalArgumentException("Cannot concatenate 0 arrays."); + + int length = 0; + for(T[] array : arrays) + length += array.length; + + T[] newArray = Arrays.copyOf(arrays[0], length); + int appendIndex = arrays[0].length; + for(int i = 1; i < arrays.length; i++) + { + System.arraycopy(arrays[i], 0, newArray, appendIndex, arrays[i].length); + appendIndex += arrays[i].length; + } + + return newArray; + } + +// @SuppressWarnings("unchecked") +// public static T[][] split(T[] array, int... lengths) +// { +// //TODO: implement array split again; This version contains an illegal cast +// int totalLength = 0; +// for(int length : lengths) +// totalLength += length; +// +// if(totalLength != array.length) +// throw new IllegalArgumentException(); //TODO: add proper error message +// +// Object[][] newArray = new Object[lengths.length][]; +// int splitIndex = 0; +// for(int i = 0; i < lengths.length; i++) +// { +// System.arraycopy(array, splitIndex, newArray, 0, lengths[i]); +// splitIndex += lengths[i]; +// } +// +// return (T[][]) newArray; +// } + + public static Bit[] and(Bit[] a, Bit[] b) + { + return binBitOp(a, b, (bA, bB) -> Bit.and(bA, bB)); + } + + public static Bit[] or(Bit[] a, Bit[] b) + { + return binBitOp(a, b, (bA, bB) -> Bit.or(bA, bB)); + } + + public static Bit[] xor(Bit[] a, Bit[] b) + { + return binBitOp(a, b, (bA, bB) -> Bit.xor(bA, bB)); + } + + private static Bit[] binBitOp(Bit[] a, Bit[] b, BitOp op) + { + if(a.length != b.length) + throw new IllegalArgumentException("Bit Arrays were not of equal length."); + Bit[] out = new Bit[a.length]; + for(int i = 0; i < a.length; i++) + { + out[i] = op.execute(a[i], b[i]); + } + return out; + } + + public static Bit[] not(Bit[] a) + { + Bit[] out = new Bit[a.length]; + for(int i = 0; i < a.length; i++) + { + out[i] = a[i].not(); + } + return out; + } + + interface BitOp + { + Bit execute(Bit a, Bit b); + } +} diff --git a/era.mi/src/era/mi/logic/WireArray.java b/era.mi/src/era/mi/logic/WireArray.java new file mode 100644 index 00000000..64d90c17 --- /dev/null +++ b/era.mi/src/era/mi/logic/WireArray.java @@ -0,0 +1,208 @@ +package era.mi.logic; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Represents an array of wires that can store n bits of information. + * @author Fabian Stemmler + * + */ +public class WireArray +{ + private Bit[] values; + private final int travelTime; + private List observers = new ArrayList<>();//(); + private final int length; + + public WireArray(int length, int travelTime) + { + if(length < 1) + throw new IllegalArgumentException("Tried to create an array of wires with length " + length + ", but a length of less than 1 makes no sense."); + this.length = length; + this.travelTime = travelTime; + initValues(); + } + + private void initValues() + { + values = new Bit[length]; + for(int i = 0; i < length; i++) + values[i] = Bit.X; + } + + /** + * Sets the wires values. This takes up time, as specified by the {@link WireArray}s travel time. + * @param newValues The new values the wires should take on. + * + * @author Fabian Stemmler + */ + public void feedSignals(Bit... newValues) + { + Simulation.TIMELINE.addEvent((e) -> setValues(newValues), travelTime); + } + + private void setValues(Bit... newValues) + { + if(length != newValues.length) + throw new IllegalArgumentException(String.format("Unexpected length for input array. Length was %d but expected %d", newValues.length, length)); //TODO: Proper handling + if(!Arrays.equals(values, newValues)) + { + values = newValues.clone(); + notifyObservers(); + } + } + + /** + * Sets values of a subarray of wires. This takes up time, as specified by the {@link WireArray}s travel time. + * @param newValues The new values the wires should take on. + * @param startingBit The first index of the subarray of wires. + * + * @author Fabian Stemmler + */ + public void feedSignals(int startingBit, Bit... newValues) + { + Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime); + } + + private void setValues(int startingBit, Bit... newValues) + { + if(length < startingBit + newValues.length) + throw new IllegalArgumentException(); //TODO: Proper handling + if(!Arrays.equals(values, startingBit, startingBit + newValues.length, newValues, 0, newValues.length)) + { + System.arraycopy(newValues, 0, values, startingBit, newValues.length); + notifyObservers(); + } + } + + /** + * The WireArray is interpreted as an unsigned integer with n bits. + * @return true if all bits are either Bit.ONE or Bit.ZERO (they do not all have to have the same value), not Bit.X or Bit.Z. false is returned otherwise. + * + * @author Fabian Stemmler + */ + public boolean hasNumericValue() + { + for(Bit b : values) + { + if(b != Bit.ZERO && b != Bit.ONE) + return false; + } + return true; + } + + /** + * The WireArray is interpreted as an unsigned integer with n bits. + * @return The unsigned value of the {@link WireArray}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public int getUnsignedValue() + { + int val = 0; + int mask = 1; + for(int i = 0; i < length; i++) + { + switch(values[i]) + { + default: + case Z: + case X: + return 0; //TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0; Random number? + case ONE: + val |= mask; + break; + case ZERO: + } + mask = mask << 1; + } + return val; + } + + /** + * The WireArray is interpreted as a signed integer with n bits. + * @return The signed value of the {@link WireArray}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on. + * + * @author Fabian Stemmler + */ + public int getSignedValue() + { + int val = getUnsignedValue(); + int mask = 1 << (length - 1); + if((mask & val) != 0) + { + int shifts = 32 - length; + return (val << shifts) >> shifts; + } + return val; + } + + /** + * Included for convenient use on {@link WireArray}s of length 1. + * @return The value of bit 0. + * + * @author Fabian Stemmler + */ + public Bit getValue() + { + return getValue(0); + } + + /** + * + * @param index Index of the requested bit. + * @return The value of the indexed bit. + * + * @author Fabian Stemmler + */ + public Bit getValue(int index) + { + //TODO: ArrayIndexOutOfBoundsException handling for accessing single bit in WireArray + return values[index]; + } + + public Bit[] getValues(int start, int end) + { + int length = end - start; + Bit[] bits = new Bit[length]; + System.arraycopy(values, start, bits, 0, length); + return bits; + } + + + /** + * @return An array of length n containing the values of the n bits in the {@link WireArray}. Can be safely modified. + * + * @author Fabian Stemmler + */ + public Bit[] getValues() + { + return values.clone(); + } + + public int length() + { + return length; + } + + + /** + * Adds an {@link WireArrayObserver}, who will be notified when the value of the {@link WireArray} is updated. + * @param ob The {@link WireArrayObserver} to be notified of changes. + * @return true if the given {@link WireArrayObserver} was not already registered, false otherwise + * + * @author Fabian Stemmler + */ + public boolean addObserver(WireArrayObserver ob) + { + return observers.add(ob); + } + + private void notifyObservers() + { + for(WireArrayObserver o : observers) + o.update(this); + } +} diff --git a/era.mi/src/era/mi/logic/WireArrayObserver.java b/era.mi/src/era/mi/logic/WireArrayObserver.java new file mode 100644 index 00000000..1b469fa9 --- /dev/null +++ b/era.mi/src/era/mi/logic/WireArrayObserver.java @@ -0,0 +1,6 @@ +package era.mi.logic; + +public interface WireArrayObserver +{ + public void update(WireArray initiator); +} diff --git a/era.mi/src/era/mi/logic/components/BasicComponent.java b/era.mi/src/era/mi/logic/components/BasicComponent.java new file mode 100644 index 00000000..ad93dfe2 --- /dev/null +++ b/era.mi/src/era/mi/logic/components/BasicComponent.java @@ -0,0 +1,29 @@ +package era.mi.logic.components; + +import era.mi.logic.Simulation; +import era.mi.logic.WireArray; +import era.mi.logic.WireArrayObserver; + +public abstract class BasicComponent implements WireArrayObserver +{ + private int processTime; + + /** + * + * @param processTime Amount of time this component takes to update its outputs. Must be more than 0, otherwise 1 is assumed. + * + * @author Fabian Stemmler + */ + public BasicComponent(int processTime) + { + this.processTime = processTime > 0 ? processTime : 1; + } + + @Override + public void update(WireArray initiator) + { + Simulation.TIMELINE.addEvent((e) -> {compute();}, processTime); + } + + protected abstract void compute(); +} diff --git a/era.mi/src/era/mi/logic/components/Clock.java b/era.mi/src/era/mi/logic/components/Clock.java new file mode 100644 index 00000000..3efde15c --- /dev/null +++ b/era.mi/src/era/mi/logic/components/Clock.java @@ -0,0 +1,31 @@ +package era.mi.logic.components; + +import era.mi.logic.Bit; +import era.mi.logic.Simulation; +import era.mi.logic.WireArray; +import era.mi.logic.timeline.TimelineEvent; +import era.mi.logic.timeline.TimelineEventHandler; + +public class Clock implements TimelineEventHandler +{ + private boolean toggle = false; + private WireArray w; + + public Clock(WireArray w) + { + this.w = w; + } + + @Override + public void handle(TimelineEvent e) + { + Simulation.TIMELINE.addEvent(this, 50); + w.feedSignals(new Bit[] { toggle ? Bit.ONE : Bit.ZERO }); + toggle = !toggle; + } + + public WireArray getW() + { + return w; + } +} diff --git a/era.mi/src/era/mi/logic/components/Merger.java b/era.mi/src/era/mi/logic/components/Merger.java new file mode 100644 index 00000000..eb910a4f --- /dev/null +++ b/era.mi/src/era/mi/logic/components/Merger.java @@ -0,0 +1,61 @@ +package era.mi.logic.components; + +import era.mi.logic.Util; +import era.mi.logic.Bit; +import era.mi.logic.WireArray; +import era.mi.logic.WireArrayObserver; + +@Deprecated +public class Merger implements WireArrayObserver +{ + private WireArray out; + private WireArray[] inputs; + + //TODO: General problem with this concept; New inputs coming in at the same time override each other + + /** + * + * @param union The output of merging n {@link WireArray}s into one. Must have length = a1.length() + a2.length() + ... + an.length(). + * @param inputs The inputs to be merged into the union + */ + public Merger(WireArray union, WireArray... inputs) + { + this.inputs = inputs; + this.out = union; + + int length = 0; + for(WireArray input : inputs) + { + length += input.length(); + input.addObserver(this); + } + + if(length != union.length()) + throw new IllegalArgumentException("The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length()."); + } + + protected void compute() + { + Bit[][] bits = new Bit[inputs.length][]; + for(int i = 0; i < inputs.length; i++) + bits[i] = inputs[i].getValues(); + Bit[] newOut = Util.concat(bits); + out.feedSignals(newOut); + } + + public WireArray getInput(int index) + { + return inputs[index]; + } + + public WireArray getUnion() + { + return out; + } + + @Override + public void update(WireArray initiator) + { + compute(); //No inner delay + } +} diff --git a/era.mi/src/era/mi/logic/components/Merger2.java b/era.mi/src/era/mi/logic/components/Merger2.java new file mode 100644 index 00000000..ca242544 --- /dev/null +++ b/era.mi/src/era/mi/logic/components/Merger2.java @@ -0,0 +1,70 @@ +package era.mi.logic.components; + +import era.mi.logic.WireArray; +import era.mi.logic.WireArrayObserver; + +public class Merger2 implements WireArrayObserver +{ + private WireArray out; + private WireArray[] inputs; + private int[] beginningIndex; + + /** + * + * @param union The output of merging n {@link WireArray}s into one. Must have length = a1.length() + a2.length() + ... + an.length(). + * @param inputs The inputs to be merged into the union + */ + public Merger2(WireArray union, WireArray... inputs) + { + this.inputs = inputs; + this.out = union; + this.beginningIndex = new int[inputs.length]; + + int length = 0; + for(int i = 0; i < inputs.length; i++) + { + beginningIndex[i] = length; + length += inputs[i].length(); + inputs[i].addObserver(this); + } + + if(length != union.length()) + throw new IllegalArgumentException("The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length()."); + } + + public WireArray getInput(int index) + { + return inputs[index]; + } + + public WireArray getUnion() + { + return out; + } + + @Override + public void update(WireArray initiator) + { + int index = find(initiator); + int beginning = beginningIndex[index]; + out.feedSignals(beginning, initiator.getValues()); + } + + private int find(WireArray w) + { + for(int i = 0; i < inputs.length; i++) + if(inputs[i] == w) + return i; + return -1; + } + + public WireArray getOut() + { + return out; + } + + public WireArray[] getInputs() + { + return inputs.clone(); + } +} diff --git a/era.mi/src/era/mi/logic/components/Mux.java b/era.mi/src/era/mi/logic/components/Mux.java new file mode 100644 index 00000000..29c48146 --- /dev/null +++ b/era.mi/src/era/mi/logic/components/Mux.java @@ -0,0 +1,77 @@ +package era.mi.logic.components; + +import era.mi.logic.Bit; +import era.mi.logic.WireArray; + +/** + * Models a Multiplexer. A is selected when select bit is 1, B when select bit is 0. Outputs X otherwise. + * @author Fabian + * + */ +public class Mux extends BasicComponent +{ + private WireArray a, b, out; + private WireArray select; + private final int size; + + /** + * {@link WireArray}s a, b and out must be of uniform length, select + * @param a Must be of uniform length with b and out. + * @param b Must be of uniform length with a and out. + * @param select C + * @param out Must be of uniform length with a and b. + */ + public Mux(int processTime, WireArray a, WireArray b, WireArray select, WireArray out) + { + super(processTime); + size = a.length(); + if(b.length() != out.length() || b.length() != size) + throw new IllegalArgumentException("All MUX wire arrays must be of uniform length!"); + this.a = a; + a.addObserver(this); + this.b = b; + b.addObserver(this); + this.select = select; + select.addObserver(this); + this.out = out; + } + + @Override + protected void compute() + { + WireArray active = b; + switch(select.getValue()) + { + case ONE: + active = a; + case ZERO: + out.feedSignals(active.getValues()); + break; + default: + Bit[] newValues = new Bit[size]; + for(int i = 0; i < size; i++) + newValues[i] = Bit.X; + out.feedSignals(newValues); + } + } + + public WireArray getA() + { + return a; + } + + public WireArray getB() + { + return b; + } + + public WireArray getOut() + { + return out; + } + + public WireArray getSelect() + { + return select; + } +} diff --git a/era.mi/src/era/mi/logic/components/Splitter.java b/era.mi/src/era/mi/logic/components/Splitter.java new file mode 100644 index 00000000..48db52d9 --- /dev/null +++ b/era.mi/src/era/mi/logic/components/Splitter.java @@ -0,0 +1,53 @@ +package era.mi.logic.components; + +import era.mi.logic.Bit; +import era.mi.logic.WireArray; +import era.mi.logic.WireArrayObserver; + +public class Splitter implements WireArrayObserver +{ + private WireArray input; + private WireArray[] outputs; + + public Splitter(WireArray input, WireArray... outputs) + { + this.input = input; + this.outputs = outputs; + input.addObserver(this); + int length = 0; + for(WireArray out : outputs) + length += out.length(); + + if(input.length() != length) + throw new IllegalArgumentException("The input of splitting one into n WireArrays must have length = a1.length() + a2.length() + ... + an.length()."); + } + + protected void compute() + { + int startIndex = 0; + Bit[] inputBits = input.getValues(); + for(int i = 0; i < outputs.length; i++) + { + Bit[] outputBits = new Bit[outputs[i].length()]; + System.arraycopy(inputBits, startIndex, outputBits, 0, outputs[i].length()); + outputs[i].feedSignals(outputBits); + startIndex += outputs[i].length(); + } + } + + public WireArray getInput() + { + return input; + } + + public WireArray[] getOutputs() + { + return outputs.clone(); + } + + @Override + public void update(WireArray initiator) + { + compute(); + } +} diff --git a/era.mi/src/era/mi/logic/components/gates/AndGate.java b/era.mi/src/era/mi/logic/components/gates/AndGate.java new file mode 100644 index 00000000..762eeef8 --- /dev/null +++ b/era.mi/src/era/mi/logic/components/gates/AndGate.java @@ -0,0 +1,40 @@ +package era.mi.logic.components.gates; + +import era.mi.logic.Util; +import era.mi.logic.WireArray; +import era.mi.logic.components.BasicComponent; + +public class AndGate extends BasicComponent +{ + private WireArray a, b, out; + + public AndGate(int processTime, WireArray a, WireArray b, WireArray out) + { + super(processTime); + this.a = a; + a.addObserver(this); + this.b = b; + b.addObserver(this); + this.out = out; + } + + protected void compute() + { + out.feedSignals(Util.and(a.getValues(), b.getValues())); + } + + public WireArray getA() + { + return a; + } + + public WireArray getB() + { + return b; + } + + public WireArray getOut() + { + return out; + } +} diff --git a/era.mi/src/era/mi/logic/components/gates/NotGate.java b/era.mi/src/era/mi/logic/components/gates/NotGate.java new file mode 100644 index 00000000..55d0cb01 --- /dev/null +++ b/era.mi/src/era/mi/logic/components/gates/NotGate.java @@ -0,0 +1,33 @@ +package era.mi.logic.components.gates; + +import era.mi.logic.Util; +import era.mi.logic.WireArray; +import era.mi.logic.components.BasicComponent; + +public class NotGate extends BasicComponent +{ + private WireArray in, out; + + public NotGate(int processTime, WireArray in, WireArray out) + { + super(processTime); + this.in = in; + in.addObserver(this); + this.out = out; + } + + public void compute() + { + out.feedSignals(Util.not(in.getValues())); + } + + public WireArray getIn() + { + return in; + } + + public WireArray getOut() + { + return out; + } +} diff --git a/era.mi/src/era/mi/logic/components/gates/OrGate.java b/era.mi/src/era/mi/logic/components/gates/OrGate.java new file mode 100644 index 00000000..06296bab --- /dev/null +++ b/era.mi/src/era/mi/logic/components/gates/OrGate.java @@ -0,0 +1,40 @@ +package era.mi.logic.components.gates; + +import era.mi.logic.Util; +import era.mi.logic.WireArray; +import era.mi.logic.components.BasicComponent; + +public class OrGate extends BasicComponent +{ + private WireArray a, b, out; + + public OrGate(int processTime, WireArray a, WireArray b, WireArray out) + { + super(processTime); + this.a = a; + a.addObserver(this); + this.b = b; + b.addObserver(this); + this.out = out; + } + + protected void compute() + { + out.feedSignals(Util.or(a.getValues(), b.getValues())); + } + + public WireArray getA() + { + return a; + } + + public WireArray getB() + { + return b; + } + + public WireArray getOut() + { + return out; + } +} diff --git a/era.mi/src/era/mi/logic/components/gates/XorGate.java b/era.mi/src/era/mi/logic/components/gates/XorGate.java new file mode 100644 index 00000000..9287f3fd --- /dev/null +++ b/era.mi/src/era/mi/logic/components/gates/XorGate.java @@ -0,0 +1,40 @@ +package era.mi.logic.components.gates; + +import era.mi.logic.Util; +import era.mi.logic.WireArray; +import era.mi.logic.components.BasicComponent; + +public class XorGate extends BasicComponent +{ + private WireArray a, b, out; + + public XorGate(int processTime, WireArray a, WireArray b, WireArray out) + { + super(processTime); + this.a = a; + a.addObserver(this); + this.b = b; + b.addObserver(this); + this.out = out; + } + + protected void compute() + { + out.feedSignals(Util.xor(a.getValues(), b.getValues())); + } + + public WireArray getA() + { + return a; + } + + public WireArray getB() + { + return b; + } + + public WireArray getOut() + { + return out; + } +} diff --git a/era.mi/src/era/mi/logic/tests/ComponentTest.java b/era.mi/src/era/mi/logic/tests/ComponentTest.java new file mode 100644 index 00000000..f5ec68c0 --- /dev/null +++ b/era.mi/src/era/mi/logic/tests/ComponentTest.java @@ -0,0 +1,206 @@ +package era.mi.logic.tests; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import era.mi.logic.Bit; +import era.mi.logic.Simulation; +import era.mi.logic.WireArray; +import era.mi.logic.components.Merger2; +import era.mi.logic.components.Mux; +import era.mi.logic.components.Splitter; +import era.mi.logic.components.gates.AndGate; +import era.mi.logic.components.gates.NotGate; +import era.mi.logic.components.gates.OrGate; + +class ComponentTest +{ + + @Test + void circuitExampleTest() + { + Simulation.TIMELINE.reset(); + WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), c = new WireArray(1, 10), d = new WireArray(2, 1), e = new WireArray(1, 1), + f = new WireArray(1, 1), g = new WireArray(1, 1), h = new WireArray(2, 1), i = new WireArray(2, 1), j = new WireArray(1, 1), k = new WireArray(1, 1); + new AndGate(1, a, b, f); + new NotGate(1, f, g); + new Merger2(h, c, g); + new Mux(1, h, d, e, i); + new Splitter(i, k, j); + + a.feedSignals(Bit.ZERO); + b.feedSignals(Bit.ONE); + c.feedSignals(Bit.ZERO); + d.feedSignals(Bit.ONE, Bit.ONE); + e.feedSignals(Bit.ONE); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(Simulation.TIMELINE.getSimulationTime(), 14); + assertEquals(Bit.ONE, j.getValue()); + assertEquals(Bit.ZERO, k.getValue()); + } + + @Test + void splitterTest() + { + Simulation.TIMELINE.reset(); + WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), in = new WireArray(8, 1); + in.feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO,Bit.ONE, Bit.ZERO, Bit.ONE); + new Splitter(in, a, b, c); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertTrue(Arrays.equals(a.getValues(), new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO })); + assertTrue(Arrays.equals(b.getValues(), new Bit[] { Bit.ONE, Bit.ZERO })); + assertTrue(Arrays.equals(c.getValues(), new Bit[] { Bit.ONE, Bit.ZERO, Bit.ONE })); + } + + @Test + void mergerTest() + { + Simulation.TIMELINE.reset(); + WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), out = new WireArray(8, 1); + a.feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO); + b.feedSignals(Bit.ONE, Bit.ZERO); + c.feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); + + new Merger2(out, a, b, c); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertTrue(Arrays.equals(out.getValues(), new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE })); + } + + @Test + void muxTest() + { + Simulation.TIMELINE.reset(); + WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), select = new WireArray(1, 1), out = new WireArray(1, 1); + + select.feedSignals(Bit.ONE); + a.feedSignals(Bit.ONE); + b.feedSignals(Bit.ZERO); + + new Mux(1, a, b, select, out); + assertEquals(out.getValue(), Bit.X); + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(out.getValue(), Bit.ONE); + select.feedSignals(Bit.ZERO); + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(out.getValue(), Bit.ZERO); + } + + @Test + void andTest() + { + Simulation.TIMELINE.reset(); + AndGate gate = new AndGate(1, new WireArray(4, 1), new WireArray(4, 1), new WireArray(4, 1)); + gate.getA().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); + gate.getB().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + assertTrue(Arrays.equals(gate.getOut().getValues(), new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO })); + } + + @Test + void orTest() + { + Simulation.TIMELINE.reset(); + OrGate gate = new OrGate(1, new WireArray(4, 1), new WireArray(4, 1), new WireArray(4, 1)); + gate.getA().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); + gate.getB().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + assertTrue(Arrays.equals(gate.getOut().getValues(), new Bit[] { Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE })); + } + + @Test + void rsLatchCircuitTest() + { + Simulation.TIMELINE.reset(); + WireArray r = new WireArray(1, 1), s = new WireArray(1, 1), t1 = new WireArray(1, 15), t2 = new WireArray(1, 1), q = new WireArray(1, 1), + nq = new WireArray(1, 1); + + new OrGate(1, r, nq, t2); + new OrGate(1, s, q, t1); + new NotGate(1, t2, q); + new NotGate(1, t1, nq); + + s.feedSignals(Bit.ONE); + r.feedSignals(Bit.ZERO); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(q.getValue(), Bit.ONE); + assertEquals(nq.getValue(), Bit.ZERO); + + s.feedSignals(Bit.ZERO); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(q.getValue(), Bit.ONE); + assertEquals(nq.getValue(), Bit.ZERO); + + r.feedSignals(Bit.ONE); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(q.getValue(), Bit.ZERO); + assertEquals(nq.getValue(), Bit.ONE); + } + + @Test + void numericValueTest() + { + Simulation.TIMELINE.reset(); + + WireArray a = new WireArray(4, 1); + a.feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE); + + while(Simulation.TIMELINE.hasNext()) + { + Simulation.TIMELINE.executeNext(); + } + + assertEquals(a.getUnsignedValue(), 15); + assertEquals(a.getSignedValue(), -1); + } +} diff --git a/era.mi/src/era/mi/logic/timeline/Timeline.java b/era.mi/src/era/mi/logic/timeline/Timeline.java new file mode 100644 index 00000000..bdd59476 --- /dev/null +++ b/era.mi/src/era/mi/logic/timeline/Timeline.java @@ -0,0 +1,90 @@ +package era.mi.logic.timeline; + +import java.util.PriorityQueue; + +/** + * Orders Events by the time they are due to be executed. Can execute Events individually. + * @author Fabian Stemmler + * + */ +public class Timeline +{ + private PriorityQueue events; + private long currentTime = 0; + + public Timeline(int initCapacity) + { + events = new PriorityQueue(initCapacity, (a, b) -> { + //Is this really necessary? If only ints are allowed as relative timing, the difference should always be an int + long difference = a.getTiming() - b.getTiming(); + if(difference == 0) + return 0; + return difference < 0 ? -1 : 1; + }); + } + + public boolean hasNext() + { + return !events.isEmpty(); + } + + public void executeNext() + { + InnerEvent first = events.poll(); + currentTime = first.getTiming(); + first.run(); + } + + public long getSimulationTime() + { + return currentTime; + } + + public void reset() + { + events.clear(); + currentTime = 0; + } + + /** + * Adds an Event to the {@link Timeline} + * @param function The {@link TimelineEventHandler} that will be executed, when the {@link InnerEvent} occurs on the timeline. + * @param relativeTiming The amount of MI ticks in which the {@link InnerEvent} is called, starting from the current time. + */ + public void addEvent(TimelineEventHandler function, int relativeTiming) + { + long timing = currentTime + relativeTiming; + events.add(new InnerEvent(function, new TimelineEvent(timing), timing)); + } + + private class InnerEvent + { + + private final long timing; + private final TimelineEventHandler function; + private final TimelineEvent event; + + /** + * Creates an {@link InnerEvent} + * @param function {@link TimelineEventHandler} to be executed when the {@link InnerEvent} occurs + * @param timing Point in the MI simulation {@link Timeline}, at which the {@link InnerEvent} is executed; + */ + InnerEvent(TimelineEventHandler function, TimelineEvent event, long timing) + { + this.function = function; + this.event = event; + this.timing = timing; + } + + public long getTiming() + { + return timing; + } + + public void run() + { + function.handle(event); + } + + } +} \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/timeline/TimelineEvent.java b/era.mi/src/era/mi/logic/timeline/TimelineEvent.java new file mode 100644 index 00000000..6cec9079 --- /dev/null +++ b/era.mi/src/era/mi/logic/timeline/TimelineEvent.java @@ -0,0 +1,17 @@ +package era.mi.logic.timeline; + +public class TimelineEvent +{ + private final long timing; + + TimelineEvent(long timing) + { + super(); + this.timing = timing; + } + + public long getTiming() + { + return timing; + } +} \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/timeline/TimelineEventHandler.java b/era.mi/src/era/mi/logic/timeline/TimelineEventHandler.java new file mode 100644 index 00000000..59a91c95 --- /dev/null +++ b/era.mi/src/era/mi/logic/timeline/TimelineEventHandler.java @@ -0,0 +1,6 @@ +package era.mi.logic.timeline; + +public interface TimelineEventHandler +{ + public void handle(TimelineEvent e); +} \ No newline at end of file -- 2.17.1